@morphllm/morphsdk 0.2.45 → 0.2.47

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 (128) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-TVFGHXPE.js → chunk-3FTAIJBH.js} +4 -4
  3. package/dist/{chunk-ZRLEAPZV.js → chunk-76DJEQEP.js} +4 -4
  4. package/dist/{chunk-W3XLPMV3.js → chunk-7HS6YXA3.js} +21 -5
  5. package/dist/{chunk-W3XLPMV3.js.map → chunk-7HS6YXA3.js.map} +1 -1
  6. package/dist/chunk-BLXC5R4W.js +82 -0
  7. package/dist/chunk-BLXC5R4W.js.map +1 -0
  8. package/dist/chunk-FA6UGPVL.js +105 -0
  9. package/dist/chunk-FA6UGPVL.js.map +1 -0
  10. package/dist/{chunk-PEGZVGG4.js → chunk-G4AWE5A2.js} +4 -4
  11. package/dist/{chunk-OUEJ6XEO.js → chunk-GJU7UOFL.js} +4 -4
  12. package/dist/{chunk-Q7PDN7TS.js → chunk-GZMUGMOZ.js} +1 -1
  13. package/dist/{chunk-Q7PDN7TS.js.map → chunk-GZMUGMOZ.js.map} +1 -1
  14. package/dist/chunk-JYBVRF72.js +1 -0
  15. package/dist/chunk-OOZSGWSK.js +70 -0
  16. package/dist/chunk-OOZSGWSK.js.map +1 -0
  17. package/dist/{chunk-GDR65N2J.js → chunk-OXHGFHEU.js} +53 -26
  18. package/dist/chunk-OXHGFHEU.js.map +1 -0
  19. package/dist/{chunk-VBBJGWHY.js → chunk-P2XKFWFD.js} +2 -2
  20. package/dist/chunk-RAKREIXE.js +76 -0
  21. package/dist/chunk-RAKREIXE.js.map +1 -0
  22. package/dist/chunk-SDI2FI6G.js +283 -0
  23. package/dist/chunk-SDI2FI6G.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-UYBIKZPM.js → chunk-UCWTZSW5.js} +3 -3
  30. package/dist/{chunk-X4CQ6D3G.js → chunk-UIZT3KVJ.js} +4 -4
  31. package/dist/chunk-WETRQJGU.js +129 -0
  32. package/dist/chunk-WETRQJGU.js.map +1 -0
  33. package/dist/{chunk-RSLIOCOE.js → chunk-XQIVYQD6.js} +3 -2
  34. package/dist/chunk-XQIVYQD6.js.map +1 -0
  35. package/dist/client-BGctTHu9.d.ts +318 -0
  36. package/dist/client.cjs +1886 -44
  37. package/dist/client.cjs.map +1 -1
  38. package/dist/client.d.ts +14 -110
  39. package/dist/client.js +28 -3
  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 +1965 -46
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.ts +8 -1
  54. package/dist/index.js +47 -5
  55. package/dist/tools/codebase_search/anthropic.js +2 -2
  56. package/dist/tools/codebase_search/index.js +9 -9
  57. package/dist/tools/codebase_search/openai.js +2 -2
  58. package/dist/tools/codebase_search/vercel.js +2 -2
  59. package/dist/tools/fastapply/anthropic.js +2 -2
  60. package/dist/tools/fastapply/index.js +7 -7
  61. package/dist/tools/fastapply/openai.js +2 -2
  62. package/dist/tools/fastapply/vercel.js +2 -2
  63. package/dist/tools/index.js +7 -7
  64. package/dist/tools/warp_grep/agent/config.cjs +80 -1
  65. package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
  66. package/dist/tools/warp_grep/agent/config.js +1 -1
  67. package/dist/tools/warp_grep/agent/parser.cjs +43 -2
  68. package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
  69. package/dist/tools/warp_grep/agent/parser.js +1 -1
  70. package/dist/tools/warp_grep/agent/prompt.cjs +89 -45
  71. package/dist/tools/warp_grep/agent/prompt.cjs.map +1 -1
  72. package/dist/tools/warp_grep/agent/prompt.d.ts +1 -1
  73. package/dist/tools/warp_grep/agent/prompt.js +1 -1
  74. package/dist/tools/warp_grep/agent/runner.cjs +229 -49
  75. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  76. package/dist/tools/warp_grep/agent/runner.js +4 -4
  77. package/dist/tools/warp_grep/agent/types.js +0 -1
  78. package/dist/tools/warp_grep/anthropic.cjs +313 -84
  79. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  80. package/dist/tools/warp_grep/anthropic.d.ts +75 -12
  81. package/dist/tools/warp_grep/anthropic.js +22 -9
  82. package/dist/tools/warp_grep/index.cjs +417 -127
  83. package/dist/tools/warp_grep/index.cjs.map +1 -1
  84. package/dist/tools/warp_grep/index.d.ts +17 -4
  85. package/dist/tools/warp_grep/index.js +30 -22
  86. package/dist/tools/warp_grep/openai.cjs +316 -84
  87. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  88. package/dist/tools/warp_grep/openai.d.ts +73 -29
  89. package/dist/tools/warp_grep/openai.js +22 -9
  90. package/dist/tools/warp_grep/providers/command.cjs +80 -1
  91. package/dist/tools/warp_grep/providers/command.cjs.map +1 -1
  92. package/dist/tools/warp_grep/providers/command.js +2 -2
  93. package/dist/tools/warp_grep/providers/local.cjs +82 -2
  94. package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
  95. package/dist/tools/warp_grep/providers/local.js +3 -3
  96. package/dist/tools/warp_grep/utils/ripgrep.cjs +2 -1
  97. package/dist/tools/warp_grep/utils/ripgrep.cjs.map +1 -1
  98. package/dist/tools/warp_grep/utils/ripgrep.js +1 -1
  99. package/dist/tools/warp_grep/vercel.cjs +293 -58
  100. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  101. package/dist/tools/warp_grep/vercel.d.ts +40 -19
  102. package/dist/tools/warp_grep/vercel.js +18 -9
  103. package/package.json +2 -1
  104. package/dist/chunk-AFEPUNAO.js +0 -15
  105. package/dist/chunk-AFEPUNAO.js.map +0 -1
  106. package/dist/chunk-GDR65N2J.js.map +0 -1
  107. package/dist/chunk-GTOXMAF2.js.map +0 -1
  108. package/dist/chunk-HKZB23U7.js +0 -85
  109. package/dist/chunk-HKZB23U7.js.map +0 -1
  110. package/dist/chunk-IQHKEIQX.js +0 -54
  111. package/dist/chunk-IQHKEIQX.js.map +0 -1
  112. package/dist/chunk-JKFVDM62.js +0 -45
  113. package/dist/chunk-JKFVDM62.js.map +0 -1
  114. package/dist/chunk-K6FQZZ2E.js +0 -104
  115. package/dist/chunk-K6FQZZ2E.js.map +0 -1
  116. package/dist/chunk-KL4YVZRF.js +0 -57
  117. package/dist/chunk-KL4YVZRF.js.map +0 -1
  118. package/dist/chunk-RSLIOCOE.js.map +0 -1
  119. package/dist/chunk-XYPMN4A3.js +0 -1
  120. /package/dist/{chunk-TVFGHXPE.js.map → chunk-3FTAIJBH.js.map} +0 -0
  121. /package/dist/{chunk-ZRLEAPZV.js.map → chunk-76DJEQEP.js.map} +0 -0
  122. /package/dist/{chunk-PEGZVGG4.js.map → chunk-G4AWE5A2.js.map} +0 -0
  123. /package/dist/{chunk-OUEJ6XEO.js.map → chunk-GJU7UOFL.js.map} +0 -0
  124. /package/dist/{chunk-XYPMN4A3.js.map → chunk-JYBVRF72.js.map} +0 -0
  125. /package/dist/{chunk-VBBJGWHY.js.map → chunk-P2XKFWFD.js.map} +0 -0
  126. /package/dist/{chunk-O5DA5V5S.js.map → chunk-UBX7QYBD.js.map} +0 -0
  127. /package/dist/{chunk-UYBIKZPM.js.map → chunk-UCWTZSW5.js.map} +0 -0
  128. /package/dist/{chunk-X4CQ6D3G.js.map → chunk-UIZT3KVJ.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];
@@ -752,9 +935,10 @@ var import_path3 = __toESM(require("path"), 1);
752
935
 
753
936
  // tools/warp_grep/utils/ripgrep.ts
754
937
  var import_child_process = require("child_process");
938
+ var import_ripgrep = require("@vscode/ripgrep");
755
939
  function runRipgrep(args, opts) {
756
940
  return new Promise((resolve) => {
757
- const child = (0, import_child_process.spawn)("rg", args, {
941
+ const child = (0, import_child_process.spawn)(import_ripgrep.rgPath, args, {
758
942
  cwd: opts?.cwd,
759
943
  env: { ...process.env, ...opts?.env || {} },
760
944
  stdio: ["ignore", "pipe", "pipe"]
@@ -937,6 +1121,97 @@ var LocalRipgrepProvider = class {
937
1121
  }
938
1122
  };
939
1123
 
1124
+ // tools/warp_grep/core.ts
1125
+ var WarpGrepClient = class {
1126
+ config;
1127
+ constructor(config = {}) {
1128
+ this.config = {
1129
+ apiKey: config.apiKey,
1130
+ debug: config.debug,
1131
+ timeout: config.timeout,
1132
+ retryConfig: config.retryConfig
1133
+ };
1134
+ }
1135
+ /**
1136
+ * Execute a code search query
1137
+ *
1138
+ * @param input - Search parameters including query, repoRoot, and optional provider
1139
+ * @returns Search results with relevant code contexts
1140
+ *
1141
+ * @example
1142
+ * ```typescript
1143
+ * const result = await client.execute({
1144
+ * query: 'Find authentication middleware',
1145
+ * repoRoot: '.'
1146
+ * });
1147
+ *
1148
+ * if (result.success) {
1149
+ * for (const ctx of result.contexts) {
1150
+ * console.log(`File: ${ctx.file}`);
1151
+ * console.log(ctx.content);
1152
+ * }
1153
+ * }
1154
+ * ```
1155
+ */
1156
+ async execute(input) {
1157
+ const provider = input.provider ?? new LocalRipgrepProvider(input.repoRoot, input.excludes);
1158
+ const result = await runWarpGrep({
1159
+ query: input.query,
1160
+ repoRoot: input.repoRoot,
1161
+ provider,
1162
+ excludes: input.excludes,
1163
+ includes: input.includes,
1164
+ debug: input.debug ?? this.config.debug ?? false,
1165
+ apiKey: this.config.apiKey
1166
+ });
1167
+ const finish = result.finish;
1168
+ if (result.terminationReason !== "completed" || !finish?.metadata) {
1169
+ return {
1170
+ success: false,
1171
+ error: "Search did not complete"
1172
+ };
1173
+ }
1174
+ const contexts = (finish.resolved ?? []).map((r) => ({
1175
+ file: r.path,
1176
+ content: r.content
1177
+ }));
1178
+ return {
1179
+ success: true,
1180
+ contexts,
1181
+ summary: finish.payload
1182
+ };
1183
+ }
1184
+ };
1185
+ async function executeWarpGrep(input, config) {
1186
+ const client = new WarpGrepClient(config);
1187
+ return client.execute(input);
1188
+ }
1189
+ function formatResult(result) {
1190
+ if (!result.success) {
1191
+ return `Search failed: ${result.error}`;
1192
+ }
1193
+ if (!result.contexts || result.contexts.length === 0) {
1194
+ return "No relevant code found. Try rephrasing your query.";
1195
+ }
1196
+ const lines = [];
1197
+ lines.push(`Found ${result.contexts.length} relevant code sections:
1198
+ `);
1199
+ result.contexts.forEach((ctx, i) => {
1200
+ lines.push(`${i + 1}. ${ctx.file}`);
1201
+ lines.push("```");
1202
+ lines.push(ctx.content);
1203
+ lines.push("```");
1204
+ lines.push("");
1205
+ });
1206
+ if (result.summary) {
1207
+ lines.push(`Summary: ${result.summary}`);
1208
+ }
1209
+ return lines.join("\n");
1210
+ }
1211
+
1212
+ // tools/warp_grep/prompts.ts
1213
+ 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.";
1214
+
940
1215
  // tools/warp_grep/providers/command.ts
941
1216
  var CommandExecProvider = class {
942
1217
  constructor(opts) {
@@ -1003,104 +1278,116 @@ var CommandExecProvider = class {
1003
1278
  };
1004
1279
 
1005
1280
  // 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
- });
1281
+ var TOOL_PARAMETERS = {
1282
+ type: "object",
1283
+ properties: {
1284
+ query: { type: "string", description: "Free-form repository question" }
1285
+ },
1286
+ required: ["query"]
1287
+ };
1288
+ async function execute(input, config) {
1289
+ const parsed = typeof input === "string" ? JSON.parse(input) : input;
1290
+ const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1291
+ const result = await runWarpGrep({
1292
+ query: parsed.query,
1293
+ repoRoot: config.repoRoot,
1294
+ provider,
1295
+ excludes: config.excludes,
1296
+ includes: config.includes,
1297
+ debug: config.debug ?? false,
1298
+ apiKey: config.apiKey
1299
+ });
1300
+ const finish = result.finish;
1301
+ if (result.terminationReason !== "completed" || !finish?.metadata) {
1302
+ return { success: false, error: "Search did not complete" };
1303
+ }
1304
+ const contexts = (finish.resolved ?? []).map((r) => ({
1305
+ file: r.path,
1306
+ content: r.content
1307
+ }));
1308
+ return { success: true, contexts, summary: finish.payload };
1309
+ }
1010
1310
  function createMorphWarpGrepTool(config) {
1011
1311
  const tool2 = {
1012
1312
  type: "function",
1013
1313
  function: {
1014
1314
  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
- }
1315
+ description: config.description ?? WARP_GREP_DESCRIPTION,
1316
+ parameters: TOOL_PARAMETERS
1023
1317
  }
1024
1318
  };
1025
1319
  return Object.assign(tool2, {
1026
1320
  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 };
1321
+ return execute(input, config);
1322
+ },
1323
+ formatResult: (result) => {
1324
+ return formatResult(result);
1325
+ },
1326
+ getSystemPrompt: () => {
1327
+ return getSystemPrompt();
1047
1328
  }
1048
1329
  });
1049
1330
  }
1050
1331
 
1051
1332
  // 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
- });
1333
+ var INPUT_SCHEMA = {
1334
+ type: "object",
1335
+ properties: {
1336
+ query: { type: "string", description: "Free-form repository question" }
1337
+ },
1338
+ required: ["query"]
1339
+ };
1340
+ async function execute2(input, config) {
1341
+ const parsed = typeof input === "string" ? JSON.parse(input) : input;
1342
+ const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1343
+ const result = await runWarpGrep({
1344
+ query: parsed.query,
1345
+ repoRoot: config.repoRoot,
1346
+ provider,
1347
+ excludes: config.excludes,
1348
+ includes: config.includes,
1349
+ debug: config.debug ?? false,
1350
+ apiKey: config.apiKey
1351
+ });
1352
+ const finish = result.finish;
1353
+ if (result.terminationReason !== "completed" || !finish?.metadata) {
1354
+ return { success: false, error: "Search did not complete" };
1355
+ }
1356
+ const contexts = (finish.resolved ?? []).map((r) => ({
1357
+ file: r.path,
1358
+ content: r.content
1359
+ }));
1360
+ return { success: true, contexts, summary: finish.payload };
1361
+ }
1056
1362
  function createMorphWarpGrepTool2(config) {
1057
1363
  const tool2 = {
1058
1364
  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
- }
1365
+ description: config.description ?? WARP_GREP_DESCRIPTION,
1366
+ input_schema: INPUT_SCHEMA
1067
1367
  };
1068
1368
  return Object.assign(tool2, {
1069
1369
  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 };
1370
+ return execute2(input, config);
1371
+ },
1372
+ formatResult: (result) => {
1373
+ return formatResult(result);
1374
+ },
1375
+ getSystemPrompt: () => {
1376
+ return getSystemPrompt();
1090
1377
  }
1091
1378
  });
1092
1379
  }
1093
1380
 
1094
1381
  // tools/warp_grep/vercel.ts
1095
1382
  var import_ai = require("ai");
1096
- var import_zod3 = require("zod");
1383
+ var import_zod = require("zod");
1384
+ var warpGrepSchema = import_zod.z.object({
1385
+ query: import_zod.z.string().describe("Free-form repository question")
1386
+ });
1097
1387
  function createMorphWarpGrepTool3(config) {
1098
- const schema = import_zod3.z.object({
1099
- query: import_zod3.z.string().describe("Free-form repository question")
1100
- });
1101
1388
  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,
1389
+ description: config.description ?? WARP_GREP_DESCRIPTION,
1390
+ inputSchema: warpGrepSchema,
1104
1391
  execute: async (params) => {
1105
1392
  const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1106
1393
  const result = await runWarpGrep({
@@ -1114,7 +1401,7 @@ function createMorphWarpGrepTool3(config) {
1114
1401
  });
1115
1402
  const finish = result.finish;
1116
1403
  if (result.terminationReason !== "completed" || !finish?.metadata) {
1117
- return { success: false, error: "Search did not complete", messages: result.messages };
1404
+ return { success: false, error: "Search did not complete" };
1118
1405
  }
1119
1406
  const contexts = (finish.resolved ?? []).map((r) => ({
1120
1407
  file: r.path,
@@ -1126,14 +1413,17 @@ function createMorphWarpGrepTool3(config) {
1126
1413
  }
1127
1414
  // Annotate the CommonJS export names for ESM import in node:
1128
1415
  0 && (module.exports = {
1129
- AGENT_CONFIG,
1130
1416
  CommandExecProvider,
1131
- DEFAULT_EXCLUDES,
1132
- DEFAULT_MODEL,
1133
1417
  LocalRipgrepProvider,
1418
+ WARP_GREP_DESCRIPTION,
1419
+ WARP_GREP_SYSTEM_PROMPT,
1420
+ WarpGrepClient,
1134
1421
  createAnthropicWarpGrepTool,
1135
1422
  createOpenAIWarpGrepTool,
1136
1423
  createVercelWarpGrepTool,
1424
+ executeWarpGrep,
1425
+ formatResult,
1426
+ getSystemPrompt,
1137
1427
  runWarpGrep
1138
1428
  });
1139
1429
  //# sourceMappingURL=index.cjs.map