#!/usr/bin/env node import { spawnSync } from "node:child_process"; import { createHash, randomUUID } from "node:crypto"; import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync, } from "node:fs"; import { tmpdir } from "node:os"; import { basename, dirname, join, relative, resolve, sep } from "node:path"; const DEFAULT_EXCLUDES = [ ".git", ".next", "node_modules", "out", ".env", ".env.local", ".env.production", "*.zip", "*.log", "public/*.apk", ]; function parseArgs(argv) { const args = { apply: false, dryRun: true, config: "mirror/nexus-mirror.config.example.json", }; for (let i = 2; i < argv.length; i += 1) { const item = argv[i]; if (item === "--apply") { args.apply = true; args.dryRun = false; } else if (item === "--dry-run") { args.apply = false; args.dryRun = true; } else if (item === "--config") { args.config = argv[++i]; } else if (item === "--source") { args.source = argv[++i]; } else if (item === "--receipt") { args.receipt = argv[++i]; } else { throw new Error(`Unknown argument: ${item}`); } } return args; } function run(command, args, options = {}) { const result = spawnSync(command, args, { cwd: options.cwd, encoding: "utf8", shell: false, }); if (result.status !== 0) { throw new Error( `${command} ${args.join(" ")} failed with ${result.status}: ${result.stderr || result.stdout}`, ); } return result.stdout.trim(); } function readJson(path) { return JSON.parse(readFileSync(path, "utf8")); } function normalizeRel(path) { return path.split(sep).join("/"); } function escapeRegex(value) { return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"); } function matchesPattern(rel, pattern) { const normalized = normalizeRel(rel); const cleanPattern = pattern.replaceAll("\\", "/"); if (cleanPattern.startsWith("*.")) { return normalized.endsWith(cleanPattern.slice(1)); } if (cleanPattern.endsWith("/*")) { return normalized.startsWith(cleanPattern.slice(0, -1)); } if (cleanPattern.includes("*")) { const regex = new RegExp(`^${cleanPattern.split("*").map(escapeRegex).join(".*")}$`, "u"); return regex.test(normalized); } return normalized === cleanPattern || normalized.startsWith(`${cleanPattern}/`); } function shouldExclude(rel, patterns) { return patterns.some((pattern) => matchesPattern(rel, pattern)); } function ensureInside(child, parent) { const childFull = resolve(child); const parentFull = resolve(parent); if (childFull !== parentFull && !childFull.startsWith(`${parentFull}${sep}`)) { throw new Error(`Path escapes source boundary: ${child}`); } } function copyTree(sourceRoot, targetRoot, includeList, excludeList) { const copied = []; function copyAny(sourcePath) { ensureInside(sourcePath, sourceRoot); const rel = normalizeRel(relative(sourceRoot, sourcePath)); if (rel && shouldExclude(rel, excludeList)) return; const stats = statSync(sourcePath); if (stats.isDirectory()) { for (const entry of readdirSync(sourcePath, { withFileTypes: true })) { copyAny(join(sourcePath, entry.name)); } return; } if (!stats.isFile()) return; const targetPath = join(targetRoot, rel); mkdirSync(dirname(targetPath), { recursive: true }); copyFileSync(sourcePath, targetPath); copied.push(rel); } for (const include of includeList) { const sourcePath = resolve(sourceRoot, include); if (!existsSync(sourcePath)) { throw new Error(`Included path missing: ${include}`); } copyAny(sourcePath); } return [...new Set(copied)].sort(); } function sha256File(path) { const hash = createHash("sha256"); hash.update(readFileSync(path)); return hash.digest("hex").toUpperCase(); } function buildFileManifest(stageRoot, files) { return files.map((rel) => { const path = join(stageRoot, rel); return { path: rel, bytes: statSync(path).size, sha256: sha256File(path), }; }); } function redactUrl(url) { return url.replace(/:\/\/([^/@]+)@/u, "://[REDACTED]@"); } function mirrorTarget(stageRoot, target, branch, dryRun) { const safeTarget = { id: target.id, type: target.type || "generic_git", url: redactUrl(target.url || ""), branch, }; if (!target.enabled) { return { ...safeTarget, status: "SKIPPED_DISABLED" }; } if (!target.url) { return { ...safeTarget, status: "BLOCKED_MISSING_URL" }; } if (dryRun) { return { ...safeTarget, status: "DRY_RUN_NO_PUSH" }; } const remoteName = `mirror_${target.id.replace(/[^A-Za-z0-9_-]/gu, "_")}`; run("git", ["remote", "add", remoteName, target.url], { cwd: stageRoot }); run("git", ["push", remoteName, `HEAD:refs/heads/${branch}`], { cwd: stageRoot }); const remoteHead = run("git", ["ls-remote", target.url, `refs/heads/${branch}`], { cwd: stageRoot, }).split(/\s+/u)[0]; const localHead = run("git", ["rev-parse", "HEAD"], { cwd: stageRoot }); return { ...safeTarget, status: remoteHead === localHead ? "REMOTE_HEAD_MATCH" : "REMOTE_HEAD_MISMATCH", local_head: localHead, remote_head: remoteHead, }; } function main() { const args = parseArgs(process.argv); const configPath = resolve(process.cwd(), args.config); const config = readJson(configPath); const sourceRoot = resolve(process.cwd(), args.source || config.source?.path || "."); const mirrorId = config.mirror_id || `NEXUS_MIRROR_${new Date().toISOString().replace(/[-:.TZ]/gu, "")}`; const runId = `${mirrorId}_${randomUUID()}`; const stageRoot = join(tmpdir(), runId); const receiptRoot = resolve( process.cwd(), args.receipt || config.receipt_dir || "mirror/receipts", ); const includeList = config.source?.include?.length ? config.source.include : ["."]; const excludeList = [...DEFAULT_EXCLUDES, ...(config.source?.exclude || [])]; const branch = config.branch || `nexus-mirror/${new Date().toISOString().slice(0, 19).replace(/[-:T]/gu, "")}`; if (!existsSync(sourceRoot)) { throw new Error(`Source path missing: ${sourceRoot}`); } mkdirSync(stageRoot, { recursive: true }); mkdirSync(receiptRoot, { recursive: true }); const copied = copyTree(sourceRoot, stageRoot, includeList, excludeList); const fileManifest = buildFileManifest(stageRoot, copied); const sourceManifest = { object: "NEXUS_OMEGA_MIRROR_SOURCE_MANIFEST_20260904_R0", generated_at: new Date().toISOString(), source_root: sourceRoot, file_count: fileManifest.length, files: fileManifest, claim_ceiling: "C1_DESCRIPTIVE_ONLY", mirror_limits: [ "MIRROR_RECEIPT_IS_TECHNICAL_INTEGRITY_EVIDENCE_ONLY", "MIRROR_PASS_IS_NOT_HOSTED_CI_PASS", "MIRROR_PASS_IS_NOT_SCIENTIFIC_VALIDATION", "MIRROR_PASS_IS_NOT_PROMOTION", ], }; writeFileSync( join(stageRoot, "NEXUS_MIRROR_MANIFEST.json"), JSON.stringify(sourceManifest, null, 2) + "\n", ); run("git", ["init"], { cwd: stageRoot }); run("git", ["config", "user.name", "NEXUS OMEGA Mirror Tool"], { cwd: stageRoot }); run("git", ["config", "user.email", "mirror@nexus-mobile.de"], { cwd: stageRoot }); run("git", ["checkout", "-b", branch], { cwd: stageRoot }); run("git", ["add", "."], { cwd: stageRoot }); run("git", ["commit", "-m", `NEXUS mirror snapshot ${mirrorId}`], { cwd: stageRoot }); const commit = run("git", ["rev-parse", "HEAD"], { cwd: stageRoot }); const tree = run("git", ["rev-parse", "HEAD^{tree}"], { cwd: stageRoot }); const bundlePath = join(receiptRoot, `${mirrorId}.bundle`); run("git", ["bundle", "create", bundlePath, "HEAD"], { cwd: stageRoot }); const targets = config.mirrors || []; const targetResults = targets.map((target) => mirrorTarget(stageRoot, target, branch, args.dryRun), ); const enabled = targetResults.filter((target) => !target.status.startsWith("SKIPPED")); const failed = enabled.filter( (target) => !["REMOTE_HEAD_MATCH", "DRY_RUN_NO_PUSH"].includes(target.status), ); const overall = failed.length > 0 ? "FAIL_CLOSED" : args.dryRun ? "LOCAL_MIRROR_BUNDLE_READY_DRY_RUN" : "REMOTE_MIRROR_VERIFIED"; const receipt = { object: "NEXUS_OMEGA_MULTI_REMOTE_MIRROR_RECEIPT_20260904_R0", generated_at: new Date().toISOString(), mirror_id: mirrorId, branch, dry_run: args.dryRun, source_root: sourceRoot, stage_root: stageRoot, file_count: fileManifest.length, commit, tree, bundle: { path: bundlePath, bytes: statSync(bundlePath).size, sha256: sha256File(bundlePath), }, targets: targetResults, overall_status: overall, claim_ceiling: "C1_DESCRIPTIVE_ONLY", canonical_limits: { r5_execution: "NOT_STARTED", phase5: "NOT_AUTHORIZED", promotion: "NO", mirror_pass_is_scientific_validation: false, }, }; const receiptPath = join(receiptRoot, `${mirrorId}.receipt.json`); writeFileSync(receiptPath, JSON.stringify(receipt, null, 2) + "\n"); console.log(JSON.stringify({ status: overall, receipt: receiptPath, commit, targets: targetResults.length })); } main();