@morphllm/morphsdk 0.2.20 → 0.2.22

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 (164) hide show
  1. package/dist/chunk-73RQWOQC.js +16 -0
  2. package/dist/chunk-73RQWOQC.js.map +1 -0
  3. package/dist/chunk-AFEPUNAO.js +15 -0
  4. package/dist/chunk-AFEPUNAO.js.map +1 -0
  5. package/dist/chunk-EAA7D24N.js +201 -0
  6. package/dist/chunk-EAA7D24N.js.map +1 -0
  7. package/dist/chunk-EK7OQPWD.js +44 -0
  8. package/dist/chunk-EK7OQPWD.js.map +1 -0
  9. package/dist/chunk-FSVBNZMU.js +44 -0
  10. package/dist/chunk-FSVBNZMU.js.map +1 -0
  11. package/dist/chunk-G2RSY56Q.js +11 -0
  12. package/dist/chunk-G2RSY56Q.js.map +1 -0
  13. package/dist/chunk-GTOXMAF2.js +140 -0
  14. package/dist/chunk-GTOXMAF2.js.map +1 -0
  15. package/dist/chunk-HKZB23U7.js +85 -0
  16. package/dist/chunk-HKZB23U7.js.map +1 -0
  17. package/dist/chunk-JZGU5UC6.js +53 -0
  18. package/dist/chunk-JZGU5UC6.js.map +1 -0
  19. package/dist/chunk-NDZO5IPV.js +121 -0
  20. package/dist/chunk-NDZO5IPV.js.map +1 -0
  21. package/dist/{chunk-XUL4CHWU.js → chunk-NSQGPBMU.js} +4 -4
  22. package/dist/chunk-RSLIOCOE.js +26 -0
  23. package/dist/chunk-RSLIOCOE.js.map +1 -0
  24. package/dist/chunk-SMGZ6A64.js +53 -0
  25. package/dist/chunk-SMGZ6A64.js.map +1 -0
  26. package/dist/chunk-TICMYDII.js +81 -0
  27. package/dist/chunk-TICMYDII.js.map +1 -0
  28. package/dist/chunk-UYBIKZPM.js +135 -0
  29. package/dist/chunk-UYBIKZPM.js.map +1 -0
  30. package/dist/chunk-VBBJGWHY.js +73 -0
  31. package/dist/chunk-VBBJGWHY.js.map +1 -0
  32. package/dist/chunk-XQLKK2ZH.js +56 -0
  33. package/dist/chunk-XQLKK2ZH.js.map +1 -0
  34. package/dist/chunk-XYPMN4A3.js +1 -0
  35. package/dist/chunk-XYPMN4A3.js.map +1 -0
  36. package/dist/chunk-Z2FBMSNE.js +10 -0
  37. package/dist/chunk-Z2FBMSNE.js.map +1 -0
  38. package/dist/client.js +3 -3
  39. package/dist/index.js +5 -5
  40. package/dist/tools/warp_grep/agent/config.cjs +41 -0
  41. package/dist/tools/warp_grep/agent/config.cjs.map +1 -0
  42. package/dist/tools/warp_grep/agent/config.js +12 -0
  43. package/dist/tools/warp_grep/agent/config.js.map +1 -0
  44. package/dist/tools/warp_grep/agent/formatter.cjs +106 -0
  45. package/dist/tools/warp_grep/agent/formatter.cjs.map +1 -0
  46. package/dist/tools/warp_grep/agent/formatter.js +10 -0
  47. package/dist/tools/warp_grep/agent/formatter.js.map +1 -0
  48. package/dist/tools/warp_grep/agent/grep_helpers.cjs +148 -0
  49. package/dist/tools/warp_grep/agent/grep_helpers.cjs.map +1 -0
  50. package/dist/tools/warp_grep/agent/grep_helpers.js +14 -0
  51. package/dist/tools/warp_grep/agent/grep_helpers.js.map +1 -0
  52. package/dist/tools/warp_grep/agent/parser.cjs +165 -0
  53. package/dist/tools/warp_grep/agent/parser.cjs.map +1 -0
  54. package/dist/tools/warp_grep/agent/parser.js +10 -0
  55. package/dist/tools/warp_grep/agent/parser.js.map +1 -0
  56. package/dist/tools/warp_grep/agent/prompt.cjs +110 -0
  57. package/dist/tools/warp_grep/agent/prompt.cjs.map +1 -0
  58. package/dist/tools/warp_grep/agent/prompt.js +10 -0
  59. package/dist/tools/warp_grep/agent/prompt.js.map +1 -0
  60. package/dist/tools/warp_grep/agent/runner.cjs +744 -0
  61. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -0
  62. package/dist/tools/warp_grep/agent/runner.js +17 -0
  63. package/dist/tools/warp_grep/agent/runner.js.map +1 -0
  64. package/dist/tools/warp_grep/agent/types.cjs +19 -0
  65. package/dist/tools/warp_grep/agent/types.cjs.map +1 -0
  66. package/dist/tools/warp_grep/agent/types.js +2 -0
  67. package/dist/tools/warp_grep/agent/types.js.map +1 -0
  68. package/dist/tools/warp_grep/anthropic.cjs +977 -0
  69. package/dist/tools/warp_grep/anthropic.cjs.map +1 -0
  70. package/dist/tools/warp_grep/anthropic.js +22 -0
  71. package/dist/tools/warp_grep/anthropic.js.map +1 -0
  72. package/dist/tools/warp_grep/index.cjs +1136 -0
  73. package/dist/tools/warp_grep/index.cjs.map +1 -0
  74. package/dist/tools/warp_grep/index.js +48 -0
  75. package/dist/tools/warp_grep/index.js.map +1 -0
  76. package/dist/tools/warp_grep/openai.cjs +980 -0
  77. package/dist/tools/warp_grep/openai.cjs.map +1 -0
  78. package/dist/tools/warp_grep/openai.js +22 -0
  79. package/dist/tools/warp_grep/openai.js.map +1 -0
  80. package/dist/tools/warp_grep/providers/command.cjs +98 -0
  81. package/dist/tools/warp_grep/providers/command.cjs.map +1 -0
  82. package/dist/tools/warp_grep/providers/command.js +9 -0
  83. package/dist/tools/warp_grep/providers/command.js.map +1 -0
  84. package/dist/tools/warp_grep/providers/local.cjs +232 -0
  85. package/dist/tools/warp_grep/providers/local.cjs.map +1 -0
  86. package/dist/tools/warp_grep/providers/local.js +12 -0
  87. package/dist/tools/warp_grep/providers/local.js.map +1 -0
  88. package/dist/tools/warp_grep/providers/types.cjs +19 -0
  89. package/dist/tools/warp_grep/providers/types.cjs.map +1 -0
  90. package/dist/tools/warp_grep/providers/types.js +1 -0
  91. package/dist/tools/warp_grep/providers/types.js.map +1 -0
  92. package/dist/tools/warp_grep/tools/analyse.cjs +40 -0
  93. package/dist/tools/warp_grep/tools/analyse.cjs.map +1 -0
  94. package/dist/tools/warp_grep/tools/analyse.js +8 -0
  95. package/dist/tools/warp_grep/tools/analyse.js.map +1 -0
  96. package/dist/tools/warp_grep/tools/finish.cjs +69 -0
  97. package/dist/tools/warp_grep/tools/finish.cjs.map +1 -0
  98. package/dist/tools/warp_grep/tools/finish.js +10 -0
  99. package/dist/tools/warp_grep/tools/finish.js.map +1 -0
  100. package/dist/tools/warp_grep/tools/grep.cjs +35 -0
  101. package/dist/tools/warp_grep/tools/grep.cjs.map +1 -0
  102. package/dist/tools/warp_grep/tools/grep.js +12 -0
  103. package/dist/tools/warp_grep/tools/grep.js.map +1 -0
  104. package/dist/tools/warp_grep/tools/read.cjs +34 -0
  105. package/dist/tools/warp_grep/tools/read.cjs.map +1 -0
  106. package/dist/tools/warp_grep/tools/read.js +8 -0
  107. package/dist/tools/warp_grep/tools/read.js.map +1 -0
  108. package/dist/tools/warp_grep/utils/files.cjs +45 -0
  109. package/dist/tools/warp_grep/utils/files.cjs.map +1 -0
  110. package/dist/tools/warp_grep/utils/files.js +8 -0
  111. package/dist/tools/warp_grep/utils/files.js.map +1 -0
  112. package/dist/tools/warp_grep/utils/format.cjs +42 -0
  113. package/dist/tools/warp_grep/utils/format.cjs.map +1 -0
  114. package/dist/tools/warp_grep/utils/format.js +18 -0
  115. package/dist/tools/warp_grep/utils/format.js.map +1 -0
  116. package/dist/tools/warp_grep/utils/paths.cjs +91 -0
  117. package/dist/tools/warp_grep/utils/paths.cjs.map +1 -0
  118. package/dist/tools/warp_grep/utils/paths.js +16 -0
  119. package/dist/tools/warp_grep/utils/paths.js.map +1 -0
  120. package/dist/tools/warp_grep/utils/ripgrep.cjs +50 -0
  121. package/dist/tools/warp_grep/utils/ripgrep.cjs.map +1 -0
  122. package/dist/tools/warp_grep/utils/ripgrep.js +8 -0
  123. package/dist/tools/warp_grep/utils/ripgrep.js.map +1 -0
  124. package/dist/tools/warp_grep/vercel.cjs +968 -0
  125. package/dist/tools/warp_grep/vercel.cjs.map +1 -0
  126. package/dist/tools/warp_grep/vercel.js +22 -0
  127. package/dist/tools/warp_grep/vercel.js.map +1 -0
  128. package/package.json +23 -3
  129. package/dist/anthropic-CknfcMoO.d.ts +0 -64
  130. package/dist/client.d.ts +0 -114
  131. package/dist/git/client.d.ts +0 -230
  132. package/dist/git/config.d.ts +0 -11
  133. package/dist/git/index.d.ts +0 -5
  134. package/dist/git/types.d.ts +0 -91
  135. package/dist/index.d.ts +0 -14
  136. package/dist/modelrouter/core.d.ts +0 -56
  137. package/dist/modelrouter/index.d.ts +0 -2
  138. package/dist/modelrouter/types.d.ts +0 -35
  139. package/dist/openai-BkKsS30n.d.ts +0 -111
  140. package/dist/tools/browser/anthropic.d.ts +0 -51
  141. package/dist/tools/browser/core.d.ts +0 -196
  142. package/dist/tools/browser/index.d.ts +0 -72
  143. package/dist/tools/browser/openai.d.ts +0 -69
  144. package/dist/tools/browser/prompts.d.ts +0 -7
  145. package/dist/tools/browser/types.d.ts +0 -227
  146. package/dist/tools/browser/vercel.d.ts +0 -69
  147. package/dist/tools/codebase_search/anthropic.d.ts +0 -40
  148. package/dist/tools/codebase_search/core.d.ts +0 -40
  149. package/dist/tools/codebase_search/index.d.ts +0 -10
  150. package/dist/tools/codebase_search/openai.d.ts +0 -87
  151. package/dist/tools/codebase_search/prompts.d.ts +0 -7
  152. package/dist/tools/codebase_search/types.d.ts +0 -46
  153. package/dist/tools/codebase_search/vercel.d.ts +0 -65
  154. package/dist/tools/fastapply/anthropic.d.ts +0 -4
  155. package/dist/tools/fastapply/core.d.ts +0 -41
  156. package/dist/tools/fastapply/index.d.ts +0 -10
  157. package/dist/tools/fastapply/openai.d.ts +0 -4
  158. package/dist/tools/fastapply/prompts.d.ts +0 -7
  159. package/dist/tools/fastapply/types.d.ts +0 -77
  160. package/dist/tools/fastapply/vercel.d.ts +0 -4
  161. package/dist/tools/index.d.ts +0 -10
  162. package/dist/tools/utils/resilience.d.ts +0 -58
  163. package/dist/vercel-B1GZ_g9N.d.ts +0 -69
  164. /package/dist/{chunk-XUL4CHWU.js.map → chunk-NSQGPBMU.js.map} +0 -0
@@ -0,0 +1,744 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // tools/warp_grep/agent/runner.ts
31
+ var runner_exports = {};
32
+ __export(runner_exports, {
33
+ runWarpGrep: () => runWarpGrep
34
+ });
35
+ module.exports = __toCommonJS(runner_exports);
36
+
37
+ // tools/warp_grep/agent/config.ts
38
+ var AGENT_CONFIG = {
39
+ // Give the model freedom; failsafe cap to prevent infinite loops
40
+ MAX_ROUNDS: 10,
41
+ TIMEOUT_MS: 3e4
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"]);
44
+ var DEFAULT_MODEL = "morph-warp-grep";
45
+
46
+ // 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.
48
+
49
+ <workflow>
50
+ You operate in exactly 3 rounds of tool exploration, followed by a final answer:
51
+
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>
55
+
56
+ <tool_calling>
57
+ You have tools at your disposal to solve the coding task. Follow these rules regarding tool calls:
58
+
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
64
+
65
+ For example:
66
+ \`\`\`
67
+ analyse src/api
68
+ analyse . "test"
69
+ \`\`\`
70
+
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
76
+
77
+ For example:
78
+ \`\`\`
79
+ read src/main.py
80
+ read src/database/connection.py:10-50
81
+ \`\`\`
82
+
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)
88
+
89
+ For example:
90
+ \`\`\`
91
+ grep 'create_user' .
92
+ grep 'import.*requests' src/api
93
+ grep 'class\\\\s+AuthService' controllers/auth.py
94
+ \`\`\`
95
+
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
100
+
101
+ For example:
102
+ \`\`\`
103
+ finish src/api/auth.py:25-50,75-80 src/models/user.py:10-15
104
+ \`\`\`
105
+ </tool_calling>
106
+
107
+ <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
112
+ </strategy>
113
+
114
+ <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
119
+ </output_format>
120
+
121
+ Begin your exploration now to find code relevant to the query.`;
122
+ function getSystemPrompt() {
123
+ return SYSTEM_PROMPT;
124
+ }
125
+
126
+ // tools/warp_grep/agent/parser.ts
127
+ var LLMResponseParseError = class extends Error {
128
+ constructor(message) {
129
+ super(message);
130
+ this.name = "LLMResponseParseError";
131
+ }
132
+ };
133
+ var LLMResponseParser = class {
134
+ finishSpecSplitRe = /,(?=[^,\s]+:)/;
135
+ parse(text) {
136
+ if (typeof text !== "string") {
137
+ throw new TypeError("Command text must be a string.");
138
+ }
139
+ const lines = text.split(/\r?\n/).map((l) => l.trim());
140
+ const commands = [];
141
+ let finishAccumulator = null;
142
+ lines.forEach((line, idx) => {
143
+ if (!line || line.startsWith("#")) return;
144
+ const ctx = { lineNumber: idx + 1, raw: line };
145
+ const parts = this.splitLine(line, ctx);
146
+ if (parts.length === 0) return;
147
+ const cmd = parts[0];
148
+ switch (cmd) {
149
+ case "analyse":
150
+ this.handleAnalyse(parts, ctx, commands);
151
+ break;
152
+ case "grep":
153
+ this.handleGrep(parts, ctx, commands);
154
+ break;
155
+ case "read":
156
+ this.handleRead(parts, ctx, commands);
157
+ break;
158
+ case "finish":
159
+ finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);
160
+ break;
161
+ default:
162
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unsupported command '${cmd}'`);
163
+ }
164
+ });
165
+ if (finishAccumulator) {
166
+ const map = finishAccumulator;
167
+ const entries = [...map.entries()];
168
+ const filesPayload = entries.map(([path2, ranges]) => ({
169
+ path: path2,
170
+ lines: [...ranges].sort((a, b) => a[0] - b[0])
171
+ }));
172
+ commands.push({ name: "finish", arguments: { files: filesPayload } });
173
+ }
174
+ return commands;
175
+ }
176
+ splitLine(line, ctx) {
177
+ try {
178
+ const parts = [];
179
+ let current = "";
180
+ let inSingle = false;
181
+ for (let i = 0; i < line.length; i++) {
182
+ const ch = line[i];
183
+ if (ch === "'" && line[i - 1] !== "\\") {
184
+ inSingle = !inSingle;
185
+ current += ch;
186
+ } else if (!inSingle && /\s/.test(ch)) {
187
+ if (current) {
188
+ parts.push(current);
189
+ current = "";
190
+ }
191
+ } else {
192
+ current += ch;
193
+ }
194
+ }
195
+ if (current) parts.push(current);
196
+ return parts;
197
+ } catch {
198
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);
199
+ }
200
+ }
201
+ handleAnalyse(parts, ctx, commands) {
202
+ if (parts.length < 2) {
203
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: analyse requires <path>`);
204
+ }
205
+ const path2 = parts[1];
206
+ const pattern = parts[2]?.replace(/^"|"$/g, "") ?? null;
207
+ commands.push({ name: "analyse", arguments: { path: path2, pattern } });
208
+ }
209
+ // no glob tool in MCP
210
+ handleGrep(parts, ctx, commands) {
211
+ if (parts.length < 3) {
212
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep requires '<pattern>' and <path>`);
213
+ }
214
+ const pat = parts[1];
215
+ if (!pat.startsWith("'") || !pat.endsWith("'")) {
216
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep pattern must be single-quoted`);
217
+ }
218
+ commands.push({ name: "grep", arguments: { pattern: pat.slice(1, -1), path: parts[2] } });
219
+ }
220
+ handleRead(parts, ctx, commands) {
221
+ if (parts.length < 2) {
222
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: read requires <path> or <path>:<start-end>`);
223
+ }
224
+ const spec = parts[1];
225
+ const rangeIdx = spec.indexOf(":");
226
+ if (rangeIdx === -1) {
227
+ commands.push({ name: "read", arguments: { path: spec } });
228
+ return;
229
+ }
230
+ const path2 = spec.slice(0, rangeIdx);
231
+ const range = spec.slice(rangeIdx + 1);
232
+ const [s, e] = range.split("-").map((v) => parseInt(v, 10));
233
+ if (!Number.isFinite(s) || !Number.isFinite(e)) {
234
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid read range '${range}'`);
235
+ }
236
+ commands.push({ name: "read", arguments: { path: path2, start: s, end: e } });
237
+ }
238
+ handleFinish(parts, ctx, acc) {
239
+ const map = acc ?? /* @__PURE__ */ new Map();
240
+ const args = parts.slice(1);
241
+ for (const token of args) {
242
+ const [path2, rangesText] = token.split(":", 2);
243
+ if (!path2 || !rangesText) {
244
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid finish token '${token}'`);
245
+ }
246
+ const rangeSpecs = rangesText.split(",").filter(Boolean);
247
+ for (const spec of rangeSpecs) {
248
+ const [s, e] = spec.split("-").map((v) => parseInt(v, 10));
249
+ if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {
250
+ throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid range '${spec}'`);
251
+ }
252
+ const arr = map.get(path2) ?? [];
253
+ arr.push([s, e]);
254
+ map.set(path2, arr);
255
+ }
256
+ }
257
+ return map;
258
+ }
259
+ };
260
+
261
+ // tools/warp_grep/tools/read.ts
262
+ async function toolRead(provider, args) {
263
+ const res = await provider.read({ path: args.path, start: args.start, end: args.end });
264
+ return res.lines.join("\n");
265
+ }
266
+
267
+ // tools/warp_grep/tools/analyse.ts
268
+ async function toolAnalyse(provider, args) {
269
+ const list = await provider.analyse({
270
+ path: args.path,
271
+ pattern: args.pattern ?? null,
272
+ maxResults: args.maxResults ?? 100,
273
+ maxDepth: args.maxDepth ?? 2
274
+ });
275
+ if (!list.length) return "empty";
276
+ return list.map((e) => `${" ".repeat(e.depth)}- ${e.type === "dir" ? "[D]" : "[F]"} ${e.name}`).join("\n");
277
+ }
278
+
279
+ // tools/utils/resilience.ts
280
+ var DEFAULT_RETRY_CONFIG = {
281
+ maxRetries: 3,
282
+ initialDelay: 1e3,
283
+ maxDelay: 3e4,
284
+ backoffMultiplier: 2,
285
+ retryableErrors: ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"]
286
+ };
287
+ async function fetchWithRetry(url, options, retryConfig = {}) {
288
+ const {
289
+ maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,
290
+ initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,
291
+ maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,
292
+ backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,
293
+ retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,
294
+ onRetry
295
+ } = retryConfig;
296
+ let lastError = null;
297
+ let delay = initialDelay;
298
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
299
+ try {
300
+ const response = await fetch(url, options);
301
+ if (response.status === 429 || response.status === 503) {
302
+ if (attempt < maxRetries) {
303
+ const retryAfter = response.headers.get("Retry-After");
304
+ const waitTime = retryAfter ? parseInt(retryAfter) * 1e3 : Math.min(delay, maxDelay);
305
+ const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);
306
+ if (onRetry) {
307
+ onRetry(attempt + 1, error);
308
+ }
309
+ await sleep(waitTime);
310
+ delay *= backoffMultiplier;
311
+ continue;
312
+ }
313
+ }
314
+ return response;
315
+ } catch (error) {
316
+ lastError = error;
317
+ const isRetryable = retryableErrors.some(
318
+ (errType) => lastError?.message?.includes(errType)
319
+ );
320
+ if (!isRetryable || attempt === maxRetries) {
321
+ throw lastError;
322
+ }
323
+ const waitTime = Math.min(delay, maxDelay);
324
+ if (onRetry) {
325
+ onRetry(attempt + 1, lastError);
326
+ }
327
+ await sleep(waitTime);
328
+ delay *= backoffMultiplier;
329
+ }
330
+ }
331
+ throw lastError || new Error("Max retries exceeded");
332
+ }
333
+ async function withTimeout(promise, timeoutMs, errorMessage) {
334
+ let timeoutId;
335
+ const timeoutPromise = new Promise((_, reject) => {
336
+ timeoutId = setTimeout(() => {
337
+ reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));
338
+ }, timeoutMs);
339
+ });
340
+ try {
341
+ const result = await Promise.race([promise, timeoutPromise]);
342
+ clearTimeout(timeoutId);
343
+ return result;
344
+ } catch (error) {
345
+ clearTimeout(timeoutId);
346
+ throw error;
347
+ }
348
+ }
349
+ function sleep(ms) {
350
+ return new Promise((resolve) => setTimeout(resolve, ms));
351
+ }
352
+
353
+ // tools/warp_grep/agent/formatter.ts
354
+ var ToolOutputFormatter = class {
355
+ format(toolName, args, output, options = {}) {
356
+ const name = (toolName ?? "").trim();
357
+ if (!name) {
358
+ return "";
359
+ }
360
+ const payload = output?.toString?.()?.trim?.() ?? "";
361
+ const isError = Boolean(options.isError);
362
+ const safeArgs = args ?? {};
363
+ if (!payload && !isError) {
364
+ return "";
365
+ }
366
+ switch (name) {
367
+ case "read":
368
+ return this.formatRead(safeArgs, payload, isError);
369
+ case "analyse":
370
+ return this.formatAnalyse(safeArgs, payload, isError);
371
+ case "grep":
372
+ return this.formatGrep(safeArgs, payload, isError);
373
+ default:
374
+ return payload ? `<tool_output>
375
+ ${payload}
376
+ </tool_output>` : "";
377
+ }
378
+ }
379
+ formatRead(args, payload, isError) {
380
+ if (isError) {
381
+ return payload;
382
+ }
383
+ const path2 = this.asString(args.path) || "...";
384
+ return `<file path="${path2}">
385
+ ${payload}
386
+ </file>`;
387
+ }
388
+ formatAnalyse(args, payload, isError) {
389
+ const path2 = this.asString(args.path) || ".";
390
+ if (isError) {
391
+ return `<analyse_results path="${path2}" status="error">
392
+ ${payload}
393
+ </analyse_results>`;
394
+ }
395
+ return `<analyse_results path="${path2}">
396
+ ${payload}
397
+ </analyse_results>`;
398
+ }
399
+ formatGrep(args, payload, isError) {
400
+ const pattern = this.asString(args.pattern);
401
+ const path2 = this.asString(args.path);
402
+ const attributes = [];
403
+ if (pattern !== void 0) {
404
+ attributes.push(`pattern="${pattern}"`);
405
+ }
406
+ if (path2 !== void 0) {
407
+ attributes.push(`path="${path2}"`);
408
+ }
409
+ if (isError) {
410
+ attributes.push('status="error"');
411
+ }
412
+ const attrText = attributes.length ? ` ${attributes.join(" ")}` : "";
413
+ return `<grep_output${attrText}>
414
+ ${payload}
415
+ </grep_output>`;
416
+ }
417
+ asString(value) {
418
+ if (value === null || value === void 0) {
419
+ return void 0;
420
+ }
421
+ return String(value);
422
+ }
423
+ };
424
+ var sharedFormatter = new ToolOutputFormatter();
425
+ function formatAgentToolOutput(toolName, args, output, options = {}) {
426
+ return sharedFormatter.format(toolName, args, output, options);
427
+ }
428
+
429
+ // tools/warp_grep/agent/grep_helpers.ts
430
+ var GrepState = class {
431
+ seenLines = /* @__PURE__ */ new Set();
432
+ isNew(path2, lineNumber) {
433
+ const key = this.makeKey(path2, lineNumber);
434
+ return !this.seenLines.has(key);
435
+ }
436
+ add(path2, lineNumber) {
437
+ this.seenLines.add(this.makeKey(path2, lineNumber));
438
+ }
439
+ makeKey(path2, lineNumber) {
440
+ return `${path2}:${lineNumber}`;
441
+ }
442
+ };
443
+ var MAX_GREP_OUTPUT_CHARS_PER_TURN = 6e4;
444
+ function extractMatchFields(payload) {
445
+ const text = payload.replace(/\r?\n$/, "");
446
+ if (!text || text.startsWith("[error]")) {
447
+ return null;
448
+ }
449
+ const firstSep = text.indexOf(":");
450
+ if (firstSep === -1) {
451
+ return null;
452
+ }
453
+ let filePath = text.slice(0, firstSep).trim();
454
+ if (!filePath) {
455
+ return null;
456
+ }
457
+ if (filePath.startsWith("./") || filePath.startsWith(".\\")) {
458
+ filePath = filePath.slice(2);
459
+ }
460
+ const remainder = text.slice(firstSep + 1);
461
+ const secondSep = remainder.indexOf(":");
462
+ if (secondSep === -1) {
463
+ return null;
464
+ }
465
+ const linePart = remainder.slice(0, secondSep);
466
+ const lineNumber = Number.parseInt(linePart, 10);
467
+ if (!Number.isInteger(lineNumber) || lineNumber <= 0) {
468
+ return null;
469
+ }
470
+ let contentSegment = remainder.slice(secondSep + 1);
471
+ const columnSep = contentSegment.indexOf(":");
472
+ if (columnSep !== -1 && /^\d+$/.test(contentSegment.slice(0, columnSep))) {
473
+ contentSegment = contentSegment.slice(columnSep + 1);
474
+ }
475
+ const content = contentSegment.trim();
476
+ if (!content) {
477
+ return null;
478
+ }
479
+ return { path: filePath, lineNumber, content };
480
+ }
481
+ function parseAndFilterGrepOutput(rawOutput, state) {
482
+ const matches = [];
483
+ if (typeof rawOutput !== "string" || !rawOutput.trim()) {
484
+ return matches;
485
+ }
486
+ for (const line of rawOutput.split(/\r?\n/)) {
487
+ const fields = extractMatchFields(line);
488
+ if (!fields) {
489
+ continue;
490
+ }
491
+ if (state.isNew(fields.path, fields.lineNumber)) {
492
+ matches.push(fields);
493
+ state.add(fields.path, fields.lineNumber);
494
+ }
495
+ }
496
+ return matches;
497
+ }
498
+ function truncateOutput(payload, maxChars) {
499
+ if (payload.length <= maxChars) {
500
+ return payload;
501
+ }
502
+ const note = "... (output truncated)";
503
+ const available = maxChars - note.length - 1;
504
+ if (available <= 0) {
505
+ return note;
506
+ }
507
+ if (payload.length <= available) {
508
+ return `${payload.slice(0, available).replace(/\n$/, "")}
509
+ ${note}`;
510
+ }
511
+ const core = payload.slice(0, Math.max(0, available - 1));
512
+ const trimmed = core.replace(/\n$/, "").replace(/\s+$/, "");
513
+ const snippet = trimmed ? `${trimmed}\u2026` : "\u2026";
514
+ return `${snippet}
515
+ ${note}`;
516
+ }
517
+ function formatTurnGrepOutput(matches, maxChars = MAX_GREP_OUTPUT_CHARS_PER_TURN) {
518
+ if (!matches || matches.length === 0) {
519
+ return "No new matches found.";
520
+ }
521
+ const matchesByFile = /* @__PURE__ */ new Map();
522
+ for (const match of matches) {
523
+ if (!matchesByFile.has(match.path)) {
524
+ matchesByFile.set(match.path, []);
525
+ }
526
+ matchesByFile.get(match.path).push(match);
527
+ }
528
+ const lines = [];
529
+ const sortedPaths = Array.from(matchesByFile.keys()).sort();
530
+ sortedPaths.forEach((filePath, index) => {
531
+ if (index > 0) {
532
+ lines.push("");
533
+ }
534
+ lines.push(filePath);
535
+ const sortedMatches = matchesByFile.get(filePath).slice().sort((a, b) => a.lineNumber - b.lineNumber);
536
+ for (const match of sortedMatches) {
537
+ lines.push(`${match.lineNumber}:${match.content}`);
538
+ }
539
+ });
540
+ return truncateOutput(lines.join("\n"), maxChars);
541
+ }
542
+
543
+ // tools/warp_grep/tools/finish.ts
544
+ async function readFinishFiles(repoRoot, files, reader) {
545
+ const out = [];
546
+ for (const f of files) {
547
+ const ranges = mergeRanges(f.lines);
548
+ const chunks = [];
549
+ for (const [s, e] of ranges) {
550
+ const lines = await reader(f.path, s, e);
551
+ chunks.push(lines.join("\n"));
552
+ }
553
+ out.push({ path: f.path, ranges, content: chunks.join("\n") });
554
+ }
555
+ return out;
556
+ }
557
+ function mergeRanges(ranges) {
558
+ if (!ranges.length) return [];
559
+ const sorted = [...ranges].sort((a, b) => a[0] - b[0]);
560
+ const merged = [];
561
+ let [cs, ce] = sorted[0];
562
+ for (let i = 1; i < sorted.length; i++) {
563
+ const [s, e] = sorted[i];
564
+ if (s <= ce + 1) {
565
+ ce = Math.max(ce, e);
566
+ } else {
567
+ merged.push([cs, ce]);
568
+ cs = s;
569
+ ce = e;
570
+ }
571
+ }
572
+ merged.push([cs, ce]);
573
+ return merged;
574
+ }
575
+
576
+ // tools/warp_grep/agent/runner.ts
577
+ var import_path = __toESM(require("path"), 1);
578
+ var import_promises = __toESM(require("fs/promises"), 1);
579
+ var parser = new LLMResponseParser();
580
+ async function buildInitialState(repoRoot, query) {
581
+ try {
582
+ const entries = await import_promises.default.readdir(repoRoot, { withFileTypes: true });
583
+ const dirs = entries.filter((e) => e.isDirectory()).map((d) => d.name).slice(0, 50);
584
+ const files = entries.filter((e) => e.isFile()).map((f) => f.name).slice(0, 50);
585
+ const parts = [
586
+ `<repo_root>${repoRoot}</repo_root>`,
587
+ `<top_dirs>${dirs.join(", ")}</top_dirs>`,
588
+ `<top_files>${files.join(", ")}</top_files>`
589
+ ];
590
+ return parts.join("\n");
591
+ } catch {
592
+ return `<repo_root>${repoRoot}</repo_root>`;
593
+ }
594
+ }
595
+ async function callModel(messages, model, apiKey) {
596
+ const api = "https://api.morphllm.com/v1/chat/completions";
597
+ const fetchPromise = fetchWithRetry(
598
+ api,
599
+ {
600
+ method: "POST",
601
+ headers: {
602
+ "Content-Type": "application/json",
603
+ Authorization: `Bearer ${apiKey || process.env.MORPH_API_KEY || ""}`
604
+ },
605
+ body: JSON.stringify({
606
+ model,
607
+ temperature: 0,
608
+ max_tokens: 1024,
609
+ messages
610
+ })
611
+ },
612
+ {}
613
+ );
614
+ const resp = await withTimeout(fetchPromise, AGENT_CONFIG.TIMEOUT_MS, "morph-warp-grep request timed out");
615
+ if (!resp.ok) {
616
+ const t = await resp.text();
617
+ throw new Error(`morph-warp-grep error ${resp.status}: ${t}`);
618
+ }
619
+ const data = await resp.json();
620
+ const content = data?.choices?.[0]?.message?.content;
621
+ if (!content || typeof content !== "string") {
622
+ throw new Error("Invalid response from model");
623
+ }
624
+ return content;
625
+ }
626
+ async function runWarpGrep(config) {
627
+ const repoRoot = import_path.default.resolve(config.repoRoot || process.cwd());
628
+ const messages = [];
629
+ const systemMessage = { role: "system", content: getSystemPrompt() };
630
+ messages.push(systemMessage);
631
+ const queryContent = `<query>${config.query}</query>`;
632
+ messages.push({ role: "user", content: queryContent });
633
+ const initialState = await buildInitialState(repoRoot, config.query);
634
+ messages.push({ role: "user", content: initialState });
635
+ const maxRounds = AGENT_CONFIG.MAX_ROUNDS;
636
+ const model = config.model || DEFAULT_MODEL;
637
+ const provider = config.provider;
638
+ const errors = [];
639
+ const grepState = new GrepState();
640
+ let finishMeta;
641
+ let terminationReason = "terminated";
642
+ for (let round = 1; round <= maxRounds; round += 1) {
643
+ const assistantContent = await callModel(messages, model, config.apiKey).catch((e) => {
644
+ errors.push({ message: e instanceof Error ? e.message : String(e) });
645
+ return "";
646
+ });
647
+ if (!assistantContent) break;
648
+ messages.push({ role: "assistant", content: assistantContent });
649
+ let toolCalls = [];
650
+ try {
651
+ toolCalls = parser.parse(assistantContent);
652
+ } catch (e) {
653
+ errors.push({ message: e instanceof Error ? e.message : String(e) });
654
+ terminationReason = "terminated";
655
+ break;
656
+ }
657
+ if (toolCalls.length === 0) {
658
+ errors.push({ message: "No tool calls produced by the model." });
659
+ terminationReason = "terminated";
660
+ break;
661
+ }
662
+ const finishCalls = toolCalls.filter((c) => c.name === "finish");
663
+ const grepCalls = toolCalls.filter((c) => c.name === "grep");
664
+ const analyseCalls = toolCalls.filter((c) => c.name === "analyse");
665
+ const readCalls = toolCalls.filter((c) => c.name === "read");
666
+ const formatted = [];
667
+ const otherPromises = [];
668
+ for (const c of analyseCalls) {
669
+ const args = c.arguments ?? {};
670
+ otherPromises.push(
671
+ toolAnalyse(provider, args).then(
672
+ (p) => formatAgentToolOutput("analyse", args, p, { isError: false }),
673
+ (err) => formatAgentToolOutput("analyse", args, String(err), { isError: true })
674
+ )
675
+ );
676
+ }
677
+ for (const c of readCalls) {
678
+ const args = c.arguments ?? {};
679
+ otherPromises.push(
680
+ toolRead(provider, args).then(
681
+ (p) => formatAgentToolOutput("read", args, p, { isError: false }),
682
+ (err) => formatAgentToolOutput("read", args, String(err), { isError: true })
683
+ )
684
+ );
685
+ }
686
+ const otherResults = await Promise.all(otherPromises);
687
+ formatted.push(...otherResults);
688
+ for (const c of grepCalls) {
689
+ const args = c.arguments ?? {};
690
+ try {
691
+ const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });
692
+ const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join("\n") : "";
693
+ const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);
694
+ let formattedPayload = formatTurnGrepOutput(newMatches);
695
+ if (formattedPayload === "No new matches found.") {
696
+ formattedPayload = "no new matches";
697
+ }
698
+ formatted.push(formatAgentToolOutput("grep", args, formattedPayload, { isError: false }));
699
+ } catch (err) {
700
+ formatted.push(formatAgentToolOutput("grep", args, String(err), { isError: true }));
701
+ }
702
+ }
703
+ if (formatted.length > 0) {
704
+ messages.push({ role: "user", content: formatted.join("\n") });
705
+ }
706
+ if (finishCalls.length) {
707
+ const fc = finishCalls[0];
708
+ const files = fc.arguments?.files ?? [];
709
+ finishMeta = { files };
710
+ terminationReason = "completed";
711
+ break;
712
+ }
713
+ }
714
+ if (terminationReason !== "completed" || !finishMeta) {
715
+ return { terminationReason, messages, errors };
716
+ }
717
+ const parts = ["Relevant context found:"];
718
+ for (const f of finishMeta.files) {
719
+ const ranges = f.lines.map(([s, e]) => `${s}-${e}`).join(", ");
720
+ parts.push(`- ${f.path}: ${ranges}`);
721
+ }
722
+ const payload = parts.join("\n");
723
+ const resolved = await readFinishFiles(
724
+ repoRoot,
725
+ finishMeta.files,
726
+ async (p, s, e) => {
727
+ const rr = await provider.read({ path: p, start: s, end: e });
728
+ return rr.lines.map((l) => {
729
+ const idx = l.indexOf("|");
730
+ return idx >= 0 ? l.slice(idx + 1) : l;
731
+ });
732
+ }
733
+ );
734
+ return {
735
+ terminationReason: "completed",
736
+ messages,
737
+ finish: { payload, metadata: finishMeta, resolved }
738
+ };
739
+ }
740
+ // Annotate the CommonJS export names for ESM import in node:
741
+ 0 && (module.exports = {
742
+ runWarpGrep
743
+ });
744
+ //# sourceMappingURL=runner.cjs.map