@adhdev/daemon-standalone 1.0.56-rc.6 → 1.0.56-rc.8
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 +1759 -1037
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/public/assets/{index-B43wNsru.js → index-keXYbbIn.js} +1 -1
- package/public/index.html +1 -1
- package/vendor/mcp-server/index.js +137 -7
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -36620,10 +36620,10 @@ var require_dist3 = __commonJS({
|
|
|
36620
36620
|
}
|
|
36621
36621
|
function getDaemonBuildInfo() {
|
|
36622
36622
|
if (cached2) return cached2;
|
|
36623
|
-
const commit = readInjected(true ? "
|
|
36624
|
-
const commitShort = readInjected(true ? "
|
|
36625
|
-
const version2 = readInjected(true ? "1.0.56-rc.
|
|
36626
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
36623
|
+
const commit = readInjected(true ? "f45b1ccbf70f856ec2232e2dc5a87acaf875243e" : void 0) ?? "unknown";
|
|
36624
|
+
const commitShort = readInjected(true ? "f45b1ccb" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
36625
|
+
const version2 = readInjected(true ? "1.0.56-rc.8" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
36626
|
+
const builtAt = readInjected(true ? "2026-08-19T16:04:19.674Z" : void 0);
|
|
36627
36627
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
36628
36628
|
return cached2;
|
|
36629
36629
|
}
|
|
@@ -40952,11 +40952,11 @@ child.on('exit', () => process.exit(0));
|
|
|
40952
40952
|
}
|
|
40953
40953
|
function windowsExtraBinDirs() {
|
|
40954
40954
|
const dirs = [];
|
|
40955
|
-
const
|
|
40955
|
+
const fs61 = require("fs");
|
|
40956
40956
|
const push = (dir) => {
|
|
40957
40957
|
if (!dir) return;
|
|
40958
40958
|
try {
|
|
40959
|
-
if (
|
|
40959
|
+
if (fs61.existsSync(dir)) dirs.push(dir);
|
|
40960
40960
|
} catch {
|
|
40961
40961
|
}
|
|
40962
40962
|
};
|
|
@@ -40972,12 +40972,12 @@ child.on('exit', () => process.exit(0));
|
|
|
40972
40972
|
}
|
|
40973
40973
|
function unixExtraBinDirs() {
|
|
40974
40974
|
const dirs = [];
|
|
40975
|
-
const
|
|
40975
|
+
const fs61 = require("fs");
|
|
40976
40976
|
const home = os52.homedir();
|
|
40977
40977
|
const push = (dir) => {
|
|
40978
40978
|
if (!dir) return;
|
|
40979
40979
|
try {
|
|
40980
|
-
if (
|
|
40980
|
+
if (fs61.existsSync(dir)) dirs.push(dir);
|
|
40981
40981
|
} catch {
|
|
40982
40982
|
}
|
|
40983
40983
|
};
|
|
@@ -41016,9 +41016,9 @@ child.on('exit', () => process.exit(0));
|
|
|
41016
41016
|
for (const ext of exes) {
|
|
41017
41017
|
const fullPath = path9.join(p, trimmed + ext);
|
|
41018
41018
|
try {
|
|
41019
|
-
const
|
|
41020
|
-
if (
|
|
41021
|
-
const stat2 =
|
|
41019
|
+
const fs61 = require("fs");
|
|
41020
|
+
if (fs61.existsSync(fullPath)) {
|
|
41021
|
+
const stat2 = fs61.statSync(fullPath);
|
|
41022
41022
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
41023
41023
|
return fullPath;
|
|
41024
41024
|
}
|
|
@@ -41032,12 +41032,12 @@ child.on('exit', () => process.exit(0));
|
|
|
41032
41032
|
function isScriptBinary(binaryPath) {
|
|
41033
41033
|
if (!path9.isAbsolute(binaryPath)) return false;
|
|
41034
41034
|
try {
|
|
41035
|
-
const
|
|
41036
|
-
const resolved =
|
|
41035
|
+
const fs61 = require("fs");
|
|
41036
|
+
const resolved = fs61.realpathSync(binaryPath);
|
|
41037
41037
|
const head = Buffer.alloc(8);
|
|
41038
|
-
const fd =
|
|
41039
|
-
|
|
41040
|
-
|
|
41038
|
+
const fd = fs61.openSync(resolved, "r");
|
|
41039
|
+
fs61.readSync(fd, head, 0, 8, 0);
|
|
41040
|
+
fs61.closeSync(fd);
|
|
41041
41041
|
let i = 0;
|
|
41042
41042
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
41043
41043
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -41048,12 +41048,12 @@ child.on('exit', () => process.exit(0));
|
|
|
41048
41048
|
function looksLikeMachOOrElf(filePath) {
|
|
41049
41049
|
if (!path9.isAbsolute(filePath)) return false;
|
|
41050
41050
|
try {
|
|
41051
|
-
const
|
|
41052
|
-
const resolved =
|
|
41051
|
+
const fs61 = require("fs");
|
|
41052
|
+
const resolved = fs61.realpathSync(filePath);
|
|
41053
41053
|
const buf = Buffer.alloc(8);
|
|
41054
|
-
const fd =
|
|
41055
|
-
|
|
41056
|
-
|
|
41054
|
+
const fd = fs61.openSync(resolved, "r");
|
|
41055
|
+
fs61.readSync(fd, buf, 0, 8, 0);
|
|
41056
|
+
fs61.closeSync(fd);
|
|
41057
41057
|
let i = 0;
|
|
41058
41058
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
41059
41059
|
const b = buf.subarray(i);
|
|
@@ -44261,6 +44261,13 @@ Next step: ${nextStep}`;
|
|
|
44261
44261
|
import_meta = {};
|
|
44262
44262
|
}
|
|
44263
44263
|
});
|
|
44264
|
+
function normalizeDeliveryMode(raw) {
|
|
44265
|
+
if (raw === void 0 || raw === null || raw === "") return { mode: DEFAULT_DELIVERY_MODE };
|
|
44266
|
+
const v = String(raw).trim().toLowerCase();
|
|
44267
|
+
if (v === "when_idle" || v === "whenidle") return { mode: "when_idle" };
|
|
44268
|
+
if (v === "interrupt") return { mode: "interrupt" };
|
|
44269
|
+
return { mode: DEFAULT_DELIVERY_MODE, unrecognized: String(raw) };
|
|
44270
|
+
}
|
|
44264
44271
|
function resolveDeliveryDecision(sessionStatus, opts) {
|
|
44265
44272
|
const status = (sessionStatus || "").trim().toLowerCase();
|
|
44266
44273
|
if (!status) {
|
|
@@ -44292,6 +44299,20 @@ Next step: ${nextStep}`;
|
|
|
44292
44299
|
message: "Session is waiting for approval \u2014 approval message delivered immediately."
|
|
44293
44300
|
};
|
|
44294
44301
|
}
|
|
44302
|
+
if (opts?.deliveryMode === "interrupt") {
|
|
44303
|
+
if (!opts.interruptSupported) {
|
|
44304
|
+
return {
|
|
44305
|
+
decision: "rejected",
|
|
44306
|
+
reason: "interrupt_unsupported_for_provider",
|
|
44307
|
+
message: opts.interruptUnsupportedMessage ?? `Session is ${status} and delivery mode 'interrupt' was requested, but this provider cannot interrupt a running turn. Refusing rather than silently queueing: queueing would let the current turn finish on the old instructions. Re-dispatch with delivery mode 'when_idle' if delivery-after-completion is acceptable.`
|
|
44308
|
+
};
|
|
44309
|
+
}
|
|
44310
|
+
return {
|
|
44311
|
+
decision: "interrupt",
|
|
44312
|
+
reason: `session_${status}_interrupt_requested`,
|
|
44313
|
+
message: `Session is ${status}. Aborting the in-flight turn via the provider's stop control, then delivering the task once it settles to idle. The work the session had not yet finished is discarded.`
|
|
44314
|
+
};
|
|
44315
|
+
}
|
|
44295
44316
|
return {
|
|
44296
44317
|
decision: "queued",
|
|
44297
44318
|
reason: `session_${status}_busy`,
|
|
@@ -44380,6 +44401,7 @@ Next step: ${nextStep}`;
|
|
|
44380
44401
|
}
|
|
44381
44402
|
}
|
|
44382
44403
|
var import_crypto4;
|
|
44404
|
+
var DEFAULT_DELIVERY_MODE;
|
|
44383
44405
|
var IMMEDIATE_DELIVERY_STATUSES;
|
|
44384
44406
|
var BUSY_DELIVERY_STATUSES;
|
|
44385
44407
|
var TERMINAL_DELIVERY_STATUSES;
|
|
@@ -44388,6 +44410,7 @@ Next step: ${nextStep}`;
|
|
|
44388
44410
|
"use strict";
|
|
44389
44411
|
import_crypto4 = require("crypto");
|
|
44390
44412
|
init_mesh_runtime_store();
|
|
44413
|
+
DEFAULT_DELIVERY_MODE = "when_idle";
|
|
44391
44414
|
IMMEDIATE_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
44392
44415
|
"idle",
|
|
44393
44416
|
"waiting_input",
|
|
@@ -45688,6 +45711,25 @@ Next step: ${nextStep}`;
|
|
|
45688
45711
|
while (end > 0 && (buf[end] & 192) === 128) end -= 1;
|
|
45689
45712
|
return `${buf.subarray(0, end).toString("utf8")}${marker}`;
|
|
45690
45713
|
}
|
|
45714
|
+
function describeAvailablePointers(upstream) {
|
|
45715
|
+
if (!upstream) return " (no output is recorded for that ref yet)";
|
|
45716
|
+
const envelope = upstream.envelope;
|
|
45717
|
+
if (!envelope || typeof envelope !== "object" || Array.isArray(envelope)) {
|
|
45718
|
+
return " (that ref has an output, but its envelope is not an object)";
|
|
45719
|
+
}
|
|
45720
|
+
const pointers = [];
|
|
45721
|
+
for (const key2 of Object.keys(envelope)) {
|
|
45722
|
+
pointers.push(`/${key2}`);
|
|
45723
|
+
if (key2 !== "worker_result") continue;
|
|
45724
|
+
const workerResult = envelope.worker_result;
|
|
45725
|
+
if (!workerResult || typeof workerResult !== "object" || Array.isArray(workerResult)) continue;
|
|
45726
|
+
for (const sub of Object.keys(workerResult)) {
|
|
45727
|
+
pointers.push(`/worker_result/${sub}`);
|
|
45728
|
+
}
|
|
45729
|
+
}
|
|
45730
|
+
if (pointers.length === 0) return " (that ref's envelope is empty)";
|
|
45731
|
+
return `. Available pointers on ref '${upstream.ref}': ${pointers.join(", ")}`;
|
|
45732
|
+
}
|
|
45691
45733
|
function resolveInputBindings(bindings, outputsByRef) {
|
|
45692
45734
|
const resolved = [];
|
|
45693
45735
|
let totalBytes = 0;
|
|
@@ -45698,7 +45740,7 @@ Next step: ${nextStep}`;
|
|
|
45698
45740
|
if (binding.required) {
|
|
45699
45741
|
throw new MeshMaterializationError(
|
|
45700
45742
|
"required_input_missing",
|
|
45701
|
-
`required binding '${binding.as}' found nothing at '${binding.select}' of ref '${binding.from}'
|
|
45743
|
+
`required binding '${binding.as}' found nothing at '${binding.select}' of ref '${binding.from}'` + describeAvailablePointers(upstream),
|
|
45702
45744
|
binding.as
|
|
45703
45745
|
);
|
|
45704
45746
|
}
|
|
@@ -47122,108 +47164,6 @@ ${blocks.join("\n\n")}`;
|
|
|
47122
47164
|
GIT_STASH_READONLY_SUBCOMMANDS = /* @__PURE__ */ new Set(["list", "show"]);
|
|
47123
47165
|
}
|
|
47124
47166
|
});
|
|
47125
|
-
function readPayloadTaskId(entry) {
|
|
47126
|
-
const value = entry.payload?.taskId;
|
|
47127
|
-
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
47128
|
-
}
|
|
47129
|
-
function parseTime(value) {
|
|
47130
|
-
if (!value) return null;
|
|
47131
|
-
const parsed = new Date(value).getTime();
|
|
47132
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
47133
|
-
}
|
|
47134
|
-
function computeMeshTaskStats(meshId, opts) {
|
|
47135
|
-
const queue = getQueue(meshId);
|
|
47136
|
-
const queueById = new Map(queue.map((task) => [task.id, task]));
|
|
47137
|
-
let targetIds;
|
|
47138
|
-
if (opts?.taskIds?.length) {
|
|
47139
|
-
targetIds = [...new Set(opts.taskIds)];
|
|
47140
|
-
} else if (opts?.missionId) {
|
|
47141
|
-
targetIds = queue.filter((task) => task.missionId === opts.missionId).map((task) => task.id);
|
|
47142
|
-
} else {
|
|
47143
|
-
targetIds = queue.map((task) => task.id);
|
|
47144
|
-
}
|
|
47145
|
-
if (targetIds.length === 0) return [];
|
|
47146
|
-
const targetSet = new Set(targetIds);
|
|
47147
|
-
const entries = readLedgerEntries(meshId, { tail: opts?.tail ?? 1e3 });
|
|
47148
|
-
const dispatches = /* @__PURE__ */ new Map();
|
|
47149
|
-
const terminals = /* @__PURE__ */ new Map();
|
|
47150
|
-
for (const entry of entries) {
|
|
47151
|
-
const taskId = readPayloadTaskId(entry);
|
|
47152
|
-
if (!taskId || !targetSet.has(taskId)) continue;
|
|
47153
|
-
if (entry.kind === "task_dispatched") {
|
|
47154
|
-
const existing = dispatches.get(taskId);
|
|
47155
|
-
if (existing) existing.count += 1;
|
|
47156
|
-
else dispatches.set(taskId, { first: entry.timestamp, count: 1 });
|
|
47157
|
-
} else if (entry.kind === "task_completed" || entry.kind === "task_failed") {
|
|
47158
|
-
terminals.set(taskId, { at: entry.timestamp, kind: entry.kind });
|
|
47159
|
-
}
|
|
47160
|
-
}
|
|
47161
|
-
return targetIds.map((taskId) => {
|
|
47162
|
-
const queueEntry = queueById.get(taskId);
|
|
47163
|
-
const dispatch = dispatches.get(taskId);
|
|
47164
|
-
const terminal = terminals.get(taskId);
|
|
47165
|
-
const status = queueEntry?.status ?? (terminal ? terminal.kind === "task_completed" ? "completed" : "failed" : "unknown");
|
|
47166
|
-
const isTerminalStatus = status === "completed" || status === "failed" || status === "cancelled";
|
|
47167
|
-
const dispatchTime = parseTime(dispatch?.first ?? queueEntry?.dispatchTimestamp);
|
|
47168
|
-
const terminalTime = parseTime(terminal?.at);
|
|
47169
|
-
const stats = {
|
|
47170
|
-
taskId,
|
|
47171
|
-
status,
|
|
47172
|
-
dispatchedAt: dispatch?.first ?? queueEntry?.dispatchTimestamp ?? null,
|
|
47173
|
-
terminalAt: terminal?.at ?? null,
|
|
47174
|
-
terminalKind: terminal?.kind ?? null,
|
|
47175
|
-
durationMs: null,
|
|
47176
|
-
dispatchCount: dispatch?.count ?? 0,
|
|
47177
|
-
requeueCount: queueEntry?.requeueCount ?? 0
|
|
47178
|
-
};
|
|
47179
|
-
if (dispatchTime !== null && terminalTime !== null && terminalTime >= dispatchTime) {
|
|
47180
|
-
stats.durationMs = terminalTime - dispatchTime;
|
|
47181
|
-
} else if (isTerminalStatus) {
|
|
47182
|
-
stats.incompleteEvidence = true;
|
|
47183
|
-
}
|
|
47184
|
-
return stats;
|
|
47185
|
-
});
|
|
47186
|
-
}
|
|
47187
|
-
function computeMeshMissionStats(meshId, missionId) {
|
|
47188
|
-
const tasks = computeMeshTaskStats(meshId, { missionId });
|
|
47189
|
-
const stats = {
|
|
47190
|
-
missionId,
|
|
47191
|
-
taskCount: tasks.length,
|
|
47192
|
-
completed: 0,
|
|
47193
|
-
failed: 0,
|
|
47194
|
-
totalDurationMs: 0,
|
|
47195
|
-
wallClockMs: null,
|
|
47196
|
-
retries: 0,
|
|
47197
|
-
incompleteTaskIds: []
|
|
47198
|
-
};
|
|
47199
|
-
let firstDispatch = null;
|
|
47200
|
-
let lastTerminal = null;
|
|
47201
|
-
for (const task of tasks) {
|
|
47202
|
-
if (task.status === "completed") stats.completed += 1;
|
|
47203
|
-
else if (task.status === "failed") stats.failed += 1;
|
|
47204
|
-
stats.retries += task.requeueCount;
|
|
47205
|
-
if (task.incompleteEvidence) {
|
|
47206
|
-
stats.incompleteTaskIds.push(task.taskId);
|
|
47207
|
-
continue;
|
|
47208
|
-
}
|
|
47209
|
-
if (task.durationMs !== null) stats.totalDurationMs += task.durationMs;
|
|
47210
|
-
const dispatchTime = parseTime(task.dispatchedAt);
|
|
47211
|
-
const terminalTime = parseTime(task.terminalAt);
|
|
47212
|
-
if (dispatchTime !== null && (firstDispatch === null || dispatchTime < firstDispatch)) firstDispatch = dispatchTime;
|
|
47213
|
-
if (terminalTime !== null && (lastTerminal === null || terminalTime > lastTerminal)) lastTerminal = terminalTime;
|
|
47214
|
-
}
|
|
47215
|
-
if (firstDispatch !== null && lastTerminal !== null && lastTerminal >= firstDispatch) {
|
|
47216
|
-
stats.wallClockMs = lastTerminal - firstDispatch;
|
|
47217
|
-
}
|
|
47218
|
-
return stats;
|
|
47219
|
-
}
|
|
47220
|
-
var init_mesh_task_stats = __esm2({
|
|
47221
|
-
"src/mesh/mesh-task-stats.ts"() {
|
|
47222
|
-
"use strict";
|
|
47223
|
-
init_mesh_ledger();
|
|
47224
|
-
init_mesh_work_queue();
|
|
47225
|
-
}
|
|
47226
|
-
});
|
|
47227
47167
|
function truncateString(value, maxChars) {
|
|
47228
47168
|
if (value.length <= maxChars) return value;
|
|
47229
47169
|
if (maxChars <= 12) return value.slice(0, Math.max(0, maxChars));
|
|
@@ -47943,6 +47883,7 @@ ${blocks.join("\n\n")}`;
|
|
|
47943
47883
|
const taskId = readNonEmptyString(metadata.taskId) || readNonEmptyString(readRecord2(metadata.payload)?.taskId);
|
|
47944
47884
|
const jobId = readRefineJobId2(event);
|
|
47945
47885
|
const timestamp2 = metadata.timestamp !== void 0 && metadata.timestamp !== null ? String(metadata.timestamp) : "";
|
|
47886
|
+
const alertReason = COORDINATOR_ALERT_EVENTS_WITH_REASON_FINGERPRINT.has(event.event) ? readNonEmptyString(metadata.reason) : void 0;
|
|
47946
47887
|
return [
|
|
47947
47888
|
event.meshId,
|
|
47948
47889
|
event.event,
|
|
@@ -47951,14 +47892,35 @@ ${blocks.join("\n\n")}`;
|
|
|
47951
47892
|
providerSessionId || "",
|
|
47952
47893
|
taskId || "",
|
|
47953
47894
|
jobId || "",
|
|
47954
|
-
timestamp2 || ""
|
|
47895
|
+
timestamp2 || "",
|
|
47896
|
+
...alertReason ? [alertReason] : []
|
|
47955
47897
|
].join("::");
|
|
47956
47898
|
}
|
|
47899
|
+
function isDurablyDedupedEvent(event) {
|
|
47900
|
+
if (!TERMINAL_COMPLETION_EVENTS.has(event.event)) return false;
|
|
47901
|
+
const metadata = readRecord2(event.metadataEvent) || {};
|
|
47902
|
+
const taskId = readNonEmptyString(metadata.taskId) || readNonEmptyString(readRecord2(metadata.payload)?.taskId);
|
|
47903
|
+
return !!taskId;
|
|
47904
|
+
}
|
|
47905
|
+
function recordDurableTerminalDedup(event, fingerprint) {
|
|
47906
|
+
if (!isDurablyDedupedEvent(event)) return;
|
|
47907
|
+
try {
|
|
47908
|
+
const store = MeshRuntimeStore.getInstance();
|
|
47909
|
+
store.recordCompletionFingerprint(event.meshId, `pending::${fingerprint}`, TERMINAL_COMPLETION_DEDUP_TTL_MS);
|
|
47910
|
+
store.sweepExpiredFingerprints();
|
|
47911
|
+
} catch {
|
|
47912
|
+
}
|
|
47913
|
+
}
|
|
47957
47914
|
function hasPendingCoordinatorEventDuplicate(event) {
|
|
47958
47915
|
const fingerprint = buildPendingEventFingerprint(event);
|
|
47959
47916
|
if (!fingerprint.trim()) return false;
|
|
47960
47917
|
try {
|
|
47961
|
-
|
|
47918
|
+
const store = MeshRuntimeStore.getInstance();
|
|
47919
|
+
if (store.hasPendingEventFingerprint(event.meshId, fingerprint)) return true;
|
|
47920
|
+
if (isDurablyDedupedEvent(event) && store.hasCompletionFingerprint(event.meshId, `pending::${fingerprint}`)) {
|
|
47921
|
+
return true;
|
|
47922
|
+
}
|
|
47923
|
+
return false;
|
|
47962
47924
|
} catch {
|
|
47963
47925
|
return false;
|
|
47964
47926
|
}
|
|
@@ -48181,6 +48143,7 @@ ${blocks.join("\n\n")}`;
|
|
|
48181
48143
|
dispatchedBy: event.dispatchedBy ? JSON.stringify(event.dispatchedBy) : null,
|
|
48182
48144
|
intendedFor: event.intendedFor ? JSON.stringify(event.intendedFor) : null
|
|
48183
48145
|
});
|
|
48146
|
+
recordDurableTerminalDedup(event, fingerprint);
|
|
48184
48147
|
return true;
|
|
48185
48148
|
} catch (e) {
|
|
48186
48149
|
LOG2.error(
|
|
@@ -48400,6 +48363,8 @@ ${blocks.join("\n\n")}`;
|
|
|
48400
48363
|
var warnedV2Violations;
|
|
48401
48364
|
var loggedSqlitePendingDrainFailure;
|
|
48402
48365
|
var TERMINAL_COMPLETION_EVENTS;
|
|
48366
|
+
var COORDINATOR_ALERT_EVENTS_WITH_REASON_FINGERPRINT;
|
|
48367
|
+
var TERMINAL_COMPLETION_DEDUP_TTL_MS;
|
|
48403
48368
|
var PENDING_EVENTS_DRAINED_RETENTION_MS;
|
|
48404
48369
|
var PENDING_EVENTS_UNDRAINED_RETENTION_MS;
|
|
48405
48370
|
var PENDING_RETENTION_EXPIRED_HOLD_REASON;
|
|
@@ -48450,6 +48415,10 @@ ${blocks.join("\n\n")}`;
|
|
|
48450
48415
|
warnedV2Violations = /* @__PURE__ */ new Set();
|
|
48451
48416
|
loggedSqlitePendingDrainFailure = false;
|
|
48452
48417
|
TERMINAL_COMPLETION_EVENTS = /* @__PURE__ */ new Set(["agent:generating_completed", "agent:stopped"]);
|
|
48418
|
+
COORDINATOR_ALERT_EVENTS_WITH_REASON_FINGERPRINT = /* @__PURE__ */ new Set([
|
|
48419
|
+
"mesh:dispatch_blocked"
|
|
48420
|
+
]);
|
|
48421
|
+
TERMINAL_COMPLETION_DEDUP_TTL_MS = 60 * 60 * 1e3;
|
|
48453
48422
|
PENDING_EVENTS_DRAINED_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
48454
48423
|
PENDING_EVENTS_UNDRAINED_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
48455
48424
|
PENDING_RETENTION_EXPIRED_HOLD_REASON = "pending_retention_expired";
|
|
@@ -48470,6 +48439,245 @@ ${blocks.join("\n\n")}`;
|
|
|
48470
48439
|
};
|
|
48471
48440
|
}
|
|
48472
48441
|
});
|
|
48442
|
+
function s(v) {
|
|
48443
|
+
return typeof v === "string" && v.trim() ? v.trim() : "";
|
|
48444
|
+
}
|
|
48445
|
+
function meshEventTraceKey(ctx) {
|
|
48446
|
+
const segs = [`task=${s(ctx.taskId) || "-"}`];
|
|
48447
|
+
const eventId = s(ctx.eventId);
|
|
48448
|
+
if (eventId) segs.push(`evt=${eventId}`);
|
|
48449
|
+
segs.push(`sess=${s(ctx.sessionId) || "-"}`);
|
|
48450
|
+
const nodeId = s(ctx.nodeId);
|
|
48451
|
+
if (nodeId) segs.push(`node=${nodeId}`);
|
|
48452
|
+
const meshId = s(ctx.meshId);
|
|
48453
|
+
if (meshId) segs.push(`mesh=${meshId}`);
|
|
48454
|
+
const event = s(ctx.event);
|
|
48455
|
+
if (event) segs.push(`event=${event}`);
|
|
48456
|
+
return segs.join(" ");
|
|
48457
|
+
}
|
|
48458
|
+
function traceMeshEventStage(stage, ctx, detail) {
|
|
48459
|
+
LOG2.info(CAT, `[stage:${stage}] ${meshEventTraceKey(ctx)}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
48460
|
+
}
|
|
48461
|
+
function traceMeshEventDrop(reason, ctx, detail) {
|
|
48462
|
+
LOG2.warn(CAT, `[drop:${reason}] ${meshEventTraceKey(ctx)}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
48463
|
+
}
|
|
48464
|
+
var CAT;
|
|
48465
|
+
var init_mesh_event_trace = __esm2({
|
|
48466
|
+
"src/mesh/mesh-event-trace.ts"() {
|
|
48467
|
+
"use strict";
|
|
48468
|
+
init_logger();
|
|
48469
|
+
CAT = "EvtTrace";
|
|
48470
|
+
}
|
|
48471
|
+
});
|
|
48472
|
+
function taskIsParked(task) {
|
|
48473
|
+
return !!readNonEmptyString(task?.parked?.reason);
|
|
48474
|
+
}
|
|
48475
|
+
function buildParkingRecord(task, reason, nowIso = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
48476
|
+
return {
|
|
48477
|
+
reason,
|
|
48478
|
+
parkedAt: nowIso,
|
|
48479
|
+
// Mirror the ORIGINAL address. `targetSessionId` also stays on the row
|
|
48480
|
+
// (that is what keeps the row unclaimable), but a later re-target
|
|
48481
|
+
// overwrites it — this copy is what still answers "who was this delta
|
|
48482
|
+
// written for?" after the coordinator has moved it.
|
|
48483
|
+
...readNonEmptyString(task.targetSessionId) ? { targetSessionId: task.targetSessionId } : {},
|
|
48484
|
+
...readNonEmptyString(task.targetNodeId) ? { targetNodeId: task.targetNodeId } : {}
|
|
48485
|
+
};
|
|
48486
|
+
}
|
|
48487
|
+
function parkedAgeMs(task, nowMs = Date.now()) {
|
|
48488
|
+
const parkedAt = readNonEmptyString(task.parked?.parkedAt);
|
|
48489
|
+
if (!parkedAt) return null;
|
|
48490
|
+
const parsed = Date.parse(parkedAt);
|
|
48491
|
+
return Number.isFinite(parsed) ? nowMs - parsed : null;
|
|
48492
|
+
}
|
|
48493
|
+
function parkedTaskRetentionExpired(task, nowMs = Date.now(), retentionMs = PARKED_TASK_RETENTION_MS) {
|
|
48494
|
+
if (!taskIsParked(task)) return false;
|
|
48495
|
+
const age = parkedAgeMs(task, nowMs);
|
|
48496
|
+
return age !== null && age >= retentionMs;
|
|
48497
|
+
}
|
|
48498
|
+
function buildParkedTaskNotice(taskId, targetSessionId, reason) {
|
|
48499
|
+
const addressee = readNonEmptyString(targetSessionId);
|
|
48500
|
+
return `The delta was addressed to session '${addressee || "(unknown)"}' and that pin went stale (${reason || PARK_REASON_PIN_EXPIRED}), so the task is now PARKED \u2014 held for you, deliberately NOT re-homed onto another session. A message written for one session's context becomes a context-free instruction anywhere else, so the daemon will not choose a new addressee for you. The task is claimable by nobody until you act on it, and it is dropped (as a terminal failure, with another notification) if left parked for ${Math.round(PARKED_TASK_RETENTION_MS / 36e5)}h. Four ways out \u2014 inspect it with mesh_view_queue (parked rows are listed under parkedTasks with their original addressee), then either re-target it with mesh_queue_requeue(task_id='${taskId}', target_session_id='<live session>') \u2014 or clear_target_session to let any compatible session take it; REWRITE it first with mesh_queue_requeue(task_id='${taskId}', message='<updated instruction>') if the situation moved on while it waited (the common case: the worker already did the part your delta was about); or cancel it with mesh_queue_cancel(task_id='${taskId}') if it is no longer wanted. Any requeue unparks the task.`;
|
|
48501
|
+
}
|
|
48502
|
+
function notifyCoordinatorOfParkedTaskDropped(meshId, task) {
|
|
48503
|
+
const taskId = task.id;
|
|
48504
|
+
const addressee = readNonEmptyString(task.parked?.targetSessionId);
|
|
48505
|
+
const hours = Math.round(PARKED_TASK_RETENTION_MS / 36e5);
|
|
48506
|
+
const coordinatorMessage = `[System] A PARKED mesh task was dropped after ${hours}h with no coordinator decision.
|
|
48507
|
+
Task ${taskId} was parked because its delta was addressed to session '${addressee || "(unknown)"}' and that pin went stale. It was held \u2014 claimable by nobody \u2014 waiting for you to re-target, rewrite, or cancel it. That never happened, so it is now marked FAILED (${PARK_RETENTION_EXPIRED_REASON}) and any dependent tasks have been unblocked.
|
|
48508
|
+
The instruction it carried was never delivered to anyone. If it still matters, re-enqueue it (mesh_enqueue_task) against a live session; the failed row remains in the queue as the audit record. To avoid this next time, check parkedTasks in mesh_view_queue \u2014 parked rows are surfaced there from the moment they park.`;
|
|
48509
|
+
const nodeLabel = readNonEmptyString(task.targetNodeId) || readNonEmptyString(task.parked?.targetNodeId) || meshId;
|
|
48510
|
+
try {
|
|
48511
|
+
const targetCoordinatorDaemonId = readNonEmptyString(loadConfig2().machineId);
|
|
48512
|
+
const targetCoordinatorSessionId = readNonEmptyString(task.sourceCoordinatorSessionId);
|
|
48513
|
+
queuePendingMeshCoordinatorEvent({
|
|
48514
|
+
event: "mesh:dispatch_blocked",
|
|
48515
|
+
meshId,
|
|
48516
|
+
nodeLabel,
|
|
48517
|
+
metadataEvent: {
|
|
48518
|
+
source: "mesh_parked_task_retention_expired",
|
|
48519
|
+
taskId,
|
|
48520
|
+
reason: PARK_RETENTION_EXPIRED_REASON,
|
|
48521
|
+
...addressee ? { parkedTargetSessionId: addressee } : {},
|
|
48522
|
+
coordinatorMessage
|
|
48523
|
+
},
|
|
48524
|
+
coordinatorMessage,
|
|
48525
|
+
queuedAt: Date.now(),
|
|
48526
|
+
...targetCoordinatorDaemonId ? { targetCoordinatorDaemonId } : {},
|
|
48527
|
+
...targetCoordinatorSessionId ? { targetCoordinatorSessionId } : {}
|
|
48528
|
+
});
|
|
48529
|
+
} catch (e) {
|
|
48530
|
+
LOG2.warn("MeshQueue", `Failed to surface parked-task retention drop for task ${taskId} (mesh ${meshId}): ${e?.message || e}`);
|
|
48531
|
+
}
|
|
48532
|
+
}
|
|
48533
|
+
function parkExpiredTargetPin(meshId, task, verdict, ttlMs, park) {
|
|
48534
|
+
if (!verdict.expired) return false;
|
|
48535
|
+
const parked = park(meshId, task.id, PARK_REASON_PIN_EXPIRED);
|
|
48536
|
+
if (parked) {
|
|
48537
|
+
noteTargetPinCleared(PARK_REASON_PIN_EXPIRED);
|
|
48538
|
+
traceMeshEventDrop("target_session_pin_expired", {
|
|
48539
|
+
taskId: task.id,
|
|
48540
|
+
sessionId: readNonEmptyString(task.targetSessionId),
|
|
48541
|
+
nodeId: readNonEmptyString(task.targetNodeId),
|
|
48542
|
+
meshId,
|
|
48543
|
+
event: "agent:ready"
|
|
48544
|
+
}, `unproductive ${Math.round((verdict.ageMs ?? 0) / 1e3)}s \u2265 ttl ${Math.round(ttlMs / 1e3)}s \u2192 task PARKED (held for the coordinator, NOT re-homed)`);
|
|
48545
|
+
}
|
|
48546
|
+
return true;
|
|
48547
|
+
}
|
|
48548
|
+
function settleParkedQueueTask(meshId, task, markSkip, sweep) {
|
|
48549
|
+
const swept = sweep(meshId, task.id);
|
|
48550
|
+
if (swept) {
|
|
48551
|
+
notifyCoordinatorOfParkedTaskDropped(meshId, task);
|
|
48552
|
+
return "swept";
|
|
48553
|
+
}
|
|
48554
|
+
markSkip(PARKED_SKIP_REASON);
|
|
48555
|
+
return "held";
|
|
48556
|
+
}
|
|
48557
|
+
function logTaskParked(meshId, taskId, reason, targetSessionId) {
|
|
48558
|
+
LOG2.warn("MeshQueue", `PIN-PARKING: task ${taskId} (mesh ${meshId}) PARKED (${reason})${targetSessionId ? ` \u2014 original addressee session ${targetSessionId}` : ""}; it is claimable by nobody until the coordinator re-targets, edits, or cancels it.`);
|
|
48559
|
+
}
|
|
48560
|
+
var PARKED_TASK_RETENTION_MS;
|
|
48561
|
+
var PARK_REASON_PIN_EXPIRED;
|
|
48562
|
+
var PARKED_SKIP_REASON;
|
|
48563
|
+
var PARK_RETENTION_EXPIRED_REASON;
|
|
48564
|
+
var init_mesh_task_parking = __esm2({
|
|
48565
|
+
"src/mesh/mesh-task-parking.ts"() {
|
|
48566
|
+
"use strict";
|
|
48567
|
+
init_logger();
|
|
48568
|
+
init_mesh_events_utils();
|
|
48569
|
+
init_mesh_events_pending();
|
|
48570
|
+
init_mesh_turn_ledger();
|
|
48571
|
+
init_mesh_event_trace();
|
|
48572
|
+
init_config();
|
|
48573
|
+
PARKED_TASK_RETENTION_MS = 24 * 60 * 6e4;
|
|
48574
|
+
PARK_REASON_PIN_EXPIRED = "target_session_pin_expired_parked";
|
|
48575
|
+
PARKED_SKIP_REASON = "target_session_pin_parked";
|
|
48576
|
+
PARK_RETENTION_EXPIRED_REASON = "parked_task_retention_expired";
|
|
48577
|
+
}
|
|
48578
|
+
});
|
|
48579
|
+
function readPayloadTaskId(entry) {
|
|
48580
|
+
const value = entry.payload?.taskId;
|
|
48581
|
+
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
48582
|
+
}
|
|
48583
|
+
function parseTime(value) {
|
|
48584
|
+
if (!value) return null;
|
|
48585
|
+
const parsed = new Date(value).getTime();
|
|
48586
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
48587
|
+
}
|
|
48588
|
+
function computeMeshTaskStats(meshId, opts) {
|
|
48589
|
+
const queue = getQueue(meshId);
|
|
48590
|
+
const queueById = new Map(queue.map((task) => [task.id, task]));
|
|
48591
|
+
let targetIds;
|
|
48592
|
+
if (opts?.taskIds?.length) {
|
|
48593
|
+
targetIds = [...new Set(opts.taskIds)];
|
|
48594
|
+
} else if (opts?.missionId) {
|
|
48595
|
+
targetIds = queue.filter((task) => task.missionId === opts.missionId).map((task) => task.id);
|
|
48596
|
+
} else {
|
|
48597
|
+
targetIds = queue.map((task) => task.id);
|
|
48598
|
+
}
|
|
48599
|
+
if (targetIds.length === 0) return [];
|
|
48600
|
+
const targetSet = new Set(targetIds);
|
|
48601
|
+
const entries = readLedgerEntries(meshId, { tail: opts?.tail ?? 1e3 });
|
|
48602
|
+
const dispatches = /* @__PURE__ */ new Map();
|
|
48603
|
+
const terminals = /* @__PURE__ */ new Map();
|
|
48604
|
+
for (const entry of entries) {
|
|
48605
|
+
const taskId = readPayloadTaskId(entry);
|
|
48606
|
+
if (!taskId || !targetSet.has(taskId)) continue;
|
|
48607
|
+
if (entry.kind === "task_dispatched") {
|
|
48608
|
+
const existing = dispatches.get(taskId);
|
|
48609
|
+
if (existing) existing.count += 1;
|
|
48610
|
+
else dispatches.set(taskId, { first: entry.timestamp, count: 1 });
|
|
48611
|
+
} else if (entry.kind === "task_completed" || entry.kind === "task_failed") {
|
|
48612
|
+
terminals.set(taskId, { at: entry.timestamp, kind: entry.kind });
|
|
48613
|
+
}
|
|
48614
|
+
}
|
|
48615
|
+
return targetIds.map((taskId) => {
|
|
48616
|
+
const queueEntry = queueById.get(taskId);
|
|
48617
|
+
const dispatch = dispatches.get(taskId);
|
|
48618
|
+
const terminal = terminals.get(taskId);
|
|
48619
|
+
const status = queueEntry?.status ?? (terminal ? terminal.kind === "task_completed" ? "completed" : "failed" : "unknown");
|
|
48620
|
+
const isTerminalStatus = status === "completed" || status === "failed" || status === "cancelled";
|
|
48621
|
+
const dispatchTime = parseTime(dispatch?.first ?? queueEntry?.dispatchTimestamp);
|
|
48622
|
+
const terminalTime = parseTime(terminal?.at);
|
|
48623
|
+
const stats = {
|
|
48624
|
+
taskId,
|
|
48625
|
+
status,
|
|
48626
|
+
dispatchedAt: dispatch?.first ?? queueEntry?.dispatchTimestamp ?? null,
|
|
48627
|
+
terminalAt: terminal?.at ?? null,
|
|
48628
|
+
terminalKind: terminal?.kind ?? null,
|
|
48629
|
+
durationMs: null,
|
|
48630
|
+
dispatchCount: dispatch?.count ?? 0,
|
|
48631
|
+
requeueCount: queueEntry?.requeueCount ?? 0
|
|
48632
|
+
};
|
|
48633
|
+
if (dispatchTime !== null && terminalTime !== null && terminalTime >= dispatchTime) {
|
|
48634
|
+
stats.durationMs = terminalTime - dispatchTime;
|
|
48635
|
+
} else if (isTerminalStatus) {
|
|
48636
|
+
stats.incompleteEvidence = true;
|
|
48637
|
+
}
|
|
48638
|
+
return stats;
|
|
48639
|
+
});
|
|
48640
|
+
}
|
|
48641
|
+
function computeMeshMissionStats(meshId, missionId) {
|
|
48642
|
+
const tasks = computeMeshTaskStats(meshId, { missionId });
|
|
48643
|
+
const stats = {
|
|
48644
|
+
missionId,
|
|
48645
|
+
taskCount: tasks.length,
|
|
48646
|
+
completed: 0,
|
|
48647
|
+
failed: 0,
|
|
48648
|
+
totalDurationMs: 0,
|
|
48649
|
+
wallClockMs: null,
|
|
48650
|
+
retries: 0,
|
|
48651
|
+
incompleteTaskIds: []
|
|
48652
|
+
};
|
|
48653
|
+
let firstDispatch = null;
|
|
48654
|
+
let lastTerminal = null;
|
|
48655
|
+
for (const task of tasks) {
|
|
48656
|
+
if (task.status === "completed") stats.completed += 1;
|
|
48657
|
+
else if (task.status === "failed") stats.failed += 1;
|
|
48658
|
+
stats.retries += task.requeueCount;
|
|
48659
|
+
if (task.incompleteEvidence) {
|
|
48660
|
+
stats.incompleteTaskIds.push(task.taskId);
|
|
48661
|
+
continue;
|
|
48662
|
+
}
|
|
48663
|
+
if (task.durationMs !== null) stats.totalDurationMs += task.durationMs;
|
|
48664
|
+
const dispatchTime = parseTime(task.dispatchedAt);
|
|
48665
|
+
const terminalTime = parseTime(task.terminalAt);
|
|
48666
|
+
if (dispatchTime !== null && (firstDispatch === null || dispatchTime < firstDispatch)) firstDispatch = dispatchTime;
|
|
48667
|
+
if (terminalTime !== null && (lastTerminal === null || terminalTime > lastTerminal)) lastTerminal = terminalTime;
|
|
48668
|
+
}
|
|
48669
|
+
if (firstDispatch !== null && lastTerminal !== null && lastTerminal >= firstDispatch) {
|
|
48670
|
+
stats.wallClockMs = lastTerminal - firstDispatch;
|
|
48671
|
+
}
|
|
48672
|
+
return stats;
|
|
48673
|
+
}
|
|
48674
|
+
var init_mesh_task_stats = __esm2({
|
|
48675
|
+
"src/mesh/mesh-task-stats.ts"() {
|
|
48676
|
+
"use strict";
|
|
48677
|
+
init_mesh_ledger();
|
|
48678
|
+
init_mesh_work_queue();
|
|
48679
|
+
}
|
|
48680
|
+
});
|
|
48473
48681
|
var mesh_missions_exports = {};
|
|
48474
48682
|
__export2(mesh_missions_exports, {
|
|
48475
48683
|
COMPACT_STATUS_GOAL_PREVIEW_MAX: () => COMPACT_STATUS_GOAL_PREVIEW_MAX,
|
|
@@ -48855,11 +49063,12 @@ ${blocks.join("\n\n")}`;
|
|
|
48855
49063
|
describeTaskDependencyState: () => describeTaskDependencyState,
|
|
48856
49064
|
enqueueTask: () => enqueueTask,
|
|
48857
49065
|
enqueueTaskGraph: () => enqueueTaskGraph,
|
|
48858
|
-
|
|
49066
|
+
failRetentionExpiredParkedTask: () => failRetentionExpiredParkedTask,
|
|
48859
49067
|
formatMeshTaskModeViolations: () => formatMeshTaskModeViolations,
|
|
48860
49068
|
getActiveDirectDispatches: () => getActiveDirectDispatches,
|
|
48861
49069
|
getMeshQueueRevision: () => getMeshQueueRevision,
|
|
48862
49070
|
getMeshQueueStats: () => getMeshQueueStats,
|
|
49071
|
+
getParkedTasks: () => getParkedTasks,
|
|
48863
49072
|
getQueue: () => getQueue,
|
|
48864
49073
|
hasPendingDependents: () => hasPendingDependents,
|
|
48865
49074
|
insertDirectDispatch: () => insertDirectDispatch,
|
|
@@ -48871,6 +49080,7 @@ ${blocks.join("\n\n")}`;
|
|
|
48871
49080
|
normalizeMeshCapabilityTags: () => normalizeMeshCapabilityTags,
|
|
48872
49081
|
normalizeMeshTaskMode: () => normalizeMeshTaskMode,
|
|
48873
49082
|
normalizeMeshTaskPriority: () => normalizeMeshTaskPriority,
|
|
49083
|
+
parkTaskTargetPin: () => parkTaskTargetPin,
|
|
48874
49084
|
reclaimStrandedAssignedTask: () => reclaimStrandedAssignedTask,
|
|
48875
49085
|
recordDirectDispatchTask: () => recordDirectDispatchTask,
|
|
48876
49086
|
recordMeshToolCall: () => recordMeshToolCall,
|
|
@@ -49352,6 +49562,7 @@ ${blocks.join("\n\n")}`;
|
|
|
49352
49562
|
entry.status = "cancelled";
|
|
49353
49563
|
entry.cancelledAt = now;
|
|
49354
49564
|
if (opts?.reason) entry.cancelReason = opts.reason;
|
|
49565
|
+
delete entry.parked;
|
|
49355
49566
|
delete entry.assignedNodeId;
|
|
49356
49567
|
delete entry.assignedSessionId;
|
|
49357
49568
|
delete entry.assignedProviderType;
|
|
@@ -49384,6 +49595,12 @@ ${blocks.join("\n\n")}`;
|
|
|
49384
49595
|
if (value) lastCancelledTaskAssignment.delete(key2);
|
|
49385
49596
|
return value;
|
|
49386
49597
|
}
|
|
49598
|
+
function applyRequeueMessageEdit(entry, message) {
|
|
49599
|
+
if (typeof message !== "string") return;
|
|
49600
|
+
const next = message.trim();
|
|
49601
|
+
if (!next || next === entry.message) return;
|
|
49602
|
+
entry.message = next;
|
|
49603
|
+
}
|
|
49387
49604
|
function requeueTask(meshId, taskId, opts) {
|
|
49388
49605
|
requireMeshHostQueueOwner(opts);
|
|
49389
49606
|
const result = withQueueLock(meshId, () => {
|
|
@@ -49418,6 +49635,8 @@ ${blocks.join("\n\n")}`;
|
|
|
49418
49635
|
entry.requeuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
49419
49636
|
entry.dispatchFailureCount = dispatchFailures;
|
|
49420
49637
|
if (opts?.reason) entry.requeueReason = opts.reason;
|
|
49638
|
+
applyRequeueMessageEdit(entry, opts?.message);
|
|
49639
|
+
delete entry.parked;
|
|
49421
49640
|
const backoffMs = DISPATCH_RETRY_BACKOFF_BASE_MS * Math.pow(2, dispatchFailures - 1);
|
|
49422
49641
|
entry.notBefore = resolveNotBefore(Math.min(backoffMs, DISPATCH_RETRY_BACKOFF_MAX_MS));
|
|
49423
49642
|
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
@@ -49446,6 +49665,8 @@ ${blocks.join("\n\n")}`;
|
|
|
49446
49665
|
entry.requeuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
49447
49666
|
entry.requeueCount = currentCount + 1;
|
|
49448
49667
|
if (opts?.reason) entry.requeueReason = opts.reason;
|
|
49668
|
+
applyRequeueMessageEdit(entry, opts?.message);
|
|
49669
|
+
delete entry.parked;
|
|
49449
49670
|
const notBefore = resolveNotBefore(opts?.notBefore);
|
|
49450
49671
|
if (notBefore) entry.notBefore = notBefore;
|
|
49451
49672
|
else delete entry.notBefore;
|
|
@@ -49455,24 +49676,46 @@ ${blocks.join("\n\n")}`;
|
|
|
49455
49676
|
if (result?.missionAffected) scheduleMissionCloseCandidateCheck(meshId, [result.entry, ...result.cascaded]);
|
|
49456
49677
|
return result ? result.entry : null;
|
|
49457
49678
|
}
|
|
49458
|
-
function
|
|
49679
|
+
function parkTaskTargetPin(meshId, taskId, opts) {
|
|
49459
49680
|
requireMeshHostQueueOwner(opts);
|
|
49460
49681
|
return withQueueLock(meshId, () => {
|
|
49461
49682
|
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
49462
49683
|
if (!entry) return null;
|
|
49463
49684
|
if (entry.status !== "pending") return null;
|
|
49464
49685
|
if (!entry.targetSessionId && !entry.targetNodeId) return null;
|
|
49465
|
-
|
|
49466
|
-
const
|
|
49467
|
-
|
|
49468
|
-
|
|
49469
|
-
entry.updatedAt =
|
|
49470
|
-
|
|
49686
|
+
if (taskIsParked(entry)) return null;
|
|
49687
|
+
const reason = opts?.reason || PARK_REASON_PIN_EXPIRED;
|
|
49688
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
49689
|
+
entry.parked = buildParkingRecord(entry, reason, now);
|
|
49690
|
+
entry.updatedAt = now;
|
|
49691
|
+
entry.requeueReason = reason;
|
|
49471
49692
|
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
49472
|
-
|
|
49693
|
+
logTaskParked(meshId, taskId, reason, entry.targetSessionId);
|
|
49473
49694
|
return entry;
|
|
49474
49695
|
});
|
|
49475
49696
|
}
|
|
49697
|
+
function failRetentionExpiredParkedTask(meshId, taskId, opts) {
|
|
49698
|
+
requireMeshHostQueueOwner(opts);
|
|
49699
|
+
const result = withQueueLock(meshId, () => {
|
|
49700
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
49701
|
+
if (!entry) return null;
|
|
49702
|
+
if (entry.status !== "pending" || !taskIsParked(entry)) return null;
|
|
49703
|
+
if (!parkedTaskRetentionExpired(entry, Date.now(), opts?.retentionMs)) return null;
|
|
49704
|
+
const hours = Math.round((opts?.retentionMs ?? PARKED_TASK_RETENTION_MS) / 36e5);
|
|
49705
|
+
entry.status = "failed";
|
|
49706
|
+
entry.cancelReason = `${PARK_RETENTION_EXPIRED_REASON}: parked for over ${hours}h (addressed to session ${entry.parked?.targetSessionId || "unknown"}) with no coordinator decision`;
|
|
49707
|
+
entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
49708
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
49709
|
+
const cascaded = propagateDependencyFailure(meshId, taskId);
|
|
49710
|
+
LOG2.warn("MeshQueue", `PIN-PARKING retention: task ${taskId} (mesh ${meshId}) stayed parked past ${hours}h with no coordinator decision; failed it (dependents unblocked). This is reported to the coordinator, never a silent drop.`);
|
|
49711
|
+
return { entry, cascaded, missionAffected: true };
|
|
49712
|
+
});
|
|
49713
|
+
if (result?.missionAffected) scheduleMissionCloseCandidateCheck(meshId, [result.entry, ...result.cascaded]);
|
|
49714
|
+
return result ? result.entry : null;
|
|
49715
|
+
}
|
|
49716
|
+
function getParkedTasks(meshId) {
|
|
49717
|
+
return getQueue(meshId, { status: ["pending"] }).filter(taskIsParked);
|
|
49718
|
+
}
|
|
49476
49719
|
function reclaimStrandedAssignedTask(meshId, taskId, opts) {
|
|
49477
49720
|
requireMeshHostQueueOwner(opts);
|
|
49478
49721
|
const result = withQueueLock(meshId, () => {
|
|
@@ -49700,6 +49943,7 @@ ${blocks.join("\n\n")}`;
|
|
|
49700
49943
|
init_mesh_graph_derived_failure();
|
|
49701
49944
|
init_dist();
|
|
49702
49945
|
init_mesh_task_mode_guardrail();
|
|
49946
|
+
init_mesh_task_parking();
|
|
49703
49947
|
init_mesh_task_mode_guardrail();
|
|
49704
49948
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
49705
49949
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
@@ -52571,6 +52815,7 @@ ${blocks.join("\n\n")}`;
|
|
|
52571
52815
|
init_config();
|
|
52572
52816
|
init_mesh_ledger();
|
|
52573
52817
|
init_mesh_work_queue();
|
|
52818
|
+
init_mesh_task_parking();
|
|
52574
52819
|
init_mesh_graph_schema();
|
|
52575
52820
|
init_mesh_graph_store();
|
|
52576
52821
|
init_slot_model_enforcement();
|
|
@@ -53539,7 +53784,8 @@ ${blocks.join("\n\n")}`;
|
|
|
53539
53784
|
};
|
|
53540
53785
|
const allowedTaskDifficulties = opts?.allowedTaskDifficulties;
|
|
53541
53786
|
const difficultyAllows = (candidate) => !allowedTaskDifficulties || candidate.difficulty === "freeform" || !candidate.difficulty || allowedTaskDifficulties.includes(candidate.difficulty);
|
|
53542
|
-
const
|
|
53787
|
+
const notParked = (candidate) => !taskIsParked(candidate);
|
|
53788
|
+
const entry = candidates.find((candidate) => nodeSatisfiesRequiredTags(candidate.requiredTags, capabilityTags) && dependenciesSatisfied(candidate) && notBeforeReady(candidate) && notParked(candidate) && convergenceAllows(candidate) && targetMatches(candidate) && difficultyAllows(candidate) && parallelCapsAllow(candidate) && nodeConflictAllows(candidate));
|
|
53543
53789
|
if (!entry) return null;
|
|
53544
53790
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
53545
53791
|
entry.status = "assigned";
|
|
@@ -54638,7 +54884,11 @@ ${blocks.join("\n\n")}`;
|
|
|
54638
54884
|
}
|
|
54639
54885
|
/** Remove all pending-event rows (drained included) for a mesh — mesh deletion / test cleanup. */
|
|
54640
54886
|
clearPendingEventsForMesh(meshId) {
|
|
54641
|
-
|
|
54887
|
+
const changes = this.db.prepare("DELETE FROM mesh_pending_events WHERE mesh_id = ?").run(meshId).changes;
|
|
54888
|
+
this.db.prepare(
|
|
54889
|
+
`DELETE FROM mesh_completion_fingerprints WHERE mesh_id = ? AND fingerprint LIKE 'pending::%'`
|
|
54890
|
+
).run(meshId);
|
|
54891
|
+
return changes;
|
|
54642
54892
|
}
|
|
54643
54893
|
pendingEventCount(meshId) {
|
|
54644
54894
|
const row = this.db.prepare(
|
|
@@ -55255,6 +55505,7 @@ ${blocks.join("\n\n")}`;
|
|
|
55255
55505
|
compactLedger: () => compactLedger,
|
|
55256
55506
|
enforceAllLedgerRotationCaps: () => enforceAllLedgerRotationCaps,
|
|
55257
55507
|
enforceLedgerRotationCap: () => enforceLedgerRotationCap,
|
|
55508
|
+
extractJsonObjectFromSummary: () => extractJsonObjectFromSummary,
|
|
55258
55509
|
getLedgerDir: () => getLedgerDir2,
|
|
55259
55510
|
getLedgerSummary: () => getLedgerSummary,
|
|
55260
55511
|
getSessionRecoveryContext: () => getSessionRecoveryContext,
|
|
@@ -58579,8 +58830,8 @@ ${rendered}`, "utf-8");
|
|
|
58579
58830
|
if (!(0, import_node_fs3.existsSync)(filePath)) return;
|
|
58580
58831
|
if (owned) {
|
|
58581
58832
|
try {
|
|
58582
|
-
const
|
|
58583
|
-
|
|
58833
|
+
const fs61 = require("fs");
|
|
58834
|
+
fs61.unlinkSync(filePath);
|
|
58584
58835
|
} catch {
|
|
58585
58836
|
}
|
|
58586
58837
|
return;
|
|
@@ -58593,8 +58844,8 @@ ${rendered}`, "utf-8");
|
|
|
58593
58844
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
58594
58845
|
if (!remaining.trim()) {
|
|
58595
58846
|
try {
|
|
58596
|
-
const
|
|
58597
|
-
|
|
58847
|
+
const fs61 = require("fs");
|
|
58848
|
+
fs61.unlinkSync(filePath);
|
|
58598
58849
|
} catch {
|
|
58599
58850
|
}
|
|
58600
58851
|
} else {
|
|
@@ -59520,6 +59771,7 @@ ${rendered}`, "utf-8");
|
|
|
59520
59771
|
void opts.registerNode;
|
|
59521
59772
|
return {
|
|
59522
59773
|
nowMs: () => Date.now(),
|
|
59774
|
+
resolveBaseRevision: (req) => defaultResolveBaseRevision(req),
|
|
59523
59775
|
createWorktree: (req) => defaultCreateWorktree(req),
|
|
59524
59776
|
findOwnedWorktree: (req) => defaultFindOwnedWorktree(req),
|
|
59525
59777
|
inspectWorktree: (req) => defaultInspectWorktree(req),
|
|
@@ -59565,6 +59817,40 @@ ${rendered}`, "utf-8");
|
|
|
59565
59817
|
env: gitChildEnv()
|
|
59566
59818
|
});
|
|
59567
59819
|
}
|
|
59820
|
+
async function defaultResolveBaseRevision(req) {
|
|
59821
|
+
let repoRoot;
|
|
59822
|
+
try {
|
|
59823
|
+
({ repoRoot } = resolveSourceRepo(req.meshId, req.sourceNodeId));
|
|
59824
|
+
} catch {
|
|
59825
|
+
return void 0;
|
|
59826
|
+
}
|
|
59827
|
+
try {
|
|
59828
|
+
const { stdout } = await execFileAsync4("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
59829
|
+
cwd: repoRoot,
|
|
59830
|
+
encoding: "utf8",
|
|
59831
|
+
timeout: GIT_TIMEOUT_MS3,
|
|
59832
|
+
maxBuffer: GIT_MAX_BUFFER2,
|
|
59833
|
+
windowsHide: true,
|
|
59834
|
+
env: gitChildEnv()
|
|
59835
|
+
});
|
|
59836
|
+
const branch = stdout.trim();
|
|
59837
|
+
if (branch && branch !== "HEAD") return branch;
|
|
59838
|
+
} catch {
|
|
59839
|
+
}
|
|
59840
|
+
try {
|
|
59841
|
+
const { stdout } = await execFileAsync4("git", ["rev-parse", "HEAD"], {
|
|
59842
|
+
cwd: repoRoot,
|
|
59843
|
+
encoding: "utf8",
|
|
59844
|
+
timeout: GIT_TIMEOUT_MS3,
|
|
59845
|
+
maxBuffer: GIT_MAX_BUFFER2,
|
|
59846
|
+
windowsHide: true,
|
|
59847
|
+
env: gitChildEnv()
|
|
59848
|
+
});
|
|
59849
|
+
return stdout.trim() || void 0;
|
|
59850
|
+
} catch {
|
|
59851
|
+
return void 0;
|
|
59852
|
+
}
|
|
59853
|
+
}
|
|
59568
59854
|
async function defaultCreateWorktree(req) {
|
|
59569
59855
|
const existing = await defaultFindOwnedWorktree({
|
|
59570
59856
|
meshId: req.meshId,
|
|
@@ -59910,8 +60196,26 @@ ${rendered}`, "utf-8");
|
|
|
59910
60196
|
}
|
|
59911
60197
|
return compensateClaimedIntent({ ...intent, ownerTag }, ports, generation);
|
|
59912
60198
|
}
|
|
59913
|
-
|
|
59914
|
-
|
|
60199
|
+
let baseRevision = intent.baseRevision;
|
|
60200
|
+
if (intent.sagaState === "declared" && !baseRevision) {
|
|
60201
|
+
const derived = await ports.resolveBaseRevision({
|
|
60202
|
+
meshId: intent.meshId,
|
|
60203
|
+
graphId,
|
|
60204
|
+
workspaceRef,
|
|
60205
|
+
sourceNodeId: intent.sourceNodeId
|
|
60206
|
+
}).catch(() => void 0);
|
|
60207
|
+
if (derived) {
|
|
60208
|
+
store.transaction(() => {
|
|
60209
|
+
store.graphStore().patchWorkspaceIntent(graphId, workspaceRef, {
|
|
60210
|
+
baseRevision: derived
|
|
60211
|
+
}, nowIso, { leaseGeneration: generation });
|
|
60212
|
+
});
|
|
60213
|
+
baseRevision = derived;
|
|
60214
|
+
LOG2.info("MeshGraphWorkspace", `derived base revision '${derived}' for ${graphId}/${workspaceRef} from source node ${intent.sourceNodeId ?? "base"}`);
|
|
60215
|
+
} else {
|
|
60216
|
+
LOG2.debug("MeshGraphWorkspace", `${graphId}/${workspaceRef} stays declared: no base_revision and none derivable from source node ${intent.sourceNodeId ?? "(none declared)"}`);
|
|
60217
|
+
return { graphId, workspaceRef, sagaState: "declared", action: "skipped_no_base" };
|
|
60218
|
+
}
|
|
59915
60219
|
}
|
|
59916
60220
|
store.transaction(() => {
|
|
59917
60221
|
store.graphStore().patchWorkspaceIntent(graphId, workspaceRef, {
|
|
@@ -59919,7 +60223,7 @@ ${rendered}`, "utf-8");
|
|
|
59919
60223
|
ownerTag
|
|
59920
60224
|
}, nowIso, { leaseGeneration: generation });
|
|
59921
60225
|
});
|
|
59922
|
-
return prepareClaimedIntent({ ...intent, sagaState: "preparing", ownerTag }, ports, generation, faults);
|
|
60226
|
+
return prepareClaimedIntent({ ...intent, baseRevision, sagaState: "preparing", ownerTag }, ports, generation, faults);
|
|
59923
60227
|
}
|
|
59924
60228
|
async function prepareClaimedIntent(intent, ports, generation, faults) {
|
|
59925
60229
|
const store = MeshRuntimeStore.getInstance();
|
|
@@ -62371,6 +62675,13 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
62371
62675
|
}
|
|
62372
62676
|
return false;
|
|
62373
62677
|
}
|
|
62678
|
+
function isReplayOfRecordedSynthSummary(recorded, incoming) {
|
|
62679
|
+
if (recorded === incoming) return true;
|
|
62680
|
+
if (!recorded || !incoming) return false;
|
|
62681
|
+
const [shorter, longer] = recorded.length <= incoming.length ? [recorded, incoming] : [incoming, recorded];
|
|
62682
|
+
if (!longer.startsWith(shorter)) return false;
|
|
62683
|
+
return longer.length <= shorter.length + 32;
|
|
62684
|
+
}
|
|
62374
62685
|
function hasIdenticalSynthesizedTerminal(args) {
|
|
62375
62686
|
const entries = readLedgerEntriesByKind(args.meshId, ["task_dispatched", ...TERMINAL_LEDGER_KINDS2]);
|
|
62376
62687
|
let afterDispatch = !args.dispatchEntryId && !args.dispatchTimestamp;
|
|
@@ -62390,7 +62701,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
62390
62701
|
if (entry.kind !== "task_completed" && entry.kind !== "task_failed") continue;
|
|
62391
62702
|
const diagnostic = readRecord2(entry.payload?.completionDiagnostic);
|
|
62392
62703
|
if (readNonEmptyString(diagnostic?.reason) !== "direct_task_transcript_reconciliation") continue;
|
|
62393
|
-
if (readNonEmptyString(entry.payload?.finalSummary)
|
|
62704
|
+
if (!isReplayOfRecordedSynthSummary(readNonEmptyString(entry.payload?.finalSummary), args.finalSummary)) continue;
|
|
62394
62705
|
const terminalTaskId = readNonEmptyString(entry.payload?.taskId);
|
|
62395
62706
|
if (terminalTaskId && terminalTaskId !== args.taskId) continue;
|
|
62396
62707
|
if (terminalTaskId && terminalTaskId === args.taskId) return true;
|
|
@@ -65073,36 +65384,6 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65073
65384
|
init_chat_history();
|
|
65074
65385
|
}
|
|
65075
65386
|
});
|
|
65076
|
-
function s(v) {
|
|
65077
|
-
return typeof v === "string" && v.trim() ? v.trim() : "";
|
|
65078
|
-
}
|
|
65079
|
-
function meshEventTraceKey(ctx) {
|
|
65080
|
-
const segs = [`task=${s(ctx.taskId) || "-"}`];
|
|
65081
|
-
const eventId = s(ctx.eventId);
|
|
65082
|
-
if (eventId) segs.push(`evt=${eventId}`);
|
|
65083
|
-
segs.push(`sess=${s(ctx.sessionId) || "-"}`);
|
|
65084
|
-
const nodeId = s(ctx.nodeId);
|
|
65085
|
-
if (nodeId) segs.push(`node=${nodeId}`);
|
|
65086
|
-
const meshId = s(ctx.meshId);
|
|
65087
|
-
if (meshId) segs.push(`mesh=${meshId}`);
|
|
65088
|
-
const event = s(ctx.event);
|
|
65089
|
-
if (event) segs.push(`event=${event}`);
|
|
65090
|
-
return segs.join(" ");
|
|
65091
|
-
}
|
|
65092
|
-
function traceMeshEventStage(stage, ctx, detail) {
|
|
65093
|
-
LOG2.info(CAT, `[stage:${stage}] ${meshEventTraceKey(ctx)}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
65094
|
-
}
|
|
65095
|
-
function traceMeshEventDrop(reason, ctx, detail) {
|
|
65096
|
-
LOG2.warn(CAT, `[drop:${reason}] ${meshEventTraceKey(ctx)}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
65097
|
-
}
|
|
65098
|
-
var CAT;
|
|
65099
|
-
var init_mesh_event_trace = __esm2({
|
|
65100
|
-
"src/mesh/mesh-event-trace.ts"() {
|
|
65101
|
-
"use strict";
|
|
65102
|
-
init_logger();
|
|
65103
|
-
CAT = "EvtTrace";
|
|
65104
|
-
}
|
|
65105
|
-
});
|
|
65106
65387
|
function isAnthropicProvider(providerType) {
|
|
65107
65388
|
const p = typeof providerType === "string" ? providerType.trim().toLowerCase() : "";
|
|
65108
65389
|
return p.length > 0 && ANTHROPIC_PROVIDER_TYPES.has(p);
|
|
@@ -65577,6 +65858,43 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65577
65858
|
const anchorMs = Date.parse(task.requeuedAt || task.createdAt || "");
|
|
65578
65859
|
return Number.isFinite(anchorMs) ? nowMs - anchorMs : null;
|
|
65579
65860
|
}
|
|
65861
|
+
function resolveTargetPinTtlVerdict(components, task, nowMs = Date.now()) {
|
|
65862
|
+
const wallAgeMs = targetPinAgeMs(task, nowMs);
|
|
65863
|
+
if (wallAgeMs === null) return { expired: false, ageMs: null, suspended: false };
|
|
65864
|
+
const targetSessionId = readNonEmptyString(task.targetSessionId);
|
|
65865
|
+
const key2 = `${task.meshId}::${task.id}`;
|
|
65866
|
+
const prior = targetPinGeneratingCreditMs.get(key2);
|
|
65867
|
+
const generating = !!targetSessionId && resolveSessionBusyVerdict(components, targetSessionId) === "GENERATING";
|
|
65868
|
+
let creditMs = prior?.creditMs ?? 0;
|
|
65869
|
+
if (generating && prior) {
|
|
65870
|
+
creditMs += Math.max(0, nowMs - prior.lastSeenMs);
|
|
65871
|
+
}
|
|
65872
|
+
targetPinGeneratingCreditMs.set(key2, { creditMs, lastSeenMs: nowMs });
|
|
65873
|
+
const unproductiveAgeMs = Math.max(0, wallAgeMs - creditMs);
|
|
65874
|
+
return {
|
|
65875
|
+
// A tick on which the addressee is OBSERVABLY GENERATING never expires the pin,
|
|
65876
|
+
// independently of the accumulated credit.
|
|
65877
|
+
//
|
|
65878
|
+
// The credit ledger alone is not sufficient here, and the difference is the
|
|
65879
|
+
// whole live defect. Credit only accrues from the SECOND observation onward
|
|
65880
|
+
// (the first has no prior interval to bank), and it is in-memory — so a pin
|
|
65881
|
+
// that crossed the wall-clock TTL while the daemon was not watching, or before
|
|
65882
|
+
// a restart, would arrive at its very first post-restart observation with zero
|
|
65883
|
+
// credit and expire on the spot, while the session it is addressed to is
|
|
65884
|
+
// visibly mid-turn. That is exactly the observed failure (`unclaimed 902s`
|
|
65885
|
+
// logged on an `agent:ready`, i.e. at the end of real work) reproduced by a
|
|
65886
|
+
// different route.
|
|
65887
|
+
//
|
|
65888
|
+
// Gating on the live verdict makes "is the addressee working right now?" the
|
|
65889
|
+
// decisive question and leaves the credit ledger as what it should be: an
|
|
65890
|
+
// optimisation that stops intermittent work from silently burning the budget.
|
|
65891
|
+
// It cannot make a pin immortal — the verdict is re-evaluated every tick from
|
|
65892
|
+
// live state and only a LOCAL, observably-generating session can produce it.
|
|
65893
|
+
expired: !generating && unproductiveAgeMs >= TARGET_SESSION_PIN_TTL_MS,
|
|
65894
|
+
ageMs: unproductiveAgeMs,
|
|
65895
|
+
suspended: generating
|
|
65896
|
+
};
|
|
65897
|
+
}
|
|
65580
65898
|
function resolveDeadTargetVerdict(components, meshId, mesh, task) {
|
|
65581
65899
|
const NOT_DEAD = { dead: false, nodeDead: false, reason: "" };
|
|
65582
65900
|
const targetSessionId = readNonEmptyString(task.targetSessionId);
|
|
@@ -65652,6 +65970,21 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65652
65970
|
summary: "the node's workspace is dirty, so auto-launch is blocked to avoid clobbering uncommitted changes",
|
|
65653
65971
|
nextAction: "Clean or commit the node's working tree (or fast-forward it); the task will then auto-assign."
|
|
65654
65972
|
};
|
|
65973
|
+
if (reason === PARKED_SKIP_REASON) {
|
|
65974
|
+
const base = "it was pinned to a specific session, that pin went stale, and the task is now PARKED \u2014 deliberately held for you rather than re-homed onto another session, because a delta written for one session's context becomes a context-free instruction anywhere else";
|
|
65975
|
+
if (evidence === "consumed") return {
|
|
65976
|
+
summary: `${base}. The delivery record shows the addressed session DID receive and start acting on this message, so the parked row is a bookkeeping remnant, not a lost delta`,
|
|
65977
|
+
nextAction: "Do NOT re-send it. Confirm with mesh_read_chat / mesh_read_terminal that the work is under way, then clear the park with mesh_queue_cancel (or requeue it only if you genuinely want it run again)."
|
|
65978
|
+
};
|
|
65979
|
+
if (evidence === "delivered") return {
|
|
65980
|
+
summary: `${base}. The message WAS handed to that session's transport but no turn start was echoed, so whether it acted on it is unconfirmed`,
|
|
65981
|
+
nextAction: "Check the session (mesh_read_chat / mesh_read_terminal) before acting. If it is already handling it, cancel the parked row; if not, mesh_queue_requeue with target_session_id=<live session> \u2014 and pass message=<rewritten instruction> if the situation moved on while it waited."
|
|
65982
|
+
};
|
|
65983
|
+
return {
|
|
65984
|
+
summary: `${base}. No delivery to that session was ever recorded, so the message did not reach it and the worker is still acting on its previous instructions`,
|
|
65985
|
+
nextAction: "Re-target it with mesh_queue_requeue(target_session_id=<live session>), or drop the pin with clear_target_session to let any compatible session take it. Re-read the work produced meanwhile and pass message=<rewritten instruction> if the delta is now partly stale; mesh_queue_cancel if it is moot."
|
|
65986
|
+
};
|
|
65987
|
+
}
|
|
65655
65988
|
if (reason === "target_session_pin_expired") {
|
|
65656
65989
|
if (evidence === "consumed") return {
|
|
65657
65990
|
summary: "it was pinned to a specific session and the pin TTL expired before the queue row was claimed \u2014 but the delivery record shows this session DID receive and start acting on the message (a turn was started for it), so the queue row lagging is a bookkeeping gap, not a lost delta",
|
|
@@ -65698,11 +66031,11 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65698
66031
|
const targetCoordinatorDaemonId = readNonEmptyString(loadConfig2().machineId);
|
|
65699
66032
|
const targetCoordinatorSessionId = readNonEmptyString(task?.sourceCoordinatorSessionId);
|
|
65700
66033
|
const nodeLabel = readNonEmptyString(nodeId) || readNonEmptyString(task?.targetNodeId);
|
|
65701
|
-
const evidence = reason === "target_session_pin_expired" ? resolveTaskDeliveryEvidence(meshId, taskId) : void 0;
|
|
66034
|
+
const evidence = reason === "target_session_pin_expired" || reason === PARKED_SKIP_REASON ? resolveTaskDeliveryEvidence(meshId, taskId) : void 0;
|
|
65702
66035
|
const { summary, nextAction } = actionableSkipGuidance(reason, evidence);
|
|
65703
66036
|
const providerAvailabilityResult = reason.startsWith("provider") || reason === "missing_provider_priority";
|
|
65704
66037
|
const reachabilityResult = reason.startsWith("remote_auto_launch");
|
|
65705
|
-
const closing = reason === "target_session_pin_expired" ? "The stale pin has already been cleared, so the task is now claimable by any compatible session \u2014 the action above is about the session it was originally addressed to." : providerAvailabilityResult ? "This result needs action if it persists: a later provider-status refresh or an already-starting usable session can clear it, but a genuinely missing, disabled, or misconfigured provider will keep the task pending until you fix that configuration." : reachabilityResult ? "This result needs action if it persists: the node reconnecting (or re-registering its daemon id) clears it on its own, but a node that stays unreachable will keep the task pending until you bring it back or re-target the task." : "This is an actionable blocker \u2014 it will NOT clear on its own; the task stays pending until you resolve it.";
|
|
66038
|
+
const closing = reason === PARKED_SKIP_REASON ? `This task is claimable by NOBODY until you act on it \u2014 no session will pick it up and no timer will re-home it. It is held for ${Math.round(PARKED_TASK_RETENTION_MS / 36e5)}h and then failed (with another notification), so it is never silently discarded. Parked rows are listed under parkedTasks in mesh_view_queue, and any mesh_queue_requeue unparks it \u2014 including one that only rewrites its message.` : reason === "target_session_pin_expired" ? "The stale pin has already been cleared, so the task is now claimable by any compatible session \u2014 the action above is about the session it was originally addressed to." : providerAvailabilityResult ? "This result needs action if it persists: a later provider-status refresh or an already-starting usable session can clear it, but a genuinely missing, disabled, or misconfigured provider will keep the task pending until you fix that configuration." : reachabilityResult ? "This result needs action if it persists: the node reconnecting (or re-registering its daemon id) clears it on its own, but a node that stays unreachable will keep the task pending until you bring it back or re-target the task." : "This is an actionable blocker \u2014 it will NOT clear on its own; the task stays pending until you resolve it.";
|
|
65706
66039
|
const coordinatorMessage = `[System] A queued mesh task${nodeLabel ? ` for node ${nodeLabel}` : ""} is not being dispatched because ${summary}. ${nextAction} ${closing}`;
|
|
65707
66040
|
try {
|
|
65708
66041
|
queuePendingMeshCoordinatorEvent({
|
|
@@ -65731,6 +66064,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65731
66064
|
var lastActionableSkipNotified;
|
|
65732
66065
|
var DEAD_TARGET_GRACE_MS;
|
|
65733
66066
|
var TARGET_SESSION_PIN_TTL_MS;
|
|
66067
|
+
var targetPinGeneratingCreditMs;
|
|
65734
66068
|
var init_mesh_skip_notify = __esm2({
|
|
65735
66069
|
"src/mesh/mesh-skip-notify.ts"() {
|
|
65736
66070
|
"use strict";
|
|
@@ -65746,6 +66080,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65746
66080
|
init_slot_model_enforcement();
|
|
65747
66081
|
init_mesh_queue_assignment();
|
|
65748
66082
|
init_mesh_queue_observability();
|
|
66083
|
+
init_mesh_task_parking();
|
|
65749
66084
|
ACTIONABLE_SKIP_REASON_PREFIXES = [
|
|
65750
66085
|
"target_node_id_unmatched",
|
|
65751
66086
|
"no_node_satisfies_required_tags",
|
|
@@ -65768,6 +66103,14 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65768
66103
|
// premise the delta was meant to correct. The coordinator must know its
|
|
65769
66104
|
// addressed message lost its address.
|
|
65770
66105
|
"target_session_pin_expired",
|
|
66106
|
+
// PIN-PARKING: the reason above's successor. The pin no longer CLEARS on expiry
|
|
66107
|
+
// (that silently re-homed a context-bound delta onto an arbitrary session); the
|
|
66108
|
+
// task PARKS instead — held, still addressed, claimable by nobody. That state is
|
|
66109
|
+
// by construction actionable and terminal-until-touched: nothing in the daemon
|
|
66110
|
+
// will ever move a parked task, so if the coordinator is not told, the work is
|
|
66111
|
+
// lost exactly as surely as if it had been dropped. Both reasons stay listed —
|
|
66112
|
+
// the old one so a version-skewed daemon's rows still page.
|
|
66113
|
+
PARKED_SKIP_REASON,
|
|
65771
66114
|
// SLOT MODEL GUARD (absent): no slot on the node declares the task's model.
|
|
65772
66115
|
// Permanent — no amount of waiting produces a slot, so the coordinator must
|
|
65773
66116
|
// re-drive (adjust difficulty, target another node, ask the owner). Its
|
|
@@ -65786,6 +66129,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
65786
66129
|
lastActionableSkipNotified = /* @__PURE__ */ new Map();
|
|
65787
66130
|
DEAD_TARGET_GRACE_MS = 6e4;
|
|
65788
66131
|
TARGET_SESSION_PIN_TTL_MS = 15 * 6e4;
|
|
66132
|
+
targetPinGeneratingCreditMs = /* @__PURE__ */ new Map();
|
|
65789
66133
|
}
|
|
65790
66134
|
});
|
|
65791
66135
|
function nodesForMesh(meshId) {
|
|
@@ -66194,6 +66538,173 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66194
66538
|
INTRA_NODE_LOSERS_MAX = 2;
|
|
66195
66539
|
}
|
|
66196
66540
|
});
|
|
66541
|
+
function localCoordinatorDaemonId() {
|
|
66542
|
+
return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
|
|
66543
|
+
}
|
|
66544
|
+
function isIdleSessionState2(state) {
|
|
66545
|
+
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
66546
|
+
if (TERMINAL_SESSION_STATUSES.includes(status)) return false;
|
|
66547
|
+
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
66548
|
+
}
|
|
66549
|
+
function sweepAutoLaunchOrphanSessions(components, meshId) {
|
|
66550
|
+
let sessions;
|
|
66551
|
+
try {
|
|
66552
|
+
sessions = components.instanceManager?.getByCategory?.("cli") || [];
|
|
66553
|
+
} catch {
|
|
66554
|
+
return;
|
|
66555
|
+
}
|
|
66556
|
+
if (!sessions.length) return;
|
|
66557
|
+
let queue;
|
|
66558
|
+
try {
|
|
66559
|
+
queue = getQueue(meshId);
|
|
66560
|
+
} catch {
|
|
66561
|
+
return;
|
|
66562
|
+
}
|
|
66563
|
+
const byId = new Map(queue.map((t) => [t.id, t]));
|
|
66564
|
+
for (const inst of sessions) {
|
|
66565
|
+
let state;
|
|
66566
|
+
try {
|
|
66567
|
+
state = inst.getState();
|
|
66568
|
+
} catch {
|
|
66569
|
+
continue;
|
|
66570
|
+
}
|
|
66571
|
+
const settings = state?.settings || {};
|
|
66572
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) continue;
|
|
66573
|
+
const originTaskId = readNonEmptyString(settings.autoLaunchedForQueueTaskId);
|
|
66574
|
+
if (!originTaskId) continue;
|
|
66575
|
+
const sessionId = readNonEmptyString(state?.instanceId);
|
|
66576
|
+
if (!sessionId) continue;
|
|
66577
|
+
if (!isIdleSessionState2(state)) continue;
|
|
66578
|
+
if (sessionHasActiveAssignment(meshId, sessionId)) continue;
|
|
66579
|
+
const originTask = byId.get(originTaskId);
|
|
66580
|
+
const assignedElsewhere = !!originTask && originTask.status === "assigned" && !!readNonEmptyString(originTask.assignedSessionId) && !sessionIdsEquivalent(readNonEmptyString(originTask.assignedSessionId), sessionId);
|
|
66581
|
+
const originGone = !originTask || originTask.status !== "pending" && originTask.status !== "assigned";
|
|
66582
|
+
const dedupKey = `${meshId}::${sessionId}`;
|
|
66583
|
+
if (!assignedElsewhere && !originGone) {
|
|
66584
|
+
autoLaunchOrphanFirstSeenAtMs.delete(dedupKey);
|
|
66585
|
+
continue;
|
|
66586
|
+
}
|
|
66587
|
+
const nowMs = Date.now();
|
|
66588
|
+
const firstSeenAtMs = autoLaunchOrphanFirstSeenAtMs.get(dedupKey);
|
|
66589
|
+
if (firstSeenAtMs === void 0) {
|
|
66590
|
+
autoLaunchOrphanFirstSeenAtMs.set(dedupKey, nowMs);
|
|
66591
|
+
if (autoLaunchOrphanFirstSeenAtMs.size > AUTO_LAUNCH_LEDGER_DEDUP_MAX) {
|
|
66592
|
+
const oldest = autoLaunchOrphanFirstSeenAtMs.keys().next().value;
|
|
66593
|
+
if (oldest !== void 0) autoLaunchOrphanFirstSeenAtMs.delete(oldest);
|
|
66594
|
+
}
|
|
66595
|
+
continue;
|
|
66596
|
+
}
|
|
66597
|
+
if (nowMs - firstSeenAtMs < AUTO_LAUNCH_ORPHAN_GRACE_MS) continue;
|
|
66598
|
+
if (autoLaunchOrphanNotified.has(dedupKey)) continue;
|
|
66599
|
+
autoLaunchOrphanNotified.add(dedupKey);
|
|
66600
|
+
if (autoLaunchOrphanNotified.size > AUTO_LAUNCH_LEDGER_DEDUP_MAX) {
|
|
66601
|
+
const oldest = autoLaunchOrphanNotified.values().next().value;
|
|
66602
|
+
if (oldest !== void 0) autoLaunchOrphanNotified.delete(oldest);
|
|
66603
|
+
}
|
|
66604
|
+
const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
66605
|
+
const detail = assignedElsewhere ? `task ${originTaskId} is assigned to a different session (${readNonEmptyString(originTask.assignedSessionId)})` : `task ${originTaskId} is no longer active (${originTask ? originTask.status : "absent from the queue"})`;
|
|
66606
|
+
recordAutoLaunchEvent(meshId, {
|
|
66607
|
+
phase: "skipped",
|
|
66608
|
+
taskId: originTaskId,
|
|
66609
|
+
reason: "auto_launch_orphan_session_detected",
|
|
66610
|
+
nodeId,
|
|
66611
|
+
sessionId
|
|
66612
|
+
});
|
|
66613
|
+
LOG2.warn("MeshQueue", `AUTOLAUNCH-ORPHAN-SWEEP: session ${sessionId}${nodeId ? ` on node ${nodeId}` : ""} (mesh ${meshId}) was auto-launched for task ${originTaskId} but ${detail}; it is idle with no work and will not self-recover.`);
|
|
66614
|
+
try {
|
|
66615
|
+
queuePendingMeshCoordinatorEvent({
|
|
66616
|
+
event: "mesh:dispatch_blocked",
|
|
66617
|
+
meshId,
|
|
66618
|
+
nodeLabel: nodeId || meshId,
|
|
66619
|
+
...nodeId ? { nodeId } : {},
|
|
66620
|
+
metadataEvent: {
|
|
66621
|
+
source: "mesh_auto_launch_orphan_session",
|
|
66622
|
+
taskId: originTaskId,
|
|
66623
|
+
sessionId,
|
|
66624
|
+
reason: "auto_launch_orphan_session_detected"
|
|
66625
|
+
},
|
|
66626
|
+
coordinatorMessage: `[System] Mesh session ${sessionId}${nodeId ? ` on node ${nodeId}` : ""} was auto-launched for task ${originTaskId}, but ${detail}. The session is idle with no work assigned and nothing reclaims it on its own. Reuse it for other queued work or stop it.`,
|
|
66627
|
+
queuedAt: Date.now(),
|
|
66628
|
+
...readNonEmptyString(originTask?.sourceCoordinatorSessionId) ? { targetCoordinatorSessionId: readNonEmptyString(originTask.sourceCoordinatorSessionId) } : {},
|
|
66629
|
+
...localCoordinatorDaemonId() ? { targetCoordinatorDaemonId: localCoordinatorDaemonId() } : {}
|
|
66630
|
+
});
|
|
66631
|
+
} catch (e) {
|
|
66632
|
+
LOG2.warn("MeshQueue", `AUTOLAUNCH-ORPHAN-SWEEP: failed to queue the coordinator notification for session ${sessionId}: ${e?.message || e}`);
|
|
66633
|
+
}
|
|
66634
|
+
}
|
|
66635
|
+
}
|
|
66636
|
+
function autoLaunchWriteWouldClobberWinner(meshId, taskId, args, awaitClaimWindowMs2) {
|
|
66637
|
+
if (args.status === "completed" && readNonEmptyString(args.sessionId)) return false;
|
|
66638
|
+
let existing;
|
|
66639
|
+
try {
|
|
66640
|
+
existing = getQueue(meshId).find((t) => t.id === taskId)?.autoLaunch;
|
|
66641
|
+
} catch {
|
|
66642
|
+
return false;
|
|
66643
|
+
}
|
|
66644
|
+
const heldSessionId = existing ? readNonEmptyString(existing.sessionId) : "";
|
|
66645
|
+
if (!existing || existing.status !== "completed" || !heldSessionId) return false;
|
|
66646
|
+
const heldAtMs = Date.parse(existing.updatedAt);
|
|
66647
|
+
if (!Number.isFinite(heldAtMs) || Date.now() - heldAtMs >= awaitClaimWindowMs2) return false;
|
|
66648
|
+
if (sessionIdsEquivalent(readNonEmptyString(args.sessionId), heldSessionId)) return false;
|
|
66649
|
+
LOG2.info("MeshQueue", `AUTOLAUNCH-WINNER-CLOBBER: suppressed a '${args.status}' autoLaunch write for task ${taskId} (mesh ${meshId}) that would have overwritten the in-window launch record for session ${heldSessionId}; the field keeps pointing at the actually-launched session.`);
|
|
66650
|
+
return true;
|
|
66651
|
+
}
|
|
66652
|
+
function awaitClaimWindowMs(cycles) {
|
|
66653
|
+
return AUTO_LAUNCH_AWAIT_CLAIM_MS * Math.pow(2, Math.min(cycles, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES));
|
|
66654
|
+
}
|
|
66655
|
+
function remoteSessionAppearsLive(meshId, sessionId) {
|
|
66656
|
+
if (!sessionId) return false;
|
|
66657
|
+
try {
|
|
66658
|
+
return MeshRuntimeStore.getInstance().getRemoteIdleSessions(meshId).some((s2) => sessionIdsEquivalent(s2.sessionId, sessionId));
|
|
66659
|
+
} catch {
|
|
66660
|
+
return false;
|
|
66661
|
+
}
|
|
66662
|
+
}
|
|
66663
|
+
function inWindowAutoLaunchSessionIdsForNode(meshId, nodeId) {
|
|
66664
|
+
const nowMs = Date.now();
|
|
66665
|
+
const out = [];
|
|
66666
|
+
for (const task of getQueue(meshId, { status: ["pending"] })) {
|
|
66667
|
+
const al = task.autoLaunch;
|
|
66668
|
+
const sid = al ? readNonEmptyString(al.sessionId) : "";
|
|
66669
|
+
if (!al || al.status !== "started" && al.status !== "completed" || !sid) continue;
|
|
66670
|
+
if (!daemonIdsEquivalent(al.nodeId, nodeId)) continue;
|
|
66671
|
+
const launchedAtMs = Date.parse(al.updatedAt);
|
|
66672
|
+
const inBaseWindow = Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
66673
|
+
const inBackoff = autoLaunchAwaitClaimBackoff.has(`${meshId}::${task.id}`);
|
|
66674
|
+
if (inBaseWindow || inBackoff) out.push(sid);
|
|
66675
|
+
}
|
|
66676
|
+
return out;
|
|
66677
|
+
}
|
|
66678
|
+
var AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
66679
|
+
var AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES;
|
|
66680
|
+
var AUTO_LAUNCH_REMOTE_IDLE_TTL_MS;
|
|
66681
|
+
var TERMINAL_SESSION_STATUSES;
|
|
66682
|
+
var autoLaunchOrphanNotified;
|
|
66683
|
+
var autoLaunchOrphanFirstSeenAtMs;
|
|
66684
|
+
var AUTO_LAUNCH_ORPHAN_GRACE_MS;
|
|
66685
|
+
var autoLaunchAwaitClaimBackoff;
|
|
66686
|
+
var init_mesh_autolaunch_integrity = __esm2({
|
|
66687
|
+
"src/mesh/mesh-autolaunch-integrity.ts"() {
|
|
66688
|
+
"use strict";
|
|
66689
|
+
init_config();
|
|
66690
|
+
init_logger();
|
|
66691
|
+
init_dist();
|
|
66692
|
+
init_mesh_work_queue();
|
|
66693
|
+
init_mesh_events_utils();
|
|
66694
|
+
init_mesh_events_pending();
|
|
66695
|
+
init_mesh_queue_observability();
|
|
66696
|
+
init_mesh_scheduling_fitness();
|
|
66697
|
+
init_mesh_runtime_store();
|
|
66698
|
+
AUTO_LAUNCH_AWAIT_CLAIM_MS = 9e4;
|
|
66699
|
+
AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES = 2;
|
|
66700
|
+
AUTO_LAUNCH_REMOTE_IDLE_TTL_MS = 5 * 60 * 1e3;
|
|
66701
|
+
TERMINAL_SESSION_STATUSES = ["stopped", "failed", "terminated", "exited", "closed"];
|
|
66702
|
+
autoLaunchOrphanNotified = /* @__PURE__ */ new Set();
|
|
66703
|
+
autoLaunchOrphanFirstSeenAtMs = /* @__PURE__ */ new Map();
|
|
66704
|
+
AUTO_LAUNCH_ORPHAN_GRACE_MS = 3e4;
|
|
66705
|
+
autoLaunchAwaitClaimBackoff = /* @__PURE__ */ new Map();
|
|
66706
|
+
}
|
|
66707
|
+
});
|
|
66197
66708
|
function classifiedDifficultiesForSlot(slot) {
|
|
66198
66709
|
const highest = slot.difficulty?.reduce((rank, value) => {
|
|
66199
66710
|
const candidate = CLASSIFIED_DIFFICULTIES.indexOf(value);
|
|
@@ -66298,7 +66809,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66298
66809
|
CLASSIFIED_DIFFICULTIES = ["easy", "medium", "difficult"];
|
|
66299
66810
|
}
|
|
66300
66811
|
});
|
|
66301
|
-
function
|
|
66812
|
+
function localCoordinatorDaemonId2() {
|
|
66302
66813
|
return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
|
|
66303
66814
|
}
|
|
66304
66815
|
function loadRepoConfigForNode(node) {
|
|
@@ -66407,7 +66918,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66407
66918
|
const routingDecision = {
|
|
66408
66919
|
source: routing?.source ?? "queue",
|
|
66409
66920
|
selectedNodeId: ctx.nodeId,
|
|
66410
|
-
...
|
|
66921
|
+
...localCoordinatorDaemonId2() ? { daemonId: localCoordinatorDaemonId2() } : {},
|
|
66411
66922
|
transport: ctx.transport,
|
|
66412
66923
|
// D: resolved execution profile — prefer the caller's resolved values, fall back
|
|
66413
66924
|
// to what the claimed task row carries (queue/idle drains carry it on the task).
|
|
@@ -66727,7 +67238,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66727
67238
|
nodeId,
|
|
66728
67239
|
sessionId,
|
|
66729
67240
|
providerType,
|
|
66730
|
-
coordinatorDaemonId:
|
|
67241
|
+
coordinatorDaemonId: localCoordinatorDaemonId2(),
|
|
66731
67242
|
coordinatorSessionId: readNonEmptyString(task.sourceCoordinatorSessionId) || void 0
|
|
66732
67243
|
});
|
|
66733
67244
|
dispatchAttemptId = attempt.attemptId;
|
|
@@ -66771,7 +67282,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66771
67282
|
if (remoteDaemonId && components.dispatchMeshCommand) {
|
|
66772
67283
|
const isLocalNode = isLocalAutoLaunchNode(node) || components.cliManager.adapters.has(sessionId);
|
|
66773
67284
|
if (!isLocalNode) {
|
|
66774
|
-
const localDaemonIdForDispatch =
|
|
67285
|
+
const localDaemonIdForDispatch = localCoordinatorDaemonId2();
|
|
66775
67286
|
const sourceCoordinatorSessionId = readNonEmptyString(task.sourceCoordinatorSessionId) || void 0;
|
|
66776
67287
|
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
66777
67288
|
deliverTaskToSession(
|
|
@@ -66821,7 +67332,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66821
67332
|
try {
|
|
66822
67333
|
const inst = components.instanceManager.getInstance(sessionId);
|
|
66823
67334
|
if (inst && typeof inst.updateSettings === "function") {
|
|
66824
|
-
const localDaemonId =
|
|
67335
|
+
const localDaemonId = localCoordinatorDaemonId2();
|
|
66825
67336
|
const localSourceCoordinatorSessionId = readNonEmptyString(task.sourceCoordinatorSessionId);
|
|
66826
67337
|
inst.updateSettings({
|
|
66827
67338
|
meshNodeFor: meshId,
|
|
@@ -66865,7 +67376,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66865
67376
|
...typeof task.dispatchNonce === "number" ? { dispatchNonce: task.dispatchNonce } : {},
|
|
66866
67377
|
// TURN-LEDGER (Stage 5): the opaque attempt identity (see remote branch above).
|
|
66867
67378
|
...dispatchAttemptId ? { attemptId: dispatchAttemptId } : {},
|
|
66868
|
-
...
|
|
67379
|
+
...localCoordinatorDaemonId2() ? { coordinatorDaemonId: localCoordinatorDaemonId2() } : {},
|
|
66869
67380
|
...readNonEmptyString(task.sourceCoordinatorSessionId) ? { coordinatorSessionId: readNonEmptyString(task.sourceCoordinatorSessionId) } : {},
|
|
66870
67381
|
...silentIdlePushOnDispatch ? { silentIdlePush: true } : {}
|
|
66871
67382
|
}
|
|
@@ -66878,38 +67389,12 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66878
67389
|
task,
|
|
66879
67390
|
transport: "local",
|
|
66880
67391
|
...readNonEmptyString(task.sourceCoordinatorSessionId) ? { sourceCoordinatorSessionId: readNonEmptyString(task.sourceCoordinatorSessionId) } : {},
|
|
66881
|
-
...
|
|
67392
|
+
...localCoordinatorDaemonId2() ? { sourceCoordinatorDaemonId: localCoordinatorDaemonId2() } : {},
|
|
66882
67393
|
...routingDecision ? { routingDecision } : {}
|
|
66883
67394
|
}
|
|
66884
67395
|
);
|
|
66885
67396
|
return true;
|
|
66886
67397
|
}
|
|
66887
|
-
function awaitClaimWindowMs(cycles) {
|
|
66888
|
-
return AUTO_LAUNCH_AWAIT_CLAIM_MS * Math.pow(2, Math.min(cycles, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES));
|
|
66889
|
-
}
|
|
66890
|
-
function remoteSessionAppearsLive(meshId, sessionId) {
|
|
66891
|
-
if (!sessionId) return false;
|
|
66892
|
-
try {
|
|
66893
|
-
return MeshRuntimeStore.getInstance().getRemoteIdleSessions(meshId).some((s2) => sessionIdsEquivalent(s2.sessionId, sessionId));
|
|
66894
|
-
} catch {
|
|
66895
|
-
return false;
|
|
66896
|
-
}
|
|
66897
|
-
}
|
|
66898
|
-
function inWindowAutoLaunchSessionIdsForNode(meshId, nodeId) {
|
|
66899
|
-
const nowMs = Date.now();
|
|
66900
|
-
const out = [];
|
|
66901
|
-
for (const task of getQueue(meshId, { status: ["pending"] })) {
|
|
66902
|
-
const al = task.autoLaunch;
|
|
66903
|
-
const sid = al ? readNonEmptyString(al.sessionId) : "";
|
|
66904
|
-
if (!al || al.status !== "started" && al.status !== "completed" || !sid) continue;
|
|
66905
|
-
if (!daemonIdsEquivalent(al.nodeId, nodeId)) continue;
|
|
66906
|
-
const launchedAtMs = Date.parse(al.updatedAt);
|
|
66907
|
-
const inBaseWindow = Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
66908
|
-
const inBackoff = autoLaunchAwaitClaimBackoff.has(`${meshId}::${task.id}`);
|
|
66909
|
-
if (inBaseWindow || inBackoff) out.push(sid);
|
|
66910
|
-
}
|
|
66911
|
-
return out;
|
|
66912
|
-
}
|
|
66913
67398
|
function sweepExpiredCooldowns() {
|
|
66914
67399
|
const now = Date.now();
|
|
66915
67400
|
for (const [key2, until] of autoLaunchCooldownUntil) {
|
|
@@ -66929,7 +67414,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66929
67414
|
function isTerminalSessionStatus(status) {
|
|
66930
67415
|
return ["stopped", "failed", "terminated", "exited", "closed"].includes(status);
|
|
66931
67416
|
}
|
|
66932
|
-
function
|
|
67417
|
+
function isIdleSessionState3(state) {
|
|
66933
67418
|
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
66934
67419
|
if (isTerminalSessionStatus(status)) return false;
|
|
66935
67420
|
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
@@ -66949,7 +67434,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66949
67434
|
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
66950
67435
|
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
66951
67436
|
const sessionId = readNonEmptyString(state.instanceId);
|
|
66952
|
-
if (currentSessionId && sessionIdsEquivalent(sessionId, currentSessionId) &&
|
|
67437
|
+
if (currentSessionId && sessionIdsEquivalent(sessionId, currentSessionId) && isIdleSessionState3(state)) return false;
|
|
66953
67438
|
return sessionStateLooksActive(state);
|
|
66954
67439
|
});
|
|
66955
67440
|
}
|
|
@@ -66980,7 +67465,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
66980
67465
|
const daemonId = readMeshNodeDaemonId(node ?? {});
|
|
66981
67466
|
if (!daemonId) return { mode: "skip", reason: "remote_auto_launch_unsupported" };
|
|
66982
67467
|
if (!components.dispatchMeshCommand) return { mode: "skip", reason: "remote_auto_launch_unsupported" };
|
|
66983
|
-
const coordinatorDaemonId =
|
|
67468
|
+
const coordinatorDaemonId = localCoordinatorDaemonId2();
|
|
66984
67469
|
if (!coordinatorDaemonId) return { mode: "skip", reason: "remote_auto_launch_no_coordinator_daemon_id" };
|
|
66985
67470
|
return { mode: "remote", daemonId, coordinatorDaemonId };
|
|
66986
67471
|
}
|
|
@@ -67054,8 +67539,8 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67054
67539
|
const reason = args.reason || args.error;
|
|
67055
67540
|
const difficultyFloorSkip = args.status === "skipped" && isDifficultyFloorWaitReason(reason);
|
|
67056
67541
|
if (difficultyFloorSkip) {
|
|
67057
|
-
handleDifficultyFloorSkip({ meshId, taskId, reason, nodeId: args.nodeId, coordinatorDaemonId:
|
|
67058
|
-
} else {
|
|
67542
|
+
handleDifficultyFloorSkip({ meshId, taskId, reason, nodeId: args.nodeId, coordinatorDaemonId: localCoordinatorDaemonId2() });
|
|
67543
|
+
} else if (!autoLaunchWriteWouldClobberWinner(meshId, taskId, args, AUTO_LAUNCH_AWAIT_CLAIM_MS)) {
|
|
67059
67544
|
recordTaskAutoLaunch(meshId, taskId, {
|
|
67060
67545
|
status: args.status,
|
|
67061
67546
|
reason,
|
|
@@ -67207,7 +67692,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67207
67692
|
const nowMs = Date.now();
|
|
67208
67693
|
const state = autoLaunchAwaitClaimBackoff.get(backoffKey) || { cycles: 0, nextAttemptAtMs: 0 };
|
|
67209
67694
|
if (state.nextAttemptAtMs && nowMs < state.nextAttemptAtMs) return "backoff";
|
|
67210
|
-
const atCap = state.cycles >=
|
|
67695
|
+
const atCap = state.cycles >= AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES2;
|
|
67211
67696
|
const live = remoteSessionAppearsLive(meshId, sessionId);
|
|
67212
67697
|
if ((live || atCap) && nodeId && providerType) {
|
|
67213
67698
|
try {
|
|
@@ -67233,7 +67718,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67233
67718
|
return "respawn";
|
|
67234
67719
|
}
|
|
67235
67720
|
}
|
|
67236
|
-
const cycles = Math.min(state.cycles + 1,
|
|
67721
|
+
const cycles = Math.min(state.cycles + 1, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES2);
|
|
67237
67722
|
autoLaunchAwaitClaimBackoff.set(backoffKey, { cycles, nextAttemptAtMs: nowMs + awaitClaimWindowMs(cycles) });
|
|
67238
67723
|
recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim_backoff", nodeId, sessionId });
|
|
67239
67724
|
return "backoff";
|
|
@@ -67254,333 +67739,339 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67254
67739
|
const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
|
|
67255
67740
|
const maxReadonlyParallelTasks = resolveMaxReadonlyParallelTasks(maxParallelTasks);
|
|
67256
67741
|
for (const task of pending) {
|
|
67257
|
-
|
|
67258
|
-
|
|
67742
|
+
const taskLaunchKey = `${meshId}::${task.id}`;
|
|
67743
|
+
if (autoLaunchTaskInProgress.has(taskLaunchKey)) {
|
|
67744
|
+
recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "auto_launch_task_in_progress" });
|
|
67259
67745
|
continue;
|
|
67260
67746
|
}
|
|
67261
|
-
|
|
67262
|
-
|
|
67263
|
-
|
|
67264
|
-
|
|
67265
|
-
const isReadonly = isTaskReadonly(task);
|
|
67266
|
-
if (isReadonly) {
|
|
67267
|
-
if (activeReadonlyAssignedCount(meshId) >= maxReadonlyParallelTasks) {
|
|
67268
|
-
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "max_readonly_parallel_tasks_reached" });
|
|
67747
|
+
autoLaunchTaskInProgress.add(taskLaunchKey);
|
|
67748
|
+
try {
|
|
67749
|
+
if (!taskDependenciesSatisfied(task, statusById)) {
|
|
67750
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "dependencies_unsatisfied" });
|
|
67269
67751
|
continue;
|
|
67270
67752
|
}
|
|
67271
|
-
|
|
67272
|
-
|
|
67273
|
-
continue;
|
|
67274
|
-
}
|
|
67275
|
-
if (task.targetSessionId) {
|
|
67276
|
-
const deadTarget = resolveDeadTargetVerdict(components, meshId, mesh, task);
|
|
67277
|
-
if (deadTarget.dead) {
|
|
67278
|
-
const requeued = requeueTask(meshId, task.id, {
|
|
67279
|
-
reason: deadTarget.reason,
|
|
67280
|
-
clearTargetSession: true,
|
|
67281
|
-
// Keep the node pin if only the SESSION died on a still-live node; clear it
|
|
67282
|
-
// when the NODE itself is absent (nothing to pin to).
|
|
67283
|
-
clearTargetNode: deadTarget.nodeDead
|
|
67284
|
-
});
|
|
67285
|
-
if (requeued) {
|
|
67286
|
-
noteTargetPinCleared(deadTarget.reason);
|
|
67287
|
-
LOG2.warn("MeshQueue", `DEAD-TARGET-SELFHEAL: task ${task.id} (mesh ${meshId}) was pinned to a dead target (${deadTarget.reason}); requeued${deadTarget.nodeDead ? " and unpinned node" : ""} (requeueCount=${requeued.requeueCount ?? "?"}, status=${requeued.status}).`);
|
|
67288
|
-
}
|
|
67289
|
-
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "target_session_dead_requeued" });
|
|
67753
|
+
if (!meshTaskNotBeforeReady(task)) {
|
|
67754
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "not_before_delayed" });
|
|
67290
67755
|
continue;
|
|
67291
67756
|
}
|
|
67292
|
-
const
|
|
67293
|
-
if (
|
|
67294
|
-
|
|
67295
|
-
|
|
67296
|
-
|
|
67297
|
-
traceMeshEventDrop("target_session_pin_expired", {
|
|
67298
|
-
taskId: task.id,
|
|
67299
|
-
sessionId: readNonEmptyString(task.targetSessionId),
|
|
67300
|
-
nodeId: readNonEmptyString(task.targetNodeId),
|
|
67301
|
-
meshId,
|
|
67302
|
-
event: "agent:ready"
|
|
67303
|
-
}, `unclaimed ${Math.round(pinAgeMs / 1e3)}s \u2265 ttl ${Math.round(TARGET_SESSION_PIN_TTL_MS / 1e3)}s \u2192 pin cleared, claimable`);
|
|
67304
|
-
LOG2.warn("MeshQueue", `TARGET-PIN-TTL: task ${task.id} (mesh ${meshId}) stayed pinned-but-unclaimed for ${Math.round(pinAgeMs / 1e3)}s (ttl ${Math.round(TARGET_SESSION_PIN_TTL_MS / 1e3)}s); expired the stale target pin so a compatible session can claim it.`);
|
|
67757
|
+
const isReadonly = isTaskReadonly(task);
|
|
67758
|
+
if (isReadonly) {
|
|
67759
|
+
if (activeReadonlyAssignedCount(meshId) >= maxReadonlyParallelTasks) {
|
|
67760
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "max_readonly_parallel_tasks_reached" });
|
|
67761
|
+
continue;
|
|
67305
67762
|
}
|
|
67306
|
-
|
|
67307
|
-
|
|
67308
|
-
}
|
|
67309
|
-
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "target_session_constraint" });
|
|
67310
|
-
continue;
|
|
67311
|
-
}
|
|
67312
|
-
if (task.autoLaunch?.status === "completed" && task.autoLaunch.sessionId) {
|
|
67313
|
-
const launchedAtMs = Date.parse(task.autoLaunch.updatedAt);
|
|
67314
|
-
const alSessionId = readNonEmptyString(task.autoLaunch.sessionId);
|
|
67315
|
-
const alNodeId = readNonEmptyString(task.autoLaunch.nodeId);
|
|
67316
|
-
const alProvider = readNonEmptyString(task.autoLaunch.providerType);
|
|
67317
|
-
if (Number.isFinite(launchedAtMs) && Date.now() - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS) {
|
|
67318
|
-
recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim", nodeId: alNodeId, sessionId: alSessionId });
|
|
67763
|
+
} else if (activeWriteAssignedCount(meshId) >= maxParallelTasks) {
|
|
67764
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "max_parallel_tasks_reached" });
|
|
67319
67765
|
continue;
|
|
67320
67766
|
}
|
|
67321
|
-
if (
|
|
67322
|
-
|
|
67323
|
-
|
|
67324
|
-
|
|
67325
|
-
|
|
67326
|
-
|
|
67327
|
-
const candidateNodes = Array.isArray(mesh?.nodes) ? mesh.nodes.filter((node) => {
|
|
67328
|
-
if (task.targetNodeId && !meshNodeIdMatches(node, task.targetNodeId)) return false;
|
|
67329
|
-
if (task.taskMode === "convergence" && node?.isLocalWorktree === true) return false;
|
|
67330
|
-
if (task.requiredTags?.length) {
|
|
67331
|
-
const slotProviders = resolveNodeCapabilitySlots(node, meshId).map((s2) => s2.provider).filter(Boolean);
|
|
67332
|
-
const priorities = slotProviders.length ? slotProviders : normalizeProviderPriority2(node?.policy);
|
|
67333
|
-
const providerCandidates = priorities.length ? priorities : [void 0];
|
|
67334
|
-
return providerCandidates.some(
|
|
67335
|
-
(p) => nodeSatisfiesRequiredTags(task.requiredTags, buildMeshNodeCapabilityTags(node, p))
|
|
67767
|
+
if (taskIsParked(task)) {
|
|
67768
|
+
settleParkedQueueTask(
|
|
67769
|
+
meshId,
|
|
67770
|
+
task,
|
|
67771
|
+
(reason) => markAutoLaunch(meshId, task.id, { status: "skipped", reason }),
|
|
67772
|
+
failRetentionExpiredParkedTask
|
|
67336
67773
|
);
|
|
67337
|
-
}
|
|
67338
|
-
return true;
|
|
67339
|
-
}) : [];
|
|
67340
|
-
if (!candidateNodes.length) {
|
|
67341
|
-
const targetPinUnmatched = !!task.targetNodeId && !(Array.isArray(mesh?.nodes) && mesh.nodes.some((n) => meshNodeIdMatches(n, task.targetNodeId)));
|
|
67342
|
-
const convergenceOntoWorktree = task.taskMode === "convergence" && Array.isArray(mesh?.nodes) && (() => {
|
|
67343
|
-
const matched = mesh.nodes.filter((n) => !task.targetNodeId || meshNodeIdMatches(n, task.targetNodeId));
|
|
67344
|
-
return matched.length > 0 && matched.every((n) => n?.isLocalWorktree === true);
|
|
67345
|
-
})();
|
|
67346
|
-
const targetTransientlyUnresolved = targetPinUnmatched && isTargetNodeTransientlyUnresolved(mesh, task);
|
|
67347
|
-
markAutoLaunch(meshId, task.id, {
|
|
67348
|
-
status: "skipped",
|
|
67349
|
-
reason: convergenceOntoWorktree ? "mesh_convergence_target_is_worktree" : targetTransientlyUnresolved ? TRANSIENT_TARGET_NODE_BOOTSTRAP_PENDING_REASON : targetPinUnmatched ? "target_node_id_unmatched" : "no_node_satisfies_required_tags",
|
|
67350
|
-
nodeId: task.targetNodeId
|
|
67351
|
-
});
|
|
67352
|
-
continue;
|
|
67353
|
-
}
|
|
67354
|
-
const strategy = resolveSchedulingStrategy(mesh);
|
|
67355
|
-
const orderedCandidateNodes = strategy === "first_eligible" ? candidateNodes : orderEligibleNodes(
|
|
67356
|
-
meshId,
|
|
67357
|
-
strategy,
|
|
67358
|
-
candidateNodes.map((node, index) => ({ nodeId: readMeshNodeId(node), node, index })).filter((c) => c.nodeId),
|
|
67359
|
-
// Auto-launch drains one task at a time, so the task IS in scope here —
|
|
67360
|
-
// pass it through for the 'fitness' strategy's task→slot ranking. The
|
|
67361
|
-
// mesh's quotaRouting thresholds ride along so the fitness score can
|
|
67362
|
-
// include the quota-headroom spread bonus (fail-open when unset).
|
|
67363
|
-
{ bumpCursor: true, task: { difficulty: task.difficulty, requiredTags: task.requiredTags }, quotaRouting: mesh?.policy?.quotaRouting ?? null, quotaFactsContext: quotaFactsContextForLiveRouting(mesh, isLocalAutoLaunchNode, components.providerLoader) }
|
|
67364
|
-
).map((c) => c.node);
|
|
67365
|
-
const skippedCandidates = [];
|
|
67366
|
-
const SKIPPED_CANDIDATES_MAX = 5;
|
|
67367
|
-
const markSkip = (nodeIdForSkip, reason, extra) => {
|
|
67368
|
-
markAutoLaunch(meshId, task.id, { status: "skipped", reason, nodeId: nodeIdForSkip, ...extra || {} });
|
|
67369
|
-
if (nodeIdForSkip && skippedCandidates.length < SKIPPED_CANDIDATES_MAX) {
|
|
67370
|
-
skippedCandidates.push({ nodeId: nodeIdForSkip, reason });
|
|
67371
|
-
}
|
|
67372
|
-
};
|
|
67373
|
-
for (const node of orderedCandidateNodes) {
|
|
67374
|
-
const nodeId = readMeshNodeId(node);
|
|
67375
|
-
if (!nodeId) continue;
|
|
67376
|
-
const launchKey = `${meshId}:${nodeId}`;
|
|
67377
|
-
const now = Date.now();
|
|
67378
|
-
const cooldownUntil = autoLaunchCooldownUntil.get(launchKey) || 0;
|
|
67379
|
-
if (cooldownUntil > 0 && now >= cooldownUntil) autoLaunchCooldownUntil.delete(launchKey);
|
|
67380
|
-
if (autoLaunchInProgress.has(launchKey)) {
|
|
67381
|
-
markSkip(nodeId, "auto_launch_in_progress");
|
|
67382
|
-
continue;
|
|
67383
|
-
}
|
|
67384
|
-
if (now < cooldownUntil) {
|
|
67385
|
-
markSkip(nodeId, "auto_launch_cooldown");
|
|
67386
|
-
continue;
|
|
67387
|
-
}
|
|
67388
|
-
if (isDirtyNode(node)) {
|
|
67389
|
-
markSkip(nodeId, "dirty_workspace");
|
|
67390
67774
|
continue;
|
|
67391
67775
|
}
|
|
67392
|
-
if (
|
|
67393
|
-
|
|
67394
|
-
|
|
67395
|
-
|
|
67396
|
-
|
|
67397
|
-
|
|
67398
|
-
|
|
67399
|
-
|
|
67400
|
-
|
|
67401
|
-
|
|
67402
|
-
|
|
67403
|
-
|
|
67404
|
-
|
|
67405
|
-
|
|
67406
|
-
|
|
67407
|
-
|
|
67408
|
-
|
|
67409
|
-
|
|
67410
|
-
|
|
67411
|
-
|
|
67412
|
-
|
|
67776
|
+
if (task.targetSessionId) {
|
|
67777
|
+
const deadTarget = resolveDeadTargetVerdict(components, meshId, mesh, task);
|
|
67778
|
+
if (deadTarget.dead) {
|
|
67779
|
+
const requeued = requeueTask(meshId, task.id, {
|
|
67780
|
+
reason: deadTarget.reason,
|
|
67781
|
+
clearTargetSession: true,
|
|
67782
|
+
// Keep the node pin if only the SESSION died on a still-live node; clear it
|
|
67783
|
+
// when the NODE itself is absent (nothing to pin to).
|
|
67784
|
+
clearTargetNode: deadTarget.nodeDead
|
|
67785
|
+
});
|
|
67786
|
+
if (requeued) {
|
|
67787
|
+
noteTargetPinCleared(deadTarget.reason);
|
|
67788
|
+
LOG2.warn("MeshQueue", `DEAD-TARGET-SELFHEAL: task ${task.id} (mesh ${meshId}) was pinned to a dead target (${deadTarget.reason}); requeued${deadTarget.nodeDead ? " and unpinned node" : ""} (requeueCount=${requeued.requeueCount ?? "?"}, status=${requeued.status}).`);
|
|
67789
|
+
}
|
|
67790
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "target_session_dead_requeued" });
|
|
67791
|
+
continue;
|
|
67792
|
+
}
|
|
67793
|
+
if (parkExpiredTargetPin(meshId, task, resolveTargetPinTtlVerdict(components, task), TARGET_SESSION_PIN_TTL_MS, (m, t, r) => parkTaskTargetPin(m, t, { reason: r }))) {
|
|
67794
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason: PARKED_SKIP_REASON });
|
|
67795
|
+
continue;
|
|
67796
|
+
}
|
|
67797
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "target_session_constraint" });
|
|
67413
67798
|
continue;
|
|
67414
67799
|
}
|
|
67415
|
-
|
|
67416
|
-
|
|
67417
|
-
|
|
67800
|
+
if (task.autoLaunch?.status === "completed" && task.autoLaunch.sessionId) {
|
|
67801
|
+
const launchedAtMs = Date.parse(task.autoLaunch.updatedAt);
|
|
67802
|
+
const alSessionId = readNonEmptyString(task.autoLaunch.sessionId);
|
|
67803
|
+
const alNodeId = readNonEmptyString(task.autoLaunch.nodeId);
|
|
67804
|
+
const alProvider = readNonEmptyString(task.autoLaunch.providerType);
|
|
67805
|
+
if (Number.isFinite(launchedAtMs) && Date.now() - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS) {
|
|
67806
|
+
recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim", nodeId: alNodeId, sessionId: alSessionId });
|
|
67807
|
+
continue;
|
|
67808
|
+
}
|
|
67809
|
+
if (Number.isFinite(launchedAtMs) && alSessionId && alNodeId) {
|
|
67810
|
+
const outcome = driveExpiredAwaitClaim(components, meshId, task, { sessionId: alSessionId, nodeId: alNodeId, providerType: alProvider });
|
|
67811
|
+
if (outcome === "claimed" || outcome === "fallback") return true;
|
|
67812
|
+
if (outcome === "backoff") continue;
|
|
67813
|
+
}
|
|
67814
|
+
}
|
|
67815
|
+
const candidateNodes = Array.isArray(mesh?.nodes) ? mesh.nodes.filter((node) => {
|
|
67816
|
+
if (task.targetNodeId && !meshNodeIdMatches(node, task.targetNodeId)) return false;
|
|
67817
|
+
if (task.taskMode === "convergence" && node?.isLocalWorktree === true) return false;
|
|
67818
|
+
if (task.requiredTags?.length) {
|
|
67819
|
+
const slotProviders = resolveNodeCapabilitySlots(node, meshId).map((s2) => s2.provider).filter(Boolean);
|
|
67820
|
+
const priorities = slotProviders.length ? slotProviders : normalizeProviderPriority2(node?.policy);
|
|
67821
|
+
const providerCandidates = priorities.length ? priorities : [void 0];
|
|
67822
|
+
return providerCandidates.some(
|
|
67823
|
+
(p) => nodeSatisfiesRequiredTags(task.requiredTags, buildMeshNodeCapabilityTags(node, p))
|
|
67824
|
+
);
|
|
67825
|
+
}
|
|
67826
|
+
return true;
|
|
67827
|
+
}) : [];
|
|
67828
|
+
if (!candidateNodes.length) {
|
|
67829
|
+
const targetPinUnmatched = !!task.targetNodeId && !(Array.isArray(mesh?.nodes) && mesh.nodes.some((n) => meshNodeIdMatches(n, task.targetNodeId)));
|
|
67830
|
+
const convergenceOntoWorktree = task.taskMode === "convergence" && Array.isArray(mesh?.nodes) && (() => {
|
|
67831
|
+
const matched = mesh.nodes.filter((n) => !task.targetNodeId || meshNodeIdMatches(n, task.targetNodeId));
|
|
67832
|
+
return matched.length > 0 && matched.every((n) => n?.isLocalWorktree === true);
|
|
67833
|
+
})();
|
|
67834
|
+
const targetTransientlyUnresolved = targetPinUnmatched && isTargetNodeTransientlyUnresolved(mesh, task);
|
|
67835
|
+
markAutoLaunch(meshId, task.id, {
|
|
67836
|
+
status: "skipped",
|
|
67837
|
+
reason: convergenceOntoWorktree ? "mesh_convergence_target_is_worktree" : targetTransientlyUnresolved ? TRANSIENT_TARGET_NODE_BOOTSTRAP_PENDING_REASON : targetPinUnmatched ? "target_node_id_unmatched" : "no_node_satisfies_required_tags",
|
|
67838
|
+
nodeId: task.targetNodeId
|
|
67839
|
+
});
|
|
67418
67840
|
continue;
|
|
67419
67841
|
}
|
|
67420
|
-
|
|
67421
|
-
|
|
67422
|
-
|
|
67423
|
-
|
|
67424
|
-
|
|
67842
|
+
const strategy = resolveSchedulingStrategy(mesh);
|
|
67843
|
+
const orderedCandidateNodes = strategy === "first_eligible" ? candidateNodes : orderEligibleNodes(
|
|
67844
|
+
meshId,
|
|
67845
|
+
strategy,
|
|
67846
|
+
candidateNodes.map((node, index) => ({ nodeId: readMeshNodeId(node), node, index })).filter((c) => c.nodeId),
|
|
67847
|
+
// Auto-launch drains one task at a time, so the task IS in scope here —
|
|
67848
|
+
// pass it through for the 'fitness' strategy's task→slot ranking. The
|
|
67849
|
+
// mesh's quotaRouting thresholds ride along so the fitness score can
|
|
67850
|
+
// include the quota-headroom spread bonus (fail-open when unset).
|
|
67851
|
+
{ bumpCursor: true, task: { difficulty: task.difficulty, requiredTags: task.requiredTags }, quotaRouting: mesh?.policy?.quotaRouting ?? null, quotaFactsContext: quotaFactsContextForLiveRouting(mesh, isLocalAutoLaunchNode, components.providerLoader) }
|
|
67852
|
+
).map((c) => c.node);
|
|
67853
|
+
const skippedCandidates = [];
|
|
67854
|
+
const SKIPPED_CANDIDATES_MAX = 5;
|
|
67855
|
+
const markSkip = (nodeIdForSkip, reason, extra) => {
|
|
67856
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason, nodeId: nodeIdForSkip, ...extra || {} });
|
|
67857
|
+
if (nodeIdForSkip && skippedCandidates.length < SKIPPED_CANDIDATES_MAX) {
|
|
67858
|
+
skippedCandidates.push({ nodeId: nodeIdForSkip, reason });
|
|
67859
|
+
}
|
|
67860
|
+
};
|
|
67861
|
+
for (const node of orderedCandidateNodes) {
|
|
67862
|
+
const nodeId = readMeshNodeId(node);
|
|
67863
|
+
if (!nodeId) continue;
|
|
67864
|
+
const launchKey = `${meshId}:${nodeId}`;
|
|
67865
|
+
const now = Date.now();
|
|
67866
|
+
const cooldownUntil = autoLaunchCooldownUntil.get(launchKey) || 0;
|
|
67867
|
+
if (cooldownUntil > 0 && now >= cooldownUntil) autoLaunchCooldownUntil.delete(launchKey);
|
|
67868
|
+
if (autoLaunchInProgress.has(launchKey)) {
|
|
67869
|
+
markSkip(nodeId, "auto_launch_in_progress");
|
|
67425
67870
|
continue;
|
|
67426
67871
|
}
|
|
67427
|
-
|
|
67428
|
-
|
|
67429
|
-
const effectiveThinkingLevel = resolveLaunchAxis(task.thinkingLevel, task.thinkingLevelSource, resolved.thinkingLevel, slotCoversDifficulty);
|
|
67430
|
-
const slotDecision = decideSlotForModel({
|
|
67431
|
-
requestedModel,
|
|
67432
|
-
slots: resolveNodeCapabilitySlots(node, meshId).map((slot) => ({
|
|
67433
|
-
slot,
|
|
67434
|
-
available: slotHasCapacity(meshId, nodeId, node, slot, mesh?.nodes, isReadonly)
|
|
67435
|
-
}))
|
|
67436
|
-
});
|
|
67437
|
-
if (slotDecision.outcome === "wait") {
|
|
67438
|
-
LOG2.info("MeshQueue", `SLOT MODEL GUARD: model '${requestedModel}' is declared on node ${nodeId} but every matching slot is at its maxParallel cap (task ${task.id}); leaving the task queued until a slot goes idle`);
|
|
67439
|
-
markSkip(nodeId, slotDecision.reason, { providerType: resolved.providerType });
|
|
67872
|
+
if (now < cooldownUntil) {
|
|
67873
|
+
markSkip(nodeId, "auto_launch_cooldown");
|
|
67440
67874
|
continue;
|
|
67441
67875
|
}
|
|
67442
|
-
if (
|
|
67443
|
-
|
|
67444
|
-
markSkip(nodeId, slotDecision.reason, { providerType: resolved.providerType });
|
|
67876
|
+
if (isDirtyNode(node)) {
|
|
67877
|
+
markSkip(nodeId, "dirty_workspace");
|
|
67445
67878
|
continue;
|
|
67446
67879
|
}
|
|
67447
|
-
|
|
67448
|
-
|
|
67449
|
-
const finalizedModel = slotDecision.slot.model?.trim() || void 0;
|
|
67450
|
-
const slotWasDemoted = resolved.slot?.provider !== slotDecision.slot.provider || winningModel !== finalizedModel;
|
|
67451
|
-
const demotionReason = slotWasDemoted ? slotHasCapacity(meshId, nodeId, node, resolved.slot, mesh?.nodes, isReadonly) ? "slot_reselected_during_launch" : "winning_slot_capacity_exhausted" : void 0;
|
|
67452
|
-
const effectiveModel = isModelCompatibleWithProvider(rawEffectiveModel, resolved.providerType) ? rawEffectiveModel : void 0;
|
|
67453
|
-
if (rawEffectiveModel && effectiveModel === void 0) {
|
|
67454
|
-
LOG2.info("MeshQueue", `CODEX-400 GUARD: dropped incompatible launch model '${rawEffectiveModel}' for non-Anthropic provider '${resolved.providerType}' on node ${nodeId} (task ${task.id}); provider will use its own default model`);
|
|
67455
|
-
}
|
|
67456
|
-
const providerCap = effectiveSlotCap(
|
|
67457
|
-
resolveProviderMaxParallel(resolveNodeCapabilitySlots(node, meshId), resolved.providerType),
|
|
67458
|
-
isReadonly
|
|
67459
|
-
);
|
|
67460
|
-
if (providerCap !== void 0 && activeProviderAssignedCount(
|
|
67461
|
-
meshId,
|
|
67462
|
-
nodeId,
|
|
67463
|
-
resolved.providerType,
|
|
67464
|
-
resolveDaemonSiblingNodeIds(nodeId, mesh?.nodes)
|
|
67465
|
-
) >= providerCap) {
|
|
67466
|
-
markSkip(nodeId, "max_provider_parallel_reached", { providerType: resolved.providerType });
|
|
67880
|
+
if (!isLaunchableNode(node)) {
|
|
67881
|
+
markSkip(nodeId, "node_health_not_launchable");
|
|
67467
67882
|
continue;
|
|
67468
67883
|
}
|
|
67469
|
-
|
|
67470
|
-
|
|
67471
|
-
|
|
67472
|
-
|
|
67473
|
-
|
|
67474
|
-
|
|
67475
|
-
|
|
67476
|
-
|
|
67477
|
-
|
|
67478
|
-
|
|
67479
|
-
|
|
67480
|
-
|
|
67481
|
-
|
|
67482
|
-
|
|
67483
|
-
|
|
67484
|
-
|
|
67485
|
-
|
|
67486
|
-
|
|
67487
|
-
|
|
67488
|
-
|
|
67489
|
-
|
|
67490
|
-
|
|
67491
|
-
|
|
67884
|
+
if (!isMeshNodeFreshEnoughToLaunch(node, freshnessGate)) {
|
|
67885
|
+
markSkip(nodeId, "node_stale_behind_upstream");
|
|
67886
|
+
continue;
|
|
67887
|
+
}
|
|
67888
|
+
const launchTarget = resolveAutoLaunchTarget(components, node);
|
|
67889
|
+
if (launchTarget.mode === "skip") {
|
|
67890
|
+
markSkip(nodeId, launchTarget.reason || "auto_launch_unavailable");
|
|
67891
|
+
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
67892
|
+
sweepExpiredCooldowns();
|
|
67893
|
+
continue;
|
|
67894
|
+
}
|
|
67895
|
+
if (nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node)) {
|
|
67896
|
+
markSkip(nodeId, "node_has_live_session_pending_claim");
|
|
67897
|
+
continue;
|
|
67898
|
+
}
|
|
67899
|
+
if (!isTaskReadonly(task) && nodeHasActiveAssignment(meshId, nodeId)) {
|
|
67900
|
+
markSkip(nodeId, "node_has_active_assignment");
|
|
67901
|
+
continue;
|
|
67902
|
+
}
|
|
67903
|
+
const maxConcurrentSessions = Number(node?.policy?.maxConcurrentSessions);
|
|
67904
|
+
if (Number.isFinite(maxConcurrentSessions) && maxConcurrentSessions >= 0 && liveSessionCountForNode(components, meshId, nodeId) >= maxConcurrentSessions) {
|
|
67905
|
+
markSkip(nodeId, "max_concurrent_sessions_reached");
|
|
67906
|
+
continue;
|
|
67907
|
+
}
|
|
67908
|
+
autoLaunchInProgress.add(launchKey);
|
|
67909
|
+
try {
|
|
67910
|
+
const resolved = await resolveUsableProvider(components, nodeId, node, meshId, task.requiredTags, { difficulty: task.difficulty, requiredTags: task.requiredTags }, mesh?.policy?.quotaRouting ?? null, quotaFactsContextForLiveRouting(mesh, isLocalAutoLaunchNode, components.providerLoader), task.id);
|
|
67911
|
+
if (!resolved.providerType) {
|
|
67912
|
+
markSkip(nodeId, resolved.reason || "provider_unusable");
|
|
67913
|
+
continue;
|
|
67914
|
+
}
|
|
67915
|
+
const slotCoversDifficulty = slotCoversTaskDifficulty(resolved.slot, task.difficulty);
|
|
67916
|
+
const requestedModel = resolveLaunchAxis(task.model, task.modelSource, resolved.model, slotCoversDifficulty);
|
|
67917
|
+
const effectiveThinkingLevel = resolveLaunchAxis(task.thinkingLevel, task.thinkingLevelSource, resolved.thinkingLevel, slotCoversDifficulty);
|
|
67918
|
+
const slotDecision = decideSlotForModel({
|
|
67919
|
+
requestedModel,
|
|
67920
|
+
slots: resolveNodeCapabilitySlots(node, meshId).map((slot) => ({
|
|
67921
|
+
slot,
|
|
67922
|
+
available: slotHasCapacity(meshId, nodeId, node, slot, mesh?.nodes, isReadonly)
|
|
67923
|
+
}))
|
|
67924
|
+
});
|
|
67925
|
+
if (slotDecision.outcome === "wait") {
|
|
67926
|
+
LOG2.info("MeshQueue", `SLOT MODEL GUARD: model '${requestedModel}' is declared on node ${nodeId} but every matching slot is at its maxParallel cap (task ${task.id}); leaving the task queued until a slot goes idle`);
|
|
67927
|
+
markSkip(nodeId, slotDecision.reason, { providerType: resolved.providerType });
|
|
67928
|
+
continue;
|
|
67929
|
+
}
|
|
67930
|
+
if (slotDecision.outcome === "notify") {
|
|
67931
|
+
LOG2.warn("MeshQueue", `SLOT MODEL GUARD: no slot on node ${nodeId} declares model '${requestedModel}' (declared: ${slotDecision.declaredModels.join(", ") || "none"}) for task ${task.id}; not launching \u2014 surfacing to the coordinator to re-drive`);
|
|
67932
|
+
markSkip(nodeId, slotDecision.reason, { providerType: resolved.providerType });
|
|
67933
|
+
continue;
|
|
67934
|
+
}
|
|
67935
|
+
const rawEffectiveModel = slotDecision.model;
|
|
67936
|
+
const winningModel = resolved.slot?.model?.trim() || void 0;
|
|
67937
|
+
const finalizedModel = slotDecision.slot.model?.trim() || void 0;
|
|
67938
|
+
const slotWasDemoted = resolved.slot?.provider !== slotDecision.slot.provider || winningModel !== finalizedModel;
|
|
67939
|
+
const demotionReason = slotWasDemoted ? slotHasCapacity(meshId, nodeId, node, resolved.slot, mesh?.nodes, isReadonly) ? "slot_reselected_during_launch" : "winning_slot_capacity_exhausted" : void 0;
|
|
67940
|
+
const effectiveModel = isModelCompatibleWithProvider(rawEffectiveModel, resolved.providerType) ? rawEffectiveModel : void 0;
|
|
67941
|
+
if (rawEffectiveModel && effectiveModel === void 0) {
|
|
67942
|
+
LOG2.info("MeshQueue", `CODEX-400 GUARD: dropped incompatible launch model '${rawEffectiveModel}' for non-Anthropic provider '${resolved.providerType}' on node ${nodeId} (task ${task.id}); provider will use its own default model`);
|
|
67943
|
+
}
|
|
67944
|
+
const providerCap = effectiveSlotCap(
|
|
67945
|
+
resolveProviderMaxParallel(resolveNodeCapabilitySlots(node, meshId), resolved.providerType),
|
|
67946
|
+
isReadonly
|
|
67947
|
+
);
|
|
67948
|
+
if (providerCap !== void 0 && activeProviderAssignedCount(
|
|
67949
|
+
meshId,
|
|
67950
|
+
nodeId,
|
|
67951
|
+
resolved.providerType,
|
|
67952
|
+
resolveDaemonSiblingNodeIds(nodeId, mesh?.nodes)
|
|
67953
|
+
) >= providerCap) {
|
|
67954
|
+
markSkip(nodeId, "max_provider_parallel_reached", { providerType: resolved.providerType });
|
|
67955
|
+
continue;
|
|
67956
|
+
}
|
|
67957
|
+
const launchSettings = {
|
|
67958
|
+
// Worker launch envelope: role + mesh context so worker can route completion events.
|
|
67959
|
+
role: "worker",
|
|
67960
|
+
meshNodeFor: meshId,
|
|
67961
|
+
meshNodeId: nodeId,
|
|
67962
|
+
spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
|
|
67963
|
+
// Coordinator-dispatched worker: auto-approve unless mesh/node policy
|
|
67964
|
+
// opts out (default true). Lands in settingsOverride and beats the
|
|
67965
|
+
// global per-provider-type boolean/mode through explicit opposite-key clearing.
|
|
67966
|
+
...delegatedWorkerAutoApproveSettingsForNode(
|
|
67967
|
+
mesh,
|
|
67968
|
+
node,
|
|
67969
|
+
components.providerLoader?.getMeta(resolved.providerType),
|
|
67970
|
+
resolved.providerType
|
|
67971
|
+
),
|
|
67972
|
+
launchedByCoordinator: true,
|
|
67973
|
+
autoLaunchedForQueueTaskId: task.id
|
|
67492
67974
|
};
|
|
67975
|
+
if (launchTarget.mode === "remote") {
|
|
67976
|
+
const remoteSettings = {
|
|
67977
|
+
...launchSettings,
|
|
67978
|
+
meshCoordinatorDaemonId: launchTarget.coordinatorDaemonId,
|
|
67979
|
+
meshCoordinatorNodeId: nodeId
|
|
67980
|
+
};
|
|
67981
|
+
markAutoLaunch(meshId, task.id, { status: "started", nodeId, providerType: resolved.providerType, ...effectiveModel ? { model: effectiveModel } : {}, ...effectiveThinkingLevel ? { thinkingLevel: effectiveThinkingLevel } : {} });
|
|
67982
|
+
let launchResult2;
|
|
67983
|
+
try {
|
|
67984
|
+
launchResult2 = await components.dispatchMeshCommand(launchTarget.daemonId, "launch_cli", withStatusProbeMarker({
|
|
67985
|
+
cliType: resolved.providerType,
|
|
67986
|
+
dir: node.workspace,
|
|
67987
|
+
settings: remoteSettings,
|
|
67988
|
+
// MAGI-KIND-PANEL model axis: forward the task's model override so the
|
|
67989
|
+
// remote worker session launches with it (initialModel). Best-effort.
|
|
67990
|
+
// Slot-aware: task override wins, else the matched slot's model.
|
|
67991
|
+
...effectiveModel ? { initialModel: effectiveModel } : {},
|
|
67992
|
+
// BRAIN-ROUTING thinking axis: forward the effective thinking level (initialThinkingLevel).
|
|
67993
|
+
...effectiveThinkingLevel ? { initialThinkingLevel: effectiveThinkingLevel } : {}
|
|
67994
|
+
}));
|
|
67995
|
+
} catch (e) {
|
|
67996
|
+
markAutoLaunch(meshId, task.id, { status: "failed", reason: `remote_launch_dispatch_failed: ${e?.message || String(e)}`, nodeId, providerType: resolved.providerType });
|
|
67997
|
+
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
67998
|
+
sweepExpiredCooldowns();
|
|
67999
|
+
return false;
|
|
68000
|
+
}
|
|
68001
|
+
const payload = launchResult2 && typeof launchResult2 === "object" && "payload" in launchResult2 && launchResult2.payload && typeof launchResult2.payload === "object" ? launchResult2.payload : launchResult2;
|
|
68002
|
+
if (!payload?.success) {
|
|
68003
|
+
const reason = readNonEmptyString(payload?.error) || "remote_launch_cli_failed";
|
|
68004
|
+
markAutoLaunch(meshId, task.id, { status: "failed", reason, nodeId, providerType: resolved.providerType });
|
|
68005
|
+
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
68006
|
+
sweepExpiredCooldowns();
|
|
68007
|
+
return false;
|
|
68008
|
+
}
|
|
68009
|
+
const remoteSessionId = readNonEmptyString(payload.sessionId) || readNonEmptyString(payload.id) || readNonEmptyString(payload.runtimeSessionId);
|
|
68010
|
+
markAutoLaunch(meshId, task.id, { status: "completed", nodeId, providerType: resolved.providerType, sessionId: remoteSessionId || void 0, ...effectiveModel ? { model: effectiveModel } : {}, ...effectiveThinkingLevel ? { thinkingLevel: effectiveThinkingLevel } : {} });
|
|
68011
|
+
logAutoLaunchQuotaFallbackSuccess(resolved, task.id, nodeId, remoteSessionId || void 0);
|
|
68012
|
+
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
68013
|
+
sweepExpiredCooldowns();
|
|
68014
|
+
return true;
|
|
68015
|
+
}
|
|
67493
68016
|
markAutoLaunch(meshId, task.id, { status: "started", nodeId, providerType: resolved.providerType, ...effectiveModel ? { model: effectiveModel } : {}, ...effectiveThinkingLevel ? { thinkingLevel: effectiveThinkingLevel } : {} });
|
|
67494
|
-
|
|
67495
|
-
|
|
67496
|
-
|
|
67497
|
-
|
|
67498
|
-
|
|
67499
|
-
|
|
67500
|
-
|
|
67501
|
-
|
|
67502
|
-
|
|
67503
|
-
|
|
67504
|
-
|
|
67505
|
-
|
|
67506
|
-
})
|
|
67507
|
-
} catch (e) {
|
|
67508
|
-
markAutoLaunch(meshId, task.id, { status: "failed", reason: `remote_launch_dispatch_failed: ${e?.message || String(e)}`, nodeId, providerType: resolved.providerType });
|
|
68017
|
+
const launchResult = await components.cliManager.handleCliCommand("launch_cli", {
|
|
68018
|
+
cliType: resolved.providerType,
|
|
68019
|
+
dir: node.workspace,
|
|
68020
|
+
settings: launchSettings,
|
|
68021
|
+
// MAGI-KIND-PANEL model axis: local launch forwards the effective model
|
|
68022
|
+
// (task override, else matched slot) as initialModel (CLI → modelLaunchArgs; ACP → setConfigOption).
|
|
68023
|
+
...effectiveModel ? { initialModel: effectiveModel } : {},
|
|
68024
|
+
// BRAIN-ROUTING thinking axis: forward the effective thinking level (initialThinkingLevel).
|
|
68025
|
+
...effectiveThinkingLevel ? { initialThinkingLevel: effectiveThinkingLevel } : {}
|
|
68026
|
+
});
|
|
68027
|
+
if (!launchResult?.success) {
|
|
68028
|
+
const reason = launchResult?.error || "launch_cli_failed";
|
|
68029
|
+
markAutoLaunch(meshId, task.id, { status: "failed", reason, nodeId, providerType: resolved.providerType });
|
|
67509
68030
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
67510
68031
|
sweepExpiredCooldowns();
|
|
67511
68032
|
return false;
|
|
67512
68033
|
}
|
|
67513
|
-
const
|
|
67514
|
-
if (!
|
|
67515
|
-
|
|
67516
|
-
markAutoLaunch(meshId, task.id, { status: "failed", reason, nodeId, providerType: resolved.providerType });
|
|
68034
|
+
const sessionId = readNonEmptyString(launchResult.sessionId) || readNonEmptyString(launchResult.id) || readNonEmptyString(launchResult.runtimeSessionId);
|
|
68035
|
+
if (!sessionId) {
|
|
68036
|
+
markAutoLaunch(meshId, task.id, { status: "failed", reason: "launch_missing_session_id", nodeId, providerType: resolved.providerType });
|
|
67517
68037
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
67518
68038
|
sweepExpiredCooldowns();
|
|
67519
68039
|
return false;
|
|
67520
68040
|
}
|
|
67521
|
-
|
|
67522
|
-
|
|
67523
|
-
|
|
67524
|
-
|
|
67525
|
-
|
|
68041
|
+
markAutoLaunch(meshId, task.id, { status: "completed", nodeId, providerType: resolved.providerType, sessionId, ...effectiveModel ? { model: effectiveModel } : {}, ...effectiveThinkingLevel ? { thinkingLevel: effectiveThinkingLevel } : {} });
|
|
68042
|
+
logAutoLaunchQuotaFallbackSuccess(resolved, task.id, nodeId, sessionId);
|
|
68043
|
+
await waitForLocalSessionReady(components, sessionId);
|
|
68044
|
+
const requiredTags = Array.isArray(task.requiredTags) ? task.requiredTags.filter((t) => !!t) : [];
|
|
68045
|
+
const routingDecision = buildAutoLaunchRoutingDecision({
|
|
68046
|
+
node,
|
|
68047
|
+
meshId,
|
|
68048
|
+
task: { difficulty: task.difficulty, requiredTags: task.requiredTags },
|
|
68049
|
+
resolved,
|
|
68050
|
+
quotaRouting: mesh?.policy?.quotaRouting ?? null,
|
|
68051
|
+
quotaFactsContext: quotaFactsContextForLiveRouting(mesh, isLocalAutoLaunchNode, components.providerLoader),
|
|
68052
|
+
skippedCandidates,
|
|
68053
|
+
requiredTagsResult: {
|
|
68054
|
+
required: requiredTags,
|
|
68055
|
+
satisfied: !requiredTags.length || nodeSatisfiesRequiredTags(requiredTags, buildMeshNodeCapabilityTags(node, resolved.providerType)),
|
|
68056
|
+
missing: requiredTags.filter((t) => !buildMeshNodeCapabilityTags(node, resolved.providerType).includes(t))
|
|
68057
|
+
},
|
|
68058
|
+
effectiveModel,
|
|
68059
|
+
effectiveThinkingLevel,
|
|
68060
|
+
executedSlot: slotDecision.slot,
|
|
68061
|
+
demotionReason
|
|
68062
|
+
});
|
|
68063
|
+
tryAssignQueueTask(components, meshId, nodeId, sessionId, resolved.providerType, routingDecision);
|
|
67526
68064
|
return true;
|
|
67527
|
-
}
|
|
67528
|
-
|
|
67529
|
-
const launchResult = await components.cliManager.handleCliCommand("launch_cli", {
|
|
67530
|
-
cliType: resolved.providerType,
|
|
67531
|
-
dir: node.workspace,
|
|
67532
|
-
settings: launchSettings,
|
|
67533
|
-
// MAGI-KIND-PANEL model axis: local launch forwards the effective model
|
|
67534
|
-
// (task override, else matched slot) as initialModel (CLI → modelLaunchArgs; ACP → setConfigOption).
|
|
67535
|
-
...effectiveModel ? { initialModel: effectiveModel } : {},
|
|
67536
|
-
// BRAIN-ROUTING thinking axis: forward the effective thinking level (initialThinkingLevel).
|
|
67537
|
-
...effectiveThinkingLevel ? { initialThinkingLevel: effectiveThinkingLevel } : {}
|
|
67538
|
-
});
|
|
67539
|
-
if (!launchResult?.success) {
|
|
67540
|
-
const reason = launchResult?.error || "launch_cli_failed";
|
|
67541
|
-
markAutoLaunch(meshId, task.id, { status: "failed", reason, nodeId, providerType: resolved.providerType });
|
|
67542
|
-
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
67543
|
-
sweepExpiredCooldowns();
|
|
67544
|
-
return false;
|
|
67545
|
-
}
|
|
67546
|
-
const sessionId = readNonEmptyString(launchResult.sessionId) || readNonEmptyString(launchResult.id) || readNonEmptyString(launchResult.runtimeSessionId);
|
|
67547
|
-
if (!sessionId) {
|
|
67548
|
-
markAutoLaunch(meshId, task.id, { status: "failed", reason: "launch_missing_session_id", nodeId, providerType: resolved.providerType });
|
|
68065
|
+
} catch (e) {
|
|
68066
|
+
markAutoLaunch(meshId, task.id, { status: "failed", error: e?.message || String(e), nodeId });
|
|
67549
68067
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
67550
|
-
sweepExpiredCooldowns();
|
|
67551
68068
|
return false;
|
|
68069
|
+
} finally {
|
|
68070
|
+
autoLaunchInProgress.delete(launchKey);
|
|
67552
68071
|
}
|
|
67553
|
-
markAutoLaunch(meshId, task.id, { status: "completed", nodeId, providerType: resolved.providerType, sessionId, ...effectiveModel ? { model: effectiveModel } : {}, ...effectiveThinkingLevel ? { thinkingLevel: effectiveThinkingLevel } : {} });
|
|
67554
|
-
logAutoLaunchQuotaFallbackSuccess(resolved, task.id, nodeId, sessionId);
|
|
67555
|
-
await waitForLocalSessionReady(components, sessionId);
|
|
67556
|
-
const requiredTags = Array.isArray(task.requiredTags) ? task.requiredTags.filter((t) => !!t) : [];
|
|
67557
|
-
const routingDecision = buildAutoLaunchRoutingDecision({
|
|
67558
|
-
node,
|
|
67559
|
-
meshId,
|
|
67560
|
-
task: { difficulty: task.difficulty, requiredTags: task.requiredTags },
|
|
67561
|
-
resolved,
|
|
67562
|
-
quotaRouting: mesh?.policy?.quotaRouting ?? null,
|
|
67563
|
-
quotaFactsContext: quotaFactsContextForLiveRouting(mesh, isLocalAutoLaunchNode, components.providerLoader),
|
|
67564
|
-
skippedCandidates,
|
|
67565
|
-
requiredTagsResult: {
|
|
67566
|
-
required: requiredTags,
|
|
67567
|
-
satisfied: !requiredTags.length || nodeSatisfiesRequiredTags(requiredTags, buildMeshNodeCapabilityTags(node, resolved.providerType)),
|
|
67568
|
-
missing: requiredTags.filter((t) => !buildMeshNodeCapabilityTags(node, resolved.providerType).includes(t))
|
|
67569
|
-
},
|
|
67570
|
-
effectiveModel,
|
|
67571
|
-
effectiveThinkingLevel,
|
|
67572
|
-
executedSlot: slotDecision.slot,
|
|
67573
|
-
demotionReason
|
|
67574
|
-
});
|
|
67575
|
-
tryAssignQueueTask(components, meshId, nodeId, sessionId, resolved.providerType, routingDecision);
|
|
67576
|
-
return true;
|
|
67577
|
-
} catch (e) {
|
|
67578
|
-
markAutoLaunch(meshId, task.id, { status: "failed", error: e?.message || String(e), nodeId });
|
|
67579
|
-
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
67580
|
-
return false;
|
|
67581
|
-
} finally {
|
|
67582
|
-
autoLaunchInProgress.delete(launchKey);
|
|
67583
68072
|
}
|
|
68073
|
+
} finally {
|
|
68074
|
+
autoLaunchTaskInProgress.delete(taskLaunchKey);
|
|
67584
68075
|
}
|
|
67585
68076
|
}
|
|
67586
68077
|
return false;
|
|
@@ -67627,7 +68118,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67627
68118
|
if (instMeshId !== meshId) continue;
|
|
67628
68119
|
const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
67629
68120
|
if (!nodeId) continue;
|
|
67630
|
-
if (!
|
|
68121
|
+
if (!isIdleSessionState3(state)) {
|
|
67631
68122
|
const status = readNonEmptyString(state.status).toLowerCase();
|
|
67632
68123
|
skippedSessions.push({
|
|
67633
68124
|
nodeId,
|
|
@@ -67700,6 +68191,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67700
68191
|
}
|
|
67701
68192
|
}
|
|
67702
68193
|
autoLaunchStarted = await maybeAutoLaunchOneQueueSession(components, meshId, mesh);
|
|
68194
|
+
sweepAutoLaunchOrphanSessions(components, meshId);
|
|
67703
68195
|
const afterQueue = getQueue(meshId);
|
|
67704
68196
|
const pendingAfter = afterQueue.filter((task) => task.status === "pending").length;
|
|
67705
68197
|
const assignedAfter = afterQueue.filter((task) => task.status === "assigned").length;
|
|
@@ -67758,12 +68250,10 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67758
68250
|
var LOCAL_LAUNCH_READY_TIMEOUT_MS;
|
|
67759
68251
|
var LOCAL_LAUNCH_READY_POLL_MS;
|
|
67760
68252
|
var autoLaunchInProgress;
|
|
68253
|
+
var autoLaunchTaskInProgress;
|
|
67761
68254
|
var autoLaunchCooldownUntil;
|
|
67762
68255
|
var AUTO_LAUNCH_COOLDOWN_MS;
|
|
67763
|
-
var
|
|
67764
|
-
var AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES;
|
|
67765
|
-
var AUTO_LAUNCH_REMOTE_IDLE_TTL_MS;
|
|
67766
|
-
var autoLaunchAwaitClaimBackoff;
|
|
68256
|
+
var AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES2;
|
|
67767
68257
|
var init_mesh_queue_assignment = __esm2({
|
|
67768
68258
|
"src/mesh/mesh-queue-assignment.ts"() {
|
|
67769
68259
|
"use strict";
|
|
@@ -67796,14 +68286,17 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67796
68286
|
init_mesh_duplicate_dispatch();
|
|
67797
68287
|
init_mesh_auto_fast_forward();
|
|
67798
68288
|
init_mesh_skip_notify();
|
|
68289
|
+
init_mesh_task_parking();
|
|
67799
68290
|
init_mesh_scheduling_fitness();
|
|
67800
68291
|
init_mesh_queue_observability();
|
|
67801
68292
|
init_mesh_routing_decision();
|
|
68293
|
+
init_mesh_autolaunch_integrity();
|
|
67802
68294
|
init_mesh_difficulty_floor();
|
|
67803
68295
|
init_mesh_difficulty_floor();
|
|
67804
68296
|
init_mesh_auto_fast_forward();
|
|
67805
68297
|
init_mesh_skip_notify();
|
|
67806
68298
|
init_mesh_scheduling_fitness();
|
|
68299
|
+
init_mesh_autolaunch_integrity();
|
|
67807
68300
|
BOOTSTRAP_TERMINAL_STATUSES = /* @__PURE__ */ new Set(["complete", "failed"]);
|
|
67808
68301
|
DISPATCH_CONFIRM_TIMEOUT_MS = 12e4;
|
|
67809
68302
|
DISPATCH_CONNECT_TIMEOUT_MS = MESH_CONNECT_TIMEOUT_MS2;
|
|
@@ -67811,12 +68304,10 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67811
68304
|
LOCAL_LAUNCH_READY_TIMEOUT_MS = 15e3;
|
|
67812
68305
|
LOCAL_LAUNCH_READY_POLL_MS = 100;
|
|
67813
68306
|
autoLaunchInProgress = /* @__PURE__ */ new Set();
|
|
68307
|
+
autoLaunchTaskInProgress = /* @__PURE__ */ new Set();
|
|
67814
68308
|
autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
|
|
67815
68309
|
AUTO_LAUNCH_COOLDOWN_MS = 5e3;
|
|
67816
|
-
|
|
67817
|
-
AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES = 2;
|
|
67818
|
-
AUTO_LAUNCH_REMOTE_IDLE_TTL_MS = 5 * 60 * 1e3;
|
|
67819
|
-
autoLaunchAwaitClaimBackoff = /* @__PURE__ */ new Map();
|
|
68310
|
+
AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES2 = 2;
|
|
67820
68311
|
}
|
|
67821
68312
|
});
|
|
67822
68313
|
function readSettings(state) {
|
|
@@ -70550,6 +71041,11 @@ ${cleanBody}`;
|
|
|
70550
71041
|
if (isFalseIdleCompletion(metadataEvent)) return false;
|
|
70551
71042
|
return !!readWorkerResultMetadata(metadataEvent) || !!readNonEmptyString(metadataEvent.finalSummary);
|
|
70552
71043
|
}
|
|
71044
|
+
function resolveGraphEnvelopeWorkerResult(metadataEvent) {
|
|
71045
|
+
const explicit = readWorkerResultMetadata(metadataEvent);
|
|
71046
|
+
if (explicit) return explicit;
|
|
71047
|
+
return extractJsonObjectFromSummary(readNonEmptyString(metadataEvent.finalSummary) || void 0);
|
|
71048
|
+
}
|
|
70553
71049
|
function supersedesTruncatedTerminalSummary(args) {
|
|
70554
71050
|
if (!args.terminalTaskId || !args.eventTaskId || args.terminalTaskId !== args.eventTaskId) return false;
|
|
70555
71051
|
if (!isGenuineCompletionEvidence(args.metadataEvent)) return false;
|
|
@@ -71187,7 +71683,7 @@ ${cleanBody}`;
|
|
|
71187
71683
|
// as the terminal flip (design :317-327 step 2).
|
|
71188
71684
|
envelope: {
|
|
71189
71685
|
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0,
|
|
71190
|
-
workerResult:
|
|
71686
|
+
workerResult: resolveGraphEnvelopeWorkerResult(args.metadataEvent),
|
|
71191
71687
|
nodeId: readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || void 0,
|
|
71192
71688
|
providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0
|
|
71193
71689
|
}
|
|
@@ -77159,8 +77655,8 @@ ${cleanBody}`;
|
|
|
77159
77655
|
let cwd = options.cwd;
|
|
77160
77656
|
if (cwd) {
|
|
77161
77657
|
try {
|
|
77162
|
-
const
|
|
77163
|
-
const stat2 =
|
|
77658
|
+
const fs61 = require("fs");
|
|
77659
|
+
const stat2 = fs61.statSync(cwd);
|
|
77164
77660
|
if (!stat2.isDirectory()) cwd = os14.homedir();
|
|
77165
77661
|
} catch {
|
|
77166
77662
|
cwd = os14.homedir();
|
|
@@ -78557,6 +79053,360 @@ ${cleanBody}`;
|
|
|
78557
79053
|
DEFAULT_REFINE_VITEST_MAX_WORKERS = 2;
|
|
78558
79054
|
}
|
|
78559
79055
|
});
|
|
79056
|
+
function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
79057
|
+
try {
|
|
79058
|
+
const output = (0, import_node_child_process11.execFileSync)(GIT4, ["diff", "--raw", "--no-abbrev", fromRef, toRef], {
|
|
79059
|
+
cwd: repoRoot,
|
|
79060
|
+
encoding: "utf8",
|
|
79061
|
+
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
79062
|
+
});
|
|
79063
|
+
const paths = /* @__PURE__ */ new Set();
|
|
79064
|
+
for (const line of output.split("\n")) {
|
|
79065
|
+
if (!line.trim()) continue;
|
|
79066
|
+
const metaAndPath = line.split(" ");
|
|
79067
|
+
const meta3 = metaAndPath[0] || "";
|
|
79068
|
+
const path58 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
79069
|
+
if (!path58) continue;
|
|
79070
|
+
const parts = meta3.split(/\s+/);
|
|
79071
|
+
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
79072
|
+
paths.add(path58);
|
|
79073
|
+
}
|
|
79074
|
+
}
|
|
79075
|
+
return [...paths].sort();
|
|
79076
|
+
} catch {
|
|
79077
|
+
return [];
|
|
79078
|
+
}
|
|
79079
|
+
}
|
|
79080
|
+
function readTreeObject(repoRoot, ref, path58) {
|
|
79081
|
+
try {
|
|
79082
|
+
const output = (0, import_node_child_process11.execFileSync)(GIT4, ["ls-tree", ref, "--", path58], {
|
|
79083
|
+
cwd: repoRoot,
|
|
79084
|
+
encoding: "utf8",
|
|
79085
|
+
maxBuffer: 1024 * 1024
|
|
79086
|
+
}).trim();
|
|
79087
|
+
const match = output.match(/\bcommit\s+([0-9a-f]{40})\b/i);
|
|
79088
|
+
return match?.[1];
|
|
79089
|
+
} catch {
|
|
79090
|
+
return void 0;
|
|
79091
|
+
}
|
|
79092
|
+
}
|
|
79093
|
+
function submoduleCommitPresent(submoduleRepoPath, commit) {
|
|
79094
|
+
if (!commit) return false;
|
|
79095
|
+
try {
|
|
79096
|
+
(0, import_node_child_process11.execFileSync)(GIT4, ["cat-file", "-e", `${commit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79097
|
+
return true;
|
|
79098
|
+
} catch {
|
|
79099
|
+
return false;
|
|
79100
|
+
}
|
|
79101
|
+
}
|
|
79102
|
+
function ensureSubmoduleCommitLocal(submoduleRepoPath, baseSubmoduleRepoPath, commit) {
|
|
79103
|
+
if (!commit) return false;
|
|
79104
|
+
const present = () => {
|
|
79105
|
+
try {
|
|
79106
|
+
(0, import_node_child_process11.execFileSync)(GIT4, ["cat-file", "-e", `${commit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79107
|
+
return true;
|
|
79108
|
+
} catch {
|
|
79109
|
+
return false;
|
|
79110
|
+
}
|
|
79111
|
+
};
|
|
79112
|
+
if (present()) return true;
|
|
79113
|
+
try {
|
|
79114
|
+
if (!fs48.existsSync(submoduleRepoPath) || !fs48.existsSync(baseSubmoduleRepoPath)) return false;
|
|
79115
|
+
} catch {
|
|
79116
|
+
return false;
|
|
79117
|
+
}
|
|
79118
|
+
const strategies = [
|
|
79119
|
+
// 1. All local branches (historical behaviour).
|
|
79120
|
+
["fetch", "-q", baseSubmoduleRepoPath, "+refs/heads/*:refs/adhdev-refine-base/*"],
|
|
79121
|
+
// 2. The base checkout's detached HEAD plus every ref it has.
|
|
79122
|
+
["fetch", "-q", baseSubmoduleRepoPath, "HEAD", "+refs/*:refs/adhdev-refine-base-all/*"],
|
|
79123
|
+
// 3. The exact object, allowing a bare-sha want on the source side.
|
|
79124
|
+
["fetch", "-q", "--upload-pack", "git -c uploadpack.allowAnySHA1InWant=true upload-pack", baseSubmoduleRepoPath, commit]
|
|
79125
|
+
];
|
|
79126
|
+
for (const args of strategies) {
|
|
79127
|
+
try {
|
|
79128
|
+
(0, import_node_child_process11.execFileSync)(GIT4, ["-c", "protocol.file.allow=always", ...args], {
|
|
79129
|
+
cwd: submoduleRepoPath,
|
|
79130
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
79131
|
+
});
|
|
79132
|
+
} catch {
|
|
79133
|
+
}
|
|
79134
|
+
if (present()) return true;
|
|
79135
|
+
}
|
|
79136
|
+
return false;
|
|
79137
|
+
}
|
|
79138
|
+
var fs48;
|
|
79139
|
+
var import_node_child_process11;
|
|
79140
|
+
var GIT4;
|
|
79141
|
+
var REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES;
|
|
79142
|
+
var init_mesh_refine_gitlink_utils = __esm2({
|
|
79143
|
+
"src/mesh/mesh-refine-gitlink-utils.ts"() {
|
|
79144
|
+
"use strict";
|
|
79145
|
+
fs48 = __toESM2(require("fs"));
|
|
79146
|
+
import_node_child_process11 = require("child_process");
|
|
79147
|
+
init_resolve_executable();
|
|
79148
|
+
GIT4 = process.platform === "win32" ? resolveWin32Executable("git") : "git";
|
|
79149
|
+
REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
79150
|
+
}
|
|
79151
|
+
});
|
|
79152
|
+
function classifySubmoduleDivergence(submoduleRepoPath, baseCommit, branchCommit) {
|
|
79153
|
+
if (!baseCommit || !branchCommit) return "undeterminable";
|
|
79154
|
+
if (baseCommit === branchCommit) return "not_diverged";
|
|
79155
|
+
try {
|
|
79156
|
+
if (!fs49.existsSync(submoduleRepoPath)) return "undeterminable";
|
|
79157
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79158
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79159
|
+
} catch {
|
|
79160
|
+
return "undeterminable";
|
|
79161
|
+
}
|
|
79162
|
+
try {
|
|
79163
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79164
|
+
return "not_diverged";
|
|
79165
|
+
} catch {
|
|
79166
|
+
}
|
|
79167
|
+
try {
|
|
79168
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["merge-base", "--is-ancestor", branchCommit, baseCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79169
|
+
return "not_diverged";
|
|
79170
|
+
} catch {
|
|
79171
|
+
}
|
|
79172
|
+
try {
|
|
79173
|
+
const mb = (0, import_node_child_process12.execFileSync)(GIT4, ["merge-base", baseCommit, branchCommit], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
|
|
79174
|
+
return mb ? "diverged" : "not_diverged";
|
|
79175
|
+
} catch {
|
|
79176
|
+
return "not_diverged";
|
|
79177
|
+
}
|
|
79178
|
+
}
|
|
79179
|
+
function resolveSubmoduleRemoteMainRef(submoduleRepoPath) {
|
|
79180
|
+
try {
|
|
79181
|
+
const sym = (0, import_node_child_process12.execFileSync)(GIT4, ["symbolic-ref", "-q", "refs/remotes/origin/HEAD"], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
|
|
79182
|
+
if (sym) return sym;
|
|
79183
|
+
} catch {
|
|
79184
|
+
}
|
|
79185
|
+
for (const branch of ["main", "master"]) {
|
|
79186
|
+
try {
|
|
79187
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["rev-parse", "--verify", "-q", `refs/remotes/origin/${branch}`], { cwd: submoduleRepoPath, stdio: ["ignore", "pipe", "pipe"] });
|
|
79188
|
+
return `refs/remotes/origin/${branch}`;
|
|
79189
|
+
} catch {
|
|
79190
|
+
}
|
|
79191
|
+
}
|
|
79192
|
+
return void 0;
|
|
79193
|
+
}
|
|
79194
|
+
function findEquivalentPublishedSubmoduleCommit(submoduleRepoPath, baseCommit, branchCommit, remoteRef) {
|
|
79195
|
+
try {
|
|
79196
|
+
const mergeTreeOut = (0, import_node_child_process12.execFileSync)(GIT4, ["merge-tree", "--write-tree", baseCommit, branchCommit], {
|
|
79197
|
+
cwd: submoduleRepoPath,
|
|
79198
|
+
encoding: "utf8",
|
|
79199
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
79200
|
+
});
|
|
79201
|
+
const mergedTree = mergeTreeOut.trim().split(/\s+/)[0] || "";
|
|
79202
|
+
if (!mergedTree) return void 0;
|
|
79203
|
+
const candidates = (0, import_node_child_process12.execFileSync)(GIT4, ["rev-list", "--max-count=100", remoteRef, "--not", baseCommit], {
|
|
79204
|
+
cwd: submoduleRepoPath,
|
|
79205
|
+
encoding: "utf8"
|
|
79206
|
+
}).split("\n").map((s2) => s2.trim()).filter(Boolean);
|
|
79207
|
+
for (const candidate of candidates) {
|
|
79208
|
+
try {
|
|
79209
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["merge-base", "--is-ancestor", baseCommit, candidate], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79210
|
+
} catch {
|
|
79211
|
+
continue;
|
|
79212
|
+
}
|
|
79213
|
+
const tree = (0, import_node_child_process12.execFileSync)(GIT4, ["rev-parse", `${candidate}^{tree}`], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
|
|
79214
|
+
if (tree === mergedTree) return candidate;
|
|
79215
|
+
}
|
|
79216
|
+
} catch {
|
|
79217
|
+
}
|
|
79218
|
+
return void 0;
|
|
79219
|
+
}
|
|
79220
|
+
function convergeDivergedSubmoduleGitlinks(worktreeRoot, baseRepoRoot, baseHead, branchHead) {
|
|
79221
|
+
const changed = readChangedGitlinkPaths(worktreeRoot, baseHead, branchHead);
|
|
79222
|
+
if (changed.length === 0) {
|
|
79223
|
+
return { converged: false, reason: "no_changed_gitlinks", resolutions: [], gitlinks: [] };
|
|
79224
|
+
}
|
|
79225
|
+
const gitlinks = [];
|
|
79226
|
+
const resolutions = [];
|
|
79227
|
+
let sawDiverged = false;
|
|
79228
|
+
let sawUndeterminable = false;
|
|
79229
|
+
for (const path58 of changed) {
|
|
79230
|
+
const baseCommit = readTreeObject(baseRepoRoot, baseHead, path58);
|
|
79231
|
+
const branchCommit = readTreeObject(worktreeRoot, branchHead, path58);
|
|
79232
|
+
const submoduleRepoPath = (0, import_path17.resolve)(worktreeRoot, path58);
|
|
79233
|
+
if (baseCommit) {
|
|
79234
|
+
ensureSubmoduleCommitLocal(submoduleRepoPath, (0, import_path17.resolve)(baseRepoRoot, path58), baseCommit);
|
|
79235
|
+
}
|
|
79236
|
+
const markUndeterminable = () => {
|
|
79237
|
+
const unavailable = [];
|
|
79238
|
+
if (!baseCommit || !submoduleCommitPresent(submoduleRepoPath, baseCommit)) unavailable.push("base");
|
|
79239
|
+
if (!branchCommit || !submoduleCommitPresent(submoduleRepoPath, branchCommit)) unavailable.push("branch");
|
|
79240
|
+
sawUndeterminable = true;
|
|
79241
|
+
gitlinks.push({ path: path58, baseCommit, branchCommit, action: "skipped_commit_unavailable", unavailable });
|
|
79242
|
+
};
|
|
79243
|
+
if (!baseCommit || !branchCommit) {
|
|
79244
|
+
markUndeterminable();
|
|
79245
|
+
continue;
|
|
79246
|
+
}
|
|
79247
|
+
const divergence = classifySubmoduleDivergence(submoduleRepoPath, baseCommit, branchCommit);
|
|
79248
|
+
if (divergence === "undeterminable") {
|
|
79249
|
+
markUndeterminable();
|
|
79250
|
+
continue;
|
|
79251
|
+
}
|
|
79252
|
+
if (divergence !== "diverged") {
|
|
79253
|
+
gitlinks.push({ path: path58, baseCommit, branchCommit, action: "skipped_not_diverged" });
|
|
79254
|
+
continue;
|
|
79255
|
+
}
|
|
79256
|
+
sawDiverged = true;
|
|
79257
|
+
try {
|
|
79258
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["-c", "protocol.file.allow=always", "fetch", "-q", "origin"], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
|
|
79259
|
+
} catch {
|
|
79260
|
+
}
|
|
79261
|
+
const remoteMainRef = resolveSubmoduleRemoteMainRef(submoduleRepoPath);
|
|
79262
|
+
const publishedEquivalent = remoteMainRef ? findEquivalentPublishedSubmoduleCommit(submoduleRepoPath, baseCommit, branchCommit, remoteMainRef) : void 0;
|
|
79263
|
+
if (publishedEquivalent) {
|
|
79264
|
+
try {
|
|
79265
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", publishedEquivalent], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
|
|
79266
|
+
} catch {
|
|
79267
|
+
}
|
|
79268
|
+
gitlinks.push({ path: path58, baseCommit, branchCommit, rebasedCommit: publishedEquivalent, action: "converged_to_published" });
|
|
79269
|
+
resolutions.push({ path: path58, baseCommit, branchCommit, rebasedCommit: publishedEquivalent });
|
|
79270
|
+
continue;
|
|
79271
|
+
}
|
|
79272
|
+
let rebasedCommit;
|
|
79273
|
+
try {
|
|
79274
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", branchCommit], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
|
|
79275
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["rebase", baseCommit], { cwd: submoduleRepoPath, stdio: ["ignore", "pipe", "pipe"] });
|
|
79276
|
+
rebasedCommit = (0, import_node_child_process12.execFileSync)(GIT4, ["rev-parse", "HEAD"], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
|
|
79277
|
+
} catch {
|
|
79278
|
+
try {
|
|
79279
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["rebase", "--abort"], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79280
|
+
} catch {
|
|
79281
|
+
}
|
|
79282
|
+
try {
|
|
79283
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79284
|
+
} catch {
|
|
79285
|
+
}
|
|
79286
|
+
gitlinks.push({ path: path58, baseCommit, branchCommit, action: "rebase_conflict" });
|
|
79287
|
+
return { converged: false, reason: "rebase_conflict", resolutions: [], gitlinks };
|
|
79288
|
+
}
|
|
79289
|
+
const branchWorkSurvived = (() => {
|
|
79290
|
+
if (!rebasedCommit) return false;
|
|
79291
|
+
if (rebasedCommit === branchCommit) return true;
|
|
79292
|
+
if (rebasedCommit === baseCommit) return false;
|
|
79293
|
+
try {
|
|
79294
|
+
const replayed = (0, import_node_child_process12.execFileSync)(GIT4, ["rev-list", "--count", `${baseCommit}..${rebasedCommit}`], {
|
|
79295
|
+
cwd: submoduleRepoPath,
|
|
79296
|
+
encoding: "utf8"
|
|
79297
|
+
}).trim();
|
|
79298
|
+
return Number.parseInt(replayed, 10) > 0;
|
|
79299
|
+
} catch {
|
|
79300
|
+
return false;
|
|
79301
|
+
}
|
|
79302
|
+
})();
|
|
79303
|
+
if (!branchWorkSurvived) {
|
|
79304
|
+
try {
|
|
79305
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79306
|
+
} catch {
|
|
79307
|
+
}
|
|
79308
|
+
gitlinks.push({ path: path58, baseCommit, branchCommit, rebasedCommit, action: "rebase_dropped_branch_commits" });
|
|
79309
|
+
return { converged: false, reason: "rebase_dropped_branch_commits", resolutions: [], gitlinks };
|
|
79310
|
+
}
|
|
79311
|
+
gitlinks.push({ path: path58, baseCommit, branchCommit, rebasedCommit, action: "rebased" });
|
|
79312
|
+
resolutions.push({ path: path58, baseCommit, branchCommit, rebasedCommit });
|
|
79313
|
+
}
|
|
79314
|
+
if (!sawDiverged) {
|
|
79315
|
+
const reason = sawUndeterminable ? "submodule_commit_unavailable" : "not_diverged";
|
|
79316
|
+
return { converged: false, reason, resolutions: [], gitlinks };
|
|
79317
|
+
}
|
|
79318
|
+
return { converged: resolutions.length > 0, resolutions, gitlinks };
|
|
79319
|
+
}
|
|
79320
|
+
function rootRebaseResolvingGitlinks(worktreeRoot, baseHead, resolutions) {
|
|
79321
|
+
const resolveByPath = new Map(resolutions.map((r) => [r.path, r.rebasedCommit]));
|
|
79322
|
+
const runRebase = (args) => {
|
|
79323
|
+
try {
|
|
79324
|
+
(0, import_node_child_process12.execFileSync)(GIT4, args, {
|
|
79325
|
+
cwd: worktreeRoot,
|
|
79326
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
79327
|
+
// A rebase editor prompt would hang; keep it non-interactive.
|
|
79328
|
+
env: { ...process.env, GIT_EDITOR: "true", GIT_SEQUENCE_EDITOR: "true" }
|
|
79329
|
+
});
|
|
79330
|
+
return { ok: true };
|
|
79331
|
+
} catch {
|
|
79332
|
+
return { ok: false };
|
|
79333
|
+
}
|
|
79334
|
+
};
|
|
79335
|
+
const unmergedPaths = () => {
|
|
79336
|
+
try {
|
|
79337
|
+
return (0, import_node_child_process12.execFileSync)(GIT4, ["diff", "--name-only", "--diff-filter=U"], { cwd: worktreeRoot, encoding: "utf8" }).split("\n").map((s2) => s2.trim()).filter(Boolean);
|
|
79338
|
+
} catch {
|
|
79339
|
+
return [];
|
|
79340
|
+
}
|
|
79341
|
+
};
|
|
79342
|
+
const abort = (reason, conflictPaths) => {
|
|
79343
|
+
try {
|
|
79344
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["rebase", "--abort"], { cwd: worktreeRoot, stdio: "ignore" });
|
|
79345
|
+
} catch {
|
|
79346
|
+
}
|
|
79347
|
+
return { ok: false, reason, conflictPaths };
|
|
79348
|
+
};
|
|
79349
|
+
let progress = runRebase(["rebase", baseHead]);
|
|
79350
|
+
let guard = 0;
|
|
79351
|
+
while (!progress.ok) {
|
|
79352
|
+
if (guard++ > 100) return abort("rebase_error");
|
|
79353
|
+
const conflicts = unmergedPaths();
|
|
79354
|
+
if (conflicts.length === 0) {
|
|
79355
|
+
return abort("rebase_error");
|
|
79356
|
+
}
|
|
79357
|
+
const unresolvable = conflicts.filter((p) => !resolveByPath.has(p));
|
|
79358
|
+
if (unresolvable.length > 0) {
|
|
79359
|
+
const unresolvableGitlink = unresolvable.some((p) => {
|
|
79360
|
+
try {
|
|
79361
|
+
const staged = (0, import_node_child_process12.execFileSync)(GIT4, ["ls-files", "--stage", "--", p], { cwd: worktreeRoot, encoding: "utf8" });
|
|
79362
|
+
return /^160000\s/m.test(staged);
|
|
79363
|
+
} catch {
|
|
79364
|
+
return false;
|
|
79365
|
+
}
|
|
79366
|
+
});
|
|
79367
|
+
const allGitlink = unresolvable.every((p) => {
|
|
79368
|
+
try {
|
|
79369
|
+
const staged = (0, import_node_child_process12.execFileSync)(GIT4, ["ls-files", "--stage", "--", p], { cwd: worktreeRoot, encoding: "utf8" });
|
|
79370
|
+
return /^160000\s/m.test(staged);
|
|
79371
|
+
} catch {
|
|
79372
|
+
return false;
|
|
79373
|
+
}
|
|
79374
|
+
});
|
|
79375
|
+
return abort(allGitlink && unresolvableGitlink ? "unexpected_gitlink" : "non_gitlink_conflict", conflicts);
|
|
79376
|
+
}
|
|
79377
|
+
for (const p of conflicts) {
|
|
79378
|
+
const commit = resolveByPath.get(p);
|
|
79379
|
+
try {
|
|
79380
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", commit], { cwd: (0, import_path17.resolve)(worktreeRoot, p), stdio: "ignore" });
|
|
79381
|
+
} catch {
|
|
79382
|
+
}
|
|
79383
|
+
try {
|
|
79384
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["add", p], { cwd: worktreeRoot, stdio: "ignore" });
|
|
79385
|
+
} catch {
|
|
79386
|
+
return abort("rebase_error", conflicts);
|
|
79387
|
+
}
|
|
79388
|
+
}
|
|
79389
|
+
progress = runRebase(["rebase", "--continue"]);
|
|
79390
|
+
}
|
|
79391
|
+
let branchHead;
|
|
79392
|
+
try {
|
|
79393
|
+
branchHead = (0, import_node_child_process12.execFileSync)(GIT4, ["rev-parse", "HEAD"], { cwd: worktreeRoot, encoding: "utf8" }).trim();
|
|
79394
|
+
} catch {
|
|
79395
|
+
}
|
|
79396
|
+
return { ok: true, branchHead };
|
|
79397
|
+
}
|
|
79398
|
+
var fs49;
|
|
79399
|
+
var import_path17;
|
|
79400
|
+
var import_node_child_process12;
|
|
79401
|
+
var init_mesh_refine_submodule_converge = __esm2({
|
|
79402
|
+
"src/mesh/mesh-refine-submodule-converge.ts"() {
|
|
79403
|
+
"use strict";
|
|
79404
|
+
fs49 = __toESM2(require("fs"));
|
|
79405
|
+
import_path17 = require("path");
|
|
79406
|
+
import_node_child_process12 = require("child_process");
|
|
79407
|
+
init_mesh_refine_gitlink_utils();
|
|
79408
|
+
}
|
|
79409
|
+
});
|
|
78560
79410
|
function truncateValidationOutput(value) {
|
|
78561
79411
|
const text = typeof value === "string" ? value : value == null ? "" : String(value);
|
|
78562
79412
|
if (text.length <= REFINE_VALIDATION_SUMMARY_CHARS) return text;
|
|
@@ -78574,13 +79424,13 @@ ${tail}`;
|
|
|
78574
79424
|
}
|
|
78575
79425
|
function writeValidationFailureLog(workspace, index, candidate, streams, now = () => /* @__PURE__ */ new Date()) {
|
|
78576
79426
|
try {
|
|
78577
|
-
const dir = (0,
|
|
78578
|
-
|
|
79427
|
+
const dir = (0, import_path18.join)(workspace, REFINE_VALIDATION_LOG_DIR);
|
|
79428
|
+
fs50.mkdirSync(dir, { recursive: true });
|
|
78579
79429
|
const stamp = now().toISOString().replace(/[:.]/g, "-");
|
|
78580
|
-
const file2 = (0,
|
|
79430
|
+
const file2 = (0, import_path18.join)(dir, `refine-${stamp}-${index}.log`);
|
|
78581
79431
|
const asText = (v) => typeof v === "string" ? v : v == null ? "" : String(v);
|
|
78582
79432
|
const shown = candidate.displayCommand || [candidate.command, ...candidate.args || []].join(" ");
|
|
78583
|
-
|
|
79433
|
+
fs50.writeFileSync(
|
|
78584
79434
|
file2,
|
|
78585
79435
|
`# refine validation failure
|
|
78586
79436
|
# command: ${shown}
|
|
@@ -78654,18 +79504,18 @@ ${asText(streams.stderr)}
|
|
|
78654
79504
|
return { enabled: false };
|
|
78655
79505
|
}
|
|
78656
79506
|
async function computeGitPatchId(cwd, fromRef, toRef, excludePaths = []) {
|
|
78657
|
-
const { execFileSync:
|
|
79507
|
+
const { execFileSync: execFileSync15 } = await import("child_process");
|
|
78658
79508
|
const diffArgs = ["diff", "--patch", "--full-index", fromRef, toRef];
|
|
78659
79509
|
if (excludePaths.length > 0) {
|
|
78660
79510
|
diffArgs.push("--", ".", ...excludePaths.map((path58) => `:(exclude)${path58}`));
|
|
78661
79511
|
}
|
|
78662
|
-
const diff =
|
|
79512
|
+
const diff = execFileSync15(GIT4, diffArgs, {
|
|
78663
79513
|
cwd,
|
|
78664
79514
|
encoding: "utf8",
|
|
78665
79515
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
78666
79516
|
});
|
|
78667
79517
|
if (!diff.trim()) return "";
|
|
78668
|
-
const patchId =
|
|
79518
|
+
const patchId = execFileSync15(GIT4, ["patch-id", "--stable"], {
|
|
78669
79519
|
cwd,
|
|
78670
79520
|
input: diff,
|
|
78671
79521
|
encoding: "utf8",
|
|
@@ -78676,8 +79526,8 @@ ${asText(streams.stderr)}
|
|
|
78676
79526
|
async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead) {
|
|
78677
79527
|
const startedAt = Date.now();
|
|
78678
79528
|
try {
|
|
78679
|
-
const { execFileSync:
|
|
78680
|
-
const git3 = (args) =>
|
|
79529
|
+
const { execFileSync: execFileSync15 } = await import("child_process");
|
|
79530
|
+
const git3 = (args) => execFileSync15(GIT4, args, {
|
|
78681
79531
|
cwd: repoRoot,
|
|
78682
79532
|
encoding: "utf8",
|
|
78683
79533
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -78778,7 +79628,7 @@ ${e?.stderr || ""}`
|
|
|
78778
79628
|
...autoPublish !== void 0 ? { autoPublishSubmoduleMainCommits: autoPublish } : {}
|
|
78779
79629
|
};
|
|
78780
79630
|
try {
|
|
78781
|
-
const git3 = (args) => (0,
|
|
79631
|
+
const git3 = (args) => (0, import_node_child_process13.execFileSync)(GIT4, args, {
|
|
78782
79632
|
cwd: repoRoot,
|
|
78783
79633
|
encoding: "utf8",
|
|
78784
79634
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES,
|
|
@@ -78832,7 +79682,7 @@ ${e?.stderr || ""}`
|
|
|
78832
79682
|
} catch {
|
|
78833
79683
|
continue;
|
|
78834
79684
|
}
|
|
78835
|
-
const submoduleRepo = (0,
|
|
79685
|
+
const submoduleRepo = (0, import_path18.join)(repoRoot, p);
|
|
78836
79686
|
let fastForward;
|
|
78837
79687
|
let reachableFromOriginMain;
|
|
78838
79688
|
if (branchCommit) {
|
|
@@ -78903,7 +79753,7 @@ ${e?.stderr || ""}`
|
|
|
78903
79753
|
}
|
|
78904
79754
|
function execGitOk(cwd, args) {
|
|
78905
79755
|
try {
|
|
78906
|
-
(0,
|
|
79756
|
+
(0, import_node_child_process13.execFileSync)(GIT4, args, { cwd, encoding: "utf8", maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES, windowsHide: true });
|
|
78907
79757
|
return true;
|
|
78908
79758
|
} catch {
|
|
78909
79759
|
return false;
|
|
@@ -78912,8 +79762,8 @@ ${e?.stderr || ""}`
|
|
|
78912
79762
|
async function checkWorktreeChangesPatchEquivalentInRef(repoRoot, ref, worktreeHead) {
|
|
78913
79763
|
const startedAt = Date.now();
|
|
78914
79764
|
try {
|
|
78915
|
-
const { execFileSync:
|
|
78916
|
-
const git3 = (gitArgs) =>
|
|
79765
|
+
const { execFileSync: execFileSync15 } = await import("child_process");
|
|
79766
|
+
const git3 = (gitArgs) => execFileSync15(GIT4, gitArgs, {
|
|
78917
79767
|
cwd: repoRoot,
|
|
78918
79768
|
encoding: "utf8",
|
|
78919
79769
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -78976,8 +79826,8 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
78976
79826
|
async function runMeshRefineEffectiveDiffGate(repoRoot, baseHead, branchHead) {
|
|
78977
79827
|
const startedAt = Date.now();
|
|
78978
79828
|
try {
|
|
78979
|
-
const { execFileSync:
|
|
78980
|
-
const git3 = (args, opts) =>
|
|
79829
|
+
const { execFileSync: execFileSync15 } = await import("child_process");
|
|
79830
|
+
const git3 = (args, opts) => execFileSync15(GIT4, args, {
|
|
78981
79831
|
cwd: opts?.cwd || repoRoot,
|
|
78982
79832
|
encoding: "utf8",
|
|
78983
79833
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -79051,45 +79901,8 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79051
79901
|
]
|
|
79052
79902
|
};
|
|
79053
79903
|
}
|
|
79054
|
-
function readChangedGitlinkPaths(repoRoot, fromRef, toRef) {
|
|
79055
|
-
try {
|
|
79056
|
-
const output = (0, import_node_child_process11.execFileSync)(GIT4, ["diff", "--raw", "--no-abbrev", fromRef, toRef], {
|
|
79057
|
-
cwd: repoRoot,
|
|
79058
|
-
encoding: "utf8",
|
|
79059
|
-
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
79060
|
-
});
|
|
79061
|
-
const paths = /* @__PURE__ */ new Set();
|
|
79062
|
-
for (const line of output.split("\n")) {
|
|
79063
|
-
if (!line.trim()) continue;
|
|
79064
|
-
const metaAndPath = line.split(" ");
|
|
79065
|
-
const meta3 = metaAndPath[0] || "";
|
|
79066
|
-
const path58 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
79067
|
-
if (!path58) continue;
|
|
79068
|
-
const parts = meta3.split(/\s+/);
|
|
79069
|
-
if (parts[0]?.includes("160000") || parts[1]?.includes("160000")) {
|
|
79070
|
-
paths.add(path58);
|
|
79071
|
-
}
|
|
79072
|
-
}
|
|
79073
|
-
return [...paths].sort();
|
|
79074
|
-
} catch {
|
|
79075
|
-
return [];
|
|
79076
|
-
}
|
|
79077
|
-
}
|
|
79078
|
-
function readTreeObject(repoRoot, ref, path58) {
|
|
79079
|
-
try {
|
|
79080
|
-
const output = (0, import_node_child_process11.execFileSync)(GIT4, ["ls-tree", ref, "--", path58], {
|
|
79081
|
-
cwd: repoRoot,
|
|
79082
|
-
encoding: "utf8",
|
|
79083
|
-
maxBuffer: 1024 * 1024
|
|
79084
|
-
}).trim();
|
|
79085
|
-
const match = output.match(/\bcommit\s+([0-9a-f]{40})\b/i);
|
|
79086
|
-
return match?.[1];
|
|
79087
|
-
} catch {
|
|
79088
|
-
return void 0;
|
|
79089
|
-
}
|
|
79090
|
-
}
|
|
79091
79904
|
function resolveGitDir(repoRoot) {
|
|
79092
|
-
const out = (0,
|
|
79905
|
+
const out = (0, import_node_child_process13.execFileSync)(GIT4, ["rev-parse", "--absolute-git-dir"], {
|
|
79093
79906
|
cwd: repoRoot,
|
|
79094
79907
|
encoding: "utf8",
|
|
79095
79908
|
maxBuffer: 1024 * 1024
|
|
@@ -79100,10 +79913,10 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79100
79913
|
if (!baseCommit || !branchCommit) return false;
|
|
79101
79914
|
if (baseCommit === branchCommit) return true;
|
|
79102
79915
|
try {
|
|
79103
|
-
if (!
|
|
79104
|
-
(0,
|
|
79105
|
-
(0,
|
|
79106
|
-
(0,
|
|
79916
|
+
if (!fs50.existsSync(submoduleRepoPath)) return false;
|
|
79917
|
+
(0, import_node_child_process13.execFileSync)(GIT4, ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79918
|
+
(0, import_node_child_process13.execFileSync)(GIT4, ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79919
|
+
(0, import_node_child_process13.execFileSync)(GIT4, ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79107
79920
|
return true;
|
|
79108
79921
|
} catch {
|
|
79109
79922
|
return false;
|
|
@@ -79111,7 +79924,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79111
79924
|
}
|
|
79112
79925
|
function readChangedPathKinds(repoRoot, fromRef, toRef) {
|
|
79113
79926
|
try {
|
|
79114
|
-
const output = (0,
|
|
79927
|
+
const output = (0, import_node_child_process13.execFileSync)(GIT4, ["diff", "--raw", "--no-abbrev", fromRef, toRef], {
|
|
79115
79928
|
cwd: repoRoot,
|
|
79116
79929
|
encoding: "utf8",
|
|
79117
79930
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -79139,7 +79952,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79139
79952
|
const baseCommit = readTreeObject(repoRoot, baseHead, path58);
|
|
79140
79953
|
const branchCommit = readTreeObject(repoRoot, branchHead, path58);
|
|
79141
79954
|
if (!baseCommit || !branchCommit) return false;
|
|
79142
|
-
return isSubmoduleFastForward((0,
|
|
79955
|
+
return isSubmoduleFastForward((0, import_path18.resolve)(repoRoot, path58), baseCommit, branchCommit);
|
|
79143
79956
|
});
|
|
79144
79957
|
}
|
|
79145
79958
|
function collectTrivialFastForwardGitlinkResolutions(worktreeRoot, baseRepoRoot, baseHead, branchHead) {
|
|
@@ -79148,8 +79961,8 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79148
79961
|
const baseCommit = readTreeObject(baseRepoRoot, baseHead, path58);
|
|
79149
79962
|
const branchCommit = readTreeObject(worktreeRoot, branchHead, path58);
|
|
79150
79963
|
if (!baseCommit || !branchCommit) continue;
|
|
79151
|
-
const submoduleRepoPath = (0,
|
|
79152
|
-
ensureSubmoduleCommitLocal(submoduleRepoPath, (0,
|
|
79964
|
+
const submoduleRepoPath = (0, import_path18.resolve)(worktreeRoot, path58);
|
|
79965
|
+
ensureSubmoduleCommitLocal(submoduleRepoPath, (0, import_path18.resolve)(baseRepoRoot, path58), baseCommit);
|
|
79153
79966
|
if (baseCommit === branchCommit) {
|
|
79154
79967
|
continue;
|
|
79155
79968
|
}
|
|
@@ -79161,254 +79974,11 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79161
79974
|
}
|
|
79162
79975
|
return resolutions;
|
|
79163
79976
|
}
|
|
79164
|
-
function isSubmoduleDivergedSibling(submoduleRepoPath, baseCommit, branchCommit) {
|
|
79165
|
-
if (!baseCommit || !branchCommit || baseCommit === branchCommit) return false;
|
|
79166
|
-
try {
|
|
79167
|
-
if (!fs48.existsSync(submoduleRepoPath)) return false;
|
|
79168
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79169
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79170
|
-
} catch {
|
|
79171
|
-
return false;
|
|
79172
|
-
}
|
|
79173
|
-
try {
|
|
79174
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79175
|
-
return false;
|
|
79176
|
-
} catch {
|
|
79177
|
-
}
|
|
79178
|
-
try {
|
|
79179
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["merge-base", "--is-ancestor", branchCommit, baseCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79180
|
-
return false;
|
|
79181
|
-
} catch {
|
|
79182
|
-
}
|
|
79183
|
-
try {
|
|
79184
|
-
const mb = (0, import_node_child_process11.execFileSync)(GIT4, ["merge-base", baseCommit, branchCommit], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
|
|
79185
|
-
return !!mb;
|
|
79186
|
-
} catch {
|
|
79187
|
-
return false;
|
|
79188
|
-
}
|
|
79189
|
-
}
|
|
79190
|
-
function resolveSubmoduleRemoteMainRef(submoduleRepoPath) {
|
|
79191
|
-
try {
|
|
79192
|
-
const sym = (0, import_node_child_process11.execFileSync)(GIT4, ["symbolic-ref", "-q", "refs/remotes/origin/HEAD"], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
|
|
79193
|
-
if (sym) return sym;
|
|
79194
|
-
} catch {
|
|
79195
|
-
}
|
|
79196
|
-
for (const branch of ["main", "master"]) {
|
|
79197
|
-
try {
|
|
79198
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["rev-parse", "--verify", "-q", `refs/remotes/origin/${branch}`], { cwd: submoduleRepoPath, stdio: ["ignore", "pipe", "pipe"] });
|
|
79199
|
-
return `refs/remotes/origin/${branch}`;
|
|
79200
|
-
} catch {
|
|
79201
|
-
}
|
|
79202
|
-
}
|
|
79203
|
-
return void 0;
|
|
79204
|
-
}
|
|
79205
|
-
function findEquivalentPublishedSubmoduleCommit(submoduleRepoPath, baseCommit, branchCommit, remoteRef) {
|
|
79206
|
-
try {
|
|
79207
|
-
const mergeTreeOut = (0, import_node_child_process11.execFileSync)(GIT4, ["merge-tree", "--write-tree", baseCommit, branchCommit], {
|
|
79208
|
-
cwd: submoduleRepoPath,
|
|
79209
|
-
encoding: "utf8",
|
|
79210
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
79211
|
-
});
|
|
79212
|
-
const mergedTree = mergeTreeOut.trim().split(/\s+/)[0] || "";
|
|
79213
|
-
if (!mergedTree) return void 0;
|
|
79214
|
-
const candidates = (0, import_node_child_process11.execFileSync)(GIT4, ["rev-list", "--max-count=100", remoteRef, "--not", baseCommit], {
|
|
79215
|
-
cwd: submoduleRepoPath,
|
|
79216
|
-
encoding: "utf8"
|
|
79217
|
-
}).split("\n").map((s2) => s2.trim()).filter(Boolean);
|
|
79218
|
-
for (const candidate of candidates) {
|
|
79219
|
-
try {
|
|
79220
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["merge-base", "--is-ancestor", baseCommit, candidate], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79221
|
-
} catch {
|
|
79222
|
-
continue;
|
|
79223
|
-
}
|
|
79224
|
-
const tree = (0, import_node_child_process11.execFileSync)(GIT4, ["rev-parse", `${candidate}^{tree}`], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
|
|
79225
|
-
if (tree === mergedTree) return candidate;
|
|
79226
|
-
}
|
|
79227
|
-
} catch {
|
|
79228
|
-
}
|
|
79229
|
-
return void 0;
|
|
79230
|
-
}
|
|
79231
|
-
function ensureSubmoduleCommitLocal(submoduleRepoPath, baseSubmoduleRepoPath, commit) {
|
|
79232
|
-
if (!commit) return;
|
|
79233
|
-
try {
|
|
79234
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["cat-file", "-e", `${commit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79235
|
-
return;
|
|
79236
|
-
} catch {
|
|
79237
|
-
}
|
|
79238
|
-
try {
|
|
79239
|
-
if (!fs48.existsSync(submoduleRepoPath) || !fs48.existsSync(baseSubmoduleRepoPath)) return;
|
|
79240
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["-c", "protocol.file.allow=always", "fetch", "-q", baseSubmoduleRepoPath, "+refs/heads/*:refs/adhdev-refine-base/*"], {
|
|
79241
|
-
cwd: submoduleRepoPath,
|
|
79242
|
-
stdio: ["ignore", "ignore", "pipe"]
|
|
79243
|
-
});
|
|
79244
|
-
} catch {
|
|
79245
|
-
}
|
|
79246
|
-
}
|
|
79247
|
-
function convergeDivergedSubmoduleGitlinks(worktreeRoot, baseRepoRoot, baseHead, branchHead) {
|
|
79248
|
-
const changed = readChangedGitlinkPaths(worktreeRoot, baseHead, branchHead);
|
|
79249
|
-
if (changed.length === 0) {
|
|
79250
|
-
return { converged: false, reason: "no_changed_gitlinks", resolutions: [], gitlinks: [] };
|
|
79251
|
-
}
|
|
79252
|
-
const gitlinks = [];
|
|
79253
|
-
const resolutions = [];
|
|
79254
|
-
let sawDiverged = false;
|
|
79255
|
-
for (const path58 of changed) {
|
|
79256
|
-
const baseCommit = readTreeObject(baseRepoRoot, baseHead, path58);
|
|
79257
|
-
const branchCommit = readTreeObject(worktreeRoot, branchHead, path58);
|
|
79258
|
-
const submoduleRepoPath = (0, import_path17.resolve)(worktreeRoot, path58);
|
|
79259
|
-
if (baseCommit) {
|
|
79260
|
-
ensureSubmoduleCommitLocal(submoduleRepoPath, (0, import_path17.resolve)(baseRepoRoot, path58), baseCommit);
|
|
79261
|
-
}
|
|
79262
|
-
if (!baseCommit || !branchCommit || !isSubmoduleDivergedSibling(submoduleRepoPath, baseCommit, branchCommit)) {
|
|
79263
|
-
gitlinks.push({ path: path58, baseCommit, branchCommit, action: "skipped_not_diverged" });
|
|
79264
|
-
continue;
|
|
79265
|
-
}
|
|
79266
|
-
sawDiverged = true;
|
|
79267
|
-
try {
|
|
79268
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["-c", "protocol.file.allow=always", "fetch", "-q", "origin"], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
|
|
79269
|
-
} catch {
|
|
79270
|
-
}
|
|
79271
|
-
const remoteMainRef = resolveSubmoduleRemoteMainRef(submoduleRepoPath);
|
|
79272
|
-
const publishedEquivalent = remoteMainRef ? findEquivalentPublishedSubmoduleCommit(submoduleRepoPath, baseCommit, branchCommit, remoteMainRef) : void 0;
|
|
79273
|
-
if (publishedEquivalent) {
|
|
79274
|
-
try {
|
|
79275
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["checkout", "-q", "--detach", publishedEquivalent], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
|
|
79276
|
-
} catch {
|
|
79277
|
-
}
|
|
79278
|
-
gitlinks.push({ path: path58, baseCommit, branchCommit, rebasedCommit: publishedEquivalent, action: "converged_to_published" });
|
|
79279
|
-
resolutions.push({ path: path58, baseCommit, branchCommit, rebasedCommit: publishedEquivalent });
|
|
79280
|
-
continue;
|
|
79281
|
-
}
|
|
79282
|
-
let rebasedCommit;
|
|
79283
|
-
try {
|
|
79284
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["checkout", "-q", "--detach", branchCommit], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
|
|
79285
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["rebase", baseCommit], { cwd: submoduleRepoPath, stdio: ["ignore", "pipe", "pipe"] });
|
|
79286
|
-
rebasedCommit = (0, import_node_child_process11.execFileSync)(GIT4, ["rev-parse", "HEAD"], { cwd: submoduleRepoPath, encoding: "utf8" }).trim();
|
|
79287
|
-
} catch {
|
|
79288
|
-
try {
|
|
79289
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["rebase", "--abort"], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79290
|
-
} catch {
|
|
79291
|
-
}
|
|
79292
|
-
try {
|
|
79293
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["checkout", "-q", "--detach", branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79294
|
-
} catch {
|
|
79295
|
-
}
|
|
79296
|
-
gitlinks.push({ path: path58, baseCommit, branchCommit, action: "rebase_conflict" });
|
|
79297
|
-
return { converged: false, reason: "rebase_conflict", resolutions: [], gitlinks };
|
|
79298
|
-
}
|
|
79299
|
-
const branchWorkSurvived = (() => {
|
|
79300
|
-
if (!rebasedCommit) return false;
|
|
79301
|
-
if (rebasedCommit === branchCommit) return true;
|
|
79302
|
-
if (rebasedCommit === baseCommit) return false;
|
|
79303
|
-
try {
|
|
79304
|
-
const replayed = (0, import_node_child_process11.execFileSync)(GIT4, ["rev-list", "--count", `${baseCommit}..${rebasedCommit}`], {
|
|
79305
|
-
cwd: submoduleRepoPath,
|
|
79306
|
-
encoding: "utf8"
|
|
79307
|
-
}).trim();
|
|
79308
|
-
return Number.parseInt(replayed, 10) > 0;
|
|
79309
|
-
} catch {
|
|
79310
|
-
return false;
|
|
79311
|
-
}
|
|
79312
|
-
})();
|
|
79313
|
-
if (!branchWorkSurvived) {
|
|
79314
|
-
try {
|
|
79315
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["checkout", "-q", "--detach", branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
79316
|
-
} catch {
|
|
79317
|
-
}
|
|
79318
|
-
gitlinks.push({ path: path58, baseCommit, branchCommit, rebasedCommit, action: "rebase_dropped_branch_commits" });
|
|
79319
|
-
return { converged: false, reason: "rebase_dropped_branch_commits", resolutions: [], gitlinks };
|
|
79320
|
-
}
|
|
79321
|
-
gitlinks.push({ path: path58, baseCommit, branchCommit, rebasedCommit, action: "rebased" });
|
|
79322
|
-
resolutions.push({ path: path58, baseCommit, branchCommit, rebasedCommit });
|
|
79323
|
-
}
|
|
79324
|
-
if (!sawDiverged) {
|
|
79325
|
-
return { converged: false, reason: "not_diverged", resolutions: [], gitlinks };
|
|
79326
|
-
}
|
|
79327
|
-
return { converged: resolutions.length > 0, resolutions, gitlinks };
|
|
79328
|
-
}
|
|
79329
|
-
function rootRebaseResolvingGitlinks(worktreeRoot, baseHead, resolutions) {
|
|
79330
|
-
const resolveByPath = new Map(resolutions.map((r) => [r.path, r.rebasedCommit]));
|
|
79331
|
-
const runRebase = (args) => {
|
|
79332
|
-
try {
|
|
79333
|
-
(0, import_node_child_process11.execFileSync)(GIT4, args, {
|
|
79334
|
-
cwd: worktreeRoot,
|
|
79335
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
79336
|
-
// A rebase editor prompt would hang; keep it non-interactive.
|
|
79337
|
-
env: { ...process.env, GIT_EDITOR: "true", GIT_SEQUENCE_EDITOR: "true" }
|
|
79338
|
-
});
|
|
79339
|
-
return { ok: true };
|
|
79340
|
-
} catch {
|
|
79341
|
-
return { ok: false };
|
|
79342
|
-
}
|
|
79343
|
-
};
|
|
79344
|
-
const unmergedPaths = () => {
|
|
79345
|
-
try {
|
|
79346
|
-
return (0, import_node_child_process11.execFileSync)(GIT4, ["diff", "--name-only", "--diff-filter=U"], { cwd: worktreeRoot, encoding: "utf8" }).split("\n").map((s2) => s2.trim()).filter(Boolean);
|
|
79347
|
-
} catch {
|
|
79348
|
-
return [];
|
|
79349
|
-
}
|
|
79350
|
-
};
|
|
79351
|
-
const abort = (reason, conflictPaths) => {
|
|
79352
|
-
try {
|
|
79353
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["rebase", "--abort"], { cwd: worktreeRoot, stdio: "ignore" });
|
|
79354
|
-
} catch {
|
|
79355
|
-
}
|
|
79356
|
-
return { ok: false, reason, conflictPaths };
|
|
79357
|
-
};
|
|
79358
|
-
let progress = runRebase(["rebase", baseHead]);
|
|
79359
|
-
let guard = 0;
|
|
79360
|
-
while (!progress.ok) {
|
|
79361
|
-
if (guard++ > 100) return abort("rebase_error");
|
|
79362
|
-
const conflicts = unmergedPaths();
|
|
79363
|
-
if (conflicts.length === 0) {
|
|
79364
|
-
return abort("rebase_error");
|
|
79365
|
-
}
|
|
79366
|
-
const unresolvable = conflicts.filter((p) => !resolveByPath.has(p));
|
|
79367
|
-
if (unresolvable.length > 0) {
|
|
79368
|
-
const unresolvableGitlink = unresolvable.some((p) => {
|
|
79369
|
-
try {
|
|
79370
|
-
const staged = (0, import_node_child_process11.execFileSync)(GIT4, ["ls-files", "--stage", "--", p], { cwd: worktreeRoot, encoding: "utf8" });
|
|
79371
|
-
return /^160000\s/m.test(staged);
|
|
79372
|
-
} catch {
|
|
79373
|
-
return false;
|
|
79374
|
-
}
|
|
79375
|
-
});
|
|
79376
|
-
const allGitlink = unresolvable.every((p) => {
|
|
79377
|
-
try {
|
|
79378
|
-
const staged = (0, import_node_child_process11.execFileSync)(GIT4, ["ls-files", "--stage", "--", p], { cwd: worktreeRoot, encoding: "utf8" });
|
|
79379
|
-
return /^160000\s/m.test(staged);
|
|
79380
|
-
} catch {
|
|
79381
|
-
return false;
|
|
79382
|
-
}
|
|
79383
|
-
});
|
|
79384
|
-
return abort(allGitlink && unresolvableGitlink ? "unexpected_gitlink" : "non_gitlink_conflict", conflicts);
|
|
79385
|
-
}
|
|
79386
|
-
for (const p of conflicts) {
|
|
79387
|
-
const commit = resolveByPath.get(p);
|
|
79388
|
-
try {
|
|
79389
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["checkout", "-q", "--detach", commit], { cwd: (0, import_path17.resolve)(worktreeRoot, p), stdio: "ignore" });
|
|
79390
|
-
} catch {
|
|
79391
|
-
}
|
|
79392
|
-
try {
|
|
79393
|
-
(0, import_node_child_process11.execFileSync)(GIT4, ["add", p], { cwd: worktreeRoot, stdio: "ignore" });
|
|
79394
|
-
} catch {
|
|
79395
|
-
return abort("rebase_error", conflicts);
|
|
79396
|
-
}
|
|
79397
|
-
}
|
|
79398
|
-
progress = runRebase(["rebase", "--continue"]);
|
|
79399
|
-
}
|
|
79400
|
-
let branchHead;
|
|
79401
|
-
try {
|
|
79402
|
-
branchHead = (0, import_node_child_process11.execFileSync)(GIT4, ["rev-parse", "HEAD"], { cwd: worktreeRoot, encoding: "utf8" }).trim();
|
|
79403
|
-
} catch {
|
|
79404
|
-
}
|
|
79405
|
-
return { ok: true, branchHead };
|
|
79406
|
-
}
|
|
79407
79977
|
function evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead) {
|
|
79408
79978
|
const changedGitlinks = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path58) => {
|
|
79409
79979
|
const baseCommit = readTreeObject(repoRoot, baseHead, path58);
|
|
79410
79980
|
const branchCommit = readTreeObject(repoRoot, branchHead, path58);
|
|
79411
|
-
const submoduleRepoPath = (0,
|
|
79981
|
+
const submoduleRepoPath = (0, import_path18.resolve)(repoRoot, path58);
|
|
79412
79982
|
const fastForward = !!baseCommit && !!branchCommit && isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit);
|
|
79413
79983
|
return { path: path58, baseCommit, branchCommit, fastForward };
|
|
79414
79984
|
});
|
|
@@ -79425,7 +79995,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79425
79995
|
}
|
|
79426
79996
|
let mergeBase = "";
|
|
79427
79997
|
try {
|
|
79428
|
-
mergeBase = (0,
|
|
79998
|
+
mergeBase = (0, import_node_child_process13.execFileSync)(GIT4, ["merge-base", baseHead, branchHead], {
|
|
79429
79999
|
cwd: repoRoot,
|
|
79430
80000
|
encoding: "utf8",
|
|
79431
80001
|
maxBuffer: 1024 * 1024
|
|
@@ -79455,7 +80025,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79455
80025
|
}
|
|
79456
80026
|
function buildTreeWithGitlinksEqualized(repoRoot, commitish, paths, placeholderCommit) {
|
|
79457
80027
|
try {
|
|
79458
|
-
const tree = (0,
|
|
80028
|
+
const tree = (0, import_node_child_process13.execFileSync)(GIT4, ["rev-parse", `${commitish}^{tree}`], {
|
|
79459
80029
|
cwd: repoRoot,
|
|
79460
80030
|
encoding: "utf8",
|
|
79461
80031
|
maxBuffer: 1024 * 1024
|
|
@@ -79463,11 +80033,11 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79463
80033
|
if (!tree) return void 0;
|
|
79464
80034
|
const updates = paths.map((path58) => `160000 commit ${placeholderCommit} ${path58}`).join("\n");
|
|
79465
80035
|
if (!updates) return tree;
|
|
79466
|
-
const tmpIndex = (0,
|
|
80036
|
+
const tmpIndex = (0, import_path18.join)(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
|
|
79467
80037
|
const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
79468
80038
|
try {
|
|
79469
|
-
(0,
|
|
79470
|
-
(0,
|
|
80039
|
+
(0, import_node_child_process13.execFileSync)(GIT4, ["read-tree", tree], { cwd: repoRoot, env: env2, stdio: "ignore" });
|
|
80040
|
+
(0, import_node_child_process13.execFileSync)(GIT4, ["update-index", "--index-info"], {
|
|
79471
80041
|
cwd: repoRoot,
|
|
79472
80042
|
env: env2,
|
|
79473
80043
|
input: `${updates}
|
|
@@ -79475,11 +80045,11 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79475
80045
|
encoding: "utf8",
|
|
79476
80046
|
stdio: ["pipe", "ignore", "ignore"]
|
|
79477
80047
|
});
|
|
79478
|
-
const newTree = (0,
|
|
80048
|
+
const newTree = (0, import_node_child_process13.execFileSync)(GIT4, ["write-tree"], { cwd: repoRoot, env: env2, encoding: "utf8" }).trim();
|
|
79479
80049
|
return newTree || void 0;
|
|
79480
80050
|
} finally {
|
|
79481
80051
|
try {
|
|
79482
|
-
|
|
80052
|
+
fs50.rmSync(tmpIndex, { force: true });
|
|
79483
80053
|
} catch {
|
|
79484
80054
|
}
|
|
79485
80055
|
}
|
|
@@ -79491,7 +80061,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79491
80061
|
try {
|
|
79492
80062
|
const branchGitlinks = gitlinks.filter((entry) => entry.branchCommit);
|
|
79493
80063
|
const gitlinkPaths = branchGitlinks.map((entry) => entry.path);
|
|
79494
|
-
const mergeBase = (0,
|
|
80064
|
+
const mergeBase = (0, import_node_child_process13.execFileSync)(GIT4, ["merge-base", baseHead, branchHead], {
|
|
79495
80065
|
cwd: repoRoot,
|
|
79496
80066
|
encoding: "utf8",
|
|
79497
80067
|
maxBuffer: 1024 * 1024
|
|
@@ -79504,22 +80074,22 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79504
80074
|
const theirsEqTree = buildTreeWithGitlinksEqualized(repoRoot, branchHead, gitlinkPaths, placeholder);
|
|
79505
80075
|
if (baseEqTree && oursEqTree && theirsEqTree) {
|
|
79506
80076
|
try {
|
|
79507
|
-
const baseEqCommit = (0,
|
|
80077
|
+
const baseEqCommit = (0, import_node_child_process13.execFileSync)(GIT4, ["commit-tree", baseEqTree, "-m", "refine-ff-base"], {
|
|
79508
80078
|
cwd: repoRoot,
|
|
79509
80079
|
encoding: "utf8",
|
|
79510
80080
|
maxBuffer: 1024 * 1024
|
|
79511
80081
|
}).trim();
|
|
79512
|
-
const oursEqCommit = (0,
|
|
80082
|
+
const oursEqCommit = (0, import_node_child_process13.execFileSync)(GIT4, ["commit-tree", oursEqTree, "-p", baseEqCommit, "-m", "refine-ff-ours"], {
|
|
79513
80083
|
cwd: repoRoot,
|
|
79514
80084
|
encoding: "utf8",
|
|
79515
80085
|
maxBuffer: 1024 * 1024
|
|
79516
80086
|
}).trim();
|
|
79517
|
-
const theirsEqCommit = (0,
|
|
80087
|
+
const theirsEqCommit = (0, import_node_child_process13.execFileSync)(GIT4, ["commit-tree", theirsEqTree, "-p", baseEqCommit, "-m", "refine-ff-theirs"], {
|
|
79518
80088
|
cwd: repoRoot,
|
|
79519
80089
|
encoding: "utf8",
|
|
79520
80090
|
maxBuffer: 1024 * 1024
|
|
79521
80091
|
}).trim();
|
|
79522
|
-
const mergeOut = (0,
|
|
80092
|
+
const mergeOut = (0, import_node_child_process13.execFileSync)(GIT4, ["merge-tree", "--write-tree", oursEqCommit, theirsEqCommit], {
|
|
79523
80093
|
cwd: repoRoot,
|
|
79524
80094
|
encoding: "utf8",
|
|
79525
80095
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
@@ -79530,7 +80100,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79530
80100
|
}
|
|
79531
80101
|
}
|
|
79532
80102
|
}
|
|
79533
|
-
const contentTree = mergedContentTree || (0,
|
|
80103
|
+
const contentTree = mergedContentTree || (0, import_node_child_process13.execFileSync)(GIT4, ["rev-parse", `${baseHead}^{tree}`], {
|
|
79534
80104
|
cwd: repoRoot,
|
|
79535
80105
|
encoding: "utf8",
|
|
79536
80106
|
maxBuffer: 1024 * 1024
|
|
@@ -79538,11 +80108,11 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79538
80108
|
if (!contentTree) return void 0;
|
|
79539
80109
|
const updates = branchGitlinks.map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
|
|
79540
80110
|
if (!updates) return contentTree;
|
|
79541
|
-
const tmpIndex = (0,
|
|
80111
|
+
const tmpIndex = (0, import_path18.join)(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
|
|
79542
80112
|
const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
79543
80113
|
try {
|
|
79544
|
-
(0,
|
|
79545
|
-
(0,
|
|
80114
|
+
(0, import_node_child_process13.execFileSync)(GIT4, ["read-tree", contentTree], { cwd: repoRoot, env: env2, stdio: "ignore" });
|
|
80115
|
+
(0, import_node_child_process13.execFileSync)(GIT4, ["update-index", "--index-info"], {
|
|
79546
80116
|
cwd: repoRoot,
|
|
79547
80117
|
env: env2,
|
|
79548
80118
|
input: `${updates}
|
|
@@ -79550,11 +80120,11 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79550
80120
|
encoding: "utf8",
|
|
79551
80121
|
stdio: ["pipe", "ignore", "ignore"]
|
|
79552
80122
|
});
|
|
79553
|
-
const newTree = (0,
|
|
80123
|
+
const newTree = (0, import_node_child_process13.execFileSync)(GIT4, ["write-tree"], { cwd: repoRoot, env: env2, encoding: "utf8" }).trim();
|
|
79554
80124
|
return newTree || void 0;
|
|
79555
80125
|
} finally {
|
|
79556
80126
|
try {
|
|
79557
|
-
|
|
80127
|
+
fs50.rmSync(tmpIndex, { force: true });
|
|
79558
80128
|
} catch {
|
|
79559
80129
|
}
|
|
79560
80130
|
}
|
|
@@ -79666,7 +80236,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79666
80236
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
79667
80237
|
};
|
|
79668
80238
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
79669
|
-
if (!
|
|
80239
|
+
if (!fs50.existsSync(worktreeSubmodulePath)) return false;
|
|
79670
80240
|
try {
|
|
79671
80241
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
79672
80242
|
} catch {
|
|
@@ -79695,7 +80265,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79695
80265
|
return match ? { commit: match[1], path: match[2] } : null;
|
|
79696
80266
|
}).filter((entry) => !!entry);
|
|
79697
80267
|
for (const gitlink of gitlinks) {
|
|
79698
|
-
const submodulePath = (0,
|
|
80268
|
+
const submodulePath = (0, import_path18.resolve)(repoRoot, gitlink.path);
|
|
79699
80269
|
const entry = {
|
|
79700
80270
|
path: gitlink.path,
|
|
79701
80271
|
commit: gitlink.commit,
|
|
@@ -79703,7 +80273,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79703
80273
|
};
|
|
79704
80274
|
let submoduleDefaultBranch = "main";
|
|
79705
80275
|
try {
|
|
79706
|
-
if (!
|
|
80276
|
+
if (!fs50.existsSync(submodulePath)) {
|
|
79707
80277
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
79708
80278
|
entry.publishRequired = true;
|
|
79709
80279
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -79722,7 +80292,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79722
80292
|
entry.localReachable = false;
|
|
79723
80293
|
if (options.allowAutoPublishSubmoduleMainCommits === true && options.worktreeRoot) {
|
|
79724
80294
|
try {
|
|
79725
|
-
const imported = await importCommitFromWorktreeSubmodule(submodulePath, (0,
|
|
80295
|
+
const imported = await importCommitFromWorktreeSubmodule(submodulePath, (0, import_path18.resolve)(options.worktreeRoot, gitlink.path), gitlink.commit);
|
|
79726
80296
|
if (imported) {
|
|
79727
80297
|
entry.localReachable = true;
|
|
79728
80298
|
entry.importedFromWorktree = true;
|
|
@@ -79952,13 +80522,13 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79952
80522
|
...extras
|
|
79953
80523
|
});
|
|
79954
80524
|
const isPackageManagerValidation = (candidate) => {
|
|
79955
|
-
const command = (0,
|
|
80525
|
+
const command = (0, import_path18.basename)(candidate.command).replace(/\.(?:cmd|exe)$/i, "");
|
|
79956
80526
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
79957
80527
|
};
|
|
79958
80528
|
const dependenciesLikelyMissing = (cwd) => {
|
|
79959
|
-
if (!
|
|
79960
|
-
if (
|
|
79961
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
80529
|
+
if (!fs50.existsSync((0, import_path18.join)(cwd, "package.json"))) return false;
|
|
80530
|
+
if (fs50.existsSync((0, import_path18.join)(cwd, "node_modules"))) return false;
|
|
80531
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs50.existsSync((0, import_path18.join)(cwd, lock)));
|
|
79962
80532
|
};
|
|
79963
80533
|
const needsNodeModules = (candidate, cwd) => isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd);
|
|
79964
80534
|
const isDaemonScopedCommand = (candidate) => {
|
|
@@ -80025,7 +80595,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
80025
80595
|
summary.bootstrap = { stage: "legacy" };
|
|
80026
80596
|
for (const candidate of selection.bootstrapCommands) {
|
|
80027
80597
|
const startedAt = Date.now();
|
|
80028
|
-
const cwd = candidate.cwd ? (0,
|
|
80598
|
+
const cwd = candidate.cwd ? (0, import_path18.resolve)(workspace, candidate.cwd) : workspace;
|
|
80029
80599
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
80030
80600
|
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
80031
80601
|
const spawn7 = buildWin32ExecFileSpawn(resolvedCommand, candidate.args);
|
|
@@ -80058,7 +80628,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
80058
80628
|
let missingDepsBlocked = false;
|
|
80059
80629
|
for (const candidate of commandsToRun) {
|
|
80060
80630
|
const startedAt = Date.now();
|
|
80061
|
-
const cwd = candidate.cwd ? (0,
|
|
80631
|
+
const cwd = candidate.cwd ? (0, import_path18.resolve)(workspace, candidate.cwd) : workspace;
|
|
80062
80632
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
80063
80633
|
const bootstrapProvidedDependencies = summary.bootstrap?.stage === "cached" || summary.bootstrap?.stage === "ran" || summary.bootstrap?.stage === "legacy";
|
|
80064
80634
|
if (!bootstrapProvidedDependencies && needsNodeModules(candidate, cwd)) {
|
|
@@ -80125,16 +80695,14 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
80125
80695
|
summary.status = "passed";
|
|
80126
80696
|
return summary;
|
|
80127
80697
|
}
|
|
80128
|
-
var
|
|
80129
|
-
var
|
|
80130
|
-
var
|
|
80131
|
-
var GIT4;
|
|
80698
|
+
var import_path18;
|
|
80699
|
+
var fs50;
|
|
80700
|
+
var import_node_child_process13;
|
|
80132
80701
|
var REFINE_VALIDATION_TIMEOUT_MS;
|
|
80133
80702
|
var REFINE_VALIDATION_OUTPUT_LIMIT_BYTES;
|
|
80134
80703
|
var REFINE_VALIDATION_SUMMARY_HEAD_CHARS;
|
|
80135
80704
|
var REFINE_VALIDATION_SUMMARY_TAIL_CHARS;
|
|
80136
80705
|
var REFINE_VALIDATION_SUMMARY_CHARS;
|
|
80137
|
-
var REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES;
|
|
80138
80706
|
var REFINE_VALIDATION_LOG_DIR;
|
|
80139
80707
|
var init_mesh_refine_gates = __esm2({
|
|
80140
80708
|
"src/mesh/mesh-refine-gates.ts"() {
|
|
@@ -80142,19 +80710,19 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
80142
80710
|
init_git_status();
|
|
80143
80711
|
init_refine_config();
|
|
80144
80712
|
init_worktree_bootstrap_config();
|
|
80145
|
-
|
|
80146
|
-
|
|
80147
|
-
|
|
80713
|
+
import_path18 = require("path");
|
|
80714
|
+
fs50 = __toESM2(require("fs"));
|
|
80715
|
+
import_node_child_process13 = require("child_process");
|
|
80148
80716
|
init_resolve_executable();
|
|
80149
80717
|
init_mesh_refine_worker_cap();
|
|
80150
|
-
|
|
80718
|
+
init_mesh_refine_gitlink_utils();
|
|
80719
|
+
init_mesh_refine_submodule_converge();
|
|
80151
80720
|
REFINE_VALIDATION_TIMEOUT_MS = 12e4;
|
|
80152
80721
|
REFINE_VALIDATION_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
80153
80722
|
REFINE_VALIDATION_SUMMARY_HEAD_CHARS = 2e3;
|
|
80154
80723
|
REFINE_VALIDATION_SUMMARY_TAIL_CHARS = 6e3;
|
|
80155
80724
|
REFINE_VALIDATION_SUMMARY_CHARS = REFINE_VALIDATION_SUMMARY_HEAD_CHARS + REFINE_VALIDATION_SUMMARY_TAIL_CHARS;
|
|
80156
|
-
|
|
80157
|
-
REFINE_VALIDATION_LOG_DIR = (0, import_path17.join)(".adhdev", "logs");
|
|
80725
|
+
REFINE_VALIDATION_LOG_DIR = (0, import_path18.join)(".adhdev", "logs");
|
|
80158
80726
|
}
|
|
80159
80727
|
});
|
|
80160
80728
|
function findOpenRefineDispatchForNode(args) {
|
|
@@ -80841,6 +81409,9 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
80841
81409
|
convergeReason: converge.reason,
|
|
80842
81410
|
gitlinks: converge.gitlinks
|
|
80843
81411
|
});
|
|
81412
|
+
if (converge.reason === "submodule_commit_unavailable") {
|
|
81413
|
+
LOG2.warn("Mesh", `[Refinery] Could NOT determine submodule gitlink divergence for node ${node.id} \u2014 a gitlink commit is missing from the local submodule object store (auto-converge could not run): ` + converge.gitlinks.filter((g) => g.action === "skipped_commit_unavailable").map((g) => `${g.path} (missing: ${(g.unavailable || []).join("+") || "unknown"}; base=${(g.baseCommit || "?").slice(0, 12)} branch=${(g.branchCommit || "?").slice(0, 12)})`).join(", "));
|
|
81414
|
+
}
|
|
80844
81415
|
recordMeshRefineStage(refineStages, "sync_base", "passed", syncStarted, {
|
|
80845
81416
|
ahead: divergence.ahead,
|
|
80846
81417
|
behind: divergence.behind,
|
|
@@ -80883,12 +81454,12 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
80883
81454
|
throw err;
|
|
80884
81455
|
}
|
|
80885
81456
|
} else {
|
|
80886
|
-
(0,
|
|
81457
|
+
(0, import_node_child_process14.execFileSync)("git", ["rebase", baseHead], { cwd: node.workspace, stdio: ["ignore", "pipe", "pipe"] });
|
|
80887
81458
|
}
|
|
80888
81459
|
} catch (rebaseErr) {
|
|
80889
81460
|
if (!rebaseErr?.alreadyAborted) {
|
|
80890
81461
|
try {
|
|
80891
|
-
(0,
|
|
81462
|
+
(0, import_node_child_process14.execFileSync)("git", ["rebase", "--abort"], { cwd: node.workspace, stdio: "ignore" });
|
|
80892
81463
|
} catch {
|
|
80893
81464
|
}
|
|
80894
81465
|
}
|
|
@@ -82342,7 +82913,7 @@ ${e?.stderr || ""}`;
|
|
|
82342
82913
|
if (!repoRoot || !workspace) return;
|
|
82343
82914
|
const branch = typeof node?.worktreeBranch === "string" && node.worktreeBranch.trim() ? node.worktreeBranch.trim() : (() => {
|
|
82344
82915
|
try {
|
|
82345
|
-
return (0,
|
|
82916
|
+
return (0, import_node_child_process14.execFileSync)("git", ["branch", "--show-current"], { cwd: workspace, encoding: "utf8" }).trim();
|
|
82346
82917
|
} catch {
|
|
82347
82918
|
return "";
|
|
82348
82919
|
}
|
|
@@ -82350,7 +82921,7 @@ ${e?.stderr || ""}`;
|
|
|
82350
82921
|
if (!branch) return;
|
|
82351
82922
|
const baseBranch = (() => {
|
|
82352
82923
|
try {
|
|
82353
|
-
return (0,
|
|
82924
|
+
return (0, import_node_child_process14.execFileSync)("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" }).trim() || "main";
|
|
82354
82925
|
} catch {
|
|
82355
82926
|
return "main";
|
|
82356
82927
|
}
|
|
@@ -82418,13 +82989,13 @@ ${e?.stderr || ""}`;
|
|
|
82418
82989
|
});
|
|
82419
82990
|
return handle;
|
|
82420
82991
|
}
|
|
82421
|
-
var
|
|
82992
|
+
var import_node_child_process14;
|
|
82422
82993
|
var import_node_fs9;
|
|
82423
82994
|
var RETRYABLE_BASE_MOVEMENT_CODES;
|
|
82424
82995
|
var init_router_refine = __esm2({
|
|
82425
82996
|
"src/commands/router-refine.ts"() {
|
|
82426
82997
|
"use strict";
|
|
82427
|
-
|
|
82998
|
+
import_node_child_process14 = require("child_process");
|
|
82428
82999
|
import_node_fs9 = require("fs");
|
|
82429
83000
|
init_logger();
|
|
82430
83001
|
init_debug_trace();
|
|
@@ -82466,6 +83037,7 @@ ${e?.stderr || ""}`;
|
|
|
82466
83037
|
CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES: () => CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES,
|
|
82467
83038
|
CHAT_MESSAGE_VISIBILITIES: () => CHAT_MESSAGE_VISIBILITIES,
|
|
82468
83039
|
COMPACT_STATUS_GOAL_PREVIEW_MAX: () => COMPACT_STATUS_GOAL_PREVIEW_MAX,
|
|
83040
|
+
CTRL_C: () => CTRL_C,
|
|
82469
83041
|
CdpDomHandlers: () => CdpDomHandlers,
|
|
82470
83042
|
CliProviderInstance: () => CliProviderInstance,
|
|
82471
83043
|
DAEMON_WS_PATH: () => DAEMON_WS_PATH2,
|
|
@@ -82475,6 +83047,7 @@ ${e?.stderr || ""}`;
|
|
|
82475
83047
|
DEFAULT_CHAT_TAIL_MISSING_SESSION_POLICY: () => DEFAULT_CHAT_TAIL_MISSING_SESSION_POLICY,
|
|
82476
83048
|
DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS: () => DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS2,
|
|
82477
83049
|
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT2,
|
|
83050
|
+
DEFAULT_DELIVERY_MODE: () => DEFAULT_DELIVERY_MODE,
|
|
82478
83051
|
DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS: () => DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
82479
83052
|
DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS2,
|
|
82480
83053
|
DEFAULT_MESH_POLICY: () => DEFAULT_MESH_POLICY,
|
|
@@ -82500,6 +83073,7 @@ ${e?.stderr || ""}`;
|
|
|
82500
83073
|
DaemonStatusReporter: () => DaemonStatusReporter,
|
|
82501
83074
|
DevServer: () => DevServer,
|
|
82502
83075
|
DuplicateMeshDispatchError: () => DuplicateMeshDispatchError,
|
|
83076
|
+
ESC: () => ESC,
|
|
82503
83077
|
FsmDriver: () => FsmDriver,
|
|
82504
83078
|
GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
|
|
82505
83079
|
GitCommandError: () => GitCommandError,
|
|
@@ -82554,6 +83128,10 @@ ${e?.stderr || ""}`;
|
|
|
82554
83128
|
OPERATING_NOTE_KIND: () => OPERATING_NOTE_KIND,
|
|
82555
83129
|
OPERATING_NOTE_TOMBSTONE_KIND: () => OPERATING_NOTE_TOMBSTONE_KIND,
|
|
82556
83130
|
P2pRelayFailureError: () => P2pRelayFailureError,
|
|
83131
|
+
PARKED_SKIP_REASON: () => PARKED_SKIP_REASON,
|
|
83132
|
+
PARKED_TASK_RETENTION_MS: () => PARKED_TASK_RETENTION_MS,
|
|
83133
|
+
PARK_REASON_PIN_EXPIRED: () => PARK_REASON_PIN_EXPIRED,
|
|
83134
|
+
PARK_RETENTION_EXPIRED_REASON: () => PARK_RETENTION_EXPIRED_REASON,
|
|
82557
83135
|
PROVIDER_CHANNEL_ENV_VAR: () => PROVIDER_CHANNEL_ENV_VAR,
|
|
82558
83136
|
PRUNABLE_ORPHAN_STALE_REASONS: () => PRUNABLE_ORPHAN_STALE_REASONS,
|
|
82559
83137
|
ProviderChannelError: () => ProviderChannelError,
|
|
@@ -82567,6 +83145,7 @@ ${e?.stderr || ""}`;
|
|
|
82567
83145
|
STALE_MAGI_WINDOW_MS: () => STALE_MAGI_WINDOW_MS,
|
|
82568
83146
|
STALE_TERMINAL_REFINE_WINDOW_MS: () => STALE_TERMINAL_REFINE_WINDOW_MS,
|
|
82569
83147
|
STANDALONE_CDP_SCAN_INTERVAL_MS: () => STANDALONE_CDP_SCAN_INTERVAL_MS2,
|
|
83148
|
+
STOP_CONTROL_ID: () => STOP_CONTROL_ID,
|
|
82570
83149
|
SYM: () => SYM,
|
|
82571
83150
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory2,
|
|
82572
83151
|
StatuslineInstallError: () => StatuslineInstallError2,
|
|
@@ -82617,6 +83196,7 @@ ${e?.stderr || ""}`;
|
|
|
82617
83196
|
buildMissionPromptSection: () => buildMissionPromptSection,
|
|
82618
83197
|
buildOrphanedPinNotice: () => buildOrphanedPinNotice,
|
|
82619
83198
|
buildP2pRelayFailurePayload: () => buildP2pRelayFailurePayload,
|
|
83199
|
+
buildParkedTaskNotice: () => buildParkedTaskNotice,
|
|
82620
83200
|
buildPinnedGlobalInstallCommand: () => buildPinnedGlobalInstallCommand,
|
|
82621
83201
|
buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
|
|
82622
83202
|
buildSessionEntries: () => buildSessionEntries,
|
|
@@ -82696,6 +83276,7 @@ ${e?.stderr || ""}`;
|
|
|
82696
83276
|
evaluateProviderQuotaGate: () => evaluateProviderQuotaGate,
|
|
82697
83277
|
execNpmCommandSync: () => execNpmCommandSync,
|
|
82698
83278
|
expandDaemonIdForms: () => expandDaemonIdForms,
|
|
83279
|
+
failRetentionExpiredParkedTask: () => failRetentionExpiredParkedTask,
|
|
82699
83280
|
fastForwardMeshNode: () => fastForwardMeshNode,
|
|
82700
83281
|
fetchAntigravityQuota: () => fetchAntigravityQuota2,
|
|
82701
83282
|
fetchClaudeQuota: () => fetchClaudeQuota2,
|
|
@@ -82748,6 +83329,7 @@ ${e?.stderr || ""}`;
|
|
|
82748
83329
|
getMeshStatusMissionSummaries: () => getMeshStatusMissionSummaries,
|
|
82749
83330
|
getMeshStatusMissionsCompact: () => getMeshStatusMissionsCompact,
|
|
82750
83331
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
83332
|
+
getParkedTasks: () => getParkedTasks,
|
|
82751
83333
|
getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
|
|
82752
83334
|
getProcessInstanceContext: () => getProcessInstanceContext,
|
|
82753
83335
|
getQueue: () => getQueue,
|
|
@@ -82847,6 +83429,7 @@ ${e?.stderr || ""}`;
|
|
|
82847
83429
|
normalizeChatMessageKind: () => normalizeChatMessageKind,
|
|
82848
83430
|
normalizeChatMessages: () => normalizeChatMessages,
|
|
82849
83431
|
normalizeChatTailActiveModal: () => normalizeChatTailActiveModal,
|
|
83432
|
+
normalizeDeliveryMode: () => normalizeDeliveryMode,
|
|
82850
83433
|
normalizeGitOutput: () => normalizeGitOutput,
|
|
82851
83434
|
normalizeGitWorkspaceSubscriptionParams: () => normalizeGitWorkspaceSubscriptionParams2,
|
|
82852
83435
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
@@ -82867,7 +83450,11 @@ ${e?.stderr || ""}`;
|
|
|
82867
83450
|
normalizeRepoMeshDeclarativeConfig: () => normalizeRepoMeshDeclarativeConfig,
|
|
82868
83451
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
82869
83452
|
notifyCoordinatorOfOrphanedPins: () => notifyCoordinatorOfOrphanedPins,
|
|
83453
|
+
notifyCoordinatorOfParkedTaskDropped: () => notifyCoordinatorOfParkedTaskDropped,
|
|
82870
83454
|
otherTrackConfigDir: () => otherTrackConfigDir,
|
|
83455
|
+
parkTaskTargetPin: () => parkTaskTargetPin,
|
|
83456
|
+
parkedAgeMs: () => parkedAgeMs,
|
|
83457
|
+
parkedTaskRetentionExpired: () => parkedTaskRetentionExpired,
|
|
82871
83458
|
parseOnDependencyFailurePolicy: () => parseOnDependencyFailurePolicy,
|
|
82872
83459
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
82873
83460
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
@@ -82951,6 +83538,7 @@ ${e?.stderr || ""}`;
|
|
|
82951
83538
|
resolveGitRepository: () => resolveGitRepository,
|
|
82952
83539
|
resolveInstanceContext: () => resolveInstanceContext,
|
|
82953
83540
|
resolveInstanceDir: () => resolveInstanceDir,
|
|
83541
|
+
resolveInterruptCapability: () => resolveInterruptCapability,
|
|
82954
83542
|
resolveMagiSessionCleanupMode: () => resolveMagiSessionCleanupMode,
|
|
82955
83543
|
resolveMaxParallelTasks: () => resolveMaxParallelTasks,
|
|
82956
83544
|
resolveMeshHostStatus: () => resolveMeshHostStatus,
|
|
@@ -83008,6 +83596,7 @@ ${e?.stderr || ""}`;
|
|
|
83008
83596
|
supportsUnicodeSymbols: () => supportsUnicodeSymbols,
|
|
83009
83597
|
sweepMeshGraphGateTimeouts: () => sweepMeshGraphGateTimeouts,
|
|
83010
83598
|
taskDependenciesSatisfied: () => taskDependenciesSatisfied,
|
|
83599
|
+
taskIsParked: () => taskIsParked,
|
|
83011
83600
|
tombstoneOperatingNote: () => tombstoneOperatingNote,
|
|
83012
83601
|
totalTokens: () => totalTokens,
|
|
83013
83602
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
@@ -85505,6 +86094,8 @@ ${e?.stderr || ""}`;
|
|
|
85505
86094
|
};
|
|
85506
86095
|
}
|
|
85507
86096
|
init_mesh_work_queue();
|
|
86097
|
+
init_mesh_work_queue();
|
|
86098
|
+
init_mesh_task_parking();
|
|
85508
86099
|
init_mesh_graph_derived_failure();
|
|
85509
86100
|
init_mesh_graph_workspace_saga();
|
|
85510
86101
|
init_mesh_graph_workspace_safety();
|
|
@@ -86104,6 +86695,12 @@ ${e?.stderr || ""}`;
|
|
|
86104
86695
|
workspaceRef: ws.workspaceRef,
|
|
86105
86696
|
detail: `Workspace '${ws.workspaceRef}' needs manual compensation: ${ws.lastError ?? "compensation refused"}.`
|
|
86106
86697
|
});
|
|
86698
|
+
} else if (ws.sagaState === "declared" && !ws.baseRevision) {
|
|
86699
|
+
actions.push({
|
|
86700
|
+
kind: "workspace_declared_no_base",
|
|
86701
|
+
workspaceRef: ws.workspaceRef,
|
|
86702
|
+
detail: `Workspace '${ws.workspaceRef}' is stuck in 'declared': no base_revision was given and none could be derived from ${ws.sourceNodeId ? `source node '${ws.sourceNodeId}' (its repo is unreachable on this daemon, or git could not resolve its HEAD)` : "a source node, because the declaration named none"}. The workspace will never clone and every task bound to it stays blocked. Re-declare the workspace with an explicit base_revision (e.g. 'main')${ws.sourceNodeId ? "" : " and a source_node_id"}.`
|
|
86703
|
+
});
|
|
86107
86704
|
}
|
|
86108
86705
|
}
|
|
86109
86706
|
return {
|
|
@@ -86270,6 +86867,47 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
86270
86867
|
init_contracts();
|
|
86271
86868
|
init_mesh_events_utils();
|
|
86272
86869
|
init_mesh_delivery_policy();
|
|
86870
|
+
var CTRL_C = "";
|
|
86871
|
+
var ESC = "\x1B";
|
|
86872
|
+
var STOP_CONTROL_ID = "stop";
|
|
86873
|
+
var LIVE_VERIFIED_PROVIDERS = /* @__PURE__ */ new Set(["claude-cli"]);
|
|
86874
|
+
function nameForKeys(keys) {
|
|
86875
|
+
if (keys === CTRL_C) return "Ctrl-C";
|
|
86876
|
+
if (keys === ESC) return "ESC";
|
|
86877
|
+
return "custom";
|
|
86878
|
+
}
|
|
86879
|
+
function resolveInterruptCapability(providerType, controlBar) {
|
|
86880
|
+
const stop = (controlBar ?? []).find((c) => c.id === STOP_CONTROL_ID);
|
|
86881
|
+
if (!stop) {
|
|
86882
|
+
return {
|
|
86883
|
+
supported: false,
|
|
86884
|
+
reason: "no_stop_control",
|
|
86885
|
+
message: `Provider '${providerType}' declares no '${STOP_CONTROL_ID}' control, so a running turn cannot be interrupted. Dispatch with delivery mode when_idle and the task will be delivered once the session finishes on its own.`
|
|
86886
|
+
};
|
|
86887
|
+
}
|
|
86888
|
+
if (stop.action?.type !== "send_keys") {
|
|
86889
|
+
return {
|
|
86890
|
+
supported: false,
|
|
86891
|
+
reason: "stop_control_not_send_keys",
|
|
86892
|
+
message: `Provider '${providerType}' declares a '${STOP_CONTROL_ID}' control of type '${stop.action?.type}', not a key write, so it cannot be used to abort a turn. Dispatch with delivery mode when_idle instead.`
|
|
86893
|
+
};
|
|
86894
|
+
}
|
|
86895
|
+
const keys = stop.action.keys;
|
|
86896
|
+
if (typeof keys !== "string" || keys.length === 0) {
|
|
86897
|
+
return {
|
|
86898
|
+
supported: false,
|
|
86899
|
+
reason: "stop_keys_empty",
|
|
86900
|
+
message: `Provider '${providerType}' declares a '${STOP_CONTROL_ID}' control with an EMPTY key sequence, so pressing it would write nothing to the terminal while still reporting success. Treating this as unsupported rather than silently doing nothing. Dispatch with delivery mode when_idle, or fix the provider spec to declare a real stop key.`
|
|
86901
|
+
};
|
|
86902
|
+
}
|
|
86903
|
+
return {
|
|
86904
|
+
supported: true,
|
|
86905
|
+
keys,
|
|
86906
|
+
keyName: nameForKeys(keys),
|
|
86907
|
+
confidence: LIVE_VERIFIED_PROVIDERS.has(providerType) ? "proven" : "declared",
|
|
86908
|
+
...stop.visible_when_state ? { visibleWhenState: stop.visible_when_state } : {}
|
|
86909
|
+
};
|
|
86910
|
+
}
|
|
86273
86911
|
var NO_FALLBACK_REASON = "This mesh operation needs a live peer-to-peer connection to the node, which is not open right now. This is often transient \u2014 the peer may be connecting, slow via TURN relay, or briefly offline. Wait a moment and retry, or re-establish the node's connection. Mesh commands use P2P only by design \u2014 there is no cloud/WS relay fallback.";
|
|
86274
86912
|
var P2P_NEXT_ACTION = "The peer connection is recoverable. Wait a moment for the connection to establish (especially over TURN relay), then retry. If the node remains unreachable, check that the target daemon is running and online, then re-establish its connection.";
|
|
86275
86913
|
var NON_P2P_NEXT_ACTION = "Inspect the provider/command error and fix the underlying logic or configuration before retrying.";
|
|
@@ -94681,7 +95319,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
94681
95319
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
94682
95320
|
return { success: false, error: `unknown category: ${category}` };
|
|
94683
95321
|
}
|
|
94684
|
-
const
|
|
95322
|
+
const fs61 = require("fs");
|
|
94685
95323
|
const path58 = require("path");
|
|
94686
95324
|
try {
|
|
94687
95325
|
const installRoot = this.getUpstreamInstallRoot();
|
|
@@ -94690,10 +95328,10 @@ ${effect.notification.body || ""}`.trim();
|
|
|
94690
95328
|
if (!targetDir.startsWith(installRootResolved + path58.sep)) {
|
|
94691
95329
|
return { success: false, error: "refusing to delete outside upstream root" };
|
|
94692
95330
|
}
|
|
94693
|
-
if (!
|
|
95331
|
+
if (!fs61.existsSync(targetDir)) {
|
|
94694
95332
|
return { success: false, error: "not installed" };
|
|
94695
95333
|
}
|
|
94696
|
-
|
|
95334
|
+
fs61.rmSync(targetDir, { recursive: true, force: true });
|
|
94697
95335
|
try {
|
|
94698
95336
|
this._ctx.providerLoader?.deactivateVerifiedChannel?.(type2);
|
|
94699
95337
|
} catch {
|
|
@@ -94713,28 +95351,28 @@ ${effect.notification.body || ""}`.trim();
|
|
|
94713
95351
|
* the UI and by the update checker.
|
|
94714
95352
|
*/
|
|
94715
95353
|
handleListInstalledProviders(_args) {
|
|
94716
|
-
const
|
|
95354
|
+
const fs61 = require("fs");
|
|
94717
95355
|
const path58 = require("path");
|
|
94718
95356
|
const installRoot = this.getUpstreamInstallRoot();
|
|
94719
|
-
if (!
|
|
95357
|
+
if (!fs61.existsSync(installRoot)) return { success: true, providers: [] };
|
|
94720
95358
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
94721
95359
|
const items = [];
|
|
94722
95360
|
for (const category of CATEGORIES) {
|
|
94723
95361
|
const categoryDir = path58.join(installRoot, category);
|
|
94724
|
-
if (!
|
|
95362
|
+
if (!fs61.existsSync(categoryDir)) continue;
|
|
94725
95363
|
let entries;
|
|
94726
95364
|
try {
|
|
94727
|
-
entries =
|
|
95365
|
+
entries = fs61.readdirSync(categoryDir);
|
|
94728
95366
|
} catch {
|
|
94729
95367
|
continue;
|
|
94730
95368
|
}
|
|
94731
95369
|
for (const type2 of entries) {
|
|
94732
95370
|
const v1Path = path58.join(categoryDir, type2, "provider.v1.json");
|
|
94733
95371
|
const v0Path = path58.join(categoryDir, type2, "provider.json");
|
|
94734
|
-
const manifestPath =
|
|
95372
|
+
const manifestPath = fs61.existsSync(v1Path) ? v1Path : fs61.existsSync(v0Path) ? v0Path : null;
|
|
94735
95373
|
if (!manifestPath) continue;
|
|
94736
95374
|
try {
|
|
94737
|
-
const m = JSON.parse(
|
|
95375
|
+
const m = JSON.parse(fs61.readFileSync(manifestPath, "utf-8"));
|
|
94738
95376
|
const modelOptions = Array.isArray(m.modelOptions) ? m.modelOptions.filter((x) => typeof x === "string" && !!x.trim()) : [];
|
|
94739
95377
|
const thinkingLevelOptions = Array.isArray(m.thinkingLevelOptions) ? m.thinkingLevelOptions.filter((x) => typeof x === "string" && !!x.trim()) : [];
|
|
94740
95378
|
items.push({
|
|
@@ -94955,7 +95593,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
94955
95593
|
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
94956
95594
|
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
94957
95595
|
}
|
|
94958
|
-
const
|
|
95596
|
+
const fs61 = require("fs");
|
|
94959
95597
|
const path58 = require("path");
|
|
94960
95598
|
const { spawnSync: spawnSync3 } = require("child_process");
|
|
94961
95599
|
const file2 = ext.loadExternalSources();
|
|
@@ -94966,8 +95604,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
94966
95604
|
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
94967
95605
|
}
|
|
94968
95606
|
const sourceDir = path58.join(ext.externalRoot(), requestedName);
|
|
94969
|
-
if (!
|
|
94970
|
-
if (
|
|
95607
|
+
if (!fs61.existsSync(ext.externalRoot())) fs61.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
95608
|
+
if (fs61.existsSync(sourceDir)) {
|
|
94971
95609
|
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
94972
95610
|
}
|
|
94973
95611
|
const clone2 = spawnSync3("git", ["clone", "--depth=1", "--branch", ref, "--", url2, sourceDir], {
|
|
@@ -94977,7 +95615,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
94977
95615
|
});
|
|
94978
95616
|
if (clone2.status !== 0) {
|
|
94979
95617
|
try {
|
|
94980
|
-
|
|
95618
|
+
fs61.rmSync(sourceDir, { recursive: true, force: true });
|
|
94981
95619
|
} catch {
|
|
94982
95620
|
}
|
|
94983
95621
|
return { success: false, error: `git clone failed: ${(clone2.stderr || clone2.stdout || "").trim() || "unknown error"}` };
|
|
@@ -95021,15 +95659,15 @@ ${effect.notification.body || ""}`.trim();
|
|
|
95021
95659
|
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
95022
95660
|
if (!name) return { success: false, error: "name is required" };
|
|
95023
95661
|
const ext = (init_external_sources(), __toCommonJS2(external_sources_exports));
|
|
95024
|
-
const
|
|
95662
|
+
const fs61 = require("fs");
|
|
95025
95663
|
const path58 = require("path");
|
|
95026
95664
|
const file2 = ext.loadExternalSources();
|
|
95027
95665
|
const match = file2.sources.find((s2) => s2.name === name);
|
|
95028
95666
|
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
95029
95667
|
const sourceDir = path58.join(ext.externalRoot(), name);
|
|
95030
|
-
if (
|
|
95668
|
+
if (fs61.existsSync(sourceDir)) {
|
|
95031
95669
|
try {
|
|
95032
|
-
|
|
95670
|
+
fs61.rmSync(sourceDir, { recursive: true, force: true });
|
|
95033
95671
|
} catch (e) {
|
|
95034
95672
|
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
95035
95673
|
}
|
|
@@ -97356,14 +97994,14 @@ ${marker}`,
|
|
|
97356
97994
|
}
|
|
97357
97995
|
},
|
|
97358
97996
|
list_coordinator_prompts: async (_ctx, _args) => {
|
|
97359
|
-
const
|
|
97997
|
+
const fs61 = await import("fs");
|
|
97360
97998
|
const path58 = await import("path");
|
|
97361
97999
|
const { getConfigDir: getConfigDir22 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
97362
98000
|
const dir = path58.join(getConfigDir22(), "coordinator-prompts");
|
|
97363
98001
|
const entries = {};
|
|
97364
98002
|
try {
|
|
97365
|
-
if (
|
|
97366
|
-
for (const name of
|
|
98003
|
+
if (fs61.existsSync(dir)) {
|
|
98004
|
+
for (const name of fs61.readdirSync(dir)) {
|
|
97367
98005
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
97368
98006
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
97369
98007
|
const m = matchAppend || matchOverride;
|
|
@@ -97373,7 +98011,7 @@ ${marker}`,
|
|
|
97373
98011
|
const full = path58.join(dir, name);
|
|
97374
98012
|
let content = "";
|
|
97375
98013
|
try {
|
|
97376
|
-
content =
|
|
98014
|
+
content = fs61.readFileSync(full, "utf8");
|
|
97377
98015
|
} catch {
|
|
97378
98016
|
}
|
|
97379
98017
|
if (!entries[key2]) entries[key2] = { override: "", append: "" };
|
|
@@ -97387,7 +98025,7 @@ ${marker}`,
|
|
|
97387
98025
|
return { success: true, dir, entries };
|
|
97388
98026
|
},
|
|
97389
98027
|
write_coordinator_prompt: async (_ctx, args) => {
|
|
97390
|
-
const
|
|
98028
|
+
const fs61 = await import("fs");
|
|
97391
98029
|
const path58 = await import("path");
|
|
97392
98030
|
const { getConfigDir: getConfigDir22 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
97393
98031
|
const key2 = typeof args?.key === "string" ? args.key.trim() : "";
|
|
@@ -97400,11 +98038,11 @@ ${marker}`,
|
|
|
97400
98038
|
const filename = kind === "append" ? `${key2}.append.md` : `${key2}.md`;
|
|
97401
98039
|
const full = path58.join(dir, filename);
|
|
97402
98040
|
try {
|
|
97403
|
-
|
|
98041
|
+
fs61.mkdirSync(dir, { recursive: true });
|
|
97404
98042
|
if (content.trim()) {
|
|
97405
|
-
|
|
97406
|
-
} else if (
|
|
97407
|
-
|
|
98043
|
+
fs61.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
98044
|
+
} else if (fs61.existsSync(full)) {
|
|
98045
|
+
fs61.unlinkSync(full);
|
|
97408
98046
|
}
|
|
97409
98047
|
return { success: true, path: full, kind, key: key2 };
|
|
97410
98048
|
} catch (error48) {
|
|
@@ -102077,6 +102715,52 @@ ${marker}`,
|
|
|
102077
102715
|
hash: hash2
|
|
102078
102716
|
};
|
|
102079
102717
|
}
|
|
102718
|
+
/**
|
|
102719
|
+
* Report whether this provider can have its in-flight turn interrupted,
|
|
102720
|
+
* resolved from the spec THIS session actually loaded (never a hardcoded
|
|
102721
|
+
* per-provider table — the stop key varies by spec version; hermes-cli
|
|
102722
|
+
* ships Ctrl-C in specs/0.14.json and an EMPTY key in specs/4.0.json).
|
|
102723
|
+
*/
|
|
102724
|
+
getInterruptCapability() {
|
|
102725
|
+
return resolveInterruptCapability(this.cliType, this.spec.control_bar);
|
|
102726
|
+
}
|
|
102727
|
+
/**
|
|
102728
|
+
* Abort the turn currently in flight by writing the provider's own stop
|
|
102729
|
+
* key to the PTY. Used by delivery mode 'interrupt': the caller then waits
|
|
102730
|
+
* for the FSM to report idle and lets the ordinary queued-send drain
|
|
102731
|
+
* deliver the new prompt as a genuine new turn.
|
|
102732
|
+
*
|
|
102733
|
+
* ★ Deliberately NOT routed through invokeScript('stop'). That path calls
|
|
102734
|
+
* FsmDriver.handleClickControl, which silently returns when the control's
|
|
102735
|
+
* `visible_when_state` does not include the current state, and calls
|
|
102736
|
+
* send_keys("") for a provider whose stop key is empty — while
|
|
102737
|
+
* invokeScript unconditionally returns `{ ok: true, effects:[sent_keys] }`
|
|
102738
|
+
* either way. Reporting a successful interrupt that wrote nothing is
|
|
102739
|
+
* exactly the failure this feature exists to remove, so capability is
|
|
102740
|
+
* validated HERE, before any write, and the outcome is reported honestly.
|
|
102741
|
+
*/
|
|
102742
|
+
async interruptTurn() {
|
|
102743
|
+
if (!this.spawned || this.exited) {
|
|
102744
|
+
return { ok: false, reason: "not_running", message: `${this.cliName} is not running.` };
|
|
102745
|
+
}
|
|
102746
|
+
const cap = this.getInterruptCapability();
|
|
102747
|
+
if (!cap.supported) {
|
|
102748
|
+
LOG2.warn("SpecAdapter", `[${this.cliType}] interrupt refused: ${cap.reason}`);
|
|
102749
|
+
return { ok: false, reason: cap.reason, message: cap.message };
|
|
102750
|
+
}
|
|
102751
|
+
const status = this.latestState?.status;
|
|
102752
|
+
if (status !== "generating") {
|
|
102753
|
+
return {
|
|
102754
|
+
ok: false,
|
|
102755
|
+
reason: "not_busy",
|
|
102756
|
+
message: `Session is '${status ?? "unknown"}', not generating \u2014 nothing to interrupt.`
|
|
102757
|
+
};
|
|
102758
|
+
}
|
|
102759
|
+
this.driver.dispatch({ kind: "pty_write", data: cap.keys });
|
|
102760
|
+
const bytes = Buffer.byteLength(cap.keys, "utf8");
|
|
102761
|
+
LOG2.info("SpecAdapter", `[${this.cliType}] turn interrupted via ${cap.keyName} (bytes=${bytes}, confidence=${cap.confidence})`);
|
|
102762
|
+
return { ok: true, keyName: cap.keyName, bytes, confidence: cap.confidence };
|
|
102763
|
+
}
|
|
102080
102764
|
/**
|
|
102081
102765
|
* MESH-SEND-KEYS (feature 3: key injection). Inject a STRUCTURED key
|
|
102082
102766
|
* sequence into the spec-driven PTY for mesh_send_keys. Mirrors
|
|
@@ -110692,6 +111376,39 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
110692
111376
|
} else if (action === "stop") {
|
|
110693
111377
|
await this.stopSession(key2);
|
|
110694
111378
|
return { success: true, stopped: true };
|
|
111379
|
+
} else if (action === "interrupt_capability") {
|
|
111380
|
+
const probe = adapter;
|
|
111381
|
+
if (typeof probe.getInterruptCapability !== "function") {
|
|
111382
|
+
return {
|
|
111383
|
+
success: true,
|
|
111384
|
+
supported: false,
|
|
111385
|
+
reason: "interrupt_not_implemented",
|
|
111386
|
+
message: `Provider '${agentType}' runs on an adapter with no interrupt support.`
|
|
111387
|
+
};
|
|
111388
|
+
}
|
|
111389
|
+
const cap = probe.getInterruptCapability();
|
|
111390
|
+
return { success: true, ...cap };
|
|
111391
|
+
} else if (action === "interrupt_turn") {
|
|
111392
|
+
const interruptible = adapter;
|
|
111393
|
+
if (typeof interruptible.interruptTurn !== "function") {
|
|
111394
|
+
return {
|
|
111395
|
+
success: false,
|
|
111396
|
+
interrupted: false,
|
|
111397
|
+
reason: "interrupt_not_implemented",
|
|
111398
|
+
error: `Provider '${agentType}' runs on an adapter that cannot interrupt a turn.`
|
|
111399
|
+
};
|
|
111400
|
+
}
|
|
111401
|
+
const outcome = await interruptible.interruptTurn();
|
|
111402
|
+
if (!outcome.ok) {
|
|
111403
|
+
return { success: false, interrupted: false, reason: outcome.reason, error: outcome.message };
|
|
111404
|
+
}
|
|
111405
|
+
return {
|
|
111406
|
+
success: true,
|
|
111407
|
+
interrupted: true,
|
|
111408
|
+
keyName: outcome.keyName,
|
|
111409
|
+
bytes: outcome.bytes,
|
|
111410
|
+
confidence: outcome.confidence
|
|
111411
|
+
};
|
|
110695
111412
|
}
|
|
110696
111413
|
throw new Error(`Unknown action: ${action}`);
|
|
110697
111414
|
}
|
|
@@ -110854,7 +111571,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
110854
111571
|
const { shouldDeferDispatchForBootstrap: shouldDeferDispatchForBootstrap2 } = await Promise.resolve().then(() => (init_worktree_bootstrap_config(), worktree_bootstrap_config_exports));
|
|
110855
111572
|
if (shouldDeferDispatchForBootstrap2(nodeObj)) {
|
|
110856
111573
|
const dispatchSessionState = dispatchSessionId ? ctx.deps.instanceManager?.getInstance?.(dispatchSessionId)?.getState?.() : void 0;
|
|
110857
|
-
const sessionConfirmedReady = !!dispatchSessionState &&
|
|
111574
|
+
const sessionConfirmedReady = !!dispatchSessionState && isIdleSessionState3(dispatchSessionState);
|
|
110858
111575
|
if (!sessionConfirmedReady) {
|
|
110859
111576
|
return {
|
|
110860
111577
|
success: false,
|
|
@@ -115553,7 +116270,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
115553
116270
|
}
|
|
115554
116271
|
if (providerDir) {
|
|
115555
116272
|
try {
|
|
115556
|
-
const
|
|
116273
|
+
const fs61 = require("fs");
|
|
115557
116274
|
const path58 = require("path");
|
|
115558
116275
|
const candidates = [];
|
|
115559
116276
|
if (Array.isArray(base.compatibility)) {
|
|
@@ -115565,13 +116282,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
115565
116282
|
}
|
|
115566
116283
|
candidates.push(path58.join(providerDir, "specs", "default.json"));
|
|
115567
116284
|
candidates.push(path58.join(providerDir, "spec.json"));
|
|
115568
|
-
const specPath = candidates.find((p) =>
|
|
116285
|
+
const specPath = candidates.find((p) => fs61.existsSync(p));
|
|
115569
116286
|
let nh;
|
|
115570
116287
|
if (specPath) {
|
|
115571
116288
|
resolved._resolvedSpecPath = specPath;
|
|
115572
116289
|
let specControls;
|
|
115573
116290
|
try {
|
|
115574
|
-
const rawSpec = JSON.parse(
|
|
116291
|
+
const rawSpec = JSON.parse(fs61.readFileSync(specPath, "utf8"));
|
|
115575
116292
|
specControls = rawSpec.control_bar;
|
|
115576
116293
|
nh = rawSpec.native_history;
|
|
115577
116294
|
} catch {
|
|
@@ -115614,7 +116331,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
115614
116331
|
}
|
|
115615
116332
|
} else if (nh.override_path) {
|
|
115616
116333
|
const overrideFile = path58.resolve(providerDir, nh.override_path);
|
|
115617
|
-
if (
|
|
116334
|
+
if (fs61.existsSync(overrideFile)) {
|
|
115618
116335
|
try {
|
|
115619
116336
|
registerProviderScriptRootSafely(path58.dirname(path58.dirname(providerDir)));
|
|
115620
116337
|
delete require.cache[require.resolve(overrideFile)];
|
|
@@ -116531,7 +117248,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
116531
117248
|
}
|
|
116532
117249
|
} else if (plat === "win32") {
|
|
116533
117250
|
try {
|
|
116534
|
-
const
|
|
117251
|
+
const fs61 = require("fs");
|
|
116535
117252
|
const appNameMap = getMacAppIdentifiers();
|
|
116536
117253
|
const appName = appNameMap[ideId];
|
|
116537
117254
|
if (appName) {
|
|
@@ -116540,8 +117257,8 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
116540
117257
|
appName,
|
|
116541
117258
|
"storage.json"
|
|
116542
117259
|
);
|
|
116543
|
-
if (
|
|
116544
|
-
const data = JSON.parse(
|
|
117260
|
+
if (fs61.existsSync(storagePath)) {
|
|
117261
|
+
const data = JSON.parse(fs61.readFileSync(storagePath, "utf-8"));
|
|
116545
117262
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
116546
117263
|
if (workspaces.length > 0) {
|
|
116547
117264
|
const recent = workspaces[0];
|
|
@@ -117231,7 +117948,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
117231
117948
|
normalizeRepoMeshDeclarativeConfig: normalizeRepoMeshDeclarativeConfig2,
|
|
117232
117949
|
MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
|
|
117233
117950
|
} = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
|
|
117234
|
-
const { existsSync:
|
|
117951
|
+
const { existsSync: existsSync69, readFileSync: readFileSync55, mkdirSync: mkdirSync31, writeFileSync: writeFileSync31 } = await import("fs");
|
|
117235
117952
|
const { dirname: dirname24, join: join67 } = await import("path");
|
|
117236
117953
|
const yaml6 = await Promise.resolve().then(() => (init_js_yaml(), js_yaml_exports));
|
|
117237
117954
|
const relativePath = MESH_JSON_CONFIG_LOCATIONS2[0];
|
|
@@ -117240,7 +117957,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
117240
117957
|
let existedAsYaml = false;
|
|
117241
117958
|
for (const relative8 of MESH_JSON_CONFIG_LOCATIONS2) {
|
|
117242
117959
|
const candidate = join67(workspace, relative8);
|
|
117243
|
-
if (!
|
|
117960
|
+
if (!existsSync69(candidate)) continue;
|
|
117244
117961
|
try {
|
|
117245
117962
|
const text = readFileSync55(candidate, "utf-8");
|
|
117246
117963
|
const parsed = /\.json$/i.test(candidate) ? JSON.parse(text) : yaml6.load(text);
|
|
@@ -118475,7 +119192,12 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
118475
119192
|
// CANON-IDENTITY: an in-flight (actively-generating) task is refused by
|
|
118476
119193
|
// default to avoid a duplicate second dispatch; an explicit operator
|
|
118477
119194
|
// force overrides that guard (and the retry cap).
|
|
118478
|
-
force: args?.force === true
|
|
119195
|
+
force: args?.force === true,
|
|
119196
|
+
// PIN-PARKING (edit): optional instruction rewrite, so a coordinator in
|
|
119197
|
+
// IPC/cloud mode has the same exit from parking as the in-process path.
|
|
119198
|
+
// Without this the field would be silently dropped exactly where the
|
|
119199
|
+
// multi-coordinator topology needs it most.
|
|
119200
|
+
message: typeof args?.message === "string" ? args.message : void 0
|
|
118479
119201
|
});
|
|
118480
119202
|
if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
|
|
118481
119203
|
if (task.status === "assigned" && args?.force !== true) {
|
|
@@ -119549,7 +120271,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
119549
120271
|
workspace
|
|
119550
120272
|
};
|
|
119551
120273
|
}
|
|
119552
|
-
const { existsSync:
|
|
120274
|
+
const { existsSync: existsSync69, readFileSync: readFileSync55, writeFileSync: writeFileSync31, copyFileSync: copyFileSync3, mkdirSync: mkdirSync31 } = await import("fs");
|
|
119553
120275
|
const { dirname: dirname24 } = await import("path");
|
|
119554
120276
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
119555
120277
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -119594,7 +120316,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
119594
120316
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
119595
120317
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
119596
120318
|
}
|
|
119597
|
-
const hadExistingMcpConfig =
|
|
120319
|
+
const hadExistingMcpConfig = existsSync69(mcpConfigPath);
|
|
119598
120320
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
119599
120321
|
if (hermesBaseConfig) {
|
|
119600
120322
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname24(mcpConfigPath));
|
|
@@ -120395,7 +121117,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120395
121117
|
const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
|
|
120396
121118
|
const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
120397
121119
|
const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
|
|
120398
|
-
const { existsSync:
|
|
121120
|
+
const { existsSync: existsSync69 } = await import("fs");
|
|
120399
121121
|
const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
120400
121122
|
const mesh = meshRecord?.mesh;
|
|
120401
121123
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
@@ -120414,7 +121136,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120414
121136
|
const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
|
|
120415
121137
|
for (const item of derivation.items) {
|
|
120416
121138
|
const workspace = item.workspace;
|
|
120417
|
-
if (!workspace || !
|
|
121139
|
+
if (!workspace || !existsSync69(workspace)) continue;
|
|
120418
121140
|
const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
|
|
120419
121141
|
try {
|
|
120420
121142
|
const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
|
|
@@ -120609,12 +121331,12 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120609
121331
|
}
|
|
120610
121332
|
init_debug_trace();
|
|
120611
121333
|
init_mesh_host_ownership();
|
|
120612
|
-
var
|
|
121334
|
+
var fs53 = __toESM2(require("fs"));
|
|
120613
121335
|
init_mesh_node_identity();
|
|
120614
121336
|
init_router_refine();
|
|
120615
|
-
var
|
|
121337
|
+
var fs51 = __toESM2(require("fs"));
|
|
120616
121338
|
var import_node_os2 = require("os");
|
|
120617
|
-
var
|
|
121339
|
+
var import_path19 = require("path");
|
|
120618
121340
|
init_logger();
|
|
120619
121341
|
init_git_locale();
|
|
120620
121342
|
init_dist();
|
|
@@ -120626,7 +121348,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120626
121348
|
function acceptableManagedWorktreePaths(resolveWorktreePath2, normalizePath2, repoRoot, meshName, branch, worktreeBaseDir) {
|
|
120627
121349
|
const safeBranch = branch.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
120628
121350
|
const safeMeshName = meshName.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
120629
|
-
const legacyPath = (0,
|
|
121351
|
+
const legacyPath = (0, import_path19.join)((0, import_path19.dirname)(repoRoot), LEGACY_WORKTREE_DIR_NAME, safeMeshName, safeBranch);
|
|
120630
121352
|
const candidates = [
|
|
120631
121353
|
resolveWorktreePath2(repoRoot, meshName, branch, worktreeBaseDir),
|
|
120632
121354
|
legacyPath
|
|
@@ -120650,8 +121372,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120650
121372
|
function looksLikeCrossTrackWorktreePath(actualPath, normalizePath2) {
|
|
120651
121373
|
const home = normalizePath2((0, import_node_os2.homedir)());
|
|
120652
121374
|
return TRACK_CONFIG_DIR_NAMES.some((trackDirName) => {
|
|
120653
|
-
const trackWorktreesDir = (0,
|
|
120654
|
-
return actualPath === normalizePath2(trackWorktreesDir) || actualPath.startsWith(normalizePath2(trackWorktreesDir) +
|
|
121375
|
+
const trackWorktreesDir = (0, import_path19.join)(home, trackDirName, "worktrees");
|
|
121376
|
+
return actualPath === normalizePath2(trackWorktreesDir) || actualPath.startsWith(normalizePath2(trackWorktreesDir) + import_path19.sep);
|
|
120655
121377
|
});
|
|
120656
121378
|
}
|
|
120657
121379
|
function unexpectedPathRecoveryHint(actualPath, normalizePath2, suffix) {
|
|
@@ -120709,14 +121431,14 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120709
121431
|
return false;
|
|
120710
121432
|
}
|
|
120711
121433
|
async function bestEffortRemoveWorktreeDir(self, dir) {
|
|
120712
|
-
if (!dir || !
|
|
121434
|
+
if (!dir || !fs51.existsSync(dir)) return { removed: true, residue: false };
|
|
120713
121435
|
const sleep3 = (ms) => new Promise((resolve30) => setTimeout(resolve30, ms));
|
|
120714
121436
|
const ABSORB = /* @__PURE__ */ new Set(["EINVAL", "EPERM", "EBUSY", "ENOTEMPTY", "EACCES", "EMFILE", "ENFILE"]);
|
|
120715
121437
|
let lastErr;
|
|
120716
121438
|
for (let attempt = 0; attempt < 4; attempt++) {
|
|
120717
121439
|
try {
|
|
120718
|
-
|
|
120719
|
-
if (!
|
|
121440
|
+
fs51.rmSync(dir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
121441
|
+
if (!fs51.existsSync(dir)) return { removed: true, residue: false };
|
|
120720
121442
|
lastErr = new Error("directory still present after rmSync");
|
|
120721
121443
|
} catch (e) {
|
|
120722
121444
|
lastErr = e;
|
|
@@ -120727,7 +121449,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120727
121449
|
}
|
|
120728
121450
|
await sleep3(150 * (attempt + 1));
|
|
120729
121451
|
}
|
|
120730
|
-
return
|
|
121452
|
+
return fs51.existsSync(dir) ? { removed: false, residue: true, error: String(lastErr?.message || lastErr || "unknown rm error") } : { removed: true, residue: false };
|
|
120731
121453
|
}
|
|
120732
121454
|
async function precheckLocalWorktreeRemovable(self, args) {
|
|
120733
121455
|
const sessionPreservedNote = " The delegated session was left running (not stopped) \u2014 resolve the issue and retry mesh_remove_node.";
|
|
@@ -120740,10 +121462,10 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120740
121462
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains." + sessionPreservedNote
|
|
120741
121463
|
};
|
|
120742
121464
|
}
|
|
120743
|
-
if (!
|
|
121465
|
+
if (!fs51.existsSync(workspace)) return { ok: true };
|
|
120744
121466
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
120745
121467
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
120746
|
-
if (!repoRoot || !
|
|
121468
|
+
if (!repoRoot || !fs51.existsSync(repoRoot)) {
|
|
120747
121469
|
return {
|
|
120748
121470
|
ok: false,
|
|
120749
121471
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -120761,9 +121483,9 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120761
121483
|
}
|
|
120762
121484
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
120763
121485
|
const normalizePath2 = (value) => {
|
|
120764
|
-
const resolved = (0,
|
|
121486
|
+
const resolved = (0, import_path19.resolve)(value);
|
|
120765
121487
|
try {
|
|
120766
|
-
return
|
|
121488
|
+
return fs51.realpathSync(resolved);
|
|
120767
121489
|
} catch {
|
|
120768
121490
|
return resolved;
|
|
120769
121491
|
}
|
|
@@ -120864,13 +121586,13 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120864
121586
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
120865
121587
|
};
|
|
120866
121588
|
}
|
|
120867
|
-
const worktreeExists =
|
|
121589
|
+
const worktreeExists = fs51.existsSync(workspace);
|
|
120868
121590
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
120869
121591
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
120870
121592
|
if (!worktreeExists) {
|
|
120871
121593
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
120872
121594
|
}
|
|
120873
|
-
if (!repoRoot || !
|
|
121595
|
+
if (!repoRoot || !fs51.existsSync(repoRoot)) {
|
|
120874
121596
|
return {
|
|
120875
121597
|
success: false,
|
|
120876
121598
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -120888,9 +121610,9 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
120888
121610
|
}
|
|
120889
121611
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
120890
121612
|
const normalizePath2 = (value) => {
|
|
120891
|
-
const resolved = (0,
|
|
121613
|
+
const resolved = (0, import_path19.resolve)(value);
|
|
120892
121614
|
try {
|
|
120893
|
-
return
|
|
121615
|
+
return fs51.realpathSync(resolved);
|
|
120894
121616
|
} catch {
|
|
120895
121617
|
return resolved;
|
|
120896
121618
|
}
|
|
@@ -121537,8 +122259,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
121537
122259
|
init_logger();
|
|
121538
122260
|
var yaml5 = __toESM2(require_js_yaml());
|
|
121539
122261
|
var import_os5 = require("os");
|
|
121540
|
-
var
|
|
121541
|
-
var
|
|
122262
|
+
var import_path20 = require("path");
|
|
122263
|
+
var fs52 = __toESM2(require("fs"));
|
|
121542
122264
|
var MESH_COORDINATOR_AUTO_IMPORT_FORMATS = ["claude_mcp_json", "hermes_config_yaml", "opencode_json"];
|
|
121543
122265
|
function isSupportedMeshCoordinatorConfigFormat(format) {
|
|
121544
122266
|
return MESH_COORDINATOR_AUTO_IMPORT_FORMATS.includes(format);
|
|
@@ -121578,14 +122300,14 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
121578
122300
|
}
|
|
121579
122301
|
function resolveHermesUserHome() {
|
|
121580
122302
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
121581
|
-
return explicitHome || (0,
|
|
122303
|
+
return explicitHome || (0, import_path20.join)((0, import_os5.homedir)(), ".hermes");
|
|
121582
122304
|
}
|
|
121583
122305
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
121584
122306
|
const sourceHome = resolveHermesUserHome();
|
|
121585
|
-
const sourceConfigPath = (0,
|
|
121586
|
-
if (!
|
|
121587
|
-
if ((0,
|
|
121588
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
122307
|
+
const sourceConfigPath = (0, import_path20.join)(sourceHome, "config.yaml");
|
|
122308
|
+
if (!fs52.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
122309
|
+
if ((0, import_path20.resolve)(sourceConfigPath) === (0, import_path20.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
122310
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs52.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
121589
122311
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
121590
122312
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
121591
122313
|
}
|
|
@@ -121618,13 +122340,13 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
121618
122340
|
return sanitized;
|
|
121619
122341
|
}
|
|
121620
122342
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
121621
|
-
if ((0,
|
|
122343
|
+
if ((0, import_path20.resolve)(sourceHome) === (0, import_path20.resolve)(targetHome)) return;
|
|
121622
122344
|
for (const fileName of [".env", "auth.json"]) {
|
|
121623
|
-
const sourcePath = (0,
|
|
121624
|
-
const targetPath = (0,
|
|
121625
|
-
if (!
|
|
122345
|
+
const sourcePath = (0, import_path20.join)(sourceHome, fileName);
|
|
122346
|
+
const targetPath = (0, import_path20.join)(targetHome, fileName);
|
|
122347
|
+
if (!fs52.existsSync(sourcePath)) continue;
|
|
121626
122348
|
try {
|
|
121627
|
-
|
|
122349
|
+
fs52.copyFileSync(sourcePath, targetPath);
|
|
121628
122350
|
} catch (error48) {
|
|
121629
122351
|
LOG2.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error48?.message || error48}`);
|
|
121630
122352
|
}
|
|
@@ -122139,7 +122861,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
122139
122861
|
const nodeId = readInlineMeshNodeId(node);
|
|
122140
122862
|
if (!nodeId || !tombstones.has(nodeId)) return true;
|
|
122141
122863
|
const workspace = readStringValue(node?.workspace);
|
|
122142
|
-
if (workspace &&
|
|
122864
|
+
if (workspace && fs53.existsSync(workspace)) {
|
|
122143
122865
|
tombstones.delete(nodeId);
|
|
122144
122866
|
return true;
|
|
122145
122867
|
}
|
|
@@ -124199,7 +124921,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124199
124921
|
};
|
|
124200
124922
|
init_io_contracts();
|
|
124201
124923
|
init_chat_message_normalization();
|
|
124202
|
-
var
|
|
124924
|
+
var fs54 = __toESM2(require("fs"));
|
|
124203
124925
|
var path522 = __toESM2(require("path"));
|
|
124204
124926
|
var os28 = __toESM2(require("os"));
|
|
124205
124927
|
var import_os6 = require("os");
|
|
@@ -124216,8 +124938,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124216
124938
|
}
|
|
124217
124939
|
load() {
|
|
124218
124940
|
try {
|
|
124219
|
-
if (
|
|
124220
|
-
this.history = JSON.parse(
|
|
124941
|
+
if (fs54.existsSync(getArchivePath2())) {
|
|
124942
|
+
this.history = JSON.parse(fs54.readFileSync(getArchivePath2(), "utf-8"));
|
|
124221
124943
|
}
|
|
124222
124944
|
} catch {
|
|
124223
124945
|
this.history = {};
|
|
@@ -124254,8 +124976,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124254
124976
|
}
|
|
124255
124977
|
save() {
|
|
124256
124978
|
try {
|
|
124257
|
-
|
|
124258
|
-
|
|
124979
|
+
fs54.mkdirSync(path522.dirname(getArchivePath2()), { recursive: true });
|
|
124980
|
+
fs54.writeFileSync(getArchivePath2(), JSON.stringify(this.history, null, 2));
|
|
124259
124981
|
} catch {
|
|
124260
124982
|
}
|
|
124261
124983
|
}
|
|
@@ -124280,8 +125002,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124280
125002
|
for (const ext of exes) {
|
|
124281
125003
|
const fullPath = path522.join(p, name + ext);
|
|
124282
125004
|
try {
|
|
124283
|
-
if (
|
|
124284
|
-
const stat2 =
|
|
125005
|
+
if (fs54.existsSync(fullPath)) {
|
|
125006
|
+
const stat2 = fs54.statSync(fullPath);
|
|
124285
125007
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
124286
125008
|
return fullPath;
|
|
124287
125009
|
}
|
|
@@ -124328,9 +125050,9 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124328
125050
|
if (p.includes("*")) {
|
|
124329
125051
|
const home = os28.homedir();
|
|
124330
125052
|
const resolved = p.replace(/\*/g, home.split(path522.sep).pop() || "");
|
|
124331
|
-
if (
|
|
125053
|
+
if (fs54.existsSync(resolved)) return resolved;
|
|
124332
125054
|
} else {
|
|
124333
|
-
if (
|
|
125055
|
+
if (fs54.existsSync(p)) return p;
|
|
124334
125056
|
}
|
|
124335
125057
|
}
|
|
124336
125058
|
return null;
|
|
@@ -124338,7 +125060,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124338
125060
|
async function getMacAppVersion(appPath) {
|
|
124339
125061
|
if ((0, import_os6.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
124340
125062
|
const plistPath = path522.join(appPath, "Contents", "Info.plist");
|
|
124341
|
-
if (!
|
|
125063
|
+
if (!fs54.existsSync(plistPath)) return null;
|
|
124342
125064
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
124343
125065
|
return raw || null;
|
|
124344
125066
|
}
|
|
@@ -124365,7 +125087,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124365
125087
|
let resolvedBin = cliBin;
|
|
124366
125088
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
124367
125089
|
const bundled = path522.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
124368
|
-
if (provider.cli &&
|
|
125090
|
+
if (provider.cli && fs54.existsSync(bundled)) resolvedBin = bundled;
|
|
124369
125091
|
}
|
|
124370
125092
|
info.installed = !!(appPath || resolvedBin);
|
|
124371
125093
|
info.path = appPath || null;
|
|
@@ -124411,7 +125133,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124411
125133
|
return results;
|
|
124412
125134
|
}
|
|
124413
125135
|
var http3 = __toESM2(require("http"));
|
|
124414
|
-
var
|
|
125136
|
+
var fs58 = __toESM2(require("fs"));
|
|
124415
125137
|
var path56 = __toESM2(require("path"));
|
|
124416
125138
|
init_config();
|
|
124417
125139
|
function generateFiles(type2, name, category, opts = {}) {
|
|
@@ -124757,7 +125479,7 @@ async (params) => {
|
|
|
124757
125479
|
}
|
|
124758
125480
|
init_logger();
|
|
124759
125481
|
init_builders();
|
|
124760
|
-
var
|
|
125482
|
+
var fs55 = __toESM2(require("fs"));
|
|
124761
125483
|
var path53 = __toESM2(require("path"));
|
|
124762
125484
|
init_logger();
|
|
124763
125485
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
@@ -124938,17 +125660,17 @@ async (params) => {
|
|
|
124938
125660
|
}
|
|
124939
125661
|
let scriptsPath = "";
|
|
124940
125662
|
const directScripts = path53.join(dir, "scripts.js");
|
|
124941
|
-
if (
|
|
125663
|
+
if (fs55.existsSync(directScripts)) {
|
|
124942
125664
|
scriptsPath = directScripts;
|
|
124943
125665
|
} else {
|
|
124944
125666
|
const scriptsDir = path53.join(dir, "scripts");
|
|
124945
|
-
if (
|
|
124946
|
-
const versions =
|
|
124947
|
-
return
|
|
125667
|
+
if (fs55.existsSync(scriptsDir)) {
|
|
125668
|
+
const versions = fs55.readdirSync(scriptsDir).filter((d) => {
|
|
125669
|
+
return fs55.statSync(path53.join(scriptsDir, d)).isDirectory();
|
|
124948
125670
|
}).sort().reverse();
|
|
124949
125671
|
for (const ver of versions) {
|
|
124950
125672
|
const p = path53.join(scriptsDir, ver, "scripts.js");
|
|
124951
|
-
if (
|
|
125673
|
+
if (fs55.existsSync(p)) {
|
|
124952
125674
|
scriptsPath = p;
|
|
124953
125675
|
break;
|
|
124954
125676
|
}
|
|
@@ -124960,7 +125682,7 @@ async (params) => {
|
|
|
124960
125682
|
return;
|
|
124961
125683
|
}
|
|
124962
125684
|
try {
|
|
124963
|
-
const source =
|
|
125685
|
+
const source = fs55.readFileSync(scriptsPath, "utf-8");
|
|
124964
125686
|
const hints = {};
|
|
124965
125687
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
124966
125688
|
let match;
|
|
@@ -125773,7 +126495,7 @@ async (params) => {
|
|
|
125773
126495
|
ctx.json(res, 500, { error: `DOM context collection failed: ${e.message}` });
|
|
125774
126496
|
}
|
|
125775
126497
|
}
|
|
125776
|
-
var
|
|
126498
|
+
var fs56 = __toESM2(require("fs"));
|
|
125777
126499
|
var path54 = __toESM2(require("path"));
|
|
125778
126500
|
function slugifyFixtureName(value) {
|
|
125779
126501
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -125789,10 +126511,10 @@ async (params) => {
|
|
|
125789
126511
|
function readCliFixture(ctx, type2, name) {
|
|
125790
126512
|
const fixtureDir = getCliFixtureDir(ctx, type2);
|
|
125791
126513
|
const filePath = path54.join(fixtureDir, `${name}.json`);
|
|
125792
|
-
if (!
|
|
126514
|
+
if (!fs56.existsSync(filePath)) {
|
|
125793
126515
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
125794
126516
|
}
|
|
125795
|
-
return JSON.parse(
|
|
126517
|
+
return JSON.parse(fs56.readFileSync(filePath, "utf-8"));
|
|
125796
126518
|
}
|
|
125797
126519
|
function getExerciseTranscriptText(result) {
|
|
125798
126520
|
const parts = [];
|
|
@@ -126542,7 +127264,7 @@ async (params) => {
|
|
|
126542
127264
|
return;
|
|
126543
127265
|
}
|
|
126544
127266
|
const fixtureDir = getCliFixtureDir(ctx, type2);
|
|
126545
|
-
|
|
127267
|
+
fs56.mkdirSync(fixtureDir, { recursive: true });
|
|
126546
127268
|
const name = slugifyFixtureName(String(body?.name || `${type2}-${Date.now()}`));
|
|
126547
127269
|
const result = await runCliExerciseInternal(ctx, { ...request, type: type2 });
|
|
126548
127270
|
const fixture = {
|
|
@@ -126570,7 +127292,7 @@ async (params) => {
|
|
|
126570
127292
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
126571
127293
|
};
|
|
126572
127294
|
const filePath = path54.join(fixtureDir, `${name}.json`);
|
|
126573
|
-
|
|
127295
|
+
fs56.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
126574
127296
|
ctx.json(res, 200, {
|
|
126575
127297
|
saved: true,
|
|
126576
127298
|
name,
|
|
@@ -126588,14 +127310,14 @@ async (params) => {
|
|
|
126588
127310
|
async function handleCliFixtureList(ctx, type2, _req, res) {
|
|
126589
127311
|
try {
|
|
126590
127312
|
const fixtureDir = getCliFixtureDir(ctx, type2);
|
|
126591
|
-
if (!
|
|
127313
|
+
if (!fs56.existsSync(fixtureDir)) {
|
|
126592
127314
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
126593
127315
|
return;
|
|
126594
127316
|
}
|
|
126595
|
-
const fixtures =
|
|
127317
|
+
const fixtures = fs56.readdirSync(fixtureDir).filter((file2) => file2.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file2) => {
|
|
126596
127318
|
const fullPath = path54.join(fixtureDir, file2);
|
|
126597
127319
|
try {
|
|
126598
|
-
const raw = JSON.parse(
|
|
127320
|
+
const raw = JSON.parse(fs56.readFileSync(fullPath, "utf-8"));
|
|
126599
127321
|
return {
|
|
126600
127322
|
name: raw.name || file2.replace(/\.json$/i, ""),
|
|
126601
127323
|
path: fullPath,
|
|
@@ -126726,7 +127448,7 @@ async (params) => {
|
|
|
126726
127448
|
ctx.json(res, 500, { error: `Raw send failed: ${e.message}` });
|
|
126727
127449
|
}
|
|
126728
127450
|
}
|
|
126729
|
-
var
|
|
127451
|
+
var fs57 = __toESM2(require("fs"));
|
|
126730
127452
|
var path55 = __toESM2(require("path"));
|
|
126731
127453
|
var os29 = __toESM2(require("os"));
|
|
126732
127454
|
var import_session_host_core10 = require_dist();
|
|
@@ -126775,10 +127497,10 @@ async (params) => {
|
|
|
126775
127497
|
return fallback?.type || null;
|
|
126776
127498
|
}
|
|
126777
127499
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
126778
|
-
if (!
|
|
126779
|
-
const versions =
|
|
127500
|
+
if (!fs57.existsSync(scriptsDir)) return null;
|
|
127501
|
+
const versions = fs57.readdirSync(scriptsDir).filter((d) => {
|
|
126780
127502
|
try {
|
|
126781
|
-
return
|
|
127503
|
+
return fs57.statSync(path55.join(scriptsDir, d)).isDirectory();
|
|
126782
127504
|
} catch {
|
|
126783
127505
|
return false;
|
|
126784
127506
|
}
|
|
@@ -126800,13 +127522,13 @@ async (params) => {
|
|
|
126800
127522
|
if (!sourceDir) {
|
|
126801
127523
|
return { dir: null, reason: `Provider source directory not found for '${type2}'` };
|
|
126802
127524
|
}
|
|
126803
|
-
if (!
|
|
126804
|
-
|
|
126805
|
-
|
|
127525
|
+
if (!fs57.existsSync(desiredDir)) {
|
|
127526
|
+
fs57.mkdirSync(path55.dirname(desiredDir), { recursive: true });
|
|
127527
|
+
fs57.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
126806
127528
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
126807
127529
|
}
|
|
126808
127530
|
const providerJson = path55.join(desiredDir, "provider.json");
|
|
126809
|
-
if (!
|
|
127531
|
+
if (!fs57.existsSync(providerJson)) {
|
|
126810
127532
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
126811
127533
|
}
|
|
126812
127534
|
return { dir: desiredDir };
|
|
@@ -126814,15 +127536,15 @@ async (params) => {
|
|
|
126814
127536
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
126815
127537
|
if (!referenceType) return {};
|
|
126816
127538
|
const refDir = ctx.findProviderDir(referenceType);
|
|
126817
|
-
if (!refDir || !
|
|
127539
|
+
if (!refDir || !fs57.existsSync(refDir)) return {};
|
|
126818
127540
|
const referenceScripts = {};
|
|
126819
127541
|
const scriptsDir = path55.join(refDir, "scripts");
|
|
126820
127542
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
126821
127543
|
if (!latestDir) return referenceScripts;
|
|
126822
|
-
for (const file2 of
|
|
127544
|
+
for (const file2 of fs57.readdirSync(latestDir)) {
|
|
126823
127545
|
if (!file2.endsWith(".js")) continue;
|
|
126824
127546
|
try {
|
|
126825
|
-
referenceScripts[file2] =
|
|
127547
|
+
referenceScripts[file2] = fs57.readFileSync(path55.join(latestDir, file2), "utf-8");
|
|
126826
127548
|
} catch {
|
|
126827
127549
|
}
|
|
126828
127550
|
}
|
|
@@ -126931,15 +127653,15 @@ async (params) => {
|
|
|
126931
127653
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
126932
127654
|
const prompt = buildAutoImplPrompt(ctx, type2, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
126933
127655
|
const tmpDir = path55.join(os29.tmpdir(), "adhdev-autoimpl");
|
|
126934
|
-
if (!
|
|
127656
|
+
if (!fs57.existsSync(tmpDir)) fs57.mkdirSync(tmpDir, { recursive: true });
|
|
126935
127657
|
const promptFile = path55.join(tmpDir, `prompt-${type2}-${Date.now()}.md`);
|
|
126936
|
-
|
|
127658
|
+
fs57.writeFileSync(promptFile, prompt, "utf-8");
|
|
126937
127659
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
126938
127660
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
126939
127661
|
const spawn7 = agentProvider?.spawn;
|
|
126940
127662
|
if (!spawn7?.command) {
|
|
126941
127663
|
try {
|
|
126942
|
-
|
|
127664
|
+
fs57.unlinkSync(promptFile);
|
|
126943
127665
|
} catch {
|
|
126944
127666
|
}
|
|
126945
127667
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -127041,7 +127763,7 @@ async (params) => {
|
|
|
127041
127763
|
} catch {
|
|
127042
127764
|
}
|
|
127043
127765
|
try {
|
|
127044
|
-
|
|
127766
|
+
fs57.unlinkSync(promptFile);
|
|
127045
127767
|
} catch {
|
|
127046
127768
|
}
|
|
127047
127769
|
ctx.log(`Auto-implement (ACP) ${success2 ? "completed" : "failed"}: ${type2} (exit: ${code})`);
|
|
@@ -127264,7 +127986,7 @@ async (params) => {
|
|
|
127264
127986
|
}
|
|
127265
127987
|
});
|
|
127266
127988
|
try {
|
|
127267
|
-
|
|
127989
|
+
fs57.unlinkSync(promptFile);
|
|
127268
127990
|
} catch {
|
|
127269
127991
|
}
|
|
127270
127992
|
ctx.log(`Auto-implement ${success2 ? "completed" : "failed"}: ${type2} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -127369,10 +128091,10 @@ async (params) => {
|
|
|
127369
128091
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
127370
128092
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
127371
128093
|
lines.push("");
|
|
127372
|
-
for (const file2 of
|
|
128094
|
+
for (const file2 of fs57.readdirSync(latestScriptsDir)) {
|
|
127373
128095
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
127374
128096
|
try {
|
|
127375
|
-
const content =
|
|
128097
|
+
const content = fs57.readFileSync(path55.join(latestScriptsDir, file2), "utf-8");
|
|
127376
128098
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
127377
128099
|
lines.push("```javascript");
|
|
127378
128100
|
lines.push(content);
|
|
@@ -127382,14 +128104,14 @@ async (params) => {
|
|
|
127382
128104
|
}
|
|
127383
128105
|
}
|
|
127384
128106
|
}
|
|
127385
|
-
const refFiles =
|
|
128107
|
+
const refFiles = fs57.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
127386
128108
|
if (refFiles.length > 0) {
|
|
127387
128109
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
127388
128110
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
127389
128111
|
lines.push("");
|
|
127390
128112
|
for (const file2 of refFiles) {
|
|
127391
128113
|
try {
|
|
127392
|
-
const content =
|
|
128114
|
+
const content = fs57.readFileSync(path55.join(latestScriptsDir, file2), "utf-8");
|
|
127393
128115
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
127394
128116
|
lines.push("```javascript");
|
|
127395
128117
|
lines.push(content);
|
|
@@ -127434,7 +128156,7 @@ async (params) => {
|
|
|
127434
128156
|
const loadGuide = (name) => {
|
|
127435
128157
|
try {
|
|
127436
128158
|
const p = path55.join(docsDir, name);
|
|
127437
|
-
if (
|
|
128159
|
+
if (fs57.existsSync(p)) return fs57.readFileSync(p, "utf-8");
|
|
127438
128160
|
} catch {
|
|
127439
128161
|
}
|
|
127440
128162
|
return null;
|
|
@@ -127678,11 +128400,11 @@ async (params) => {
|
|
|
127678
128400
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
127679
128401
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
127680
128402
|
lines.push("");
|
|
127681
|
-
for (const file2 of
|
|
128403
|
+
for (const file2 of fs57.readdirSync(latestScriptsDir)) {
|
|
127682
128404
|
if (!file2.endsWith(".js")) continue;
|
|
127683
128405
|
if (!targetFileNames.has(file2)) continue;
|
|
127684
128406
|
try {
|
|
127685
|
-
const content =
|
|
128407
|
+
const content = fs57.readFileSync(path55.join(latestScriptsDir, file2), "utf-8");
|
|
127686
128408
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
127687
128409
|
lines.push("```javascript");
|
|
127688
128410
|
lines.push(content);
|
|
@@ -127691,14 +128413,14 @@ async (params) => {
|
|
|
127691
128413
|
} catch {
|
|
127692
128414
|
}
|
|
127693
128415
|
}
|
|
127694
|
-
const refFiles =
|
|
128416
|
+
const refFiles = fs57.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
127695
128417
|
if (refFiles.length > 0) {
|
|
127696
128418
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
127697
128419
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
127698
128420
|
lines.push("");
|
|
127699
128421
|
for (const file2 of refFiles) {
|
|
127700
128422
|
try {
|
|
127701
|
-
const content =
|
|
128423
|
+
const content = fs57.readFileSync(path55.join(latestScriptsDir, file2), "utf-8");
|
|
127702
128424
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
127703
128425
|
lines.push("```javascript");
|
|
127704
128426
|
lines.push(content);
|
|
@@ -127735,7 +128457,7 @@ async (params) => {
|
|
|
127735
128457
|
const loadGuide = (name) => {
|
|
127736
128458
|
try {
|
|
127737
128459
|
const p = path55.join(docsDir, name);
|
|
127738
|
-
if (
|
|
128460
|
+
if (fs57.existsSync(p)) return fs57.readFileSync(p, "utf-8");
|
|
127739
128461
|
} catch {
|
|
127740
128462
|
}
|
|
127741
128463
|
return null;
|
|
@@ -128473,7 +129195,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128473
129195
|
path56.join(process.cwd(), "packages/web-devconsole/dist")
|
|
128474
129196
|
];
|
|
128475
129197
|
for (const dir of candidates) {
|
|
128476
|
-
if (
|
|
129198
|
+
if (fs58.existsSync(path56.join(dir, "index.html"))) return dir;
|
|
128477
129199
|
}
|
|
128478
129200
|
return null;
|
|
128479
129201
|
}
|
|
@@ -128485,7 +129207,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128485
129207
|
}
|
|
128486
129208
|
const htmlPath = path56.join(distDir, "index.html");
|
|
128487
129209
|
try {
|
|
128488
|
-
const html =
|
|
129210
|
+
const html = fs58.readFileSync(htmlPath, "utf-8");
|
|
128489
129211
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
128490
129212
|
res.end(html);
|
|
128491
129213
|
} catch (e) {
|
|
@@ -128515,7 +129237,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128515
129237
|
return;
|
|
128516
129238
|
}
|
|
128517
129239
|
try {
|
|
128518
|
-
const content =
|
|
129240
|
+
const content = fs58.readFileSync(filePath);
|
|
128519
129241
|
const ext = path56.extname(filePath);
|
|
128520
129242
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
128521
129243
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
@@ -128624,14 +129346,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128624
129346
|
const files = [];
|
|
128625
129347
|
const scan = (d, prefix) => {
|
|
128626
129348
|
try {
|
|
128627
|
-
for (const entry of
|
|
129349
|
+
for (const entry of fs58.readdirSync(d, { withFileTypes: true })) {
|
|
128628
129350
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
128629
129351
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
128630
129352
|
if (entry.isDirectory()) {
|
|
128631
129353
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
128632
129354
|
scan(path56.join(d, entry.name), rel);
|
|
128633
129355
|
} else {
|
|
128634
|
-
const stat2 =
|
|
129356
|
+
const stat2 = fs58.statSync(path56.join(d, entry.name));
|
|
128635
129357
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
128636
129358
|
}
|
|
128637
129359
|
}
|
|
@@ -128659,11 +129381,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128659
129381
|
this.json(res, 403, { error: "Forbidden" });
|
|
128660
129382
|
return;
|
|
128661
129383
|
}
|
|
128662
|
-
if (!
|
|
129384
|
+
if (!fs58.existsSync(fullPath) || fs58.statSync(fullPath).isDirectory()) {
|
|
128663
129385
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
128664
129386
|
return;
|
|
128665
129387
|
}
|
|
128666
|
-
const content =
|
|
129388
|
+
const content = fs58.readFileSync(fullPath, "utf-8");
|
|
128667
129389
|
this.json(res, 200, { type: type2, path: filePath, content, lines: content.split("\n").length });
|
|
128668
129390
|
}
|
|
128669
129391
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -128685,9 +129407,9 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128685
129407
|
return;
|
|
128686
129408
|
}
|
|
128687
129409
|
try {
|
|
128688
|
-
if (
|
|
128689
|
-
|
|
128690
|
-
|
|
129410
|
+
if (fs58.existsSync(fullPath)) fs58.copyFileSync(fullPath, fullPath + ".bak");
|
|
129411
|
+
fs58.mkdirSync(path56.dirname(fullPath), { recursive: true });
|
|
129412
|
+
fs58.writeFileSync(fullPath, content, "utf-8");
|
|
128691
129413
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
128692
129414
|
this.providerLoader.reload();
|
|
128693
129415
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -128704,8 +129426,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128704
129426
|
}
|
|
128705
129427
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
128706
129428
|
const p = path56.join(dir, name);
|
|
128707
|
-
if (
|
|
128708
|
-
const source =
|
|
129429
|
+
if (fs58.existsSync(p)) {
|
|
129430
|
+
const source = fs58.readFileSync(p, "utf-8");
|
|
128709
129431
|
this.json(res, 200, { type: type2, path: p, source, lines: source.split("\n").length });
|
|
128710
129432
|
return;
|
|
128711
129433
|
}
|
|
@@ -128724,11 +129446,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128724
129446
|
this.json(res, 404, { error: `Provider not found: ${type2}` });
|
|
128725
129447
|
return;
|
|
128726
129448
|
}
|
|
128727
|
-
const target =
|
|
129449
|
+
const target = fs58.existsSync(path56.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
128728
129450
|
const targetPath = path56.join(dir, target);
|
|
128729
129451
|
try {
|
|
128730
|
-
if (
|
|
128731
|
-
|
|
129452
|
+
if (fs58.existsSync(targetPath)) fs58.copyFileSync(targetPath, targetPath + ".bak");
|
|
129453
|
+
fs58.writeFileSync(targetPath, source, "utf-8");
|
|
128732
129454
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
128733
129455
|
this.providerLoader.reload();
|
|
128734
129456
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -128873,20 +129595,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128873
129595
|
let targetDir;
|
|
128874
129596
|
targetDir = this.providerLoader.getUserProviderDir(category, type2);
|
|
128875
129597
|
const jsonPath = path56.join(targetDir, "provider.json");
|
|
128876
|
-
if (
|
|
129598
|
+
if (fs58.existsSync(jsonPath)) {
|
|
128877
129599
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
128878
129600
|
return;
|
|
128879
129601
|
}
|
|
128880
129602
|
try {
|
|
128881
129603
|
const result = generateFiles(type2, name, category, { cdpPorts, cli, processName, installPath, binary: binary2, extensionId, version: version2, osPaths, processNames });
|
|
128882
|
-
|
|
128883
|
-
|
|
129604
|
+
fs58.mkdirSync(targetDir, { recursive: true });
|
|
129605
|
+
fs58.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
128884
129606
|
const createdFiles = ["provider.json"];
|
|
128885
129607
|
if (result.files) {
|
|
128886
129608
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
128887
129609
|
const fullPath = path56.join(targetDir, relPath);
|
|
128888
|
-
|
|
128889
|
-
|
|
129610
|
+
fs58.mkdirSync(path56.dirname(fullPath), { recursive: true });
|
|
129611
|
+
fs58.writeFileSync(fullPath, content, "utf-8");
|
|
128890
129612
|
createdFiles.push(relPath);
|
|
128891
129613
|
}
|
|
128892
129614
|
}
|
|
@@ -128935,10 +129657,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128935
129657
|
}
|
|
128936
129658
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
128937
129659
|
getLatestScriptVersionDir(scriptsDir) {
|
|
128938
|
-
if (!
|
|
128939
|
-
const versions =
|
|
129660
|
+
if (!fs58.existsSync(scriptsDir)) return null;
|
|
129661
|
+
const versions = fs58.readdirSync(scriptsDir).filter((d) => {
|
|
128940
129662
|
try {
|
|
128941
|
-
return
|
|
129663
|
+
return fs58.statSync(path56.join(scriptsDir, d)).isDirectory();
|
|
128942
129664
|
} catch {
|
|
128943
129665
|
return false;
|
|
128944
129666
|
}
|
|
@@ -128960,13 +129682,13 @@ data: ${JSON.stringify(msg.data)}
|
|
|
128960
129682
|
if (!sourceDir) {
|
|
128961
129683
|
return { dir: null, reason: `Provider source directory not found for '${type2}'` };
|
|
128962
129684
|
}
|
|
128963
|
-
if (!
|
|
128964
|
-
|
|
128965
|
-
|
|
129685
|
+
if (!fs58.existsSync(desiredDir)) {
|
|
129686
|
+
fs58.mkdirSync(path56.dirname(desiredDir), { recursive: true });
|
|
129687
|
+
fs58.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
128966
129688
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
128967
129689
|
}
|
|
128968
129690
|
const providerJson = path56.join(desiredDir, "provider.json");
|
|
128969
|
-
if (!
|
|
129691
|
+
if (!fs58.existsSync(providerJson)) {
|
|
128970
129692
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
128971
129693
|
}
|
|
128972
129694
|
return { dir: desiredDir };
|
|
@@ -129775,7 +130497,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129775
130497
|
}
|
|
129776
130498
|
}
|
|
129777
130499
|
var import_child_process14 = require("child_process");
|
|
129778
|
-
var
|
|
130500
|
+
var fs59 = __toESM2(require("fs"));
|
|
129779
130501
|
var os30 = __toESM2(require("os"));
|
|
129780
130502
|
var path57 = __toESM2(require("path"));
|
|
129781
130503
|
var import_session_host_core14 = require_dist();
|
|
@@ -129801,7 +130523,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129801
130523
|
path57.resolve(__dirname, "../../vendor/session-host-daemon/index.js")
|
|
129802
130524
|
];
|
|
129803
130525
|
for (const candidate of packagedCandidates) {
|
|
129804
|
-
if (
|
|
130526
|
+
if (fs59.existsSync(candidate)) {
|
|
129805
130527
|
return candidate;
|
|
129806
130528
|
}
|
|
129807
130529
|
}
|
|
@@ -129821,8 +130543,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129821
130543
|
function getPid() {
|
|
129822
130544
|
try {
|
|
129823
130545
|
const pidFile = getPidFile();
|
|
129824
|
-
if (!
|
|
129825
|
-
const pid = Number.parseInt(
|
|
130546
|
+
if (!fs59.existsSync(pidFile)) return null;
|
|
130547
|
+
const pid = Number.parseInt(fs59.readFileSync(pidFile, "utf8").trim(), 10);
|
|
129826
130548
|
return Number.isFinite(pid) ? pid : null;
|
|
129827
130549
|
} catch {
|
|
129828
130550
|
return null;
|
|
@@ -129872,7 +130594,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129872
130594
|
if (markerIndex === -1) return;
|
|
129873
130595
|
const activePrefix = entry.slice(0, markerIndex);
|
|
129874
130596
|
const candidates = resolveConptyPrebuildCandidates(activePrefix);
|
|
129875
|
-
const found = candidates.find((candidate) =>
|
|
130597
|
+
const found = candidates.find((candidate) => fs59.existsSync(candidate));
|
|
129876
130598
|
if (!found) {
|
|
129877
130599
|
throw new Error(
|
|
129878
130600
|
`conpty.node missing at boot despite passing the install-time gate \u2014 likely deleted post-install (checked: ${candidates.join(", ")}). Every session-host spawn would crash requiring node-pty; refusing to spawn.`
|
|
@@ -129888,8 +130610,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129888
130610
|
let logFd = null;
|
|
129889
130611
|
if (options.spawnStdio === "logfile") {
|
|
129890
130612
|
const logDir = path57.join(instance().configDir, "logs");
|
|
129891
|
-
|
|
129892
|
-
logFd =
|
|
130613
|
+
fs59.mkdirSync(logDir, { recursive: true });
|
|
130614
|
+
logFd = fs59.openSync(path57.join(logDir, "session-host.log"), "a");
|
|
129893
130615
|
stdio = ["ignore", logFd, logFd];
|
|
129894
130616
|
}
|
|
129895
130617
|
const child = (0, import_child_process14.spawn)(nodeExecutable, [entry], {
|
|
@@ -129901,7 +130623,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129901
130623
|
child.unref();
|
|
129902
130624
|
if (logFd !== null) {
|
|
129903
130625
|
try {
|
|
129904
|
-
|
|
130626
|
+
fs59.closeSync(logFd);
|
|
129905
130627
|
} catch {
|
|
129906
130628
|
}
|
|
129907
130629
|
}
|
|
@@ -129919,8 +130641,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129919
130641
|
const pidFile = getPidFile();
|
|
129920
130642
|
let keepPidFile = false;
|
|
129921
130643
|
try {
|
|
129922
|
-
if (
|
|
129923
|
-
const pid = Number.parseInt(
|
|
130644
|
+
if (fs59.existsSync(pidFile)) {
|
|
130645
|
+
const pid = Number.parseInt(fs59.readFileSync(pidFile, "utf8").trim(), 10);
|
|
129924
130646
|
if (Number.isFinite(pid) && pid !== process.pid) {
|
|
129925
130647
|
const managed = isManagedPid(pid);
|
|
129926
130648
|
if (managed) {
|
|
@@ -129940,7 +130662,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129940
130662
|
} finally {
|
|
129941
130663
|
if (!keepPidFile) {
|
|
129942
130664
|
try {
|
|
129943
|
-
|
|
130665
|
+
fs59.unlinkSync(pidFile);
|
|
129944
130666
|
} catch {
|
|
129945
130667
|
}
|
|
129946
130668
|
}
|
|
@@ -129976,7 +130698,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
129976
130698
|
}
|
|
129977
130699
|
if (!reported) return;
|
|
129978
130700
|
if (pathsEquivalent(reported, currentEntry)) return;
|
|
129979
|
-
const reportedExists =
|
|
130701
|
+
const reportedExists = fs59.existsSync(reported);
|
|
129980
130702
|
LOG2.warn(
|
|
129981
130703
|
"SessionHost",
|
|
129982
130704
|
`Reachable session-host reports it is running from ${reported}${reportedExists ? "" : " (which no longer exists)"}, but this install runs from ${currentEntry}. That host would fail every create_session loading node-pty from its own prefix; stopping it so a current one is spawned in its place.`
|
|
@@ -130203,8 +130925,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
130203
130925
|
const res = await fetch(extension.vsixUrl);
|
|
130204
130926
|
if (res.ok) {
|
|
130205
130927
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
130206
|
-
const
|
|
130207
|
-
|
|
130928
|
+
const fs61 = await import("fs");
|
|
130929
|
+
fs61.writeFileSync(vsixPath, buffer);
|
|
130208
130930
|
return new Promise((resolve30) => {
|
|
130209
130931
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
130210
130932
|
(0, import_child_process15.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
|
|
@@ -130350,7 +131072,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
130350
131072
|
init_mesh_events();
|
|
130351
131073
|
init_mesh_reconcile_loop();
|
|
130352
131074
|
var import_fs19 = require("fs");
|
|
130353
|
-
var
|
|
131075
|
+
var import_path21 = require("path");
|
|
130354
131076
|
var import_crypto18 = require("crypto");
|
|
130355
131077
|
init_logger();
|
|
130356
131078
|
init_mesh_ledger();
|
|
@@ -130428,7 +131150,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
130428
131150
|
}
|
|
130429
131151
|
for (const name of names) {
|
|
130430
131152
|
if (!isPendingEventsFile(name)) continue;
|
|
130431
|
-
const path58 = (0,
|
|
131153
|
+
const path58 = (0, import_path21.join)(dir, name);
|
|
130432
131154
|
result.filesScanned++;
|
|
130433
131155
|
const claimed = `${path58}.migrating`;
|
|
130434
131156
|
try {
|
|
@@ -131207,7 +131929,7 @@ ${upgradeFailureNotice.notice}${supersededHint}`);
|
|
|
131207
131929
|
Object.values(V1_PRIMITIVE_CATALOG).flat()
|
|
131208
131930
|
);
|
|
131209
131931
|
var V1_CONTRACT_VERSION = "1.0.0";
|
|
131210
|
-
var
|
|
131932
|
+
var fs60 = __toESM2(require("fs"));
|
|
131211
131933
|
var import_chalk2 = __toESM2((init_source(), __toCommonJS(source_exports)));
|
|
131212
131934
|
init_dist();
|
|
131213
131935
|
var CLAUDE_NO_API_LINE = "Claude has no quota API \u2014 adhdev borrows your statusLine to read it.";
|
|
@@ -131318,7 +132040,7 @@ ${upgradeFailureNotice.notice}${supersededHint}`);
|
|
|
131318
132040
|
console.log(import_chalk2.default.gray(` Backup: ${status.paths.backupFile}`));
|
|
131319
132041
|
let snapshotMtimeMs = null;
|
|
131320
132042
|
try {
|
|
131321
|
-
snapshotMtimeMs =
|
|
132043
|
+
snapshotMtimeMs = fs60.statSync(status.paths.snapshotFile).mtimeMs;
|
|
131322
132044
|
} catch {
|
|
131323
132045
|
}
|
|
131324
132046
|
console.log(import_chalk2.default.gray(
|