neoctl 0.2.29 → 0.2.31
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/README.md +40 -4
- package/dist/context/compaction.d.ts +20 -4
- package/dist/context/compaction.js +377 -186
- package/dist/context/compaction.js.map +1 -1
- package/dist/context/context-manager.d.ts +7 -1
- package/dist/context/context-manager.js +15 -11
- package/dist/context/context-manager.js.map +1 -1
- package/dist/context/prompts.js +2 -0
- package/dist/context/prompts.js.map +1 -1
- package/dist/context/smoke-context.js +266 -17
- package/dist/context/smoke-context.js.map +1 -1
- package/dist/core/assistant-output-filter.d.ts +1 -0
- package/dist/core/assistant-output-filter.js +54 -2
- package/dist/core/assistant-output-filter.js.map +1 -1
- package/dist/core/context-metrics.d.ts +1 -0
- package/dist/core/context-metrics.js +18 -12
- package/dist/core/context-metrics.js.map +1 -1
- package/dist/core/image-registry.d.ts +16 -3
- package/dist/core/image-registry.js +65 -30
- package/dist/core/image-registry.js.map +1 -1
- package/dist/core/image-storage.d.ts +15 -1
- package/dist/core/image-storage.js +140 -17
- package/dist/core/image-storage.js.map +1 -1
- package/dist/core/message-pipeline.js +18 -4
- package/dist/core/message-pipeline.js.map +1 -1
- package/dist/core/query-engine.d.ts +12 -2
- package/dist/core/query-engine.js +57 -8
- package/dist/core/query-engine.js.map +1 -1
- package/dist/core/query.d.ts +13 -2
- package/dist/core/query.js +56 -21
- package/dist/core/query.js.map +1 -1
- package/dist/core/smoke-core-loop.js +68 -3
- package/dist/core/smoke-core-loop.js.map +1 -1
- package/dist/core/smoke-image-integrity.d.ts +1 -0
- package/dist/core/smoke-image-integrity.js +67 -0
- package/dist/core/smoke-image-integrity.js.map +1 -0
- package/dist/core/state.d.ts +1 -1
- package/dist/core/state.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/model/model-metadata.json +4 -4
- package/dist/plugins/plugin-system.d.ts +61 -0
- package/dist/plugins/plugin-system.js +189 -0
- package/dist/plugins/plugin-system.js.map +1 -0
- package/dist/plugins/smoke-plugin-system.d.ts +1 -0
- package/dist/plugins/smoke-plugin-system.js +63 -0
- package/dist/plugins/smoke-plugin-system.js.map +1 -0
- package/dist/repl/index.js +8 -3
- package/dist/repl/index.js.map +1 -1
- package/dist/session/session-export.d.ts +2 -0
- package/dist/session/session-export.js +10 -0
- package/dist/session/session-export.js.map +1 -1
- package/dist/session/session-store.d.ts +41 -0
- package/dist/session/session-store.js +292 -59
- package/dist/session/session-store.js.map +1 -1
- package/dist/session/smoke-session.js +127 -7
- package/dist/session/smoke-session.js.map +1 -1
- package/dist/tools/builtins/exec-process-manager.d.ts +16 -2
- package/dist/tools/builtins/exec-process-manager.js +119 -25
- package/dist/tools/builtins/exec-process-manager.js.map +1 -1
- package/dist/tools/builtins/exec-tool.js +11 -2
- package/dist/tools/builtins/exec-tool.js.map +1 -1
- package/dist/tools/builtins/image-generation-tool.js +32 -42
- package/dist/tools/builtins/image-generation-tool.js.map +1 -1
- package/dist/tools/builtins/image-loader-tool.js +10 -4
- package/dist/tools/builtins/image-loader-tool.js.map +1 -1
- package/dist/tools/builtins/image-note-tool.js +8 -3
- package/dist/tools/builtins/image-note-tool.js.map +1 -1
- package/dist/tools/registry.d.ts +8 -1
- package/dist/tools/registry.js +37 -13
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/smoke-exec-process.js +88 -4
- package/dist/tools/smoke-exec-process.js.map +1 -1
- package/dist/tools/smoke-tool-system.js +24 -6
- package/dist/tools/smoke-tool-system.js.map +1 -1
- package/dist/types/events.d.ts +5 -1
- package/dist/types/messages.d.ts +13 -5
- package/dist/types/messages.js +4 -0
- package/dist/types/messages.js.map +1 -1
- package/dist/ui/display-message.d.ts +10 -2
- package/dist/ui/display-message.js +18 -9
- package/dist/ui/display-message.js.map +1 -1
- package/dist/web/index.d.ts +176 -11
- package/dist/web/index.js +986 -106
- package/dist/web/index.js.map +1 -1
- package/dist/web/runtime-context-protocol.d.ts +12 -1
- package/dist/web/runtime-context-protocol.js +16 -1
- package/dist/web/runtime-context-protocol.js.map +1 -1
- package/dist/web/smoke-runtime-context-protocol.js +3 -0
- package/dist/web/smoke-runtime-context-protocol.js.map +1 -1
- package/dist/web/smoke-web-history.d.ts +1 -0
- package/dist/web/smoke-web-history.js +121 -0
- package/dist/web/smoke-web-history.js.map +1 -0
- package/dist/web/smoke-web-terminal-tasks.d.ts +1 -0
- package/dist/web/smoke-web-terminal-tasks.js +90 -0
- package/dist/web/smoke-web-terminal-tasks.js.map +1 -0
- package/package.json +5 -1
|
@@ -4,7 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { FileToolResultMemory, PERSISTED_OUTPUT_TAG } from "./tool-result-memory.js";
|
|
5
5
|
import { SessionStore } from "./session-store.js";
|
|
6
6
|
import { writeSessionMarkdownExport } from "./session-export.js";
|
|
7
|
-
import { createThinkingMessage } from "../types/messages.js";
|
|
7
|
+
import { createTextMessage, createThinkingMessage } from "../types/messages.js";
|
|
8
8
|
async function main() {
|
|
9
9
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), "agent-session-smoke-"));
|
|
10
10
|
const sessionId = "smoke-session";
|
|
@@ -17,15 +17,56 @@ async function main() {
|
|
|
17
17
|
for (const message of messages)
|
|
18
18
|
store.recordMessage(message);
|
|
19
19
|
store.recordMessage(createThinkingMessage("persisted visible reasoning"));
|
|
20
|
+
store.recordMessage(createTextMessage("assistant", "assistant before compact"));
|
|
20
21
|
store.recordContentReplacements(first.records);
|
|
21
22
|
store.recordTitle("Smoke Session Title", "initial");
|
|
22
23
|
store.recordTitle("Refined Smoke Session Title", "refinement");
|
|
23
24
|
store.recordFastMode(true);
|
|
25
|
+
store.recordContextWindowTokens(256000);
|
|
24
26
|
store.recordMessage({ ...messages[0], role: "progress" });
|
|
27
|
+
const compactionBoundary = {
|
|
28
|
+
...createTextMessage("system", "<compact_state>persisted compact state</compact_state>"),
|
|
29
|
+
isMeta: true,
|
|
30
|
+
metadata: { compactBoundary: true, compactionReason: "manualcompact", modelDriven: true },
|
|
31
|
+
};
|
|
32
|
+
const preservedUser = { ...createTextMessage("user", "preserved user request"), metadata: { compactPreservedUser: true } };
|
|
33
|
+
store.recordCompactCheckpoint([preservedUser, compactionBoundary], "manualcompact", {
|
|
34
|
+
reason: "manualcompact",
|
|
35
|
+
summary: "persisted compact summary",
|
|
36
|
+
continuationState: "persisted compact state",
|
|
37
|
+
sourceMessages: messages.length + 2,
|
|
38
|
+
preservedUserMessages: 1,
|
|
39
|
+
newWindowMessages: 2,
|
|
40
|
+
charsFreed: 1234,
|
|
41
|
+
modelDriven: true,
|
|
42
|
+
imageCount: 0,
|
|
43
|
+
});
|
|
44
|
+
store.recordMessage(createTextMessage("assistant", "assistant between compacts"));
|
|
45
|
+
const secondCompactionBoundary = {
|
|
46
|
+
...createTextMessage("system", "<compact_state>second compact state</compact_state>"),
|
|
47
|
+
isMeta: true,
|
|
48
|
+
metadata: { compactBoundary: true, compactionReason: "manualcompact", modelDriven: true },
|
|
49
|
+
};
|
|
50
|
+
store.recordCompactCheckpoint([preservedUser, secondCompactionBoundary], "manualcompact", {
|
|
51
|
+
reason: "manualcompact",
|
|
52
|
+
summary: "second compact summary",
|
|
53
|
+
continuationState: "second compact state",
|
|
54
|
+
sourceMessages: 3,
|
|
55
|
+
preservedUserMessages: 1,
|
|
56
|
+
newWindowMessages: 2,
|
|
57
|
+
charsFreed: 2345,
|
|
58
|
+
modelDriven: true,
|
|
59
|
+
imageCount: 0,
|
|
60
|
+
});
|
|
61
|
+
store.recordMessage(createTextMessage("assistant", "assistant after second compact"));
|
|
25
62
|
const resumed = await SessionStore.open({ agentId: "main", rootDir: root, sessionId, resume: true });
|
|
26
63
|
const latest = await SessionStore.open({ agentId: "main", rootDir: root, resume: true });
|
|
27
64
|
const listed = await SessionStore.list({ agentId: "main", rootDir: root });
|
|
28
65
|
const resumedBudget = await resumed.toolResultMemory.applyBudget(resumed.getInitialMessages(), { maxSerializedLength: 180 });
|
|
66
|
+
const displayEntries = resumed.getDisplayEntries();
|
|
67
|
+
const displayMessages = displayEntries.filter((entry) => entry.type === "message").map((entry) => entry.message);
|
|
68
|
+
const displayCompactions = displayEntries.filter((entry) => entry.type === "compact");
|
|
69
|
+
const displayCompactionIndexes = displayEntries.flatMap((entry, index) => entry.type === "compact" ? [index] : []);
|
|
29
70
|
const exportPath = path.join(root, "exports", "session.md");
|
|
30
71
|
const exportResult = await writeSessionMarkdownExport({
|
|
31
72
|
outputPath: exportPath,
|
|
@@ -41,6 +82,36 @@ async function main() {
|
|
|
41
82
|
maxToolResultLines: 3,
|
|
42
83
|
});
|
|
43
84
|
const exportedMarkdown = await fs.readFile(exportPath, "utf8");
|
|
85
|
+
const truncatedTailSessionId = "truncated-tail-session";
|
|
86
|
+
const truncatedTailStore = await SessionStore.open({ agentId: "main", rootDir: root, sessionId: truncatedTailSessionId });
|
|
87
|
+
truncatedTailStore.recordMessage(createTextMessage("user", "durable before partial tail"));
|
|
88
|
+
await fs.appendFile(truncatedTailStore.transcriptPath, '{"type":"message","sessionId":"truncated-tail-session"', "utf8");
|
|
89
|
+
const recoveredTailStore = await SessionStore.open({ agentId: "main", rootDir: root, sessionId: truncatedTailSessionId, resume: true });
|
|
90
|
+
const recoveredTailMessagesBeforeAppend = recoveredTailStore.getInitialMessages();
|
|
91
|
+
const repairedTailText = await fs.readFile(truncatedTailStore.transcriptPath, "utf8");
|
|
92
|
+
recoveredTailStore.recordMessage(createTextMessage("assistant", "durable after partial tail"));
|
|
93
|
+
const recoveredTailAgain = await SessionStore.open({ agentId: "main", rootDir: root, sessionId: truncatedTailSessionId, resume: true });
|
|
94
|
+
const unterminatedValidSessionId = "unterminated-valid-session";
|
|
95
|
+
const unterminatedValidStore = await SessionStore.open({ agentId: "main", rootDir: root, sessionId: unterminatedValidSessionId });
|
|
96
|
+
unterminatedValidStore.recordMessage(createTextMessage("user", "valid record without final newline"));
|
|
97
|
+
const validTranscript = await fs.readFile(unterminatedValidStore.transcriptPath, "utf8");
|
|
98
|
+
await fs.writeFile(unterminatedValidStore.transcriptPath, validTranscript.replace(/\n$/u, ""), "utf8");
|
|
99
|
+
const recoveredValidTail = await SessionStore.open({ agentId: "main", rootDir: root, sessionId: unterminatedValidSessionId, resume: true });
|
|
100
|
+
const repairedValidText = await fs.readFile(unterminatedValidStore.transcriptPath, "utf8");
|
|
101
|
+
const corruptMiddleSessionId = "corrupt-middle-session";
|
|
102
|
+
const corruptMiddleStore = await SessionStore.open({ agentId: "main", rootDir: root, sessionId: corruptMiddleSessionId });
|
|
103
|
+
corruptMiddleStore.recordMessage(createTextMessage("user", "before corrupt middle"));
|
|
104
|
+
corruptMiddleStore.recordMessage(createTextMessage("assistant", "after corrupt middle"));
|
|
105
|
+
const corruptLines = (await fs.readFile(corruptMiddleStore.transcriptPath, "utf8")).trimEnd().split("\n");
|
|
106
|
+
await fs.writeFile(corruptMiddleStore.transcriptPath, `${corruptLines[0]}\n{malformed}\n${corruptLines[1]}\n`, "utf8");
|
|
107
|
+
const corruptMiddleRejected = await SessionStore.open({ agentId: "main", rootDir: root, sessionId: corruptMiddleSessionId, resume: true })
|
|
108
|
+
.then(() => false)
|
|
109
|
+
.catch((error) => error instanceof Error && error.message.includes("Malformed session transcript"));
|
|
110
|
+
const durabilitySessionsDeleted = await Promise.all([
|
|
111
|
+
truncatedTailSessionId,
|
|
112
|
+
unterminatedValidSessionId,
|
|
113
|
+
corruptMiddleSessionId,
|
|
114
|
+
].map((durabilitySessionId) => SessionStore.delete({ rootDir: root, sessionId: durabilitySessionId })));
|
|
44
115
|
const afterReset = await SessionStore.open({ agentId: "main", rootDir: root, sessionId, resume: true });
|
|
45
116
|
afterReset.reset();
|
|
46
117
|
const resetResume = await SessionStore.open({ agentId: "main", rootDir: root, sessionId, resume: true });
|
|
@@ -50,33 +121,82 @@ async function main() {
|
|
|
50
121
|
persistedBlocks.length === 1 &&
|
|
51
122
|
second.records.length === 0 &&
|
|
52
123
|
JSON.stringify(first.messages) === JSON.stringify(second.messages) &&
|
|
53
|
-
resumed.snapshot().resumedMessages ===
|
|
54
|
-
resumed.getInitialMessages()
|
|
124
|
+
resumed.snapshot().resumedMessages === 3 &&
|
|
125
|
+
resumed.getInitialMessages()[0]?.metadata?.compactPreservedUser === true &&
|
|
126
|
+
resumed.getInitialMessages()[1]?.metadata?.compactBoundary === true &&
|
|
127
|
+
resumed.getInitialMessages().at(-1)?.blocks.some((block) => block.type === "text" && block.text === "assistant after second compact") === true &&
|
|
128
|
+
displayMessages.length === messages.length + 4 &&
|
|
129
|
+
displayMessages.some((message) => message.role === "assistant" && message.blocks.some((block) => block.type === "text" && block.text === "assistant before compact")) &&
|
|
130
|
+
displayMessages.some((message) => message.role === "assistant" && message.blocks.some((block) => block.type === "text" && block.text === "assistant between compacts")) &&
|
|
131
|
+
displayMessages.some((message) => message.role === "assistant" && message.blocks.some((block) => block.type === "text" && block.text === "assistant after second compact")) &&
|
|
132
|
+
displayCompactions.length === 2 &&
|
|
133
|
+
displayCompactions[0]?.report?.summary === "persisted compact summary" &&
|
|
134
|
+
displayCompactions[1]?.report?.summary === "second compact summary" &&
|
|
135
|
+
displayEntries.findIndex((entry) => entry.type === "compact") > displayEntries.findIndex((entry) => entry.type === "message" && entry.message.blocks.some((block) => block.type === "text" && block.text === "assistant before compact")) &&
|
|
136
|
+
displayEntries.findIndex((entry) => entry.type === "message" && entry.message.blocks.some((block) => block.type === "text" && block.text === "assistant between compacts")) > displayEntries.findIndex((entry) => entry.type === "compact") &&
|
|
137
|
+
displayCompactionIndexes.at(-1) < displayEntries.findIndex((entry) => entry.type === "message" && entry.message.blocks.some((block) => block.type === "text" && block.text === "assistant after second compact")) &&
|
|
138
|
+
resumed.snapshot().lastCompaction?.summary === "second compact summary" &&
|
|
139
|
+
resumed.snapshot().lastCompaction?.continuationState === "second compact state" &&
|
|
55
140
|
resumed.snapshot().title === "Refined Smoke Session Title" &&
|
|
56
141
|
resumed.snapshot().titleKind === "refinement" &&
|
|
57
142
|
resumed.snapshot().hasInitialTitle &&
|
|
58
143
|
resumed.snapshot().hasTitleRefinement &&
|
|
59
144
|
resumed.snapshot().fastMode === true &&
|
|
145
|
+
resumed.snapshot().contextWindowTokens === 256000 &&
|
|
146
|
+
resumed.getContextWindowTokens() === 256000 &&
|
|
60
147
|
latest.snapshot().sessionId === sessionId &&
|
|
61
|
-
latest.snapshot().resumedMessages ===
|
|
148
|
+
latest.snapshot().resumedMessages === 3 &&
|
|
149
|
+
latest.snapshot().lastCompaction?.charsFreed === 2345 &&
|
|
62
150
|
latest.snapshot().title === "Refined Smoke Session Title" &&
|
|
63
151
|
latest.snapshot().titleKind === "refinement" &&
|
|
64
152
|
listed.length === 1 &&
|
|
65
153
|
listed[0]?.sessionId === sessionId &&
|
|
66
154
|
listed[0]?.title === "Refined Smoke Session Title" &&
|
|
67
155
|
resumedBudget.records.length === 0 &&
|
|
68
|
-
resumedBudget.messages.
|
|
156
|
+
resumedBudget.messages.every((message) => message.role !== "tool_result") &&
|
|
69
157
|
exportResult.bytes > 0 &&
|
|
70
158
|
exportedMarkdown.includes("# Neo Session Export") &&
|
|
71
159
|
exportedMarkdown.includes("system prompt smoke") &&
|
|
72
160
|
exportedMarkdown.includes("## Transcript") &&
|
|
73
161
|
exportedMarkdown.includes("Tool use ID: call_a") &&
|
|
74
|
-
exportedMarkdown.includes("persisted
|
|
162
|
+
exportedMarkdown.includes("persisted compact state") &&
|
|
163
|
+
recoveredTailMessagesBeforeAppend.length === 1 &&
|
|
164
|
+
recoveredTailMessagesBeforeAppend[0]?.blocks.some((block) => block.type === "text" && block.text === "durable before partial tail") === true &&
|
|
165
|
+
repairedTailText.endsWith("\n") &&
|
|
166
|
+
repairedTailText.trimEnd().split("\n").length === 1 &&
|
|
167
|
+
recoveredTailAgain.getInitialMessages().length === 2 &&
|
|
168
|
+
recoveredTailAgain.getInitialMessages()[1]?.blocks.some((block) => block.type === "text" && block.text === "durable after partial tail") === true &&
|
|
169
|
+
recoveredValidTail.getInitialMessages().length === 1 &&
|
|
170
|
+
repairedValidText.endsWith("\n") &&
|
|
171
|
+
corruptMiddleRejected &&
|
|
172
|
+
durabilitySessionsDeleted.every(Boolean) &&
|
|
75
173
|
resetResume.snapshot().resumedMessages === 0 &&
|
|
174
|
+
resetResume.snapshot().lastCompaction === undefined &&
|
|
76
175
|
resetResume.snapshot().fastMode === true &&
|
|
176
|
+
resetResume.snapshot().contextWindowTokens === 256000 &&
|
|
77
177
|
deleted &&
|
|
78
178
|
listedAfterDelete.length === 0;
|
|
79
|
-
console.log(JSON.stringify({
|
|
179
|
+
console.log(JSON.stringify({
|
|
180
|
+
ok,
|
|
181
|
+
firstRecords: first.records.length,
|
|
182
|
+
persistedBlocks: persistedBlocks.length,
|
|
183
|
+
exportResult,
|
|
184
|
+
resumed: resumed.snapshot(),
|
|
185
|
+
latest: latest.snapshot(),
|
|
186
|
+
listed,
|
|
187
|
+
durability: {
|
|
188
|
+
recoveredTailMessagesBeforeAppend: recoveredTailMessagesBeforeAppend.length,
|
|
189
|
+
repairedTailLines: repairedTailText.trimEnd().split("\n").length,
|
|
190
|
+
recoveredTailAgainMessages: recoveredTailAgain.getInitialMessages().length,
|
|
191
|
+
recoveredValidTailMessages: recoveredValidTail.getInitialMessages().length,
|
|
192
|
+
repairedValidEndsWithNewline: repairedValidText.endsWith("\n"),
|
|
193
|
+
corruptMiddleRejected,
|
|
194
|
+
durabilitySessionsDeleted,
|
|
195
|
+
},
|
|
196
|
+
reset: resetResume.snapshot(),
|
|
197
|
+
deleted,
|
|
198
|
+
listedAfterDelete,
|
|
199
|
+
}, null, 2));
|
|
80
200
|
if (!ok)
|
|
81
201
|
process.exitCode = 1;
|
|
82
202
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smoke-session.js","sourceRoot":"","sources":["../../src/session/smoke-session.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"smoke-session.js","sourceRoot":"","sources":["../../src/session/smoke-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type ExecOutputStream = "stdout" | "stderr";
|
|
2
2
|
export type ExecProcessStatus = "running" | "exited" | "failed" | "timed_out" | "killed";
|
|
3
|
+
export type ExecTerminationReason = "completed" | "failed" | "user_interrupt" | "user_terminate" | "user_kill" | "timeout" | "external_signal" | "spawn_error";
|
|
3
4
|
export interface ExecProcessStartOptions {
|
|
4
5
|
ownerId?: string;
|
|
5
6
|
command: string;
|
|
@@ -9,21 +10,25 @@ export interface ExecProcessStartOptions {
|
|
|
9
10
|
requested: string;
|
|
10
11
|
file: string;
|
|
11
12
|
args: string[];
|
|
13
|
+
commandPrefix?: string;
|
|
12
14
|
};
|
|
13
15
|
env: Record<string, string>;
|
|
14
16
|
timeoutMs: number;
|
|
15
17
|
maxOutputChars: number;
|
|
16
18
|
tty: boolean;
|
|
19
|
+
redactOutput?: (text: string) => string;
|
|
17
20
|
}
|
|
18
21
|
export interface ExecProcessOutputDelta {
|
|
19
22
|
sessionId: string;
|
|
20
23
|
stream: ExecOutputStream;
|
|
21
24
|
text: string;
|
|
25
|
+
outputStart?: number;
|
|
26
|
+
outputEnd?: number;
|
|
22
27
|
}
|
|
23
28
|
export interface ExecProcessResult {
|
|
24
29
|
status: ExecProcessStatus;
|
|
25
30
|
session_id: string;
|
|
26
|
-
process_id: number;
|
|
31
|
+
process_id: number | null;
|
|
27
32
|
command: string;
|
|
28
33
|
description?: string;
|
|
29
34
|
cwd: string;
|
|
@@ -31,6 +36,7 @@ export interface ExecProcessResult {
|
|
|
31
36
|
tty: boolean;
|
|
32
37
|
exit_code: number | null;
|
|
33
38
|
signal: string | number | null;
|
|
39
|
+
termination_reason: ExecTerminationReason | null;
|
|
34
40
|
duration_ms: number;
|
|
35
41
|
timed_out: boolean;
|
|
36
42
|
stdout: string;
|
|
@@ -56,6 +62,7 @@ export declare class ExecProcessManager {
|
|
|
56
62
|
private readonly options;
|
|
57
63
|
private readonly sessions;
|
|
58
64
|
private readonly subscribers;
|
|
65
|
+
private readonly outputSubscribers;
|
|
59
66
|
private nextId;
|
|
60
67
|
constructor(options?: {
|
|
61
68
|
maxProcesses?: number;
|
|
@@ -64,12 +71,19 @@ export declare class ExecProcessManager {
|
|
|
64
71
|
start(options: ExecProcessStartOptions): string;
|
|
65
72
|
interact(sessionId: string, interaction: ExecProcessInteraction): Promise<ExecProcessResult>;
|
|
66
73
|
execute(options: ExecProcessStartOptions, yieldTimeMs: number, onOutput?: (delta: ExecProcessOutputDelta) => void, abortSignal?: AbortSignal): Promise<ExecProcessResult>;
|
|
67
|
-
list(): Array<Pick<ExecProcessResult, "session_id" | "process_id" | "status" | "command" | "cwd" | "duration_ms" | "tty"
|
|
74
|
+
list(): Array<Pick<ExecProcessResult, "session_id" | "process_id" | "status" | "command" | "description" | "cwd" | "shell" | "duration_ms" | "tty" | "termination_reason"> & {
|
|
75
|
+
backgrounded: boolean;
|
|
76
|
+
output: string;
|
|
77
|
+
outputEnd: number;
|
|
78
|
+
}>;
|
|
68
79
|
activeCount(): number;
|
|
80
|
+
isBackgroundRunning(sessionId: string): boolean;
|
|
69
81
|
subscribe(listener: () => void): () => void;
|
|
82
|
+
subscribeOutput(listener: (delta: ExecProcessOutputDelta) => void): () => void;
|
|
70
83
|
terminateAll(): void;
|
|
71
84
|
private createSession;
|
|
72
85
|
private signal;
|
|
86
|
+
private finalizeSession;
|
|
73
87
|
private notifyExit;
|
|
74
88
|
private waitForExit;
|
|
75
89
|
private drain;
|
|
@@ -2,10 +2,12 @@ import { spawn as spawnChild } from "node:child_process";
|
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import os from "node:os";
|
|
5
|
+
const LIVE_OUTPUT_MAX_CHARS = 40_000;
|
|
5
6
|
export class ExecProcessManager {
|
|
6
7
|
options;
|
|
7
8
|
sessions = new Map();
|
|
8
9
|
subscribers = new Set();
|
|
10
|
+
outputSubscribers = new Set();
|
|
9
11
|
nextId = 1;
|
|
10
12
|
constructor(options = {}) {
|
|
11
13
|
this.options = options;
|
|
@@ -19,13 +21,12 @@ export class ExecProcessManager {
|
|
|
19
21
|
session.timeout = setTimeout(() => {
|
|
20
22
|
if (session.status !== "running")
|
|
21
23
|
return;
|
|
22
|
-
session.
|
|
24
|
+
session.requestedTerminationReason = "timeout";
|
|
23
25
|
session.backend.terminate(false);
|
|
24
|
-
setTimeout(() => {
|
|
25
|
-
if (session.status === "
|
|
26
|
+
session.escalation = setTimeout(() => {
|
|
27
|
+
if (session.status === "running")
|
|
26
28
|
session.backend.terminate(true);
|
|
27
29
|
}, 1_000).unref();
|
|
28
|
-
this.notifyExit(session);
|
|
29
30
|
}, options.timeoutMs);
|
|
30
31
|
session.timeout.unref();
|
|
31
32
|
return id;
|
|
@@ -65,7 +66,18 @@ export class ExecProcessManager {
|
|
|
65
66
|
}
|
|
66
67
|
async execute(options, yieldTimeMs, onOutput, abortSignal) {
|
|
67
68
|
const sessionId = this.start(options);
|
|
68
|
-
|
|
69
|
+
const result = await this.interact(sessionId, { ownerId: options.ownerId, yieldTimeMs, onOutput, abortSignal });
|
|
70
|
+
if (result.status === "running") {
|
|
71
|
+
const session = this.sessions.get(sessionId);
|
|
72
|
+
if (session && !session.backgrounded) {
|
|
73
|
+
session.backgrounded = true;
|
|
74
|
+
if (session.timeout)
|
|
75
|
+
clearTimeout(session.timeout);
|
|
76
|
+
session.timeout = undefined;
|
|
77
|
+
this.notify();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
69
81
|
}
|
|
70
82
|
list() {
|
|
71
83
|
return [...this.sessions.values()].map((session) => ({
|
|
@@ -73,46 +85,71 @@ export class ExecProcessManager {
|
|
|
73
85
|
process_id: session.backend.pid,
|
|
74
86
|
status: session.status,
|
|
75
87
|
command: session.options.command,
|
|
88
|
+
description: session.options.description,
|
|
76
89
|
cwd: session.options.cwd,
|
|
77
|
-
|
|
90
|
+
shell: session.options.shell.requested,
|
|
91
|
+
duration_ms: (session.finishedAt ?? Date.now()) - session.startedAt,
|
|
78
92
|
tty: session.options.tty,
|
|
93
|
+
termination_reason: session.terminationReason,
|
|
94
|
+
backgrounded: session.backgrounded,
|
|
95
|
+
output: session.liveOutput.snapshot().text,
|
|
96
|
+
outputEnd: session.liveOutput.observedChars(),
|
|
79
97
|
}));
|
|
80
98
|
}
|
|
81
99
|
activeCount() {
|
|
82
|
-
return [...this.sessions.values()].filter((session) => session.status === "running").length;
|
|
100
|
+
return [...this.sessions.values()].filter((session) => session.status === "running" && session.backgrounded).length;
|
|
101
|
+
}
|
|
102
|
+
isBackgroundRunning(sessionId) {
|
|
103
|
+
const session = this.sessions.get(sessionId);
|
|
104
|
+
return Boolean(session?.backgrounded && session.status === "running");
|
|
83
105
|
}
|
|
84
106
|
subscribe(listener) {
|
|
85
107
|
this.subscribers.add(listener);
|
|
86
108
|
return () => this.subscribers.delete(listener);
|
|
87
109
|
}
|
|
110
|
+
subscribeOutput(listener) {
|
|
111
|
+
this.outputSubscribers.add(listener);
|
|
112
|
+
return () => this.outputSubscribers.delete(listener);
|
|
113
|
+
}
|
|
88
114
|
terminateAll() {
|
|
89
115
|
for (const session of this.sessions.values()) {
|
|
90
116
|
if (session.status === "running") {
|
|
91
|
-
session.
|
|
117
|
+
session.requestedTerminationReason = "user_kill";
|
|
92
118
|
session.backend.terminate(true);
|
|
93
|
-
this.notifyExit(session);
|
|
94
119
|
}
|
|
95
120
|
}
|
|
96
121
|
}
|
|
97
122
|
createSession(id, options) {
|
|
98
123
|
let session;
|
|
124
|
+
let redactOutput = options.redactOutput;
|
|
125
|
+
let liveOutputOffset = 0;
|
|
99
126
|
const onOutput = (stream, text) => {
|
|
100
127
|
const normalized = normalizeOutput(text);
|
|
101
128
|
if (!normalized)
|
|
102
129
|
return;
|
|
103
130
|
session[stream].push(normalized);
|
|
131
|
+
const safeOutput = redactOutput?.(normalized) ?? normalized;
|
|
132
|
+
const liveText = stream === "stderr" ? `[stderr] ${safeOutput}` : safeOutput;
|
|
133
|
+
session.liveOutput.push(liveText);
|
|
104
134
|
const delta = { sessionId: id, stream, text: normalized };
|
|
105
135
|
for (const subscriber of session.subscribers)
|
|
106
136
|
subscriber(delta);
|
|
137
|
+
const outputStart = liveOutputOffset;
|
|
138
|
+
liveOutputOffset += liveText.length;
|
|
139
|
+
if (session.backgrounded) {
|
|
140
|
+
const publicDelta = { sessionId: id, stream, text: liveText, outputStart, outputEnd: liveOutputOffset };
|
|
141
|
+
for (const subscriber of this.outputSubscribers)
|
|
142
|
+
subscriber(publicDelta);
|
|
143
|
+
}
|
|
107
144
|
};
|
|
108
145
|
const onExit = (exitCode, signal, error) => {
|
|
109
|
-
if (session.
|
|
110
|
-
|
|
111
|
-
session.exitCode = exitCode;
|
|
112
|
-
session.signal = signal;
|
|
146
|
+
if (session.finishedAt !== undefined)
|
|
147
|
+
return;
|
|
113
148
|
if (error)
|
|
114
149
|
onOutput("stderr", `${error.message}\n`);
|
|
115
|
-
|
|
150
|
+
redactOutput = undefined;
|
|
151
|
+
session.options.redactOutput = undefined;
|
|
152
|
+
this.finalizeSession(session, exitCode, signal, error);
|
|
116
153
|
session.backend.dispose();
|
|
117
154
|
};
|
|
118
155
|
const backend = options.tty
|
|
@@ -123,11 +160,14 @@ export class ExecProcessManager {
|
|
|
123
160
|
options,
|
|
124
161
|
backend,
|
|
125
162
|
startedAt: Date.now(),
|
|
163
|
+
backgrounded: false,
|
|
126
164
|
status: "running",
|
|
127
165
|
exitCode: null,
|
|
128
166
|
signal: null,
|
|
167
|
+
terminationReason: null,
|
|
129
168
|
stdout: new TextWindow(options.maxOutputChars),
|
|
130
169
|
stderr: new TextWindow(options.maxOutputChars),
|
|
170
|
+
liveOutput: new TextWindow(Math.min(options.maxOutputChars, LIVE_OUTPUT_MAX_CHARS)),
|
|
131
171
|
waiters: new Set(),
|
|
132
172
|
subscribers: new Set(),
|
|
133
173
|
interactionTail: Promise.resolve(),
|
|
@@ -138,16 +178,55 @@ export class ExecProcessManager {
|
|
|
138
178
|
if (session.status !== "running")
|
|
139
179
|
return;
|
|
140
180
|
if (signal === "interrupt") {
|
|
181
|
+
session.requestedTerminationReason = "user_interrupt";
|
|
141
182
|
session.backend.interrupt();
|
|
142
183
|
return;
|
|
143
184
|
}
|
|
144
|
-
session.
|
|
185
|
+
session.requestedTerminationReason = signal === "kill" ? "user_kill" : "user_terminate";
|
|
145
186
|
session.backend.terminate(signal === "kill");
|
|
187
|
+
}
|
|
188
|
+
finalizeSession(session, exitCode, signal, error) {
|
|
189
|
+
if (session.finishedAt !== undefined)
|
|
190
|
+
return;
|
|
191
|
+
session.finishedAt = Date.now();
|
|
192
|
+
const requested = session.requestedTerminationReason;
|
|
193
|
+
if (requested === "timeout") {
|
|
194
|
+
session.status = "timed_out";
|
|
195
|
+
session.exitCode = null;
|
|
196
|
+
session.signal = null;
|
|
197
|
+
session.terminationReason = "timeout";
|
|
198
|
+
}
|
|
199
|
+
else if (requested) {
|
|
200
|
+
session.status = "killed";
|
|
201
|
+
session.exitCode = null;
|
|
202
|
+
session.signal = signal;
|
|
203
|
+
session.terminationReason = requested;
|
|
204
|
+
}
|
|
205
|
+
else if (error) {
|
|
206
|
+
session.status = "failed";
|
|
207
|
+
session.exitCode = null;
|
|
208
|
+
session.signal = signal;
|
|
209
|
+
session.terminationReason = "spawn_error";
|
|
210
|
+
}
|
|
211
|
+
else if (signal !== null) {
|
|
212
|
+
session.status = "killed";
|
|
213
|
+
session.exitCode = exitCode;
|
|
214
|
+
session.signal = signal;
|
|
215
|
+
session.terminationReason = "external_signal";
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
session.status = "exited";
|
|
219
|
+
session.exitCode = exitCode;
|
|
220
|
+
session.signal = null;
|
|
221
|
+
session.terminationReason = exitCode === 0 ? "completed" : "failed";
|
|
222
|
+
}
|
|
146
223
|
this.notifyExit(session);
|
|
147
224
|
}
|
|
148
225
|
notifyExit(session) {
|
|
149
226
|
if (session.timeout)
|
|
150
227
|
clearTimeout(session.timeout);
|
|
228
|
+
if (session.escalation)
|
|
229
|
+
clearTimeout(session.escalation);
|
|
151
230
|
for (const waiter of [...session.waiters])
|
|
152
231
|
waiter();
|
|
153
232
|
session.waiters.clear();
|
|
@@ -193,7 +272,8 @@ export class ExecProcessManager {
|
|
|
193
272
|
tty: session.options.tty,
|
|
194
273
|
exit_code: session.exitCode,
|
|
195
274
|
signal: session.signal,
|
|
196
|
-
|
|
275
|
+
termination_reason: session.terminationReason,
|
|
276
|
+
duration_ms: (session.finishedAt ?? Date.now()) - session.startedAt,
|
|
197
277
|
timed_out: session.status === "timed_out",
|
|
198
278
|
stdout: stdout.text,
|
|
199
279
|
stderr: stderr.text,
|
|
@@ -243,10 +323,16 @@ class TextWindow {
|
|
|
243
323
|
this.head = combined.slice(0, headSize);
|
|
244
324
|
this.tail = combined.slice(-tailSize);
|
|
245
325
|
}
|
|
246
|
-
|
|
326
|
+
observedChars() {
|
|
327
|
+
return this.observed;
|
|
328
|
+
}
|
|
329
|
+
snapshot() {
|
|
247
330
|
const omitted = Math.max(0, this.observed - this.head.length - this.tail.length);
|
|
248
331
|
const marker = omitted > 0 ? `\n[... ${omitted} characters omitted ...]\n` : "";
|
|
249
|
-
|
|
332
|
+
return { text: this.head + marker + this.tail, observed: this.observed, omitted };
|
|
333
|
+
}
|
|
334
|
+
drain() {
|
|
335
|
+
const result = this.snapshot();
|
|
250
336
|
this.head = "";
|
|
251
337
|
this.tail = "";
|
|
252
338
|
this.observed = 0;
|
|
@@ -259,7 +345,8 @@ function createPtyBackend(options, onOutput, onExit) {
|
|
|
259
345
|
stdio: ["ignore", "ignore", "pipe", "ipc"],
|
|
260
346
|
windowsHide: true,
|
|
261
347
|
});
|
|
262
|
-
let terminalPid = host.pid
|
|
348
|
+
let terminalPid = host.pid && host.pid > 0 ? host.pid : null;
|
|
349
|
+
let ready = false;
|
|
263
350
|
let disposed = false;
|
|
264
351
|
let completed = false;
|
|
265
352
|
let diagnostic = "";
|
|
@@ -273,7 +360,9 @@ function createPtyBackend(options, onOutput, onExit) {
|
|
|
273
360
|
return;
|
|
274
361
|
const record = message;
|
|
275
362
|
if (record.type === "ready" && typeof record.pid === "number") {
|
|
276
|
-
|
|
363
|
+
ready = true;
|
|
364
|
+
if (record.pid > 0)
|
|
365
|
+
terminalPid = record.pid;
|
|
277
366
|
for (const chars of pendingWrites.splice(0))
|
|
278
367
|
host.send?.({ type: "write", chars });
|
|
279
368
|
}
|
|
@@ -302,7 +391,7 @@ function createPtyBackend(options, onOutput, onExit) {
|
|
|
302
391
|
host.send({
|
|
303
392
|
type: "start",
|
|
304
393
|
file: options.shell.file,
|
|
305
|
-
args: [...options.shell.args, options
|
|
394
|
+
args: [...options.shell.args, shellCommand(options)],
|
|
306
395
|
cwd: options.cwd,
|
|
307
396
|
env: { ...process.env, ...options.env },
|
|
308
397
|
cols: 120,
|
|
@@ -319,7 +408,7 @@ function createPtyBackend(options, onOutput, onExit) {
|
|
|
319
408
|
get pid() { return terminalPid; },
|
|
320
409
|
write: (data) => {
|
|
321
410
|
const chars = normalizePtyInput(data);
|
|
322
|
-
if (
|
|
411
|
+
if (!ready)
|
|
323
412
|
pendingWrites.push(chars);
|
|
324
413
|
else
|
|
325
414
|
host.send?.({ type: "write", chars });
|
|
@@ -330,7 +419,7 @@ function createPtyBackend(options, onOutput, onExit) {
|
|
|
330
419
|
};
|
|
331
420
|
}
|
|
332
421
|
function createPipeBackend(options, onOutput, onExit) {
|
|
333
|
-
const child = spawnChild(options.shell.file, [...options.shell.args, options
|
|
422
|
+
const child = spawnChild(options.shell.file, [...options.shell.args, shellCommand(options)], {
|
|
334
423
|
cwd: options.cwd,
|
|
335
424
|
env: { ...process.env, ...options.env },
|
|
336
425
|
windowsHide: true,
|
|
@@ -344,7 +433,7 @@ function createPipeBackend(options, onOutput, onExit) {
|
|
|
344
433
|
child.once("error", (error) => onExit(null, null, error));
|
|
345
434
|
child.once("close", (exitCode, signal) => onExit(exitCode, signal));
|
|
346
435
|
return {
|
|
347
|
-
pid: child.pid
|
|
436
|
+
pid: child.pid && child.pid > 0 ? child.pid : null,
|
|
348
437
|
write: (data) => child.stdin.write(data),
|
|
349
438
|
interrupt: () => interruptPipe(child),
|
|
350
439
|
terminate: (force) => terminatePipe(child, force),
|
|
@@ -356,6 +445,9 @@ function createPipeBackend(options, onOutput, onExit) {
|
|
|
356
445
|
},
|
|
357
446
|
};
|
|
358
447
|
}
|
|
448
|
+
function shellCommand(options) {
|
|
449
|
+
return options.shell.commandPrefix ? `${options.shell.commandPrefix}${options.command}` : options.command;
|
|
450
|
+
}
|
|
359
451
|
function normalizeOutput(text) {
|
|
360
452
|
return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
361
453
|
}
|
|
@@ -379,7 +471,9 @@ function terminatePipe(child, force) {
|
|
|
379
471
|
if (!child.pid)
|
|
380
472
|
return;
|
|
381
473
|
if (os.platform() === "win32") {
|
|
382
|
-
|
|
474
|
+
// Windows console processes do not reliably react to taskkill without /F.
|
|
475
|
+
// The cross-platform intent remains available through termination_reason.
|
|
476
|
+
const args = ["/pid", String(child.pid), "/t", "/f"];
|
|
383
477
|
const killer = spawnChild("taskkill.exe", args, { windowsHide: true, stdio: "ignore" });
|
|
384
478
|
killer.unref();
|
|
385
479
|
return;
|