@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.
- package/dist/{chunk-4MELBN55.js → chunk-FYQUSDOE.js} +4 -4
- package/dist/{chunk-Z2FBMSNE.js → chunk-HQO45BAJ.js} +5 -1
- package/dist/chunk-HQO45BAJ.js.map +1 -0
- package/dist/{chunk-NRWVMX4O.js → chunk-L5BMGLLQ.js} +29 -22
- package/dist/chunk-L5BMGLLQ.js.map +1 -0
- package/dist/{chunk-SWQPIKPY.js → chunk-LVPVVLTI.js} +70 -49
- package/dist/chunk-LVPVVLTI.js.map +1 -0
- package/dist/{chunk-2TXLSKGU.js → chunk-MZT6HVGD.js} +3 -3
- package/dist/{chunk-DZRBTNQR.js → chunk-PZDR5ZZ2.js} +5 -5
- package/dist/{chunk-KH3RKPPO.js → chunk-UU6XCZG3.js} +4 -4
- package/dist/{chunk-5ASRBH5I.js → chunk-YR53PPVM.js} +4 -4
- package/dist/{chunk-MLDK7SCW.js → chunk-ZJIIICRA.js} +29 -7
- package/dist/chunk-ZJIIICRA.js.map +1 -0
- package/dist/client.cjs +116 -68
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +13 -13
- package/dist/index.cjs +116 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -13
- package/dist/tools/warp_grep/agent/parser.cjs +69 -48
- package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/parser.d.ts +2 -0
- package/dist/tools/warp_grep/agent/parser.js +1 -1
- package/dist/tools/warp_grep/agent/runner.cjs +88 -62
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.js +7 -7
- package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/types.d.ts +1 -1
- package/dist/tools/warp_grep/anthropic.cjs +116 -68
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.js +10 -10
- package/dist/tools/warp_grep/index.cjs +116 -68
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.js +12 -12
- package/dist/tools/warp_grep/openai.cjs +116 -68
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.js +10 -10
- package/dist/tools/warp_grep/providers/local.cjs +28 -6
- package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/local.js +1 -1
- package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/types.d.ts +2 -0
- package/dist/tools/warp_grep/tools/grep.cjs +3 -0
- package/dist/tools/warp_grep/tools/grep.cjs.map +1 -1
- package/dist/tools/warp_grep/tools/grep.js +3 -0
- package/dist/tools/warp_grep/tools/grep.js.map +1 -1
- package/dist/tools/warp_grep/tools/read.cjs +4 -0
- package/dist/tools/warp_grep/tools/read.cjs.map +1 -1
- package/dist/tools/warp_grep/tools/read.js +1 -1
- package/dist/tools/warp_grep/vercel.cjs +116 -68
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.js +10 -10
- package/package.json +1 -1
- package/dist/chunk-MLDK7SCW.js.map +0 -1
- package/dist/chunk-NRWVMX4O.js.map +0 -1
- package/dist/chunk-SWQPIKPY.js.map +0 -1
- package/dist/chunk-Z2FBMSNE.js.map +0 -1
- /package/dist/{chunk-4MELBN55.js.map → chunk-FYQUSDOE.js.map} +0 -0
- /package/dist/{chunk-2TXLSKGU.js.map → chunk-MZT6HVGD.js.map} +0 -0
- /package/dist/{chunk-DZRBTNQR.js.map → chunk-PZDR5ZZ2.js.map} +0 -0
- /package/dist/{chunk-KH3RKPPO.js.map → chunk-UU6XCZG3.js.map} +0 -0
- /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-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
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-
|
|
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-
|
|
20
|
-
import "./chunk-
|
|
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
|
|
1170
|
+
lines.forEach((line) => {
|
|
1177
1171
|
if (!line || line.startsWith("#")) return;
|
|
1178
|
-
const
|
|
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,
|
|
1177
|
+
this.handleAnalyse(parts, line, commands);
|
|
1185
1178
|
break;
|
|
1186
1179
|
case "grep":
|
|
1187
|
-
this.handleGrep(parts,
|
|
1180
|
+
this.handleGrep(parts, line, commands);
|
|
1188
1181
|
break;
|
|
1189
1182
|
case "read":
|
|
1190
|
-
this.handleRead(parts,
|
|
1183
|
+
this.handleRead(parts, line, commands);
|
|
1191
1184
|
break;
|
|
1192
1185
|
case "finish":
|
|
1193
|
-
finishAccumulator = this.handleFinish(parts,
|
|
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
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
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,
|
|
1228
|
+
handleAnalyse(parts, rawLine, commands) {
|
|
1236
1229
|
if (parts.length < 2) {
|
|
1237
|
-
|
|
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,
|
|
1240
|
+
handleGrep(parts, rawLine, commands) {
|
|
1245
1241
|
if (parts.length < 3) {
|
|
1246
|
-
|
|
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
|
-
|
|
1249
|
-
if (
|
|
1250
|
-
|
|
1247
|
+
let pat = parts[1];
|
|
1248
|
+
if (pat.startsWith("'") && pat.endsWith("'")) {
|
|
1249
|
+
pat = pat.slice(1, -1);
|
|
1251
1250
|
}
|
|
1252
|
-
|
|
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,
|
|
1259
|
+
handleRead(parts, rawLine, commands) {
|
|
1255
1260
|
if (parts.length < 2) {
|
|
1256
|
-
|
|
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
|
|
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
|
-
|
|
1276
|
+
commands.push({ name: "read", arguments: { path: filePath } });
|
|
1277
|
+
return;
|
|
1269
1278
|
}
|
|
1270
|
-
commands.push({ name: "read", arguments: { path:
|
|
1279
|
+
commands.push({ name: "read", arguments: { path: filePath, start: s, end: e } });
|
|
1271
1280
|
}
|
|
1272
|
-
handleFinish(parts,
|
|
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 [
|
|
1277
|
-
if (!
|
|
1278
|
-
|
|
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
|
-
|
|
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(
|
|
1301
|
+
const arr = map.get(filePath) ?? [];
|
|
1287
1302
|
arr.push([s, e]);
|
|
1288
|
-
map.set(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|