--- name: design-patterns description: "Use when choosing or applying a proven architecture pattern for a project built on Effect v4 / the @effected kit — splitting a tool into cli + mcp + lsp packages, deciding how a monorepo ships its bins, making \"install one package\" true for a consumer, a Claude Code or Copilot plugin launching a project's own bins, or threading one version identity through several front ends. This skill indexes patterns as loadable references; consult it before inventing an architecture the kit's own consumers have already worked out. Also use when: carrier package, meta-package, one package to install, bins missing from node_modules/.bin, cli + mcp + lsp split, front end vs engine, keeping the package graph acyclic, plugin loader script, version threading, distribution, engine_version, manifest DAG test, packed-install e2e" --- # Design patterns Proven architecture patterns for building on Effect v4 and the `@effected` kit, distilled from real multi-package tools and indexed as loadable references. This skill routes; depth lives in `references/`. ## Pattern index | Pattern | Reach for it when | Reference | | --- | --- | --- | | Carrier package — core/engine/front ends → carrier | a tool ships more than one bin (CLI, MCP server, LSP server, …) and you want "install one package" to be true, or you're debugging why a consumer's `node_modules/.bin` is missing a bin that resolves fine as a dependency | [carrier-package.md](./references/carrier-package.md), [carrier-entry-contract.md](./references/carrier-entry-contract.md), [carrier-version-threading.md](./references/carrier-version-threading.md), [carrier-plugin-loader.md](./references/carrier-plugin-loader.md), [carrier-verification.md](./references/carrier-verification.md), [carrier-app-and-schemas.md](./references/carrier-app-and-schemas.md) (optional), [carrier-case-studies.md](./references/carrier-case-studies.md) | More rows land here as more patterns are distilled. A pattern earns a row once it has shipped in more than one real tool and the trade-offs are settled, not on first use. ## Kit exports The carrier pattern's references teach the shape; where a piece of that shape has shipped as a kit export, reach for the export instead of hand-rolling the recipe again. | construct | import | reach for it when | | --- | --- | --- | | `CurrentDistribution`, `DistributionField`, `distributionSuffix` | `@effected/engine` | threading which meta-package a front end was installed through | | `LaunchContext` | `@effected/engine` | resolving an agent-launched project directory from `argv`/`env`/`cwd` | | `CliRuntime.main` | `@effected/cli` | assembling a CLI front end's `main.ts` | | `McpStdio` | `@effected/mcp` | assembling an MCP front end's `main.ts` — launch, stdio boundary, teardown | | `ProcessGuard`, `McpGuard` | `@effected/engine/guard`, `@effected/mcp/guard` | crash guards in a server front end's `main.ts` before its graph loads — any transport (an LSP), or MCP with the launch built in | | `WorkspaceLayering`, `LayerPolicy` | `@effected/workspaces/testing` | the manifest DAG test that holds the package graph to a committed policy | | `SourceBoundary` | `@effected/workspaces/testing` | a package's own `process`/import boundary test | | `PackedInstall` | `@effected/workspaces/testing` | the cross-package-manager packed-install e2e | | `McpProbe` | `@effected/mcp/testing` | the MCP half of a packed-install proof | ## Standards - **Name the layer, not the file.** "Front end", "engine", "carrier" are roles a package plays, not folder names — a repo may fold a role into an existing package (the carrier as a library) as long as the edges still point one way. - **Keep every edge pointing down.** A pattern that needs a same-layer or upward edge to work is the wrong shape for the problem, not a reason to add an exception. - **Verify a pattern against a real tool before applying it**, the same evidence discipline as any other platform claim — a pattern description is a distillation, not a substitute for reading the case study it came from. - **Prefer adding a package over introducing a back-edge.** Smaller, focused packages composed acyclically have proven more reliable than a shared package importing "up" for convenience. ## Footguns - Bin-linking is direct-dependency-only in every package manager — see [carrier-package.md](./references/carrier-package.md) for why hoisting and hand-rolled hoist patterns don't fix it. - A carrier's front ends belong in `dependencies`, never `peerDependencies` — see [carrier-package.md](./references/carrier-package.md). - An MCP `main.ts` that imports its server graph statically runs that graph before its crash guards exist: Node prints the throw and exits `1` on its own, but the server's own handler never runs — `McpStdio.launch` does not remove this requirement, it sits around it — see [carrier-entry-contract.md](./references/carrier-entry-contract.md) and `effect-v4-mcp`'s `server-wiring.md#crash-guards`. - A package.json read for "my own version" reports the wrong package's version once code moves to a shared engine — `CurrentDistribution` fixes the identity-threading half of this, not the build-time-literal half — see [carrier-version-threading.md](./references/carrier-version-threading.md). - A plugin loader that dispatches through `pnpm exec` / `yarn exec` / `bunx` resolves bins differently per package manager — see [carrier-plugin-loader.md](./references/carrier-plugin-loader.md). - A manifest DAG test with no positive-control fixture can pass while checking nothing — `WorkspaceLayering`'s own `edgeCount` guard is that control; a hand-rolled `LAYER_RANKS` table has to add it itself — see [carrier-verification.md](./references/carrier-verification.md). ## Additional resources - [references/carrier-package.md](./references/carrier-package.md) — the problem the carrier pattern solves, its roles and edge direction, the carrier-as-library deviation, the dependencies-vs-peers rule, and the release model. Load when: deciding whether a multi-bin tool needs this shape at all, or reviewing a package's `dependencies` vs `peerDependencies` split. - [references/carrier-entry-contract.md](./references/carrier-entry-contract.md) — the four-file front-end contract (`bin.ts`/`main.ts`/`index.ts`/`version.ts`), the carrier's bin shims, who declares a bin (carrier-only, recommended; or shared, at the cost of provenance), and the MCP crash-guard requirement. Load when: scaffolding a new front-end package or a carrier's bin shims. - [references/carrier-version-threading.md](./references/carrier-version-threading.md) — build-time version literals, the `Distribution` `Context.Reference`, `engine_version` as the comparable version, and the `--version` format. Load when: a tool needs to report which meta-package it was installed through, or two front ends disagree about "the version." - [references/carrier-plugin-loader.md](./references/carrier-plugin-loader.md) — the Claude Code / Copilot plugin loader shape (`node_modules/.bin` first, install hint, major-pinned `npx -p` fallback through the carrier) and the hook CLI resolution order. Load when: writing or reviewing a plugin's `mcpServers`/`lspServers` loader script or a hook that shells out to a project's own CLI. - [references/carrier-verification.md](./references/carrier-verification.md) — the manifest DAG test with non-vacuity, source boundary tests, and the packed-install e2e across package managers. Load when: adding the repo-shape checks to a multi-package tool — uses the kit's checks, not copied tests. - [references/carrier-app-and-schemas.md](./references/carrier-app-and-schemas.md) — the OPTIONAL extension: where the app layer (platform + config discovery) and a published config-file JSON Schema belong — core owns shape/version/hosted identity, the engine owns platform + discovery, front ends only pass in process-derived inputs. Load when: the tool has a user config file a person hand-edits, or publishes a JSON Schema for it — cross-links `building-schemastore-schemas` for the generation and drift-gate mechanics rather than re-teaching them here. - [references/carrier-case-studies.md](./references/carrier-case-studies.md) — okfit, vitest-agent and systems: what each does best, what each is missing, and the deviations each made and why. Load when: you want a worked, citable example instead of the prescriptive rule alone. ## Related skills - **`effect-v4-cli`** and **`effect-v4-mcp`** own each front end's own depth — assembling `main.ts`, exit codes, protocol wiring, tool definitions and testing. This skill teaches the shape a multi-front-end tool takes; the two front-end skills teach what happens inside each front end. Knowledge stays split rather than duplicated across all three.