/** * `OutpostsClient` — typed client for the hq-pro `/outpost/*` control plane. * * These are the same routes hq-console's outpost panel calls and the same ones * `hq outposts` drives, so this class is the single implementation of the wire * contract for every first-party surface. * * Portable: the only things it touches are its injected transport, its injected * token source, and `setTimeout`. No Node built-ins, no filesystem, no * `process.exit`, no module-level side effects — safe to import from a Next.js * server action, a route handler, or an edge function. * * Outposts are PERSONAL / caller-scoped: hq-pro keys every route on the caller's * Cognito sub, so no method takes a company. `outpostId` selects a specific box; * omitting it targets the caller's primary slot. * * Every non-2xx throws {@link OutpostHttpError} — nothing is swallowed, and the * server's `step` is preserved so callers can distinguish a retryable * `teardown-incomplete` from a real failure. */ import type { OutpostRequest, OutpostTransport } from "./transport.js"; import type { OutpostExecAsyncResult, OutpostExecResult, OutpostExecStage, OutpostExecSubmission, OutpostSshAccess, OutpostSummary, OutpostTerminalSession, OutpostTerminalStarting, ProvisionOutpostInput } from "./types.js"; /** * A bearer token, or a function that resolves one per request. * * The function form is the important one: hq-cli passes `ensureCognitoToken`, so * a long-lived client re-resolves a refreshed token instead of pinning the one * that happened to be valid at construction. A Next.js app passes a closure over * its session. */ export type OutpostTokenSource = string | (() => string | Promise); export interface OutpostsClientOptions { /** How requests reach the control plane. See `createOutpostTransport`. */ transport: OutpostTransport; /** Bearer token, or a resolver called once per request. */ token: OutpostTokenSource; /** Origin override passed through to the transport on every request. */ baseUrl?: string; } /** Tuning for {@link OutpostsClient.waitForExecResult}. */ export interface WaitForExecOptions { /** First poll delay in ms. Defaults to 500. */ initialPollMs?: number; /** Ceiling for the exponential backoff in ms. Defaults to 5000. */ maxPollMs?: number; /** Abort the wait. The in-flight poll rejects with the abort reason. */ signal?: AbortSignal; } /** The widest AWS-RunShellScript `executionTimeout`, in seconds (48h). */ export declare const EXEC_MAX_TIMEOUT_SECONDS = 172800; export declare class OutpostsClient { private readonly transport; private readonly tokenSource; private readonly baseUrl?; constructor(options: OutpostsClientOptions); /** Resolve the bearer token for one request. */ private token; /** * Authenticated JSON round-trip. Throws {@link OutpostHttpError} on any * non-2xx, decoding hq-pro's `{ error | message, step }` envelope for the * reason plus the two structural envelopes (`billing`, `capped`) that carry no * message at all. */ request(options: Omit): Promise; /** * Provision the caller's Outpost. * * `refreshToken` lets the box authenticate AS the caller — the same body * hq-console's `provisionMyOutpost` sends. It travels over HTTPS and is never * logged. * * No duplicate is ever created: a caller already at their per-person cap gets a * `409` whose body lists their existing boxes, surfaced here as an * `OutpostHttpError` carrying `capped`. hq-pro checks the cap BEFORE activation * billing, so a capped call is never charged. * * A payer with no usable card gets a `402` carrying `billing`. */ provision(input: ProvisionOutpostInput): Promise>; /** Every Outpost the caller owns. */ list(): Promise; /** Live detail for one box. */ status(outpostId?: string): Promise>; /** Enable (or retry) Codex on a box. */ enableCodex(outpostId?: string): Promise>; /** Ask the box to mint a fresh Claude login URL. */ regenerateLoginUrl(outpostId?: string): Promise>; /** * Hand the box the one-time Claude sign-in code from the login URL. hq-pro * stores it as the row's pending code; the box polls for it, feeds it to * `claude`, and flips itself `awaiting-claude-login → ready`. */ submitLoginCode(code: string, outpostId?: string): Promise>; /** * Permanently destroy a box and its cloud resources. * * Idempotent: a `409` / `step: "teardown-incomplete"` means the gateway's * timeout fired while the Lambda kept working. The row is preserved — re-issue * the same call to finish. */ destroy(outpostId?: string): Promise>; /** * Run a one-shot shell command via server-brokered SSM (no SSH). Synchronous, * so it is bounded by the API gateway's ~20s cap — use the submit/result pair * for anything longer. * * A `step: "platform-unsupported"` error means the box is Lightsail and has no * SSM agent; fall back to SSH via {@link sshAccess}. */ exec(command: string, outpostId?: string, runAsRoot?: boolean): Promise; /** Presign an input upload for an asynchronous command. */ stageExecInput(outpostId?: string): Promise; /** Submit an asynchronous command; returns as soon as SSM accepts it. */ submitExec(command: string, outpostId?: string, timeoutSeconds?: number, runAsRoot?: boolean): Promise; /** * Poll an asynchronous command once. Streams arrive only once `done`. * * `signal` aborts the in-flight request itself — not just the caller's wait — * so a slow or hung poll is cancelled rather than left pending. */ fetchExecResult(commandId: string, outpostId?: string, signal?: AbortSignal): Promise; /** * Poll until an asynchronous command reaches a terminal state, backing off * exponentially. * * A `429` is treated as back-pressure and retried — the command is still * running, and giving up on a rate limit would strand a job that is fine. Any * other error propagates. */ waitForExecResult(commandId: string, outpostId?: string, options?: WaitForExecOptions): Promise; /** * Fetch SSH connection info + key for a box and open the caller's IP on its SSH * port. The route exists to reach a Lightsail box, which has no SSM agent. * * The result carries a PEM private key. Treat it as a credential: never log it, * never return it to a browser, and write it only to a mode-0600 file. */ sshAccess(outpostId?: string): Promise; /** * Vend an interactive SSM Session Manager session (or a loopback * port-forward) on a box. A `202` parses as {@link OutpostTerminalStarting} * — the box is starting or its SSM agent has not registered yet; re-call * after `retryAfterSeconds` (the node entry's `waitForTerminalSession` is * the canonical loop). * * The `200` result carries a ONE-TIME session token. Treat it like the SSH * key above: never log it, never return it to a browser — hand it straight * to `session-manager-plugin` (see `outposts/node`'s * `launchSessionManagerPlugin`). */ terminalSession(options?: { outpostId?: string; forward?: { portNumber: number; localPortNumber?: number; }; }): Promise; } //# sourceMappingURL=client.d.ts.map