/** * Gateway wiring for the deploy job: `senpi.deploy.start` / `.status`. * * These two methods are **internal transport** between the `senpi deploy` CLI * verbs and the plugin. They are deliberately absent from the cheatsheet, the * README's agent-facing sections and the skills: one teaching surface (the CLI) * wins routing, and naming the RPCs too would invite raw-RPC calls that bypass * the CLI-side validation. * * The module owns no logic of its own beyond adapting ctx → collaborators: * everything it needs arrives in an explicit {@link DeployGatewayContext}, so it * never reaches into the plugin's boot closure. */ import type { SenpiClient } from "../senpi/client.js"; import { type RegistryEntryLite, type ScannerRowLite } from "./orchestrator.js"; import { type DeployJobController } from "./job.js"; /** * Mirrors `installRuntimeCore`'s return shape (index.ts) without importing the boot closure. * * `payload.unwired` is the unwired phase — the install succeeded, but the runtime has NO live entry * scanners. Deploy reads it as an install failure (it funded a wallet for a runtime that can never * tick); direct gateway/CLI installs keep treating `ok` as ok. */ export type InstallGatewayResult = { ok: true; payload: { id: string; name: string; wallet: string; unwired?: string; }; } | { ok: false; error: { code: string; message: string; }; }; /** The slice of the plugin API this module uses. */ export interface DeployPluginApi { registerGatewayMethod(name: string, handler: (ctx: { respond: (ok: boolean, value: unknown) => void; params?: Record; }) => void | Promise, opts?: { scope?: "operator.write" | "operator.read"; }): void; } /** * Everything the deploy gateway needs from the plugin boot closure, injected * explicitly — register.ts never reaches into index.ts internals. */ export interface DeployGatewayContext { controller: DeployJobController; /** * Runs fn with a fresh connected SenpiClient; always disconnects. One helper, reused per job. * * NOTE: a deploy holds this client for the whole job (up to `maxWait` + `tickWait` + install), * unlike every other call site, which connects per operation. That is deliberate — the create * poll must keep the same session — but it is the seam where an MCP idle/TTL bound would first * surface, as a throw from the poll. That throw is now contained: the orchestrator records the * step `failed` with the message quoted rather than losing the whole report. */ withSenpiClient(fn: (client: SenpiClient) => Promise): Promise; /** = installRuntimeCore */ installRuntime(params: Record): Promise; /** = deleteRuntimeCore — archival/launcher teardown is NOT reimplemented here. */ deleteRuntime(id: string): Promise; registryFindByWallet(wallet: string): Promise; registryFindById(id: string): Promise; getScannerRows(runtimeId: string): Promise; /** H4: does this runtime id have a LIVE handle (not merely a registry row)? */ runtimeIsLive(id: string): Promise; /** = the gateway's in-process install fence; see `installsInFlight` in index.ts. */ installPendingOnWallet(wallet: string): Promise; logger: { info(line: string): void; }; } export interface DeployLiveLayer { strategies: Array<{ strategyName: string; status: string; strategyWalletAddress: string; totalFunded?: number; }>; runtimes: Array<{ id: string; wallet?: string; }>; /** * Set when this layer could not be read at all — the package is gone (moved/deleted) or the * strategy read failed closed (`listStrategies` throws rather than reporting zero). The layer is * then EMPTY, not wrong: the renderer prints the reason instead of "none matching this package", * which over a job that may have funded wallets would be the one claim this layer exists to * prevent. Never set for a genuinely empty result. */ unavailable?: string; } /** Register the internal deploy transport pair. */ export declare function registerDeployGatewayMethods(api: DeployPluginApi, ctx: DeployGatewayContext): void; //# sourceMappingURL=register.d.ts.map