关于 darkmatter-ts-toolchain
为 Darkmatter 仓库规定 TypeScript 开发约定与首选技术栈,涵盖工具、架构、测试、数据访问、部署和发布流程。
主要功能
- 01仅使用 Bun 管理包
- 02使用 TypeScript 编写运维脚本
- 03Effect 与类型化 RPC 技术栈
- 04优先采用 Postgres 的数据规范
- 05使用 Alchemy 部署
- 06按序执行类型检查、测试和 lint
适用场景
- 01建立新的 TypeScript 仓库
- 02使仓库符合 Darkmatter 约定
- 03提交 PR 前验证更改
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ darkmatter/ skills --skill darkmatter-ts-toolchain安装后在 Claude Code 中输入/darkmatter-ts-toolchain确认已加载。
详细介绍
Darkmatter TypeScript 工具链
适用于全组织 TS 仓库(platform、nixmac-web 等)的约定。以 darkmatter/template 目录中的参考 monorepo 为准,统一新仓库的规范。此技术栈经过审慎选择;换成熟悉的默认选项(npm、jest、wrangler、将 D1 作为默认数据库)会形成第二套规范,并导致 CI 失败。
应用 codebase-design,确保可读性和模块边界。工具链检查旨在支持内聚的实现和精简的公共接口;辅助函数是否合适,不能仅由函数长度决定。
运维脚本——使用 TypeScript,而非 bash
如果仓库仅使用 TypeScript,实用工具和 CI 脚本也应使用 TypeScript
(scripts/*.ts、bun scripts/ci.ts)。不要添加 .sh 文件。参见
ADR-0012。
包管理——仅使用 Bun
- 安装:
bun install;CI 使用bun install --frozen-lockfile。如果 CI 因“lockfile had changes, but lockfile is frozen”而失败,说明 lockfile 与某个package.json不一致——运行本地bun install并提交bun.lock即可修复;绝不要为了“修复”而删除 lockfile。 - 使用
bun run <script>运行脚本;使用bun x <tool>执行工具。 - Monorepo 使用 Turbo + workspaces(
@repo/*包)。将共享代码添加到 workspace 包中,不要通过相对路径../../在应用之间导入。 - 共享依赖版本统一定义在根目录的
workspaces.catalog中;包清单使用catalog:或workspace:*,不要重复填写版本。
推荐的技术栈默认选项
除非目标仓库有文档记录的例外情况,否则使用以下默认选项:
| 领域 | 默认选项 |
|---|---|
| 运行时/包管理器 | Bun、workspace catalogs;需要 Node 时使用 Node >= 24 |
| Effect | Effect 4、effect-solutions、@effect/tsgo、@effect/vitest、@effect/platform-bun |
| Agent | 优先使用 effect/unstable/ai/effect-agent API,而非手写 Agent 循环或重复定义约定 |
| 类型化 RPC | [email protected],以及版本为 >=1.13 的 @orpc/server、@orpc/client、@orpc/contract 和 @orpc/shared;加载 effect-typescript 以了解使用规则 |
| 数据 | 优先使用 Postgres。对于查询密集型 TypeScript,优先选择 Kysely + pg;对于原生使用 Effect 的数据库服务,选择 Effect SQL Postgres。不要将 D1 或 sqlite 选作默认持久化层。 |
| 部署 | 由 Alchemy 管理的基础设施,通常根据应用选择 Cloudflare Workers 或 AWS |
| Web/UI | Vite 或 vite-plus、Vitest、React 19、Tailwind v4、shadcn/Radix,以及仓库的共享 UI 包 |
| 代码检查/格式化 | 使用带 Effect/tsgo 规则的 oxlint,使用 oxfmt 格式化 |
按此顺序验证
bun run typecheck # tsgo -p tsconfig.json (NOT tsc)
bun run test # vitest
bun run lint # oxlint
bun run fmt:check # oxfmt
首先运行覆盖变更范围的最小目标(单个测试文件、单个包),交接前再运行整个仓库的检查。三项检查都必须在 main 上通过;合并队列会强制执行必需的检查——即使你的凭据在技术上能够绕过保护,也应优先创建 PR,而非直接推送。
测试文件应命名为 <file>.test.ts,并与其覆盖的源文件放在一起;vitest 会在任何位置发现这些文件(include: ["**/*.test.ts"])。不要在每个包中添加 test/ 或 tests/ 目录。仓库根目录的 tests/ 仅用于会启动真实服务或跨越多个包的端到端测试。
有实际 I/O 时使用 Effect
涉及实际 I/O(网络、数据库、队列、重试)的代码使用 Effect — 服务、
Layer、类型化错误,以及用于配置的 Config(命名配置文件,以
环境变量和标志作为覆盖项:ADR-0014)。加载 effect-typescript 技能
以了解相关模式。简单的胶水代码可以使用普通的 async/await;不要为了形式而包装单个 fetch。
在适配器边界将基于 Promise 的驱动程序转换为 Effect,并让内部操作保持在 Effect 中。负责持久化、故障处理和清理,直到操作完成;不要在工作仍未得到观察时就返回成功。
数据库查询和解码应放在负责它们的适配器中。除非项目特定决策另有规定,新的应用数据应从 Postgres 开始。如果服务查询繁重,使用 Kysely 和
pg;如果仓库已将持久化组织为 Effect 服务和 Layer,则使用 Effect SQL Postgres。D1/sqlite 仅适用于范围狭窄的平台本地状态、演示或明确的边缘约束;不能仅仅因为它们易于配置就将其作为默认选项。适用时使用现有的类型化查询工具;也允许使用带行验证和行为查询验证的参数化 SQL。行泛型不会验证数据,而可读性改进也不要求迁移 ORM。参见
ADR-0015。
部署 — 使用 Alchemy,绝不使用 wrangler
- 基础设施以代码形式写在
alchemy.run.ts中;禁止使用wrangler.toml。 - 部署:
STAGE=prod bun run deploy(每个应用单独部署;查看应用的 README/运行配置,了解所需的环境变量)。密钥在部署时通过himitsu read <path>获取,配置使用 SOPS — 绝不硬编码。 - Alchemy 的配置架构要求在环境变量中显式设置
SOPS_AGE_KEY;它不会回退到~/.config/sops/age/keys.txt:SOPS_AGE_KEY=$(grep '^AGE-SECRET-KEY-' ~/.config/sops/age/keys.txt | head -1)。 - Vite 应用:必须先构建
client,再构建ssr(hydration manifest)。
发布
Changesets 是发布的唯一事实来源:面向用户的更改须附带
.changeset/*.md;版本升级和变更日志由工具生成,不要手动编辑。
容易让新人意外的风格规则
- 实用的辅助函数: 当命名能隐藏一个重要决策,或能促进有用的复用时,提取为辅助函数。纯转发包装器应内联;简短或仅使用一次的辅助函数也可能值得保留。检查现有 lint 诊断,并修复不必要的间接层,而不是悄悄禁用规则。
- 文件限制: 保留已配置的限制;新增文件时,使用 300 行非空、非注释代码作为标准。按职责拆分;如果模块内聚,则记录合理的限制提高或例外。不要为了满足计数器而制造转发文件。
- 遵循 Conventional Commits,主题不超过 50 个字符;仅在原因不明显时添加正文。
- 在问题根源处修复问题,并移除过时的兼容路径。保留明确的公共重新导出以及用于转换真实外部 API 的适配器;移除不提供有用契约的内部转发链。