@markusylisiurunen/tau 0.1.2

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.
Files changed (106) hide show
  1. package/README.md +228 -0
  2. package/dist/app.js +1140 -0
  3. package/dist/app.js.map +1 -0
  4. package/dist/bash_commands.js +81 -0
  5. package/dist/bash_commands.js.map +1 -0
  6. package/dist/cli.js +147 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/clipboard.js +16 -0
  9. package/dist/clipboard.js.map +1 -0
  10. package/dist/commands.js +76 -0
  11. package/dist/commands.js.map +1 -0
  12. package/dist/config.js +39 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/content_loader.js +241 -0
  15. package/dist/content_loader.js.map +1 -0
  16. package/dist/debug-ui.js +134 -0
  17. package/dist/debug-ui.js.map +1 -0
  18. package/dist/main.js +85 -0
  19. package/dist/main.js.map +1 -0
  20. package/dist/personas.js +227 -0
  21. package/dist/personas.js.map +1 -0
  22. package/dist/prompts.js +261 -0
  23. package/dist/prompts.js.map +1 -0
  24. package/dist/session/message_accumulator.js +56 -0
  25. package/dist/session/message_accumulator.js.map +1 -0
  26. package/dist/session/session_engine.js +290 -0
  27. package/dist/session/session_engine.js.map +1 -0
  28. package/dist/subagents/explore.js +42 -0
  29. package/dist/subagents/explore.js.map +1 -0
  30. package/dist/subagents/registry.js +30 -0
  31. package/dist/subagents/registry.js.map +1 -0
  32. package/dist/subagents/subagent_engine.js +147 -0
  33. package/dist/subagents/subagent_engine.js.map +1 -0
  34. package/dist/subagents/types.js +2 -0
  35. package/dist/subagents/types.js.map +1 -0
  36. package/dist/terminal.js +115 -0
  37. package/dist/terminal.js.map +1 -0
  38. package/dist/tools/bash.js +334 -0
  39. package/dist/tools/bash.js.map +1 -0
  40. package/dist/tools/edit.js +199 -0
  41. package/dist/tools/edit.js.map +1 -0
  42. package/dist/tools/registry.js +15 -0
  43. package/dist/tools/registry.js.map +1 -0
  44. package/dist/tools/task.js +202 -0
  45. package/dist/tools/task.js.map +1 -0
  46. package/dist/tools/write.js +89 -0
  47. package/dist/tools/write.js.map +1 -0
  48. package/dist/types.js +9 -0
  49. package/dist/types.js.map +1 -0
  50. package/dist/ui/assistant_message.js +87 -0
  51. package/dist/ui/assistant_message.js.map +1 -0
  52. package/dist/ui/bash_execution.js +127 -0
  53. package/dist/ui/bash_execution.js.map +1 -0
  54. package/dist/ui/chat_container.js +90 -0
  55. package/dist/ui/chat_container.js.map +1 -0
  56. package/dist/ui/components/dynamic_border.js +11 -0
  57. package/dist/ui/components/dynamic_border.js.map +1 -0
  58. package/dist/ui/components/one_line_segments.js +79 -0
  59. package/dist/ui/components/one_line_segments.js.map +1 -0
  60. package/dist/ui/components/padded_container.js +24 -0
  61. package/dist/ui/components/padded_container.js.map +1 -0
  62. package/dist/ui/custom_editor.js +53 -0
  63. package/dist/ui/custom_editor.js.map +1 -0
  64. package/dist/ui/file_execution.js +189 -0
  65. package/dist/ui/file_execution.js.map +1 -0
  66. package/dist/ui/footer.js +56 -0
  67. package/dist/ui/footer.js.map +1 -0
  68. package/dist/ui/queued_messages.js +31 -0
  69. package/dist/ui/queued_messages.js.map +1 -0
  70. package/dist/ui/session_divider.js +17 -0
  71. package/dist/ui/session_divider.js.map +1 -0
  72. package/dist/ui/session_summary.js +30 -0
  73. package/dist/ui/session_summary.js.map +1 -0
  74. package/dist/ui/slash_autocomplete.js +177 -0
  75. package/dist/ui/slash_autocomplete.js.map +1 -0
  76. package/dist/ui/system_message.js +8 -0
  77. package/dist/ui/system_message.js.map +1 -0
  78. package/dist/ui/task_execution.js +190 -0
  79. package/dist/ui/task_execution.js.map +1 -0
  80. package/dist/ui/theme.js +108 -0
  81. package/dist/ui/theme.js.map +1 -0
  82. package/dist/ui/tool_output.js +24 -0
  83. package/dist/ui/tool_output.js.map +1 -0
  84. package/dist/ui/user_message.js +14 -0
  85. package/dist/ui/user_message.js.map +1 -0
  86. package/dist/utils/color.js +13 -0
  87. package/dist/utils/color.js.map +1 -0
  88. package/dist/utils/context.js +108 -0
  89. package/dist/utils/context.js.map +1 -0
  90. package/dist/utils/fork.js +41 -0
  91. package/dist/utils/fork.js.map +1 -0
  92. package/dist/utils/format.js +35 -0
  93. package/dist/utils/format.js.map +1 -0
  94. package/dist/utils/fuzzy.js +48 -0
  95. package/dist/utils/fuzzy.js.map +1 -0
  96. package/dist/utils/git.js +21 -0
  97. package/dist/utils/git.js.map +1 -0
  98. package/dist/utils/messages.js +41 -0
  99. package/dist/utils/messages.js.map +1 -0
  100. package/dist/utils/never.js +4 -0
  101. package/dist/utils/never.js.map +1 -0
  102. package/dist/utils/project_files.js +96 -0
  103. package/dist/utils/project_files.js.map +1 -0
  104. package/dist/utils/truncate.js +299 -0
  105. package/dist/utils/truncate.js.map +1 -0
  106. package/package.json +37 -0
@@ -0,0 +1,115 @@
1
+ import { closeSync, openSync } from "node:fs";
2
+ import { ReadStream } from "node:tty";
3
+ import { ProcessTerminal } from "@mariozechner/pi-tui";
4
+ export class TauTerminal {
5
+ input;
6
+ output;
7
+ cleanupInput;
8
+ wasRaw = false;
9
+ inputHandler;
10
+ resizeHandler;
11
+ constructor(input, output, cleanupInput) {
12
+ this.input = input;
13
+ this.output = output;
14
+ this.cleanupInput = cleanupInput;
15
+ }
16
+ start(onInput, onResize) {
17
+ this.inputHandler = onInput;
18
+ this.resizeHandler = onResize;
19
+ this.wasRaw = this.input.isRaw || false;
20
+ if (this.input.setRawMode) {
21
+ this.input.setRawMode(true);
22
+ }
23
+ this.input.setEncoding("utf8");
24
+ this.input.resume();
25
+ this.output.write("\x1b[?2004h");
26
+ this.input.on("data", this.inputHandler);
27
+ this.output.on("resize", this.resizeHandler);
28
+ }
29
+ stop() {
30
+ this.output.write("\x1b[?2004l");
31
+ if (this.inputHandler) {
32
+ this.input.removeListener("data", this.inputHandler);
33
+ this.inputHandler = undefined;
34
+ }
35
+ if (this.resizeHandler) {
36
+ this.output.removeListener("resize", this.resizeHandler);
37
+ this.resizeHandler = undefined;
38
+ }
39
+ if (this.input.setRawMode) {
40
+ this.input.setRawMode(this.wasRaw);
41
+ }
42
+ if (this.cleanupInput) {
43
+ this.cleanupInput();
44
+ this.cleanupInput = undefined;
45
+ }
46
+ }
47
+ write(data) {
48
+ this.output.write(data);
49
+ }
50
+ get columns() {
51
+ return this.output.columns || 80;
52
+ }
53
+ get rows() {
54
+ return this.output.rows || 24;
55
+ }
56
+ moveBy(lines) {
57
+ if (lines > 0) {
58
+ this.output.write(`\x1b[${lines}B`);
59
+ }
60
+ else if (lines < 0) {
61
+ this.output.write(`\x1b[${-lines}A`);
62
+ }
63
+ }
64
+ hideCursor() {
65
+ this.output.write("\x1b[?25l");
66
+ }
67
+ showCursor() {
68
+ this.output.write("\x1b[?25h");
69
+ }
70
+ clearLine() {
71
+ this.output.write("\x1b[K");
72
+ }
73
+ clearFromCursor() {
74
+ this.output.write("\x1b[J");
75
+ }
76
+ clearScreen() {
77
+ this.output.write("\x1b[2J\x1b[H");
78
+ }
79
+ }
80
+ /**
81
+ * Create a terminal for Tau. If stdin is piped and we're still running in a TTY,
82
+ * we fall back to reading input from /dev/tty so the chat remains interactive.
83
+ */
84
+ export function createAppTerminal(preferTtyInput) {
85
+ // Normal mode: stdin is a TTY, use upstream ProcessTerminal.
86
+ if (!preferTtyInput && process.stdin.isTTY) {
87
+ return new ProcessTerminal();
88
+ }
89
+ // If stdin is not a TTY but we're still in an interactive terminal,
90
+ // try to read input from /dev/tty so the UI stays interactive.
91
+ if (!process.stdin.isTTY && process.stdout.isTTY) {
92
+ try {
93
+ const fd = openSync("/dev/tty", "r");
94
+ const input = new ReadStream(fd);
95
+ return new TauTerminal(input, process.stdout, () => {
96
+ input.destroy();
97
+ try {
98
+ closeSync(fd);
99
+ }
100
+ catch {
101
+ // ignore
102
+ }
103
+ });
104
+ }
105
+ catch {
106
+ // Fall through to process.stdin.
107
+ }
108
+ }
109
+ // Fallback: use process streams directly.
110
+ // In piped mode without a controlling terminal, this will behave non-interactively.
111
+ return preferTtyInput
112
+ ? new TauTerminal(process.stdin, process.stdout)
113
+ : new ProcessTerminal();
114
+ }
115
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,334 @@
1
+ import { spawn } from "node:child_process";
2
+ import { Type } from "@sinclair/typebox";
3
+ import { createToolError, createToolResult } from "../utils/messages.js";
4
+ import { truncateMiddle, truncateMiddleForModel, truncateToBytesFromStart, } from "../utils/truncate.js";
5
+ export const BASH_MAX_CAPTURE_BYTES = 2 * 1024 * 1024; // 2MB
6
+ export const BASH_DISPLAY_MAX_LINES = 32;
7
+ export const BASH_DISPLAY_MAX_BYTES = 50 * 1024; // 50KB
8
+ export const BASH_MODEL_MAX_LINES = 10_000;
9
+ export const BASH_MODEL_MAX_BYTES = 1024 * 1024; // 1MB
10
+ export const BASH_MODEL_BYTES_PER_TOKEN = 4;
11
+ export const BASH_DEFAULT_TIMEOUT_MS = 60_000;
12
+ export const BASH_KILL_GRACE_MS = 2_000;
13
+ const SENSITIVE_ENV_PATTERNS = [/_KEY$/, /_SECRET$/, /_TOKEN$/, /_PASSWORD$/, /^API_KEY$/];
14
+ const ALLOWED_ENV_VARS = new Set([
15
+ "PATH",
16
+ "HOME",
17
+ "USER",
18
+ "SHELL",
19
+ "TERM",
20
+ "LANG",
21
+ "LC_ALL",
22
+ "LC_CTYPE",
23
+ "TMPDIR",
24
+ "TMP",
25
+ "TEMP",
26
+ "PWD",
27
+ "OLDPWD",
28
+ "EDITOR",
29
+ "VISUAL",
30
+ "PAGER",
31
+ "XDG_CONFIG_HOME",
32
+ "XDG_DATA_HOME",
33
+ "XDG_CACHE_HOME",
34
+ ]);
35
+ function sanitizeEnvironment() {
36
+ const sanitized = {};
37
+ for (const [key, value] of Object.entries(process.env)) {
38
+ if (value === undefined)
39
+ continue;
40
+ // Always include explicitly allowed vars
41
+ if (ALLOWED_ENV_VARS.has(key)) {
42
+ sanitized[key] = value;
43
+ continue;
44
+ }
45
+ // Exclude vars matching sensitive patterns
46
+ if (SENSITIVE_ENV_PATTERNS.some((pattern) => pattern.test(key))) {
47
+ continue;
48
+ }
49
+ // Include other vars (e.g., npm config, go paths, etc.)
50
+ sanitized[key] = value;
51
+ }
52
+ return sanitized;
53
+ }
54
+ const BASH_DESCRIPTION = [
55
+ "Execute a shell command in the current working directory and return stdout/stderr.",
56
+ "CRITICAL: Always evaluate and provide an accurate safetyLevel assessment.",
57
+ ].join(" ");
58
+ const BASH_COMMAND_DESCRIPTION = "The shell command to execute.";
59
+ const BASH_SAFETY_LEVEL_DESCRIPTION = [
60
+ "Safety classification: 'read' (query-only, no side effects) or 'write' (modifies or has the potential to modify system state).",
61
+ "Use 'read' for: queries (ls, rg, cat, fd, find, ps, df, etc), information gathering (curl for APIs, git log, etc), analysis (wc, sort, sha256sum, etc).",
62
+ "Use 'write' for: filesystem changes (cp, mv, rm, mkdir, touch, echo >, etc), file modifications (sed -i, tee, chmod, chown, etc), process management (kill, pkill, etc), package management (apt, npm, etc), network changes (firewall, DNS, interfaces, etc), or any command that creates/deletes/modifies resources.",
63
+ "When in doubt, default to 'write' to be conservative. The system will enforce appropriate access controls based on your declared safetyLevel.",
64
+ "Always respect and strictly adhere to user-defined risk tolerance levels; never exceed the configured risk level under any circumstances.",
65
+ ].join(" ");
66
+ export const BASH_TOOL = {
67
+ name: "bash",
68
+ description: BASH_DESCRIPTION,
69
+ parameters: Type.Object({
70
+ command: Type.String({ description: BASH_COMMAND_DESCRIPTION }),
71
+ safetyLevel: Type.String({ description: BASH_SAFETY_LEVEL_DESCRIPTION }),
72
+ }, { additionalProperties: false }),
73
+ };
74
+ function combineOutputForDisplay(stdout, stderr) {
75
+ const parts = [];
76
+ if (stdout.trim()) {
77
+ parts.push(stdout);
78
+ }
79
+ if (stderr.trim()) {
80
+ parts.push(`[stderr]\n${stderr}`);
81
+ }
82
+ return parts.join("\n");
83
+ }
84
+ export function prepareBashOutput(stdout, stderr, captureTruncated) {
85
+ const combined = combineOutputForDisplay(stdout, stderr);
86
+ const modelTruncation = truncateMiddleForModel(combined, {
87
+ maxLines: BASH_MODEL_MAX_LINES,
88
+ maxBytes: BASH_MODEL_MAX_BYTES,
89
+ bytesPerTokenApprox: BASH_MODEL_BYTES_PER_TOKEN,
90
+ });
91
+ const displayTruncation = truncateMiddle(modelTruncation.content, {
92
+ maxLines: BASH_DISPLAY_MAX_LINES,
93
+ maxBytes: BASH_DISPLAY_MAX_BYTES,
94
+ });
95
+ return {
96
+ display: displayTruncation,
97
+ model: modelTruncation,
98
+ captureTruncated,
99
+ hasStderr: stderr.trim().length > 0,
100
+ };
101
+ }
102
+ export function formatBashToolResultText(args) {
103
+ const { truncationInfo, exitCode } = args;
104
+ const { model, captureTruncated } = truncationInfo;
105
+ const outputForContext = model.content.trimEnd() || "(no output)";
106
+ const truncNote = model.truncated || captureTruncated
107
+ ? `\n\n[output truncated for context: ${model.outputLines} lines / ${model.outputBytes} bytes shown of ${model.totalLines} lines / ${model.totalBytes} bytes]`
108
+ : "";
109
+ const exitNote = exitCode !== null && exitCode !== 0 ? `\n(exit ${exitCode})` : "";
110
+ return `${outputForContext}${truncNote}${exitNote}`;
111
+ }
112
+ export function formatBashUserMessageText(args) {
113
+ const { command, truncationInfo } = args;
114
+ const { model, captureTruncated } = truncationInfo;
115
+ const outputForContext = model.content.trimEnd() || "(no output)";
116
+ const truncNote = model.truncated || captureTruncated
117
+ ? `\n\n[output truncated for context: ${model.outputLines} lines / ${model.outputBytes} bytes shown of ${model.totalLines} lines / ${model.totalBytes} bytes]`
118
+ : "";
119
+ const bashContextText = `$ ${command}\n${outputForContext}${truncNote}`;
120
+ return `Bash command output:\n${bashContextText}`;
121
+ }
122
+ export function executeBashTool(command, options = {}) {
123
+ return new Promise((resolve, reject) => {
124
+ const timeoutMs = options.timeoutMs;
125
+ const signal = options.signal;
126
+ const cwd = options.cwd;
127
+ const child = spawn(command, {
128
+ shell: true,
129
+ stdio: ["ignore", "pipe", "pipe"],
130
+ env: sanitizeEnvironment(),
131
+ detached: true,
132
+ cwd,
133
+ });
134
+ let stdout = "";
135
+ let stderr = "";
136
+ let truncated = false;
137
+ let terminationNote;
138
+ const truncateIfNeeded = () => {
139
+ const totalBytes = Buffer.byteLength(stdout, "utf-8") + Buffer.byteLength(stderr, "utf-8");
140
+ if (totalBytes > BASH_MAX_CAPTURE_BYTES) {
141
+ truncated = true;
142
+ stdout = truncateToBytesFromStart(stdout, BASH_MAX_CAPTURE_BYTES / 2);
143
+ stderr = truncateToBytesFromStart(stderr, BASH_MAX_CAPTURE_BYTES / 2);
144
+ }
145
+ };
146
+ const appendStdout = (chunk) => {
147
+ if (truncated)
148
+ return;
149
+ if (!chunk)
150
+ return;
151
+ stdout += chunk;
152
+ truncateIfNeeded();
153
+ };
154
+ const appendStderr = (chunk) => {
155
+ if (truncated)
156
+ return;
157
+ if (!chunk)
158
+ return;
159
+ stderr += chunk;
160
+ truncateIfNeeded();
161
+ };
162
+ const ensureTerminationNote = () => {
163
+ const note = terminationNote?.trim();
164
+ if (!note)
165
+ return;
166
+ if (stdout.includes(note) || stderr.includes(note))
167
+ return;
168
+ const noteText = `${stderr && !stderr.endsWith("\n") ? "\n" : ""}${note}\n`;
169
+ const noteBytes = Buffer.byteLength(noteText, "utf-8");
170
+ const currentBytes = Buffer.byteLength(stdout, "utf-8") + Buffer.byteLength(stderr, "utf-8");
171
+ if (currentBytes + noteBytes > BASH_MAX_CAPTURE_BYTES) {
172
+ truncated = true;
173
+ const remaining = Math.max(0, BASH_MAX_CAPTURE_BYTES - noteBytes);
174
+ const stdoutBudget = Math.floor(remaining / 2);
175
+ const stderrBudget = remaining - stdoutBudget;
176
+ stdout = truncateToBytesFromStart(stdout, stdoutBudget);
177
+ stderr = truncateToBytesFromStart(stderr, stderrBudget);
178
+ }
179
+ stderr += noteText;
180
+ };
181
+ const killProcess = (sig) => {
182
+ if (child.killed)
183
+ return;
184
+ if (child.pid) {
185
+ try {
186
+ // Kill the whole process group, not just the shell.
187
+ process.kill(-child.pid, sig);
188
+ return;
189
+ }
190
+ catch {
191
+ // Fall back to killing only the child.
192
+ }
193
+ }
194
+ try {
195
+ child.kill(sig);
196
+ }
197
+ catch {
198
+ // ignore
199
+ }
200
+ };
201
+ let terminationRequested = false;
202
+ let killTimer;
203
+ const requestTermination = (note) => {
204
+ if (terminationRequested)
205
+ return;
206
+ terminationRequested = true;
207
+ terminationNote = note;
208
+ killProcess("SIGTERM");
209
+ killTimer = setTimeout(() => killProcess("SIGKILL"), BASH_KILL_GRACE_MS);
210
+ };
211
+ const abortHandler = () => requestTermination("(tau) aborted");
212
+ const timeoutId = typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0
213
+ ? setTimeout(() => requestTermination(`(tau) timed out after ${timeoutMs}ms`), timeoutMs)
214
+ : undefined;
215
+ const cleanup = () => {
216
+ if (timeoutId) {
217
+ clearTimeout(timeoutId);
218
+ }
219
+ if (killTimer) {
220
+ clearTimeout(killTimer);
221
+ }
222
+ if (signal) {
223
+ signal.removeEventListener("abort", abortHandler);
224
+ }
225
+ };
226
+ if (signal) {
227
+ if (signal.aborted) {
228
+ abortHandler();
229
+ }
230
+ else {
231
+ signal.addEventListener("abort", abortHandler, { once: true });
232
+ }
233
+ }
234
+ child.stdout?.on("data", (d) => appendStdout(d.toString()));
235
+ child.stderr?.on("data", (d) => appendStderr(d.toString()));
236
+ child.on("error", (err) => {
237
+ cleanup();
238
+ reject(err);
239
+ });
240
+ child.on("close", (exitCode, closeSignal) => {
241
+ if (!terminationNote && closeSignal) {
242
+ terminationNote = `(tau) terminated by signal ${closeSignal}`;
243
+ }
244
+ cleanup();
245
+ ensureTerminationNote();
246
+ resolve({ stdout, stderr, exitCode, truncated });
247
+ });
248
+ });
249
+ }
250
+ function getMissingArgsMessage(command, safetyLevel) {
251
+ if (!command && !safetyLevel) {
252
+ return "bash tool call missing valid 'command' and 'safetyLevel' fields.";
253
+ }
254
+ if (!command) {
255
+ return "bash tool call missing a valid 'command' string.";
256
+ }
257
+ return "bash tool call missing a valid 'safetyLevel' value ('read' or 'write').";
258
+ }
259
+ function parseBashArgs(raw) {
260
+ const args = raw;
261
+ const command = typeof args?.command === "string" ? args.command.trim() : "";
262
+ const safetyLevel = args?.safetyLevel === "read" || args?.safetyLevel === "write"
263
+ ? args.safetyLevel
264
+ : undefined;
265
+ const commandForDisplay = command || "(missing command)";
266
+ return { command, safetyLevel, commandForDisplay };
267
+ }
268
+ export function createBashToolDefinition() {
269
+ return {
270
+ schema: BASH_TOOL,
271
+ async dispatch(toolCall, riskLevel, signal) {
272
+ const { command, safetyLevel, commandForDisplay } = parseBashArgs(toolCall.arguments);
273
+ const blocked = (reason) => {
274
+ const toolResult = createToolError(toolCall, reason);
275
+ const uiEvent = { type: "bash_blocked", command: commandForDisplay, reason };
276
+ return { kind: "single", toolResult, uiEvent };
277
+ };
278
+ if (riskLevel === "none") {
279
+ return blocked("Blocked due to risk level being set to 'none'. Ask the user to enable it with /risk:read-only or /risk:read-write.");
280
+ }
281
+ if (!command || !safetyLevel) {
282
+ const msg = getMissingArgsMessage(command, safetyLevel);
283
+ const toolResult = createToolError(toolCall, msg);
284
+ const uiEvent = {
285
+ type: "bash_blocked",
286
+ command: commandForDisplay,
287
+ reason: msg,
288
+ };
289
+ return { kind: "single", toolResult, uiEvent };
290
+ }
291
+ if (riskLevel === "read-only" && safetyLevel === "write") {
292
+ return blocked("Blocked due to risk level being set to 'read-only'. The declared safetyLevel 'write' exceeds the current risk level. Ask the user to enable it with /risk:read-write or revise to a read-only command.");
293
+ }
294
+ // All acceptance checks passed; return two-phase result
295
+ return {
296
+ kind: "phased",
297
+ startedUiEvent: {
298
+ type: "bash_started",
299
+ toolCallId: toolCall.id,
300
+ command,
301
+ },
302
+ run: (async () => {
303
+ try {
304
+ const { stdout, stderr, exitCode, truncated: captureTruncated, } = await executeBashTool(command, { signal, timeoutMs: BASH_DEFAULT_TIMEOUT_MS });
305
+ const truncationInfo = prepareBashOutput(stdout, stderr, captureTruncated);
306
+ const toolText = formatBashToolResultText({ truncationInfo, exitCode });
307
+ const isError = exitCode !== null && exitCode !== 0;
308
+ const toolResult = createToolResult(toolCall, toolText, isError);
309
+ const uiEvent = {
310
+ type: "bash_execution",
311
+ toolCallId: toolCall.id,
312
+ command,
313
+ exitCode,
314
+ truncationInfo,
315
+ };
316
+ return { kind: "single", toolResult, uiEvent };
317
+ }
318
+ catch (e) {
319
+ const msg = `bash tool execution failed: ${e instanceof Error ? e.message : String(e)}`;
320
+ const toolResult = createToolError(toolCall, msg);
321
+ const uiEvent = {
322
+ type: "bash_blocked",
323
+ command: commandForDisplay,
324
+ reason: msg,
325
+ toolCallId: toolCall.id,
326
+ };
327
+ return { kind: "single", toolResult, uiEvent };
328
+ }
329
+ })(),
330
+ };
331
+ },
332
+ };
333
+ }
334
+ //# sourceMappingURL=bash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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"}