@adhdev/daemon-core 0.9.77-rc.49 → 0.9.77-rc.50
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/commands/router.d.ts +1 -0
- package/dist/index.js +161 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +161 -12
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events.d.ts +8 -0
- package/dist/mesh/mesh-ledger.d.ts +38 -0
- package/package.json +1 -1
- package/src/commands/router.ts +54 -2
- package/src/mesh/mesh-events.ts +90 -4
- package/src/mesh/mesh-ledger.ts +88 -1
|
@@ -93,6 +93,7 @@ export declare class DaemonCommandRouter {
|
|
|
93
93
|
private cleanupLocalWorktreeNode;
|
|
94
94
|
private getWorktreeForceCleanupConvergence;
|
|
95
95
|
private isCompletedHostedSession;
|
|
96
|
+
private recordIntentionalMeshSessionStop;
|
|
96
97
|
private cleanupMeshSessions;
|
|
97
98
|
private traceSessionHostAction;
|
|
98
99
|
/**
|
package/dist/index.js
CHANGED
|
@@ -798,13 +798,20 @@ __export(mesh_ledger_exports, {
|
|
|
798
798
|
MAX_LEDGER_SLICE_LIMIT: () => MAX_LEDGER_SLICE_LIMIT,
|
|
799
799
|
appendLedgerEntry: () => appendLedgerEntry,
|
|
800
800
|
appendRemoteLedgerEntries: () => appendRemoteLedgerEntries,
|
|
801
|
+
buildTaskCompletionEvidence: () => buildTaskCompletionEvidence,
|
|
801
802
|
getLedgerDir: () => getLedgerDir,
|
|
802
803
|
getLedgerSummary: () => getLedgerSummary,
|
|
803
804
|
getSessionRecoveryContext: () => getSessionRecoveryContext,
|
|
805
|
+
isIntentionalCleanupStopEntry: () => isIntentionalCleanupStopEntry,
|
|
804
806
|
meshLedgerEvents: () => meshLedgerEvents,
|
|
805
807
|
readLedgerEntries: () => readLedgerEntries,
|
|
806
808
|
readLedgerSlice: () => readLedgerSlice
|
|
807
809
|
});
|
|
810
|
+
function isIntentionalCleanupStopEntry(entry) {
|
|
811
|
+
if (entry.kind !== "session_stopped" && entry.kind !== "task_failed" && entry.kind !== "task_stalled") return false;
|
|
812
|
+
const payload = entry.payload && typeof entry.payload === "object" && !Array.isArray(entry.payload) ? entry.payload : {};
|
|
813
|
+
return payload.intentional === true && (payload.reason === "operator_cleanup" || payload.intentionalStopReason === "operator_cleanup" || payload.source === "mesh_cleanup_sessions" || payload.source === "mesh_remove_node");
|
|
814
|
+
}
|
|
808
815
|
function getLedgerDir() {
|
|
809
816
|
const dir = (0, import_path3.join)(getConfigDir(), LEDGER_DIR_NAME);
|
|
810
817
|
if (!(0, import_fs3.existsSync)(dir)) {
|
|
@@ -820,6 +827,37 @@ function getRotatedPath(meshId, index) {
|
|
|
820
827
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
821
828
|
return (0, import_path3.join)(getLedgerDir(), `${safe}.${index}.jsonl`);
|
|
822
829
|
}
|
|
830
|
+
function buildTaskCompletionEvidence(opts) {
|
|
831
|
+
const providerSessionId = opts.providerSessionId?.trim() || void 0;
|
|
832
|
+
const providerType = opts.providerType?.trim() || void 0;
|
|
833
|
+
return {
|
|
834
|
+
source: "agent_status_event",
|
|
835
|
+
event: opts.event,
|
|
836
|
+
nodeId: opts.nodeId,
|
|
837
|
+
sessionId: opts.sessionId,
|
|
838
|
+
providerType,
|
|
839
|
+
completedAt: opts.completedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
840
|
+
transcriptHandle: {
|
|
841
|
+
kind: providerSessionId ? "provider_session" : "runtime_session",
|
|
842
|
+
sessionId: opts.sessionId,
|
|
843
|
+
providerSessionId,
|
|
844
|
+
finalSummaryAvailable: typeof opts.finalSummary === "string" && opts.finalSummary.trim().length > 0
|
|
845
|
+
},
|
|
846
|
+
git: {
|
|
847
|
+
status: "deferred",
|
|
848
|
+
reason: "ordinary_completion_git_status_not_checked"
|
|
849
|
+
},
|
|
850
|
+
validation: {
|
|
851
|
+
status: "deferred",
|
|
852
|
+
commandsRun: [],
|
|
853
|
+
reason: "ordinary_completion_validation_not_run"
|
|
854
|
+
},
|
|
855
|
+
checkpoint: {
|
|
856
|
+
attempted: false,
|
|
857
|
+
reason: "not_attempted_for_ordinary_completion"
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
}
|
|
823
861
|
function appendLedgerEntry(meshId, partial) {
|
|
824
862
|
const entry = {
|
|
825
863
|
id: (0, import_crypto4.randomUUID)(),
|
|
@@ -980,15 +1018,17 @@ function getLedgerSummary(meshId) {
|
|
|
980
1018
|
summary.taskCompleted++;
|
|
981
1019
|
break;
|
|
982
1020
|
case "task_failed": {
|
|
1021
|
+
if (isIntentionalCleanupStopEntry(entry)) break;
|
|
983
1022
|
summary.taskFailed++;
|
|
984
1023
|
if (new Date(entry.timestamp).getTime() >= recentFailureCutoff) {
|
|
985
1024
|
summary.recentFailures++;
|
|
986
1025
|
}
|
|
987
1026
|
break;
|
|
988
1027
|
}
|
|
989
|
-
case "task_stalled":
|
|
990
|
-
summary.taskStalled++;
|
|
1028
|
+
case "task_stalled": {
|
|
1029
|
+
if (!isIntentionalCleanupStopEntry(entry)) summary.taskStalled++;
|
|
991
1030
|
break;
|
|
1031
|
+
}
|
|
992
1032
|
case "session_launched":
|
|
993
1033
|
summary.sessionLaunched++;
|
|
994
1034
|
break;
|
|
@@ -1027,6 +1067,7 @@ function getSessionRecoveryContext(meshId, opts) {
|
|
|
1027
1067
|
if (new Date(e.timestamp).getTime() < recentWindow) break;
|
|
1028
1068
|
if (opts.nodeId && e.nodeId !== opts.nodeId) continue;
|
|
1029
1069
|
if (e.kind === "task_failed") {
|
|
1070
|
+
if (isIntentionalCleanupStopEntry(e)) continue;
|
|
1030
1071
|
consecutiveNodeFailures++;
|
|
1031
1072
|
} else if (e.kind === "task_completed" || e.kind === "task_dispatched") {
|
|
1032
1073
|
break;
|
|
@@ -1669,6 +1710,28 @@ function getMeshWithCache(components, meshId) {
|
|
|
1669
1710
|
if (localMesh) return localMesh;
|
|
1670
1711
|
return components.router?.getCachedInlineMesh(meshId);
|
|
1671
1712
|
}
|
|
1713
|
+
function isIntentionalCleanupStopMetadata(event) {
|
|
1714
|
+
return event.intentional === true || event.intentionalStop === true || event.operatorCleanup === true || event.reason === "operator_cleanup" || event.stopReason === "operator_cleanup" || event.cleanupReason === "operator_cleanup" || event.source === "mesh_cleanup_sessions" || event.source === "mesh_remove_node";
|
|
1715
|
+
}
|
|
1716
|
+
function hasRecentIntentionalCleanupStop(meshId, sessionId, nodeId) {
|
|
1717
|
+
if (!sessionId && !nodeId) return false;
|
|
1718
|
+
const cutoff = Date.now() - INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS;
|
|
1719
|
+
const entries = readLedgerEntries(meshId);
|
|
1720
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
1721
|
+
const entry = entries[i];
|
|
1722
|
+
const timestamp = new Date(entry.timestamp).getTime();
|
|
1723
|
+
if (!Number.isNaN(timestamp) && timestamp < cutoff) break;
|
|
1724
|
+
if (!isIntentionalCleanupStopEntry(entry)) continue;
|
|
1725
|
+
if (sessionId && entry.sessionId === sessionId) return true;
|
|
1726
|
+
if (!sessionId && nodeId && entry.nodeId === nodeId) return true;
|
|
1727
|
+
}
|
|
1728
|
+
return false;
|
|
1729
|
+
}
|
|
1730
|
+
function shouldSuppressIntentionalCleanupStop(args) {
|
|
1731
|
+
if (args.event !== "agent:stopped" && args.event !== "monitor:long_generating") return false;
|
|
1732
|
+
if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
|
|
1733
|
+
return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
|
|
1734
|
+
}
|
|
1672
1735
|
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
|
|
1673
1736
|
const task = claimNextTask(meshId, nodeId, sessionId);
|
|
1674
1737
|
if (!task) {
|
|
@@ -2005,6 +2068,22 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
2005
2068
|
return "";
|
|
2006
2069
|
}
|
|
2007
2070
|
function injectMeshSystemMessage(components, args) {
|
|
2071
|
+
const eventSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2072
|
+
const eventNodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
2073
|
+
const intentionalCleanupStop = shouldSuppressIntentionalCleanupStop({
|
|
2074
|
+
event: args.event,
|
|
2075
|
+
meshId: args.meshId,
|
|
2076
|
+
metadataEvent: args.metadataEvent,
|
|
2077
|
+
sessionId: eventSessionId || void 0,
|
|
2078
|
+
nodeId: eventNodeId || void 0
|
|
2079
|
+
});
|
|
2080
|
+
if (intentionalCleanupStop) {
|
|
2081
|
+
if (eventSessionId && eventNodeId) {
|
|
2082
|
+
remoteIdleSessions.delete(`${eventNodeId}:${eventSessionId}`);
|
|
2083
|
+
}
|
|
2084
|
+
LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
|
|
2085
|
+
return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
|
|
2086
|
+
}
|
|
2008
2087
|
let completedTaskForLedger = null;
|
|
2009
2088
|
if (args.event === "agent:generating_completed") {
|
|
2010
2089
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
@@ -2038,7 +2117,15 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2038
2117
|
taskId: completedTask.id,
|
|
2039
2118
|
completedViaReady: true,
|
|
2040
2119
|
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
2041
|
-
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
2120
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0,
|
|
2121
|
+
evidence: buildTaskCompletionEvidence({
|
|
2122
|
+
event: "agent:ready",
|
|
2123
|
+
nodeId,
|
|
2124
|
+
sessionId,
|
|
2125
|
+
providerType: providerType || void 0,
|
|
2126
|
+
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
2127
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
2128
|
+
})
|
|
2042
2129
|
}
|
|
2043
2130
|
});
|
|
2044
2131
|
} catch (e) {
|
|
@@ -2073,17 +2160,29 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2073
2160
|
const ledgerKind = EVENT_TO_LEDGER_KIND[args.event];
|
|
2074
2161
|
if (ledgerKind) {
|
|
2075
2162
|
try {
|
|
2163
|
+
const ledgerNodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || void 0;
|
|
2164
|
+
const ledgerSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0;
|
|
2165
|
+
const ledgerProviderType = readNonEmptyString(args.metadataEvent.providerType) || void 0;
|
|
2166
|
+
const completionEvidence = ledgerKind === "task_completed" && ledgerNodeId && ledgerSessionId ? buildTaskCompletionEvidence({
|
|
2167
|
+
event: "agent:generating_completed",
|
|
2168
|
+
nodeId: ledgerNodeId,
|
|
2169
|
+
sessionId: ledgerSessionId,
|
|
2170
|
+
providerType: ledgerProviderType,
|
|
2171
|
+
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
2172
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
2173
|
+
}) : void 0;
|
|
2076
2174
|
appendLedgerEntry(args.meshId, {
|
|
2077
2175
|
kind: ledgerKind,
|
|
2078
|
-
nodeId:
|
|
2079
|
-
sessionId:
|
|
2080
|
-
providerType:
|
|
2176
|
+
nodeId: ledgerNodeId,
|
|
2177
|
+
sessionId: ledgerSessionId,
|
|
2178
|
+
providerType: ledgerProviderType,
|
|
2081
2179
|
payload: {
|
|
2082
2180
|
event: args.event,
|
|
2083
2181
|
nodeLabel: args.nodeLabel,
|
|
2084
2182
|
taskId: completedTaskForLedger?.id || void 0,
|
|
2085
2183
|
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
2086
|
-
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
2184
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0,
|
|
2185
|
+
evidence: completionEvidence
|
|
2087
2186
|
}
|
|
2088
2187
|
});
|
|
2089
2188
|
} catch (e) {
|
|
@@ -2199,7 +2298,14 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
2199
2298
|
targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId) || readNonEmptyString(payload.instanceId),
|
|
2200
2299
|
providerType: readNonEmptyString(payload.providerType),
|
|
2201
2300
|
providerSessionId: readNonEmptyString(payload.providerSessionId),
|
|
2202
|
-
finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary)
|
|
2301
|
+
finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary),
|
|
2302
|
+
intentional: payload.intentional === true,
|
|
2303
|
+
intentionalStop: payload.intentionalStop === true,
|
|
2304
|
+
operatorCleanup: payload.operatorCleanup === true,
|
|
2305
|
+
reason: readNonEmptyString(payload.reason),
|
|
2306
|
+
stopReason: readNonEmptyString(payload.stopReason),
|
|
2307
|
+
cleanupReason: readNonEmptyString(payload.cleanupReason),
|
|
2308
|
+
source: readNonEmptyString(payload.source)
|
|
2203
2309
|
}
|
|
2204
2310
|
});
|
|
2205
2311
|
}
|
|
@@ -2235,7 +2341,7 @@ function setupMeshEventForwarding(components) {
|
|
|
2235
2341
|
});
|
|
2236
2342
|
});
|
|
2237
2343
|
}
|
|
2238
|
-
var remoteIdleSessions, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
|
|
2344
|
+
var remoteIdleSessions, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
|
|
2239
2345
|
var init_mesh_events = __esm({
|
|
2240
2346
|
"src/mesh/mesh-events.ts"() {
|
|
2241
2347
|
"use strict";
|
|
@@ -2262,6 +2368,7 @@ var init_mesh_events = __esm({
|
|
|
2262
2368
|
"agent:stopped": "task_failed",
|
|
2263
2369
|
"monitor:long_generating": "task_stalled"
|
|
2264
2370
|
};
|
|
2371
|
+
INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
|
|
2265
2372
|
autoLaunchInProgress = /* @__PURE__ */ new Set();
|
|
2266
2373
|
autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
|
|
2267
2374
|
AUTO_LAUNCH_COOLDOWN_MS = 5e3;
|
|
@@ -24211,6 +24318,27 @@ var DaemonCommandRouter = class {
|
|
|
24211
24318
|
isCompletedHostedSession(record) {
|
|
24212
24319
|
return record?.lifecycle === "stopped" || record?.lifecycle === "failed" || record?.lifecycle === "interrupted";
|
|
24213
24320
|
}
|
|
24321
|
+
async recordIntentionalMeshSessionStop(args) {
|
|
24322
|
+
try {
|
|
24323
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
24324
|
+
appendLedgerEntry2(args.meshId, {
|
|
24325
|
+
kind: "session_stopped",
|
|
24326
|
+
nodeId: args.nodeId,
|
|
24327
|
+
sessionId: args.sessionId,
|
|
24328
|
+
payload: {
|
|
24329
|
+
intentional: true,
|
|
24330
|
+
reason: "operator_cleanup",
|
|
24331
|
+
intentionalStopReason: "operator_cleanup",
|
|
24332
|
+
source: args.source,
|
|
24333
|
+
cleanupMode: args.mode,
|
|
24334
|
+
action: args.action,
|
|
24335
|
+
workspace: typeof args.node?.workspace === "string" ? args.node.workspace : void 0
|
|
24336
|
+
}
|
|
24337
|
+
});
|
|
24338
|
+
} catch (e) {
|
|
24339
|
+
LOG.warn("MeshCleanup", `Failed to record intentional cleanup stop for ${args.sessionId}: ${e?.message || e}`);
|
|
24340
|
+
}
|
|
24341
|
+
}
|
|
24214
24342
|
async cleanupMeshSessions(args) {
|
|
24215
24343
|
if (args.mode === "preserve") {
|
|
24216
24344
|
return { success: true, mode: "preserve", matchedCount: 0, stoppedSessionIds: [], deletedSessionIds: [], skippedSessionIds: [] };
|
|
@@ -24227,6 +24355,21 @@ var DaemonCommandRouter = class {
|
|
|
24227
24355
|
const deleteUnsupportedSessionIds = [];
|
|
24228
24356
|
const recordsRemainSessionIds = [];
|
|
24229
24357
|
const errors = [];
|
|
24358
|
+
const cleanupSource = args.source || "mesh_cleanup_sessions";
|
|
24359
|
+
const markedIntentionalStopSessionIds = /* @__PURE__ */ new Set();
|
|
24360
|
+
const markIntentionalStop = async (sessionId, action) => {
|
|
24361
|
+
if (args.dryRun || markedIntentionalStopSessionIds.has(sessionId)) return;
|
|
24362
|
+
markedIntentionalStopSessionIds.add(sessionId);
|
|
24363
|
+
await this.recordIntentionalMeshSessionStop({
|
|
24364
|
+
meshId: args.meshId,
|
|
24365
|
+
nodeId: args.nodeId,
|
|
24366
|
+
node: args.node,
|
|
24367
|
+
sessionId,
|
|
24368
|
+
mode: args.mode,
|
|
24369
|
+
source: cleanupSource,
|
|
24370
|
+
action
|
|
24371
|
+
});
|
|
24372
|
+
};
|
|
24230
24373
|
const matchedBySurfaceKind = {
|
|
24231
24374
|
live_runtime: 0,
|
|
24232
24375
|
recovery_snapshot: 0,
|
|
@@ -24249,7 +24392,10 @@ var DaemonCommandRouter = class {
|
|
|
24249
24392
|
try {
|
|
24250
24393
|
if (args.mode === "stop") {
|
|
24251
24394
|
if (!completed) {
|
|
24252
|
-
if (!args.dryRun)
|
|
24395
|
+
if (!args.dryRun) {
|
|
24396
|
+
await markIntentionalStop(sessionId, "stop_session");
|
|
24397
|
+
await this.deps.sessionHostControl.stopSession(sessionId);
|
|
24398
|
+
}
|
|
24253
24399
|
stoppedSessionIds.push(sessionId);
|
|
24254
24400
|
} else {
|
|
24255
24401
|
skippedSessionIds.push(sessionId);
|
|
@@ -24266,6 +24412,7 @@ var DaemonCommandRouter = class {
|
|
|
24266
24412
|
continue;
|
|
24267
24413
|
}
|
|
24268
24414
|
if (args.mode === "stop_and_delete") {
|
|
24415
|
+
if (!completed) await markIntentionalStop(sessionId, "delete_session_force");
|
|
24269
24416
|
if (!args.dryRun) await this.deps.sessionHostControl.deleteSession(sessionId, { force: true });
|
|
24270
24417
|
deletedSessionIds.push(sessionId);
|
|
24271
24418
|
continue;
|
|
@@ -24277,6 +24424,7 @@ var DaemonCommandRouter = class {
|
|
|
24277
24424
|
recordsRemainSessionIds.push(sessionId);
|
|
24278
24425
|
if (args.mode === "stop_and_delete" && !completed) {
|
|
24279
24426
|
try {
|
|
24427
|
+
await markIntentionalStop(sessionId, "stop_session");
|
|
24280
24428
|
await this.deps.sessionHostControl.stopSession(sessionId);
|
|
24281
24429
|
stoppedSessionIds.push(sessionId);
|
|
24282
24430
|
} catch (stopError) {
|
|
@@ -25177,7 +25325,8 @@ var DaemonCommandRouter = class {
|
|
|
25177
25325
|
node,
|
|
25178
25326
|
mode,
|
|
25179
25327
|
sessionIds,
|
|
25180
|
-
dryRun: args?.dryRun === true
|
|
25328
|
+
dryRun: args?.dryRun === true,
|
|
25329
|
+
source: "mesh_cleanup_sessions"
|
|
25181
25330
|
});
|
|
25182
25331
|
return result;
|
|
25183
25332
|
} catch (e) {
|
|
@@ -25312,7 +25461,7 @@ var DaemonCommandRouter = class {
|
|
|
25312
25461
|
);
|
|
25313
25462
|
let sessionCleanup;
|
|
25314
25463
|
if (node && sessionCleanupMode !== "preserve") {
|
|
25315
|
-
sessionCleanup = await this.cleanupMeshSessions({ meshId, nodeId, node, mode: sessionCleanupMode });
|
|
25464
|
+
sessionCleanup = await this.cleanupMeshSessions({ meshId, nodeId, node, mode: sessionCleanupMode, source: "mesh_remove_node" });
|
|
25316
25465
|
if (sessionCleanup.success === false) return { success: false, removed: false, sessionCleanup };
|
|
25317
25466
|
}
|
|
25318
25467
|
let worktreeCleanup;
|