@morphllm/morphsdk 0.2.44 → 0.2.46

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 (142) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-TVFGHXPE.js → chunk-3FTAIJBH.js} +4 -4
  3. package/dist/chunk-5JTJOQUX.js +283 -0
  4. package/dist/chunk-5JTJOQUX.js.map +1 -0
  5. package/dist/{chunk-ZRLEAPZV.js → chunk-76DJEQEP.js} +4 -4
  6. package/dist/{chunk-W3XLPMV3.js → chunk-7HS6YXA3.js} +21 -5
  7. package/dist/{chunk-W3XLPMV3.js.map → chunk-7HS6YXA3.js.map} +1 -1
  8. package/dist/chunk-7T7YOPJV.js +82 -0
  9. package/dist/chunk-7T7YOPJV.js.map +1 -0
  10. package/dist/chunk-CL45IWIU.js +105 -0
  11. package/dist/chunk-CL45IWIU.js.map +1 -0
  12. package/dist/chunk-D6OD3IST.js +70 -0
  13. package/dist/chunk-D6OD3IST.js.map +1 -0
  14. package/dist/{chunk-PEGZVGG4.js → chunk-G4AWE5A2.js} +4 -4
  15. package/dist/{chunk-OUEJ6XEO.js → chunk-GJU7UOFL.js} +4 -4
  16. package/dist/{chunk-Q7PDN7TS.js → chunk-GZMUGMOZ.js} +1 -1
  17. package/dist/{chunk-Q7PDN7TS.js.map → chunk-GZMUGMOZ.js.map} +1 -1
  18. package/dist/chunk-JYBVRF72.js +1 -0
  19. package/dist/{chunk-EYHXBQQX.js → chunk-LVY5LPEX.js} +70 -10
  20. package/dist/chunk-LVY5LPEX.js.map +1 -0
  21. package/dist/{chunk-GDR65N2J.js → chunk-OXHGFHEU.js} +53 -26
  22. package/dist/chunk-OXHGFHEU.js.map +1 -0
  23. package/dist/{chunk-VBBJGWHY.js → chunk-P2XKFWFD.js} +2 -2
  24. package/dist/chunk-PABIV7X6.js +76 -0
  25. package/dist/chunk-PABIV7X6.js.map +1 -0
  26. package/dist/{chunk-GTOXMAF2.js → chunk-SWQPIKPY.js} +44 -3
  27. package/dist/chunk-SWQPIKPY.js.map +1 -0
  28. package/dist/chunk-TJIUA27P.js +94 -0
  29. package/dist/chunk-TJIUA27P.js.map +1 -0
  30. package/dist/{chunk-O5DA5V5S.js → chunk-UBX7QYBD.js} +4 -4
  31. package/dist/{chunk-X4CQ6D3G.js → chunk-UIZT3KVJ.js} +4 -4
  32. package/dist/{chunk-UYBIKZPM.js → chunk-UXYK7WZX.js} +2 -2
  33. package/dist/chunk-WETRQJGU.js +129 -0
  34. package/dist/chunk-WETRQJGU.js.map +1 -0
  35. package/dist/client-BGctTHu9.d.ts +318 -0
  36. package/dist/client.cjs +1954 -53
  37. package/dist/client.cjs.map +1 -1
  38. package/dist/client.d.ts +14 -110
  39. package/dist/client.js +29 -4
  40. package/dist/core-DxiUwyBe.d.ts +156 -0
  41. package/dist/git/client.cjs +52 -25
  42. package/dist/git/client.cjs.map +1 -1
  43. package/dist/git/client.d.ts +17 -8
  44. package/dist/git/client.js +1 -1
  45. package/dist/git/index.cjs +52 -25
  46. package/dist/git/index.cjs.map +1 -1
  47. package/dist/git/index.d.ts +1 -1
  48. package/dist/git/index.js +2 -2
  49. package/dist/git/types.cjs.map +1 -1
  50. package/dist/git/types.d.ts +20 -2
  51. package/dist/index.cjs +2033 -55
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.ts +8 -1
  54. package/dist/index.js +48 -6
  55. package/dist/tools/browser/anthropic.cjs +1 -0
  56. package/dist/tools/browser/anthropic.cjs.map +1 -1
  57. package/dist/tools/browser/anthropic.js +1 -1
  58. package/dist/tools/browser/core.cjs +69 -9
  59. package/dist/tools/browser/core.cjs.map +1 -1
  60. package/dist/tools/browser/core.js +1 -1
  61. package/dist/tools/browser/index.cjs +69 -9
  62. package/dist/tools/browser/index.cjs.map +1 -1
  63. package/dist/tools/browser/index.js +1 -1
  64. package/dist/tools/browser/openai.cjs +1 -0
  65. package/dist/tools/browser/openai.cjs.map +1 -1
  66. package/dist/tools/browser/openai.js +1 -1
  67. package/dist/tools/browser/types.cjs.map +1 -1
  68. package/dist/tools/browser/types.d.ts +2 -0
  69. package/dist/tools/browser/vercel.cjs +1 -0
  70. package/dist/tools/browser/vercel.cjs.map +1 -1
  71. package/dist/tools/browser/vercel.js +1 -1
  72. package/dist/tools/codebase_search/anthropic.js +2 -2
  73. package/dist/tools/codebase_search/index.js +9 -9
  74. package/dist/tools/codebase_search/openai.js +2 -2
  75. package/dist/tools/codebase_search/vercel.js +2 -2
  76. package/dist/tools/fastapply/anthropic.js +2 -2
  77. package/dist/tools/fastapply/index.js +7 -7
  78. package/dist/tools/fastapply/openai.js +2 -2
  79. package/dist/tools/fastapply/vercel.js +2 -2
  80. package/dist/tools/index.js +7 -7
  81. package/dist/tools/warp_grep/agent/config.cjs +80 -1
  82. package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
  83. package/dist/tools/warp_grep/agent/config.js +1 -1
  84. package/dist/tools/warp_grep/agent/parser.cjs +43 -2
  85. package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
  86. package/dist/tools/warp_grep/agent/parser.js +1 -1
  87. package/dist/tools/warp_grep/agent/prompt.cjs +89 -45
  88. package/dist/tools/warp_grep/agent/prompt.cjs.map +1 -1
  89. package/dist/tools/warp_grep/agent/prompt.d.ts +1 -1
  90. package/dist/tools/warp_grep/agent/prompt.js +1 -1
  91. package/dist/tools/warp_grep/agent/runner.cjs +229 -49
  92. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  93. package/dist/tools/warp_grep/agent/runner.js +4 -4
  94. package/dist/tools/warp_grep/agent/types.js +0 -1
  95. package/dist/tools/warp_grep/anthropic.cjs +311 -83
  96. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  97. package/dist/tools/warp_grep/anthropic.d.ts +75 -12
  98. package/dist/tools/warp_grep/anthropic.js +21 -8
  99. package/dist/tools/warp_grep/index.cjs +415 -126
  100. package/dist/tools/warp_grep/index.cjs.map +1 -1
  101. package/dist/tools/warp_grep/index.d.ts +17 -4
  102. package/dist/tools/warp_grep/index.js +29 -21
  103. package/dist/tools/warp_grep/openai.cjs +314 -83
  104. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  105. package/dist/tools/warp_grep/openai.d.ts +73 -29
  106. package/dist/tools/warp_grep/openai.js +21 -8
  107. package/dist/tools/warp_grep/providers/command.cjs +80 -1
  108. package/dist/tools/warp_grep/providers/command.cjs.map +1 -1
  109. package/dist/tools/warp_grep/providers/command.js +2 -2
  110. package/dist/tools/warp_grep/providers/local.cjs +80 -1
  111. package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
  112. package/dist/tools/warp_grep/providers/local.js +2 -2
  113. package/dist/tools/warp_grep/vercel.cjs +291 -57
  114. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  115. package/dist/tools/warp_grep/vercel.d.ts +40 -19
  116. package/dist/tools/warp_grep/vercel.js +17 -8
  117. package/package.json +1 -1
  118. package/dist/chunk-AFEPUNAO.js +0 -15
  119. package/dist/chunk-AFEPUNAO.js.map +0 -1
  120. package/dist/chunk-EYHXBQQX.js.map +0 -1
  121. package/dist/chunk-GDR65N2J.js.map +0 -1
  122. package/dist/chunk-GTOXMAF2.js.map +0 -1
  123. package/dist/chunk-HKZB23U7.js +0 -85
  124. package/dist/chunk-HKZB23U7.js.map +0 -1
  125. package/dist/chunk-IQHKEIQX.js +0 -54
  126. package/dist/chunk-IQHKEIQX.js.map +0 -1
  127. package/dist/chunk-JKFVDM62.js +0 -45
  128. package/dist/chunk-JKFVDM62.js.map +0 -1
  129. package/dist/chunk-KL4YVZRF.js +0 -57
  130. package/dist/chunk-KL4YVZRF.js.map +0 -1
  131. package/dist/chunk-SMR2T5BT.js +0 -104
  132. package/dist/chunk-SMR2T5BT.js.map +0 -1
  133. package/dist/chunk-XYPMN4A3.js +0 -1
  134. /package/dist/{chunk-TVFGHXPE.js.map → chunk-3FTAIJBH.js.map} +0 -0
  135. /package/dist/{chunk-ZRLEAPZV.js.map → chunk-76DJEQEP.js.map} +0 -0
  136. /package/dist/{chunk-PEGZVGG4.js.map → chunk-G4AWE5A2.js.map} +0 -0
  137. /package/dist/{chunk-OUEJ6XEO.js.map → chunk-GJU7UOFL.js.map} +0 -0
  138. /package/dist/{chunk-XYPMN4A3.js.map → chunk-JYBVRF72.js.map} +0 -0
  139. /package/dist/{chunk-VBBJGWHY.js.map → chunk-P2XKFWFD.js.map} +0 -0
  140. /package/dist/{chunk-O5DA5V5S.js.map → chunk-UBX7QYBD.js.map} +0 -0
  141. /package/dist/{chunk-X4CQ6D3G.js.map → chunk-UIZT3KVJ.js.map} +0 -0
  142. /package/dist/{chunk-UYBIKZPM.js.map → chunk-UXYK7WZX.js.map} +0 -0
@@ -40,84 +40,207 @@ var AGENT_CONFIG = {
40
40
  MAX_ROUNDS: 10,
41
41
  TIMEOUT_MS: 3e4
42
42
  };
43
- var DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || "").split(",").map((s) => s.trim()).filter(Boolean).concat(["node_modules", ".git", "dist", "build", ".cache", "venv", "target"]);
43
+ var BUILTIN_EXCLUDES = [
44
+ // Version control
45
+ ".git",
46
+ ".svn",
47
+ ".hg",
48
+ ".bzr",
49
+ // Dependencies
50
+ "node_modules",
51
+ "bower_components",
52
+ ".pnpm",
53
+ ".yarn",
54
+ "vendor",
55
+ "packages",
56
+ "Pods",
57
+ ".bundle",
58
+ // Python
59
+ "__pycache__",
60
+ ".pytest_cache",
61
+ ".mypy_cache",
62
+ ".ruff_cache",
63
+ ".venv",
64
+ "venv",
65
+ ".tox",
66
+ ".nox",
67
+ ".eggs",
68
+ "*.egg-info",
69
+ // Build outputs
70
+ "dist",
71
+ "build",
72
+ "out",
73
+ "output",
74
+ "target",
75
+ "_build",
76
+ ".next",
77
+ ".nuxt",
78
+ ".output",
79
+ ".vercel",
80
+ ".netlify",
81
+ // Cache directories
82
+ ".cache",
83
+ ".parcel-cache",
84
+ ".turbo",
85
+ ".nx",
86
+ ".gradle",
87
+ // IDE/Editor
88
+ ".idea",
89
+ ".vscode",
90
+ ".vs",
91
+ // Coverage
92
+ "coverage",
93
+ ".coverage",
94
+ "htmlcov",
95
+ ".nyc_output",
96
+ // Temporary
97
+ "tmp",
98
+ "temp",
99
+ ".tmp",
100
+ ".temp",
101
+ // Lock files
102
+ "package-lock.json",
103
+ "yarn.lock",
104
+ "pnpm-lock.yaml",
105
+ "bun.lockb",
106
+ "Cargo.lock",
107
+ "Gemfile.lock",
108
+ "poetry.lock",
109
+ // Binary/minified
110
+ "*.min.js",
111
+ "*.min.css",
112
+ "*.bundle.js",
113
+ "*.wasm",
114
+ "*.so",
115
+ "*.dll",
116
+ "*.pyc",
117
+ "*.map",
118
+ "*.js.map",
119
+ // Hidden directories catch-all
120
+ ".*"
121
+ ];
122
+ var DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || "").split(",").map((s) => s.trim()).filter(Boolean).concat(BUILTIN_EXCLUDES);
44
123
  var DEFAULT_MODEL = "morph-warp-grep";
45
124
 
46
125
  // tools/warp_grep/agent/prompt.ts
47
- var SYSTEM_PROMPT = `You are a code search agent. Your task is to find relevant code snippets based on a search query.
126
+ var SYSTEM_PROMPT = `You are a code search agent. Your task is to find all relevant code for a given query.
48
127
 
49
128
  <workflow>
50
- You operate in exactly 3 rounds of tool exploration, followed by a final answer:
129
+ You have exactly 4 turns. The 4th turn MUST be a \`finish\` call. Each turn allows up to 8 parallel tool calls.
51
130
 
52
- 1. In each round, you can make MULTIPLE tool calls (up to 8) to search in parallel. All tool results will be returned together after each round.
53
- 2. After your third round of tool calls, your next turn MUST be a single call to the \`finish\` tool with all the context you have found.
54
- </workflow>
131
+ - Turn 1: Map the territory OR dive deep (based on query specificity)
132
+ - Turn 2-3: Refine based on findings
133
+ - Turn 4: MUST call \`finish\` with all relevant code locations
134
+ - You MAY call \`finish\` early if confident\u2014but never before at least 1 search turn.
55
135
 
56
- <tool_calling>
57
- You have tools at your disposal to solve the coding task. Follow these rules regarding tool calls:
136
+ Remember, if the task feels easy to you, it is strongly desirable to call \`finish\` early using fewer turns, but quality over speed.
137
+ </workflow>
58
138
 
59
- ### 1. \`analyse\` - Explore Directories
60
- Explore directory structure in a tree-like format.
61
- **Syntax:** \`analyse <path> [pattern]\`
62
- - \`<path>\`: Directory path to analyze (defaults to \`.\`)
63
- - \`[pattern]\`: Optional regex pattern to filter names
139
+ <tools>
140
+ ### \`analyse <path> [pattern]\`
141
+ Directory tree or file search. Shows structure of a path, optionally filtered by regex pattern.
142
+ - \`path\`: Required. Directory or file path (use \`.\` for repo root)
143
+ - \`pattern\`: Optional regex to filter results
64
144
 
65
- For example:
145
+ Examples:
66
146
  \`\`\`
147
+ analyse .
67
148
  analyse src/api
68
- analyse . "test"
149
+ analyse . ".*\\.ts$"
150
+ analyse src "test.*"
69
151
  \`\`\`
70
152
 
71
- ### 2. \`read\` - Read File Contents
72
- Read entire files or specific line ranges.
73
- **Syntax:** \`read <path>[:start-end]\`
74
- - \`<path>\`: File path to read
75
- - \`[:start-end]\`: Optional 1-based, inclusive line range
153
+ ### \`read <path>[:start-end]\`
154
+ Read file contents. Line range is 1-based, inclusive.
155
+ - Returns numbered lines for easy reference
156
+ - Omit range to read entire file
76
157
 
77
- For example:
158
+ Examples:
78
159
  \`\`\`
79
160
  read src/main.py
80
- read src/database/connection.py:10-50
161
+ read src/db/conn.py:10-50
162
+ read package.json:1-20
81
163
  \`\`\`
82
164
 
83
- ### 3. \`grep\` - Search with Regex
84
- Search for regex patterns across files using ripgrep.
85
- **Syntax:** \`grep '<pattern>' <path>\`
86
- - \`'<pattern>'\`: Regex pattern (always wrap in single quotes)
87
- - \`<path>\`: Directory or file to search (use \`.\` for the repo root)
165
+ ### \`grep '<pattern>' <path>\`
166
+ Ripgrep search. Finds pattern matches across files.
167
+ - \`'<pattern>'\`: Required. Regex pattern wrapped in single quotes
168
+ - \`<path>\`: Required. Directory or file to search (use \`.\` for repo root)
88
169
 
89
- For example:
170
+ Examples:
90
171
  \`\`\`
91
- grep 'create_user' .
92
- grep 'import.*requests' src/api
93
- grep 'class\\\\s+AuthService' controllers/auth.py
172
+ grep 'class.*Service' src/
173
+ grep 'def authenticate' .
174
+ grep 'import.*from' src/components/
175
+ grep 'TODO' .
94
176
  \`\`\`
95
177
 
96
- ### 4. \`finish\` - Submit Final Answer
97
- Submit your findings when complete.
98
- **Syntax:** \`finish <file1:range1,range2...> [file2:range3...]\`
99
- - Provide file paths with colon-separated, comma-separated line ranges
178
+ ### \`finish <file1:ranges> [file2:ranges ...]\`
179
+ Submit final answer with all relevant code locations.
180
+ - Include generous line ranges\u2014don't be stingy with context
181
+ - Ranges are comma-separated: \`file.py:10-30,50-60\`
182
+ - ALWAYS include import statements at the top of files (usually lines 1-20)
183
+ - If code spans multiple files, include ALL of them
184
+ - Small files can be returned in full
100
185
 
101
- For example:
186
+ Examples:
102
187
  \`\`\`
103
- finish src/api/auth.py:25-50,75-80 src/models/user.py:10-15
188
+ finish src/auth.py:1-15,25-50,75-80 src/models/user.py:1-10,20-45
189
+ finish src/index.ts:1-100
104
190
  \`\`\`
105
- </tool_calling>
191
+ </tools>
106
192
 
107
193
  <strategy>
108
- - Use the \`analyse\`, \`grep\`, and \`read\` tools to gather information about the codebase.
109
- - Leverage the tools smartly to make full use of their potential
110
- - Make parallel tool calls within each round to investigate multiple paths or files efficiently
111
- - Be systematic and thorough within your 3-round limit
194
+ **Before your first tool call, classify the query:**
195
+
196
+ | Query Type | Turn 1 Strategy | Early Finish? |
197
+ |------------|-----------------|---------------|
198
+ | **Specific** (function name, error string, unique identifier) | 8 parallel greps on likely paths | Often by turn 2 |
199
+ | **Conceptual** (how does X work, where is Y handled) | analyse + 2-3 broad greps | Rarely early |
200
+ | **Exploratory** (find all tests, list API endpoints) | analyse at multiple depths | Usually needs 3 turns |
201
+
202
+ **Parallel call patterns:**
203
+ - **Shotgun grep**: Same pattern, 8 different directories\u2014fast coverage
204
+ - **Variant grep**: 8 pattern variations (synonyms, naming conventions)\u2014catches inconsistent codebases
205
+ - **Funnel**: 1 analyse + 7 greps\u2014orient and search simultaneously
206
+ - **Deep read**: 8 reads on files you already identified\u2014gather full context fast
112
207
  </strategy>
113
208
 
114
209
  <output_format>
115
- - Only output tool calls themselves
116
- - Do not include explanatory text, reasoning, or commentary
117
- - Each tool call should be on its own line
118
- - After 3 rounds of exploration, call \`finish\` with all relevant code snippets you found
210
+ EVERY response MUST follow this exact format:
211
+
212
+ 1. First, wrap your reasoning in \`<think>...</think>\` tags containing:
213
+ - Query classification (specific/conceptual/exploratory)
214
+ - Confidence estimate (can I finish in 1-2 turns?)
215
+ - This turn's parallel strategy
216
+ - What signals would let me finish early?
217
+
218
+ 2. Then, output tool calls wrapped in \`<tool_call>...</tool_call>\` tags, one per line.
219
+
220
+ Example:
221
+ \`\`\`
222
+ <think>
223
+ This is a specific query about authentication. I'll grep for auth-related patterns.
224
+ High confidence I can finish in 2 turns if I find the auth module.
225
+ Strategy: Shotgun grep across likely directories.
226
+ </think>
227
+ <tool_call>grep 'authenticate' src/</tool_call>
228
+ <tool_call>grep 'login' src/</tool_call>
229
+ <tool_call>analyse src/auth</tool_call>
230
+ \`\`\`
231
+
232
+ No commentary outside \`<think>\`. No explanations after tool calls.
119
233
  </output_format>
120
234
 
235
+ <finishing_requirements>
236
+ When calling \`finish\`:
237
+ - Include the import section (typically lines 1-20) of each file
238
+ - Include all function/class definitions that are relevant
239
+ - Include any type definitions, interfaces, or constants used
240
+ - Better to over-include than leave the user missing context
241
+ - If unsure about boundaries, include more rather than less
242
+ </finishing_requirements>
243
+
121
244
  Begin your exploration now to find code relevant to the query.`;
122
245
  function getSystemPrompt() {
123
246
  return SYSTEM_PROMPT;
@@ -130,13 +253,54 @@ var LLMResponseParseError = class extends Error {
130
253
  this.name = "LLMResponseParseError";
131
254
  }
132
255
  };
256
+ var VALID_COMMANDS = ["analyse", "grep", "read", "finish"];
257
+ function preprocessText(text) {
258
+ let processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
259
+ const openingTagRegex = /<tool_call>|<tool>/gi;
260
+ const closingTagRegex = /<\/tool_call>|<\/tool>/gi;
261
+ const openingMatches = processed.match(openingTagRegex) || [];
262
+ const closingMatches = processed.match(closingTagRegex) || [];
263
+ if (openingMatches.length > closingMatches.length) {
264
+ const lastClosingMatch = /<\/tool_call>|<\/tool>/gi;
265
+ let lastClosingIndex = -1;
266
+ let match;
267
+ while ((match = lastClosingMatch.exec(processed)) !== null) {
268
+ lastClosingIndex = match.index + match[0].length;
269
+ }
270
+ if (lastClosingIndex > 0) {
271
+ processed = processed.slice(0, lastClosingIndex);
272
+ }
273
+ }
274
+ const toolCallLines = [];
275
+ const toolTagRegex = /<tool_call>([\s\S]*?)<\/tool_call>|<tool>([\s\S]*?)<\/tool>/gi;
276
+ let tagMatch;
277
+ while ((tagMatch = toolTagRegex.exec(processed)) !== null) {
278
+ const content = (tagMatch[1] || tagMatch[2] || "").trim();
279
+ if (content) {
280
+ const lines = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l);
281
+ toolCallLines.push(...lines);
282
+ }
283
+ }
284
+ const allLines = processed.split(/\r?\n/).map((l) => l.trim());
285
+ for (const line of allLines) {
286
+ if (!line) continue;
287
+ if (line.startsWith("<")) continue;
288
+ const firstWord = line.split(/\s/)[0];
289
+ if (VALID_COMMANDS.includes(firstWord)) {
290
+ if (!toolCallLines.includes(line)) {
291
+ toolCallLines.push(line);
292
+ }
293
+ }
294
+ }
295
+ return toolCallLines;
296
+ }
133
297
  var LLMResponseParser = class {
134
298
  finishSpecSplitRe = /,(?=[^,\s]+:)/;
135
299
  parse(text) {
136
300
  if (typeof text !== "string") {
137
301
  throw new TypeError("Command text must be a string.");
138
302
  }
139
- const lines = text.split(/\r?\n/).map((l) => l.trim());
303
+ const lines = preprocessText(text);
140
304
  const commands = [];
141
305
  let finishAccumulator = null;
142
306
  lines.forEach((line, idx) => {
@@ -159,7 +323,7 @@ var LLMResponseParser = class {
159
323
  finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);
160
324
  break;
161
325
  default:
162
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unsupported command '${cmd}'`);
326
+ break;
163
327
  }
164
328
  });
165
329
  if (finishAccumulator) {
@@ -701,7 +865,23 @@ async function runWarpGrep(config) {
701
865
  }
702
866
  }
703
867
  if (formatted.length > 0) {
704
- messages.push({ role: "user", content: formatted.join("\n") });
868
+ const turnsUsed = round;
869
+ const turnsRemaining = 4 - turnsUsed;
870
+ let turnMessage;
871
+ if (turnsRemaining === 0) {
872
+ turnMessage = `
873
+
874
+ [Turn ${turnsUsed}/4] This is your LAST turn. You MUST call the finish tool now.`;
875
+ } else if (turnsRemaining === 1) {
876
+ turnMessage = `
877
+
878
+ [Turn ${turnsUsed}/4] You have 1 turn remaining. Next turn you MUST call the finish tool.`;
879
+ } else {
880
+ turnMessage = `
881
+
882
+ [Turn ${turnsUsed}/4] You have ${turnsRemaining} turns remaining.`;
883
+ }
884
+ messages.push({ role: "user", content: formatted.join("\n") + turnMessage });
705
885
  }
706
886
  if (finishCalls.length) {
707
887
  const fc = finishCalls[0];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../tools/warp_grep/agent/runner.ts","../../../../tools/warp_grep/agent/config.ts","../../../../tools/warp_grep/agent/prompt.ts","../../../../tools/warp_grep/agent/parser.ts","../../../../tools/warp_grep/tools/read.ts","../../../../tools/warp_grep/tools/analyse.ts","../../../../tools/utils/resilience.ts","../../../../tools/warp_grep/agent/formatter.ts","../../../../tools/warp_grep/agent/grep_helpers.ts","../../../../tools/warp_grep/tools/finish.ts"],"sourcesContent":["import { AGENT_CONFIG, DEFAULT_MODEL } from './config.js';\nimport { getSystemPrompt } from './prompt.js';\nimport type { AgentRunResult, ChatMessage, SessionConfig, ToolCall, AgentFinish } from './types.js';\nimport { LLMResponseParser, LLMResponseParseError } from './parser.js';\nimport type { WarpGrepProvider } from '../providers/types.js';\nimport { toolRead } from '../tools/read.js';\nimport { toolAnalyse } from '../tools/analyse.js';\nimport { fetchWithRetry, withTimeout } from '../../utils/resilience.js';\nimport { formatAgentToolOutput } from './formatter.js';\nimport { GrepState, parseAndFilterGrepOutput, formatTurnGrepOutput } from './grep_helpers.js';\nimport { readFinishFiles } from '../tools/finish.js';\nimport path from 'path';\nimport fs from 'fs/promises';\n\ntype EventName =\n | 'initial_state'\n | 'round_start'\n | 'round_end'\n | 'finish'\n | 'error';\n\nexport type EventCallback = (name: EventName, payload: Record<string, unknown>) => void;\n\nconst parser = new LLMResponseParser();\n\nasync function buildInitialState(repoRoot: string, query: string): Promise<string> {\n // Summarize top-level directories and file counts\n try {\n const entries = await fs.readdir(repoRoot, { withFileTypes: true });\n const dirs = entries.filter(e => e.isDirectory()).map(d => d.name).slice(0, 50);\n const files = entries.filter(e => e.isFile()).map(f => f.name).slice(0, 50);\n const parts = [\n `<repo_root>${repoRoot}</repo_root>`,\n `<top_dirs>${dirs.join(', ')}</top_dirs>`,\n `<top_files>${files.join(', ')}</top_files>`,\n ];\n return parts.join('\\n');\n } catch {\n return `<repo_root>${repoRoot}</repo_root>`;\n }\n}\n\nfunction formatAssistantToolBlock(name: string, args: Record<string, unknown>, payload: string, isError = false): string {\n const argStr = Object.entries(args)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n .join(' ');\n const prefix = isError ? 'error' : 'result';\n return `<${prefix} name=\"${name}\" ${argStr}>\\n${payload}\\n</${prefix}>`;\n}\n\nasync function callModel(messages: ChatMessage[], model: string, apiKey?: string): Promise<string> {\n const api = 'https://api.morphllm.com/v1/chat/completions';\n const fetchPromise = fetchWithRetry(\n api,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey || process.env.MORPH_API_KEY || ''}`,\n },\n body: JSON.stringify({\n model,\n temperature: 0.0,\n max_tokens: 1024,\n messages,\n }),\n },\n {}\n );\n const resp = await withTimeout(fetchPromise, AGENT_CONFIG.TIMEOUT_MS, 'morph-warp-grep request timed out');\n if (!resp.ok) {\n const t = await resp.text();\n throw new Error(`morph-warp-grep error ${resp.status}: ${t}`);\n }\n const data = await resp.json();\n const content = data?.choices?.[0]?.message?.content;\n if (!content || typeof content !== 'string') {\n throw new Error('Invalid response from model');\n }\n return content;\n}\n\nexport async function runWarpGrep(config: SessionConfig & { provider: WarpGrepProvider }): Promise<AgentRunResult> {\n const repoRoot = path.resolve(config.repoRoot || process.cwd());\n const messages: ChatMessage[] = [];\n\n // system\n const systemMessage = { role: 'system' as const, content: getSystemPrompt() };\n messages.push(systemMessage);\n // user query\n const queryContent = `<query>${config.query}</query>`;\n messages.push({ role: 'user', content: queryContent });\n // initial state\n const initialState = await buildInitialState(repoRoot, config.query);\n messages.push({ role: 'user', content: initialState });\n\n const maxRounds = AGENT_CONFIG.MAX_ROUNDS;\n const model = config.model || DEFAULT_MODEL;\n const provider = config.provider;\n const errors: Array<{ message: string }> = [];\n const grepState = new GrepState();\n\n let finishMeta: AgentFinish | undefined;\n let terminationReason: AgentRunResult['terminationReason'] = 'terminated';\n\n for (let round = 1; round <= maxRounds; round += 1) {\n // call model\n const assistantContent = await callModel(messages, model, config.apiKey).catch((e: unknown) => {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n return '';\n });\n if (!assistantContent) break;\n messages.push({ role: 'assistant', content: assistantContent });\n\n // parse tool calls\n let toolCalls: ToolCall[] = [];\n try {\n toolCalls = parser.parse(assistantContent);\n } catch (e) {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n terminationReason = 'terminated';\n break;\n }\n if (toolCalls.length === 0) {\n errors.push({ message: 'No tool calls produced by the model.' });\n terminationReason = 'terminated';\n break;\n }\n\n const finishCalls = toolCalls.filter(c => c.name === 'finish');\n const grepCalls = toolCalls.filter(c => c.name === 'grep');\n const analyseCalls = toolCalls.filter(c => c.name === 'analyse');\n const readCalls = toolCalls.filter(c => c.name === 'read');\n\n const formatted: string[] = [];\n\n // Execute non-grep tools in parallel\n const otherPromises: Array<Promise<string>> = [];\n for (const c of analyseCalls) {\n const args = (c.arguments ?? {}) as { path: string; pattern?: string | null };\n otherPromises.push(\n toolAnalyse(provider, args).then(\n p => formatAgentToolOutput('analyse', args, p, { isError: false }),\n err => formatAgentToolOutput('analyse', args, String(err), { isError: true })\n )\n );\n }\n for (const c of readCalls) {\n const args = (c.arguments ?? {}) as { path: string; start?: number; end?: number };\n otherPromises.push(\n toolRead(provider, args).then(\n p => formatAgentToolOutput('read', args, p, { isError: false }),\n err => formatAgentToolOutput('read', args, String(err), { isError: true })\n )\n );\n }\n const otherResults = await Promise.all(otherPromises);\n formatted.push(...otherResults);\n\n // Execute grep calls sequentially like MCP runner to keep outputs compact\n for (const c of grepCalls) {\n const args = (c.arguments ?? {}) as { pattern: string; path: string };\n try {\n const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });\n const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join('\\n') : '';\n const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);\n let formattedPayload = formatTurnGrepOutput(newMatches);\n if (formattedPayload === \"No new matches found.\") {\n formattedPayload = \"no new matches\";\n }\n formatted.push(formatAgentToolOutput('grep', args, formattedPayload, { isError: false }));\n } catch (err) {\n formatted.push(formatAgentToolOutput('grep', args, String(err), { isError: true }));\n }\n }\n\n if (formatted.length > 0) {\n messages.push({ role: 'user', content: formatted.join('\\n') });\n }\n\n if (finishCalls.length) {\n const fc = finishCalls[0];\n const files = ((fc.arguments as any)?.files ?? []) as AgentFinish['files'];\n finishMeta = { files };\n terminationReason = 'completed';\n break;\n }\n }\n\n if (terminationReason !== 'completed' || !finishMeta) {\n return { terminationReason, messages, errors };\n }\n\n // Build finish payload\n const parts: string[] = ['Relevant context found:'];\n for (const f of finishMeta.files) {\n const ranges = f.lines.map(([s, e]) => `${s}-${e}`).join(', ');\n parts.push(`- ${f.path}: ${ranges}`);\n }\n const payload = parts.join('\\n');\n\n // Resolve file contents for returned ranges\n const resolved = await readFinishFiles(\n repoRoot,\n finishMeta.files,\n async (p: string, s: number, e: number) => {\n const rr = await provider.read({ path: p, start: s, end: e });\n // rr.lines are \"line|content\" → strip the \"line|\" prefix\n return rr.lines.map(l => {\n const idx = l.indexOf('|');\n return idx >= 0 ? l.slice(idx + 1) : l;\n });\n }\n );\n\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta, resolved },\n };\n}\n\n\n","// Agent configuration defaults for morph-warp-grep\n// Hard-coded: SDK does not expose control over rounds or timeout.\nexport const AGENT_CONFIG = {\n // Give the model freedom; failsafe cap to prevent infinite loops\n MAX_ROUNDS: 10,\n TIMEOUT_MS: 30000,\n};\n\nexport const DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || '')\n .split(',')\n .map(s => s.trim())\n .filter(Boolean)\n .concat(['node_modules', '.git', 'dist', 'build', '.cache', 'venv', 'target']);\n\nexport const DEFAULT_MODEL = 'morph-warp-grep';\n\n\n","export const SYSTEM_PROMPT = `You are a code search agent. Your task is to find relevant code snippets based on a search query.\n\n<workflow>\nYou operate in exactly 3 rounds of tool exploration, followed by a final answer:\n\n1. In each round, you can make MULTIPLE tool calls (up to 8) to search in parallel. All tool results will be returned together after each round.\n2. After your third round of tool calls, your next turn MUST be a single call to the \\`finish\\` tool with all the context you have found.\n</workflow>\n\n<tool_calling>\nYou have tools at your disposal to solve the coding task. Follow these rules regarding tool calls:\n\n### 1. \\`analyse\\` - Explore Directories\nExplore directory structure in a tree-like format.\n**Syntax:** \\`analyse <path> [pattern]\\`\n- \\`<path>\\`: Directory path to analyze (defaults to \\`.\\`)\n- \\`[pattern]\\`: Optional regex pattern to filter names\n\nFor example:\n\\`\\`\\`\nanalyse src/api\nanalyse . \"test\"\n\\`\\`\\`\n\n### 2. \\`read\\` - Read File Contents\nRead entire files or specific line ranges.\n**Syntax:** \\`read <path>[:start-end]\\`\n- \\`<path>\\`: File path to read\n- \\`[:start-end]\\`: Optional 1-based, inclusive line range\n\nFor example:\n\\`\\`\\`\nread src/main.py\nread src/database/connection.py:10-50\n\\`\\`\\`\n\n### 3. \\`grep\\` - Search with Regex\nSearch for regex patterns across files using ripgrep.\n**Syntax:** \\`grep '<pattern>' <path>\\`\n- \\`'<pattern>'\\`: Regex pattern (always wrap in single quotes)\n- \\`<path>\\`: Directory or file to search (use \\`.\\` for the repo root)\n\nFor example:\n\\`\\`\\`\ngrep 'create_user' .\ngrep 'import.*requests' src/api\ngrep 'class\\\\\\\\s+AuthService' controllers/auth.py\n\\`\\`\\`\n\n### 4. \\`finish\\` - Submit Final Answer\nSubmit your findings when complete.\n**Syntax:** \\`finish <file1:range1,range2...> [file2:range3...]\\`\n- Provide file paths with colon-separated, comma-separated line ranges\n\nFor example:\n\\`\\`\\`\nfinish src/api/auth.py:25-50,75-80 src/models/user.py:10-15\n\\`\\`\\`\n</tool_calling>\n\n<strategy>\n- Use the \\`analyse\\`, \\`grep\\`, and \\`read\\` tools to gather information about the codebase.\n- Leverage the tools smartly to make full use of their potential\n- Make parallel tool calls within each round to investigate multiple paths or files efficiently\n- Be systematic and thorough within your 3-round limit\n</strategy>\n\n<output_format>\n- Only output tool calls themselves\n- Do not include explanatory text, reasoning, or commentary\n- Each tool call should be on its own line\n- After 3 rounds of exploration, call \\`finish\\` with all relevant code snippets you found\n</output_format>\n\nBegin your exploration now to find code relevant to the query.`;\n\nexport function getSystemPrompt(): string {\n\treturn SYSTEM_PROMPT;\n}\n\n\n","// Parses assistant lines into structured tool calls\nimport type { ToolCall } from './types.js';\n\nexport class LLMResponseParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'LLMResponseParseError';\n }\n}\n\ntype LineContext = { lineNumber: number; raw: string };\n\nexport class LLMResponseParser {\n private readonly finishSpecSplitRe = /,(?=[^,\\s]+:)/;\n\n parse(text: string): ToolCall[] {\n if (typeof text !== 'string') {\n throw new TypeError('Command text must be a string.');\n }\n const lines = text.split(/\\r?\\n/).map(l => l.trim());\n const commands: ToolCall[] = [];\n let finishAccumulator: Map<string, number[][]> | null = null;\n\n lines.forEach((line, idx) => {\n if (!line || line.startsWith('#')) return;\n const ctx: LineContext = { lineNumber: idx + 1, raw: line };\n const parts = this.splitLine(line, ctx);\n if (parts.length === 0) return;\n const cmd = parts[0];\n switch (cmd) {\n case 'analyse':\n this.handleAnalyse(parts, ctx, commands);\n break;\n case 'grep':\n this.handleGrep(parts, ctx, commands);\n break;\n case 'read':\n this.handleRead(parts, ctx, commands);\n break;\n case 'finish':\n finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);\n break;\n default:\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unsupported command '${cmd}'`);\n }\n });\n\n if (finishAccumulator) {\n const map = finishAccumulator as Map<string, number[][]>;\n const entries = [...map.entries()];\n const filesPayload = entries.map(([path, ranges]) => ({\n path,\n lines: [...ranges].sort((a, b) => a[0] - b[0]) as Array<[number, number]>,\n }));\n commands.push({ name: 'finish', arguments: { files: filesPayload } });\n }\n return commands;\n }\n\n private splitLine(line: string, ctx: LineContext): string[] {\n try {\n // Split by whitespace but keep quoted blocks as one\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n for (let i = 0; i < line.length; i++) {\n const ch = line[i];\n if (ch === \"'\" && line[i - 1] !== '\\\\') {\n inSingle = !inSingle;\n current += ch;\n } else if (!inSingle && /\\s/.test(ch)) {\n if (current) {\n parts.push(current);\n current = '';\n }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n } catch {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);\n }\n }\n\n private handleAnalyse(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // analyse <path> [pattern]\n if (parts.length < 2) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: analyse requires <path>`);\n }\n const path = parts[1];\n const pattern = parts[2]?.replace(/^\"|\"$/g, '') ?? null;\n commands.push({ name: 'analyse', arguments: { path, pattern } });\n }\n\n // no glob tool in MCP\n\n private handleGrep(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // grep '<pattern>' <path>\n if (parts.length < 3) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep requires '<pattern>' and <path>`);\n }\n const pat = parts[1];\n if (!pat.startsWith(\"'\") || !pat.endsWith(\"'\")) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep pattern must be single-quoted`);\n }\n commands.push({ name: 'grep', arguments: { pattern: pat.slice(1, -1), path: parts[2] } });\n }\n\n private handleRead(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // read <path>[:start-end]\n if (parts.length < 2) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: read requires <path> or <path>:<start-end>`);\n }\n const spec = parts[1];\n const rangeIdx = spec.indexOf(':');\n if (rangeIdx === -1) {\n commands.push({ name: 'read', arguments: { path: spec } });\n return;\n }\n const path = spec.slice(0, rangeIdx);\n const range = spec.slice(rangeIdx + 1);\n const [s, e] = range.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e)) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid read range '${range}'`);\n }\n commands.push({ name: 'read', arguments: { path, start: s, end: e } });\n }\n\n private handleFinish(parts: string[], ctx: LineContext, acc: Map<string, number[][]> | null) {\n // finish file1:1-10,20-30 file2:5-7\n const map = acc ?? new Map<string, number[][]>();\n const args = parts.slice(1);\n for (const token of args) {\n const [path, rangesText] = token.split(':', 2);\n if (!path || !rangesText) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid finish token '${token}'`);\n }\n const rangeSpecs = rangesText.split(',').filter(Boolean);\n for (const spec of rangeSpecs) {\n const [s, e] = spec.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid range '${spec}'`);\n }\n const arr = map.get(path) ?? [];\n arr.push([s, e]);\n map.set(path, arr);\n }\n }\n return map;\n }\n}\n\n\n","import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolRead(\n provider: WarpGrepProvider,\n args: { path: string; start?: number; end?: number }\n): Promise<string> {\n const res = await provider.read({ path: args.path, start: args.start, end: args.end });\n return res.lines.join('\\n');\n}\n\n\n","import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolAnalyse(\n provider: WarpGrepProvider,\n args: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }\n): Promise<string> {\n const list = await provider.analyse({\n path: args.path,\n pattern: args.pattern ?? null,\n maxResults: args.maxResults ?? 100,\n maxDepth: args.maxDepth ?? 2,\n });\n if (!list.length) return 'empty';\n return list\n .map((e) => `${' '.repeat(e.depth)}- ${e.type === 'dir' ? '[D]' : '[F]'} ${e.name}`)\n .join('\\n');\n}\n\n\n","/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nexport interface RetryConfig {\n maxRetries?: number; // Default: 3\n initialDelay?: number; // Default: 1000ms\n maxDelay?: number; // Default: 30000ms\n backoffMultiplier?: number; // Default: 2\n retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * 'https://api.example.com/data',\n * { method: 'POST', body: JSON.stringify(data) },\n * { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryConfig: RetryConfig = {}\n): Promise<Response> {\n const {\n maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n onRetry,\n } = retryConfig;\n\n let lastError: Error | null = null;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n \n // Retry on 429 (rate limit) or 503 (service unavailable)\n if (response.status === 429 || response.status === 503) {\n if (attempt < maxRetries) {\n // Check for Retry-After header\n const retryAfter = response.headers.get('Retry-After');\n const waitTime = retryAfter \n ? parseInt(retryAfter) * 1000 \n : Math.min(delay, maxDelay);\n \n const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n if (onRetry) {\n onRetry(attempt + 1, error);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n continue;\n }\n }\n\n return response;\n } catch (error) {\n lastError = error as Error;\n \n // Check if error is retryable\n const isRetryable = retryableErrors.some(errType => \n lastError?.message?.includes(errType)\n );\n\n if (!isRetryable || attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff\n const waitTime = Math.min(delay, maxDelay);\n if (onRetry) {\n onRetry(attempt + 1, lastError);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n }\n }\n\n throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage?: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout | number;\n \n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'MorphError';\n }\n}\n\n\n","export class ToolOutputFormatter {\n\tformat(\n\t\ttoolName: string,\n\t\targs: Record<string, unknown> | null | undefined,\n\t\toutput: string,\n\t\toptions: { isError?: boolean } = {}\n\t): string {\n\t\tconst name = (toolName ?? \"\").trim();\n\t\tif (!name) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst payload = (output as any)?.toString?.()?.trim?.() ?? \"\";\n\t\tconst isError = Boolean(options.isError);\n\t\tconst safeArgs = args ?? {};\n\n\t\tif (!payload && !isError) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tswitch (name) {\n\t\t\tcase \"read\":\n\t\t\t\treturn this.formatRead(safeArgs, payload, isError);\n\t\t\tcase \"analyse\":\n\t\t\t\treturn this.formatAnalyse(safeArgs, payload, isError);\n\t\t\tcase \"grep\":\n\t\t\t\treturn this.formatGrep(safeArgs, payload, isError);\n\t\t\tdefault:\n\t\t\t\treturn payload ? `<tool_output>\\n${payload}\\n</tool_output>` : \"\";\n\t\t}\n\t}\n\n\tprivate formatRead(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tif (isError) {\n\t\t\treturn payload;\n\t\t}\n\t\tconst path = this.asString(args.path) || \"...\";\n\t\treturn `<file path=\"${path}\">\\n${payload}\\n</file>`;\n\t}\n\n\tprivate formatAnalyse(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tconst path = this.asString(args.path) || \".\";\n\t\tif (isError) {\n\t\t\treturn `<analyse_results path=\"${path}\" status=\"error\">\\n${payload}\\n</analyse_results>`;\n\t\t}\n\t\treturn `<analyse_results path=\"${path}\">\\n${payload}\\n</analyse_results>`;\n\t}\n\n\tprivate formatGrep(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tconst pattern = this.asString(args.pattern);\n\t\tconst path = this.asString(args.path);\n\t\tconst attributes: string[] = [];\n\t\tif (pattern !== undefined) {\n\t\t\tattributes.push(`pattern=\"${pattern}\"`);\n\t\t}\n\t\tif (path !== undefined) {\n\t\t\tattributes.push(`path=\"${path}\"`);\n\t\t}\n\t\tif (isError) {\n\t\t\tattributes.push('status=\"error\"');\n\t\t}\n\t\tconst attrText = attributes.length ? ` ${attributes.join(\" \")}` : \"\";\n\t\treturn `<grep_output${attrText}>\\n${payload}\\n</grep_output>`;\n\t}\n\n\tprivate asString(value: unknown): string | undefined {\n\t\tif (value === null || value === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn String(value);\n\t}\n}\n\nconst sharedFormatter = new ToolOutputFormatter();\n\nexport function formatAgentToolOutput(\n\ttoolName: string,\n\targs: Record<string, unknown> | null | undefined,\n\toutput: string,\n\toptions: { isError?: boolean } = {}\n): string {\n\treturn sharedFormatter.format(toolName, args, output, options);\n}\n\n","export interface GrepMatch {\n\tpath: string;\n\tlineNumber: number;\n\tcontent: string;\n}\n\nexport class GrepState {\n\tprivate readonly seenLines = new Set<string>();\n\n\tisNew(path: string, lineNumber: number): boolean {\n\t\tconst key = this.makeKey(path, lineNumber);\n\t\treturn !this.seenLines.has(key);\n\t}\n\n\tadd(path: string, lineNumber: number): void {\n\t\tthis.seenLines.add(this.makeKey(path, lineNumber));\n\t}\n\n\tprivate makeKey(path: string, lineNumber: number): string {\n\t\treturn `${path}:${lineNumber}`;\n\t}\n}\n\nexport const MAX_GREP_OUTPUT_CHARS_PER_TURN = 60_000;\n\nfunction extractMatchFields(payload: string): GrepMatch | null {\n\tconst text = payload.replace(/\\r?\\n$/, \"\");\n\tif (!text || text.startsWith(\"[error]\")) {\n\t\treturn null;\n\t}\n\n\tconst firstSep = text.indexOf(\":\");\n\tif (firstSep === -1) {\n\t\treturn null;\n\t}\n\tlet filePath = text.slice(0, firstSep).trim();\n\tif (!filePath) {\n\t\treturn null;\n\t}\n\tif (filePath.startsWith(\"./\") || filePath.startsWith(\".\\\\\")) {\n\t\tfilePath = filePath.slice(2);\n\t}\n\n\tconst remainder = text.slice(firstSep + 1);\n\tconst secondSep = remainder.indexOf(\":\");\n\tif (secondSep === -1) {\n\t\treturn null;\n\t}\n\n\tconst linePart = remainder.slice(0, secondSep);\n\tconst lineNumber = Number.parseInt(linePart, 10);\n\tif (!Number.isInteger(lineNumber) || lineNumber <= 0) {\n\t\treturn null;\n\t}\n\n\tlet contentSegment = remainder.slice(secondSep + 1);\n\tconst columnSep = contentSegment.indexOf(\":\");\n\tif (columnSep !== -1 && /^\\d+$/.test(contentSegment.slice(0, columnSep))) {\n\t\tcontentSegment = contentSegment.slice(columnSep + 1);\n\t}\n\n\tconst content = contentSegment.trim();\n\tif (!content) {\n\t\treturn null;\n\t}\n\n\treturn { path: filePath, lineNumber, content };\n}\n\nexport function parseAndFilterGrepOutput(rawOutput: string, state: GrepState): GrepMatch[] {\n\tconst matches: GrepMatch[] = [];\n\tif (typeof rawOutput !== \"string\" || !rawOutput.trim()) {\n\t\treturn matches;\n\t}\n\n\tfor (const line of rawOutput.split(/\\r?\\n/)) {\n\t\tconst fields = extractMatchFields(line);\n\t\tif (!fields) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (state.isNew(fields.path, fields.lineNumber)) {\n\t\t\tmatches.push(fields);\n\t\t\tstate.add(fields.path, fields.lineNumber);\n\t\t}\n\t}\n\n\treturn matches;\n}\n\nfunction truncateOutput(payload: string, maxChars: number): string {\n\tif (payload.length <= maxChars) {\n\t\treturn payload;\n\t}\n\n\tconst note = \"... (output truncated)\";\n\tconst available = maxChars - note.length - 1;\n\tif (available <= 0) {\n\t\treturn note;\n\t}\n\n\tif (payload.length <= available) {\n\t\treturn `${payload.slice(0, available).replace(/\\n$/, \"\")}\\n${note}`;\n\t}\n\n\tconst core = payload.slice(0, Math.max(0, available - 1));\n\tconst trimmed = core.replace(/\\n$/, \"\").replace(/\\s+$/, \"\");\n\tconst snippet = trimmed ? `${trimmed}…` : \"…\";\n\treturn `${snippet}\\n${note}`;\n}\n\nexport function formatTurnGrepOutput(\n\tmatches: GrepMatch[],\n\tmaxChars: number = MAX_GREP_OUTPUT_CHARS_PER_TURN\n): string {\n\tif (!matches || matches.length === 0) {\n\t\treturn \"No new matches found.\";\n\t}\n\n\tconst matchesByFile = new Map<string, GrepMatch[]>();\n\tfor (const match of matches) {\n\t\tif (!matchesByFile.has(match.path)) {\n\t\t\tmatchesByFile.set(match.path, []);\n\t\t}\n\t\tmatchesByFile.get(match.path)!.push(match);\n\t}\n\n\tconst lines: string[] = [];\n\tconst sortedPaths = Array.from(matchesByFile.keys()).sort();\n\tsortedPaths.forEach((filePath, index) => {\n\t\tif (index > 0) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tlines.push(filePath);\n\t\tconst sortedMatches = matchesByFile\n\t\t\t.get(filePath)!\n\t\t\t.slice()\n\t\t\t.sort((a, b) => a.lineNumber - b.lineNumber);\n\t\tfor (const match of sortedMatches) {\n\t\t\tlines.push(`${match.lineNumber}:${match.content}`);\n\t\t}\n\t});\n\n\treturn truncateOutput(lines.join(\"\\n\"), maxChars);\n}\n\n\n","import type { FinishFileSpec } from '../agent/types.js';\nimport fs from 'fs/promises';\n\nexport function normalizeFinishFiles(files: FinishFileSpec[]): FinishFileSpec[] {\n return files.map((f) => {\n const merged = mergeRanges(f.lines);\n return { path: f.path, lines: merged };\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 ranges = mergeRanges(f.lines);\n const chunks: string[] = [];\n for (const [s, e] of ranges) {\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 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"],"mappings":"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","names":["path","path","path","fs","path"]}
1
+ {"version":3,"sources":["../../../../tools/warp_grep/agent/runner.ts","../../../../tools/warp_grep/agent/config.ts","../../../../tools/warp_grep/agent/prompt.ts","../../../../tools/warp_grep/agent/parser.ts","../../../../tools/warp_grep/tools/read.ts","../../../../tools/warp_grep/tools/analyse.ts","../../../../tools/utils/resilience.ts","../../../../tools/warp_grep/agent/formatter.ts","../../../../tools/warp_grep/agent/grep_helpers.ts","../../../../tools/warp_grep/tools/finish.ts"],"sourcesContent":["import { AGENT_CONFIG, DEFAULT_MODEL } from './config.js';\nimport { getSystemPrompt } from './prompt.js';\nimport type { AgentRunResult, ChatMessage, SessionConfig, ToolCall, AgentFinish } from './types.js';\nimport { LLMResponseParser, LLMResponseParseError } from './parser.js';\nimport type { WarpGrepProvider } from '../providers/types.js';\nimport { toolRead } from '../tools/read.js';\nimport { toolAnalyse } from '../tools/analyse.js';\nimport { fetchWithRetry, withTimeout } from '../../utils/resilience.js';\nimport { formatAgentToolOutput } from './formatter.js';\nimport { GrepState, parseAndFilterGrepOutput, formatTurnGrepOutput } from './grep_helpers.js';\nimport { readFinishFiles } from '../tools/finish.js';\nimport path from 'path';\nimport fs from 'fs/promises';\n\ntype EventName =\n | 'initial_state'\n | 'round_start'\n | 'round_end'\n | 'finish'\n | 'error';\n\nexport type EventCallback = (name: EventName, payload: Record<string, unknown>) => void;\n\nconst parser = new LLMResponseParser();\n\nasync function buildInitialState(repoRoot: string, query: string): Promise<string> {\n // Summarize top-level directories and file counts\n try {\n const entries = await fs.readdir(repoRoot, { withFileTypes: true });\n const dirs = entries.filter(e => e.isDirectory()).map(d => d.name).slice(0, 50);\n const files = entries.filter(e => e.isFile()).map(f => f.name).slice(0, 50);\n const parts = [\n `<repo_root>${repoRoot}</repo_root>`,\n `<top_dirs>${dirs.join(', ')}</top_dirs>`,\n `<top_files>${files.join(', ')}</top_files>`,\n ];\n return parts.join('\\n');\n } catch {\n return `<repo_root>${repoRoot}</repo_root>`;\n }\n}\n\nfunction formatAssistantToolBlock(name: string, args: Record<string, unknown>, payload: string, isError = false): string {\n const argStr = Object.entries(args)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n .join(' ');\n const prefix = isError ? 'error' : 'result';\n return `<${prefix} name=\"${name}\" ${argStr}>\\n${payload}\\n</${prefix}>`;\n}\n\nasync function callModel(messages: ChatMessage[], model: string, apiKey?: string): Promise<string> {\n const api = 'https://api.morphllm.com/v1/chat/completions';\n const fetchPromise = fetchWithRetry(\n api,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey || process.env.MORPH_API_KEY || ''}`,\n },\n body: JSON.stringify({\n model,\n temperature: 0.0,\n max_tokens: 1024,\n messages,\n }),\n },\n {}\n );\n const resp = await withTimeout(fetchPromise, AGENT_CONFIG.TIMEOUT_MS, 'morph-warp-grep request timed out');\n if (!resp.ok) {\n const t = await resp.text();\n throw new Error(`morph-warp-grep error ${resp.status}: ${t}`);\n }\n const data = await resp.json();\n const content = data?.choices?.[0]?.message?.content;\n if (!content || typeof content !== 'string') {\n throw new Error('Invalid response from model');\n }\n return content;\n}\n\nexport async function runWarpGrep(config: SessionConfig & { provider: WarpGrepProvider }): Promise<AgentRunResult> {\n const repoRoot = path.resolve(config.repoRoot || process.cwd());\n const messages: ChatMessage[] = [];\n\n // system\n const systemMessage = { role: 'system' as const, content: getSystemPrompt() };\n messages.push(systemMessage);\n // user query\n const queryContent = `<query>${config.query}</query>`;\n messages.push({ role: 'user', content: queryContent });\n // initial state\n const initialState = await buildInitialState(repoRoot, config.query);\n messages.push({ role: 'user', content: initialState });\n\n const maxRounds = AGENT_CONFIG.MAX_ROUNDS;\n const model = config.model || DEFAULT_MODEL;\n const provider = config.provider;\n const errors: Array<{ message: string }> = [];\n const grepState = new GrepState();\n\n let finishMeta: AgentFinish | undefined;\n let terminationReason: AgentRunResult['terminationReason'] = 'terminated';\n\n for (let round = 1; round <= maxRounds; round += 1) {\n // call model\n const assistantContent = await callModel(messages, model, config.apiKey).catch((e: unknown) => {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n return '';\n });\n if (!assistantContent) break;\n messages.push({ role: 'assistant', content: assistantContent });\n\n // parse tool calls\n let toolCalls: ToolCall[] = [];\n try {\n toolCalls = parser.parse(assistantContent);\n } catch (e) {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n terminationReason = 'terminated';\n break;\n }\n if (toolCalls.length === 0) {\n errors.push({ message: 'No tool calls produced by the model.' });\n terminationReason = 'terminated';\n break;\n }\n\n const finishCalls = toolCalls.filter(c => c.name === 'finish');\n const grepCalls = toolCalls.filter(c => c.name === 'grep');\n const analyseCalls = toolCalls.filter(c => c.name === 'analyse');\n const readCalls = toolCalls.filter(c => c.name === 'read');\n\n const formatted: string[] = [];\n\n // Execute non-grep tools in parallel\n const otherPromises: Array<Promise<string>> = [];\n for (const c of analyseCalls) {\n const args = (c.arguments ?? {}) as { path: string; pattern?: string | null };\n otherPromises.push(\n toolAnalyse(provider, args).then(\n p => formatAgentToolOutput('analyse', args, p, { isError: false }),\n err => formatAgentToolOutput('analyse', args, String(err), { isError: true })\n )\n );\n }\n for (const c of readCalls) {\n const args = (c.arguments ?? {}) as { path: string; start?: number; end?: number };\n otherPromises.push(\n toolRead(provider, args).then(\n p => formatAgentToolOutput('read', args, p, { isError: false }),\n err => formatAgentToolOutput('read', args, String(err), { isError: true })\n )\n );\n }\n const otherResults = await Promise.all(otherPromises);\n formatted.push(...otherResults);\n\n // Execute grep calls sequentially like MCP runner to keep outputs compact\n for (const c of grepCalls) {\n const args = (c.arguments ?? {}) as { pattern: string; path: string };\n try {\n const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });\n const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join('\\n') : '';\n const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);\n let formattedPayload = formatTurnGrepOutput(newMatches);\n if (formattedPayload === \"No new matches found.\") {\n formattedPayload = \"no new matches\";\n }\n formatted.push(formatAgentToolOutput('grep', args, formattedPayload, { isError: false }));\n } catch (err) {\n formatted.push(formatAgentToolOutput('grep', args, String(err), { isError: true }));\n }\n }\n\n if (formatted.length > 0) {\n // Add turn counter message\n const turnsUsed = round;\n const turnsRemaining = 4 - turnsUsed;\n let turnMessage: string;\n if (turnsRemaining === 0) {\n turnMessage = `\\n\\n[Turn ${turnsUsed}/4] This is your LAST turn. You MUST call the finish tool now.`;\n } else if (turnsRemaining === 1) {\n turnMessage = `\\n\\n[Turn ${turnsUsed}/4] You have 1 turn remaining. Next turn you MUST call the finish tool.`;\n } else {\n turnMessage = `\\n\\n[Turn ${turnsUsed}/4] You have ${turnsRemaining} turns remaining.`;\n }\n messages.push({ role: 'user', content: formatted.join('\\n') + turnMessage });\n }\n\n if (finishCalls.length) {\n const fc = finishCalls[0];\n const files = ((fc.arguments as any)?.files ?? []) as AgentFinish['files'];\n finishMeta = { files };\n terminationReason = 'completed';\n break;\n }\n }\n\n if (terminationReason !== 'completed' || !finishMeta) {\n return { terminationReason, messages, errors };\n }\n\n // Build finish payload\n const parts: string[] = ['Relevant context found:'];\n for (const f of finishMeta.files) {\n const ranges = f.lines.map(([s, e]) => `${s}-${e}`).join(', ');\n parts.push(`- ${f.path}: ${ranges}`);\n }\n const payload = parts.join('\\n');\n\n // Resolve file contents for returned ranges\n const resolved = await readFinishFiles(\n repoRoot,\n finishMeta.files,\n async (p: string, s: number, e: number) => {\n const rr = await provider.read({ path: p, start: s, end: e });\n // rr.lines are \"line|content\" → strip the \"line|\" prefix\n return rr.lines.map(l => {\n const idx = l.indexOf('|');\n return idx >= 0 ? l.slice(idx + 1) : l;\n });\n }\n );\n\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta, resolved },\n };\n}\n\n\n","// Agent configuration defaults for morph-warp-grep\n// Hard-coded: SDK does not expose control over rounds or timeout.\nexport const AGENT_CONFIG = {\n // Give the model freedom; failsafe cap to prevent infinite loops\n MAX_ROUNDS: 10,\n TIMEOUT_MS: 30000,\n};\n\n/**\n * Comprehensive exclusion list for directories and files\n * These patterns are used with ripgrep's -g flag\n */\nconst BUILTIN_EXCLUDES = [\n // Version control\n '.git', '.svn', '.hg', '.bzr',\n \n // Dependencies\n 'node_modules', 'bower_components', '.pnpm', '.yarn',\n 'vendor', 'packages', 'Pods', '.bundle',\n \n // Python\n '__pycache__', '.pytest_cache', '.mypy_cache', '.ruff_cache',\n '.venv', 'venv', '.tox', '.nox', '.eggs', '*.egg-info',\n \n // Build outputs\n 'dist', 'build', 'out', 'output', 'target', '_build',\n '.next', '.nuxt', '.output', '.vercel', '.netlify',\n \n // Cache directories\n '.cache', '.parcel-cache', '.turbo', '.nx', '.gradle',\n \n // IDE/Editor\n '.idea', '.vscode', '.vs',\n \n // Coverage\n 'coverage', '.coverage', 'htmlcov', '.nyc_output',\n \n // Temporary\n 'tmp', 'temp', '.tmp', '.temp',\n \n // Lock files\n 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb',\n 'Cargo.lock', 'Gemfile.lock', 'poetry.lock',\n \n // Binary/minified\n '*.min.js', '*.min.css', '*.bundle.js',\n '*.wasm', '*.so', '*.dll', '*.pyc',\n '*.map', '*.js.map',\n \n // Hidden directories catch-all\n '.*',\n];\n\nexport const DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || '')\n .split(',')\n .map(s => s.trim())\n .filter(Boolean)\n .concat(BUILTIN_EXCLUDES);\n\nexport const DEFAULT_MODEL = 'morph-warp-grep';\n\n\n","export const SYSTEM_PROMPT = `You are a code search agent. Your task is to find all relevant code for a given query.\n\n<workflow>\nYou have exactly 4 turns. The 4th turn MUST be a \\`finish\\` call. Each turn allows up to 8 parallel tool calls.\n\n- Turn 1: Map the territory OR dive deep (based on query specificity)\n- Turn 2-3: Refine based on findings\n- Turn 4: MUST call \\`finish\\` with all relevant code locations\n- You MAY call \\`finish\\` early if confident—but never before at least 1 search turn.\n\nRemember, if the task feels easy to you, it is strongly desirable to call \\`finish\\` early using fewer turns, but quality over speed.\n</workflow>\n\n<tools>\n### \\`analyse <path> [pattern]\\`\nDirectory tree or file search. Shows structure of a path, optionally filtered by regex pattern.\n- \\`path\\`: Required. Directory or file path (use \\`.\\` for repo root)\n- \\`pattern\\`: Optional regex to filter results\n\nExamples:\n\\`\\`\\`\nanalyse .\nanalyse src/api\nanalyse . \".*\\\\.ts$\"\nanalyse src \"test.*\"\n\\`\\`\\`\n\n### \\`read <path>[:start-end]\\`\nRead file contents. Line range is 1-based, inclusive.\n- Returns numbered lines for easy reference\n- Omit range to read entire file\n\nExamples:\n\\`\\`\\`\nread src/main.py\nread src/db/conn.py:10-50\nread package.json:1-20\n\\`\\`\\`\n\n### \\`grep '<pattern>' <path>\\`\nRipgrep search. Finds pattern matches across files.\n- \\`'<pattern>'\\`: Required. Regex pattern wrapped in single quotes\n- \\`<path>\\`: Required. Directory or file to search (use \\`.\\` for repo root)\n\nExamples:\n\\`\\`\\`\ngrep 'class.*Service' src/\ngrep 'def authenticate' .\ngrep 'import.*from' src/components/\ngrep 'TODO' .\n\\`\\`\\`\n\n### \\`finish <file1:ranges> [file2:ranges ...]\\`\nSubmit final answer with all relevant code locations.\n- Include generous line ranges—don't be stingy with context\n- Ranges are comma-separated: \\`file.py:10-30,50-60\\`\n- ALWAYS include import statements at the top of files (usually lines 1-20)\n- If code spans multiple files, include ALL of them\n- Small files can be returned in full\n\nExamples:\n\\`\\`\\`\nfinish src/auth.py:1-15,25-50,75-80 src/models/user.py:1-10,20-45\nfinish src/index.ts:1-100\n\\`\\`\\`\n</tools>\n\n<strategy>\n**Before your first tool call, classify the query:**\n\n| Query Type | Turn 1 Strategy | Early Finish? |\n|------------|-----------------|---------------|\n| **Specific** (function name, error string, unique identifier) | 8 parallel greps on likely paths | Often by turn 2 |\n| **Conceptual** (how does X work, where is Y handled) | analyse + 2-3 broad greps | Rarely early |\n| **Exploratory** (find all tests, list API endpoints) | analyse at multiple depths | Usually needs 3 turns |\n\n**Parallel call patterns:**\n- **Shotgun grep**: Same pattern, 8 different directories—fast coverage\n- **Variant grep**: 8 pattern variations (synonyms, naming conventions)—catches inconsistent codebases\n- **Funnel**: 1 analyse + 7 greps—orient and search simultaneously\n- **Deep read**: 8 reads on files you already identified—gather full context fast\n</strategy>\n\n<output_format>\nEVERY response MUST follow this exact format:\n\n1. First, wrap your reasoning in \\`<think>...</think>\\` tags containing:\n - Query classification (specific/conceptual/exploratory)\n - Confidence estimate (can I finish in 1-2 turns?)\n - This turn's parallel strategy\n - What signals would let me finish early?\n\n2. Then, output tool calls wrapped in \\`<tool_call>...</tool_call>\\` tags, one per line.\n\nExample:\n\\`\\`\\`\n<think>\nThis is a specific query about authentication. I'll grep for auth-related patterns.\nHigh confidence I can finish in 2 turns if I find the auth module.\nStrategy: Shotgun grep across likely directories.\n</think>\n<tool_call>grep 'authenticate' src/</tool_call>\n<tool_call>grep 'login' src/</tool_call>\n<tool_call>analyse src/auth</tool_call>\n\\`\\`\\`\n\nNo commentary outside \\`<think>\\`. No explanations after tool calls.\n</output_format>\n\n<finishing_requirements>\nWhen calling \\`finish\\`:\n- Include the import section (typically lines 1-20) of each file\n- Include all function/class definitions that are relevant\n- Include any type definitions, interfaces, or constants used\n- Better to over-include than leave the user missing context\n- If unsure about boundaries, include more rather than less\n</finishing_requirements>\n\nBegin your exploration now to find code relevant to the query.`;\n\nexport function getSystemPrompt(): string {\n\treturn SYSTEM_PROMPT;\n}\n","// Parses assistant lines into structured tool calls\nimport type { ToolCall } from './types.js';\n\nexport class LLMResponseParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'LLMResponseParseError';\n }\n}\n\ntype LineContext = { lineNumber: number; raw: string };\n\n// Valid tool command names\nconst VALID_COMMANDS = ['analyse', 'grep', 'read', 'finish'];\n\n/**\n * Preprocesses text to handle XML tags:\n * 1. Removes <think>...</think> blocks entirely\n * 2. Extracts content from <tool>...</tool> or <tool_call>...</tool_call> tags\n * 3. Passes through raw tool calls (lines starting with valid commands)\n * 4. Discards unclosed <tool...> tags\n */\nfunction preprocessText(text: string): string[] {\n // Step 1: Remove <think>...</think> blocks (including multiline)\n let processed = text.replace(/<think>[\\s\\S]*?<\\/think>/gi, '');\n \n // Step 2: Check for unclosed <tool or <tool_call tags and discard them\n // Find all opening tags and their positions\n const openingTagRegex = /<tool_call>|<tool>/gi;\n const closingTagRegex = /<\\/tool_call>|<\\/tool>/gi;\n \n // Count opening and closing tags\n const openingMatches = processed.match(openingTagRegex) || [];\n const closingMatches = processed.match(closingTagRegex) || [];\n \n // If there are more opening than closing tags, we have unclosed tags\n // In that case, only process complete tag pairs\n if (openingMatches.length > closingMatches.length) {\n // Remove any content after the last complete closing tag\n const lastClosingMatch = /<\\/tool_call>|<\\/tool>/gi;\n let lastClosingIndex = -1;\n let match;\n while ((match = lastClosingMatch.exec(processed)) !== null) {\n lastClosingIndex = match.index + match[0].length;\n }\n if (lastClosingIndex > 0) {\n processed = processed.slice(0, lastClosingIndex);\n }\n }\n \n // Step 3: Extract content from <tool_call>...</tool_call> and <tool>...</tool> tags\n const toolCallLines: string[] = [];\n const toolTagRegex = /<tool_call>([\\s\\S]*?)<\\/tool_call>|<tool>([\\s\\S]*?)<\\/tool>/gi;\n let tagMatch;\n \n while ((tagMatch = toolTagRegex.exec(processed)) !== null) {\n const content = (tagMatch[1] || tagMatch[2] || '').trim();\n if (content) {\n // Split content by newlines in case there are multiple tool calls in one tag\n const lines = content.split(/\\r?\\n/).map(l => l.trim()).filter(l => l);\n toolCallLines.push(...lines);\n }\n }\n \n // Step 4: Also extract raw tool calls (lines starting with valid commands)\n // This provides backwards compatibility\n const allLines = processed.split(/\\r?\\n/).map(l => l.trim());\n for (const line of allLines) {\n if (!line) continue;\n \n // Skip lines that are inside XML tags (already processed above)\n if (line.startsWith('<')) continue;\n \n // Check if line starts with a valid command\n const firstWord = line.split(/\\s/)[0];\n if (VALID_COMMANDS.includes(firstWord)) {\n // Avoid duplicates\n if (!toolCallLines.includes(line)) {\n toolCallLines.push(line);\n }\n }\n }\n \n return toolCallLines;\n}\n\nexport class LLMResponseParser {\n private readonly finishSpecSplitRe = /,(?=[^,\\s]+:)/;\n\n parse(text: string): ToolCall[] {\n if (typeof text !== 'string') {\n throw new TypeError('Command text must be a string.');\n }\n \n // Preprocess to handle XML tags\n const lines = preprocessText(text);\n \n const commands: ToolCall[] = [];\n let finishAccumulator: Map<string, number[][]> | null = null;\n\n lines.forEach((line, idx) => {\n if (!line || line.startsWith('#')) return;\n const ctx: LineContext = { lineNumber: idx + 1, raw: line };\n const parts = this.splitLine(line, ctx);\n if (parts.length === 0) return;\n const cmd = parts[0];\n switch (cmd) {\n case 'analyse':\n this.handleAnalyse(parts, ctx, commands);\n break;\n case 'grep':\n this.handleGrep(parts, ctx, commands);\n break;\n case 'read':\n this.handleRead(parts, ctx, commands);\n break;\n case 'finish':\n finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);\n break;\n default:\n // Silently ignore unknown commands after preprocessing\n // (they might be remnants of XML or other content)\n break;\n }\n });\n\n if (finishAccumulator) {\n const map = finishAccumulator as Map<string, number[][]>;\n const entries = [...map.entries()];\n const filesPayload = entries.map(([path, ranges]) => ({\n path,\n lines: [...ranges].sort((a, b) => a[0] - b[0]) as Array<[number, number]>,\n }));\n commands.push({ name: 'finish', arguments: { files: filesPayload } });\n }\n return commands;\n }\n\n private splitLine(line: string, ctx: LineContext): string[] {\n try {\n // Split by whitespace but keep quoted blocks as one\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n for (let i = 0; i < line.length; i++) {\n const ch = line[i];\n if (ch === \"'\" && line[i - 1] !== '\\\\') {\n inSingle = !inSingle;\n current += ch;\n } else if (!inSingle && /\\s/.test(ch)) {\n if (current) {\n parts.push(current);\n current = '';\n }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n } catch {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);\n }\n }\n\n private handleAnalyse(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // analyse <path> [pattern]\n if (parts.length < 2) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: analyse requires <path>`);\n }\n const path = parts[1];\n const pattern = parts[2]?.replace(/^\"|\"$/g, '') ?? null;\n commands.push({ name: 'analyse', arguments: { path, pattern } });\n }\n\n // no glob tool in MCP\n\n private handleGrep(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // grep '<pattern>' <path>\n if (parts.length < 3) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep requires '<pattern>' and <path>`);\n }\n const pat = parts[1];\n if (!pat.startsWith(\"'\") || !pat.endsWith(\"'\")) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep pattern must be single-quoted`);\n }\n commands.push({ name: 'grep', arguments: { pattern: pat.slice(1, -1), path: parts[2] } });\n }\n\n private handleRead(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // read <path>[:start-end]\n if (parts.length < 2) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: read requires <path> or <path>:<start-end>`);\n }\n const spec = parts[1];\n const rangeIdx = spec.indexOf(':');\n if (rangeIdx === -1) {\n commands.push({ name: 'read', arguments: { path: spec } });\n return;\n }\n const path = spec.slice(0, rangeIdx);\n const range = spec.slice(rangeIdx + 1);\n const [s, e] = range.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e)) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid read range '${range}'`);\n }\n commands.push({ name: 'read', arguments: { path, start: s, end: e } });\n }\n\n private handleFinish(parts: string[], ctx: LineContext, acc: Map<string, number[][]> | null) {\n // finish file1:1-10,20-30 file2:5-7\n const map = acc ?? new Map<string, number[][]>();\n const args = parts.slice(1);\n for (const token of args) {\n const [path, rangesText] = token.split(':', 2);\n if (!path || !rangesText) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid finish token '${token}'`);\n }\n const rangeSpecs = rangesText.split(',').filter(Boolean);\n for (const spec of rangeSpecs) {\n const [s, e] = spec.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid range '${spec}'`);\n }\n const arr = map.get(path) ?? [];\n arr.push([s, e]);\n map.set(path, arr);\n }\n }\n return map;\n }\n}\n","import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolRead(\n provider: WarpGrepProvider,\n args: { path: string; start?: number; end?: number }\n): Promise<string> {\n const res = await provider.read({ path: args.path, start: args.start, end: args.end });\n return res.lines.join('\\n');\n}\n\n\n","import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolAnalyse(\n provider: WarpGrepProvider,\n args: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }\n): Promise<string> {\n const list = await provider.analyse({\n path: args.path,\n pattern: args.pattern ?? null,\n maxResults: args.maxResults ?? 100,\n maxDepth: args.maxDepth ?? 2,\n });\n if (!list.length) return 'empty';\n return list\n .map((e) => `${' '.repeat(e.depth)}- ${e.type === 'dir' ? '[D]' : '[F]'} ${e.name}`)\n .join('\\n');\n}\n\n\n","/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nexport interface RetryConfig {\n maxRetries?: number; // Default: 3\n initialDelay?: number; // Default: 1000ms\n maxDelay?: number; // Default: 30000ms\n backoffMultiplier?: number; // Default: 2\n retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * 'https://api.example.com/data',\n * { method: 'POST', body: JSON.stringify(data) },\n * { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryConfig: RetryConfig = {}\n): Promise<Response> {\n const {\n maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n onRetry,\n } = retryConfig;\n\n let lastError: Error | null = null;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n \n // Retry on 429 (rate limit) or 503 (service unavailable)\n if (response.status === 429 || response.status === 503) {\n if (attempt < maxRetries) {\n // Check for Retry-After header\n const retryAfter = response.headers.get('Retry-After');\n const waitTime = retryAfter \n ? parseInt(retryAfter) * 1000 \n : Math.min(delay, maxDelay);\n \n const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n if (onRetry) {\n onRetry(attempt + 1, error);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n continue;\n }\n }\n\n return response;\n } catch (error) {\n lastError = error as Error;\n \n // Check if error is retryable\n const isRetryable = retryableErrors.some(errType => \n lastError?.message?.includes(errType)\n );\n\n if (!isRetryable || attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff\n const waitTime = Math.min(delay, maxDelay);\n if (onRetry) {\n onRetry(attempt + 1, lastError);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n }\n }\n\n throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage?: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout | number;\n \n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'MorphError';\n }\n}\n\n\n","export class ToolOutputFormatter {\n\tformat(\n\t\ttoolName: string,\n\t\targs: Record<string, unknown> | null | undefined,\n\t\toutput: string,\n\t\toptions: { isError?: boolean } = {}\n\t): string {\n\t\tconst name = (toolName ?? \"\").trim();\n\t\tif (!name) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst payload = (output as any)?.toString?.()?.trim?.() ?? \"\";\n\t\tconst isError = Boolean(options.isError);\n\t\tconst safeArgs = args ?? {};\n\n\t\tif (!payload && !isError) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tswitch (name) {\n\t\t\tcase \"read\":\n\t\t\t\treturn this.formatRead(safeArgs, payload, isError);\n\t\t\tcase \"analyse\":\n\t\t\t\treturn this.formatAnalyse(safeArgs, payload, isError);\n\t\t\tcase \"grep\":\n\t\t\t\treturn this.formatGrep(safeArgs, payload, isError);\n\t\t\tdefault:\n\t\t\t\treturn payload ? `<tool_output>\\n${payload}\\n</tool_output>` : \"\";\n\t\t}\n\t}\n\n\tprivate formatRead(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tif (isError) {\n\t\t\treturn payload;\n\t\t}\n\t\tconst path = this.asString(args.path) || \"...\";\n\t\treturn `<file path=\"${path}\">\\n${payload}\\n</file>`;\n\t}\n\n\tprivate formatAnalyse(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tconst path = this.asString(args.path) || \".\";\n\t\tif (isError) {\n\t\t\treturn `<analyse_results path=\"${path}\" status=\"error\">\\n${payload}\\n</analyse_results>`;\n\t\t}\n\t\treturn `<analyse_results path=\"${path}\">\\n${payload}\\n</analyse_results>`;\n\t}\n\n\tprivate formatGrep(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tconst pattern = this.asString(args.pattern);\n\t\tconst path = this.asString(args.path);\n\t\tconst attributes: string[] = [];\n\t\tif (pattern !== undefined) {\n\t\t\tattributes.push(`pattern=\"${pattern}\"`);\n\t\t}\n\t\tif (path !== undefined) {\n\t\t\tattributes.push(`path=\"${path}\"`);\n\t\t}\n\t\tif (isError) {\n\t\t\tattributes.push('status=\"error\"');\n\t\t}\n\t\tconst attrText = attributes.length ? ` ${attributes.join(\" \")}` : \"\";\n\t\treturn `<grep_output${attrText}>\\n${payload}\\n</grep_output>`;\n\t}\n\n\tprivate asString(value: unknown): string | undefined {\n\t\tif (value === null || value === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn String(value);\n\t}\n}\n\nconst sharedFormatter = new ToolOutputFormatter();\n\nexport function formatAgentToolOutput(\n\ttoolName: string,\n\targs: Record<string, unknown> | null | undefined,\n\toutput: string,\n\toptions: { isError?: boolean } = {}\n): string {\n\treturn sharedFormatter.format(toolName, args, output, options);\n}\n\n","export interface GrepMatch {\n\tpath: string;\n\tlineNumber: number;\n\tcontent: string;\n}\n\nexport class GrepState {\n\tprivate readonly seenLines = new Set<string>();\n\n\tisNew(path: string, lineNumber: number): boolean {\n\t\tconst key = this.makeKey(path, lineNumber);\n\t\treturn !this.seenLines.has(key);\n\t}\n\n\tadd(path: string, lineNumber: number): void {\n\t\tthis.seenLines.add(this.makeKey(path, lineNumber));\n\t}\n\n\tprivate makeKey(path: string, lineNumber: number): string {\n\t\treturn `${path}:${lineNumber}`;\n\t}\n}\n\nexport const MAX_GREP_OUTPUT_CHARS_PER_TURN = 60_000;\n\nfunction extractMatchFields(payload: string): GrepMatch | null {\n\tconst text = payload.replace(/\\r?\\n$/, \"\");\n\tif (!text || text.startsWith(\"[error]\")) {\n\t\treturn null;\n\t}\n\n\tconst firstSep = text.indexOf(\":\");\n\tif (firstSep === -1) {\n\t\treturn null;\n\t}\n\tlet filePath = text.slice(0, firstSep).trim();\n\tif (!filePath) {\n\t\treturn null;\n\t}\n\tif (filePath.startsWith(\"./\") || filePath.startsWith(\".\\\\\")) {\n\t\tfilePath = filePath.slice(2);\n\t}\n\n\tconst remainder = text.slice(firstSep + 1);\n\tconst secondSep = remainder.indexOf(\":\");\n\tif (secondSep === -1) {\n\t\treturn null;\n\t}\n\n\tconst linePart = remainder.slice(0, secondSep);\n\tconst lineNumber = Number.parseInt(linePart, 10);\n\tif (!Number.isInteger(lineNumber) || lineNumber <= 0) {\n\t\treturn null;\n\t}\n\n\tlet contentSegment = remainder.slice(secondSep + 1);\n\tconst columnSep = contentSegment.indexOf(\":\");\n\tif (columnSep !== -1 && /^\\d+$/.test(contentSegment.slice(0, columnSep))) {\n\t\tcontentSegment = contentSegment.slice(columnSep + 1);\n\t}\n\n\tconst content = contentSegment.trim();\n\tif (!content) {\n\t\treturn null;\n\t}\n\n\treturn { path: filePath, lineNumber, content };\n}\n\nexport function parseAndFilterGrepOutput(rawOutput: string, state: GrepState): GrepMatch[] {\n\tconst matches: GrepMatch[] = [];\n\tif (typeof rawOutput !== \"string\" || !rawOutput.trim()) {\n\t\treturn matches;\n\t}\n\n\tfor (const line of rawOutput.split(/\\r?\\n/)) {\n\t\tconst fields = extractMatchFields(line);\n\t\tif (!fields) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (state.isNew(fields.path, fields.lineNumber)) {\n\t\t\tmatches.push(fields);\n\t\t\tstate.add(fields.path, fields.lineNumber);\n\t\t}\n\t}\n\n\treturn matches;\n}\n\nfunction truncateOutput(payload: string, maxChars: number): string {\n\tif (payload.length <= maxChars) {\n\t\treturn payload;\n\t}\n\n\tconst note = \"... (output truncated)\";\n\tconst available = maxChars - note.length - 1;\n\tif (available <= 0) {\n\t\treturn note;\n\t}\n\n\tif (payload.length <= available) {\n\t\treturn `${payload.slice(0, available).replace(/\\n$/, \"\")}\\n${note}`;\n\t}\n\n\tconst core = payload.slice(0, Math.max(0, available - 1));\n\tconst trimmed = core.replace(/\\n$/, \"\").replace(/\\s+$/, \"\");\n\tconst snippet = trimmed ? `${trimmed}…` : \"…\";\n\treturn `${snippet}\\n${note}`;\n}\n\nexport function formatTurnGrepOutput(\n\tmatches: GrepMatch[],\n\tmaxChars: number = MAX_GREP_OUTPUT_CHARS_PER_TURN\n): string {\n\tif (!matches || matches.length === 0) {\n\t\treturn \"No new matches found.\";\n\t}\n\n\tconst matchesByFile = new Map<string, GrepMatch[]>();\n\tfor (const match of matches) {\n\t\tif (!matchesByFile.has(match.path)) {\n\t\t\tmatchesByFile.set(match.path, []);\n\t\t}\n\t\tmatchesByFile.get(match.path)!.push(match);\n\t}\n\n\tconst lines: string[] = [];\n\tconst sortedPaths = Array.from(matchesByFile.keys()).sort();\n\tsortedPaths.forEach((filePath, index) => {\n\t\tif (index > 0) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tlines.push(filePath);\n\t\tconst sortedMatches = matchesByFile\n\t\t\t.get(filePath)!\n\t\t\t.slice()\n\t\t\t.sort((a, b) => a.lineNumber - b.lineNumber);\n\t\tfor (const match of sortedMatches) {\n\t\t\tlines.push(`${match.lineNumber}:${match.content}`);\n\t\t}\n\t});\n\n\treturn truncateOutput(lines.join(\"\\n\"), maxChars);\n}\n\n\n","import type { FinishFileSpec } from '../agent/types.js';\nimport fs from 'fs/promises';\n\nexport function normalizeFinishFiles(files: FinishFileSpec[]): FinishFileSpec[] {\n return files.map((f) => {\n const merged = mergeRanges(f.lines);\n return { path: f.path, lines: merged };\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 ranges = mergeRanges(f.lines);\n const chunks: string[] = [];\n for (const [s, e] of ranges) {\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 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"],"mappings":"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","names":["path","path","path","fs","path"]}
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  runWarpGrep
3
- } from "../../../chunk-W3XLPMV3.js";
3
+ } from "../../../chunk-7HS6YXA3.js";
4
4
  import "../../../chunk-EK7OQPWD.js";
5
5
  import "../../../chunk-Z2FBMSNE.js";
6
- import "../../../chunk-GTOXMAF2.js";
7
- import "../../../chunk-HKZB23U7.js";
6
+ import "../../../chunk-SWQPIKPY.js";
7
+ import "../../../chunk-WETRQJGU.js";
8
8
  import "../../../chunk-73RQWOQC.js";
9
- import "../../../chunk-AFEPUNAO.js";
9
+ import "../../../chunk-TJIUA27P.js";
10
10
  import "../../../chunk-TICMYDII.js";
11
11
  import "../../../chunk-NDZO5IPV.js";
12
12
  import "../../../chunk-4VWJFZVS.js";
@@ -1,2 +1 @@
1
- import "../../../chunk-XYPMN4A3.js";
2
1
  //# sourceMappingURL=types.js.map