UNPKG

@sellable/install

Version:

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

68 lines (63 loc) • 2.2 kB
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; }