flavor-code 1.2.17 → 1.2.18
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/{app-F4P7RV2X.js → app-YE3I7JMR.js} +47 -20
- package/dist/{chunk-YRIPE5K5.js → chunk-JB57IX2A.js} +1 -1
- package/dist/{chunk-QQCXJC4U.js → chunk-STZQ3Y3P.js} +83 -39
- package/dist/cli.js +3 -3
- package/dist/desktop/main.js +63 -20
- package/dist/production.d.ts +8 -0
- package/dist/sdk/index.js +2 -2
- package/dist/utils/async.d.ts +14 -0
- package/package.json +1 -1
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
modelContentTranscriptText,
|
|
15
15
|
packageVersion,
|
|
16
16
|
redactErrorText,
|
|
17
|
-
transcriptReducer
|
|
18
|
-
|
|
17
|
+
transcriptReducer,
|
|
18
|
+
withTimeout
|
|
19
|
+
} from "./chunk-STZQ3Y3P.js";
|
|
19
20
|
import "./chunk-IG4Z23CL.js";
|
|
20
21
|
import {
|
|
21
22
|
Box_default,
|
|
@@ -874,21 +875,27 @@ function CodeBlock({ token }) {
|
|
|
874
875
|
const langLabel = token.lang?.trim();
|
|
875
876
|
const label = langLabel && langLabel.length > 0 ? langLabel : "code";
|
|
876
877
|
const topBarWidth = Math.max(0, columns - 4 - label.length - 4);
|
|
877
|
-
return
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
"
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
878
|
+
return (
|
|
879
|
+
// Code blocks are self-contained painted regions. Marking the region
|
|
880
|
+
// opaque prevents ScrollBox's incremental renderer from blitting cached
|
|
881
|
+
// blank cells over clean, single-line code bodies during transcript
|
|
882
|
+
// scrolls/redraws.
|
|
883
|
+
/* @__PURE__ */ jsxs(Box_default, { flexDirection: "column", paddingX: 1, opaque: true, children: [
|
|
884
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
885
|
+
"\u256D\u2500 ",
|
|
886
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: label }),
|
|
887
|
+
" ",
|
|
888
|
+
"\u2500".repeat(topBarWidth),
|
|
889
|
+
"\u256E"
|
|
890
|
+
] }),
|
|
891
|
+
/* @__PURE__ */ jsx(Box_default, { flexDirection: "column", paddingX: 1, children: truncated.map((line, i) => /* @__PURE__ */ jsx(Text, { color: "gray", children: line }, i)) }),
|
|
892
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
893
|
+
"\u2570",
|
|
894
|
+
"\u2500".repeat(Math.max(0, columns - 6)),
|
|
895
|
+
"\u256F"
|
|
896
|
+
] })
|
|
890
897
|
] })
|
|
891
|
-
|
|
898
|
+
);
|
|
892
899
|
}
|
|
893
900
|
function BlockquoteView({ token }) {
|
|
894
901
|
return /* @__PURE__ */ jsx(Box_default, { flexDirection: "column", children: token.tokens.map((child, i) => {
|
|
@@ -1098,9 +1105,15 @@ function AssistantTextInner({ text }) {
|
|
|
1098
1105
|
var AssistantText = React2.memo(AssistantTextInner);
|
|
1099
1106
|
|
|
1100
1107
|
// src/ui/signals.ts
|
|
1101
|
-
function createSessionInterruptHandler(getSession, shutdown) {
|
|
1108
|
+
function createSessionInterruptHandler(getSession, shutdown, options) {
|
|
1109
|
+
let shuttingDown = false;
|
|
1102
1110
|
return () => {
|
|
1111
|
+
if (shuttingDown) {
|
|
1112
|
+
options.forceExit();
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1103
1115
|
if (getSession()?.interrupt() === "cancelled") return;
|
|
1116
|
+
shuttingDown = true;
|
|
1104
1117
|
void shutdown();
|
|
1105
1118
|
};
|
|
1106
1119
|
}
|
|
@@ -1901,7 +1914,8 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
|
|
|
1901
1914
|
const interruptRef = useRef4(void 0);
|
|
1902
1915
|
interruptRef.current ??= createSessionInterruptHandler(
|
|
1903
1916
|
() => runtimeRef.current?.session,
|
|
1904
|
-
() => shutdownRef.current(runtimeRef.current)
|
|
1917
|
+
() => shutdownRef.current(runtimeRef.current),
|
|
1918
|
+
{ forceExit: () => process.exit(1) }
|
|
1905
1919
|
);
|
|
1906
1920
|
const interrupt = interruptRef.current;
|
|
1907
1921
|
useEffect3(() => {
|
|
@@ -3529,11 +3543,23 @@ async function submitSafely(session, prompt, report) {
|
|
|
3529
3543
|
safeReport(report, safeUiError(error));
|
|
3530
3544
|
}
|
|
3531
3545
|
}
|
|
3532
|
-
|
|
3546
|
+
var SHUTDOWN_TIMEOUT_MS = 8e3;
|
|
3547
|
+
var FORCE_EXIT_GRACE_MS = 250;
|
|
3548
|
+
async function shutdownRuntime(runtime, exit, report, options = {}) {
|
|
3549
|
+
const timeoutMs = options.shutdownTimeoutMs ?? SHUTDOWN_TIMEOUT_MS;
|
|
3550
|
+
let timedOut = false;
|
|
3533
3551
|
try {
|
|
3534
|
-
await closeAndDisposeRuntime(runtime, report);
|
|
3552
|
+
const outcome = await withTimeout(closeAndDisposeRuntime(runtime, report), timeoutMs);
|
|
3553
|
+
timedOut = outcome.timedOut;
|
|
3554
|
+
if (timedOut) report(`Shutdown timed out after ${timeoutMs}ms; forcing exit.`);
|
|
3535
3555
|
} finally {
|
|
3536
3556
|
exit();
|
|
3557
|
+
if (timedOut) {
|
|
3558
|
+
const forceExit = options.forceExit ?? (() => {
|
|
3559
|
+
process.exit(1);
|
|
3560
|
+
});
|
|
3561
|
+
setTimeout(forceExit, FORCE_EXIT_GRACE_MS);
|
|
3562
|
+
}
|
|
3537
3563
|
}
|
|
3538
3564
|
}
|
|
3539
3565
|
async function closeAndDisposeRuntime(runtime, report) {
|
|
@@ -3565,6 +3591,7 @@ export {
|
|
|
3565
3591
|
HISTORY_CAP,
|
|
3566
3592
|
MentionMenu,
|
|
3567
3593
|
PromptLine,
|
|
3594
|
+
SHUTDOWN_TIMEOUT_MS,
|
|
3568
3595
|
SinglePendingPrompt,
|
|
3569
3596
|
TerminalLayout,
|
|
3570
3597
|
appRuntimeOptions,
|
|
@@ -62,6 +62,52 @@ function normalizeProviderError(error) {
|
|
|
62
62
|
return { code, message: message2 };
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
// src/utils/async.ts
|
|
66
|
+
function withTimeout(promise, ms) {
|
|
67
|
+
return new Promise((resolve26, reject) => {
|
|
68
|
+
let settled = false;
|
|
69
|
+
const timer = setTimeout(() => {
|
|
70
|
+
if (settled) return;
|
|
71
|
+
settled = true;
|
|
72
|
+
resolve26({ timedOut: true, value: void 0 });
|
|
73
|
+
}, ms);
|
|
74
|
+
timer.unref?.();
|
|
75
|
+
promise.then(
|
|
76
|
+
(value) => {
|
|
77
|
+
if (!settled) {
|
|
78
|
+
settled = true;
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
resolve26({ timedOut: false, value });
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
(error) => {
|
|
84
|
+
if (!settled) {
|
|
85
|
+
settled = true;
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
reject(error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function awaitWithSignal(promise, signal) {
|
|
94
|
+
signal.throwIfAborted();
|
|
95
|
+
return new Promise((resolve26, reject) => {
|
|
96
|
+
const onAbort = () => reject(signal.reason);
|
|
97
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
98
|
+
promise.then(
|
|
99
|
+
(value) => {
|
|
100
|
+
signal.removeEventListener("abort", onAbort);
|
|
101
|
+
resolve26(value);
|
|
102
|
+
},
|
|
103
|
+
(error) => {
|
|
104
|
+
signal.removeEventListener("abort", onAbort);
|
|
105
|
+
reject(error);
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
65
111
|
// src/utils/error.ts
|
|
66
112
|
function message(error) {
|
|
67
113
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -5058,25 +5104,6 @@ function hasCycle(nodes) {
|
|
|
5058
5104
|
return visited !== nodes.length;
|
|
5059
5105
|
}
|
|
5060
5106
|
|
|
5061
|
-
// src/utils/async.ts
|
|
5062
|
-
function awaitWithSignal(promise, signal) {
|
|
5063
|
-
signal.throwIfAborted();
|
|
5064
|
-
return new Promise((resolve26, reject) => {
|
|
5065
|
-
const onAbort = () => reject(signal.reason);
|
|
5066
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
5067
|
-
promise.then(
|
|
5068
|
-
(value) => {
|
|
5069
|
-
signal.removeEventListener("abort", onAbort);
|
|
5070
|
-
resolve26(value);
|
|
5071
|
-
},
|
|
5072
|
-
(error) => {
|
|
5073
|
-
signal.removeEventListener("abort", onAbort);
|
|
5074
|
-
reject(error);
|
|
5075
|
-
}
|
|
5076
|
-
);
|
|
5077
|
-
});
|
|
5078
|
-
}
|
|
5079
|
-
|
|
5080
5107
|
// src/agent/subagents.ts
|
|
5081
5108
|
var SubagentResultSchema = z5.object({
|
|
5082
5109
|
taskId: z5.string().min(1),
|
|
@@ -18993,6 +19020,7 @@ var INTERRUPTED_TASK_PLAN_CONTEXT = [
|
|
|
18993
19020
|
"Reassess the current query independently.",
|
|
18994
19021
|
"If the current work needs a plan, create a fresh one with TaskPlan before using TaskUpdate."
|
|
18995
19022
|
].join(" ");
|
|
19023
|
+
var DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS = 3e3;
|
|
18996
19024
|
function createPromptEnvironment(input = {}) {
|
|
18997
19025
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
18998
19026
|
return {
|
|
@@ -20561,23 +20589,24 @@ ${renderMemoryDocument(entries)}`;
|
|
|
20561
20589
|
async dispose() {
|
|
20562
20590
|
if (disposed) return;
|
|
20563
20591
|
disposed = true;
|
|
20592
|
+
const stepTimeoutMs = options.shutdownStepTimeoutMs ?? DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS;
|
|
20564
20593
|
collaborationEventsOpen = false;
|
|
20565
20594
|
unsubscribeCollaboration?.();
|
|
20566
|
-
await collaborationEventPump;
|
|
20595
|
+
if (collaborationEventPump !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-event-pump", collaborationEventPump);
|
|
20567
20596
|
mcpDiscarded = true;
|
|
20568
|
-
await sleepScheduler
|
|
20569
|
-
await memoryCoordinator
|
|
20570
|
-
await persist();
|
|
20571
|
-
await persistTail;
|
|
20572
|
-
if (ideSessionId !== void 0) await ide.endSession(ideSessionId);
|
|
20573
|
-
await executionEnvironment
|
|
20597
|
+
if (sleepScheduler !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "sleep-scheduler", sleepScheduler.dispose());
|
|
20598
|
+
if (memoryCoordinator !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "memory-flush", memoryCoordinator.flush());
|
|
20599
|
+
await boundedStep(stepTimeoutMs, diagnostics, "persist", persist());
|
|
20600
|
+
if (persistTail !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "persist-tail", persistTail);
|
|
20601
|
+
if (ideSessionId !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "ide-end-session", ide.endSession(ideSessionId));
|
|
20602
|
+
if (executionEnvironment !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "execution-environment", executionEnvironment.dispose());
|
|
20574
20603
|
terminals.dispose();
|
|
20575
|
-
await jobs.dispose();
|
|
20604
|
+
await boundedStep(stepTimeoutMs, diagnostics, "jobs", jobs.dispose());
|
|
20576
20605
|
auditLogger.close();
|
|
20577
20606
|
evolveService.dispose();
|
|
20578
20607
|
memoryReviews.dispose();
|
|
20579
|
-
await collaborationClient
|
|
20580
|
-
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harness);
|
|
20608
|
+
if (collaborationClient !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-close", collaborationClient.close());
|
|
20609
|
+
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harness, { stepTimeoutMs });
|
|
20581
20610
|
}
|
|
20582
20611
|
};
|
|
20583
20612
|
} catch (primaryError) {
|
|
@@ -20585,16 +20614,17 @@ ${renderMemoryDocument(entries)}`;
|
|
|
20585
20614
|
mcpDiscarded = true;
|
|
20586
20615
|
memoryReviews.dispose();
|
|
20587
20616
|
try {
|
|
20588
|
-
|
|
20589
|
-
await
|
|
20590
|
-
await
|
|
20617
|
+
const stepTimeoutMs = options.shutdownStepTimeoutMs ?? DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS;
|
|
20618
|
+
if (ideSessionId !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "ide-end-session", ide.endSession(ideSessionId));
|
|
20619
|
+
if (sleepScheduler !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "sleep-scheduler", sleepScheduler.dispose());
|
|
20620
|
+
if (executionEnvironment !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "execution-environment", executionEnvironment.dispose());
|
|
20591
20621
|
terminals.dispose();
|
|
20592
|
-
await jobs.dispose();
|
|
20622
|
+
await boundedStep(stepTimeoutMs, diagnostics, "jobs", jobs.dispose());
|
|
20593
20623
|
unsubscribeCollaboration?.();
|
|
20594
20624
|
pendingCollaborationEvents.length = 0;
|
|
20595
|
-
await collaborationEventPump;
|
|
20596
|
-
await collaborationClient
|
|
20597
|
-
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harnessCreated ? harness : void 0);
|
|
20625
|
+
if (collaborationEventPump !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-event-pump", collaborationEventPump);
|
|
20626
|
+
if (collaborationClient !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-close", collaborationClient.close());
|
|
20627
|
+
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harnessCreated ? harness : void 0, { stepTimeoutMs });
|
|
20598
20628
|
} catch (cleanupError) {
|
|
20599
20629
|
attachCleanupError(primaryError, cleanupError);
|
|
20600
20630
|
}
|
|
@@ -21215,7 +21245,8 @@ function storedConversation(snapshot4) {
|
|
|
21215
21245
|
})
|
|
21216
21246
|
};
|
|
21217
21247
|
}
|
|
21218
|
-
async function cleanupProduction(approvals, questions, pluginHost, mcpManager, harness) {
|
|
21248
|
+
async function cleanupProduction(approvals, questions, pluginHost, mcpManager, harness, cleanupOptions = { stepTimeoutMs: DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS }) {
|
|
21249
|
+
const { stepTimeoutMs } = cleanupOptions;
|
|
21219
21250
|
let primary;
|
|
21220
21251
|
try {
|
|
21221
21252
|
approvals.resolve("deny");
|
|
@@ -21229,7 +21260,8 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
21229
21260
|
else attachCleanupError(primary, error);
|
|
21230
21261
|
}
|
|
21231
21262
|
try {
|
|
21232
|
-
await pluginHost.unloadAll();
|
|
21263
|
+
const outcome = await withTimeout(pluginHost.unloadAll(), stepTimeoutMs);
|
|
21264
|
+
if (outcome.timedOut) primary = new Error(`Plugin unload timed out after ${stepTimeoutMs}ms`);
|
|
21233
21265
|
} catch (error) {
|
|
21234
21266
|
if (primary === void 0) primary = error;
|
|
21235
21267
|
else attachCleanupError(primary, error);
|
|
@@ -21241,7 +21273,14 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
21241
21273
|
else attachCleanupError(primary, error);
|
|
21242
21274
|
}
|
|
21243
21275
|
try {
|
|
21244
|
-
|
|
21276
|
+
if (mcpManager !== void 0) {
|
|
21277
|
+
const outcome = await withTimeout(mcpManager.close(), stepTimeoutMs);
|
|
21278
|
+
if (outcome.timedOut) {
|
|
21279
|
+
const timeoutError = new Error(`MCP shutdown timed out after ${stepTimeoutMs}ms`);
|
|
21280
|
+
if (primary === void 0) primary = timeoutError;
|
|
21281
|
+
else attachCleanupError(primary, timeoutError);
|
|
21282
|
+
}
|
|
21283
|
+
}
|
|
21245
21284
|
} catch (error) {
|
|
21246
21285
|
if (primary === void 0) primary = error;
|
|
21247
21286
|
else attachCleanupError(primary, error);
|
|
@@ -21249,6 +21288,10 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
21249
21288
|
}
|
|
21250
21289
|
if (primary !== void 0) throw primary;
|
|
21251
21290
|
}
|
|
21291
|
+
async function boundedStep(timeoutMs, diagnostics, name, step) {
|
|
21292
|
+
const outcome = await withTimeout(step, timeoutMs);
|
|
21293
|
+
if (outcome.timedOut) diagnostics.push(`Shutdown step "${name}" timed out after ${timeoutMs}ms and was abandoned.`);
|
|
21294
|
+
}
|
|
21252
21295
|
function attachCleanupError(primary, cleanup) {
|
|
21253
21296
|
if (typeof primary !== "object" && typeof primary !== "function" || primary === null || !Object.isExtensible(primary)) return;
|
|
21254
21297
|
try {
|
|
@@ -21334,6 +21377,7 @@ function createMemoryTaskId() {
|
|
|
21334
21377
|
|
|
21335
21378
|
export {
|
|
21336
21379
|
modelContentTranscriptText,
|
|
21380
|
+
withTimeout,
|
|
21337
21381
|
message,
|
|
21338
21382
|
isDestructiveTool,
|
|
21339
21383
|
redactErrorText,
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createRequire } from "node:module"; const require = createRequire(impor
|
|
|
3
3
|
import {
|
|
4
4
|
FlavorRpcServer,
|
|
5
5
|
TraceRecorder
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JB57IX2A.js";
|
|
7
7
|
import {
|
|
8
8
|
staticTaskLines
|
|
9
9
|
} from "./chunk-KKIBYDJI.js";
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
packageVersion,
|
|
23
23
|
redactErrorText,
|
|
24
24
|
runPalBroker
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-STZQ3Y3P.js";
|
|
26
26
|
import {
|
|
27
27
|
McpServerConfigSchema,
|
|
28
28
|
McpServerNameSchema,
|
|
@@ -861,7 +861,7 @@ async function runInteractiveCli(props) {
|
|
|
861
861
|
const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
|
|
862
862
|
import("./claude-ink-ORUA7GWG.js"),
|
|
863
863
|
import("react"),
|
|
864
|
-
import("./app-
|
|
864
|
+
import("./app-YE3I7JMR.js")
|
|
865
865
|
]);
|
|
866
866
|
const instance = await render(createElement(
|
|
867
867
|
AlternateScreen,
|
package/dist/desktop/main.js
CHANGED
|
@@ -4348,6 +4348,33 @@ function hasCycle(nodes) {
|
|
|
4348
4348
|
}
|
|
4349
4349
|
|
|
4350
4350
|
// src/utils/async.ts
|
|
4351
|
+
function withTimeout(promise, ms) {
|
|
4352
|
+
return new Promise((resolve34, reject) => {
|
|
4353
|
+
let settled = false;
|
|
4354
|
+
const timer = setTimeout(() => {
|
|
4355
|
+
if (settled) return;
|
|
4356
|
+
settled = true;
|
|
4357
|
+
resolve34({ timedOut: true, value: void 0 });
|
|
4358
|
+
}, ms);
|
|
4359
|
+
timer.unref?.();
|
|
4360
|
+
promise.then(
|
|
4361
|
+
(value) => {
|
|
4362
|
+
if (!settled) {
|
|
4363
|
+
settled = true;
|
|
4364
|
+
clearTimeout(timer);
|
|
4365
|
+
resolve34({ timedOut: false, value });
|
|
4366
|
+
}
|
|
4367
|
+
},
|
|
4368
|
+
(error) => {
|
|
4369
|
+
if (!settled) {
|
|
4370
|
+
settled = true;
|
|
4371
|
+
clearTimeout(timer);
|
|
4372
|
+
reject(error);
|
|
4373
|
+
}
|
|
4374
|
+
}
|
|
4375
|
+
);
|
|
4376
|
+
});
|
|
4377
|
+
}
|
|
4351
4378
|
function awaitWithSignal3(promise, signal) {
|
|
4352
4379
|
signal.throwIfAborted();
|
|
4353
4380
|
return new Promise((resolve34, reject) => {
|
|
@@ -22696,6 +22723,7 @@ var INTERRUPTED_TASK_PLAN_CONTEXT = [
|
|
|
22696
22723
|
"Reassess the current query independently.",
|
|
22697
22724
|
"If the current work needs a plan, create a fresh one with TaskPlan before using TaskUpdate."
|
|
22698
22725
|
].join(" ");
|
|
22726
|
+
var DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS = 3e3;
|
|
22699
22727
|
function createPromptEnvironment(input = {}) {
|
|
22700
22728
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
22701
22729
|
return {
|
|
@@ -24264,23 +24292,24 @@ ${renderMemoryDocument(entries)}`;
|
|
|
24264
24292
|
async dispose() {
|
|
24265
24293
|
if (disposed) return;
|
|
24266
24294
|
disposed = true;
|
|
24295
|
+
const stepTimeoutMs = options.shutdownStepTimeoutMs ?? DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS;
|
|
24267
24296
|
collaborationEventsOpen = false;
|
|
24268
24297
|
unsubscribeCollaboration?.();
|
|
24269
|
-
await collaborationEventPump;
|
|
24298
|
+
if (collaborationEventPump !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-event-pump", collaborationEventPump);
|
|
24270
24299
|
mcpDiscarded = true;
|
|
24271
|
-
await sleepScheduler
|
|
24272
|
-
await memoryCoordinator
|
|
24273
|
-
await persist();
|
|
24274
|
-
await persistTail;
|
|
24275
|
-
if (ideSessionId !== void 0) await ide.endSession(ideSessionId);
|
|
24276
|
-
await executionEnvironment
|
|
24300
|
+
if (sleepScheduler !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "sleep-scheduler", sleepScheduler.dispose());
|
|
24301
|
+
if (memoryCoordinator !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "memory-flush", memoryCoordinator.flush());
|
|
24302
|
+
await boundedStep(stepTimeoutMs, diagnostics, "persist", persist());
|
|
24303
|
+
if (persistTail !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "persist-tail", persistTail);
|
|
24304
|
+
if (ideSessionId !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "ide-end-session", ide.endSession(ideSessionId));
|
|
24305
|
+
if (executionEnvironment !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "execution-environment", executionEnvironment.dispose());
|
|
24277
24306
|
terminals.dispose();
|
|
24278
|
-
await jobs.dispose();
|
|
24307
|
+
await boundedStep(stepTimeoutMs, diagnostics, "jobs", jobs.dispose());
|
|
24279
24308
|
auditLogger.close();
|
|
24280
24309
|
evolveService.dispose();
|
|
24281
24310
|
memoryReviews.dispose();
|
|
24282
|
-
await collaborationClient
|
|
24283
|
-
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harness);
|
|
24311
|
+
if (collaborationClient !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-close", collaborationClient.close());
|
|
24312
|
+
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harness, { stepTimeoutMs });
|
|
24284
24313
|
}
|
|
24285
24314
|
};
|
|
24286
24315
|
} catch (primaryError) {
|
|
@@ -24288,16 +24317,17 @@ ${renderMemoryDocument(entries)}`;
|
|
|
24288
24317
|
mcpDiscarded = true;
|
|
24289
24318
|
memoryReviews.dispose();
|
|
24290
24319
|
try {
|
|
24291
|
-
|
|
24292
|
-
await
|
|
24293
|
-
await
|
|
24320
|
+
const stepTimeoutMs = options.shutdownStepTimeoutMs ?? DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS;
|
|
24321
|
+
if (ideSessionId !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "ide-end-session", ide.endSession(ideSessionId));
|
|
24322
|
+
if (sleepScheduler !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "sleep-scheduler", sleepScheduler.dispose());
|
|
24323
|
+
if (executionEnvironment !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "execution-environment", executionEnvironment.dispose());
|
|
24294
24324
|
terminals.dispose();
|
|
24295
|
-
await jobs.dispose();
|
|
24325
|
+
await boundedStep(stepTimeoutMs, diagnostics, "jobs", jobs.dispose());
|
|
24296
24326
|
unsubscribeCollaboration?.();
|
|
24297
24327
|
pendingCollaborationEvents.length = 0;
|
|
24298
|
-
await collaborationEventPump;
|
|
24299
|
-
await collaborationClient
|
|
24300
|
-
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harnessCreated ? harness : void 0);
|
|
24328
|
+
if (collaborationEventPump !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-event-pump", collaborationEventPump);
|
|
24329
|
+
if (collaborationClient !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-close", collaborationClient.close());
|
|
24330
|
+
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harnessCreated ? harness : void 0, { stepTimeoutMs });
|
|
24301
24331
|
} catch (cleanupError) {
|
|
24302
24332
|
attachCleanupError(primaryError, cleanupError);
|
|
24303
24333
|
}
|
|
@@ -24918,7 +24948,8 @@ function storedConversation(snapshot4) {
|
|
|
24918
24948
|
})
|
|
24919
24949
|
};
|
|
24920
24950
|
}
|
|
24921
|
-
async function cleanupProduction(approvals, questions, pluginHost, mcpManager, harness) {
|
|
24951
|
+
async function cleanupProduction(approvals, questions, pluginHost, mcpManager, harness, cleanupOptions = { stepTimeoutMs: DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS }) {
|
|
24952
|
+
const { stepTimeoutMs } = cleanupOptions;
|
|
24922
24953
|
let primary;
|
|
24923
24954
|
try {
|
|
24924
24955
|
approvals.resolve("deny");
|
|
@@ -24932,7 +24963,8 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
24932
24963
|
else attachCleanupError(primary, error);
|
|
24933
24964
|
}
|
|
24934
24965
|
try {
|
|
24935
|
-
await pluginHost.unloadAll();
|
|
24966
|
+
const outcome = await withTimeout(pluginHost.unloadAll(), stepTimeoutMs);
|
|
24967
|
+
if (outcome.timedOut) primary = new Error(`Plugin unload timed out after ${stepTimeoutMs}ms`);
|
|
24936
24968
|
} catch (error) {
|
|
24937
24969
|
if (primary === void 0) primary = error;
|
|
24938
24970
|
else attachCleanupError(primary, error);
|
|
@@ -24944,7 +24976,14 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
24944
24976
|
else attachCleanupError(primary, error);
|
|
24945
24977
|
}
|
|
24946
24978
|
try {
|
|
24947
|
-
|
|
24979
|
+
if (mcpManager !== void 0) {
|
|
24980
|
+
const outcome = await withTimeout(mcpManager.close(), stepTimeoutMs);
|
|
24981
|
+
if (outcome.timedOut) {
|
|
24982
|
+
const timeoutError = new Error(`MCP shutdown timed out after ${stepTimeoutMs}ms`);
|
|
24983
|
+
if (primary === void 0) primary = timeoutError;
|
|
24984
|
+
else attachCleanupError(primary, timeoutError);
|
|
24985
|
+
}
|
|
24986
|
+
}
|
|
24948
24987
|
} catch (error) {
|
|
24949
24988
|
if (primary === void 0) primary = error;
|
|
24950
24989
|
else attachCleanupError(primary, error);
|
|
@@ -24952,6 +24991,10 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
24952
24991
|
}
|
|
24953
24992
|
if (primary !== void 0) throw primary;
|
|
24954
24993
|
}
|
|
24994
|
+
async function boundedStep(timeoutMs, diagnostics, name, step) {
|
|
24995
|
+
const outcome = await withTimeout(step, timeoutMs);
|
|
24996
|
+
if (outcome.timedOut) diagnostics.push(`Shutdown step "${name}" timed out after ${timeoutMs}ms and was abandoned.`);
|
|
24997
|
+
}
|
|
24955
24998
|
function attachCleanupError(primary, cleanup) {
|
|
24956
24999
|
if (typeof primary !== "object" && typeof primary !== "function" || primary === null || !Object.isExtensible(primary)) return;
|
|
24957
25000
|
try {
|
package/dist/production.d.ts
CHANGED
|
@@ -11,6 +11,12 @@ import { type TranscriptState } from "./ui/transcript.js";
|
|
|
11
11
|
import { MemoryReviewBridge } from "./memory/review.js";
|
|
12
12
|
import { type JobSnapshot } from "./jobs/registry.js";
|
|
13
13
|
import { type PalClientLike } from "./pals/tools.js";
|
|
14
|
+
/**
|
|
15
|
+
* Per-step shutdown budget. On Windows a hung child-process pipe, named pipe,
|
|
16
|
+
* or MCP stdio server can block one cleanup step forever; abandoning that step
|
|
17
|
+
* after the budget lets the remaining steps — and process exit — proceed.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS = 3000;
|
|
14
20
|
export interface ProductionRuntimeOptions {
|
|
15
21
|
workspace?: string;
|
|
16
22
|
home?: string;
|
|
@@ -27,6 +33,8 @@ export interface ProductionRuntimeOptions {
|
|
|
27
33
|
resumeSession?: string | true;
|
|
28
34
|
/** Test and embedding seam for creating configured MCP clients. */
|
|
29
35
|
mcpClientFactory?: McpClientFactory;
|
|
36
|
+
/** Per-step timeout (ms) for shutdown/disposal steps so a hung cleanup cannot block process exit. */
|
|
37
|
+
shutdownStepTimeoutMs?: number;
|
|
30
38
|
/** Additional tools provided by embedders (e.g. desktop-only D2C tools). */
|
|
31
39
|
extraTools?: readonly ToolDefinition<unknown>[];
|
|
32
40
|
/** Explicitly opt into CLI-local collaboration. Omit for print/RPC/eval callers. */
|
package/dist/sdk/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
FlavorRpcServer,
|
|
5
5
|
TraceRecordSchema,
|
|
6
6
|
TraceRecorder
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-JB57IX2A.js";
|
|
8
8
|
import {
|
|
9
9
|
AgentMessageQueue,
|
|
10
10
|
DockerExecutionEnvironment,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
WorkspaceCheckpointStore,
|
|
14
14
|
buildDockerInvocation,
|
|
15
15
|
createProductionRuntime
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-STZQ3Y3P.js";
|
|
17
17
|
import "../chunk-IG4Z23CL.js";
|
|
18
18
|
import "../chunk-RQTYHUMK.js";
|
|
19
19
|
import "../chunk-S32JRDZK.js";
|
package/dist/utils/async.d.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
export interface TimeoutOutcome<T> {
|
|
2
|
+
/** True when the deadline passed before the promise settled. */
|
|
3
|
+
timedOut: boolean;
|
|
4
|
+
/** The promise value; undefined when timed out (or when the value itself is undefined). */
|
|
5
|
+
value: T | undefined;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Race a promise against a deadline. Settles like the promise when it finishes
|
|
9
|
+
* in time; when the deadline passes first it resolves with `{ timedOut: true }`.
|
|
10
|
+
* The timer is always cleared so it never keeps the event loop alive on its own.
|
|
11
|
+
* The underlying promise is NOT cancelled — it keeps running in the background —
|
|
12
|
+
* so only use this for work you are willing to abandon (e.g. shutdown cleanup).
|
|
13
|
+
*/
|
|
14
|
+
export declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<TimeoutOutcome<T>>;
|
|
1
15
|
/**
|
|
2
16
|
* Race a promise against an AbortSignal. If the signal fires before the
|
|
3
17
|
* promise settles the returned promise rejects with the signal's reason.
|