mcpField
A
alchemy

alchemy

github.com/darkmatter云与 DevOps0303 次安装5 天前更新
代码仓库

关于 alchemy

面向 TypeScript 和 Effect 项目的 Alchemy v2 基础设施部署技能,适用于配置、开发、部署和排查云资源。它以 Effect 程序声明资源,并涵盖本地开发、部署阶段、状态管理及 CI/CD。

主要功能

  1. 01以 Effect 程序声明基础设施
  2. 02配置云提供商与资源
  3. 03通过 alchemy dev 本地开发
  4. 04管理阶段、配置与状态
  5. 05参考上游文档和示例

适用场景

  1. 01为 TypeScript 项目配置 Alchemy 部署
  2. 02在本地运行应用并连接真实云资源
  3. 03设置预览环境与 CI/CD 部署

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/darkmatter/skills --skill alchemy

安装后在 Claude Code 中输入/alchemy确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
examples.md
provider-implementation.md
upstream-concepts.md

详细介绍

Alchemy

在配置、开发、部署或调试基础设施时,如果使用 Alchemy v2 和 alchemy-run/alchemy-effect 中原生支持 Effect 的模式,请使用此技能。Alchemy 将基础设施视为 Effect 程序:堆栈声明资源,提供程序提供云集成,本地开发可在本地运行应用代码并使用真实云资源,部署则会使声明的资源与实时云状态保持一致。

对于新的 TypeScript/Effect 可部署基础设施,Alchemy 是 Darkmatter 的首选方案。除非仓库有明确例外,或已有不应干扰的生产系统,否则应优先使用它,而不是临时编写提供程序脚本、手写 Wrangler/Terraform 胶水代码或一次性部署工作流。

Alchemy v2 和 alchemy-effect 迭代很快。更改部署或开发代码前,请先核实上游文档,尤其是软件包版本、提供程序 API、alchemy dev 的行为和 CLI 标志。此技能通过本地子模块 reference/alchemy-effect 引入上游 alchemy-run/alchemy-effect 仓库,供查看源码、示例和 Agent 指令。

适用场景

  • 用户要求设置或审核 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 中的示例。

不适用场景

  • 请求涉及的是区块链数据/API 公司 Alchemy,而不是 alchemy.run。
  • 项目不使用 TypeScript、Effect、Bun/Node 或 Alchemy,且用户只是在询问通用部署问题。
  • 任务是在上游 alchemy-effect 仓库中实现或修改提供程序。请直接使用上游仓库的 AGENTS.md,然后仅在涉及部署配置时使用此技能。
  • 任务纯属 Effect 应用逻辑,不涉及可部署基础设施。请使用 effect-typescript。
  • 成熟的仓库已有生产部署流程,用户只要求修复一个范围有限的 bug。除非用户明确要求迁移,否则请保留现有可用流程。

检查上游资料

开始编辑前,请检查当前文档或本地已安装的软件包:

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/:查看提供程序/资源的实现模式。

如果上游内容与此技能冲突,请遵循上游内容,并说明差异。

如果全新检出时缺少子模块,请先初始化,再依赖本地参考资料:

git submodule update --init skills/alchemy/reference/alchemy-effect

在应用/部署工作期间,请将子模块视为只读。只有用户明确要求为上游 alchemy-effect 做贡献时,才编辑该子模块;届时请遵循 reference/alchemy-effect/AGENTS.md,将其作为仓库本地的权威规范。

项目设置

除非项目已经统一使用其他包管理器,否则优先使用 Bun。当前 Alchemy v2 文档建议使用 Bun 或 Node.js 22+,并通过 Effect 平台包安装 Alchemy:

bun add "[email protected]" "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"

根据现有仓库策略固定软件包版本。如果仓库已使用 catalog、workspace 协议或仅通过 lockfile 升级的流程,应遵循该流程,而不是盲目粘贴文档中的命令。

向现有仓库添加 Alchemy 之前,请检查当前设置:

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。不要默默创建仅用于部署的设置:alchemy dev 会通过预配真实云资源、公开预览 URL,以及支持使用本地代码测试 webhook/OAuth 回调来改变本地工作流。如果用户同意,请在首次实现中加入 dev 脚本、dev 阶段/配置文件指南、公开预览输出处理方式,以及 webhook 测试说明。

如果仓库有多个应用,请添加脚本,明确指定堆栈路径:

{
  "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。

组织默认做法

对于 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 阶段,而不是自定义名称拼接。
  • 本地 webhook 测试应使用 alchemy dev 或由 Alchemy 管理的隧道/预览流程;如果 Alchemy 能提供所需路由,就不要使用单独的 ngrok/Cloudflare Tunnel 脚本。
  • 手写的提供商 CLI 仍可用于诊断,但没有充分理由时,不应将其作为长期部署控制平面。

堆栈结构

每个部署文件都应默认导出 Alchemy.Stack(name, options, Effect.gen(...))。

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 原生提供方模块布局

遵循 codebase-design 中的通用可读性规则。提供方负责协调资源的操作,以及这些操作失败或完成时所需的清理工作。在选择 API 名称或注册形式之前,请检查已安装的 Alchemy 版本和固定版本的上游提供方。向上游贡献代码时,应遵循该仓库自身的布局。

对于在 Darkmatter 应用或软件包中实现的提供方:

  • 按资源或提供方领域分组,然后在各角色确有职责时使用 models/、services/、adapters/ 和 workflows/。单领域软件包本身已提供归属边界。
  • 将资源 schema 和推断类型放在一起。通过明确的软件包入口公开资源契约和受支持的提供方层。
  • 将采用、比较、映射和状态辅助逻辑与需要它们的生命周期实现放在一起。只有在能隐藏复杂性或实现有用的复用时才提取;避免为每个辅助函数单独建文件,也避免拆分出独立的 Types 和 Schemas 副本。
  • 共享客户端可以负责 API 请求、响应解码和类型化错误。直接使用 Effect 原生 SDK;仅在边界处封装 Promise SDK。将配置和凭据保留在现有配置/提供方层中。
  • 保留 Alchemy 的资源/提供方集合和绑定契约。公共组合可以注册多个资源层,而无需通过一连串 barrel 文件重新导出每个内部辅助模块。
  • 遵守已配置的文件大小限制。如果强行拆分会让一个连贯的协调器分散开来,请记录有针对性的限制上调。

通过资源或提供方接口测试重构。根据实际情况,保留创建、重复部署、采用、更新和销毁的生命周期覆盖。使用真实提供方客户端,或通过 Layer 替换外部服务。不要仅为测试而提取或导出私有的选择/映射辅助函数;具有独立契约的公共纯函数可以保留针对性测试。

本地开发

当应用可以通过 Alchemy 运行时,使用 alchemy dev 作为默认的本地开发循环:

bun alchemy dev ./alchemy.run.ts

Alchemy 开发模式会将基础设施部署到真实云提供方,在本地运行受支持的应用代码,并在文件变更时热重载。对于 Cloudflare Workers,Worker 会在 workerd 中本地运行,同时由云代理在公共云端点和本地进程之间路由请求。

这对 webhook 开发很重要:外部服务需要公共 URL,而开发者需要本地代码、断点和热重载。可用时,优先使用 Alchemy 开发/预览 URL 作为 webhook 回调地址,然后将第三方 webhook 目标配置为该 URL,以供当前会话或预览阶段使用。

当应用有多个本地服务或需要固定的回调 URL 时,使用明确的开发端口:

export const Worker = Cloudflare.Worker("Worker", {
  main: "./src/worker.ts",
  dev: {
    port: 3000,
  },
});

开发模式规则:

  • 将 alchemy dev 创建的云资源视为真实资源,而非模拟器。
  • 在共享账户附近操作时,明确指定阶段/配置文件。
  • 在 stack 输出中返回本地/公共 URL,以便 Agent 测试实时路由。
  • 如有提供方的实际投递日志,请通过这些日志验证 webhook 流程。
  • 妥善停止开发进程;当开发/预览资源不再需要且由 stack 管理时,将其销毁。

阶段和配置文件规则

将阶段和配置文件视为部署约定的一部分:

  • 阶段会隔离状态和物理名称。默认值因开发者而异;在共享环境中使用显式的 --stage prod、--stage staging 或 --stage pr-123。
  • 配置文件用于选择凭据。首次部署可能会提示你进行交互式操作,并将凭据保存到 ~/.alchemy/profiles.json;非交互式 CI 必须在部署前准备好配置文件或提供商凭据。
  • 生产脚本应同时传入 --stage prod 和预期的 --profile。
  • 预览部署应根据 PR、分支或 issue ID 派生确定性阶段,并在不再需要时销毁该阶段。

常用命令:

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 生成名称,或使用与环境关联的确定性名称。

绑定和运行时依赖项

优先使用绑定,而不是手动通过环境变量传递已部署的标识符。绑定是附加到运行时资源的部署时数据,可确保函数/Worker 获得所需的确切基础设施依赖项。

对于 Cloudflare,直接将平台资源绑定到 Worker 或 Vite 应用:

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。

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

每项 Alchemy 能力都以一对层的形式提供:

  • Binding.Service — 运行时 SDK 包装器,通过 Function/Worker 上的 Effect 提供(打包到已部署的制品中)。
  • Binding.Policy — 部署时的 IAM/绑定附加项,通过 AWS.providers()() 在 Stack 上提供,绝不打包。

对于 Cloudflare,Worker 的 bindings: { ... } 字段会自动处理两端。对于 AWS,Service 层应添加到 Function 上,Policy 层则必须在堆栈级别启用。默认的 AWS.providers() 已启用常见的策略层;只有在编写或覆盖某项能力时,才使用 AWS.providers()(extraLayers)。

仅运行时方法中的 Alchemy.RuntimeContext

绑定会暴露一个带类型的可调用对象,其内部 Effect 需要 Alchemy.RuntimeContext。请将其视为一种带颜色的函数:

  • 外层 Effect(在函数初始化时设置)不需要 RuntimeContext。
  • 内层 Effect(实际的 SDK 调用)必须需要 RuntimeContext,且只能在已部署的 Function/Worker 内运行。

如果服务包装绑定时意外将 WorkerEnvironment / Lambda.FunctionEnvironment 泄漏到其接口中,该服务就会与云环境耦合。应在构建 Layer 时解析一次云环境服务并将其闭包捕获,而不要将它们作为消费者 Effect 的依赖项暴露。

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

Alchemy 堆栈和 Worker/Function 主体以 Effect 程序运行。不要在 Effect.gen 中使用原生异步操作或 Node 原语:

不要应使用
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:pathconst 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))让辅助函数本身返回 Effect

纯转换不需要 Effect 包装。在 Effect 中挂起环境读取和副作用;跨越外部边界时,对预期的抛出型故障进行分类。包装 CPU 计算并不会让该计算变得可中断。一旦驱动程序完成适配,就让内部操作继续使用 Effect,并且只在宿主或运行时要求的边界处运行它们。

这适用于堆栈主体、自定义资源辅助函数和测试。测试中任何文件/路径访问都必须使用 FileSystem.FileSystem / Path.Path。

部署/运行时测试的轮询规则:

  • 使用带有 until 谓词和 times: N 上限的 Effect.repeat 与 Schedule。
  • 不要编写 while (Date.now() < deadline) 循环——它们会忽略中断,并导致 vitest 超时。
// good — declarative, bounded, interruption-safe
const value =
  yield *
  fetchValue.pipe(
    Effect.repeat({
      schedule: Schedule.spaced("5 seconds"),
      until: (v) => v.ready,
      times: 36,
    }),
  );

Provider 生命周期测试

编写自定义 Alchemy provider/resource 时,使用 alchemy/Test/Vitest 添加 provider 风格的测试,而不只是对辅助函数进行单元测试。这些测试会在一个 Effect 程序中运行真正的 Alchemy 计划/应用引擎、私有临时状态、重复部署和销毁行为。

资源生命周期测试使用以下模式:

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 测试规则:

  • 在每个文件中使用 const { test } = Test.make({ providers: Namespace.providers() }) 配置一次 providers。
  • 集成测试优先使用真实 provider SDK/客户端断言。如果实时凭据或真实资源成本高昂/存在风险,可以使用模拟服务层,但仍须通过 test.provider、stack.deploy(...)、重复部署和 stack.destroy() 运行测试。
  • 在同一个 test.provider 主体中测试 create → update/noop/replace(视情况而定)→ destroy,以便 Alchemy 状态在各次部署间共享。
  • 使用传递给测试的临时堆栈;不要在 provider 测试中写入 .alchemy/ 或共享状态。
  • Provider 实现应在构建 provider 时闭包捕获服务(在返回生命周期方法之前执行 const client = yield* Client),与 Cloudflare providers 保持一致。除非在 read/diff/reconcile/delete 中明确提供该 Effect,否则不要将 yield* Client 要求留在这些方法内;test.provider 应能通过 “Service not found” 故障捕获此问题。
  • 需要凭据的实时 provider 测试,应通过与 alchemy deploy 相同的 AuthProvider/配置路径解析凭据(例如 env-method 凭据或 alchemy login 测试配置)。缺少凭据时跳过或限制运行测试;不要提交密钥。
  • 保留有用的公共契约测试,包括纯计算。不要要求为每个私有的选择/名称/状态/映射辅助函数编写单元测试;provider 测试应继续验证真实的生命周期语义。

构建和类型检查

提交涉及堆栈、自定义资源或运行时绑定的更改前,务必进行类型检查:

bun tsc -b

这会以项目引用模式运行工作区构建。CI 遇到类型错误时会失败,因此这项检查不容妥协。如果陈旧的构建产物或依赖项漂移导致无法解释的失败,请改用干净构建:

bun run build       # clean + tsc + build the alchemy package
bun build:clean     # full reset: clean . + bun i + build + download env

bun build:clean 会删除未跟踪的文件(保留 .env)、重新安装依赖项、重新构建并刷新环境文件。请将其视为恢复命令,而非常规命令。

密钥和配置

除非仓库明确拥有远程状态后端,且该文件专为版本控制而设计,否则不要提交提供商令牌、API 密钥、生成的配置档案或状态文件。

请遵循以下规则:

  • 部署凭据优先使用提供商配置档案或 CI 密钥。
  • 运行时密钥使用 Alchemy 密钥资源或提供商原生密钥资源。
  • 不要将非机密配置放入密钥资源。运行时配置应使用仓库中的具名配置文件,并通过 effect/Config 读取;在 Workers 上,应打包具名配置,并让部署过程只设置选择器变量(ADR-0014)。
  • 在 darkmatter 仓库中,应通过仓库现有的 SOPS/Himitsu/CI 密钥路径管理持久化密钥,而不是另创 .env 约定。
  • 说明每个部署目标所属的配置档案、账户、区域、地域或项目。

CI 部署

CI 应可确定且无需交互:

  1. 使用仓库锁定的包管理器命令安装依赖项。
  2. 部署前运行类型检查。
  3. 在无需浏览器提示的情况下通过提供商身份验证。
  4. 使用明确指定的堆栈路径、阶段和配置档案进行部署。
  5. 打印或捕获堆栈输出,以供冒烟测试使用。
  6. 工作流负责临时基础设施时,在分支或 PR 清理期间销毁预览阶段。

CI 命令示例:

bun install --frozen-lockfile
bun tsc -b
bun alchemy deploy ./alchemy.run.ts --stage "$ALCHEMY_STAGE" --profile "$ALCHEMY_PROFILE"

如果部署失败始于提供商身份验证、配置档案查找、状态锁定/状态持久化或缺少 CI 密钥,应先修复相应环节,再更改资源代码。

预览 URL 和 Webhook

公开预览是 Alchemy 工作流中的预期做法:

  • PR 部署应使用 --stage pr-<number>;如果仓库具有 GitHub 访问权限,还应将生成的应用 URL 发布回 PR。
  • 如果 Webhook 或协作者需要访问由本地代码提供服务的公开 URL,本地开发应使用 alchemy dev。
  • 预览 URL 应根据堆栈输出或提供商资源生成,而不是根据 PR 编号猜测。
  • 在可行时,Webhook 测试应使用真实的外部发送方,而不只是使用 curl。
  • PR 关闭或合并时,应清理并销毁预览阶段,同时注销临时 Webhook。

验证

如果请求涉及部署行为,务必验证实际部署的目标:

bun alchemy deploy ./alchemy.run.ts --stage "$STAGE" --profile "$PROFILE"
curl -fsS "$DEPLOYED_URL"

对于本地开发行为,请运行开发服务器;如果 Alchemy 同时输出本地 URL 和公开/代理 URL,则应分别访问:

bun alchemy dev ./alchemy.run.ts --stage "$STAGE" --profile "$PROFILE"
curl -fsS "$LOCAL_URL"
curl -fsS "$PUBLIC_PREVIEW_URL"

对于原生支持 Effect 的 Workers/函数,应优先使用已部署的测试实例或冒烟测试路由,而非纯本地断言。新建的 Workers、Lambda URL、队列、cron 和 DNS 通常需要有限次数的重试以等待传播;请使用 Effect.retry 或结合 Schedule 的 Effect.repeat,不要手动编写轮询循环。

审查清单

  • 如果仓库包含多个应用或软件包,需明确指定栈路径。
  • 除非仓库有明确理由,否则使用 Alchemy 作为部署/开发控制平面。
  • 栈名称、逻辑 ID、阶段名称和物理名称应稳定且确定。
  • 应根据环境有意选择 Provider 和状态存储。
  • Prod 部署需显式传入 --stage 和 --profile。
  • 对需要真实云资源、公开预览 URL 或 Webhook 测试的本地开发循环,配置 alchemy dev。
  • 在 Alchemy 支持绑定的情况下,运行时资源应使用绑定,而不是散落的字符串环境变量。
  • 不得提交密钥、在日志中回显密钥,或将密钥编码到栈输出中。
  • CI 部署应以非交互方式运行,并验证栈输出或在线端点。
  • 预览部署应有销毁途径。
  • Effect 代码应使用类型化错误、Layers 和 Schedule 进行重试;Promise SDK 应在边界处进行适配,纯转换则保持为普通 TypeScript。
  • Provider 操作负责完成、错误处理和清理。文件拆分不得掩盖实际复杂性;应保留已配置的限制,并记录有针对性的例外。

为 alchemy-effect 贡献代码

如果 darkmatter 仓库缺少某项 Provider 功能,通常应向上游提交 PR,而不是维护本地 fork。提交 PR 时有两条约定需要注意:

  • PR 标题使用 Conventional Commits 格式(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 中的详细约定。

参考资料

  • reference/upstream-concepts.md — 在应用/部署工作中应用 Alchemy v2 和 alchemy-effect 概念。
  • reference/examples.md — 将 alchemy-run/alchemy-effect/examples 目录对应到常见部署场景。
  • reference/provider-implementation.md — 有关上游 Provider 贡献的文件系统、协调器准则、能力形式、标签、运行时上下文、测试夹具、JSDoc/文档和教程标准。
  • reference/alchemy-effect/ — alchemy-run/alchemy-effect 的固定版本 Git 子模块,包含当前源码、示例、文档和上游 Agent 指南。

评论

支持 Markdown