mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 16:26:36 +00:00
* 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>
129 lines
4.3 KiB
TypeScript
129 lines
4.3 KiB
TypeScript
import { z } from "zod";
|
|
|
|
import { browserCompletenessSchema } from "./browserCompleteness.js";
|
|
import { browserScenarioCompletenessSchema } from "./browserScenarioCaptureValues.js";
|
|
import { digestSchema, prefixedDigestSchema } from "./digests.js";
|
|
import { absoluteLocalPathStringSchema } from "./localPath.js";
|
|
|
|
/** Export already captured scripts into one absent, caller-selected directory. */
|
|
export const exportWebScriptsInputSchema = z.strictObject({
|
|
capture_path: absoluteLocalPathStringSchema.describe(
|
|
"Absolute filesystem path to saved inspect_web_page or capture_browser_scenario JSON, normalized result or complete Evidence",
|
|
),
|
|
output_directory: absoluteLocalPathStringSchema.describe(
|
|
"Absolute absent filesystem directory for verified scripts and manifest; parent directory must exist",
|
|
),
|
|
});
|
|
export type ExportWebScriptsInput = z.output<
|
|
typeof exportWebScriptsInputSchema
|
|
>;
|
|
|
|
const sourceSchema = z.discriminatedUnion("kind", [
|
|
z.strictObject({
|
|
kind: z.literal("page-script"),
|
|
script_key: z.string().min(1),
|
|
frame_id: z.string().nullable(),
|
|
is_module: z.boolean().nullable(),
|
|
language: z.string().nullable(),
|
|
source_map_url: z.string().nullable(),
|
|
}),
|
|
z.strictObject({
|
|
kind: z.literal("scenario-response"),
|
|
transaction_id: z.string().min(1),
|
|
request_sequence: z.int().min(1),
|
|
response_sequence: z.int().min(1).nullable(),
|
|
status: z.number().nullable(),
|
|
}),
|
|
]);
|
|
|
|
/** Exact retained-source identity and publication outcome. */
|
|
export const exportedWebScriptSchema = z.strictObject({
|
|
source: sourceSchema,
|
|
url: z.string(),
|
|
content: z.discriminatedUnion("state", [
|
|
z.strictObject({
|
|
state: z.literal("exported"),
|
|
relative_path: z.string().min(1),
|
|
layout: z.enum(["url-path", "isolated"]),
|
|
layout_reason: z.string().nullable(),
|
|
sha256: digestSchema,
|
|
bytes: z.int().min(0),
|
|
media_type: z.string().nullable(),
|
|
redacted: z.boolean().nullable(),
|
|
representation: z.enum([
|
|
"debugger-source-utf8",
|
|
"playwright-response-body-bytes",
|
|
// Accept already-saved exports from before the response representation
|
|
// was narrowed to the Playwright API result.
|
|
"browser-decoded-response-bytes",
|
|
]),
|
|
}),
|
|
z.strictObject({
|
|
state: z.literal("unavailable"),
|
|
reason: z.string().min(1),
|
|
message: z.string().min(1),
|
|
}),
|
|
]),
|
|
});
|
|
export type ExportedWebScript = z.output<typeof exportedWebScriptSchema>;
|
|
|
|
/** Persisted manifest, also returned inline without duplicating script bytes. */
|
|
export const webScriptExportManifestSchema = z.strictObject({
|
|
capture_path: z.string().min(1),
|
|
capture_sha256: digestSchema,
|
|
capture_kind: z.enum(["page-inspection", "browser-scenario"]),
|
|
source_evidence_id: prefixedDigestSchema("ev").nullable(),
|
|
capture_completeness: z.union([
|
|
browserCompletenessSchema,
|
|
browserScenarioCompletenessSchema,
|
|
]),
|
|
output_directory: z.string().min(1),
|
|
analysis_input: z
|
|
.strictObject({
|
|
input_path: z.string().min(1),
|
|
format: z.literal("directory"),
|
|
})
|
|
.nullable(),
|
|
scripts: z.array(exportedWebScriptSchema),
|
|
limitations: z.array(z.string()),
|
|
});
|
|
|
|
/** Verified publication including the digest of the persisted manifest. */
|
|
export const webScriptExportResultSchema = webScriptExportManifestSchema.extend(
|
|
{
|
|
manifest: z.strictObject({
|
|
path: z.string().min(1),
|
|
sha256: digestSchema,
|
|
bytes: z.int().min(0),
|
|
}),
|
|
},
|
|
);
|
|
export type WebScriptExportResult = z.output<
|
|
typeof webScriptExportResultSchema
|
|
>;
|
|
|
|
/** Completed publication retained when cleanup fails after durable commit. */
|
|
export interface WebScriptExportPartialObservation {
|
|
readonly kind: "web-script-export";
|
|
readonly result: WebScriptExportResult;
|
|
}
|
|
|
|
/** Adapter input to the provider-neutral path planner and publisher. */
|
|
export interface CapturedWebScript {
|
|
readonly source: ExportedWebScript["source"];
|
|
readonly url: string;
|
|
readonly content:
|
|
| {
|
|
readonly state: "captured";
|
|
readonly bytes: Buffer;
|
|
readonly sha256: string;
|
|
readonly media_type: string | null;
|
|
readonly redacted: boolean | null;
|
|
readonly representation: Extract<
|
|
ExportedWebScript["content"],
|
|
{ readonly state: "exported" }
|
|
>["representation"];
|
|
}
|
|
| Extract<ExportedWebScript["content"], { state: "unavailable" }>;
|
|
}
|