-
-
Notifications
You must be signed in to change notification settings - Fork 735
feat: accept view_range as alias for offset/length in read_file #517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -87,6 +87,19 @@ export async function handleReadFile(args: unknown): Promise<ServerResult> { | |||||||||||||
|
|
||||||||||||||
| const defaultLimit = config.fileReadLineLimit ?? 1000; | ||||||||||||||
|
|
||||||||||||||
| // Normalize view_range ([startLine, endLine], 1-based inclusive) into the | ||||||||||||||
| // offset/length the readers use (offset is 0-based). This lets clients that | ||||||||||||||
| // reach for the text-editor style view_range "just work". | ||||||||||||||
| let effectiveOffset = parsed.offset ?? 0; | ||||||||||||||
| let effectiveLength = parsed.length ?? defaultLimit; | ||||||||||||||
| if (parsed.view_range) { | ||||||||||||||
| const [start, end] = parsed.view_range; | ||||||||||||||
| effectiveOffset = Math.max(0, Math.floor(start) - 1); | ||||||||||||||
| effectiveLength = end < 0 | ||||||||||||||
| ? defaultLimit // endLine -1 => "to end", capped by config | ||||||||||||||
| : Math.max(1, Math.floor(end) - Math.floor(start) + 1); | ||||||||||||||
|
Comment on lines
+98
to
+100
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On Line 98, any negative Proposed fix- effectiveLength = end < 0
+ effectiveLength = end === -1
? defaultLimit
: Math.max(1, Math.floor(end) - Math.floor(start) + 1);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Convert sheet parameter: numeric strings become numbers for Excel index access | ||||||||||||||
| let sheetParam: string | number | undefined = parsed.sheet; | ||||||||||||||
| if (parsed.sheet !== undefined && /^\d+$/.test(parsed.sheet)) { | ||||||||||||||
|
|
@@ -95,8 +108,8 @@ export async function handleReadFile(args: unknown): Promise<ServerResult> { | |||||||||||||
|
|
||||||||||||||
| const options: ReadOptions = { | ||||||||||||||
| isUrl: parsed.isUrl, | ||||||||||||||
| offset: parsed.offset ?? 0, | ||||||||||||||
| length: parsed.length ?? defaultLimit, | ||||||||||||||
| offset: effectiveOffset, | ||||||||||||||
| length: effectiveLength, | ||||||||||||||
| sheet: sheetParam, | ||||||||||||||
| range: parsed.range | ||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -50,6 +50,10 @@ export const ReadFileArgsSchema = z.object({ | |||||||||||||||||||||||||||
| isUrl: z.boolean().optional().default(false), | ||||||||||||||||||||||||||||
| offset: z.number().optional().default(0), | ||||||||||||||||||||||||||||
| length: z.number().optional().default(1000), | ||||||||||||||||||||||||||||
| // Optional [startLine, endLine] convenience alias, 1-based and inclusive | ||||||||||||||||||||||||||||
| // (matches the text-editor view_range convention). Normalized to offset/length | ||||||||||||||||||||||||||||
| // in the handler. endLine of -1 means "to end of file". | ||||||||||||||||||||||||||||
| view_range: z.array(z.number()).length(2).optional(), | ||||||||||||||||||||||||||||
|
Comment on lines
+53
to
+56
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On Line 56, the schema enforces only “2 numbers,” but the feature contract is stricter ( Proposed schema hardening- view_range: z.array(z.number()).length(2).optional(),
+ view_range: z
+ .tuple([z.number().int().min(1), z.number().int()])
+ .refine(([start, end]) => end === -1 || end >= start, {
+ message: "view_range must be [startLine, endLine] with endLine = -1 or endLine >= startLine",
+ })
+ .optional(),📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| sheet: z.string().optional(), // String only for MCP client compatibility (Cursor doesn't support union types in JSON Schema) | ||||||||||||||||||||||||||||
| range: z.string().optional(), | ||||||||||||||||||||||||||||
| options: z.record(z.any()).optional() | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Configured
fileReadLineLimitis bypassed for normal reads.Line 94 falls back to
defaultLimit, butparsed.lengthis pre-filled by schema default (1000), so config won’t apply when callers omitlength. This makes the runtime behavior diverge from the documented configurable default.Proposed fix (preserve config default semantics)
🤖 Prompt for AI Agents