fix(mcp): advertise absolute paths for tools that reject relative inputs (#9179)

* fix(mcp): advertise absolute paths for tools that reject relative inputs

The domain schemas accepted relative paths, then handlers rejected them
with isAbsolute. Those inputs now use absoluteLocalPathStringSchema, and
the duplicate handler checks are gone.

* fix(javascript): own recovery path admission in the schema

Relative recovery paths now fail in absoluteLocalPathStringSchema, including
the additional_paths index. Drop the duplicate handler check, and make the
CLI, MCP, and tools/list tests assert that schema fact.

* test: assert absolute-path facts instead of error prose

Recovery and web-script tests keep the field, format code, and regex
expectation. They no longer freeze the schema's explanatory sentence.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
morlutoandCursor Agent authored and GitHub committed 2026-11-07 15:49:50 +08:00
1 parent 923e6f77e3
commit 562779bd71
19 files changed
+180 -131

No files matched your search

@@ -154,7 +154,13 @@ describe("JavaScript recovery workflow", () => {
expect(invoked).toBe(false);
if (result.ok) throw new Error("expected invalid path");
expect(result.error).toMatchObject({
issues: [{ path: ["additional_paths"], reason: "invalid_format" }],
issues: [
{
path: ["additional_paths", 0],
reason: "invalid_format",
expected: "regex",
},
],
});
});
});
@@ -1,10 +1,6 @@
import { parseAnalysisInput } from "../AnalysisInput.js";
import { isAbsolute } from "node:path";
import {
AnalysisInputError,
AnalysisOutputError,
} from "../../domain/analysisErrorCore.js";
import { AnalysisOutputError } from "../../domain/analysisErrorCore.js";
import type { AnalysisError } from "../../domain/analysisErrorBase.js";
import { createEvidence, type Evidence } from "../../domain/evidence.js";
import {
@@ -38,27 +34,6 @@ export class JavaScriptRecoveryService {
options?.signal,
);
if (!parsed.ok) return parsed;
const invalidPaths = (["path", "output_directory"] as const).filter(
(field) => !isAbsolute(parsed.value[field]),
);
const invalidAdditional = (parsed.value.additional_paths ?? []).filter(
(additional) => !isAbsolute(additional),
);
if (invalidPaths.length > 0 || invalidAdditional.length > 0)
return err(
new AnalysisInputError(OPERATION, undefined, [
...invalidPaths.map((field) => ({
path: [field],
reason: "invalid_format" as const,
message: `${field} must be an absolute filesystem path on this host.`,
})),
...invalidAdditional.map((additional) => ({
path: ["additional_paths"],
reason: "invalid_format" as const,
message: `additional_paths entries must be absolute filesystem paths on this host: ${additional}`,
})),
]),
);
const execution = await this.provider.recover(parsed.value, options);
if (!execution.ok) return execution;
const result = javascriptRecoveryResultSchema.safeParse(