@sellable/install
Version:
One-command installer for Sellable MCP in Claude Code, Codex, and Hermes
68 lines (63 loc) • 2.2 kB
JavaScript
import { createHash } from "node:crypto";
const ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
const SHA256 = /^[a-f0-9]{64}$/;
function sha256(value) {
return createHash("sha256").update(value).digest("hex");
}
export function validateEndpointUatCompletionControl(control, claim) {
if (control === null || control === undefined) return null;
const attempt = claim?.attempt;
if (
!control ||
typeof control !== "object" ||
Array.isArray(control) ||
JSON.stringify(Object.keys(control).sort()) !==
JSON.stringify([
"bodyDigest",
"enrollmentId",
"generation",
"releaseAt",
"schemaVersion",
]) ||
control.schemaVersion !== "sellable-agent-endpoint-uat-completion/v1" ||
!ID.test(control.enrollmentId ?? "") ||
!Number.isSafeInteger(control.generation) ||
control.generation < 1 ||
!SHA256.test(control.bodyDigest ?? "") ||
control.bodyDigest !== claim?.run?.inputHash ||
!attempt ||
!Number.isFinite(Date.parse(control.releaseAt)) ||
Date.parse(control.releaseAt) !== Date.parse(attempt.deadlineAt)
) {
throw new Error("customer_endpoint_uat_completion_control_rejected");
}
return Object.freeze({ ...control });
}
export async function holdEndpointUatNativeCompletion(input) {
const control = validateEndpointUatCompletionControl(
input.control,
input.claim
);
if (!control) return input.event;
if (
input.event?.terminal !== true ||
!["COMPLETED", "RUN_COMPLETED"].includes(
input.event.classification ?? input.event.kind
) ||
!SHA256.test(input.event.outputDigest ?? "")
) {
return input.event;
}
const eventDigestBefore = sha256(JSON.stringify(input.event));
while (input.now().getTime() < Date.parse(control.releaseAt)) {
if (input.signal?.aborted) {
throw new Error("customer_endpoint_uat_completion_hold_aborted");
}
const remaining = Date.parse(control.releaseAt) - input.now().getTime();
await input.sleep(Math.min(remaining, 1_000));
}
if (sha256(JSON.stringify(input.event)) !== eventDigestBefore) {
throw new Error("customer_endpoint_uat_completion_mutated");
}
return input.event;
}