diff --git a/src/summary.ts b/src/summary.ts index 67bcea1..d278814 100644 --- a/src/summary.ts +++ b/src/summary.ts @@ -52,9 +52,11 @@ export function readCall( args: { path?: string; offset?: number; limit?: number }, max: number = DEFAULT_CLIP, ): string { + const offset = args.offset ? Number(args.offset) : undefined; + const limit = args.limit ? Number(args.limit) : undefined; const range = - args.offset || args.limit - ? theme.fg("dim", ` · lines ${args.offset ?? 1}${args.limit ? `–${(args.offset ?? 1) + args.limit - 1}` : "+"}`) + offset || limit + ? theme.fg("dim", ` · lines ${offset ?? 1}${limit ? `–${(offset ?? 1) + limit - 1}` : "+"}`) : ""; return title(theme, "Read") + theme.fg("accent", compactPath(args.path ?? "", max)) + range; } diff --git a/test/pretty.test.ts b/test/pretty.test.ts index 0375cff..32e9f16 100644 --- a/test/pretty.test.ts +++ b/test/pretty.test.ts @@ -29,6 +29,19 @@ test("readCall shows path and range", () => { assert.equal(readCall(theme, { path: "src/a.ts" }), "Read src/a.ts"); assert.ok(readCall(theme, { path: "a", offset: 10, limit: 5 }).includes("lines 10–14")); assert.ok(readCall(theme, { path: "a", offset: 3 }).includes("lines 3+")); + // LLMs may pass numeric arguments as strings at runtime + assert.ok( + readCall(theme, { path: "a", offset: "1" as unknown as number, limit: "2000" as unknown as number }).includes( + "lines 1–2000", + ), + ); + assert.ok( + readCall(theme, { path: "a", offset: "1046" as unknown as number, limit: "400" as unknown as number }).includes( + "lines 1046–1445", + ), + ); + assert.ok(readCall(theme, { path: "a", offset: "5" as unknown as number }).includes("lines 5+")); + assert.ok(readCall(theme, { path: "a", limit: "20" as unknown as number }).includes("lines 1–20")); }); test("readSummary counts lines, flags truncation and failure", () => {