# Repository layout The complete catalog of what lives in this repository: every workspace package, what it is for, and where it is published. The root [README](../README.md#repository-layout) carries the short map; this is the long one. `scripts/check-package-catalog.mjs` fails CI when a workspace package is missing from this page, so it cannot drift from the tree. One pnpm workspace, split into reusable **libraries** (published to npm + a public runner image on GHCR and Docker Hub) and example **deployments** that depend on them. Other organizations copy `deploy/*`, point the config at their own resources, and deploy both halves on their end. **Libraries** (published): | Path | Package | Role | | --------------------------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [`frontend/app`](../frontend/app) | `@cat-factory/app` | Reusable **Nuxt layer** (`ssr: false`): the board UI, Pinia stores, composables, the WebSocket stream. Consumed via `extends`. Carries a [modular-vue](../backend/docs/adr/0049-modular-vue-adoption.md) registry seam (`registerAppModule`) so a deployment contributes its own frontend modules without forking. | | [`frontend/storybook`](../frontend/storybook) | `@cat-factory/storybook` | Private. Component stories for the SPA: a Nuxt app that extends `@cat-factory/app` and nothing else, plus the Storybook and story-test config. Not a deployment template. See [the authoring guide](./internal/storybook.md). | | [`backend/packages/contracts`](../backend/packages/contracts) | `@cat-factory/contracts` | Valibot wire contracts shared by SPA + the backends. | | [`backend/packages/kernel`](../backend/packages/kernel) | `@cat-factory/kernel` | Shared vocabulary: domain types, pure logic + constants, and **all** repository/port interfaces, including the `Logger` port and the `runBestEffort` convention every package logs through ([`backend/docs/logging.md`](../backend/docs/logging.md)). | | [`backend/packages/caching`](../backend/packages/caching) | `@cat-factory/caching` | The app-level caching seam (layered-loader): `createAppCaches` builds the named in-memory read-through caches behind the kernel `AppCaches` port, with optional Redis-notified invalidation. See [its README](../backend/packages/caching/README.md). | | [`backend/packages/orchestration`](../backend/packages/orchestration) | `@cat-factory/orchestration` | The delivery-workflow engine + domain **composition root** (`createCore()`): module services for execution, bootstrap, pipelines, board, requirements, merge, … | | [`backend/packages/integrations`](../backend/packages/integrations) | `@cat-factory/integrations` | Opt-in integration services (GitHub, documents, tasks, environments, runner pools) behind kernel ports. | | [`backend/packages/agents`](../backend/packages/agents) | `@cat-factory/agents` | Agent catalog + prompt composition (`systemPromptFor`/`userPromptFor`, the per-kind roles, prompt-version registry) **and the AI provisioning facade** (`CompositeModelProvider` + the neutral resolvers). | | [`backend/packages/provider-bedrock`](../backend/packages/provider-bedrock) | `@cat-factory/provider-bedrock` | Opt-in AWS Bedrock model resolver (`@ai-sdk/amazon-bedrock`) with a supported-model allow-list; mixed into a facade's registry when configured. See [its README](../backend/packages/provider-bedrock/README.md). | | [`backend/packages/spend`](../backend/packages/spend) | `@cat-factory/spend` | The spend safeguard: pricing tables + spend metering/gating. | | [`backend/packages/workspaces`](../backend/packages/workspaces) | `@cat-factory/workspaces` | Workspace + account services. | | [`backend/packages/server`](../backend/packages/server) | `@cat-factory/server` | Runtime-neutral **HTTP layer** shared by every facade: all Hono controllers, middleware (auth/authz/CORS/error), request helpers, the gateway seams, the `AppConfig` contract, and the shared row↔domain mappers. | | [`backend/packages/prompt-fragments`](../backend/packages/prompt-fragments) | `@cat-factory/prompt-fragments` | The built-in tier of best-practice prompt fragments. See [its README](../backend/packages/prompt-fragments/README.md). | | [`backend/packages/acceptance-kit`](../backend/packages/acceptance-kit) | `@cat-factory/acceptance-kit` | Building blocks for writing your **own** headless acceptance suite against a live deployment (to cover your custom providers, agent kinds or gates): the scenario driver, the resumable ledger and progress journal, a prerequisite gate whose refusals carry rendered remedies, waits that state their last observation, and the SDK-driven run driver. The platform's own acceptance suite is built from it. | | [`backend/packages/gates`](../backend/packages/gates) | `@cat-factory/gates` | The built-in polling-gate suite (CI, merge-conflicts, post-release health + on-call escalation), authored through the public `registerGate` seam; a facade imports it and wires each gate's provider. | | [`backend/packages/delegation-github-actions`](../backend/packages/delegation-github-actions) | `@cat-factory/delegation-github-actions` | A `DelegatedExecutor` over **GitHub Actions**, for a deployment plugging its own implement/review/test workflow in as the executor of a pipeline step: dispatch, correlate the run by the platform’s own key (`workflow_dispatch` returns no run id), map Actions’ conclusions, and find the pull request it opened. See [its AGENTS.md](../backend/packages/delegation-github-actions/AGENTS.md). | | [`backend/packages/binary-generators`](../backend/packages/binary-generators) | `@cat-factory/binary-generators` | The built-in generative binary integrations (`nano-banana`, Google's Gemini image models) plus `defineBinaryGenerator`, the authoring seam a deployment writes its own with. Authored through the public `BinaryGeneratorRegistry` seam; every facade defaults its registry to `binaryGeneratorRegistryWithBuiltins()`. See [its README](../backend/packages/binary-generators/README.md). | | [`backend/packages/consensus`](../backend/packages/consensus) | `@cat-factory/consensus` | Opt-in consensus orchestration (specialist panel / debate / ranked voting) that fans an agent step across runs and reconciles them, gated on the task estimate: per step, or through the workspace's reusable, tiered **consensus group** library. | | [`backend/packages/gitlab`](../backend/packages/gitlab) | `@cat-factory/gitlab` | Opt-in GitLab VCS provider: the provider-neutral `VcsClient`/webhook/provisioning ports over GitLab REST v4, registered via `registerGitLab(vcsRegistry, …)` onto the facade's app-owned `VcsProviderRegistry`. | | [`backend/packages/provider-cloudflare`](../backend/packages/provider-cloudflare) | `@cat-factory/provider-cloudflare` | Opt-in Cloudflare Workers AI model registry mixed into a `CompositeModelProvider` (in-process binding on the Worker, OpenAI-compatible REST elsewhere). | | [`backend/packages/provider-s3`](../backend/packages/provider-s3) | `@cat-factory/provider-s3` | Opt-in AWS S3 blob backend implementing the kernel `BinaryBlobBackend` port over an S3 bucket. See [its README](../backend/packages/provider-s3/README.md). | | [`backend/packages/eks`](../backend/packages/eks) | `@cat-factory/eks` | Opt-in AWS **EKS** runner + environment backends: reuses the native Kubernetes transport/provider verbatim, adding only EKS IAM (SigV4 STS `GetCallerIdentity`) apiserver-token minting. See [its README](../backend/packages/eks/README.md). | | [`backend/packages/observability-langfuse`](../backend/packages/observability-langfuse) | `@cat-factory/observability-langfuse` | Opt-in Langfuse trace sink: a fetch-based `LlmTraceSink` streaming LLM generations + tool spans; runs on both the Worker and Node facades. See [its README](../backend/packages/observability-langfuse/README.md). | | [`backend/packages/observability-otel`](../backend/packages/observability-otel) | `@cat-factory/observability-otel` | Opt-in OpenTelemetry (OTLP) publisher: per-run LLM traces + metrics (a workerd-safe fetch exporter and the official `@opentelemetry/*` SDK exporter for Node, kept conformant by a shared mapping layer), plus a periodic push of the deployment-level run-health aggregates as OTLP gauge metrics and an opt-in export of the platform's own log lines as OTLP log records. See [its README](../backend/packages/observability-otel/README.md). | | [`backend/packages/sandbox`](../backend/packages/sandbox) | `@cat-factory/sandbox` | Parallel prompt/model testing surface: versioned prompt candidates, experiment matrices, judge + objective grading. Isolated so it can be extracted. | | [`backend/packages/sandbox-fixtures`](../backend/packages/sandbox-fixtures) | `@cat-factory/sandbox-fixtures` | Hand-authored, graded no-repo fixtures (six families of inline agent inputs + expectations, including a repo-scale review) the sandbox grades against. | | [`backend/packages/cli`](../backend/packages/cli) | `@cat-factory/cli` | Bootstrap CLI (`cat-factory init`): scaffolds a local-mode deployment on your machine, generating crypto secrets, minting a GitHub/GitLab PAT, and writing a gitignored `.env`. See [its README](../backend/packages/cli/README.md). | **Public-API SDK clients**: official clients for the external `/api/v1` surface, in four languages. Models and operations are GENERATED from the published OpenAPI spec (which is itself generated from the Valibot contracts), so they cannot drift from the deployment they talk to; transports are hand-written. Beside them, `sdk/mcp` is a **Model Context Protocol facade** over the same surface: the published operations projected as MCP tools from that same spec, over the TypeScript client, so an MCP host can drive a workspace directly (the two SSE endpoints aside, a tool call having no channel to stream over). It serves both the `cat-factory-mcp` stdio binary and the backend's hosted `POST /api/v1/mcp`, mounted from this same package. `sdk/gatekeeper` is a third projection from the same generator: a **policy-annotated operation table** (per-operation key-scope floors, mutation and transport metadata, invoke thunks over the TypeScript client) for credential-holding front-ends such as a Cloudflare OS Gatekeeper; see the [design record](../backend/docs/adr/0052-cloudflare-os-gatekeeper.md). Three members are hand-written rather than projected: `sdk/webhooks`, the **signed-delivery verifier** every receiver uses; `sdk/directory-sync`, which keeps an account's **directory in sync** over a storage adapter the integrator writes; and `sdk/gatekeeper-worker`, the **Gatekeeper Worker machinery** a deployment installs (capabilities compiled from that table, the Cloudflare OS object model and approval queue in front of them, per-actor key minting, the verified webhook receiver and the approval inbox), leaving `deploy/gatekeeper` as a template holding only the policy and the bindings. Design notes, the Java/Kotlin story and the release process: [`sdk/README.md`](../sdk/README.md). | Path | Package | Registry | | --------------------------------------------------- | ----------------------------------------- | ------------------------------------------- | | [`sdk/typescript`](../sdk/typescript) | `@cat-factory/sdk` | npm (versioned by changesets) | | [`sdk/python`](../sdk/python) | `cat-factory-sdk` | PyPI | | [`sdk/go`](../sdk/go) | `github.com/kibertoad/cat-factory/sdk/go` | the Go module proxy (a `sdk/go/vX.Y.Z` tag) | | [`sdk/java`](../sdk/java) | `ai.catfactory:cat-factory-sdk` | Maven Central (serves **Java and Kotlin**) | | [`sdk/mcp`](../sdk/mcp) | `@cat-factory/mcp-server` | npm (versioned by changesets) | | [`sdk/gatekeeper`](../sdk/gatekeeper) | `@cat-factory/gatekeeper-bindings` | npm (versioned by changesets) | | [`sdk/gatekeeper-worker`](../sdk/gatekeeper-worker) | `@cat-factory/gatekeeper-worker` | npm (versioned by changesets) | | [`sdk/webhooks`](../sdk/webhooks) | `@cat-factory/webhooks` | npm (versioned by changesets) | | [`sdk/directory-sync`](../sdk/directory-sync) | `@cat-factory/directory-sync` | npm (versioned by changesets) | **AWS-stack packages** (opt-in): three independent, capability-scoped AWS integrations, each registering into its own seam and sharing no dependencies, so a deployment pulls in only what it uses (and an all-AWS deployment composes all three): - [`@cat-factory/provider-bedrock`](../backend/packages/provider-bedrock): Bedrock **LLM models** (mixed into the `CompositeModelProvider`); see its [README](../backend/packages/provider-bedrock/README.md). - [`@cat-factory/provider-s3`](../backend/packages/provider-s3): S3 **blob storage** (the kernel `BinaryBlobBackend` port); see its [README](../backend/packages/provider-s3/README.md). A store the platform does not ship is the same port, [registered in your own code](../backend/docs/custom-binary-stores.md). - [`@cat-factory/eks`](../backend/packages/eks): EKS **runner + environment backends**; see its [README](../backend/packages/eks/README.md) for the design (AWS-SDK-free, WebCrypto SigV4 token minting) and the floci integration-test setup. **Runtime facades** (one per deployment target; serve the same `@cat-factory/server` app): | Path | Package | Role | | --------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [`backend/runtimes/cloudflare`](../backend/runtimes/cloudflare) | `@cat-factory/worker` | Cloudflare Worker facade: D1 repos, Durable Objects, Workflows, per-run Containers, queues/cron, the CF gateway impls. Thin `createApp()`/`buildContainer()` over `@cat-factory/server`; ships the D1 `migrations/`. | | [`backend/runtimes/node`](../backend/runtimes/node) | `@cat-factory/node-server` | Node.js service facade: serves the shared app via `@hono/node-server` with Drizzle/Postgres repos + pg-boss durable execution. `start()` / `createServer()`; `DATABASE_URL` selects the database. | | [`backend/runtimes/local`](../backend/runtimes/local) | `@cat-factory/local-server` | Local-mode facade: the Node stack with agent jobs run as local Docker/Podman containers and GitHub reached via a PAT, so a developer runs the whole product on their own machine. `startLocal()`. | **Internal** (private; not published to npm): | Path | Package | Role | | ----------------------------------------------------------------------------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [`backend/internal/executor-harness`](../backend/internal/executor-harness) | `@cat-factory/executor-harness` | The payload that runs **inside** each per-run container (the Pi coding-agent harness). Published to **npm** (the entry local native mode spawns) **and** as a public multi-arch **Docker image to GHCR + Docker Hub**. See [its README](../backend/internal/executor-harness/README.md). | | [`backend/internal/benchmark-harness`](../backend/internal/benchmark-harness) | `@cat-factory/benchmark-harness` | Headless agent benchmarking (`cat-bench`); internal. See [its README](../backend/internal/benchmark-harness/README.md). | | [`backend/internal/conformance`](../backend/internal/conformance) | `@cat-factory/conformance` | Cross-runtime conformance suite + the canonical deterministic `FakeAgentExecutor`; run by both runtime facades' test suites to mandate feature parity. | | [`backend/internal/e2e`](../backend/internal/e2e) | `@cat-factory/e2e` | Playwright end-to-end suite: a real Chromium drives the real SPA against a real Node backend (real Postgres + WebSocket push), only external deps faked. See [its README](../backend/internal/e2e/README.md). | | [`backend/internal/acceptance`](../backend/internal/acceptance) | `@cat-factory/acceptance` | Acceptance suite against a **live** local deployment with nothing faked: adopts two empty repositories you created, scaffolds a service into each, ships a cross-service feature onto a real k3s ephemeral environment, then investigates and fixes the defect it leaves behind. `run configure` assembles its `.env` by resolving what the deployment and kubeconfig already know. Real agents, real spend, real pull requests; **never run in CI**. See [its README](../backend/internal/acceptance/README.md). | | [`backend/internal/sdk-smoketest`](../backend/internal/sdk-smoketest) | `@cat-factory/sdk-smoketest` | Cross-SDK smoketest: boots a real Node backend and drives the SAME scenario through all four public-API SDK clients (TypeScript/Python/Go/Java), then compares their observation reports field by field: the only check that can see the four clients **disagree**. See [its README](../backend/internal/sdk-smoketest/README.md). | | [`backend/internal/smoketest-harness`](../backend/internal/smoketest-harness) | `@cat-factory/smoketest-harness` | Headless Pi-agent smoketest (`cat-smoke`): runs real coding tasks through the actual Pi setup against Cloudflare AI and flags breakage / dead-ends / loops (no grading). See [its README](../backend/internal/smoketest-harness/README.md). | | [`backend/internal/deploy-harness`](../backend/internal/deploy-harness) | `@cat-factory/deploy-harness` | Container payload that renders a service's Kubernetes manifests (kubectl/kustomize/helm) into a per-PR namespace for ephemeral environments; carries no secrets. See [its README](../backend/internal/deploy-harness/README.md). | | [`backend/internal/example-custom-agent`](../backend/internal/example-custom-agent) | `@cat-factory/example-custom-agent` | Worked example of a company-authored extension package registered purely via the public app-owned registries (by reference): a repo-writing agent that ships with zero harness changes, a rubric **judge** that can bounce or block a run (`registerExampleScopeJudge`), a bundled skill + an MCP tool server declared on one of its kinds, plus a custom test-infrastructure provider with a multi-file `detect()` autodetection hook (`registerExampleStackDeployProvider`). | | [`backend/internal/example-delegated-executor`](../backend/internal/example-delegated-executor) | `@cat-factory/example-delegated-executor` | Worked example of the OTHER extension shape: a deployment plugging an **external executor** it already runs in as the executor of one pipeline step (a `DelegatedExecutorDefinition`, an agent kind that runs on it, and a pipeline that keeps cat-factory’s CI gate and merge tail around it). The executor is a fake, so it runs with no external system. | **Deployments** (examples; copy these to deploy on your own infra): | Path | Package | Role | | ------------------------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [`deploy/backend`](../deploy/backend) | `@cat-factory/deploy-backend` | Cloudflare Worker deployment TEMPLATE: re-exports `@cat-factory/worker` + a placeholder-filled `wrangler.toml`. See [its README](../deploy/backend/README.md). | | [`deploy/node`](../deploy/node) | `@cat-factory/deploy-node` | Node.js service deployment: calls `@cat-factory/node-server`'s `start()` (Postgres + pg-boss); ships a `Dockerfile` + `.env.example`. See [its README](../deploy/node/README.md). | | [`deploy/frontend`](../deploy/frontend) | `@cat-factory/deploy-frontend` | Pages deployment TEMPLATE: a thin Nuxt app that `extends` `@cat-factory/app` + the Pages `wrangler.toml`, plus a worked **consumer extension** example (the `acme:security` module, the frontend analogue of `example-custom-agent`, contributing a result window / nav entry / inspector panel / custom task type via `registerAppModule`). See [its README](../deploy/frontend/README.md). | | [`deploy/local`](../deploy/local) | `@cat-factory/deploy-local` | Local-mode deployment: calls `@cat-factory/local-server`'s `startLocal()`: agent jobs as local Docker containers, GitHub via a PAT, a local Postgres. See [its README](../deploy/local/README.md). | | [`deploy/gatekeeper`](../deploy/gatekeeper) | `@cat-factory/deploy-gatekeeper` | **Cloudflare OS Gatekeeper** deployment TEMPLATE: the wrangler bindings, the policy an operator writes (`src/policy.config.ts`) and three lines of wiring over the published `@cat-factory/gatekeeper-worker`, which carries the machinery. A consumer of the published surface, unpublished, with its own CI lane. See [its README](../deploy/gatekeeper/README.md). | | [`deploy/preview`](../deploy/preview) | none | Per-PR **test environments for cat-factory itself** (no package): a single-origin docker-compose stack for local deployments, and the reference preview workflow the built-in `cloudflare` environment backend drives (per-PR Worker + D1 + Pages preview). See [its README](../deploy/preview/README.md) and [`docs/internal/dogfooding.md`](./internal/dogfooding.md). | In this repo the deployments depend on the libraries via `workspace:*`; in your own copy you swap that for the published npm version. The backend is a hexagonal monorepo: controllers (worker) → services (core) → ports, with infra adapters wired in `container.ts`. The full breakdown is in the [backend overview](../backend/README.md). Releases use changesets; see [`CONTRIBUTING.md`](../CONTRIBUTING.md).