关于 effect-v4
effect-v4 是面向使用 Effect v4 项目的编码技能,要求开发者依据已安装类型和对应版本源码核实 API,并提供编码约定、参考资料及只读检查器。
主要功能
- 01API 核验的源码权威顺序
- 02Effect v4 编码约定
- 03按任务分类的参考指南
- 04只读诊断检查器
- 05编译器补丁使用说明
适用场景
- 01编码前核实 Effect API
- 02实现服务、错误类型或 Schema
- 03使用附带诊断规则检查代码
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ klausborges/ skilltree --skill effect-v4安装后在 Claude Code 中输入/effect-v4确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlassets/oxlintrc.jsonsgconfig.ymlassets/.ast-grep/rules/no-effect-in-pure-core.ymlno-effectful-ternary.ymlno-layer-memory.ymlno-live-suffix.ymlno-manual-runtime-in-tests.ymlno-v3-effect-either.ymlno-v3-schema-refinements.ymlno-v3-service-tag.ymlno-v3-servicemap.ymlassets/.ast-grep/tests/no-effect-in-pure-core-test.ymlno-effectful-ternary-test.ymlno-layer-memory-test.ymlno-live-suffix-test.ymlno-manual-runtime-in-tests-test.ymlno-v3-effect-either-test.ymlno-v3-schema-refinements-test.ymlno-v3-service-tag-test.ymlno-v3-servicemap-test.ymlassets/.ast-grep/tests/__snapshots__/no-effect-in-pure-core-snapshot.ymlno-effectful-ternary-snapshot.ymlno-layer-memory-snapshot.ymlno-live-suffix-snapshot.ymlno-manual-runtime-in-tests-snapshot.ymlno-v3-effect-either-snapshot.ymlno-v3-schema-refinements-snapshot.ymlno-v3-service-tag-snapshot.ymlno-v3-servicemap-snapshot.yml详细介绍
Effect v4
Effect v4 在模型训练数据中的内容极少,而 effect.website
记录的是 v3——回忆起来似乎正确的 API,实际上并不正确。各个 Beta 版本并非单调演进:
其他 Beta 版本中的模式只能作为需要验证的依据,不能视为事实;甚至一手文档也落后于已发布的代码(migration/yieldable.md 仍记录了一个并不存在的 .asEffect())。如果这些内容与
源码有出入,以源码为准。
除非任务明确要求更改,否则应优先遵循已确立的项目约定。
源码规则
猜测前,按以下顺序检查这些内容,优先级从高到低:
- 项目已安装的
node_modules/effect类型定义——以此为准。 - 如果仓库中 vendored 了 Effect 源码,检查与项目版本对应标签的固定检出版本。
- 该检出版本中的一手文档:
LLMS.md、ai-docs/src/**、migration/**、packages/effect/SCHEMA.md。 - 这些参考文件。
编写 Effect 代码前,先说明项目固定使用的版本。
应阅读哪些参考文件
只阅读任务所需的内容。
| 任务 | 阅读 |
|---|---|
| 什么情况下需要服务或接缝、协调器与存储层的拆分、契约优先、设计审查 | references/architecture.md |
服务、层、依赖注入、在哪里调用 provide、Effect.fn | references/services-layers.md |
| 类型化错误、捕获、恢复、缺陷 | references/errors.md |
| 重试/重复策略、轮询、TTL 缓存 | references/schedule-cache.md |
| Schema、解析不可信输入、领域建模 | references/schema-boundaries.md |
测试、伪实现、TestClock、属性测试 | references/testing.md |
入口点、运行时、Config、CLI、可观测性 | references/runtime-config.md |
| 移植 v3 代码,或处理“应该”存在的 API | references/v3-to-v4.md |
| 模块所属的包或导入路径 | references/module-paths.md |
如果任务涉及多个方面,编辑前先阅读所有匹配的文件。
核心默认约定
| 情况 | 使用 |
|---|---|
| 定义服务 | class X extends Context.Service<X, Shape>()("pkg/dir/X") {} |
| 关联实现 | static readonly layer = Layer.effect(X, ...),返回 X.of({...}) |
| 为返回 Effect 的函数命名 | Effect.fn("X.method")(function* () {...}) |
向 Effect.fn 添加组合器 | 作为末尾参数传入——不要使用 .pipe |
| 定义错误 | class E extends Schema.TaggedErrorClass<E>()("E", {...}) {} |
| 引发错误 | return yield* E.make({...})——必须使用 return |
| 捕获 | Effect.catchTag / catchTags;使用 Effect.catch 处理整个通道 |
| 包装外部 cause | cause: Schema.Defect() |
| 解码不可信输入 | Schema.decodeUnknownEffect(S)(input) |
| 精炼 Schema | .check(Schema.isMinLength(1)) |
| 建模领域值 | Schema.Class;结构化形状使用 Schema.Struct |
| 读取配置 | 使用 Config.*,绝不使用 process.env |
| 当前时间/随机性 | 使用 Clock、DateTime、Random——绝不使用 Date.now、Math.random |
| 文件、路径、终端 | 使用核心 effect 中的 FileSystem、Path——不要使用 node:fs |
| 运行程序 | NodeRuntime.runMain / BunRuntime.runMain |
| 编写测试 | 使用 @effect/vitest 中的 assert,并通过 it.effect 编写 |
provide 层 | 在闭合自身依赖的层内部,以及进程根部各调用一次——其他位置均不允许 |
层的命名
layer(生产环境)· layerNoDeps(依赖保留在 RIn 中)· layerFake ·
layerTest · layerInProcess · layerInMemoryStore · layerFromEnv
绝不使用 Live 后缀。绝不使用通用名称 layerMemory。
强制检查预设
此技能附带一个只读检查器,用于检查以下规则。在审查前或进行大量修改后,请对项目运行它:
nu <path-to-this-skill>/scripts/check-effect.nu <project-dir> [source-paths...]
它会使用 assets/ 中的预设运行 effect-tsgo 诊断、oxlint 和 ast-grep,绝不会写入目标项目;如果目标项目缺少某项检查所需的工具,则会将该检查标记为跳过。将这些诊断永久接入项目的 tsconfig/编辑器属于项目自身的工作:npx @effect/tsgo setup。
assets/tsconfig-compiler-options.json 是诊断所依据的严格性基线;请同时扩展 tsconfig-language-service.json。没有 strict 就不会启用 noImplicitAny,而 effectFnImplicitAny 会静默地不执行任何操作。
effect-tsgo patch 并非幂等——它会就地修补已安装的 tsc 二进制文件。请做好防护:修补后,tsc --version 会显示 +effect-tsgo.<version> 后缀;因此仅当该后缀不存在或与已安装的 @effect/tsgo 版本不一致时才修补。直接使用 "prepare": "effect-tsgo patch" 会再次修补已修补过的编译器。
适配器例外
适配器文件是厂商实际情况落地之处,少数诊断必须在这些文件中让步。请以能解决问题的最小范围屏蔽规则:
- 在文件顶部使用
// @effect-diagnostics <rule>:off——这是首选方式。任何通过--lspconfig注入配置的运行器都会丢弃项目本地插件的overrides条目(因为它会替换项目插件配置);而这个指令在两种路径中都能保留。参见references/runtime-config.md。 - 仅针对
leakingRequirements,语言服务提供两种 JSDoc 例外:在某个依赖的接口声明上标注@effect-leakable-service,表示该依赖需要透传;或在泄漏该依赖的服务上标注@effect-expect-leaking <Type>。
每项例外都意味着你确认厂商边界确实存在。如果某个文件需要多项例外,说明边界划分错了位置。
禁止事项
- 不要在
Effect.gen内使用try/catch——它无法识别 Effect 失败。请使用Effect.result并进行分支处理。 - 不要使用
async/await或裸 Promise;请通过Effect.tryPromise跨越边界。 - 不要在库代码中调用
Effect.runPromise/runSync/runFork。 - 不要编写函数体唯一内容是返回
Effect.gen的普通函数——请使用Effect.fn。 - 不要使用
as any、as unknown as、非空断言!或未经检查的类型断言来绕过 Effect 类型检查。请改用分支处理、解析或类型细化。 - 不要使用
JSON.parse(x) as T——请通过 schema 解码。 - 不要手写
isString这类类型守卫;请使用Predicate。 - 不要手写重试/轮询循环或 TTL 缓存;请使用
Schedule和Cache。 - 不要在配置、状态、协调或恢复路径上使用
Effect.orDie。 - 不要导入 v3 包:
@effect/platform、@effect/schema、@effect/cli、@effect/rpc、@effect/cluster、@effect/experimental。 - 不要使用
Context.Tag、Context.GenericTag、Effect.Tag或任何名为ServiceMap的内容——这些都是 v4 之前或中间 beta 阶段的名称。 - 不要将
Layer.mergeAll或provideMerge当作让代码通过编译的工具。