@adhdev/daemon-standalone 0.9.82-rc.350 → 0.9.82-rc.352
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 +524 -209
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/vendor/mcp-server/index.js +90 -8
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -30036,10 +30036,10 @@ var require_dist3 = __commonJS({
|
|
|
30036
30036
|
}
|
|
30037
30037
|
function getDaemonBuildInfo() {
|
|
30038
30038
|
if (cached2) return cached2;
|
|
30039
|
-
const commit = readInjected(true ? "
|
|
30040
|
-
const commitShort = readInjected(true ? "
|
|
30041
|
-
const version2 = readInjected(true ? "0.9.82-rc.
|
|
30042
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
30039
|
+
const commit = readInjected(true ? "ca5f944b7763a621357fc28a9f62ac398b0ced6c" : void 0) ?? "unknown";
|
|
30040
|
+
const commitShort = readInjected(true ? "ca5f944b" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
30041
|
+
const version2 = readInjected(true ? "0.9.82-rc.352" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
30042
|
+
const builtAt = readInjected(true ? "2026-06-22T07:17:32.309Z" : void 0);
|
|
30043
30043
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
30044
30044
|
return cached2;
|
|
30045
30045
|
}
|
|
@@ -32936,6 +32936,7 @@ Follow these recovery rules:
|
|
|
32936
32936
|
var LEVEL_NUM;
|
|
32937
32937
|
var LEVEL_LABEL;
|
|
32938
32938
|
var currentLevel;
|
|
32939
|
+
var ADHDEV_HOME;
|
|
32939
32940
|
var LOG_DIR;
|
|
32940
32941
|
var MAX_LOG_SIZE;
|
|
32941
32942
|
var MAX_LOG_DAYS;
|
|
@@ -32961,7 +32962,8 @@ Follow these recovery rules:
|
|
|
32961
32962
|
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
32962
32963
|
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
32963
32964
|
currentLevel = "info";
|
|
32964
|
-
|
|
32965
|
+
ADHDEV_HOME = process.env.ADHDEV_CONFIG_DIR && process.env.ADHDEV_CONFIG_DIR.trim() ? process.env.ADHDEV_CONFIG_DIR.trim() : path9.join(os32.homedir(), ".adhdev");
|
|
32966
|
+
LOG_DIR = path9.join(ADHDEV_HOME, "logs");
|
|
32965
32967
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
32966
32968
|
MAX_LOG_DAYS = 7;
|
|
32967
32969
|
try {
|
|
@@ -33774,6 +33776,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
33774
33776
|
nodeSatisfiesRequiredTags: () => nodeSatisfiesRequiredTags,
|
|
33775
33777
|
normalizeMeshCapabilityTags: () => normalizeMeshCapabilityTags,
|
|
33776
33778
|
normalizeMeshTaskMode: () => normalizeMeshTaskMode,
|
|
33779
|
+
reclaimStrandedAssignedTask: () => reclaimStrandedAssignedTask,
|
|
33777
33780
|
recordDirectDispatchTask: () => recordDirectDispatchTask,
|
|
33778
33781
|
recordMeshToolCall: () => recordMeshToolCall,
|
|
33779
33782
|
recordTaskAutoLaunch: () => recordTaskAutoLaunch,
|
|
@@ -34209,6 +34212,52 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34209
34212
|
return entry;
|
|
34210
34213
|
});
|
|
34211
34214
|
}
|
|
34215
|
+
function reclaimStrandedAssignedTask(meshId, taskId, opts) {
|
|
34216
|
+
requireMeshHostQueueOwner(opts);
|
|
34217
|
+
return withQueueLock(meshId, () => {
|
|
34218
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
34219
|
+
if (!entry) return null;
|
|
34220
|
+
if (entry.status !== "assigned") return null;
|
|
34221
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
34222
|
+
const reason = opts?.reason || "assigned_stranded_dispatch_unconfirmed";
|
|
34223
|
+
const reclaims = (entry.strandedReclaimCount || 0) + 1;
|
|
34224
|
+
const prevNode = entry.assignedNodeId;
|
|
34225
|
+
const prevSession = entry.assignedSessionId;
|
|
34226
|
+
delete entry.assignedNodeId;
|
|
34227
|
+
delete entry.assignedSessionId;
|
|
34228
|
+
delete entry.assignedProviderType;
|
|
34229
|
+
delete entry.dispatchTimestamp;
|
|
34230
|
+
entry.strandedReclaimCount = reclaims;
|
|
34231
|
+
entry.updatedAt = now;
|
|
34232
|
+
if (reclaims > MAX_STRANDED_RECLAIMS) {
|
|
34233
|
+
entry.status = "failed";
|
|
34234
|
+
entry.cancelReason = `stranded_dispatch_unrecovered: reclaimed ${reclaims - 1} time(s) without a confirmed dispatch`;
|
|
34235
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
34236
|
+
propagateDependencyFailure(meshId, taskId);
|
|
34237
|
+
} else {
|
|
34238
|
+
entry.status = "pending";
|
|
34239
|
+
entry.requeuedAt = now;
|
|
34240
|
+
entry.requeueReason = reason;
|
|
34241
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
34242
|
+
}
|
|
34243
|
+
try {
|
|
34244
|
+
appendLedgerEntry(meshId, {
|
|
34245
|
+
kind: "task_reclaimed",
|
|
34246
|
+
nodeId: prevNode,
|
|
34247
|
+
sessionId: prevSession,
|
|
34248
|
+
payload: {
|
|
34249
|
+
taskId,
|
|
34250
|
+
reason,
|
|
34251
|
+
...typeof opts?.ageMs === "number" ? { ageMs: opts.ageMs } : {},
|
|
34252
|
+
reclaimCount: reclaims,
|
|
34253
|
+
outcome: entry.status
|
|
34254
|
+
}
|
|
34255
|
+
});
|
|
34256
|
+
} catch {
|
|
34257
|
+
}
|
|
34258
|
+
return entry;
|
|
34259
|
+
});
|
|
34260
|
+
}
|
|
34212
34261
|
function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
34213
34262
|
return withQueueLock(meshId, () => {
|
|
34214
34263
|
const store = MeshRuntimeStore.getInstance();
|
|
@@ -34332,6 +34381,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34332
34381
|
var GIT_MUTATION_SUBCOMMANDS;
|
|
34333
34382
|
var GIT_STASH_READONLY_SUBCOMMANDS;
|
|
34334
34383
|
var DEPENDENCY_FAILURE_TERMINALS;
|
|
34384
|
+
var MAX_STRANDED_RECLAIMS;
|
|
34335
34385
|
var init_mesh_work_queue = __esm2({
|
|
34336
34386
|
"src/mesh/mesh-work-queue.ts"() {
|
|
34337
34387
|
"use strict";
|
|
@@ -34341,6 +34391,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34341
34391
|
init_mesh_runtime_store();
|
|
34342
34392
|
init_mesh_config();
|
|
34343
34393
|
init_logger();
|
|
34394
|
+
init_mesh_ledger();
|
|
34344
34395
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
34345
34396
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
34346
34397
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -34393,6 +34444,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34393
34444
|
]);
|
|
34394
34445
|
GIT_STASH_READONLY_SUBCOMMANDS = /* @__PURE__ */ new Set(["list", "show"]);
|
|
34395
34446
|
DEPENDENCY_FAILURE_TERMINALS = /* @__PURE__ */ new Set(["failed", "cancelled"]);
|
|
34447
|
+
MAX_STRANDED_RECLAIMS = 3;
|
|
34396
34448
|
}
|
|
34397
34449
|
});
|
|
34398
34450
|
function loadDatabaseCtor() {
|
|
@@ -34454,6 +34506,10 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34454
34506
|
migratedMeshIds = /* @__PURE__ */ new Set();
|
|
34455
34507
|
fingerprintSweepCounter = 0;
|
|
34456
34508
|
walWriteCounter = 0;
|
|
34509
|
+
// Independent cadence for the tool-call-log sweep. Must NOT share walWriteCounter:
|
|
34510
|
+
// sharing makes each store's threshold drift by the other's write volume (WAL
|
|
34511
|
+
// checkpoint at 500 vs tool-log sweep at 200 would interfere arbitrarily).
|
|
34512
|
+
toolCallLogCounter = 0;
|
|
34457
34513
|
static WAL_CHECK_INTERVAL = 500;
|
|
34458
34514
|
static WAL_MAX_BYTES = 50 * 1024 * 1024;
|
|
34459
34515
|
// 50 MB
|
|
@@ -35276,6 +35332,22 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
35276
35332
|
updatedAt: r.updated_at
|
|
35277
35333
|
}));
|
|
35278
35334
|
}
|
|
35335
|
+
/**
|
|
35336
|
+
* Bug B watchdog support: true when at least one delivery record for the task has
|
|
35337
|
+
* reached a confirmed-handed-off status (delivered / acked / completed). The
|
|
35338
|
+
* assigned-stranded watchdog uses this to distinguish a dispatch that was never
|
|
35339
|
+
* confirmed (reclaimable) from one that WAS handed to the worker (a genuinely
|
|
35340
|
+
* in-flight or completion-lost task, which is PHASE 4's responsibility, not this
|
|
35341
|
+
* watchdog's). Indexed by (mesh_id, task_id).
|
|
35342
|
+
*/
|
|
35343
|
+
taskHasConfirmedDelivery(meshId, taskId) {
|
|
35344
|
+
const row = this.db.prepare(`
|
|
35345
|
+
SELECT 1 FROM mesh_session_delivery
|
|
35346
|
+
WHERE mesh_id = ? AND task_id = ? AND status IN ('delivered','acked','completed')
|
|
35347
|
+
LIMIT 1
|
|
35348
|
+
`).get(meshId, taskId);
|
|
35349
|
+
return !!row;
|
|
35350
|
+
}
|
|
35279
35351
|
expireStaleSessionDeliveries(meshId) {
|
|
35280
35352
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
35281
35353
|
this.db.prepare(`
|
|
@@ -35347,7 +35419,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
35347
35419
|
"SELECT COUNT(*) as cnt FROM mesh_tool_call_log WHERE mesh_id = ? AND tool = ? AND called_at >= ?"
|
|
35348
35420
|
).get(meshId, tool, windowStart);
|
|
35349
35421
|
const callsInWindow = row?.cnt ?? 0;
|
|
35350
|
-
if (++this.
|
|
35422
|
+
if (++this.toolCallLogCounter % 200 === 0) {
|
|
35351
35423
|
this.db.prepare(
|
|
35352
35424
|
"DELETE FROM mesh_tool_call_log WHERE called_at < ?"
|
|
35353
35425
|
).run(now - Math.max(windowMs * 10, 6e4));
|
|
@@ -35800,9 +35872,9 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
35800
35872
|
}
|
|
35801
35873
|
return targetIds.map((taskId) => {
|
|
35802
35874
|
const queueEntry = queueById.get(taskId);
|
|
35803
|
-
const status = queueEntry?.status ?? "unknown";
|
|
35804
35875
|
const dispatch = dispatches.get(taskId);
|
|
35805
35876
|
const terminal = terminals.get(taskId);
|
|
35877
|
+
const status = queueEntry?.status ?? (terminal ? terminal.kind === "task_completed" ? "completed" : "failed" : "unknown");
|
|
35806
35878
|
const isTerminalStatus = status === "completed" || status === "failed" || status === "cancelled";
|
|
35807
35879
|
const dispatchTime = parseTime(dispatch?.first ?? queueEntry?.dispatchTimestamp);
|
|
35808
35880
|
const terminalTime = parseTime(terminal?.at);
|
|
@@ -37700,6 +37772,35 @@ ${rendered}`, "utf-8");
|
|
|
37700
37772
|
if (!trimmed) return false;
|
|
37701
37773
|
return normalizeMeshNodeId(node) === trimmed;
|
|
37702
37774
|
}
|
|
37775
|
+
function machineCoreFromDaemonId(id) {
|
|
37776
|
+
const trimmed = readString5(id);
|
|
37777
|
+
if (!trimmed) return void 0;
|
|
37778
|
+
for (const prefix of DAEMON_ID_PREFIXES) {
|
|
37779
|
+
if (trimmed.startsWith(prefix)) {
|
|
37780
|
+
const core = trimmed.slice(prefix.length).trim();
|
|
37781
|
+
return core || void 0;
|
|
37782
|
+
}
|
|
37783
|
+
}
|
|
37784
|
+
return trimmed;
|
|
37785
|
+
}
|
|
37786
|
+
function expandDaemonIdForms(ids) {
|
|
37787
|
+
const list = Array.isArray(ids) ? ids : ids != null ? [ids] : [];
|
|
37788
|
+
const out = [];
|
|
37789
|
+
const seen = /* @__PURE__ */ new Set();
|
|
37790
|
+
const add = (value) => {
|
|
37791
|
+
if (!value || seen.has(value)) return;
|
|
37792
|
+
seen.add(value);
|
|
37793
|
+
out.push(value);
|
|
37794
|
+
};
|
|
37795
|
+
for (const raw of list) add(readString5(raw));
|
|
37796
|
+
for (const raw of list) {
|
|
37797
|
+
const core = machineCoreFromDaemonId(readString5(raw));
|
|
37798
|
+
if (!core || !core.startsWith("mach_")) continue;
|
|
37799
|
+
add(core);
|
|
37800
|
+
for (const prefix of DAEMON_ID_PREFIXES) add(`${prefix}${core}`);
|
|
37801
|
+
}
|
|
37802
|
+
return out;
|
|
37803
|
+
}
|
|
37703
37804
|
function summarizeGitShape(status) {
|
|
37704
37805
|
const record2 = readRecord3(status);
|
|
37705
37806
|
if (!Object.keys(record2).length) return null;
|
|
@@ -37734,9 +37835,11 @@ ${rendered}`, "utf-8");
|
|
|
37734
37835
|
submodules
|
|
37735
37836
|
};
|
|
37736
37837
|
}
|
|
37838
|
+
var DAEMON_ID_PREFIXES;
|
|
37737
37839
|
var init_dist = __esm2({
|
|
37738
37840
|
"../mesh-shared/dist/index.mjs"() {
|
|
37739
37841
|
"use strict";
|
|
37842
|
+
DAEMON_ID_PREFIXES = ["daemon_", "standalone_"];
|
|
37740
37843
|
}
|
|
37741
37844
|
});
|
|
37742
37845
|
function readString6(value) {
|
|
@@ -37812,6 +37915,14 @@ ${rendered}`, "utf-8");
|
|
|
37812
37915
|
if (entry.kind === "task_completed") return "idle";
|
|
37813
37916
|
return "failed";
|
|
37814
37917
|
}
|
|
37918
|
+
function classifyDirectDispatch(params) {
|
|
37919
|
+
const { status, isTerminalRow, hasTerminalStatus, liveStatus, liveStaleReason, dispatchedToIdleSession } = params;
|
|
37920
|
+
const isNoTransition = !hasTerminalStatus && !liveStatus;
|
|
37921
|
+
const isIdleUnacknowledged = status === "idle";
|
|
37922
|
+
const ledgerOnlyStaleReason = !isTerminalRow && (isIdleUnacknowledged || isNoTransition || dispatchedToIdleSession && isIdleUnacknowledged) ? LEDGER_ONLY_STALE_REASON : void 0;
|
|
37923
|
+
const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !liveStaleReason);
|
|
37924
|
+
return { ledgerOnlyStaleReason, isFreshUnacknowledged };
|
|
37925
|
+
}
|
|
37815
37926
|
function buildMeshActiveWorkSummary(activeWork) {
|
|
37816
37927
|
const statusCounts = {
|
|
37817
37928
|
pending: 0,
|
|
@@ -37874,10 +37985,14 @@ ${rendered}`, "utf-8");
|
|
|
37874
37985
|
const dbStatus = dispatch.status;
|
|
37875
37986
|
const isTerminal = dbStatus === "completed" || dbStatus === "failed" || dbStatus === "stale";
|
|
37876
37987
|
const status = isTerminal ? dbStatus === "completed" ? "idle" : "failed" : live.status || (dbStatus === "acked" ? "generating" : "assigned");
|
|
37877
|
-
const
|
|
37878
|
-
|
|
37879
|
-
|
|
37880
|
-
|
|
37988
|
+
const { ledgerOnlyStaleReason, isFreshUnacknowledged } = classifyDirectDispatch({
|
|
37989
|
+
status,
|
|
37990
|
+
isTerminalRow: isTerminal,
|
|
37991
|
+
hasTerminalStatus: isTerminal,
|
|
37992
|
+
liveStatus: live.status,
|
|
37993
|
+
liveStaleReason: live.staleReason,
|
|
37994
|
+
dispatchedToIdleSession: dispatch.dispatchedToIdleSession === true
|
|
37995
|
+
});
|
|
37881
37996
|
const { title, summary: summary2 } = summarizeMessage(dispatch.message || "");
|
|
37882
37997
|
const record2 = {
|
|
37883
37998
|
taskId: dispatch.taskId,
|
|
@@ -37920,13 +38035,16 @@ ${rendered}`, "utf-8");
|
|
|
37920
38035
|
const live = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
|
|
37921
38036
|
const status = terminalStatus || live.status || "assigned";
|
|
37922
38037
|
const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
|
|
37923
|
-
const
|
|
37924
|
-
|
|
37925
|
-
|
|
37926
|
-
|
|
38038
|
+
const { ledgerOnlyStaleReason, isFreshUnacknowledged } = classifyDirectDispatch({
|
|
38039
|
+
status,
|
|
38040
|
+
isTerminalRow: terminalRow,
|
|
38041
|
+
hasTerminalStatus: Boolean(terminalStatus),
|
|
38042
|
+
liveStatus: live.status,
|
|
38043
|
+
liveStaleReason: live.staleReason,
|
|
38044
|
+
dispatchedToIdleSession: dispatch.payload?.dispatchedToIdleSession === true
|
|
38045
|
+
});
|
|
37927
38046
|
const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
|
|
37928
38047
|
const { title, summary: summary2 } = summarizeMessage(message);
|
|
37929
|
-
const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
|
|
37930
38048
|
const record2 = {
|
|
37931
38049
|
taskId,
|
|
37932
38050
|
source: "direct",
|
|
@@ -37968,13 +38086,16 @@ ${rendered}`, "utf-8");
|
|
|
37968
38086
|
const live = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
|
|
37969
38087
|
const status = terminalStatus || live.status || "assigned";
|
|
37970
38088
|
const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
|
|
37971
|
-
const
|
|
37972
|
-
|
|
37973
|
-
|
|
37974
|
-
|
|
38089
|
+
const { ledgerOnlyStaleReason, isFreshUnacknowledged } = classifyDirectDispatch({
|
|
38090
|
+
status,
|
|
38091
|
+
isTerminalRow: terminalRow,
|
|
38092
|
+
hasTerminalStatus: Boolean(terminalStatus),
|
|
38093
|
+
liveStatus: live.status,
|
|
38094
|
+
liveStaleReason: live.staleReason,
|
|
38095
|
+
dispatchedToIdleSession: dispatch.payload?.dispatchedToIdleSession === true
|
|
38096
|
+
});
|
|
37975
38097
|
const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
|
|
37976
38098
|
const { title, summary: summary2 } = summarizeMessage(message);
|
|
37977
|
-
const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !live.staleReason);
|
|
37978
38099
|
const record2 = {
|
|
37979
38100
|
taskId,
|
|
37980
38101
|
source: "direct",
|
|
@@ -38127,6 +38248,7 @@ ${rendered}`, "utf-8");
|
|
|
38127
38248
|
}
|
|
38128
38249
|
var DIRECT_DISPATCH_VIA;
|
|
38129
38250
|
var TERMINAL_LEDGER_KINDS;
|
|
38251
|
+
var LEDGER_ONLY_STALE_REASON;
|
|
38130
38252
|
var PRUNABLE_ORPHAN_STALE_REASONS;
|
|
38131
38253
|
var init_mesh_active_work = __esm2({
|
|
38132
38254
|
"src/mesh/mesh-active-work.ts"() {
|
|
@@ -38136,6 +38258,7 @@ ${rendered}`, "utf-8");
|
|
|
38136
38258
|
init_dist();
|
|
38137
38259
|
DIRECT_DISPATCH_VIA = /* @__PURE__ */ new Set(["p2p_direct", "local_direct", "mesh_send_task"]);
|
|
38138
38260
|
TERMINAL_LEDGER_KINDS = /* @__PURE__ */ new Set(["task_completed", "task_failed", "task_stalled"]);
|
|
38261
|
+
LEDGER_ONLY_STALE_REASON = "direct task dispatch has no provider acknowledgement, transcript append, or active runtime transition";
|
|
38139
38262
|
PRUNABLE_ORPHAN_STALE_REASONS = /* @__PURE__ */ new Set([
|
|
38140
38263
|
"direct task node is no longer in the live mesh",
|
|
38141
38264
|
"direct task session is not present in live session records",
|
|
@@ -38371,17 +38494,7 @@ Next step: ${nextStep}`;
|
|
|
38371
38494
|
}
|
|
38372
38495
|
});
|
|
38373
38496
|
function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
|
|
38374
|
-
|
|
38375
|
-
const seen = /* @__PURE__ */ new Set();
|
|
38376
|
-
const out = [];
|
|
38377
|
-
for (const id of raw) {
|
|
38378
|
-
if (typeof id !== "string") continue;
|
|
38379
|
-
const trimmed = id.trim();
|
|
38380
|
-
if (!trimmed || seen.has(trimmed)) continue;
|
|
38381
|
-
seen.add(trimmed);
|
|
38382
|
-
out.push(trimmed);
|
|
38383
|
-
}
|
|
38384
|
-
return out;
|
|
38497
|
+
return expandDaemonIdForms(coordinatorDaemonId);
|
|
38385
38498
|
}
|
|
38386
38499
|
function readRefineJobId2(event) {
|
|
38387
38500
|
const metadata = readRecord4(event.metadataEvent) || event;
|
|
@@ -38569,6 +38682,7 @@ Next step: ${nextStep}`;
|
|
|
38569
38682
|
return true;
|
|
38570
38683
|
}
|
|
38571
38684
|
const fingerprint = buildPendingEventFingerprint(event);
|
|
38685
|
+
let sqliteOk = false;
|
|
38572
38686
|
try {
|
|
38573
38687
|
MeshRuntimeStore.getInstance().insertPendingEvent({
|
|
38574
38688
|
id: (0, import_crypto7.randomUUID)(),
|
|
@@ -38579,11 +38693,17 @@ Next step: ${nextStep}`;
|
|
|
38579
38693
|
fingerprint: fingerprint || null,
|
|
38580
38694
|
queuedAt: event.queuedAt
|
|
38581
38695
|
});
|
|
38696
|
+
sqliteOk = true;
|
|
38582
38697
|
} catch {
|
|
38583
38698
|
}
|
|
38584
|
-
|
|
38585
|
-
|
|
38586
|
-
|
|
38699
|
+
try {
|
|
38700
|
+
const path422 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
38701
|
+
trimPendingEventsIfNeeded(path422);
|
|
38702
|
+
(0, import_fs10.appendFileSync)(path422, JSON.stringify(event) + "\n", "utf-8");
|
|
38703
|
+
} catch (e) {
|
|
38704
|
+
if (!sqliteOk) throw e;
|
|
38705
|
+
LOG2.warn("MeshEvents", `JSONL append failed for mesh ${event.meshId}; SQLite holds the event: ${e?.message || e}`);
|
|
38706
|
+
}
|
|
38587
38707
|
return true;
|
|
38588
38708
|
} catch (e) {
|
|
38589
38709
|
LOG2.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
@@ -38769,6 +38889,7 @@ Next step: ${nextStep}`;
|
|
|
38769
38889
|
init_mesh_ledger();
|
|
38770
38890
|
init_mesh_runtime_store();
|
|
38771
38891
|
init_mesh_events_utils();
|
|
38892
|
+
init_dist();
|
|
38772
38893
|
REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
|
|
38773
38894
|
MAX_PENDING_EVENTS_BYTES = 100 * 1024;
|
|
38774
38895
|
MAX_PENDING_EVENTS_KEEP = 50;
|
|
@@ -38986,6 +39107,12 @@ Next step: ${nextStep}`;
|
|
|
38986
39107
|
}
|
|
38987
39108
|
return false;
|
|
38988
39109
|
}
|
|
39110
|
+
function isWeakCompletionLedgerPayload(payload) {
|
|
39111
|
+
if (!payload) return false;
|
|
39112
|
+
if (payload.evidenceLevel === "insufficient" || payload.reviewRecommended === true) return true;
|
|
39113
|
+
const diag = readRecord4(payload.completionDiagnostic);
|
|
39114
|
+
return diag?.finalAssistantPresent === false || diag?.blockReason === "missing_final_assistant";
|
|
39115
|
+
}
|
|
38989
39116
|
function findDirectDispatchLedgerEntry(args) {
|
|
38990
39117
|
const entries = readLedgerEntries(args.meshId, { tail: 500 });
|
|
38991
39118
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
@@ -39022,6 +39149,7 @@ Next step: ${nextStep}`;
|
|
|
39022
39149
|
if (!afterDispatch) continue;
|
|
39023
39150
|
}
|
|
39024
39151
|
if (entry.kind !== "task_completed" && entry.kind !== "task_failed" && entry.kind !== "task_stalled") continue;
|
|
39152
|
+
if (entry.kind === "task_completed" && isWeakCompletionLedgerPayload(entry.payload)) continue;
|
|
39025
39153
|
const terminalTaskId = readNonEmptyString2(entry.payload?.taskId);
|
|
39026
39154
|
if (terminalTaskId && terminalTaskId === args.taskId) return true;
|
|
39027
39155
|
if (terminalTaskId && terminalTaskId !== args.taskId) continue;
|
|
@@ -42219,12 +42347,9 @@ ${cleanBody}`;
|
|
|
42219
42347
|
}
|
|
42220
42348
|
});
|
|
42221
42349
|
function resolveCoordinatorDrainDaemonIds(components) {
|
|
42222
|
-
const ids = /* @__PURE__ */ new Set();
|
|
42223
42350
|
const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
|
|
42224
|
-
if (statusInstanceId) ids.add(statusInstanceId);
|
|
42225
42351
|
const machineId = readNonEmptyString2(loadConfig2().machineId);
|
|
42226
|
-
|
|
42227
|
-
return [...ids];
|
|
42352
|
+
return expandDaemonIdForms([statusInstanceId, machineId]);
|
|
42228
42353
|
}
|
|
42229
42354
|
function getCachedMeshByWorkspace(workspace) {
|
|
42230
42355
|
const now = Date.now();
|
|
@@ -42351,6 +42476,79 @@ ${cleanBody}`;
|
|
|
42351
42476
|
recordFingerprintSeen(fingerprint);
|
|
42352
42477
|
return false;
|
|
42353
42478
|
}
|
|
42479
|
+
function isFalseIdleCompletion(metadataEvent) {
|
|
42480
|
+
const diag = readRecord4(metadataEvent.completionDiagnostic);
|
|
42481
|
+
if (!diag) return false;
|
|
42482
|
+
return diag.finalAssistantPresent === false || diag.blockReason === "missing_final_assistant";
|
|
42483
|
+
}
|
|
42484
|
+
function isGenuineCompletionEvidence(metadataEvent) {
|
|
42485
|
+
if (isFalseIdleCompletion(metadataEvent)) return false;
|
|
42486
|
+
return !!readWorkerResultMetadata(metadataEvent) || !!readNonEmptyString2(metadataEvent.finalSummary);
|
|
42487
|
+
}
|
|
42488
|
+
function isWeakTerminalLedgerPayload(payload) {
|
|
42489
|
+
if (!payload) return false;
|
|
42490
|
+
if (payload.evidenceLevel === "insufficient" || payload.reviewRecommended === true) return true;
|
|
42491
|
+
const diag = readRecord4(payload.completionDiagnostic);
|
|
42492
|
+
return diag?.finalAssistantPresent === false || diag?.blockReason === "missing_final_assistant";
|
|
42493
|
+
}
|
|
42494
|
+
function resolveActiveDirectDispatchTaskId(meshId, sessionId) {
|
|
42495
|
+
try {
|
|
42496
|
+
const matches = getActiveDirectDispatches(meshId).filter((d) => d.sessionId === sessionId);
|
|
42497
|
+
if (!matches.length) return void 0;
|
|
42498
|
+
return readNonEmptyString2(matches[matches.length - 1].taskId) || void 0;
|
|
42499
|
+
} catch {
|
|
42500
|
+
return void 0;
|
|
42501
|
+
}
|
|
42502
|
+
}
|
|
42503
|
+
function deliverTaskToSession(dispatchThunk, ctx) {
|
|
42504
|
+
const delivery = createSessionDelivery({
|
|
42505
|
+
meshId: ctx.meshId,
|
|
42506
|
+
nodeId: ctx.nodeId,
|
|
42507
|
+
sessionId: ctx.sessionId,
|
|
42508
|
+
providerType: ctx.providerType,
|
|
42509
|
+
taskId: ctx.task.id,
|
|
42510
|
+
kind: "task",
|
|
42511
|
+
message: ctx.task.message,
|
|
42512
|
+
status: "delivering",
|
|
42513
|
+
...ctx.sourceCoordinatorSessionId ? { sourceCoordinatorSessionId: ctx.sourceCoordinatorSessionId } : {},
|
|
42514
|
+
...ctx.sourceCoordinatorDaemonId ? { sourceCoordinatorDaemonId: ctx.sourceCoordinatorDaemonId } : {}
|
|
42515
|
+
});
|
|
42516
|
+
let dispatchPromise;
|
|
42517
|
+
try {
|
|
42518
|
+
dispatchPromise = Promise.resolve(dispatchThunk());
|
|
42519
|
+
} catch (e) {
|
|
42520
|
+
dispatchPromise = Promise.reject(e);
|
|
42521
|
+
}
|
|
42522
|
+
let timer;
|
|
42523
|
+
const guarded = Promise.race([
|
|
42524
|
+
dispatchPromise,
|
|
42525
|
+
new Promise((_, reject) => {
|
|
42526
|
+
timer = setTimeout(
|
|
42527
|
+
() => reject(new Error(`dispatch_confirm_timeout after ${DISPATCH_CONFIRM_TIMEOUT_MS}ms`)),
|
|
42528
|
+
DISPATCH_CONFIRM_TIMEOUT_MS
|
|
42529
|
+
);
|
|
42530
|
+
if (typeof timer?.unref === "function") timer.unref();
|
|
42531
|
+
})
|
|
42532
|
+
]);
|
|
42533
|
+
guarded.then(() => {
|
|
42534
|
+
if (timer) clearTimeout(timer);
|
|
42535
|
+
updateSessionDeliveryStatus(delivery.id, "delivered");
|
|
42536
|
+
}).catch((e) => {
|
|
42537
|
+
if (timer) clearTimeout(timer);
|
|
42538
|
+
LOG2.error("MeshQueue", `Failed to dispatch task via ${ctx.transport} to node ${ctx.nodeId}: ${e?.message}`);
|
|
42539
|
+
updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
42540
|
+
updateTaskStatus(ctx.meshId, ctx.task.id, "pending");
|
|
42541
|
+
try {
|
|
42542
|
+
appendLedgerEntry(ctx.meshId, {
|
|
42543
|
+
kind: "dispatch_failed",
|
|
42544
|
+
nodeId: ctx.nodeId,
|
|
42545
|
+
sessionId: ctx.sessionId,
|
|
42546
|
+
payload: { taskId: ctx.task.id, deliveryId: delivery.id, error: e?.message, retryable: true, transport: ctx.transport }
|
|
42547
|
+
});
|
|
42548
|
+
} catch {
|
|
42549
|
+
}
|
|
42550
|
+
});
|
|
42551
|
+
}
|
|
42354
42552
|
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
|
|
42355
42553
|
const mesh = getMeshWithCache(components, meshId);
|
|
42356
42554
|
const node = mesh?.nodes.find((n) => readMeshNodeId(n) === nodeId);
|
|
@@ -42369,46 +42567,33 @@ ${cleanBody}`;
|
|
|
42369
42567
|
if (!isLocalNode) {
|
|
42370
42568
|
const localDaemonIdForDispatch = readNonEmptyString2(loadConfig2().machineId) || void 0;
|
|
42371
42569
|
const sourceCoordinatorSessionId = readNonEmptyString2(task.sourceCoordinatorSessionId) || void 0;
|
|
42372
|
-
const
|
|
42373
|
-
|
|
42374
|
-
|
|
42375
|
-
|
|
42376
|
-
|
|
42377
|
-
|
|
42378
|
-
|
|
42379
|
-
|
|
42380
|
-
|
|
42381
|
-
|
|
42382
|
-
|
|
42383
|
-
|
|
42384
|
-
|
|
42385
|
-
|
|
42386
|
-
|
|
42387
|
-
|
|
42388
|
-
|
|
42389
|
-
meshContext: {
|
|
42570
|
+
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
42571
|
+
const remoteDaemonId = node.daemonId;
|
|
42572
|
+
deliverTaskToSession(
|
|
42573
|
+
() => dispatchMeshCommand(remoteDaemonId, "agent_command", {
|
|
42574
|
+
targetSessionId: sessionId,
|
|
42575
|
+
cliType: providerType,
|
|
42576
|
+
action: "send_chat",
|
|
42577
|
+
message: task.message,
|
|
42578
|
+
meshContext: {
|
|
42579
|
+
meshId,
|
|
42580
|
+
nodeId,
|
|
42581
|
+
taskId: task.id,
|
|
42582
|
+
...localDaemonIdForDispatch ? { coordinatorDaemonId: localDaemonIdForDispatch } : {},
|
|
42583
|
+
...sourceCoordinatorSessionId ? { coordinatorSessionId: sourceCoordinatorSessionId } : {}
|
|
42584
|
+
}
|
|
42585
|
+
}),
|
|
42586
|
+
{
|
|
42390
42587
|
meshId,
|
|
42391
42588
|
nodeId,
|
|
42392
|
-
|
|
42393
|
-
|
|
42394
|
-
|
|
42395
|
-
|
|
42396
|
-
|
|
42397
|
-
|
|
42398
|
-
}).catch((e) => {
|
|
42399
|
-
LOG2.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
|
|
42400
|
-
updateSessionDeliveryStatus(delivery2.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
42401
|
-
updateTaskStatus(meshId, task.id, "pending");
|
|
42402
|
-
try {
|
|
42403
|
-
appendLedgerEntry(meshId, {
|
|
42404
|
-
kind: "dispatch_failed",
|
|
42405
|
-
nodeId,
|
|
42406
|
-
sessionId,
|
|
42407
|
-
payload: { taskId: task.id, deliveryId: delivery2.id, error: e?.message, retryable: true }
|
|
42408
|
-
});
|
|
42409
|
-
} catch {
|
|
42589
|
+
sessionId,
|
|
42590
|
+
providerType,
|
|
42591
|
+
task,
|
|
42592
|
+
transport: "remote",
|
|
42593
|
+
...sourceCoordinatorSessionId ? { sourceCoordinatorSessionId } : {},
|
|
42594
|
+
...localDaemonIdForDispatch ? { sourceCoordinatorDaemonId: localDaemonIdForDispatch } : {}
|
|
42410
42595
|
}
|
|
42411
|
-
|
|
42596
|
+
);
|
|
42412
42597
|
return true;
|
|
42413
42598
|
}
|
|
42414
42599
|
}
|
|
@@ -42430,39 +42615,24 @@ ${cleanBody}`;
|
|
|
42430
42615
|
}
|
|
42431
42616
|
} catch {
|
|
42432
42617
|
}
|
|
42433
|
-
|
|
42434
|
-
|
|
42435
|
-
|
|
42436
|
-
|
|
42437
|
-
|
|
42438
|
-
|
|
42439
|
-
|
|
42440
|
-
|
|
42441
|
-
|
|
42442
|
-
|
|
42443
|
-
|
|
42444
|
-
|
|
42445
|
-
|
|
42446
|
-
|
|
42447
|
-
|
|
42448
|
-
|
|
42449
|
-
message: task.message
|
|
42450
|
-
}).then(() => {
|
|
42451
|
-
updateSessionDeliveryStatus(delivery.id, "delivered");
|
|
42452
|
-
}).catch((e) => {
|
|
42453
|
-
LOG2.error("MeshQueue", `Failed to dispatch task locally to node ${nodeId}: ${e?.message}`);
|
|
42454
|
-
updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
42455
|
-
updateTaskStatus(meshId, task.id, "pending");
|
|
42456
|
-
try {
|
|
42457
|
-
appendLedgerEntry(meshId, {
|
|
42458
|
-
kind: "dispatch_failed",
|
|
42459
|
-
nodeId,
|
|
42460
|
-
sessionId,
|
|
42461
|
-
payload: { taskId: task.id, deliveryId: delivery.id, error: e?.message, retryable: true }
|
|
42462
|
-
});
|
|
42463
|
-
} catch {
|
|
42618
|
+
deliverTaskToSession(
|
|
42619
|
+
() => components.cliManager.handleCliCommand("agent_command", {
|
|
42620
|
+
targetSessionId: sessionId,
|
|
42621
|
+
cliType: providerType,
|
|
42622
|
+
action: "send_chat",
|
|
42623
|
+
message: task.message
|
|
42624
|
+
}),
|
|
42625
|
+
{
|
|
42626
|
+
meshId,
|
|
42627
|
+
nodeId,
|
|
42628
|
+
sessionId,
|
|
42629
|
+
providerType,
|
|
42630
|
+
task,
|
|
42631
|
+
transport: "local",
|
|
42632
|
+
...readNonEmptyString2(task.sourceCoordinatorSessionId) ? { sourceCoordinatorSessionId: readNonEmptyString2(task.sourceCoordinatorSessionId) } : {},
|
|
42633
|
+
...readNonEmptyString2(loadConfig2().machineId) ? { sourceCoordinatorDaemonId: readNonEmptyString2(loadConfig2().machineId) } : {}
|
|
42464
42634
|
}
|
|
42465
|
-
|
|
42635
|
+
);
|
|
42466
42636
|
return true;
|
|
42467
42637
|
}
|
|
42468
42638
|
function sweepExpiredCooldowns() {
|
|
@@ -42727,7 +42897,7 @@ ${cleanBody}`;
|
|
|
42727
42897
|
}
|
|
42728
42898
|
}
|
|
42729
42899
|
const candidateNodes = Array.isArray(mesh?.nodes) ? mesh.nodes.filter((node) => {
|
|
42730
|
-
if (task.targetNodeId &&
|
|
42900
|
+
if (task.targetNodeId && !meshNodeIdMatches(node, task.targetNodeId)) return false;
|
|
42731
42901
|
if (task.requiredTags?.length) {
|
|
42732
42902
|
const priorities = normalizeProviderPriority(node?.policy);
|
|
42733
42903
|
const providerCandidates = priorities.length ? priorities : [void 0];
|
|
@@ -42738,7 +42908,12 @@ ${cleanBody}`;
|
|
|
42738
42908
|
return true;
|
|
42739
42909
|
}) : [];
|
|
42740
42910
|
if (!candidateNodes.length) {
|
|
42741
|
-
|
|
42911
|
+
const targetPinUnmatched = !!task.targetNodeId && !(Array.isArray(mesh?.nodes) && mesh.nodes.some((n) => meshNodeIdMatches(n, task.targetNodeId)));
|
|
42912
|
+
markAutoLaunch(meshId, task.id, {
|
|
42913
|
+
status: "skipped",
|
|
42914
|
+
reason: targetPinUnmatched ? "target_node_id_unmatched" : "no_node_satisfies_required_tags",
|
|
42915
|
+
nodeId: task.targetNodeId
|
|
42916
|
+
});
|
|
42742
42917
|
continue;
|
|
42743
42918
|
}
|
|
42744
42919
|
const strategy = resolveSchedulingStrategy(mesh);
|
|
@@ -43195,7 +43370,8 @@ ${cleanBody}`;
|
|
|
43195
43370
|
});
|
|
43196
43371
|
if (terminal?.kind === "task_completed" && !sessionHasActiveAssignment(args.meshId, eventSessionId)) {
|
|
43197
43372
|
const newDispatchAfterTerminal = hasDispatchAfterTerminal(args.meshId, eventSessionId, terminal.id);
|
|
43198
|
-
|
|
43373
|
+
const supersedesWeakTerminal = isWeakTerminalLedgerPayload(terminal.payload) && isGenuineCompletionEvidence(args.metadataEvent);
|
|
43374
|
+
if (!newDispatchAfterTerminal && !supersedesWeakTerminal) {
|
|
43199
43375
|
const terminalProviderSessionId = readNonEmptyString2(terminal.payload.providerSessionId);
|
|
43200
43376
|
const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
|
|
43201
43377
|
const eventProviderSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
|
|
@@ -43241,24 +43417,30 @@ ${cleanBody}`;
|
|
|
43241
43417
|
return { success: true, forwarded: 0, suppressed: true, duplicateStopped: true };
|
|
43242
43418
|
}
|
|
43243
43419
|
}
|
|
43244
|
-
function markSessionTerminal(sessionId, outcome, occurredAtMs) {
|
|
43420
|
+
function markSessionTerminal(sessionId, outcome, occurredAtMs, opts) {
|
|
43245
43421
|
const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId) || void 0;
|
|
43246
43422
|
const task = updateSessionTaskStatus(args.meshId, sessionId, outcome, {
|
|
43247
43423
|
occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0,
|
|
43248
43424
|
taskId: eventTaskId
|
|
43249
43425
|
});
|
|
43250
|
-
|
|
43426
|
+
const leaveDirectDispatchActive = !task && opts?.tentativeIfDirect === true;
|
|
43427
|
+
if (!leaveDirectDispatchActive) {
|
|
43428
|
+
updateDirectDispatchStatus(args.meshId, sessionId, outcome);
|
|
43429
|
+
}
|
|
43251
43430
|
markSessionDeliveriesTerminal(args.meshId, sessionId, outcome);
|
|
43252
43431
|
setImmediate(() => cleanupTerminalDirectDispatches());
|
|
43253
43432
|
return task ? { id: task.id } : null;
|
|
43254
43433
|
}
|
|
43255
43434
|
let completedTaskForLedger = null;
|
|
43435
|
+
let directDispatchTaskIdForLedger;
|
|
43256
43436
|
if (args.event === "agent:generating_completed") {
|
|
43257
43437
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
43258
43438
|
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
43259
43439
|
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
43260
43440
|
if (sessionId) {
|
|
43261
|
-
|
|
43441
|
+
directDispatchTaskIdForLedger = resolveActiveDirectDispatchTaskId(args.meshId, sessionId);
|
|
43442
|
+
const isFalseIdle = isFalseIdleCompletion(args.metadataEvent);
|
|
43443
|
+
completedTaskForLedger = markSessionTerminal(sessionId, "completed", eventTimestamp, { tentativeIfDirect: isFalseIdle });
|
|
43262
43444
|
if (nodeId && providerType) {
|
|
43263
43445
|
runIdleMaintenanceThenAssignQueue(components, { meshId: args.meshId, nodeId, sessionId, providerType });
|
|
43264
43446
|
}
|
|
@@ -43361,6 +43543,7 @@ ${cleanBody}`;
|
|
|
43361
43543
|
}
|
|
43362
43544
|
}
|
|
43363
43545
|
if (sessionId) {
|
|
43546
|
+
directDispatchTaskIdForLedger = resolveActiveDirectDispatchTaskId(args.meshId, sessionId);
|
|
43364
43547
|
completedTaskForLedger = markSessionTerminal(sessionId, "failed");
|
|
43365
43548
|
}
|
|
43366
43549
|
}
|
|
@@ -43390,7 +43573,10 @@ ${cleanBody}`;
|
|
|
43390
43573
|
payload: {
|
|
43391
43574
|
event: args.event,
|
|
43392
43575
|
nodeLabel: args.nodeLabel,
|
|
43393
|
-
|
|
43576
|
+
// Fix B: fall back to the direct-dispatch taskId when no work-queue row
|
|
43577
|
+
// matched, so the terminal entry is attributable in mesh task-stats
|
|
43578
|
+
// (otherwise the direct task shows status='unknown' / terminalKind=null).
|
|
43579
|
+
taskId: completedTaskForLedger?.id || directDispatchTaskIdForLedger || void 0,
|
|
43394
43580
|
providerSessionId,
|
|
43395
43581
|
finalSummary,
|
|
43396
43582
|
workerResult,
|
|
@@ -43686,6 +43872,7 @@ ${cleanBody}`;
|
|
|
43686
43872
|
var idleAutoFastForwardLastAttempt;
|
|
43687
43873
|
var INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS;
|
|
43688
43874
|
var RECENT_COMPLETION_FINGERPRINT_TTL_MS;
|
|
43875
|
+
var DISPATCH_CONFIRM_TIMEOUT_MS;
|
|
43689
43876
|
var autoLaunchInProgress;
|
|
43690
43877
|
var autoLaunchCooldownUntil;
|
|
43691
43878
|
var AUTO_LAUNCH_COOLDOWN_MS;
|
|
@@ -43723,6 +43910,7 @@ ${cleanBody}`;
|
|
|
43723
43910
|
idleAutoFastForwardLastAttempt = /* @__PURE__ */ new Map();
|
|
43724
43911
|
INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
|
|
43725
43912
|
RECENT_COMPLETION_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
|
|
43913
|
+
DISPATCH_CONFIRM_TIMEOUT_MS = 12e4;
|
|
43726
43914
|
autoLaunchInProgress = /* @__PURE__ */ new Set();
|
|
43727
43915
|
autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
|
|
43728
43916
|
AUTO_LAUNCH_COOLDOWN_MS = 5e3;
|
|
@@ -43776,12 +43964,9 @@ ${cleanBody}`;
|
|
|
43776
43964
|
return DEFAULT_RECONCILE_INTERVAL_MS;
|
|
43777
43965
|
}
|
|
43778
43966
|
function resolveCoordinatorDaemonIds(components) {
|
|
43779
|
-
const ids = /* @__PURE__ */ new Set();
|
|
43780
43967
|
const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
|
|
43781
|
-
if (statusInstanceId) ids.add(statusInstanceId);
|
|
43782
43968
|
const machineId = readNonEmptyString2(loadConfig2().machineId);
|
|
43783
|
-
|
|
43784
|
-
return [...ids];
|
|
43969
|
+
return expandDaemonIdForms([statusInstanceId, machineId]);
|
|
43785
43970
|
}
|
|
43786
43971
|
function daemonHostsMesh(mesh, daemonIds) {
|
|
43787
43972
|
const host = mesh.meshHost;
|
|
@@ -43865,6 +44050,24 @@ ${cleanBody}`;
|
|
|
43865
44050
|
}
|
|
43866
44051
|
}
|
|
43867
44052
|
}
|
|
44053
|
+
function recoverStrandedAssignedDispatches(meshId, store) {
|
|
44054
|
+
const assigned = getQueue(meshId, { status: ["assigned"] });
|
|
44055
|
+
if (!assigned.length) return;
|
|
44056
|
+
const nowMs = Date.now();
|
|
44057
|
+
for (const row of assigned) {
|
|
44058
|
+
const dispatchedAtMs = Date.parse(row.dispatchTimestamp ?? "");
|
|
44059
|
+
if (!Number.isFinite(dispatchedAtMs)) continue;
|
|
44060
|
+
if (nowMs - dispatchedAtMs < ASSIGNED_STRANDED_DEADLINE_MS) continue;
|
|
44061
|
+
if (store.taskHasConfirmedDelivery(meshId, row.id)) continue;
|
|
44062
|
+
const reclaimed = reclaimStrandedAssignedTask(meshId, row.id, {
|
|
44063
|
+
reason: "assigned_stranded_dispatch_unconfirmed",
|
|
44064
|
+
ageMs: nowMs - dispatchedAtMs
|
|
44065
|
+
});
|
|
44066
|
+
if (reclaimed) {
|
|
44067
|
+
LOG2.warn("MeshReconcile", `Reclaimed stranded assigned task ${row.id} on mesh ${meshId} (node=${row.assignedNodeId ?? "?"} session=${row.assignedSessionId ?? "?"}, dispatched ${Math.round((nowMs - dispatchedAtMs) / 1e3)}s ago, never confirmed delivered \u2192 ${reclaimed.status})`);
|
|
44068
|
+
}
|
|
44069
|
+
}
|
|
44070
|
+
}
|
|
43868
44071
|
async function runMeshReconcileTick(components) {
|
|
43869
44072
|
const localDaemonId = readNonEmptyString2(loadConfig2().machineId) || void 0;
|
|
43870
44073
|
const drainDaemonIds = resolveCoordinatorDaemonIds(components);
|
|
@@ -43894,6 +44097,17 @@ ${cleanBody}`;
|
|
|
43894
44097
|
}
|
|
43895
44098
|
}
|
|
43896
44099
|
}
|
|
44100
|
+
if (store) {
|
|
44101
|
+
for (const mesh of listMeshes()) {
|
|
44102
|
+
const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
|
|
44103
|
+
if (!daemonHostsMesh(mesh, selfIds)) continue;
|
|
44104
|
+
try {
|
|
44105
|
+
recoverStrandedAssignedDispatches(mesh.id, store);
|
|
44106
|
+
} catch (e) {
|
|
44107
|
+
LOG2.warn("MeshReconcile", `Assigned-stranded watchdog failed for mesh ${mesh.id}: ${e?.message || e}`);
|
|
44108
|
+
}
|
|
44109
|
+
}
|
|
44110
|
+
}
|
|
43897
44111
|
for (const mesh of listMeshes()) {
|
|
43898
44112
|
const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
|
|
43899
44113
|
if (!daemonHostsMesh(mesh, selfIds)) continue;
|
|
@@ -44284,6 +44498,7 @@ ${cleanBody}`;
|
|
|
44284
44498
|
var DEFAULT_RECONCILE_INTERVAL_MS;
|
|
44285
44499
|
var DEFAULT_AUTO_PRUNE_MIN_AGE_MS;
|
|
44286
44500
|
var heldEventLedgerRecorded;
|
|
44501
|
+
var ASSIGNED_STRANDED_DEADLINE_MS;
|
|
44287
44502
|
var STRICT_SESSION_MATCH_TTL_MS;
|
|
44288
44503
|
var init_mesh_reconcile_loop = __esm2({
|
|
44289
44504
|
"src/mesh/mesh-reconcile-loop.ts"() {
|
|
@@ -44297,6 +44512,7 @@ ${cleanBody}`;
|
|
|
44297
44512
|
init_mesh_events_coordinator();
|
|
44298
44513
|
init_mesh_unresolved_forward_outbox();
|
|
44299
44514
|
init_mesh_events_utils();
|
|
44515
|
+
init_dist();
|
|
44300
44516
|
init_mesh_work_queue();
|
|
44301
44517
|
init_mesh_ledger();
|
|
44302
44518
|
init_mesh_active_work();
|
|
@@ -44305,6 +44521,7 @@ ${cleanBody}`;
|
|
|
44305
44521
|
DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
|
|
44306
44522
|
DEFAULT_AUTO_PRUNE_MIN_AGE_MS = 24 * 60 * 6e4;
|
|
44307
44523
|
heldEventLedgerRecorded = /* @__PURE__ */ new Set();
|
|
44524
|
+
ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
|
|
44308
44525
|
STRICT_SESSION_MATCH_TTL_MS = 6e4;
|
|
44309
44526
|
}
|
|
44310
44527
|
});
|
|
@@ -44334,6 +44551,82 @@ ${cleanBody}`;
|
|
|
44334
44551
|
init_mesh_events_coordinator();
|
|
44335
44552
|
}
|
|
44336
44553
|
});
|
|
44554
|
+
function normalizeApprovalLabel(value) {
|
|
44555
|
+
return String(value || "").toLowerCase().replace(/^[\s\[(<{]*\d+(?:\s*[.)\]}>:-]|\s)+/, "").replace(/[^\p{L}\p{N}]+/gu, " ").trim();
|
|
44556
|
+
}
|
|
44557
|
+
function isNegativeApprovalLabel(value) {
|
|
44558
|
+
const label = normalizeApprovalLabel(value);
|
|
44559
|
+
return /^(no|deny|reject|cancel|skip|exit|stop)\b/.test(label) || /\bwithout\b/.test(label) || /\bdo not\b/.test(label);
|
|
44560
|
+
}
|
|
44561
|
+
function hasNegativeApprovalOption(buttons) {
|
|
44562
|
+
return (buttons || []).some((button) => isNegativeApprovalLabel(String(button || "")));
|
|
44563
|
+
}
|
|
44564
|
+
function getApprovalPositiveHints(provider) {
|
|
44565
|
+
const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
|
|
44566
|
+
return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
|
|
44567
|
+
}
|
|
44568
|
+
function pickApprovalButton(buttons, provider) {
|
|
44569
|
+
const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
|
|
44570
|
+
if (labels.length === 0) {
|
|
44571
|
+
return { index: -1, label: "" };
|
|
44572
|
+
}
|
|
44573
|
+
const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
|
|
44574
|
+
const hints = getApprovalPositiveHints(provider);
|
|
44575
|
+
for (const hint of hints) {
|
|
44576
|
+
const exactIndex = normalizedButtons.findIndex((label, index) => label === hint && !isNegativeApprovalLabel(labels[index]));
|
|
44577
|
+
if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
|
|
44578
|
+
const prefixIndex = normalizedButtons.findIndex((label, index) => label.startsWith(hint) && !isNegativeApprovalLabel(labels[index]));
|
|
44579
|
+
if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
|
|
44580
|
+
const includeIndex = normalizedButtons.findIndex((label, index) => label.includes(hint) && !isNegativeApprovalLabel(labels[index]));
|
|
44581
|
+
if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
|
|
44582
|
+
}
|
|
44583
|
+
return { index: -1, label: "" };
|
|
44584
|
+
}
|
|
44585
|
+
function pickAutoApprovalButton(buttons) {
|
|
44586
|
+
const labels = (buttons || []).map((button) => String(button || "").trim());
|
|
44587
|
+
const index = labels.findIndex(Boolean);
|
|
44588
|
+
return index >= 0 ? { index, label: labels[index] } : { index: -1, label: "" };
|
|
44589
|
+
}
|
|
44590
|
+
function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
44591
|
+
const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
|
|
44592
|
+
const cleanMessage = String(modalMessage || "").trim();
|
|
44593
|
+
if (cleanMessage) lines.push(cleanMessage);
|
|
44594
|
+
return lines.join("\n");
|
|
44595
|
+
}
|
|
44596
|
+
function looksLikeActiveApprovalPromptText(content) {
|
|
44597
|
+
const text = content.trim();
|
|
44598
|
+
if (!text || text.length > 2e3) return false;
|
|
44599
|
+
const hasApprovalQuestion = /do you want to (?:proceed|allow|run|make this edit|create)/i.test(text) || /this command requires approval/i.test(text) || /quick safety check/i.test(text) || /is this a project you trust/i.test(text);
|
|
44600
|
+
const hasNumberedChoices = /^\s*[❯›>]?\s*1[.)]\s+(?:yes|allow|proceed|run)/im.test(text) || /^\s*1[.)]\s+yes\b/im.test(text);
|
|
44601
|
+
if (hasApprovalQuestion && hasNumberedChoices) return true;
|
|
44602
|
+
const lastLines = text.split(/\r?\n/).slice(-12).join("\n");
|
|
44603
|
+
const hasDontAskAgain = /yes.*don'?t ask again/i.test(lastLines) || /yes.*always allow/i.test(lastLines);
|
|
44604
|
+
const hasNoOption = /^\s*[❯›>]?\s*\d+[.)]\s+no\b/im.test(lastLines);
|
|
44605
|
+
if (hasDontAskAgain && hasNoOption) return true;
|
|
44606
|
+
if (/what do you want to do\?/i.test(text) && /^\s*\d+[.)]\s+\S/m.test(text)) return true;
|
|
44607
|
+
return false;
|
|
44608
|
+
}
|
|
44609
|
+
var DEFAULT_APPROVAL_POSITIVE_HINTS;
|
|
44610
|
+
var init_approval_utils = __esm2({
|
|
44611
|
+
"src/providers/approval-utils.ts"() {
|
|
44612
|
+
"use strict";
|
|
44613
|
+
DEFAULT_APPROVAL_POSITIVE_HINTS = [
|
|
44614
|
+
"yes",
|
|
44615
|
+
"allow once",
|
|
44616
|
+
"approve",
|
|
44617
|
+
"accept",
|
|
44618
|
+
"continue",
|
|
44619
|
+
"run",
|
|
44620
|
+
"proceed",
|
|
44621
|
+
"confirm",
|
|
44622
|
+
"save",
|
|
44623
|
+
"ok",
|
|
44624
|
+
"trust",
|
|
44625
|
+
"allow",
|
|
44626
|
+
"always allow"
|
|
44627
|
+
];
|
|
44628
|
+
}
|
|
44629
|
+
});
|
|
44337
44630
|
function normalizeCategories(categories) {
|
|
44338
44631
|
if (!Array.isArray(categories)) return [];
|
|
44339
44632
|
return categories.map((category) => String(category || "").trim()).filter(Boolean);
|
|
@@ -45320,6 +45613,27 @@ ${cleanBody}`;
|
|
|
45320
45613
|
});
|
|
45321
45614
|
return { prompt, footers };
|
|
45322
45615
|
}
|
|
45616
|
+
function extractButtonLabels(spec, text) {
|
|
45617
|
+
if (!text) return [];
|
|
45618
|
+
const flags = spec.buttonFlags && spec.buttonFlags.includes("m") ? spec.buttonFlags : `${spec.buttonFlags ?? ""}m`;
|
|
45619
|
+
const buttonRe = compile2(spec.buttonPattern, flags);
|
|
45620
|
+
const labelGroup = Number.isInteger(spec.buttonLabelGroup) && (spec.buttonLabelGroup ?? 0) > 0 ? spec.buttonLabelGroup : 1;
|
|
45621
|
+
const out = [];
|
|
45622
|
+
for (const line of text.split("\n")) {
|
|
45623
|
+
buttonRe.lastIndex = 0;
|
|
45624
|
+
const m = buttonRe.exec(line);
|
|
45625
|
+
if (!m) continue;
|
|
45626
|
+
const captured = m[labelGroup] ?? (labelGroup === 1 && m.length > 2 ? m[m.length - 1] : void 0);
|
|
45627
|
+
if (captured && captured.trim()) out.push(captured.trim());
|
|
45628
|
+
}
|
|
45629
|
+
return out;
|
|
45630
|
+
}
|
|
45631
|
+
function buttonBlockApprovalCue(spec, text) {
|
|
45632
|
+
const labels = extractButtonLabels(spec, text);
|
|
45633
|
+
if (labels.length < 2) return false;
|
|
45634
|
+
if (pickApprovalButton(labels).index < 0) return false;
|
|
45635
|
+
return hasNegativeApprovalOption(labels);
|
|
45636
|
+
}
|
|
45323
45637
|
function modalMatches(spec, input) {
|
|
45324
45638
|
const text = input.screenText ?? "";
|
|
45325
45639
|
const question = compile2(spec.questionPattern, spec.questionFlags ?? "i");
|
|
@@ -45328,6 +45642,7 @@ ${cleanBody}`;
|
|
|
45328
45642
|
const re = compile2(variant.regex, variant.flags ?? "i");
|
|
45329
45643
|
if (re.test(text)) return true;
|
|
45330
45644
|
}
|
|
45645
|
+
if (buttonBlockApprovalCue(spec, text)) return true;
|
|
45331
45646
|
return false;
|
|
45332
45647
|
}
|
|
45333
45648
|
function evaluateGroup(group, spec, input, compiled) {
|
|
@@ -45382,6 +45697,7 @@ ${cleanBody}`;
|
|
|
45382
45697
|
"src/providers/sdk/v1/builders/cli/detect-status.ts"() {
|
|
45383
45698
|
"use strict";
|
|
45384
45699
|
init_visible_region();
|
|
45700
|
+
init_approval_utils();
|
|
45385
45701
|
DEFAULT_ORDER = ["spinner", "modal", "settled-prompt"];
|
|
45386
45702
|
}
|
|
45387
45703
|
});
|
|
@@ -49980,6 +50296,7 @@ ${lastSnapshot}`;
|
|
|
49980
50296
|
readLedgerEntries: () => readLedgerEntries,
|
|
49981
50297
|
readLedgerSlice: () => readLedgerSlice,
|
|
49982
50298
|
readLedgerSliceFromStore: () => readLedgerSliceFromStore,
|
|
50299
|
+
readMeshCompletionSummary: () => readMeshCompletionSummary,
|
|
49983
50300
|
reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
|
|
49984
50301
|
recordCompletionConflict: () => recordCompletionConflict,
|
|
49985
50302
|
recordDebugTrace: () => recordDebugTrace,
|
|
@@ -50005,6 +50322,7 @@ ${lastSnapshot}`;
|
|
|
50005
50322
|
resolveMeshHostStatus: () => resolveMeshHostStatus,
|
|
50006
50323
|
resolveMeshNodeAttribution: () => resolveMeshNodeAttribution,
|
|
50007
50324
|
resolveMeshRefineValidationPlan: () => resolveMeshRefineValidationPlan,
|
|
50325
|
+
resolveMeshSurfacedSessionPreview: () => resolveMeshSurfacedSessionPreview,
|
|
50008
50326
|
resolveNodeSchedulingPriority: () => resolveNodeSchedulingPriority,
|
|
50009
50327
|
resolveSessionHostAppName: () => resolveSessionHostAppName,
|
|
50010
50328
|
resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution2,
|
|
@@ -51889,6 +52207,7 @@ ${lastSnapshot}`;
|
|
|
51889
52207
|
init_mesh_refine_status();
|
|
51890
52208
|
init_mesh_host_ownership();
|
|
51891
52209
|
init_mesh_events();
|
|
52210
|
+
init_mesh_events_utils();
|
|
51892
52211
|
init_mesh_delivery_policy();
|
|
51893
52212
|
var NO_FALLBACK_REASON = "Repo Mesh command/data-plane is P2P-only; WS/REST command fallback is intentionally disabled to preserve the transport boundary.";
|
|
51894
52213
|
var P2P_NEXT_ACTION = "Check daemon/P2P health, wait briefly for connection establishment, then do one bounded retry or requeue the mesh task after clearing stale target session metadata.";
|
|
@@ -55767,73 +56086,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
55767
56086
|
if (raw.coverage === "full" || raw.coverage === "tail" || raw.coverage === "current-turn") normalized.coverage = raw.coverage;
|
|
55768
56087
|
return normalized;
|
|
55769
56088
|
}
|
|
55770
|
-
|
|
55771
|
-
"yes",
|
|
55772
|
-
"allow once",
|
|
55773
|
-
"approve",
|
|
55774
|
-
"accept",
|
|
55775
|
-
"continue",
|
|
55776
|
-
"run",
|
|
55777
|
-
"proceed",
|
|
55778
|
-
"confirm",
|
|
55779
|
-
"save",
|
|
55780
|
-
"ok",
|
|
55781
|
-
"trust",
|
|
55782
|
-
"allow",
|
|
55783
|
-
"always allow"
|
|
55784
|
-
];
|
|
55785
|
-
function normalizeApprovalLabel(value) {
|
|
55786
|
-
return String(value || "").toLowerCase().replace(/^[\s\[(<{]*\d+(?:\s*[.)\]}>:-]|\s)+/, "").replace(/[^\p{L}\p{N}]+/gu, " ").trim();
|
|
55787
|
-
}
|
|
55788
|
-
function isNegativeApprovalLabel(value) {
|
|
55789
|
-
const label = normalizeApprovalLabel(value);
|
|
55790
|
-
return /^(no|deny|reject|cancel|skip|exit|stop)\b/.test(label) || /\bwithout\b/.test(label) || /\bdo not\b/.test(label);
|
|
55791
|
-
}
|
|
55792
|
-
function getApprovalPositiveHints(provider) {
|
|
55793
|
-
const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
|
|
55794
|
-
return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
|
|
55795
|
-
}
|
|
55796
|
-
function pickApprovalButton(buttons, provider) {
|
|
55797
|
-
const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
|
|
55798
|
-
if (labels.length === 0) {
|
|
55799
|
-
return { index: -1, label: "" };
|
|
55800
|
-
}
|
|
55801
|
-
const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
|
|
55802
|
-
const hints = getApprovalPositiveHints(provider);
|
|
55803
|
-
for (const hint of hints) {
|
|
55804
|
-
const exactIndex = normalizedButtons.findIndex((label, index) => label === hint && !isNegativeApprovalLabel(labels[index]));
|
|
55805
|
-
if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
|
|
55806
|
-
const prefixIndex = normalizedButtons.findIndex((label, index) => label.startsWith(hint) && !isNegativeApprovalLabel(labels[index]));
|
|
55807
|
-
if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
|
|
55808
|
-
const includeIndex = normalizedButtons.findIndex((label, index) => label.includes(hint) && !isNegativeApprovalLabel(labels[index]));
|
|
55809
|
-
if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
|
|
55810
|
-
}
|
|
55811
|
-
return { index: -1, label: "" };
|
|
55812
|
-
}
|
|
55813
|
-
function pickAutoApprovalButton(buttons) {
|
|
55814
|
-
const labels = (buttons || []).map((button) => String(button || "").trim());
|
|
55815
|
-
const index = labels.findIndex(Boolean);
|
|
55816
|
-
return index >= 0 ? { index, label: labels[index] } : { index: -1, label: "" };
|
|
55817
|
-
}
|
|
55818
|
-
function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
55819
|
-
const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
|
|
55820
|
-
const cleanMessage = String(modalMessage || "").trim();
|
|
55821
|
-
if (cleanMessage) lines.push(cleanMessage);
|
|
55822
|
-
return lines.join("\n");
|
|
55823
|
-
}
|
|
55824
|
-
function looksLikeActiveApprovalPromptText(content) {
|
|
55825
|
-
const text = content.trim();
|
|
55826
|
-
if (!text || text.length > 2e3) return false;
|
|
55827
|
-
const hasApprovalQuestion = /do you want to (?:proceed|allow|run|make this edit|create)/i.test(text) || /this command requires approval/i.test(text) || /quick safety check/i.test(text) || /is this a project you trust/i.test(text);
|
|
55828
|
-
const hasNumberedChoices = /^\s*[❯›>]?\s*1[.)]\s+(?:yes|allow|proceed|run)/im.test(text) || /^\s*1[.)]\s+yes\b/im.test(text);
|
|
55829
|
-
if (hasApprovalQuestion && hasNumberedChoices) return true;
|
|
55830
|
-
const lastLines = text.split(/\r?\n/).slice(-12).join("\n");
|
|
55831
|
-
const hasDontAskAgain = /yes.*don'?t ask again/i.test(lastLines) || /yes.*always allow/i.test(lastLines);
|
|
55832
|
-
const hasNoOption = /^\s*[❯›>]?\s*\d+[.)]\s+no\b/im.test(lastLines);
|
|
55833
|
-
if (hasDontAskAgain && hasNoOption) return true;
|
|
55834
|
-
if (/what do you want to do\?/i.test(text) && /^\s*\d+[.)]\s+\S/m.test(text)) return true;
|
|
55835
|
-
return false;
|
|
55836
|
-
}
|
|
56089
|
+
init_approval_utils();
|
|
55837
56090
|
init_provider_patch_state();
|
|
55838
56091
|
init_chat_message_normalization();
|
|
55839
56092
|
init_open_panel_support();
|
|
@@ -56897,6 +57150,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
56897
57150
|
var import_node_crypto3 = require("crypto");
|
|
56898
57151
|
init_contracts();
|
|
56899
57152
|
init_provider_input_support();
|
|
57153
|
+
init_approval_utils();
|
|
56900
57154
|
init_coordinator_registry();
|
|
56901
57155
|
init_logger();
|
|
56902
57156
|
init_debug_config();
|
|
@@ -64837,6 +65091,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
64837
65091
|
}
|
|
64838
65092
|
init_logger();
|
|
64839
65093
|
init_control_effects();
|
|
65094
|
+
init_approval_utils();
|
|
64840
65095
|
init_provider_patch_state();
|
|
64841
65096
|
function normalizeProviderSessionId(provider, providerSessionId) {
|
|
64842
65097
|
const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
|
|
@@ -65090,6 +65345,20 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
65090
65345
|
* keystroke until the modal *content* has settled.
|
|
65091
65346
|
*/
|
|
65092
65347
|
static AUTO_APPROVE_SETTLE_MS = 600;
|
|
65348
|
+
/**
|
|
65349
|
+
* Busy-side hysteresis for the settle gate. A momentary `generating` flip
|
|
65350
|
+
* while the SAME approval modal's button block is still on screen (its
|
|
65351
|
+
* question line scrolled out of the captured frame, only the buttons + a
|
|
65352
|
+
* residual `esc to interrupt` spinner remain) briefly reports
|
|
65353
|
+
* status!=waiting_approval. Without hysteresis that flip wipes the settle
|
|
65354
|
+
* clock, and the modal→generating→modal flap restarts the 600ms window
|
|
65355
|
+
* every time so auto-approve never fires. We keep the in-progress settle
|
|
65356
|
+
* gate warm across an inactive blip up to this bound; only once the modal
|
|
65357
|
+
* has genuinely stayed gone this long (a real resolution → idle) is the
|
|
65358
|
+
* gate cleared. Bounded so a genuinely new, later approval still re-settles
|
|
65359
|
+
* from scratch rather than firing on a stale timestamp.
|
|
65360
|
+
*/
|
|
65361
|
+
static AUTO_APPROVE_GATE_HYSTERESIS_MS = 1500;
|
|
65093
65362
|
adapter;
|
|
65094
65363
|
context = null;
|
|
65095
65364
|
events = [];
|
|
@@ -65111,6 +65380,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
65111
65380
|
pendingAutoApprovalSignature = "";
|
|
65112
65381
|
pendingAutoApprovalSince = 0;
|
|
65113
65382
|
autoApproveSettleTimer = null;
|
|
65383
|
+
// Wall-clock when auto-approve first observed status!=waiting_approval while
|
|
65384
|
+
// a settle gate was in progress. Drives AUTO_APPROVE_GATE_HYSTERESIS_MS so a
|
|
65385
|
+
// brief generating flip does not immediately wipe the settle clock.
|
|
65386
|
+
autoApproveInactiveSince = 0;
|
|
65114
65387
|
controlValues = {};
|
|
65115
65388
|
summaryMetadata = void 0;
|
|
65116
65389
|
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
@@ -65931,14 +66204,28 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
65931
66204
|
const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove();
|
|
65932
66205
|
if (!autoApproveActive) {
|
|
65933
66206
|
this.lastAutoApprovalSignature = "";
|
|
66207
|
+
if (this.pendingAutoApprovalSince) {
|
|
66208
|
+
if (!this.autoApproveInactiveSince) this.autoApproveInactiveSince = now;
|
|
66209
|
+
const goneForMs = now - this.autoApproveInactiveSince;
|
|
66210
|
+
if (goneForMs < _CliProviderInstance.AUTO_APPROVE_GATE_HYSTERESIS_MS) {
|
|
66211
|
+
if (this.autoApproveSettleTimer) clearTimeout(this.autoApproveSettleTimer);
|
|
66212
|
+
this.autoApproveSettleTimer = setTimeout(() => {
|
|
66213
|
+
this.autoApproveSettleTimer = null;
|
|
66214
|
+
this.recheckAutoApproveSettled();
|
|
66215
|
+
}, _CliProviderInstance.AUTO_APPROVE_GATE_HYSTERESIS_MS - goneForMs + 20);
|
|
66216
|
+
return autoApproveActive;
|
|
66217
|
+
}
|
|
66218
|
+
}
|
|
65934
66219
|
this.pendingAutoApprovalSignature = "";
|
|
65935
66220
|
this.pendingAutoApprovalSince = 0;
|
|
66221
|
+
this.autoApproveInactiveSince = 0;
|
|
65936
66222
|
if (this.autoApproveSettleTimer) {
|
|
65937
66223
|
clearTimeout(this.autoApproveSettleTimer);
|
|
65938
66224
|
this.autoApproveSettleTimer = null;
|
|
65939
66225
|
}
|
|
65940
66226
|
return autoApproveActive;
|
|
65941
66227
|
}
|
|
66228
|
+
this.autoApproveInactiveSince = 0;
|
|
65942
66229
|
const modal = adapterStatus.activeModal;
|
|
65943
66230
|
const buttons = Array.isArray(modal?.buttons) ? modal.buttons.map((b) => String(b || "").trim()).filter(Boolean) : [];
|
|
65944
66231
|
if (!modal || buttons.length === 0) {
|
|
@@ -65948,18 +66235,18 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
65948
66235
|
if (buttonIndex < 0) {
|
|
65949
66236
|
return autoApproveActive;
|
|
65950
66237
|
}
|
|
65951
|
-
const
|
|
65952
|
-
const signature = [
|
|
65953
|
-
approvalEntrySeq,
|
|
66238
|
+
const modalSignature = [
|
|
65954
66239
|
typeof modal?.message === "string" ? modal.message.trim() : "",
|
|
65955
66240
|
buttons.join("|"),
|
|
65956
66241
|
buttonIndex
|
|
65957
66242
|
].join("::");
|
|
65958
|
-
|
|
66243
|
+
const approvalEntrySeq = typeof adapterStatus?.approvalEntrySeq === "number" ? adapterStatus.approvalEntrySeq : 0;
|
|
66244
|
+
const busySignature = `${approvalEntrySeq}::${modalSignature}`;
|
|
66245
|
+
if (this.autoApproveBusy && busySignature === this.lastAutoApprovalSignature) {
|
|
65959
66246
|
return autoApproveActive;
|
|
65960
66247
|
}
|
|
65961
|
-
if (
|
|
65962
|
-
this.pendingAutoApprovalSignature =
|
|
66248
|
+
if (modalSignature !== this.pendingAutoApprovalSignature) {
|
|
66249
|
+
this.pendingAutoApprovalSignature = modalSignature;
|
|
65963
66250
|
this.pendingAutoApprovalSince = now;
|
|
65964
66251
|
}
|
|
65965
66252
|
const settledForMs = now - this.pendingAutoApprovalSince;
|
|
@@ -65976,9 +66263,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
65976
66263
|
this.autoApproveSettleTimer = null;
|
|
65977
66264
|
}
|
|
65978
66265
|
this.autoApproveBusy = true;
|
|
65979
|
-
this.lastAutoApprovalSignature =
|
|
66266
|
+
this.lastAutoApprovalSignature = busySignature;
|
|
65980
66267
|
this.pendingAutoApprovalSignature = "";
|
|
65981
66268
|
this.pendingAutoApprovalSince = 0;
|
|
66269
|
+
this.autoApproveInactiveSince = 0;
|
|
65982
66270
|
if (this.autoApproveBusyTimer) clearTimeout(this.autoApproveBusyTimer);
|
|
65983
66271
|
this.autoApproveBusyTimer = setTimeout(() => {
|
|
65984
66272
|
this.autoApproveBusy = false;
|
|
@@ -72827,7 +73115,8 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
72827
73115
|
var fs23 = __toESM2(require("fs"));
|
|
72828
73116
|
var path35 = __toESM2(require("path"));
|
|
72829
73117
|
var os26 = __toESM2(require("os"));
|
|
72830
|
-
var
|
|
73118
|
+
var ADHDEV_HOME2 = process.env.ADHDEV_CONFIG_DIR && process.env.ADHDEV_CONFIG_DIR.trim() ? process.env.ADHDEV_CONFIG_DIR.trim() : path35.join(os26.homedir(), ".adhdev");
|
|
73119
|
+
var LOG_DIR2 = path35.join(ADHDEV_HOME2, "logs");
|
|
72831
73120
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
72832
73121
|
var MAX_DAYS = 7;
|
|
72833
73122
|
try {
|
|
@@ -73275,7 +73564,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
73275
73564
|
return "";
|
|
73276
73565
|
}
|
|
73277
73566
|
}
|
|
73278
|
-
function
|
|
73567
|
+
function readRecord5(repoRoot) {
|
|
73279
73568
|
const path422 = (0, import_node_path2.resolve)(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
73280
73569
|
if (!(0, import_node_fs4.existsSync)(path422)) return null;
|
|
73281
73570
|
try {
|
|
@@ -73315,7 +73604,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
73315
73604
|
}
|
|
73316
73605
|
function buildPreviewFreshness(repoRoot) {
|
|
73317
73606
|
const current = readCurrentMainCommit(repoRoot);
|
|
73318
|
-
const record2 =
|
|
73607
|
+
const record2 = readRecord5(repoRoot);
|
|
73319
73608
|
const lastPreviewCommit = normalizeCommit(record2?.lastPreviewCommit);
|
|
73320
73609
|
const targets = readTargetFreshness(record2, current.currentMainCommit);
|
|
73321
73610
|
let status = "unknown";
|
|
@@ -73662,13 +73951,14 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
73662
73951
|
}
|
|
73663
73952
|
}
|
|
73664
73953
|
}
|
|
73665
|
-
function stopSessionHostProcesses(appName) {
|
|
73954
|
+
async function stopSessionHostProcesses(appName) {
|
|
73666
73955
|
const pidFile = path36.join(os27.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
73956
|
+
let killedPid = null;
|
|
73667
73957
|
try {
|
|
73668
73958
|
if (fs25.existsSync(pidFile)) {
|
|
73669
73959
|
const pid = Number.parseInt(fs25.readFileSync(pidFile, "utf8").trim(), 10);
|
|
73670
73960
|
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
73671
|
-
killPid2(pid);
|
|
73961
|
+
if (killPid2(pid)) killedPid = pid;
|
|
73672
73962
|
}
|
|
73673
73963
|
}
|
|
73674
73964
|
} catch {
|
|
@@ -73678,6 +73968,15 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
73678
73968
|
} catch {
|
|
73679
73969
|
}
|
|
73680
73970
|
}
|
|
73971
|
+
if (killedPid !== null) {
|
|
73972
|
+
await waitForPidExit(killedPid, 15e3);
|
|
73973
|
+
}
|
|
73974
|
+
}
|
|
73975
|
+
function isRetriableInstallLockError(error48) {
|
|
73976
|
+
const code = error48?.code;
|
|
73977
|
+
if (code === "EBUSY" || code === "EPERM") return true;
|
|
73978
|
+
const text = `${error48?.message || ""} ${error48?.stderr || ""}`;
|
|
73979
|
+
return /\bEBUSY\b|\bEPERM\b|resource busy or locked/i.test(text);
|
|
73681
73980
|
}
|
|
73682
73981
|
function removeDaemonPidFile() {
|
|
73683
73982
|
const pidFile = path36.join(os27.homedir(), ".adhdev", "daemon.pid");
|
|
@@ -73757,22 +74056,37 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
73757
74056
|
appendUpgradeLog(`Waiting for parent pid ${payload.parentPid} to exit`);
|
|
73758
74057
|
await waitForPidExit(payload.parentPid, 15e3);
|
|
73759
74058
|
}
|
|
73760
|
-
stopSessionHostProcesses(sessionHostAppName);
|
|
74059
|
+
await stopSessionHostProcesses(sessionHostAppName);
|
|
73761
74060
|
removeDaemonPidFile();
|
|
73762
74061
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
73763
74062
|
const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
|
|
73764
74063
|
appendUpgradeLog(`Installing ${spec}`);
|
|
73765
|
-
const
|
|
73766
|
-
|
|
73767
|
-
|
|
73768
|
-
{
|
|
73769
|
-
|
|
73770
|
-
|
|
73771
|
-
|
|
73772
|
-
|
|
73773
|
-
|
|
74064
|
+
const maxInstallAttempts = process.platform === "win32" ? 3 : 1;
|
|
74065
|
+
let installOutput = "";
|
|
74066
|
+
for (let attempt = 1; attempt <= maxInstallAttempts; attempt++) {
|
|
74067
|
+
try {
|
|
74068
|
+
installOutput = String((0, import_child_process8.execFileSync)(
|
|
74069
|
+
installCommand.command,
|
|
74070
|
+
installCommand.args,
|
|
74071
|
+
{
|
|
74072
|
+
encoding: "utf8",
|
|
74073
|
+
stdio: "pipe",
|
|
74074
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
74075
|
+
env: buildInstallEnvWithNodeOnPath(),
|
|
74076
|
+
...installCommand.execOptions
|
|
74077
|
+
}
|
|
74078
|
+
));
|
|
74079
|
+
break;
|
|
74080
|
+
} catch (error48) {
|
|
74081
|
+
if (attempt < maxInstallAttempts && isRetriableInstallLockError(error48)) {
|
|
74082
|
+
appendUpgradeLog(`Install attempt ${attempt} hit a file lock (${error48?.code || "lock"}); cleaning staging and retrying after backoff`);
|
|
74083
|
+
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
74084
|
+
await new Promise((resolve24) => setTimeout(resolve24, attempt * 1500));
|
|
74085
|
+
continue;
|
|
74086
|
+
}
|
|
74087
|
+
throw error48;
|
|
73774
74088
|
}
|
|
73775
|
-
|
|
74089
|
+
}
|
|
73776
74090
|
if (installOutput.trim()) {
|
|
73777
74091
|
appendUpgradeLog(installOutput.trim());
|
|
73778
74092
|
}
|
|
@@ -82516,6 +82830,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
82516
82830
|
}
|
|
82517
82831
|
};
|
|
82518
82832
|
init_logger();
|
|
82833
|
+
init_approval_utils();
|
|
82519
82834
|
init_chat_message_normalization();
|
|
82520
82835
|
var AgentStreamPoller = class {
|
|
82521
82836
|
deps;
|