Skip to main content

learn-rat-stack

Trace a capability through Effect, XState, five projections, the CLI, and Alchemy. Try hosted search and read.

ソース情報

リポジトリ
joelhooks/rat-stack
ソースの最終更新活動
2026年10月2日 18:16
検出された SKILL.md の言語
英語
スター
81
フォーク
3

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
learn-rat-stack
description
Trace a capability through Effect, XState, five projections, the CLI, and Alchemy. Try hosted search and read.
# Learn the stack Start with one [capability](/systems/capabilities): `inspectFile`. Follow its [contract](/systems/capabilities), handler, service, machine, and [projections](/lore/one-capability-every-surface). Then try the hosted content tools. ## The pieces - Effect supplies schemas, services, typed errors, and Layers. - XState owns finite lifecycles. The Effect bridge runs their declared actors. - TypeScript 7 and Effect diagnostics check types and Effect usage. - Oxlint, Oxfmt, Vitest, and lefthook enforce [the fence](/lore/the-fence). - pnpm and Turborepo connect packages and cache checks. - Alchemy declares the cloud. Follow [learn Alchemy](/skills/learn-alchemy) for the deployment graph. **What to notice:** Each piece has a job. The pinned examples below show their connections. ## One action, five surfaces ```text ┌─ CLI ├─ HTTP One Capability ──────┼─ MCP ├─ code mode └─ RPC ``` A [projection](/lore/one-capability-every-surface) exposes the same action through another interface. RPC serves browser clients. [Code mode](/lore/one-program-can-replace-several-tool-calls) lets agents compose calls in one program. **What to notice:** The diagram shows interfaces, not five separate handlers. ## Trace one action These excerpts pin the code to `5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b` on the repository's main branch. The CLI uses `inspectFile`. The hosted site uses a separate content registry. ### 1. Define the contract The [contract](/systems/capabilities) names the action and its input, output, and failure schemas. ```ts repo=rat-stack path=packages/core/src/contracts.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=155-163 {155,158-163} ``` **What to notice:** `FileStatsError` belongs to the interface. The annotations mark a repeatable, read-only action. ### 2. Bind one handler `implement` binds the contract to `runInspectMachine`. The registry includes the resulting [capability](/systems/capabilities). ```ts repo=rat-stack path=packages/core/src/inspect-file.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=7-11 {7-9,11} ``` **What to notice:** The handler starts a machine. It does not read the file itself. ### 3. Put file work in a service `FileInspector.make` captures the file system. Its `inspect` method reads bytes and maps file errors to `FileStatsError`. ```ts repo=rat-stack path=packages/core/src/file-inspector.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=14-29 {15,20-24,28} ``` The service exposes its [Layer](/lore/layer-constructor-pattern) beside the implementation. This follows [hexagonal architecture](/lore/hexagonal-architecture): composition supplies the file-system dependency. ```ts repo=rat-stack path=packages/core/src/file-inspector.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=31-35 {34} ``` **What to notice:** Callers ask the service to inspect a path. They do not choose a file-system implementation. ### 4. Give the lifecycle named states A declared `fromEffect` actor calls `FileInspector`. ```ts repo=rat-stack path=packages/core/src/inspect-machine.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=26-30 {26,28} ``` The machine starts in `reading`. It finishes in `inspected` or `unreadable`. ```ts repo=rat-stack path=packages/core/src/inspect-machine.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=40-64 {40,43,51,57,59,62} ``` **What to notice:** Success and failure are states. The declared actor owns the file read. ### 5. Project the registered actions The CLI's server surfaces use the same `capabilities` list. ```ts repo=rat-stack path=apps/cli/src/surfaces.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=21-32 {21,23,25,29} ``` The RPC [projection](/lore/one-capability-every-surface) derives contracts from its supplied capabilities. ```ts repo=rat-stack path=packages/capability/src/to-rpc.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=24-27 {24,27} ``` **What to notice:** A projection takes a registry. It does not require another domain handler. ### 6. Wire the CLI `toCommand` derives each command. `inspectFile` also gets the `stats` alias. ```ts repo=rat-stack path=apps/cli/src/command.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=20-30 {23-27} ``` The entry point supplies the service [Layer](/lore/layer-constructor-pattern) and Node services. It denies [approval](/systems/capabilities) by default. ```ts repo=rat-stack path=apps/cli/src/cli.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=16-22 {18,20} ``` **What to notice:** Composition provides dependencies. The command keeps the shared handler. ### 7. Compose the cloud Alchemy declares the Stack, Cloudflare providers, and state. The Stack includes `Mischief` and `Website`. ```ts repo=rat-stack path=apps/infra/alchemy.run.ts at=5c0f78e03d69ff9ea00f6b95d02cc36a3de91a0b lines=12-18,114-119 {12,15-16,114-115} ``` **What to notice:** This is cloud composition, not a deployment of the Node file-inspection CLI. ## Try hosted search and read Use [POST /api/execute](/api/execute) for [code mode](/lore/one-program-can-replace-several-tool-calls). The [agent guide](/llms.txt) documents this search → read program: ```js const found = await tools.search({ query: "cartridges", limit: 1 }); const page = await tools.read({ id: found.matches[0].id }); return { title: page.title, id: page.id }; ``` Send it as a JSON `code` string: ```sh curl --request POST 'https://ratstack.sh/api/execute' \ --header 'content-type: application/json' \ --data '{"code":"const found = await tools.search({ query: \"cartridges\", limit: 1 }); const page = await tools.read({ id: found.matches[0].id }); return { title: page.title, id: page.id };"}' ``` **What to notice:** `read` takes the exact ID from `search`. This hosted program reads content, not local files. ## Read before changing a piece 1. Read [`AGENTS.md`](/AGENTS.md) for pins, boundaries, and [the fence](/lore/the-fence). 2. Read [VISION.md](/VISION.md) for intent. 3. Read the package you plan to change. 4. Before Effect or XState work, read `node_modules/effect/AGENTS.md` and the pinned sources listed in repo law. In a copied product repo, replace the template's product notes and rules. Keep the stack lessons that still serve the product. **What to notice:** Repo law and pinned code win over a stale example. ## Pick the next skill - Add schemas and a shared action: [`add-a-capability`](/skills/add-a-capability). - Model a lifecycle: [add a lifecycle machine](/skills/add-a-lifecycle-machine). - Remove a surface: [keep or cut](/skills/keep-or-cut). - Follow the cloud footprint: [learn Alchemy](/skills/learn-alchemy). **What to notice:** Pick the skill for the boundary you plan to change. ## Finish Run the full gate: ```sh pnpm turbo run check test build ``` Fix failures. Keep [the fence](/lore/the-fence) intact. **What to notice:** A passing gate is the check, not a claim that the cloud was deployed.
GitHubで見る