@morphllm/morphsdk 0.2.50 → 0.2.52

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 (62) hide show
  1. package/dist/{chunk-4MELBN55.js → chunk-FYQUSDOE.js} +4 -4
  2. package/dist/{chunk-Z2FBMSNE.js → chunk-HQO45BAJ.js} +5 -1
  3. package/dist/chunk-HQO45BAJ.js.map +1 -0
  4. package/dist/{chunk-NRWVMX4O.js → chunk-L5BMGLLQ.js} +29 -22
  5. package/dist/chunk-L5BMGLLQ.js.map +1 -0
  6. package/dist/{chunk-SWQPIKPY.js → chunk-LVPVVLTI.js} +70 -49
  7. package/dist/chunk-LVPVVLTI.js.map +1 -0
  8. package/dist/{chunk-2TXLSKGU.js → chunk-MZT6HVGD.js} +3 -3
  9. package/dist/{chunk-DZRBTNQR.js → chunk-PZDR5ZZ2.js} +5 -5
  10. package/dist/{chunk-KH3RKPPO.js → chunk-UU6XCZG3.js} +4 -4
  11. package/dist/{chunk-5ASRBH5I.js → chunk-YR53PPVM.js} +4 -4
  12. package/dist/{chunk-MLDK7SCW.js → chunk-ZJIIICRA.js} +29 -7
  13. package/dist/chunk-ZJIIICRA.js.map +1 -0
  14. package/dist/client.cjs +116 -68
  15. package/dist/client.cjs.map +1 -1
  16. package/dist/client.js +13 -13
  17. package/dist/index.cjs +116 -68
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.js +13 -13
  20. package/dist/tools/warp_grep/agent/parser.cjs +69 -48
  21. package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
  22. package/dist/tools/warp_grep/agent/parser.d.ts +2 -0
  23. package/dist/tools/warp_grep/agent/parser.js +1 -1
  24. package/dist/tools/warp_grep/agent/runner.cjs +88 -62
  25. package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
  26. package/dist/tools/warp_grep/agent/runner.js +7 -7
  27. package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
  28. package/dist/tools/warp_grep/agent/types.d.ts +1 -1
  29. package/dist/tools/warp_grep/anthropic.cjs +116 -68
  30. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  31. package/dist/tools/warp_grep/anthropic.js +10 -10
  32. package/dist/tools/warp_grep/index.cjs +116 -68
  33. package/dist/tools/warp_grep/index.cjs.map +1 -1
  34. package/dist/tools/warp_grep/index.js +12 -12
  35. package/dist/tools/warp_grep/openai.cjs +116 -68
  36. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  37. package/dist/tools/warp_grep/openai.js +10 -10
  38. package/dist/tools/warp_grep/providers/local.cjs +28 -6
  39. package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
  40. package/dist/tools/warp_grep/providers/local.js +1 -1
  41. package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
  42. package/dist/tools/warp_grep/providers/types.d.ts +2 -0
  43. package/dist/tools/warp_grep/tools/grep.cjs +3 -0
  44. package/dist/tools/warp_grep/tools/grep.cjs.map +1 -1
  45. package/dist/tools/warp_grep/tools/grep.js +3 -0
  46. package/dist/tools/warp_grep/tools/grep.js.map +1 -1
  47. package/dist/tools/warp_grep/tools/read.cjs +4 -0
  48. package/dist/tools/warp_grep/tools/read.cjs.map +1 -1
  49. package/dist/tools/warp_grep/tools/read.js +1 -1
  50. package/dist/tools/warp_grep/vercel.cjs +116 -68
  51. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  52. package/dist/tools/warp_grep/vercel.js +10 -10
  53. package/package.json +1 -1
  54. package/dist/chunk-MLDK7SCW.js.map +0 -1
  55. package/dist/chunk-NRWVMX4O.js.map +0 -1
  56. package/dist/chunk-SWQPIKPY.js.map +0 -1
  57. package/dist/chunk-Z2FBMSNE.js.map +0 -1
  58. /package/dist/{chunk-4MELBN55.js.map → chunk-FYQUSDOE.js.map} +0 -0
  59. /package/dist/{chunk-2TXLSKGU.js.map → chunk-MZT6HVGD.js.map} +0 -0
  60. /package/dist/{chunk-DZRBTNQR.js.map → chunk-PZDR5ZZ2.js.map} +0 -0
  61. /package/dist/{chunk-KH3RKPPO.js.map → chunk-UU6XCZG3.js.map} +0 -0
  62. /package/dist/{chunk-5ASRBH5I.js.map → chunk-YR53PPVM.js.map} +0 -0
package/dist/client.js CHANGED
@@ -1,23 +1,23 @@
1
1
  import {
2
2
  MorphClient
3
- } from "./chunk-DZRBTNQR.js";
4
- import "./chunk-5ASRBH5I.js";
5
- import "./chunk-KH3RKPPO.js";
6
- import "./chunk-4MELBN55.js";
7
- import "./chunk-2TXLSKGU.js";
8
- import "./chunk-NRWVMX4O.js";
9
- import "./chunk-EK7OQPWD.js";
10
- import "./chunk-Z2FBMSNE.js";
11
- import "./chunk-SWQPIKPY.js";
3
+ } from "./chunk-PZDR5ZZ2.js";
4
+ import "./chunk-YR53PPVM.js";
5
+ import "./chunk-UU6XCZG3.js";
6
+ import "./chunk-FYQUSDOE.js";
7
+ import "./chunk-MZT6HVGD.js";
8
+ import "./chunk-L5BMGLLQ.js";
9
+ import "./chunk-TICMYDII.js";
10
+ import "./chunk-NDZO5IPV.js";
11
+ import "./chunk-LVPVVLTI.js";
12
12
  import "./chunk-WETRQJGU.js";
13
- import "./chunk-MLDK7SCW.js";
13
+ import "./chunk-HQO45BAJ.js";
14
+ import "./chunk-ZJIIICRA.js";
14
15
  import "./chunk-G2RSY56Q.js";
15
16
  import "./chunk-SMGZ6A64.js";
16
17
  import "./chunk-TPP2UGQP.js";
17
- import "./chunk-73RQWOQC.js";
18
18
  import "./chunk-TJIUA27P.js";
19
- import "./chunk-TICMYDII.js";
20
- import "./chunk-NDZO5IPV.js";
19
+ import "./chunk-73RQWOQC.js";
20
+ import "./chunk-EK7OQPWD.js";
21
21
  import "./chunk-UBX7QYBD.js";
22
22
  import "./chunk-GJU7UOFL.js";
23
23
  import "./chunk-76DJEQEP.js";
package/dist/index.cjs CHANGED
@@ -1117,12 +1117,6 @@ function getSystemPrompt() {
1117
1117
  }
1118
1118
 
1119
1119
  // tools/warp_grep/agent/parser.ts
1120
- var LLMResponseParseError = class extends Error {
1121
- constructor(message) {
1122
- super(message);
1123
- this.name = "LLMResponseParseError";
1124
- }
1125
- };
1126
1120
  var VALID_COMMANDS = ["analyse", "grep", "read", "finish"];
1127
1121
  function preprocessText(text) {
1128
1122
  let processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
@@ -1173,24 +1167,23 @@ var LLMResponseParser = class {
1173
1167
  const lines = preprocessText(text);
1174
1168
  const commands = [];
1175
1169
  let finishAccumulator = null;
1176
- lines.forEach((line, idx) => {
1170
+ lines.forEach((line) => {
1177
1171
  if (!line || line.startsWith("#")) return;
1178
- const ctx = { lineNumber: idx + 1, raw: line };
1179
- const parts = this.splitLine(line, ctx);
1172
+ const parts = this.splitLine(line);
1180
1173
  if (parts.length === 0) return;
1181
1174
  const cmd = parts[0];
1182
1175
  switch (cmd) {
1183
1176
  case "analyse":
1184
- this.handleAnalyse(parts, ctx, commands);
1177
+ this.handleAnalyse(parts, line, commands);
1185
1178
  break;
1186
1179
  case "grep":
1187
- this.handleGrep(parts, ctx, commands);
1180
+ this.handleGrep(parts, line, commands);
1188
1181
  break;
1189
1182
  case "read":
1190
- this.handleRead(parts, ctx, commands);
1183
+ this.handleRead(parts, line, commands);
1191
1184
  break;
1192
1185
  case "finish":
1193
- finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);
1186
+ finishAccumulator = this.handleFinish(parts, line, commands, finishAccumulator);
1194
1187
  break;
1195
1188
  default:
1196
1189
  break;
@@ -1207,53 +1200,68 @@ var LLMResponseParser = class {
1207
1200
  }
1208
1201
  return commands;
1209
1202
  }
1210
- splitLine(line, ctx) {
1211
- try {
1212
- const parts = [];
1213
- let current = "";
1214
- let inSingle = false;
1215
- for (let i = 0; i < line.length; i++) {
1216
- const ch = line[i];
1217
- if (ch === "'" && line[i - 1] !== "\\") {
1218
- inSingle = !inSingle;
1219
- current += ch;
1220
- } else if (!inSingle && /\s/.test(ch)) {
1221
- if (current) {
1222
- parts.push(current);
1223
- current = "";
1224
- }
1225
- } else {
1226
- current += ch;
1203
+ splitLine(line) {
1204
+ const parts = [];
1205
+ let current = "";
1206
+ let inSingle = false;
1207
+ for (let i = 0; i < line.length; i++) {
1208
+ const ch = line[i];
1209
+ if (ch === "'" && line[i - 1] !== "\\") {
1210
+ inSingle = !inSingle;
1211
+ current += ch;
1212
+ } else if (!inSingle && /\s/.test(ch)) {
1213
+ if (current) {
1214
+ parts.push(current);
1215
+ current = "";
1227
1216
  }
1217
+ } else {
1218
+ current += ch;
1228
1219
  }
1229
- if (current) parts.push(current);
1230
- return parts;
1231
- } catch {
1232
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);
1233
1220
  }
1221
+ if (current) parts.push(current);
1222
+ return parts;
1223
+ }
1224
+ /** Helper to create a _skip tool call with an error message */
1225
+ skip(message) {
1226
+ return { name: "_skip", arguments: { message } };
1234
1227
  }
1235
- handleAnalyse(parts, ctx, commands) {
1228
+ handleAnalyse(parts, rawLine, commands) {
1236
1229
  if (parts.length < 2) {
1237
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: analyse requires <path>`);
1230
+ commands.push(this.skip(
1231
+ `[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: analyse <path> [pattern]. Example: analyse src/`
1232
+ ));
1233
+ return;
1238
1234
  }
1239
1235
  const path4 = parts[1];
1240
1236
  const pattern = parts[2]?.replace(/^"|"$/g, "") ?? null;
1241
1237
  commands.push({ name: "analyse", arguments: { path: path4, pattern } });
1242
1238
  }
1243
1239
  // no glob tool in MCP
1244
- handleGrep(parts, ctx, commands) {
1240
+ handleGrep(parts, rawLine, commands) {
1245
1241
  if (parts.length < 3) {
1246
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep requires '<pattern>' and <path>`);
1242
+ commands.push(this.skip(
1243
+ `[SKIPPED] Your command "${rawLine}" is missing arguments. Correct format: grep '<pattern>' <path>. Example: grep 'TODO' src/`
1244
+ ));
1245
+ return;
1247
1246
  }
1248
- const pat = parts[1];
1249
- if (!pat.startsWith("'") || !pat.endsWith("'")) {
1250
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep pattern must be single-quoted`);
1247
+ let pat = parts[1];
1248
+ if (pat.startsWith("'") && pat.endsWith("'")) {
1249
+ pat = pat.slice(1, -1);
1251
1250
  }
1252
- commands.push({ name: "grep", arguments: { pattern: pat.slice(1, -1), path: parts[2] } });
1251
+ if (!pat) {
1252
+ commands.push(this.skip(
1253
+ `[SKIPPED] Your command "${rawLine}" has an empty pattern. Provide a non-empty search pattern. Example: grep 'function' src/`
1254
+ ));
1255
+ return;
1256
+ }
1257
+ commands.push({ name: "grep", arguments: { pattern: pat, path: parts[2] } });
1253
1258
  }
1254
- handleRead(parts, ctx, commands) {
1259
+ handleRead(parts, rawLine, commands) {
1255
1260
  if (parts.length < 2) {
1256
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: read requires <path> or <path>:<start-end>`);
1261
+ commands.push(this.skip(
1262
+ `[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: read <path> or read <path>:<start>-<end>. Example: read src/index.ts:1-50`
1263
+ ));
1264
+ return;
1257
1265
  }
1258
1266
  const spec = parts[1];
1259
1267
  const rangeIdx = spec.indexOf(":");
@@ -1261,31 +1269,38 @@ var LLMResponseParser = class {
1261
1269
  commands.push({ name: "read", arguments: { path: spec } });
1262
1270
  return;
1263
1271
  }
1264
- const path4 = spec.slice(0, rangeIdx);
1272
+ const filePath = spec.slice(0, rangeIdx);
1265
1273
  const range = spec.slice(rangeIdx + 1);
1266
1274
  const [s, e] = range.split("-").map((v) => parseInt(v, 10));
1267
1275
  if (!Number.isFinite(s) || !Number.isFinite(e)) {
1268
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid read range '${range}'`);
1276
+ commands.push({ name: "read", arguments: { path: filePath } });
1277
+ return;
1269
1278
  }
1270
- commands.push({ name: "read", arguments: { path: path4, start: s, end: e } });
1279
+ commands.push({ name: "read", arguments: { path: filePath, start: s, end: e } });
1271
1280
  }
1272
- handleFinish(parts, ctx, acc) {
1281
+ handleFinish(parts, rawLine, commands, acc) {
1273
1282
  const map = acc ?? /* @__PURE__ */ new Map();
1274
1283
  const args = parts.slice(1);
1275
1284
  for (const token of args) {
1276
- const [path4, rangesText] = token.split(":", 2);
1277
- if (!path4 || !rangesText) {
1278
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid finish token '${token}'`);
1285
+ const [filePath, rangesText] = token.split(":", 2);
1286
+ if (!filePath || !rangesText) {
1287
+ commands.push(this.skip(
1288
+ `[SKIPPED] Invalid finish token "${token}". Correct format: finish <path>:<start>-<end>. Example: finish src/index.ts:1-50`
1289
+ ));
1290
+ continue;
1279
1291
  }
1280
1292
  const rangeSpecs = rangesText.split(",").filter(Boolean);
1281
1293
  for (const spec of rangeSpecs) {
1282
1294
  const [s, e] = spec.split("-").map((v) => parseInt(v, 10));
1283
1295
  if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {
1284
- throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid range '${spec}'`);
1296
+ commands.push(this.skip(
1297
+ `[SKIPPED] Invalid range "${spec}" in "${token}". Ranges must be <start>-<end> where start <= end. Example: 1-50`
1298
+ ));
1299
+ continue;
1285
1300
  }
1286
- const arr = map.get(path4) ?? [];
1301
+ const arr = map.get(filePath) ?? [];
1287
1302
  arr.push([s, e]);
1288
- map.set(path4, arr);
1303
+ map.set(filePath, arr);
1289
1304
  }
1290
1305
  }
1291
1306
  return map;
@@ -1295,6 +1310,10 @@ var LLMResponseParser = class {
1295
1310
  // tools/warp_grep/tools/read.ts
1296
1311
  async function toolRead(provider, args) {
1297
1312
  const res = await provider.read({ path: args.path, start: args.start, end: args.end });
1313
+ if (res.error) {
1314
+ return res.error;
1315
+ }
1316
+ if (!res.lines.length) return "(empty file)";
1298
1317
  return res.lines.join("\n");
1299
1318
  }
1300
1319
 
@@ -1606,14 +1625,7 @@ async function runWarpGrep(config) {
1606
1625
  });
1607
1626
  if (!assistantContent) break;
1608
1627
  messages.push({ role: "assistant", content: assistantContent });
1609
- let toolCalls = [];
1610
- try {
1611
- toolCalls = parser.parse(assistantContent);
1612
- } catch (e) {
1613
- errors.push({ message: e instanceof Error ? e.message : String(e) });
1614
- terminationReason = "terminated";
1615
- break;
1616
- }
1628
+ const toolCalls = parser.parse(assistantContent);
1617
1629
  if (toolCalls.length === 0) {
1618
1630
  errors.push({ message: "No tool calls produced by the model." });
1619
1631
  terminationReason = "terminated";
@@ -1623,7 +1635,12 @@ async function runWarpGrep(config) {
1623
1635
  const grepCalls = toolCalls.filter((c) => c.name === "grep");
1624
1636
  const analyseCalls = toolCalls.filter((c) => c.name === "analyse");
1625
1637
  const readCalls = toolCalls.filter((c) => c.name === "read");
1638
+ const skipCalls = toolCalls.filter((c) => c.name === "_skip");
1626
1639
  const formatted = [];
1640
+ for (const c of skipCalls) {
1641
+ const msg = c.arguments?.message || "Command skipped due to parsing error";
1642
+ formatted.push(msg);
1643
+ }
1627
1644
  const otherPromises = [];
1628
1645
  for (const c of analyseCalls) {
1629
1646
  const args = c.arguments ?? {};
@@ -1649,6 +1666,15 @@ async function runWarpGrep(config) {
1649
1666
  const args = c.arguments ?? {};
1650
1667
  try {
1651
1668
  const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });
1669
+ if (grepRes.error) {
1670
+ errors.push({ message: grepRes.error });
1671
+ terminationReason = "terminated";
1672
+ return {
1673
+ terminationReason: "terminated",
1674
+ messages,
1675
+ errors
1676
+ };
1677
+ }
1652
1678
  const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join("\n") : "";
1653
1679
  const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);
1654
1680
  let formattedPayload = formatTurnGrepOutput(newMatches);
@@ -1860,10 +1886,22 @@ var LocalRipgrepProvider = class {
1860
1886
  ];
1861
1887
  const res = await runRipgrep(args, { cwd: this.repoRoot });
1862
1888
  if (res.exitCode === -1) {
1863
- throw new Error(res.stderr || "ripgrep (rg) execution failed.");
1889
+ return {
1890
+ lines: [],
1891
+ error: `[RIPGREP NOT AVAILABLE] ripgrep (rg) is required but failed to execute. Please install it:
1892
+ \u2022 macOS: brew install ripgrep
1893
+ \u2022 Ubuntu/Debian: apt install ripgrep
1894
+ \u2022 Windows: choco install ripgrep
1895
+ \u2022 Or visit: https://github.com/BurntSushi/ripgrep#installation
1896
+ Exit code: ${res.exitCode}${res.stderr ? `
1897
+ Details: ${res.stderr}` : ""}`
1898
+ };
1864
1899
  }
1865
1900
  if (res.exitCode !== 0 && res.exitCode !== 1) {
1866
- throw new Error(res.stderr || `ripgrep failed with code ${res.exitCode}`);
1901
+ return {
1902
+ lines: [],
1903
+ error: `[RIPGREP ERROR] grep failed with exit code ${res.exitCode}${res.stderr ? `: ${res.stderr}` : ""}`
1904
+ };
1867
1905
  }
1868
1906
  const lines = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
1869
1907
  return { lines };
@@ -1881,7 +1919,8 @@ var LocalRipgrepProvider = class {
1881
1919
  ];
1882
1920
  const res = await runRipgrep(args, { cwd: this.repoRoot });
1883
1921
  if (res.exitCode === -1) {
1884
- throw new Error(res.stderr || "ripgrep (rg) execution failed.");
1922
+ console.warn(`[warp_grep] ripgrep not available for glob: ${res.stderr || "execution failed"}`);
1923
+ return { files: [] };
1885
1924
  }
1886
1925
  const files = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
1887
1926
  return { files };
@@ -1890,13 +1929,22 @@ var LocalRipgrepProvider = class {
1890
1929
  const abs = resolveUnderRepo(this.repoRoot, params.path);
1891
1930
  const stat = await import_promises4.default.stat(abs).catch(() => null);
1892
1931
  if (!stat || !stat.isFile()) {
1893
- throw new Error(`Path is not a file: ${params.path}`);
1932
+ return {
1933
+ lines: [],
1934
+ error: `[FILE NOT FOUND] You tried to read "${params.path}" but there is no file at this path. Double-check the path exists and is spelled correctly.`
1935
+ };
1894
1936
  }
1895
1937
  if (isSymlink(abs)) {
1896
- throw new Error(`Refusing to read symlink: ${params.path}`);
1938
+ return {
1939
+ lines: [],
1940
+ error: `[SYMLINK] You tried to read "${params.path}" but this is a symlink. Try reading the actual file it points to instead.`
1941
+ };
1897
1942
  }
1898
1943
  if (!isTextualFile(abs)) {
1899
- throw new Error(`Non-text or too-large file: ${params.path}`);
1944
+ return {
1945
+ lines: [],
1946
+ error: `[UNREADABLE FILE] You tried to read "${params.path}" but this file is either too large or not a text file, so it cannot be read. Try a different file.`
1947
+ };
1900
1948
  }
1901
1949
  const lines = await readAllLines(abs);
1902
1950
  const total = lines.length;