reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { spawnSync } = require("child_process");
|
||||
const { buildPipeline, detectPatterns, getPattern } = require("./pipeline-config");
|
||||
const { collectMetricsFromFile } = require("./collect-residue-metrics");
|
||||
|
||||
function sanitizeStepName(name) {
|
||||
return String(name).replace(/[^a-z0-9_]+/gi, "_");
|
||||
}
|
||||
|
||||
function runStep(nodePath, step, currentPath, nextPath) {
|
||||
const start = Date.now();
|
||||
const result = spawnSync(nodePath, [step.scriptPath, currentPath, nextPath], {
|
||||
encoding: "utf8",
|
||||
env: process.env,
|
||||
timeout: step.timeoutMs
|
||||
});
|
||||
const durationMs = Date.now() - start;
|
||||
const stdout = result.stdout ? result.stdout.trim() : "";
|
||||
const stderr = result.stderr ? result.stderr.trim() : "";
|
||||
const timedOut = Boolean(result.error && result.error.code === "ETIMEDOUT");
|
||||
return {
|
||||
id: step.id,
|
||||
script: step.script,
|
||||
outputFile: path.basename(nextPath),
|
||||
timeoutMs: step.timeoutMs,
|
||||
durationMs,
|
||||
status: timedOut ? "timed_out" : result.status === 0 ? "ok" : "failed",
|
||||
exitCode: typeof result.status === "number" ? result.status : null,
|
||||
stdout,
|
||||
stderr,
|
||||
error: result.error ? String(result.error.message || result.error) : ""
|
||||
};
|
||||
}
|
||||
|
||||
function copyFile(fromPath, toPath) {
|
||||
fs.copyFileSync(fromPath, toPath);
|
||||
}
|
||||
|
||||
function ensureDir(dirPath) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
|
||||
function main() {
|
||||
const [, , inputPath, outputDir, hint = ""] = process.argv;
|
||||
if (!inputPath || !outputDir) {
|
||||
console.error("Usage: node run-pipeline.js <input.js> <output-dir> [hint]");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const absoluteInput = path.resolve(inputPath);
|
||||
const absoluteOutputDir = path.resolve(outputDir);
|
||||
ensureDir(absoluteOutputDir);
|
||||
|
||||
const sourceText = fs.readFileSync(absoluteInput, "utf8");
|
||||
const detection = detectPatterns({
|
||||
inputPath: absoluteInput,
|
||||
hint,
|
||||
sourceText
|
||||
});
|
||||
const pattern = getPattern(detection.bestId);
|
||||
const pipeline = buildPipeline(pattern.id);
|
||||
|
||||
const report = {
|
||||
inputPath: absoluteInput,
|
||||
outputDir: absoluteOutputDir,
|
||||
hint,
|
||||
selectedPattern: {
|
||||
id: pattern.id,
|
||||
displayName: pattern.displayName,
|
||||
reference: pattern.reference,
|
||||
families: pattern.families,
|
||||
notes: pattern.notes
|
||||
},
|
||||
detections: detection.detections,
|
||||
steps: [],
|
||||
status: "ok",
|
||||
failedStep: null,
|
||||
lastGoodFile: "00_source.js",
|
||||
finalMetrics: null
|
||||
};
|
||||
|
||||
const sourceCopyPath = path.join(absoluteOutputDir, "00_source.js");
|
||||
copyFile(absoluteInput, sourceCopyPath);
|
||||
|
||||
let currentPath = sourceCopyPath;
|
||||
for (let index = 0; index < pipeline.length; index += 1) {
|
||||
const step = pipeline[index];
|
||||
const stepName = `${String(index + 1).padStart(2, "0")}_${sanitizeStepName(step.id)}.js`;
|
||||
const nextPath = path.join(absoluteOutputDir, stepName);
|
||||
const outcome = runStep(process.execPath, step, currentPath, nextPath);
|
||||
report.steps.push(outcome);
|
||||
if (outcome.status !== "ok") {
|
||||
report.status = outcome.status;
|
||||
report.failedStep = step.id;
|
||||
break;
|
||||
}
|
||||
currentPath = nextPath;
|
||||
report.lastGoodFile = stepName;
|
||||
}
|
||||
|
||||
const finalPath = path.join(absoluteOutputDir, "final.js");
|
||||
copyFile(currentPath, finalPath);
|
||||
report.finalMetrics = collectMetricsFromFile(finalPath);
|
||||
|
||||
fs.writeFileSync(path.join(absoluteOutputDir, "selected-patterns.json"), JSON.stringify({
|
||||
bestId: detection.bestId,
|
||||
detections: detection.detections,
|
||||
selectedPattern: report.selectedPattern
|
||||
}, null, 2), "utf8");
|
||||
fs.writeFileSync(path.join(absoluteOutputDir, "pipeline-report.json"), JSON.stringify(report, null, 2), "utf8");
|
||||
process.stdout.write(`${JSON.stringify({
|
||||
status: report.status,
|
||||
selectedPattern: report.selectedPattern.id,
|
||||
failedStep: report.failedStep,
|
||||
lastGoodFile: report.lastGoodFile
|
||||
})}\n`);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
Reference in New Issue
Block a user