diff --git a/src/cli/guidanceCommands.ts b/src/cli/guidanceCommands.ts index 34486f309b..6758d93bf7 100644 --- a/src/cli/guidanceCommands.ts +++ b/src/cli/guidanceCommands.ts @@ -14,6 +14,7 @@ import { logCliCommand } from "../cliLogging.js"; import { projectAnalysisError } from "../domain/analysisErrorProjection.js"; import type { Logger } from "pino"; import type { CliInstance } from "./types.js"; +import { cliDecimalField } from "./options.js"; /** Guidance descriptors owned by one CLI host. */ export class CliGuidanceResources { @@ -64,9 +65,10 @@ export const registerGuidanceCommands = ( locator: readGuidanceSectionInputSchema.shape.locator .optional() .describe("Required with --action read; locator returned by search"), - limit: searchGuidanceLimitSchema - .optional() - .describe("Maximum search matches; search only, defaults to 8"), + // Decimal tokens only: numeric coercion would read "0x2" as 2. + limit: cliDecimalField(searchGuidanceLimitSchema.optional()).describe( + "Maximum search matches; search only, defaults to 8", + ), cursor: searchGuidanceInputSchema.shape.cursor .optional() .describe("Continue a search page; search only"), diff --git a/tests/boundary/cli/guidanceCli.test.ts b/tests/boundary/cli/guidanceCli.test.ts index f169bd17eb..bb51ca6002 100644 --- a/tests/boundary/cli/guidanceCli.test.ts +++ b/tests/boundary/cli/guidanceCli.test.ts @@ -75,6 +75,13 @@ it("reports no matches and rejects invalid CLI inputs", async () => { }); const empty = await run(["guidance", "--query", " "]); expect(empty.exitCode).not.toBe(0); + // Numeric coercion would read "0x2" as a two-match page. + const hexLimit = await run(["guidance", "--query", "module", "--limit=0x2"]); + expect(hexLimit.exitCode).not.toBe(0); + expect(JSON.parse(hexLimit.stdout)).toMatchObject({ + code: "VALIDATION_ERROR", + fieldErrors: [expect.objectContaining({ path: "limit" })], + }); const malformed = await run([ "guidance", "--action",