diff --git a/src/domain/evm/evmInterface.ts b/src/domain/evm/evmInterface.ts index 75ada1f97..6db3f7e16 100644 --- a/src/domain/evm/evmInterface.ts +++ b/src/domain/evm/evmInterface.ts @@ -1,14 +1,15 @@ import { z } from "zod"; +import { localPathStringSchema } from "../localPath.js"; + const byteOffset = z.number().int().nonnegative(); const sha256 = z.string().regex(/^[a-f0-9]{64}$/); /** Select the carrier representation explicitly; no RPC or deployed-contract lookup is implied. */ export const inspectEvmInterfaceInputSchema = z.strictObject({ - path: z - .string() - .min(1) - .describe("Absolute path to caller-selected local bytecode carrier"), + path: localPathStringSchema.describe( + "Absolute path to caller-selected local bytecode carrier", + ), encoding: z .enum(["raw", "hex"]) .describe( diff --git a/src/domain/native/binaryLayout.ts b/src/domain/native/binaryLayout.ts index e2a8d20cf..62ebb34f2 100644 --- a/src/domain/native/binaryLayout.ts +++ b/src/domain/native/binaryLayout.ts @@ -1,5 +1,6 @@ import { z } from "zod"; +import { localPathStringSchema } from "../localPath.js"; import { CANONICAL_BASE64_PATTERN } from "../stringPatterns.js"; const unsignedHex = z.string().regex(/^0x(?:0|[1-9a-f][0-9a-f]{0,15})$/); @@ -16,10 +17,9 @@ const name = z.strictObject({ /** Explicit local object selection, independent of an active disassembler target. */ export const inspectBinaryLayoutInputSchema = z.strictObject({ - path: z - .string() - .min(1) - .describe("Absolute filesystem path to the selected binary"), + path: localPathStringSchema.describe( + "Absolute filesystem path to the selected binary", + ), }); /** File and linked-image evidence; numeric ELF values never pass through unsafe JSON numbers. */ diff --git a/src/domain/native/peResources.ts b/src/domain/native/peResources.ts index 80fcc80bb..9ed9c3552 100644 --- a/src/domain/native/peResources.ts +++ b/src/domain/native/peResources.ts @@ -1,5 +1,7 @@ import { z } from "zod"; +import { localPathStringSchema } from "../localPath.js"; + const uint = z.number().int().min(0).max(0xffffffff); const range = z.strictObject({ offset: uint, bytes: uint }); const identity = z.discriminatedUnion("kind", [ @@ -14,7 +16,9 @@ const identity = z.discriminatedUnion("kind", [ /** Complete bounded inspection of a caller-selected PE image, without execution. */ export const inspectPeResourcesInputSchema = z.strictObject({ - path: z.string().min(1).describe("Absolute filesystem path to a PE image"), + path: localPathStringSchema.describe( + "Absolute filesystem path to a PE image", + ), max_file_bytes: z .number() .int() diff --git a/src/domain/native/recordedCrash.ts b/src/domain/native/recordedCrash.ts index adef5a7ea..110bd1d91 100644 --- a/src/domain/native/recordedCrash.ts +++ b/src/domain/native/recordedCrash.ts @@ -1,5 +1,6 @@ import { z } from "zod"; +import { localPathStringSchema } from "../localPath.js"; import { CANONICAL_BASE64_PATTERN } from "../stringPatterns.js"; import { recordedNoteCoverageIssues } from "./recordedCrashNoteCoverage.js"; @@ -50,10 +51,9 @@ const supportedRegisters = new Set(RECORDED_LINUX_AMD64_REGISTERS); /** Select an explicit recording and optionally request debugger-derived mapping context. */ export const inspectRecordedCrashInputSchema = z.strictObject({ - path: z - .string() - .min(1) - .describe("Absolute filesystem path to a supplied Linux ELF core"), + path: localPathStringSchema.describe( + "Absolute filesystem path to a supplied Linux ELF core", + ), include_debugger_context: z .boolean() .default(false) diff --git a/src/domain/wasm/wasmArtifact.ts b/src/domain/wasm/wasmArtifact.ts index 70a86b79a..ed2a120e0 100644 --- a/src/domain/wasm/wasmArtifact.ts +++ b/src/domain/wasm/wasmArtifact.ts @@ -1,5 +1,7 @@ import { z } from "zod"; +import { localPathStringSchema } from "../localPath.js"; + const digest = z.string().regex(/^[a-f0-9]{64}$/); const artifact = z.strictObject({ path: z.string().min(1), @@ -8,12 +10,11 @@ const artifact = z.strictObject({ }); /** All artifacts are explicitly selected local files; references never trigger acquisition. */ export const inspectWasmArtifactInputSchema = z.strictObject({ - path: z - .string() - .min(1) - .describe("Absolute selected local WASM artifact path"), - glue_paths: z.array(z.string().min(1)).max(16).default([]), - candidate_paths: z.array(z.string().min(1)).max(16).default([]), + path: localPathStringSchema.describe( + "Absolute selected local WASM artifact path", + ), + glue_paths: z.array(localPathStringSchema).max(16).default([]), + candidate_paths: z.array(localPathStringSchema).max(16).default([]), }); /** Upstream output stays intact; import/export names are never split on ambiguous punctuation. */ export const wasmArtifactSchema = z diff --git a/tests/acceptance/tools/localToolContracts.test.ts b/tests/acceptance/tools/localToolContracts.test.ts index 638240296..dfd38344b 100644 --- a/tests/acceptance/tools/localToolContracts.test.ts +++ b/tests/acceptance/tools/localToolContracts.test.ts @@ -96,6 +96,16 @@ const pathRequests: readonly [string, Record][] = [ "export_web_scripts", { capture_path: nul, output_directory: "/tmp/exported-scripts" }, ], + ["inspect_pe_resources", { path: nul }], + ["inspect_binary_layout", { path: nul }], + ["inspect_recorded_crash", { path: nul }], + ["inspect_wasm_artifact", { path: nul }], + ["inspect_wasm_artifact", { path: "/tmp/sample.wasm", glue_paths: [nul] }], + [ + "inspect_wasm_artifact", + { path: "/tmp/sample.wasm", candidate_paths: [nul] }, + ], + ["inspect_evm_interface", { path: nul, encoding: "raw" }], [ "export_web_scripts", { capture_path: "/tmp/capture.json", output_directory: nul },