@ottocode/sdk 0.1.294 → 0.1.296
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -42,10 +42,30 @@ function killProcessTree(pid: number) {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export type ShellOutputMode = 'full' | 'tail';
|
|
46
|
+
|
|
47
|
+
const DEFAULT_TAIL_LINES = 100;
|
|
48
|
+
|
|
49
|
+
export function appendTailLines(
|
|
50
|
+
current: string,
|
|
51
|
+
text: string,
|
|
52
|
+
tailLines: number,
|
|
53
|
+
): string {
|
|
54
|
+
if (!text) return current;
|
|
55
|
+
const linesToKeep = Math.max(1, Math.floor(tailLines));
|
|
56
|
+
const combined = `${current}${text}`;
|
|
57
|
+
const lines = combined.split('\n');
|
|
58
|
+
const entriesToKeep = combined.endsWith('\n') ? linesToKeep + 1 : linesToKeep;
|
|
59
|
+
if (lines.length <= entriesToKeep) return combined;
|
|
60
|
+
return lines.slice(-entriesToKeep).join('\n');
|
|
61
|
+
}
|
|
62
|
+
|
|
45
63
|
type ShellResult = ToolResponse<{
|
|
46
64
|
exitCode: number;
|
|
47
65
|
stdout: string;
|
|
48
66
|
stderr: string;
|
|
67
|
+
outputMode?: ShellOutputMode;
|
|
68
|
+
tailLines?: number;
|
|
49
69
|
}>;
|
|
50
70
|
|
|
51
71
|
type ShellStreamChunk =
|
|
@@ -89,6 +109,23 @@ const shellInputSchema = z
|
|
|
89
109
|
.optional()
|
|
90
110
|
.default(300000)
|
|
91
111
|
.describe('Timeout in milliseconds (default: 300000 = 5 minutes)'),
|
|
112
|
+
outputMode: z
|
|
113
|
+
.enum(['full', 'tail'])
|
|
114
|
+
.optional()
|
|
115
|
+
.default('full')
|
|
116
|
+
.describe(
|
|
117
|
+
'Output capture mode. Use "full" for complete stdout/stderr, or "tail" to keep only the last tailLines lines and avoid huge tool results.',
|
|
118
|
+
),
|
|
119
|
+
tailLines: z
|
|
120
|
+
.number()
|
|
121
|
+
.int()
|
|
122
|
+
.min(1)
|
|
123
|
+
.max(5000)
|
|
124
|
+
.optional()
|
|
125
|
+
.default(DEFAULT_TAIL_LINES)
|
|
126
|
+
.describe(
|
|
127
|
+
'Number of trailing stdout/stderr lines to keep when outputMode is "tail"',
|
|
128
|
+
),
|
|
92
129
|
})
|
|
93
130
|
.strict();
|
|
94
131
|
|
|
@@ -112,7 +149,14 @@ export function buildShellTool(projectRoot: string): {
|
|
|
112
149
|
description: DESCRIPTION,
|
|
113
150
|
inputSchema: shellInputSchema,
|
|
114
151
|
execute(
|
|
115
|
-
{
|
|
152
|
+
{
|
|
153
|
+
cmd,
|
|
154
|
+
cwd,
|
|
155
|
+
allowNonZeroExit,
|
|
156
|
+
timeout = 300000,
|
|
157
|
+
outputMode = 'full',
|
|
158
|
+
tailLines = DEFAULT_TAIL_LINES,
|
|
159
|
+
}: ShellInput,
|
|
116
160
|
options?: { abortSignal?: AbortSignal },
|
|
117
161
|
): AsyncIterable<ShellStreamChunk> | ShellResult {
|
|
118
162
|
const abortSignal = options?.abortSignal;
|
|
@@ -128,7 +172,14 @@ export function buildShellTool(projectRoot: string): {
|
|
|
128
172
|
const shellExecutor = shellExecutorContext.getStore();
|
|
129
173
|
if (shellExecutor) {
|
|
130
174
|
return shellExecutor(
|
|
131
|
-
{
|
|
175
|
+
{
|
|
176
|
+
cmd: finalCmd,
|
|
177
|
+
cwd: absCwd,
|
|
178
|
+
allowNonZeroExit,
|
|
179
|
+
timeout,
|
|
180
|
+
outputMode,
|
|
181
|
+
tailLines,
|
|
182
|
+
},
|
|
132
183
|
options,
|
|
133
184
|
) as AsyncIterable<ShellStreamChunk> | ShellResult;
|
|
134
185
|
}
|
|
@@ -196,13 +247,19 @@ export function buildShellTool(projectRoot: string): {
|
|
|
196
247
|
|
|
197
248
|
proc.stdout?.on('data', (chunk) => {
|
|
198
249
|
const text = chunk.toString();
|
|
199
|
-
stdout
|
|
250
|
+
stdout =
|
|
251
|
+
outputMode === 'tail'
|
|
252
|
+
? appendTailLines(stdout, text, tailLines)
|
|
253
|
+
: `${stdout}${text}`;
|
|
200
254
|
pushDelta(text);
|
|
201
255
|
});
|
|
202
256
|
|
|
203
257
|
proc.stderr?.on('data', (chunk) => {
|
|
204
258
|
const text = chunk.toString();
|
|
205
|
-
stderr
|
|
259
|
+
stderr =
|
|
260
|
+
outputMode === 'tail'
|
|
261
|
+
? appendTailLines(stderr, text, tailLines)
|
|
262
|
+
: `${stderr}${text}`;
|
|
206
263
|
pushDelta(text);
|
|
207
264
|
});
|
|
208
265
|
|
|
@@ -213,6 +270,7 @@ export function buildShellTool(projectRoot: string): {
|
|
|
213
270
|
cmd,
|
|
214
271
|
stdout,
|
|
215
272
|
stderr,
|
|
273
|
+
...(outputMode === 'tail' ? { outputMode, tailLines } : {}),
|
|
216
274
|
}),
|
|
217
275
|
);
|
|
218
276
|
return;
|
|
@@ -228,6 +286,7 @@ export function buildShellTool(projectRoot: string): {
|
|
|
228
286
|
value: timeout,
|
|
229
287
|
stdout,
|
|
230
288
|
stderr,
|
|
289
|
+
...(outputMode === 'tail' ? { outputMode, tailLines } : {}),
|
|
231
290
|
suggestion: 'Increase timeout or optimize the command',
|
|
232
291
|
},
|
|
233
292
|
),
|
|
@@ -244,6 +303,7 @@ export function buildShellTool(projectRoot: string): {
|
|
|
244
303
|
stdout,
|
|
245
304
|
stderr,
|
|
246
305
|
cmd,
|
|
306
|
+
...(outputMode === 'tail' ? { outputMode, tailLines } : {}),
|
|
247
307
|
suggestion: 'Check command syntax or use allowNonZeroExit: true',
|
|
248
308
|
}),
|
|
249
309
|
);
|
|
@@ -255,6 +315,7 @@ export function buildShellTool(projectRoot: string): {
|
|
|
255
315
|
exitCode: exitCode ?? 0,
|
|
256
316
|
stdout,
|
|
257
317
|
stderr,
|
|
318
|
+
...(outputMode === 'tail' ? { outputMode, tailLines } : {}),
|
|
258
319
|
});
|
|
259
320
|
});
|
|
260
321
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
- Chain commands with `&&` to fail-fast.
|
|
10
10
|
- For long outputs, redirect to a file and `read` it back.
|
|
11
|
+
- For verbose commands like builds or tests, set `outputMode: "tail"` and optionally `tailLines` to return only the last N stdout/stderr lines in the final tool result while still streaming full output to the UI. Use `outputMode: "full"` when you need complete output in the result.
|
|
11
12
|
- For long-running non-interactive commands, set an appropriate `timeout` and ensure the command exits on its own.
|
|
12
13
|
- Batch independent checks (e.g. `git status && git diff`) in parallel tool calls rather than sequential shell chains when you need results separately.
|
|
13
14
|
- Never use `shell` with `sed`/`awk` for programmatic file editing — use the dedicated file-editing tools instead.
|