UNPKG

@sellable/install

Version:

One-command installer for Sellable MCP in Claude Code, Codex, and Hermes

311 lines (298 loc) • 10 kB
import { createHash, randomUUID } from "node:crypto"; import { chmodSync, closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync, } from "node:fs"; import { dirname } from "node:path"; const RECOVERY_SCHEMA = "sellable-admin-state-receipt-recovery/v1"; const canonical = (value) => `${JSON.stringify(value, null, 2)}\n`; const sha256 = (value) => createHash("sha256").update(value).digest("hex"); function fail(code) { throw new Error(code); } function regularFile(path, code, { privateMode = false } = {}) { let stat; try { stat = lstatSync(path); } catch { fail(code); } if (stat.isSymbolicLink() || !stat.isFile() || stat.nlink !== 1) fail(code); if (typeof process.getuid === "function" && stat.uid !== process.getuid()) { fail(code); } if (privateMode && (stat.mode & 0o077) !== 0) fail(code); return stat; } function fsyncDirectory(path) { const descriptor = openSync(path, "r"); try { fsyncSync(descriptor); } finally { closeSync(descriptor); } } function atomicPrivateFile(path, bytes) { mkdirSync(dirname(path), { recursive: true, mode: 0o700 }); const temporary = `${path}.tmp.${process.pid}.${randomUUID()}`; const descriptor = openSync(temporary, "wx", 0o600); try { writeFileSync(descriptor, bytes); fsyncSync(descriptor); } finally { closeSync(descriptor); } if (!readFileSync(temporary).equals(Buffer.from(bytes))) { fail("admin_state_generation_temp_readback_rejected"); } renameSync(temporary, path); chmodSync(path, 0o600); fsyncDirectory(dirname(path)); if (!readFileSync(path).equals(Buffer.from(bytes))) { fail("admin_state_generation_readback_rejected"); } } function receiptCore(entry) { const { entryDigest: _entryDigest, ...core } = entry; return core; } function readValidReceipt(path) { regularFile(path, "admin_state_receipt_recovery_receipt_rejected", { privateMode: true, }); let receipt; try { receipt = JSON.parse(readFileSync(path, "utf8")); } catch { fail("admin_state_receipt_recovery_receipt_rejected"); } if ( receipt?.schemaVersion !== 1 || !Array.isArray(receipt.entries) || receipt.entries.length === 0 ) { fail("admin_state_receipt_recovery_receipt_rejected"); } let previousDigest = null; for (const [index, entry] of receipt.entries.entries()) { if ( entry?.sequence !== index + 1 || entry.previousDigest !== previousDigest || !["acquire", "mutation", "release", "reclaim"].includes(entry.kind) || !Number.isFinite(entry.recordedAt) || (entry.stateDigest !== null && !/^[a-f0-9]{64}$/.test(String(entry.stateDigest))) || !entry.owner || !Number.isInteger(entry.owner.pid) || typeof entry.owner.processStart !== "string" || typeof entry.owner.bootIdentity !== "string" || typeof entry.owner.ownerToken !== "string" || typeof entry.owner.fenceToken !== "string" || typeof entry.owner.runId !== "string" || !/^[a-f0-9]{64}$/.test(String(entry.owner.inputHash ?? "")) || !Number.isFinite(entry.ownerAcquiredAt) || sha256(canonical(receiptCore(entry))) !== entry.entryDigest ) { fail("admin_state_receipt_recovery_receipt_rejected"); } previousDigest = entry.entryDigest; } return receipt; } function recoveryPaths(liveStatePath, legacyReceiptDigest = null) { const receiptPath = `${liveStatePath}.receipts.json`; return { receiptPath, markerPath: `${liveStatePath}.receipt-recovery.json`, quarantinePath: legacyReceiptDigest ? `${receiptPath}.quarantine.${legacyReceiptDigest}` : null, }; } function readRecoveryMarker(markerPath) { regularFile(markerPath, "admin_state_receipt_recovery_marker_rejected", { privateMode: true, }); try { return JSON.parse(readFileSync(markerPath, "utf8")); } catch { fail("admin_state_receipt_recovery_marker_rejected"); } } /** Initialize the receipt-owned working state exactly once. */ export function prepareAdminStateGeneration({ deliveredStatePath, liveStatePath, }) { regularFile(deliveredStatePath, "admin_state_generation_delivery_rejected"); const delivered = readFileSync(deliveredStatePath); if (!existsSync(liveStatePath)) { atomicPrivateFile(liveStatePath, delivered); return Object.freeze({ decision: "INITIALIZED", deliveredStateDigest: sha256(delivered), }); } regularFile(liveStatePath, "admin_state_generation_live_rejected", { privateMode: true, }); return Object.freeze({ decision: "PRESERVED", deliveredStateDigest: sha256(delivered), liveStateDigest: sha256(readFileSync(liveStatePath)), }); } /** * Recover only the known legacy raw-copy defect. Unknown state drift remains * closed: the live bytes must be byte-identical to the verified generation. */ export function recoverAdminStateReceiptMismatch({ deliveredStatePath, liveStatePath, failureCode, }) { if (failureCode !== "admin_state_receipt_state_mismatch") { fail("admin_state_receipt_recovery_failure_rejected"); } regularFile( deliveredStatePath, "admin_state_receipt_recovery_delivery_rejected" ); regularFile(liveStatePath, "admin_state_receipt_recovery_state_rejected", { privateMode: true, }); const delivered = readFileSync(deliveredStatePath); const live = readFileSync(liveStatePath); if (!live.equals(delivered)) { fail("admin_state_receipt_recovery_state_rejected"); } const { receiptPath, markerPath } = recoveryPaths(liveStatePath); if (existsSync(markerPath)) { const marker = readRecoveryMarker(markerPath); if ( marker?.schemaVersion !== RECOVERY_SCHEMA || !["PREPARING", "PREPARED"].includes(marker.status) || marker.liveStateDigest !== sha256(live) || marker.deliveredStateDigest !== sha256(delivered) || !/^[a-f0-9]{64}$/.test(String(marker.legacyReceiptDigest ?? "")) || typeof marker.quarantinePath !== "string" || marker.quarantinePath !== recoveryPaths(liveStatePath, marker.legacyReceiptDigest).quarantinePath ) { fail("admin_state_receipt_recovery_marker_rejected"); } if (marker.status === "PREPARING") { if (existsSync(receiptPath)) { readValidReceipt(receiptPath); if (sha256(readFileSync(receiptPath)) !== marker.legacyReceiptDigest) { fail("admin_state_receipt_recovery_receipt_rejected"); } if (existsSync(marker.quarantinePath)) { fail("admin_state_receipt_recovery_quarantine_rejected"); } renameSync(receiptPath, marker.quarantinePath); chmodSync(marker.quarantinePath, 0o600); fsyncDirectory(dirname(receiptPath)); } regularFile( marker.quarantinePath, "admin_state_receipt_recovery_quarantine_rejected", { privateMode: true } ); if ( sha256(readFileSync(marker.quarantinePath)) !== marker.legacyReceiptDigest ) { fail("admin_state_receipt_recovery_quarantine_rejected"); } if (existsSync(receiptPath)) { fail("admin_state_receipt_recovery_receipt_rejected"); } atomicPrivateFile( markerPath, canonical({ ...marker, status: "PREPARED" }) ); } else if (!existsSync(marker.quarantinePath) || existsSync(receiptPath)) { fail("admin_state_receipt_recovery_marker_rejected"); } return Object.freeze({ decision: "PREPARED", markerPath, quarantinePath: marker.quarantinePath, replayed: true, }); } const receipt = readValidReceipt(receiptPath); const latest = receipt.entries.at(-1); if (latest.stateDigest === sha256(live)) { fail("admin_state_receipt_recovery_not_required"); } const receiptBytes = readFileSync(receiptPath); const legacyReceiptDigest = sha256(receiptBytes); const { quarantinePath } = recoveryPaths(liveStatePath, legacyReceiptDigest); const marker = { schemaVersion: RECOVERY_SCHEMA, status: "PREPARING", liveStateDigest: sha256(live), deliveredStateDigest: sha256(delivered), legacyReceiptDigest, quarantinePath, }; atomicPrivateFile(markerPath, canonical(marker)); if (existsSync(quarantinePath)) { fail("admin_state_receipt_recovery_quarantine_rejected"); } renameSync(receiptPath, quarantinePath); chmodSync(quarantinePath, 0o600); fsyncDirectory(dirname(receiptPath)); atomicPrivateFile(markerPath, canonical({ ...marker, status: "PREPARED" })); return Object.freeze({ decision: "PREPARED", markerPath, quarantinePath, replayed: false, }); } /** Seal the migration only after the normal installer recreates a valid chain. */ export function completeAdminStateReceiptRecovery({ liveStatePath }) { const { receiptPath, markerPath } = recoveryPaths(liveStatePath); if (!existsSync(markerPath)) { return Object.freeze({ decision: "NOT_REQUIRED" }); } const marker = readRecoveryMarker(markerPath); if (marker?.schemaVersion !== RECOVERY_SCHEMA) { fail("admin_state_receipt_recovery_marker_rejected"); } if (marker.status === "COMPLETED") { return Object.freeze({ decision: "COMPLETED", replayed: true }); } if (marker.status !== "PREPARED") { fail("admin_state_receipt_recovery_marker_rejected"); } regularFile(liveStatePath, "admin_state_receipt_recovery_state_rejected", { privateMode: true, }); const receipt = readValidReceipt(receiptPath); const liveStateDigest = sha256(readFileSync(liveStatePath)); if (receipt.entries.at(-1)?.stateDigest !== liveStateDigest) { fail("admin_state_receipt_recovery_replacement_rejected"); } const receiptBytes = readFileSync(receiptPath); atomicPrivateFile( markerPath, canonical({ ...marker, status: "COMPLETED", replacementReceiptDigest: sha256(receiptBytes), }) ); return Object.freeze({ decision: "COMPLETED", replayed: false }); }