@sellable/install
Version:
One-command installer for Sellable MCP in Claude Code, Codex, and Hermes
311 lines (298 loc) • 10 kB
JavaScript
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 });
}