@chiwanpark/pi-squared-agent 0.1.0

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 (162) hide show
  1. package/README.md +13 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +144 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/index.d.ts +11 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +11 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/runtime/auth-store.d.ts +36 -0
  11. package/dist/runtime/auth-store.d.ts.map +1 -0
  12. package/dist/runtime/auth-store.js +131 -0
  13. package/dist/runtime/auth-store.js.map +1 -0
  14. package/dist/runtime/config-store.d.ts +44 -0
  15. package/dist/runtime/config-store.d.ts.map +1 -0
  16. package/dist/runtime/config-store.js +138 -0
  17. package/dist/runtime/config-store.js.map +1 -0
  18. package/dist/runtime/messages.d.ts +12 -0
  19. package/dist/runtime/messages.d.ts.map +1 -0
  20. package/dist/runtime/messages.js +101 -0
  21. package/dist/runtime/messages.js.map +1 -0
  22. package/dist/runtime/model-resolver.d.ts +52 -0
  23. package/dist/runtime/model-resolver.d.ts.map +1 -0
  24. package/dist/runtime/model-resolver.js +175 -0
  25. package/dist/runtime/model-resolver.js.map +1 -0
  26. package/dist/runtime/pi-agent.d.ts +83 -0
  27. package/dist/runtime/pi-agent.d.ts.map +1 -0
  28. package/dist/runtime/pi-agent.js +405 -0
  29. package/dist/runtime/pi-agent.js.map +1 -0
  30. package/dist/runtime/status-store.d.ts +50 -0
  31. package/dist/runtime/status-store.d.ts.map +1 -0
  32. package/dist/runtime/status-store.js +65 -0
  33. package/dist/runtime/status-store.js.map +1 -0
  34. package/dist/runtime/system-prompt.d.ts +11 -0
  35. package/dist/runtime/system-prompt.d.ts.map +1 -0
  36. package/dist/runtime/system-prompt.js +43 -0
  37. package/dist/runtime/system-prompt.js.map +1 -0
  38. package/dist/runtime/tools/bash.d.ts +23 -0
  39. package/dist/runtime/tools/bash.d.ts.map +1 -0
  40. package/dist/runtime/tools/bash.js +206 -0
  41. package/dist/runtime/tools/bash.js.map +1 -0
  42. package/dist/runtime/tools/child-process.d.ts +13 -0
  43. package/dist/runtime/tools/child-process.d.ts.map +1 -0
  44. package/dist/runtime/tools/child-process.js +75 -0
  45. package/dist/runtime/tools/child-process.js.map +1 -0
  46. package/dist/runtime/tools/output-accumulator.d.ts +52 -0
  47. package/dist/runtime/tools/output-accumulator.d.ts.map +1 -0
  48. package/dist/runtime/tools/output-accumulator.js +160 -0
  49. package/dist/runtime/tools/output-accumulator.js.map +1 -0
  50. package/dist/runtime/tools/shell.d.ts +26 -0
  51. package/dist/runtime/tools/shell.d.ts.map +1 -0
  52. package/dist/runtime/tools/shell.js +116 -0
  53. package/dist/runtime/tools/shell.js.map +1 -0
  54. package/dist/runtime/tools/truncate.d.ts +38 -0
  55. package/dist/runtime/tools/truncate.d.ts.map +1 -0
  56. package/dist/runtime/tools/truncate.js +98 -0
  57. package/dist/runtime/tools/truncate.js.map +1 -0
  58. package/dist/tools/bash/child-process.d.ts +13 -0
  59. package/dist/tools/bash/child-process.d.ts.map +1 -0
  60. package/dist/tools/bash/child-process.js +79 -0
  61. package/dist/tools/bash/child-process.js.map +1 -0
  62. package/dist/tools/bash/output-accumulator.d.ts +54 -0
  63. package/dist/tools/bash/output-accumulator.d.ts.map +1 -0
  64. package/dist/tools/bash/output-accumulator.js +171 -0
  65. package/dist/tools/bash/output-accumulator.js.map +1 -0
  66. package/dist/tools/bash/shell.d.ts +26 -0
  67. package/dist/tools/bash/shell.d.ts.map +1 -0
  68. package/dist/tools/bash/shell.js +129 -0
  69. package/dist/tools/bash/shell.js.map +1 -0
  70. package/dist/tools/bash/tool.d.ts +23 -0
  71. package/dist/tools/bash/tool.d.ts.map +1 -0
  72. package/dist/tools/bash/tool.js +219 -0
  73. package/dist/tools/bash/tool.js.map +1 -0
  74. package/dist/tools/bash/truncate.d.ts +50 -0
  75. package/dist/tools/bash/truncate.d.ts.map +1 -0
  76. package/dist/tools/bash/truncate.js +184 -0
  77. package/dist/tools/bash/truncate.js.map +1 -0
  78. package/dist/tools/external-tool.d.ts +2 -0
  79. package/dist/tools/external-tool.d.ts.map +1 -0
  80. package/dist/tools/external-tool.js +15 -0
  81. package/dist/tools/external-tool.js.map +1 -0
  82. package/dist/tools/file/edit-diff.d.ts +27 -0
  83. package/dist/tools/file/edit-diff.d.ts.map +1 -0
  84. package/dist/tools/file/edit-diff.js +196 -0
  85. package/dist/tools/file/edit-diff.js.map +1 -0
  86. package/dist/tools/file/edit.d.ts +26 -0
  87. package/dist/tools/file/edit.d.ts.map +1 -0
  88. package/dist/tools/file/edit.js +106 -0
  89. package/dist/tools/file/edit.js.map +1 -0
  90. package/dist/tools/file/find.d.ts +27 -0
  91. package/dist/tools/file/find.d.ts.map +1 -0
  92. package/dist/tools/file/find.js +150 -0
  93. package/dist/tools/file/find.js.map +1 -0
  94. package/dist/tools/file/glob.d.ts +6 -0
  95. package/dist/tools/file/glob.d.ts.map +1 -0
  96. package/dist/tools/file/glob.js +50 -0
  97. package/dist/tools/file/glob.js.map +1 -0
  98. package/dist/tools/file/grep.d.ts +29 -0
  99. package/dist/tools/file/grep.d.ts.map +1 -0
  100. package/dist/tools/file/grep.js +220 -0
  101. package/dist/tools/file/grep.js.map +1 -0
  102. package/dist/tools/file/index.d.ts +7 -0
  103. package/dist/tools/file/index.d.ts.map +1 -0
  104. package/dist/tools/file/index.js +7 -0
  105. package/dist/tools/file/index.js.map +1 -0
  106. package/dist/tools/file/ls.d.ts +27 -0
  107. package/dist/tools/file/ls.d.ts.map +1 -0
  108. package/dist/tools/file/ls.js +82 -0
  109. package/dist/tools/file/ls.js.map +1 -0
  110. package/dist/tools/file/read.d.ts +23 -0
  111. package/dist/tools/file/read.d.ts.map +1 -0
  112. package/dist/tools/file/read.js +98 -0
  113. package/dist/tools/file/read.js.map +1 -0
  114. package/dist/tools/file/write.d.ts +17 -0
  115. package/dist/tools/file/write.d.ts.map +1 -0
  116. package/dist/tools/file/write.js +45 -0
  117. package/dist/tools/file/write.js.map +1 -0
  118. package/dist/tools/file-mutation-queue.d.ts +3 -0
  119. package/dist/tools/file-mutation-queue.d.ts.map +1 -0
  120. package/dist/tools/file-mutation-queue.js +47 -0
  121. package/dist/tools/file-mutation-queue.js.map +1 -0
  122. package/dist/tools/path-utils.d.ts +5 -0
  123. package/dist/tools/path-utils.d.ts.map +1 -0
  124. package/dist/tools/path-utils.js +79 -0
  125. package/dist/tools/path-utils.js.map +1 -0
  126. package/dist/tools/web/index.d.ts +2 -0
  127. package/dist/tools/web/index.d.ts.map +1 -0
  128. package/dist/tools/web/index.js +2 -0
  129. package/dist/tools/web/index.js.map +1 -0
  130. package/dist/tools/web/search.d.ts +44 -0
  131. package/dist/tools/web/search.d.ts.map +1 -0
  132. package/dist/tools/web/search.js +209 -0
  133. package/dist/tools/web/search.js.map +1 -0
  134. package/dist/tui/box.d.ts +11 -0
  135. package/dist/tui/box.d.ts.map +1 -0
  136. package/dist/tui/box.js +24 -0
  137. package/dist/tui/box.js.map +1 -0
  138. package/dist/tui/chat-screen.d.ts +29 -0
  139. package/dist/tui/chat-screen.d.ts.map +1 -0
  140. package/dist/tui/chat-screen.js +475 -0
  141. package/dist/tui/chat-screen.js.map +1 -0
  142. package/dist/tui/commands.d.ts +34 -0
  143. package/dist/tui/commands.d.ts.map +1 -0
  144. package/dist/tui/commands.js +691 -0
  145. package/dist/tui/commands.js.map +1 -0
  146. package/dist/tui/interactive.d.ts +9 -0
  147. package/dist/tui/interactive.d.ts.map +1 -0
  148. package/dist/tui/interactive.js +88 -0
  149. package/dist/tui/interactive.js.map +1 -0
  150. package/dist/tui/overlays.d.ts +39 -0
  151. package/dist/tui/overlays.d.ts.map +1 -0
  152. package/dist/tui/overlays.js +157 -0
  153. package/dist/tui/overlays.js.map +1 -0
  154. package/dist/tui/theme.d.ts +40 -0
  155. package/dist/tui/theme.d.ts.map +1 -0
  156. package/dist/tui/theme.js +120 -0
  157. package/dist/tui/theme.js.map +1 -0
  158. package/dist/tui/welcome.d.ts +3 -0
  159. package/dist/tui/welcome.d.ts.map +1 -0
  160. package/dist/tui/welcome.js +37 -0
  161. package/dist/tui/welcome.js.map +1 -0
  162. package/package.json +54 -0
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Shell configuration, environment helpers, and process-kill utilities.
3
+ *
4
+ * Ported from @earendil-works/pi-coding-agent.
5
+ * Simplification: getShellEnv() returns process.env as-is without prepending a
6
+ * pi-specific bin directory.
7
+ */
8
+ import { existsSync } from "node:fs";
9
+ import { spawn, spawnSync } from "child_process";
10
+ /** Find bash executable on PATH (cross-platform). */
11
+ function findBashOnPath() {
12
+ if (process.platform === "win32") {
13
+ try {
14
+ const result = spawnSync("where", ["bash.exe"], {
15
+ encoding: "utf-8",
16
+ timeout: 5000,
17
+ windowsHide: true,
18
+ });
19
+ if (result.status === 0 && result.stdout) {
20
+ const firstMatch = result.stdout.trim().split(/\r?\n/)[0];
21
+ if (firstMatch && existsSync(firstMatch))
22
+ return firstMatch;
23
+ }
24
+ }
25
+ catch {
26
+ // ignore
27
+ }
28
+ return null;
29
+ }
30
+ try {
31
+ const result = spawnSync("which", ["bash"], { encoding: "utf-8", timeout: 5000 });
32
+ if (result.status === 0 && result.stdout) {
33
+ const firstMatch = result.stdout.trim().split(/\r?\n/)[0];
34
+ if (firstMatch)
35
+ return firstMatch;
36
+ }
37
+ }
38
+ catch {
39
+ // ignore
40
+ }
41
+ return null;
42
+ }
43
+ /**
44
+ * Resolve shell configuration based on platform and an optional explicit shell path.
45
+ *
46
+ * Resolution order:
47
+ * 1. User-specified shellPath
48
+ * 2. On Windows: Git Bash in known locations, then bash on PATH
49
+ * 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh
50
+ */
51
+ export function getShellConfig(customShellPath) {
52
+ if (customShellPath) {
53
+ if (existsSync(customShellPath))
54
+ return { shell: customShellPath, args: ["-c"] };
55
+ throw new Error(`Custom shell path not found: ${customShellPath}`);
56
+ }
57
+ if (process.platform === "win32") {
58
+ const paths = [];
59
+ const programFiles = process.env["ProgramFiles"];
60
+ if (programFiles)
61
+ paths.push(`${programFiles}\\Git\\bin\\bash.exe`);
62
+ const programFilesX86 = process.env["ProgramFiles(x86)"];
63
+ if (programFilesX86)
64
+ paths.push(`${programFilesX86}\\Git\\bin\\bash.exe`);
65
+ for (const p of paths) {
66
+ if (existsSync(p))
67
+ return { shell: p, args: ["-c"] };
68
+ }
69
+ const bashOnPath = findBashOnPath();
70
+ if (bashOnPath)
71
+ return { shell: bashOnPath, args: ["-c"] };
72
+ throw new Error(`No bash shell found. Options:\n` +
73
+ ` 1. Install Git for Windows: https://git-scm.com/download/win\n` +
74
+ ` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\n` +
75
+ ` 3. Set shellPath in settings.json\n\n` +
76
+ `Searched Git Bash in:\n${paths.map((p) => ` ${p}`).join("\n")}`);
77
+ }
78
+ // Unix: /bin/bash → bash on PATH → sh
79
+ if (existsSync("/bin/bash"))
80
+ return { shell: "/bin/bash", args: ["-c"] };
81
+ const bashOnPath = findBashOnPath();
82
+ if (bashOnPath)
83
+ return { shell: bashOnPath, args: ["-c"] };
84
+ return { shell: "sh", args: ["-c"] };
85
+ }
86
+ /** Return the current process environment for spawned commands. */
87
+ export function getShellEnv() {
88
+ return { ...process.env };
89
+ }
90
+ /**
91
+ * Detached child processes are tracked so they can be cleaned up when the
92
+ * parent receives SIGHUP/SIGTERM.
93
+ */
94
+ const trackedDetachedChildPids = new Set();
95
+ export function trackDetachedChildPid(pid) {
96
+ trackedDetachedChildPids.add(pid);
97
+ }
98
+ export function untrackDetachedChildPid(pid) {
99
+ trackedDetachedChildPids.delete(pid);
100
+ }
101
+ /** Kill a process and its entire process group (cross-platform). */
102
+ export function killProcessTree(pid) {
103
+ if (process.platform === "win32") {
104
+ try {
105
+ spawn("taskkill", ["/F", "/T", "/PID", String(pid)], {
106
+ stdio: "ignore",
107
+ detached: true,
108
+ windowsHide: true,
109
+ });
110
+ }
111
+ catch {
112
+ // ignore
113
+ }
114
+ }
115
+ else {
116
+ try {
117
+ process.kill(-pid, "SIGKILL");
118
+ }
119
+ catch {
120
+ try {
121
+ process.kill(pid, "SIGKILL");
122
+ }
123
+ catch {
124
+ // process already dead
125
+ }
126
+ }
127
+ }
128
+ }
129
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../src/tools/bash/shell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Bash tool — executes shell commands and returns stdout+stderr.
3
+ *
4
+ * Ported from @earendil-works/pi-coding-agent. TUI rendering components have
5
+ * been omitted; only the core execute logic is kept.
6
+ */
7
+ import type { AgentTool } from "@earendil-works/pi-agent-core";
8
+ import { Type } from "typebox";
9
+ import { type TruncationResult } from "./truncate.js";
10
+ declare const bashSchema: Type.TObject<{
11
+ command: Type.TString;
12
+ timeout: Type.TOptional<Type.TNumber>;
13
+ }>;
14
+ interface BashToolDetails {
15
+ truncation?: TruncationResult;
16
+ fullOutputPath?: string;
17
+ }
18
+ /**
19
+ * Create a bash AgentTool that executes commands in `cwd`.
20
+ */
21
+ export declare function createBashTool(cwd: string): AgentTool<typeof bashSchema, BashToolDetails | undefined>;
22
+ export {};
23
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../src/tools/bash/tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAA4C,MAAM,+BAA+B,CAAC;AAIzG,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAW5C,OAAO,EAAoD,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAMxG,QAAA,MAAM,UAAU;;;EAGd,CAAC;AAQH,UAAU,eAAe;IACvB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAYD;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CA+MrG"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Bash tool — executes shell commands and returns stdout+stderr.
3
+ *
4
+ * Ported from @earendil-works/pi-coding-agent. TUI rendering components have
5
+ * been omitted; only the core execute logic is kept.
6
+ */
7
+ import { constants } from "node:fs";
8
+ import { access as fsAccess } from "node:fs/promises";
9
+ import { spawn } from "child_process";
10
+ import { Type } from "typebox";
11
+ import { waitForChildProcess } from "./child-process.js";
12
+ import { OutputAccumulator } from "./output-accumulator.js";
13
+ import { getShellConfig, getShellEnv, killProcessTree, trackDetachedChildPid, untrackDetachedChildPid, } from "./shell.js";
14
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize } from "./truncate.js";
15
+ // ---------------------------------------------------------------------------
16
+ // Schema
17
+ // ---------------------------------------------------------------------------
18
+ const bashSchema = Type.Object({
19
+ command: Type.String({ description: "Bash command to execute" }),
20
+ timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional, no default timeout)" })),
21
+ });
22
+ // ---------------------------------------------------------------------------
23
+ // Throttle constant for streaming updates
24
+ // ---------------------------------------------------------------------------
25
+ const UPDATE_THROTTLE_MS = 100;
26
+ // ---------------------------------------------------------------------------
27
+ // createBashTool
28
+ // ---------------------------------------------------------------------------
29
+ /**
30
+ * Create a bash AgentTool that executes commands in `cwd`.
31
+ */
32
+ export function createBashTool(cwd) {
33
+ return {
34
+ name: "bash",
35
+ label: "bash",
36
+ description: [
37
+ "Execute a bash command in the current working directory.",
38
+ "Returns stdout and stderr.",
39
+ `Output is truncated to the last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,
40
+ "If truncated, full output is saved to a temp file.",
41
+ "Optionally provide a timeout in seconds.",
42
+ ].join(" "),
43
+ parameters: bashSchema,
44
+ execute: async (_toolCallId, { command, timeout }, signal, onUpdate) => {
45
+ const { shell, args } = getShellConfig();
46
+ // Verify the working directory exists before spawning.
47
+ try {
48
+ await fsAccess(cwd, constants.F_OK);
49
+ }
50
+ catch {
51
+ throw new Error(`Working directory does not exist: ${cwd}\nCannot execute bash commands.`);
52
+ }
53
+ if (signal?.aborted)
54
+ throw new Error("aborted");
55
+ const child = spawn(shell, [...args, command], {
56
+ cwd,
57
+ detached: process.platform !== "win32",
58
+ env: getShellEnv(),
59
+ stdio: ["ignore", "pipe", "pipe"],
60
+ windowsHide: true,
61
+ });
62
+ if (child.pid)
63
+ trackDetachedChildPid(child.pid);
64
+ let timedOut = false;
65
+ let timeoutHandle;
66
+ const onAbort = () => {
67
+ if (child.pid)
68
+ killProcessTree(child.pid);
69
+ };
70
+ // -----------------------------------------------------------------------
71
+ // Output accumulation + streaming updates
72
+ // -----------------------------------------------------------------------
73
+ const output = new OutputAccumulator({ tempFilePrefix: "pi2-bash" });
74
+ let updateTimer;
75
+ let updateDirty = false;
76
+ let lastUpdateAt = 0;
77
+ const emitOutputUpdate = () => {
78
+ if (!onUpdate || !updateDirty)
79
+ return;
80
+ updateDirty = false;
81
+ lastUpdateAt = Date.now();
82
+ const snapshot = output.snapshot({ persistIfTruncated: true });
83
+ onUpdate({
84
+ content: [{ type: "text", text: snapshot.content || "" }],
85
+ details: snapshot.truncation.truncated
86
+ ? {
87
+ truncation: snapshot.truncation,
88
+ ...(snapshot.fullOutputPath !== undefined && { fullOutputPath: snapshot.fullOutputPath }),
89
+ }
90
+ : undefined,
91
+ });
92
+ };
93
+ const clearUpdateTimer = () => {
94
+ if (updateTimer) {
95
+ clearTimeout(updateTimer);
96
+ updateTimer = undefined;
97
+ }
98
+ };
99
+ const scheduleOutputUpdate = () => {
100
+ if (!onUpdate)
101
+ return;
102
+ updateDirty = true;
103
+ const delay = UPDATE_THROTTLE_MS - (Date.now() - lastUpdateAt);
104
+ if (delay <= 0) {
105
+ clearUpdateTimer();
106
+ emitOutputUpdate();
107
+ return;
108
+ }
109
+ updateTimer ??= setTimeout(() => {
110
+ updateTimer = undefined;
111
+ emitOutputUpdate();
112
+ }, delay);
113
+ };
114
+ if (onUpdate)
115
+ onUpdate({ content: [], details: undefined });
116
+ child.stdout?.on("data", (data) => {
117
+ output.append(data);
118
+ scheduleOutputUpdate();
119
+ });
120
+ child.stderr?.on("data", (data) => {
121
+ output.append(data);
122
+ scheduleOutputUpdate();
123
+ });
124
+ // -----------------------------------------------------------------------
125
+ // Timeout + abort wiring
126
+ // -----------------------------------------------------------------------
127
+ if (timeout !== undefined && timeout > 0) {
128
+ timeoutHandle = setTimeout(() => {
129
+ timedOut = true;
130
+ if (child.pid)
131
+ killProcessTree(child.pid);
132
+ }, timeout * 1000);
133
+ }
134
+ if (signal) {
135
+ if (signal.aborted)
136
+ onAbort();
137
+ else
138
+ signal.addEventListener("abort", onAbort, { once: true });
139
+ }
140
+ // -----------------------------------------------------------------------
141
+ // Helpers
142
+ // -----------------------------------------------------------------------
143
+ const finishOutput = async () => {
144
+ output.finish();
145
+ clearUpdateTimer();
146
+ emitOutputUpdate();
147
+ const snapshot = output.snapshot({ persistIfTruncated: true });
148
+ await output.closeTempFile();
149
+ return snapshot;
150
+ };
151
+ const formatOutput = (snapshot, emptyText = "(no output)") => {
152
+ const { truncation } = snapshot;
153
+ let text = snapshot.content || emptyText;
154
+ let details;
155
+ if (truncation.truncated) {
156
+ details = {
157
+ truncation,
158
+ ...(snapshot.fullOutputPath !== undefined && { fullOutputPath: snapshot.fullOutputPath }),
159
+ };
160
+ const startLine = truncation.totalLines - truncation.outputLines + 1;
161
+ const endLine = truncation.totalLines;
162
+ if (truncation.lastLinePartial) {
163
+ const lastLineSize = formatSize(output.getLastLineBytes());
164
+ text += `\n\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`;
165
+ }
166
+ else if (truncation.truncatedBy === "lines") {
167
+ text += `\n\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${snapshot.fullOutputPath}]`;
168
+ }
169
+ else {
170
+ text += `\n\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Full output: ${snapshot.fullOutputPath}]`;
171
+ }
172
+ }
173
+ return { text, details };
174
+ };
175
+ const appendStatus = (text, status) => `${text ? `${text}\n\n` : ""}${status}`;
176
+ // -----------------------------------------------------------------------
177
+ // Execute and wait
178
+ // -----------------------------------------------------------------------
179
+ try {
180
+ let exitCode;
181
+ try {
182
+ exitCode = await waitForChildProcess(child);
183
+ if (signal?.aborted)
184
+ throw new Error("aborted");
185
+ if (timedOut)
186
+ throw new Error(`timeout:${timeout}`);
187
+ }
188
+ catch (err) {
189
+ const snapshot = await finishOutput();
190
+ const { text } = formatOutput(snapshot, "");
191
+ if (err instanceof Error && err.message === "aborted") {
192
+ throw new Error(appendStatus(text, "Command aborted"));
193
+ }
194
+ if (err instanceof Error && err.message.startsWith("timeout:")) {
195
+ const secs = err.message.split(":")[1];
196
+ throw new Error(appendStatus(text, `Command timed out after ${secs} seconds`));
197
+ }
198
+ throw err;
199
+ }
200
+ const snapshot = await finishOutput();
201
+ const { text, details } = formatOutput(snapshot);
202
+ if (exitCode !== 0 && exitCode !== null) {
203
+ throw new Error(appendStatus(text, `Command exited with code ${exitCode}`));
204
+ }
205
+ return { content: [{ type: "text", text }], details };
206
+ }
207
+ finally {
208
+ if (child.pid)
209
+ untrackDetachedChildPid(child.pid);
210
+ if (timeoutHandle)
211
+ clearTimeout(timeoutHandle);
212
+ if (signal)
213
+ signal.removeEventListener("abort", onAbort);
214
+ clearUpdateTimer();
215
+ }
216
+ },
217
+ };
218
+ }
219
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../src/tools/bash/tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Shared truncation utilities for tool outputs.
3
+ *
4
+ * Truncation is based on two independent limits — whichever is hit first wins:
5
+ * - Line limit (default: 2000 lines)
6
+ * - Byte limit (default: 50 KB)
7
+ *
8
+ * Ported from @earendil-works/pi-coding-agent.
9
+ */
10
+ export declare const DEFAULT_MAX_LINES = 2000;
11
+ export declare const DEFAULT_MAX_BYTES: number;
12
+ export declare const GREP_MAX_LINE_LENGTH = 500;
13
+ export interface TruncationResult {
14
+ content: string;
15
+ truncated: boolean;
16
+ truncatedBy: "lines" | "bytes" | null;
17
+ totalLines: number;
18
+ totalBytes: number;
19
+ outputLines: number;
20
+ outputBytes: number;
21
+ lastLinePartial: boolean;
22
+ firstLineExceedsLimit: boolean;
23
+ maxLines: number;
24
+ maxBytes: number;
25
+ }
26
+ export interface TruncationOptions {
27
+ maxLines?: number;
28
+ maxBytes?: number;
29
+ }
30
+ /** Format bytes as human-readable size. */
31
+ export declare function formatSize(bytes: number): string;
32
+ /**
33
+ * Truncate content from the head (keep first N lines/bytes).
34
+ * Never returns partial lines. If the first line exceeds the byte limit,
35
+ * returns empty content with firstLineExceedsLimit=true.
36
+ */
37
+ export declare function truncateHead(content: string, options?: TruncationOptions): TruncationResult;
38
+ /**
39
+ * Truncate content from the tail (keep last N lines/bytes).
40
+ * Suitable for bash output where you want to see the end (errors, final results).
41
+ *
42
+ * May return a partial first line if the last line alone exceeds the byte limit.
43
+ */
44
+ export declare function truncateTail(content: string, options?: TruncationOptions): TruncationResult;
45
+ /** Truncate a single grep line, adding a marker when shortened. */
46
+ export declare function truncateLine(line: string, maxChars?: number): {
47
+ text: string;
48
+ wasTruncated: boolean;
49
+ };
50
+ //# sourceMappingURL=truncate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncate.d.ts","sourceRoot":"","sources":["../../../src/tools/bash/truncate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,iBAAiB,QAAY,CAAC;AAC3C,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIhD;AASD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAyE/F;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAiE/F;AAWD,mEAAmE;AACnE,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAA6B,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAGzC"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Shared truncation utilities for tool outputs.
3
+ *
4
+ * Truncation is based on two independent limits — whichever is hit first wins:
5
+ * - Line limit (default: 2000 lines)
6
+ * - Byte limit (default: 50 KB)
7
+ *
8
+ * Ported from @earendil-works/pi-coding-agent.
9
+ */
10
+ export const DEFAULT_MAX_LINES = 2000;
11
+ export const DEFAULT_MAX_BYTES = 50 * 1024; // 50 KB
12
+ export const GREP_MAX_LINE_LENGTH = 500;
13
+ /** Format bytes as human-readable size. */
14
+ export function formatSize(bytes) {
15
+ if (bytes < 1024)
16
+ return `${bytes}B`;
17
+ if (bytes < 1024 * 1024)
18
+ return `${(bytes / 1024).toFixed(1)}KB`;
19
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
20
+ }
21
+ function splitLinesForCounting(content) {
22
+ if (content.length === 0)
23
+ return [];
24
+ const lines = content.split("\n");
25
+ if (content.endsWith("\n"))
26
+ lines.pop();
27
+ return lines;
28
+ }
29
+ /**
30
+ * Truncate content from the head (keep first N lines/bytes).
31
+ * Never returns partial lines. If the first line exceeds the byte limit,
32
+ * returns empty content with firstLineExceedsLimit=true.
33
+ */
34
+ export function truncateHead(content, options = {}) {
35
+ const maxLines = options.maxLines ?? DEFAULT_MAX_LINES;
36
+ const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
37
+ const totalBytes = Buffer.byteLength(content, "utf-8");
38
+ const lines = splitLinesForCounting(content);
39
+ const totalLines = lines.length;
40
+ if (totalLines <= maxLines && totalBytes <= maxBytes) {
41
+ return {
42
+ content,
43
+ truncated: false,
44
+ truncatedBy: null,
45
+ totalLines,
46
+ totalBytes,
47
+ outputLines: totalLines,
48
+ outputBytes: totalBytes,
49
+ lastLinePartial: false,
50
+ firstLineExceedsLimit: false,
51
+ maxLines,
52
+ maxBytes,
53
+ };
54
+ }
55
+ const firstLineBytes = Buffer.byteLength(lines[0] ?? "", "utf-8");
56
+ if (firstLineBytes > maxBytes) {
57
+ return {
58
+ content: "",
59
+ truncated: true,
60
+ truncatedBy: "bytes",
61
+ totalLines,
62
+ totalBytes,
63
+ outputLines: 0,
64
+ outputBytes: 0,
65
+ lastLinePartial: false,
66
+ firstLineExceedsLimit: true,
67
+ maxLines,
68
+ maxBytes,
69
+ };
70
+ }
71
+ const outputLinesArr = [];
72
+ let outputBytesCount = 0;
73
+ let truncatedBy = "lines";
74
+ for (let i = 0; i < lines.length && i < maxLines; i++) {
75
+ const line = lines[i] ?? "";
76
+ const lineBytes = Buffer.byteLength(line, "utf-8") + (i > 0 ? 1 : 0);
77
+ if (outputBytesCount + lineBytes > maxBytes) {
78
+ truncatedBy = "bytes";
79
+ break;
80
+ }
81
+ outputLinesArr.push(line);
82
+ outputBytesCount += lineBytes;
83
+ }
84
+ if (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {
85
+ truncatedBy = "lines";
86
+ }
87
+ const outputContent = outputLinesArr.join("\n");
88
+ return {
89
+ content: outputContent,
90
+ truncated: true,
91
+ truncatedBy,
92
+ totalLines,
93
+ totalBytes,
94
+ outputLines: outputLinesArr.length,
95
+ outputBytes: Buffer.byteLength(outputContent, "utf-8"),
96
+ lastLinePartial: false,
97
+ firstLineExceedsLimit: false,
98
+ maxLines,
99
+ maxBytes,
100
+ };
101
+ }
102
+ /**
103
+ * Truncate content from the tail (keep last N lines/bytes).
104
+ * Suitable for bash output where you want to see the end (errors, final results).
105
+ *
106
+ * May return a partial first line if the last line alone exceeds the byte limit.
107
+ */
108
+ export function truncateTail(content, options = {}) {
109
+ const maxLines = options.maxLines ?? DEFAULT_MAX_LINES;
110
+ const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
111
+ const totalBytes = Buffer.byteLength(content, "utf-8");
112
+ const lines = splitLinesForCounting(content);
113
+ const totalLines = lines.length;
114
+ if (totalLines <= maxLines && totalBytes <= maxBytes) {
115
+ return {
116
+ content,
117
+ truncated: false,
118
+ truncatedBy: null,
119
+ totalLines,
120
+ totalBytes,
121
+ outputLines: totalLines,
122
+ outputBytes: totalBytes,
123
+ lastLinePartial: false,
124
+ firstLineExceedsLimit: false,
125
+ maxLines,
126
+ maxBytes,
127
+ };
128
+ }
129
+ const outputLinesArr = [];
130
+ let outputBytesCount = 0;
131
+ let truncatedBy = "lines";
132
+ let lastLinePartial = false;
133
+ for (let i = lines.length - 1; i >= 0 && outputLinesArr.length < maxLines; i--) {
134
+ const line = lines[i] ?? "";
135
+ const lineBytes = Buffer.byteLength(line, "utf-8") + (outputLinesArr.length > 0 ? 1 : 0);
136
+ if (outputBytesCount + lineBytes > maxBytes) {
137
+ truncatedBy = "bytes";
138
+ // Edge case: first line alone exceeds the limit — take the tail of that line.
139
+ if (outputLinesArr.length === 0) {
140
+ const truncatedLine = truncateStringToBytesFromEnd(line, maxBytes);
141
+ outputLinesArr.unshift(truncatedLine);
142
+ outputBytesCount = Buffer.byteLength(truncatedLine, "utf-8");
143
+ lastLinePartial = true;
144
+ }
145
+ break;
146
+ }
147
+ outputLinesArr.unshift(line);
148
+ outputBytesCount += lineBytes;
149
+ }
150
+ if (outputLinesArr.length >= maxLines && outputBytesCount <= maxBytes) {
151
+ truncatedBy = "lines";
152
+ }
153
+ const outputContent = outputLinesArr.join("\n");
154
+ return {
155
+ content: outputContent,
156
+ truncated: true,
157
+ truncatedBy,
158
+ totalLines,
159
+ totalBytes,
160
+ outputLines: outputLinesArr.length,
161
+ outputBytes: Buffer.byteLength(outputContent, "utf-8"),
162
+ lastLinePartial,
163
+ firstLineExceedsLimit: false,
164
+ maxLines,
165
+ maxBytes,
166
+ };
167
+ }
168
+ function truncateStringToBytesFromEnd(str, maxBytes) {
169
+ const buf = Buffer.from(str, "utf-8");
170
+ if (buf.length <= maxBytes)
171
+ return str;
172
+ let start = buf.length - maxBytes;
173
+ // Advance to the next valid UTF-8 character boundary.
174
+ while (start < buf.length && ((buf[start] ?? 0) & 0xc0) === 0x80)
175
+ start++;
176
+ return buf.subarray(start).toString("utf-8");
177
+ }
178
+ /** Truncate a single grep line, adding a marker when shortened. */
179
+ export function truncateLine(line, maxChars = GREP_MAX_LINE_LENGTH) {
180
+ if (line.length <= maxChars)
181
+ return { text: line, wasTruncated: false };
182
+ return { text: `${line.slice(0, maxChars)}... [truncated]`, wasTruncated: true };
183
+ }
184
+ //# sourceMappingURL=truncate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncate.js","sourceRoot":"","sources":["../../../src/tools/bash/truncate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function findExecutable(candidates: string[]): string | undefined;
2
+ //# sourceMappingURL=external-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-tool.d.ts","sourceRoot":"","sources":["../../src/tools/external-tool.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAevE"}