@morphllm/morphsdk 0.2.145 → 0.2.146

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 (205) hide show
  1. package/dist/{chunk-HBIW2XV2.js → chunk-4PBUB77N.js} +2 -2
  2. package/dist/{chunk-SUE4GYA2.js → chunk-BDHKL3MT.js} +2 -2
  3. package/dist/{chunk-S54SPKX3.js → chunk-BIQ7234U.js} +2 -2
  4. package/dist/{chunk-I3J46TSB.js → chunk-DKODF3YG.js} +4 -5
  5. package/dist/chunk-DKODF3YG.js.map +1 -0
  6. package/dist/{chunk-MRPASJBX.js → chunk-E45FW5EK.js} +2 -2
  7. package/dist/{chunk-BXRJYLRS.js → chunk-E4YKEKGW.js} +2 -2
  8. package/dist/{chunk-G23BI5CQ.js → chunk-EU7OLX4Z.js} +2 -2
  9. package/dist/chunk-EUHNJMWL.js +409 -0
  10. package/dist/chunk-EUHNJMWL.js.map +1 -0
  11. package/dist/{chunk-HE7K2QNQ.js → chunk-FBOJJ3UY.js} +17 -17
  12. package/dist/{chunk-HYRHI2UL.js → chunk-FIVYDIHX.js} +1 -1
  13. package/dist/{chunk-GXM3G7Z4.js → chunk-FYO46OT6.js} +2 -2
  14. package/dist/{chunk-GHPQYSSF.js → chunk-GJUB3ECP.js} +2 -2
  15. package/dist/{chunk-4Y2NM6JD.js → chunk-HZOTLGJH.js} +2 -42
  16. package/dist/chunk-HZOTLGJH.js.map +1 -0
  17. package/dist/{chunk-MTJ3PR4M.js → chunk-I7SFRYTX.js} +2 -2
  18. package/dist/{chunk-PX7ODEML.js → chunk-J2HIK4GB.js} +2 -2
  19. package/dist/{chunk-RZXS4ADX.js → chunk-JSWNBCGS.js} +2 -2
  20. package/dist/{chunk-GXCWKYGU.js → chunk-KYKRRF7E.js} +2 -2
  21. package/dist/{chunk-N7TTZIBK.js → chunk-MMBQKN4G.js} +2 -2
  22. package/dist/{chunk-B3AKP3RA.js → chunk-NF2QWJDY.js} +2 -31
  23. package/dist/chunk-NF2QWJDY.js.map +1 -0
  24. package/dist/{chunk-JMUAQQJU.js → chunk-NKUSUSVI.js} +3 -3
  25. package/dist/{chunk-VRV5UYTN.js → chunk-OV57JBMB.js} +2 -2
  26. package/dist/{chunk-EPIOAODF.js → chunk-Q36MNOFA.js} +2 -2
  27. package/dist/{chunk-JRBU4UNP.js → chunk-QRSWXP4K.js} +2 -2
  28. package/dist/{chunk-KELRCMA6.js → chunk-SJYAKVSS.js} +2 -2
  29. package/dist/{chunk-KELRCMA6.js.map → chunk-SJYAKVSS.js.map} +1 -1
  30. package/dist/{chunk-IRWHN55G.js → chunk-T564HFSH.js} +1 -1
  31. package/dist/{chunk-6CFKWZK3.js → chunk-UVNENJ6H.js} +3 -3
  32. package/dist/{chunk-5FCXLQJU.js → chunk-UYPWKQKV.js} +2 -2
  33. package/dist/{chunk-BAF33L6C.js → chunk-V73GO5AJ.js} +2 -2
  34. package/dist/chunk-VCKJ22DX.js +131 -0
  35. package/dist/chunk-VCKJ22DX.js.map +1 -0
  36. package/dist/{chunk-XL7R3XN5.js → chunk-VZ6VYRQB.js} +2 -2
  37. package/dist/{chunk-4LWMPKSB.js → chunk-YIETFYCL.js} +44 -71
  38. package/dist/chunk-YIETFYCL.js.map +1 -0
  39. package/dist/client.cjs +438 -426
  40. package/dist/client.cjs.map +1 -1
  41. package/dist/client.js +27 -26
  42. package/dist/edge.cjs +1 -1
  43. package/dist/edge.cjs.map +1 -1
  44. package/dist/edge.js +4 -4
  45. package/dist/{finish-Ddj1MPGt.d.ts → finish-DBKuo8yj.d.ts} +1 -1
  46. package/dist/index.cjs +438 -445
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.js +29 -29
  49. package/dist/modelrouter/core.cjs +1 -1
  50. package/dist/modelrouter/core.cjs.map +1 -1
  51. package/dist/modelrouter/core.js +3 -3
  52. package/dist/modelrouter/index.cjs +1 -1
  53. package/dist/modelrouter/index.cjs.map +1 -1
  54. package/dist/modelrouter/index.js +3 -3
  55. package/dist/subagents/anthropic.cjs +434 -422
  56. package/dist/subagents/anthropic.cjs.map +1 -1
  57. package/dist/subagents/anthropic.js +9 -8
  58. package/dist/subagents/vercel.cjs +434 -422
  59. package/dist/subagents/vercel.cjs.map +1 -1
  60. package/dist/subagents/vercel.js +9 -8
  61. package/dist/tools/browser/anthropic.cjs +1 -1
  62. package/dist/tools/browser/anthropic.cjs.map +1 -1
  63. package/dist/tools/browser/anthropic.js +5 -5
  64. package/dist/tools/browser/core.cjs +1 -1
  65. package/dist/tools/browser/core.cjs.map +1 -1
  66. package/dist/tools/browser/core.js +4 -4
  67. package/dist/tools/browser/index.cjs +1 -1
  68. package/dist/tools/browser/index.cjs.map +1 -1
  69. package/dist/tools/browser/index.js +7 -7
  70. package/dist/tools/browser/openai.cjs +1 -1
  71. package/dist/tools/browser/openai.cjs.map +1 -1
  72. package/dist/tools/browser/openai.js +5 -5
  73. package/dist/tools/browser/profiles/core.cjs +1 -1
  74. package/dist/tools/browser/profiles/core.cjs.map +1 -1
  75. package/dist/tools/browser/profiles/core.js +3 -3
  76. package/dist/tools/browser/profiles/index.cjs +1 -1
  77. package/dist/tools/browser/profiles/index.cjs.map +1 -1
  78. package/dist/tools/browser/profiles/index.js +3 -3
  79. package/dist/tools/browser/vercel.cjs +1 -1
  80. package/dist/tools/browser/vercel.cjs.map +1 -1
  81. package/dist/tools/browser/vercel.js +5 -5
  82. package/dist/tools/codebase_search/anthropic.cjs +1 -1
  83. package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
  84. package/dist/tools/codebase_search/anthropic.js +4 -4
  85. package/dist/tools/codebase_search/core.cjs +1 -1
  86. package/dist/tools/codebase_search/core.cjs.map +1 -1
  87. package/dist/tools/codebase_search/core.js +3 -3
  88. package/dist/tools/codebase_search/index.cjs +1 -1
  89. package/dist/tools/codebase_search/index.cjs.map +1 -1
  90. package/dist/tools/codebase_search/index.js +6 -6
  91. package/dist/tools/codebase_search/openai.cjs +1 -1
  92. package/dist/tools/codebase_search/openai.cjs.map +1 -1
  93. package/dist/tools/codebase_search/openai.js +4 -4
  94. package/dist/tools/codebase_search/vercel.cjs +1 -1
  95. package/dist/tools/codebase_search/vercel.cjs.map +1 -1
  96. package/dist/tools/codebase_search/vercel.js +4 -4
  97. package/dist/tools/fastapply/anthropic.cjs +1 -1
  98. package/dist/tools/fastapply/anthropic.cjs.map +1 -1
  99. package/dist/tools/fastapply/anthropic.js +4 -4
  100. package/dist/tools/fastapply/apply.cjs +1 -1
  101. package/dist/tools/fastapply/apply.cjs.map +1 -1
  102. package/dist/tools/fastapply/apply.js +2 -2
  103. package/dist/tools/fastapply/core.cjs +1 -1
  104. package/dist/tools/fastapply/core.cjs.map +1 -1
  105. package/dist/tools/fastapply/core.js +3 -3
  106. package/dist/tools/fastapply/index.cjs +1 -1
  107. package/dist/tools/fastapply/index.cjs.map +1 -1
  108. package/dist/tools/fastapply/index.js +6 -6
  109. package/dist/tools/fastapply/openai.cjs +1 -1
  110. package/dist/tools/fastapply/openai.cjs.map +1 -1
  111. package/dist/tools/fastapply/openai.js +4 -4
  112. package/dist/tools/fastapply/vercel.cjs +1 -1
  113. package/dist/tools/fastapply/vercel.cjs.map +1 -1
  114. package/dist/tools/fastapply/vercel.js +4 -4
  115. package/dist/tools/index.cjs +1 -1
  116. package/dist/tools/index.cjs.map +1 -1
  117. package/dist/tools/index.js +6 -6
  118. package/dist/tools/utils/resilience.cjs +1 -1
  119. package/dist/tools/utils/resilience.cjs.map +1 -1
  120. package/dist/tools/utils/resilience.js +2 -2
  121. package/dist/tools/warp_grep/agent/config.cjs +3 -4
  122. package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
  123. package/dist/tools/warp_grep/agent/config.d.ts +1 -2
  124. package/dist/tools/warp_grep/agent/config.js +1 -1
  125. package/dist/tools/warp_grep/agent/parser.cjs +121 -52
  126. package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
  127. package/dist/tools/warp_grep/agent/parser.d.ts +5 -12
  128. package/dist/tools/warp_grep/agent/parser.js +3 -7
  129. package/dist/tools/warp_grep/agent/runner.cjs +416 -335
  130. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  131. package/dist/tools/warp_grep/agent/runner.d.ts +3 -6
  132. package/dist/tools/warp_grep/agent/runner.js +6 -5
  133. package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
  134. package/dist/tools/warp_grep/agent/types.d.ts +3 -22
  135. package/dist/tools/warp_grep/anthropic.cjs +434 -422
  136. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  137. package/dist/tools/warp_grep/anthropic.js +9 -8
  138. package/dist/tools/warp_grep/client.cjs +434 -422
  139. package/dist/tools/warp_grep/client.cjs.map +1 -1
  140. package/dist/tools/warp_grep/client.js +8 -7
  141. package/dist/tools/warp_grep/gemini.cjs +434 -422
  142. package/dist/tools/warp_grep/gemini.cjs.map +1 -1
  143. package/dist/tools/warp_grep/gemini.js +8 -7
  144. package/dist/tools/warp_grep/gemini.js.map +1 -1
  145. package/dist/tools/warp_grep/harness.cjs +176 -164
  146. package/dist/tools/warp_grep/harness.cjs.map +1 -1
  147. package/dist/tools/warp_grep/harness.d.ts +38 -17
  148. package/dist/tools/warp_grep/harness.js +14 -15
  149. package/dist/tools/warp_grep/harness.js.map +1 -1
  150. package/dist/tools/warp_grep/index.cjs +434 -441
  151. package/dist/tools/warp_grep/index.cjs.map +1 -1
  152. package/dist/tools/warp_grep/index.d.ts +1 -1
  153. package/dist/tools/warp_grep/index.js +10 -10
  154. package/dist/tools/warp_grep/openai.cjs +434 -422
  155. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  156. package/dist/tools/warp_grep/openai.js +9 -8
  157. package/dist/tools/warp_grep/providers/local.cjs +2 -43
  158. package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
  159. package/dist/tools/warp_grep/providers/local.d.ts +1 -5
  160. package/dist/tools/warp_grep/providers/local.js +2 -2
  161. package/dist/tools/warp_grep/providers/remote.cjs +2 -32
  162. package/dist/tools/warp_grep/providers/remote.cjs.map +1 -1
  163. package/dist/tools/warp_grep/providers/remote.d.ts +1 -9
  164. package/dist/tools/warp_grep/providers/remote.js +2 -2
  165. package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
  166. package/dist/tools/warp_grep/providers/types.d.ts +1 -14
  167. package/dist/tools/warp_grep/vercel.cjs +434 -422
  168. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  169. package/dist/tools/warp_grep/vercel.js +9 -8
  170. package/dist/version.cjs +1 -1
  171. package/dist/version.cjs.map +1 -1
  172. package/dist/version.js +1 -1
  173. package/package.json +1 -1
  174. package/dist/chunk-4LWMPKSB.js.map +0 -1
  175. package/dist/chunk-4Y2NM6JD.js.map +0 -1
  176. package/dist/chunk-B3AKP3RA.js.map +0 -1
  177. package/dist/chunk-CMSHXALI.js +0 -60
  178. package/dist/chunk-CMSHXALI.js.map +0 -1
  179. package/dist/chunk-I3J46TSB.js.map +0 -1
  180. package/dist/chunk-OPEQQGST.js +0 -396
  181. package/dist/chunk-OPEQQGST.js.map +0 -1
  182. /package/dist/{chunk-HBIW2XV2.js.map → chunk-4PBUB77N.js.map} +0 -0
  183. /package/dist/{chunk-SUE4GYA2.js.map → chunk-BDHKL3MT.js.map} +0 -0
  184. /package/dist/{chunk-S54SPKX3.js.map → chunk-BIQ7234U.js.map} +0 -0
  185. /package/dist/{chunk-MRPASJBX.js.map → chunk-E45FW5EK.js.map} +0 -0
  186. /package/dist/{chunk-BXRJYLRS.js.map → chunk-E4YKEKGW.js.map} +0 -0
  187. /package/dist/{chunk-G23BI5CQ.js.map → chunk-EU7OLX4Z.js.map} +0 -0
  188. /package/dist/{chunk-HE7K2QNQ.js.map → chunk-FBOJJ3UY.js.map} +0 -0
  189. /package/dist/{chunk-HYRHI2UL.js.map → chunk-FIVYDIHX.js.map} +0 -0
  190. /package/dist/{chunk-GXM3G7Z4.js.map → chunk-FYO46OT6.js.map} +0 -0
  191. /package/dist/{chunk-GHPQYSSF.js.map → chunk-GJUB3ECP.js.map} +0 -0
  192. /package/dist/{chunk-MTJ3PR4M.js.map → chunk-I7SFRYTX.js.map} +0 -0
  193. /package/dist/{chunk-PX7ODEML.js.map → chunk-J2HIK4GB.js.map} +0 -0
  194. /package/dist/{chunk-RZXS4ADX.js.map → chunk-JSWNBCGS.js.map} +0 -0
  195. /package/dist/{chunk-GXCWKYGU.js.map → chunk-KYKRRF7E.js.map} +0 -0
  196. /package/dist/{chunk-N7TTZIBK.js.map → chunk-MMBQKN4G.js.map} +0 -0
  197. /package/dist/{chunk-JMUAQQJU.js.map → chunk-NKUSUSVI.js.map} +0 -0
  198. /package/dist/{chunk-VRV5UYTN.js.map → chunk-OV57JBMB.js.map} +0 -0
  199. /package/dist/{chunk-EPIOAODF.js.map → chunk-Q36MNOFA.js.map} +0 -0
  200. /package/dist/{chunk-JRBU4UNP.js.map → chunk-QRSWXP4K.js.map} +0 -0
  201. /package/dist/{chunk-IRWHN55G.js.map → chunk-T564HFSH.js.map} +0 -0
  202. /package/dist/{chunk-6CFKWZK3.js.map → chunk-UVNENJ6H.js.map} +0 -0
  203. /package/dist/{chunk-5FCXLQJU.js.map → chunk-UYPWKQKV.js.map} +0 -0
  204. /package/dist/{chunk-BAF33L6C.js.map → chunk-V73GO5AJ.js.map} +0 -0
  205. /package/dist/{chunk-XL7R3XN5.js.map → chunk-VZ6VYRQB.js.map} +0 -0
@@ -0,0 +1,131 @@
1
+ // tools/warp_grep/agent/parser.ts
2
+ var VALID_COMMANDS = ["list_directory", "ripgrep", "read", "finish"];
3
+ function isValidCommand(name) {
4
+ return VALID_COMMANDS.includes(name);
5
+ }
6
+ function parseQwen3ToolCalls(text) {
7
+ const tools = [];
8
+ const toolCallRegex = /<tool_call>\s*<function=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/function>\s*<\/tool_call>/gi;
9
+ let match;
10
+ while ((match = toolCallRegex.exec(text)) !== null) {
11
+ const funcName = match[1].toLowerCase();
12
+ const body = match[2];
13
+ if (!isValidCommand(funcName)) continue;
14
+ const params = {};
15
+ const paramRegex = /<parameter=([a-z_][a-z0-9_]*)>([\s\S]*?)<\/parameter>/gi;
16
+ let paramMatch;
17
+ while ((paramMatch = paramRegex.exec(body)) !== null) {
18
+ params[paramMatch[1].toLowerCase()] = paramMatch[2].trim();
19
+ }
20
+ if (funcName === "ripgrep") {
21
+ const pattern = params.pattern;
22
+ if (!pattern) continue;
23
+ const args = {
24
+ pattern,
25
+ path: params.path || ".",
26
+ ...params.glob && { glob: params.glob },
27
+ ...params.context_lines && { context_lines: parseInt(params.context_lines, 10) },
28
+ ...params.case_sensitive && { case_sensitive: params.case_sensitive === "true" }
29
+ };
30
+ tools.push({ name: "grep", arguments: args });
31
+ } else if (funcName === "list_directory") {
32
+ const command = params.command;
33
+ const directPath = params.path;
34
+ let dirPath = directPath || ".";
35
+ if (!directPath && command) {
36
+ const tokens = command.trim().split(/\s+/);
37
+ const pathTokens = tokens.slice(1).filter((t) => !t.startsWith("-") && !t.startsWith("|") && !t.startsWith("\\("));
38
+ if (pathTokens.length > 0) {
39
+ dirPath = pathTokens[0];
40
+ }
41
+ }
42
+ tools.push({ name: "list_directory", arguments: { path: dirPath, pattern: params.pattern || null } });
43
+ } else if (funcName === "read") {
44
+ const filePath = params.path;
45
+ if (!filePath) continue;
46
+ const args = { path: filePath };
47
+ const linesStr = params.lines;
48
+ if (linesStr) {
49
+ const ranges = [];
50
+ for (const rangeStr of linesStr.split(",")) {
51
+ const trimmed = rangeStr.trim();
52
+ if (!trimmed) continue;
53
+ const [s, e] = trimmed.split("-").map((v) => parseInt(v.trim(), 10));
54
+ if (Number.isFinite(s) && Number.isFinite(e)) {
55
+ ranges.push([s, e]);
56
+ } else if (Number.isFinite(s)) {
57
+ ranges.push([s, s]);
58
+ }
59
+ }
60
+ if (ranges.length === 1) {
61
+ args.start = ranges[0][0];
62
+ args.end = ranges[0][1];
63
+ } else if (ranges.length > 1) {
64
+ args.lines = ranges;
65
+ }
66
+ }
67
+ tools.push({ name: "read", arguments: args });
68
+ } else if (funcName === "finish") {
69
+ if (params.result && !params.files) {
70
+ tools.push({ name: "finish", arguments: { files: [], textResult: params.result } });
71
+ continue;
72
+ }
73
+ const filesStr = params.files;
74
+ if (!filesStr) {
75
+ tools.push({ name: "finish", arguments: { files: [], textResult: "No relevant code found." } });
76
+ continue;
77
+ }
78
+ const files = [];
79
+ for (const line of filesStr.split("\n")) {
80
+ const trimmed = line.trim();
81
+ if (!trimmed) continue;
82
+ const colonIdx = trimmed.indexOf(":");
83
+ if (colonIdx === -1) {
84
+ files.push({ path: trimmed, lines: "*" });
85
+ } else {
86
+ const filePath = trimmed.slice(0, colonIdx);
87
+ const rangesPart = trimmed.slice(colonIdx + 1);
88
+ const ranges = [];
89
+ for (const rangeStr of rangesPart.split(",")) {
90
+ const rt = rangeStr.trim();
91
+ if (!rt || rt === "*") {
92
+ files.push({ path: filePath, lines: "*" });
93
+ break;
94
+ }
95
+ const [s, e] = rt.split("-").map((v) => parseInt(v.trim(), 10));
96
+ if (Number.isFinite(s) && Number.isFinite(e)) {
97
+ ranges.push([s, e]);
98
+ } else if (Number.isFinite(s)) {
99
+ ranges.push([s, s]);
100
+ }
101
+ }
102
+ if (ranges.length > 0) {
103
+ files.push({ path: filePath, lines: ranges });
104
+ } else if (!files.some((f) => f.path === filePath)) {
105
+ files.push({ path: filePath, lines: "*" });
106
+ }
107
+ }
108
+ }
109
+ if (files.length > 0) {
110
+ tools.push({ name: "finish", arguments: { files } });
111
+ } else {
112
+ tools.push({ name: "finish", arguments: { files: [], textResult: filesStr } });
113
+ }
114
+ }
115
+ }
116
+ return tools;
117
+ }
118
+ var LLMResponseParser = class {
119
+ parse(text) {
120
+ if (typeof text !== "string") {
121
+ throw new TypeError("Command text must be a string.");
122
+ }
123
+ const withoutThink = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
124
+ return parseQwen3ToolCalls(withoutThink);
125
+ }
126
+ };
127
+
128
+ export {
129
+ LLMResponseParser
130
+ };
131
+ //# sourceMappingURL=chunk-VCKJ22DX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/warp_grep/agent/parser.ts"],"sourcesContent":["// Parses assistant lines into structured tool calls (Qwen3-Coder-Next format only)\nimport type { ToolCall } from './types.js';\n\nconst VALID_COMMANDS = ['list_directory', 'ripgrep', 'read', 'finish'] as const;\ntype ValidCommand = typeof VALID_COMMANDS[number];\n\nfunction isValidCommand(name: string): name is ValidCommand {\n return VALID_COMMANDS.includes(name as ValidCommand);\n}\n\n/**\n * Parse Qwen3-Coder-Next native XML tool call format:\n * <tool_call><function=NAME><parameter=KEY>VALUE</parameter></function></tool_call>\n */\nfunction parseQwen3ToolCalls(text: string): ToolCall[] {\n const tools: ToolCall[] = [];\n const toolCallRegex = /<tool_call>\\s*<function=([a-z_][a-z0-9_]*)>([\\s\\S]*?)<\\/function>\\s*<\\/tool_call>/gi;\n let match;\n\n while ((match = toolCallRegex.exec(text)) !== null) {\n const funcName = match[1].toLowerCase();\n const body = match[2];\n\n if (!isValidCommand(funcName)) continue;\n\n // Extract all <parameter=KEY>VALUE</parameter> pairs\n const params: Record<string, string> = {};\n const paramRegex = /<parameter=([a-z_][a-z0-9_]*)>([\\s\\S]*?)<\\/parameter>/gi;\n let paramMatch;\n while ((paramMatch = paramRegex.exec(body)) !== null) {\n params[paramMatch[1].toLowerCase()] = paramMatch[2].trim();\n }\n\n if (funcName === 'ripgrep') {\n const pattern = params.pattern;\n if (!pattern) continue;\n const args: Record<string, unknown> = {\n pattern,\n path: params.path || '.',\n ...(params.glob && { glob: params.glob }),\n ...(params.context_lines && { context_lines: parseInt(params.context_lines, 10) }),\n ...(params.case_sensitive && { case_sensitive: params.case_sensitive === 'true' }),\n };\n tools.push({ name: 'grep', arguments: args });\n } else if (funcName === 'list_directory') {\n // Extract path from command parameter (best effort: look for target directory)\n const command = params.command;\n const directPath = params.path;\n let dirPath = directPath || '.';\n if (!directPath && command) {\n // Try to extract a meaningful path from the command string\n // Common patterns: \"find <path> ...\", \"ls <path>\", \"ls -la <path>\"\n // Skip the command name and any flags (tokens starting with -, \\(, |)\n const tokens = command.trim().split(/\\s+/);\n const pathTokens = tokens.slice(1).filter(t => !t.startsWith('-') && !t.startsWith('|') && !t.startsWith('\\\\('));\n if (pathTokens.length > 0) {\n dirPath = pathTokens[0];\n }\n }\n tools.push({ name: 'list_directory', arguments: { path: dirPath, pattern: params.pattern || null } });\n } else if (funcName === 'read') {\n const filePath = params.path;\n if (!filePath) continue;\n const args: Record<string, unknown> = { path: filePath };\n const linesStr = params.lines;\n if (linesStr) {\n const ranges: Array<[number, number]> = [];\n for (const rangeStr of linesStr.split(',')) {\n const trimmed = rangeStr.trim();\n if (!trimmed) continue;\n const [s, e] = trimmed.split('-').map(v => parseInt(v.trim(), 10));\n if (Number.isFinite(s) && Number.isFinite(e)) {\n ranges.push([s, e]);\n } else if (Number.isFinite(s)) {\n ranges.push([s, s]);\n }\n }\n if (ranges.length === 1) {\n args.start = ranges[0][0];\n args.end = ranges[0][1];\n } else if (ranges.length > 1) {\n args.lines = ranges;\n }\n }\n tools.push({ name: 'read', arguments: args });\n } else if (funcName === 'finish') {\n // If the model used \"result\" parameter instead of \"files\", treat as text-only finish\n if (params.result && !params.files) {\n tools.push({ name: 'finish', arguments: { files: [], textResult: params.result } });\n continue;\n }\n const filesStr = params.files;\n if (!filesStr) {\n tools.push({ name: 'finish', arguments: { files: [], textResult: 'No relevant code found.' } });\n continue;\n }\n // Parse flat string format: \"path:start-end\\npath\" or \"path\\npath:start-end\"\n const files: Array<{ path: string; lines: '*' | Array<[number, number]> }> = [];\n for (const line of filesStr.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) {\n // No colon — whole file\n files.push({ path: trimmed, lines: '*' });\n } else {\n const filePath = trimmed.slice(0, colonIdx);\n const rangesPart = trimmed.slice(colonIdx + 1);\n const ranges: Array<[number, number]> = [];\n for (const rangeStr of rangesPart.split(',')) {\n const rt = rangeStr.trim();\n if (!rt || rt === '*') {\n // Whole file marker\n files.push({ path: filePath, lines: '*' });\n break;\n }\n const [s, e] = rt.split('-').map(v => parseInt(v.trim(), 10));\n if (Number.isFinite(s) && Number.isFinite(e)) {\n ranges.push([s, e]);\n } else if (Number.isFinite(s)) {\n // Single line\n ranges.push([s, s]);\n }\n }\n if (ranges.length > 0) {\n files.push({ path: filePath, lines: ranges });\n } else if (!files.some(f => f.path === filePath)) {\n files.push({ path: filePath, lines: '*' });\n }\n }\n }\n if (files.length > 0) {\n tools.push({ name: 'finish', arguments: { files } });\n } else {\n tools.push({ name: 'finish', arguments: { files: [], textResult: filesStr } });\n }\n }\n }\n\n return tools;\n}\n\nexport class LLMResponseParser {\n parse(text: string): ToolCall[] {\n if (typeof text !== 'string') {\n throw new TypeError('Command text must be a string.');\n }\n\n // Strip <think> blocks\n const withoutThink = text.replace(/<think>[\\s\\S]*?<\\/think>/gi, '');\n\n // Parse Qwen3 <tool_call><function=...> format\n return parseQwen3ToolCalls(withoutThink);\n }\n}\n"],"mappings":";AAGA,IAAM,iBAAiB,CAAC,kBAAkB,WAAW,QAAQ,QAAQ;AAGrE,SAAS,eAAe,MAAoC;AAC1D,SAAO,eAAe,SAAS,IAAoB;AACrD;AAMA,SAAS,oBAAoB,MAA0B;AACrD,QAAM,QAAoB,CAAC;AAC3B,QAAM,gBAAgB;AACtB,MAAI;AAEJ,UAAQ,QAAQ,cAAc,KAAK,IAAI,OAAO,MAAM;AAClD,UAAM,WAAW,MAAM,CAAC,EAAE,YAAY;AACtC,UAAM,OAAO,MAAM,CAAC;AAEpB,QAAI,CAAC,eAAe,QAAQ,EAAG;AAG/B,UAAM,SAAiC,CAAC;AACxC,UAAM,aAAa;AACnB,QAAI;AACJ,YAAQ,aAAa,WAAW,KAAK,IAAI,OAAO,MAAM;AACpD,aAAO,WAAW,CAAC,EAAE,YAAY,CAAC,IAAI,WAAW,CAAC,EAAE,KAAK;AAAA,IAC3D;AAEA,QAAI,aAAa,WAAW;AAC1B,YAAM,UAAU,OAAO;AACvB,UAAI,CAAC,QAAS;AACd,YAAM,OAAgC;AAAA,QACpC;AAAA,QACA,MAAM,OAAO,QAAQ;AAAA,QACrB,GAAI,OAAO,QAAQ,EAAE,MAAM,OAAO,KAAK;AAAA,QACvC,GAAI,OAAO,iBAAiB,EAAE,eAAe,SAAS,OAAO,eAAe,EAAE,EAAE;AAAA,QAChF,GAAI,OAAO,kBAAkB,EAAE,gBAAgB,OAAO,mBAAmB,OAAO;AAAA,MAClF;AACA,YAAM,KAAK,EAAE,MAAM,QAAQ,WAAW,KAAK,CAAC;AAAA,IAC9C,WAAW,aAAa,kBAAkB;AAExC,YAAM,UAAU,OAAO;AACvB,YAAM,aAAa,OAAO;AAC1B,UAAI,UAAU,cAAc;AAC5B,UAAI,CAAC,cAAc,SAAS;AAI1B,cAAM,SAAS,QAAQ,KAAK,EAAE,MAAM,KAAK;AACzC,cAAM,aAAa,OAAO,MAAM,CAAC,EAAE,OAAO,OAAK,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC,EAAE,WAAW,KAAK,CAAC;AAC/G,YAAI,WAAW,SAAS,GAAG;AACzB,oBAAU,WAAW,CAAC;AAAA,QACxB;AAAA,MACF;AACA,YAAM,KAAK,EAAE,MAAM,kBAAkB,WAAW,EAAE,MAAM,SAAS,SAAS,OAAO,WAAW,KAAK,EAAE,CAAC;AAAA,IACtG,WAAW,aAAa,QAAQ;AAC9B,YAAM,WAAW,OAAO;AACxB,UAAI,CAAC,SAAU;AACf,YAAM,OAAgC,EAAE,MAAM,SAAS;AACvD,YAAM,WAAW,OAAO;AACxB,UAAI,UAAU;AACZ,cAAM,SAAkC,CAAC;AACzC,mBAAW,YAAY,SAAS,MAAM,GAAG,GAAG;AAC1C,gBAAM,UAAU,SAAS,KAAK;AAC9B,cAAI,CAAC,QAAS;AACd,gBAAM,CAAC,GAAG,CAAC,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,OAAK,SAAS,EAAE,KAAK,GAAG,EAAE,CAAC;AACjE,cAAI,OAAO,SAAS,CAAC,KAAK,OAAO,SAAS,CAAC,GAAG;AAC5C,mBAAO,KAAK,CAAC,GAAG,CAAC,CAAC;AAAA,UACpB,WAAW,OAAO,SAAS,CAAC,GAAG;AAC7B,mBAAO,KAAK,CAAC,GAAG,CAAC,CAAC;AAAA,UACpB;AAAA,QACF;AACA,YAAI,OAAO,WAAW,GAAG;AACvB,eAAK,QAAQ,OAAO,CAAC,EAAE,CAAC;AACxB,eAAK,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,QACxB,WAAW,OAAO,SAAS,GAAG;AAC5B,eAAK,QAAQ;AAAA,QACf;AAAA,MACF;AACA,YAAM,KAAK,EAAE,MAAM,QAAQ,WAAW,KAAK,CAAC;AAAA,IAC9C,WAAW,aAAa,UAAU;AAEhC,UAAI,OAAO,UAAU,CAAC,OAAO,OAAO;AAClC,cAAM,KAAK,EAAE,MAAM,UAAU,WAAW,EAAE,OAAO,CAAC,GAAG,YAAY,OAAO,OAAO,EAAE,CAAC;AAClF;AAAA,MACF;AACA,YAAM,WAAW,OAAO;AACxB,UAAI,CAAC,UAAU;AACb,cAAM,KAAK,EAAE,MAAM,UAAU,WAAW,EAAE,OAAO,CAAC,GAAG,YAAY,0BAA0B,EAAE,CAAC;AAC9F;AAAA,MACF;AAEA,YAAM,QAAuE,CAAC;AAC9E,iBAAW,QAAQ,SAAS,MAAM,IAAI,GAAG;AACvC,cAAM,UAAU,KAAK,KAAK;AAC1B,YAAI,CAAC,QAAS;AACd,cAAM,WAAW,QAAQ,QAAQ,GAAG;AACpC,YAAI,aAAa,IAAI;AAEnB,gBAAM,KAAK,EAAE,MAAM,SAAS,OAAO,IAAI,CAAC;AAAA,QAC1C,OAAO;AACL,gBAAM,WAAW,QAAQ,MAAM,GAAG,QAAQ;AAC1C,gBAAM,aAAa,QAAQ,MAAM,WAAW,CAAC;AAC7C,gBAAM,SAAkC,CAAC;AACzC,qBAAW,YAAY,WAAW,MAAM,GAAG,GAAG;AAC5C,kBAAM,KAAK,SAAS,KAAK;AACzB,gBAAI,CAAC,MAAM,OAAO,KAAK;AAErB,oBAAM,KAAK,EAAE,MAAM,UAAU,OAAO,IAAI,CAAC;AACzC;AAAA,YACF;AACA,kBAAM,CAAC,GAAG,CAAC,IAAI,GAAG,MAAM,GAAG,EAAE,IAAI,OAAK,SAAS,EAAE,KAAK,GAAG,EAAE,CAAC;AAC5D,gBAAI,OAAO,SAAS,CAAC,KAAK,OAAO,SAAS,CAAC,GAAG;AAC5C,qBAAO,KAAK,CAAC,GAAG,CAAC,CAAC;AAAA,YACpB,WAAW,OAAO,SAAS,CAAC,GAAG;AAE7B,qBAAO,KAAK,CAAC,GAAG,CAAC,CAAC;AAAA,YACpB;AAAA,UACF;AACA,cAAI,OAAO,SAAS,GAAG;AACrB,kBAAM,KAAK,EAAE,MAAM,UAAU,OAAO,OAAO,CAAC;AAAA,UAC9C,WAAW,CAAC,MAAM,KAAK,OAAK,EAAE,SAAS,QAAQ,GAAG;AAChD,kBAAM,KAAK,EAAE,MAAM,UAAU,OAAO,IAAI,CAAC;AAAA,UAC3C;AAAA,QACF;AAAA,MACF;AACA,UAAI,MAAM,SAAS,GAAG;AACpB,cAAM,KAAK,EAAE,MAAM,UAAU,WAAW,EAAE,MAAM,EAAE,CAAC;AAAA,MACrD,OAAO;AACL,cAAM,KAAK,EAAE,MAAM,UAAU,WAAW,EAAE,OAAO,CAAC,GAAG,YAAY,SAAS,EAAE,CAAC;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,MAAM,MAA0B;AAC9B,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,IAAI,UAAU,gCAAgC;AAAA,IACtD;AAGA,UAAM,eAAe,KAAK,QAAQ,8BAA8B,EAAE;AAGlE,WAAO,oBAAoB,YAAY;AAAA,EACzC;AACF;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  WarpGrepClient,
3
3
  formatResult
4
- } from "./chunk-JMUAQQJU.js";
4
+ } from "./chunk-NKUSUSVI.js";
5
5
  import {
6
6
  CODEBASE_SEARCH_TOOL,
7
7
  SEND_MESSAGE_TOOL,
@@ -262,4 +262,4 @@ function deduplicateContexts(contexts) {
262
262
  export {
263
263
  createExploreSubagent
264
264
  };
265
- //# sourceMappingURL=chunk-XL7R3XN5.js.map
265
+ //# sourceMappingURL=chunk-VZ6VYRQB.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AGENT_CONFIG
3
- } from "./chunk-I3J46TSB.js";
3
+ } from "./chunk-DKODF3YG.js";
4
4
 
5
5
  // tools/warp_grep/agent/tools/grep.ts
6
6
  async function toolGrep(provider, args) {
@@ -50,42 +50,29 @@ async function toolRead(provider, args) {
50
50
  }
51
51
 
52
52
  // tools/warp_grep/agent/tools/list_directory.ts
53
- import path from "path";
54
- async function toolListDirectory(provider, args, repoRoot) {
55
- const maxResults = args.maxResults ?? AGENT_CONFIG.MAX_LIST_RESULTS;
56
- const maxDepth = args.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;
57
- const entries = await provider.listDirectory({
58
- path: args.path,
59
- pattern: args.pattern ?? null,
60
- maxResults,
61
- maxDepth
62
- });
63
- if (!entries.length) return "empty";
64
- if (repoRoot) {
65
- const absRoot = path.resolve(repoRoot);
66
- const lines = entries.map((e) => path.join(absRoot, e.path));
67
- return lines.join("\n");
68
- }
69
- return entries.map((e) => e.path).join("\n");
70
- }
71
-
72
- // tools/warp_grep/agent/tools/glob.ts
73
- async function toolGlob(provider, args) {
74
- const res = await provider.glob(args);
75
- if (res.error) {
76
- return res.error;
77
- }
78
- if (!res.files.length) {
79
- return "no matches";
53
+ async function toolListDirectory(provider, args) {
54
+ const maxResults = args.maxResults ?? AGENT_CONFIG.MAX_OUTPUT_LINES;
55
+ const initialDepth = args.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;
56
+ async function getListRecursive(currentDepth) {
57
+ const entries = await provider.listDirectory({
58
+ path: args.path,
59
+ pattern: args.pattern ?? null,
60
+ maxResults,
61
+ maxDepth: currentDepth
62
+ });
63
+ if (entries.length >= maxResults && currentDepth > 0) {
64
+ return getListRecursive(currentDepth - 1);
65
+ }
66
+ return { entries };
80
67
  }
81
- const header = `Found ${res.totalFound} file(s) matching "${args.pattern}" within ${res.searchDir}, sorted by modification time (newest first):`;
82
- const body = res.files.join("\n");
83
- const truncated = res.totalFound > res.files.length ? `
84
- [${res.totalFound - res.files.length} files truncated]` : "";
85
- return `${header}
86
- ---
87
- ${body}
88
- ---${truncated}`;
68
+ const { entries: list } = await getListRecursive(initialDepth);
69
+ if (!list.length) return "empty";
70
+ const tree = list.map((e) => {
71
+ const indent = " ".repeat(e.depth);
72
+ const name = e.type === "dir" ? `${e.name}/` : e.name;
73
+ return `${indent}${name}`;
74
+ }).join("\n");
75
+ return tree;
89
76
  }
90
77
 
91
78
  // tools/warp_grep/agent/tools/finish.ts
@@ -155,19 +142,8 @@ function mergeRanges(ranges) {
155
142
  }
156
143
 
157
144
  // tools/warp_grep/agent/helpers.ts
158
- import path2 from "path";
145
+ import path from "path";
159
146
  var TRUNCATED_MARKER = "[truncated for context limit]";
160
- function getMessageSize(m) {
161
- if (m.role === "tool") return m.content.length;
162
- if (m.role === "assistant") {
163
- let size = typeof m.content === "string" ? m.content.length : 0;
164
- if (m.tool_calls) {
165
- size += m.tool_calls.reduce((s, tc) => s + tc.function.name.length + tc.function.arguments.length, 0);
166
- }
167
- return size;
168
- }
169
- return m.content.length;
170
- }
171
147
  function formatTurnMessage(turnsUsed, maxTurns) {
172
148
  const turnsRemaining = maxTurns - turnsUsed;
173
149
  if (turnsRemaining === 1) {
@@ -178,7 +154,7 @@ You have used ${turnsUsed} turns, you only have 1 turn remaining. You have run o
178
154
  You have used ${turnsUsed} turn${turnsUsed === 1 ? "" : "s"} and have ${turnsRemaining} remaining`;
179
155
  }
180
156
  function calculateContextBudget(messages) {
181
- const totalChars = messages.reduce((sum, m) => sum + getMessageSize(m), 0);
157
+ const totalChars = messages.reduce((sum, m) => sum + m.content.length, 0);
182
158
  const maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS;
183
159
  const percent = Math.round(totalChars / maxChars * 100);
184
160
  const usedK = Math.round(totalChars / 1e3);
@@ -187,21 +163,24 @@ function calculateContextBudget(messages) {
187
163
  }
188
164
  async function buildInitialState(repoRoot, searchTerm, provider, options) {
189
165
  const budget = calculateContextBudget([]);
190
- const turnTag = `You have used 0 turns and have ${AGENT_CONFIG.MAX_TURNS} remaining`;
166
+ const turnTag = `Turn 0/${AGENT_CONFIG.MAX_TURNS}`;
191
167
  const treeDepth = options?.search_type === "node_modules" ? 1 : 2;
192
- const absRoot = path2.resolve(repoRoot);
193
168
  try {
194
169
  const entries = await provider.listDirectory({
195
170
  path: ".",
196
171
  maxResults: AGENT_CONFIG.MAX_OUTPUT_LINES,
197
172
  maxDepth: treeDepth
198
173
  });
199
- const lines = [absRoot];
200
- for (const e of entries) {
201
- lines.push(path2.join(absRoot, e.path));
202
- }
174
+ const treeLines = entries.map((e) => {
175
+ const indent = " ".repeat(e.depth);
176
+ const name = e.type === "dir" ? `${e.name}/` : e.name;
177
+ return `${indent}${name}`;
178
+ });
179
+ const repoName = path.basename(repoRoot);
180
+ const treeOutput = treeLines.length > 0 ? `${repoName}/
181
+ ${treeLines.join("\n")}` : `${repoName}/`;
203
182
  return `<repo_structure>
204
- ${lines.join("\n")}
183
+ ${treeOutput}
205
184
  </repo_structure>
206
185
 
207
186
  <search_string>
@@ -210,8 +189,9 @@ ${searchTerm}
210
189
  ${budget}
211
190
  ${turnTag}`;
212
191
  } catch {
192
+ const repoName = path.basename(repoRoot);
213
193
  return `<repo_structure>
214
- ${absRoot}
194
+ ${repoName}/
215
195
  </repo_structure>
216
196
 
217
197
  <search_string>
@@ -230,32 +210,26 @@ function formatListDirectoryTree(entries) {
230
210
  }).join("\n");
231
211
  }
232
212
  function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS) {
233
- const getTotalChars = () => messages.reduce((sum, m) => sum + getMessageSize(m), 0);
213
+ const getTotalChars = () => messages.reduce((sum, m) => sum + m.content.length, 0);
234
214
  if (getTotalChars() <= maxChars) {
235
215
  return messages;
236
216
  }
237
- const truncatableIndices = [];
217
+ const userIndices = [];
238
218
  let firstUserSkipped = false;
239
219
  for (let i = 0; i < messages.length; i++) {
240
- const m = messages[i];
241
- if (m.role === "tool") {
242
- truncatableIndices.push(i);
243
- } else if (m.role === "user") {
220
+ if (messages[i].role === "user") {
244
221
  if (!firstUserSkipped) {
245
222
  firstUserSkipped = true;
246
223
  continue;
247
224
  }
248
- truncatableIndices.push(i);
225
+ userIndices.push(i);
249
226
  }
250
227
  }
251
- for (const idx of truncatableIndices) {
228
+ for (const idx of userIndices) {
252
229
  if (getTotalChars() <= maxChars) {
253
230
  break;
254
231
  }
255
- const m = messages[idx];
256
- if (m.role === "tool" && m.content !== TRUNCATED_MARKER) {
257
- messages[idx] = { role: "tool", tool_call_id: m.tool_call_id, content: TRUNCATED_MARKER };
258
- } else if (m.role === "user" && m.content !== TRUNCATED_MARKER) {
232
+ if (messages[idx].content !== TRUNCATED_MARKER) {
259
233
  messages[idx] = { role: "user", content: TRUNCATED_MARKER };
260
234
  }
261
235
  }
@@ -266,7 +240,6 @@ export {
266
240
  toolGrep,
267
241
  toolRead,
268
242
  toolListDirectory,
269
- toolGlob,
270
243
  normalizeFinishFiles,
271
244
  readFinishFiles,
272
245
  formatTurnMessage,
@@ -275,4 +248,4 @@ export {
275
248
  formatListDirectoryTree,
276
249
  enforceContextLimit
277
250
  };
278
- //# sourceMappingURL=chunk-4LWMPKSB.js.map
251
+ //# sourceMappingURL=chunk-YIETFYCL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/warp_grep/agent/tools/grep.ts","../tools/warp_grep/agent/tools/read.ts","../tools/warp_grep/agent/tools/list_directory.ts","../tools/warp_grep/agent/tools/finish.ts","../tools/warp_grep/agent/helpers.ts"],"sourcesContent":["import type { WarpGrepProvider } from '../../providers/types.js';\n\nexport async function toolGrep(\n provider: WarpGrepProvider,\n args: { pattern: string; path: string; glob?: string; context_lines?: number; case_sensitive?: boolean }\n): Promise<{ output: string }> {\n const res = await provider.grep(args);\n \n // Return errors as output - let the model see and handle them\n if (res.error) {\n return { output: res.error };\n }\n \n if (!res.lines.length) {\n return { output: 'no matches' };\n }\n \n return { output: res.lines.join('\\n') };\n}\n\n","import type { WarpGrepProvider } from '../../providers/types.js';\n\nfunction isValidRange(start: unknown, end: unknown): boolean {\n return (\n typeof start === 'number' &&\n typeof end === 'number' &&\n Number.isFinite(start) &&\n Number.isFinite(end) &&\n start > 0 &&\n end >= start\n );\n}\n\nexport async function toolRead(\n provider: WarpGrepProvider,\n args: { path: string; start?: number; end?: number; lines?: Array<[number, number]> }\n): Promise<string> {\n if (args.lines && Array.isArray(args.lines) && args.lines.length > 0) {\n const validRanges: Array<[number, number]> = [];\n for (const range of args.lines) {\n if (Array.isArray(range) && range.length >= 2 && isValidRange(range[0], range[1])) {\n validRanges.push([range[0], range[1]]);\n }\n }\n \n if (validRanges.length === 0) {\n const res = await provider.read({ path: args.path });\n if (res.error) return res.error;\n if (!res.lines.length) return '(empty file)';\n return res.lines.join('\\n');\n }\n \n const chunks: string[] = [];\n for (const [start, end] of validRanges) {\n const res = await provider.read({ path: args.path, start, end });\n if (res.error) return res.error;\n chunks.push(res.lines.join('\\n'));\n }\n if (chunks.every(c => c === '')) return '(empty file)';\n return chunks.join('\\n...\\n');\n }\n\n const res = await provider.read({ path: args.path, start: args.start, end: args.end });\n if (res.error) {\n return res.error;\n }\n if (!res.lines.length) return '(empty file)';\n return res.lines.join('\\n');\n}\n\n","import type { WarpGrepProvider } from '../../providers/types.js';\nimport { AGENT_CONFIG } from '../config.js';\n\nexport async function toolListDirectory(\n provider: WarpGrepProvider,\n args: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }\n): Promise<string> {\n\n const maxResults = args.maxResults ?? AGENT_CONFIG.MAX_OUTPUT_LINES;\n const initialDepth = args.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;\n\n type DirectoryEntries = Awaited<ReturnType<typeof provider.listDirectory>>;\n async function getListRecursive(currentDepth: number): Promise<{ entries: DirectoryEntries; }> {\n const entries = await provider.listDirectory({\n path: args.path,\n pattern: args.pattern ?? null,\n maxResults,\n maxDepth: currentDepth,\n });\n\n if (entries.length >= maxResults && currentDepth > 0) {\n return getListRecursive(currentDepth - 1);\n }\n\n return { entries };\n }\n const { entries: list } = await getListRecursive(initialDepth);\n\n if (!list.length) return 'empty';\n\n const tree = list\n .map((e) => {\n const indent = ' '.repeat(e.depth);\n const name = e.type === 'dir' ? `${e.name}/` : e.name;\n return `${indent}${name}`;\n })\n .join('\\n');\n\n return tree;\n}\n","import type { FinishFileSpec } from '../types.js';\n\nfunction isValidRange(range: unknown): range is [number, number] {\n return (\n Array.isArray(range) &&\n range.length >= 2 &&\n typeof range[0] === 'number' &&\n typeof range[1] === 'number' &&\n Number.isFinite(range[0]) &&\n Number.isFinite(range[1]) &&\n range[0] > 0 &&\n range[1] >= range[0]\n );\n}\n\nfunction extractValidRanges(lines: unknown): Array<[number, number]> | null {\n if (!Array.isArray(lines)) return null;\n const valid: Array<[number, number]> = [];\n for (const range of lines) {\n if (isValidRange(range)) {\n valid.push([range[0], range[1]]);\n }\n }\n return valid.length > 0 ? valid : null;\n}\n\nexport function normalizeFinishFiles(files: FinishFileSpec[]): FinishFileSpec[] {\n return files.map((f) => {\n if (f.lines === '*') return { path: f.path, lines: '*' };\n const validRanges = extractValidRanges(f.lines);\n if (!validRanges) return { path: f.path, lines: '*' };\n return { path: f.path, lines: mergeRanges(validRanges) };\n });\n}\n\nexport async function readFinishFiles(\n repoRoot: string,\n files: FinishFileSpec[],\n reader: (path: string, start?: number, end?: number) => Promise<string[]>\n): Promise<{ path: string; ranges: '*' | Array<[number, number]>; content: string }[]> {\n const out: { path: string; ranges: '*' | Array<[number, number]>; content: string }[] = [];\n for (const f of files) {\n const validRanges = f.lines === '*' ? null : extractValidRanges(f.lines);\n if (f.lines === '*' || !validRanges) {\n const lines = await reader(f.path);\n out.push({ path: f.path, ranges: '*', content: lines.join('\\n') });\n } else {\n const ranges = mergeRanges(validRanges);\n const chunks: string[] = [];\n for (let i = 0; i < ranges.length; i++) {\n const [s, e] = ranges[i];\n if (i === 0 && s > 1) {\n chunks.push(`// ... existing code, block starting at line ${s} ...`);\n } else if (i > 0) {\n chunks.push(`// ... existing code, block starting at line ${s} ...`);\n }\n const lines = await reader(f.path, s, e);\n chunks.push(lines.join('\\n'));\n }\n out.push({ path: f.path, ranges, content: chunks.join('\\n') });\n }\n }\n return out;\n}\n\nfunction mergeRanges(ranges: Array<[number, number]>): Array<[number, number]> {\n if (!ranges.length) return [];\n const sorted = [...ranges].sort((a, b) => a[0] - b[0]);\n const merged: Array<[number, number]> = [];\n let [cs, ce] = sorted[0];\n for (let i = 1; i < sorted.length; i++) {\n const [s, e] = sorted[i];\n if (s <= ce + 1) {\n ce = Math.max(ce, e);\n } else {\n merged.push([cs, ce]);\n cs = s;\n ce = e;\n }\n }\n merged.push([cs, ce]);\n return merged;\n}\n\n","/**\n * Shared helper functions for warp-grep agent loop.\n * Used by both the internal runner and exported for harness users.\n */\n\nimport path from 'path';\nimport { AGENT_CONFIG } from './config.js';\nimport type { ChatMessage } from './types.js';\nimport type { WarpGrepProvider, ListDirectoryEntry } from '../providers/types.js';\n\nconst TRUNCATED_MARKER = '[truncated for context limit]';\n\n/**\n * Format the turn counter message shown to the model.\n */\nexport function formatTurnMessage(turnsUsed: number, maxTurns: number): string {\n const turnsRemaining = maxTurns - turnsUsed;\n if (turnsRemaining === 1) {\n return `\\nYou have used ${turnsUsed} turns, you only have 1 turn remaining. You have run out of turns to explore the code base and MUST call the finish tool now`;\n }\n return `\\nYou have used ${turnsUsed} turn${turnsUsed === 1 ? '' : 's'} and have ${turnsRemaining} remaining`;\n}\n\n/**\n * Calculate and format the context budget indicator.\n */\nexport function calculateContextBudget(messages: ChatMessage[]): string {\n const totalChars = messages.reduce((sum, m) => sum + m.content.length, 0);\n const maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS;\n const percent = Math.round((totalChars / maxChars) * 100);\n const usedK = Math.round(totalChars / 1000);\n const maxK = Math.round(maxChars / 1000);\n return `<context_budget>${percent}% (${usedK}K/${maxK}K chars used)</context_budget>`;\n}\n\n/**\n * Build the initial state message containing repo structure and search term.\n */\nexport async function buildInitialState(\n repoRoot: string,\n searchTerm: string,\n provider: WarpGrepProvider,\n options?: { search_type?: string },\n): Promise<string> {\n const budget = calculateContextBudget([]);\n const turnTag = `Turn 0/${AGENT_CONFIG.MAX_TURNS}`;\n const treeDepth = options?.search_type === 'node_modules' ? 1 : 2;\n\n try {\n const entries = await provider.listDirectory({\n path: '.',\n maxResults: AGENT_CONFIG.MAX_OUTPUT_LINES,\n maxDepth: treeDepth,\n });\n const treeLines = entries.map((e) => {\n const indent = ' '.repeat(e.depth);\n const name = e.type === 'dir' ? `${e.name}/` : e.name;\n return `${indent}${name}`;\n });\n\n const repoName = path.basename(repoRoot);\n const treeOutput =\n treeLines.length > 0 ? `${repoName}/\\n${treeLines.join('\\n')}` : `${repoName}/`;\n\n return `<repo_structure>\\n${treeOutput}\\n</repo_structure>\\n\\n<search_string>\\n${searchTerm}\\n</search_string>\\n${budget}\\n${turnTag}`;\n } catch {\n const repoName = path.basename(repoRoot);\n return `<repo_structure>\\n${repoName}/\\n</repo_structure>\\n\\n<search_string>\\n${searchTerm}\\n</search_string>\\n${budget}\\n${turnTag}`;\n }\n}\n\n/**\n * Format directory entries as an indented tree string.\n */\nexport function formatListDirectoryTree(entries: ListDirectoryEntry[]): string {\n if (!entries.length) return 'empty';\n return entries\n .map((e) => {\n const indent = ' '.repeat(e.depth);\n const name = e.type === 'dir' ? `${e.name}/` : e.name;\n return `${indent}${name}`;\n })\n .join('\\n');\n}\n\n/**\n * Enforce hard context limit by truncating user messages.\n * Preserves system prompt, first user message (initial query), and all assistant messages.\n * Removes tool result user messages from oldest to newest until under the threshold.\n * \n * @param messages - The conversation messages array (mutated in place)\n * @param maxChars - Maximum total character count (defaults to AGENT_CONFIG.MAX_CONTEXT_CHARS)\n * @returns The same messages array, truncated if necessary\n */\nexport function enforceContextLimit(\n messages: ChatMessage[],\n maxChars: number = AGENT_CONFIG.MAX_CONTEXT_CHARS\n): ChatMessage[] {\n const getTotalChars = () => messages.reduce((sum, m) => sum + m.content.length, 0);\n \n if (getTotalChars() <= maxChars) {\n return messages;\n }\n\n // Find indices of user messages, skipping the first one (initial query with repo structure)\n // We truncate tool result messages from oldest to newest\n const userIndices: number[] = [];\n let firstUserSkipped = false;\n for (let i = 0; i < messages.length; i++) {\n if (messages[i].role === 'user') {\n if (!firstUserSkipped) {\n firstUserSkipped = true;\n continue; // Skip first user message (contains the search query)\n }\n userIndices.push(i);\n }\n }\n\n // Truncate user messages from oldest to newest until under limit\n for (const idx of userIndices) {\n if (getTotalChars() <= maxChars) {\n break;\n }\n // Only truncate if not already truncated\n if (messages[idx].content !== TRUNCATED_MARKER) {\n messages[idx] = { role: 'user', content: TRUNCATED_MARKER };\n }\n }\n\n return messages;\n}\n\n"],"mappings":"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","names":["res","isValidRange"]}