@caupulican/pi-adaptative 0.80.22 → 0.80.23

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 (74) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/cli/file-processor.d.ts.map +1 -1
  3. package/dist/cli/file-processor.js +28 -1
  4. package/dist/cli/file-processor.js.map +1 -1
  5. package/dist/core/agent-session.d.ts.map +1 -1
  6. package/dist/core/agent-session.js +10 -76
  7. package/dist/core/agent-session.js.map +1 -1
  8. package/dist/core/bash-executor.d.ts.map +1 -1
  9. package/dist/core/bash-executor.js +16 -7
  10. package/dist/core/bash-executor.js.map +1 -1
  11. package/dist/core/exec.d.ts +20 -1
  12. package/dist/core/exec.d.ts.map +1 -1
  13. package/dist/core/exec.js +52 -19
  14. package/dist/core/exec.js.map +1 -1
  15. package/dist/core/extensions/loader.d.ts +6 -0
  16. package/dist/core/extensions/loader.d.ts.map +1 -1
  17. package/dist/core/extensions/loader.js +33 -1
  18. package/dist/core/extensions/loader.js.map +1 -1
  19. package/dist/core/extensions/types.d.ts +2 -0
  20. package/dist/core/extensions/types.d.ts.map +1 -1
  21. package/dist/core/extensions/types.js.map +1 -1
  22. package/dist/core/message-retention.d.ts +26 -0
  23. package/dist/core/message-retention.d.ts.map +1 -0
  24. package/dist/core/message-retention.js +95 -0
  25. package/dist/core/message-retention.js.map +1 -0
  26. package/dist/core/package-manager.d.ts.map +1 -1
  27. package/dist/core/package-manager.js +14 -6
  28. package/dist/core/package-manager.js.map +1 -1
  29. package/dist/core/resource-loader.d.ts.map +1 -1
  30. package/dist/core/resource-loader.js +4 -1
  31. package/dist/core/resource-loader.js.map +1 -1
  32. package/dist/core/session-manager.d.ts +3 -1
  33. package/dist/core/session-manager.d.ts.map +1 -1
  34. package/dist/core/session-manager.js +45 -9
  35. package/dist/core/session-manager.js.map +1 -1
  36. package/dist/core/skills.d.ts.map +1 -1
  37. package/dist/core/skills.js +12 -0
  38. package/dist/core/skills.js.map +1 -1
  39. package/dist/core/tools/git-filter.d.ts +9 -1
  40. package/dist/core/tools/git-filter.d.ts.map +1 -1
  41. package/dist/core/tools/git-filter.js +94 -8
  42. package/dist/core/tools/git-filter.js.map +1 -1
  43. package/dist/core/tools/read.d.ts +31 -0
  44. package/dist/core/tools/read.d.ts.map +1 -1
  45. package/dist/core/tools/read.js +164 -33
  46. package/dist/core/tools/read.js.map +1 -1
  47. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  48. package/dist/modes/interactive/components/tool-execution.js +37 -4
  49. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  50. package/dist/modes/interactive/interactive-mode.d.ts +2 -1
  51. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  52. package/dist/modes/interactive/interactive-mode.js +54 -18
  53. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  54. package/dist/modes/rpc/jsonl.d.ts +0 -7
  55. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  56. package/dist/modes/rpc/jsonl.js +17 -0
  57. package/dist/modes/rpc/jsonl.js.map +1 -1
  58. package/dist/utils/safe-write-stream.d.ts +10 -0
  59. package/dist/utils/safe-write-stream.d.ts.map +1 -0
  60. package/dist/utils/safe-write-stream.js +16 -0
  61. package/dist/utils/safe-write-stream.js.map +1 -0
  62. package/dist/utils/sleep.d.ts +3 -1
  63. package/dist/utils/sleep.d.ts.map +1 -1
  64. package/dist/utils/sleep.js +10 -4
  65. package/dist/utils/sleep.js.map +1 -1
  66. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  67. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  68. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  69. package/examples/extensions/sandbox/package-lock.json +2 -2
  70. package/examples/extensions/sandbox/package.json +1 -1
  71. package/examples/extensions/with-deps/package-lock.json +2 -2
  72. package/examples/extensions/with-deps/package.json +1 -1
  73. package/npm-shrinkwrap.json +12 -12
  74. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"git-filter.js","sourceRoot":"","sources":["../../../src/core/tools/git-filter.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { waitForChildProcess } from \"../../utils/child-process.ts\";\nimport { killProcessTree, trackDetachedChildPid, untrackDetachedChildPid } from \"../../utils/shell.ts\";\n\nconst SUPPORTED_SUBCOMMANDS = new Set([\n\t\"status\",\n\t\"log\",\n\t\"diff\",\n\t\"show\",\n\t\"add\",\n\t\"commit\",\n\t\"push\",\n\t\"pull\",\n\t\"branch\",\n\t\"fetch\",\n\t\"stash\",\n\t\"worktree\",\n]);\n\nexport interface FilterResult {\n\toutput: string;\n\texitCode: number;\n\trawOut: string;\n\trawBytes?: Buffer;\n}\n\ninterface GitQueryResult {\n\tstdout: string;\n\tstderr: string;\n\tstatus: number | null;\n\trawBytes: Buffer;\n}\n\ninterface GitFilterOptions {\n\tsignal?: AbortSignal;\n\ttimeout?: number;\n}\n\nexport function unicodeTruncate(str: string, maxLength: number): string {\n\tconst chars = Array.from(str);\n\tif (chars.length <= maxLength) return str;\n\treturn `${chars.slice(0, maxLength).join(\"\")}...`;\n}\n\nexport function tokenizeCommand(command: string): string[] | null {\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet inDoubleQuotes = false;\n\tlet inSingleQuotes = false;\n\tlet escapeNext = false;\n\n\tfor (let i = 0; i < command.length; i++) {\n\t\tconst char = command[i];\n\t\tif (escapeNext) {\n\t\t\tcurrent += char;\n\t\t\tescapeNext = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\\\" && !inSingleQuotes) {\n\t\t\tescapeNext = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '\"' && !inSingleQuotes) {\n\t\t\tinDoubleQuotes = !inDoubleQuotes;\n\t\t} else if (char === \"'\" && !inDoubleQuotes) {\n\t\t\tinSingleQuotes = !inSingleQuotes;\n\t\t} else if (/\\s/.test(char) && !inDoubleQuotes && !inSingleQuotes) {\n\t\t\tif (current) {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent += char;\n\t\t}\n\t}\n\tif (inDoubleQuotes || inSingleQuotes || escapeNext) return null;\n\tif (current) args.push(current);\n\treturn args;\n}\n\nexport interface ParsedCommand {\n\tenvVars: Record<string, string>;\n\tcoreCommandTokens: string[];\n}\n\nexport function parseCommandPrefixes(command: string): ParsedCommand | null {\n\tconst tokens = tokenizeCommand(command);\n\tif (!tokens || tokens.length === 0) return null;\n\n\tconst envVars: Record<string, string> = {};\n\tlet i = 0;\n\tconst envPattern = /^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/;\n\n\twhile (i < tokens.length) {\n\t\tconst token = tokens[i];\n\t\tconst match = token.match(envPattern);\n\t\tif (!match) break;\n\t\tlet value = match[2];\n\t\tif ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n\t\t\tvalue = value.slice(1, -1);\n\t\t}\n\t\tenvVars[match[1]] = value;\n\t\ti++;\n\t}\n\n\treturn { envVars, coreCommandTokens: tokens.slice(i) };\n}\n\nexport function isComplexShellCommand(command: string): boolean {\n\treturn /[|><&;\\n\\r$`()*?[\\]#]/.test(command);\n}\n\nfunction quoteForShell(arg: string): string {\n\tif (/^[A-Za-z0-9_./:=+-]+$/.test(arg)) return arg;\n\treturn `'${arg.replace(/'/g, `'\"'\"'`)}'`;\n}\n\nfunction gitCommand(globalOptions: string[], args: string[]): string {\n\treturn [\"git\", ...globalOptions, ...args].map(quoteForShell).join(\" \");\n}\n\nfunction rawText(res: GitQueryResult, combine = false): string {\n\tif (combine) return `${res.stderr}${res.stderr && res.stdout ? \"\\n\" : \"\"}${res.stdout}`;\n\treturn res.stderr || res.stdout;\n}\n\nfunction resultFromQuery(res: GitQueryResult, output: string, exitCode = res.status ?? 0): FilterResult {\n\treturn { output, exitCode, rawOut: rawText(res), rawBytes: res.rawBytes };\n}\n\nexport async function runGitQuery(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<GitQueryResult> {\n\tif (options?.signal?.aborted) throw new Error(\"aborted\");\n\n\tconst child = spawn(\"git\", [...globalOptions, ...args], {\n\t\tcwd,\n\t\tdetached: process.platform !== \"win32\",\n\t\tenv: { ...process.env, LC_ALL: \"C\" },\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\twindowsHide: true,\n\t});\n\tif (child.pid) trackDetachedChildPid(child.pid);\n\n\tconst stdoutChunks: Buffer[] = [];\n\tconst stderrChunks: Buffer[] = [];\n\tlet timedOut = false;\n\tconst timeoutSeconds = options?.timeout;\n\tlet timeoutHandle: NodeJS.Timeout | undefined;\n\tconst killChild = () => {\n\t\tif (child.pid) killProcessTree(child.pid);\n\t};\n\n\ttry {\n\t\tif (timeoutSeconds !== undefined && timeoutSeconds > 0) {\n\t\t\ttimeoutHandle = setTimeout(() => {\n\t\t\t\ttimedOut = true;\n\t\t\t\tkillChild();\n\t\t\t}, timeoutSeconds * 1000);\n\t\t}\n\t\tif (options?.signal) {\n\t\t\tif (options.signal.aborted) killChild();\n\t\t\telse options.signal.addEventListener(\"abort\", killChild, { once: true });\n\t\t}\n\n\t\tchild.stdout?.on(\"data\", (chunk: Buffer) => stdoutChunks.push(chunk));\n\t\tchild.stderr?.on(\"data\", (chunk: Buffer) => stderrChunks.push(chunk));\n\t\tconst status = await waitForChildProcess(child);\n\t\tif (options?.signal?.aborted) throw new Error(\"aborted\");\n\t\tif (timedOut) throw new Error(`timeout:${timeoutSeconds}`);\n\t\tconst stdoutBuffer = Buffer.concat(stdoutChunks);\n\t\tconst stderrBuffer = Buffer.concat(stderrChunks);\n\t\tconst rawBytes = Buffer.concat([stderrBuffer, stdoutBuffer]);\n\t\treturn {\n\t\t\tstdout: stdoutBuffer.toString(\"utf-8\"),\n\t\t\tstderr: stderrBuffer.toString(\"utf-8\"),\n\t\t\tstatus,\n\t\t\trawBytes,\n\t\t};\n\t} finally {\n\t\tif (child.pid) untrackDetachedChildPid(child.pid);\n\t\tif (timeoutHandle) clearTimeout(timeoutHandle);\n\t\tif (options?.signal) options.signal.removeEventListener(\"abort\", killChild);\n\t}\n}\n\nexport function classifyGitCommand(\n\tcommand: string,\n\tparentEnv?: NodeJS.ProcessEnv,\n): {\n\teligible: boolean;\n\tsubcommand?: string;\n\tglobalOptions?: string[];\n\tsubcommandArgs?: string[];\n\tlocalEnv?: Record<string, string>;\n} {\n\tif (isComplexShellCommand(command)) return { eligible: false };\n\n\tconst parsed = parseCommandPrefixes(command);\n\tif (!parsed || parsed.coreCommandTokens.length === 0) return { eligible: false };\n\n\tconst { envVars, coreCommandTokens } = parsed;\n\tconst toolFilterDisabled =\n\t\tprocess.env.PI_TOOL_FILTER_DISABLED === \"1\" ||\n\t\tparentEnv?.PI_TOOL_FILTER_DISABLED === \"1\" ||\n\t\tenvVars.PI_TOOL_FILTER_DISABLED === \"1\";\n\tconst gitFilterDisabled =\n\t\tprocess.env.PI_GIT_FILTER_DISABLED === \"1\" ||\n\t\tparentEnv?.PI_GIT_FILTER_DISABLED === \"1\" ||\n\t\tenvVars.PI_GIT_FILTER_DISABLED === \"1\";\n\tif (toolFilterDisabled || gitFilterDisabled) return { eligible: false };\n\n\tconst envKeys = Object.keys(envVars).filter(\n\t\t(key) => key !== \"PI_TOOL_FILTER_DISABLED\" && key !== \"PI_GIT_FILTER_DISABLED\",\n\t);\n\tif (envKeys.length > 0) return { eligible: false };\n\n\tconst cmdName = coreCommandTokens[0];\n\tif (cmdName !== \"git\" && cmdName !== \"yadm\") return { eligible: false };\n\n\tlet idx = 1;\n\tconst globalOptions: string[] = [];\n\twhile (idx < coreCommandTokens.length) {\n\t\tconst token = coreCommandTokens[idx];\n\t\tif (token === \"-C\" || token === \"-c\" || token === \"--git-dir\" || token === \"--work-tree\") {\n\t\t\tif (idx + 1 >= coreCommandTokens.length) return { eligible: false };\n\t\t\tglobalOptions.push(token, coreCommandTokens[idx + 1]);\n\t\t\tidx += 2;\n\t\t} else if (token.startsWith(\"--git-dir=\") || token.startsWith(\"--work-tree=\")) {\n\t\t\tglobalOptions.push(token);\n\t\t\tidx++;\n\t\t} else if (\n\t\t\ttoken === \"--no-pager\" ||\n\t\t\ttoken === \"--no-optional-locks\" ||\n\t\t\ttoken === \"--bare\" ||\n\t\t\ttoken === \"--literal-pathspecs\"\n\t\t) {\n\t\t\tglobalOptions.push(token);\n\t\t\tidx++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (idx === coreCommandTokens.length) return { eligible: false };\n\tconst subcommand = coreCommandTokens[idx];\n\tif (!SUPPORTED_SUBCOMMANDS.has(subcommand)) return { eligible: false };\n\n\treturn {\n\t\teligible: true,\n\t\tsubcommand,\n\t\tglobalOptions,\n\t\tsubcommandArgs: coreCommandTokens.slice(idx + 1),\n\t\tlocalEnv: envVars,\n\t};\n}\n\nexport function detectGitState(gitDir: string): string[] {\n\tconst states: string[] = [];\n\tif (!gitDir) return states;\n\tif (existsSync(join(gitDir, \"rebase-merge\")) || existsSync(join(gitDir, \"rebase-apply\"))) {\n\t\tstates.push(\"rebase in progress\");\n\t}\n\tif (existsSync(join(gitDir, \"MERGE_HEAD\"))) states.push(\"merge in progress\");\n\tif (existsSync(join(gitDir, \"CHERRY_PICK_HEAD\"))) states.push(\"cherry-pick in progress\");\n\tif (existsSync(join(gitDir, \"REVERT_HEAD\"))) states.push(\"revert in progress\");\n\tif (existsSync(join(gitDir, \"BISECT_LOG\"))) states.push(\"bisect in progress\");\n\tif (existsSync(join(gitDir, \"applying\"))) states.push(\"am in progress\");\n\treturn states;\n}\n\nasync function handleStatus(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst isSimple =\n\t\targs.length === 0 || args.every((arg) => arg === \"-s\" || arg === \"--short\" || arg === \"-b\" || arg === \"--branch\");\n\n\tif (!isSimple) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"status\", ...args], options);\n\t\tconst rawOut = rawText(res);\n\t\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\t\tconst cleanedLines = res.stdout\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trimEnd())\n\t\t\t.filter((line) => line.length > 0 && !line.trim().startsWith(\"(use \"));\n\t\tconst output = cleanedLines.join(\"\\n\");\n\t\treturn resultFromQuery(res, output || \"success\", 0);\n\t}\n\n\tconst res = await runGitQuery(cwd, globalOptions, [\"status\", \"--porcelain=v1\", \"-b\"], options);\n\tlet rawOut = rawText(res);\n\tif (res.status !== 0) {\n\t\tif (rawOut.includes(\"not a git repository\")) rawOut = \"fatal: not a git repository\";\n\t\treturn { output: rawOut.trim(), exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\t}\n\n\tconst lines = res.stdout.split(\"\\n\").filter((line) => line.trim().length > 0);\n\tlet branchLine = \"\";\n\tconst fileLines: string[] = [];\n\tfor (const line of lines) {\n\t\tif (line.startsWith(\"##\")) branchLine = line;\n\t\telse fileLines.push(line);\n\t}\n\n\tlet statePrefix = \"\";\n\tconst gitDirRes = await runGitQuery(cwd, globalOptions, [\"rev-parse\", \"--git-dir\"], options);\n\tif (gitDirRes.status === 0) {\n\t\tconst gitDir = resolve(cwd, gitDirRes.stdout.trim());\n\t\tconst states = detectGitState(gitDir);\n\t\tif (states.length > 0) statePrefix = `[${states.join(\", \")}]\\n`;\n\t}\n\n\tif (branchLine.includes(\"HEAD (no branch)\")) {\n\t\tconst headHashRes = await runGitQuery(cwd, globalOptions, [\"rev-parse\", \"--short\", \"HEAD\"], options);\n\t\tconst hash = headHashRes.status === 0 ? headHashRes.stdout.trim() : \"unknown\";\n\t\tbranchLine = `## HEAD (detached at ${hash})`;\n\t}\n\n\tif (fileLines.length === 0) {\n\t\treturn resultFromQuery(res, `${statePrefix}${branchLine}\\nnothing to commit, working tree clean`, 0);\n\t}\n\treturn resultFromQuery(res, `${statePrefix}${branchLine}\\n${fileLines.join(\"\\n\")}`, 0);\n}\n\nasync function handleLog(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst hasLimit = args.some(\n\t\t(arg) => /^-n\\d+$/.test(arg) || arg === \"-n\" || /^-?\\d+$/.test(arg) || arg.startsWith(\"--max-count\"),\n\t);\n\tconst hasPretty = args.some(\n\t\t(arg) => arg.startsWith(\"--pretty\") || arg.startsWith(\"--format\") || arg === \"--oneline\",\n\t);\n\n\tif (hasLimit || hasPretty) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"log\", ...args], options);\n\t\treturn resultFromQuery(res, rawText(res), res.status ?? 0);\n\t}\n\n\tconst res = await runGitQuery(cwd, globalOptions, [\"log\", \"-n\", \"10\", \"--no-merges\"], options);\n\tconst rawOut = rawText(res);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\n\tconst commits = res.stdout.split(/(?=^commit [0-9a-f]{7,40})/m).filter((commit) => commit.trim().length > 0);\n\tconst compactedCommits: string[] = [];\n\tconst trailerPrefixes = [\n\t\t\"Signed-off-by:\",\n\t\t\"Co-authored-by:\",\n\t\t\"Reported-by:\",\n\t\t\"Reviewed-by:\",\n\t\t\"Tested-by:\",\n\t\t\"Suggested-by:\",\n\t\t\"CC:\",\n\t];\n\n\tfor (const commit of commits) {\n\t\tconst lines = commit.split(\"\\n\");\n\t\tconst commitLine = lines[0];\n\t\tif (!commitLine) continue;\n\t\tconst shortCommitLine = commitLine.replace(/^commit ([0-9a-f]{7})[0-9a-f]+/, \"commit $1\");\n\t\tconst bodyLines: string[] = [];\n\t\tfor (let i = 1; i < lines.length; i++) {\n\t\t\tconst line = lines[i];\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed) continue;\n\t\t\tif (line.startsWith(\"Author:\") || line.startsWith(\"Date:\") || line.startsWith(\"Merge:\")) continue;\n\t\t\tif (trailerPrefixes.some((prefix) => trimmed.startsWith(prefix))) continue;\n\t\t\tbodyLines.push(line);\n\t\t}\n\t\tconst displayBody = bodyLines.slice(0, 3).map((line) => unicodeTruncate(line, 160));\n\t\tconst omitted = bodyLines.length - displayBody.length;\n\t\tif (omitted > 0) displayBody.push(` ... (${omitted} lines omitted)`);\n\t\tcompactedCommits.push(`${shortCommitLine}\\n${displayBody.join(\"\\n\")}`);\n\t}\n\n\treturn resultFromQuery(res, compactedCommits.join(\"\\n\\n\"), 0);\n}\n\nexport function compactDiff(diffOutput: string, maxLines = 150): { compacted: string; truncated: boolean } {\n\tconst lines = diffOutput.split(\"\\n\");\n\tconst output: string[] = [];\n\tlet linesCount = 0;\n\tlet truncated = false;\n\tlet contextBuffer: string[] = [];\n\tlet trailingContextRemaining = 0;\n\n\tfor (const line of lines) {\n\t\tif (linesCount >= maxLines) {\n\t\t\ttruncated = true;\n\t\t\tbreak;\n\t\t}\n\t\tif (\n\t\t\tline.startsWith(\"diff --git\") ||\n\t\t\tline.startsWith(\"--- \") ||\n\t\t\tline.startsWith(\"+++ \") ||\n\t\t\tline.startsWith(\"index \")\n\t\t) {\n\t\t\tcontextBuffer = [];\n\t\t\ttrailingContextRemaining = 0;\n\t\t\toutput.push(line);\n\t\t\tlinesCount++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"@@ \")) {\n\t\t\tcontextBuffer = [];\n\t\t\ttrailingContextRemaining = 0;\n\t\t\toutput.push(line);\n\t\t\tlinesCount++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"+\") || line.startsWith(\"-\")) {\n\t\t\tfor (const ctx of contextBuffer) {\n\t\t\t\tif (linesCount >= maxLines) {\n\t\t\t\t\ttruncated = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\toutput.push(ctx);\n\t\t\t\tlinesCount++;\n\t\t\t}\n\t\t\tcontextBuffer = [];\n\t\t\tif (truncated) break;\n\t\t\toutput.push(line);\n\t\t\tlinesCount++;\n\t\t\ttrailingContextRemaining = 3;\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\" \")) {\n\t\t\tif (trailingContextRemaining > 0) {\n\t\t\t\toutput.push(line);\n\t\t\t\tlinesCount++;\n\t\t\t\ttrailingContextRemaining--;\n\t\t\t} else {\n\t\t\t\tcontextBuffer.push(line);\n\t\t\t\tif (contextBuffer.length > 3) contextBuffer.shift();\n\t\t\t}\n\t\t} else {\n\t\t\toutput.push(line);\n\t\t\tlinesCount++;\n\t\t}\n\t}\n\n\treturn { compacted: output.join(\"\\n\"), truncated };\n}\n\nasync function handleDiff(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst cleanArgs = [...args];\n\tconst noCompactIndex = cleanArgs.indexOf(\"--no-compact\");\n\tconst optOut = noCompactIndex !== -1;\n\tif (optOut) cleanArgs.splice(noCompactIndex, 1);\n\n\tconst statFlags = [\"--stat\", \"--numstat\", \"--shortstat\", \"--summary\", \"--name-only\", \"--name-status\", \"--check\"];\n\tconst isStatOnly = cleanArgs.some((arg) => statFlags.includes(arg));\n\tif (optOut || isStatOnly) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"diff\", ...cleanArgs], options);\n\t\treturn resultFromQuery(res, rawText(res), res.status ?? 0);\n\t}\n\n\tconst hasDoubleDash = cleanArgs.includes(\"--\");\n\tif (!hasDoubleDash) {\n\t\tconst pathIdx = cleanArgs.findIndex((arg) => {\n\t\t\tif (arg.startsWith(\"-\")) return false;\n\t\t\tif (!(arg.includes(\"/\") || arg.includes(\".\") || existsSync(join(cwd, arg)))) return false;\n\t\t\treturn existsSync(resolve(cwd, arg));\n\t\t});\n\t\tif (pathIdx !== -1) cleanArgs.splice(pathIdx, 0, \"--\");\n\t}\n\n\tconst statRes = await runGitQuery(cwd, globalOptions, [\"diff\", \"--stat\", ...cleanArgs], options);\n\tif (statRes.status !== 0) return resultFromQuery(statRes, rawText(statRes), statRes.status ?? 1);\n\tconst diffRes = await runGitQuery(cwd, globalOptions, [\"diff\", ...cleanArgs], options);\n\tif (diffRes.status !== 0) return resultFromQuery(diffRes, rawText(diffRes), diffRes.status ?? 1);\n\n\tconst { compacted, truncated } = compactDiff(diffRes.stdout);\n\tlet output = `${statRes.stdout.trimEnd()}\\n\\n${compacted}`.trim();\n\tif (truncated) output += \"\\n\\n[Diff truncated. Re-run with: git diff --no-compact]\";\n\treturn { output, exitCode: 0, rawOut: diffRes.stdout, rawBytes: diffRes.rawBytes };\n}\n\nasync function handleShow(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst statFlags = [\"--stat\", \"--numstat\", \"--shortstat\", \"--summary\", \"--name-only\", \"--name-status\", \"--check\"];\n\tconst hasStatOnly = args.some((arg) => statFlags.includes(arg));\n\tconst hasPretty = args.some(\n\t\t(arg) => arg.startsWith(\"--pretty\") || arg.startsWith(\"--format\") || arg === \"--oneline\",\n\t);\n\tconst hasBlob = args.some((arg) => !arg.startsWith(\"-\") && arg.includes(\":\"));\n\tif (hasStatOnly || hasPretty || hasBlob) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"show\", ...args], options);\n\t\treturn resultFromQuery(res, rawText(res), res.status ?? 0);\n\t}\n\n\tconst showRes = await runGitQuery(cwd, globalOptions, [\"show\", ...args], options);\n\tconst rawOut = rawText(showRes);\n\tif (showRes.status !== 0)\n\t\treturn { output: rawOut, exitCode: showRes.status ?? 1, rawOut, rawBytes: showRes.rawBytes };\n\n\tconst lines = showRes.stdout.split(\"\\n\");\n\tconst diffStart = lines.findIndex((line) => line.startsWith(\"diff --git\"));\n\tconst headerLines = diffStart === -1 ? lines : lines.slice(0, diffStart);\n\tconst diffLines = diffStart === -1 ? [] : lines.slice(diffStart);\n\tconst summaryLines = headerLines.filter((line) => {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) return false;\n\t\tif (line.startsWith(\"Author:\") || line.startsWith(\"Date:\") || line.startsWith(\"Merge:\")) return false;\n\t\treturn true;\n\t});\n\tconst shortSummary = summaryLines\n\t\t.slice(0, 4)\n\t\t.map((line) => unicodeTruncate(line.replace(/^commit ([0-9a-f]{7})[0-9a-f]+/, \"commit $1\"), 160));\n\tconst { compacted, truncated } = compactDiff(diffLines.join(\"\\n\"));\n\tlet output = shortSummary.join(\"\\n\");\n\tif (compacted.trim()) output += `\\n\\n${compacted}`;\n\tif (truncated) output += \"\\n\\n[Diff truncated.]\";\n\treturn resultFromQuery(showRes, output.trim(), 0);\n}\n\nasync function handlePassthroughGit(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst res = await runGitQuery(cwd, globalOptions, args, options);\n\treturn resultFromQuery(res, rawText(res, true).trim(), res.status ?? 0);\n}\n\nasync function handleAdd(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tif (args.length === 0) return handlePassthroughGit(cwd, globalOptions, [\"add\"], options);\n\tconst addRes = await runGitQuery(cwd, globalOptions, [\"add\", ...args], options);\n\tconst rawOut = rawText(addRes);\n\tif (addRes.status !== 0) return { output: rawOut, exitCode: addRes.status ?? 1, rawOut, rawBytes: addRes.rawBytes };\n\tconst statRes = await runGitQuery(cwd, globalOptions, [\"diff\", \"--cached\", \"--stat\"], options);\n\tif (statRes.status === 0 && statRes.stdout.trim().length > 0) {\n\t\treturn { output: `Staged changes:\\n${statRes.stdout.trim()}`, exitCode: 0, rawOut, rawBytes: addRes.rawBytes };\n\t}\n\treturn { output: rawOut.trim() || \"Successfully staged.\", exitCode: 0, rawOut, rawBytes: addRes.rawBytes };\n}\n\nasync function handleCommit(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst hasMsg = args.some(\n\t\t(arg) => arg === \"-m\" || arg === \"-F\" || arg.startsWith(\"--message\") || arg.startsWith(\"--file\"),\n\t);\n\tif (!hasMsg) return { output: \"\", exitCode: -100, rawOut: \"\" };\n\tconst res = await runGitQuery(cwd, globalOptions, [\"commit\", ...args], options);\n\tconst rawOut = rawText(res, true);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (rawOut.includes(\"nothing to commit\") || rawOut.includes(\"working tree clean\")) {\n\t\treturn { output: \"nothing to commit, working tree clean\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\t}\n\tconst firstLine = rawOut\n\t\t.split(\"\\n\")\n\t\t.find((line) => line.trim().length > 0)\n\t\t?.trim();\n\treturn { output: firstLine || \"Committed successfully.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handlePush(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst res = await runGitQuery(cwd, globalOptions, [\"push\", ...args], options);\n\tconst rawOut = rawText(res, true);\n\tconst outputLines = rawOut\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trimEnd())\n\t\t.filter((line) => {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed) return false;\n\t\t\treturn ![\"Writing objects:\", \"Counting objects:\", \"Delta compression\", \"Compressing objects:\", \"Total \"].some(\n\t\t\t\t(prefix) => trimmed.startsWith(prefix),\n\t\t\t);\n\t\t});\n\tif (res.status !== 0)\n\t\treturn { output: outputLines.join(\"\\n\"), exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (outputLines.some((line) => line.includes(\"Everything up-to-date\"))) {\n\t\treturn { output: \"Everything up-to-date.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\t}\n\tconst remoteMessages = outputLines.filter((line) => line.trim().startsWith(\"remote:\"));\n\tconst pushDetail = outputLines.find((line) => line.includes(\"->\"));\n\tconst summary = pushDetail ? `Pushed: ${pushDetail.trim()}` : \"Push successful.\";\n\treturn { output: [...remoteMessages, summary].join(\"\\n\"), exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handlePull(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst res = await runGitQuery(cwd, globalOptions, [\"pull\", ...args], options);\n\tconst rawOut = rawText(res, true);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (rawOut.includes(\"Already up to date.\"))\n\t\treturn { output: \"Already up to date.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\tconst lines = rawOut.split(\"\\n\");\n\tconst summary = lines.filter(\n\t\t(line) => line.includes(\"Fast-forward\") || line.includes(\"file changed\") || line.includes(\"files changed\"),\n\t);\n\treturn { output: summary.join(\"\\n\") || \"Pull successful.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handleFetch(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst res = await runGitQuery(cwd, globalOptions, [\"fetch\", ...args], options);\n\tconst rawOut = rawText(res, true);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tconst refs = rawOut\n\t\t.split(\"\\n\")\n\t\t.filter((line) => line.includes(\"[new branch]\") || line.includes(\"[new tag]\") || line.includes(\"->\"));\n\treturn {\n\t\toutput: refs.length\n\t\t\t? `Fetched:\\n${refs.map((line) => line.trim()).join(\"\\n\")}`\n\t\t\t: \"Fetch successful (no new refs).\",\n\t\texitCode: 0,\n\t\trawOut,\n\t\trawBytes: res.rawBytes,\n\t};\n}\n\nasync function handleBranch(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tif (args.includes(\"--show-current\")) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"branch\", \"--show-current\"], options);\n\t\treturn { output: res.stdout.trim(), exitCode: res.status ?? 0, rawOut: rawText(res), rawBytes: res.rawBytes };\n\t}\n\tconst isWrite = args.some(\n\t\t(arg) =>\n\t\t\targ === \"-d\" || arg === \"-D\" || arg === \"-m\" || arg === \"-M\" || (!arg.startsWith(\"-\") && args.length === 1),\n\t);\n\tif (isWrite) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"branch\", ...args], options);\n\t\tconst rawOut = rawText(res);\n\t\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\t\treturn { output: rawOut.trim() || \"Branch updated successfully.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\t}\n\tconst res = await runGitQuery(cwd, globalOptions, [\"branch\", \"--no-color\", ...args], options);\n\tconst rawOut = rawText(res);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tconst lines = res.stdout.split(\"\\n\").filter((line) => line.trim().length > 0);\n\tconst remoteBranches = lines.filter((line) => line.includes(\"remotes/\"));\n\tconst localBranches = lines.filter((line) => !line.includes(\"remotes/\"));\n\tconst remoteDisplay = remoteBranches.slice(0, 5);\n\tconst omitted = remoteBranches.length - remoteDisplay.length;\n\tif (omitted > 0) remoteDisplay.push(` remotes/... (${omitted} more remote branches)`);\n\treturn { output: [...localBranches, ...remoteDisplay].join(\"\\n\"), exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handleStash(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst sub = args[0] || \"push\";\n\tconst res = await runGitQuery(cwd, globalOptions, [\"stash\", ...args], options);\n\tconst rawOut = rawText(res);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (sub === \"list\")\n\t\treturn { output: res.stdout.trim() || \"No stashes found.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\tif (sub === \"show\") {\n\t\tconst { compacted, truncated } = compactDiff(res.stdout);\n\t\treturn {\n\t\t\toutput: `${compacted.trim()}${truncated ? \"\\n\\n[Diff truncated.]\" : \"\"}`,\n\t\t\texitCode: 0,\n\t\t\trawOut,\n\t\t\trawBytes: res.rawBytes,\n\t\t};\n\t}\n\tif (res.stdout.includes(\"No local changes to save\"))\n\t\treturn { output: \"No local changes to save.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\tconst firstLine = res.stdout\n\t\t.split(\"\\n\")\n\t\t.find((line) => line.trim().length > 0)\n\t\t?.trim();\n\treturn { output: firstLine || \"Stash successful.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handleWorktree(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst sub = args[0] || \"list\";\n\tconst res = await runGitQuery(cwd, globalOptions, [\"worktree\", ...(sub === \"list\" ? [\"list\"] : args)], options);\n\tconst rawOut = rawText(res, true);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (sub !== \"list\") return { output: rawOut.trim(), exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\tconst home = process.env.HOME || \"\";\n\tconst output = res.stdout\n\t\t.split(\"\\n\")\n\t\t.map((line) => (home && line.startsWith(home) ? `~${line.slice(home.length)}` : line))\n\t\t.join(\"\\n\")\n\t\t.trim();\n\treturn { output, exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nexport async function executeFilteredGit(\n\tcwd: string,\n\tsubcommand: string,\n\tglobalOptions: string[],\n\tsubcommandArgs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tswitch (subcommand) {\n\t\tcase \"status\":\n\t\t\treturn handleStatus(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"log\":\n\t\t\treturn handleLog(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"diff\":\n\t\t\treturn handleDiff(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"show\":\n\t\t\treturn handleShow(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"add\":\n\t\t\treturn handleAdd(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"commit\":\n\t\t\treturn handleCommit(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"push\":\n\t\t\treturn handlePush(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"pull\":\n\t\t\treturn handlePull(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"branch\":\n\t\t\treturn handleBranch(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"fetch\":\n\t\t\treturn handleFetch(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"stash\":\n\t\t\treturn handleStash(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"worktree\":\n\t\t\treturn handleWorktree(cwd, globalOptions, subcommandArgs, options);\n\t\tdefault:\n\t\t\treturn { output: \"\", exitCode: -100, rawOut: \"\" };\n\t}\n}\n\nexport function makeGitCommandForDisplay(globalOptions: string[], subcommand: string, args: string[]): string {\n\treturn gitCommand(globalOptions, [subcommand, ...args]);\n}\n"]}
1
+ {"version":3,"file":"git-filter.js","sourceRoot":"","sources":["../../../src/core/tools/git-filter.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport { existsSync, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { waitForChildProcess } from \"../../utils/child-process.ts\";\nimport { createSafeWriteStream } from \"../../utils/safe-write-stream.ts\";\nimport { killProcessTree, trackDetachedChildPid, untrackDetachedChildPid } from \"../../utils/shell.ts\";\n\n/**\n * Retention budget for git output held in memory while filtering. Output beyond\n * the budget is spilled to a temp file so a giant `git log -p`/`git diff` cannot\n * exhaust the V8 heap. Override with PI_GIT_FILTER_MAX_RETAINED_BYTES.\n */\nconst DEFAULT_MAX_RETAINED_GIT_OUTPUT_BYTES = 48 * 1024 * 1024;\nconst MAX_RETAINED_GIT_STDERR_BYTES = 8 * 1024 * 1024;\n\nfunction maxRetainedGitOutputBytes(): number {\n\tconst raw = process.env.PI_GIT_FILTER_MAX_RETAINED_BYTES;\n\tif (raw !== undefined) {\n\t\tconst parsed = Number.parseInt(raw, 10);\n\t\tif (Number.isFinite(parsed) && parsed > 0) return parsed;\n\t}\n\treturn DEFAULT_MAX_RETAINED_GIT_OUTPUT_BYTES;\n}\n\nconst SUPPORTED_SUBCOMMANDS = new Set([\n\t\"status\",\n\t\"log\",\n\t\"diff\",\n\t\"show\",\n\t\"add\",\n\t\"commit\",\n\t\"push\",\n\t\"pull\",\n\t\"branch\",\n\t\"fetch\",\n\t\"stash\",\n\t\"worktree\",\n]);\n\nexport interface FilterResult {\n\toutput: string;\n\texitCode: number;\n\trawOut: string;\n\trawBytes?: Buffer;\n\t/** Set when git output exceeded the in-memory retention budget; the file holds the full output. */\n\tfullOutputPath?: string;\n}\n\ninterface GitQueryResult {\n\tstdout: string;\n\tstderr: string;\n\tstatus: number | null;\n\t/** Full raw output (stderr then stdout). Absent when output overflowed to disk. */\n\trawBytes?: Buffer;\n\t/** Set when stdout exceeded the retention budget and was spilled to a temp file. */\n\toverflow?: { fullOutputPath: string; totalBytes: number };\n}\n\ninterface GitFilterOptions {\n\tsignal?: AbortSignal;\n\ttimeout?: number;\n}\n\nexport function unicodeTruncate(str: string, maxLength: number): string {\n\tconst chars = Array.from(str);\n\tif (chars.length <= maxLength) return str;\n\treturn `${chars.slice(0, maxLength).join(\"\")}...`;\n}\n\nexport function tokenizeCommand(command: string): string[] | null {\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet inDoubleQuotes = false;\n\tlet inSingleQuotes = false;\n\tlet escapeNext = false;\n\n\tfor (let i = 0; i < command.length; i++) {\n\t\tconst char = command[i];\n\t\tif (escapeNext) {\n\t\t\tcurrent += char;\n\t\t\tescapeNext = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\\\" && !inSingleQuotes) {\n\t\t\tescapeNext = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '\"' && !inSingleQuotes) {\n\t\t\tinDoubleQuotes = !inDoubleQuotes;\n\t\t} else if (char === \"'\" && !inDoubleQuotes) {\n\t\t\tinSingleQuotes = !inSingleQuotes;\n\t\t} else if (/\\s/.test(char) && !inDoubleQuotes && !inSingleQuotes) {\n\t\t\tif (current) {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent += char;\n\t\t}\n\t}\n\tif (inDoubleQuotes || inSingleQuotes || escapeNext) return null;\n\tif (current) args.push(current);\n\treturn args;\n}\n\nexport interface ParsedCommand {\n\tenvVars: Record<string, string>;\n\tcoreCommandTokens: string[];\n}\n\nexport function parseCommandPrefixes(command: string): ParsedCommand | null {\n\tconst tokens = tokenizeCommand(command);\n\tif (!tokens || tokens.length === 0) return null;\n\n\tconst envVars: Record<string, string> = {};\n\tlet i = 0;\n\tconst envPattern = /^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$/;\n\n\twhile (i < tokens.length) {\n\t\tconst token = tokens[i];\n\t\tconst match = token.match(envPattern);\n\t\tif (!match) break;\n\t\tlet value = match[2];\n\t\tif ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n\t\t\tvalue = value.slice(1, -1);\n\t\t}\n\t\tenvVars[match[1]] = value;\n\t\ti++;\n\t}\n\n\treturn { envVars, coreCommandTokens: tokens.slice(i) };\n}\n\nexport function isComplexShellCommand(command: string): boolean {\n\treturn /[|><&;\\n\\r$`()*?[\\]#]/.test(command);\n}\n\nfunction quoteForShell(arg: string): string {\n\tif (/^[A-Za-z0-9_./:=+-]+$/.test(arg)) return arg;\n\treturn `'${arg.replace(/'/g, `'\"'\"'`)}'`;\n}\n\nfunction gitCommand(globalOptions: string[], args: string[]): string {\n\treturn [\"git\", ...globalOptions, ...args].map(quoteForShell).join(\" \");\n}\n\nfunction rawText(res: GitQueryResult, combine = false): string {\n\tif (combine) return `${res.stderr}${res.stderr && res.stdout ? \"\\n\" : \"\"}${res.stdout}`;\n\treturn res.stderr || res.stdout;\n}\n\nfunction applyOverflowDisclosure(res: GitQueryResult, result: FilterResult): FilterResult {\n\tif (!res.overflow) return result;\n\tconst totalMb = (res.overflow.totalBytes / (1024 * 1024)).toFixed(1);\n\treturn {\n\t\t...result,\n\t\toutput: `${result.output}\\n\\n[git output was ${totalMb}MB; filtered view computed from the retained head. Full output: ${res.overflow.fullOutputPath}]`,\n\t\tfullOutputPath: res.overflow.fullOutputPath,\n\t};\n}\n\nfunction resultFromQuery(res: GitQueryResult, output: string, exitCode = res.status ?? 0): FilterResult {\n\treturn applyOverflowDisclosure(res, { output, exitCode, rawOut: rawText(res), rawBytes: res.rawBytes });\n}\n\nexport async function runGitQuery(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<GitQueryResult> {\n\tif (options?.signal?.aborted) throw new Error(\"aborted\");\n\n\tconst child = spawn(\"git\", [...globalOptions, ...args], {\n\t\tcwd,\n\t\tdetached: process.platform !== \"win32\",\n\t\tenv: { ...process.env, LC_ALL: \"C\" },\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\twindowsHide: true,\n\t});\n\tif (child.pid) trackDetachedChildPid(child.pid);\n\n\tconst stdoutChunks: Buffer[] = [];\n\tconst stderrChunks: Buffer[] = [];\n\tconst maxRetainedBytes = maxRetainedGitOutputBytes();\n\tlet retainedStdoutBytes = 0;\n\tlet totalStdoutBytes = 0;\n\tlet retainedStderrBytes = 0;\n\tlet overflowPath: string | undefined;\n\tlet overflowStream: WriteStream | undefined;\n\tlet overflowStreamEnded = false;\n\tlet overflowWriteError: Error | undefined;\n\tlet timedOut = false;\n\tconst timeoutSeconds = options?.timeout;\n\tlet timeoutHandle: NodeJS.Timeout | undefined;\n\tconst killChild = () => {\n\t\tif (child.pid) killProcessTree(child.pid);\n\t};\n\n\ttry {\n\t\tif (timeoutSeconds !== undefined && timeoutSeconds > 0) {\n\t\t\ttimeoutHandle = setTimeout(() => {\n\t\t\t\ttimedOut = true;\n\t\t\t\tkillChild();\n\t\t\t}, timeoutSeconds * 1000);\n\t\t}\n\t\tif (options?.signal) {\n\t\t\tif (options.signal.aborted) killChild();\n\t\t\telse options.signal.addEventListener(\"abort\", killChild, { once: true });\n\t\t}\n\n\t\tchild.stdout?.on(\"data\", (chunk: Buffer) => {\n\t\t\ttotalStdoutBytes += chunk.length;\n\t\t\tif (overflowStream) {\n\t\t\t\toverflowStream.write(chunk);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstdoutChunks.push(chunk);\n\t\t\tretainedStdoutBytes += chunk.length;\n\t\t\tif (retainedStdoutBytes > maxRetainedBytes) {\n\t\t\t\toverflowPath = join(tmpdir(), `pi-git-${randomBytes(8).toString(\"hex\")}.log`);\n\t\t\t\toverflowStream = createSafeWriteStream(overflowPath, (error) => {\n\t\t\t\t\toverflowWriteError = error;\n\t\t\t\t});\n\t\t\t\tfor (const retained of stdoutChunks) overflowStream.write(retained);\n\t\t\t}\n\t\t});\n\t\tchild.stderr?.on(\"data\", (chunk: Buffer) => {\n\t\t\tstderrChunks.push(chunk);\n\t\t\tretainedStderrBytes += chunk.length;\n\t\t\twhile (retainedStderrBytes > MAX_RETAINED_GIT_STDERR_BYTES && stderrChunks.length > 1) {\n\t\t\t\tretainedStderrBytes -= stderrChunks.shift()?.length ?? 0;\n\t\t\t}\n\t\t});\n\t\tconst status = await waitForChildProcess(child);\n\t\tif (options?.signal?.aborted) throw new Error(\"aborted\");\n\t\tif (timedOut) throw new Error(`timeout:${timeoutSeconds}`);\n\t\tconst stdoutBuffer = Buffer.concat(stdoutChunks);\n\t\tconst stderrBuffer = Buffer.concat(stderrChunks);\n\t\tif (overflowStream !== undefined && overflowPath !== undefined) {\n\t\t\tif (stderrBuffer.length > 0 && !overflowStream.writableEnded) {\n\t\t\t\toverflowStream.write(\"\\n--- stderr ---\\n\");\n\t\t\t\toverflowStream.write(stderrBuffer);\n\t\t\t}\n\t\t\tconst stream = overflowStream;\n\t\t\tawait new Promise<void>((resolveEnd) => {\n\t\t\t\tstream.end(() => resolveEnd());\n\t\t\t});\n\t\t\toverflowStreamEnded = true;\n\t\t\tif (overflowWriteError !== undefined) {\n\t\t\t\t// Spill failed (e.g. disk full): disclose the loss instead of pointing\n\t\t\t\t// consumers at a broken artifact, and keep the retained head usable.\n\t\t\t\treturn {\n\t\t\t\t\tstdout: stdoutBuffer.toString(\"utf-8\"),\n\t\t\t\t\tstderr: `${stderrBuffer.toString(\"utf-8\")}\\n[git output overflow spill failed: ${overflowWriteError.message}; output beyond the retained head was lost]`,\n\t\t\t\t\tstatus,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstdout: stdoutBuffer.toString(\"utf-8\"),\n\t\t\t\tstderr: stderrBuffer.toString(\"utf-8\"),\n\t\t\t\tstatus,\n\t\t\t\toverflow: { fullOutputPath: overflowPath, totalBytes: totalStdoutBytes },\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tstdout: stdoutBuffer.toString(\"utf-8\"),\n\t\t\tstderr: stderrBuffer.toString(\"utf-8\"),\n\t\t\tstatus,\n\t\t\trawBytes: Buffer.concat([stderrBuffer, stdoutBuffer]),\n\t\t};\n\t} finally {\n\t\tif (child.pid) untrackDetachedChildPid(child.pid);\n\t\tif (timeoutHandle) clearTimeout(timeoutHandle);\n\t\tif (options?.signal) options.signal.removeEventListener(\"abort\", killChild);\n\t\tif (overflowStream !== undefined && !overflowStreamEnded) overflowStream.end();\n\t}\n}\n\nexport function classifyGitCommand(\n\tcommand: string,\n\tparentEnv?: NodeJS.ProcessEnv,\n): {\n\teligible: boolean;\n\tsubcommand?: string;\n\tglobalOptions?: string[];\n\tsubcommandArgs?: string[];\n\tlocalEnv?: Record<string, string>;\n} {\n\tif (isComplexShellCommand(command)) return { eligible: false };\n\n\tconst parsed = parseCommandPrefixes(command);\n\tif (!parsed || parsed.coreCommandTokens.length === 0) return { eligible: false };\n\n\tconst { envVars, coreCommandTokens } = parsed;\n\tconst toolFilterDisabled =\n\t\tprocess.env.PI_TOOL_FILTER_DISABLED === \"1\" ||\n\t\tparentEnv?.PI_TOOL_FILTER_DISABLED === \"1\" ||\n\t\tenvVars.PI_TOOL_FILTER_DISABLED === \"1\";\n\tconst gitFilterDisabled =\n\t\tprocess.env.PI_GIT_FILTER_DISABLED === \"1\" ||\n\t\tparentEnv?.PI_GIT_FILTER_DISABLED === \"1\" ||\n\t\tenvVars.PI_GIT_FILTER_DISABLED === \"1\";\n\tif (toolFilterDisabled || gitFilterDisabled) return { eligible: false };\n\n\tconst envKeys = Object.keys(envVars).filter(\n\t\t(key) => key !== \"PI_TOOL_FILTER_DISABLED\" && key !== \"PI_GIT_FILTER_DISABLED\",\n\t);\n\tif (envKeys.length > 0) return { eligible: false };\n\n\tconst cmdName = coreCommandTokens[0];\n\tif (cmdName !== \"git\" && cmdName !== \"yadm\") return { eligible: false };\n\n\tlet idx = 1;\n\tconst globalOptions: string[] = [];\n\twhile (idx < coreCommandTokens.length) {\n\t\tconst token = coreCommandTokens[idx];\n\t\tif (token === \"-C\" || token === \"-c\" || token === \"--git-dir\" || token === \"--work-tree\") {\n\t\t\tif (idx + 1 >= coreCommandTokens.length) return { eligible: false };\n\t\t\tglobalOptions.push(token, coreCommandTokens[idx + 1]);\n\t\t\tidx += 2;\n\t\t} else if (token.startsWith(\"--git-dir=\") || token.startsWith(\"--work-tree=\")) {\n\t\t\tglobalOptions.push(token);\n\t\t\tidx++;\n\t\t} else if (\n\t\t\ttoken === \"--no-pager\" ||\n\t\t\ttoken === \"--no-optional-locks\" ||\n\t\t\ttoken === \"--bare\" ||\n\t\t\ttoken === \"--literal-pathspecs\"\n\t\t) {\n\t\t\tglobalOptions.push(token);\n\t\t\tidx++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (idx === coreCommandTokens.length) return { eligible: false };\n\tconst subcommand = coreCommandTokens[idx];\n\tif (!SUPPORTED_SUBCOMMANDS.has(subcommand)) return { eligible: false };\n\n\treturn {\n\t\teligible: true,\n\t\tsubcommand,\n\t\tglobalOptions,\n\t\tsubcommandArgs: coreCommandTokens.slice(idx + 1),\n\t\tlocalEnv: envVars,\n\t};\n}\n\nexport function detectGitState(gitDir: string): string[] {\n\tconst states: string[] = [];\n\tif (!gitDir) return states;\n\tif (existsSync(join(gitDir, \"rebase-merge\")) || existsSync(join(gitDir, \"rebase-apply\"))) {\n\t\tstates.push(\"rebase in progress\");\n\t}\n\tif (existsSync(join(gitDir, \"MERGE_HEAD\"))) states.push(\"merge in progress\");\n\tif (existsSync(join(gitDir, \"CHERRY_PICK_HEAD\"))) states.push(\"cherry-pick in progress\");\n\tif (existsSync(join(gitDir, \"REVERT_HEAD\"))) states.push(\"revert in progress\");\n\tif (existsSync(join(gitDir, \"BISECT_LOG\"))) states.push(\"bisect in progress\");\n\tif (existsSync(join(gitDir, \"applying\"))) states.push(\"am in progress\");\n\treturn states;\n}\n\nasync function handleStatus(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst isSimple =\n\t\targs.length === 0 || args.every((arg) => arg === \"-s\" || arg === \"--short\" || arg === \"-b\" || arg === \"--branch\");\n\n\tif (!isSimple) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"status\", ...args], options);\n\t\tconst rawOut = rawText(res);\n\t\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\t\tconst cleanedLines = res.stdout\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trimEnd())\n\t\t\t.filter((line) => line.length > 0 && !line.trim().startsWith(\"(use \"));\n\t\tconst output = cleanedLines.join(\"\\n\");\n\t\treturn resultFromQuery(res, output || \"success\", 0);\n\t}\n\n\tconst res = await runGitQuery(cwd, globalOptions, [\"status\", \"--porcelain=v1\", \"-b\"], options);\n\tlet rawOut = rawText(res);\n\tif (res.status !== 0) {\n\t\tif (rawOut.includes(\"not a git repository\")) rawOut = \"fatal: not a git repository\";\n\t\treturn { output: rawOut.trim(), exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\t}\n\n\tconst lines = res.stdout.split(\"\\n\").filter((line) => line.trim().length > 0);\n\tlet branchLine = \"\";\n\tconst fileLines: string[] = [];\n\tfor (const line of lines) {\n\t\tif (line.startsWith(\"##\")) branchLine = line;\n\t\telse fileLines.push(line);\n\t}\n\n\tlet statePrefix = \"\";\n\tconst gitDirRes = await runGitQuery(cwd, globalOptions, [\"rev-parse\", \"--git-dir\"], options);\n\tif (gitDirRes.status === 0) {\n\t\tconst gitDir = resolve(cwd, gitDirRes.stdout.trim());\n\t\tconst states = detectGitState(gitDir);\n\t\tif (states.length > 0) statePrefix = `[${states.join(\", \")}]\\n`;\n\t}\n\n\tif (branchLine.includes(\"HEAD (no branch)\")) {\n\t\tconst headHashRes = await runGitQuery(cwd, globalOptions, [\"rev-parse\", \"--short\", \"HEAD\"], options);\n\t\tconst hash = headHashRes.status === 0 ? headHashRes.stdout.trim() : \"unknown\";\n\t\tbranchLine = `## HEAD (detached at ${hash})`;\n\t}\n\n\tif (fileLines.length === 0) {\n\t\treturn resultFromQuery(res, `${statePrefix}${branchLine}\\nnothing to commit, working tree clean`, 0);\n\t}\n\treturn resultFromQuery(res, `${statePrefix}${branchLine}\\n${fileLines.join(\"\\n\")}`, 0);\n}\n\nasync function handleLog(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst hasLimit = args.some(\n\t\t(arg) => /^-n\\d+$/.test(arg) || arg === \"-n\" || /^-?\\d+$/.test(arg) || arg.startsWith(\"--max-count\"),\n\t);\n\tconst hasPretty = args.some(\n\t\t(arg) => arg.startsWith(\"--pretty\") || arg.startsWith(\"--format\") || arg === \"--oneline\",\n\t);\n\n\tif (hasLimit || hasPretty) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"log\", ...args], options);\n\t\treturn resultFromQuery(res, rawText(res), res.status ?? 0);\n\t}\n\n\tconst res = await runGitQuery(cwd, globalOptions, [\"log\", \"-n\", \"10\", \"--no-merges\"], options);\n\tconst rawOut = rawText(res);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\n\tconst commits = res.stdout.split(/(?=^commit [0-9a-f]{7,40})/m).filter((commit) => commit.trim().length > 0);\n\tconst compactedCommits: string[] = [];\n\tconst trailerPrefixes = [\n\t\t\"Signed-off-by:\",\n\t\t\"Co-authored-by:\",\n\t\t\"Reported-by:\",\n\t\t\"Reviewed-by:\",\n\t\t\"Tested-by:\",\n\t\t\"Suggested-by:\",\n\t\t\"CC:\",\n\t];\n\n\tfor (const commit of commits) {\n\t\tconst lines = commit.split(\"\\n\");\n\t\tconst commitLine = lines[0];\n\t\tif (!commitLine) continue;\n\t\tconst shortCommitLine = commitLine.replace(/^commit ([0-9a-f]{7})[0-9a-f]+/, \"commit $1\");\n\t\tconst bodyLines: string[] = [];\n\t\tfor (let i = 1; i < lines.length; i++) {\n\t\t\tconst line = lines[i];\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed) continue;\n\t\t\tif (line.startsWith(\"Author:\") || line.startsWith(\"Date:\") || line.startsWith(\"Merge:\")) continue;\n\t\t\tif (trailerPrefixes.some((prefix) => trimmed.startsWith(prefix))) continue;\n\t\t\tbodyLines.push(line);\n\t\t}\n\t\tconst displayBody = bodyLines.slice(0, 3).map((line) => unicodeTruncate(line, 160));\n\t\tconst omitted = bodyLines.length - displayBody.length;\n\t\tif (omitted > 0) displayBody.push(` ... (${omitted} lines omitted)`);\n\t\tcompactedCommits.push(`${shortCommitLine}\\n${displayBody.join(\"\\n\")}`);\n\t}\n\n\treturn resultFromQuery(res, compactedCommits.join(\"\\n\\n\"), 0);\n}\n\nexport function compactDiff(diffOutput: string, maxLines = 150): { compacted: string; truncated: boolean } {\n\tconst lines = diffOutput.split(\"\\n\");\n\tconst output: string[] = [];\n\tlet linesCount = 0;\n\tlet truncated = false;\n\tlet contextBuffer: string[] = [];\n\tlet trailingContextRemaining = 0;\n\n\tfor (const line of lines) {\n\t\tif (linesCount >= maxLines) {\n\t\t\ttruncated = true;\n\t\t\tbreak;\n\t\t}\n\t\tif (\n\t\t\tline.startsWith(\"diff --git\") ||\n\t\t\tline.startsWith(\"--- \") ||\n\t\t\tline.startsWith(\"+++ \") ||\n\t\t\tline.startsWith(\"index \")\n\t\t) {\n\t\t\tcontextBuffer = [];\n\t\t\ttrailingContextRemaining = 0;\n\t\t\toutput.push(line);\n\t\t\tlinesCount++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"@@ \")) {\n\t\t\tcontextBuffer = [];\n\t\t\ttrailingContextRemaining = 0;\n\t\t\toutput.push(line);\n\t\t\tlinesCount++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"+\") || line.startsWith(\"-\")) {\n\t\t\tfor (const ctx of contextBuffer) {\n\t\t\t\tif (linesCount >= maxLines) {\n\t\t\t\t\ttruncated = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\toutput.push(ctx);\n\t\t\t\tlinesCount++;\n\t\t\t}\n\t\t\tcontextBuffer = [];\n\t\t\tif (truncated) break;\n\t\t\toutput.push(line);\n\t\t\tlinesCount++;\n\t\t\ttrailingContextRemaining = 3;\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\" \")) {\n\t\t\tif (trailingContextRemaining > 0) {\n\t\t\t\toutput.push(line);\n\t\t\t\tlinesCount++;\n\t\t\t\ttrailingContextRemaining--;\n\t\t\t} else {\n\t\t\t\tcontextBuffer.push(line);\n\t\t\t\tif (contextBuffer.length > 3) contextBuffer.shift();\n\t\t\t}\n\t\t} else {\n\t\t\toutput.push(line);\n\t\t\tlinesCount++;\n\t\t}\n\t}\n\n\treturn { compacted: output.join(\"\\n\"), truncated };\n}\n\nasync function handleDiff(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst cleanArgs = [...args];\n\tconst noCompactIndex = cleanArgs.indexOf(\"--no-compact\");\n\tconst optOut = noCompactIndex !== -1;\n\tif (optOut) cleanArgs.splice(noCompactIndex, 1);\n\n\tconst statFlags = [\"--stat\", \"--numstat\", \"--shortstat\", \"--summary\", \"--name-only\", \"--name-status\", \"--check\"];\n\tconst isStatOnly = cleanArgs.some((arg) => statFlags.includes(arg));\n\tif (optOut || isStatOnly) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"diff\", ...cleanArgs], options);\n\t\treturn resultFromQuery(res, rawText(res), res.status ?? 0);\n\t}\n\n\tconst hasDoubleDash = cleanArgs.includes(\"--\");\n\tif (!hasDoubleDash) {\n\t\tconst pathIdx = cleanArgs.findIndex((arg) => {\n\t\t\tif (arg.startsWith(\"-\")) return false;\n\t\t\tif (!(arg.includes(\"/\") || arg.includes(\".\") || existsSync(join(cwd, arg)))) return false;\n\t\t\treturn existsSync(resolve(cwd, arg));\n\t\t});\n\t\tif (pathIdx !== -1) cleanArgs.splice(pathIdx, 0, \"--\");\n\t}\n\n\tconst statRes = await runGitQuery(cwd, globalOptions, [\"diff\", \"--stat\", ...cleanArgs], options);\n\tif (statRes.status !== 0) return resultFromQuery(statRes, rawText(statRes), statRes.status ?? 1);\n\tconst diffRes = await runGitQuery(cwd, globalOptions, [\"diff\", ...cleanArgs], options);\n\tif (diffRes.status !== 0) return resultFromQuery(diffRes, rawText(diffRes), diffRes.status ?? 1);\n\n\tconst { compacted, truncated } = compactDiff(diffRes.stdout);\n\tlet output = `${statRes.stdout.trimEnd()}\\n\\n${compacted}`.trim();\n\tif (truncated) output += \"\\n\\n[Diff truncated. Re-run with: git diff --no-compact]\";\n\treturn applyOverflowDisclosure(diffRes, { output, exitCode: 0, rawOut: diffRes.stdout, rawBytes: diffRes.rawBytes });\n}\n\nasync function handleShow(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst statFlags = [\"--stat\", \"--numstat\", \"--shortstat\", \"--summary\", \"--name-only\", \"--name-status\", \"--check\"];\n\tconst hasStatOnly = args.some((arg) => statFlags.includes(arg));\n\tconst hasPretty = args.some(\n\t\t(arg) => arg.startsWith(\"--pretty\") || arg.startsWith(\"--format\") || arg === \"--oneline\",\n\t);\n\tconst hasBlob = args.some((arg) => !arg.startsWith(\"-\") && arg.includes(\":\"));\n\tif (hasStatOnly || hasPretty || hasBlob) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"show\", ...args], options);\n\t\treturn resultFromQuery(res, rawText(res), res.status ?? 0);\n\t}\n\n\tconst showRes = await runGitQuery(cwd, globalOptions, [\"show\", ...args], options);\n\tconst rawOut = rawText(showRes);\n\tif (showRes.status !== 0)\n\t\treturn { output: rawOut, exitCode: showRes.status ?? 1, rawOut, rawBytes: showRes.rawBytes };\n\n\tconst lines = showRes.stdout.split(\"\\n\");\n\tconst diffStart = lines.findIndex((line) => line.startsWith(\"diff --git\"));\n\tconst headerLines = diffStart === -1 ? lines : lines.slice(0, diffStart);\n\tconst diffLines = diffStart === -1 ? [] : lines.slice(diffStart);\n\tconst summaryLines = headerLines.filter((line) => {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) return false;\n\t\tif (line.startsWith(\"Author:\") || line.startsWith(\"Date:\") || line.startsWith(\"Merge:\")) return false;\n\t\treturn true;\n\t});\n\tconst shortSummary = summaryLines\n\t\t.slice(0, 4)\n\t\t.map((line) => unicodeTruncate(line.replace(/^commit ([0-9a-f]{7})[0-9a-f]+/, \"commit $1\"), 160));\n\tconst { compacted, truncated } = compactDiff(diffLines.join(\"\\n\"));\n\tlet output = shortSummary.join(\"\\n\");\n\tif (compacted.trim()) output += `\\n\\n${compacted}`;\n\tif (truncated) output += \"\\n\\n[Diff truncated.]\";\n\treturn resultFromQuery(showRes, output.trim(), 0);\n}\n\nasync function handlePassthroughGit(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst res = await runGitQuery(cwd, globalOptions, args, options);\n\treturn resultFromQuery(res, rawText(res, true).trim(), res.status ?? 0);\n}\n\nasync function handleAdd(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tif (args.length === 0) return handlePassthroughGit(cwd, globalOptions, [\"add\"], options);\n\tconst addRes = await runGitQuery(cwd, globalOptions, [\"add\", ...args], options);\n\tconst rawOut = rawText(addRes);\n\tif (addRes.status !== 0) return { output: rawOut, exitCode: addRes.status ?? 1, rawOut, rawBytes: addRes.rawBytes };\n\tconst statRes = await runGitQuery(cwd, globalOptions, [\"diff\", \"--cached\", \"--stat\"], options);\n\tif (statRes.status === 0 && statRes.stdout.trim().length > 0) {\n\t\treturn { output: `Staged changes:\\n${statRes.stdout.trim()}`, exitCode: 0, rawOut, rawBytes: addRes.rawBytes };\n\t}\n\treturn { output: rawOut.trim() || \"Successfully staged.\", exitCode: 0, rawOut, rawBytes: addRes.rawBytes };\n}\n\nasync function handleCommit(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst hasMsg = args.some(\n\t\t(arg) => arg === \"-m\" || arg === \"-F\" || arg.startsWith(\"--message\") || arg.startsWith(\"--file\"),\n\t);\n\tif (!hasMsg) return { output: \"\", exitCode: -100, rawOut: \"\" };\n\tconst res = await runGitQuery(cwd, globalOptions, [\"commit\", ...args], options);\n\tconst rawOut = rawText(res, true);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (rawOut.includes(\"nothing to commit\") || rawOut.includes(\"working tree clean\")) {\n\t\treturn { output: \"nothing to commit, working tree clean\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\t}\n\tconst firstLine = rawOut\n\t\t.split(\"\\n\")\n\t\t.find((line) => line.trim().length > 0)\n\t\t?.trim();\n\treturn { output: firstLine || \"Committed successfully.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handlePush(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst res = await runGitQuery(cwd, globalOptions, [\"push\", ...args], options);\n\tconst rawOut = rawText(res, true);\n\tconst outputLines = rawOut\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trimEnd())\n\t\t.filter((line) => {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed) return false;\n\t\t\treturn ![\"Writing objects:\", \"Counting objects:\", \"Delta compression\", \"Compressing objects:\", \"Total \"].some(\n\t\t\t\t(prefix) => trimmed.startsWith(prefix),\n\t\t\t);\n\t\t});\n\tif (res.status !== 0)\n\t\treturn { output: outputLines.join(\"\\n\"), exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (outputLines.some((line) => line.includes(\"Everything up-to-date\"))) {\n\t\treturn { output: \"Everything up-to-date.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\t}\n\tconst remoteMessages = outputLines.filter((line) => line.trim().startsWith(\"remote:\"));\n\tconst pushDetail = outputLines.find((line) => line.includes(\"->\"));\n\tconst summary = pushDetail ? `Pushed: ${pushDetail.trim()}` : \"Push successful.\";\n\treturn { output: [...remoteMessages, summary].join(\"\\n\"), exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handlePull(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst res = await runGitQuery(cwd, globalOptions, [\"pull\", ...args], options);\n\tconst rawOut = rawText(res, true);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (rawOut.includes(\"Already up to date.\"))\n\t\treturn { output: \"Already up to date.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\tconst lines = rawOut.split(\"\\n\");\n\tconst summary = lines.filter(\n\t\t(line) => line.includes(\"Fast-forward\") || line.includes(\"file changed\") || line.includes(\"files changed\"),\n\t);\n\treturn { output: summary.join(\"\\n\") || \"Pull successful.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handleFetch(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst res = await runGitQuery(cwd, globalOptions, [\"fetch\", ...args], options);\n\tconst rawOut = rawText(res, true);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tconst refs = rawOut\n\t\t.split(\"\\n\")\n\t\t.filter((line) => line.includes(\"[new branch]\") || line.includes(\"[new tag]\") || line.includes(\"->\"));\n\treturn {\n\t\toutput: refs.length\n\t\t\t? `Fetched:\\n${refs.map((line) => line.trim()).join(\"\\n\")}`\n\t\t\t: \"Fetch successful (no new refs).\",\n\t\texitCode: 0,\n\t\trawOut,\n\t\trawBytes: res.rawBytes,\n\t};\n}\n\nasync function handleBranch(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tif (args.includes(\"--show-current\")) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"branch\", \"--show-current\"], options);\n\t\treturn { output: res.stdout.trim(), exitCode: res.status ?? 0, rawOut: rawText(res), rawBytes: res.rawBytes };\n\t}\n\tconst isWrite = args.some(\n\t\t(arg) =>\n\t\t\targ === \"-d\" || arg === \"-D\" || arg === \"-m\" || arg === \"-M\" || (!arg.startsWith(\"-\") && args.length === 1),\n\t);\n\tif (isWrite) {\n\t\tconst res = await runGitQuery(cwd, globalOptions, [\"branch\", ...args], options);\n\t\tconst rawOut = rawText(res);\n\t\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\t\treturn { output: rawOut.trim() || \"Branch updated successfully.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\t}\n\tconst res = await runGitQuery(cwd, globalOptions, [\"branch\", \"--no-color\", ...args], options);\n\tconst rawOut = rawText(res);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tconst lines = res.stdout.split(\"\\n\").filter((line) => line.trim().length > 0);\n\tconst remoteBranches = lines.filter((line) => line.includes(\"remotes/\"));\n\tconst localBranches = lines.filter((line) => !line.includes(\"remotes/\"));\n\tconst remoteDisplay = remoteBranches.slice(0, 5);\n\tconst omitted = remoteBranches.length - remoteDisplay.length;\n\tif (omitted > 0) remoteDisplay.push(` remotes/... (${omitted} more remote branches)`);\n\treturn { output: [...localBranches, ...remoteDisplay].join(\"\\n\"), exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handleStash(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst sub = args[0] || \"push\";\n\tconst res = await runGitQuery(cwd, globalOptions, [\"stash\", ...args], options);\n\tconst rawOut = rawText(res);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (sub === \"list\")\n\t\treturn { output: res.stdout.trim() || \"No stashes found.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\tif (sub === \"show\") {\n\t\tconst { compacted, truncated } = compactDiff(res.stdout);\n\t\treturn applyOverflowDisclosure(res, {\n\t\t\toutput: `${compacted.trim()}${truncated ? \"\\n\\n[Diff truncated.]\" : \"\"}`,\n\t\t\texitCode: 0,\n\t\t\trawOut,\n\t\t\trawBytes: res.rawBytes,\n\t\t});\n\t}\n\tif (res.stdout.includes(\"No local changes to save\"))\n\t\treturn { output: \"No local changes to save.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\tconst firstLine = res.stdout\n\t\t.split(\"\\n\")\n\t\t.find((line) => line.trim().length > 0)\n\t\t?.trim();\n\treturn { output: firstLine || \"Stash successful.\", exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nasync function handleWorktree(\n\tcwd: string,\n\tglobalOptions: string[],\n\targs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tconst sub = args[0] || \"list\";\n\tconst res = await runGitQuery(cwd, globalOptions, [\"worktree\", ...(sub === \"list\" ? [\"list\"] : args)], options);\n\tconst rawOut = rawText(res, true);\n\tif (res.status !== 0) return { output: rawOut, exitCode: res.status ?? 1, rawOut, rawBytes: res.rawBytes };\n\tif (sub !== \"list\") return { output: rawOut.trim(), exitCode: 0, rawOut, rawBytes: res.rawBytes };\n\tconst home = process.env.HOME || \"\";\n\tconst output = res.stdout\n\t\t.split(\"\\n\")\n\t\t.map((line) => (home && line.startsWith(home) ? `~${line.slice(home.length)}` : line))\n\t\t.join(\"\\n\")\n\t\t.trim();\n\treturn { output, exitCode: 0, rawOut, rawBytes: res.rawBytes };\n}\n\nexport async function executeFilteredGit(\n\tcwd: string,\n\tsubcommand: string,\n\tglobalOptions: string[],\n\tsubcommandArgs: string[],\n\toptions?: GitFilterOptions,\n): Promise<FilterResult> {\n\tswitch (subcommand) {\n\t\tcase \"status\":\n\t\t\treturn handleStatus(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"log\":\n\t\t\treturn handleLog(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"diff\":\n\t\t\treturn handleDiff(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"show\":\n\t\t\treturn handleShow(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"add\":\n\t\t\treturn handleAdd(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"commit\":\n\t\t\treturn handleCommit(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"push\":\n\t\t\treturn handlePush(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"pull\":\n\t\t\treturn handlePull(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"branch\":\n\t\t\treturn handleBranch(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"fetch\":\n\t\t\treturn handleFetch(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"stash\":\n\t\t\treturn handleStash(cwd, globalOptions, subcommandArgs, options);\n\t\tcase \"worktree\":\n\t\t\treturn handleWorktree(cwd, globalOptions, subcommandArgs, options);\n\t\tdefault:\n\t\t\treturn { output: \"\", exitCode: -100, rawOut: \"\" };\n\t}\n}\n\nexport function makeGitCommandForDisplay(globalOptions: string[], subcommand: string, args: string[]): string {\n\treturn gitCommand(globalOptions, [subcommand, ...args]);\n}\n"]}
@@ -25,12 +25,43 @@ export interface ReadOperations {
25
25
  access: (absolutePath: string) => Promise<void>;
26
26
  /** Detect image MIME type, return null or undefined for non-images */
27
27
  detectImageMimeType?: (absolutePath: string) => Promise<string | null | undefined>;
28
+ /** File size in bytes, used to decide between whole-file and sliced reads. */
29
+ stat?: (absolutePath: string) => Promise<{
30
+ size: number;
31
+ }>;
32
+ /**
33
+ * Stream a slice of lines out of the file with bounded memory. Any region of an
34
+ * arbitrarily large file stays reachable in batches via offset continuation.
35
+ */
36
+ readLineSlice?: (absolutePath: string, options: LineSliceOptions) => Promise<LineSlice>;
37
+ /** Count lines by streaming (bounded memory); used to resolve tail reads on oversized files. */
38
+ countLines?: (absolutePath: string) => Promise<number>;
39
+ }
40
+ export interface LineSliceOptions {
41
+ /** 0-based line to start collecting at. */
42
+ startLine: number;
43
+ /** Maximum number of lines to collect. */
44
+ maxLines: number;
45
+ /** Maximum total characters to collect across lines. */
46
+ maxChars: number;
47
+ }
48
+ export interface LineSlice {
49
+ lines: {
50
+ text: string;
51
+ originalIndex: number;
52
+ }[];
53
+ /** True when the end of the file was reached while collecting. */
54
+ reachedEnd: boolean;
28
55
  }
29
56
  export interface ReadToolOptions {
30
57
  /** Whether to auto-resize images to 2000x2000 max. Default: true */
31
58
  autoResizeImages?: boolean;
32
59
  /** Custom operations for file reading. Default: local filesystem */
33
60
  operations?: ReadOperations;
61
+ /** Whole-file load budget for text reads; larger files stream line slices instead. Default 16 MiB. */
62
+ maxTextReadBytes?: number;
63
+ /** Pathology guard for image reads; larger images return downscale guidance. Default 128 MiB. */
64
+ maxImageReadBytes?: number;
34
65
  }
35
66
  export declare function createReadToolDefinition(cwd: string, options?: ReadToolOptions): ToolDefinition<typeof readSchema, ReadToolDetails | undefined>;
36
67
  export declare function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/core/tools/read.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK3D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAO5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAAoD,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAEtH,QAAA,MAAM,UAAU;;;;;;;EAWd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAgBD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,+CAA+C;IAC/C,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACnF;AAQD,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AA4ID,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CA4PhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG","sourcesContent":["import { basename, dirname, isAbsolute, relative, resolve as resolvePath, sep } from \"node:path\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport type { Api, ImageContent, Model, TextContent } from \"@caupulican/pi-ai\";\nimport { Text } from \"@caupulican/pi-tui\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, readFile as fsReadFile } from \"fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { getReadmePath } from \"../../config.ts\";\nimport { keyHint, keyText } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { getLanguageFromPath, highlightCode, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { formatDimensionNote, resizeImage } from \"../../utils/image-resize.ts\";\nimport { detectSupportedImageMimeTypeFromFile } from \"../../utils/mime.ts\";\nimport { formatPathRelativeToCwdOrAbsolute } from \"../../utils/paths.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport { resolveReadPathAsync, resolveToCwd } from \"./path-utils.ts\";\nimport { getTextOutput, renderToolPath, replaceTabs, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nconst readSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to read (relative or absolute)\" }),\n\toffset: Type.Optional(Type.Number({ description: \"Line number to start reading from (1-indexed)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of lines to read\" })),\n\tlineNumbers: Type.Optional(Type.Boolean({ description: \"Include line numbers in the output\" })),\n\ttail: Type.Optional(Type.Number({ description: \"Number of lines to read from the end of the file\" })),\n\tfilter: Type.Optional(\n\t\tType.Union([Type.Literal(\"none\"), Type.Literal(\"minimal\"), Type.Literal(\"aggressive\")], {\n\t\t\tdescription: \"Safe text filtering level (none, minimal, aggressive)\",\n\t\t}),\n\t),\n});\n\nexport type ReadToolInput = Static<typeof readSchema>;\n\nexport interface ReadToolDetails {\n\ttruncation?: TruncationResult;\n}\n\ninterface CompactReadClassification {\n\tkind: \"docs\" | \"resource\" | \"skill\";\n\tlabel: string;\n}\n\nconst COMPACT_RESOURCE_FILE_NAMES = new Set([\n\t\"AGENTS.md\",\n\t\"AGENTS.MD\",\n\t\"CLAUDE.md\",\n\t\"CLAUDE.MD\",\n\t\"GEMINI.md\",\n\t\"GEMINI.MD\",\n]);\n\n/**\n * Pluggable operations for the read tool.\n * Override these to delegate file reading to remote systems (for example SSH).\n */\nexport interface ReadOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Check if file is readable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n\t/** Detect image MIME type, return null or undefined for non-images */\n\tdetectImageMimeType?: (absolutePath: string) => Promise<string | null | undefined>;\n}\n\nconst defaultReadOperations: ReadOperations = {\n\treadFile: (path) => fsReadFile(path),\n\taccess: (path) => fsAccess(path, constants.R_OK),\n\tdetectImageMimeType: detectSupportedImageMimeTypeFromFile,\n};\n\nexport interface ReadToolOptions {\n\t/** Whether to auto-resize images to 2000x2000 max. Default: true */\n\tautoResizeImages?: boolean;\n\t/** Custom operations for file reading. Default: local filesystem */\n\toperations?: ReadOperations;\n}\n\ntype ReadRenderArgs = { path?: string; file_path?: string; offset?: number; limit?: number };\n\nfunction formatReadLineRange(args: ReadRenderArgs | undefined, theme: Theme): string {\n\tif (args?.offset === undefined && args?.limit === undefined) return \"\";\n\tconst startLine = args.offset ?? 1;\n\tconst endLine = args.limit !== undefined ? startLine + args.limit - 1 : \"\";\n\treturn theme.fg(\"warning\", `:${startLine}${endLine ? `-${endLine}` : \"\"}`);\n}\n\nfunction formatReadCall(args: ReadRenderArgs | undefined, theme: Theme, cwd: string): string {\n\tconst pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);\n\treturn `${theme.fg(\"toolTitle\", theme.bold(\"read\"))} ${pathDisplay}${formatReadLineRange(args, theme)}`;\n}\n\nfunction trimTrailingEmptyLines(lines: string[]): string[] {\n\tlet end = lines.length;\n\twhile (end > 0 && lines[end - 1] === \"\") {\n\t\tend--;\n\t}\n\treturn lines.slice(0, end);\n}\n\nfunction getNonVisionImageNote(model: Model<Api> | undefined): string | undefined {\n\tif (!model || model.input.includes(\"image\")) {\n\t\treturn undefined;\n\t}\n\treturn \"[Current model does not support images. The image will be omitted from this request.]\";\n}\n\nfunction toPosixPath(filePath: string): string {\n\treturn filePath.split(sep).join(\"/\");\n}\n\nfunction getPiDocsClassification(absolutePath: string): CompactReadClassification | undefined {\n\tconst packageRoot = dirname(getReadmePath());\n\tconst relativePath = relative(resolvePath(packageRoot), resolvePath(absolutePath));\n\tif (\n\t\trelativePath === \"\" ||\n\t\trelativePath === \"..\" ||\n\t\trelativePath.startsWith(`..${sep}`) ||\n\t\tisAbsolute(relativePath)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst label = toPosixPath(relativePath);\n\tif (label === \"README.md\" || label.startsWith(\"docs/\") || label.startsWith(\"examples/\")) {\n\t\treturn { kind: \"docs\", label };\n\t}\n\treturn undefined;\n}\n\nfunction getCompactReadClassification(\n\targs: ReadRenderArgs | undefined,\n\tcwd: string,\n): CompactReadClassification | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tif (!rawPath) return undefined;\n\n\tconst absolutePath = resolveToCwd(rawPath, cwd);\n\tconst fileName = basename(absolutePath);\n\tif (fileName === \"SKILL.md\") {\n\t\treturn { kind: \"skill\", label: basename(dirname(absolutePath)) || fileName };\n\t}\n\n\tconst docsClassification = getPiDocsClassification(absolutePath);\n\tif (docsClassification) return docsClassification;\n\n\tif (COMPACT_RESOURCE_FILE_NAMES.has(fileName)) {\n\t\treturn { kind: \"resource\", label: formatPathRelativeToCwdOrAbsolute(absolutePath, cwd) };\n\t}\n\n\treturn undefined;\n}\n\nfunction formatCompactReadCall(\n\tclassification: CompactReadClassification,\n\targs: ReadRenderArgs | undefined,\n\ttheme: Theme,\n): string {\n\tconst expandHint = theme.fg(\"dim\", ` (${keyText(\"app.tools.expand\")} to expand)`);\n\tif (classification.kind === \"skill\") {\n\t\treturn (\n\t\t\ttheme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m `) +\n\t\t\ttheme.fg(\"customMessageText\", classification.label) +\n\t\t\tformatReadLineRange(args, theme) +\n\t\t\texpandHint\n\t\t);\n\t}\n\n\treturn (\n\t\ttheme.fg(\"toolTitle\", theme.bold(`read ${classification.kind}`)) +\n\t\t\" \" +\n\t\ttheme.fg(\"accent\", classification.label) +\n\t\tformatReadLineRange(args, theme) +\n\t\texpandHint\n\t);\n}\n\nfunction formatReadResult(\n\targs: ReadRenderArgs | undefined,\n\tresult: { content: (TextContent | ImageContent)[]; details?: ReadToolDetails },\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n\t_cwd: string,\n\tisError: boolean,\n): string {\n\tif (!options.expanded && !isError) {\n\t\treturn \"\";\n\t}\n\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst output = getTextOutput(result, showImages);\n\tconst lang = rawPath ? getLanguageFromPath(rawPath) : undefined;\n\tconst renderedLines = lang ? highlightCode(replaceTabs(output), lang) : output.split(\"\\n\");\n\tconst lines = trimTrailingEmptyLines(renderedLines);\n\tconst maxLines = options.expanded ? lines.length : 10;\n\tconst displayLines = lines.slice(0, maxLines);\n\tconst remaining = lines.length - maxLines;\n\tlet text = `\\n${displayLines.map((line) => (lang ? replaceTabs(line) : theme.fg(\"toolOutput\", replaceTabs(line)))).join(\"\\n\")}`;\n\tif (remaining > 0) {\n\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t}\n\n\tconst truncation = result.details?.truncation;\n\tif (truncation?.truncated) {\n\t\tif (truncation.firstLineExceedsLimit) {\n\t\t\ttext += `\\n${theme.fg(\"warning\", `[First line exceeds ${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit]`)}`;\n\t\t} else if (truncation.truncatedBy === \"lines\") {\n\t\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${truncation.maxLines ?? DEFAULT_MAX_LINES} line limit)]`)}`;\n\t\t} else {\n\t\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)]`)}`;\n\t\t}\n\t}\n\treturn text;\n}\n\nexport function createReadToolDefinition(\n\tcwd: string,\n\toptions?: ReadToolOptions,\n): ToolDefinition<typeof readSchema, ReadToolDetails | undefined> {\n\tconst autoResizeImages = options?.autoResizeImages ?? true;\n\tconst ops = options?.operations ?? defaultReadOperations;\n\treturn {\n\t\tname: \"read\",\n\t\tlabel: \"read\",\n\t\tdescription: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,\n\t\tpromptSnippet: \"Read file contents\",\n\t\tpromptGuidelines: [\"Use read to examine files instead of cat or sed.\"],\n\t\tparameters: readSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\toffset,\n\t\t\t\tlimit,\n\t\t\t\tlineNumbers,\n\t\t\t\ttail,\n\t\t\t\tfilter,\n\t\t\t}: {\n\t\t\t\tpath: string;\n\t\t\t\toffset?: number;\n\t\t\t\tlimit?: number;\n\t\t\t\tlineNumbers?: boolean;\n\t\t\t\ttail?: number;\n\t\t\t\tfilter?: \"none\" | \"minimal\" | \"aggressive\";\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\tctx?,\n\t\t) {\n\t\t\treturn new Promise<{ content: (TextContent | ImageContent)[]; details: ReadToolDetails | undefined }>(\n\t\t\t\t(resolve, reject) => {\n\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet aborted = false;\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t};\n\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst absolutePath = await resolveReadPathAsync(path, cwd);\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\t// Check if file exists and is readable.\n\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tconst mimeType = ops.detectImageMimeType ? await ops.detectImageMimeType(absolutePath) : undefined;\n\t\t\t\t\t\t\tlet content: (TextContent | ImageContent)[];\n\t\t\t\t\t\t\tlet details: ReadToolDetails | undefined;\n\t\t\t\t\t\t\tconst nonVisionImageNote = getNonVisionImageNote(ctx?.model);\n\t\t\t\t\t\t\tif (mimeType) {\n\t\t\t\t\t\t\t\t// Read image as binary.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tif (autoResizeImages) {\n\t\t\t\t\t\t\t\t\t// Resize image if needed before sending it back to the model.\n\t\t\t\t\t\t\t\t\tconst resized = await resizeImage(buffer, mimeType);\n\t\t\t\t\t\t\t\t\tif (!resized) {\n\t\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${mimeType}]\\n[Image omitted: could not be resized below the inline image size limit.]`;\n\t\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\t\tcontent = [{ type: \"text\", text: textNote }];\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst dimensionNote = formatDimensionNote(resized);\n\t\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${resized.mimeType}]`;\n\t\t\t\t\t\t\t\t\t\tif (dimensionNote) textNote += `\\n${dimensionNote}`;\n\t\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\t\tcontent = [\n\t\t\t\t\t\t\t\t\t\t\t{ type: \"text\", text: textNote },\n\t\t\t\t\t\t\t\t\t\t\t{ type: \"image\", data: resized.data, mimeType: resized.mimeType },\n\t\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${mimeType}]`;\n\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\tcontent = [\n\t\t\t\t\t\t\t\t\t\t{ type: \"text\", text: textNote },\n\t\t\t\t\t\t\t\t\t\t{ type: \"image\", data: buffer.toString(\"base64\"), mimeType },\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Read text content.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tconst textContent = buffer.toString(\"utf-8\");\n\t\t\t\t\t\t\t\tconst allLines = textContent.split(\"\\n\");\n\t\t\t\t\t\t\t\tconst totalFileLines = allLines.length;\n\t\t\t\t\t\t\t\t// Apply offset/tail if specified. Convert from 1-indexed input to 0-indexed array access.\n\t\t\t\t\t\t\t\tlet startLine = 0;\n\t\t\t\t\t\t\t\tlet userLimitedLines = limit;\n\t\t\t\t\t\t\t\tif (offset !== undefined) {\n\t\t\t\t\t\t\t\t\tstartLine = Math.max(0, offset - 1);\n\t\t\t\t\t\t\t\t} else if (tail !== undefined) {\n\t\t\t\t\t\t\t\t\tstartLine = Math.max(0, totalFileLines - tail);\n\t\t\t\t\t\t\t\t\tif (limit === undefined) {\n\t\t\t\t\t\t\t\t\t\tuserLimitedLines = tail;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst startLineDisplay = startLine + 1;\n\t\t\t\t\t\t\t\t// Check if offset is out of bounds.\n\t\t\t\t\t\t\t\tif (startLine >= allLines.length && allLines.length > 0) {\n\t\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t\t`Offset ${startLine + 1} is beyond end of file (${allLines.length} lines total)`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tlet slicedLines =\n\t\t\t\t\t\t\t\t\tuserLimitedLines !== undefined\n\t\t\t\t\t\t\t\t\t\t? allLines\n\t\t\t\t\t\t\t\t\t\t\t\t.map((line, idx) => ({ text: line, originalIndex: idx + 1 }))\n\t\t\t\t\t\t\t\t\t\t\t\t.slice(startLine, startLine + userLimitedLines)\n\t\t\t\t\t\t\t\t\t\t: allLines.map((line, idx) => ({ text: line, originalIndex: idx + 1 })).slice(startLine);\n\n\t\t\t\t\t\t\t\t// Safe text filtering\n\t\t\t\t\t\t\t\tlet canFilter = true;\n\t\t\t\t\t\t\t\tif (mimeType) {\n\t\t\t\t\t\t\t\t\tcanFilter = false;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tconst fileNameLower = path.toLowerCase();\n\t\t\t\t\t\t\t\t\tconst unsafeExtensions = [\n\t\t\t\t\t\t\t\t\t\t\".json\",\n\t\t\t\t\t\t\t\t\t\t\".jsonl\",\n\t\t\t\t\t\t\t\t\t\t\".yml\",\n\t\t\t\t\t\t\t\t\t\t\".yaml\",\n\t\t\t\t\t\t\t\t\t\t\".toml\",\n\t\t\t\t\t\t\t\t\t\t\".xml\",\n\t\t\t\t\t\t\t\t\t\t\".csv\",\n\t\t\t\t\t\t\t\t\t\t\".tsv\",\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\tif (unsafeExtensions.some((ext) => fileNameLower.endsWith(ext))) {\n\t\t\t\t\t\t\t\t\t\tcanFilter = false;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tJSON.parse(textContent);\n\t\t\t\t\t\t\t\t\t\t\tcanFilter = false;\n\t\t\t\t\t\t\t\t\t\t} catch {}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (canFilter && filter && filter !== \"none\") {\n\t\t\t\t\t\t\t\t\tconst filtered: typeof slicedLines = [];\n\t\t\t\t\t\t\t\t\tif (filter === \"minimal\") {\n\t\t\t\t\t\t\t\t\t\tlet consecutiveBlank = 0;\n\t\t\t\t\t\t\t\t\t\tfor (const item of slicedLines) {\n\t\t\t\t\t\t\t\t\t\t\tconst trimmed = item.text.trimEnd();\n\t\t\t\t\t\t\t\t\t\t\tif (trimmed === \"\") {\n\t\t\t\t\t\t\t\t\t\t\t\tconsecutiveBlank++;\n\t\t\t\t\t\t\t\t\t\t\t\tif (consecutiveBlank <= 1) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tfiltered.push({ text: \"\", originalIndex: item.originalIndex });\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\tconsecutiveBlank = 0;\n\t\t\t\t\t\t\t\t\t\t\t\tfiltered.push({ text: trimmed, originalIndex: item.originalIndex });\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\twhile (filtered.length > 0 && filtered[filtered.length - 1].text === \"\") {\n\t\t\t\t\t\t\t\t\t\t\tfiltered.pop();\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else if (filter === \"aggressive\") {\n\t\t\t\t\t\t\t\t\t\tfor (const item of slicedLines) {\n\t\t\t\t\t\t\t\t\t\t\tconst trimmed = item.text.trimEnd();\n\t\t\t\t\t\t\t\t\t\t\tconst trimmedStart = trimmed.trimStart();\n\t\t\t\t\t\t\t\t\t\t\tif (trimmedStart === \"\") {\n\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\ttrimmedStart.startsWith(\"//\") ||\n\t\t\t\t\t\t\t\t\t\t\t\ttrimmedStart.startsWith(\"#\") ||\n\t\t\t\t\t\t\t\t\t\t\t\t(trimmedStart.startsWith(\"/*\") && trimmedStart.endsWith(\"*/\"))\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tfiltered.push({ text: trimmed, originalIndex: item.originalIndex });\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// If filtering would empty a non-empty list, keep original\n\t\t\t\t\t\t\t\t\tconst isOriginalNotEmpty = slicedLines.some((item) => item.text.trim().length > 0);\n\t\t\t\t\t\t\t\t\tconst isFilteredEmpty = filtered.every((item) => item.text.trim().length === 0);\n\t\t\t\t\t\t\t\t\tif (isOriginalNotEmpty && isFilteredEmpty) {\n\t\t\t\t\t\t\t\t\t\t// Fallback to slicedLines\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tslicedLines = filtered;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst finalLines = slicedLines.map((item) =>\n\t\t\t\t\t\t\t\t\tlineNumbers ? `${item.originalIndex}: ${item.text}` : item.text,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst selectedContent = finalLines.join(\"\\n\");\n\n\t\t\t\t\t\t\t\t// Apply truncation, respecting both line and byte limits.\n\t\t\t\t\t\t\t\tconst truncation = truncateHead(selectedContent);\n\t\t\t\t\t\t\t\tlet outputText: string;\n\t\t\t\t\t\t\t\tif (truncation.firstLineExceedsLimit) {\n\t\t\t\t\t\t\t\t\t// First line alone exceeds the byte limit. Point the model at a bash fallback.\n\t\t\t\t\t\t\t\t\tconst firstLineSize = formatSize(Buffer.byteLength(allLines[startLine], \"utf-8\"));\n\t\t\t\t\t\t\t\t\toutputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${path} | head -c ${DEFAULT_MAX_BYTES}]`;\n\t\t\t\t\t\t\t\t\tdetails = { truncation };\n\t\t\t\t\t\t\t\t} else if (truncation.truncated) {\n\t\t\t\t\t\t\t\t\t// Truncation occurred. Build an actionable continuation notice.\n\t\t\t\t\t\t\t\t\tconst endLineDisplay = startLineDisplay + truncation.outputLines - 1;\n\t\t\t\t\t\t\t\t\tconst nextOffset = endLineDisplay + 1;\n\t\t\t\t\t\t\t\t\toutputText = truncation.content;\n\t\t\t\t\t\t\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\t\t\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}. Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines} (${formatSize(DEFAULT_MAX_BYTES)} limit). Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdetails = { truncation };\n\t\t\t\t\t\t\t\t} else if (userLimitedLines !== undefined && startLine + userLimitedLines < allLines.length) {\n\t\t\t\t\t\t\t\t\t// User-specified limit stopped early, but the file still has more content.\n\t\t\t\t\t\t\t\t\tconst remaining = allLines.length - (startLine + userLimitedLines);\n\t\t\t\t\t\t\t\t\tconst nextOffset = startLine + userLimitedLines + 1;\n\t\t\t\t\t\t\t\t\toutputText = `${truncation.content}\\n\\n[${remaining} more lines in file. Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// No truncation and no remaining user-limited content.\n\t\t\t\t\t\t\t\t\toutputText = truncation.content;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontent = [{ type: \"text\", text: outputText }];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tresolve({ content, details });\n\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tif (!aborted) reject(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\tconst classification = !context.expanded ? getCompactReadClassification(args, context.cwd) : undefined;\n\t\t\ttext.setText(\n\t\t\t\tclassification\n\t\t\t\t\t? formatCompactReadCall(classification, args, theme)\n\t\t\t\t\t: formatReadCall(args, theme, context.cwd),\n\t\t\t);\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(\n\t\t\t\tformatReadResult(context.args, result, options, theme, context.showImages, context.cwd, context.isError),\n\t\t\t);\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema> {\n\treturn wrapToolDefinition(createReadToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/core/tools/read.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK3D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAO5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAAoD,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAEtH,QAAA,MAAM,UAAU;;;;;;;EAWd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAgBD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,qCAAqC;IACrC,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,+CAA+C;IAC/C,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACnF,8EAA8E;IAC9E,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxF,gGAAgG;IAChG,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,gBAAgB;IAChC,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjD,kEAAkE;IAClE,UAAU,EAAE,OAAO,CAAC;CACpB;AA8ED,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,sGAAsG;IACtG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA4ID,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CA0ThE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG","sourcesContent":["import { basename, dirname, isAbsolute, relative, resolve as resolvePath, sep } from \"node:path\";\nimport { StringDecoder } from \"node:string_decoder\";\nimport type { AgentTool } from \"@caupulican/pi-agent-core\";\nimport type { Api, ImageContent, Model, TextContent } from \"@caupulican/pi-ai\";\nimport { Text } from \"@caupulican/pi-tui\";\nimport { constants } from \"fs\";\nimport { access as fsAccess, open as fsOpen, readFile as fsReadFile, stat as fsStat } from \"fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { getReadmePath } from \"../../config.ts\";\nimport { keyHint, keyText } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { getLanguageFromPath, highlightCode, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { formatDimensionNote, resizeImage } from \"../../utils/image-resize.ts\";\nimport { detectSupportedImageMimeTypeFromFile } from \"../../utils/mime.ts\";\nimport { formatPathRelativeToCwdOrAbsolute } from \"../../utils/paths.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport { resolveReadPathAsync, resolveToCwd } from \"./path-utils.ts\";\nimport { getTextOutput, renderToolPath, replaceTabs, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nconst readSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to read (relative or absolute)\" }),\n\toffset: Type.Optional(Type.Number({ description: \"Line number to start reading from (1-indexed)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of lines to read\" })),\n\tlineNumbers: Type.Optional(Type.Boolean({ description: \"Include line numbers in the output\" })),\n\ttail: Type.Optional(Type.Number({ description: \"Number of lines to read from the end of the file\" })),\n\tfilter: Type.Optional(\n\t\tType.Union([Type.Literal(\"none\"), Type.Literal(\"minimal\"), Type.Literal(\"aggressive\")], {\n\t\t\tdescription: \"Safe text filtering level (none, minimal, aggressive)\",\n\t\t}),\n\t),\n});\n\nexport type ReadToolInput = Static<typeof readSchema>;\n\nexport interface ReadToolDetails {\n\ttruncation?: TruncationResult;\n}\n\ninterface CompactReadClassification {\n\tkind: \"docs\" | \"resource\" | \"skill\";\n\tlabel: string;\n}\n\nconst COMPACT_RESOURCE_FILE_NAMES = new Set([\n\t\"AGENTS.md\",\n\t\"AGENTS.MD\",\n\t\"CLAUDE.md\",\n\t\"CLAUDE.MD\",\n\t\"GEMINI.md\",\n\t\"GEMINI.MD\",\n]);\n\n/**\n * Pluggable operations for the read tool.\n * Override these to delegate file reading to remote systems (for example SSH).\n */\nexport interface ReadOperations {\n\t/** Read file contents as a Buffer */\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\t/** Check if file is readable (throw if not) */\n\taccess: (absolutePath: string) => Promise<void>;\n\t/** Detect image MIME type, return null or undefined for non-images */\n\tdetectImageMimeType?: (absolutePath: string) => Promise<string | null | undefined>;\n\t/** File size in bytes, used to decide between whole-file and sliced reads. */\n\tstat?: (absolutePath: string) => Promise<{ size: number }>;\n\t/**\n\t * Stream a slice of lines out of the file with bounded memory. Any region of an\n\t * arbitrarily large file stays reachable in batches via offset continuation.\n\t */\n\treadLineSlice?: (absolutePath: string, options: LineSliceOptions) => Promise<LineSlice>;\n\t/** Count lines by streaming (bounded memory); used to resolve tail reads on oversized files. */\n\tcountLines?: (absolutePath: string) => Promise<number>;\n}\n\nexport interface LineSliceOptions {\n\t/** 0-based line to start collecting at. */\n\tstartLine: number;\n\t/** Maximum number of lines to collect. */\n\tmaxLines: number;\n\t/** Maximum total characters to collect across lines. */\n\tmaxChars: number;\n}\n\nexport interface LineSlice {\n\tlines: { text: string; originalIndex: number }[];\n\t/** True when the end of the file was reached while collecting. */\n\treachedEnd: boolean;\n}\n\nconst SLICE_SCAN_CHUNK_BYTES = 1024 * 1024;\n\nasync function scanLines(\n\tabsolutePath: string,\n\tonLine: (text: string | undefined, index: number) => boolean,\n): Promise<void> {\n\tconst handle = await fsOpen(absolutePath, \"r\");\n\ttry {\n\t\tconst decoder = new StringDecoder(\"utf8\");\n\t\tconst buffer = Buffer.allocUnsafe(SLICE_SCAN_CHUNK_BYTES);\n\t\tlet pending = \"\";\n\t\tlet index = 0;\n\t\twhile (true) {\n\t\t\tconst { bytesRead } = await handle.read(buffer, 0, buffer.length, null);\n\t\t\tif (bytesRead === 0) break;\n\t\t\tpending += decoder.write(buffer.subarray(0, bytesRead));\n\t\t\tlet lineStart = 0;\n\t\t\tlet newlineIndex = pending.indexOf(\"\\n\", lineStart);\n\t\t\twhile (newlineIndex !== -1) {\n\t\t\t\tif (!onLine(pending.slice(lineStart, newlineIndex), index++)) return;\n\t\t\t\tlineStart = newlineIndex + 1;\n\t\t\t\tnewlineIndex = pending.indexOf(\"\\n\", lineStart);\n\t\t\t}\n\t\t\tpending = pending.slice(lineStart);\n\t\t}\n\t\tpending += decoder.end();\n\t\tonLine(pending, index);\n\t} finally {\n\t\tawait handle.close();\n\t}\n}\n\nasync function readLocalLineSlice(absolutePath: string, options: LineSliceOptions): Promise<LineSlice> {\n\tconst lines: { text: string; originalIndex: number }[] = [];\n\tlet collectedChars = 0;\n\tlet sawMore = false;\n\tawait scanLines(absolutePath, (text, index) => {\n\t\tif (text === undefined) return false;\n\t\tif (index < options.startLine) return true;\n\t\tif (lines.length >= options.maxLines || collectedChars > options.maxChars) {\n\t\t\tsawMore = true;\n\t\t\treturn false;\n\t\t}\n\t\tlines.push({ text, originalIndex: index + 1 });\n\t\tcollectedChars += text.length;\n\t\treturn true;\n\t});\n\treturn { lines, reachedEnd: !sawMore };\n}\n\nasync function countLocalLines(absolutePath: string): Promise<number> {\n\tlet count = 0;\n\tawait scanLines(absolutePath, () => {\n\t\tcount++;\n\t\treturn true;\n\t});\n\treturn count;\n}\n\nconst defaultReadOperations: ReadOperations = {\n\treadFile: (path) => fsReadFile(path),\n\taccess: (path) => fsAccess(path, constants.R_OK),\n\tdetectImageMimeType: detectSupportedImageMimeTypeFromFile,\n\tstat: async (path) => ({ size: (await fsStat(path)).size }),\n\treadLineSlice: readLocalLineSlice,\n\tcountLines: countLocalLines,\n};\n\n// Loading a whole file before truncation lets a single giant file spike the heap\n// to its full size. Beyond these budgets, text reads stream line slices (every\n// region stays reachable in batches — lossless). The image budget is deliberately\n// far above any real screenshot/photo so quality-degrading workarounds are never\n// needed in practice; it only guards against pathological files.\nconst DEFAULT_MAX_TEXT_READ_BYTES = 16 * 1024 * 1024;\nconst DEFAULT_MAX_IMAGE_READ_BYTES = 128 * 1024 * 1024;\n\nexport interface ReadToolOptions {\n\t/** Whether to auto-resize images to 2000x2000 max. Default: true */\n\tautoResizeImages?: boolean;\n\t/** Custom operations for file reading. Default: local filesystem */\n\toperations?: ReadOperations;\n\t/** Whole-file load budget for text reads; larger files stream line slices instead. Default 16 MiB. */\n\tmaxTextReadBytes?: number;\n\t/** Pathology guard for image reads; larger images return downscale guidance. Default 128 MiB. */\n\tmaxImageReadBytes?: number;\n}\n\ntype ReadRenderArgs = { path?: string; file_path?: string; offset?: number; limit?: number };\n\nfunction formatReadLineRange(args: ReadRenderArgs | undefined, theme: Theme): string {\n\tif (args?.offset === undefined && args?.limit === undefined) return \"\";\n\tconst startLine = args.offset ?? 1;\n\tconst endLine = args.limit !== undefined ? startLine + args.limit - 1 : \"\";\n\treturn theme.fg(\"warning\", `:${startLine}${endLine ? `-${endLine}` : \"\"}`);\n}\n\nfunction formatReadCall(args: ReadRenderArgs | undefined, theme: Theme, cwd: string): string {\n\tconst pathDisplay = renderToolPath(str(args?.file_path ?? args?.path), theme, cwd);\n\treturn `${theme.fg(\"toolTitle\", theme.bold(\"read\"))} ${pathDisplay}${formatReadLineRange(args, theme)}`;\n}\n\nfunction trimTrailingEmptyLines(lines: string[]): string[] {\n\tlet end = lines.length;\n\twhile (end > 0 && lines[end - 1] === \"\") {\n\t\tend--;\n\t}\n\treturn lines.slice(0, end);\n}\n\nfunction getNonVisionImageNote(model: Model<Api> | undefined): string | undefined {\n\tif (!model || model.input.includes(\"image\")) {\n\t\treturn undefined;\n\t}\n\treturn \"[Current model does not support images. The image will be omitted from this request.]\";\n}\n\nfunction toPosixPath(filePath: string): string {\n\treturn filePath.split(sep).join(\"/\");\n}\n\nfunction getPiDocsClassification(absolutePath: string): CompactReadClassification | undefined {\n\tconst packageRoot = dirname(getReadmePath());\n\tconst relativePath = relative(resolvePath(packageRoot), resolvePath(absolutePath));\n\tif (\n\t\trelativePath === \"\" ||\n\t\trelativePath === \"..\" ||\n\t\trelativePath.startsWith(`..${sep}`) ||\n\t\tisAbsolute(relativePath)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst label = toPosixPath(relativePath);\n\tif (label === \"README.md\" || label.startsWith(\"docs/\") || label.startsWith(\"examples/\")) {\n\t\treturn { kind: \"docs\", label };\n\t}\n\treturn undefined;\n}\n\nfunction getCompactReadClassification(\n\targs: ReadRenderArgs | undefined,\n\tcwd: string,\n): CompactReadClassification | undefined {\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tif (!rawPath) return undefined;\n\n\tconst absolutePath = resolveToCwd(rawPath, cwd);\n\tconst fileName = basename(absolutePath);\n\tif (fileName === \"SKILL.md\") {\n\t\treturn { kind: \"skill\", label: basename(dirname(absolutePath)) || fileName };\n\t}\n\n\tconst docsClassification = getPiDocsClassification(absolutePath);\n\tif (docsClassification) return docsClassification;\n\n\tif (COMPACT_RESOURCE_FILE_NAMES.has(fileName)) {\n\t\treturn { kind: \"resource\", label: formatPathRelativeToCwdOrAbsolute(absolutePath, cwd) };\n\t}\n\n\treturn undefined;\n}\n\nfunction formatCompactReadCall(\n\tclassification: CompactReadClassification,\n\targs: ReadRenderArgs | undefined,\n\ttheme: Theme,\n): string {\n\tconst expandHint = theme.fg(\"dim\", ` (${keyText(\"app.tools.expand\")} to expand)`);\n\tif (classification.kind === \"skill\") {\n\t\treturn (\n\t\t\ttheme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m `) +\n\t\t\ttheme.fg(\"customMessageText\", classification.label) +\n\t\t\tformatReadLineRange(args, theme) +\n\t\t\texpandHint\n\t\t);\n\t}\n\n\treturn (\n\t\ttheme.fg(\"toolTitle\", theme.bold(`read ${classification.kind}`)) +\n\t\t\" \" +\n\t\ttheme.fg(\"accent\", classification.label) +\n\t\tformatReadLineRange(args, theme) +\n\t\texpandHint\n\t);\n}\n\nfunction formatReadResult(\n\targs: ReadRenderArgs | undefined,\n\tresult: { content: (TextContent | ImageContent)[]; details?: ReadToolDetails },\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n\t_cwd: string,\n\tisError: boolean,\n): string {\n\tif (!options.expanded && !isError) {\n\t\treturn \"\";\n\t}\n\n\tconst rawPath = str(args?.file_path ?? args?.path);\n\tconst output = getTextOutput(result, showImages);\n\tconst lang = rawPath ? getLanguageFromPath(rawPath) : undefined;\n\tconst renderedLines = lang ? highlightCode(replaceTabs(output), lang) : output.split(\"\\n\");\n\tconst lines = trimTrailingEmptyLines(renderedLines);\n\tconst maxLines = options.expanded ? lines.length : 10;\n\tconst displayLines = lines.slice(0, maxLines);\n\tconst remaining = lines.length - maxLines;\n\tlet text = `\\n${displayLines.map((line) => (lang ? replaceTabs(line) : theme.fg(\"toolOutput\", replaceTabs(line)))).join(\"\\n\")}`;\n\tif (remaining > 0) {\n\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t}\n\n\tconst truncation = result.details?.truncation;\n\tif (truncation?.truncated) {\n\t\tif (truncation.firstLineExceedsLimit) {\n\t\t\ttext += `\\n${theme.fg(\"warning\", `[First line exceeds ${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit]`)}`;\n\t\t} else if (truncation.truncatedBy === \"lines\") {\n\t\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${truncation.maxLines ?? DEFAULT_MAX_LINES} line limit)]`)}`;\n\t\t} else {\n\t\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit)]`)}`;\n\t\t}\n\t}\n\treturn text;\n}\n\nexport function createReadToolDefinition(\n\tcwd: string,\n\toptions?: ReadToolOptions,\n): ToolDefinition<typeof readSchema, ReadToolDetails | undefined> {\n\tconst autoResizeImages = options?.autoResizeImages ?? true;\n\tconst ops = options?.operations ?? defaultReadOperations;\n\tconst maxTextReadBytes = options?.maxTextReadBytes ?? DEFAULT_MAX_TEXT_READ_BYTES;\n\tconst maxImageReadBytes = options?.maxImageReadBytes ?? DEFAULT_MAX_IMAGE_READ_BYTES;\n\treturn {\n\t\tname: \"read\",\n\t\tlabel: \"read\",\n\t\tdescription: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,\n\t\tpromptSnippet: \"Read file contents\",\n\t\tpromptGuidelines: [\"Use read to examine files instead of cat or sed.\"],\n\t\tparameters: readSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\toffset,\n\t\t\t\tlimit,\n\t\t\t\tlineNumbers,\n\t\t\t\ttail,\n\t\t\t\tfilter,\n\t\t\t}: {\n\t\t\t\tpath: string;\n\t\t\t\toffset?: number;\n\t\t\t\tlimit?: number;\n\t\t\t\tlineNumbers?: boolean;\n\t\t\t\ttail?: number;\n\t\t\t\tfilter?: \"none\" | \"minimal\" | \"aggressive\";\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\tctx?,\n\t\t) {\n\t\t\treturn new Promise<{ content: (TextContent | ImageContent)[]; details: ReadToolDetails | undefined }>(\n\t\t\t\t(resolve, reject) => {\n\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet aborted = false;\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t};\n\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst absolutePath = await resolveReadPathAsync(path, cwd);\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\t// Check if file exists and is readable.\n\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tconst mimeType = ops.detectImageMimeType ? await ops.detectImageMimeType(absolutePath) : undefined;\n\t\t\t\t\t\t\tlet content: (TextContent | ImageContent)[];\n\t\t\t\t\t\t\tlet details: ReadToolDetails | undefined;\n\t\t\t\t\t\t\tconst nonVisionImageNote = getNonVisionImageNote(ctx?.model);\n\t\t\t\t\t\t\tconst fileSize = ops.stat ? (await ops.stat(absolutePath)).size : undefined;\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tif (mimeType) {\n\t\t\t\t\t\t\t\tif (fileSize !== undefined && fileSize > maxImageReadBytes) {\n\t\t\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\t\t\ttext: `Image file is ${formatSize(fileSize)} (${formatSize(maxImageReadBytes)} inline decode limit). Downscale it first, e.g. with bash (ImageMagick: magick \"${path}\" -resize 2000x2000 /tmp/preview.png) and read the result.`,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Read image as binary.\n\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\tif (autoResizeImages) {\n\t\t\t\t\t\t\t\t\t// Resize image if needed before sending it back to the model.\n\t\t\t\t\t\t\t\t\tconst resized = await resizeImage(buffer, mimeType);\n\t\t\t\t\t\t\t\t\tif (!resized) {\n\t\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${mimeType}]\\n[Image omitted: could not be resized below the inline image size limit.]`;\n\t\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\t\tcontent = [{ type: \"text\", text: textNote }];\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst dimensionNote = formatDimensionNote(resized);\n\t\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${resized.mimeType}]`;\n\t\t\t\t\t\t\t\t\t\tif (dimensionNote) textNote += `\\n${dimensionNote}`;\n\t\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\t\tcontent = [\n\t\t\t\t\t\t\t\t\t\t\t{ type: \"text\", text: textNote },\n\t\t\t\t\t\t\t\t\t\t\t{ type: \"image\", data: resized.data, mimeType: resized.mimeType },\n\t\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tlet textNote = `Read image file [${mimeType}]`;\n\t\t\t\t\t\t\t\t\tif (nonVisionImageNote) textNote += `\\n${nonVisionImageNote}`;\n\t\t\t\t\t\t\t\t\tcontent = [\n\t\t\t\t\t\t\t\t\t\t{ type: \"text\", text: textNote },\n\t\t\t\t\t\t\t\t\t\t{ type: \"image\", data: buffer.toString(\"base64\"), mimeType },\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Read text content. Oversized files are streamed as line slices so\n\t\t\t\t\t\t\t\t// any region stays reachable in batches without loading the whole file.\n\t\t\t\t\t\t\t\tconst useSlicedRead =\n\t\t\t\t\t\t\t\t\tfileSize !== undefined && fileSize > maxTextReadBytes && ops.readLineSlice !== undefined;\n\t\t\t\t\t\t\t\tlet startLine = 0;\n\t\t\t\t\t\t\t\tlet userLimitedLines = limit;\n\t\t\t\t\t\t\t\tlet totalFileLines: number | undefined;\n\t\t\t\t\t\t\t\tlet moreContentRemains = false;\n\t\t\t\t\t\t\t\tlet textContentForJsonCheck: string | undefined;\n\t\t\t\t\t\t\t\tlet slicedLines: { text: string; originalIndex: number }[];\n\t\t\t\t\t\t\t\tif (useSlicedRead && ops.readLineSlice) {\n\t\t\t\t\t\t\t\t\tif (offset !== undefined) {\n\t\t\t\t\t\t\t\t\t\tstartLine = Math.max(0, offset - 1);\n\t\t\t\t\t\t\t\t\t} else if (tail !== undefined) {\n\t\t\t\t\t\t\t\t\t\tconst counted = ops.countLines ? await ops.countLines(absolutePath) : undefined;\n\t\t\t\t\t\t\t\t\t\tif (counted !== undefined) {\n\t\t\t\t\t\t\t\t\t\t\ttotalFileLines = counted;\n\t\t\t\t\t\t\t\t\t\t\tstartLine = Math.max(0, counted - tail);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (limit === undefined) {\n\t\t\t\t\t\t\t\t\t\t\tuserLimitedLines = tail;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst slice = await ops.readLineSlice(absolutePath, {\n\t\t\t\t\t\t\t\t\t\tstartLine,\n\t\t\t\t\t\t\t\t\t\tmaxLines: userLimitedLines ?? DEFAULT_MAX_LINES,\n\t\t\t\t\t\t\t\t\t\tmaxChars: DEFAULT_MAX_BYTES * 4,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tif (slice.lines.length === 0 && startLine > 0) {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(`Offset ${startLine + 1} is beyond end of file`);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tslicedLines = slice.lines;\n\t\t\t\t\t\t\t\t\tmoreContentRemains = !slice.reachedEnd;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\t\t\t\tconst textContent = buffer.toString(\"utf-8\");\n\t\t\t\t\t\t\t\t\ttextContentForJsonCheck = textContent;\n\t\t\t\t\t\t\t\t\tconst allLines = textContent.split(\"\\n\");\n\t\t\t\t\t\t\t\t\ttotalFileLines = allLines.length;\n\t\t\t\t\t\t\t\t\t// Apply offset/tail if specified. Convert from 1-indexed input to 0-indexed array access.\n\t\t\t\t\t\t\t\t\tif (offset !== undefined) {\n\t\t\t\t\t\t\t\t\t\tstartLine = Math.max(0, offset - 1);\n\t\t\t\t\t\t\t\t\t} else if (tail !== undefined) {\n\t\t\t\t\t\t\t\t\t\tstartLine = Math.max(0, totalFileLines - tail);\n\t\t\t\t\t\t\t\t\t\tif (limit === undefined) {\n\t\t\t\t\t\t\t\t\t\t\tuserLimitedLines = tail;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// Check if offset is out of bounds.\n\t\t\t\t\t\t\t\t\tif (startLine >= allLines.length && allLines.length > 0) {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t\t\t`Offset ${startLine + 1} is beyond end of file (${allLines.length} lines total)`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tslicedLines =\n\t\t\t\t\t\t\t\t\t\tuserLimitedLines !== undefined\n\t\t\t\t\t\t\t\t\t\t\t? allLines\n\t\t\t\t\t\t\t\t\t\t\t\t\t.map((line, idx) => ({ text: line, originalIndex: idx + 1 }))\n\t\t\t\t\t\t\t\t\t\t\t\t\t.slice(startLine, startLine + userLimitedLines)\n\t\t\t\t\t\t\t\t\t\t\t: allLines\n\t\t\t\t\t\t\t\t\t\t\t\t\t.map((line, idx) => ({ text: line, originalIndex: idx + 1 }))\n\t\t\t\t\t\t\t\t\t\t\t\t\t.slice(startLine);\n\t\t\t\t\t\t\t\t\tmoreContentRemains =\n\t\t\t\t\t\t\t\t\t\tuserLimitedLines !== undefined && startLine + userLimitedLines < allLines.length;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst startLineDisplay = startLine + 1;\n\t\t\t\t\t\t\t\tconst firstSelectedLineText = slicedLines[0]?.text ?? \"\";\n\n\t\t\t\t\t\t\t\t// Safe text filtering\n\t\t\t\t\t\t\t\tlet canFilter = true;\n\t\t\t\t\t\t\t\tif (mimeType) {\n\t\t\t\t\t\t\t\t\tcanFilter = false;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tconst fileNameLower = path.toLowerCase();\n\t\t\t\t\t\t\t\t\tconst unsafeExtensions = [\n\t\t\t\t\t\t\t\t\t\t\".json\",\n\t\t\t\t\t\t\t\t\t\t\".jsonl\",\n\t\t\t\t\t\t\t\t\t\t\".yml\",\n\t\t\t\t\t\t\t\t\t\t\".yaml\",\n\t\t\t\t\t\t\t\t\t\t\".toml\",\n\t\t\t\t\t\t\t\t\t\t\".xml\",\n\t\t\t\t\t\t\t\t\t\t\".csv\",\n\t\t\t\t\t\t\t\t\t\t\".tsv\",\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\tif (unsafeExtensions.some((ext) => fileNameLower.endsWith(ext))) {\n\t\t\t\t\t\t\t\t\t\tcanFilter = false;\n\t\t\t\t\t\t\t\t\t} else if (textContentForJsonCheck !== undefined) {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tJSON.parse(textContentForJsonCheck);\n\t\t\t\t\t\t\t\t\t\t\tcanFilter = false;\n\t\t\t\t\t\t\t\t\t\t} catch {}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (canFilter && filter && filter !== \"none\") {\n\t\t\t\t\t\t\t\t\tconst filtered: typeof slicedLines = [];\n\t\t\t\t\t\t\t\t\tif (filter === \"minimal\") {\n\t\t\t\t\t\t\t\t\t\tlet consecutiveBlank = 0;\n\t\t\t\t\t\t\t\t\t\tfor (const item of slicedLines) {\n\t\t\t\t\t\t\t\t\t\t\tconst trimmed = item.text.trimEnd();\n\t\t\t\t\t\t\t\t\t\t\tif (trimmed === \"\") {\n\t\t\t\t\t\t\t\t\t\t\t\tconsecutiveBlank++;\n\t\t\t\t\t\t\t\t\t\t\t\tif (consecutiveBlank <= 1) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tfiltered.push({ text: \"\", originalIndex: item.originalIndex });\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\tconsecutiveBlank = 0;\n\t\t\t\t\t\t\t\t\t\t\t\tfiltered.push({ text: trimmed, originalIndex: item.originalIndex });\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\twhile (filtered.length > 0 && filtered[filtered.length - 1].text === \"\") {\n\t\t\t\t\t\t\t\t\t\t\tfiltered.pop();\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else if (filter === \"aggressive\") {\n\t\t\t\t\t\t\t\t\t\tfor (const item of slicedLines) {\n\t\t\t\t\t\t\t\t\t\t\tconst trimmed = item.text.trimEnd();\n\t\t\t\t\t\t\t\t\t\t\tconst trimmedStart = trimmed.trimStart();\n\t\t\t\t\t\t\t\t\t\t\tif (trimmedStart === \"\") {\n\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\ttrimmedStart.startsWith(\"//\") ||\n\t\t\t\t\t\t\t\t\t\t\t\ttrimmedStart.startsWith(\"#\") ||\n\t\t\t\t\t\t\t\t\t\t\t\t(trimmedStart.startsWith(\"/*\") && trimmedStart.endsWith(\"*/\"))\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tfiltered.push({ text: trimmed, originalIndex: item.originalIndex });\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// If filtering would empty a non-empty list, keep original\n\t\t\t\t\t\t\t\t\tconst isOriginalNotEmpty = slicedLines.some((item) => item.text.trim().length > 0);\n\t\t\t\t\t\t\t\t\tconst isFilteredEmpty = filtered.every((item) => item.text.trim().length === 0);\n\t\t\t\t\t\t\t\t\tif (isOriginalNotEmpty && isFilteredEmpty) {\n\t\t\t\t\t\t\t\t\t\t// Fallback to slicedLines\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tslicedLines = filtered;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst finalLines = slicedLines.map((item) =>\n\t\t\t\t\t\t\t\t\tlineNumbers ? `${item.originalIndex}: ${item.text}` : item.text,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst selectedContent = finalLines.join(\"\\n\");\n\n\t\t\t\t\t\t\t\t// Apply truncation, respecting both line and byte limits.\n\t\t\t\t\t\t\t\tconst truncation = truncateHead(selectedContent);\n\t\t\t\t\t\t\t\tlet outputText: string;\n\t\t\t\t\t\t\t\tconst totalDisplay =\n\t\t\t\t\t\t\t\t\ttotalFileLines !== undefined\n\t\t\t\t\t\t\t\t\t\t? String(totalFileLines)\n\t\t\t\t\t\t\t\t\t\t: `a ${fileSize !== undefined ? formatSize(fileSize) : \"large\"} file`;\n\t\t\t\t\t\t\t\tif (truncation.firstLineExceedsLimit) {\n\t\t\t\t\t\t\t\t\t// First line alone exceeds the byte limit. Point the model at a bash fallback.\n\t\t\t\t\t\t\t\t\tconst firstLineSize = formatSize(Buffer.byteLength(firstSelectedLineText, \"utf-8\"));\n\t\t\t\t\t\t\t\t\toutputText = `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${formatSize(DEFAULT_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${path} | head -c ${DEFAULT_MAX_BYTES}]`;\n\t\t\t\t\t\t\t\t\tdetails = { truncation };\n\t\t\t\t\t\t\t\t} else if (truncation.truncated) {\n\t\t\t\t\t\t\t\t\t// Truncation occurred. Build an actionable continuation notice.\n\t\t\t\t\t\t\t\t\tconst endLineDisplay = startLineDisplay + truncation.outputLines - 1;\n\t\t\t\t\t\t\t\t\tconst nextOffset = endLineDisplay + 1;\n\t\t\t\t\t\t\t\t\toutputText = truncation.content;\n\t\t\t\t\t\t\t\t\tif (truncation.truncatedBy === \"lines\") {\n\t\t\t\t\t\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalDisplay}. Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\toutputText += `\\n\\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalDisplay} (${formatSize(DEFAULT_MAX_BYTES)} limit). Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tdetails = { truncation };\n\t\t\t\t\t\t\t\t} else if (moreContentRemains) {\n\t\t\t\t\t\t\t\t\t// More content exists beyond this slice; hand the model a continuation pointer.\n\t\t\t\t\t\t\t\t\tconst nextOffset = startLine + slicedLines.length + 1;\n\t\t\t\t\t\t\t\t\tconst remaining =\n\t\t\t\t\t\t\t\t\t\ttotalFileLines !== undefined && userLimitedLines !== undefined\n\t\t\t\t\t\t\t\t\t\t\t? `${totalFileLines - (startLine + userLimitedLines)} more lines in file`\n\t\t\t\t\t\t\t\t\t\t\t: \"More content remains\";\n\t\t\t\t\t\t\t\t\toutputText = `${truncation.content}\\n\\n[${remaining}. Use offset=${nextOffset} to continue.]`;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// No truncation and no remaining content.\n\t\t\t\t\t\t\t\t\toutputText = truncation.content;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontent = [{ type: \"text\", text: outputText }];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (aborted) return;\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tresolve({ content, details });\n\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\tif (!aborted) reject(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\tconst classification = !context.expanded ? getCompactReadClassification(args, context.cwd) : undefined;\n\t\t\ttext.setText(\n\t\t\t\tclassification\n\t\t\t\t\t? formatCompactReadCall(classification, args, theme)\n\t\t\t\t\t: formatReadCall(args, theme, context.cwd),\n\t\t\t);\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(\n\t\t\t\tformatReadResult(context.args, result, options, theme, context.showImages, context.cwd, context.isError),\n\t\t\t);\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema> {\n\treturn wrapToolDefinition(createReadToolDefinition(cwd, options));\n}\n"]}