/** * The error catalog — ONE table every failure surface renders from (design 2026-09-06): * the stderr line, the --json envelope, /llms.txt + /docs/cli, and `clustly explain`. * * `origin` is the field a builder's agent branches on: whose fault, and therefore what to do. * It decides the exit code (EXIT_BY_ORIGIN) so a code can never disagree with its exit. * Codes are STABLE and additive-only: agents grep them and humans type them into `explain`. * Dependency-free on purpose — the docs module (src/lib/docs) imports it. */ export type Origin = "usage" | "state" | "agent" | "platform"; export interface CatalogEntry { code: string; origin: Origin; /** What went wrong — one sentence, no command names. */ meaning: string; /** What to do — one sentence, ending with the command or URL when there is one. */ fix: string; } /** The published exit taxonomy (commands/failure.ts documents it; /llms.txt publishes it). */ export declare const EXIT_BY_ORIGIN: Readonly>; export declare const ERROR_CATALOG: readonly [{ readonly code: "USAGE"; readonly origin: "usage"; readonly meaning: "The command was typed wrong: an unknown flag, a bad positional, or flags that exclude each other."; readonly fix: "Fix the invocation; `clustly --help` shows the accepted form."; }, { readonly code: "NOT_SIGNED_IN"; readonly origin: "state"; readonly meaning: "No usable Clustly credentials on this machine: none stored, or the stored key was rejected (rotated or revoked)."; readonly fix: "Run `clustly login` (or pipe a key to `clustly login --with-token`)."; }, { readonly code: "AGENT_KEY_REQUIRED"; readonly origin: "state"; readonly meaning: "This command acts AS an agent and needs that agent's API key (clk_…) in CLUSTLY_API_KEY; none was set, or a builder key was given. The builder key `clustly login` stores (clb_…) deploys agents, it cannot act as one."; readonly fix: "export CLUSTLY_API_KEY=clk_… with the agent key from the console's agent setup, then re-run."; }, { readonly code: "NOT_DEPLOYED"; readonly origin: "state"; readonly meaning: "This workspace has never been deployed, so there is no hosted agent to act on."; readonly fix: "Run `clustly deploy` first."; }, { readonly code: "NO_RELEASE"; readonly origin: "state"; readonly meaning: "The agent exists but no usable release is recorded for this action."; readonly fix: "Run `clustly deploy`, then retry once `clustly status` shows a deployed release."; }, { readonly code: "SECRETS_MISSING"; readonly origin: "state"; readonly meaning: "clustly.yaml declares env names the hosted secret store does not hold, so the agent cannot serve."; readonly fix: "Set each one with `clustly secrets set NAME` (value via stdin), then deploy again."; }, { readonly code: "SECRET_SCAN_BLOCKED"; readonly origin: "state"; readonly meaning: "The bundle contains what looks like a credential; nothing was packed or uploaded."; readonly fix: "Move the value into .env (excluded from the bundle) or a hosted secret, then deploy again."; }, { readonly code: "LOCKFILE_MISSING"; readonly origin: "state"; readonly meaning: "A node bundle ships package.json without a lockfile, so hosting cannot vuln-scan its dependencies."; readonly fix: "Run `npm install --package-lock-only` (or ship pnpm-lock.yaml / yarn.lock), then deploy again."; }, { readonly code: "CREDENTIAL_CONFLICT"; readonly origin: "state"; readonly meaning: "The code reads a second model credential that clustly.yaml's `credential:` mode does not declare."; readonly fix: "Stop reading it, or set `credential: mixed` in clustly.yaml to declare both deliberately."; }, { readonly code: "MANIFEST_INVALID"; readonly origin: "state"; readonly meaning: "clustly.yaml could not be parsed, failed validation, or lacks a field this command needs."; readonly fix: "Correct the line the message names; `clustly init` rewrites a minimal valid file."; }, { readonly code: "BUNDLE_TOO_LARGE"; readonly origin: "state"; readonly meaning: "The files that would ship exceed hosting's bundle cap; nothing was packed or uploaded."; readonly fix: "Add build outputs, media, and node_modules to `exclude:` in clustly.yaml, then deploy again."; }, { readonly code: "REFUSED"; readonly origin: "state"; readonly meaning: "Clustly refused the action for the current state of your agent (already done, disabled, not yours)."; readonly fix: "Run `clustly status` (or `clustly identity`) to see the state before retrying."; }, { readonly code: "RELEASE_REJECTED"; readonly origin: "state"; readonly meaning: "The security review rejected this release, so nothing new is serving; the previous release (if any) still is."; readonly fix: "Run `clustly logs --findings`, fix each finding, then `clustly deploy` again."; }, { readonly code: "RELEASE_FAILED"; readonly origin: "state"; readonly meaning: "The release failed to build or deploy after the upload; nothing new is serving."; readonly fix: "Run `clustly logs` for the cause, fix it, then `clustly deploy` again."; }, { readonly code: "CANCELLED"; readonly origin: "state"; readonly meaning: "You declined a confirmation, so the command stopped without changing anything."; readonly fix: "Re-run and answer yes, or pass --ci with an explicit path to skip the prompt."; }, { readonly code: "AGENT_CRASHED"; readonly origin: "agent"; readonly meaning: "Your handler threw, or your process exited non-zero, while running a job. Clustly's runner and image were fine."; readonly fix: "Read the trace, fix the handler locally, then `clustly deploy` again. Do not retry unchanged."; }, { readonly code: "AGENT_CONTRACT"; readonly origin: "agent"; readonly meaning: "Your entry does not export the handler the hosted shim calls (node: a default-export async function; python: a module-level `handler(job)`), or it returned the wrong shape."; readonly fix: "Export `async function handler({ id, input })` returning the deliverable, then `clustly deploy` again."; }, { readonly code: "AGENT_TIMEOUT"; readonly origin: "agent"; readonly meaning: "Your handler did not finish within the run limit."; readonly fix: "Make the job finish faster or return partial work; then `clustly deploy` again."; }, { readonly code: "AGENT_BUILD_FAILED"; readonly origin: "agent"; readonly meaning: "Your workspace's own install step (`npm ci` / `pip install`) failed inside the sandbox image."; readonly fix: "Run the install locally against a clean checkout, fix the lockfile or requirements, then `clustly deploy` again."; }, { readonly code: "HOSTED_BINARY_MISSING"; readonly origin: "agent"; readonly meaning: "Your code spawns a system binary by name (ffmpeg, python3, tesseract, yt-dlp, …) that the hosted image does not carry, and `apt-get install` fails inside the sandbox while a local dry-run could install it — so this is refused before it passes locally and fails hosted."; readonly fix: "Declare the Debian package under `packages:` in clustly.yaml (hosting installs it at image build), or depend on a package that bundles the binary (e.g. ffmpeg-static) and spawn that path."; }, { readonly code: "PLATFORM"; readonly origin: "platform"; readonly meaning: "Clustly's server, the network, or something we did not classify failed; your input was fine."; readonly fix: "Retry with backoff; if it persists, report it with the message shown."; }, { readonly code: "SANDBOX_UNAVAILABLE"; readonly origin: "platform"; readonly meaning: "Docker could not build or run Clustly's own dry-run image (base image pull, daemon, disk) — not your agent's code."; readonly fix: "Check `docker version` and disk space and retry, or skip the dry-run: `clustly test` runs the real sandbox after deploy."; }]; export type ErrorCode = (typeof ERROR_CATALOG)[number]["code"]; export declare function catalogEntry(code: ErrorCode): CatalogEntry; export declare function exitFor(code: ErrorCode): 1 | 2 | 3 | 4; /** True when `text` names a catalog code (the `explain` command's input gate). */ export declare function isErrorCode(text: string): text is ErrorCode;