@morphllm/morphsdk 0.2.45 → 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 (122) 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-GDR65N2J.js → chunk-OXHGFHEU.js} +53 -26
  20. package/dist/chunk-OXHGFHEU.js.map +1 -0
  21. package/dist/{chunk-VBBJGWHY.js → chunk-P2XKFWFD.js} +2 -2
  22. package/dist/chunk-PABIV7X6.js +76 -0
  23. package/dist/chunk-PABIV7X6.js.map +1 -0
  24. package/dist/{chunk-GTOXMAF2.js → chunk-SWQPIKPY.js} +44 -3
  25. package/dist/chunk-SWQPIKPY.js.map +1 -0
  26. package/dist/chunk-TJIUA27P.js +94 -0
  27. package/dist/chunk-TJIUA27P.js.map +1 -0
  28. package/dist/{chunk-O5DA5V5S.js → chunk-UBX7QYBD.js} +4 -4
  29. package/dist/{chunk-X4CQ6D3G.js → chunk-UIZT3KVJ.js} +4 -4
  30. package/dist/{chunk-UYBIKZPM.js → chunk-UXYK7WZX.js} +2 -2
  31. package/dist/chunk-WETRQJGU.js +129 -0
  32. package/dist/chunk-WETRQJGU.js.map +1 -0
  33. package/dist/client-BGctTHu9.d.ts +318 -0
  34. package/dist/client.cjs +1885 -44
  35. package/dist/client.cjs.map +1 -1
  36. package/dist/client.d.ts +14 -110
  37. package/dist/client.js +28 -3
  38. package/dist/core-DxiUwyBe.d.ts +156 -0
  39. package/dist/git/client.cjs +52 -25
  40. package/dist/git/client.cjs.map +1 -1
  41. package/dist/git/client.d.ts +17 -8
  42. package/dist/git/client.js +1 -1
  43. package/dist/git/index.cjs +52 -25
  44. package/dist/git/index.cjs.map +1 -1
  45. package/dist/git/index.d.ts +1 -1
  46. package/dist/git/index.js +2 -2
  47. package/dist/git/types.cjs.map +1 -1
  48. package/dist/git/types.d.ts +20 -2
  49. package/dist/index.cjs +1964 -46
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.d.ts +8 -1
  52. package/dist/index.js +47 -5
  53. package/dist/tools/codebase_search/anthropic.js +2 -2
  54. package/dist/tools/codebase_search/index.js +9 -9
  55. package/dist/tools/codebase_search/openai.js +2 -2
  56. package/dist/tools/codebase_search/vercel.js +2 -2
  57. package/dist/tools/fastapply/anthropic.js +2 -2
  58. package/dist/tools/fastapply/index.js +7 -7
  59. package/dist/tools/fastapply/openai.js +2 -2
  60. package/dist/tools/fastapply/vercel.js +2 -2
  61. package/dist/tools/index.js +7 -7
  62. package/dist/tools/warp_grep/agent/config.cjs +80 -1
  63. package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
  64. package/dist/tools/warp_grep/agent/config.js +1 -1
  65. package/dist/tools/warp_grep/agent/parser.cjs +43 -2
  66. package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
  67. package/dist/tools/warp_grep/agent/parser.js +1 -1
  68. package/dist/tools/warp_grep/agent/prompt.cjs +89 -45
  69. package/dist/tools/warp_grep/agent/prompt.cjs.map +1 -1
  70. package/dist/tools/warp_grep/agent/prompt.d.ts +1 -1
  71. package/dist/tools/warp_grep/agent/prompt.js +1 -1
  72. package/dist/tools/warp_grep/agent/runner.cjs +229 -49
  73. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  74. package/dist/tools/warp_grep/agent/runner.js +4 -4
  75. package/dist/tools/warp_grep/agent/types.js +0 -1
  76. package/dist/tools/warp_grep/anthropic.cjs +311 -83
  77. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  78. package/dist/tools/warp_grep/anthropic.d.ts +75 -12
  79. package/dist/tools/warp_grep/anthropic.js +21 -8
  80. package/dist/tools/warp_grep/index.cjs +415 -126
  81. package/dist/tools/warp_grep/index.cjs.map +1 -1
  82. package/dist/tools/warp_grep/index.d.ts +17 -4
  83. package/dist/tools/warp_grep/index.js +29 -21
  84. package/dist/tools/warp_grep/openai.cjs +314 -83
  85. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  86. package/dist/tools/warp_grep/openai.d.ts +73 -29
  87. package/dist/tools/warp_grep/openai.js +21 -8
  88. package/dist/tools/warp_grep/providers/command.cjs +80 -1
  89. package/dist/tools/warp_grep/providers/command.cjs.map +1 -1
  90. package/dist/tools/warp_grep/providers/command.js +2 -2
  91. package/dist/tools/warp_grep/providers/local.cjs +80 -1
  92. package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
  93. package/dist/tools/warp_grep/providers/local.js +2 -2
  94. package/dist/tools/warp_grep/vercel.cjs +291 -57
  95. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  96. package/dist/tools/warp_grep/vercel.d.ts +40 -19
  97. package/dist/tools/warp_grep/vercel.js +17 -8
  98. package/package.json +1 -1
  99. package/dist/chunk-AFEPUNAO.js +0 -15
  100. package/dist/chunk-AFEPUNAO.js.map +0 -1
  101. package/dist/chunk-GDR65N2J.js.map +0 -1
  102. package/dist/chunk-GTOXMAF2.js.map +0 -1
  103. package/dist/chunk-HKZB23U7.js +0 -85
  104. package/dist/chunk-HKZB23U7.js.map +0 -1
  105. package/dist/chunk-IQHKEIQX.js +0 -54
  106. package/dist/chunk-IQHKEIQX.js.map +0 -1
  107. package/dist/chunk-JKFVDM62.js +0 -45
  108. package/dist/chunk-JKFVDM62.js.map +0 -1
  109. package/dist/chunk-K6FQZZ2E.js +0 -104
  110. package/dist/chunk-K6FQZZ2E.js.map +0 -1
  111. package/dist/chunk-KL4YVZRF.js +0 -57
  112. package/dist/chunk-KL4YVZRF.js.map +0 -1
  113. package/dist/chunk-XYPMN4A3.js +0 -1
  114. /package/dist/{chunk-TVFGHXPE.js.map → chunk-3FTAIJBH.js.map} +0 -0
  115. /package/dist/{chunk-ZRLEAPZV.js.map → chunk-76DJEQEP.js.map} +0 -0
  116. /package/dist/{chunk-PEGZVGG4.js.map → chunk-G4AWE5A2.js.map} +0 -0
  117. /package/dist/{chunk-OUEJ6XEO.js.map → chunk-GJU7UOFL.js.map} +0 -0
  118. /package/dist/{chunk-XYPMN4A3.js.map → chunk-JYBVRF72.js.map} +0 -0
  119. /package/dist/{chunk-VBBJGWHY.js.map → chunk-P2XKFWFD.js.map} +0 -0
  120. /package/dist/{chunk-O5DA5V5S.js.map → chunk-UBX7QYBD.js.map} +0 -0
  121. /package/dist/{chunk-X4CQ6D3G.js.map → chunk-UIZT3KVJ.js.map} +0 -0
  122. /package/dist/{chunk-UYBIKZPM.js.map → chunk-UXYK7WZX.js.map} +0 -0
@@ -30,14 +30,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // tools/warp_grep/index.ts
31
31
  var warp_grep_exports = {};
32
32
  __export(warp_grep_exports, {
33
- AGENT_CONFIG: () => AGENT_CONFIG,
34
33
  CommandExecProvider: () => CommandExecProvider,
35
- DEFAULT_EXCLUDES: () => DEFAULT_EXCLUDES,
36
- DEFAULT_MODEL: () => DEFAULT_MODEL,
37
34
  LocalRipgrepProvider: () => LocalRipgrepProvider,
35
+ WARP_GREP_DESCRIPTION: () => WARP_GREP_DESCRIPTION,
36
+ WARP_GREP_SYSTEM_PROMPT: () => SYSTEM_PROMPT,
37
+ WarpGrepClient: () => WarpGrepClient,
38
38
  createAnthropicWarpGrepTool: () => createMorphWarpGrepTool2,
39
39
  createOpenAIWarpGrepTool: () => createMorphWarpGrepTool,
40
40
  createVercelWarpGrepTool: () => createMorphWarpGrepTool3,
41
+ executeWarpGrep: () => executeWarpGrep,
42
+ formatResult: () => formatResult,
43
+ getSystemPrompt: () => getSystemPrompt,
41
44
  runWarpGrep: () => runWarpGrep
42
45
  });
43
46
  module.exports = __toCommonJS(warp_grep_exports);
@@ -48,84 +51,207 @@ var AGENT_CONFIG = {
48
51
  MAX_ROUNDS: 10,
49
52
  TIMEOUT_MS: 3e4
50
53
  };
51
- 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"]);
54
+ var BUILTIN_EXCLUDES = [
55
+ // Version control
56
+ ".git",
57
+ ".svn",
58
+ ".hg",
59
+ ".bzr",
60
+ // Dependencies
61
+ "node_modules",
62
+ "bower_components",
63
+ ".pnpm",
64
+ ".yarn",
65
+ "vendor",
66
+ "packages",
67
+ "Pods",
68
+ ".bundle",
69
+ // Python
70
+ "__pycache__",
71
+ ".pytest_cache",
72
+ ".mypy_cache",
73
+ ".ruff_cache",
74
+ ".venv",
75
+ "venv",
76
+ ".tox",
77
+ ".nox",
78
+ ".eggs",
79
+ "*.egg-info",
80
+ // Build outputs
81
+ "dist",
82
+ "build",
83
+ "out",
84
+ "output",
85
+ "target",
86
+ "_build",
87
+ ".next",
88
+ ".nuxt",
89
+ ".output",
90
+ ".vercel",
91
+ ".netlify",
92
+ // Cache directories
93
+ ".cache",
94
+ ".parcel-cache",
95
+ ".turbo",
96
+ ".nx",
97
+ ".gradle",
98
+ // IDE/Editor
99
+ ".idea",
100
+ ".vscode",
101
+ ".vs",
102
+ // Coverage
103
+ "coverage",
104
+ ".coverage",
105
+ "htmlcov",
106
+ ".nyc_output",
107
+ // Temporary
108
+ "tmp",
109
+ "temp",
110
+ ".tmp",
111
+ ".temp",
112
+ // Lock files
113
+ "package-lock.json",
114
+ "yarn.lock",
115
+ "pnpm-lock.yaml",
116
+ "bun.lockb",
117
+ "Cargo.lock",
118
+ "Gemfile.lock",
119
+ "poetry.lock",
120
+ // Binary/minified
121
+ "*.min.js",
122
+ "*.min.css",
123
+ "*.bundle.js",
124
+ "*.wasm",
125
+ "*.so",
126
+ "*.dll",
127
+ "*.pyc",
128
+ "*.map",
129
+ "*.js.map",
130
+ // Hidden directories catch-all
131
+ ".*"
132
+ ];
133
+ var DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || "").split(",").map((s) => s.trim()).filter(Boolean).concat(BUILTIN_EXCLUDES);
52
134
  var DEFAULT_MODEL = "morph-warp-grep";
53
135
 
54
136
  // tools/warp_grep/agent/prompt.ts
55
- var SYSTEM_PROMPT = `You are a code search agent. Your task is to find relevant code snippets based on a search query.
137
+ var SYSTEM_PROMPT = `You are a code search agent. Your task is to find all relevant code for a given query.
56
138
 
57
139
  <workflow>
58
- You operate in exactly 3 rounds of tool exploration, followed by a final answer:
140
+ You have exactly 4 turns. The 4th turn MUST be a \`finish\` call. Each turn allows up to 8 parallel tool calls.
59
141
 
60
- 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.
61
- 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.
62
- </workflow>
142
+ - Turn 1: Map the territory OR dive deep (based on query specificity)
143
+ - Turn 2-3: Refine based on findings
144
+ - Turn 4: MUST call \`finish\` with all relevant code locations
145
+ - You MAY call \`finish\` early if confident\u2014but never before at least 1 search turn.
63
146
 
64
- <tool_calling>
65
- You have tools at your disposal to solve the coding task. Follow these rules regarding tool calls:
147
+ Remember, if the task feels easy to you, it is strongly desirable to call \`finish\` early using fewer turns, but quality over speed.
148
+ </workflow>
66
149
 
67
- ### 1. \`analyse\` - Explore Directories
68
- Explore directory structure in a tree-like format.
69
- **Syntax:** \`analyse <path> [pattern]\`
70
- - \`<path>\`: Directory path to analyze (defaults to \`.\`)
71
- - \`[pattern]\`: Optional regex pattern to filter names
150
+ <tools>
151
+ ### \`analyse <path> [pattern]\`
152
+ Directory tree or file search. Shows structure of a path, optionally filtered by regex pattern.
153
+ - \`path\`: Required. Directory or file path (use \`.\` for repo root)
154
+ - \`pattern\`: Optional regex to filter results
72
155
 
73
- For example:
156
+ Examples:
74
157
  \`\`\`
158
+ analyse .
75
159
  analyse src/api
76
- analyse . "test"
160
+ analyse . ".*\\.ts$"
161
+ analyse src "test.*"
77
162
  \`\`\`
78
163
 
79
- ### 2. \`read\` - Read File Contents
80
- Read entire files or specific line ranges.
81
- **Syntax:** \`read <path>[:start-end]\`
82
- - \`<path>\`: File path to read
83
- - \`[:start-end]\`: Optional 1-based, inclusive line range
164
+ ### \`read <path>[:start-end]\`
165
+ Read file contents. Line range is 1-based, inclusive.
166
+ - Returns numbered lines for easy reference
167
+ - Omit range to read entire file
84
168
 
85
- For example:
169
+ Examples:
86
170
  \`\`\`
87
171
  read src/main.py
88
- read src/database/connection.py:10-50
172
+ read src/db/conn.py:10-50
173
+ read package.json:1-20
89
174
  \`\`\`
90
175
 
91
- ### 3. \`grep\` - Search with Regex
92
- Search for regex patterns across files using ripgrep.
93
- **Syntax:** \`grep '<pattern>' <path>\`
94
- - \`'<pattern>'\`: Regex pattern (always wrap in single quotes)
95
- - \`<path>\`: Directory or file to search (use \`.\` for the repo root)
176
+ ### \`grep '<pattern>' <path>\`
177
+ Ripgrep search. Finds pattern matches across files.
178
+ - \`'<pattern>'\`: Required. Regex pattern wrapped in single quotes
179
+ - \`<path>\`: Required. Directory or file to search (use \`.\` for repo root)
96
180
 
97
- For example:
181
+ Examples:
98
182
  \`\`\`
99
- grep 'create_user' .
100
- grep 'import.*requests' src/api
101
- grep 'class\\\\s+AuthService' controllers/auth.py
183
+ grep 'class.*Service' src/
184
+ grep 'def authenticate' .
185
+ grep 'import.*from' src/components/
186
+ grep 'TODO' .
102
187
  \`\`\`
103
188
 
104
- ### 4. \`finish\` - Submit Final Answer
105
- Submit your findings when complete.
106
- **Syntax:** \`finish <file1:range1,range2...> [file2:range3...]\`
107
- - Provide file paths with colon-separated, comma-separated line ranges
189
+ ### \`finish <file1:ranges> [file2:ranges ...]\`
190
+ Submit final answer with all relevant code locations.
191
+ - Include generous line ranges\u2014don't be stingy with context
192
+ - Ranges are comma-separated: \`file.py:10-30,50-60\`
193
+ - ALWAYS include import statements at the top of files (usually lines 1-20)
194
+ - If code spans multiple files, include ALL of them
195
+ - Small files can be returned in full
108
196
 
109
- For example:
197
+ Examples:
110
198
  \`\`\`
111
- finish src/api/auth.py:25-50,75-80 src/models/user.py:10-15
199
+ finish src/auth.py:1-15,25-50,75-80 src/models/user.py:1-10,20-45
200
+ finish src/index.ts:1-100
112
201
  \`\`\`
113
- </tool_calling>
202
+ </tools>
114
203
 
115
204
  <strategy>
116
- - Use the \`analyse\`, \`grep\`, and \`read\` tools to gather information about the codebase.
117
- - Leverage the tools smartly to make full use of their potential
118
- - Make parallel tool calls within each round to investigate multiple paths or files efficiently
119
- - Be systematic and thorough within your 3-round limit
205
+ **Before your first tool call, classify the query:**
206
+
207
+ | Query Type | Turn 1 Strategy | Early Finish? |
208
+ |------------|-----------------|---------------|
209
+ | **Specific** (function name, error string, unique identifier) | 8 parallel greps on likely paths | Often by turn 2 |
210
+ | **Conceptual** (how does X work, where is Y handled) | analyse + 2-3 broad greps | Rarely early |
211
+ | **Exploratory** (find all tests, list API endpoints) | analyse at multiple depths | Usually needs 3 turns |
212
+
213
+ **Parallel call patterns:**
214
+ - **Shotgun grep**: Same pattern, 8 different directories\u2014fast coverage
215
+ - **Variant grep**: 8 pattern variations (synonyms, naming conventions)\u2014catches inconsistent codebases
216
+ - **Funnel**: 1 analyse + 7 greps\u2014orient and search simultaneously
217
+ - **Deep read**: 8 reads on files you already identified\u2014gather full context fast
120
218
  </strategy>
121
219
 
122
220
  <output_format>
123
- - Only output tool calls themselves
124
- - Do not include explanatory text, reasoning, or commentary
125
- - Each tool call should be on its own line
126
- - After 3 rounds of exploration, call \`finish\` with all relevant code snippets you found
221
+ EVERY response MUST follow this exact format:
222
+
223
+ 1. First, wrap your reasoning in \`<think>...</think>\` tags containing:
224
+ - Query classification (specific/conceptual/exploratory)
225
+ - Confidence estimate (can I finish in 1-2 turns?)
226
+ - This turn's parallel strategy
227
+ - What signals would let me finish early?
228
+
229
+ 2. Then, output tool calls wrapped in \`<tool_call>...</tool_call>\` tags, one per line.
230
+
231
+ Example:
232
+ \`\`\`
233
+ <think>
234
+ This is a specific query about authentication. I'll grep for auth-related patterns.
235
+ High confidence I can finish in 2 turns if I find the auth module.
236
+ Strategy: Shotgun grep across likely directories.
237
+ </think>
238
+ <tool_call>grep 'authenticate' src/</tool_call>
239
+ <tool_call>grep 'login' src/</tool_call>
240
+ <tool_call>analyse src/auth</tool_call>
241
+ \`\`\`
242
+
243
+ No commentary outside \`<think>\`. No explanations after tool calls.
127
244
  </output_format>
128
245
 
246
+ <finishing_requirements>
247
+ When calling \`finish\`:
248
+ - Include the import section (typically lines 1-20) of each file
249
+ - Include all function/class definitions that are relevant
250
+ - Include any type definitions, interfaces, or constants used
251
+ - Better to over-include than leave the user missing context
252
+ - If unsure about boundaries, include more rather than less
253
+ </finishing_requirements>
254
+
129
255
  Begin your exploration now to find code relevant to the query.`;
130
256
  function getSystemPrompt() {
131
257
  return SYSTEM_PROMPT;
@@ -138,13 +264,54 @@ var LLMResponseParseError = class extends Error {
138
264
  this.name = "LLMResponseParseError";
139
265
  }
140
266
  };
267
+ var VALID_COMMANDS = ["analyse", "grep", "read", "finish"];
268
+ function preprocessText(text) {
269
+ let processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
270
+ const openingTagRegex = /<tool_call>|<tool>/gi;
271
+ const closingTagRegex = /<\/tool_call>|<\/tool>/gi;
272
+ const openingMatches = processed.match(openingTagRegex) || [];
273
+ const closingMatches = processed.match(closingTagRegex) || [];
274
+ if (openingMatches.length > closingMatches.length) {
275
+ const lastClosingMatch = /<\/tool_call>|<\/tool>/gi;
276
+ let lastClosingIndex = -1;
277
+ let match;
278
+ while ((match = lastClosingMatch.exec(processed)) !== null) {
279
+ lastClosingIndex = match.index + match[0].length;
280
+ }
281
+ if (lastClosingIndex > 0) {
282
+ processed = processed.slice(0, lastClosingIndex);
283
+ }
284
+ }
285
+ const toolCallLines = [];
286
+ const toolTagRegex = /<tool_call>([\s\S]*?)<\/tool_call>|<tool>([\s\S]*?)<\/tool>/gi;
287
+ let tagMatch;
288
+ while ((tagMatch = toolTagRegex.exec(processed)) !== null) {
289
+ const content = (tagMatch[1] || tagMatch[2] || "").trim();
290
+ if (content) {
291
+ const lines = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l);
292
+ toolCallLines.push(...lines);
293
+ }
294
+ }
295
+ const allLines = processed.split(/\r?\n/).map((l) => l.trim());
296
+ for (const line of allLines) {
297
+ if (!line) continue;
298
+ if (line.startsWith("<")) continue;
299
+ const firstWord = line.split(/\s/)[0];
300
+ if (VALID_COMMANDS.includes(firstWord)) {
301
+ if (!toolCallLines.includes(line)) {
302
+ toolCallLines.push(line);
303
+ }
304
+ }
305
+ }
306
+ return toolCallLines;
307
+ }
141
308
  var LLMResponseParser = class {
142
309
  finishSpecSplitRe = /,(?=[^,\s]+:)/;
143
310
  parse(text) {
144
311
  if (typeof text !== "string") {
145
312
  throw new TypeError("Command text must be a string.");
146
313
  }
147
- const lines = text.split(/\r?\n/).map((l) => l.trim());
314
+ const lines = preprocessText(text);
148
315
  const commands = [];
149
316
  let finishAccumulator = null;
150
317
  lines.forEach((line, idx) => {
@@ -167,7 +334,7 @@ var LLMResponseParser = class {
167
334
  finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);
168
335
  break;
169
336
  default:
170
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unsupported command '${cmd}'`);
337
+ break;
171
338
  }
172
339
  });
173
340
  if (finishAccumulator) {
@@ -709,7 +876,23 @@ async function runWarpGrep(config) {
709
876
  }
710
877
  }
711
878
  if (formatted.length > 0) {
712
- messages.push({ role: "user", content: formatted.join("\n") });
879
+ const turnsUsed = round;
880
+ const turnsRemaining = 4 - turnsUsed;
881
+ let turnMessage;
882
+ if (turnsRemaining === 0) {
883
+ turnMessage = `
884
+
885
+ [Turn ${turnsUsed}/4] This is your LAST turn. You MUST call the finish tool now.`;
886
+ } else if (turnsRemaining === 1) {
887
+ turnMessage = `
888
+
889
+ [Turn ${turnsUsed}/4] You have 1 turn remaining. Next turn you MUST call the finish tool.`;
890
+ } else {
891
+ turnMessage = `
892
+
893
+ [Turn ${turnsUsed}/4] You have ${turnsRemaining} turns remaining.`;
894
+ }
895
+ messages.push({ role: "user", content: formatted.join("\n") + turnMessage });
713
896
  }
714
897
  if (finishCalls.length) {
715
898
  const fc = finishCalls[0];
@@ -937,6 +1120,97 @@ var LocalRipgrepProvider = class {
937
1120
  }
938
1121
  };
939
1122
 
1123
+ // tools/warp_grep/core.ts
1124
+ var WarpGrepClient = class {
1125
+ config;
1126
+ constructor(config = {}) {
1127
+ this.config = {
1128
+ apiKey: config.apiKey,
1129
+ debug: config.debug,
1130
+ timeout: config.timeout,
1131
+ retryConfig: config.retryConfig
1132
+ };
1133
+ }
1134
+ /**
1135
+ * Execute a code search query
1136
+ *
1137
+ * @param input - Search parameters including query, repoRoot, and optional provider
1138
+ * @returns Search results with relevant code contexts
1139
+ *
1140
+ * @example
1141
+ * ```typescript
1142
+ * const result = await client.execute({
1143
+ * query: 'Find authentication middleware',
1144
+ * repoRoot: '.'
1145
+ * });
1146
+ *
1147
+ * if (result.success) {
1148
+ * for (const ctx of result.contexts) {
1149
+ * console.log(`File: ${ctx.file}`);
1150
+ * console.log(ctx.content);
1151
+ * }
1152
+ * }
1153
+ * ```
1154
+ */
1155
+ async execute(input) {
1156
+ const provider = input.provider ?? new LocalRipgrepProvider(input.repoRoot, input.excludes);
1157
+ const result = await runWarpGrep({
1158
+ query: input.query,
1159
+ repoRoot: input.repoRoot,
1160
+ provider,
1161
+ excludes: input.excludes,
1162
+ includes: input.includes,
1163
+ debug: input.debug ?? this.config.debug ?? false,
1164
+ apiKey: this.config.apiKey
1165
+ });
1166
+ const finish = result.finish;
1167
+ if (result.terminationReason !== "completed" || !finish?.metadata) {
1168
+ return {
1169
+ success: false,
1170
+ error: "Search did not complete"
1171
+ };
1172
+ }
1173
+ const contexts = (finish.resolved ?? []).map((r) => ({
1174
+ file: r.path,
1175
+ content: r.content
1176
+ }));
1177
+ return {
1178
+ success: true,
1179
+ contexts,
1180
+ summary: finish.payload
1181
+ };
1182
+ }
1183
+ };
1184
+ async function executeWarpGrep(input, config) {
1185
+ const client = new WarpGrepClient(config);
1186
+ return client.execute(input);
1187
+ }
1188
+ function formatResult(result) {
1189
+ if (!result.success) {
1190
+ return `Search failed: ${result.error}`;
1191
+ }
1192
+ if (!result.contexts || result.contexts.length === 0) {
1193
+ return "No relevant code found. Try rephrasing your query.";
1194
+ }
1195
+ const lines = [];
1196
+ lines.push(`Found ${result.contexts.length} relevant code sections:
1197
+ `);
1198
+ result.contexts.forEach((ctx, i) => {
1199
+ lines.push(`${i + 1}. ${ctx.file}`);
1200
+ lines.push("```");
1201
+ lines.push(ctx.content);
1202
+ lines.push("```");
1203
+ lines.push("");
1204
+ });
1205
+ if (result.summary) {
1206
+ lines.push(`Summary: ${result.summary}`);
1207
+ }
1208
+ return lines.join("\n");
1209
+ }
1210
+
1211
+ // tools/warp_grep/prompts.ts
1212
+ var WARP_GREP_DESCRIPTION = "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.";
1213
+
940
1214
  // tools/warp_grep/providers/command.ts
941
1215
  var CommandExecProvider = class {
942
1216
  constructor(opts) {
@@ -1003,104 +1277,116 @@ var CommandExecProvider = class {
1003
1277
  };
1004
1278
 
1005
1279
  // tools/warp_grep/openai.ts
1006
- var import_zod = require("zod");
1007
- var INPUT_SCHEMA = import_zod.z.object({
1008
- query: import_zod.z.string().describe("Free-form repository question")
1009
- });
1280
+ var TOOL_PARAMETERS = {
1281
+ type: "object",
1282
+ properties: {
1283
+ query: { type: "string", description: "Free-form repository question" }
1284
+ },
1285
+ required: ["query"]
1286
+ };
1287
+ async function execute(input, config) {
1288
+ const parsed = typeof input === "string" ? JSON.parse(input) : input;
1289
+ const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1290
+ const result = await runWarpGrep({
1291
+ query: parsed.query,
1292
+ repoRoot: config.repoRoot,
1293
+ provider,
1294
+ excludes: config.excludes,
1295
+ includes: config.includes,
1296
+ debug: config.debug ?? false,
1297
+ apiKey: config.apiKey
1298
+ });
1299
+ const finish = result.finish;
1300
+ if (result.terminationReason !== "completed" || !finish?.metadata) {
1301
+ return { success: false, error: "Search did not complete" };
1302
+ }
1303
+ const contexts = (finish.resolved ?? []).map((r) => ({
1304
+ file: r.path,
1305
+ content: r.content
1306
+ }));
1307
+ return { success: true, contexts, summary: finish.payload };
1308
+ }
1010
1309
  function createMorphWarpGrepTool(config) {
1011
1310
  const tool2 = {
1012
1311
  type: "function",
1013
1312
  function: {
1014
1313
  name: "morph-warp-grep",
1015
- description: config.description ?? "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1016
- parameters: {
1017
- type: "object",
1018
- properties: {
1019
- query: { type: "string", description: "Free-form repository question" }
1020
- },
1021
- required: ["query"]
1022
- }
1314
+ description: config.description ?? WARP_GREP_DESCRIPTION,
1315
+ parameters: TOOL_PARAMETERS
1023
1316
  }
1024
1317
  };
1025
1318
  return Object.assign(tool2, {
1026
1319
  execute: async (input) => {
1027
- const parsed = INPUT_SCHEMA.parse(typeof input === "string" ? JSON.parse(input) : input);
1028
- const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1029
- const result = await runWarpGrep({
1030
- query: parsed.query,
1031
- repoRoot: config.repoRoot,
1032
- provider,
1033
- excludes: config.excludes,
1034
- includes: config.includes,
1035
- debug: config.debug ?? false,
1036
- apiKey: config.apiKey
1037
- });
1038
- const finish = result.finish;
1039
- if (result.terminationReason !== "completed" || !finish?.metadata) {
1040
- return { success: false, error: "Search did not complete", messages: result.messages };
1041
- }
1042
- const contexts = (finish.resolved ?? []).map((r) => ({
1043
- file: r.path,
1044
- content: r.content
1045
- }));
1046
- return { success: true, contexts, summary: finish.payload };
1320
+ return execute(input, config);
1321
+ },
1322
+ formatResult: (result) => {
1323
+ return formatResult(result);
1324
+ },
1325
+ getSystemPrompt: () => {
1326
+ return getSystemPrompt();
1047
1327
  }
1048
1328
  });
1049
1329
  }
1050
1330
 
1051
1331
  // tools/warp_grep/anthropic.ts
1052
- var import_zod2 = require("zod");
1053
- var INPUT_SCHEMA2 = import_zod2.z.object({
1054
- query: import_zod2.z.string().describe("Free-form repository question")
1055
- });
1332
+ var INPUT_SCHEMA = {
1333
+ type: "object",
1334
+ properties: {
1335
+ query: { type: "string", description: "Free-form repository question" }
1336
+ },
1337
+ required: ["query"]
1338
+ };
1339
+ async function execute2(input, config) {
1340
+ const parsed = typeof input === "string" ? JSON.parse(input) : input;
1341
+ const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1342
+ const result = await runWarpGrep({
1343
+ query: parsed.query,
1344
+ repoRoot: config.repoRoot,
1345
+ provider,
1346
+ excludes: config.excludes,
1347
+ includes: config.includes,
1348
+ debug: config.debug ?? false,
1349
+ apiKey: config.apiKey
1350
+ });
1351
+ const finish = result.finish;
1352
+ if (result.terminationReason !== "completed" || !finish?.metadata) {
1353
+ return { success: false, error: "Search did not complete" };
1354
+ }
1355
+ const contexts = (finish.resolved ?? []).map((r) => ({
1356
+ file: r.path,
1357
+ content: r.content
1358
+ }));
1359
+ return { success: true, contexts, summary: finish.payload };
1360
+ }
1056
1361
  function createMorphWarpGrepTool2(config) {
1057
1362
  const tool2 = {
1058
1363
  name: "morph-warp-grep",
1059
- description: config.description ?? "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1060
- input_schema: {
1061
- type: "object",
1062
- properties: {
1063
- query: { type: "string", description: "Free-form repository question" }
1064
- },
1065
- required: ["query"]
1066
- }
1364
+ description: config.description ?? WARP_GREP_DESCRIPTION,
1365
+ input_schema: INPUT_SCHEMA
1067
1366
  };
1068
1367
  return Object.assign(tool2, {
1069
1368
  execute: async (input) => {
1070
- const parsed = INPUT_SCHEMA2.parse(typeof input === "string" ? JSON.parse(input) : input);
1071
- const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1072
- const result = await runWarpGrep({
1073
- query: parsed.query,
1074
- repoRoot: config.repoRoot,
1075
- provider,
1076
- excludes: config.excludes,
1077
- includes: config.includes,
1078
- debug: config.debug ?? false,
1079
- apiKey: config.apiKey
1080
- });
1081
- const finish = result.finish;
1082
- if (result.terminationReason !== "completed" || !finish?.metadata) {
1083
- return { success: false, error: "Search did not complete", messages: result.messages };
1084
- }
1085
- const contexts = (finish.resolved ?? []).map((r) => ({
1086
- file: r.path,
1087
- content: r.content
1088
- }));
1089
- return { success: true, contexts, summary: finish.payload };
1369
+ return execute2(input, config);
1370
+ },
1371
+ formatResult: (result) => {
1372
+ return formatResult(result);
1373
+ },
1374
+ getSystemPrompt: () => {
1375
+ return getSystemPrompt();
1090
1376
  }
1091
1377
  });
1092
1378
  }
1093
1379
 
1094
1380
  // tools/warp_grep/vercel.ts
1095
1381
  var import_ai = require("ai");
1096
- var import_zod3 = require("zod");
1382
+ var import_zod = require("zod");
1383
+ var warpGrepSchema = import_zod.z.object({
1384
+ query: import_zod.z.string().describe("Free-form repository question")
1385
+ });
1097
1386
  function createMorphWarpGrepTool3(config) {
1098
- const schema = import_zod3.z.object({
1099
- query: import_zod3.z.string().describe("Free-form repository question")
1100
- });
1101
1387
  return (0, import_ai.tool)({
1102
- description: config.description ?? "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1103
- inputSchema: schema,
1388
+ description: config.description ?? WARP_GREP_DESCRIPTION,
1389
+ inputSchema: warpGrepSchema,
1104
1390
  execute: async (params) => {
1105
1391
  const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1106
1392
  const result = await runWarpGrep({
@@ -1114,7 +1400,7 @@ function createMorphWarpGrepTool3(config) {
1114
1400
  });
1115
1401
  const finish = result.finish;
1116
1402
  if (result.terminationReason !== "completed" || !finish?.metadata) {
1117
- return { success: false, error: "Search did not complete", messages: result.messages };
1403
+ return { success: false, error: "Search did not complete" };
1118
1404
  }
1119
1405
  const contexts = (finish.resolved ?? []).map((r) => ({
1120
1406
  file: r.path,
@@ -1126,14 +1412,17 @@ function createMorphWarpGrepTool3(config) {
1126
1412
  }
1127
1413
  // Annotate the CommonJS export names for ESM import in node:
1128
1414
  0 && (module.exports = {
1129
- AGENT_CONFIG,
1130
1415
  CommandExecProvider,
1131
- DEFAULT_EXCLUDES,
1132
- DEFAULT_MODEL,
1133
1416
  LocalRipgrepProvider,
1417
+ WARP_GREP_DESCRIPTION,
1418
+ WARP_GREP_SYSTEM_PROMPT,
1419
+ WarpGrepClient,
1134
1420
  createAnthropicWarpGrepTool,
1135
1421
  createOpenAIWarpGrepTool,
1136
1422
  createVercelWarpGrepTool,
1423
+ executeWarpGrep,
1424
+ formatResult,
1425
+ getSystemPrompt,
1137
1426
  runWarpGrep
1138
1427
  });
1139
1428
  //# sourceMappingURL=index.cjs.map