mirror of
https://github.com/morluto/rea.git
synced 2026-10-27 09:55:46 +00:00
* feat(javascript): recover readable modules with Wakaru Integrate pinned upstream source behind a typed optional recovery port, preserve source identity and producer provenance, and publish verified artifacts for existing JavaScript analysis through CLI and MCP. Add focused real-tool CI with genuine bundler fixtures and bounded resource, cancellation, cleanup, schema and packaged-artifact checks. Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis) Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing) * fix(javascript): align recovery catalog and browser verification Share canonical Wakaru provider identity, describe CLI mode options, and format the new workflow test. Disconnect the real page transport after its observation readiness progress instead of a fixed delay. Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis) Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing) * refactor(javascript): consume the investigation evidence writer Verify that the SDK recovery handler records complete Evidence through the newly shared investigation owner. Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis) * chore(test): account for isolated recovery fixture compilers * fix(javascript): validate recovery paths before acquiring the engine Return field-specific invalid_format diagnostics for relative paths and verify compiled CLI/MCP parity even when the optional engine is unavailable. Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis) Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
105 lines
3.4 KiB
JavaScript
105 lines
3.4 KiB
JavaScript
import { createRequire } from "node:module";
|
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
/** Compile source-owned fixtures using explicitly supplied, pinned toolchains. */
|
|
export async function buildRecoveryFixtures(root, prefix) {
|
|
if (!prefix)
|
|
throw new Error(
|
|
"verify:javascript:recovery requires REA_JAVASCRIPT_FIXTURE_TOOLS pointing to the isolated esbuild/webpack installation",
|
|
);
|
|
const require = createRequire(join(prefix, "package.json"));
|
|
const esbuild = require("esbuild");
|
|
const webpack = require("webpack");
|
|
const webpackVersion = require("webpack/package.json").version;
|
|
if (esbuild.version !== "0.25.10" || webpackVersion !== "5.101.3")
|
|
throw new Error(
|
|
"Fixture compilers must be esbuild 0.25.10 and webpack 5.101.3",
|
|
);
|
|
const source = fileURLToPath(
|
|
new URL("../fixtures/javascript-recovery/entry.mjs", import.meta.url),
|
|
);
|
|
const webpackOutput = join(root, "webpack");
|
|
await mkdir(webpackOutput);
|
|
await new Promise((resolve, reject) => {
|
|
const compiler = webpack({
|
|
mode: "production",
|
|
entry: source,
|
|
parallelism: 1,
|
|
optimization: { concatenateModules: false },
|
|
output: { path: webpackOutput, filename: "bundle.js" },
|
|
});
|
|
compiler.run((error, stats) => {
|
|
compiler.close((closeError) => {
|
|
if (error || closeError) return reject(error ?? closeError);
|
|
if (!stats || stats.hasErrors())
|
|
return reject(new Error(stats?.toString() ?? "No webpack stats"));
|
|
resolve();
|
|
});
|
|
});
|
|
});
|
|
const esbuildPath = join(root, "esbuild.js");
|
|
await esbuild.build({
|
|
entryPoints: [source],
|
|
outfile: esbuildPath,
|
|
bundle: true,
|
|
format: "iife",
|
|
minify: true,
|
|
logLevel: "silent",
|
|
});
|
|
// One self-contained source fixture avoids unresolved imports in the oracle.
|
|
const helperSource = await readFile(
|
|
fileURLToPath(
|
|
new URL("../fixtures/javascript-recovery/helpers.mjs", import.meta.url),
|
|
),
|
|
"utf8",
|
|
);
|
|
const plain = await esbuild.transform(
|
|
helperSource.replaceAll("export ", "") +
|
|
"\nglobalThis.recoveryFixture = {greet, total};",
|
|
{ minify: true },
|
|
);
|
|
const minifiedPath = join(root, "minified.js");
|
|
await writeFile(minifiedPath, plain.code);
|
|
if (plain.code.length === 0)
|
|
throw new Error("Expected a real minifier output");
|
|
return {
|
|
files: [
|
|
{
|
|
name: "minified",
|
|
path: minifiedPath,
|
|
expectedFormat: "unknown",
|
|
expectedModules: 1,
|
|
},
|
|
{
|
|
name: "webpack",
|
|
path: join(webpackOutput, "bundle.js"),
|
|
expectedFormat: "webpack5",
|
|
expectedModules: 2,
|
|
},
|
|
{
|
|
name: "esbuild-scope-hoisted",
|
|
path: esbuildPath,
|
|
expectedFormat: "unknown",
|
|
expectedModules: 1,
|
|
},
|
|
{
|
|
name: "heuristic-aggressive",
|
|
path: minifiedPath,
|
|
expectedFormat: "unknown",
|
|
expectedModules: 1,
|
|
options: { extraction_mode: "heuristic", rewrite_level: "aggressive" },
|
|
},
|
|
{
|
|
name: "inspection-minimal",
|
|
path: join(webpackOutput, "bundle.js"),
|
|
expectedFormat: "webpack5",
|
|
expectedModules: 2,
|
|
options: { extraction_mode: "inspection", rewrite_level: "minimal" },
|
|
},
|
|
],
|
|
toolchains: { esbuild: esbuild.version, webpack: webpackVersion },
|
|
};
|
|
}
|