/ src / server / tools / bash / limits.ts
limits.ts
 1  export const BASH_TOOL_DEFAULT_TIMEOUT_MS = 8_000
 2  export const BASH_TOOL_MAX_TIMEOUT_MS = 30_000
 3  export const BASH_TOOL_MIN_TIMEOUT_MS = 500
 4  export const BASH_TOOL_MAX_COMMAND_CHARS = 4_000
 5  export const BASH_TOOL_MAX_OUTPUT_CHARS = 12_000
 6  export const BASH_TOOL_PREFLIGHT_MAX_SCRIPT_BYTES = 512 * 1024
 7  
 8  export function appendTruncatedText(
 9    current: string,
10    chunk: string,
11    maxChars: number,
12  ): { value: string; truncated: boolean } {
13    if (!chunk) return { value: current, truncated: false }
14    if (current.length >= maxChars) {
15      return { value: current, truncated: true }
16    }
17    const next = current + chunk
18    if (next.length <= maxChars) {
19      return { value: next, truncated: false }
20    }
21    return {
22      value: next.slice(0, maxChars),
23      truncated: true,
24    }
25  }
26  
27  export function clampBashToolTimeout(value: number | null): number {
28    if (value == null) return BASH_TOOL_DEFAULT_TIMEOUT_MS
29    return Math.max(
30      BASH_TOOL_MIN_TIMEOUT_MS,
31      Math.min(BASH_TOOL_MAX_TIMEOUT_MS, Math.round(value)),
32    )
33  }
34  
35  export function sanitizeCommandOutput(value: string): string {
36    if (!value) return ''
37    const scrubbed = value.replace(/[\p{Format}\p{Surrogate}]/gu, '')
38    if (!scrubbed) return ''
39  
40    const chunks: string[] = []
41    for (const char of scrubbed) {
42      const code = char.codePointAt(0)
43      if (code == null) continue
44      if (code === 0x09 || code === 0x0a || code === 0x0d) {
45        chunks.push(char)
46        continue
47      }
48      if (code < 0x20) continue
49      chunks.push(char)
50    }
51    return chunks.join('')
52  }