Files
reverse-engineering-anything/src/domain/environmentBundleExport.ts
T
gensokyo-devandEdgar Arakelyan 3fcbabe593 feat(browser): reuse saved response values across scenario steps (#7267)
Save typed response fields and reuse generated IDs or authentication values across browser scenario requests, UI observations and navigation through the shared CLI/MCP workflow.

Preserve exact numbers, retained Evidence, explicit source/coverage limits and prospective page-value semantics. Bound response decoding, retained spellings and request serialization before allocation, and protect marked response values across source records, follow-up text and planned screenshots.

Integrates Edgar Arakelyan's #7162, including follow-ups through 9f5191ab0. Final local validation: 560 feature-branch tests and 561 current-main integration tests, static/build/docs checks and real PocketBase CLI/MCP privacy workflows. Whole-task comparison and verification limits are recorded in docs/verification/browser-saved-values-2026-10-26.md.

Co-authored-by: Edgar Arakelyan <edgar.arakelyan@scale.com>
2026-10-27 08:15:52 +08:00

123 lines
4.2 KiB
TypeScript

import { z } from "zod";
import { environmentCoverageSchema } from "./analysisView/environmentCoverageView.js";
import { TEMPLATE_RULES } from "./analysisView/environmentManifestRules.js";
import { prefixedDigestSchema } from "./digests.js";
import { retainedEvidenceReferenceSchema } from "./evidenceReference.js";
import { absoluteLocalPathStringSchema } from "./localPath.js";
/** Capture Evidence retained in this session, or one capture Evidence file on this host. */
const environmentCaptureSourceSchema = z.discriminatedUnion("kind", [
retainedEvidenceReferenceSchema.describe(
"Capture Evidence this session retained, such as a capture_browser_scenario or inspect_web_network_capture result.",
),
z.strictObject({
kind: z.literal("evidence-file"),
path: absoluteLocalPathStringSchema.describe(
"Absolute path of one capture Evidence JSON file, copied byte for byte into the bundle.",
),
}),
]);
export const exportEnvironmentBundleInputSchema = z.strictObject({
source: environmentCaptureSourceSchema.describe(
"The capture the environment is built from: capture_browser_scenario Evidence, or HAR inspect_web_network_capture Evidence.",
),
output_directory: absoluteLocalPathStringSchema.describe(
"Absolute, absent output directory for the bundle folder; parent must exist.",
),
name: z
.string()
.min(1)
.optional()
.describe(
"Env folder and env id (kebab-case). Default: the manifest's name; required when the capture's origin is a loopback or IP address.",
),
template_rules: z
.array(z.enum(TEMPLATE_RULES))
.optional()
.describe(
"Opt-in template rules, each at most once; [] applies only the format rules. Default: after-uid-literal, opaque-token, sibling-variance and prefix-variance.",
),
package_tarball: absoluteLocalPathStringSchema
.optional()
.describe(
"Absolute path of a packed rea-agents tarball the bundle installs instead of the registry package of this version.",
),
dry_run: z
.boolean()
.default(false)
.describe("Report what the bundle would hold without writing anything."),
});
export type ExportEnvironmentBundleInput = z.infer<
typeof exportEnvironmentBundleInputSchema
>;
/** What a built or planned bundle serves and holds; environment-build prints the same report. */
export const environmentBuildReportSchema = z.strictObject({
status: z.enum(["built", "planned"]),
directory: z.string().nullable(),
name: z.string(),
capture: z.strictObject({
evidence_id: prefixedDigestSchema("ev"),
operation: z.string(),
records: z.int().nonnegative(),
input: z.enum(["har", "evidence"]),
}),
manifest: z.strictObject({
evidence_id: prefixedDigestSchema("ev"),
tools: z.int().nonnegative(),
excluded_groups: z.int().nonnegative(),
template_rules: z.array(z.enum(TEMPLATE_RULES)),
}),
state: z
.union([
z.strictObject({
served: z.literal(true),
evidence_id: z.string(),
}),
z.strictObject({
served: z.literal(false),
reason: z.literal("unavailable"),
code: z.string(),
message: z.string(),
}),
])
.describe(
"Whether the bundle serves from the derived state, or replays and why.",
),
coverage: environmentCoverageSchema
.nullable()
.describe(
"Read tools answered from the state or replayed, and write tools served or withheld; null when the bundle serves replay.",
),
tool_count: z.int().nonnegative(),
package_source: z.union([
z.strictObject({ kind: z.literal("registry"), specifier: z.string() }),
z.strictObject({ kind: z.literal("tarball"), path: z.string() }),
]),
files: z.array(
z.strictObject({ path: z.string(), bytes: z.int().nonnegative() }),
),
warnings: z.array(
z.strictObject({
code: z.enum([
"name-from-file",
"credential-named-members",
"credential-scan-incomplete",
"credential-named-saved-values",
]),
message: z.string(),
pointers: z
.array(z.string())
.describe(
"Where the warning applies, such as record pointers; never values.",
),
}),
),
next: z.array(z.string()),
});
export type EnvironmentBuildReport = z.infer<
typeof environmentBuildReportSchema
>;