pi-agent-flow 2.0.1 → 2.0.5

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 (233) hide show
  1. package/README.md +126 -489
  2. package/agents/audit.md +24 -15
  3. package/agents/build.md +4 -3
  4. package/agents/craft.md +4 -4
  5. package/agents/debug.md +5 -4
  6. package/agents/ideas.md +6 -5
  7. package/agents/scout.md +10 -8
  8. package/agents/trace.md +23 -0
  9. package/dist/batch/apply-patch.d.ts +60 -0
  10. package/dist/batch/apply-patch.d.ts.map +1 -0
  11. package/dist/batch/apply-patch.js +477 -0
  12. package/dist/batch/apply-patch.js.map +1 -0
  13. package/dist/batch/batch-bash.d.ts +10 -6
  14. package/dist/batch/batch-bash.d.ts.map +1 -1
  15. package/dist/batch/batch-bash.js +59 -11
  16. package/dist/batch/batch-bash.js.map +1 -1
  17. package/dist/batch/constants.d.ts +38 -6
  18. package/dist/batch/constants.d.ts.map +1 -1
  19. package/dist/batch/constants.js +26 -4
  20. package/dist/batch/constants.js.map +1 -1
  21. package/dist/batch/execute.d.ts +8 -2
  22. package/dist/batch/execute.d.ts.map +1 -1
  23. package/dist/batch/execute.js +222 -67
  24. package/dist/batch/execute.js.map +1 -1
  25. package/dist/batch/fuzzy-edit.d.ts +4 -1
  26. package/dist/batch/fuzzy-edit.d.ts.map +1 -1
  27. package/dist/batch/fuzzy-edit.js +7 -2
  28. package/dist/batch/fuzzy-edit.js.map +1 -1
  29. package/dist/batch/index.d.ts +10 -24
  30. package/dist/batch/index.d.ts.map +1 -1
  31. package/dist/batch/index.js +120 -120
  32. package/dist/batch/index.js.map +1 -1
  33. package/dist/batch/render.d.ts +22 -5
  34. package/dist/batch/render.d.ts.map +1 -1
  35. package/dist/batch/render.js +353 -15
  36. package/dist/batch/render.js.map +1 -1
  37. package/dist/batch/summary.d.ts.map +1 -1
  38. package/dist/batch/summary.js +26 -4
  39. package/dist/batch/summary.js.map +1 -1
  40. package/dist/config/config.d.ts +5 -4
  41. package/dist/config/config.d.ts.map +1 -1
  42. package/dist/config/config.js +15 -5
  43. package/dist/config/config.js.map +1 -1
  44. package/dist/config/models.d.ts.map +1 -1
  45. package/dist/config/models.js +7 -1
  46. package/dist/config/models.js.map +1 -1
  47. package/dist/config/settings-resolver.d.ts +5 -4
  48. package/dist/config/settings-resolver.d.ts.map +1 -1
  49. package/dist/config/settings-resolver.js +50 -21
  50. package/dist/config/settings-resolver.js.map +1 -1
  51. package/dist/core2/snapshot.d.ts +21 -0
  52. package/dist/core2/snapshot.d.ts.map +1 -0
  53. package/dist/core2/snapshot.js +214 -0
  54. package/dist/core2/snapshot.js.map +1 -0
  55. package/dist/{core → flow}/agents.d.ts.map +1 -1
  56. package/dist/{core → flow}/agents.js +5 -2
  57. package/dist/{core → flow}/agents.js.map +1 -1
  58. package/dist/flow/auto-warp.d.ts +1 -1
  59. package/dist/flow/auto-warp.js +1 -1
  60. package/dist/flow/command.d.ts +1 -1
  61. package/dist/flow/command.d.ts.map +1 -1
  62. package/dist/flow/complexity.d.ts +20 -0
  63. package/dist/flow/complexity.d.ts.map +1 -0
  64. package/dist/flow/complexity.js +34 -0
  65. package/dist/flow/complexity.js.map +1 -0
  66. package/dist/flow/continuation.d.ts +1 -1
  67. package/dist/flow/continuation.d.ts.map +1 -1
  68. package/dist/flow/continuation.js +4 -3
  69. package/dist/flow/continuation.js.map +1 -1
  70. package/dist/{core → flow}/depth.d.ts +4 -4
  71. package/dist/{core → flow}/depth.d.ts.map +1 -1
  72. package/dist/{core → flow}/depth.js +5 -5
  73. package/dist/{core → flow}/depth.js.map +1 -1
  74. package/dist/{core → flow}/executor.d.ts +42 -22
  75. package/dist/flow/executor.d.ts.map +1 -0
  76. package/dist/flow/executor.js +727 -0
  77. package/dist/flow/executor.js.map +1 -0
  78. package/dist/flow/index.d.ts +4 -4
  79. package/dist/flow/index.d.ts.map +1 -1
  80. package/dist/flow/index.js +4 -4
  81. package/dist/flow/index.js.map +1 -1
  82. package/dist/flow/loop-command.d.ts +1 -1
  83. package/dist/flow/loop-command.d.ts.map +1 -1
  84. package/dist/flow/loop-command.js +3 -0
  85. package/dist/flow/loop-command.js.map +1 -1
  86. package/dist/{core/flow.d.ts → flow/runner.d.ts} +20 -16
  87. package/dist/flow/runner.d.ts.map +1 -0
  88. package/dist/{core/flow.js → flow/runner.js} +105 -61
  89. package/dist/flow/runner.js.map +1 -0
  90. package/dist/{core → flow}/session-registry.d.ts.map +1 -1
  91. package/dist/{core → flow}/session-registry.js.map +1 -1
  92. package/dist/flow/settings-command.d.ts +3 -3
  93. package/dist/flow/settings-command.d.ts.map +1 -1
  94. package/dist/flow/settings-command.js +43 -22
  95. package/dist/flow/settings-command.js.map +1 -1
  96. package/dist/{core/delegation.d.ts → flow/transition.d.ts} +8 -8
  97. package/dist/{core/delegation.d.ts.map → flow/transition.d.ts.map} +1 -1
  98. package/dist/{core/delegation.js → flow/transition.js} +12 -12
  99. package/dist/{core/delegation.js.map → flow/transition.js.map} +1 -1
  100. package/dist/flow/types.d.ts +4 -0
  101. package/dist/flow/types.d.ts.map +1 -1
  102. package/dist/flow/warp.d.ts +15 -0
  103. package/dist/flow/warp.d.ts.map +1 -0
  104. package/dist/flow/warp.js +207 -0
  105. package/dist/flow/warp.js.map +1 -0
  106. package/dist/index.d.ts +1 -2
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +237 -89
  109. package/dist/index.js.map +1 -1
  110. package/dist/notify/notify.d.ts +1 -1
  111. package/dist/notify/notify.d.ts.map +1 -1
  112. package/dist/notify/notify.js +1 -1
  113. package/dist/snapshot/cli-args.d.ts +2 -2
  114. package/dist/snapshot/cli-args.d.ts.map +1 -1
  115. package/dist/snapshot/cli-args.js +21 -5
  116. package/dist/snapshot/cli-args.js.map +1 -1
  117. package/dist/snapshot/runner-events.d.ts +7 -2
  118. package/dist/snapshot/runner-events.d.ts.map +1 -1
  119. package/dist/snapshot/runner-events.js +137 -19
  120. package/dist/snapshot/runner-events.js.map +1 -1
  121. package/dist/snapshot/structured-output.d.ts +1 -1
  122. package/dist/snapshot/structured-output.d.ts.map +1 -1
  123. package/dist/snapshot/structured-output.js +20 -2
  124. package/dist/snapshot/structured-output.js.map +1 -1
  125. package/dist/steering/flow-prompt.d.ts +4 -4
  126. package/dist/steering/flow-prompt.d.ts.map +1 -1
  127. package/dist/steering/flow-prompt.js +18 -37
  128. package/dist/steering/flow-prompt.js.map +1 -1
  129. package/dist/steering/sliding-prompt.d.ts.map +1 -1
  130. package/dist/steering/sliding-prompt.js +8 -7
  131. package/dist/steering/sliding-prompt.js.map +1 -1
  132. package/dist/steering/tool-utils.d.ts +31 -8
  133. package/dist/steering/tool-utils.d.ts.map +1 -1
  134. package/dist/steering/tool-utils.js +63 -30
  135. package/dist/steering/tool-utils.js.map +1 -1
  136. package/dist/tools/ask-user.d.ts +2 -19
  137. package/dist/tools/ask-user.d.ts.map +1 -1
  138. package/dist/tools/ask-user.js +14 -38
  139. package/dist/tools/ask-user.js.map +1 -1
  140. package/dist/tools/timed-bash.d.ts +1 -1
  141. package/dist/tools/timed-bash.d.ts.map +1 -1
  142. package/dist/tools/timed-bash.js +11 -9
  143. package/dist/tools/timed-bash.js.map +1 -1
  144. package/dist/tools/trace.d.ts +34 -0
  145. package/dist/tools/trace.d.ts.map +1 -0
  146. package/dist/tools/trace.js +180 -0
  147. package/dist/tools/trace.js.map +1 -0
  148. package/dist/tools/web-ops.d.ts +85 -0
  149. package/dist/tools/web-ops.d.ts.map +1 -0
  150. package/dist/tools/{web-tool.js → web-ops.js} +51 -127
  151. package/dist/tools/web-ops.js.map +1 -0
  152. package/dist/tui/flow-colors.d.ts +1 -0
  153. package/dist/tui/flow-colors.d.ts.map +1 -1
  154. package/dist/tui/flow-colors.js +2 -2
  155. package/dist/tui/flow-colors.js.map +1 -1
  156. package/dist/tui/render-utils.d.ts.map +1 -1
  157. package/dist/tui/render-utils.js +2 -4
  158. package/dist/tui/render-utils.js.map +1 -1
  159. package/dist/tui/render.d.ts +41 -1
  160. package/dist/tui/render.d.ts.map +1 -1
  161. package/dist/tui/render.js +724 -189
  162. package/dist/tui/render.js.map +1 -1
  163. package/dist/tui/scramble/algorithm.d.ts +4 -2
  164. package/dist/tui/scramble/algorithm.d.ts.map +1 -1
  165. package/dist/tui/scramble/algorithm.js +44 -12
  166. package/dist/tui/scramble/algorithm.js.map +1 -1
  167. package/dist/tui/scramble/constants.d.ts +3 -0
  168. package/dist/tui/scramble/constants.d.ts.map +1 -1
  169. package/dist/tui/scramble/constants.js +4 -1
  170. package/dist/tui/scramble/constants.js.map +1 -1
  171. package/dist/tui/scramble/index.d.ts +3 -2
  172. package/dist/tui/scramble/index.d.ts.map +1 -1
  173. package/dist/tui/scramble/index.js +2 -2
  174. package/dist/tui/scramble/index.js.map +1 -1
  175. package/dist/tui/scramble/manager.d.ts +2 -2
  176. package/dist/tui/scramble/manager.d.ts.map +1 -1
  177. package/dist/tui/scramble/manager.js +37 -20
  178. package/dist/tui/scramble/manager.js.map +1 -1
  179. package/dist/tui/scramble/utils.js +1 -1
  180. package/dist/tui/scramble/utils.js.map +1 -1
  181. package/dist/types/flow.d.ts +17 -1
  182. package/dist/types/flow.d.ts.map +1 -1
  183. package/dist/types/flow.js +11 -2
  184. package/dist/types/flow.js.map +1 -1
  185. package/dist/types/output.d.ts +11 -36
  186. package/dist/types/output.d.ts.map +1 -1
  187. package/dist/types/output.js +1 -1
  188. package/dist/types/ui.d.ts +1 -1
  189. package/dist/types/ui.d.ts.map +1 -1
  190. package/package.json +10 -10
  191. package/dist/core/executor.d.ts.map +0 -1
  192. package/dist/core/executor.js +0 -378
  193. package/dist/core/executor.js.map +0 -1
  194. package/dist/core/flow.d.ts.map +0 -1
  195. package/dist/core/flow.js.map +0 -1
  196. package/dist/core/session-mode.d.ts +0 -11
  197. package/dist/core/session-mode.d.ts.map +0 -1
  198. package/dist/core/session-mode.js +0 -26
  199. package/dist/core/session-mode.js.map +0 -1
  200. package/dist/core/transitions.d.ts +0 -39
  201. package/dist/core/transitions.d.ts.map +0 -1
  202. package/dist/core/transitions.js +0 -59
  203. package/dist/core/transitions.js.map +0 -1
  204. package/dist/flow/perform-warp.d.ts +0 -28
  205. package/dist/flow/perform-warp.d.ts.map +0 -1
  206. package/dist/flow/perform-warp.js +0 -127
  207. package/dist/flow/perform-warp.js.map +0 -1
  208. package/dist/flow/warp-command.d.ts +0 -8
  209. package/dist/flow/warp-command.d.ts.map +0 -1
  210. package/dist/flow/warp-command.js +0 -144
  211. package/dist/flow/warp-command.js.map +0 -1
  212. package/dist/flow/warp-utils.d.ts +0 -11
  213. package/dist/flow/warp-utils.d.ts.map +0 -1
  214. package/dist/flow/warp-utils.js +0 -187
  215. package/dist/flow/warp-utils.js.map +0 -1
  216. package/dist/snapshot/index.d.ts +0 -2
  217. package/dist/snapshot/index.d.ts.map +0 -1
  218. package/dist/snapshot/index.js +0 -2
  219. package/dist/snapshot/index.js.map +0 -1
  220. package/dist/snapshot/reasoning-strip.d.ts +0 -22
  221. package/dist/snapshot/reasoning-strip.d.ts.map +0 -1
  222. package/dist/snapshot/reasoning-strip.js +0 -58
  223. package/dist/snapshot/reasoning-strip.js.map +0 -1
  224. package/dist/snapshot/snapshot.d.ts +0 -77
  225. package/dist/snapshot/snapshot.d.ts.map +0 -1
  226. package/dist/snapshot/snapshot.js +0 -1791
  227. package/dist/snapshot/snapshot.js.map +0 -1
  228. package/dist/tools/web-tool.d.ts +0 -46
  229. package/dist/tools/web-tool.d.ts.map +0 -1
  230. package/dist/tools/web-tool.js.map +0 -1
  231. /package/dist/{core → flow}/agents.d.ts +0 -0
  232. /package/dist/{core → flow}/session-registry.d.ts +0 -0
  233. /package/dist/{core → flow}/session-registry.js +0 -0
@@ -0,0 +1,477 @@
1
+ /**
2
+ * apply-patch — 1:1 port of OpenAI Codex CLI apply_patch tool.
3
+ *
4
+ * Parses patch text into hunks, locates context via 4-stage fuzzy matching,
5
+ * computes replacements, and applies them to the filesystem.
6
+ */
7
+ import * as fs from "node:fs/promises";
8
+ import * as path from "node:path";
9
+ // ---------------------------------------------------------------------------
10
+ // Parser constants
11
+ // ---------------------------------------------------------------------------
12
+ const BEGIN_PATCH_MARKER = "*** Begin Patch";
13
+ const END_PATCH_MARKER = "*** End Patch";
14
+ const ENVIRONMENT_ID_MARKER = "*** Environment ID: ";
15
+ const ADD_FILE_MARKER = "*** Add File: ";
16
+ const DELETE_FILE_MARKER = "*** Delete File: ";
17
+ const UPDATE_FILE_MARKER = "*** Update File: ";
18
+ const MOVE_TO_MARKER = "*** Move to: ";
19
+ const EOF_MARKER = "*** End of File";
20
+ const CHANGE_CONTEXT_MARKER = "@@ ";
21
+ const EMPTY_CHANGE_CONTEXT_MARKER = "@@";
22
+ export class ParseError extends Error {
23
+ kind;
24
+ lineNumber;
25
+ constructor(kind, message, lineNumber) {
26
+ super(message);
27
+ this.kind = kind;
28
+ this.lineNumber = lineNumber;
29
+ this.name = "ParseError";
30
+ }
31
+ }
32
+ export class ComputeReplacementsError extends Error {
33
+ constructor(message) {
34
+ super(message);
35
+ this.name = "ComputeReplacementsError";
36
+ }
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // Patch parser
40
+ // ---------------------------------------------------------------------------
41
+ function checkPatchBoundariesStrict(lines) {
42
+ if (lines.length === 0) {
43
+ throw new ParseError("invalid-patch", "The first line of the patch must be '*** Begin Patch'");
44
+ }
45
+ const first = lines[0].trim();
46
+ const last = lines[lines.length - 1].trim();
47
+ if (first !== BEGIN_PATCH_MARKER) {
48
+ throw new ParseError("invalid-patch", "The first line of the patch must be '*** Begin Patch'");
49
+ }
50
+ if (last !== END_PATCH_MARKER) {
51
+ throw new ParseError("invalid-patch", "The last line of the patch must be '*** End Patch'");
52
+ }
53
+ return { patchLines: lines, hunkLines: lines.slice(1, -1) };
54
+ }
55
+ function checkPatchBoundariesLenient(lines) {
56
+ try {
57
+ return checkPatchBoundariesStrict(lines);
58
+ }
59
+ catch (strictErr) {
60
+ if (lines.length >= 4) {
61
+ const first = lines[0].trim();
62
+ const last = lines[lines.length - 1].trim();
63
+ if ((first === "<<EOF" || first === "<<'EOF'" || first === '<<"EOF"') &&
64
+ last.endsWith("EOF")) {
65
+ const inner = lines.slice(1, -1);
66
+ try {
67
+ return checkPatchBoundariesStrict(inner);
68
+ }
69
+ catch {
70
+ /* fall through to return original error */
71
+ }
72
+ }
73
+ }
74
+ throw strictErr;
75
+ }
76
+ }
77
+ function parseEnvironmentIdPreamble(lines) {
78
+ if (lines.length === 0) {
79
+ return { remaining: lines, lineNumber: 2 };
80
+ }
81
+ const first = lines[0].trimStart();
82
+ if (first.startsWith(ENVIRONMENT_ID_MARKER)) {
83
+ const id = first.slice(ENVIRONMENT_ID_MARKER.length).trim();
84
+ if (id === "") {
85
+ throw new ParseError("invalid-patch", "apply_patch environment_id cannot be empty");
86
+ }
87
+ return { environmentId: id, remaining: lines.slice(1), lineNumber: 3 };
88
+ }
89
+ return { remaining: lines, lineNumber: 2 };
90
+ }
91
+ function parseUpdateFileChunk(lines, lineNumber, allowMissingContext) {
92
+ if (lines.length === 0) {
93
+ throw new ParseError("invalid-hunk", "Update hunk does not contain any lines", lineNumber);
94
+ }
95
+ let changeContext;
96
+ let startIndex = 0;
97
+ if (lines[0] === EMPTY_CHANGE_CONTEXT_MARKER) {
98
+ changeContext = undefined;
99
+ startIndex = 1;
100
+ }
101
+ else if (lines[0].startsWith(CHANGE_CONTEXT_MARKER)) {
102
+ changeContext = lines[0].slice(CHANGE_CONTEXT_MARKER.length);
103
+ startIndex = 1;
104
+ }
105
+ else {
106
+ if (!allowMissingContext) {
107
+ throw new ParseError("invalid-hunk", `Expected update hunk to start with a @@ context marker, got: '${lines[0]}'`, lineNumber);
108
+ }
109
+ changeContext = undefined;
110
+ startIndex = 0;
111
+ }
112
+ if (startIndex >= lines.length) {
113
+ throw new ParseError("invalid-hunk", "Update hunk does not contain any lines", lineNumber + 1);
114
+ }
115
+ const oldLines = [];
116
+ const newLines = [];
117
+ let isEndOfFile = false;
118
+ let parsedLines = 0;
119
+ for (let i = startIndex; i < lines.length; i++) {
120
+ const line = lines[i];
121
+ if (line === EOF_MARKER) {
122
+ if (parsedLines === 0) {
123
+ throw new ParseError("invalid-hunk", "Update hunk does not contain any lines", lineNumber + 1);
124
+ }
125
+ isEndOfFile = true;
126
+ parsedLines += 1;
127
+ break;
128
+ }
129
+ const firstChar = line.charAt(0);
130
+ if (firstChar === "") {
131
+ oldLines.push("");
132
+ newLines.push("");
133
+ }
134
+ else if (firstChar === " ") {
135
+ oldLines.push(line.slice(1));
136
+ newLines.push(line.slice(1));
137
+ }
138
+ else if (firstChar === "+") {
139
+ newLines.push(line.slice(1));
140
+ }
141
+ else if (firstChar === "-") {
142
+ oldLines.push(line.slice(1));
143
+ }
144
+ else {
145
+ if (parsedLines === 0) {
146
+ throw new ParseError("invalid-hunk", `Unexpected line found in update hunk: '${line}'. Every line should start with ' ' (context line), '+' (added line), or '-' (removed line)`, lineNumber + 1);
147
+ }
148
+ // Assume start of next hunk.
149
+ break;
150
+ }
151
+ parsedLines += 1;
152
+ }
153
+ return {
154
+ chunk: { changeContext, oldLines, newLines, isEndOfFile },
155
+ parsedLines: parsedLines + startIndex,
156
+ };
157
+ }
158
+ function parseOneHunk(lines, lineNumber) {
159
+ const firstLine = lines[0].trim();
160
+ if (firstLine.startsWith(ADD_FILE_MARKER)) {
161
+ const filePath = firstLine.slice(ADD_FILE_MARKER.length);
162
+ let contents = "";
163
+ let parsedLines = 1;
164
+ for (let i = 1; i < lines.length; i++) {
165
+ const line = lines[i];
166
+ if (line.startsWith("+")) {
167
+ contents += line.slice(1) + "\n";
168
+ parsedLines += 1;
169
+ }
170
+ else {
171
+ break;
172
+ }
173
+ }
174
+ return { hunk: { type: "add", path: filePath, contents }, parsedLines };
175
+ }
176
+ if (firstLine.startsWith(DELETE_FILE_MARKER)) {
177
+ const filePath = firstLine.slice(DELETE_FILE_MARKER.length);
178
+ return { hunk: { type: "delete", path: filePath }, parsedLines: 1 };
179
+ }
180
+ if (firstLine.startsWith(UPDATE_FILE_MARKER)) {
181
+ const filePath = firstLine.slice(UPDATE_FILE_MARKER.length);
182
+ let remaining = lines.slice(1);
183
+ let parsedLines = 1;
184
+ let movePath;
185
+ if (remaining.length > 0 && remaining[0].startsWith(MOVE_TO_MARKER)) {
186
+ movePath = remaining[0].slice(MOVE_TO_MARKER.length);
187
+ remaining = remaining.slice(1);
188
+ parsedLines += 1;
189
+ }
190
+ const chunks = [];
191
+ while (remaining.length > 0) {
192
+ if (remaining[0].trim() === "") {
193
+ parsedLines += 1;
194
+ remaining = remaining.slice(1);
195
+ continue;
196
+ }
197
+ if (remaining[0].startsWith("*")) {
198
+ break;
199
+ }
200
+ const { chunk, parsedLines: chunkLines } = parseUpdateFileChunk(remaining, lineNumber + parsedLines, chunks.length === 0);
201
+ chunks.push(chunk);
202
+ parsedLines += chunkLines;
203
+ remaining = remaining.slice(chunkLines);
204
+ }
205
+ if (chunks.length === 0) {
206
+ throw new ParseError("invalid-hunk", `Update file hunk for path '${filePath}' is empty`, lineNumber);
207
+ }
208
+ return { hunk: { type: "update", path: filePath, movePath, chunks }, parsedLines };
209
+ }
210
+ throw new ParseError("invalid-hunk", `'${firstLine}' is not a valid hunk header. Valid hunk headers: '*** Add File: {path}', '*** Delete File: {path}', '*** Update File: {path}'`, lineNumber);
211
+ }
212
+ export function parsePatch(patch) {
213
+ const trimmed = patch.trim();
214
+ const lines = trimmed.split("\n");
215
+ const { patchLines, hunkLines } = checkPatchBoundariesLenient(lines);
216
+ const { environmentId, remaining, lineNumber } = parseEnvironmentIdPreamble(hunkLines);
217
+ let remainingLines = remaining;
218
+ let currentLine = lineNumber;
219
+ const hunks = [];
220
+ while (remainingLines.length > 0) {
221
+ const { hunk, parsedLines } = parseOneHunk(remainingLines, currentLine);
222
+ hunks.push(hunk);
223
+ currentLine += parsedLines;
224
+ remainingLines = remainingLines.slice(parsedLines);
225
+ }
226
+ return {
227
+ patch: patchLines.join("\n"),
228
+ hunks,
229
+ environmentId,
230
+ };
231
+ }
232
+ // ---------------------------------------------------------------------------
233
+ // seek_sequence — 4-stage fuzzy matching
234
+ // ---------------------------------------------------------------------------
235
+ export function seekSequence(lines, pattern, start, eof) {
236
+ if (pattern.length === 0) {
237
+ return start;
238
+ }
239
+ if (pattern.length > lines.length) {
240
+ return undefined;
241
+ }
242
+ const searchStart = eof && lines.length >= pattern.length ? lines.length - pattern.length : start;
243
+ // Stage 1: exact match
244
+ for (let i = searchStart; i <= lines.length - pattern.length; i++) {
245
+ let ok = true;
246
+ for (let j = 0; j < pattern.length; j++) {
247
+ if (lines[i + j] !== pattern[j]) {
248
+ ok = false;
249
+ break;
250
+ }
251
+ }
252
+ if (ok)
253
+ return i;
254
+ }
255
+ // Stage 2: rstrip match (ignore trailing whitespace)
256
+ for (let i = searchStart; i <= lines.length - pattern.length; i++) {
257
+ let ok = true;
258
+ for (let j = 0; j < pattern.length; j++) {
259
+ if (lines[i + j].trimEnd() !== pattern[j].trimEnd()) {
260
+ ok = false;
261
+ break;
262
+ }
263
+ }
264
+ if (ok)
265
+ return i;
266
+ }
267
+ // Stage 3: trim match (ignore leading and trailing whitespace)
268
+ for (let i = searchStart; i <= lines.length - pattern.length; i++) {
269
+ let ok = true;
270
+ for (let j = 0; j < pattern.length; j++) {
271
+ if (lines[i + j].trim() !== pattern[j].trim()) {
272
+ ok = false;
273
+ break;
274
+ }
275
+ }
276
+ if (ok)
277
+ return i;
278
+ }
279
+ // Stage 4: Unicode normalisation
280
+ function normalise(s) {
281
+ return s
282
+ .trim()
283
+ .split("")
284
+ .map((c) => {
285
+ switch (c) {
286
+ // Dashes / hyphens → ASCII '-'
287
+ case "\u2010":
288
+ case "\u2011":
289
+ case "\u2012":
290
+ case "\u2013":
291
+ case "\u2014":
292
+ case "\u2015":
293
+ case "\u2212":
294
+ return "-";
295
+ // Fancy single quotes → '\''
296
+ case "\u2018":
297
+ case "\u2019":
298
+ case "\u201A":
299
+ case "\u201B":
300
+ return "'";
301
+ // Fancy double quotes → '"'
302
+ case "\u201C":
303
+ case "\u201D":
304
+ case "\u201E":
305
+ case "\u201F":
306
+ return '"';
307
+ // Odd spaces → normal space
308
+ case "\u00A0":
309
+ case "\u2002":
310
+ case "\u2003":
311
+ case "\u2004":
312
+ case "\u2005":
313
+ case "\u2006":
314
+ case "\u2007":
315
+ case "\u2008":
316
+ case "\u2009":
317
+ case "\u200A":
318
+ case "\u202F":
319
+ case "\u205F":
320
+ case "\u3000":
321
+ return " ";
322
+ default:
323
+ return c;
324
+ }
325
+ })
326
+ .join("");
327
+ }
328
+ for (let i = searchStart; i <= lines.length - pattern.length; i++) {
329
+ let ok = true;
330
+ for (let j = 0; j < pattern.length; j++) {
331
+ if (normalise(lines[i + j]) !== normalise(pattern[j])) {
332
+ ok = false;
333
+ break;
334
+ }
335
+ }
336
+ if (ok)
337
+ return i;
338
+ }
339
+ return undefined;
340
+ }
341
+ // ---------------------------------------------------------------------------
342
+ // compute_replacements + apply_replacements
343
+ // ---------------------------------------------------------------------------
344
+ export function computeReplacements(originalLines, filePath, chunks) {
345
+ const replacements = [];
346
+ let lineIndex = 0;
347
+ for (const chunk of chunks) {
348
+ if (chunk.changeContext) {
349
+ const idx = seekSequence(originalLines, [chunk.changeContext], lineIndex, false);
350
+ if (idx === undefined) {
351
+ throw new ComputeReplacementsError(`Failed to find context '${chunk.changeContext}' in ${filePath}`);
352
+ }
353
+ lineIndex = idx + 1;
354
+ }
355
+ if (chunk.oldLines.length === 0) {
356
+ // Pure addition — insert at end (or just before the trailing empty line).
357
+ const insertionIdx = originalLines.length > 0 && originalLines[originalLines.length - 1] === ""
358
+ ? originalLines.length - 1
359
+ : originalLines.length;
360
+ replacements.push({ startIdx: insertionIdx, oldLen: 0, newLines: chunk.newLines });
361
+ continue;
362
+ }
363
+ let pattern = chunk.oldLines;
364
+ let found = seekSequence(originalLines, pattern, lineIndex, chunk.isEndOfFile);
365
+ let newSlice = chunk.newLines;
366
+ if (found === undefined && pattern.length > 0 && pattern[pattern.length - 1] === "") {
367
+ // Retry without the trailing empty sentinel.
368
+ pattern = pattern.slice(0, -1);
369
+ if (newSlice.length > 0 && newSlice[newSlice.length - 1] === "") {
370
+ newSlice = newSlice.slice(0, -1);
371
+ }
372
+ found = seekSequence(originalLines, pattern, lineIndex, chunk.isEndOfFile);
373
+ }
374
+ if (found === undefined) {
375
+ throw new ComputeReplacementsError(`Failed to find expected lines in ${filePath}:\n${chunk.oldLines.join("\n")}`);
376
+ }
377
+ replacements.push({ startIdx: found, oldLen: pattern.length, newLines: newSlice });
378
+ lineIndex = found + pattern.length;
379
+ }
380
+ replacements.sort((a, b) => a.startIdx - b.startIdx);
381
+ return replacements;
382
+ }
383
+ export function applyReplacements(lines, replacements) {
384
+ const result = [...lines];
385
+ for (let i = replacements.length - 1; i >= 0; i--) {
386
+ const { startIdx, oldLen, newLines } = replacements[i];
387
+ result.splice(startIdx, oldLen, ...newLines);
388
+ }
389
+ return result;
390
+ }
391
+ function deriveNewContentsFromChunks(originalContent, chunks, filePath) {
392
+ let originalLines = originalContent.split("\n").map((l) => l);
393
+ // Drop the trailing empty element that results from the final newline
394
+ // so that line counts match the behaviour of standard diff.
395
+ if (originalLines.length > 0 && originalLines[originalLines.length - 1] === "") {
396
+ originalLines.pop();
397
+ }
398
+ const replacements = computeReplacements(originalLines, filePath, chunks);
399
+ let newLines = applyReplacements(originalLines, replacements);
400
+ // Ensure file terminates with a newline.
401
+ if (newLines.length === 0 || newLines[newLines.length - 1] !== "") {
402
+ newLines.push("");
403
+ }
404
+ return newLines.join("\n");
405
+ }
406
+ export async function applyPatch(patchText, cwd) {
407
+ const args = parsePatch(patchText);
408
+ const added = [];
409
+ const modified = [];
410
+ const deleted = [];
411
+ let exact = true;
412
+ for (const hunk of args.hunks) {
413
+ switch (hunk.type) {
414
+ case "add": {
415
+ const targetPath = path.resolve(cwd, hunk.path);
416
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
417
+ await fs.writeFile(targetPath, hunk.contents, "utf-8");
418
+ added.push(hunk.path);
419
+ break;
420
+ }
421
+ case "delete": {
422
+ const targetPath = path.resolve(cwd, hunk.path);
423
+ try {
424
+ await fs.unlink(targetPath);
425
+ }
426
+ catch (err) {
427
+ if (err.code === "ENOENT") {
428
+ exact = false;
429
+ }
430
+ else {
431
+ throw err;
432
+ }
433
+ }
434
+ deleted.push(hunk.path);
435
+ break;
436
+ }
437
+ case "update": {
438
+ const targetPath = path.resolve(cwd, hunk.path);
439
+ let originalContent;
440
+ try {
441
+ originalContent = await fs.readFile(targetPath, "utf-8");
442
+ }
443
+ catch (err) {
444
+ if (err.code === "ENOENT") {
445
+ throw new Error(`File not found: ${hunk.path}`);
446
+ }
447
+ throw err;
448
+ }
449
+ const newContent = deriveNewContentsFromChunks(originalContent, hunk.chunks, hunk.path);
450
+ if (hunk.movePath) {
451
+ const destPath = path.resolve(cwd, hunk.movePath);
452
+ await fs.mkdir(path.dirname(destPath), { recursive: true });
453
+ await fs.writeFile(destPath, newContent, "utf-8");
454
+ try {
455
+ await fs.unlink(targetPath);
456
+ }
457
+ catch (err) {
458
+ if (err.code === "ENOENT") {
459
+ exact = false;
460
+ }
461
+ else {
462
+ throw err;
463
+ }
464
+ }
465
+ modified.push(hunk.movePath);
466
+ }
467
+ else {
468
+ await fs.writeFile(targetPath, newContent, "utf-8");
469
+ modified.push(hunk.path);
470
+ }
471
+ break;
472
+ }
473
+ }
474
+ }
475
+ return { affected: { added, modified, deleted }, exact };
476
+ }
477
+ //# sourceMappingURL=apply-patch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-patch.js","sourceRoot":"","sources":["../../src/batch/apply-patch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAC7C,MAAM,gBAAgB,GAAG,eAAe,CAAC;AACzC,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AACrD,MAAM,eAAe,GAAG,gBAAgB,CAAC;AACzC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAC/C,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAC/C,MAAM,cAAc,GAAG,eAAe,CAAC;AACvC,MAAM,UAAU,GAAG,iBAAiB,CAAC;AACrC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AACpC,MAAM,2BAA2B,GAAG,IAAI,CAAC;AAwBzC,MAAM,OAAO,UAAW,SAAQ,KAAK;IAEnB;IAEA;IAHjB,YACiB,IAAsC,EACtD,OAAe,EACC,UAAmB;QAEnC,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAkC;QAEtC,eAAU,GAAV,UAAU,CAAS;QAGnC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC1B,CAAC;CACD;AAED,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IAClD,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACxC,CAAC;CACD;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,SAAS,0BAA0B,CAAC,KAAe;IAClD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC,eAAe,EAAE,uDAAuD,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,IAAI,KAAK,KAAK,kBAAkB,EAAE,CAAC;QAClC,MAAM,IAAI,UAAU,CAAC,eAAe,EAAE,uDAAuD,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAC/B,MAAM,IAAI,UAAU,CAAC,eAAe,EAAE,oDAAoD,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAe;IACnD,IAAI,CAAC;QACJ,OAAO,0BAA0B,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,SAAS,EAAE,CAAC;QACpB,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,IACC,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,CAAC;gBACjE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EACnB,CAAC;gBACF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACjC,IAAI,CAAC;oBACJ,OAAO,0BAA0B,CAAC,KAAK,CAAC,CAAC;gBAC1C,CAAC;gBAAC,MAAM,CAAC;oBACR,2CAA2C;gBAC5C,CAAC;YACF,CAAC;QACF,CAAC;QACD,MAAM,SAAS,CAAC;IACjB,CAAC;AACF,CAAC;AAED,SAAS,0BAA0B,CAClC,KAAe;IAEf,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACnC,IAAI,KAAK,CAAC,UAAU,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAC7C,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5D,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,UAAU,CAAC,eAAe,EAAE,4CAA4C,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IACxE,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,oBAAoB,CAC5B,KAAe,EACf,UAAkB,EAClB,mBAA4B;IAE5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC,cAAc,EAAE,wCAAwC,EAAE,UAAU,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,aAAiC,CAAC;IACtC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,2BAA2B,EAAE,CAAC;QAC9C,aAAa,GAAG,SAAS,CAAC;QAC1B,UAAU,GAAG,CAAC,CAAC;IAChB,CAAC;SAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACvD,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC7D,UAAU,GAAG,CAAC,CAAC;IAChB,CAAC;SAAM,CAAC;QACP,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1B,MAAM,IAAI,UAAU,CACnB,cAAc,EACd,iEAAiE,KAAK,CAAC,CAAC,CAAC,GAAG,EAC5E,UAAU,CACV,CAAC;QACH,CAAC;QACD,aAAa,GAAG,SAAS,CAAC;QAC1B,UAAU,GAAG,CAAC,CAAC;IAChB,CAAC;IAED,IAAI,UAAU,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,UAAU,CAAC,cAAc,EAAE,wCAAwC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACzB,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,UAAU,CACnB,cAAc,EACd,wCAAwC,EACxC,UAAU,GAAG,CAAC,CACd,CAAC;YACH,CAAC;YACD,WAAW,GAAG,IAAI,CAAC;YACnB,WAAW,IAAI,CAAC,CAAC;YACjB,MAAM;QACP,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;aAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACP,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,UAAU,CACnB,cAAc,EACd,0CAA0C,IAAI,6FAA6F,EAC3I,UAAU,GAAG,CAAC,CACd,CAAC;YACH,CAAC;YACD,6BAA6B;YAC7B,MAAM;QACP,CAAC;QACD,WAAW,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,OAAO;QACN,KAAK,EAAE,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE;QACzD,WAAW,EAAE,WAAW,GAAG,UAAU;KACrC,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAe,EAAE,UAAkB;IACxD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAElC,IAAI,SAAS,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;gBACjC,WAAW,IAAI,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACP,MAAM;YACP,CAAC;QACF,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;IAED,IAAI,SAAS,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC5D,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IACrE,CAAC;IAED,IAAI,SAAS,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,IAAI,QAA4B,CAAC;QACjC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YACrE,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACrD,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/B,WAAW,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAChC,WAAW,IAAI,CAAC,CAAC;gBACjB,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC/B,SAAS;YACV,CAAC;YACD,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,MAAM;YACP,CAAC;YAED,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,oBAAoB,CAC9D,SAAS,EACT,UAAU,GAAG,WAAW,EACxB,MAAM,CAAC,MAAM,KAAK,CAAC,CACnB,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,WAAW,IAAI,UAAU,CAAC;YAC1B,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,UAAU,CACnB,cAAc,EACd,8BAA8B,QAAQ,YAAY,EAClD,UAAU,CACV,CAAC;QACH,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC;IACpF,CAAC;IAED,MAAM,IAAI,UAAU,CACnB,cAAc,EACd,IAAI,SAAS,gIAAgI,EAC7I,UAAU,CACV,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IAErE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,0BAA0B,CAAC,SAAS,CAAC,CAAC;IACvF,IAAI,cAAc,GAAG,SAAS,CAAC;IAC/B,IAAI,WAAW,GAAG,UAAU,CAAC;IAC7B,MAAM,KAAK,GAAW,EAAE,CAAC;IAEzB,OAAO,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QACxE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,WAAW,IAAI,WAAW,CAAC;QAC3B,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpD,CAAC;IAED,OAAO;QACN,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,KAAK;QACL,aAAa;KACb,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,yCAAyC;AACzC,8EAA8E;AAE9E,MAAM,UAAU,YAAY,CAC3B,KAAe,EACf,OAAiB,EACjB,KAAa,EACb,GAAY;IAEZ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAElG,uBAAuB;IACvB,KAAK,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnE,IAAI,EAAE,GAAG,IAAI,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjC,EAAE,GAAG,KAAK,CAAC;gBACX,MAAM;YACP,CAAC;QACF,CAAC;QACD,IAAI,EAAE;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IAED,qDAAqD;IACrD,KAAK,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnE,IAAI,EAAE,GAAG,IAAI,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;gBACrD,EAAE,GAAG,KAAK,CAAC;gBACX,MAAM;YACP,CAAC;QACF,CAAC;QACD,IAAI,EAAE;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IAED,+DAA+D;IAC/D,KAAK,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnE,IAAI,EAAE,GAAG,IAAI,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC/C,EAAE,GAAG,KAAK,CAAC;gBACX,MAAM;YACP,CAAC;QACF,CAAC;QACD,IAAI,EAAE;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IAED,iCAAiC;IACjC,SAAS,SAAS,CAAC,CAAS;QAC3B,OAAO,CAAC;aACN,IAAI,EAAE;aACN,KAAK,CAAC,EAAE,CAAC;aACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACV,QAAQ,CAAC,EAAE,CAAC;gBACX,+BAA+B;gBAC/B,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ;oBACZ,OAAO,GAAG,CAAC;gBACZ,6BAA6B;gBAC7B,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ;oBACZ,OAAO,GAAG,CAAC;gBACZ,4BAA4B;gBAC5B,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ;oBACZ,OAAO,GAAG,CAAC;gBACZ,4BAA4B;gBAC5B,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ;oBACZ,OAAO,GAAG,CAAC;gBACZ;oBACC,OAAO,CAAC,CAAC;YACV,CAAC;QACF,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnE,IAAI,EAAE,GAAG,IAAI,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvD,EAAE,GAAG,KAAK,CAAC;gBACX,MAAM;YACP,CAAC;QACF,CAAC;QACD,IAAI,EAAE;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,4CAA4C;AAC5C,8EAA8E;AAE9E,MAAM,UAAU,mBAAmB,CAClC,aAAuB,EACvB,QAAgB,EAChB,MAAyB;IAEzB,MAAM,YAAY,GAAoE,EAAE,CAAC;IACzF,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACjF,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,wBAAwB,CACjC,2BAA2B,KAAK,CAAC,aAAa,QAAQ,QAAQ,EAAE,CAChE,CAAC;YACH,CAAC;YACD,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC;QACrB,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,0EAA0E;YAC1E,MAAM,YAAY,GACjB,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE;gBACzE,CAAC,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;gBAC1B,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YACnF,SAAS;QACV,CAAC;QAED,IAAI,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC7B,IAAI,KAAK,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/E,IAAI,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAE9B,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YACrF,6CAA6C;YAC7C,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;gBACjE,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC;YACD,KAAK,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,wBAAwB,CACjC,oCAAoC,QAAQ,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7E,CAAC;QACH,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnF,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;IACpC,CAAC;IAED,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IACrD,OAAO,YAAY,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAChC,KAAe,EACf,YAA6E;IAE7E,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,2BAA2B,CACnC,eAAuB,EACvB,MAAyB,EACzB,QAAgB;IAEhB,IAAI,aAAa,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAE9D,sEAAsE;IACtE,4DAA4D;IAC5D,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QAChF,aAAa,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1E,IAAI,QAAQ,GAAG,iBAAiB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAE9D,yCAAyC;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAYD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC/B,SAAiB,EACjB,GAAW;IAEX,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,KAAK,GAAG,IAAI,CAAC;IAEjB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,KAAK,CAAC,CAAC,CAAC;gBACZ,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9D,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACvD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtB,MAAM;YACP,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,CAAC;oBACJ,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC7B,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBACnB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC3B,KAAK,GAAG,KAAK,CAAC;oBACf,CAAC;yBAAM,CAAC;wBACP,MAAM,GAAG,CAAC;oBACX,CAAC;gBACF,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxB,MAAM;YACP,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,eAAuB,CAAC;gBAC5B,IAAI,CAAC;oBACJ,eAAe,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAC1D,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBACnB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC3B,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBACjD,CAAC;oBACD,MAAM,GAAG,CAAC;gBACX,CAAC;gBACD,MAAM,UAAU,GAAG,2BAA2B,CAAC,eAAe,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAExF,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAClD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC5D,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;oBAClD,IAAI,CAAC;wBACJ,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;oBAC7B,CAAC;oBAAC,OAAO,GAAQ,EAAE,CAAC;wBACnB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BAC3B,KAAK,GAAG,KAAK,CAAC;wBACf,CAAC;6BAAM,CAAC;4BACP,MAAM,GAAG,CAAC;wBACX,CAAC;oBACF,CAAC;oBACD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC9B,CAAC;qBAAM,CAAC;oBACP,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;oBACpD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;gBACD,MAAM;YACP,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC;AAC1D,CAAC"}
@@ -39,6 +39,16 @@ export declare class BashProcessTracker {
39
39
  abortAll(): void;
40
40
  }
41
41
  /** Generate a short random ID for bash ops that don't provide one. */
42
+ /**
43
+ * Run a single bash command with output truncation and optional timeout.
44
+ * Returns a promise that resolves with stdout, stderr, and exitCode.
45
+ * Uses execFile (synchronous completion) with truncateBashOutput applied.
46
+ */
47
+ export declare function runBashWithLimits(command: string, cwd: string, timeoutMs?: number, signal?: AbortSignal): Promise<{
48
+ stdout: string;
49
+ stderr: string;
50
+ exitCode: number;
51
+ }>;
42
52
  export declare function generateBashId(): string;
43
53
  /**
44
54
  * Truncate bash stdout/stderr to prevent oversized tool results.
@@ -80,12 +90,6 @@ export declare function createBatchBashPollTool(tracker: BashProcessTracker): {
80
90
  details: {
81
91
  results: PendingBashResult[];
82
92
  };
83
- } | {
84
- content: {
85
- type: string;
86
- text: string;
87
- }[];
88
- isError: boolean;
89
93
  }>;
90
94
  };
91
95
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"batch-bash.d.ts","sourceRoot":"","sources":["../../src/batch/batch-bash.ts"],"names":[],"mappings":"AAkBA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAKtB,MAAM,gBAAgB,CAAC;AAgBxB,UAAU,iBAAiB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,SAAS,CAAwC;IAEzD,sFAAsF;IACtF,MAAM,CACL,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,GAClB,IAAI;IAwGP,2CAA2C;IAC3C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI9B,0DAA0D;IAC1D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAOlC,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIjD,iFAAiF;IACjF,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIxD,mFAAmF;IACnF,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAMvD,+CAA+C;IAC/C,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI5C,wCAAwC;IACxC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIjC,qCAAqC;IACrC,OAAO,CAAC,SAAS;IAWjB,6CAA6C;IAC7C,QAAQ,IAAI,IAAI;CAKhB;AAWD,sEAAsE;AACtE,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAA8B,EACxC,QAAQ,GAAE,MAA8B,GACtC,MAAM,CAiCR;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASrF;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC5D,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,kBAAkB,EAC3B,MAAM,CAAC,EAAE,WAAW,EACpB,aAAa,GAAE,MAA6B,GAC1C,OAAO,CAAC,YAAY,EAAE,CAAC,CAqDzB;AAoCD,uCAAuC;AACvC,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,MAAM,EAAE,EACb,OAAO,EAAE,kBAAkB,GACzB,iBAAiB,EAAE,CAgCrB;AAaD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB;;;;;;;4BAgBzC,OAAO,GAAG,OAAO;yBAS3B,MAAM,SACZ,OAAO,YACJ,WAAW,cACT,OAAO;;;;;;;;;;;;;;;EAqCrB"}
1
+ {"version":3,"file":"batch-bash.d.ts","sourceRoot":"","sources":["../../src/batch/batch-bash.ts"],"names":[],"mappings":"AAyBA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAKtB,MAAM,gBAAgB,CAAC;AAgBxB,UAAU,iBAAiB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,SAAS,CAAwC;IAEzD,sFAAsF;IACtF,MAAM,CACL,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,WAAW,GAClB,IAAI;IAwGP,2CAA2C;IAC3C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI9B,0DAA0D;IAC1D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAOlC,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIjD,iFAAiF;IACjF,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIxD,mFAAmF;IACnF,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAMvD,+CAA+C;IAC/C,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI5C,wCAAwC;IACxC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIjC,qCAAqC;IACrC,OAAO,CAAC,SAAS;IAWjB,6CAA6C;IAC7C,QAAQ,IAAI,IAAI;CAKhB;AAWD,sEAAsE;AACtE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAyB/D;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAA8B,EACxC,QAAQ,GAAE,MAA8B,GACtC,MAAM,CA0CR;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASrF;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,KAAK,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC5D,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,kBAAkB,EAC3B,MAAM,CAAC,EAAE,WAAW,EACpB,aAAa,GAAE,MAA6B,GAC1C,OAAO,CAAC,YAAY,EAAE,CAAC,CAqDzB;AAoCD,uCAAuC;AACvC,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,MAAM,EAAE,EACb,OAAO,EAAE,kBAAkB,GACzB,iBAAiB,EAAE,CAgCrB;AAaD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB;;;;;;;4BAgBzC,OAAO,GAAG,OAAO;yBAS3B,MAAM,SACZ,OAAO,YACJ,WAAW,cACT,OAAO;;;;;;;;;EAkCrB"}
@@ -1,4 +1,4 @@
1
- import { appendStrategicHintOnce } from "../steering/tool-utils.js";
1
+ import { appendDirectiveOnce } from "../steering/tool-utils.js";
2
2
  import { compressOutput } from "./shell-compress.js";
3
3
  /**
4
4
  * batch bash -- parallel bash execution and polling.
@@ -11,8 +11,15 @@ import { compressOutput } from "./shell-compress.js";
11
11
  * wait time before the batch tool returns partial results. Commands that
12
12
  * haven't finished continue running in the background and can be polled
13
13
  * via the `batch_bash_poll` tool.
14
+ *
15
+ * Why not `createLocalBashOperations` from `@earendil-works/pi-coding-agent`?
16
+ * That helper is a simple exec wrapper (returns a promise when the process exits).
17
+ * Our tracker needs background execution + polling: processes must outlive the
18
+ * soft timeout and be queried later via `batch_bash_poll`. We therefore use raw
19
+ * `node:child_process.spawn` directly to retain full control over detached mode,
20
+ * per-process AbortControllers, and background lifecycle.
14
21
  */
15
- import { spawn } from "node:child_process";
22
+ import { spawn, execFile } from "node:child_process";
16
23
  import { Type } from "@sinclair/typebox";
17
24
  import { BASH_SOFT_TIMEOUT_MS, BASH_POLL_TAIL_LINES, MAX_BASH_OUTPUT_BYTES, MAX_BASH_OUTPUT_LINES, } from "./constants.js";
18
25
  import { classifyDuration } from "../tools/timed-bash.js";
@@ -182,6 +189,39 @@ function tailLines(text, n) {
182
189
  return lines.slice(-n).join("\n");
183
190
  }
184
191
  /** Generate a short random ID for bash ops that don't provide one. */
192
+ /**
193
+ * Run a single bash command with output truncation and optional timeout.
194
+ * Returns a promise that resolves with stdout, stderr, and exitCode.
195
+ * Uses execFile (synchronous completion) with truncateBashOutput applied.
196
+ */
197
+ export function runBashWithLimits(command, cwd, timeoutMs, signal) {
198
+ return new Promise((resolve) => {
199
+ const child = execFile("bash", ["-c", command], { cwd, timeout: timeoutMs }, (error, stdout, stderr) => {
200
+ const out = truncateBashOutput(stdout);
201
+ const err = truncateBashOutput(stderr);
202
+ if (error) {
203
+ resolve({ stdout: out, stderr: err, exitCode: error.code ?? 1 });
204
+ }
205
+ else {
206
+ resolve({ stdout: out, stderr: err, exitCode: 0 });
207
+ }
208
+ });
209
+ child.stdout?.setEncoding("utf-8");
210
+ child.stderr?.setEncoding("utf-8");
211
+ if (signal) {
212
+ const onAbort = () => {
213
+ child.kill("SIGTERM");
214
+ resolve({ stdout: "", stderr: "[aborted]", exitCode: -1 });
215
+ };
216
+ if (signal.aborted) {
217
+ onAbort();
218
+ }
219
+ else {
220
+ signal.addEventListener("abort", onAbort, { once: true });
221
+ }
222
+ }
223
+ });
224
+ }
185
225
  export function generateBashId() {
186
226
  return Math.random().toString(36).slice(2, 10);
187
227
  }
@@ -205,14 +245,25 @@ export function truncateBashOutput(text, maxBytes = MAX_BASH_OUTPUT_BYTES, maxLi
205
245
  const resultBytes = Buffer.byteLength(result, "utf-8");
206
246
  if (resultBytes > maxBytes) {
207
247
  const buf = Buffer.from(result, "utf-8");
208
- // Find last newline before maxBytes
248
+ // Find last newline before maxBytes, never cutting inside a multi-byte UTF-8 character
209
249
  let cutAt = maxBytes;
210
- while (cutAt > 0 && buf[cutAt] !== 0x0a) {
250
+ while (cutAt > 0) {
251
+ // Skip UTF-8 continuation bytes so we land on a character boundary
252
+ while (cutAt > 0 && (buf[cutAt] & 0xc0) === 0x80) {
253
+ cutAt--;
254
+ }
255
+ if (cutAt <= 0)
256
+ break;
257
+ if (buf[cutAt] === 0x0a)
258
+ break;
211
259
  cutAt--;
212
260
  }
213
261
  if (cutAt <= 0) {
214
- // No newline found within safe range; force cut at maxBytes
262
+ // No newline found within safe range; force cut at maxBytes aligned to char boundary
215
263
  cutAt = maxBytes;
264
+ while (cutAt > 0 && (buf[cutAt] & 0xc0) === 0x80) {
265
+ cutAt--;
266
+ }
216
267
  }
217
268
  result = buf.slice(0, cutAt).toString("utf-8");
218
269
  result += `\n[... truncated at ${(maxBytes / 1024).toFixed(0)} KB, ${totalBytes} total ...]`;
@@ -372,7 +423,7 @@ export function createBatchBashPollTool(tracker) {
372
423
  ].join("\n"),
373
424
  promptSnippet: "Poll pending bash commands for results",
374
425
  promptGuidelines: [
375
- "Use batch_bash_poll to check on bash commands that returned pending from a batch call.",
426
+ "Use `batch_bash_poll` to check on bash commands that returned pending from a batch call.",
376
427
  "Pass the `i` (id) values from the pending results.",
377
428
  ],
378
429
  parameters: BatchBashPollParams,
@@ -389,10 +440,7 @@ export function createBatchBashPollTool(tracker) {
389
440
  const args = (input ?? {});
390
441
  const ids = Array.isArray(args.i) ? args.i : Array.isArray(args.ids) ? args.ids : [];
391
442
  if (ids.length === 0) {
392
- return {
393
- content: [{ type: "text", text: "Error: i (ids) array is required and must not be empty." }],
394
- isError: true,
395
- };
443
+ throw new Error("Error: i (ids) array is required and must not be empty.");
396
444
  }
397
445
  const results = pollBatchBashResults(ids, tracker);
398
446
  const lines = [];
@@ -418,7 +466,7 @@ export function createBatchBashPollTool(tracker) {
418
466
  content: [{ type: "text", text: lines.join("\n").trimEnd() }],
419
467
  details: { results },
420
468
  };
421
- appendStrategicHintOnce(pollResult);
469
+ appendDirectiveOnce(pollResult);
422
470
  return pollResult;
423
471
  },
424
472
  };