@kolisachint/hoocode-agent 0.4.74 → 0.4.76

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 (135) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/cli/args.d.ts +0 -2
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +0 -11
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-frontmatter.d.ts.map +1 -1
  7. package/dist/core/agent-frontmatter.js +2 -2
  8. package/dist/core/agent-frontmatter.js.map +1 -1
  9. package/dist/core/agent-session-services.d.ts +0 -1
  10. package/dist/core/agent-session-services.d.ts.map +1 -1
  11. package/dist/core/agent-session-services.js +0 -1
  12. package/dist/core/agent-session-services.js.map +1 -1
  13. package/dist/core/agent-session.d.ts +1 -17
  14. package/dist/core/agent-session.d.ts.map +1 -1
  15. package/dist/core/agent-session.js +10 -199
  16. package/dist/core/agent-session.js.map +1 -1
  17. package/dist/core/bash-executor.d.ts.map +1 -1
  18. package/dist/core/bash-executor.js +7 -4
  19. package/dist/core/bash-executor.js.map +1 -1
  20. package/dist/core/compaction/utils.d.ts.map +1 -1
  21. package/dist/core/compaction/utils.js +8 -5
  22. package/dist/core/compaction/utils.js.map +1 -1
  23. package/dist/core/exec.d.ts.map +1 -1
  24. package/dist/core/exec.js +13 -4
  25. package/dist/core/exec.js.map +1 -1
  26. package/dist/core/model-categories.d.ts +28 -0
  27. package/dist/core/model-categories.d.ts.map +1 -0
  28. package/dist/core/model-categories.js +51 -0
  29. package/dist/core/model-categories.js.map +1 -0
  30. package/dist/core/model-registry.d.ts +0 -6
  31. package/dist/core/model-registry.d.ts.map +1 -1
  32. package/dist/core/model-registry.js +0 -32
  33. package/dist/core/model-registry.js.map +1 -1
  34. package/dist/core/sdk.d.ts +0 -6
  35. package/dist/core/sdk.d.ts.map +1 -1
  36. package/dist/core/sdk.js +0 -1
  37. package/dist/core/sdk.js.map +1 -1
  38. package/dist/core/session-manager.d.ts.map +1 -1
  39. package/dist/core/session-manager.js +16 -3
  40. package/dist/core/session-manager.js.map +1 -1
  41. package/dist/core/settings-manager.d.ts +14 -0
  42. package/dist/core/settings-manager.d.ts.map +1 -1
  43. package/dist/core/settings-manager.js.map +1 -1
  44. package/dist/core/subagent-pool-instance.d.ts.map +1 -1
  45. package/dist/core/subagent-pool-instance.js +9 -1
  46. package/dist/core/subagent-pool-instance.js.map +1 -1
  47. package/dist/core/subagent-pool.d.ts +5 -0
  48. package/dist/core/subagent-pool.d.ts.map +1 -1
  49. package/dist/core/subagent-pool.js +13 -2
  50. package/dist/core/subagent-pool.js.map +1 -1
  51. package/dist/core/tools/edit-diff.d.ts +3 -0
  52. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  53. package/dist/core/tools/edit-diff.js +132 -40
  54. package/dist/core/tools/edit-diff.js.map +1 -1
  55. package/dist/core/tools/edit.d.ts.map +1 -1
  56. package/dist/core/tools/edit.js +7 -1
  57. package/dist/core/tools/edit.js.map +1 -1
  58. package/dist/core/tools/fd-utils.d.ts +23 -0
  59. package/dist/core/tools/fd-utils.d.ts.map +1 -0
  60. package/dist/core/tools/fd-utils.js +47 -0
  61. package/dist/core/tools/fd-utils.js.map +1 -0
  62. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  63. package/dist/core/tools/file-mutation-queue.js +15 -2
  64. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  65. package/dist/core/tools/find.d.ts.map +1 -1
  66. package/dist/core/tools/find.js +3 -24
  67. package/dist/core/tools/find.js.map +1 -1
  68. package/dist/core/tools/glob.d.ts +42 -0
  69. package/dist/core/tools/glob.d.ts.map +1 -0
  70. package/dist/core/tools/glob.js +432 -0
  71. package/dist/core/tools/glob.js.map +1 -0
  72. package/dist/core/tools/grep.d.ts.map +1 -1
  73. package/dist/core/tools/grep.js +34 -19
  74. package/dist/core/tools/grep.js.map +1 -1
  75. package/dist/core/tools/index.d.ts +4 -1
  76. package/dist/core/tools/index.d.ts.map +1 -1
  77. package/dist/core/tools/index.js +13 -1
  78. package/dist/core/tools/index.js.map +1 -1
  79. package/dist/core/tools/ls.d.ts +12 -1
  80. package/dist/core/tools/ls.d.ts.map +1 -1
  81. package/dist/core/tools/ls.js +58 -33
  82. package/dist/core/tools/ls.js.map +1 -1
  83. package/dist/core/tools/output-accumulator.d.ts +4 -0
  84. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  85. package/dist/core/tools/output-accumulator.js +39 -20
  86. package/dist/core/tools/output-accumulator.js.map +1 -1
  87. package/dist/core/tools/output-compression.d.ts +53 -0
  88. package/dist/core/tools/output-compression.d.ts.map +1 -0
  89. package/dist/core/tools/output-compression.js +392 -0
  90. package/dist/core/tools/output-compression.js.map +1 -0
  91. package/dist/core/tools/read.d.ts.map +1 -1
  92. package/dist/core/tools/read.js +9 -1
  93. package/dist/core/tools/read.js.map +1 -1
  94. package/dist/core/tools/render-utils.d.ts.map +1 -1
  95. package/dist/core/tools/render-utils.js +9 -2
  96. package/dist/core/tools/render-utils.js.map +1 -1
  97. package/dist/core/tools/write.d.ts.map +1 -1
  98. package/dist/core/tools/write.js +4 -1
  99. package/dist/core/tools/write.js.map +1 -1
  100. package/dist/main.d.ts.map +1 -1
  101. package/dist/main.js +0 -1
  102. package/dist/main.js.map +1 -1
  103. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  104. package/dist/modes/interactive/components/bash-execution.js +2 -2
  105. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  106. package/dist/modes/interactive/components/task-panel.d.ts.map +1 -1
  107. package/dist/modes/interactive/components/task-panel.js +10 -26
  108. package/dist/modes/interactive/components/task-panel.js.map +1 -1
  109. package/dist/utils/tools-manager.d.ts.map +1 -1
  110. package/dist/utils/tools-manager.js +16 -0
  111. package/dist/utils/tools-manager.js.map +1 -1
  112. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  113. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  114. package/examples/extensions/sandbox/package.json +1 -1
  115. package/examples/extensions/with-deps/package.json +1 -1
  116. package/package.json +4 -4
  117. package/templates/agents/explore.md +1 -1
  118. package/templates/agents/general-purpose.md +1 -1
  119. package/templates/agents/plan.md +1 -1
  120. package/dist/core/routing/local-inference.d.ts +0 -128
  121. package/dist/core/routing/local-inference.d.ts.map +0 -1
  122. package/dist/core/routing/local-inference.js +0 -145
  123. package/dist/core/routing/local-inference.js.map +0 -1
  124. package/dist/core/routing/metrics.d.ts +0 -27
  125. package/dist/core/routing/metrics.d.ts.map +0 -1
  126. package/dist/core/routing/metrics.js +0 -35
  127. package/dist/core/routing/metrics.js.map +0 -1
  128. package/dist/core/routing/mlx-server.d.ts +0 -43
  129. package/dist/core/routing/mlx-server.d.ts.map +0 -1
  130. package/dist/core/routing/mlx-server.js +0 -115
  131. package/dist/core/routing/mlx-server.js.map +0 -1
  132. package/dist/core/routing/tool-result-prompts.d.ts +0 -26
  133. package/dist/core/routing/tool-result-prompts.d.ts.map +0 -1
  134. package/dist/core/routing/tool-result-prompts.js +0 -45
  135. package/dist/core/routing/tool-result-prompts.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAKjE,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAItF,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;;;EAYd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,mEAAmE;IACnE,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClE,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC7D;AAOD,MAAM,WAAW,eAAe;IAC/B,yEAAyE;IACzE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAyDD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAqQhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport { Text } from \"@kolisachint/hoocode-tui\";\nimport { spawn } from \"child_process\";\nimport { readFileSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.js\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: (p) => statSync(p).isDirectory(),\n\treadFile: (p) => readFileSync(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus ripgrep */\n\toperations?: GrepOperations;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst rgPath = await ensureTool(\"rg\", true);\n\t\t\t\t\t\tif (!rgPath) {\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\"ripgrep (rg) unavailable and could not be downloaded — use the bash tool to run grep/rg instead\",\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);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = customOps ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (!child.killed) {\n\t\t\t\t\t\t\t\tkilledDueToLimit = dueToLimit;\n\t\t\t\t\t\t\t\tchild.kill();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchCount >= effectiveLimit) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText });\n\t\t\t\t\t\t\t\tif (matchCount >= effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tchild.on(\"close\", async (code) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\t\tconst relativePath = formatPath(match.filePath);\n\t\t\t\t\t\t\t\t\tconst sanitized = match.lineText\n\t\t\t\t\t\t\t\t\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t\t\t\t\t\t\t\t\t.replace(/\\r/g, \"\")\n\t\t\t\t\t\t\t\t\t\t.replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\t\toutputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\t\toutputLines.push(...block);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t\t// Apply byte truncation. There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\t\t\t\t// Build actionable notices for truncation and match limits.\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (matchLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (linesTruncated) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\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\ttext.setText(formatGrepCall(args, theme));\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(formatGrepResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAKjE,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AAKtF,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;;;EAYd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAGtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,mEAAmE;IACnE,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClE,2CAA2C;IAC3C,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC7D;AAOD,MAAM,WAAW,eAAe;IAC/B,yEAAyE;IACzE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAyDD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAoRhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport { Text } from \"@kolisachint/hoocode-tui\";\nimport { spawn } from \"child_process\";\nimport { readFileSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { compressGrepOutput } from \"./output-compression.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.js\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: (p) => statSync(p).isDirectory(),\n\treadFile: (p) => readFileSync(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus ripgrep */\n\toperations?: GrepOperations;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst rgPath = await ensureTool(\"rg\", true);\n\t\t\t\t\t\tif (!rgPath) {\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\"ripgrep (rg) unavailable and could not be downloaded — use the bash tool to run grep/rg instead\",\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);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = customOps ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (!child.killed) {\n\t\t\t\t\t\t\t\tkilledDueToLimit = dueToLimit;\n\t\t\t\t\t\t\t\tchild.kill();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Format a context block around a match line. Path is omitted (emitted once per file).\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [` ${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchCount >= effectiveLimit) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText });\n\t\t\t\t\t\t\t\tif (matchCount >= effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tchild.on(\"close\", async (code) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Group matches by file path, showing filename once per file.\n\t\t\t\t\t\t\tconst fileGroups = new Map<string, typeof matches>();\n\t\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\t\tlet group = fileGroups.get(match.filePath);\n\t\t\t\t\t\t\t\tif (!group) {\n\t\t\t\t\t\t\t\t\tgroup = [];\n\t\t\t\t\t\t\t\t\tfileGroups.set(match.filePath, group);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tgroup.push(match);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfor (const [filePath, fileMatches] of fileGroups) {\n\t\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\t\toutputLines.push(relativePath);\n\t\t\t\t\t\t\t\tfor (const match of fileMatches) {\n\t\t\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\t\t\tconst sanitized = match.lineText\n\t\t\t\t\t\t\t\t\t\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t\t\t\t\t\t\t\t\t\t.replace(/\\r/g, \"\")\n\t\t\t\t\t\t\t\t\t\t\t.replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\t\t\toutputLines.push(`${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\t\t\toutputLines.push(...block);\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}\n\n\t\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t\t// Apply lossless compression then byte truncation.\n\t\t\t\t\t\t\tconst compressedOutput = compressGrepOutput(rawOutput);\n\t\t\t\t\t\t\t// Apply byte truncation. There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\t\tconst truncation = truncateHead(compressedOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\t\t\t\t// Build actionable notices for truncation and match limits.\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (matchLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (linesTruncated) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\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\ttext.setText(formatGrepCall(args, theme));\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(formatGrepResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
@@ -6,6 +6,7 @@ import path from "path";
6
6
  import { Type } from "typebox";
7
7
  import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
8
8
  import { ensureTool } from "../../utils/tools-manager.js";
9
+ import { compressGrepOutput } from "./output-compression.js";
9
10
  import { resolveToCwd } from "./path-utils.js";
10
11
  import { getTextOutput, invalidArgText, shortenPath, str } from "./render-utils.js";
11
12
  import { wrapToolDefinition } from "./tool-definition-wrapper.js";
@@ -168,11 +169,11 @@ export function createGrepToolDefinition(cwd, options) {
168
169
  child.stderr?.on("data", (chunk) => {
169
170
  stderr += chunk.toString();
170
171
  });
172
+ // Format a context block around a match line. Path is omitted (emitted once per file).
171
173
  const formatBlock = async (filePath, lineNumber) => {
172
- const relativePath = formatPath(filePath);
173
174
  const lines = await getFileLines(filePath);
174
175
  if (!lines.length)
175
- return [`${relativePath}:${lineNumber}: (unable to read file)`];
176
+ return [` ${lineNumber}: (unable to read file)`];
176
177
  const block = [];
177
178
  const start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;
178
179
  const end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;
@@ -185,9 +186,9 @@ export function createGrepToolDefinition(cwd, options) {
185
186
  if (wasTruncated)
186
187
  linesTruncated = true;
187
188
  if (isMatchLine)
188
- block.push(`${relativePath}:${current}: ${truncatedText}`);
189
+ block.push(`${current}: ${truncatedText}`);
189
190
  else
190
- block.push(`${relativePath}-${current}- ${truncatedText}`);
191
+ block.push(`${current}- ${truncatedText}`);
191
192
  }
192
193
  return block;
193
194
  };
@@ -235,27 +236,41 @@ export function createGrepToolDefinition(cwd, options) {
235
236
  settle(() => resolve({ content: [{ type: "text", text: "No matches found" }], details: undefined }));
236
237
  return;
237
238
  }
238
- // Format matches after streaming finishes so custom readFile() backends can be async.
239
+ // Group matches by file path, showing filename once per file.
240
+ const fileGroups = new Map();
239
241
  for (const match of matches) {
240
- if (contextValue === 0 && match.lineText !== undefined) {
241
- const relativePath = formatPath(match.filePath);
242
- const sanitized = match.lineText
243
- .replace(/\r\n/g, "\n")
244
- .replace(/\r/g, "")
245
- .replace(/\n$/, "");
246
- const { text: truncatedText, wasTruncated } = truncateLine(sanitized);
247
- if (wasTruncated)
248
- linesTruncated = true;
249
- outputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedText}`);
242
+ let group = fileGroups.get(match.filePath);
243
+ if (!group) {
244
+ group = [];
245
+ fileGroups.set(match.filePath, group);
250
246
  }
251
- else {
252
- const block = await formatBlock(match.filePath, match.lineNumber);
253
- outputLines.push(...block);
247
+ group.push(match);
248
+ }
249
+ for (const [filePath, fileMatches] of fileGroups) {
250
+ const relativePath = formatPath(filePath);
251
+ outputLines.push(relativePath);
252
+ for (const match of fileMatches) {
253
+ if (contextValue === 0 && match.lineText !== undefined) {
254
+ const sanitized = match.lineText
255
+ .replace(/\r\n/g, "\n")
256
+ .replace(/\r/g, "")
257
+ .replace(/\n$/, "");
258
+ const { text: truncatedText, wasTruncated } = truncateLine(sanitized);
259
+ if (wasTruncated)
260
+ linesTruncated = true;
261
+ outputLines.push(`${match.lineNumber}: ${truncatedText}`);
262
+ }
263
+ else {
264
+ const block = await formatBlock(match.filePath, match.lineNumber);
265
+ outputLines.push(...block);
266
+ }
254
267
  }
255
268
  }
256
269
  const rawOutput = outputLines.join("\n");
270
+ // Apply lossless compression then byte truncation.
271
+ const compressedOutput = compressGrepOutput(rawOutput);
257
272
  // Apply byte truncation. There is no line limit here because the match limit already capped rows.
258
- const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
273
+ const truncation = truncateHead(compressedOutput, { maxLines: Number.MAX_SAFE_INTEGER });
259
274
  let output = truncation.content;
260
275
  const details = {};
261
276
  // Build actionable notices for truncation and match limits.
@@ -1 +1 @@
1
- {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport { Text } from \"@kolisachint/hoocode-tui\";\nimport { spawn } from \"child_process\";\nimport { readFileSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.js\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: (p) => statSync(p).isDirectory(),\n\treadFile: (p) => readFileSync(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus ripgrep */\n\toperations?: GrepOperations;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst rgPath = await ensureTool(\"rg\", true);\n\t\t\t\t\t\tif (!rgPath) {\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\"ripgrep (rg) unavailable and could not be downloaded — use the bash tool to run grep/rg instead\",\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);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = customOps ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (!child.killed) {\n\t\t\t\t\t\t\t\tkilledDueToLimit = dueToLimit;\n\t\t\t\t\t\t\t\tchild.kill();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [`${relativePath}:${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${relativePath}:${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${relativePath}-${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchCount >= effectiveLimit) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText });\n\t\t\t\t\t\t\t\tif (matchCount >= effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tchild.on(\"close\", async (code) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Format matches after streaming finishes so custom readFile() backends can be async.\n\t\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\t\tconst relativePath = formatPath(match.filePath);\n\t\t\t\t\t\t\t\t\tconst sanitized = match.lineText\n\t\t\t\t\t\t\t\t\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t\t\t\t\t\t\t\t\t.replace(/\\r/g, \"\")\n\t\t\t\t\t\t\t\t\t\t.replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\t\toutputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\t\toutputLines.push(...block);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t\t// Apply byte truncation. There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\t\t\t\t// Build actionable notices for truncation and match limits.\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (matchLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (linesTruncated) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\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\ttext.setText(formatGrepCall(args, theme));\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(formatGrepResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/core/tools/grep.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport { Text } from \"@kolisachint/hoocode-tui\";\nimport { spawn } from \"child_process\";\nimport { readFileSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.js\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.js\";\nimport { compressGrepOutput } from \"./output-compression.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\nimport { getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.js\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.js\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from \"./truncate.js\";\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: \"Search pattern (regex or literal string)\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search (default: current directory)\" })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts' or '**/*.spec.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: \"Case-insensitive search (default: false)\" })),\n\tliteral: Type.Optional(\n\t\tType.Boolean({ description: \"Treat pattern as literal string instead of regex (default: false)\" }),\n\t),\n\tcontext: Type.Optional(\n\t\tType.Number({ description: \"Number of lines to show before and after each match (default: 0)\" }),\n\t),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default: 100)\" })),\n});\n\nexport type GrepToolInput = Static<typeof grepSchema>;\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\n/**\n * Pluggable operations for the grep tool.\n * Override these to delegate search to remote systems (for example SSH).\n */\nexport interface GrepOperations {\n\t/** Check if path is a directory. Throws if path does not exist. */\n\tisDirectory: (absolutePath: string) => Promise<boolean> | boolean;\n\t/** Read file contents for context lines */\n\treadFile: (absolutePath: string) => Promise<string> | string;\n}\n\nconst defaultGrepOperations: GrepOperations = {\n\tisDirectory: (p) => statSync(p).isDirectory(),\n\treadFile: (p) => readFileSync(p, \"utf-8\"),\n};\n\nexport interface GrepToolOptions {\n\t/** Custom operations for grep. Default: local filesystem plus ripgrep */\n\toperations?: GrepOperations;\n}\n\nfunction formatGrepCall(\n\targs: { pattern: string; path?: string; glob?: string; limit?: number } | undefined,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst glob = str(args?.glob);\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"grep\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", `/${pattern || \"\"}/`)) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (glob) text += theme.fg(\"toolOutput\", ` (${glob})`);\n\tif (limit !== undefined) text += theme.fg(\"toolOutput\", ` limit ${limit}`);\n\treturn text;\n}\n\nfunction formatGrepResult(\n\tresult: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tdetails?: GrepToolDetails;\n\t},\n\toptions: ToolRenderResultOptions,\n\ttheme: typeof import(\"../../modes/interactive/theme/theme.js\").theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 15;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst matchLimit = result.details?.matchLimitReached;\n\tconst truncation = result.details?.truncation;\n\tconst linesTruncated = result.details?.linesTruncated;\n\tif (matchLimit || truncation?.truncated || linesTruncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (matchLimit) warnings.push(`${matchLimit} matches limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\tif (linesTruncated) warnings.push(\"some lines truncated\");\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\nexport function createGrepToolDefinition(\n\tcwd: string,\n\toptions?: GrepToolOptions,\n): ToolDefinition<typeof grepSchema, GrepToolDetails | undefined> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"grep\",\n\t\tlabel: \"grep\",\n\t\tdescription: `Search file contents for a pattern. Returns matching lines with file paths and line numbers. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} matches or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Long lines are truncated to ${GREP_MAX_LINE_LENGTH} chars.`,\n\t\tpromptSnippet: \"Search file contents for patterns (respects .gitignore)\",\n\t\tparameters: grepSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{\n\t\t\t\tpattern,\n\t\t\t\tpath: searchDir,\n\t\t\t\tglob,\n\t\t\t\tignoreCase,\n\t\t\t\tliteral,\n\t\t\t\tcontext,\n\t\t\t\tlimit,\n\t\t\t}: {\n\t\t\t\tpattern: string;\n\t\t\t\tpath?: string;\n\t\t\t\tglob?: string;\n\t\t\t\tignoreCase?: boolean;\n\t\t\t\tliteral?: boolean;\n\t\t\t\tcontext?: number;\n\t\t\t\tlimit?: number;\n\t\t\t},\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet settled = false;\n\t\t\t\tconst settle = (fn: () => void) => {\n\t\t\t\t\tif (!settled) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tfn();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst rgPath = await ensureTool(\"rg\", true);\n\t\t\t\t\t\tif (!rgPath) {\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\t\"ripgrep (rg) unavailable and could not be downloaded — use the bash tool to run grep/rg instead\",\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);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst searchPath = resolveToCwd(searchDir || \".\", cwd);\n\t\t\t\t\t\tconst ops = customOps ?? defaultGrepOperations;\n\t\t\t\t\t\tlet isDirectory: boolean;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tisDirectory = await ops.isDirectory(searchPath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Path not found: ${searchPath}`)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contextValue = context && context > 0 ? context : 0;\n\t\t\t\t\t\tconst effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT);\n\t\t\t\t\t\tconst formatPath = (filePath: string): string => {\n\t\t\t\t\t\t\tif (isDirectory) {\n\t\t\t\t\t\t\t\tconst relative = path.relative(searchPath, filePath);\n\t\t\t\t\t\t\t\tif (relative && !relative.startsWith(\"..\")) {\n\t\t\t\t\t\t\t\t\treturn relative.replace(/\\\\/g, \"/\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn path.basename(filePath);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst fileCache = new Map<string, string[]>();\n\t\t\t\t\t\tconst getFileLines = async (filePath: string): Promise<string[]> => {\n\t\t\t\t\t\t\tlet lines = fileCache.get(filePath);\n\t\t\t\t\t\t\tif (!lines) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst content = await ops.readFile(filePath);\n\t\t\t\t\t\t\t\t\tlines = content.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").split(\"\\n\");\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tlines = [];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfileCache.set(filePath, lines);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn lines;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst args: string[] = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\t\t\t\t\tif (ignoreCase) args.push(\"--ignore-case\");\n\t\t\t\t\t\tif (literal) args.push(\"--fixed-strings\");\n\t\t\t\t\t\tif (glob) args.push(\"--glob\", glob);\n\t\t\t\t\t\targs.push(\"--\", pattern, searchPath);\n\n\t\t\t\t\t\tconst child = spawn(rgPath, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\t\t\t\t\tconst rl = createInterface({ input: child.stdout });\n\t\t\t\t\t\tlet stderr = \"\";\n\t\t\t\t\t\tlet matchCount = 0;\n\t\t\t\t\t\tlet matchLimitReached = false;\n\t\t\t\t\t\tlet linesTruncated = false;\n\t\t\t\t\t\tlet aborted = false;\n\t\t\t\t\t\tlet killedDueToLimit = false;\n\t\t\t\t\t\tconst outputLines: string[] = [];\n\n\t\t\t\t\t\tconst cleanup = () => {\n\t\t\t\t\t\t\trl.close();\n\t\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst stopChild = (dueToLimit = false) => {\n\t\t\t\t\t\t\tif (!child.killed) {\n\t\t\t\t\t\t\t\tkilledDueToLimit = dueToLimit;\n\t\t\t\t\t\t\t\tchild.kill();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\tstopChild();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\tstderr += chunk.toString();\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Format a context block around a match line. Path is omitted (emitted once per file).\n\t\t\t\t\t\tconst formatBlock = async (filePath: string, lineNumber: number): Promise<string[]> => {\n\t\t\t\t\t\t\tconst lines = await getFileLines(filePath);\n\t\t\t\t\t\t\tif (!lines.length) return [` ${lineNumber}: (unable to read file)`];\n\t\t\t\t\t\t\tconst block: string[] = [];\n\t\t\t\t\t\t\tconst start = contextValue > 0 ? Math.max(1, lineNumber - contextValue) : lineNumber;\n\t\t\t\t\t\t\tconst end = contextValue > 0 ? Math.min(lines.length, lineNumber + contextValue) : lineNumber;\n\t\t\t\t\t\t\tfor (let current = start; current <= end; current++) {\n\t\t\t\t\t\t\t\tconst lineText = lines[current - 1] ?? \"\";\n\t\t\t\t\t\t\t\tconst sanitized = lineText.replace(/\\r/g, \"\");\n\t\t\t\t\t\t\t\tconst isMatchLine = current === lineNumber;\n\t\t\t\t\t\t\t\t// Truncate long lines so grep output stays compact.\n\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\tif (isMatchLine) block.push(`${current}: ${truncatedText}`);\n\t\t\t\t\t\t\t\telse block.push(`${current}- ${truncatedText}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Collect matches during streaming, then format them after rg exits.\n\t\t\t\t\t\tconst matches: Array<{ filePath: string; lineNumber: number; lineText?: string }> = [];\n\t\t\t\t\t\trl.on(\"line\", (line) => {\n\t\t\t\t\t\t\tif (!line.trim() || matchCount >= effectiveLimit) return;\n\t\t\t\t\t\t\tlet event: any;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevent = JSON.parse(line);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.type === \"match\") {\n\t\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t\t\tconst filePath = event.data?.path?.text;\n\t\t\t\t\t\t\t\tconst lineNumber = event.data?.line_number;\n\t\t\t\t\t\t\t\tconst lineText = event.data?.lines?.text;\n\t\t\t\t\t\t\t\tif (filePath && typeof lineNumber === \"number\")\n\t\t\t\t\t\t\t\t\tmatches.push({ filePath, lineNumber, lineText });\n\t\t\t\t\t\t\t\tif (matchCount >= effectiveLimit) {\n\t\t\t\t\t\t\t\t\tmatchLimitReached = true;\n\t\t\t\t\t\t\t\t\tstopChild(true);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tsettle(() => reject(new Error(`Failed to run ripgrep: ${error.message}`)));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tchild.on(\"close\", async (code) => {\n\t\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!killedDueToLimit && code !== 0 && code !== 1) {\n\t\t\t\t\t\t\t\tconst errorMsg = stderr.trim() || `ripgrep exited with code ${code}`;\n\t\t\t\t\t\t\t\tsettle(() => reject(new Error(errorMsg)));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (matchCount === 0) {\n\t\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\t\tresolve({ content: [{ type: \"text\", text: \"No matches found\" }], details: undefined }),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Group matches by file path, showing filename once per file.\n\t\t\t\t\t\t\tconst fileGroups = new Map<string, typeof matches>();\n\t\t\t\t\t\t\tfor (const match of matches) {\n\t\t\t\t\t\t\t\tlet group = fileGroups.get(match.filePath);\n\t\t\t\t\t\t\t\tif (!group) {\n\t\t\t\t\t\t\t\t\tgroup = [];\n\t\t\t\t\t\t\t\t\tfileGroups.set(match.filePath, group);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tgroup.push(match);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfor (const [filePath, fileMatches] of fileGroups) {\n\t\t\t\t\t\t\t\tconst relativePath = formatPath(filePath);\n\t\t\t\t\t\t\t\toutputLines.push(relativePath);\n\t\t\t\t\t\t\t\tfor (const match of fileMatches) {\n\t\t\t\t\t\t\t\t\tif (contextValue === 0 && match.lineText !== undefined) {\n\t\t\t\t\t\t\t\t\t\tconst sanitized = match.lineText\n\t\t\t\t\t\t\t\t\t\t\t.replace(/\\r\\n/g, \"\\n\")\n\t\t\t\t\t\t\t\t\t\t\t.replace(/\\r/g, \"\")\n\t\t\t\t\t\t\t\t\t\t\t.replace(/\\n$/, \"\");\n\t\t\t\t\t\t\t\t\t\tconst { text: truncatedText, wasTruncated } = truncateLine(sanitized);\n\t\t\t\t\t\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\t\t\t\t\t\t\t\t\t\toutputLines.push(`${match.lineNumber}: ${truncatedText}`);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst block = await formatBlock(match.filePath, match.lineNumber);\n\t\t\t\t\t\t\t\t\t\toutputLines.push(...block);\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}\n\n\t\t\t\t\t\t\tconst rawOutput = outputLines.join(\"\\n\");\n\t\t\t\t\t\t\t// Apply lossless compression then byte truncation.\n\t\t\t\t\t\t\tconst compressedOutput = compressGrepOutput(rawOutput);\n\t\t\t\t\t\t\t// Apply byte truncation. There is no line limit here because the match limit already capped rows.\n\t\t\t\t\t\t\tconst truncation = truncateHead(compressedOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\t\t\t\t\t\t\tlet output = truncation.content;\n\t\t\t\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\t\t\t\t// Build actionable notices for truncation and match limits.\n\t\t\t\t\t\t\tconst notices: string[] = [];\n\t\t\t\t\t\t\tif (matchLimitReached) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`${effectiveLimit} matches limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (linesTruncated) {\n\t\t\t\t\t\t\t\tnotices.push(\n\t\t\t\t\t\t\t\t\t`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars. Use read tool to see full lines`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\t\t\t\t\t\t\tsettle(() =>\n\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\t\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsettle(() => reject(err as Error));\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\ttext.setText(formatGrepCall(args, theme));\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(formatGrepResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema> {\n\treturn wrapToolDefinition(createGrepToolDefinition(cwd, options));\n}\n"]}
@@ -2,6 +2,7 @@ export { type BashOperations, type BashSpawnContext, type BashSpawnHook, type Ba
2
2
  export { createEditTool, createEditToolDefinition, type EditOperations, type EditToolDetails, type EditToolInput, type EditToolOptions, } from "./edit.js";
3
3
  export { withFileMutationQueue } from "./file-mutation-queue.js";
4
4
  export { createFindTool, createFindToolDefinition, type FindOperations, type FindToolDetails, type FindToolInput, type FindToolOptions, } from "./find.js";
5
+ export { createGlobTool, createGlobToolDefinition, type GlobOperations, type GlobToolDetails, type GlobToolInput, type GlobToolOptions, } from "./glob.js";
5
6
  export { createGrepTool, createGrepToolDefinition, type GrepOperations, type GrepToolDetails, type GrepToolInput, type GrepToolOptions, } from "./grep.js";
6
7
  export { createLsTool, createLsToolDefinition, type LsOperations, type LsToolDetails, type LsToolInput, type LsToolOptions, } from "./ls.js";
7
8
  export { expandPath, resolveReadPath, resolveToCwd } from "./path-utils.js";
@@ -15,13 +16,14 @@ import type { ToolDefinition } from "../extensions/types.js";
15
16
  import { type BashToolOptions } from "./bash.js";
16
17
  import { type EditToolOptions } from "./edit.js";
17
18
  import { type FindToolOptions } from "./find.js";
19
+ import { type GlobToolOptions } from "./glob.js";
18
20
  import { type GrepToolOptions } from "./grep.js";
19
21
  import { type LsToolOptions } from "./ls.js";
20
22
  import { type ReadToolOptions } from "./read.js";
21
23
  import { type WriteToolOptions } from "./write.js";
22
24
  export type Tool = AgentTool<any>;
23
25
  export type ToolDef = ToolDefinition<any, any>;
24
- export type ToolName = "read" | "bash" | "edit" | "write" | "grep" | "find" | "ls";
26
+ export type ToolName = "read" | "bash" | "edit" | "write" | "grep" | "find" | "glob" | "ls";
25
27
  export declare const allToolNames: Set<ToolName>;
26
28
  export interface ToolsOptions {
27
29
  read?: ReadToolOptions;
@@ -30,6 +32,7 @@ export interface ToolsOptions {
30
32
  edit?: EditToolOptions;
31
33
  grep?: GrepToolOptions;
32
34
  find?: FindToolOptions;
35
+ glob?: GlobToolOptions;
33
36
  ls?: LsToolOptions;
34
37
  }
35
38
  export declare function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.js\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.js\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.js\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.js\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.js\";\nexport { expandPath, resolveReadPath, resolveToCwd } from \"./path-utils.js\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.js\";\n// Off-by-default tools (enabled per session via flags/settings).\nexport {\n\tbuildTaskMainPrompt,\n\tcreateTaskOutputToolDefinition,\n\tcreateTaskToolDefinition,\n\ttype TaskOutputDetails,\n\ttype TaskToolDetails,\n} from \"./subagent.js\";\nexport { createTodoWriteToolDefinition, type TodoWriteDetails } from \"./todo.js\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.js\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.js\";\n\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.js\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.js\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.js\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.js\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.js\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.js\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.js\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"ls\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tls: createLsTool(cwd, options?.ls),\n\t};\n}\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.js\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.js\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.js\";\nexport {\n\tcreateGlobTool,\n\tcreateGlobToolDefinition,\n\ttype GlobOperations,\n\ttype GlobToolDetails,\n\ttype GlobToolInput,\n\ttype GlobToolOptions,\n} from \"./glob.js\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.js\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.js\";\nexport { expandPath, resolveReadPath, resolveToCwd } from \"./path-utils.js\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.js\";\n// Off-by-default tools (enabled per session via flags/settings).\nexport {\n\tbuildTaskMainPrompt,\n\tcreateTaskOutputToolDefinition,\n\tcreateTaskToolDefinition,\n\ttype TaskOutputDetails,\n\ttype TaskToolDetails,\n} from \"./subagent.js\";\nexport { createTodoWriteToolDefinition, type TodoWriteDetails } from \"./todo.js\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.js\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.js\";\n\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.js\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.js\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.js\";\nimport { createGlobTool, createGlobToolDefinition, type GlobToolOptions } from \"./glob.js\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.js\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.js\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.js\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.js\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"glob\" | \"ls\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"glob\", \"ls\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tglob?: GlobToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"glob\":\n\t\t\treturn createGlobToolDefinition(cwd, options?.glob);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"glob\":\n\t\t\treturn createGlobTool(cwd, options?.glob);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateGlobToolDefinition(cwd, options?.glob),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateGlobToolDefinition(cwd, options?.glob),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tglob: createGlobToolDefinition(cwd, options?.glob),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateGlobTool(cwd, options?.glob),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateGlobTool(cwd, options?.glob),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tglob: createGlobTool(cwd, options?.glob),\n\t\tls: createLsTool(cwd, options?.ls),\n\t};\n}\n"]}
@@ -2,6 +2,7 @@ export { createBashTool, createBashToolDefinition, createLocalBashOperations, }
2
2
  export { createEditTool, createEditToolDefinition, } from "./edit.js";
3
3
  export { withFileMutationQueue } from "./file-mutation-queue.js";
4
4
  export { createFindTool, createFindToolDefinition, } from "./find.js";
5
+ export { createGlobTool, createGlobToolDefinition, } from "./glob.js";
5
6
  export { createGrepTool, createGrepToolDefinition, } from "./grep.js";
6
7
  export { createLsTool, createLsToolDefinition, } from "./ls.js";
7
8
  export { expandPath, resolveReadPath, resolveToCwd } from "./path-utils.js";
@@ -14,11 +15,12 @@ export { createWriteTool, createWriteToolDefinition, } from "./write.js";
14
15
  import { createBashTool, createBashToolDefinition } from "./bash.js";
15
16
  import { createEditTool, createEditToolDefinition } from "./edit.js";
16
17
  import { createFindTool, createFindToolDefinition } from "./find.js";
18
+ import { createGlobTool, createGlobToolDefinition } from "./glob.js";
17
19
  import { createGrepTool, createGrepToolDefinition } from "./grep.js";
18
20
  import { createLsTool, createLsToolDefinition } from "./ls.js";
19
21
  import { createReadTool, createReadToolDefinition } from "./read.js";
20
22
  import { createWriteTool, createWriteToolDefinition } from "./write.js";
21
- export const allToolNames = new Set(["read", "bash", "edit", "write", "grep", "find", "ls"]);
23
+ export const allToolNames = new Set(["read", "bash", "edit", "write", "grep", "find", "glob", "ls"]);
22
24
  export function createToolDefinition(toolName, cwd, options) {
23
25
  switch (toolName) {
24
26
  case "read":
@@ -33,6 +35,8 @@ export function createToolDefinition(toolName, cwd, options) {
33
35
  return createGrepToolDefinition(cwd, options?.grep);
34
36
  case "find":
35
37
  return createFindToolDefinition(cwd, options?.find);
38
+ case "glob":
39
+ return createGlobToolDefinition(cwd, options?.glob);
36
40
  case "ls":
37
41
  return createLsToolDefinition(cwd, options?.ls);
38
42
  default:
@@ -53,6 +57,8 @@ export function createTool(toolName, cwd, options) {
53
57
  return createGrepTool(cwd, options?.grep);
54
58
  case "find":
55
59
  return createFindTool(cwd, options?.find);
60
+ case "glob":
61
+ return createGlobTool(cwd, options?.glob);
56
62
  case "ls":
57
63
  return createLsTool(cwd, options?.ls);
58
64
  default:
@@ -67,6 +73,7 @@ export function createCodingToolDefinitions(cwd, options) {
67
73
  createWriteToolDefinition(cwd, options?.write),
68
74
  createGrepToolDefinition(cwd, options?.grep),
69
75
  createFindToolDefinition(cwd, options?.find),
76
+ createGlobToolDefinition(cwd, options?.glob),
70
77
  createLsToolDefinition(cwd, options?.ls),
71
78
  ];
72
79
  }
@@ -75,6 +82,7 @@ export function createReadOnlyToolDefinitions(cwd, options) {
75
82
  createReadToolDefinition(cwd, options?.read),
76
83
  createGrepToolDefinition(cwd, options?.grep),
77
84
  createFindToolDefinition(cwd, options?.find),
85
+ createGlobToolDefinition(cwd, options?.glob),
78
86
  createLsToolDefinition(cwd, options?.ls),
79
87
  ];
80
88
  }
@@ -86,6 +94,7 @@ export function createAllToolDefinitions(cwd, options) {
86
94
  write: createWriteToolDefinition(cwd, options?.write),
87
95
  grep: createGrepToolDefinition(cwd, options?.grep),
88
96
  find: createFindToolDefinition(cwd, options?.find),
97
+ glob: createGlobToolDefinition(cwd, options?.glob),
89
98
  ls: createLsToolDefinition(cwd, options?.ls),
90
99
  };
91
100
  }
@@ -97,6 +106,7 @@ export function createCodingTools(cwd, options) {
97
106
  createWriteTool(cwd, options?.write),
98
107
  createGrepTool(cwd, options?.grep),
99
108
  createFindTool(cwd, options?.find),
109
+ createGlobTool(cwd, options?.glob),
100
110
  createLsTool(cwd, options?.ls),
101
111
  ];
102
112
  }
@@ -105,6 +115,7 @@ export function createReadOnlyTools(cwd, options) {
105
115
  createReadTool(cwd, options?.read),
106
116
  createGrepTool(cwd, options?.grep),
107
117
  createFindTool(cwd, options?.find),
118
+ createGlobTool(cwd, options?.glob),
108
119
  createLsTool(cwd, options?.ls),
109
120
  ];
110
121
  }
@@ -116,6 +127,7 @@ export function createAllTools(cwd, options) {
116
127
  write: createWriteTool(cwd, options?.write),
117
128
  grep: createGrepTool(cwd, options?.grep),
118
129
  find: createFindTool(cwd, options?.find),
130
+ glob: createGlobTool(cwd, options?.glob),
119
131
  ls: createLsTool(cwd, options?.ls),
120
132
  };
121
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.js\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.js\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.js\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.js\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.js\";\nexport { expandPath, resolveReadPath, resolveToCwd } from \"./path-utils.js\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.js\";\n// Off-by-default tools (enabled per session via flags/settings).\nexport {\n\tbuildTaskMainPrompt,\n\tcreateTaskOutputToolDefinition,\n\tcreateTaskToolDefinition,\n\ttype TaskOutputDetails,\n\ttype TaskToolDetails,\n} from \"./subagent.js\";\nexport { createTodoWriteToolDefinition, type TodoWriteDetails } from \"./todo.js\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.js\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.js\";\n\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.js\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.js\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.js\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.js\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.js\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.js\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.js\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"ls\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tls: createLsTool(cwd, options?.ls),\n\t};\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.js\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.js\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.js\";\nexport {\n\tcreateGlobTool,\n\tcreateGlobToolDefinition,\n\ttype GlobOperations,\n\ttype GlobToolDetails,\n\ttype GlobToolInput,\n\ttype GlobToolOptions,\n} from \"./glob.js\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.js\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.js\";\nexport { expandPath, resolveReadPath, resolveToCwd } from \"./path-utils.js\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.js\";\n// Off-by-default tools (enabled per session via flags/settings).\nexport {\n\tbuildTaskMainPrompt,\n\tcreateTaskOutputToolDefinition,\n\tcreateTaskToolDefinition,\n\ttype TaskOutputDetails,\n\ttype TaskToolDetails,\n} from \"./subagent.js\";\nexport { createTodoWriteToolDefinition, type TodoWriteDetails } from \"./todo.js\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.js\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.js\";\n\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.js\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.js\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.js\";\nimport { createGlobTool, createGlobToolDefinition, type GlobToolOptions } from \"./glob.js\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.js\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.js\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.js\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.js\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"glob\" | \"ls\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"glob\", \"ls\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tglob?: GlobToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"glob\":\n\t\t\treturn createGlobToolDefinition(cwd, options?.glob);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"glob\":\n\t\t\treturn createGlobTool(cwd, options?.glob);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateGlobToolDefinition(cwd, options?.glob),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateGlobToolDefinition(cwd, options?.glob),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tglob: createGlobToolDefinition(cwd, options?.glob),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateGlobTool(cwd, options?.glob),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateGlobTool(cwd, options?.glob),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tglob: createGlobTool(cwd, options?.glob),\n\t\tls: createLsTool(cwd, options?.ls),\n\t};\n}\n"]}
@@ -25,8 +25,19 @@ export interface LsOperations {
25
25
  }> | {
26
26
  isDirectory: () => boolean;
27
27
  };
28
- /** Read directory entries */
28
+ /** Read directory entries as strings (used when readdirEntries is not provided) */
29
29
  readdir: (absolutePath: string) => Promise<string[]> | string[];
30
+ /**
31
+ * Optional: read directory entries with type info in a single syscall.
32
+ * When provided, eliminates per-entry stat() calls for the isDirectory check.
33
+ */
34
+ readdirEntries?: (absolutePath: string) => Promise<Array<{
35
+ name: string;
36
+ isDirectory: () => boolean;
37
+ }>> | Array<{
38
+ name: string;
39
+ isDirectory: () => boolean;
40
+ }>;
30
41
  }
31
42
  export interface LsToolOptions {
32
43
  /** Custom operations for directory listing. Default: local filesystem */