@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,10 +30,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // tools/warp_grep/anthropic.ts
31
31
  var anthropic_exports = {};
32
32
  __export(anthropic_exports, {
33
- createMorphWarpGrepTool: () => createMorphWarpGrepTool
33
+ createMorphWarpGrepTool: () => createMorphWarpGrepTool,
34
+ default: () => anthropic_default,
35
+ execute: () => execute,
36
+ formatResult: () => formatResult,
37
+ getSystemPrompt: () => getSystemPrompt,
38
+ warpGrepTool: () => warpGrepTool
34
39
  });
35
40
  module.exports = __toCommonJS(anthropic_exports);
36
- var import_zod = require("zod");
37
41
 
38
42
  // tools/warp_grep/agent/config.ts
39
43
  var AGENT_CONFIG = {
@@ -41,84 +45,207 @@ var AGENT_CONFIG = {
41
45
  MAX_ROUNDS: 10,
42
46
  TIMEOUT_MS: 3e4
43
47
  };
44
- 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"]);
48
+ var BUILTIN_EXCLUDES = [
49
+ // Version control
50
+ ".git",
51
+ ".svn",
52
+ ".hg",
53
+ ".bzr",
54
+ // Dependencies
55
+ "node_modules",
56
+ "bower_components",
57
+ ".pnpm",
58
+ ".yarn",
59
+ "vendor",
60
+ "packages",
61
+ "Pods",
62
+ ".bundle",
63
+ // Python
64
+ "__pycache__",
65
+ ".pytest_cache",
66
+ ".mypy_cache",
67
+ ".ruff_cache",
68
+ ".venv",
69
+ "venv",
70
+ ".tox",
71
+ ".nox",
72
+ ".eggs",
73
+ "*.egg-info",
74
+ // Build outputs
75
+ "dist",
76
+ "build",
77
+ "out",
78
+ "output",
79
+ "target",
80
+ "_build",
81
+ ".next",
82
+ ".nuxt",
83
+ ".output",
84
+ ".vercel",
85
+ ".netlify",
86
+ // Cache directories
87
+ ".cache",
88
+ ".parcel-cache",
89
+ ".turbo",
90
+ ".nx",
91
+ ".gradle",
92
+ // IDE/Editor
93
+ ".idea",
94
+ ".vscode",
95
+ ".vs",
96
+ // Coverage
97
+ "coverage",
98
+ ".coverage",
99
+ "htmlcov",
100
+ ".nyc_output",
101
+ // Temporary
102
+ "tmp",
103
+ "temp",
104
+ ".tmp",
105
+ ".temp",
106
+ // Lock files
107
+ "package-lock.json",
108
+ "yarn.lock",
109
+ "pnpm-lock.yaml",
110
+ "bun.lockb",
111
+ "Cargo.lock",
112
+ "Gemfile.lock",
113
+ "poetry.lock",
114
+ // Binary/minified
115
+ "*.min.js",
116
+ "*.min.css",
117
+ "*.bundle.js",
118
+ "*.wasm",
119
+ "*.so",
120
+ "*.dll",
121
+ "*.pyc",
122
+ "*.map",
123
+ "*.js.map",
124
+ // Hidden directories catch-all
125
+ ".*"
126
+ ];
127
+ var DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || "").split(",").map((s) => s.trim()).filter(Boolean).concat(BUILTIN_EXCLUDES);
45
128
  var DEFAULT_MODEL = "morph-warp-grep";
46
129
 
47
130
  // tools/warp_grep/agent/prompt.ts
48
- var SYSTEM_PROMPT = `You are a code search agent. Your task is to find relevant code snippets based on a search query.
131
+ var SYSTEM_PROMPT = `You are a code search agent. Your task is to find all relevant code for a given query.
49
132
 
50
133
  <workflow>
51
- You operate in exactly 3 rounds of tool exploration, followed by a final answer:
134
+ You have exactly 4 turns. The 4th turn MUST be a \`finish\` call. Each turn allows up to 8 parallel tool calls.
52
135
 
53
- 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.
54
- 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.
55
- </workflow>
136
+ - Turn 1: Map the territory OR dive deep (based on query specificity)
137
+ - Turn 2-3: Refine based on findings
138
+ - Turn 4: MUST call \`finish\` with all relevant code locations
139
+ - You MAY call \`finish\` early if confident\u2014but never before at least 1 search turn.
56
140
 
57
- <tool_calling>
58
- You have tools at your disposal to solve the coding task. Follow these rules regarding tool calls:
141
+ Remember, if the task feels easy to you, it is strongly desirable to call \`finish\` early using fewer turns, but quality over speed.
142
+ </workflow>
59
143
 
60
- ### 1. \`analyse\` - Explore Directories
61
- Explore directory structure in a tree-like format.
62
- **Syntax:** \`analyse <path> [pattern]\`
63
- - \`<path>\`: Directory path to analyze (defaults to \`.\`)
64
- - \`[pattern]\`: Optional regex pattern to filter names
144
+ <tools>
145
+ ### \`analyse <path> [pattern]\`
146
+ Directory tree or file search. Shows structure of a path, optionally filtered by regex pattern.
147
+ - \`path\`: Required. Directory or file path (use \`.\` for repo root)
148
+ - \`pattern\`: Optional regex to filter results
65
149
 
66
- For example:
150
+ Examples:
67
151
  \`\`\`
152
+ analyse .
68
153
  analyse src/api
69
- analyse . "test"
154
+ analyse . ".*\\.ts$"
155
+ analyse src "test.*"
70
156
  \`\`\`
71
157
 
72
- ### 2. \`read\` - Read File Contents
73
- Read entire files or specific line ranges.
74
- **Syntax:** \`read <path>[:start-end]\`
75
- - \`<path>\`: File path to read
76
- - \`[:start-end]\`: Optional 1-based, inclusive line range
158
+ ### \`read <path>[:start-end]\`
159
+ Read file contents. Line range is 1-based, inclusive.
160
+ - Returns numbered lines for easy reference
161
+ - Omit range to read entire file
77
162
 
78
- For example:
163
+ Examples:
79
164
  \`\`\`
80
165
  read src/main.py
81
- read src/database/connection.py:10-50
166
+ read src/db/conn.py:10-50
167
+ read package.json:1-20
82
168
  \`\`\`
83
169
 
84
- ### 3. \`grep\` - Search with Regex
85
- Search for regex patterns across files using ripgrep.
86
- **Syntax:** \`grep '<pattern>' <path>\`
87
- - \`'<pattern>'\`: Regex pattern (always wrap in single quotes)
88
- - \`<path>\`: Directory or file to search (use \`.\` for the repo root)
170
+ ### \`grep '<pattern>' <path>\`
171
+ Ripgrep search. Finds pattern matches across files.
172
+ - \`'<pattern>'\`: Required. Regex pattern wrapped in single quotes
173
+ - \`<path>\`: Required. Directory or file to search (use \`.\` for repo root)
89
174
 
90
- For example:
175
+ Examples:
91
176
  \`\`\`
92
- grep 'create_user' .
93
- grep 'import.*requests' src/api
94
- grep 'class\\\\s+AuthService' controllers/auth.py
177
+ grep 'class.*Service' src/
178
+ grep 'def authenticate' .
179
+ grep 'import.*from' src/components/
180
+ grep 'TODO' .
95
181
  \`\`\`
96
182
 
97
- ### 4. \`finish\` - Submit Final Answer
98
- Submit your findings when complete.
99
- **Syntax:** \`finish <file1:range1,range2...> [file2:range3...]\`
100
- - Provide file paths with colon-separated, comma-separated line ranges
183
+ ### \`finish <file1:ranges> [file2:ranges ...]\`
184
+ Submit final answer with all relevant code locations.
185
+ - Include generous line ranges\u2014don't be stingy with context
186
+ - Ranges are comma-separated: \`file.py:10-30,50-60\`
187
+ - ALWAYS include import statements at the top of files (usually lines 1-20)
188
+ - If code spans multiple files, include ALL of them
189
+ - Small files can be returned in full
101
190
 
102
- For example:
191
+ Examples:
103
192
  \`\`\`
104
- finish src/api/auth.py:25-50,75-80 src/models/user.py:10-15
193
+ finish src/auth.py:1-15,25-50,75-80 src/models/user.py:1-10,20-45
194
+ finish src/index.ts:1-100
105
195
  \`\`\`
106
- </tool_calling>
196
+ </tools>
107
197
 
108
198
  <strategy>
109
- - Use the \`analyse\`, \`grep\`, and \`read\` tools to gather information about the codebase.
110
- - Leverage the tools smartly to make full use of their potential
111
- - Make parallel tool calls within each round to investigate multiple paths or files efficiently
112
- - Be systematic and thorough within your 3-round limit
199
+ **Before your first tool call, classify the query:**
200
+
201
+ | Query Type | Turn 1 Strategy | Early Finish? |
202
+ |------------|-----------------|---------------|
203
+ | **Specific** (function name, error string, unique identifier) | 8 parallel greps on likely paths | Often by turn 2 |
204
+ | **Conceptual** (how does X work, where is Y handled) | analyse + 2-3 broad greps | Rarely early |
205
+ | **Exploratory** (find all tests, list API endpoints) | analyse at multiple depths | Usually needs 3 turns |
206
+
207
+ **Parallel call patterns:**
208
+ - **Shotgun grep**: Same pattern, 8 different directories\u2014fast coverage
209
+ - **Variant grep**: 8 pattern variations (synonyms, naming conventions)\u2014catches inconsistent codebases
210
+ - **Funnel**: 1 analyse + 7 greps\u2014orient and search simultaneously
211
+ - **Deep read**: 8 reads on files you already identified\u2014gather full context fast
113
212
  </strategy>
114
213
 
115
214
  <output_format>
116
- - Only output tool calls themselves
117
- - Do not include explanatory text, reasoning, or commentary
118
- - Each tool call should be on its own line
119
- - After 3 rounds of exploration, call \`finish\` with all relevant code snippets you found
215
+ EVERY response MUST follow this exact format:
216
+
217
+ 1. First, wrap your reasoning in \`<think>...</think>\` tags containing:
218
+ - Query classification (specific/conceptual/exploratory)
219
+ - Confidence estimate (can I finish in 1-2 turns?)
220
+ - This turn's parallel strategy
221
+ - What signals would let me finish early?
222
+
223
+ 2. Then, output tool calls wrapped in \`<tool_call>...</tool_call>\` tags, one per line.
224
+
225
+ Example:
226
+ \`\`\`
227
+ <think>
228
+ This is a specific query about authentication. I'll grep for auth-related patterns.
229
+ High confidence I can finish in 2 turns if I find the auth module.
230
+ Strategy: Shotgun grep across likely directories.
231
+ </think>
232
+ <tool_call>grep 'authenticate' src/</tool_call>
233
+ <tool_call>grep 'login' src/</tool_call>
234
+ <tool_call>analyse src/auth</tool_call>
235
+ \`\`\`
236
+
237
+ No commentary outside \`<think>\`. No explanations after tool calls.
120
238
  </output_format>
121
239
 
240
+ <finishing_requirements>
241
+ When calling \`finish\`:
242
+ - Include the import section (typically lines 1-20) of each file
243
+ - Include all function/class definitions that are relevant
244
+ - Include any type definitions, interfaces, or constants used
245
+ - Better to over-include than leave the user missing context
246
+ - If unsure about boundaries, include more rather than less
247
+ </finishing_requirements>
248
+
122
249
  Begin your exploration now to find code relevant to the query.`;
123
250
  function getSystemPrompt() {
124
251
  return SYSTEM_PROMPT;
@@ -131,13 +258,54 @@ var LLMResponseParseError = class extends Error {
131
258
  this.name = "LLMResponseParseError";
132
259
  }
133
260
  };
261
+ var VALID_COMMANDS = ["analyse", "grep", "read", "finish"];
262
+ function preprocessText(text) {
263
+ let processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
264
+ const openingTagRegex = /<tool_call>|<tool>/gi;
265
+ const closingTagRegex = /<\/tool_call>|<\/tool>/gi;
266
+ const openingMatches = processed.match(openingTagRegex) || [];
267
+ const closingMatches = processed.match(closingTagRegex) || [];
268
+ if (openingMatches.length > closingMatches.length) {
269
+ const lastClosingMatch = /<\/tool_call>|<\/tool>/gi;
270
+ let lastClosingIndex = -1;
271
+ let match;
272
+ while ((match = lastClosingMatch.exec(processed)) !== null) {
273
+ lastClosingIndex = match.index + match[0].length;
274
+ }
275
+ if (lastClosingIndex > 0) {
276
+ processed = processed.slice(0, lastClosingIndex);
277
+ }
278
+ }
279
+ const toolCallLines = [];
280
+ const toolTagRegex = /<tool_call>([\s\S]*?)<\/tool_call>|<tool>([\s\S]*?)<\/tool>/gi;
281
+ let tagMatch;
282
+ while ((tagMatch = toolTagRegex.exec(processed)) !== null) {
283
+ const content = (tagMatch[1] || tagMatch[2] || "").trim();
284
+ if (content) {
285
+ const lines = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l);
286
+ toolCallLines.push(...lines);
287
+ }
288
+ }
289
+ const allLines = processed.split(/\r?\n/).map((l) => l.trim());
290
+ for (const line of allLines) {
291
+ if (!line) continue;
292
+ if (line.startsWith("<")) continue;
293
+ const firstWord = line.split(/\s/)[0];
294
+ if (VALID_COMMANDS.includes(firstWord)) {
295
+ if (!toolCallLines.includes(line)) {
296
+ toolCallLines.push(line);
297
+ }
298
+ }
299
+ }
300
+ return toolCallLines;
301
+ }
134
302
  var LLMResponseParser = class {
135
303
  finishSpecSplitRe = /,(?=[^,\s]+:)/;
136
304
  parse(text) {
137
305
  if (typeof text !== "string") {
138
306
  throw new TypeError("Command text must be a string.");
139
307
  }
140
- const lines = text.split(/\r?\n/).map((l) => l.trim());
308
+ const lines = preprocessText(text);
141
309
  const commands = [];
142
310
  let finishAccumulator = null;
143
311
  lines.forEach((line, idx) => {
@@ -160,7 +328,7 @@ var LLMResponseParser = class {
160
328
  finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);
161
329
  break;
162
330
  default:
163
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unsupported command '${cmd}'`);
331
+ break;
164
332
  }
165
333
  });
166
334
  if (finishAccumulator) {
@@ -702,7 +870,23 @@ async function runWarpGrep(config) {
702
870
  }
703
871
  }
704
872
  if (formatted.length > 0) {
705
- messages.push({ role: "user", content: formatted.join("\n") });
873
+ const turnsUsed = round;
874
+ const turnsRemaining = 4 - turnsUsed;
875
+ let turnMessage;
876
+ if (turnsRemaining === 0) {
877
+ turnMessage = `
878
+
879
+ [Turn ${turnsUsed}/4] This is your LAST turn. You MUST call the finish tool now.`;
880
+ } else if (turnsRemaining === 1) {
881
+ turnMessage = `
882
+
883
+ [Turn ${turnsUsed}/4] You have 1 turn remaining. Next turn you MUST call the finish tool.`;
884
+ } else {
885
+ turnMessage = `
886
+
887
+ [Turn ${turnsUsed}/4] You have ${turnsRemaining} turns remaining.`;
888
+ }
889
+ messages.push({ role: "user", content: formatted.join("\n") + turnMessage });
706
890
  }
707
891
  if (finishCalls.length) {
708
892
  const fc = finishCalls[0];
@@ -930,49 +1114,93 @@ var LocalRipgrepProvider = class {
930
1114
  }
931
1115
  };
932
1116
 
1117
+ // tools/warp_grep/prompts.ts
1118
+ 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.";
1119
+
1120
+ // tools/warp_grep/core.ts
1121
+ function formatResult(result) {
1122
+ if (!result.success) {
1123
+ return `Search failed: ${result.error}`;
1124
+ }
1125
+ if (!result.contexts || result.contexts.length === 0) {
1126
+ return "No relevant code found. Try rephrasing your query.";
1127
+ }
1128
+ const lines = [];
1129
+ lines.push(`Found ${result.contexts.length} relevant code sections:
1130
+ `);
1131
+ result.contexts.forEach((ctx, i) => {
1132
+ lines.push(`${i + 1}. ${ctx.file}`);
1133
+ lines.push("```");
1134
+ lines.push(ctx.content);
1135
+ lines.push("```");
1136
+ lines.push("");
1137
+ });
1138
+ if (result.summary) {
1139
+ lines.push(`Summary: ${result.summary}`);
1140
+ }
1141
+ return lines.join("\n");
1142
+ }
1143
+
933
1144
  // tools/warp_grep/anthropic.ts
934
- var INPUT_SCHEMA = import_zod.z.object({
935
- query: import_zod.z.string().describe("Free-form repository question")
936
- });
1145
+ var INPUT_SCHEMA = {
1146
+ type: "object",
1147
+ properties: {
1148
+ query: { type: "string", description: "Free-form repository question" }
1149
+ },
1150
+ required: ["query"]
1151
+ };
1152
+ var warpGrepTool = {
1153
+ name: "morph-warp-grep",
1154
+ description: WARP_GREP_DESCRIPTION,
1155
+ input_schema: INPUT_SCHEMA
1156
+ };
1157
+ async function execute(input, config) {
1158
+ const parsed = typeof input === "string" ? JSON.parse(input) : input;
1159
+ const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
1160
+ const result = await runWarpGrep({
1161
+ query: parsed.query,
1162
+ repoRoot: config.repoRoot,
1163
+ provider,
1164
+ excludes: config.excludes,
1165
+ includes: config.includes,
1166
+ debug: config.debug ?? false,
1167
+ apiKey: config.apiKey
1168
+ });
1169
+ const finish = result.finish;
1170
+ if (result.terminationReason !== "completed" || !finish?.metadata) {
1171
+ return { success: false, error: "Search did not complete" };
1172
+ }
1173
+ const contexts = (finish.resolved ?? []).map((r) => ({
1174
+ file: r.path,
1175
+ content: r.content
1176
+ }));
1177
+ return { success: true, contexts, summary: finish.payload };
1178
+ }
937
1179
  function createMorphWarpGrepTool(config) {
938
1180
  const tool = {
939
1181
  name: "morph-warp-grep",
940
- 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.",
941
- input_schema: {
942
- type: "object",
943
- properties: {
944
- query: { type: "string", description: "Free-form repository question" }
945
- },
946
- required: ["query"]
947
- }
1182
+ description: config.description ?? WARP_GREP_DESCRIPTION,
1183
+ input_schema: INPUT_SCHEMA
948
1184
  };
949
1185
  return Object.assign(tool, {
950
1186
  execute: async (input) => {
951
- const parsed = INPUT_SCHEMA.parse(typeof input === "string" ? JSON.parse(input) : input);
952
- const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
953
- const result = await runWarpGrep({
954
- query: parsed.query,
955
- repoRoot: config.repoRoot,
956
- provider,
957
- excludes: config.excludes,
958
- includes: config.includes,
959
- debug: config.debug ?? false,
960
- apiKey: config.apiKey
961
- });
962
- const finish = result.finish;
963
- if (result.terminationReason !== "completed" || !finish?.metadata) {
964
- return { success: false, error: "Search did not complete", messages: result.messages };
965
- }
966
- const contexts = (finish.resolved ?? []).map((r) => ({
967
- file: r.path,
968
- content: r.content
969
- }));
970
- return { success: true, contexts, summary: finish.payload };
1187
+ return execute(input, config);
1188
+ },
1189
+ formatResult: (result) => {
1190
+ return formatResult(result);
1191
+ },
1192
+ getSystemPrompt: () => {
1193
+ return getSystemPrompt();
971
1194
  }
972
1195
  });
973
1196
  }
1197
+ var anthropic_default = warpGrepTool;
974
1198
  // Annotate the CommonJS export names for ESM import in node:
975
1199
  0 && (module.exports = {
976
- createMorphWarpGrepTool
1200
+ createMorphWarpGrepTool,
1201
+ execute,
1202
+ formatResult,
1203
+ getSystemPrompt,
1204
+ warpGrepTool
977
1205
  });
978
1206
  //# sourceMappingURL=anthropic.cjs.map