run402-mcp
Version:
MCP server for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.
216 lines • 10.8 kB
TypeScript
/**
* `deploy` namespace — the canonical unified deploy primitive.
*
* Three layers exposed:
* - `apply(spec, opts?)` — one-shot, awaits to completion or terminal failure.
* - `start(spec, opts?)` — returns a `DeployOperation` with `events()` + `result()`.
* - `plan` / `upload` / `commit` — low-level steps for CLI and tests.
*
* All bytes ride through the CAS content service via presigned PUTs to S3.
* The wire body to `POST /apply/v1/plans` carries `ContentRef` objects only —
* never inline file bytes. When the normalized spec exceeds 5 MB JSON, the
* SDK uploads the manifest itself as a CAS object and references it.
*
* Idempotency is keyed on the gateway-computed manifest digest, not the
* SDK's local digest. The SDK does not canonicalize for correctness — the
* gateway is authoritative.
*
* See `unified-deploy` and `cas-content` capability specs for normative
* behavior; this file is the implementation.
*/
import type { Client } from "../kernel.js";
import type { ApplyOptions, ActiveReleaseInventory, DeployEvent, DeployEventsResponse, DeployListOptions, DeployListResponse, DeployOperation, DeployResult, DeployResolveOptions, DeployResolveResponse, EdgeCoherenceReport, EdgeCoherenceWaitOptions, EdgeCoherenceWaitResult, VaultCommitDeclaration, VaultPlanDeclaration, OperationSnapshot, PlanResponse, PromoteOptions, PromoteResult, ReleaseDiffOptions, ReleaseInventory, ReleaseInventoryByIdOptions, ReleaseInventoryOptions, ReleaseSpec, ReleaseToReleaseDiff, RehearsePlanOptions, RehearsePlanResult, StartOptions } from "./deploy.types.js";
export declare class Deploy {
private readonly client;
constructor(client: Client);
/**
* One-shot deploy. Normalizes byte sources, plans, uploads missing
* content, commits, and polls until terminal. Throws
* {@link Run402DeployError} on any state-machine failure.
*/
apply(spec: ReleaseSpec, opts?: ApplyOptions): Promise<DeployResult>;
/**
* Start a resumable deploy operation. Returns an object exposing the
* operation id, an event async-iterable, and a result promise.
*/
start(spec: ReleaseSpec, opts?: StartOptions): Promise<DeployOperation>;
/**
* Low-level plan: normalize the spec, upload the manifest as CAS if over
* the inline limit, and call `POST /apply/v1/plans`. Returns the plan
* response and a byte-reader map keyed by sha256 (used by `upload`).
*/
plan(spec: ReleaseSpec, opts?: {
idempotencyKey?: string;
dryRun?: boolean;
mode?: "legacyDryRun" | "reviewedPlan";
requiredPlan?: {
planId: string;
planFingerprint?: string;
};
/** vault §6.5: bind this plan to a capture (see `runVaultDeploy`). */
vault?: VaultPlanDeclaration;
}): Promise<{
plan: PlanResponse;
byteReaders: Map<string, ByteReader>;
}>;
/**
* Low-level upload: ensure every ref the gateway reported as missing for
* this project has bytes in CAS. Issues a content-plan, PUTs bytes to
* the returned presigned URLs, and finalizes the content plan. Caller
* passes the project id so the apikey-gated CAS routes can authenticate.
*/
upload(plan: PlanResponse, opts: {
project: string;
byteReaders: Map<string, ByteReader>;
onEvent?: (event: DeployEvent) => void;
}): Promise<void>;
/**
* Low-level commit: `POST /apply/v1/plans/:plan_id/commit`, then poll
* `/operations/:id` until terminal. Pass the project id whose anon_key
* should authenticate the polling — the operations endpoint requires
* apikey auth even though the plan/commit endpoints accept SIWX.
*/
commit(planId: string, opts?: {
onEvent?: (event: DeployEvent) => void;
idempotencyKey?: string;
project?: string;
requiredPlan?: {
planId: string;
planFingerprint?: string;
};
/**
* vault §6.5: present the activation token minted for this operation,
* or the audited unvaulted override. A `required` project refuses a
* commit that carries neither.
*/
vault?: VaultCommitDeclaration;
}): Promise<DeployResult>;
rehearse(planId: string, opts?: RehearsePlanOptions): Promise<RehearsePlanResult>;
/**
* Resume an operation in `schema_settling` or `activation_pending`. The
* gateway re-runs only the failed phase forward — never replays SQL.
* Returns the resulting snapshot, polling until terminal. The resume
* endpoint accepts wallet (SIWX) auth; the polling that follows requires
* the project's apikey, so pass `project` to enable polling. (Without
* `project`, this method returns once the gateway accepts the resume
* request — successful resumes typically reach `ready` synchronously
* via the auto-resume worker.)
*/
resume(operationId: string, opts?: {
onEvent?: (event: DeployEvent) => void;
project?: string;
}): Promise<DeployResult>;
/**
* Promote an existing release to be the project's current live release —
* a pointer swap on `internal.projects.live_release_id` without re-running
* the apply pipeline. Designed for recovery from a destructive
* apply ("oops on a real project ID"). The prior release's bytes,
* functions, and migrations remain persisted; this just routes traffic
* back to them.
*
* Surfaces structured warnings via the result envelope:
*
* - `MIGRATIONS_NOT_REVERSIBLE` (requires_confirmation: true) when the
* target release predates migrations applied since. The migrations
* remain applied; the new live release runs against the current
* schema. Ack via `opts.allowWarningCodes`.
*
* - `FUNCTION_VERSION_MISMATCH` (informational) when overlapping
* function names have different code_hashes. The Lambda code is
* whatever's currently $LATEST.
*
* Rejected cases:
* - `PROMOTE_TARGET_NOT_FOUND` — releaseId doesn't exist
* - `PROMOTE_PROJECT_MISMATCH` — releaseId belongs to a different project
* - `PROMOTE_RELEASE_NOT_READY` — release status isn't promotable
* - `PROMOTE_NO_OP` — releaseId IS already the project's current live
* - `PROMOTE_WARNING_REQUIRES_ACK` — at least one blocking warning unacked
*
* Capability: unified-deploy (v1.58+, release-promote).
*/
promote(project: string, releaseId: string, opts?: PromoteOptions): Promise<PromoteResult>;
/**
* Snapshot a deploy operation. The endpoint requires `apikey` auth, so
* pass the project that owns the operation. (When omitted, the request
* is sent without an apikey header and the gateway will return 401.)
*/
status(operationId: string, opts?: {
project?: string;
}): Promise<OperationSnapshot>;
/**
* List recent deploy operations for a project. The endpoint requires
* `apikey` auth, so a project id is required — accepted as a bare string
* (matches `r.functions.list(projectId)` and friends) or as `{ project,
* limit?, cursor? }`. `limit` and `cursor` are forwarded to the gateway
* as query strings when set; the gateway picks a default page otherwise.
*/
list(opts: string | DeployListOptions): Promise<DeployListResponse>;
/**
* Fetch the synthesized phase event stream for an operation. Returns the
* events the gateway has recorded so far — useful for inspecting a deploy
* after the fact, or resuming an event subscription from a different
* process. For live subscription during an in-flight deploy, use
* {@link Deploy.start} and iterate `op.events()`.
*
* The endpoint requires `apikey` auth, so `project` is required.
*/
events(operationId: string, opts: {
project: string;
}): Promise<DeployEventsResponse>;
/**
* Probe whether the gateway and edge pointers agree on the active release
* for an operation. The endpoint requires `apikey` auth, so `project` is
* required. Use `waitEdgeCoherent` when you want bounded polling.
*/
edgeCoherence(operationId: string, opts: {
project: string;
}): Promise<EdgeCoherenceReport>;
/**
* Poll `edgeCoherence` until the report is coherent or the timeout elapses.
* Returns the last report either way so automation can explain stale paths
* without issuing a second request.
*/
waitEdgeCoherent(operationId: string, opts: EdgeCoherenceWaitOptions): Promise<EdgeCoherenceWaitResult>;
/**
* Fetch a release inventory by id. The endpoint requires `apikey` auth, so
* pass the owning project id. `siteLimit` controls how many site paths the
* gateway includes before reporting `site.totals.paths`.
*/
getRelease(opts: ReleaseInventoryByIdOptions): Promise<ReleaseInventory>;
/**
* Fetch the currently active release inventory for a project. If the project
* has not activated a release yet, the gateway returns an empty current-live
* inventory with `release_id: null`.
*/
getActiveRelease(opts: ReleaseInventoryOptions): Promise<ActiveReleaseInventory>;
/**
* Diff two materialized release targets for a project. `from` may be
* `"empty"`, `"active"`, or a release id. `to` may be `"active"` or a
* release id; the gateway treats `"active"` as the current-live target.
*/
diff(opts: ReleaseDiffOptions): Promise<ReleaseToReleaseDiff>;
/**
* Diagnose how a stable public URL or host/path would resolve against the
* current live release. This is an authenticated read: `project` is used
* only for local apikey lookup and is not sent to the gateway.
*/
resolve(opts: DeployResolveOptions): Promise<DeployResolveResponse>;
}
/**
* A deferred byte reader: returns the bytes when called. The `label` is a
* human-readable hint surfaced via `content.upload.progress` events. The
* `contentType` is forwarded to the CAS content service when we issue the
* upload session — same value the spec carried at normalization time.
*/
export interface ByteReader {
(): Promise<Uint8Array>;
label?: string;
contentType?: string;
/** Which spec slice category registered this byte reader. Set by the
* slice-tagged `remember` in `normalizeReleaseSpec` and surfaces on
* `content.upload.*` events so callers can group telemetry by slice.
* Cross-kind CAS dedup escalates the value to `"mixed"`. */
slice?: "release" | "asset" | "mixed";
}
export declare function guessContentType(path: string): string;
//# sourceMappingURL=deploy.d.ts.map