import { Flow, PreviewKey, Elb, Ingest, WalkerOS, Simulation, ObserveWeb } from '@walkeros/core'; export { Flow } from '@walkeros/core'; import { BuildOptions as BuildOptions$1 } from 'esbuild'; import { z } from '@walkeros/core/dev'; import * as openapi_fetch from 'openapi-fetch'; /** * CLI Build Configuration * * CLI-specific build options for walkerOS bundle generation. * Uses Flow.Json (root) and Flow (single flow) from @walkeros/core for config structure. * * @packageDocumentation */ /** * CLI-specific build options (public API). * * @remarks * These are CLI-only options not part of the config file. * The config file uses Flow.Json from @walkeros/core. * * Platform-derived defaults: * - web: format=iife, target=es2020, platform=browser * - server: format=esm, target=node18, platform=node */ interface CLIBuildOptions extends Pick { /** * Output file path (CLI argument, not in config). * @default "./dist/walker.js" (web) or "./dist/flow.mjs" (server) */ output?: string; /** * Temporary directory for build artifacts. * @default ".tmp" */ tempDir?: string; /** * Enable package caching. * @default true */ cache?: boolean; /** * User code to include in bundle. */ code?: string; } /** * Internal build options used by the bundler. * * @remarks * Combines CLI options with resolved esbuild settings. * This is populated after processing config and CLI arguments. */ interface BuildOptions extends CLIBuildOptions { /** * Output file path (required for bundler). */ output: string; /** * Packages to include in the bundle. */ packages: Record; /** * Transitive dependency version overrides. * Flat `Record` matching npm's `overrides` semantics. * Only substitutes transitive specs; direct package specs always win. */ overrides?: Record; /** * Extra paths or globs the bundler must include in the trace output. * Sourced from `flow..config.bundle.traceInclude`. Resolved against * the bundler install root before being passed to the file tracer. Globs * (entries containing `*`, `?`, `[`, or `{`) are expanded via picomatch. */ traceInclude?: string[]; /** * Output format. */ format: 'esm' | 'iife' | 'cjs'; /** * Target platform. */ platform: 'browser' | 'node'; /** * Enable minification. * @default true */ minify?: boolean; /** * Enable source maps. * @default false */ sourcemap?: boolean; /** * ECMAScript target version. */ target?: string; /** * Minification options. */ minifyOptions?: MinifyOptions; /** * Window property name for collector (web platform only). * @default "collector" */ windowCollector?: string; /** * Window property name for elb function (web platform only). * * @deprecated The browser source is the single writer of * `window[settings.elb]`. Set the browser source's `config.settings.elb` * instead. The CLI forwards `flow.config.settings.windowElb` onto that field * during bundling for backward compatibility, but emits no window assignment * of its own. * @default "elb" */ windowElb?: string; /** * Skip platform wrapper (Step 2) and output raw ESM. * Used by CLI push for direct import of the bundled module. * * @deprecated Use `target` option instead. `skipWrapper` conflates skeleton * emission with /dev schema inclusion. See `BundleTarget` presets * (`cdn` | `cdn-skeleton` | `runner` | `simulate` | `push`). * Will be removed in the next major release. * * @default false */ skipWrapper?: boolean; /** * Include `@walkeros/*\/dev` imports for schema validation / simulate / push. * Derived from the resolved `BundleTarget` preset by `bundle()`. * If undefined, falls back to `skipWrapper === true` for backward compatibility * with direct `bundleCore` callers (push, simulate) and legacy callers. * @internal */ withDev?: boolean; /** * Gates browser `/dev` externalization. Derived from the resolved * `BundleTarget` preset by `bundle()`. * * When `true` (deploy skeletons), each `/dev` is externalized so the lazy * registry stays a literal `import('/dev')` and the deploy wrap DCEs the * /dev graph to zero bytes. When `false`/undefined (in-process simulate/push), * `/dev` is inlined so the lazy thunk resolves an already-bundled module * with no host node_modules lookup. Node platform ignores this flag (it always * externalizes step packages, which prefix-covers `/dev`). * @internal */ externalizeDev?: boolean; /** * Folders to include in the output directory. * These folders are copied alongside the bundle for runtime access. * @default ["./shared"] if folder exists */ include?: string[]; /** * Base directory for resolving include paths. * Typically the directory containing the config file. */ configDir?: string; } /** * Minification options. * * @remarks * Controls esbuild's minification behavior. */ interface MinifyOptions { /** * Minify identifiers (variable names). * @default true */ identifiers?: boolean; /** * Minify syntax (shorten code). * @default true */ syntax?: boolean; /** * Minify whitespace. * @default true */ whitespace?: boolean; /** * Keep original function/class names. * @default false */ keepNames?: boolean; /** * How to handle legal comments. * @default "none" */ legalComments?: 'none' | 'inline' | 'eof' | 'linked' | 'external'; } interface BundleStats { totalSize: number; packages: { name: string; }[]; buildTime: number; treeshakingEffective: boolean; } /** * Build the wireConfig data payload for a flow as a plain object. * * This is the same object the bundler bakes into a skeleton as * `__configData` (section, step id, data-layer props), produced by the * same classification pass the bundler uses. Callers that inject data at * simulate time (the `data` option of the simulate functions) must build * the FULL payload from the FULL config with this helper; injection * replaces the baked payload, it does not merge. * * Mirrors the bundler's own call path (`detectNamedImports` feeding * `buildSplitConfigObject`) so the result stays identical to the baked * payload by construction. */ declare function buildDataPayload(flowSettings: Flow): Record; /** * Generate a stage 2 entry file for wrapping an ALREADY-embedded skeleton. * * Unlike `generateWebEntry`, this variant imports `__configData` from the * skeleton (instead of inlining a `dataPayload` string). Used by the * publish-time `wrapSkeleton` helper, which runs on a stage 1 skeleton * produced via `bundle({ skipWrapper: true })` — those skeletons already * export `__configData` alongside `wireConfig` and `startFlow`. */ /** * Preview activation wiring. When present and enabled, the generated entry * imports the activator from core and lets it decide whether a preview bundle * boots in place of this flow. The bundle carries only PUBLIC values: a keyring, * an issuer, and opaque bindings. Never a project id, never a secret. */ interface WrapEntryPreview { enabled: boolean; keyring: PreviewKey[]; iss: string; /** Opaque project binding. Omitted only on demo hosts. */ pb?: string; /** Demo hosts only: accept another project's preview, confined to demoAllowlist. */ acceptForeign?: boolean; demoAllowlist?: string[]; /** Bare CDN hostname. */ previewOrigin: string; } /** * Named bundle targets with frozen presets. * * A target is the ONLY input callers should pass. All internal booleans * (skipWrapper, withDev, platform, env injection) derive from the preset. * This prevents the class of bug where the same boolean means different * things in different code paths (see: skipWrapper conflation, 2026-04-16). */ type BundleTarget = 'cdn' | 'cdn-skeleton' | 'runner' | 'simulate' | 'push'; interface BundleCommandOptions { config?: string; output?: string; flow?: string; all?: boolean; stats?: boolean; json?: boolean; cache?: boolean; verbose?: boolean; silent?: boolean; /** Config release id baked into config.collector.release (set-if-absent). */ release?: string; } declare function bundleCommand(options: BundleCommandOptions): Promise; /** * High-level bundle function for programmatic usage. * * Handles configuration loading, parsing, and logger creation internally. * * @param configOrPath - Bundle configuration (Flow.Json) or path to config file * @param options - Bundle options * @param options.silent - Suppress all output (default: false) * @param options.verbose - Enable verbose logging (default: false) * @param options.stats - Collect and return bundle statistics (default: false) * @param options.cache - Enable package caching (default: true) * @param options.flowName - Flow to use (required for multi-flow configs) * @returns Bundle statistics if stats option is true, otherwise void * * @example * ```typescript * // With Flow.Json config object * await bundle({ * version: 4, * flows: { * default: { * config: { * platform: 'web', * bundle: { packages: { '@walkeros/collector': { imports: ['startFlow'] } } }, * }, * destinations: { api: { code: 'destinationApi' } }, * } * } * }); * * // With config file * await bundle('./walker.config.json', { stats: true }); * ``` */ declare function bundle(configOrPath: unknown, options?: { silent?: boolean; verbose?: boolean; stats?: boolean; cache?: boolean; flowName?: string; /** * Config release id baked into `config.collector.release` (set-if-absent), * stamping this flow's entry in `event.source.release` at runtime. */ release?: string; /** * Named bundle target. If omitted, falls back to * `buildOverrides.skipWrapper` mapping (deprecated) or `'cdn'`. */ target?: BundleTarget; buildOverrides?: Partial; }): Promise; /** * Input Detector * * Detects whether CLI input is a config JSON or pre-built bundle. * Supports both local files and URLs. */ type Platform = 'web' | 'server'; /** * Resolve a bearer for an API call, refreshing the stored session when needed. * * Priority: `WALKEROS_TOKEN`, then a legacy static token, then the OAuth * session. Returns null when nothing can be resolved, which callers render as * "run `walkeros auth login`". * * Throws when a refresh was needed but could not be carried out, which is a * different problem from having no session and must not be reported as one. */ declare function resolveAccessToken(opts?: { fetch?: typeof fetch; now?: () => number; }): Promise; /** * Authorization header for the resolved credential, or an empty object when * there is none. Async because resolving may have to refresh the session. */ declare function getAuthHeaders(): Promise>; /** * Where a credential would come from, without resolving or refreshing it. * For commands that want to send someone to `walkeros auth login` before spending * a network round trip. */ declare function credentialSource(): 'env' | 'config' | null; declare function requireProjectId(): string; /** * Merge a bearer token into a headers object. * Shared by apiFetch, deployFetch, and runtime callers that manage their own tokens. */ declare function mergeAuthHeaders(token: string | null | undefined, headers?: HeadersInit): Record; /** * Authenticated fetch — resolves base URL + adds auth token. * Use for all API calls that require WALKEROS_TOKEN. * * The transport is checked only once a credential is actually going out. * `resolveAppUrl` keeps answering with whatever is configured, which is what * the paths that merely REPORT the target (diagnostics, health, telemetry) * need from it. */ declare function apiFetch(path: string, init?: RequestInit): Promise; /** * Unauthenticated fetch — resolves base URL, no auth. * Use for public endpoints (login device flow, feedback). */ declare function publicFetch(path: string, init?: RequestInit): Promise; /** * Deploy-authenticated fetch — uses deploy token with fallback to user token. * Use for runtime operations (heartbeat, config polling, secrets). */ declare function deployFetch(path: string, init?: RequestInit): Promise; interface SSEEvent { type: string; data: string; } interface SSEParseResult { parsed: SSEEvent[]; remainder: string; } declare function parseSSEEvents(buffer: string): SSEParseResult; /** Captured network call from polyfilled fetch/sendBeacon during simulation */ interface NetworkCall { type: 'fetch' | 'beacon'; url: string; method?: string; body?: string | null; headers?: Record; timestamp: number; } /** * Push command options */ interface PushCommandOptions { config?: string; event: string; output?: string; flow?: string; json?: boolean; verbose?: boolean; silent?: boolean; platform?: 'web' | 'server'; simulate?: string[]; mock?: string[]; snapshot?: string; /** * Pipeline context a simulated transformer reads via `ctx.ingest` (e.g. a * request decoder reads `ingest.url`). Forwarded to `simulateTransformer`. */ ingest?: Omit; } /** * Push execution result */ interface PushResult { success: boolean; elbResult?: Elb.PushResult; /** Network calls captured during web simulation (fetch + sendBeacon) */ networkCalls?: NetworkCall[]; duration: number; error?: string; } /** * Push Command Schemas * * Zod schemas for push command parameter validation. */ /** * Push options schema. * * @remarks * Options for the programmatic push() API. */ declare const PushOptionsSchema: z.ZodObject<{ silent: z.ZodOptional; verbose: z.ZodOptional; json: z.ZodOptional; }, z.core.$strip>; type PushOptions = z.infer; /** * CLI command handler for push command. * * Thin wrapper around `runPushCommand`: delegates result production to the * pure helper, then formats output and decides the exit code. Tests target * `runPushCommand` directly to avoid `process.exit` killing Jest workers. */ declare function pushCommand(options: PushCommandOptions): Promise; /** * High-level push function for programmatic usage. * * WARNING: This makes real API calls to real endpoints. * Events will be sent to configured destinations (analytics, CRM, etc.). * * @param configOrPath - Path to flow configuration file or pre-built bundle * @param event - Event object to push * @param options - Push options * @param options.silent - Suppress all output (default: false) * @param options.verbose - Enable verbose logging (default: false) * @param options.json - Format output as JSON (default: false) * @returns Push result with success status, elb result, and duration * * @example * ```typescript * const result = await push('./walker.config.json', { * name: 'page view', * data: { title: 'Home Page', path: '/', url: 'https://example.com' } * }); * ``` */ declare function push(configOrPath: string | unknown, event: unknown, options?: PushOptions & { flow?: string; platform?: Platform; mock?: string[]; snapshot?: string; }): Promise; /** * Shared data-injection seam for all simulate functions. */ interface SimulateDataOptions { /** * Wire-config data payload to execute instead of the bundle's baked * `__configData`. Shape: the split-config data payload the bundler * emits (section, step id, data-layer props), as built by * `buildDataPayload`. * * The payload REPLACES the baked data, there is no deep-merge: build * the full payload from the full config. Injection granularity follows * the skeleton's `__data` references, which are emitted per TOP-LEVEL * step prop. Changed values for any nested key under an existing * top-level data prop (e.g. a new entity-action rule inside an existing * `mapping`) take effect without a rebundle. An entirely NEW top-level * data prop on a step has no `__data` reference in the skeleton, so it * is IGNORED by injection and requires a rebundle. */ data?: Record; } interface SimulateSourceOptions extends SimulateDataOptions { sourceId: string; bundlePath?: string; flow?: string; silent?: boolean; verbose?: boolean; snapshot?: string; } /** * Self-contained source simulation. * * Loads the flow config, bundles it, resolves the source package's /dev export * to get createTrigger, then invokes the trigger inside a flow context with a * prePush hook that captures events before they reach destinations. * * The `input` parameter is `unknown` — the CLI is agnostic to source-specific * content shapes. The source's createTrigger defines what it expects. */ declare function simulateSource(configOrPath: string | Flow.Json, input: unknown, options: SimulateSourceOptions): Promise; interface SimulateTransformerOptions extends SimulateDataOptions { transformerId: string; bundlePath?: string; flow?: string; mock?: string[]; silent?: boolean; verbose?: boolean; snapshot?: string; /** * Pipeline context the transformer reads via `ctx.ingest` (e.g. a decoder * reads `ingest.url`). Merged onto a fresh ingest so `_meta` is always * present; provide only the keys the step reads. */ ingest?: Omit; } /** * Self-contained transformer simulation. * * Takes a DeepPartialEvent, validates it with Zod, loads the flow config, * bundles it, starts the flow to get initialized transformers, then runs * the event through the target transformer (with optional before chain). * * Captured array: first entry = input event, subsequent entries = output event(s). * If the transformer drops the event (returns false), output event is null. */ declare function simulateTransformer(configOrPath: string | Flow.Json, event: WalkerOS.DeepPartialEvent, options: SimulateTransformerOptions): Promise; interface SimulateCollectorOptions extends SimulateDataOptions { collectorName: string; bundlePath?: string; flow?: string; silent?: boolean; verbose?: boolean; snapshot?: string; state?: { consent?: WalkerOS.Consent; user?: WalkerOS.User; globals?: WalkerOS.Properties; timing?: number; }; } /** * Self-contained collector enrichment simulation. * * Takes a post-next `DeepPartialEvent` and an optional collector-state * snapshot, then returns the fully enriched event the runtime produces between * the pre-collector `next` chain and the post-collector `before` chain. Reuses * the runtime's own enrichment (`enrichEvent`); it does not reimplement it. */ declare function simulateCollector(configOrPath: string | Flow.Json, event: WalkerOS.DeepPartialEvent, options: SimulateCollectorOptions): Promise; interface SimulateDestinationOptions extends SimulateDataOptions { destinationId: string; bundlePath?: string; flow?: string; mock?: string[]; silent?: boolean; verbose?: boolean; snapshot?: string; } /** * Self-contained destination simulation. * * Takes a DeepPartialEvent, validates it with Zod, loads the flow config, * bundles it, starts the flow, then pushes via collector.push with an include * filter so only the target destination receives the event. This gives full * pipeline support — consent checks, event mapping, createEvent enrichment, * before chains — without manual wiring. */ declare function simulateDestination(configOrPath: string | Flow.Json, event: WalkerOS.DeepPartialEvent, options: SimulateDestinationOptions): Promise; /** * Run Command Types * * Types for running walkerOS flows via CLI or Docker. */ /** * CLI command options for `walkeros run` */ interface RunCommandOptions { /** Flow configuration file path (.json or pre-built .mjs) */ config?: string; /** Server port (overrides flow config) */ port?: number; /** Flow name for multi-flow configs */ flow?: string; /** API flow ID (enables heartbeat, polling, secrets) */ flowId?: string; /** Deployment ID (for heartbeat tracking) */ deploymentId?: string; /** Project ID */ project?: string; /** Opt-in dotenv file to load into process.env before config resolution */ envFile?: string; /** Enable JSON output */ json?: boolean; /** Verbose logging */ verbose?: boolean; /** Suppress output */ silent?: boolean; } /** * Programmatic run options */ interface RunOptions { /** Flow configuration file path (.json or pre-built .mjs) */ config?: string; /** Server port */ port?: number; /** Flow name for multi-flow configs */ flow?: string; /** API flow ID (enables heartbeat, polling, secrets) */ flowId?: string; /** Project ID */ project?: string; /** Verbose logging */ verbose?: boolean; /** Suppress output */ silent?: boolean; } /** * Result from running a flow */ interface RunResult { /** Whether the flow ran successfully */ success: boolean; /** Exit code */ exitCode: number; /** Error message if failed */ error?: string; /** Execution duration in milliseconds */ duration: number; } /** * Run Command * * Unified entry point for running walkerOS flows. * Used by both `walkeros run` (CLI) and Docker containers. */ /** * CLI command function for `walkeros run` */ declare function runCommand(options: RunCommandOptions): Promise; /** * Programmatic run function */ declare function run(options: RunOptions): Promise; type ValidationType = 'contract' | 'event' | 'flow' | 'mapping'; type ValidateResultType = ValidationType | 'entry'; interface ValidateCommandOptions { type: ValidationType; input?: string; output?: string; flow?: string; path?: string; json?: boolean; verbose?: boolean; strict?: boolean; silent?: boolean; } interface ValidationError { path: string; message: string; value?: unknown; code?: string; } interface ValidationWarning { path: string; message: string; suggestion?: string; code?: string; } interface ValidateResult { valid: boolean; type: ValidateResultType; errors: ValidationError[]; warnings: ValidationWarning[]; details: Record; } /** * Programmatic API for validation. * Can be called directly from code or MCP server. * * Accepts parsed objects, JSON strings, file paths, or URLs as input. */ declare function validate(type: ValidationType, input: unknown, options?: { flow?: string; path?: string; strict?: boolean; }): Promise; /** * CLI command handler for validate command. */ declare function validateCommand(options: ValidateCommandOptions): Promise; /** * Global CLI Options * * Options that apply to all commands. */ /** * Global options available across all CLI commands */ interface GlobalOptions { /** * Show detailed execution logs * @default false */ verbose?: boolean; /** * Suppress all output except errors * @default false */ silent?: boolean; } interface LoginCommandOptions extends GlobalOptions { url?: string; json?: boolean; } interface LoginResult { success: boolean; email?: string; configPath?: string; error?: string; } interface LoginOptions { url?: string; /** Override browser opener for testing */ openUrl?: (url: string) => Promise; /** Override fetch for testing */ fetch?: typeof globalThis.fetch; /** Max poll attempts before giving up (for testing) */ maxPollAttempts?: number; /** Poll interval, replacing the server's stated one (for testing) */ pollIntervalMs?: number; } /** * The outcome of finishing a device authorization. * * It carries no token material. `completeDeviceLogin` stores the session * itself, so the credential file keeps exactly one writer and a caller can * neither persist nor leak what came back. * * `pending` and `slow_down` both mean the window closed with the approval * still outstanding: the device code is untouched, so the same code can be * handed back in. `slow_down` is that same situation with the server asking * for a wider gap before the next attempt. */ type DeviceLoginResult = { status: 'ok'; } | { status: 'pending'; } | { status: 'slow_down'; } | { status: 'denied'; } | { status: 'expired'; } | { status: 'error'; error: string; }; interface CompleteDeviceLoginOptions { /** App to poll. Defaults to the resolved app URL. */ url?: string; /** Stop polling after this long. */ timeoutMs?: number; /** Wait between polls, before any `slow_down` widens it. */ intervalMs?: number; /** Override fetch for testing */ fetch?: typeof globalThis.fetch; /** Max poll attempts before giving up (for testing) */ maxPollAttempts?: number; } declare function loginCommand(options: LoginCommandOptions): Promise; /** * Poll a device authorization to its end and store the session it yields. * * Split out from `login` so a caller holding only a device code can finish an * authorization that is already under way. `login` cannot serve that: it * starts a fresh authorization on every call, which would strand the code the * person is looking at. */ declare function completeDeviceLogin(deviceCode: string, options?: CompleteDeviceLoginOptions): Promise; declare function login(options?: LoginOptions): Promise; interface LogoutCommandOptions extends GlobalOptions { json?: boolean; } declare function logoutCommand(options: LogoutCommandOptions): Promise; interface LogoutResult { deleted: boolean; /** A different session reached the config while the revocation was in flight. */ superseded: boolean; } /** * Revoke the stored refresh token, then drop the local config. * * Revocation first, because deleting the file alone would leave a credential * alive on the server that nothing can ever reach to retire. It is best * effort: a logout on a plane still has to clear the machine. */ declare function logout(): Promise; declare function whoami(): Promise<{ userId: string; email: string; projectId: string | null; }>; interface WhoamiCommandOptions extends GlobalOptions { json?: boolean; output?: string; } declare function whoamiCommand(options: WhoamiCommandOptions): Promise; interface ListProjectsOptions { cursor?: string; limit?: number; } declare function listProjects(options?: ListProjectsOptions): Promise<{ projects: { id: string; name: string; role: "owner" | "admin" | "member" | "deployer" | "viewer"; createdAt: string; updatedAt: string; memberCount: number; flowCount: number; deploymentCount: number; isDemo: boolean; }[]; total: number; nextCursor: string | null; }>; declare function getProject(options?: { projectId?: string; }): Promise<{ id: string; name: string; siteUrl?: string | null | undefined; role: "owner" | "admin" | "member" | "deployer" | "viewer"; }>; declare function createProject(options: { name: string; }): Promise<{ id: string; name: string; createdAt: string; }>; declare function updateProject(options: { projectId?: string; name: string; }): Promise<{ id: string; name: string; updatedAt: string; }>; declare function deleteProject(options?: { projectId?: string; }): Promise<{ success: boolean; }>; interface ProjectsCommandOptions extends GlobalOptions { json?: boolean; output?: string; project?: string; name?: string; cursor?: string; limit?: number; } declare function listProjectsCommand(options: ProjectsCommandOptions): Promise; declare function getProjectCommand(projectId: string | undefined, options: ProjectsCommandOptions): Promise; declare function createProjectCommand(name: string, options: ProjectsCommandOptions): Promise; declare function updateProjectCommand(projectId: string | undefined, options: ProjectsCommandOptions): Promise; declare function deleteProjectCommand(projectId: string | undefined, options: ProjectsCommandOptions): Promise; /** * This file was auto-generated by openapi-typescript. * Do not make direct changes to the file. */ interface paths { '/api/auth/magic-link': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Request magic link * @description Send a magic link to the provided email address for passwordless authentication. Always returns success to prevent email enumeration. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['MagicLinkRequest']; }; }; responses: { /** @description Magic link sent (or would be sent if email exists) */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['MagicLinkResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/auth/verify': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Legacy magic link entry point * @description Side-effect-free redirector to the /auth/verify page for links minted before the page-URL change. Never consumes the token; redemption happens via POST. */ get: { parameters: { query: { /** @description Magic link token */ token: string; /** @description Redirect URL after verification */ redirect_to?: string; }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Redirect to the /auth/verify page with the token forwarded */ 307: { headers: { [name: string]: unknown; }; content?: never; }; }; }; put?: never; /** * Redeem magic link token * @description Redeem a magic link token and create an authenticated session. Redeems immediately when the browser-nonce cookie from the magic-link request matches; otherwise answers confirm_required and expects a follow-up call with confirm: true. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['VerifyRequest']; }; }; responses: { /** @description Redemption result. status=ok sets the session cookie and carries the redirect target. */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['VerifyResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/auth/logout': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * End session * @description Destroy the current session and clear the session cookie. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Redirect to login page */ 302: { headers: { [name: string]: unknown; }; content?: never; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/auth/whoami': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Current identity * @description Return the identity of the authenticated user. Supports session cookie and Bearer token. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Current user identity */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['WhoamiResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/account': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Delete own account * @description Soft-delete the authenticated account, starting the 30-day grace window. Requires a confirmation of the account email in the body. Revokes all sessions, API tokens, and MCP tokens. Blocked with 409 when the caller is the sole owner of a project that still has other members. */ delete: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['DeleteAccountRequest']; }; }; responses: { /** @description Account scheduled for deletion */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Confirmation email does not match */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Sole owner of a shared project */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeleteAccountBlocked']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/account/export': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Export own account data * @description Download a portable JSON export of everything the platform holds about the authenticated account: profile, memberships, token and session metadata, MCP sessions with messages, feedback, and invitations. Metadata only; token hashes and secret values are never included. Served as a file attachment. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Account data export (file attachment) */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['AccountExportResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/sessions': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List sessions * @description List all active sessions for the authenticated user. The current session is marked with isCurrent: true. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description List of active sessions */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListSessionsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/sessions/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Revoke session * @description Revoke a session by ID. Cannot revoke the current session (use logout instead). */ delete: { parameters: { query?: never; header?: never; path: { id: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Session revoked */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List my projects * @description List all projects where the authenticated user is a member. */ get: { parameters: { query?: { cursor?: string; limit?: number; }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description List of projects */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListProjectsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create project * @description Create a new project. The authenticated user becomes the owner. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateProjectRequest']; }; }; responses: { /** @description Project created */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreateProjectResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get project * @description Get a single project by ID. Requires membership. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Project details */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ProjectDetailResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; /** * Delete project * @description Delete a project and all its resources. Requires owner role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Project deleted */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; /** * Update project * @description Update project details. Requires owner role. */ patch: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['UpdateProjectRequest']; }; }; responses: { /** @description Project updated */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['UpdateProjectResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; trace?: never; }; '/api/projects/{projectId}/members': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List members * @description List all members of a project. Requires membership. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of members */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListMembersResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Add member * @description Add a member to the project by email. Requires owner role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['AddMemberRequest']; }; }; responses: { /** @description Member added */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['Member']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/members/{userId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Remove member * @description Remove a member from the project. Requires owner role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; userId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Member removed */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; /** * Update member role * @description Update a member's role. Requires owner role. */ patch: { parameters: { query?: never; header?: never; path: { projectId: string; userId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['UpdateMemberRequest']; }; }; responses: { /** @description Role updated */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['Member']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; trace?: never; }; '/api/projects/{projectId}/flows': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List flows * @description List all flows for a project. */ get: { parameters: { query?: { sort?: 'name' | 'updated_at' | 'created_at'; order?: 'asc' | 'desc'; include_deleted?: 'true' | 'false'; cursor?: string; limit?: number; }; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of flows */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListFlowsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create flow * @description Create a new flow in the project. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateFlowRequest']; }; }; responses: { /** @description Flow created */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['Flow']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get flow * @description Get a single flow by ID. Use ?fields to select specific sections (reduces response size). */ get: { parameters: { query?: { /** @description Comma-separated dot-paths to select specific fields (e.g., "config.variables,config.flows.tracking.sources"). Always includes id, createdAt, updatedAt. */ fields?: string; }; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Flow details */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['FlowDetailResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; /** * Soft-delete flow * @description Soft delete a flow (sets deleted_at timestamp). Requires member role. */ delete: { parameters: { query?: never; header?: { /** @description ETag from a previous GET. Returns 412 if flow was modified since. */ 'if-match'?: string; }; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Flow deleted */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description ETag mismatch — flow was modified since last read */ 412: { headers: { [name: string]: unknown; }; content?: never; }; }; }; options?: never; head?: never; /** * Update flow * @description Update an existing flow. Creates a version snapshot before applying changes. Requires member role. Use Content-Type: application/merge-patch+json to send only changed fields (RFC 7386). */ patch: { parameters: { query?: never; header?: { /** @description ETag from a previous GET. Returns 412 if flow was modified since. */ 'if-match'?: string; }; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['UpdateFlowRequest']; 'application/merge-patch+json': components['schemas']['UpdateFlowRequest']; }; }; responses: { /** @description Flow updated */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['FlowUpdateResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description ETag mismatch — flow was modified since last read */ 412: { headers: { [name: string]: unknown; }; content?: never; }; }; }; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/duplicate': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Duplicate flow * @description Create a copy of an existing flow with a new ID and no version history. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['DuplicateFlowRequest']; }; }; responses: { /** @description Flow duplicated */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['Flow']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/secrets': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List secrets * @description List a flow's secrets as metadata only (name, id, timestamps). Values are never returned. Requires member role and the secrets entitlement. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Secret metadata list */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { secrets: { id: string; name: string; flowId: string; /** Format: date-time */ createdAt: string | null; /** Format: date-time */ updatedAt: string | null; }[]; }; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create secret * @description Create a secret for a flow. The value is encrypted at rest and never returned. Requires member role and the secrets entitlement. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { name: string; value: string; }; }; }; responses: { /** @description Secret created (metadata only) */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': { id: string; name: string; flowId: string; /** Format: date-time */ createdAt: string | null; /** Format: date-time */ updatedAt: string | null; }; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/secrets/{secretId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; /** * Update secret value * @description Rotate a secret's value (re-encrypts). The value is never returned. Requires member role and the secrets entitlement. */ put: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; secretId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { value: string; }; }; }; responses: { /** @description Secret updated (metadata only) */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { id: string; name: string; flowId: string; /** Format: date-time */ createdAt: string | null; /** Format: date-time */ updatedAt: string | null; }; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; post?: never; /** * Delete secret * @description Soft-delete a secret. Idempotent: deleting a missing secret returns 204. Requires member role and the secrets entitlement. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; secretId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Secret deleted */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/secrets/values': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get decrypted secret values * @description Return decrypted secret values for a flow as a name-to-value map. Dual auth: a runtime container Bearer token bound to (projectId, flowId) with the `runner:read-secrets` scope returns only the bundle-referenced subset; a session cookie with member role returns all of the flow's secrets for administration. Responses are never cached. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Decrypted secret values keyed by name */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { values: { [key: string]: string; }; }; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/steps/{stepPath}/examples': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; /** * Edit step example * @description Edit an existing named example in place, merging provided fields onto the stored entry. Returns 404 when the named example does not exist. */ put: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; /** @description Dot-segmented step path (sectionKey.stepName), e.g. "destinations.gtag". */ stepPath: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['EditStepExampleRequest']; }; }; responses: { /** @description Updated examples object map */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['StepExamplesResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unprocessable entity */ 422: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; /** * Add step example * @description Add a named example to a step. Examples are stored as an object map keyed by name. Rejects duplicate names with 409. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; /** @description Dot-segmented step path (sectionKey.stepName), e.g. "destinations.gtag". */ stepPath: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateStepExampleRequest']; }; }; responses: { /** @description Updated examples object map */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['StepExamplesResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unprocessable entity */ 422: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; /** * Remove step example * @description Remove a named example from a step. Returns 404 when the named example does not exist. */ delete: { parameters: { query: { /** @description Name of the example to remove. */ name: string; }; header?: never; path: { projectId: string; flowId: string; /** @description Dot-segmented step path (sectionKey.stepName), e.g. "destinations.gtag". */ stepPath: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Updated examples object map */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['StepExamplesResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unprocessable entity */ 422: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/observe-examples': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Save an observed hop as a step example * @description Persist an observed journey hop as a named example on a step of the DRAFT flow config. Gated by the 'observe' feature. The step path and scenario come from the body; `example.in` is stored verbatim (post-redaction). Rejects a duplicate scenario name with 409. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['ObserveSaveExampleRequest']; }; }; responses: { /** @description Updated examples object map */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['StepExamplesResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unprocessable entity */ 422: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/deploy': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get latest deployment * @description Get the latest deployment for a flow. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Latest deployment (or null) */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeploymentResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Start deployment * @description Start a new deployment for a flow. The bundle runs asynchronously on the worker. Returns 400 AMBIGUOUS_CONFIG when the flow has multiple named settings (use the per-settings deploy endpoint instead). When an Idempotency-Key replays a prior request, returns 200 with status `already_created`. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deployment started, or idempotent replay of a prior request */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['StartDeploymentResponse']; }; }; /** @description Deployment started */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['StartDeploymentResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Deployment already in progress */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited or concurrent deploy limit (Retry-After header) */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Service unavailable */ 503: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/deploy/{deploymentId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get deployment * @description Get a specific deployment by ID. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deployment details */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeploymentDetailResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; /** * Delete deployment * @description Delete a deployment and its container. Requires owner role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deployment deleted */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { id: string; /** @enum {string} */ status: 'deleted'; }; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/settings': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List settings * @description List active named settings for a flow. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of settings */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListSettingsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/settings/{settingsId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get settings * @description Get a single settings entry with its latest deployment. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; settingsId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Settings details with deployment */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['FlowSettingsDetail']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/json': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Download settings JSON * @description Download the named flow settings as a self-contained Config JSON file. Includes parent variables and definitions. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; settingsId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Flow Config JSON file */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['FlowConfig']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/bundle': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Download settings bundle * @description Download the compiled JS/MJS for the settings' latest deployment. Redirects to a presigned download URL. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; settingsId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Redirect to presigned bundle URL */ 302: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Service unavailable */ 503: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/deploy': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get latest settings deployment * @description Get the latest deployment for a specific settings entry. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; settingsId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Latest deployment (or null) */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['SettingsDeploymentResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Deploy settings * @description Start a deployment for a specific settings entry. Detects platform from the settings. The body is optional and carries only `humanText`, the reason for the change, which becomes the description of the release this deploy produces; it is ignored when the release already has one. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; settingsId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['DeploySettingsRequest']; }; }; responses: { /** @description Deployment started */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeploySettingsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Deployment already in progress */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Settings orphaned */ 422: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Service unavailable */ 503: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/deployments/{deploymentId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get settings deployment detail * @description Get a specific deployment by ID, scoped to a settings entry. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; settingsId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deployment details */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['SettingsDeploymentDetailResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/previews': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List previews * @description List all previews for a flow, ordered by creation date descending. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of previews */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListPreviewsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create preview * @description Create a new preview for a web flow settings entry. Bundles the flow and publishes to a unique token-based URL. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreatePreviewRequest']; }; }; responses: { /** @description Preview created */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreatePreviewResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Quota exceeded */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Bundle or upload failed */ 502: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/previews/{previewId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get preview * @description Get a single preview by ID. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; previewId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Preview details */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['PreviewResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; /** * Delete preview * @description Delete a preview and its S3 bundle. Requires member role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; previewId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Preview deleted */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/previews/{previewId}/grant': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Mint preview activation grant * @description Mint a fresh, origin-bound activation grant for an existing preview. Grants are origin-bound, so a preview needs one grant per host origin — re-mint whenever the target origin changes. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; previewId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['MintGrantRequest']; }; }; responses: { /** @description Grant minted */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['MintGrantResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description No active web deployment / host bundle not preview-enabled */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/observe-sessions': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Start observe session * @description Start an Observe session for a flow. Validates the flow topology, inserts the row, and kicks off detached provisioning. Returns the row immediately as arming. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateObserveSessionRequest']; }; }; responses: { /** @description Observe session started */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ObserveSessionResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Flow topology not supported */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limit exceeded */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get observe session * @description Get an observe session: status, error message, config snapshot, web activation info, and the live server endpoint when live. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; sessionId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Observe session details */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ObserveSessionResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; /** * End observe session * @description End an observe session: tear down the container, revoke credentials, delete the web preview, delete the row. Idempotent. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; sessionId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Observe session ended */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}/journeys': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get observe session journeys * @description Assemble the session's cross-runtime journeys server-side: fetch the raw records from the observer, derive the pipeline topology from the config snapshot, and run the pure assembler. Returns the journeys and per-platform loss gaps wrapped with the session scope. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; sessionId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Assembled journeys */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ObserveSessionJourneysResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Observer unavailable */ 502: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/journeys': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get flow journeys * @description Resolve the flow's single active Observe session and assemble its cross-runtime journeys server-side. `observe_sessions.flow_id` is UNIQUE, so a flow has at most one session; when none is active the response carries `sessionId: null` with empty journeys rather than a 404. Narrow with `traceId` (one trace) and `limit` (page cap, most recent kept). This is the MCP `observe_journeys` REST contract. */ get: { parameters: { query?: { traceId?: string; limit?: number; }; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Assembled flow journeys */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['FlowJourneysResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Observer unavailable */ 502: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}/heartbeat': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Heartbeat observe session * @description Keep an observe session warm. The window posts this every 30s while open; a stale session is reaped by the janitor. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; sessionId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Heartbeat recorded */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ObserveSessionHeartbeatResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/observe-sessions/{sessionId}/end': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * End observe session (beacon) * @description The navigator.sendBeacon end target for page unload. Mirrors the DELETE end route because sendBeacon cannot send a DELETE. Idempotent. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; sessionId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Observe session ended */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/versions': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List versions * @description List all versions for a flow. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of versions */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListVersionsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/versions/{versionNumber}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get version * @description Get a specific version of a flow. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; versionNumber: number; }; cookie?: never; }; requestBody?: never; responses: { /** @description Version details with content */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['GetVersionResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/versions/{versionNumber}/restore': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Restore version * @description Restore a flow to a specific version. Creates a new version snapshot. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; versionNumber: number; }; cookie?: never; }; requestBody?: never; responses: { /** @description Flow restored */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['Flow']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/tokens': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List my automation tokens * @description The caller's live automation tokens, with the scope and audience each carries. No raw token value is ever returned; `tokenPrefix` is the only fragment of one that survives issuance. A connected app's access token lives in the same store and is deliberately absent: it is taken back by disconnecting the app. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description List of automation tokens */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListAutomationTokensResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create automation token * @description Mint an automation token for the authenticated user. The audience is `api` and `mcp`, so one token works against REST and against `/api/mcp`, and the chosen scope decides how far it gets at either: `read` is refused every non-safe REST method with 403 `INSUFFICIENT_SCOPE`. The raw token is returned once and cannot be retrieved again, so the answer carries `Cache-Control: no-store`. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateAutomationTokenRequest']; }; }; responses: { /** @description Token created (raw token shown once) */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreateAutomationTokenResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/tokens/revoke-all': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Revoke all access * @description Revoke every grant this person holds, the tokens hanging from them, and every automation token they hold. Runner tokens survive: those are the credentials deployed flow containers run with, so revoking them would stop every container the person is running. Session only: a bearer credential is refused with 401 `SESSION_REQUIRED`, so a machine token cannot disconnect everything its owner has connected. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Access revoked */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/tokens/{tokenId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Revoke automation token * @description Revoke one of the caller's tokens. Idempotent and scoped to the caller: an unknown id, another person's token and an already revoked one all answer 204, since a distinguishable answer would tell the caller which ids exist. */ delete: { parameters: { query?: never; header?: never; path: { tokenId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Token revoked */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/bundle': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Bundle flow * @description Bundle a flow using CLI. Returns bundleId (content-hash). Use ?output=download to redirect to presigned S3 URL. */ post: { parameters: { query?: { /** @description Named flow to bundle (required for multi-settings flows) */ flow?: string; /** @description Set to "download" to redirect to the bundle file */ output?: 'download'; }; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Bundle result */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['BundleResponse']; }; }; /** @description Redirect to presigned bundle URL (when output=download) */ 302: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/simulate': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Simulate a flow step * @description Execute a simulation against a pre-built bundle. Requires bundleId from the bundle endpoint. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['SimulateRequest']; }; }; responses: { /** @description Simulation result */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['SimulateResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Simulation container error */ 502: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List deployments * @description List deployments for a project. Supports filtering by status, type, origin, and flowId, plus pagination. */ get: { parameters: { query?: { status?: | 'idle' | 'deploying' | 'published' | 'active' | 'stopped' | 'failed'; type?: 'web' | 'server'; origin?: 'cloud' | 'self-hosted'; flowId?: string; sort?: 'created_at' | 'updated_at'; order?: 'asc' | 'desc'; limit?: number; offset?: number | null; cursor?: string; }; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of deployments */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListDeploymentsResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create deployment * @description Create a new deployment slot. Supports an Idempotency-Key header — a repeated key returns the original deployment id with status `already_created`. Requires member role. */ post: { parameters: { query?: never; header?: { /** @description Optional client key to make creation idempotent. */ 'idempotency-key'?: string; }; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { /** * @example web * @enum {string} */ type: 'web' | 'server'; label?: string; flowId?: string; flowSettingsId?: string; }; }; }; responses: { /** @description Deployment created */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreateDeploymentResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments/latest': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List latest deployments * @description List the latest deployment for each flow in the project. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Latest deployment per flow */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['LatestDeploymentsByFlow']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/runtimes/register': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Register runtime * @description Register a server-side runtime container and get a presigned bundle URL. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['RegisterRuntimeRequest']; }; }; responses: { /** @description Presigned bundle URL */ 200: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/observe/ticket': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Create SSE ticket * @description Generate a one-time ticket for authenticating an SSE connection to the Observer service. Requires project membership. An optional scope narrows the ticket to a subset of the project feed (e.g. one Observe session). */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['ObserveTicketRequest']; }; }; responses: { /** @description Ticket generated */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ObserveTicketResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/observe/validate-ticket': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Validate ticket * @description Internal endpoint for the Observer service to validate and consume a ticket. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['ValidateTicketRequest']; }; }; responses: { /** @description Ticket payload */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ValidateTicketResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Invalid or expired ticket */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/health': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Health check * @description Check the health of the API and its dependencies. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Health status */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['HealthResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/openapi.json': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * OpenAPI spec * @description Return the OpenAPI 3.1 specification for this API. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description OpenAPI document */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { [key: string]: unknown; }; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/ingest/v1/{projectId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Event ingestion * @description Ingest walkerOS events for a project. Served by the Observer service (port 3001). */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Accepted */ 202: { headers: { [name: string]: unknown; }; content?: never; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/stream/v1': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * SSE stream * @description Server-Sent Events stream for real-time event observation. Requires a valid ticket. Served by the Observer service (port 3001). */ get: { parameters: { query: { /** @description One-time ticket from /api/projects/{projectId}/observe/ticket */ ticket: string; /** @description Project ID for scoped validation */ project: string; }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description SSE event stream */ 200: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/health': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Observer health * @description Health check for the Observer service (port 3001). */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Health status */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { status: string; }; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/feedback': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Submit user feedback * @description Accepts free-form feedback from the walkerOS CLI, MCP, or a future in-app form. Public endpoint — no authentication required. The body `userId` is stored verbatim as a best-effort contact email and is not validated against the app users table. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['FeedbackRequest']; }; }; responses: { /** @description Feedback stored */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['FeedbackResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/service-accounts': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List service accounts * @description List service accounts for a project. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of service accounts */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListServiceAccountsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create service account * @description Create a service account and its first token. The raw token is returned once and cannot be retrieved again. Requires admin role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateServiceAccountRequest']; }; }; responses: { /** @description Service account created (raw token shown once) */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreateServiceAccountResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/service-accounts/{serviceAccountId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get service account * @description Get a single service account by ID. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; serviceAccountId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Service account details */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ServiceAccountSummary']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; /** * Delete service account * @description Soft-delete a service account and revoke all its tokens. Requires admin role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; serviceAccountId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Service account deleted */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; /** * Update service account * @description Update a service account's name, description, or role. Requires admin role. */ patch: { parameters: { query?: never; header?: never; path: { projectId: string; serviceAccountId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['UpdateServiceAccountRequest']; }; }; responses: { /** @description Service account updated */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ServiceAccountSummary']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; trace?: never; }; '/api/projects/{projectId}/service-accounts/{serviceAccountId}/tokens': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List service account tokens * @description List tokens for a service account. Returns summaries (no raw token values). Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; serviceAccountId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of tokens */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListSaTokensResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create service account token * @description Create a new token for a service account. The raw token is returned once and cannot be retrieved again. Requires admin role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; serviceAccountId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateSaTokenRequest']; }; }; responses: { /** @description Token created (raw token shown once) */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreateSaTokenResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/service-accounts/{serviceAccountId}/tokens/{tokenId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Revoke service account token * @description Revoke a service account token. Requires admin role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; serviceAccountId: string; tokenId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Token revoked */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/invitations': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List invitations * @description List invitations for a project. Defaults to pending; pass ?status=all for every status. Requires admin role. */ get: { parameters: { query?: { status?: | 'pending' | 'accepted' | 'declined' | 'expired' | 'cancelled' | 'all'; }; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description List of invitations */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListInvitationsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create invitation * @description Create an invitation and send the invite email. Requires admin role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateInvitationRequest']; }; }; responses: { /** @description Invitation created */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreateInvitationResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Invitation limit reached */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/invitations/{inviteId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Cancel invitation * @description Cancel a pending invitation. Requires admin role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; inviteId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Invitation cancelled */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/invitations/{token}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Preview invitation * @description Preview invitation details. No authentication required — the token is the credential. */ get: { parameters: { query?: never; header?: never; path: { /** @description Opaque invitation token (the credential). */ token: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Invitation preview */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['InvitationPreview']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/invitations/{token}/accept': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Accept invitation * @description Accept an invitation. Requires authentication; the authenticated user's email must match the invitation email. */ post: { parameters: { query?: never; header?: never; path: { /** @description Opaque invitation token (the credential). */ token: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Invitation accepted */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['AcceptInvitationResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/invitations/{token}/decline': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Decline invitation * @description Decline an invitation. No authentication required — the token is the credential. */ post: { parameters: { query?: never; header?: never; path: { /** @description Opaque invitation token (the credential). */ token: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Invitation declined */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeclineInvitationResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/telemetry': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Submit telemetry event * @description Accept a single walkerOS v4 event from the CLI or MCP telemetry emitter. Public endpoint — no authentication. `source.type` is constrained to `cli` or `mcp`. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['TelemetryEvent']; }; }; responses: { /** @description Telemetry event accepted */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/billing': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get billing details * @description Get billing details for a project, or null when none are set. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Billing details (or null when unset) */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': | components['schemas']['BillingDetailsResponse'] | null; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; /** * Upsert billing details * @description Create or update billing details for a project. Requires owner role. */ put: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['UpsertBillingDetailsRequest']; }; }; responses: { /** @description Billing details saved */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['BillingDetailsResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments/{deploymentId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get deployment detail * @description Get deployment detail. Accepts a dep_ID or a slug. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deployment detail */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeploymentDetailResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; /** * Delete deployment * @description Tear down and soft-delete a deployment. Idempotent. Requires owner role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deployment deleted (or already absent) */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; /** * Update deployment * @description Update a deployment's label, or stop/resume it. Stop and resume require admin role; label updates require member role. */ patch: { parameters: { query?: never; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { label?: string; /** @enum {string} */ action?: 'stop' | 'resume'; }; }; }; responses: { /** @description Deployment updated */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['UpdateDeploymentResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Deployment state changed concurrently */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; trace?: never; }; '/api/projects/{projectId}/deployments/{deploymentId}/publish': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Publish deployment version * @description Push a new version to a deployment, either from an existing flow setting or from a direct config upload. Bundles in-process and transitions the deployment to `deploying`. Requires member role. */ post: { parameters: { query?: never; header?: { /** @description Optional client key to make publishing idempotent. */ 'idempotency-key'?: string; }; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': | { /** @enum {string} */ source: 'flow'; flowId: string; flowSettingsName: string; } | { /** @enum {string} */ source: 'config'; config: { [key: string]: unknown; }; }; }; }; responses: { /** @description Version published (bundling/deploying) */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['PublishVersionResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Publish already in progress */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited or concurrent deploy limit */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Build service unavailable */ 503: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments/{deploymentId}/stream': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Stream deployment status (SSE) * @description Server-Sent Events (`text/event-stream`) stream of a deployment's live status. Emits named events: `status` (a snapshot payload, schema below), `done` (terminal, no body), and `timeout`. The CLI consumes this with a raw fetch while waiting for a deploy to finish. Requires member role. The schema documents the JSON `data:` of a `status` event; `errorCode`/`errorMessage` carry the persisted, redacted classification of a failed deploy. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description SSE stream; `status` event payload shape documented here. */ 200: { headers: { [name: string]: unknown; }; content: { 'text/event-stream': components['schemas']['DeploymentStreamStatusEvent']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments/{deploymentId}/versions': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List deployment versions * @description List the version history for a deployment, paginated. Requires member role. */ get: { parameters: { query?: { limit?: number; offset?: number | null; }; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Version history */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListDeploymentVersionsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/releases': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List flow releases * @description List the release history for a flow across all of its deployment lineages, newest first, paginated. Each entry is a deployed version joined to its parent deployment (slug and type). `rationale=true` joins each row's stored rationale summary on, which requires the `hub` feature; without it the `rationale` key is absent from every row rather than null, and no feature beyond member role is needed. Requires member role. */ get: { parameters: { query?: { limit?: number; offset?: number | null; rationale?: 'true' | 'false'; }; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Flow release history */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListFlowReleasesResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/releases/{versionId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Read one release in full * @description One release of this flow with its rationale and its diff. The path segment is either the spine version id (`ver_...`) or the flow-unique spine number, and the route decides which it was, so a caller holding only the number needs no lookup first. The diff is computed server-side from the two stored snapshots and is never accepted from a caller; its predecessor is the next LOWER spine number, not the previous row by time, because spine rows are reused across redeploys of identical content. `diff.text` is rendered from masked content, so an empty string can still mean the releases differ inside an inline secret: `diff.contentIdentical`, compared over the unmasked hashes, is the trustworthy answer. `diff` is null for the flow's oldest release. An unknown address, a sibling flow's version, and an autosave revision all answer 404 alike. Requires member role and the `hub` feature. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; /** @description Spine version id of the release (ver_...) or its spine number */ versionId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The release, its rationale, and its diff */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ReleaseDetailResponse']; }; }; /** @description Invalid release reference */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/releases/{versionId}/content': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Read a release snapshot * @description The flow config one release of this flow froze, addressed by its spine version id. This is the only route that serves a release snapshot: the positional `/versions/{versionNumber}` route numbers the autosave revisions, a disjoint set of rows, so a release number handed to it addresses an unrelated revision or nothing. Inline secret literals are masked. An unknown id, a sibling flow's version, and an autosave revision all answer 404 alike. Requires member role and the `hub` feature. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; /** @description Spine version ID of the release (ver_...) */ versionId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The release snapshot */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ReleaseContentResponse']; }; }; /** @description Invalid version id */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/releases/annotations': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List release rationale * @description Read the rationale attached to the given releases of a flow. `versionIds` is a comma-separated list of spine version ids (at most 100), all of which must belong to this flow. Releases without rationale are absent from the response. Requires member role. */ get: { parameters: { query: { versionIds: string; }; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Rationale for the requested releases */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListVersionAnnotationsResponse']; }; }; /** @description Invalid version ids */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; /** * Write release rationale * @description Create or update the human rationale for one release of this flow. A null `humanText` clears it. The generated summary is machine-written and cannot be set through this route. The target must be a numbered release version of this flow, not an autosave revision. Requires member role. */ put: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { /** @example ver_a1b2c3d4 */ versionId: string; humanText: string | null; }; }; }; responses: { /** @description The stored rationale */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['UpsertVersionAnnotationResponse']; }; }; /** @description Invalid body, or the target is not a release */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/threads': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List discussion threads on a flow * @description Threads anchored to things in this flow, most recently active first. `anchorType` and `anchorKey` narrow to one anchor and are only meaningful together. `includeMessages=true` attaches the messages; otherwise each thread carries `messageCount` alone. Attaching them holds the page to a smaller ceiling than the lean index and caps each thread at its newest 50 messages, with `hasMoreMessages` set when a thread holds more. Because that ceiling is below the `limit` a caller may pass, the response carries `hasMoreThreads`: a full page is not proof of a complete list. A resolved thread carries the release that settled it, and `resolvedByVersionId` is null once that release is gone, which is what `anchorLabel` is kept for. Requires member role. */ get: { parameters: { query?: { anchorType?: | 'step' | 'entity_action' | 'release' | 'contract' | 'tag'; anchorKey?: string; status?: 'open' | 'resolved'; includeMessages?: 'true' | 'false'; limit?: number; }; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Threads on this flow */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListHubThreadsResponse']; }; }; /** @description Invalid query */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Open a discussion thread * @description Open a thread on one anchor, with its first message. A thread never exists empty, so `text` is required and may not be blank. A `release` anchor must name a numbered release of this flow: the server verifies it and derives the label, so `anchorLabel` is ignored for that type. For any other anchor type `anchorLabel` is a display snapshot of the anchor as it reads now, stored so a later rename leaves the thread readable instead of unlabeled, and defaults to the anchor key. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { /** * @example release * @enum {string} */ anchorType: | 'step' | 'entity_action' | 'release' | 'contract' | 'tag'; anchorKey: string; anchorLabel?: string; text: string; }; }; }; responses: { /** @description The opened thread, with its first message */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['HubThreadResponse']; }; }; /** @description Invalid body, or the anchor is not a release */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Flow not found, or the anchor names no release of it */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/threads/{threadId}/messages': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Reply to a thread * @description Append a message to a thread. `text` may not be blank: a message cannot be cleared, so empty is invalid rather than a way to erase one. Replying does not reopen a resolved thread: the resolve link is a statement about a release and is never retracted implicitly. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; /** @description Thread ID (thr_...) */ threadId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { text: string; }; }; }; responses: { /** @description The thread, with the new message */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['HubThreadResponse']; }; }; /** @description Invalid body */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/threads/{threadId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; delete?: never; options?: never; head?: never; /** * Resolve or reopen a thread * @description Resolving records the release that settled the thread: pass `resolvedByVersionId`, or omit it to record the flow’s newest release. The target must be a numbered release of this flow, never an autosave revision. Reopening drops the link. Requires member role. */ patch: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; /** @description Thread ID (thr_...) */ threadId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { /** * @example open * @enum {string} */ status: 'open' | 'resolved'; /** @example ver_a1b2c3d4 */ resolvedByVersionId?: string; }; }; }; responses: { /** @description The updated thread */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['HubThreadResponse']; }; }; /** @description Invalid body, or the target is not a release */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; trace?: never; }; '/api/projects/{projectId}/knowledge': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List knowledge captured in this project * @description What people wrote on the frames of a page, most recently active first. Two kinds come back together and `kind` separates them: a `thread` carries its text in messages, a `description` carries one body and cannot be replied to. `pageKey` narrows to a whole page, resolved server-side to every frame that page holds at any depth; `frameId` narrows to one frame; `markId` narrows to one mark within it and is refused without `frameId`, since a mark id alone addresses nothing. `includeMessages=true` attaches message bodies and holds the page to a much smaller ceiling, so `hasMoreEntries` is what separates a complete answer from a truncated one. `validity` says when an entry was true and `freshness` compares that against the flow’s newest release; neither is a verdict. Requires member role. */ get: { parameters: { query?: { pageKey?: string; frameId?: string; markId?: string; includeMessages?: 'true' | 'false'; limit?: number; }; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Knowledge in this project */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListKnowledgeResponse']; }; }; /** @description Invalid query, or a mark filter with no frame */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Open a thread on a mark or a frame * @description Open a thread on one mark of one frame, or on the frame itself with `anchorType` `page` and no `markId`, with its first message. A thread never exists empty, so `text` is required and may not be blank. `clientThreadId` and `clientMessageId` are minted by the client at compose time and are what make a replay idempotent: repeating a known `clientThreadId` hands back the existing thread and writes nothing, so an offline queue can drain repeatedly without duplicating what a person wrote once. `flowId` binds the capture to a flow or is explicitly null; a flow this project cannot see answers 404, never 403. A frame this project does not hold answers 404 with `FRAME_NOT_FOUND`, which a draining client waits on and retries, because the frame’s own write may not have landed yet. The server decides the composed anchor key, the born release, the author and the source: a client cannot assert any of them. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { /** * @example tag * @enum {string} */ anchorType: 'tag' | 'page'; /** @example frm_V1StGXR8Z5jdHi6BmyT7K */ frameId: string; markId?: string; anchorLabel?: string; flowId: string | null; subjectKey?: string; spatial?: components['schemas']['KnowledgeSpatial']; /** @example ct_7f3a91 */ clientThreadId: string; text: string; /** @example ct_7f3a91 */ clientMessageId: string; }; }; }; responses: { /** @description The thread, with its first message */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['KnowledgeThreadResponse']; }; }; /** @description Invalid body */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description The named flow or frame is not in this project */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/knowledge/{threadId}/messages': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Reply to a knowledge thread * @description Append a message to a thread and get the whole thread back, so a surface renders the new exchange without a second read. `text` may not be blank: a message cannot be cleared, so empty is invalid rather than a way to erase one. Repeating a `clientMessageId` already on the thread appends nothing and leaves `updatedAt` alone, so a retrying drain never keeps bumping a thread to the top of every list. A description has no conversation and cannot be replied to; addressing one answers 404. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; /** @description Thread ID (thr_...) */ threadId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { text: string; /** @example ct_7f3a91 */ clientMessageId: string; }; }; }; responses: { /** @description The thread, with the new message */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['KnowledgeThreadResponse']; }; }; /** @description Invalid body */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/knowledge/description': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; /** * Write the description of a mark or a frame * @description Write the one description of one anchor, a mark or the frame itself, replacing whatever it said before. There is no id to mint: the anchor is the key, so a replayed write lands on the same row by construction, which is why this is a PUT. An empty `body` is refused rather than stored, so a drain that arrives with nothing to say can never erase what a person wrote. The response is 200 whether the description was opened or replaced. Requires member role. */ put: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { /** * @example tag * @enum {string} */ anchorType: 'tag' | 'page'; /** @example frm_V1StGXR8Z5jdHi6BmyT7K */ frameId: string; markId?: string; anchorLabel?: string; flowId: string | null; subjectKey?: string; spatial?: components['schemas']['KnowledgeSpatial']; body: string; }; }; }; responses: { /** @description The stored description */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['KnowledgeDescriptionResponse']; }; }; /** @description Invalid body */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description The named flow or frame is not in this project */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/frames': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List the frames of a page, or of the whole project * @description A frame is a named rectangle with marks inside it, the spatial unit of a measurement plan. Naming a `pageKey` returns that page’s frames at any depth, marks and all, newest updated first: the walk starts at the page’s top-level frames and descends containment, so a child is reachable through its parent rather than by carrying a page of its own. Naming no page returns every live frame of the project WITHOUT its marks, which is what makes that read cheap enough to answer "what does this project have": the marks are the bulk of a frame and a listing never renders them. That lean read asks nothing about containment, so a frame whose parent cannot be resolved still appears. `include=marks` asks that project-wide read for the marks anyway, for a surface that spans pages and cannot fetch a page at a time; it is a second, heavier read of the same rows, taken after the lean list has already painted, and omitting it returns exactly the lean rows. It says nothing to the page read, which carries marks either way. Requires member role. */ get: { parameters: { query?: { pageKey?: string; include?: 'marks'; }; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The page’s frames with their marks, or the project’s frames without them */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': | components['schemas']['FrameListResponse'] | components['schemas']['FrameLeanListResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/frames/{frameId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Read one frame * @description One frame with its marks. A frame of another project reads back as nothing and answers 404, never 403, so this route cannot become an oracle for what exists elsewhere. A deleted frame is gone to every read. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; /** @description Frame ID (frm_...) */ frameId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The frame */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['Frame']; }; }; /** @description The path segment does not address a frame */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; /** * Create or replace one frame * @description The path is the identity, so the body carries no id: a create is a write to an absent row at `baseVersion` 0 and everything else is a replace. `clientWriteId` is minted at compose time and is what makes a replayed drain exact: a write whose id already produced the stored version landed once and is answered with that version, writing nothing, so an offline queue drains repeatedly without turning one edit into two versions. A write against a version someone else has moved past answers 409 `FRAME_VERSION_CONFLICT` carrying the head, which is what lets a client raise keep-mine against load-theirs on the one frame that conflicted instead of dropping what a person drew. A name another live frame already holds is a distinct 409 `FRAME_NAME_EXISTS`. A relation naming a frame this project does not hold, or one that would place a frame inside itself, is 400 `INVALID_FRAME`. The screenshot is never touched here: a frame write carries no capture. Requires member role. */ put: { parameters: { query?: never; header?: never; path: { projectId: string; /** @description Frame ID (frm_...) */ frameId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { frame: components['schemas']['FrameInput']; baseVersion: number; clientWriteId: string; }; }; }; responses: { /** @description The stored version */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['PutFrameResponse']; }; }; /** @description Invalid body, a bad relation, or a path segment that addresses no frame */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description A stale base version, carrying the head, or a name another live frame already holds. Only the version conflict carries `head`: a name clash needs no frame to resolve, since the client already knows the name it sent. */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': | components['schemas']['FrameConflictResponse'] | components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; post?: never; /** * Delete one frame * @description Soft-delete the frame and, transitively, every variation of what this delete removes. Children are not variations and survive: each live frame under a removed one is re-parented to its nearest live ancestor in the same transaction, and one left with no live ancestor becomes top-level and inherits the page it hung under, so nothing is left unreachable. Those re-parents are server writes that bump their own versions, so a client still holding a pre-delete version meets a conflict carrying the new parent. A frame this project does not hold answers 404: a delete that removed nothing is not a delete that succeeded. Requires member role. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; /** @description Frame ID (frm_...) */ frameId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The frame is deleted */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description The path segment does not address a frame */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/frames/{frameId}/screenshot': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Store the capture of one frame * @description Store one screenshot and set it on its frame. The image arrives as base64 rather than multipart, because the extension relay carries string bodies only. The server decides everything about the bytes: it decodes them, counts the DECODED length against a 4 MB cap, reads the type from the file’s own magic bytes, and hashes them, so nothing the client claims about size or type is consulted. Captures are deduplicated by content within a project: identical pixels resolve to one asset and one upload, and `reused` says whether that happened, which is the common answer rather than the rare one because re-capturing an unchanged frame produces identical bytes. A body past the cap is 413 `PAYLOAD_TOO_LARGE` and one that is not a PNG is 415 `UNSUPPORTED_MEDIA_TYPE`. The capture bumps no frame version: it is not an edit, so an upload never conflicts with the frame write the client queued beside it. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; /** @description Frame ID (frm_...) */ frameId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { imageBase64: string; meta: components['schemas']['FrameScreenshotMeta']; }; }; }; responses: { /** @description The asset the bytes resolved to, and whether it already existed */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ScreenshotUploadResponse']; }; }; /** @description Invalid body, or a path segment that addresses no frame */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description This project does not hold the named frame */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description The decoded image is past the 4 MB cap */ 413: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description The bytes are not a PNG */ 415: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/assets/{assetId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Read one stored capture * @description The bytes of one frame screenshot, for the app canvas. The extension keeps its own capture locally and never reads assets back. Same-origin and session-authenticated: the response carries `Cross-Origin-Resource-Policy: same-origin`, so no other site can embed a tenant capture off the reader’s session. The bytes are immutable by construction, since the object key is their own content hash, which is why they are cacheable for a year, and `private` keeps a shared cache from serving one tenant’s capture to the next request for the same URL. An asset another project holds answers 404, never 403. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; /** @description Asset ID (fas_...) */ assetId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The image bytes */ 200: { headers: { [name: string]: unknown; }; content: { 'image/png': string; }; }; /** @description The path segment does not address an asset */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/canvases': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List the canvases of the project * @description A canvas is a named, freely arranged board over a project’s frames, the surface on which a plan is laid out across pages rather than within one. This returns every live canvas by name WITHOUT its document: the document is the bulk of a canvas and a listing renders none of it, so opening a board is the single-canvas read. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The project’s canvases, without their documents */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CanvasListResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create one canvas * @description Create one empty canvas at version 1. The id is the client’s, so a board drawn before the first save keeps its identity when it arrives. A canvas comes into existence here and nowhere else: a document write to an id the project does not hold is a 404 rather than a create, which is what keeps a stray write from minting a board. A name another live canvas already holds is 409 `CANVAS_NAME_EXISTS`; the partial unique index is over live rows, so a name a deleted canvas still carries is free. An id that is not a canvas id is refused by the body schema as 400 `VALIDATION_ERROR`. An id that is not available, because a canvas, in this project or another, already holds it, is 400 `INVALID_CANVAS`, whose message says nothing about the project that holds it. Requires member role. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { /** @example cnv_V1StGXR8Z5jdHi6BmyT7K */ id: string; name: string; }; }; }; responses: { /** @description The created canvas, with its empty document */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['Canvas']; }; }; /** @description Invalid body, or an id that is not available */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description A name another live canvas already holds */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/canvases/{canvasId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Read one canvas * @description One canvas with its whole document: the nodes with their positions, the edges, and the node keys the board suppresses. A canvas of another project reads back as nothing and answers 404, never 403, so this route cannot become an oracle for what exists elsewhere. A deleted canvas is gone to every read. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; /** @description Canvas ID (cnv_...) */ canvasId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The canvas */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['Canvas']; }; }; /** @description The path segment does not address a canvas */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; /** * Replace the document of one canvas * @description The whole board every time: a canvas is read and written as a unit, so there is no partial write to reconcile. `clientWriteId` is minted at compose time and is what makes a replayed drain exact: a write whose id already produced the stored version landed once and is answered with that version, writing nothing, so an offline queue drains repeatedly without turning one edit into two versions. A write against a version someone else has moved past answers 409 `CANVAS_VERSION_CONFLICT` carrying the head, which is what lets a client raise keep-mine against load-theirs on the board that conflicted instead of dropping what a person drew. A canvas this project does not hold, or one that was removed, is 404 `CANVAS_NOT_FOUND`: this door replaces a document and never creates one. Requires member role. */ put: { parameters: { query?: never; header?: never; path: { projectId: string; /** @description Canvas ID (cnv_...) */ canvasId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { document: components['schemas']['CanvasDocument']; baseVersion: number; clientWriteId: string; }; }; }; responses: { /** @description The stored version */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['PutCanvasResponse']; }; }; /** @description Invalid body, or a path segment that addresses no canvas */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description This project does not hold the named canvas */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description A stale base version, carrying the head */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CanvasConflictResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/releases/step-history': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List the releases that touched one step * @description The releases of this flow that added, changed, or removed one step, newest first, each carrying the rationale stored for it. `step` is a `type.name` key over source, transformer, destination, store, and contract. `flow` narrows the scan to one named flow inside the config and is ignored for a contract key. `limit` bounds the releases scanned, not the entries returned. When nothing matched, `knownSteps` lists the addressable keys of the newest scanned release. Requires member role. */ get: { parameters: { query: { step: string; flow?: string; limit?: number | null; }; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description The releases that touched the step */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['StepHistoryResponse']; }; }; /** @description Invalid step key or query */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/releases/summarize': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Summarize or check a release * @description Describe what one release of this flow changed against an earlier release, or check a written note against that same change. In `draft` mode the generated text is stored as the release's generated summary; in `check` mode nothing is stored and the response says whether the note matches. The diff is always recomputed from the two stored snapshots, with secret literals masked, and is never taken from the request. Both versions must be numbered releases of this flow, and `prevVersionId` must be the earlier of the two. Requires member role and the `hub` feature. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': { /** @example ver_a1b2c3d4 */ versionId: string; /** @example ver_a1b2c3d4 */ prevVersionId: string; /** @enum {string} */ mode: 'draft' | 'check'; currentText?: string; }; }; }; responses: { /** @description The generated summary or the check verdict */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['SummarizeReleaseResponse']; }; }; /** @description Invalid body, a target is not a release, the pair is out of order, or no LLM provider is configured */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description The model call failed or returned no usable text */ 502: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments/{deploymentId}/versions/current/content': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get current deployed content * @description Get the active deployed per-setting content for a deployment, used to diff changes since deploy. Content is masked and display-only; every field is null when there is no deployed baseline. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deployed content (or a null baseline) */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeployedContentResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Rate limited */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments/{deploymentId}/heartbeats': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List deployment heartbeats * @description List heartbeat records for a deployment with optional from/to time-range filtering and pagination. Requires member role. */ get: { parameters: { query?: { /** @description ISO start of the time range. */ from?: string; /** @description ISO end of the time range. */ to?: string; limit?: number; offset?: number | null; }; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Heartbeat history */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListHeartbeatsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments/{deploymentId}/rotate-ingest-token': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Rotate ingest token * @description Rotate the ingest token for a deployment. Owner-only. No grace window: the previous token is immediately invalidated and the new token is returned once. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description New ingest token */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['RotateIngestTokenResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/deployments/{deploymentId}/usage': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Deployment usage * @description Aggregate usage summary plus bucketed chart data for a deployment over the requested period. Requires member role. */ get: { parameters: { query?: { /** @description Time window for the usage summary. */ period?: '1h' | '24h' | '7d' | '30d'; }; header?: never; path: { projectId: string; deploymentId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Usage summary and chart buckets */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeploymentUsageResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/custom-domains': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List custom domains * @description List custom domains attached to any deployment of this flow. Requires member role and the customDomains feature. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Custom domains for the flow */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListCustomDomainsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Attach custom domain * @description Attach a custom domain to the flow's latest server deployment, or to an explicit deployment supplied in the body. Requires member role and the customDomains feature. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateCustomDomainRequest']; }; }; responses: { /** @description Custom domain attached */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CustomDomain']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Conflict */ 409: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/custom-domains/{domainId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Detach custom domain * @description Detach a custom domain from its deployment and remove the Scaleway record. Idempotent: a missing domain still returns 204. */ delete: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; domainId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Custom domain detached */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/flows/{flowId}/settings/{settingsId}/deploy-token': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Self-hosted deploy-token status * @description Report whether a self-hosted deploy token exists for this config, plus the deployment health summary when present. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; settingsId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deploy-token status */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeployTokenStatusResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Mint self-hosted deploy token * @description Create a self-hosted deployment (if none exists) and mint a flow+deployment-bound runner token. Admin-only. The raw token is returned once and never stored in plaintext. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; flowId: string; settingsId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Deploy token minted */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreateDeployTokenResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/entitlements': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Resolved entitlements * @description Return resolved feature entitlements for the authenticated user and project. Used by CLI/API clients; the web UI uses SSR-resolved entitlements. Requires viewer role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Resolved entitlements */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['EntitlementsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/settings/llm': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Active LLM provider * @description Report which LLM provider is currently active for the project and where billing is sourced. Never returns the apiKey. Requires member role and the chat feature. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Active LLM provider status */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['LlmConfigStatusResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description No platform LLM provider configured */ 503: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['LlmConfigStatusResponse']; }; }; }; }; put?: never; /** * Set LLM provider * @description Set or clear the project LLM provider override. Admin-only, gated by the chat feature. The apiKey is write-only: it is encrypted and never returned. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['SetLlmConfigRequest']; }; }; responses: { /** @description LLM config saved or cleared */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['SetLlmConfigResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/chat/sessions': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List chat sessions * @description List the caller's recent chat sessions for a project, ordered by last activity. Requires member role and the chat feature. */ get: { parameters: { query?: { limit?: number; offset?: number | null; }; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Chat session list */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListChatSessionsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/chat/sessions/{sessionId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Get chat session * @description Return a chat session and its full message history when the caller owns it. Foreign or unknown sessions return 404 (never 403) so existence is not leaked. Requires member role and the chat feature. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; sessionId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Chat session with messages */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ChatSessionDetailResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/chat/elicit': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Answer elicitation prompt * @description Answer a pending MCP elicitation prompt (accept, decline, or cancel), unblocking the waiting tool invocation. Requires member role and the chat feature. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['ElicitRequest']; }; }; responses: { /** @description Elicitation resolved */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ElicitResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/runners': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List runners (deprecated) * @description Deprecated: runners migrated to deployments (origin=self-hosted). Always returns an empty list for backward compatibility. Requires member role. */ get: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Empty runner list */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListRunnersResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/projects/{projectId}/runners/heartbeat': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Runner heartbeat * @description Accept a self-hosted runner heartbeat with usage counters. Authenticated by a flow+deployment-bound runner token. Updates deployment liveness and records an immutable usage row. */ post: { parameters: { query?: never; header?: never; path: { projectId: string; }; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['HeartbeatRequest']; }; }; responses: { /** @description Heartbeat accepted */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['RunnerHeartbeatResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/packages': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Package catalog * @description Resolved `@walkeros/*` package catalog for the add-step picker, optionally filtered by type and platform. */ get: { parameters: { query?: { /** @description Filter by package type. */ type?: string; /** @description Filter by platform. */ platform?: string; }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Package catalog */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['PackageCatalogResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Package catalog unavailable */ 502: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/packages/search': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * Search packages * @description Returns the full @walkeros/* package catalog; clients filter locally. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Search results */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['PackageSearchResponse']; }; }; /** @description Package search unavailable */ 502: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Log a settled search * @description Records one settled search outcome (the term the user paused on and whether the catalog matched it). Fire-and-forget; returns 204. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['PackageSearchLogRequest']; }; }; responses: { /** @description Search logged */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/observe/timing': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Report connect timing * @description Fire-and-forget beacon for client-side connect timing SLIs. No auth required; carries no secrets. Returns 204. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['ObserveTimingRequest']; }; }; responses: { /** @description Timing recorded */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/oauth/register': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Register a client * @description RFC 7591 dynamic client registration. Unauthenticated: a client registers itself before it holds any credential. Issues public clients only (`token_endpoint_auth_method: none`), which prove themselves with PKCE. Errors use the RFC 7591 section 3.2.2 shape, not the standard error envelope. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['OAuthClientRegistrationRequest']; }; }; responses: { /** @description Client registered */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthClientRegistrationResponse']; }; }; /** @description Invalid client metadata or redirect URI */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthRegistrationError']; }; }; /** @description Registration ceiling reached (Retry-After header) */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/oauth/device_authorization': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Start a device authorization * @description RFC 8628 section 3.1. A client that cannot host a browser redirect asks for a device code and a user code here, then polls the token endpoint while the person approves the user code at `/oauth/device`. Unauthenticated, and public clients only: the code is worth nothing until a signed-in person approves it. Body is `application/x-www-form-urlencoded`; errors use the RFC 6749 section 5.2 shape, not the standard error envelope. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/x-www-form-urlencoded': components['schemas']['DeviceAuthorizationRequest']; }; }; responses: { /** @description Device authorization opened */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeviceAuthorizationResponse']; }; }; /** @description invalid_request, unauthorized_client, invalid_scope or invalid_target */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthError']; }; }; /** @description invalid_client: unknown, revoked or confidential client */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthError']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/oauth/token': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Exchange a grant for tokens * @description RFC 6749 section 3.2. Runs the authorization code, refresh token and device code grants. The client authenticates here: a public client with PKCE, a confidential one with HTTP Basic or a form secret. Body is `application/x-www-form-urlencoded` only; errors use the RFC 6749 section 5.2 shape, not the standard error envelope, and a failed Basic authentication is answered with a `WWW-Authenticate: Basic` challenge. Responses are never cacheable. Rate limited per `client_id`. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/x-www-form-urlencoded': components['schemas']['TokenRequest']; }; }; responses: { /** @description Tokens issued */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['TokenResponse']; }; }; /** @description invalid_request, invalid_grant, invalid_scope, invalid_target, unsupported_grant_type, or a device grant status (authorization_pending, slow_down, access_denied, expired_token) */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthError']; }; }; /** @description invalid_client: unknown, revoked, or bad credentials */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthError']; }; }; /** @description Per-client token budget reached (Retry-After header) */ 429: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/oauth/revoke': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Revoke a token * @description RFC 7009. Client authentication is the same as at the token endpoint. A refresh token revokes its whole rotation family, an access token only itself. An authenticated request always answers 200 with an empty body, unknown tokens included: a distinguishable answer would be an oracle. Body is `application/x-www-form-urlencoded`. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/x-www-form-urlencoded': components['schemas']['RevocationRequest']; }; }; responses: { /** @description Revoked, or nothing matched */ 200: { headers: { [name: string]: unknown; }; content?: never; }; /** @description invalid_request or unsupported_token_type */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthError']; }; }; /** @description invalid_client: unknown, revoked, or bad credentials */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthError']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/oauth/device/approve': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Decide a device authorization * @description The person's approve or deny decision on a pending device authorization. Session only: a bearer credential is refused with 401 `SESSION_REQUIRED`, so a machine token can never approve its own device. Requires the `X-CSRF-Token` minted with the consent page, bound to this user code. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['DeviceApprovalRequest']; }; }; responses: { /** @description Decision recorded */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['DeviceApprovalResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Forbidden */ 403: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/oauth/authorize': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; /** * Decide a consent request * @description The person's allow or deny decision on the consent screen at `/oauth/authorize`. The ticket is the HMAC-signed authorization request that screen was rendered from, so the decision cannot alter what was validated, and it is bound to the person it was minted for. Session only: a bearer credential is refused with 401 `SESSION_REQUIRED`, so a machine token can never approve a consent. The response says where to send the browser: the client's registered redirect URI, carrying `code` on allow and `error=access_denied` on deny. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['OAuthConsentDecisionRequest']; }; }; responses: { /** @description Decision recorded */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['OAuthConsentDecisionResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/oauth/grants': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List connected apps * @description The apps the signed-in person has consented to, as the Connected apps page renders them. Revoked grants are absent. Session only: a bearer credential is refused with 401 `SESSION_REQUIRED`, so a machine token cannot read the connections its owner holds. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Connected apps */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListOAuthGrantsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; post?: never; /** * Disconnect every app * @description Revoke every grant this person holds and the tokens hanging from them. Automation tokens hang from no grant and survive. Session only: a bearer credential is refused with 401 `SESSION_REQUIRED`, so a read-scoped machine token cannot disconnect everything its owner has connected. */ delete: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description Apps disconnected */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/oauth/grants/{grantId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Disconnect one app * @description Revoke one grant and the tokens hanging from it. Idempotent: an unknown grant, another person's grant and an already revoked one all answer 204, and the token sweep runs either way, so pressing Disconnect twice cleans up a token minted inside the first press's window. Session only: a bearer credential is refused with 401 `SESSION_REQUIRED`. */ delete: { parameters: { query?: never; header?: never; path: { grantId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description App disconnected */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; '/api/admin/oauth/clients': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; /** * List OAuth clients * @description Every registered OAuth client, revoked ones included. No secret material is returned. Admin only: a non-admin caller gets 404, not 403, so the endpoint does not confirm its own existence. */ get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { /** @description OAuth client list */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ListOAuthClientsResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; put?: never; /** * Create a confidential OAuth client * @description Create an OAuth client that authenticates with a secret. The raw secret is returned exactly once and is never retrievable afterwards. Admin only: a non-admin caller gets 404, not 403. */ post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: { content: { 'application/json': components['schemas']['CreateOAuthClientRequest']; }; }; responses: { /** @description Client created */ 201: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['CreateOAuthClientResponse']; }; }; /** @description Validation error */ 400: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; '/api/admin/oauth/clients/{clientId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; get?: never; put?: never; post?: never; /** * Revoke an OAuth client * @description Revoke a client together with the grants consented to it and the tokens minted under them. Admin only: a non-admin caller gets 404, not 403, the same answer an unknown client id gets. */ delete: { parameters: { query?: never; header?: never; path: { clientId: string; }; cookie?: never; }; requestBody?: never; responses: { /** @description Client revoked */ 204: { headers: { [name: string]: unknown; }; content?: never; }; /** @description Unauthorized */ 401: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; /** @description Not found */ 404: { headers: { [name: string]: unknown; }; content: { 'application/json': components['schemas']['ErrorResponse']; }; }; }; }; options?: never; head?: never; patch?: never; trace?: never; }; } interface components { schemas: { ErrorResponse: { error: { /** @example VALIDATION_ERROR */ code: string; /** @example Validation failed */ message: string; details?: { field?: string; reason?: string; errors?: { path: string; message: string; }[]; } & { [key: string]: unknown; }; }; }; ClientOutdatedError: { error: { /** @enum {string} */ code: 'CLIENT_OUTDATED'; /** @example This endpoint requires @walkeros/cli >= 3.5.0 (you are on 3.3.1). */ message: string; /** @example 3.5.0 */ minVersion: string; /** @example 3.3.1 */ clientVersion: string; /** @example cli */ client: string; /** @example npm install -g @walkeros/cli@latest */ upgrade: string; /** * Format: uri * @example https://walkeros.io/docs/upgrading */ docs: string; }; }; FlowConfig: { /** @enum {number} */ version: 4; $schema?: string; include?: string[]; variables?: { [key: string]: unknown; }; definitions?: { [key: string]: unknown; }; flows?: { [key: string]: unknown; }; contract?: { [key: string]: unknown; }; } & { [key: string]: unknown; }; Flow: { /** @example flow_a1b2c3d4 */ id: string; /** @example my-website-flow */ name: string; config: components['schemas']['FlowConfig']; settings?: components['schemas']['FlowSettingsSummary'][]; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; /** Format: date-time */ deletedAt?: string | null; }; FlowSettingsSummary: { /** @example cfg_a1b2c3d4 */ id: string; name: string; /** * @example web * @enum {string} */ platform: 'web' | 'server'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; }; FlowSummary: { /** @example flow_a1b2c3d4 */ id: string; /** @example my-website-flow */ name: string; summary?: string; settings?: components['schemas']['FlowSettingsListItem'][]; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; /** Format: date-time */ deletedAt: string | null; }; FlowSettingsListItem: { /** @example cfg_a1b2c3d4 */ id: string; name: string; /** * @example web * @enum {string} */ platform: 'web' | 'server'; serving: components['schemas']['ServingStatus']; latestAttempt: components['schemas']['LatestAttemptStatus']; deploymentUrl: string | null; deployedAt: string | null; }; /** @enum {string} */ ServingStatus: 'live' | 'none'; /** @enum {string|null} */ LatestAttemptStatus: | 'idle' | 'deploying' | 'published' | 'active' | 'stopped' | 'failed' | null; Version: { /** @example 1 */ version: number; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * @example user * @enum {string} */ createdBy: 'user' | 'auto_save' | 'restore' | 'deploy' | 'preview'; /** @example sha256:abc123... */ contentHash?: string; }; Project: { /** @example proj_x7y8z9 */ id: string; /** @example My Website */ name: string; /** * @example owner * @enum {string} */ role: 'owner' | 'admin' | 'member' | 'deployer' | 'viewer'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; /** @example 3 */ memberCount: number; /** @example 5 */ flowCount: number; /** @example 2 */ deploymentCount: number; /** @example false */ isDemo: boolean; }; Member: { userId: string; /** Format: email */ email: string; /** @enum {string} */ role: 'owner' | 'admin' | 'member' | 'deployer' | 'viewer'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; }; DeleteAccountRequest: { /** @example me@example.com */ confirm: string; }; DeleteAccountBlocked: { error: { /** * @example SOLE_OWNER * @enum {string} */ code: 'SOLE_OWNER'; message: string; details: { /** * @example [ * "proj_abc123" * ] */ projects: string[]; }; }; }; AccountExportResponse: { /** @example 2026-06-10T12:00:00.000Z */ exportedAt: string; profile: { /** @example user_a1b2c3d4 */ id: string; /** @example me@example.com */ email: string; displayName: string | null; createdAt: string; lastLoginAt: string | null; /** @example user */ globalRole: string; traits: string[]; }; memberships: { projectId: string; projectName: string; role: string; joinedAt: string; }[]; tokens: { id: string; name: string; /** @example automation */ kind: string; /** @example read write */ scope: string; /** @example api mcp */ audience: string; projectId: string | null; createdAt: string; lastUsedAt: string | null; expiresAt: string; revokedAt: string | null; }[]; sessions: { id: string; createdAt: string; expiresAt: string; lastTouchedAt: string; }[]; mcpSessions: { id: string; projectId: string | null; createdAt: string; lastActiveAt: string; expiresAt: string; messages: { seq: number; role: string; content?: unknown; createdAt: string; }[]; }[]; feedback: { id: string; projectId: string | null; text: string; source: string; createdAt: string; }[]; invitations: { id: string; projectId: string; invitedEmail: string; role: string; status: string; createdAt: string; expiresAt: string; acceptedAt: string | null; declinedAt: string | null; cancelledAt: string | null; }[]; }; AutomationTokenSummary: { /** @example tok_a1b2c3d4 */ id: string; /** @example CI Pipeline */ name: string; /** @example wos_pat_a1b2 */ tokenPrefix: string; /** * @example [ * "read", * "write" * ] */ scope: string[]; /** * @example [ * "api", * "mcp" * ] */ audience: string[]; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ lastUsedAt: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ expiresAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ revokedAt: string | null; }; FlowSettingsDetail: { /** @example cfg_a1b2c3d4 */ id: string; name: string; /** * @example web * @enum {string} */ platform: 'web' | 'server'; config: { [key: string]: unknown; }; deployment?: { id: string; status: string; type: string; containerUrl?: string | null; publicUrl?: string | null; errorMessage?: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; } | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; }; DeploySettingsRequest: { flow?: string; humanText?: string; }; DeploySettingsResponse: { deploymentId: string; /** @example cfg_a1b2c3d4 */ settingsId: string; status: string; }; FlowDetailResponse: { /** @example flow_a1b2c3d4 */ id: string; /** @example my-website-flow */ name: string; config: components['schemas']['FlowConfig']; settings?: components['schemas']['FlowSettingsEnriched'][]; bundleId?: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; /** Format: date-time */ deletedAt: string | null; }; FlowSettingsEnriched: { id: string; name: string; /** @enum {string} */ platform: 'web' | 'server'; deployment: { id: string; slug: string; status: string; type: string; target: string | null; containerUrl: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; updatedAt: string | null; } | null; serving: components['schemas']['ServingStatus']; latestAttempt: components['schemas']['LatestAttemptStatus']; deployedAt: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; }; FlowUpdateResponse: { /** @example flow_a1b2c3d4 */ id: string; /** @example my-website-flow */ name: string; config: components['schemas']['FlowConfig']; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; }; CreateProjectResponse: { /** @example proj_x7y8z9 */ id: string; name: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; }; UpdateProjectResponse: { /** @example proj_x7y8z9 */ id: string; name: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; }; DeploymentSummary: { /** @example dep_a1b2c3d4 */ id: string; /** * @example web * @enum {string} */ type: 'web' | 'server'; /** @example k7m2x9p4q1w8 */ slug: string; target: string | null; label: string | null; /** * @example cloud * @enum {string} */ origin: 'cloud' | 'self-hosted'; /** * @example active * @enum {string} */ status: | 'idle' | 'deploying' | 'published' | 'active' | 'stopped' | 'failed'; serving: components['schemas']['ServingStatus']; currentVersionNumber: number | null; url: string | null; /** @example flow_a1b2c3d4 */ flowId: string | null; flowName: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; usageSummary?: { eventsIn24h: number; healthy: boolean; }; }; DeploymentDetailResponse: { /** @example dep_a1b2c3d4 */ id: string; /** * @example web * @enum {string} */ type: 'web' | 'server'; /** @example k7m2x9p4q1w8 */ slug: string; target: string | null; label: string | null; /** * @example cloud * @enum {string} */ origin: 'cloud' | 'self-hosted'; /** * @example active * @enum {string} */ status: | 'idle' | 'deploying' | 'published' | 'active' | 'stopped' | 'failed'; currentVersion: components['schemas']['DeploymentVersionDetail'] | null; versions: components['schemas']['DeploymentVersionHistoryEntry'][]; error: components['schemas']['DeploymentError'] | null; recentErrors?: | { message: string; count: number; firstSeen: string; lastSeen: string; }[] | null; recentLogs?: | { time: string; level: string; message: string; }[] | null; url: string | null; selfHosted: { /** Format: date-time */ lastHeartbeatAt: string; instanceId: string | null; cliVersion: string | null; healthy: boolean; } | null; /** Format: date-time */ lastHeartbeatAt?: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; }; DeploymentVersionDetail: { number: number; status: string; source: { type: string; flowId?: string; flowSettingsId?: string; configHash?: string; }; errorMessage: string | null; errorCode: string | null; /** Format: date-time */ publishedAt: string; publishedBy: string | null; }; DeploymentVersionHistoryEntry: { versionNumber: number; status: string; source: string; errorCode: string | null; errorMessage: string | null; errorPhase: string | null; errorDetail?: string | null; /** Format: date-time */ publishedAt: string; }; DeploymentError: { code: string; message: string; /** * @example bundle * @enum {string} */ phase: 'preflight' | 'deploy' | 'bundle' | 'publish' | 'provision'; detail?: string; }; CreateDeploymentResponse: { /** @example dep_a1b2c3d4 */ id: string; /** * @example web * @enum {string} */ type: 'web' | 'server'; /** @example k7m2x9p4q1w8 */ slug: string; target: string | null; label: string | null; /** * @example cloud * @enum {string} */ origin: 'cloud' | 'self-hosted'; /** * @example active * @enum {string} */ status: | 'idle' | 'deploying' | 'published' | 'active' | 'stopped' | 'failed'; serving: components['schemas']['ServingStatus']; currentVersionNumber: number | null; url: string | null; /** @example flow_a1b2c3d4 */ flowId: string | null; flowName: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; usageSummary?: { eventsIn24h: number; healthy: boolean; }; }; StartDeploymentResponse: | { /** @example dep_a1b2c3d4 */ deploymentId: string; /** @example k7m2x9p4q1w8 */ slug: string; target: string | null; /** * @example web * @enum {string} */ type: 'web' | 'server'; /** @enum {string} */ status: 'deploying'; settingsId?: string; versionId: string; versionNumber: number; } | { deploymentId: string; /** @enum {string} */ status: 'already_created'; }; DeploymentStreamStatusEvent: { status: string; substatus: string | null; /** * @example web * @enum {string} */ type: 'web' | 'server'; target: string | null; containerUrl: string | null; errorCode: string | null; errorMessage: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; }; ListDeploymentsResponse: { deployments: components['schemas']['DeploymentSummary'][]; total: number; limit: number; offset: number; nextCursor: string | null; }; UpdateDeploymentResponse: { /** @example dep_a1b2c3d4 */ id: string; /** * @example web * @enum {string} */ type: 'web' | 'server'; /** @example k7m2x9p4q1w8 */ slug: string; target: string | null; label: string | null; /** * @example cloud * @enum {string} */ origin: 'cloud' | 'self-hosted'; /** * @example active * @enum {string} */ status: | 'idle' | 'deploying' | 'published' | 'active' | 'stopped' | 'failed'; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; }; LatestDeploymentsByFlow: { [key: string]: { id: string; flowId: string; slug: string; type: string; status: string; target: string | null; containerUrl: string | null; createdAt: string; }; }; PublishVersionResponse: { versionNumber: number; versionId: string; /** @example dep_a1b2c3d4 */ deploymentId: string; /** @enum {string} */ status: 'deploying'; source: | { /** @enum {string} */ type: 'flow'; flowId: string; flowSettingsName: string; } | { /** @enum {string} */ type: 'config'; }; /** Format: date-time */ createdAt: string; }; ListDeploymentVersionsResponse: { versions: { number: number; status: string; source: { type: string; flowId?: string; flowSettingsId?: string; configHash?: string; }; errorMessage: string | null; errorCode: string | null; bundlePath: string | null; /** Format: date-time */ publishedAt: string; publishedBy: string | null; }[]; total: number; limit: number; offset: number; }; ListFlowReleasesResponse: { releases: components['schemas']['FlowRelease'][]; total: number; limit: number; offset: number; }; FlowRelease: { id: string; /** @example dep_a1b2c3d4 */ deploymentId: string; /** @example k7m2x9p4q1w8 */ deploymentSlug: string | null; /** * @example web * @enum {string|null} */ deploymentType: 'web' | 'server' | null; versionNumber: number; /** @example ver_a1b2c3d4 */ flowVersionId: string | null; flowVersionNumber: number | null; status: string; source: string; errorCode: string | null; /** Format: date-time */ createdAt: string; createdBy: string | null; createdByLabel: string | null; rationale?: components['schemas']['ReleaseRationaleSummary'] | null; }; ReleaseRationaleSummary: { hasHumanText: boolean; hasGeneratedSummary: boolean; firstLine: string | null; }; ReleaseContentResponse: { /** @example ver_a1b2c3d4 */ versionId: string; /** @example 22 */ versionNumber: number; content: components['schemas']['FlowConfig']; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** @enum {string} */ createdBy: 'user' | 'auto_save' | 'restore' | 'deploy' | 'preview'; }; ReleaseDiff: { /** @example ver_a1b2c3d4 */ prevVersionId: string; prevVersionNumber: number; text: string; contentIdentical: boolean; }; ReleaseDetailResponse: { /** @example ver_a1b2c3d4 */ versionId: string; versionNumber: number; contentHash: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; createdBy: string; rationale: components['schemas']['VersionAnnotation'] | null; diff: components['schemas']['ReleaseDiff'] | null; }; VersionAnnotation: { /** @example ver_a1b2c3d4 */ versionId: string; humanText: string | null; generatedSummary: string | null; /** @example user_a1b2c3d4 */ author: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; }; ListVersionAnnotationsResponse: { annotations: components['schemas']['VersionAnnotation'][]; }; UpsertVersionAnnotationResponse: { /** @example ver_a1b2c3d4 */ versionId: string; humanText: string | null; generatedSummary: string | null; /** @example user_a1b2c3d4 */ author: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; }; ListHubThreadsResponse: { threads: components['schemas']['HubThread'][]; hasMoreThreads: boolean; }; HubThread: { /** @example thr_a1b2c3d4 */ id: string; /** * @example release * @enum {string} */ anchorType: 'step' | 'entity_action' | 'release' | 'contract' | 'tag'; anchorKey: string; anchorLabel: string; /** * @example open * @enum {string} */ status: 'open' | 'resolved'; resolvedByVersionId: string | null; resolvedByVersionNumber: number | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ resolvedAt: string | null; resolvedBy: string | null; createdBy: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; messageCount: number; messages?: components['schemas']['HubMessage'][]; hasMoreMessages?: boolean; }; HubMessage: { id: string; /** @example user_a1b2c3d4 */ author: string; text: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; }; HubThreadResponse: { /** @example thr_a1b2c3d4 */ id: string; /** * @example release * @enum {string} */ anchorType: 'step' | 'entity_action' | 'release' | 'contract' | 'tag'; anchorKey: string; anchorLabel: string; /** * @example open * @enum {string} */ status: 'open' | 'resolved'; resolvedByVersionId: string | null; resolvedByVersionNumber: number | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ resolvedAt: string | null; resolvedBy: string | null; createdBy: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; messageCount: number; messages?: components['schemas']['HubMessage'][]; hasMoreMessages?: boolean; }; ListKnowledgeResponse: { entries: components['schemas']['KnowledgeEntry'][]; hasMoreEntries: boolean; }; KnowledgeEntry: | components['schemas']['KnowledgeThread'] | components['schemas']['KnowledgeDescription']; KnowledgeThread: { id: string; anchorKey: string; anchorLabel: string; frameId: string | null; frameName: string | null; flowId: string | null; subjectKey: string | null; spatial: components['schemas']['KnowledgeSpatial'] | null; validity: components['schemas']['KnowledgeValidity']; /** @enum {string} */ freshness: 'current' | 'subject_changed' | 'unknown'; author: components['schemas']['KnowledgeAuthor']; /** @enum {string} */ source: 'tag_mode' | 'hub' | 'mcp'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; /** * @description discriminator enum property added by openapi-typescript * @enum {string} */ kind: 'thread'; /** * @example tag * @enum {string} */ anchorType: | 'step' | 'entity_action' | 'release' | 'contract' | 'tag' | 'page'; /** * @example open * @enum {string} */ status: 'open' | 'resolved'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; messageCount: number; messages?: components['schemas']['KnowledgeMessage'][]; hasMoreMessages?: boolean; }; KnowledgeSpatial: { at: { x: number; y: number; }; element?: { [key: string]: unknown; }; }; KnowledgeValidity: | { /** @enum {string} */ tier: 'release'; versionId: string; versionNumber: number; promoted: boolean; } | { /** @enum {string} */ tier: 'draft'; versionId?: string; } | { /** @enum {string} */ tier: 'none'; }; KnowledgeAuthor: { /** @enum {string} */ kind: 'user' | 'preview' | 'agent'; id: string | null; label: string; }; KnowledgeMessage: { id: string; /** @example user_a1b2c3d4 */ author: string; /** @example ayla@elbwalker.com */ authorLabel: string; text: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; clientMessageId: string | null; }; KnowledgeDescription: { id: string; anchorKey: string; anchorLabel: string; frameId: string | null; frameName: string | null; flowId: string | null; subjectKey: string | null; spatial: components['schemas']['KnowledgeSpatial'] | null; validity: components['schemas']['KnowledgeValidity']; /** @enum {string} */ freshness: 'current' | 'subject_changed' | 'unknown'; author: components['schemas']['KnowledgeAuthor']; /** @enum {string} */ source: 'tag_mode' | 'hub' | 'mcp'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; /** * @description discriminator enum property added by openapi-typescript * @enum {string} */ kind: 'description'; /** * @example tag * @enum {string} */ anchorType: 'tag' | 'page'; body: string; }; KnowledgeThreadResponse: { id: string; anchorKey: string; anchorLabel: string; frameId: string | null; frameName: string | null; flowId: string | null; subjectKey: string | null; spatial: components['schemas']['KnowledgeSpatial'] | null; validity: components['schemas']['KnowledgeValidity']; /** @enum {string} */ freshness: 'current' | 'subject_changed' | 'unknown'; author: components['schemas']['KnowledgeAuthor']; /** @enum {string} */ source: 'tag_mode' | 'hub' | 'mcp'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; /** @enum {string} */ kind: 'thread'; /** * @example tag * @enum {string} */ anchorType: | 'step' | 'entity_action' | 'release' | 'contract' | 'tag' | 'page'; /** * @example open * @enum {string} */ status: 'open' | 'resolved'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; messageCount: number; messages?: components['schemas']['KnowledgeMessage'][]; hasMoreMessages?: boolean; }; KnowledgeDescriptionResponse: { id: string; anchorKey: string; anchorLabel: string; frameId: string | null; frameName: string | null; flowId: string | null; subjectKey: string | null; spatial: components['schemas']['KnowledgeSpatial'] | null; validity: components['schemas']['KnowledgeValidity']; /** @enum {string} */ freshness: 'current' | 'subject_changed' | 'unknown'; author: components['schemas']['KnowledgeAuthor']; /** @enum {string} */ source: 'tag_mode' | 'hub' | 'mcp'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; /** @enum {string} */ kind: 'description'; /** * @example tag * @enum {string} */ anchorType: 'tag' | 'page'; body: string; }; FrameInput: { name: string; /** @example frm_V1StGXR8Z5jdHi6BmyT7K */ parentId: string | null; placements: components['schemas']['FramePlacement'][]; size: components['schemas']['PlanSize']; marks: { [key: string]: unknown; }; /** @example frm_V1StGXR8Z5jdHi6BmyT7K */ extends: string | null; source: components['schemas']['FrameSource']; /** @enum {string} */ origin: 'drawn' | 'imported' | 'observed'; flowId: string | null; }; FramePlacement: { id: string; rect: components['schemas']['PlanRect']; selector?: string; anchor?: { [key: string]: unknown; }; }; PlanRect: { x: number; y: number; w: number; h: number; }; PlanSize: { width: number; height: number; }; FrameSource: | { /** @enum {string} */ kind: 'page'; key: string; url: string; } | { /** @enum {string} */ kind: 'figma'; fileKey: string; nodeId: string; } | { /** @enum {string} */ kind: 'image'; } | null; Frame: { /** @example frm_V1StGXR8Z5jdHi6BmyT7K */ id: string; projectId: string; name: string; parentId: string | null; placements: components['schemas']['FramePlacement'][]; size: components['schemas']['PlanSize']; marks: { [key: string]: unknown; }; extends: string | null; source: components['schemas']['FrameSource']; /** @enum {string} */ origin: 'drawn' | 'imported' | 'observed'; flowId: string | null; screenshot: components['schemas']['FrameScreenshot'] | null; version: number; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; createdBy: string; updatedBy: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ deletedAt: string | null; }; FrameScreenshot: { assetId: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ capturedAt: string; size: components['schemas']['PlanSize']; dpr: number; capturedRect: components['schemas']['PlanRect']; }; FrameLean: { /** @example frm_V1StGXR8Z5jdHi6BmyT7K */ id: string; projectId: string; name: string; parentId: string | null; placements: components['schemas']['FramePlacement'][]; size: components['schemas']['PlanSize']; extends: string | null; source: components['schemas']['FrameSource']; /** @enum {string} */ origin: 'drawn' | 'imported' | 'observed'; flowId: string | null; screenshot: components['schemas']['FrameScreenshot'] | null; version: number; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; createdBy: string; updatedBy: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ deletedAt: string | null; }; FrameListResponse: { frames: components['schemas']['Frame'][]; }; FrameLeanListResponse: { frames: components['schemas']['FrameLean'][]; }; PutFrameResponse: { version: number; }; FrameConflictResponse: { error: { /** @enum {string} */ code: 'FRAME_VERSION_CONFLICT'; message: string; }; head: components['schemas']['Frame']; }; CanvasDocument: { /** @enum {number} */ v: 1; nodes: components['schemas']['CanvasNodeEntry'][]; edges: components['schemas']['CanvasEdgeEntry'][]; hidden: string[]; }; CanvasNodeEntry: { kind: string; ref: string; position: components['schemas']['CanvasPoint']; parent?: string; size?: { width: number; height: number; }; label?: string; }; CanvasPoint: { x: number; y: number; }; CanvasEdgeEntry: { id: string; /** @enum {string} */ kind: 'navigation'; from: string; to: string; label?: string; }; Canvas: { /** @example cnv_V1StGXR8Z5jdHi6BmyT7K */ id: string; projectId: string; name: string; document: components['schemas']['CanvasDocument']; version: number; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; createdBy: string; updatedBy: string; }; CanvasLean: { /** @example cnv_V1StGXR8Z5jdHi6BmyT7K */ id: string; projectId: string; name: string; version: number; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ updatedAt: string; createdBy: string; updatedBy: string; }; CanvasListResponse: { canvases: components['schemas']['CanvasLean'][]; }; PutCanvasResponse: { version: number; }; CanvasConflictResponse: { error: { /** @enum {string} */ code: 'CANVAS_VERSION_CONFLICT'; message: string; }; head: components['schemas']['Canvas']; }; SummarizeReleaseResponse: { /** @enum {string} */ mode: 'draft' | 'check'; text: string; cached: boolean; /** @example mistral/platform/mistral-large-2512 */ modelId: string; versionNumber: number; prevVersionNumber: number; }; StepHistoryResponse: { step: string; flow: string | null; entries: components['schemas']['StepHistoryEntry'][]; scanned: number; truncated: boolean; entriesTruncated: boolean; knownSteps?: string[]; }; StepHistoryEntry: { /** @example ver_a1b2c3d4 */ versionId: string; versionNumber: number; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; flow: string | null; /** * @example changed * @enum {string} */ change: 'added' | 'removed' | 'changed'; humanText: string | null; generatedSummary: string | null; }; HeartbeatResponse: { /** @enum {boolean} */ ack: true; /** @example dep_a1b2c3d4 */ deploymentId: string; /** @enum {string} */ action: 'none' | 'stop' | 'update'; versionNumber?: number; bundleUrl?: string; }; ObserveTicketRequest: { scope?: { /** @enum {string} */ kind: 'session'; sessionId: string; }; }; ObserveTicketResponse: { ticket: string; /** Format: uri */ observerUrl: string; }; PreviewResponse: { /** @example prv_abc123xyz456 */ id: string; /** @example flow_a1b2c3d4 */ flowId: string; flowSettingsId: string; projectId: string; /** Format: uri */ bundleUrl: string; activationUrl: string | null; tagMode: boolean; createdBy: string; /** Format: date-time */ createdAt: string; }; CreatePreviewResponse: components['schemas']['PreviewResponse'] & { grant: string | null; }; ListPreviewsResponse: { previews: components['schemas']['PreviewResponse'][]; total: number; }; CreatePreviewRequest: { flowSettingsId: string; source?: | { /** @enum {string} */ kind: 'draft'; } | { /** @enum {string} */ kind: 'deployment-version'; deploymentVersionId: string; }; /** @default true */ tagMode: boolean; }; MintGrantRequest: { origins: string[]; sessionId?: string; }; MintGrantResponse: { grant: string; /** Format: uri */ activationUrl: string; /** Format: date-time */ sessionExpiresAt: string; sessionGrant?: string; sessionId?: string; }; ObserveSessionResponse: { /** @example ses_abc123xyz456 */ id: string; projectId: string; /** @example flow_a1b2c3d4 */ flowId: string; status: string; errorMessage: string | null; configSnapshot: { [key: string]: unknown; }; observedFlowName: string | null; serverFlowName: string | null; serverEndpoint: string | null; web: components['schemas']['ObserveSessionWeb'] | null; server: components['schemas']['ObserveSessionServer'] | null; /** Format: date-time */ expiresAt: string; recordsReceived: number; createdBy: string; /** Format: date-time */ createdAt: string; }; ObserveSessionWeb: { /** Format: uri */ activationUrl: string | null; credential: string; previewEnabled: boolean; /** Format: uri */ bundleUrl: string; /** Format: uri */ url?: string; binding?: string; }; ObserveSessionServer: { /** Format: uri */ endpoint: string | null; env: components['schemas']['ObserveSessionServerEnv']; }; ObserveSessionServerEnv: { /** Format: uri */ WALKEROS_OBSERVER_URL: string; WALKEROS_DEPLOYMENT_ID: string; WALKEROS_INGEST_TOKEN: string; }; ObserveSessionJourneysResponse: { /** @example ses_abc123xyz456 */ sessionId: string; /** @example flow_a1b2c3d4 */ flowId: string; /** Format: date-time */ assembledAt: string; journeys: { [key: string]: unknown; }[]; gaps: { [key: string]: unknown; }[]; unattributed?: { [key: string]: unknown; }[]; }; CreateObserveSessionRequest: { settingsName: string; force?: boolean; replace?: boolean; level?: components['schemas']['ObserveLevel']; origins?: string[]; tagMode?: boolean; }; /** @enum {string} */ ObserveLevel: 'off' | 'standard' | 'trace'; ObserveSessionHeartbeatResponse: { /** @enum {boolean} */ ok: true; }; SecretName: string; CreateSecretRequest: { name: string; value: string; }; UpdateSecretRequest: { value: string; }; SecretSummary: { id: string; name: string; flowId: string; /** Format: date-time */ createdAt: string | null; /** Format: date-time */ updatedAt: string | null; }; SecretListResponse: { secrets: { id: string; name: string; flowId: string; /** Format: date-time */ createdAt: string | null; /** Format: date-time */ updatedAt: string | null; }[]; }; FeedbackRequest: { /** @example The MCP flow_bundle tool is great but slow on large configs. */ text: string; /** * Format: email * @example alex@example.com */ userId?: string; /** @example proj_abc123 */ projectId?: string; /** @example 0.4.2 */ version?: string; }; FeedbackResponse: { /** @enum {boolean} */ ok: true; /** @example fb_abcdef1234567890 */ id: string; }; StepExample: { title?: string; description?: string; public?: boolean; trigger?: { type?: string; options?: unknown; }; mapping?: unknown; command?: string; in: components['schemas']['StepExampleEvent']; out?: unknown[][]; }; StepExampleEvent: { entity?: string; action?: string; data?: { [key: string]: unknown; }; context?: { [key: string]: unknown; }; globals?: { [key: string]: unknown; }; custom?: { [key: string]: unknown; }; id?: string; timestamp?: string; timing?: { [key: string]: unknown; }; user?: { [key: string]: unknown; }; version?: string; source?: string; trigger?: string; }; CreateStepExampleRequest: { title?: string; description?: string; public?: boolean; trigger?: { type?: string; options?: unknown; }; mapping?: unknown; command?: string; name: string; event: components['schemas']['StepExampleEvent']; out?: unknown[][]; }; EditStepExampleRequest: { title?: string; description?: string; public?: boolean; trigger?: { type?: string; options?: unknown; }; mapping?: unknown; command?: string; name: string; event?: components['schemas']['StepExampleEvent']; out?: unknown[][]; }; StepExamplesResponse: { examples: { [key: string]: components['schemas']['StepExample']; }; }; ObserveStepExample: { in?: unknown; out?: unknown; mapping?: unknown; title?: string; description?: string; }; ObserveSaveExampleRequest: { stepPath: string; scenario: string; example: components['schemas']['ObserveStepExample']; }; SecretValuesResponse: { values: { [key: string]: string; }; }; ServiceAccountSummary: { id: string; name: string; /** @enum {string} */ role: 'member' | 'deployer' | 'viewer'; email: string; description: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; }; CreateServiceAccountRequest: { name: string; /** @enum {string} */ role: 'member' | 'deployer' | 'viewer'; description?: string; }; UpdateServiceAccountRequest: { name?: string; description?: string; /** @enum {string} */ role?: 'member' | 'deployer' | 'viewer'; }; CreateServiceAccountResponse: { id: string; name: string; /** @enum {string} */ role: 'member' | 'deployer' | 'viewer'; email: string; token: string; tokenId: string; tokenPrefix: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; }; ListServiceAccountsResponse: { serviceAccounts: components['schemas']['ServiceAccountSummary'][]; total: number; }; CreateSaTokenRequest: { name: string; expiresInDays?: number; }; SaTokenSummary: { id: string; name: string; prefix: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ lastUsedAt: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ expiresAt: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ revokedAt: string | null; }; CreateSaTokenResponse: { id: string; name: string; token: string; prefix: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ expiresAt: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; }; ListSaTokensResponse: { tokens: components['schemas']['SaTokenSummary'][]; total: number; }; Invitation: { id: string; /** * Format: email * @example user@example.com */ email: string; /** * @default member * @example member * @enum {string} */ role: 'admin' | 'member' | 'deployer' | 'viewer'; /** @enum {string} */ status: 'pending' | 'accepted' | 'declined' | 'expired' | 'cancelled'; invitedBy: string | null; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ expiresAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; }; CreateInvitationRequest: { /** * Format: email * @example user@example.com */ email: string; /** * @default member * @example member * @enum {string} */ role: 'admin' | 'member' | 'deployer' | 'viewer'; }; CreateInvitationResponse: { id: string; /** * Format: email * @example user@example.com */ email: string; /** * @default member * @example member * @enum {string} */ role: 'admin' | 'member' | 'deployer' | 'viewer'; /** @enum {string} */ status: 'pending'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ expiresAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; }; ListInvitationsResponse: { invitations: components['schemas']['Invitation'][]; total: number; }; InvitationPreview: { projectName: string; /** * Format: email * @example user@example.com */ email: string; /** * @default member * @example member * @enum {string} */ role: 'admin' | 'member' | 'deployer' | 'viewer'; /** @enum {string} */ status: 'pending' | 'accepted' | 'declined' | 'expired' | 'cancelled'; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ expiresAt: string; /** * Format: email * @example user@example.com */ invitedByEmail: string; }; AcceptInvitationResponse: { projectId: string; projectName: string; /** * @default member * @example member * @enum {string} */ role: 'admin' | 'member' | 'deployer' | 'viewer'; alreadyMember: boolean; }; TelemetryEvent: { id: string; name: string; entity: string; action: string; data: { [key: string]: unknown; }; context: { [key: string]: unknown; }; globals: { [key: string]: unknown; }; custom: { [key: string]: unknown; }; user: { device: string; session?: string; os: string; osVersion: string; node: string; language: string; timezone: string; } & { [key: string]: unknown; }; nested: unknown[]; consent: { [key: string]: boolean; }; trigger: string; timestamp: number; timing: number; source: { /** @enum {string} */ type: 'cli' | 'mcp'; platform?: string; release?: { [key: string]: string; }; version?: string; schema?: string; tool?: string; command?: string; } & { [key: string]: unknown; }; }; UpsertBillingDetailsRequest: { companyName: string; address: string; address2?: string; postalCode: string; city: string; country: string; vatId?: string; /** Format: email */ invoiceEmail: string; contactName?: string; }; BillingDetailsResponse: { id: string; projectId: string; companyName: string; address: string; address2: string | null; postalCode: string; city: string; country: string; vatId: string | null; invoiceEmail: string; contactName: string | null; /** @enum {string} */ taxTreatment: 'reverse_charge' | 'domestic' | 'export' | 'eu_standard'; /** @enum {string} */ viesStatus: 'verified' | 'invalid' | 'unavailable' | 'not_checked'; viesCompanyName: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; }; DeployedContentResponse: { deploymentId: string | null; versionNumber: number | null; status: string | null; flowSettingsName: string | null; /** Format: date-time */ publishedAt: string | null; content?: unknown; }; ListHeartbeatsResponse: { records: components['schemas']['HeartbeatRecord'][]; total: number; limit: number; offset: number; }; HeartbeatRecord: { id: string; instanceId: string | null; cliVersion: string | null; configVersion: number | null; mode: string | null; uptime: number | null; eventsIn: number | null; eventsOut: number | null; eventsFailed: number | null; perDestinationBreakdown?: unknown; /** Format: date-time */ receivedAt: string; }; RotateIngestTokenResponse: { ingestToken: string; }; DeploymentUsageResponse: { totalEventsIn: number; totalEventsOut: number; totalEventsFailed: number; totalInstances: number; heartbeatCount: number; /** Format: date-time */ from: string; /** Format: date-time */ to: string; averageThroughputPerHour: number; period: string; buckets: components['schemas']['UsageBucket'][]; destinations?: components['schemas']['UsageDestination'][]; }; UsageBucket: { /** Format: date-time */ bucket: string; eventsIn: number; eventsOut: number; eventsFailed: number; instances: number; }; UsageDestination: { name: string; count: number; failed: number; duration: number; dlqSize: number; dropped: number; }; CreateCustomDomainRequest: { hostname: string; deploymentId?: string; }; CustomDomain: { id: string; deploymentId: string; hostname: string; kind: string; status: string; scwResourceId: string | null; certStatus: string; /** Format: date-time */ verifiedAt: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; }; ListCustomDomainsResponse: { domains: components['schemas']['CustomDomain'][]; }; DeployTokenStatusResponse: | { /** @enum {boolean} */ hasToken: false; } | { /** @enum {boolean} */ hasToken: true; deploymentId: string; status: string; healthy: boolean; /** Format: date-time */ lastHeartbeatAt: string | null; instanceId: string | null; cliVersion: string | null; }; CreateDeployTokenResponse: { token: string; deploymentId: string; projectId: string; flowId: string; configName: string; }; EntitlementsResponse: { planId: string; role: string; entitlements: { [key: string]: boolean | number; }; }; SetLlmConfigRequest: | { /** @enum {string} */ action: 'clear'; } | { /** @enum {string} */ action: 'set'; config: | { /** @enum {string} */ provider: 'mistral'; modelId: string; apiKey: string; } | { /** @enum {string} */ provider: 'anthropic'; modelId: string; apiKey: string; } | { /** @enum {string} */ provider: 'openai'; modelId: string; apiKey: string; } | { /** @enum {string} */ provider: 'google'; modelId: string; apiKey: string; } | { /** @enum {string} */ provider: 'openai-compatible'; modelId: string; apiKey: string; /** Format: uri */ baseURL: string; }; }; SetLlmConfigResponse: | { /** @enum {boolean} */ cleared: true; } | { /** @enum {boolean} */ saved: true; }; LlmConfigStatusResponse: { provider: string; /** @enum {string} */ source: 'platform' | 'byok' | 'byom'; }; ListChatSessionsResponse: { sessions: components['schemas']['ChatSessionSummary'][]; total: number; }; ChatSessionSummary: { id: string; /** Format: date-time */ createdAt: string; /** Format: date-time */ lastActiveAt: string; messageCount: number; firstUserMessage?: string; }; ChatSessionDetailResponse: { id: string; /** Format: date-time */ createdAt: string; /** Format: date-time */ lastActiveAt: string; messages: components['schemas']['ChatSessionMessage'][]; }; ChatSessionMessage: { seq: number; role: string; content?: unknown; /** Format: date-time */ createdAt: string; }; ElicitRequest: { sessionId: string; elicitationId: string; result: | { /** @enum {string} */ action: 'accept'; content?: { [key: string]: string | number | boolean | string[]; }; } | { /** @enum {string} */ action: 'decline'; } | { /** @enum {string} */ action: 'cancel'; }; }; ElicitResponse: { /** @enum {boolean} */ ok: true; }; PackageCatalogResponse: { catalog: components['schemas']['PackageCatalogEntry'][]; count: number; }; PackageCatalogEntry: { name: string; version: string; description?: string; type: string; platform: string[]; }; PackageSearchResponse: { packages: components['schemas']['PackageSearchHit'][]; count: number; }; PackageSearchHit: { name: string; version: string; description: string; }; PackageSearchLogRequest: { query: string; /** @enum {string} */ result: 'hit' | 'miss'; /** @enum {string} */ platform?: 'web' | 'server'; projectId?: string; }; ListRunnersResponse: { runners: unknown[]; total: number; }; RunnerHeartbeatResponse: { id: string; instanceId: string; deploymentId: string; }; ObserveTimingRequest: { connectId: string; ticketMs: number; sseMs: number; totalMs: number; }; MagicLinkResponse: { /** @example true */ success: boolean; /** @example Magic link sent */ message: string; }; MagicLinkRequest: { /** * Format: email * @example user@example.com */ email: string; /** @example /dashboard */ redirect_to?: string; }; VerifyResponse: | { /** @enum {string} */ status: 'ok'; /** @example / */ redirectTo: string; } | { /** @enum {string} */ status: 'confirm_required'; /** @example user@example.com */ email: string; } | { /** @enum {string} */ status: 'expired' | 'used' | 'invalid' | 'malformed'; }; VerifyRequest: { token: string; /** @example /dashboard */ redirect_to?: string; confirm?: boolean; }; WhoamiResponse: { /** @example user_a1b2c3d4 */ userId: string; /** * Format: email * @example user@example.com */ email: string; /** @example null */ projectId: string | null; }; ListSessionsResponse: { sessions: { id: string; /** Format: date-time */ createdAt: string; /** Format: date-time */ expiresAt: string; /** Format: date-time */ lastTouchedAt: string; isCurrent: boolean; }[]; }; ListProjectsResponse: { projects: components['schemas']['Project'][]; total: number; nextCursor: string | null; }; CreateProjectRequest: { name: string; }; ProjectDetailResponse: { /** @example proj_x7y8z9 */ id: string; name: string; /** * Format: uri * @example https://example.com */ siteUrl?: string | null; /** @enum {string} */ role: 'owner' | 'admin' | 'member' | 'deployer' | 'viewer'; }; UpdateProjectRequest: { name?: string; /** * Format: uri * @example https://example.com */ siteUrl?: string | null; }; ListMembersResponse: { members: components['schemas']['Member'][]; total: number; }; AddMemberRequest: { /** * Format: email * @example user@example.com */ email: string; /** * @default member * @enum {string} */ role: 'owner' | 'admin' | 'member' | 'deployer' | 'viewer'; }; UpdateMemberRequest: { /** @enum {string} */ role: 'owner' | 'admin' | 'member' | 'deployer' | 'viewer'; }; ListFlowsResponse: { flows: components['schemas']['FlowSummary'][]; total: number; nextCursor: string | null; }; CreateFlowRequest: { /** @example my-website-flow */ name: string; config?: components['schemas']['FlowConfig']; }; UpdateFlowRequest: { /** @example my-website-flow */ name?: string; config?: components['schemas']['FlowConfig']; }; DuplicateFlowRequest: { /** @example my-website-flow */ name?: string; }; DeploymentResponse: { id: string; flowId: string; /** @enum {string} */ type: 'web' | 'server'; status: string; containerUrl: string | null; publicUrl?: string | null; errorMessage: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; } | null; ListSettingsResponse: { settings: components['schemas']['FlowSettingsSummary'][]; }; SettingsDeploymentResponse: { id: string; flowId: string; settingsId: string; /** @enum {string} */ type: 'web' | 'server'; status: string; containerUrl: string | null; publicUrl: string | null; errorMessage: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; } | null; SettingsDeploymentDetailResponse: { id: string; flowId: string; settingsId: string; status: string; /** @enum {string} */ type: 'web' | 'server'; containerUrl: string | null; publicUrl: string | null; errorMessage: string | null; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; }; FlowJourneysResponse: { /** @example ses_abc123xyz456 */ sessionId: string | null; /** @example flow_a1b2c3d4 */ flowId: string; /** Format: date-time */ assembledAt: string; journeys: { [key: string]: unknown; }[]; gaps: { [key: string]: unknown; }[]; unattributed?: { [key: string]: unknown; }[]; }; ListVersionsResponse: { data: components['schemas']['Version'][]; /** @example flow_a1b2c3d4 */ flowId: string; total: number; limit: number; offset: number; hasMore: boolean; }; GetVersionResponse: { /** @example 1 */ version: number; content: components['schemas']['FlowConfig']; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** @enum {string} */ createdBy: 'user' | 'auto_save' | 'restore' | 'deploy' | 'preview'; }; ListAutomationTokensResponse: { tokens: components['schemas']['AutomationTokenSummary'][]; }; CreateAutomationTokenResponse: { /** @example tok_a1b2c3d4 */ id: string; /** @example CI Pipeline */ name: string; /** @example wos_pat_a1b2c3d4... */ token: string; /** @example wos_pat_a1b2 */ tokenPrefix: string; /** * @example [ * "read", * "write" * ] */ scope: string[]; /** * @example [ * "api", * "mcp" * ] */ audience: string[]; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ expiresAt: string; }; CreateAutomationTokenRequest: { /** @example CI Pipeline */ name: string; /** * @example read write * @enum {string} */ scope: 'read' | 'read write'; /** @example 90 */ expiresInDays: 30 | 90 | 180 | 365; }; BundleResponse: { bundleId: string; cached: boolean; }; SimulateResponse: { success: boolean; result?: { /** @enum {string} */ step: 'source' | 'transformer' | 'destination'; name: string; events: { [key: string]: unknown; }[]; calls: { fn: string; args: unknown[]; ts: number; }[]; duration: number; }; }; SimulateRequest: { bundleId: string; config: { [key: string]: unknown; }; event: { [key: string]: unknown; }; step: string; }; RegisterRuntimeRequest: { flowId: string; bundlePath: string; }; ValidateTicketResponse: { userId: string; projectId: string; replay: { size: number; ttlMs: number; }; scope: { /** @enum {string} */ kind: 'session'; sessionId: string; } | null; }; ValidateTicketRequest: { ticket: string; }; HealthResponse: { /** @example ok */ status: string; /** * @description Build identity of the running app (git short hash injected at build time). * @example a1b2c3d */ appVersion: string; /** * @description Semver of the API contract the server implements. * @example 1.0.0 */ contractVersion: string; /** * @description Deterministic sha256 of the OpenAPI contract content. * @example e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 */ contractHash: string; }; DeclineInvitationResponse: { message: string; }; ScreenshotUploadResponse: { /** @example fas_V1StGXR8Z5jdHi6BmyT7K */ assetId: string; reused: boolean; }; FrameScreenshotMeta: { /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ capturedAt: string; size: components['schemas']['PlanSize']; dpr: number; capturedRect: components['schemas']['PlanRect']; }; HeartbeatRequest: { /** @example a1b2c3d4e5f6 */ instanceId: string; /** @example flow_abc123 */ flowId: string; configVersion?: string; /** @enum {string} */ mode?: 'local' | 'collect' | 'serve'; /** @example 1.3.0 */ cliVersion?: string; uptime?: number; metadata?: { [key: string]: unknown; }; /** @example dpl_abc123 */ deploymentId?: string; counters?: { eventsIn: number; eventsOut: number; eventsFailed: number; destinations: { [key: string]: { count: number; failed: number; duration: number; dlqSize?: number; dropped?: number; }; }; }; recentErrors?: { message: string; count: number; /** Format: date-time */ firstSeen: string; /** Format: date-time */ lastSeen: string; }[]; recentLogs?: { /** Format: date-time */ time: string; /** @enum {string} */ level: 'error' | 'warn' | 'info' | 'debug'; message: string; }[]; }; OAuthClientRegistrationResponse: { /** @example client_abc */ client_id: string; /** @example 1725400000 */ client_id_issued_at: number; client_name: string; redirect_uris: string[]; /** @enum {string} */ token_endpoint_auth_method: 'none'; grant_types: string[]; response_types: string[]; }; OAuthRegistrationError: { /** @enum {string} */ error: 'invalid_client_metadata' | 'invalid_redirect_uri'; error_description: string; }; OAuthClientRegistrationRequest: { /** * @example [ * "https://claude.ai/api/mcp/auth_callback" * ] */ redirect_uris: string[]; client_name?: string; /** @enum {string} */ token_endpoint_auth_method?: 'none'; grant_types?: ('authorization_code' | 'refresh_token')[]; response_types?: 'code'[]; /** Format: uri */ client_uri?: string; /** Format: uri */ logo_uri?: string; scope?: string; software_id?: string; software_version?: string; }; DeviceAuthorizationResponse: { device_code: string; /** @example WDJB-MJHT */ user_code: string; verification_uri: string; verification_uri_complete: string; /** @example 900 */ expires_in: number; /** @example 5 */ interval: number; }; OAuthError: { /** @example invalid_client */ error: string; error_description: string; }; DeviceAuthorizationRequest: { /** @example walkeros-cli */ client_id: string; /** @example read write offline_access */ scope?: string; /** @example https://app.walkeros.io/api */ resource?: string; }; TokenResponse: { access_token: string; /** @enum {string} */ token_type: 'Bearer'; /** @example 3600 */ expires_in: number; refresh_token?: string; /** @example read write offline_access */ scope: string; }; TokenRequest: { /** * @example authorization_code * @enum {string} */ grant_type: | 'authorization_code' | 'refresh_token' | 'urn:ietf:params:oauth:grant-type:device_code'; /** @example walkeros-cli */ client_id?: string; client_secret?: string; code?: string; redirect_uri?: string; code_verifier?: string; refresh_token?: string; device_code?: string; /** @example read offline_access */ scope?: string; /** @example https://app.walkeros.io/api */ resource?: string; }; RevocationRequest: { token: string; /** @enum {string} */ token_type_hint?: 'access_token' | 'refresh_token'; client_id?: string; client_secret?: string; }; DeviceApprovalResponse: { /** @enum {boolean} */ success: true; /** @enum {string} */ decision: 'approve' | 'deny'; }; DeviceApprovalRequest: { /** @example WDJB-MJHT */ userCode: string; /** @enum {string} */ decision: 'approve' | 'deny'; }; OAuthConsentDecisionResponse: { /** @example https://claude.ai/api/mcp/auth_callback?code=abc&state=xyz */ redirectTo: string; }; OAuthConsentDecisionRequest: { ticket: string; /** @enum {string} */ decision: 'allow' | 'deny'; }; ListOAuthGrantsResponse: { grants: components['schemas']['OAuthGrantSummary'][]; }; OAuthGrantSummary: { id: string; clientId: string; clientName: string; scope: string[]; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ createdAt: string; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ lastUsedAt: string | null; }; ListOAuthClientsResponse: { clients: components['schemas']['OAuthClientSummary'][]; }; OAuthClientSummary: { clientId: string; /** @enum {string} */ kind: 'dcr' | 'cimd' | 'confidential' | 'builtin'; name: string; redirectUris: string[]; grantTypes: string[]; /** @enum {string} */ tokenEndpointAuthMethod: | 'none' | 'client_secret_basic' | 'client_secret_post'; allowedResources: ('mcp' | 'api')[]; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ revokedAt: string | null; }; CreateOAuthClientResponse: { clientId: string; /** @enum {string} */ kind: 'dcr' | 'cimd' | 'confidential' | 'builtin'; name: string; redirectUris: string[]; grantTypes: string[]; /** @enum {string} */ tokenEndpointAuthMethod: | 'none' | 'client_secret_basic' | 'client_secret_post'; allowedResources: ('mcp' | 'api')[]; /** * Format: date-time * @example 2026-01-26T14:30:00.000Z */ revokedAt: string | null; clientSecret: string; }; CreateOAuthClientRequest: { name: string; redirectUris: string[]; /** * @default [ * "authorization_code", * "refresh_token" * ] */ grantTypes: ('authorization_code' | 'refresh_token')[]; /** * @default [ * "mcp", * "api" * ] */ allowedResources: ('mcp' | 'api')[]; /** * @default client_secret_basic * @enum {string} */ authMethod: 'client_secret_basic' | 'client_secret_post'; }; }; responses: never; parameters: never; requestBodies: never; headers: never; pathItems: never; } type FlowSummary = paths['/api/projects/{projectId}/flows']['get']['responses']['200']['content']['application/json']['flows'][number]; type Project = paths['/api/projects']['get']['responses']['200']['content']['application/json']['projects'][number]; interface ProjectFlows { project: { id: Project['id']; name: Project['name']; }; flows: FlowSummary[]; } interface ListFlowsOptions { projectId?: string; sort?: 'name' | 'updated_at' | 'created_at'; order?: 'asc' | 'desc'; includeDeleted?: boolean; cursor?: string; limit?: number; } declare function listFlows(options?: ListFlowsOptions): Promise<{ flows: { id: string; name: string; summary?: string | undefined; settings?: { id: string; name: string; platform: "web" | "server"; serving: components["schemas"]["ServingStatus"]; latestAttempt: components["schemas"]["LatestAttemptStatus"]; deploymentUrl: string | null; deployedAt: string | null; }[] | undefined; createdAt: string; updatedAt: string; deletedAt: string | null; }[]; total: number; nextCursor: string | null; }>; declare function listAllFlows(options?: Omit): Promise; declare function getFlow(options: { flowId: string; projectId?: string; fields?: string[]; }): Promise<{ id: string; name: string; config: { [x: string]: unknown; version: 4; $schema?: string | undefined; include?: string[] | undefined; variables?: { [x: string]: unknown; } | undefined; definitions?: { [x: string]: unknown; } | undefined; flows?: { [x: string]: unknown; } | undefined; contract?: { [x: string]: unknown; } | undefined; }; settings?: { id: string; name: string; platform: "web" | "server"; deployment: { id: string; slug: string; status: string; type: string; target: string | null; containerUrl: string | null; createdAt: string; updatedAt: string | null; } | null; serving: components["schemas"]["ServingStatus"]; latestAttempt: components["schemas"]["LatestAttemptStatus"]; deployedAt: string | null; createdAt: string; updatedAt: string; }[] | undefined; bundleId?: string | null | undefined; createdAt: string; updatedAt: string; deletedAt: string | null; }>; declare function createFlow(options: { name: string; content: Record; projectId?: string; }): Promise<{ id: string; name: string; config: { [x: string]: unknown; version: 4; $schema?: string | undefined; include?: string[] | undefined; variables?: { [x: string]: unknown; } | undefined; definitions?: { [x: string]: unknown; } | undefined; flows?: { [x: string]: unknown; } | undefined; contract?: { [x: string]: unknown; } | undefined; }; settings?: { id: string; name: string; platform: "web" | "server"; createdAt: string; updatedAt: string; }[] | undefined; createdAt: string; updatedAt: string; deletedAt?: string | null | undefined; }>; declare function updateFlow(options: { flowId: string; name?: string; content?: Record; projectId?: string; mergePatch?: boolean; }): Promise<{ id: string; name: string; config: { [x: string]: unknown; version: 4; $schema?: string | undefined; include?: string[] | undefined; variables?: { [x: string]: unknown; } | undefined; definitions?: { [x: string]: unknown; } | undefined; flows?: { [x: string]: unknown; } | undefined; contract?: { [x: string]: unknown; } | undefined; }; createdAt: string; updatedAt: string; } | undefined>; declare function deleteFlow(options: { flowId: string; projectId?: string; }): Promise<{ success: boolean; }>; declare function duplicateFlow(options: { flowId: string; name?: string; projectId?: string; }): Promise<{ id: string; name: string; config: { [x: string]: unknown; version: 4; $schema?: string | undefined; include?: string[] | undefined; variables?: { [x: string]: unknown; } | undefined; definitions?: { [x: string]: unknown; } | undefined; flows?: { [x: string]: unknown; } | undefined; contract?: { [x: string]: unknown; } | undefined; }; settings?: { id: string; name: string; platform: "web" | "server"; createdAt: string; updatedAt: string; }[] | undefined; createdAt: string; updatedAt: string; deletedAt?: string | null | undefined; }>; interface FlowsCommandOptions extends GlobalOptions { json?: boolean; output?: string; project?: string; } declare function listFlowsCommand(options: FlowsCommandOptions & { sort?: string; order?: string; includeDeleted?: boolean; cursor?: string; limit?: number; }): Promise; declare function getFlowCommand(flowId: string, options: FlowsCommandOptions): Promise; declare function createFlowCommand(name: string, options: FlowsCommandOptions & { content?: string; }): Promise; declare function updateFlowCommand(flowId: string, options: FlowsCommandOptions & { name?: string; content?: string; }): Promise; declare function deleteFlowCommand(flowId: string, options: FlowsCommandOptions): Promise; declare function duplicateFlowCommand(flowId: string, options: FlowsCommandOptions & { name?: string; }): Promise; interface DeployOptions { flowId: string; projectId?: string; wait?: boolean; flowName?: string; timeout?: number; signal?: AbortSignal; onStatus?: (status: string, substatus: string | null) => void; } declare function deploy(options: DeployOptions): Promise<{ deploymentId: string; settingsId: string; status: string; } | { deploymentId: string; slug: string; target: string | null; type: "web" | "server"; status: "deploying"; settingsId?: string | undefined; versionId: string; versionNumber: number; } | { deploymentId: string; status: "already_created"; } | { status: string; substatus?: string | null; type: string; containerUrl?: string | null; publicUrl?: string | null; errorMessage?: string | null; deploymentId: string; slug: string; target: string | null; settingsId?: string | undefined; versionId: string; versionNumber: number; } | { status: string; substatus?: string | null; type?: string; containerUrl?: string | null; publicUrl?: string | null; errorMessage?: string | null; deploymentId: string; }>; declare function getDeployment(options: { flowId: string; projectId?: string; flowName?: string; }): Promise; interface DeployCommandOptions extends GlobalOptions { project?: string; flow?: string; wait?: boolean; timeout?: string; output?: string; json?: boolean; } declare function deployCommand(flowId: string, options: DeployCommandOptions): Promise; declare function getDeploymentCommand(flowId: string, options: DeployCommandOptions): Promise; interface ListDeploymentsOptions { projectId?: string; type?: 'web' | 'server'; status?: string; flowId?: string; cursor?: string; limit?: number; } declare function listDeployments(options?: ListDeploymentsOptions): Promise; /** * Summary of an active deployment returned by listDeployments, used when * disambiguating which deployment to operate on for a given flow. */ interface DeploymentSummaryForFlow { slug: string; type: string; status: string; updatedAt: string; } /** * Error thrown by deleteDeploymentByFlowId and other flow-scoped helpers when * the flow has multiple active (non-deleted) deployments and the caller did * not disambiguate with an explicit slug. * * Callers (e.g. the MCP layer) can translate this into a structured error. * The CLI package does not depend on MCP helpers. */ declare class DeploymentAmbiguityError extends Error { readonly code = "MULTIPLE_DEPLOYMENTS"; readonly details: DeploymentSummaryForFlow[]; constructor(message: string, details: DeploymentSummaryForFlow[]); } /** * Delete a deployment identified by flowId, optionally disambiguated by slug * when the flow has more than one active deployment. Throws * DeploymentAmbiguityError when the flow has >= 2 active deployments and no * slug is provided. Throws a plain Error when the flow has no matches or when * a provided slug does not belong to the flow. */ declare function deleteDeploymentByFlowId(options: { projectId?: string; flowId: string; slug?: string; }): Promise; declare function getDeploymentBySlug(options: { slug: string; projectId?: string; }): Promise; declare function createDeployment(options: { type: 'web' | 'server'; label?: string; projectId?: string; }): Promise; declare function deleteDeployment(options: { slug: string; projectId?: string; }): Promise; interface DeploymentsCommandOptions extends GlobalOptions { json?: boolean; output?: string; project?: string; type?: string; status?: string; label?: string; cursor?: string; limit?: number; } declare function listDeploymentsCommand(options: DeploymentsCommandOptions): Promise; declare function getDeploymentBySlugCommand(slug: string, options: DeploymentsCommandOptions): Promise; declare function createDeploymentCommand(options: DeploymentsCommandOptions): Promise; declare function deleteDeploymentCommand(slug: string, options: DeploymentsCommandOptions): Promise; declare function createDeployCommand(config: string | undefined, options: DeploymentsCommandOptions & { flow?: string; }): Promise; interface FeedbackOptions { anonymous?: boolean; version?: string; } declare function feedback(text: string, options?: FeedbackOptions): Promise; declare function feedbackCommand(text: string): Promise; /** * Report current telemetry state to stdout. Three possible outcomes: * * - Not yet chosen: config has no `telemetryEnabled` field. * - Enabled: `telemetryEnabled === true`. * - Disabled: `telemetryEnabled === false`, or forced off by an env var. */ declare function telemetryStatusCommand(): void; /** * Persist explicit consent: `telemetryEnabled: true` plus a stable * installation UUID. `createInstallationId` is idempotent, re-enabling * preserves any existing UUID. */ declare function telemetryEnableCommand(): void; /** * Persist explicit refusal: `telemetryEnabled: false`. Does not create an * installation UUID, a disabled state has no need for a stable identifier. * Preserves any existing UUID (e.g. from a prior enable) so re-enabling * later keeps the same id. */ declare function telemetryDisableCommand(): void; /** * Check if a config value contains code markers that require esbuild compilation. * Returns true if the value (or any nested value) contains: * - $code: prefix (raw JS expression) * - $store. prefix (JS variable reference) * - __WALKEROS_ENV: prefix (process.env expression) * - __WALKEROS_SECRET: prefix (guarded process.env read for a deferred secret) */ declare function containsCodeMarkers(value: unknown): boolean; /** * Split a step's properties into code-layer (for esbuild) and data-layer (post-build). * * Code layer: 'code' key always, plus any property containing code markers * Data layer: plain JSON values (settings, mappings, chains, etc.) * * Not applicable to InlineCode steps — those go entirely to the code layer. */ declare function classifyStepProperties(step: Record): { codeProps: Record; dataProps: Record; }; /** * Pure structural validation of a flow config — the exact checks the bundler * runs at codegen time, BEFORE any esbuild compile or package/archive fetch. * * Runs synchronously and never touches the network, the filesystem, or * esbuild. Aggregates every structural problem instead of throwing on the * first one, so a single call surfaces all issues in a config. * * Checks performed per flow: * - component names are valid JavaScript identifiers (they become generated * property names), * - each source/destination/store reference specifies exactly one of * package or code, and each transformer entry is a closed, valid shape, * - every `$store.` reference points at a defined store. * * Intended for fast deploy preflight: catch a bad flow config in well under a * second without spinning up a container or compiling anything. */ declare function validateFlowStructure(flowConfig: Flow.Json): ValidateResult; /** * Publish-time wrap step. * * Takes a Stage 1 ESM skeleton produced via `bundle({ skipWrapper: true })` * and produces a wrapped output: * - `browser`: self-executing async IIFE that calls `wireConfig(__configData)`, * injects `env.window` / `env.document` into every source, then calls * `startFlow(config)` and optionally assigns the resulting collector/elb * onto `window`. * - `node`: ESM module whose default export is an async factory function * that the runtime container (see `runtime/load-bundle.ts:53-66`) calls * with a context to get back `{ collector, elb, httpHandler? }`. * * The skeleton must export `wireConfig`, `startFlow`, and `__configData`. * The skipWrapper branch of `bundleCore` already emits exactly that shape. */ interface WrapSkeletonOptions { /** * Absolute path to the Stage 1 skeleton ESM file. Must export * `wireConfig`, `startFlow`, and `__configData`. */ skeletonPath: string; /** Target platform — controls which entry generator runs. */ platform: 'browser' | 'node'; /** Absolute path where the wrapped output will be written. */ outputPath: string; /** * Browser-only: window property name for the collector. * When unset, no `window.*` assignment is emitted. */ windowCollector?: string; /** * Browser-only: window property name for the elb function. * When unset, no `window.*` assignment is emitted. */ windowElb?: string; /** * Browser-only: preview activation wiring. Only host (deploy) wraps set * this; the preview-artifact wrap always omits it, per the anti-recursion * invariant in `generateWrapEntry`. */ preview?: WrapEntryPreview; /** * Browser-only: preview-ARTIFACT grant injection. The preview-artifact wrap * sets this to the server-bound destination keys that should receive the * `X-Walkeros-Preview` header read from `localStorage['elbPreviewSession']` at boot. * Mutually exclusive with `preview` (a host activates, an artifact injects); * passing both throws. */ previewGrantTargets?: string[]; /** * Browser-only: STATIC observe connect config baked onto the startFlow * config. PUBLIC values only (`url` + `binding`, plus optional * `flowId`/`level`/`sample` scoping); the runtime connect module reads the * per-session credential out-of-band at boot via the `elbObserve` slot. * This is the preview-artifact observation wiring: it bakes no ingest * token into the emitted bytes. */ observe?: ObserveWeb; /** * esbuild target. @default 'es2018' for browser, 'node18' for node. */ target?: string; /** Whether to minify the output. @default true */ minify?: boolean; /** Fine-grained minification options, forwarded to esbuild. */ minifyOptions?: MinifyOptions; } declare function wrapSkeleton(options: WrapSkeletonOptions): Promise; interface DeviceAuthorization { deviceCode: string; userCode: string; verificationUri: string; verificationUriComplete: string; expiresIn: number; interval: number; } /** * RFC 8628 section 3.1. Ask for a device code and the URL to send the person * to. Unauthenticated: the code is worth nothing until somebody approves it. */ declare function startDeviceAuthorization(appUrl: string, fetchFn?: typeof fetch): Promise; declare function createApiClient(): openapi_fetch.Client; /** * Semver of the API contract this client was built against, baked from the * bundled `openapi/spec.json` `info.version` at build time. */ declare const bakedContractVersion: string; /** * Canonical content hash of the bundled OpenAPI contract, baked at build time. * Computed with {@link canonicalContractHash} so it is byte-for-byte comparable * to the app's live `contractHash`. */ declare const bakedContractHash: string; /** * Deterministic sha256 hex of an OpenAPI document's content. * * Parity contract: identical to the app's `computeContractHash` * (app/src/lib/api/contract-version.ts): sha256 of * `JSON.stringify(canonicalize(stripInfoVersion(doc)))`. Drift detection only * works while this stays in lockstep with the app helper. */ declare function canonicalContractHash(doc: unknown): string; interface HealthResult { reachable: boolean; status?: string; appVersion?: string; contractVersion?: string; contractHash?: string; } /** * Tokenless reachability + contract probe of the app's PUBLIC `/api/health` * route. Uses a plain `fetch` (never `createApiClient`, whose every request * rejects without a credential) and defensively parses the JSON body. Resolves `{ reachable: false }` * only on a real network/timeout failure; a non-2xx status still counts as * reachable. * * `baseUrl` names the app to probe, without a trailing slash. Omitted, it * falls back to `resolveAppUrl()`, the local machine's chain * (`WALKEROS_APP_URL`, then the CLI config file, then the built-in default), * which is what every `walkeros` binary invocation wants. A caller that is * NOT the local CLI has to pass its own: an in-process host has no CLI config * to read, so the fallback would silently probe a different backend than the * one that caller talks to. */ declare function fetchHealth(baseUrl?: string): Promise; type ContractVerdict = 'in-sync' | 'client-older' | 'client-newer' | 'unknown'; interface ContractComparison { verdict: ContractVerdict; bakedVersion: string; liveVersion?: string; action?: string; } interface CompareContractInput { bakedVersion?: string; bakedHash?: string; /** * The app to probe, without a trailing slash. Omitted, the probe resolves * the local machine's app URL; see {@link fetchHealth}. */ baseUrl?: string; } /** * Compare the client's baked contract against the live app's `/api/health`. * The app is `input.baseUrl` when given, otherwise the locally resolved one. * * - unreachable / missing `contractVersion`+`contractHash` → `unknown` * - baked hash == live hash → `in-sync` * - hashes differ → semver-compare versions: * live > baked → `client-older` (with an upgrade `action`) * otherwise → `client-newer` */ declare function compareContract(input?: CompareContractInput): Promise; /** * Turn an opaque failure into an actionable one by appending the contract-drift * verdict. Use on the error/unexpected-shape path: when a request fails in a way * the client cannot parse, a `client-older` verdict explains why ("you may be * behind the server"). Returns the original error untouched when in-sync or when * drift can't be determined (unknown / unreachable), so a network blip never * masks the real error. */ declare function annotateErrorWithDrift(error: Error, input?: CompareContractInput): Promise; interface ApiErrorDetail { path: string; message: string; } interface ApiErrorOptions { code?: string; details?: ApiErrorDetail[]; status?: number; retryable?: boolean; retryAfterSeconds?: number; minVersion?: string; clientVersion?: string; client?: string; upgrade?: string; docs?: string; } declare class ApiError extends Error { code?: string; details?: ApiErrorDetail[]; status?: number; retryable?: boolean; retryAfterSeconds?: number; minVersion?: string; clientVersion?: string; client?: string; upgrade?: string; docs?: string; constructor(message: string, options?: ApiErrorOptions); } /** * Extract structured error from an openapi-fetch error response and throw. * * For `code === 'CLIENT_OUTDATED'` (HTTP 426), also extracts the upgrade * metadata: `minVersion`, `clientVersion`, `client`, `upgrade`, `docs`. */ declare function throwApiError(error: unknown, fallbackMessage: string): never; type ClientType = 'cli' | 'mcp' | 'runner'; interface ClientContext { type: ClientType; version: string; } /** * Set the client context used to identify this process to the walkerOS app. * * The CLI binary calls this at startup, the MCP server calls it on boot, and * the runner Docker image overrides the resolved type via the * `WALKEROS_CLIENT_TYPE` env var (env wins over `input.type`). */ declare function setClientContext(input: { type?: ClientType; version: string; }): void; declare function getClientContext(): ClientContext | undefined; declare function resetClientContext(): void; /** * Produce the outbound client-identification headers, or an empty object when * no context has been set yet (e.g. in tests or pre-bootstrap code paths). */ declare function clientContextHeaders(): Record; interface ListPreviewsOptions { projectId?: string; flowId: string; } declare function listPreviews(options: ListPreviewsOptions): Promise; interface GetPreviewOptions { projectId?: string; flowId: string; previewId: string; } declare function getPreview(options: GetPreviewOptions): Promise; interface CreatePreviewOptions { projectId?: string; flowId: string; flowName?: string; flowSettingsId?: string; /** What the preview should run: the flow's draft (default) or a deployed * version's stored config. Anchored to the generated API contract so a new * request field becomes a type error here rather than silent drift. */ source?: components['schemas']['CreatePreviewRequest']['source']; /** Target site URL. When present, the CLI asks the server to re-mint an * origin-bound activation grant for this URL's origin. Grants are * app-signed and origin-bound, so a client cannot forge a working activation * URL for an arbitrary origin by string-appending a token — only the server * can mint one. The returned preview's `activationUrl` is the grant URL for * this origin. */ url?: string; } declare function createPreview(options: CreatePreviewOptions): Promise; interface RegrantPreviewOptions { projectId?: string; flowId: string; previewId: string; /** Bare `https://host[:port]` origins the grant may activate on; the * returned `activationUrl` targets the first. */ origins: string[]; /** Observe session id — binds the minted grant to that session so * forwarded events reach its container. Opaque to the CLI. */ sessionId?: string; } /** * Mint a fresh, origin-bound activation grant for an existing preview. * Grants are app-signed and origin-bound, so a client cannot forge a working * activation URL by string-appending a token — only the server can mint one. */ declare function regrantPreview(options: RegrantPreviewOptions): Promise; interface DeletePreviewOptions { projectId?: string; flowId: string; previewId: string; } declare function deletePreview(options: DeletePreviewOptions): Promise; interface ListJourneysOptions { projectId?: string; flowId: string; /** Return only journeys for one trace, when given. */ traceId?: string; /** Max journeys to return (most recent kept). */ limit?: number; } /** * Read a flow's active Observe session journeys from the app. The flow's session * is resolved app-side (`observe_sessions.flow_id` is UNIQUE), so the caller * passes `flowId`, not a session id; a flow with no active session returns an * envelope with `sessionId: null` and empty journeys rather than an error. */ declare function listJourneys(options: ListJourneysOptions): Promise; type ObserveSessionResponse = components['schemas']['ObserveSessionResponse']; type ObserveLevel = components['schemas']['ObserveLevel']; interface StartObserveSessionOptions { projectId?: string; flowId: string; /** Flow settings name; the mint contract requires it. */ settingsName: string; /** Replace an existing active session for the flow (`--replace`). */ replace?: boolean; /** Observation detail level for the session. */ level?: ObserveLevel; /** Origins the session's web activation grant may activate on. */ origins?: string[]; } /** * Mint an observe session via the app's authenticated boundary. Thin client: * the app validates topology, inserts the row, and provisions detached; the * mint response comes back immediately (usually `arming`, with the web and * server parts still null - GET assembles them once the session settles). */ declare function startObserveSession(options: StartObserveSessionOptions): Promise; interface GetObserveSessionOptions { projectId?: string; flowId: string; sessionId: string; } declare function getObserveSession(options: GetObserveSessionOptions): Promise; interface EndObserveSessionOptions { projectId?: string; flowId: string; sessionId: string; } /** * End a session through the app's authenticated boundary: the app tears down * the container, revokes credentials, deletes the web preview, and drops the * row. Ends the WHOLE session including every attached arm. Idempotent * app-side, and the 204 carries no body, so this resolves with nothing; a * session scoped to another flow or project is a 404, never a cross-tenant end. */ declare function endObserveSession(options: EndObserveSessionOptions): Promise; type VersionAnnotation = components['schemas']['VersionAnnotation']; type StepHistoryResponse = components['schemas']['StepHistoryResponse']; type ListHubThreadsResponse = components['schemas']['ListHubThreadsResponse']; type HubThreadResponse = components['schemas']['HubThreadResponse']; type ListKnowledgeResponse = components['schemas']['ListKnowledgeResponse']; /** The rationale summary a release index row carries when asked for one. */ type ReleaseRationaleSummary = components['schemas']['ReleaseRationaleSummary']; /** The release index. Each row carries `rationale` when one was asked for. */ type ReleaseIndexResponse = components['schemas']['ListFlowReleasesResponse']; /** The diff a release carries against its spine predecessor. */ type ReleaseDiffResponse = components['schemas']['ReleaseDiff']; /** One release in full: rationale plus the diff the server computed. */ type ReleaseDetailResponse = components['schemas']['ReleaseDetailResponse']; interface ListReleasesOptions { projectId?: string; flowId: string; limit?: number; offset?: number; } /** The release index WITH its rationale summary. Requires the hub feature. */ declare function listReleases(options: ListReleasesOptions): Promise; /** How a release is addressed: by spine id, or by spine number. */ type ReleaseRef = { versionId: string; } | { versionNumber: number; }; interface GetReleaseOptions { projectId?: string; flowId: string; ref: ReleaseRef; } /** * One release in full: rationale plus the diff the SERVER computed against the * spine predecessor. The path segment is the id or the number; the app decides * which it was. */ declare function getRelease(options: GetReleaseOptions): Promise; interface ListStepHistoryOptions { projectId?: string; flowId: string; step: string; flow?: string; limit?: number; } declare function listStepHistory(options: ListStepHistoryOptions): Promise; interface SetReleaseRationaleOptions { projectId?: string; flowId: string; versionId: string; /** * The rationale to store. `null` CLEARS the one already there: `humanText` * is the only field a client may write, and null is how the route says * "remove it". Without it there would be no way back from a rationale * written by mistake. */ text: string | null; } declare function setReleaseRationale(options: SetReleaseRationaleOptions): Promise; type ThreadAnchorType = 'step' | 'entity_action' | 'release' | 'contract' | 'tag'; type ThreadStatus = 'open' | 'resolved'; interface ListThreadsOptions { projectId?: string; flowId: string; anchorType?: ThreadAnchorType; anchorKey?: string; status?: ThreadStatus; includeMessages: boolean; limit?: number; } declare function listThreads(options: ListThreadsOptions): Promise; interface CreateThreadOptions { projectId?: string; flowId: string; anchorType: ThreadAnchorType; anchorKey: string; anchorLabel?: string; text: string; } declare function createThread(options: CreateThreadOptions): Promise; interface AddThreadMessageOptions { projectId?: string; flowId: string; threadId: string; text: string; } declare function addThreadMessage(options: AddThreadMessageOptions): Promise; interface ListKnowledgeOptions { projectId?: string; pageKey?: string; frameId?: string; markId?: string; includeMessages: boolean; limit?: number; } declare function listKnowledge(options: ListKnowledgeOptions): Promise; type FrameResponse = components['schemas']['Frame']; type FrameListResponse = components['schemas']['FrameListResponse']; type FrameLeanListResponse = components['schemas']['FrameLeanListResponse']; interface ListFramesOptions { projectId?: string; } /** Every live frame of the project, without marks. Requires the frames feature. */ declare function listFrames(options?: ListFramesOptions): Promise; interface ListPageFramesOptions { projectId?: string; pageKey: string; } /** The frames of one page at any depth, with their marks. */ declare function listPageFrames(options: ListPageFramesOptions): Promise; interface GetFrameOptions { projectId?: string; frameId: string; } declare function getFrame(options: GetFrameOptions): Promise; interface ListSecretsOptions { projectId?: string; flowId: string; } declare function listSecrets(options: ListSecretsOptions): Promise; interface CreateSecretOptions { projectId?: string; flowId: string; name: string; value: string; } declare function createSecret(options: CreateSecretOptions): Promise; interface UpdateSecretOptions { projectId?: string; flowId: string; secretId: string; value: string; } declare function updateSecret(options: UpdateSecretOptions): Promise; interface DeleteSecretOptions { projectId?: string; flowId: string; secretId: string; } declare function deleteSecret(options: DeleteSecretOptions): Promise<{ success: true; }>; interface WalkerOSConfig { /** * Static bearer written by the pre-OAuth CLI. Honored until it expires, and * the first use in a process prints a one-line notice naming * `walkeros auth login`, which replaces it with a refreshable session. */ token?: string; /** Short-lived bearer from the device authorization grant. */ accessToken?: string; /** ISO 8601 instant at which `accessToken` stops being accepted. */ accessTokenExpiresAt?: string; /** Single-use credential that buys a new `accessToken`. */ refreshToken?: string; email?: string; appUrl?: string; anonymousFeedback?: boolean; defaultProjectId?: string; /** * UUID v4, generated and persisted only when the user explicitly opts in * to telemetry (`walkeros telemetry enable`). Absent in the default state. */ installationId?: string; /** * Explicit consent toggle for telemetry. Tri-state: * - `undefined`: no decision yet, default (nothing is collected). * - `true`: user opted in via `walkeros telemetry enable`. * - `false`: user opted out via `walkeros telemetry disable`. */ telemetryEnabled?: boolean; } /** * Read the stored config, or null if not found */ declare function readConfig(): WalkerOSConfig | null; /** * Merge `config` into the stored config and write the result. * * Merging rather than replacing, because the file holds fields owned by * unrelated commands: a writer that knows only about tokens would otherwise * drop `defaultProjectId`, `installationId`, `telemetryEnabled` and * `anonymousFeedback` every time somebody logs in. * * A key passed explicitly as `undefined` is removed from the written file, * which is how login drops the legacy static token it replaces. */ declare function writeConfig(config: WalkerOSConfig): void; /** * Remove every credential field, keeping the rest of the config. * * Used when the stored session is known to be dead, so the next command can * say "run `walkeros auth login`" instead of failing against the API. */ declare function clearAuthFields(): void; /** * Delete the config file (logout) */ declare function deleteConfig(): boolean; /** * Set the anonymous feedback preference in the config. * Does nothing when no config exists (avoids creating a skeleton config). */ declare function setFeedbackPreference(anonymous: boolean): void; /** * Get the anonymous feedback preference from the config. * Returns undefined when not set or no config exists. */ declare function getFeedbackPreference(): boolean | undefined; /** * Set the default project ID in the config. * Throws if no config exists (user not authenticated). */ declare function setDefaultProject(projectId: string): void; /** * Get the default project ID from the config, or null if not set. */ declare function getDefaultProject(): string | null; /** * Resolve the API token using priority order: * 1. WALKEROS_TOKEN env var * 2. Config file (~/.config/walkeros/config.json) * 3. null (not authenticated) */ declare function resolveToken(): { token: string; source: 'env' | 'config'; } | null; /** * Resolve the app URL. * WALKEROS_APP_URL env var > config file > default. */ declare function resolveAppUrl(): string; /** CLI package version */ declare const VERSION: string; /** * Load configuration from a file path, URL, or inline string. * * Supports two modes: * - `json: true` (default) — resolves content and parses as JSON * - `json: false` — resolves content and returns raw string * * Detection priority: * 1. URL (http://, https://) — download content * 2. Existing file path — read file content * 3. Inline string (starting with { or [) — use directly * * @param input - Path to file, HTTP/HTTPS URL, or inline string * @param options - Optional settings * @param options.json - Parse as JSON (default: true) * @returns Parsed object (json: true) or raw string (json: false) * @throws Error if file not found, download fails, or invalid JSON * * @example * ```typescript * // JSON mode (default) — same as loadJsonConfig * const config = await loadConfig('./config.json') * const config = await loadConfig('https://example.com/config.json') * const config = await loadConfig('{"version":3,"flows":{}}') * * // Raw string mode — returns file/URL content as string * const code = await loadConfig('./bundle.js', { json: false }) * ``` */ declare function loadConfig(input: string, options?: { json?: boolean; }): Promise; /** * Load and parse JSON configuration from a file path, URL, or inline JSON string. * * Thin wrapper around `loadConfig` with `json: true` (default). * * Detection priority: * 1. URL (http://, https://) — download and parse * 2. Existing file path — read and parse * 3. Inline JSON string (starting with { or [) — parse directly * * @param configPath - Path to JSON file, HTTP/HTTPS URL, or inline JSON string * @returns Parsed configuration object * @throws Error if file not found, download fails, or invalid JSON * * @example * ```typescript * // Local file * const config = await loadJsonConfig('./config.json') * * // Remote URL * const config = await loadJsonConfig('https://example.com/config.json') * * // Inline JSON * const config = await loadJsonConfig('{"version":3,"flows":{}}') * ``` */ declare function loadJsonConfig(configPath: string): Promise; type StepType = 'source' | 'transformer' | 'destination'; interface ExampleLookupResult { stepType: StepType; stepName: string; exampleName: string; example: { in?: unknown; mapping?: unknown; out?: unknown; }; } /** * Find a named example in a flow config. * * Searches sources, transformers, and destinations for a matching example. * If --step is provided (e.g. "destination.gtag"), looks only in that step. * If not, searches all steps and errors if ambiguous. * * @param config - Raw (unresolved) flow config with examples intact * @param exampleName - Name of the example to find * @param stepTarget - Optional step target in "type.name" format * @returns The found example with its location */ declare function findExample(config: Flow, exampleName: string, stepTarget?: string): ExampleLookupResult; /** * Compare simulation output against expected example output. */ declare function compareOutput(expected: unknown, actual: unknown): { expected: unknown; actual: unknown; match: boolean; diff?: string; }; interface EmitterOptions { /** Caller supplies the v4 source verbatim (type, platform, etc). */ source: WalkerOS.Source; packageVersion: string; session?: string; } interface Emitter { send(name: string, data: WalkerOS.Properties, timingMs?: number, sourceOverride?: Partial): Promise; } /** * Build the walkerOS telemetry emitter. * * Consent, debug, and first-run-notice are resolved up-front. When telemetry * is not enabled the returned `send` is a no-op that never initializes the * collector, never writes a config file, and never touches the network. * * In debug mode we synthesize the event shape that the collector would emit * and write it to stderr instead of starting a real collector. Keeps the * output deterministic and avoids paying for collector init when only * inspecting payloads. * * The production path lazily boots a collector on first `send`. The * `{ package, config }` shorthand produced by `buildInitConfig` is resolved * here into a real `{ code, config }` `Destination.Init` by importing * `destinationAPI` from `@walkeros/server-destination-api`. This keeps * `init-config.ts` free of the server-destination runtime dependency while * centralizing the resolution in the one place that actually runs the flow. */ declare function createEmitter(opts: EmitterOptions): Promise; /** * Read the stored installation UUID if one exists. Never writes. * * Returns `undefined` when no config file exists or the config has no * `installationId` field, both mean the user has not opted in to telemetry * yet, so no persistent identifier has been created. */ declare function getInstallationId(): string | undefined; /** * Generate and persist an installation UUID if none exists yet, then return * it. Idempotent. * * This is the only function in the telemetry stack that may write an * installation identifier. Callers must only invoke it as part of an opt-in * action (the `walkeros telemetry enable` command). Any other caller is a * consent-before-write bug. */ declare function createInstallationId(): string; /** * Is telemetry actively enabled for this process? * * Returns `true` only when the user has given explicit consent via * `walkeros telemetry enable` (recorded as `telemetryEnabled: true` in the * config file). Every other state (no config, config without the field, or * `telemetryEnabled: false`) returns `false`. * * `DO_NOT_TRACK` and `WALKEROS_TELEMETRY_DISABLED` are honored as forced-off * overrides for backward compatibility and for users who want a belt-and- * braces guarantee even after opting in. */ declare function isTelemetryEnabled(): boolean; /** Whether telemetry debug logging is enabled via `WALKEROS_TELEMETRY_DEBUG`. */ declare function isDebugMode(): boolean; interface CiInfo { ci: boolean; ci_name?: string; } interface CiInput { isCI: boolean; name?: string | null; } /** * CI environment detection. Accepts an injected input for testability; * production callers pass no argument and `ci-info` is read directly. */ declare function getCiInfo(input?: CiInput): CiInfo; type index_CiInfo = CiInfo; type index_Emitter = Emitter; type index_EmitterOptions = EmitterOptions; declare const index_createEmitter: typeof createEmitter; declare const index_createInstallationId: typeof createInstallationId; declare const index_getCiInfo: typeof getCiInfo; declare const index_getInstallationId: typeof getInstallationId; declare const index_isDebugMode: typeof isDebugMode; declare const index_isTelemetryEnabled: typeof isTelemetryEnabled; declare namespace index { export { type index_CiInfo as CiInfo, type index_Emitter as Emitter, type index_EmitterOptions as EmitterOptions, index_createEmitter as createEmitter, index_createInstallationId as createInstallationId, index_getCiInfo as getCiInfo, index_getInstallationId as getInstallationId, index_isDebugMode as isDebugMode, index_isTelemetryEnabled as isTelemetryEnabled }; } /** * Overrides structure for destination config properties. * Shape mirrors Collector.InitConfig.destinations but without requiring `code`. * Used with deepMerge at runtime to overlay mock/disabled flags. */ interface PushOverrides { destinations?: Record; simulation?: string[]; }>; sources?: Record; /** Path-specific transformer mocks: chainPath → { transformerId → mockValue } */ transformerMocks?: Record>; transformers?: Record; } type PrepareInput = { mode: 'build'; config: Flow.Json; flow?: string; simulate?: string[]; mock?: string[]; silent?: boolean; verbose?: boolean; } | { mode: 'prebuilt'; bundlePath: string; config: Flow.Json; flow?: string; simulate?: string[]; mock?: string[]; silent?: boolean; verbose?: boolean; }; interface PreparedFlow { bundlePath: string; platform: 'web' | 'server'; overrides: PushOverrides; flowSettings: Flow; cleanup: () => Promise; } declare module '@walkeros/core' { interface SourceMap { cli: { type: 'cli'; platform: 'terminal'; command?: string; }; } } export { type AddThreadMessageOptions, ApiError, type ApiErrorDetail, type BuildOptions, type BundleStats, type CLIBuildOptions, type ClientContext, type ClientType, type CompareContractInput, type CompleteDeviceLoginOptions, type ContractComparison, type ContractVerdict, type CreatePreviewOptions, type CreateSecretOptions, type CreateThreadOptions, type DeletePreviewOptions, type DeleteSecretOptions, type DeployOptions, DeploymentAmbiguityError, type DeploymentSummaryForFlow, type DeviceAuthorization, type DeviceLoginResult, type EndObserveSessionOptions, type ExampleLookupResult, type FeedbackOptions, type GetFrameOptions, type GetObserveSessionOptions, type GetPreviewOptions, type GetReleaseOptions, type GlobalOptions, type HealthResult, type ListDeploymentsOptions, type ListFlowsOptions, type ListFramesOptions, type ListJourneysOptions, type ListKnowledgeOptions, type ListPageFramesOptions, type ListPreviewsOptions, type ListProjectsOptions, type ListReleasesOptions, type ListSecretsOptions, type ListStepHistoryOptions, type ListThreadsOptions, type LoginOptions, type LoginResult, type MinifyOptions, type PrepareInput, type PreparedFlow, type ProjectFlows, type PushResult, type RegrantPreviewOptions, type ReleaseDetailResponse, type ReleaseDiffResponse, type ReleaseIndexResponse, type ReleaseRationaleSummary, type ReleaseRef, type RunCommandOptions, type RunOptions, type RunResult, type SSEEvent, type SSEParseResult, type SetReleaseRationaleOptions, type SimulateCollectorOptions, type SimulateDataOptions, type SimulateDestinationOptions, type SimulateSourceOptions, type SimulateTransformerOptions, type StartObserveSessionOptions, type ThreadAnchorType, type ThreadStatus, type UpdateSecretOptions, VERSION, type ValidateResult, type ValidationError, type ValidationType, type ValidationWarning, type WalkerOSConfig, type WrapSkeletonOptions, addThreadMessage, annotateErrorWithDrift, apiFetch, bakedContractHash, bakedContractVersion, buildDataPayload, bundle, bundleCommand, canonicalContractHash, classifyStepProperties, clearAuthFields, clientContextHeaders, compareContract, compareOutput, completeDeviceLogin, containsCodeMarkers, createApiClient, createDeployCommand, createDeployment, createDeploymentCommand, createFlow, createFlowCommand, createPreview, createProject, createProjectCommand, createSecret, createThread, credentialSource, deleteConfig, deleteDeployment, deleteDeploymentByFlowId, deleteDeploymentCommand, deleteFlow, deleteFlowCommand, deletePreview, deleteProject, deleteProjectCommand, deleteSecret, deploy, deployCommand, deployFetch, duplicateFlow, duplicateFlowCommand, endObserveSession, feedback, feedbackCommand, fetchHealth, findExample, getAuthHeaders, getClientContext, getDefaultProject, getDeployment, getDeploymentBySlug, getDeploymentBySlugCommand, getDeploymentCommand, getFeedbackPreference, getFlow, getFlowCommand, getFrame, getObserveSession, getPreview, getProject, getProjectCommand, getRelease, listAllFlows, listDeployments, listDeploymentsCommand, listFlows, listFlowsCommand, listFrames, listJourneys, listKnowledge, listPageFrames, listPreviews, listProjects, listProjectsCommand, listReleases, listSecrets, listStepHistory, listThreads, loadConfig, loadJsonConfig, login, loginCommand, logout, logoutCommand, mergeAuthHeaders, parseSSEEvents, publicFetch, push, pushCommand, readConfig, regrantPreview, requireProjectId, resetClientContext, resolveAccessToken, resolveAppUrl, resolveToken, run, runCommand, setClientContext, setDefaultProject, setFeedbackPreference, setReleaseRationale, simulateCollector, simulateDestination, simulateSource, simulateTransformer, startDeviceAuthorization, startObserveSession, index as telemetry, telemetryDisableCommand, telemetryEnableCommand, telemetryStatusCommand, throwApiError, updateFlow, updateFlowCommand, updateProject, updateProjectCommand, updateSecret, validate, validateCommand, validateFlowStructure, whoami, whoamiCommand, wrapSkeleton, writeConfig };