aws-runtime-bridge 1.9.0 → 1.9.1
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/adapter/AcodeSdkAdapter.d.ts +2 -0
- package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/AcodeSdkAdapter.js +84 -18
- package/dist/adapter/AcodeSdkAdapter.test.js +275 -13
- package/dist/adapter/acode-tool-names.d.ts +16 -0
- package/dist/adapter/acode-tool-names.d.ts.map +1 -0
- package/dist/adapter/acode-tool-names.js +37 -0
- package/dist/adapter/acode-tool-names.test.d.ts +2 -0
- package/dist/adapter/acode-tool-names.test.d.ts.map +1 -0
- package/dist/adapter/acode-tool-names.test.js +28 -0
- package/dist/adapter/types.d.ts +22 -3
- package/dist/adapter/types.d.ts.map +1 -1
- package/dist/adapter/types.js +2 -1
- package/dist/routes/git.d.ts +10 -0
- package/dist/routes/git.d.ts.map +1 -1
- package/dist/routes/git.js +37 -3
- package/dist/routes/git.test.js +47 -1
- package/dist/routes/sessions.d.ts +1 -1
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +11 -4
- package/dist/routes/sessions.test.js +3 -0
- package/dist/routes/terminal.d.ts +28 -8
- package/dist/routes/terminal.d.ts.map +1 -1
- package/dist/routes/terminal.js +260 -44
- package/dist/routes/terminal.stop-options.test.d.ts +2 -0
- package/dist/routes/terminal.stop-options.test.d.ts.map +1 -0
- package/dist/routes/terminal.stop-options.test.js +39 -0
- package/dist/routes/terminal.test.js +87 -4
- package/dist/services/session-output.d.ts +5 -0
- package/dist/services/session-output.d.ts.map +1 -1
- package/package/acode/dist/built-in-file-tools.d.ts +5 -1
- package/package/acode/dist/built-in-file-tools.d.ts.map +1 -1
- package/package/acode/dist/built-in-file-tools.js +14 -203
- package/package/acode/dist/builtins/commandArtifacts.d.ts +25 -0
- package/package/acode/dist/builtins/commandArtifacts.d.ts.map +1 -0
- package/package/acode/dist/builtins/commandArtifacts.js +77 -0
- package/package/acode/dist/builtins/commandOutputEvents.d.ts +21 -0
- package/package/acode/dist/builtins/commandOutputEvents.d.ts.map +1 -0
- package/package/acode/dist/builtins/commandOutputEvents.js +56 -0
- package/package/acode/dist/builtins/shellCommandPreparation.d.ts +15 -0
- package/package/acode/dist/builtins/shellCommandPreparation.d.ts.map +1 -0
- package/package/acode/dist/builtins/shellCommandPreparation.js +44 -0
- package/package/acode/dist/builtins/shellCommandResult.d.ts +30 -0
- package/package/acode/dist/builtins/shellCommandResult.d.ts.map +1 -0
- package/package/acode/dist/builtins/shellCommandResult.js +71 -0
- package/package/acode/dist/builtins/shellCommandRunner.d.ts +14 -0
- package/package/acode/dist/builtins/shellCommandRunner.d.ts.map +1 -0
- package/package/acode/dist/builtins/shellCommandRunner.js +114 -0
- package/package/acode/dist/builtins/shellOutputDecoder.d.ts +5 -0
- package/package/acode/dist/builtins/shellOutputDecoder.d.ts.map +1 -0
- package/package/acode/dist/builtins/shellOutputDecoder.js +30 -0
- package/package/acode/dist/mcpToolNames.d.ts +11 -0
- package/package/acode/dist/mcpToolNames.d.ts.map +1 -0
- package/package/acode/dist/mcpToolNames.js +17 -0
- package/package/acode/dist/runtime.d.ts +19 -0
- package/package/acode/dist/runtime.d.ts.map +1 -1
- package/package/acode/dist/runtime.js +233 -35
- package/package/acode/dist/types.d.ts +1 -1
- package/package/acode/dist/types.d.ts.map +1 -1
- package/package/acode/package.json +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +3 -3
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js +10 -7
- package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js +47 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +1 -36
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +3 -169
- package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.js +45 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/memory-tools.d.ts +11 -0
- package/package/aws-client-agent-mcp/dist/memory-tools.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/memory-tools.js +144 -0
- package/package/aws-client-agent-mcp/dist/memory-tools.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.js +1 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js +43 -3
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-output.d.ts","sourceRoot":"","sources":["../../src/services/session-output.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,UAAU,uBAAuB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"session-output.d.ts","sourceRoot":"","sources":["../../src/services/session-output.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,UAAU,uBAAuB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA8BD,aAAa;AACb,eAAO,MAAM,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAa,CAAC;AAExD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,uBAAuB,EACpC,KAAK,CAAC,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EACrD,WAAW,CAAC,EAAE,0BAA0B,GACvC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CA4C7C;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,qBAAqB,EAChC,WAAW,CAAC,EAAE,0BAA0B,GACvC,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,OAAO,EAAE,EACpB,WAAW,CAAC,EAAE,0BAA0B,GACvC,OAAO,CAAC,IAAI,CAAC,CAef;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAgBzE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAa3D;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCzE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CommandOutputSink } from "./builtins/shellCommandRunner.js";
|
|
1
2
|
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
2
3
|
[key: string]: JsonValue;
|
|
3
4
|
};
|
|
@@ -10,7 +11,10 @@ export interface ACodeBuiltInTool {
|
|
|
10
11
|
exposedName: string;
|
|
11
12
|
description: string;
|
|
12
13
|
inputSchema: JsonObject;
|
|
13
|
-
execute(args: JsonObject): Promise<unknown>;
|
|
14
|
+
execute(args: JsonObject, context?: ACodeBuiltInToolExecutionContext): Promise<unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface ACodeBuiltInToolExecutionContext {
|
|
17
|
+
readonly onOutput?: CommandOutputSink;
|
|
14
18
|
}
|
|
15
19
|
export declare function createBuiltInFileTools(workingDirectory: string): ACodeBuiltInTool[];
|
|
16
20
|
//# sourceMappingURL=built-in-file-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"built-in-file-tools.d.ts","sourceRoot":"","sources":["../src/built-in-file-tools.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"built-in-file-tools.d.ts","sourceRoot":"","sources":["../src/built-in-file-tools.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,kCAAkC,CAAC;AAE1C,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AACjC,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,OAAO,CACL,IAAI,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE,gCAAgC,GACzC,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAsfD,wBAAgB,sBAAsB,CACpC,gBAAgB,EAAE,MAAM,GACvB,gBAAgB,EAAE,CAOpB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
1
|
import { randomUUID } from "node:crypto";
|
|
3
2
|
import { promises as fs } from "node:fs";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import { runShellCommand, } from "./builtins/shellCommandRunner.js";
|
|
5
5
|
function toDisplayPath(targetPath) {
|
|
6
6
|
return targetPath.replace(/\\/g, "/");
|
|
7
7
|
}
|
|
@@ -178,208 +178,10 @@ async function readFileInsideWorkspace(workingDirectory, filePath) {
|
|
|
178
178
|
content: await fs.readFile(realTargetPath, "utf-8"),
|
|
179
179
|
};
|
|
180
180
|
}
|
|
181
|
-
const DEFAULT_COMMAND_TIMEOUT_MS = 30_000;
|
|
182
181
|
const MAX_COMMAND_TIMEOUT_MS = 10 * 60_000;
|
|
182
|
+
const DEFAULT_COMMAND_TIMEOUT_MS = MAX_COMMAND_TIMEOUT_MS;
|
|
183
183
|
const DEFAULT_COMMAND_INACTIVITY_TIMEOUT_MS = 60_000;
|
|
184
184
|
const MAX_COMMAND_INACTIVITY_TIMEOUT_MS = 10 * 60_000;
|
|
185
|
-
const MAX_COMMAND_OUTPUT_BYTES = 128 * 1024;
|
|
186
|
-
const COMMAND_OUTPUT_SPILLOVER_LINE_LIMIT = 100;
|
|
187
|
-
function padDatePart(value) {
|
|
188
|
-
return String(value).padStart(2, "0");
|
|
189
|
-
}
|
|
190
|
-
function countOutputLines(output) {
|
|
191
|
-
if (!output) {
|
|
192
|
-
return 0;
|
|
193
|
-
}
|
|
194
|
-
const normalized = output.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
195
|
-
const withoutTrailingLineBreak = normalized.endsWith("\n")
|
|
196
|
-
? normalized.slice(0, -1)
|
|
197
|
-
: normalized;
|
|
198
|
-
return withoutTrailingLineBreak
|
|
199
|
-
? withoutTrailingLineBreak.split("\n").length
|
|
200
|
-
: 1;
|
|
201
|
-
}
|
|
202
|
-
function buildCommandOutputSpilloverPath(workspaceRoot, now = new Date()) {
|
|
203
|
-
const year = now.getFullYear();
|
|
204
|
-
const month = padDatePart(now.getMonth() + 1);
|
|
205
|
-
const day = padDatePart(now.getDate());
|
|
206
|
-
const hour = padDatePart(now.getHours());
|
|
207
|
-
const minute = padDatePart(now.getMinutes());
|
|
208
|
-
const timestamp = `${year}${month}${day}-${hour}${minute}${padDatePart(now.getSeconds())}-${String(now.getMilliseconds()).padStart(3, "0")}-${process.pid}-${randomUUID().slice(0, 8)}`;
|
|
209
|
-
return path.join(workspaceRoot, ".agentswork", "acode", "cmd-dist", `${year}-${month}-${day}`, hour, minute, `${timestamp}-cmd.out`);
|
|
210
|
-
}
|
|
211
|
-
async function writeCommandOutputSpilloverFile(workspaceRoot, content) {
|
|
212
|
-
const targetPath = buildCommandOutputSpilloverPath(workspaceRoot);
|
|
213
|
-
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
214
|
-
await fs.writeFile(targetPath, content, "utf-8");
|
|
215
|
-
return targetPath;
|
|
216
|
-
}
|
|
217
|
-
function buildCommandOutputSpilloverContent(input) {
|
|
218
|
-
return [
|
|
219
|
-
`Command: ${input.commandText}`,
|
|
220
|
-
`CWD: ${input.cwd}`,
|
|
221
|
-
`Started: ${input.startedAt.toISOString()}`,
|
|
222
|
-
`Ended: ${input.endedAt.toISOString()}`,
|
|
223
|
-
`Exit code: ${input.exitCode ?? "null"}`,
|
|
224
|
-
`Signal: ${input.signal ?? "null"}`,
|
|
225
|
-
`Timed out: ${input.timedOut}`,
|
|
226
|
-
`Timed out by inactivity: ${input.inactivityTimedOut}`,
|
|
227
|
-
"",
|
|
228
|
-
"--- stdout ---",
|
|
229
|
-
input.stdout,
|
|
230
|
-
"",
|
|
231
|
-
"--- stderr ---",
|
|
232
|
-
input.stderr,
|
|
233
|
-
].join("\n");
|
|
234
|
-
}
|
|
235
|
-
function formatCommandOutputSpilloverStdout(outputFilePath, outputLineCount) {
|
|
236
|
-
return [
|
|
237
|
-
`[ACode] 命令输出超过 ${COMMAND_OUTPUT_SPILLOVER_LINE_LIMIT} 行(共 ${outputLineCount} 行),完整输出已写入: ${toDisplayPath(outputFilePath)}`,
|
|
238
|
-
"[ACode] Agent 可自行读取该文件,或在该文件中搜索需要的内容。",
|
|
239
|
-
"",
|
|
240
|
-
].join("\n");
|
|
241
|
-
}
|
|
242
|
-
function truncateOutput(value) {
|
|
243
|
-
const bytes = Buffer.byteLength(value, "utf-8");
|
|
244
|
-
if (bytes <= MAX_COMMAND_OUTPUT_BYTES) {
|
|
245
|
-
return { text: value, truncated: false };
|
|
246
|
-
}
|
|
247
|
-
const buffer = Buffer.from(value, "utf-8");
|
|
248
|
-
return {
|
|
249
|
-
text: buffer.subarray(0, MAX_COMMAND_OUTPUT_BYTES).toString("utf-8") +
|
|
250
|
-
`\n...[truncated after ${MAX_COMMAND_OUTPUT_BYTES} bytes]`,
|
|
251
|
-
truncated: true,
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
function shellExecutable() {
|
|
255
|
-
if (process.platform === "win32") {
|
|
256
|
-
return {
|
|
257
|
-
command: process.env.ComSpec || "cmd.exe",
|
|
258
|
-
argsPrefix: ["/d", "/s", "/c"],
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
return { command: process.env.SHELL || "/bin/sh", argsPrefix: ["-lc"] };
|
|
262
|
-
}
|
|
263
|
-
function runShellCommand(commandText, workspaceRoot, cwd, timeoutMs, inactivityTimeoutMs) {
|
|
264
|
-
return new Promise((resolve, reject) => {
|
|
265
|
-
const shell = shellExecutable();
|
|
266
|
-
const startedAt = new Date();
|
|
267
|
-
const child = spawn(shell.command, [...shell.argsPrefix, commandText], {
|
|
268
|
-
cwd,
|
|
269
|
-
env: process.env,
|
|
270
|
-
windowsHide: true,
|
|
271
|
-
});
|
|
272
|
-
let stdout = "";
|
|
273
|
-
let stderr = "";
|
|
274
|
-
let timedOut = false;
|
|
275
|
-
let inactivityTimedOut = false;
|
|
276
|
-
let killEscalationTimer;
|
|
277
|
-
let inactivityTimer;
|
|
278
|
-
const escalateKill = () => {
|
|
279
|
-
killEscalationTimer = setTimeout(() => {
|
|
280
|
-
if (!child.killed) {
|
|
281
|
-
child.kill("SIGKILL");
|
|
282
|
-
}
|
|
283
|
-
}, 1000);
|
|
284
|
-
killEscalationTimer.unref?.();
|
|
285
|
-
};
|
|
286
|
-
const timer = setTimeout(() => {
|
|
287
|
-
timedOut = true;
|
|
288
|
-
child.kill("SIGTERM");
|
|
289
|
-
escalateKill();
|
|
290
|
-
}, timeoutMs);
|
|
291
|
-
timer.unref?.();
|
|
292
|
-
const resetInactivityTimer = () => {
|
|
293
|
-
if (inactivityTimer) {
|
|
294
|
-
clearTimeout(inactivityTimer);
|
|
295
|
-
}
|
|
296
|
-
inactivityTimer = setTimeout(() => {
|
|
297
|
-
inactivityTimedOut = true;
|
|
298
|
-
timedOut = true;
|
|
299
|
-
child.kill("SIGTERM");
|
|
300
|
-
escalateKill();
|
|
301
|
-
}, inactivityTimeoutMs);
|
|
302
|
-
inactivityTimer.unref?.();
|
|
303
|
-
};
|
|
304
|
-
resetInactivityTimer();
|
|
305
|
-
child.stdout?.setEncoding("utf-8");
|
|
306
|
-
child.stderr?.setEncoding("utf-8");
|
|
307
|
-
child.stdout?.on("data", (chunk) => {
|
|
308
|
-
stdout += chunk;
|
|
309
|
-
resetInactivityTimer();
|
|
310
|
-
});
|
|
311
|
-
child.stderr?.on("data", (chunk) => {
|
|
312
|
-
stderr += chunk;
|
|
313
|
-
resetInactivityTimer();
|
|
314
|
-
});
|
|
315
|
-
child.on("error", (error) => {
|
|
316
|
-
clearTimeout(timer);
|
|
317
|
-
if (inactivityTimer) {
|
|
318
|
-
clearTimeout(inactivityTimer);
|
|
319
|
-
}
|
|
320
|
-
if (killEscalationTimer) {
|
|
321
|
-
clearTimeout(killEscalationTimer);
|
|
322
|
-
}
|
|
323
|
-
reject(error);
|
|
324
|
-
});
|
|
325
|
-
child.on("close", async (exitCode, signal) => {
|
|
326
|
-
clearTimeout(timer);
|
|
327
|
-
if (inactivityTimer) {
|
|
328
|
-
clearTimeout(inactivityTimer);
|
|
329
|
-
}
|
|
330
|
-
if (killEscalationTimer) {
|
|
331
|
-
clearTimeout(killEscalationTimer);
|
|
332
|
-
}
|
|
333
|
-
const endedAt = new Date();
|
|
334
|
-
const outputLineCount = countOutputLines(`${stdout}${stderr}`);
|
|
335
|
-
try {
|
|
336
|
-
if (outputLineCount > COMMAND_OUTPUT_SPILLOVER_LINE_LIMIT) {
|
|
337
|
-
const outputFilePath = await writeCommandOutputSpilloverFile(workspaceRoot, buildCommandOutputSpilloverContent({
|
|
338
|
-
commandText,
|
|
339
|
-
cwd,
|
|
340
|
-
startedAt,
|
|
341
|
-
endedAt,
|
|
342
|
-
exitCode,
|
|
343
|
-
signal,
|
|
344
|
-
timedOut,
|
|
345
|
-
inactivityTimedOut,
|
|
346
|
-
stdout,
|
|
347
|
-
stderr,
|
|
348
|
-
}));
|
|
349
|
-
resolve({
|
|
350
|
-
exitCode,
|
|
351
|
-
signal,
|
|
352
|
-
stdout: formatCommandOutputSpilloverStdout(outputFilePath, outputLineCount),
|
|
353
|
-
stderr: "",
|
|
354
|
-
durationMs: endedAt.getTime() - startedAt.getTime(),
|
|
355
|
-
timedOut,
|
|
356
|
-
inactivityTimedOut,
|
|
357
|
-
outputSpilled: true,
|
|
358
|
-
outputFilePath: toDisplayPath(outputFilePath),
|
|
359
|
-
outputLineCount,
|
|
360
|
-
});
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
const truncatedStdout = truncateOutput(stdout);
|
|
364
|
-
const truncatedStderr = truncateOutput(stderr);
|
|
365
|
-
resolve({
|
|
366
|
-
exitCode,
|
|
367
|
-
signal,
|
|
368
|
-
stdout: truncatedStdout.text,
|
|
369
|
-
stderr: truncatedStderr.text,
|
|
370
|
-
durationMs: endedAt.getTime() - startedAt.getTime(),
|
|
371
|
-
timedOut,
|
|
372
|
-
inactivityTimedOut,
|
|
373
|
-
outputSpilled: false,
|
|
374
|
-
outputLineCount,
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
catch (error) {
|
|
378
|
-
reject(error);
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
185
|
function writeFileTool(workingDirectory) {
|
|
384
186
|
return {
|
|
385
187
|
kind: "builtin",
|
|
@@ -512,7 +314,7 @@ function bashTool(workingDirectory) {
|
|
|
512
314
|
},
|
|
513
315
|
timeout_ms: {
|
|
514
316
|
type: "number",
|
|
515
|
-
description: "Optional timeout in milliseconds. Defaults to
|
|
317
|
+
description: "Optional timeout in milliseconds. Defaults to 600000 and is capped at 600000.",
|
|
516
318
|
},
|
|
517
319
|
inactivity_timeout_ms: {
|
|
518
320
|
type: "number",
|
|
@@ -526,7 +328,7 @@ function bashTool(workingDirectory) {
|
|
|
526
328
|
required: ["command"],
|
|
527
329
|
additionalProperties: false,
|
|
528
330
|
},
|
|
529
|
-
async execute(args) {
|
|
331
|
+
async execute(args, context) {
|
|
530
332
|
const command = readStringArg(args, ["command"], "command").trim();
|
|
531
333
|
if (!command) {
|
|
532
334
|
throw new Error("command must not be empty");
|
|
@@ -537,7 +339,14 @@ function bashTool(workingDirectory) {
|
|
|
537
339
|
const inactivityTimeoutMs = Math.min(requestedInactivityTimeoutMs, MAX_COMMAND_INACTIVITY_TIMEOUT_MS);
|
|
538
340
|
const cwdArg = readOptionalStringArg(args, ["cwd"]);
|
|
539
341
|
const resolved = await resolveWorkspaceDirectory(workingDirectory, cwdArg);
|
|
540
|
-
const result = await runShellCommand(
|
|
342
|
+
const result = await runShellCommand({
|
|
343
|
+
commandText: command,
|
|
344
|
+
workspaceRoot: resolved.workspaceRoot,
|
|
345
|
+
cwd: resolved.cwd,
|
|
346
|
+
timeoutMs,
|
|
347
|
+
inactivityTimeoutMs,
|
|
348
|
+
onOutput: context?.onOutput,
|
|
349
|
+
});
|
|
541
350
|
return {
|
|
542
351
|
ok: result.exitCode === 0 && !result.timedOut,
|
|
543
352
|
tool: "Bash",
|
|
@@ -553,6 +362,8 @@ function bashTool(workingDirectory) {
|
|
|
553
362
|
outputSpilled: result.outputSpilled,
|
|
554
363
|
outputFilePath: result.outputFilePath,
|
|
555
364
|
outputLineCount: result.outputLineCount,
|
|
365
|
+
commandFilePath: result.commandFilePath,
|
|
366
|
+
commandLineCount: result.commandLineCount,
|
|
556
367
|
stdout: result.stdout,
|
|
557
368
|
stderr: result.stderr,
|
|
558
369
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const COMMAND_OUTPUT_SPILLOVER_LINE_LIMIT = 300;
|
|
2
|
+
export declare const LONG_COMMAND_LINE_LIMIT = 300;
|
|
3
|
+
export declare const MAX_COMMAND_OUTPUT_BYTES: number;
|
|
4
|
+
export declare function toDisplayPath(targetPath: string): string;
|
|
5
|
+
export declare function countOutputLines(output: string): number;
|
|
6
|
+
export declare function writeCommandArtifactFile(workspaceRoot: string, suffix: string, extension: string, content: string, now?: Date): Promise<string>;
|
|
7
|
+
export declare function buildCommandOutputSpilloverContent(input: {
|
|
8
|
+
readonly commandText: string;
|
|
9
|
+
readonly commandFilePath?: string;
|
|
10
|
+
readonly commandLineCount: number;
|
|
11
|
+
readonly cwd: string;
|
|
12
|
+
readonly startedAt: Date;
|
|
13
|
+
readonly endedAt: Date;
|
|
14
|
+
readonly exitCode: number | null;
|
|
15
|
+
readonly signal: NodeJS.Signals | null;
|
|
16
|
+
readonly timedOut: boolean;
|
|
17
|
+
readonly inactivityTimedOut: boolean;
|
|
18
|
+
readonly stdout: string;
|
|
19
|
+
readonly stderr: string;
|
|
20
|
+
}): string;
|
|
21
|
+
export declare function formatCommandOutputSpilloverStdout(outputFilePath: string, outputLineCount: number): string;
|
|
22
|
+
export declare function truncateOutput(value: string): {
|
|
23
|
+
readonly text: string;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=commandArtifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandArtifacts.d.ts","sourceRoot":"","sources":["../../src/builtins/commandArtifacts.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,mCAAmC,MAAM,CAAC;AACvD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,wBAAwB,QAAa,CAAC;AAEnD,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExD;AAMD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWvD;AA4BD,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,GAAG,OAAa,GACf,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAgB,kCAAkC,CAAC,KAAK,EAAE;IACxD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,GAAG,MAAM,CAmBT;AAED,wBAAgB,kCAAkC,CAChD,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,GACtB,MAAM,CAMR;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAWvE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
export const COMMAND_OUTPUT_SPILLOVER_LINE_LIMIT = 300;
|
|
5
|
+
export const LONG_COMMAND_LINE_LIMIT = 300;
|
|
6
|
+
export const MAX_COMMAND_OUTPUT_BYTES = 128 * 1024;
|
|
7
|
+
export function toDisplayPath(targetPath) {
|
|
8
|
+
return targetPath.replace(/\\/g, "/");
|
|
9
|
+
}
|
|
10
|
+
function padDatePart(value) {
|
|
11
|
+
return String(value).padStart(2, "0");
|
|
12
|
+
}
|
|
13
|
+
export function countOutputLines(output) {
|
|
14
|
+
if (!output) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
const normalized = output.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
18
|
+
const withoutTrailingLineBreak = normalized.endsWith("\n")
|
|
19
|
+
? normalized.slice(0, -1)
|
|
20
|
+
: normalized;
|
|
21
|
+
return withoutTrailingLineBreak
|
|
22
|
+
? withoutTrailingLineBreak.split("\n").length
|
|
23
|
+
: 1;
|
|
24
|
+
}
|
|
25
|
+
function buildCommandArtifactPath(workspaceRoot, now, suffix, extension) {
|
|
26
|
+
const year = now.getFullYear();
|
|
27
|
+
const month = padDatePart(now.getMonth() + 1);
|
|
28
|
+
const day = padDatePart(now.getDate());
|
|
29
|
+
const hour = padDatePart(now.getHours());
|
|
30
|
+
const minute = padDatePart(now.getMinutes());
|
|
31
|
+
const timestamp = `${year}${month}${day}-${hour}${minute}${padDatePart(now.getSeconds())}-${String(now.getMilliseconds()).padStart(3, "0")}-${process.pid}-${randomUUID().slice(0, 8)}`;
|
|
32
|
+
return path.join(workspaceRoot, ".agentswork", "acode", "cmd-dist", `${year}-${month}-${day}`, hour, minute, `${timestamp}-${suffix}.${extension}`);
|
|
33
|
+
}
|
|
34
|
+
export async function writeCommandArtifactFile(workspaceRoot, suffix, extension, content, now = new Date()) {
|
|
35
|
+
const targetPath = buildCommandArtifactPath(workspaceRoot, now, suffix, extension);
|
|
36
|
+
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
37
|
+
await fs.writeFile(targetPath, content, "utf-8");
|
|
38
|
+
return targetPath;
|
|
39
|
+
}
|
|
40
|
+
export function buildCommandOutputSpilloverContent(input) {
|
|
41
|
+
return [
|
|
42
|
+
`Command: ${input.commandText}`,
|
|
43
|
+
`Command file: ${input.commandFilePath ?? "null"}`,
|
|
44
|
+
`Command line count: ${input.commandLineCount}`,
|
|
45
|
+
`CWD: ${input.cwd}`,
|
|
46
|
+
`Started: ${input.startedAt.toISOString()}`,
|
|
47
|
+
`Ended: ${input.endedAt.toISOString()}`,
|
|
48
|
+
`Exit code: ${input.exitCode ?? "null"}`,
|
|
49
|
+
`Signal: ${input.signal ?? "null"}`,
|
|
50
|
+
`Timed out: ${input.timedOut}`,
|
|
51
|
+
`Timed out by inactivity: ${input.inactivityTimedOut}`,
|
|
52
|
+
"",
|
|
53
|
+
"--- stdout ---",
|
|
54
|
+
input.stdout,
|
|
55
|
+
"",
|
|
56
|
+
"--- stderr ---",
|
|
57
|
+
input.stderr,
|
|
58
|
+
].join("\n");
|
|
59
|
+
}
|
|
60
|
+
export function formatCommandOutputSpilloverStdout(outputFilePath, outputLineCount) {
|
|
61
|
+
return [
|
|
62
|
+
`[ACode] 命令输出超过 ${COMMAND_OUTPUT_SPILLOVER_LINE_LIMIT} 行(共 ${outputLineCount} 行),完整输出已写入: ${toDisplayPath(outputFilePath)}`,
|
|
63
|
+
"[ACode] Agent 可自行读取该文件,或在该文件中搜索需要的内容。",
|
|
64
|
+
"",
|
|
65
|
+
].join("\n");
|
|
66
|
+
}
|
|
67
|
+
export function truncateOutput(value) {
|
|
68
|
+
const bytes = Buffer.byteLength(value, "utf-8");
|
|
69
|
+
if (bytes <= MAX_COMMAND_OUTPUT_BYTES) {
|
|
70
|
+
return { text: value };
|
|
71
|
+
}
|
|
72
|
+
const buffer = Buffer.from(value, "utf-8");
|
|
73
|
+
return {
|
|
74
|
+
text: buffer.subarray(0, MAX_COMMAND_OUTPUT_BYTES).toString("utf-8") +
|
|
75
|
+
`\n...[truncated after ${MAX_COMMAND_OUTPUT_BYTES} bytes]`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type CommandOutputStream = "stdout" | "stderr" | "mixed";
|
|
2
|
+
export interface CommandOutputEvent {
|
|
3
|
+
readonly stream: CommandOutputStream;
|
|
4
|
+
readonly text: string;
|
|
5
|
+
readonly sequence: number;
|
|
6
|
+
readonly cwd: string;
|
|
7
|
+
readonly commandLineCount: number;
|
|
8
|
+
readonly commandFilePath?: string;
|
|
9
|
+
}
|
|
10
|
+
export type CommandOutputSink = (event: CommandOutputEvent) => void;
|
|
11
|
+
export interface OutputEventCollector {
|
|
12
|
+
readonly push: (stream: Exclude<CommandOutputStream, "mixed">, text: string) => void;
|
|
13
|
+
readonly close: () => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function createOutputEventCollector(input: {
|
|
16
|
+
readonly cwd: string;
|
|
17
|
+
readonly commandLineCount: number;
|
|
18
|
+
readonly commandFilePath?: string;
|
|
19
|
+
readonly onOutput?: CommandOutputSink;
|
|
20
|
+
}): OutputEventCollector;
|
|
21
|
+
//# sourceMappingURL=commandOutputEvents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandOutputEvents.d.ts","sourceRoot":"","sources":["../../src/builtins/commandOutputEvents.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAOpE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,CACb,MAAM,EAAE,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,EAC7C,IAAI,EAAE,MAAM,KACT,IAAI,CAAC;IACV,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;CAC5B;AAKD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CACvC,GAAG,oBAAoB,CAsDvB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const COMMAND_OUTPUT_EVENT_FLUSH_MS = 80;
|
|
2
|
+
const MAX_COMMAND_OUTPUT_EVENT_CHARS = 16 * 1024;
|
|
3
|
+
export function createOutputEventCollector(input) {
|
|
4
|
+
const onOutput = input.onOutput;
|
|
5
|
+
const pendingChunks = [];
|
|
6
|
+
let pendingCharCount = 0;
|
|
7
|
+
let sequence = 0;
|
|
8
|
+
let flushTimer;
|
|
9
|
+
const clearFlushTimer = () => {
|
|
10
|
+
if (!flushTimer)
|
|
11
|
+
return;
|
|
12
|
+
clearTimeout(flushTimer);
|
|
13
|
+
flushTimer = undefined;
|
|
14
|
+
};
|
|
15
|
+
const flush = () => {
|
|
16
|
+
if (!onOutput || pendingChunks.length === 0)
|
|
17
|
+
return;
|
|
18
|
+
clearFlushTimer();
|
|
19
|
+
sequence += 1;
|
|
20
|
+
const streams = new Set(pendingChunks.map((chunk) => chunk.stream));
|
|
21
|
+
const stream = streams.size === 1 ? pendingChunks[0]?.stream ?? "mixed" : "mixed";
|
|
22
|
+
const text = pendingChunks.map((chunk) => chunk.text).join("");
|
|
23
|
+
pendingChunks.length = 0;
|
|
24
|
+
pendingCharCount = 0;
|
|
25
|
+
onOutput({
|
|
26
|
+
stream,
|
|
27
|
+
text,
|
|
28
|
+
sequence,
|
|
29
|
+
cwd: input.cwd,
|
|
30
|
+
commandLineCount: input.commandLineCount,
|
|
31
|
+
...(input.commandFilePath
|
|
32
|
+
? { commandFilePath: input.commandFilePath }
|
|
33
|
+
: {}),
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
push(stream, text) {
|
|
38
|
+
if (!onOutput || !text)
|
|
39
|
+
return;
|
|
40
|
+
pendingChunks.push({ stream, text });
|
|
41
|
+
pendingCharCount += text.length;
|
|
42
|
+
if (pendingCharCount >= MAX_COMMAND_OUTPUT_EVENT_CHARS) {
|
|
43
|
+
flush();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!flushTimer) {
|
|
47
|
+
flushTimer = setTimeout(flush, COMMAND_OUTPUT_EVENT_FLUSH_MS);
|
|
48
|
+
flushTimer.unref?.();
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
close() {
|
|
52
|
+
flush();
|
|
53
|
+
clearFlushTimer();
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ShellExecutable {
|
|
2
|
+
readonly command: string;
|
|
3
|
+
readonly argsPrefix: readonly string[];
|
|
4
|
+
readonly scriptExtension: "cmd" | "sh";
|
|
5
|
+
readonly scriptInvocation: (scriptPath: string) => string;
|
|
6
|
+
}
|
|
7
|
+
export interface PreparedShellCommand {
|
|
8
|
+
readonly commandText: string;
|
|
9
|
+
readonly originalCommandText: string;
|
|
10
|
+
readonly commandLineCount: number;
|
|
11
|
+
readonly commandFilePath?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function shellExecutable(): ShellExecutable;
|
|
14
|
+
export declare function prepareShellCommand(commandText: string, workspaceRoot: string, shell: ShellExecutable): Promise<PreparedShellCommand>;
|
|
15
|
+
//# sourceMappingURL=shellCommandPreparation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellCommandPreparation.d.ts","sourceRoot":"","sources":["../../src/builtins/shellCommandPreparation.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,eAAe,EAAE,KAAK,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3D;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAUD,wBAAgB,eAAe,IAAI,eAAe,CAejD;AAcD,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,oBAAoB,CAAC,CAkB/B"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { countOutputLines, LONG_COMMAND_LINE_LIMIT, toDisplayPath, writeCommandArtifactFile, } from "./commandArtifacts.js";
|
|
2
|
+
function quotePosixShellArg(value) {
|
|
3
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
4
|
+
}
|
|
5
|
+
function quoteWindowsCmdPath(value) {
|
|
6
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
7
|
+
}
|
|
8
|
+
export function shellExecutable() {
|
|
9
|
+
if (process.platform === "win32") {
|
|
10
|
+
return {
|
|
11
|
+
command: process.env.ComSpec || "cmd.exe",
|
|
12
|
+
argsPrefix: ["/d", "/c"],
|
|
13
|
+
scriptExtension: "cmd",
|
|
14
|
+
scriptInvocation: (scriptPath) => `call ${quoteWindowsCmdPath(scriptPath)}`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
command: process.env.SHELL || "/bin/sh",
|
|
19
|
+
argsPrefix: ["-lc"],
|
|
20
|
+
scriptExtension: "sh",
|
|
21
|
+
scriptInvocation: (scriptPath) => `sh ${quotePosixShellArg(scriptPath)}`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function buildCommandFileContent(commandText, scriptExtension) {
|
|
25
|
+
const commandWithTrailingLineBreak = commandText.endsWith("\n")
|
|
26
|
+
? commandText
|
|
27
|
+
: `${commandText}\n`;
|
|
28
|
+
return scriptExtension === "cmd"
|
|
29
|
+
? `@echo off\r\n${commandWithTrailingLineBreak}`
|
|
30
|
+
: commandWithTrailingLineBreak;
|
|
31
|
+
}
|
|
32
|
+
export async function prepareShellCommand(commandText, workspaceRoot, shell) {
|
|
33
|
+
const commandLineCount = countOutputLines(commandText);
|
|
34
|
+
if (commandLineCount <= LONG_COMMAND_LINE_LIMIT) {
|
|
35
|
+
return { commandText, originalCommandText: commandText, commandLineCount };
|
|
36
|
+
}
|
|
37
|
+
const commandFilePath = await writeCommandArtifactFile(workspaceRoot, "cmd", shell.scriptExtension, buildCommandFileContent(commandText, shell.scriptExtension));
|
|
38
|
+
return {
|
|
39
|
+
commandText: shell.scriptInvocation(commandFilePath),
|
|
40
|
+
originalCommandText: commandText,
|
|
41
|
+
commandLineCount,
|
|
42
|
+
commandFilePath: toDisplayPath(commandFilePath),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PreparedShellCommand } from "./shellCommandPreparation.js";
|
|
2
|
+
export interface ShellCommandResult {
|
|
3
|
+
readonly exitCode: number | null;
|
|
4
|
+
readonly signal: NodeJS.Signals | null;
|
|
5
|
+
readonly stdout: string;
|
|
6
|
+
readonly stderr: string;
|
|
7
|
+
readonly durationMs: number;
|
|
8
|
+
readonly timedOut: boolean;
|
|
9
|
+
readonly inactivityTimedOut: boolean;
|
|
10
|
+
readonly outputSpilled: boolean;
|
|
11
|
+
readonly outputFilePath?: string;
|
|
12
|
+
readonly outputLineCount: number;
|
|
13
|
+
readonly commandFilePath?: string;
|
|
14
|
+
readonly commandLineCount: number;
|
|
15
|
+
}
|
|
16
|
+
interface ClosedShellCommandInput {
|
|
17
|
+
readonly exitCode: number | null;
|
|
18
|
+
readonly signal: NodeJS.Signals | null;
|
|
19
|
+
readonly stdout: string;
|
|
20
|
+
readonly stderr: string;
|
|
21
|
+
readonly startedAt: Date;
|
|
22
|
+
readonly timedOut: boolean;
|
|
23
|
+
readonly inactivityTimedOut: boolean;
|
|
24
|
+
readonly prepared: PreparedShellCommand;
|
|
25
|
+
readonly workspaceRoot: string;
|
|
26
|
+
readonly cwd: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function resolveClosedShellCommand(input: ClosedShellCommandInput): Promise<ShellCommandResult>;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=shellCommandResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellCommandResult.d.ts","sourceRoot":"","sources":["../../src/builtins/shellCommandResult.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CAClC;AAED,UAAU,uBAAuB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AA0CD,wBAAsB,yBAAyB,CAC9C,KAAK,EAAE,uBAAuB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAuD7B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { buildCommandOutputSpilloverContent, COMMAND_OUTPUT_SPILLOVER_LINE_LIMIT, countOutputLines, formatCommandOutputSpilloverStdout, toDisplayPath, truncateOutput, writeCommandArtifactFile, } from "./commandArtifacts.js";
|
|
2
|
+
async function writeCommandOutputSpilloverFile(workspaceRoot, content) {
|
|
3
|
+
return writeCommandArtifactFile(workspaceRoot, "cmd", "out", content);
|
|
4
|
+
}
|
|
5
|
+
function buildShellCommandResult(input) {
|
|
6
|
+
return {
|
|
7
|
+
exitCode: input.exitCode,
|
|
8
|
+
signal: input.signal,
|
|
9
|
+
stdout: input.stdout,
|
|
10
|
+
stderr: input.stderr,
|
|
11
|
+
durationMs: input.endedAt.getTime() - input.startedAt.getTime(),
|
|
12
|
+
timedOut: input.timedOut,
|
|
13
|
+
inactivityTimedOut: input.inactivityTimedOut,
|
|
14
|
+
outputSpilled: input.outputSpilled,
|
|
15
|
+
outputLineCount: input.outputLineCount,
|
|
16
|
+
...(input.outputFilePath ? { outputFilePath: input.outputFilePath } : {}),
|
|
17
|
+
...(input.commandFilePath
|
|
18
|
+
? { commandFilePath: input.commandFilePath }
|
|
19
|
+
: {}),
|
|
20
|
+
commandLineCount: input.commandLineCount,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export async function resolveClosedShellCommand(input) {
|
|
24
|
+
const endedAt = new Date();
|
|
25
|
+
const outputLineCount = countOutputLines(`${input.stdout}${input.stderr}`);
|
|
26
|
+
if (outputLineCount > COMMAND_OUTPUT_SPILLOVER_LINE_LIMIT) {
|
|
27
|
+
const outputFilePath = await writeCommandOutputSpilloverFile(input.workspaceRoot, buildCommandOutputSpilloverContent({
|
|
28
|
+
commandText: input.prepared.originalCommandText,
|
|
29
|
+
commandFilePath: input.prepared.commandFilePath,
|
|
30
|
+
commandLineCount: input.prepared.commandLineCount,
|
|
31
|
+
cwd: input.cwd,
|
|
32
|
+
startedAt: input.startedAt,
|
|
33
|
+
endedAt,
|
|
34
|
+
exitCode: input.exitCode,
|
|
35
|
+
signal: input.signal,
|
|
36
|
+
timedOut: input.timedOut,
|
|
37
|
+
inactivityTimedOut: input.inactivityTimedOut,
|
|
38
|
+
stdout: input.stdout,
|
|
39
|
+
stderr: input.stderr,
|
|
40
|
+
}));
|
|
41
|
+
return buildShellCommandResult({
|
|
42
|
+
exitCode: input.exitCode,
|
|
43
|
+
signal: input.signal,
|
|
44
|
+
stdout: formatCommandOutputSpilloverStdout(outputFilePath, outputLineCount),
|
|
45
|
+
stderr: "",
|
|
46
|
+
startedAt: input.startedAt,
|
|
47
|
+
endedAt,
|
|
48
|
+
timedOut: input.timedOut,
|
|
49
|
+
inactivityTimedOut: input.inactivityTimedOut,
|
|
50
|
+
outputSpilled: true,
|
|
51
|
+
outputFilePath: toDisplayPath(outputFilePath),
|
|
52
|
+
outputLineCount,
|
|
53
|
+
commandFilePath: input.prepared.commandFilePath,
|
|
54
|
+
commandLineCount: input.prepared.commandLineCount,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return buildShellCommandResult({
|
|
58
|
+
exitCode: input.exitCode,
|
|
59
|
+
signal: input.signal,
|
|
60
|
+
stdout: truncateOutput(input.stdout).text,
|
|
61
|
+
stderr: truncateOutput(input.stderr).text,
|
|
62
|
+
startedAt: input.startedAt,
|
|
63
|
+
endedAt,
|
|
64
|
+
timedOut: input.timedOut,
|
|
65
|
+
inactivityTimedOut: input.inactivityTimedOut,
|
|
66
|
+
outputSpilled: false,
|
|
67
|
+
outputLineCount,
|
|
68
|
+
commandFilePath: input.prepared.commandFilePath,
|
|
69
|
+
commandLineCount: input.prepared.commandLineCount,
|
|
70
|
+
});
|
|
71
|
+
}
|