alchemy

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Alchemy

Alchemy

Use this skill when configuring, developing, deploying, or debugging infrastructure with Alchemy v2 and the Effect-native patterns from
alchemy-run/alchemy-effect
. Alchemy treats infrastructure as an Effect program: stacks declare resources, providers supply cloud integrations, local dev can run app code locally against real cloud resources, and deploys converge declared resources into live cloud state.
Alchemy is the preferred Darkmatter path for new TypeScript/Effect deployable infrastructure. Reach for it before ad hoc provider scripts, hand-written Wrangler/Terraform glue, or one-off deploy workflows unless a repo has an explicit exception or an existing production system that should not be disturbed.
Alchemy v2 and
alchemy-effect
move quickly. Verify upstream docs before changing deploy or dev code, especially package versions, provider APIs,
alchemy dev
behavior, and CLI flags. This skill carries the upstream
alchemy-run/alchemy-effect
repo as a local submodule at
reference/alchemy-effect
for source, examples, and agent instructions.
当你使用Alchemy v2以及
alchemy-run/alchemy-effect
提供的Effect原生模式配置、开发、部署或调试基础设施时,可使用此技能。Alchemy将基础设施视为一个Effect程序:栈(stack)声明资源,提供商(provider)提供云集成能力,本地开发可以在真实云资源上运行应用代码,部署则会将声明的资源收敛为实际的云状态。
对于新的TypeScript/Effect可部署基础设施,Alchemy是Darkmatter的首选方案。优先使用Alchemy,而非临时编写的提供商脚本、手写的Wrangler/Terraform粘合代码,或是一次性部署工作流——除非仓库有明确的例外规定,或是存在不应被改动的现有生产系统。
Alchemy v2和
alchemy-effect
迭代很快。在修改部署或开发代码之前,请先查阅上游文档,尤其是包版本、提供商API、
alchemy dev
的行为以及CLI参数。此技能将上游的
alchemy-run/alchemy-effect
仓库作为本地子模块放在
reference/alchemy-effect
路径下,可用于查看源码、示例和Agent操作说明。

When to use

适用场景

  • The user asks to set up or review an
    alchemy.run.ts
    file.
  • The user asks to develop with
    alchemy dev
    , local Workers, public preview URLs, hot reload, or webhook testing.
  • The user asks to configure an Alchemy deploy for Cloudflare Workers, Vite apps, R2, Queues, Durable Objects, D1, AWS Lambda, S3, DynamoDB, ECS, EC2, static sites, or related resources.
  • The user asks how to use Alchemy stages, profiles, state stores, bindings, stack outputs, cross-stack references, or CI/CD.
  • The user asks to migrate deploy plumbing toward Alchemy v2 or away from ad hoc provider scripts.
  • The user asks for examples from
    alchemy-run/alchemy-effect/examples
    .
  • 用户要求设置或审查
    alchemy.run.ts
    文件。
  • 用户要求使用
    alchemy dev
    、本地Workers、公共预览URL、热重载或webhook测试进行开发。
  • 用户要求为Cloudflare Workers、Vite应用、R2、Queues、Durable Objects、D1、AWS Lambda、S3、DynamoDB、ECS、EC2、静态站点或相关资源配置Alchemy部署。
  • 用户询问如何使用Alchemy的部署阶段、配置文件、状态存储、绑定、栈输出、跨栈引用或CI/CD。
  • 用户要求将部署底层设施迁移到Alchemy v2,或是替换掉临时的提供商脚本。
  • 用户需要
    alchemy-run/alchemy-effect/examples
    中的示例。

When NOT to use

不适用场景

  • The request is about the blockchain data/API company Alchemy and not
    alchemy.run
    .
  • The project does not use TypeScript, Effect, Bun/Node, or Alchemy, and the user is only asking a generic deployment question.
  • The task is to implement or modify a provider inside the upstream
    alchemy-effect
    repo. Use the upstream repo's
    AGENTS.md
    directly, then use this skill only for deploy-configuration implications.
  • The task is purely Effect application logic with no deployable infrastructure. Use
    effect-typescript
    .
  • A mature repo already has a production deploy path and the user asks for a narrow bug fix. Preserve the working path unless they explicitly ask to migrate.
  • 请求涉及的是区块链数据/API公司Alchemy,而非
    alchemy.run
    。
  • 项目不使用TypeScript、Effect、Bun/Node或Alchemy,且用户只是询问通用的部署问题。
  • 任务是在上游
    alchemy-effect
    仓库中实现或修改提供商。请直接使用上游仓库的
    AGENTS.md
    ,此技能仅用于处理部署配置相关的影响。
  • 任务是纯Effect应用逻辑,不涉及可部署基础设施。请使用
    effect-typescript
    技能。
  • 成熟的仓库已有生产部署路径,且用户只要求修复特定bug。请保留现有可用路径,除非用户明确要求迁移。

Upstream check

上游检查

Before editing, inspect the current docs or local installed package:
bash
bun alchemy --help
bun alchemy dev --help
bun pm ls alchemy effect @effect/platform-bun @effect/platform-node
Use these upstream references first:
  • https://v2.alchemy.run/getting-started/
    for the current install command, first stack shape, and deploy flow.
  • https://v2.alchemy.run/concepts/stack/
    for stack names, outputs, stages, cross-stack references, and state isolation.
  • https://v2.alchemy.run/concepts/local-development/
    and
    https://v2.alchemy.run/tutorial/part-4/
    for
    alchemy dev
    .
  • https://v2.alchemy.run/concepts/state-store/
    for where state is persisted.
  • https://v2.alchemy.run/guides/ci/
    for non-interactive deploys and PR preview environments.
  • reference/alchemy-effect/AGENTS.md
    for upstream Effect-native infrastructure conventions.
  • reference/alchemy-effect/README.md
    for the current project overview and install shape.
  • reference/alchemy-effect/examples/
    for concrete app patterns.
  • reference/alchemy-effect/packages/alchemy/src/
    for provider/resource implementation patterns.
If upstream conflicts with this skill, follow upstream and mention the drift.
If the submodule is missing in a fresh checkout, initialize it before relying on local references:
bash
git submodule update --init skills/alchemy/reference/alchemy-effect
Treat the submodule as read-only during app/deploy work. Edit it only when the user explicitly asks for an upstream
alchemy-effect
contribution, and then follow
reference/alchemy-effect/AGENTS.md
as the repo-local authority.
在编辑之前,请检查当前文档或本地安装的包:
bash
bun alchemy --help
bun alchemy dev --help
bun pm ls alchemy effect @effect/platform-bun @effect/platform-node
请优先参考以下上游资料:
  • https://v2.alchemy.run/getting-started/
    :查看当前安装命令、首个栈的结构和部署流程。
  • https://v2.alchemy.run/concepts/stack/
    :查看栈名称、输出、阶段、跨栈引用和状态隔离。
  • https://v2.alchemy.run/concepts/local-development/
    和
    https://v2.alchemy.run/tutorial/part-4/
    :了解
    alchemy dev
    的用法。
  • https://v2.alchemy.run/concepts/state-store/
    :了解状态的持久化位置。
  • https://v2.alchemy.run/guides/ci/
    :了解非交互式部署和PR预览环境。
  • reference/alchemy-effect/AGENTS.md
    :查看上游Effect原生基础设施约定。
  • reference/alchemy-effect/README.md
    :查看当前项目概览和安装方式。
  • reference/alchemy-effect/examples/
    :查看具体的应用模式。
  • reference/alchemy-effect/packages/alchemy/src/
    :查看提供商/资源的实现模式。
如果上游文档与此技能存在冲突,请遵循上游文档,并说明差异。
如果在新克隆的代码中子模块缺失,请先初始化子模块,再依赖本地参考资料:
bash
git submodule update --init skills/alchemy/reference/alchemy-effect
在应用/部署工作中,请将子模块视为只读。仅当用户明确要求向上游
alchemy-effect
贡献代码时才可编辑,且需遵循
reference/alchemy-effect/AGENTS.md
作为仓库本地的权威规范。

Project setup

项目设置

Prefer Bun unless the project already standardizes on another package manager. Current Alchemy v2 docs recommend Bun or Node.js 22+ and install Alchemy with Effect platform packages:
bash
bun add "alchemy@2.0.0-beta.40" "effect@>=4.0.0-beta.66 || >=4.0.0" "@effect/platform-bun@>=4.0.0-beta.66 || >=4.0.0" "@effect/platform-node@>=4.0.0-beta.66 || >=4.0.0"
Pin package versions according to the existing repo policy. If a repo already uses a catalog, workspace protocol, or lockfile-only upgrade lane, follow that instead of pasting the docs command blindly.
Before adding Alchemy to an existing repo, inspect the current setup:
bash
rg -n "alchemy|alchemy.run|alchemy dev|alchemy deploy" package.json bun.lock package-lock.json pnpm-lock.yaml yarn.lock .github scripts . --glob '!node_modules'
find . -name 'alchemy.run.ts' -o -name 'alchemy.run.js'
If the repo does not already have Alchemy configured, ask the user whether they want Alchemy set up for local development as well as deploys. Do not silently create a deploy-only setup:
alchemy dev
changes the local workflow by provisioning real cloud resources, exposing public preview URLs, and enabling webhook/OAuth callback testing against local code. If the user says yes, include the
dev
script, dev-stage/profile guidance, public preview output handling, and webhook test notes in the first implementation.
Add scripts that make the stack path explicit when the repo has more than one app:
json
{
  "scripts": {
    "dev": "alchemy dev ./alchemy.run.ts",
    "deploy": "alchemy deploy ./alchemy.run.ts",
    "destroy": "alchemy destroy ./alchemy.run.ts",
    "deploy:prod": "alchemy deploy ./alchemy.run.ts --stage prod --profile prod"
  }
}
Use plain
bun alchemy deploy
only in tiny repos where
alchemy.run.ts
at the root is unambiguous.
除非项目已标准化使用其他包管理器,否则优先使用Bun。当前Alchemy v2文档推荐使用Bun或Node.js 22+,并通过Effect平台包安装Alchemy:
bash
bun add "alchemy@2.0.0-beta.40" "effect@>=4.0.0-beta.66 || >=4.0.0" "@effect/platform-bun@>=4.0.0-beta.66 || >=4.0.0" "@effect/platform-node@>=4.0.0-beta.66 || >=4.0.0"
请根据现有仓库的策略锁定包版本。如果仓库已使用目录、workspace协议或仅lockfile升级路径,请遵循该策略,不要盲目粘贴文档中的命令。
在向现有仓库添加Alchemy之前,请检查当前的配置:
bash
rg -n "alchemy|alchemy.run|alchemy dev|alchemy deploy" package.json bun.lock package-lock.json pnpm-lock.yaml yarn.lock .github scripts . --glob '!node_modules'
find . -name 'alchemy.run.ts' -o -name 'alchemy.run.js'
如果仓库尚未配置Alchemy,请询问用户是否需要同时配置本地开发和部署功能。不要静默创建仅用于部署的配置:
alchemy dev
会通过供应真实云资源、暴露公共预览URL、支持针对本地代码的webhook/OAuth回调测试,来改变本地工作流。如果用户同意,请在首次实现中包含
dev
脚本、开发阶段/配置文件指引、公共预览输出处理以及webhook测试说明。
当仓库中有多个应用时,请添加脚本以明确栈的路径:
json
{
  "scripts": {
    "dev": "alchemy dev ./alchemy.run.ts",
    "deploy": "alchemy deploy ./alchemy.run.ts",
    "destroy": "alchemy destroy ./alchemy.run.ts",
    "deploy:prod": "alchemy deploy ./alchemy.run.ts --stage prod --profile prod"
  }
}
仅在根目录下的
alchemy.run.ts
不存在歧义的小型仓库中,才使用简单的
bun alchemy deploy
命令。

Org default

组织默认规范

For Darkmatter TypeScript/Effect projects, prefer Alchemy for deployable infrastructure:
  • New Cloudflare Workers, Vite/frontends, queues, R2/KV, workflows, AI Gateway, tunnels, and GitHub deploy automation should start with Alchemy.
  • Application data is Postgres-first. Use Kysely +
    pg
    for query-heavy TypeScript adapters, or Effect SQL Postgres for Effect-native database services. Let Alchemy own the deploy wiring, bindings, secrets, and network resources around that database where the provider supports it.
  • Use D1/sqlite only for narrow edge-local state, demos, or an explicit project decision. Do not pick D1 because the app is on Cloudflare if the data model belongs in Postgres.
  • New AWS Lambda, S3, DynamoDB, API Gateway, ECS/EC2/EKS/RDS, and static-site deploys should consider Alchemy first.
  • Shared preview environments should use Alchemy stages instead of bespoke name mangling.
  • Local webhook testing should use
    alchemy dev
    or an Alchemy-managed tunnel/preview flow instead of separate ngrok/Cloudflare Tunnel scripts when Alchemy can provide the route.
  • Hand-written provider CLIs can still be useful for diagnostics, but should not become the durable deploy control plane without a reason.
对于Darkmatter的TypeScript/Effect项目,可部署基础设施优先使用Alchemy:
  • 新的Cloudflare Workers、Vite/前端应用、队列、R2/KV、工作流、AI Gateway、隧道和GitHub部署自动化,都应从Alchemy开始。
  • 应用数据优先使用Postgres。对于查询密集的TypeScript适配器,使用Kysely +
    pg
    ;对于Effect原生数据库服务,使用Effect SQL Postgres。在提供商支持的情况下,由Alchemy负责该数据库的部署配置、绑定、密钥和网络资源。
  • 仅在有限的边缘本地状态、演示或明确的项目决策下,才使用D1/sqlite。如果数据模型适合Postgres,不要因为应用部署在Cloudflare上就选择D1。
  • 新的AWS Lambda、S3、DynamoDB、API Gateway、ECS/EC2/EKS/RDS和静态站点部署,应优先考虑Alchemy。
  • 共享预览环境应使用Alchemy的阶段,而非自定义的名称拼接。
  • 当Alchemy可以提供路由时,本地webhook测试应使用
    alchemy dev
    或Alchemy管理的隧道/预览流程,而非单独的ngrok/Cloudflare Tunnel脚本。
  • 手写的提供商CLI对于诊断仍然有用,但不应无故成为长期的部署控制平面。

Stack shape

栈结构

Every deploy file should default-export
Alchemy.Stack(name, options, Effect.gen(...))
.
ts
import * as Alchemy from "alchemy";
import * as Cloudflare from "alchemy/Cloudflare";
import * as Effect from "effect/Effect";

export default Alchemy.Stack(
  "MyApp",
  {
    providers: Cloudflare.providers(),
    state: Cloudflare.state(),
  },
  Effect.gen(function* () {
    const bucket = yield* Cloudflare.R2Bucket("Bucket");

    return {
      bucketName: bucket.bucketName,
    };
  }),
);
The load-bearing pieces are:
  • Stack name: stable logical deployment unit. Do not casually rename it; state and names derive from it.
  • Providers: cloud auth and provider implementations, for example
    Cloudflare.providers()
    or
    AWS.providers()
    .
  • State: choose deliberately. Cloudflare deploys commonly use
    Cloudflare.state()
    ; simple AWS examples may use
    Alchemy.localState()
    .
  • Effect body: declare resources with
    yield*
    , compose dependencies through references and bindings, and return useful outputs for smoke checks.
每个部署文件都应默认导出
Alchemy.Stack(name, options, Effect.gen(...))
。
ts
import * as Alchemy from "alchemy";
import * as Cloudflare from "alchemy/Cloudflare";
import * as Effect from "effect/Effect";

export default Alchemy.Stack(
  "MyApp",
  {
    providers: Cloudflare.providers(),
    state: Cloudflare.state(),
  },
  Effect.gen(function* () {
    const bucket = yield* Cloudflare.R2Bucket("Bucket");

    return {
      bucketName: bucket.bucketName,
    };
  }),
);
核心组成部分包括:
  • 栈名称:稳定的逻辑部署单元。不要随意重命名;状态和名称都由此派生。
  • 提供商:云认证和提供商实现,例如
    Cloudflare.providers()
    或
    AWS.providers()
    。
  • 状态:需谨慎选择。Cloudflare部署通常使用
    Cloudflare.state()
    ;简单的AWS示例可能使用
    Alchemy.localState()
    。
  • Effect主体:使用
    yield*
    声明资源,通过引用和绑定组合依赖,并返回有用的输出用于冒烟测试。

Effect-native provider module layout

Effect原生提供商模块结构

Follow codebase-design for shared readability rules. A provider owns the operations that converge a resource and the cleanup needed when those operations fail or finish. Inspect the installed Alchemy version and pinned upstream provider before choosing API names or registration shapes. Upstream contributions follow that repository's own layout.
For a provider implemented in a Darkmatter app or package:
  • Group by the resource or provider domain, then use
    models/
    ,
    services/
    ,
    adapters/
    , and
    workflows/
    where those roles have real responsibilities. A single-domain package already supplies the owner.
  • Keep resource schemas and inferred types together. Expose the resource contract and supported provider layer through explicit package entries.
  • Keep adoption, comparison, mapping, and status helpers with the lifecycle implementation that needs them. Extract when it hides complexity or enables useful reuse; avoid a file per helper or separate
    Types
    and
    Schemas
    copies.
  • A shared client can own API requests, response decoding, and typed failures. Use an Effect-native SDK directly; wrap a Promise SDK only at that edge. Keep configuration and credentials in the existing config/provider layers.
  • Preserve Alchemy's resource/provider collection and binding contracts. Public composition may register several resource layers without re-exporting every internal helper through a chain of barrels.
  • Keep configured file limits. Document a targeted increase when a forced split would scatter one coherent reconciler.
Test refactors through the resource or provider interface. Retain lifecycle coverage for create, repeated deploy, adoption, update, and destroy as applicable. Use real provider clients or substitute an external service through a Layer. Do not extract or export private selection/mapping helpers just to test them; a public pure helper with its own contract can retain focused tests.
请遵循代码库设计中的通用可读性规则。提供商负责资源收敛操作,以及操作失败或完成后的清理工作。在选择API名称或注册形式之前,请检查已安装的Alchemy版本和锁定的上游提供商。上游贡献需遵循对应仓库自身的结构规范。
对于在Darkmatter应用或包中实现的提供商:
  • 按资源或提供商领域分组,然后根据实际职责使用
    models/
    、
    services/
    、
    adapters/
    和
    workflows/
    目录。单领域包本身已经明确了归属。
  • 将资源schema和推断类型放在一起。通过明确的包入口暴露资源契约和支持的提供商层。
  • 将采纳、比较、映射和状态辅助函数与需要它们的生命周期实现放在一起。仅当这些辅助函数能隐藏复杂性或实现有用的复用才提取出来;避免每个辅助函数一个文件,或是分离出
    Types
    和
    Schemas
    的副本。
  • 共享客户端可以负责API请求、响应解码和类型化错误。直接使用Effect原生SDK;仅在边界处封装Promise SDK。将配置和凭证保存在现有的配置/提供商层中。
  • 保留Alchemy的资源/提供商集合和绑定契约。公共组合可以注册多个资源层,而无需通过一连串的重新导出文件暴露每个内部辅助函数。
  • 遵守配置的文件数量限制。如果强制拆分导致一个连贯的协调器被分散,请记录针对性的文件数上调说明。
通过资源或提供商接口测试重构。根据适用情况,保留对创建、重复部署、采纳、更新和销毁的生命周期覆盖。使用真实的提供商客户端,或通过Layer替换外部服务。不要为了测试就提取或导出私有的选择/映射辅助函数;具有自身契约的公共纯函数可以保留针对性的测试。

Local development

本地开发

Use
alchemy dev
for the default local loop when the app can run through Alchemy:
bash
bun alchemy dev ./alchemy.run.ts
Alchemy dev mode deploys infrastructure to the real cloud provider, runs supported app code locally, and hot reloads on file changes. For Cloudflare Workers, the Worker runs locally in
workerd
while a cloud proxy routes requests between public cloud endpoints and the local process.
This matters for webhook work: external services need a public URL, while the developer needs local code, breakpoints, and hot reload. Prefer an Alchemy dev/preview URL for webhook callbacks when available, then configure the third-party webhook target to that URL for the session or preview stage.
Use explicit dev ports when the app has multiple local services or a fixed callback URL:
ts
export const Worker = Cloudflare.Worker("Worker", {
  main: "./src/worker.ts",
  dev: {
    port: 3000,
  },
});
Dev-mode rules:
  • Treat cloud resources created by
    alchemy dev
    as real resources, not emulators.
  • Keep stage/profile explicit when working near shared accounts.
  • Return local/public URLs from stack outputs so the agent can test the live route.
  • Verify webhook flows with the provider's actual delivery logs when available.
  • Stop the dev process cleanly; destroy dev/preview resources when they are no longer needed and the stack owns them.
当应用可以通过Alchemy运行时,使用
alchemy dev
作为默认的本地开发循环:
bash
bun alchemy dev ./alchemy.run.ts
Alchemy开发模式会将基础设施部署到真实的云提供商,在本地运行支持的应用代码,并在文件变更时热重载。对于Cloudflare Workers,Worker在本地的
workerd
中运行,同时云代理在公共云端点和本地进程之间路由请求。
这对于webhook开发很重要:外部服务需要公共URL,而开发者需要本地代码、断点和热重载。在可用的情况下,优先使用Alchemy开发/预览URL作为webhook回调地址,然后将第三方webhook目标配置为该URL,用于当前会话或预览阶段。
当应用有多个本地服务或固定的回调URL时,请使用明确的开发端口:
ts
export const Worker = Cloudflare.Worker("Worker", {
  main: "./src/worker.ts",
  dev: {
    port: 3000,
  },
});
开发模式规则:
  • 将
    alchemy dev
    创建的云资源视为真实资源,而非模拟器。
  • 在共享账户上工作时,保持阶段/配置文件的明确性。
  • 从栈输出中返回本地/公共URL,以便Agent可以测试实时路由。
  • 在可用的情况下,使用提供商的实际投递日志验证webhook流程。
  • 干净地停止开发进程;当开发/预览资源不再需要且属于该栈时,销毁这些资源。

Stage and profile rules

阶段与配置文件规则

Treat stage and profile as part of the deployment contract:
  • Stage isolates state and physical names. The default is developer-specific; use explicit
    --stage prod
    ,
    --stage staging
    , or
    --stage pr-123
    for shared environments.
  • Profile selects credentials. First deploy may prompt interactively and save credentials under
    ~/.alchemy/profiles.json
    ; non-interactive CI must have profiles or provider credentials prepared before deploy.
  • Production scripts should pass both
    --stage prod
    and the intended
    --profile
    .
  • Preview deploys should derive a deterministic stage from the PR, branch, or issue id and should destroy that stage when it is no longer needed.
Useful commands:
bash
bun alchemy deploy ./alchemy.run.ts --stage dev_cm
bun alchemy deploy ./alchemy.run.ts --stage prod --profile prod
bun alchemy destroy ./alchemy.run.ts --stage pr-123 --profile preview
alchemy login --configure
alchemy login --profile prod --configure
Never use
Date.now()
or random timestamps in physical names. Let Alchemy generate names from stack, stage, and logical id, or use a deterministic name tied to the environment.
将阶段和配置文件视为部署契约的一部分:
  • 阶段用于隔离状态和物理名称。默认是开发者专属的;对于共享环境,请使用明确的
    --stage prod
    、
    --stage staging
    或
    --stage pr-123
    。
  • 配置文件用于选择凭证。首次部署可能会交互式提示,并将凭证保存在
    ~/.alchemy/profiles.json
    下;非交互式CI必须在部署前准备好配置文件或提供商凭证。
  • 生产环境脚本应同时传递
    --stage prod
    和目标
    --profile
    。
  • 预览部署应从PR、分支或issue ID派生出确定性的阶段,并在不再需要时销毁该阶段。
常用命令:
bash
bun alchemy deploy ./alchemy.run.ts --stage dev_cm
bun alchemy deploy ./alchemy.run.ts --stage prod --profile prod
bun alchemy destroy ./alchemy.run.ts --stage pr-123 --profile preview
alchemy login --configure
alchemy login --profile prod --configure
切勿在物理名称中使用
Date.now()
或随机时间戳。让Alchemy根据栈、阶段和逻辑ID生成名称,或使用与环境绑定的确定性名称。

Bindings and runtime dependencies

绑定与运行时依赖

Prefer bindings over manually threading deployed identifiers through environment variables. A binding is deploy-time data attached to a runtime resource so the function/worker receives exactly the infrastructure dependency it needs.
For Cloudflare, bind platform resources directly into a Worker or Vite app:
ts
export const Bucket = Cloudflare.R2Bucket("Bucket");

export const Worker = Cloudflare.Worker("Worker", {
  main: "./src/worker.ts",
  bindings: {
    Bucket,
  },
});
Keep Postgres connection details in the app's config/secrets layer and expose the runtime client through a service Layer. Only bind a database-like Cloudflare resource when the repo has an explicit reason not to use Postgres for that data.
For Effect-native runtimes, keep runtime services and deploy wiring separate. Alchemy owns cloud resources and bindings; Effect services own runtime behavior. Use Layers at the stack boundary when the resource requires a runtime implementation.
优先使用绑定,而非通过环境变量手动传递部署后的标识符。绑定是附加在运行时资源上的部署时数据,这样函数/worker就能准确接收其所需的基础设施依赖。
对于Cloudflare,将平台资源直接绑定到Worker或Vite应用:
ts
export const Bucket = Cloudflare.R2Bucket("Bucket");

export const Worker = Cloudflare.Worker("Worker", {
  main: "./src/worker.ts",
  bindings: {
    Bucket,
  },
});
将Postgres连接详情保存在应用的配置/密钥层中,并通过服务Layer暴露运行时客户端。仅当仓库有明确理由不使用Postgres存储该数据时,才绑定类似数据库的Cloudflare资源。
对于Effect原生运行时,将运行时服务和部署配置分开。Alchemy负责云资源和绑定;Effect服务负责运行时行为。当资源需要运行时实现时,在栈边界使用Layers。

Capability shape:
Binding.Service
+
Binding.Policy

能力结构:
Binding.Service
+
Binding.Policy

Every Alchemy capability ships as a pair of layers:
  • Binding.Service
    — runtime SDK wrapper, provided on the Function/Worker Effect (bundled into the deployed artifact).
  • Binding.Policy
    — deploy-time IAM/binding attachment, provided on the Stack via
    AWS.providers()()
    , never bundled.
For Cloudflare, the worker
bindings: { ... }
field handles both sides automatically. For AWS, the Service layer goes on the Function and the Policy layer must be enabled at the stack level. The default
AWS.providers()
already enables the common policy layers; only reach for
AWS.providers()(extraLayers)
when you author or override a capability.
每个Alchemy能力都以一对层的形式提供:
  • Binding.Service
    — 运行时SDK封装器,在Function/Worker的Effect上提供(被打包到部署产物中)。
  • Binding.Policy
    — 部署时IAM/绑定附件,通过
    AWS.providers()()
    在栈上提供,永远不会被打包。
对于Cloudflare,worker的
bindings: { ... }
字段会自动处理这两部分。对于AWS,Service层位于Function上,而Policy层必须在栈级别启用。默认的
AWS.providers()
已经启用了常用的策略层;仅当你编写或覆盖某个能力时,才需要使用
AWS.providers()(extraLayers)
。

Alchemy.RuntimeContext
on runtime-only methods

仅运行时方法上的
Alchemy.RuntimeContext

Bindings expose a typed callable whose inner Effect carries an
Alchemy.RuntimeContext
requirement. Treat that as a colored function:
  • The outer Effect (setup at function init) does NOT require
    RuntimeContext
    .
  • The inner Effect (the actual SDK call) MUST require
    RuntimeContext
    and only runs inside a deployed Function/Worker.
If a service wraps a binding and accidentally leaks
WorkerEnvironment
/
Lambda.FunctionEnvironment
into its interface, that service becomes cloud-coupled. Resolve cloud env services once during Layer construction and close over them — do not expose them as requirements on consumer Effects.
绑定暴露一个类型化的可调用对象,其内部Effect带有
Alchemy.RuntimeContext
依赖。请将其视为一种「有色函数」:
  • 外层Effect(在函数初始化时设置)不需要
    RuntimeContext
    。
  • 内层Effect(实际的SDK调用)必须依赖
    RuntimeContext
    ,且仅在已部署的Function/Worker中运行。
如果某个服务封装了一个绑定,却不小心将
WorkerEnvironment
/
Lambda.FunctionEnvironment
泄露到其接口中,那么该服务就会与云耦合。在Layer构造期间一次性解析云环境服务并将其闭包起来——不要将它们作为依赖暴露给消费者的Effect。

Effect platform rules in app/runtime code

应用/运行时代码中的Effect平台规则

Alchemy stacks and Worker/Function bodies run as Effect programs. Do not reach for raw async or Node primitives inside
Effect.gen
:
Don'tDo
import fs from "node:fs/promises"
const fs = yield* FileSystem.FileSystem
await fs.readFile(p, "utf8")
yield* fs.readFileString(p)
import path from "pathe"
/
node:path
const path = yield* Path.Path
await fetch(...)
yield* HttpClient.HttpClient
+
HttpClientRequest
new Promise((res) => setTimeout(res, ms))
yield* Effect.sleep(Duration.millis(ms))
Effect.promise(() => listSqlFiles(dir))
Make the helper itself return an
Effect
Pure transformations do not need Effect wrappers. Suspend environment reads and side effects in Effect; classify expected thrown failures when crossing an external boundary. Wrapping a CPU calculation does not make that calculation interruptible. Keep internal operations in Effect once a driver has been adapted, and run them only at the host or runtime boundary that requires it.
This applies to stack bodies, custom resource helpers, and tests. Tests must use
FileSystem.FileSystem
/
Path.Path
for any file/path access.
Polling rules for deploy/runtime tests:
  • Use
    Effect.repeat
    with
    Schedule
    + an
    until
    predicate and a bounded
    times: N
    cap.
  • Do not write
    while (Date.now() < deadline)
    loops — they ignore interruption and leak into the vitest timeout.
ts
// good — declarative, bounded, interruption-safe
const value =
  yield *
  fetchValue.pipe(
    Effect.repeat({
      schedule: Schedule.spaced("5 seconds"),
      until: (v) => v.ready,
      times: 36,
    }),
  );
Alchemy栈和Worker/Function体都作为Effect程序运行。不要在
Effect.gen
中使用原始的async或Node原语:
不要这样做应该这样做
import fs from "node:fs/promises"
const fs = yield* FileSystem.FileSystem
await fs.readFile(p, "utf-8")
yield* fs.readFileString(p)
import path from "pathe"
/
node:path
const path = yield* Path.Path
await fetch(...)
yield* HttpClient.HttpClient
+
HttpClientRequest
new Promise((res) => setTimeout(res, ms))
yield* Effect.sleep(Duration.millis(ms))
Effect.promise(() => listSqlFiles(dir))
Make the helper itself return an
Effect
纯转换不需要Effect封装。将环境读取和副作用挂起到Effect中;在跨越外部边界时,对预期的抛出错误进行分类。封装CPU计算并不会让该计算变得可中断。一旦适配了驱动程序,就将内部操作放在Effect中,并仅在需要的主机或运行时边界执行它们。
这适用于栈主体、自定义资源辅助函数和测试。测试中任何文件/路径访问都必须使用
FileSystem.FileSystem
/
Path.Path
。
部署/运行时测试的轮询规则:
  • 使用
    Effect.repeat
    带
    Schedule
    +
    until
    谓词,并设置有界的
    times: N
    上限。
  • 不要编写
    while (Date.now() < deadline)
    循环——它们会忽略中断,并且会超出vitest的超时时间。
ts
// good — declarative, bounded, interruption-safe
const value =
  yield *
  fetchValue.pipe(
    Effect.repeat({
      schedule: Schedule.spaced("5 seconds"),
      until: (v) => v.ready,
      times: 36,
    }),
  );

Provider lifecycle tests

提供商生命周期测试

When authoring custom Alchemy providers/resources, add provider-style tests with
alchemy/Test/Vitest
rather than only unit-testing helper functions. These tests exercise the real Alchemy plan/apply engine, private scratch state, repeated deploys, and destroy behavior in one Effect program.
Use this shape for resource lifecycle tests:
ts
import * as Test from "alchemy/Test/Vitest";
import { expect } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as ProviderNamespace from "../src/ProviderNamespace/index.ts";

const { test } = Test.make({ providers: ProviderNamespace.providers() });

test.provider("create, update, and delete resource", (stack) =>
  Effect.gen(function* () {
    const client = yield* ProviderNamespace.Client;

    const created = yield* stack.deploy(
      Effect.gen(function* () {
        return yield* ProviderNamespace.Resource("TestResource", {
          name: "v1",
        });
      }),
    );
    expect(created.resourceId).toBeDefined();

    // Verify live provider state through the provider SDK/client, not only
    // through returned attributes.
    const live1 = yield* client.get(created.resourceId);
    expect(live1.name).toBe("v1");

    const updated = yield* stack.deploy(
      Effect.gen(function* () {
        return yield* ProviderNamespace.Resource("TestResource", {
          name: "v2",
        });
      }),
    );
    expect(updated.resourceId).toBe(created.resourceId);

    const live2 = yield* client.get(updated.resourceId);
    expect(live2.name).toBe("v2");

    yield* stack.destroy();
  }),
);
Provider test rules:
  • Configure providers once per file with
    const { test } = Test.make({ providers: Namespace.providers() })
    .
  • Prefer real provider SDK/client assertions for integration tests. If live credentials or real resources are expensive/dangerous, use a fake service layer but still run through
    test.provider
    ,
    stack.deploy(...)
    , repeated deploy, and
    stack.destroy()
    .
  • Test create → update/noop/replace as appropriate → destroy in the same
    test.provider
    body so Alchemy state is shared across deploys.
  • Use the scratch stack handed to the test; do not write to
    .alchemy/
    or shared state from provider tests.
  • Provider implementations should close over services at provider construction (
    const client = yield* Client
    before returning lifecycle methods), matching Cloudflare providers. Do not leave
    yield* Client
    requirements inside
    read
    /
    diff
    /
    reconcile
    /
    delete
    unless the effect is explicitly provided there;
    test.provider
    should catch this with a “Service not found” failure.
  • For live provider tests that need credentials, resolve them through the same AuthProvider/config path as
    alchemy deploy
    (for example env-method credentials or an
    alchemy login
    test profile). Skip or gate the test when credentials are absent; do not commit secrets.
  • Preserve useful public-contract tests, including pure calculations. Do not require unit tests for every private selection/name/status/mapping helper; provider tests should continue to verify real lifecycle semantics.
在编写自定义Alchemy提供商/资源时,请使用
alchemy/Test/Vitest
添加提供商风格的测试,而不仅仅是对辅助函数进行单元测试。这些测试会在一个Effect程序中验证真实的Alchemy计划/应用引擎、私有临时状态、重复部署和销毁行为。
资源生命周期测试请使用以下结构:
ts
import * as Test from "alchemy/Test/Vitest";
import { expect } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as ProviderNamespace from "../src/ProviderNamespace/index.ts";

const { test } = Test.make({ providers: ProviderNamespace.providers() });

test.provider("create, update, and delete resource", (stack) =>
  Effect.gen(function* () {
    const client = yield* ProviderNamespace.Client;

    const created = yield* stack.deploy(
      Effect.gen(function* () {
        return yield* ProviderNamespace.Resource("TestResource", {
          name: "v1",
        });
      }),
    );
    expect(created.resourceId).toBeDefined();

    // Verify live provider state through the provider SDK/client, not only
    // through returned attributes.
    const live1 = yield* client.get(created.resourceId);
    expect(live1.name).toBe("v1");

    const updated = yield* stack.deploy(
      Effect.gen(function* () {
        return yield* ProviderNamespace.Resource("TestResource", {
          name: "v2",
        });
      }),
    );
    expect(updated.resourceId).toBe(created.resourceId);

    const live2 = yield* client.get(updated.resourceId);
    expect(live2.name).toBe("v2");

    yield* stack.destroy();
  }),
);
提供商测试规则:
  • 每个文件配置一次提供商,使用
    const { test } = Test.make({ providers: Namespace.providers() })
    。
  • 集成测试优先使用真实的提供商SDK/客户端断言。如果真实凭证或真实资源成本过高/有风险,可以使用模拟服务层,但仍需通过
    test.provider
    、
    stack.deploy(...)
    、重复部署和
    stack.destroy()
    运行。
  • 在同一个
    test.provider
    体中测试创建→更新/无操作/替换(视情况而定)→销毁的流程,这样Alchemy状态会在多次部署之间共享。
  • 使用传递给测试的临时栈;不要从提供商测试中写入
    .alchemy/
    或共享状态。
  • 提供商实现应在提供商构造时闭包服务(在返回生命周期方法之前执行
    const client = yield* Client
    ),与Cloudflare提供商保持一致。不要在
    read
    /
    diff
    /
    reconcile
    /
    delete
    中留下
    yield* Client
    依赖,除非该Effect在那里被明确提供;
    test.provider
    应该会通过「Service not found」错误捕获到这种情况。
  • 对于需要凭证的真实提供商测试,请通过与
    alchemy deploy
    相同的AuthProvider/配置路径解析凭证(例如环境变量方式的凭证或
    alchemy login
    的测试配置文件)。当缺少凭证时,跳过或限制测试;不要提交密钥。
  • 保留有用的公共契约测试,包括纯计算。不要要求每个私有的选择/名称/状态/映射辅助函数都有单元测试;提供商测试应继续验证真实的生命周期语义。

Build and type checking

构建与类型检查

Always type-check before committing changes that touch a stack, custom resource, or runtime binding:
bash
bun tsc -b
This runs the workspace build in project-reference mode. CI fails on type errors, so this is non-negotiable. When stale artifacts or dependency drift cause unexplained failures, fall back to a clean rebuild:
bash
bun run build       # clean + tsc + build the alchemy package
bun build:clean     # full reset: clean . + bun i + build + download env
bun build:clean
removes untracked files (preserving
.env
), reinstalls dependencies, rebuilds, and refreshes environment files. Treat it as a recovery command, not a routine one.
提交涉及栈、自定义资源或运行时绑定的更改之前,务必进行类型检查:
bash
bun tsc -b
这会以项目引用模式运行工作区构建。CI会因类型错误而失败,因此这是必须执行的。当过时的产物或依赖漂移导致无法解释的失败时,请回退到干净重建:
bash
bun run build       # clean + tsc + build the alchemy package
bun build:clean     # full reset: clean . + bun i + build + download env
bun build:clean
会删除未跟踪的文件(保留
.env
)、重新安装依赖、重建并刷新环境文件。请将其视为恢复命令,而非常规命令。

Secrets and config

密钥与配置

Do not commit provider tokens, API keys, generated profiles, or state files unless the repo explicitly owns a remote state backend and the file is designed for version control.
Use these rules:
  • Prefer provider profiles or CI secrets for deploy credentials.
  • Use Alchemy secret resources or provider-native secret resources for runtime secrets.
  • Keep non-secret config out of secret resources. Runtime configuration is a named config file in the repo, read through
    effect/Config
    ; on Workers, bundle the named configs and let the deploy set only the selector var (ADR-0014).
  • In darkmatter repos, route durable secrets through the repo's existing SOPS/Himitsu/CI secret path instead of inventing a new
    .env
    convention.
  • Document which profile, account, zone, region, or project owns each deploy target.
不要提交提供商令牌、API密钥、生成的配置文件或状态文件,除非仓库明确拥有远程状态后端,且该文件是为版本控制设计的。
请遵循以下规则:
  • 部署凭证优先使用提供商配置文件或CI密钥。
  • 运行时密钥使用Alchemy密钥资源或提供商原生的密钥资源。
  • 非密钥配置不要放在密钥资源中。运行时配置是仓库中的命名配置文件,通过
    effect/Config
    读取;在Workers上,打包命名配置,让部署仅设置选择器变量(ADR-0014)。
  • 在Darkmatter仓库中,持久化密钥通过仓库现有的SOPS/Himitsu/CI密钥路径传递,不要发明新的
    .env
    约定。
  • 记录每个部署目标所属的配置文件、账户、区域、地区或项目。

CI deploys

CI部署

CI should be deterministic and non-interactive:
  1. Install dependencies with the repo's locked package manager command.
  2. Run type checks before deploy.
  3. Authenticate the provider without a browser prompt.
  4. Deploy with explicit stack path, stage, and profile.
  5. Print or capture stack outputs for smoke tests.
  6. Destroy preview stages on branch/PR cleanup when the workflow owns temporary infrastructure.
Example CI command shape:
bash
bun install --frozen-lockfile
bun tsc -b
bun alchemy deploy ./alchemy.run.ts --stage "$ALCHEMY_STAGE" --profile "$ALCHEMY_PROFILE"
If a deploy failure starts in provider auth, profile lookup, state lock/state persistence, or missing CI secrets, fix that layer before changing resource code.
CI应具有确定性且非交互式:
  1. 使用仓库锁定的包管理器命令安装依赖。
  2. 在部署前运行类型检查。
  3. 无需浏览器提示即可完成提供商认证。
  4. 使用明确的栈路径、阶段和配置文件进行部署。
  5. 打印或捕获栈输出以用于冒烟测试。
  6. 当工作流拥有临时基础设施时,在分支/PR清理时销毁预览阶段。
CI命令示例格式:
bash
bun install --frozen-lockfile
bun tsc -b
bun alchemy deploy ./alchemy.run.ts --stage "$ALCHEMY_STAGE" --profile "$ALCHEMY_PROFILE"
如果部署失败始于提供商认证、配置文件查找、状态锁/状态持久化或缺少CI密钥,请先修复该层,再修改资源代码。

Preview URLs and webhooks

预览URL与webhook

Public previews are an expected Alchemy workflow:
  • PR deploys should use
    --stage pr-<number>
    and post the resulting app URL back to the PR when the repo has GitHub access.
  • Local development should use
    alchemy dev
    when a webhook or collaborator needs to reach a public URL backed by local code.
  • Preview URLs should be derived from stack outputs or provider resources, not guessed from PR numbers.
  • Webhook tests should exercise the real external sender when feasible, not only
    curl
    .
  • Cleanup should destroy preview stages on PR close/merge and retire temporary webhook registrations.
公共预览是Alchemy的标准工作流:
  • PR部署应使用
    --stage pr-<number>
    ,并在仓库有GitHub访问权限时将生成的应用URL回发到PR。
  • 当webhook或协作者需要访问由本地代码支持的公共URL时,本地开发应使用
    alchemy dev
    。
  • 预览URL应从栈输出或提供商资源中获取,而非根据PR编号猜测。
  • 可行的话,webhook测试应使用真实的外部发送方,而不仅仅是
    curl
    。
  • 清理时应在PR关闭/合并时销毁预览阶段,并注销临时webhook注册。

Verification

验证

Always verify the real deployed target when the request concerns deploy behavior:
bash
bun alchemy deploy ./alchemy.run.ts --stage "$STAGE" --profile "$PROFILE"
curl -fsS "$DEPLOYED_URL"
For local dev behavior, run the dev server and hit both local and public/proxied URLs when Alchemy prints both:
bash
bun alchemy dev ./alchemy.run.ts --stage "$STAGE" --profile "$PROFILE"
curl -fsS "$LOCAL_URL"
curl -fsS "$PUBLIC_PREVIEW_URL"
For Effect-native workers/functions, prefer a deployed fixture or smoke route over a purely local assertion. Fresh Workers, Lambda URLs, queues, cron, and DNS often need bounded retries for propagation; use
Effect.retry
or
Effect.repeat
with
Schedule
, not manual polling loops.
当请求涉及部署行为时,务必验证真实的部署目标:
bash
bun alchemy deploy ./alchemy.run.ts --stage "$STAGE" --profile "$PROFILE"
curl -fsS "$DEPLOYED_URL"
对于本地开发行为,当Alchemy同时打印本地和公共/代理URL时,请运行开发服务器并访问这两个URL:
bash
bun alchemy dev ./alchemy.run.ts --stage "$STAGE" --profile "$PROFILE"
curl -fsS "$LOCAL_URL"
curl -fsS "$PUBLIC_PREVIEW_URL"
对于Effect原生的workers/functions,优先使用已部署的测试夹具或冒烟路由,而非纯本地断言。新的Workers、Lambda URL、队列、cron和DNS通常需要有界的重试来完成传播;使用带有
Schedule
的
Effect.retry
或
Effect.repeat
,而非手动轮询循环。

Review checklist

审查清单

  • The stack path is explicit where the repo has multiple apps or packages.
  • Alchemy is used as the deploy/dev control plane unless the repo has an explicit reason not to.
  • Stack name, logical IDs, stage names, and physical names are stable and deterministic.
  • Provider and state store choices are intentional for the environment.
  • Prod deploys pass explicit
    --stage
    and
    --profile
    .
  • alchemy dev
    is configured for local loops that need real cloud resources, public preview URLs, or webhook testing.
  • Runtime resources use bindings rather than scattered string env vars where Alchemy supports bindings.
  • Secrets are not committed, echoed in logs, or encoded into stack outputs.
  • CI deploys are non-interactive and verify stack outputs or live endpoints.
  • Preview deploys have a destroy path.
  • Effect code uses typed errors, Layers, and
    Schedule
    for retries; Promise SDKs are adapted at their edge, and pure transformations stay plain TypeScript.
  • Provider operations own completion, errors, and cleanup. File splits hide real complexity and retain configured limits with documented, targeted exceptions.
  • 当仓库有多个应用或包时,栈路径是明确的。
  • Alchemy被用作部署/开发控制平面,除非仓库有明确的理由不这样做。
  • 栈名称、逻辑ID、阶段名称和物理名称是稳定且确定的。
  • 提供商和状态存储的选择是针对环境有意选择的。
  • 生产部署传递了明确的
    --stage
    和
    --profile
    。
  • alchemy dev
    已为需要真实云资源、公共预览URL或webhook测试的本地开发循环配置好。
  • 在Alchemy支持绑定的情况下,运行时资源使用绑定,而非分散的字符串环境变量。
  • 密钥没有被提交、在日志中回显,或是被编码到栈输出中。
  • CI部署是非交互式的,并验证栈输出或实时端点。
  • 预览部署有销毁路径。
  • Effect代码使用类型化错误、Layers和
    Schedule
    进行重试;Promise SDK在边界处被适配,纯转换保持为普通TypeScript。
  • 提供商操作负责完成、错误和清理。文件拆分应隐藏真实复杂性,并通过记录在案的针对性例外保留配置的限制。

Contributing back to
alchemy-effect

向
alchemy-effect
贡献代码

If a darkmatter repo needs a missing provider feature, the path is usually a PR upstream rather than a local fork. Two conventions matter when you open that PR:
  • PR title uses conventional commits (
    feat(aws/s3): add bucket lifecycle rules
    ,
    fix(website): mobile theme metas
    ).
  • PR description never starts with a
    #
    or
    ##
    heading — GitHub already renders the title above it. Use
    ###
    at most, and only when the description genuinely has multiple sections. Lead with a short prose summary or a code snippet that shows the new shape; cut anything that restates what the diff already shows. Never include a "Test plan" or checklist.
  • Outstanding work belongs in the PR-creation chat, not in the PR body. If something is unfinished or needs manual verification, mark the PR as draft and tell the user what is outstanding.
  • Body delivery: write the body to a temp file and pass
    --body-file
    to
    gh pr create
    /
    gh pr edit
    . Heredoc/
    --body "$(cat …)"
    mangles backticks across
    gh
    versions.
If you edit tutorial docs under
website/src/content/docs/tutorial/
, one concept gets one
##
heading, one diff snippet, and one prose paragraph. "Two/three things just happened" + a numbered list is the smell that says split the snippet.
If you edit resource JSDoc, run
bun generate:api-reference
to refresh
website/src/content/docs/providers/{Cloud}/{Resource}.md
. The generated markdown is overwritten on every regeneration — never hand-edit it.
reference/provider-implementation.md
has the detailed conventions you need before touching anything under
packages/alchemy/src/
upstream.
如果Darkmatter仓库需要某个缺失的提供商功能,通常的做法是向上游提交PR,而非本地分叉。提交PR时需要注意两个约定:
  • PR标题使用约定式提交(例如
    feat(aws/s3): add bucket lifecycle rules
    、
    fix(website): mobile theme metas
    )。
  • PR描述不要以
    #
    或
    ##
    标题开头——GitHub已经在上方渲染了标题。最多使用
    ###
    ,且仅当描述确实有多个部分时才用。以简短的文字摘要或展示新结构的代码片段开头;删掉任何重复diff已经展示内容的部分。永远不要包含「测试计划」或清单。
  • 未完成工作应放在PR创建的聊天中,而非PR正文中。如果有未完成的内容或需要手动验证,请将PR标记为草稿,并告知用户未完成的内容。
  • 正文传递:将正文写入临时文件,并将
    --body-file
    传递给
    gh pr create
    /
    gh pr edit
    。Heredoc/
    --body "$(cat …)"
    的方式在不同
    gh
    版本中会破坏反引号。
如果你编辑
website/src/content/docs/tutorial/
下的教程文档,一个概念对应一个
##
标题、一个diff片段和一段文字说明。如果出现「刚刚发生了两三件事」+编号列表的情况,就说明应该拆分片段了。
如果你编辑资源的JSDoc,请运行
bun generate:api-reference
来刷新
website/src/content/docs/providers/{Cloud}/{Resource}.md
。生成的markdown在每次重新生成时都会被覆盖——永远不要手动编辑它。
在接触上游
packages/alchemy/src/
下的任何内容之前,
reference/provider-implementation.md
中有你需要的详细约定。

References

参考资料

  • reference/upstream-concepts.md
    — Alchemy v2 and
    alchemy-effect
    concepts applied during app/deploy work.
  • reference/examples.md
    —
    alchemy-run/alchemy-effect/examples
    directories mapped to common deploy scenarios.
  • reference/provider-implementation.md
    — file system, reconciler doctrine, capability shape, tags, runtime context, test fixtures, JSDoc/docs, and tutorial standards for upstream provider contributions.
  • reference/alchemy-effect/
    — pinned git submodule of
    alchemy-run/alchemy-effect
    for current source, examples, docs, and upstream agent instructions.
  • reference/upstream-concepts.md
    — 应用/部署工作中用到的Alchemy v2和
    alchemy-effect
    概念。
  • reference/examples.md
    — 映射到常见部署场景的
    alchemy-run/alchemy-effect/examples
    目录。
  • reference/provider-implementation.md
    — 上游提供商贡献的文件系统、协调器原则、能力结构、标签、运行时上下文、测试夹具、JSDoc/文档和教程标准。
  • reference/alchemy-effect/
    —
    alchemy-run/alchemy-effect
    的固定git子模块,用于查看当前源码、示例、文档和上游Agent操作说明。