opencode-effect-enforcer 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -10
- package/docs/effect-4.0.0-rc.112.md +316 -0
- package/guidance/effect-first-development.md +30 -17
- package/guidance/progressive-disclosure-guidance.md +13 -0
- package/package.json +4 -3
- package/patterns/avoid-direct-tag-checks.md +8 -2
- package/patterns/avoid-react-hooks.md +18 -37
- package/patterns/effect-run-in-body.md +1 -1
- package/patterns/require-effect-concurrency.md +11 -0
- package/patterns/use-console-service.md +6 -1
- package/skills/effect-ai-language-model/SKILL.md +10 -16
- package/skills/effect-ai-prompt/SKILL.md +36 -2
- package/skills/effect-ai-provider/SKILL.md +13 -0
- package/skills/effect-ai-streaming/SKILL.md +81 -108
- package/skills/effect-ai-tool/SKILL.md +50 -87
- package/skills/effect-atom-rpc/SKILL.md +9 -2
- package/skills/effect-atom-state/SKILL.md +5 -0
- package/skills/effect-cache/SKILL.md +32 -0
- package/skills/effect-cli/SKILL.md +22 -3
- package/skills/effect-concurrency-testing/SKILL.md +7 -9
- package/skills/effect-domain-modeling/SKILL.md +208 -1169
- package/skills/effect-domain-predicates/SKILL.md +5 -6
- package/skills/effect-error-handling/SKILL.md +5 -4
- package/skills/effect-http-api/SKILL.md +12 -1
- package/skills/effect-http-client/SKILL.md +1 -1
- package/skills/effect-http-server/SKILL.md +14 -3
- package/skills/effect-layer-design/SKILL.md +22 -56
- package/skills/effect-mcp-server/SKILL.md +1 -1
- package/skills/effect-pattern-matching/SKILL.md +44 -11
- package/skills/effect-platform-abstraction/SKILL.md +1 -1
- package/skills/effect-platform-layers/SKILL.md +1 -1
- package/skills/effect-rpc-api/SKILL.md +8 -1
- package/skills/effect-rpc-client/SKILL.md +20 -6
- package/skills/effect-rpc-cluster/SKILL.md +44 -14
- package/skills/effect-rpc-server/SKILL.md +32 -5
- package/skills/effect-scheduling/SKILL.md +1 -1
- package/skills/effect-schema-composition/SKILL.md +69 -15
- package/skills/effect-schema-v4/SKILL.md +43 -1
- package/skills/effect-scope/SKILL.md +30 -0
- package/skills/effect-service-implementation/SKILL.md +10 -4
- package/skills/effect-socket/SKILL.md +5 -5
- package/skills/effect-sql/SKILL.md +22 -0
- package/skills/effect-stream/SKILL.md +32 -1
- package/skills/effect-testing/SKILL.md +39 -31
- package/skills/effect-workflow/SKILL.md +6 -0
- package/src/enforcer.ts +1 -1
- package/src/index.ts +1 -1
- package/src/skills.ts +4 -4
- package/patterns/vm-in-wrong-file.md +0 -51
- package/skills/effect-react-vm/SKILL.md +0 -675
package/README.md
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
An opinionated OpenCode V2 plugin that gives coding agents current Effect v4
|
|
7
7
|
guidance and reviews their TypeScript edits for common Effect anti-patterns.
|
|
8
8
|
|
|
9
|
+
**Supported Effect version: `4.0.0-rc.112`.** See the
|
|
10
|
+
[full rc.111 → rc.112 release notes and audit](docs/effect-4.0.0-rc.112.md)
|
|
11
|
+
for upstream changes, companion-package notes, and repository migration details.
|
|
12
|
+
|
|
9
13
|
## Install
|
|
10
14
|
|
|
11
15
|
Add the npm package to your global or project `opencode.jsonc`:
|
|
@@ -21,7 +25,7 @@ That is the complete installation. OpenCode resolves published package entries
|
|
|
21
25
|
for you; there is no separate `npm install` step. Use the global config at
|
|
22
26
|
`~/.config/opencode/opencode.jsonc` to enable it everywhere, or a project config
|
|
23
27
|
to enable it only for that project. You can also pin a release, for example
|
|
24
|
-
`"opencode-effect-enforcer@0.2.
|
|
28
|
+
`"opencode-effect-enforcer@0.2.5"`.
|
|
25
29
|
|
|
26
30
|
Start a new OpenCode session, then verify the plugin if needed:
|
|
27
31
|
|
|
@@ -57,12 +61,12 @@ Look for `opencode.effect-enforcer` with `state.status` set to `active`.
|
|
|
57
61
|
|
|
58
62
|
## What You Get
|
|
59
63
|
|
|
60
|
-
- **
|
|
64
|
+
- **53 focused skills** registered in OpenCode's native skill catalog, covering
|
|
61
65
|
Effect's core, platform, AI, RPC, SQL, frontend, and testing APIs.
|
|
62
66
|
- **4 guidance documents** injected into model context so Effect-first
|
|
63
67
|
boundaries, domain modeling, dependency design, and skill routing stay
|
|
64
68
|
visible while the agent works.
|
|
65
|
-
- **
|
|
69
|
+
- **45 tested patterns** run after successful `write`, `edit`, `patch`, and
|
|
66
70
|
`apply_patch` calls, reporting only violations in newly added text.
|
|
67
71
|
- **Advisory remediation** appended to the completed tool result so the model
|
|
68
72
|
reviews and fixes valid findings without a detector blocking the underlying
|
|
@@ -81,7 +85,7 @@ available.
|
|
|
81
85
|
- [Effect, and the Near-Inexpressible Majesty of Layers](guidance/post__effect-and-the-near-inexpressible-majesty-of-layers.md): Explains services, Layers, typed dependencies, and testable implementations.
|
|
82
86
|
- [Parse, don't validate](guidance/post__parse-dont-validate.md): Shows how refined types preserve validation knowledge and make illegal states unrepresentable.
|
|
83
87
|
|
|
84
|
-
### Skills (
|
|
88
|
+
### Skills (53)
|
|
85
89
|
|
|
86
90
|
#### Modeling And Core APIs
|
|
87
91
|
|
|
@@ -147,7 +151,6 @@ available.
|
|
|
147
151
|
- [`effect-atom-state`](skills/effect-atom-state/SKILL.md): Manage reactive React state with Effect Atom.
|
|
148
152
|
- [`effect-atom-rpc`](skills/effect-atom-rpc/SKILL.md): Build cached, invalidating, SSR-aware RPC atoms for React clients.
|
|
149
153
|
- [`effect-react-composition`](skills/effect-react-composition/SKILL.md): Compose React components around explicit Effect Atom state and behavior.
|
|
150
|
-
- [`effect-react-vm`](skills/effect-react-vm/SKILL.md): Implement testable View Models that bridge Effect services and React views.
|
|
151
154
|
|
|
152
155
|
#### Configuration, Operations, And Testing
|
|
153
156
|
|
|
@@ -158,7 +161,7 @@ available.
|
|
|
158
161
|
- [`effect-concurrency-testing`](skills/effect-concurrency-testing/SKILL.md): Test fibers, PubSub, Deferred, Latch, SubscriptionRef, and concurrent streams.
|
|
159
162
|
- [`effect-incremental-migration`](skills/effect-incremental-migration/SKILL.md): Migrate Promise-based modules incrementally while preserving required compatibility.
|
|
160
163
|
|
|
161
|
-
### Patterns (
|
|
164
|
+
### Patterns (45)
|
|
162
165
|
|
|
163
166
|
#### Types, Modeling, And Collections
|
|
164
167
|
|
|
@@ -217,8 +220,7 @@ available.
|
|
|
217
220
|
|
|
218
221
|
#### React And Testing Conventions
|
|
219
222
|
|
|
220
|
-
- [`avoid-react-hooks`](patterns/avoid-react-hooks.md):
|
|
221
|
-
- [`vm-in-wrong-file`](patterns/vm-in-wrong-file.md): Enforces dedicated `.vm.ts` files for View Model definitions.
|
|
223
|
+
- [`avoid-react-hooks`](patterns/avoid-react-hooks.md): Reviews React state and effects for Effect Atom alternatives.
|
|
222
224
|
- [`avoid-expect-in-if`](patterns/avoid-expect-in-if.md): Prevents conditional assertions that allow tests to pass without checking behavior.
|
|
223
225
|
|
|
224
226
|
## Per-Agent Opt-Out
|
|
@@ -283,8 +285,8 @@ The release tag must exactly match the package version, such as `v0.2.0` for
|
|
|
283
285
|
`"version": "0.2.0"`.
|
|
284
286
|
|
|
285
287
|
There is no generated `dist` tree. OpenCode imports the TypeScript entrypoint,
|
|
286
|
-
and npm publishes the authoritative `src/`, `skills/`, `guidance/`,
|
|
287
|
-
`
|
|
288
|
+
and npm publishes the authoritative `src/`, `skills/`, `guidance/`, `patterns/`,
|
|
289
|
+
and `docs/` directories directly.
|
|
288
290
|
|
|
289
291
|
## Credits
|
|
290
292
|
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# Effect 4.0.0-rc.111 → 4.0.0-rc.112
|
|
2
|
+
|
|
3
|
+
## Version and provenance
|
|
4
|
+
|
|
5
|
+
- Previous direct dependency: `effect@4.0.0-rc.111`.
|
|
6
|
+
- Target: `effect@4.0.0-rc.112`, the npm `rc` dist-tag checked on 2026-09-06.
|
|
7
|
+
- Rechecked on 2026-09-07: `rc` remains rc.112; `latest` is the separate v3 line (`3.22.1`).
|
|
8
|
+
- Exact source: [`effect@4.0.0-rc.112`](https://github.com/Effect-TS/effect/tree/effect%404.0.0-rc.112), release commit `2600f62f`.
|
|
9
|
+
- [Complete source comparison](https://github.com/Effect-TS/effect/compare/effect%404.0.0-rc.111...effect%404.0.0-rc.112).
|
|
10
|
+
- [Upstream Effect changelog](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/effect/CHANGELOG.md).
|
|
11
|
+
|
|
12
|
+
The interval is **exclusive of rc.111 and inclusive of rc.112**: one release.
|
|
13
|
+
The notes below retain every upstream Effect release entry and every additional
|
|
14
|
+
companion-package change. Dependency-only companion releases are recorded in the
|
|
15
|
+
package table. Earlier beta/RC corrections found during this repository's audit
|
|
16
|
+
are separate from the upstream release notes.
|
|
17
|
+
|
|
18
|
+
## Full upstream Effect release notes
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- [#7390](https://github.com/Effect-TS/effect/pull/7390) [`a5f78d3`](https://github.com/Effect-TS/effect/commit/a5f78d3fcbaa792d49e80d103ab438e0b50812fd) Thanks @tim-smart! - Make RPC serialization schema-aware.
|
|
23
|
+
|
|
24
|
+
Add `codecFor` to RPC serialization and client/server protocols so RPC and cluster
|
|
25
|
+
network payloads use the transport's schema codec. Framing, cluster storage, and
|
|
26
|
+
existing built-in wire formats remain unchanged.
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- [#7411](https://github.com/Effect-TS/effect/pull/7411) [`20cb4f2`](https://github.com/Effect-TS/effect/commit/20cb4f260e45d37fa417c292c57be015314efe16) Thanks @altendky! - Add `RcMap.getOption` and `LayerMap.contextEffectOption` for atomically retaining
|
|
31
|
+
entries only when they are already cached.
|
|
32
|
+
|
|
33
|
+
- [#7437](https://github.com/Effect-TS/effect/pull/7437) [`44675cb`](https://github.com/Effect-TS/effect/commit/44675cbce3dabfb85c68a3703b5de525768336fb) Thanks @wmaurer! - Add an optional `description` to `AiError.AuthenticationError`, rendered after the kind-based suggestion, and pass the provider's own error text through it on HTTP 401 and 403, so authentication failures report what actually went wrong instead of only a category.
|
|
34
|
+
|
|
35
|
+
- [#7393](https://github.com/Effect-TS/effect/pull/7393) [`b6bf5e1`](https://github.com/Effect-TS/effect/commit/b6bf5e14492643076454131148f97cde24ad5306) Thanks @wmaurer! - Fix `Prompt.autoComplete` swallowing `j` and `k` while typing a filter query.
|
|
36
|
+
|
|
37
|
+
- [#7401](https://github.com/Effect-TS/effect/pull/7401) [`0b9f780`](https://github.com/Effect-TS/effect/commit/0b9f780ff28b71042241791a9e8bcb5b631be2bd) Thanks @gjermundgaraba! - Retry transient EventLog remote write failures so pending local entries are synchronized after recovery.
|
|
38
|
+
|
|
39
|
+
- [#7384](https://github.com/Effect-TS/effect/pull/7384) [`150e92c`](https://github.com/Effect-TS/effect/commit/150e92c4169c245e701da02575eef0b69c3ecd64) Thanks @tim-smart! - Improve synchronous Schema decode and encode performance by preserving completed parser exits and using a direct loop for common struct parsers.
|
|
40
|
+
|
|
41
|
+
- [#7386](https://github.com/Effect-TS/effect/pull/7386) [`6740db2`](https://github.com/Effect-TS/effect/commit/6740db247ed20cb85da43c9f48ade8fecfd8c1ae) Thanks @tim-smart! - Add `Schema.TaggedUnion.matchOrElse` for partial case matching with a typed fallback.
|
|
42
|
+
|
|
43
|
+
- [#7389](https://github.com/Effect-TS/effect/pull/7389) [`d57bba1`](https://github.com/Effect-TS/effect/commit/d57bba1486fa60971b6e0bf7459a329cfd5acdc4) Thanks @tim-smart! - Improve `SchemaError` construction performance by skipping stack frame capture.
|
|
44
|
+
|
|
45
|
+
- [#7402](https://github.com/Effect-TS/effect/pull/7402) [`be75d5e`](https://github.com/Effect-TS/effect/commit/be75d5ea6e516c25e3affec25806d31c2b203bc4) Thanks @tim-smart! - Improve Pool acquisition and release performance. Pool now tracks usage
|
|
46
|
+
incrementally, stores available items in an intrusive FIFO, and skips work for
|
|
47
|
+
fixed and empty pools. This changes the public `Pool.State` and `Pool.PoolItem`
|
|
48
|
+
interfaces.
|
|
49
|
+
|
|
50
|
+
- [#7402](https://github.com/Effect-TS/effect/pull/7402) [`be75d5e`](https://github.com/Effect-TS/effect/commit/be75d5ea6e516c25e3affec25806d31c2b203bc4) Thanks @tim-smart! - Add `Pool.use`, which borrows an item while an effect runs and returns it on any
|
|
51
|
+
exit. Unlike `Effect.scoped(Pool.get(pool))`, it does not require a `Scope`.
|
|
52
|
+
|
|
53
|
+
- [#7402](https://github.com/Effect-TS/effect/pull/7402) [`be75d5e`](https://github.com/Effect-TS/effect/commit/be75d5ea6e516c25e3affec25806d31c2b203bc4) Thanks @tim-smart! - Reduce scoped resource acquisition allocations by storing the first Scope
|
|
54
|
+
finalizer inline and allocating a Map only when a second is added. This changes
|
|
55
|
+
the public `Scope.State.Open` interface.
|
|
56
|
+
|
|
57
|
+
- [#7424](https://github.com/Effect-TS/effect/pull/7424) [`02a5146`](https://github.com/Effect-TS/effect/commit/02a5146d6933c7f6052553550bce5658225e4100) Thanks @tim-smart! - Skip remote event journal write callbacks when there are no uncommitted entries and return an `Option` indicating
|
|
58
|
+
whether the callback ran.
|
|
59
|
+
|
|
60
|
+
- [#7312](https://github.com/Effect-TS/effect/pull/7312) [`15272a6`](https://github.com/Effect-TS/effect/commit/15272a66adf02501e7747761e2a3c41bff67bb46) Thanks @godu! - Fix shell completion for choice values containing quotes, spaces, word-break characters, Unicode, and shell metacharacters.
|
|
61
|
+
|
|
62
|
+
Bash now quotes candidates for readline, keeps choice values intact when reconstructing words, and supports Bash 3.2 without associative arrays. Fish and Zsh escape choices across both parsing rounds, and Fish hides value-taking flags after use without suppressing their value completions.
|
|
63
|
+
|
|
64
|
+
- [#7395](https://github.com/Effect-TS/effect/pull/7395) [`436f10d`](https://github.com/Effect-TS/effect/commit/436f10d1efccec308426532ff3f88df9a96434f3) Thanks @wmaurer! - Fix `Prompt.file` swallowing `j` and `k` while typing a filter query.
|
|
65
|
+
|
|
66
|
+
- [#7406](https://github.com/Effect-TS/effect/pull/7406) [`058fb15`](https://github.com/Effect-TS/effect/commit/058fb15647fa01ad771277bd368783fcf5f262e8) Thanks @gcanti! - Preserve finite string and unique symbol key unions in the return types of `Array.groupBy` and `Iterable.groupBy`.
|
|
67
|
+
|
|
68
|
+
Previously, grouping widened finite keys to `string` or `symbol`, which lost known-key autocomplete and allowed access to keys that the selector could never produce. The new `Record.ReadonlyRecord.GroupByResult` keeps finite keys and marks their properties optional because any group may be absent at runtime, while open `string` and `symbol` selectors retain their existing record index signatures.
|
|
69
|
+
|
|
70
|
+
- [#7415](https://github.com/Effect-TS/effect/pull/7415) [`4d89bb8`](https://github.com/Effect-TS/effect/commit/4d89bb8ffb4cf567a1d11072246b6161ce638712) Thanks @gcanti! - Reject unsupported JSON Schema references instead of resolving them by their final path segment, closes [#7409](https://github.com/Effect-TS/effect/issues/7409).
|
|
71
|
+
|
|
72
|
+
- [#7420](https://github.com/Effect-TS/effect/pull/7420) [`480fb15`](https://github.com/Effect-TS/effect/commit/480fb156590785cf98f67bdec4fc282a608e2d87) Thanks @gcanti! - Make JSON Schema dialect conversions preserve custom keywords, translate conditionals, contains, dependencies, identifiers, and tuples where representable, relocate local references after structural changes, and throw instead of silently changing unsupported constraints.
|
|
73
|
+
|
|
74
|
+
- [#7417](https://github.com/Effect-TS/effect/pull/7417) [`f77ec19`](https://github.com/Effect-TS/effect/commit/f77ec19cff1cbbeeae928e3bd0ece00a7d22bab8) Thanks @Makisuo! - Defer built-in OpenAPI response generation until the documentation route is first requested, retrying after generation defects.
|
|
75
|
+
|
|
76
|
+
- [#7388](https://github.com/Effect-TS/effect/pull/7388) [`925b82a`](https://github.com/Effect-TS/effect/commit/925b82a81f59a4d459b488621030f24ba99d6a27) Thanks @ebramanti! - Fix MCP initialize rejected over the protocol version header
|
|
77
|
+
|
|
78
|
+
`McpServer.layerHttp` validated the `MCP-Protocol-Version` header on every POST, including
|
|
79
|
+
the `initialize` request. That header reports the version negotiated by an earlier
|
|
80
|
+
`initialize`, so on a fresh connection a client can only send its own default. Whenever
|
|
81
|
+
that default was not among the server's registered protocols the `initialize` returned
|
|
82
|
+
`400` and never reached version negotiation, even when the body offered a version the
|
|
83
|
+
server supports.
|
|
84
|
+
|
|
85
|
+
The header check now applies only to requests after initialization, where the
|
|
86
|
+
specification requires it. An `initialize` negotiates from the version offered in its
|
|
87
|
+
body, through the protocol registry, and reports the selected version in the response.
|
|
88
|
+
|
|
89
|
+
- [#7403](https://github.com/Effect-TS/effect/pull/7403) [`7455246`](https://github.com/Effect-TS/effect/commit/7455246f352385f5cbbdd8299555265ee289490e) Thanks @hsyntax! - Add support for explicit cache breakpoints on the OpenAI responses API for GPT-5.6-or-later.
|
|
90
|
+
|
|
91
|
+
- [#7442](https://github.com/Effect-TS/effect/pull/7442) [`118124d`](https://github.com/Effect-TS/effect/commit/118124d913d0a02ac5c1f7799a39bd90031769d9) Thanks @tim-smart! - Redact password prompt values from CLI wizard command output.
|
|
92
|
+
|
|
93
|
+
- [#7366](https://github.com/Effect-TS/effect/pull/7366) [`0dd7825`](https://github.com/Effect-TS/effect/commit/0dd7825e4da4d3a00fa9bd410a1d55f3d4874d07) Thanks @tim-smart! - Add `SchemaBinary`, a compact schema-derived codec with streaming, optional fingerprints and dictionaries, and RPC support.
|
|
94
|
+
|
|
95
|
+
- [#7404](https://github.com/Effect-TS/effect/pull/7404) [`b722eca`](https://github.com/Effect-TS/effect/commit/b722eca6d283a88970ad0efba0b4e921915eca78) Thanks @gcanti! - Add a public `StandardSchema` module containing the vendored Standard Schema V1 specification and remove the direct dependency on `@standard-schema/spec`.
|
|
96
|
+
|
|
97
|
+
- [#7436](https://github.com/Effect-TS/effect/pull/7436) [`811d579`](https://github.com/Effect-TS/effect/commit/811d579c432856a9e3fc05b517fd8e924cbf991a) Thanks @gcanti! - Fix JSON Schema imports:
|
|
98
|
+
|
|
99
|
+
- Type-specific keywords no longer imply a type. For example, `minLength` validates strings without rejecting
|
|
100
|
+
non-string values.
|
|
101
|
+
- Constraints next to `const`, `enum`, and `$ref` are now applied instead of being ignored.
|
|
102
|
+
- Disjoint and linear union intersections are imported without a Cartesian expansion. Other overlapping union
|
|
103
|
+
intersections fail with an explicit error.
|
|
104
|
+
- References to definitions without unions no longer make otherwise linear intersections fail.
|
|
105
|
+
- Imported `oneOf` schemas remain `oneOf` when exported again.
|
|
106
|
+
- `minItems` is preserved when `prefixItems` does not fully enforce it.
|
|
107
|
+
|
|
108
|
+
- [#7382](https://github.com/Effect-TS/effect/pull/7382) [`043b587`](https://github.com/Effect-TS/effect/commit/043b587e6e93f6624bf974bcd7ed976eaa17f0e1) Thanks @tim-smart! - Replace per-prompt prefix options with a context-based theme for CLI prompt symbols and colors.
|
|
109
|
+
|
|
110
|
+
- [#7373](https://github.com/Effect-TS/effect/pull/7373) [`8583727`](https://github.com/Effect-TS/effect/commit/85837274fa929a921985464585513a68c261e365) Thanks @ChubbyDuck! - Drop unreachable concurrency guard in iteratorEagerImpl
|
|
111
|
+
|
|
112
|
+
- [#7429](https://github.com/Effect-TS/effect/pull/7429) [`d9d2cfc`](https://github.com/Effect-TS/effect/commit/d9d2cfcb732754001b7323cf8afaccc48539bb74) Thanks @gcanti! - Reject unsupported JSON Schema validation keywords and object or array `const` / `enum` values during import instead of
|
|
113
|
+
silently weakening validation.
|
|
114
|
+
|
|
115
|
+
- [#7428](https://github.com/Effect-TS/effect/pull/7428) [`5c4b7a0`](https://github.com/Effect-TS/effect/commit/5c4b7a0b17931cd1538c6595a54b21ffe9c1e906) Thanks @ebramanti! - Return workflow execution IDs from generated RPC and HTTP discard endpoints.
|
|
116
|
+
|
|
117
|
+
## Additional companion-package release notes
|
|
118
|
+
|
|
119
|
+
The four AI provider packages repeat #7437 above; `@effect/ai-openai` also
|
|
120
|
+
repeats #7403. The remaining non-dependency entries are reproduced here:
|
|
121
|
+
|
|
122
|
+
- **`@effect/atom-react`** — [#7435](https://github.com/Effect-TS/effect/pull/7435) [`4148e21`](https://github.com/Effect-TS/effect/commit/4148e21eb5f86ef37e07086ec9f3cc7e55d24e90) Thanks @mattrobrob! - Relax react peer dependency range
|
|
123
|
+
- **`@effect/platform-bun`** — [#7408](https://github.com/Effect-TS/effect/pull/7408) [`e1fb57f`](https://github.com/Effect-TS/effect/commit/e1fb57ffbf3cef2dd3016bacd26a4166a52618b7) Thanks @phibr0! - Compress outgoing Bun WebSocket messages when per-message deflate is configured and negotiated. Messages
|
|
124
|
+
smaller than 1 KiB are left uncompressed, matching the default threshold used by Node's `ws` server.
|
|
125
|
+
The threshold is configurable via the new `websocket.compressionThreshold` server option.
|
|
126
|
+
- **`@effect/platform-node`** — [#7440](https://github.com/Effect-TS/effect/pull/7440) [`7d8535a`](https://github.com/Effect-TS/effect/commit/7d8535af823a0186f771a78a02fa07dbee706df9) Thanks @tim-smart! - Return `Option.none()` when reading an incoming message's remote address after Node clears its socket.
|
|
127
|
+
- **`@effect/sql-d1`, `@effect/sql-mysql2`, `@effect/sql-pglite`, `@effect/doctest`** — [#7421](https://github.com/Effect-TS/effect/pull/7421) [`1f686d9`](https://github.com/Effect-TS/effect/commit/1f686d99a79e36ef144bd9ad6f4141a5a43d2599) Thanks @tim-smart! - Update production dependencies to their latest releases.
|
|
128
|
+
- **`@effect/sql-pg`** — [#7391](https://github.com/Effect-TS/effect/pull/7391) [`1144032`](https://github.com/Effect-TS/effect/commit/1144032cedda7b5eacc1ebf980d06957c7a59ddf) Thanks @tim-smart! - Add low-level PostgreSQL protocol, binary type, and authentication codecs to `@effect/sql-pg`.
|
|
129
|
+
|
|
130
|
+
`PgProtocol` encodes protocol 3.0 messages and incrementally parses backend frames. Its stateful parser throws terminal errors. `PgTypes` handles binary scalar and one-dimensional array OIDs; its public codecs return typed `Result` failures, while parser field readers use an internal throwing fast path. `PgAuth` implements MD5 and SCRAM-SHA-256 with typed `Result` failures.
|
|
131
|
+
|
|
132
|
+
Encoded frames and decoded byte fields are stable views over internal buffers. Copy data that must outlive its message. `PgClient` remains unchanged and still uses `pg` at runtime.
|
|
133
|
+
|
|
134
|
+
### Complete companion release inventory
|
|
135
|
+
|
|
136
|
+
All packages below move from `4.0.0-rc.111` to `4.0.0-rc.112` and update their
|
|
137
|
+
Effect dependency to rc.112. Paths link to the exact-tag changelogs, including
|
|
138
|
+
their full repeated dependency commit lists. “Dependency only” means no separate
|
|
139
|
+
feature/fix release note; it does not assert that every source file is identical.
|
|
140
|
+
|
|
141
|
+
| Package | Additional notes | Other Effect-family dependency updates |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| [@effect/ai-anthropic](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/ai/anthropic/CHANGELOG.md) | #7437 | — |
|
|
144
|
+
| [@effect/ai-openai](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/ai/openai/CHANGELOG.md) | #7437, #7403 | — |
|
|
145
|
+
| [@effect/ai-openai-compat](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/ai/openai-compat/CHANGELOG.md) | #7437 | — |
|
|
146
|
+
| [@effect/ai-openrouter](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/ai/openrouter/CHANGELOG.md) | #7437 | — |
|
|
147
|
+
| [@effect/atom-react](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/atom/react/CHANGELOG.md) | #7435 | — |
|
|
148
|
+
| [@effect/atom-solid](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/atom/solid/CHANGELOG.md) | Dependency only | — |
|
|
149
|
+
| [@effect/atom-vue](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/atom/vue/CHANGELOG.md) | Dependency only | — |
|
|
150
|
+
| [@effect/opentelemetry](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/opentelemetry/CHANGELOG.md) | Dependency only | — |
|
|
151
|
+
| [@effect/platform-browser](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/browser/CHANGELOG.md) | Dependency only | — |
|
|
152
|
+
| [@effect/platform-bun](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/bun/CHANGELOG.md) | #7408 | platform-node-shared |
|
|
153
|
+
| [@effect/platform-deno](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/deno/CHANGELOG.md) | Dependency only | platform-node-shared |
|
|
154
|
+
| [@effect/platform-node](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/node/CHANGELOG.md) | #7440 | platform-node-shared |
|
|
155
|
+
| [@effect/platform-node-shared](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/node-shared/CHANGELOG.md) | Dependency only | — |
|
|
156
|
+
| [@effect/sql-clickhouse](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/clickhouse/CHANGELOG.md) | Dependency only | platform-node |
|
|
157
|
+
| [@effect/sql-d1](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/d1/CHANGELOG.md) | #7421 | — |
|
|
158
|
+
| [@effect/sql-libsql](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/libsql/CHANGELOG.md) | Dependency only | — |
|
|
159
|
+
| [@effect/sql-mssql](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/mssql/CHANGELOG.md) | Dependency only | — |
|
|
160
|
+
| [@effect/sql-mysql2](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/mysql2/CHANGELOG.md) | #7421 | — |
|
|
161
|
+
| [@effect/sql-pg](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/pg/CHANGELOG.md) | #7391 | — |
|
|
162
|
+
| [@effect/sql-pglite](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/pglite/CHANGELOG.md) | #7421 | — |
|
|
163
|
+
| [@effect/sql-sqlite-bun](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-bun/CHANGELOG.md) | Dependency only | — |
|
|
164
|
+
| [@effect/sql-sqlite-do](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-do/CHANGELOG.md) | Dependency only | — |
|
|
165
|
+
| [@effect/sql-sqlite-node](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-node/CHANGELOG.md) | Dependency only | — |
|
|
166
|
+
| [@effect/sql-sqlite-react-native](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-react-native/CHANGELOG.md) | Dependency only | — |
|
|
167
|
+
| [@effect/sql-sqlite-wasm](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-wasm/CHANGELOG.md) | Dependency only | — |
|
|
168
|
+
| [@effect/docgen](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/tools/docgen/CHANGELOG.md) | Dependency only | platform-node |
|
|
169
|
+
| [@effect/doctest](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/tools/doctest/CHANGELOG.md) | #7421 | — |
|
|
170
|
+
| [@effect/openapi-generator](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/tools/openapi-generator/CHANGELOG.md) | Dependency only | platform-node |
|
|
171
|
+
| [@effect/vitest](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/vitest/CHANGELOG.md) | Dependency only | — |
|
|
172
|
+
|
|
173
|
+
## Migration map for this repository
|
|
174
|
+
|
|
175
|
+
The release was audited from the exact tag, including public signatures and
|
|
176
|
+
implementation semantics. Moving `main` was already ahead of the release and was
|
|
177
|
+
not used to infer rc.112 availability. The local runtime typechecks with rc.112
|
|
178
|
+
without source changes; the dependency/lockfile update is the runtime migration.
|
|
179
|
+
|
|
180
|
+
| Surface | Required action / guidance | Owning skills |
|
|
181
|
+
| --- | --- | --- |
|
|
182
|
+
| Schema-aware RPC | Forward required `codecFor` on custom client/server protocols; preserve schema services. Existing built-in formats retain their encoding; cluster storage stays JSON. | `effect-rpc-api`, `effect-rpc-client`, `effect-rpc-server`, `effect-rpc-cluster`, `effect-atom-rpc` |
|
|
183
|
+
| Binary schemas | Public `SchemaBinary.toCodec`, streaming channels, incremental parsing, fingerprints, dictionary lifetime, frame limits, and buffer ownership; avoid exported `@internal` fast paths. | `effect-schema-composition`, `effect-schema-v4`, `effect-stream` |
|
|
184
|
+
| Schema semantics | `matchOrElse` overloads and fallback narrowing, strict JSON Schema imports/conversions, vendored Standard Schema types, stack-free SchemaError. | `effect-schema-v4`, `effect-pattern-matching`, `effect-domain-modeling` |
|
|
185
|
+
| Resource ownership | Atomic cached-only retention with `RcMap.getOption` / `LayerMap.contextEffectOption`, `Pool.use`, and changed public Pool/Scope state interfaces. | `effect-cache`, `effect-layer-design`, `effect-scope`, `effect-service-implementation` |
|
|
186
|
+
| CLI | Replace `prefix` with `theme`, context/local precedence, filter navigation, password wizard redaction, and shell completion escaping. | `effect-cli` |
|
|
187
|
+
| AI | Authentication descriptions preserve provider text; OpenAI Responses GPT-5.6+ explicit cache configuration and prompt breakpoints. | `effect-ai-provider`, `effect-ai-prompt` |
|
|
188
|
+
| Event replication | Empty remote batches skip callbacks and return `None`; non-empty callbacks return `Some`; transient remote writes retry and synchronize pending entries. | `effect-rpc-cluster` |
|
|
189
|
+
| Workflow proxies | Generated RPC/HTTP discard endpoints return string execution IDs; distinguish these endpoints from client-side response-discard options. | `effect-workflow`, `effect-rpc-cluster`, `effect-atom-rpc` |
|
|
190
|
+
| HTTP / MCP | Lazy OpenAPI generation retries after defects; MCP initialize negotiates from body before header validation; Bun WebSocket compression threshold and missing Node remote addresses. | `effect-http-api`, `effect-mcp-server`, `effect-http-server` |
|
|
191
|
+
| Collections | Finite `groupBy` keys remain finite and optional; consumers handle absent groups. | `effect-domain-modeling` |
|
|
192
|
+
| PostgreSQL | Public `PgProtocol`, `PgTypes`, `PgAuth`; synchronous parser vs typed Result failures and buffer ownership. `PgClient` still uses `pg`. | `effect-sql` |
|
|
193
|
+
| Companion peers | React peer range is `>=19.0.0 <20.0.0`; the rc.112 Vitest adapter requires `>=4.1.0 <5.0.0`. | `effect-atom-state`, `effect-testing` |
|
|
194
|
+
|
|
195
|
+
## Earlier documentation drift corrected during the audit
|
|
196
|
+
|
|
197
|
+
These are **not new rc.112 breaking changes**:
|
|
198
|
+
|
|
199
|
+
- Correct `Schema.Schema<T>` versus `Schema.Codec<T, E, RD, RE>` signatures.
|
|
200
|
+
Constructor defaults, including tags, are not automatically decoding defaults;
|
|
201
|
+
`.makeEffect` belongs to the schema instance and fails with `SchemaIssue.Issue`.
|
|
202
|
+
- Replace the repetitive domain-modeling templates with a coherent, compiler-
|
|
203
|
+
checked class-based lifecycle: branded identity, legal transitions, class-
|
|
204
|
+
preserving construction, schema equivalence, orders, optional fields, and
|
|
205
|
+
recursive encoded types. Remove the invalid “change only `_tag`” transition.
|
|
206
|
+
- Correct `Stream.mapArrayEffect`, `Effect.andThen`, `Effect.catch`,
|
|
207
|
+
`Effect.catchCause`, `Effect.mapError` + `orDie`, `Effect.die`, and `runFold`'s
|
|
208
|
+
initial-value thunk. AI streaming examples now scope accumulators per run and
|
|
209
|
+
release semaphore permits even if history setup fails.
|
|
210
|
+
- Yield a Toolkit and provide its handler Layer; use `Tool.HandlerServices` and
|
|
211
|
+
error schemas rather than instance-only JSON checks. The complete tool example
|
|
212
|
+
uses a typed service implementation instead of unchecked database casts.
|
|
213
|
+
- Replace the incomplete Deferred/fiber deduplication example with `Effect.cached`;
|
|
214
|
+
explain that caches and restartable worker coordinators have different contracts.
|
|
215
|
+
- Distinguish complete `Layer.succeed` fakes from partial, defect-stubbing
|
|
216
|
+
`Layer.mock`; preserve deliberate caller-scoped service requirements.
|
|
217
|
+
- Correct RPC abort inspection (`onExit`, interrupt-reason annotations) and HTTP
|
|
218
|
+
streaming semantics: bounded framed response queues backpressure producers even
|
|
219
|
+
without RPC acks. Discarded responses do not erase transport failures.
|
|
220
|
+
- Correct v4 test utilities (`Result`, `TxRef` / `Effect.tx`, `Logger.layer`,
|
|
221
|
+
`Fiber.await`), lexical scope in the event-publisher test, and interruption
|
|
222
|
+
assertions. Keep this repository's existing Vitest runner for compiler/inventory
|
|
223
|
+
tests; installing `@effect/vitest` would require a separate peer-version migration.
|
|
224
|
+
- Apply Effect.fn result transformations in its constructor call and use a
|
|
225
|
+
Duration-input `Metric.timer` with `Effect.trackDuration`; correct the
|
|
226
|
+
`timeoutOrElse` option to `orElse`.
|
|
227
|
+
- Repair flattened upstream platform paths and remove tool-specific/stale
|
|
228
|
+
line-number references from core guidance.
|
|
229
|
+
|
|
230
|
+
## Coverage and intentionally retained material
|
|
231
|
+
|
|
232
|
+
The changed-surface and qualified-symbol scan covered **all 53 remaining bundled
|
|
233
|
+
skills, 45 patterns, four guidance documents, and runtime source**. Findings were checked
|
|
234
|
+
against exact-tag exports/signatures before edits; aliases, re-exports, custom
|
|
235
|
+
application services, and explicitly obsolete examples are not missing APIs.
|
|
236
|
+
|
|
237
|
+
**35 skills changed.** In addition to the migration-map owners, corrective edits
|
|
238
|
+
cover `effect-ai-language-model`, `effect-ai-streaming`, `effect-ai-tool`,
|
|
239
|
+
`effect-concurrency-testing`, `effect-domain-predicates`, `effect-error-handling`,
|
|
240
|
+
`effect-http-client`, `effect-platform-abstraction`, `effect-platform-layers`,
|
|
241
|
+
`effect-scheduling`, and `effect-socket`.
|
|
242
|
+
|
|
243
|
+
The other **18 skills** had no migration requirement identified by this release
|
|
244
|
+
surface/symbol audit: `effect-ai-chat`, `effect-batching`,
|
|
245
|
+
`effect-command-executor`, `effect-config`, `effect-context-witness`,
|
|
246
|
+
`effect-fiber`, `effect-filesystem`, `effect-graph`, `effect-incremental-migration`,
|
|
247
|
+
`effect-managed-runtime`, `effect-observability`, `effect-optics`,
|
|
248
|
+
`effect-parallelization`, `effect-path`, `effect-pubsub-event-bus`,
|
|
249
|
+
`effect-react-composition`, `effect-typeclass-design`, and
|
|
250
|
+
`effect-wide-events`. Their relevant new cross-cutting semantics live in the
|
|
251
|
+
owning skills above rather than duplicated release notes in every file.
|
|
252
|
+
|
|
253
|
+
**Five retained patterns changed:**
|
|
254
|
+
|
|
255
|
+
- `require-effect-concurrency`: detect the removed literal `concurrency: 'inherit'`
|
|
256
|
+
in addition to missing explicit concurrency. Regression cases cover data-first,
|
|
257
|
+
curried, quoted-key, and unrelated-string cases.
|
|
258
|
+
- `avoid-direct-tag-checks`: correct the false claim that TypeScript cannot narrow
|
|
259
|
+
tags; recommend schema match/guards and explain `matchOrElse`.
|
|
260
|
+
- `effect-run-in-body`: use the platform `BunRuntime.runMain` boundary.
|
|
261
|
+
- `use-console-service`: correct TestConsole capture APIs and distinguish console
|
|
262
|
+
capture from structured log capture.
|
|
263
|
+
- `avoid-react-hooks`: direct shared state/effect guidance to Effect Atom in
|
|
264
|
+
ordinary state modules, with React-specific hook use reviewed contextually.
|
|
265
|
+
|
|
266
|
+
The other 40 detector definitions require no rc.112 API migration. All 45 retain
|
|
267
|
+
their one-to-one detector tests and README catalog entries.
|
|
268
|
+
|
|
269
|
+
**Two guidance documents changed:** core Effect-first conventions and
|
|
270
|
+
version-aware progressive disclosure/routing. Both bundled essays retain their
|
|
271
|
+
original text.
|
|
272
|
+
|
|
273
|
+
At the user's request, the `effect-react-vm` skill, `vm-in-wrong-file` pattern,
|
|
274
|
+
and its detector test were removed. Atom RPC cross-links now point directly to
|
|
275
|
+
`effect-atom-state`. The catalog contains **53 skills, 45 patterns, and four
|
|
276
|
+
guidance documents**.
|
|
277
|
+
|
|
278
|
+
## Verification
|
|
279
|
+
|
|
280
|
+
`test/documentation-types.test.ts` compiles the **14 self-contained TypeScript
|
|
281
|
+
blocks** marked `<!-- typecheck -->` directly from their Markdown source. It
|
|
282
|
+
uses the installed pinned Effect release with strict types, exact optional
|
|
283
|
+
properties, and unchecked-index checking. Virtual modules keep normal package
|
|
284
|
+
resolution; no generated source/distribution files are committed. A malformed
|
|
285
|
+
marker/fence fails the test instead of silently dropping coverage.
|
|
286
|
+
|
|
287
|
+
The checked blocks cover binary codec/channel round trips, pool borrowing,
|
|
288
|
+
cached-only retention, task construction/transitions/recursion, tagged matching,
|
|
289
|
+
cache layer composition, RPC abort inspection, tool handler wiring, streaming
|
|
290
|
+
history ownership, and workflow logging/metrics. Partial snippets, intentionally
|
|
291
|
+
bad examples, conceptual pseudocode, and examples needing optional companion
|
|
292
|
+
packages are reviewed guidance, not part of this compiler gate. The gate does
|
|
293
|
+
not claim to execute every documentation example or replace upstream integration
|
|
294
|
+
tests.
|
|
295
|
+
|
|
296
|
+
Repository completion commands:
|
|
297
|
+
|
|
298
|
+
```sh
|
|
299
|
+
bun run check
|
|
300
|
+
bun run lint
|
|
301
|
+
bun run test
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Verified on 2026-09-07 after the VM-related removals:
|
|
305
|
+
|
|
306
|
+
- `bun run check` passed formatting, lint, and TypeScript checks.
|
|
307
|
+
- `bun run lint` passed with zero warnings and errors.
|
|
308
|
+
- `bun run test` passed **912 tests across 53 test files**, including all 14
|
|
309
|
+
marked documentation examples and the 53-skill / 45-pattern / four-guidance
|
|
310
|
+
inventory checks.
|
|
311
|
+
- `git diff --check` passed.
|
|
312
|
+
|
|
313
|
+
The full test suite includes the bidirectional pattern inventory, README/skill
|
|
314
|
+
inventory, runtime adapter tests, detector regressions, and documentation compiler
|
|
315
|
+
gate. Published files remain authoritative; `docs/` is included in the package
|
|
316
|
+
so this release record ships alongside the skills and guidance.
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
This document defines the working model behind Effect-first code using the Effect v4 ecosystem.
|
|
4
4
|
|
|
5
|
+
Bundled baseline: **Effect 4.0.0-rc.112**. Check the consuming project's installed
|
|
6
|
+
version and inspect the matching upstream release tag before using newer APIs.
|
|
7
|
+
The release changelog and migration audit are in `docs/effect-4.0.0-rc.112.md`.
|
|
8
|
+
Source paths below are relative to the Effect source reference; locate symbols
|
|
9
|
+
by name rather than relying on line numbers or a particular tool name.
|
|
10
|
+
|
|
5
11
|
## Definition
|
|
6
12
|
|
|
7
13
|
Effect-first development means domain code is written in Effect-native constructs first, and native JavaScript/TypeScript patterns only at explicit boundaries.
|
|
@@ -289,7 +295,8 @@ export type Tenant = typeof Tenant.Type;
|
|
|
289
295
|
- If schema properties are a union of literal strings (for example `kind`, `state`, `category`), compose class variants into a `Schema.Union` and finalize with `Schema.toTaggedUnion("<field>")`.
|
|
290
296
|
- Prefer `Schema.Class` for tagged union member schemas.
|
|
291
297
|
- Use `Schema.TaggedUnion` only for canonical `_tag` object-union construction.
|
|
292
|
-
- Reference:
|
|
298
|
+
- Reference: `packages/effect/SCHEMA.md`, sections `TaggedUnion` and `toTaggedUnion`.
|
|
299
|
+
- In rc.112, both union forms offer `matchOrElse` for partial matching with a typed fallback. Prefer `match` when every variant must be handled separately. `toTaggedUnion` narrows fallback input to unmatched variants; direct `Schema.TaggedUnion` types it as the full union.
|
|
293
300
|
|
|
294
301
|
Example:
|
|
295
302
|
|
|
@@ -342,7 +349,8 @@ export const InternalJobEvent = Schema.TaggedUnion({
|
|
|
342
349
|
|
|
343
350
|
- Prefer `Effect.fn("Name")(...)` for reusable/public effectful functions.
|
|
344
351
|
- Use `Effect.fnUntraced(...)` for internal hot paths where tracing overhead is unnecessary.
|
|
345
|
-
- Reference:
|
|
352
|
+
- Reference: `Effect.fn` / `Effect.fnUntraced` in `packages/effect/src/Effect.ts`.
|
|
353
|
+
- Pass result-transforming combinators after the function body in the `Effect.fn` constructor call. The returned function itself has no `.pipe` method; its returned Effect does.
|
|
346
354
|
|
|
347
355
|
Example:
|
|
348
356
|
|
|
@@ -374,11 +382,12 @@ const parseInternal = Effect.fnUntraced(function* (input: string) {
|
|
|
374
382
|
|
|
375
383
|
Example:
|
|
376
384
|
|
|
385
|
+
<!-- typecheck -->
|
|
377
386
|
```ts
|
|
378
387
|
import { Effect } from 'effect';
|
|
379
388
|
import * as Metric from 'effect/Metric';
|
|
380
389
|
|
|
381
|
-
const durationMs = Metric.
|
|
390
|
+
const durationMs = Metric.timer('workflow_duration_ms', {
|
|
382
391
|
boundaries: Metric.boundariesFromIterable([10, 50, 100, 250, 500, 1000])
|
|
383
392
|
});
|
|
384
393
|
const failures = Metric.counter('workflow_failures_total');
|
|
@@ -387,7 +396,7 @@ const workflow = Effect.fn('Workflow.run')(function* (requestId: string) {
|
|
|
387
396
|
yield* Effect.annotateCurrentSpan('requestId', requestId);
|
|
388
397
|
yield* Effect.logInfo('workflow started');
|
|
389
398
|
return 'ok';
|
|
390
|
-
}
|
|
399
|
+
},
|
|
391
400
|
Effect.withLogSpan('workflow.run'),
|
|
392
401
|
Effect.annotateLogs({ service: 'my-app' }),
|
|
393
402
|
Effect.trackDuration(durationMs),
|
|
@@ -418,7 +427,7 @@ const program = Effect.sleep(pollInterval).pipe(Effect.timeout(timeout));
|
|
|
418
427
|
- `Schema.OptionFromNullishOr`
|
|
419
428
|
- `Schema.OptionFromOptionalKey`
|
|
420
429
|
- `Schema.OptionFromOptional`
|
|
421
|
-
- Reference:
|
|
430
|
+
- Reference: `Schema.OptionFrom*` in `packages/effect/src/Schema.ts` and optional fields in `packages/effect/SCHEMA.md`.
|
|
422
431
|
|
|
423
432
|
Example:
|
|
424
433
|
|
|
@@ -439,7 +448,7 @@ export class AccountInput extends Schema.Class<AccountInput>('AccountInput')({
|
|
|
439
448
|
- Data-first: `fn(self, arg)`
|
|
440
449
|
- Data-last: `pipe(self, fn(arg))`
|
|
441
450
|
- Build these helpers with `dual` from `effect/Function`.
|
|
442
|
-
- Reference:
|
|
451
|
+
- Reference: `dual` in `packages/effect/src/Function.ts`.
|
|
443
452
|
|
|
444
453
|
Example:
|
|
445
454
|
|
|
@@ -492,7 +501,7 @@ You are not done if these fail:
|
|
|
492
501
|
- Application entrypoints and tests may execute effects with `Effect.run*`.
|
|
493
502
|
- Library and domain exports should return `Effect` values.
|
|
494
503
|
- Keep runtime execution in one place so wiring, logging, and lifecycle behavior stay auditable.
|
|
495
|
-
- Reference:
|
|
504
|
+
- Reference: `runPromise`, `runSync`, and `runFork` in `packages/effect/src/Effect.ts`.
|
|
496
505
|
|
|
497
506
|
Example:
|
|
498
507
|
|
|
@@ -530,7 +539,8 @@ const readSdkValue = (client: ExternalSdk) =>
|
|
|
530
539
|
- Use `Effect.acquireUseRelease` for acquisition/use/release flows.
|
|
531
540
|
- Prefer `Effect.scoped` for helper composition that allocates resources.
|
|
532
541
|
- Do not manually open resources without an explicit finalization strategy.
|
|
533
|
-
- Reference:
|
|
542
|
+
- Reference: `acquireUseRelease` and `scoped` in `packages/effect/src/Effect.ts`.
|
|
543
|
+
- For pool checkouts in rc.112 use `Pool.use(pool, callback)` to return the item on every exit without adding a caller `Scope` requirement. Do not return an item from `Effect.scoped(Pool.get(pool))` and then use it after release.
|
|
534
544
|
|
|
535
545
|
Example:
|
|
536
546
|
|
|
@@ -549,7 +559,7 @@ const withConnection = <A, E, R>(
|
|
|
549
559
|
- Keep retry policy close to the failing effect.
|
|
550
560
|
- Retry only proven-idempotent operations at the narrowest boundary that can classify the failure.
|
|
551
561
|
- Let exhausted failures remain visible unless the boundary has a truthful fallback.
|
|
552
|
-
- Reference:
|
|
562
|
+
- Reference: `retry` in `packages/effect/src/Effect.ts` and the Schedule cookbook.
|
|
553
563
|
|
|
554
564
|
Example:
|
|
555
565
|
|
|
@@ -564,17 +574,18 @@ const resilientFetch = fetchRemote.pipe(Effect.retry(Schedule.recurs(3)));
|
|
|
564
574
|
- Use `Effect.timeoutOption` when timeout should become `Option.None`.
|
|
565
575
|
- Use `Effect.timeoutOrElse` when timeout should produce a typed fallback effect.
|
|
566
576
|
- Avoid manually racing ad-hoc timers for business logic timeouts.
|
|
567
|
-
- Reference:
|
|
577
|
+
- Reference: `timeoutOption` and `timeoutOrElse` in `packages/effect/src/Effect.ts`.
|
|
568
578
|
|
|
569
579
|
Example:
|
|
570
580
|
|
|
571
581
|
```ts
|
|
572
582
|
import { Duration, Effect } from 'effect';
|
|
573
583
|
|
|
584
|
+
declare const slowLookup: Effect.Effect<string>;
|
|
574
585
|
const lookupCachedOnTimeout = slowLookup.pipe(
|
|
575
586
|
Effect.timeoutOrElse({
|
|
576
587
|
duration: Duration.seconds(2),
|
|
577
|
-
|
|
588
|
+
orElse: () => Effect.succeed('cached-value')
|
|
578
589
|
})
|
|
579
590
|
);
|
|
580
591
|
```
|
|
@@ -584,7 +595,7 @@ const lookupCachedOnTimeout = slowLookup.pipe(
|
|
|
584
595
|
- Prefer `Effect.forkChild` so lifecycle is supervised by parent scope.
|
|
585
596
|
- Use `Effect.forkDetach` only for explicit daemon semantics.
|
|
586
597
|
- Make fork intent explicit in code review and comments for detached work.
|
|
587
|
-
- Reference:
|
|
598
|
+
- Reference: `forkChild` and `forkDetach` in `packages/effect/src/Effect.ts`.
|
|
588
599
|
|
|
589
600
|
Example:
|
|
590
601
|
|
|
@@ -621,7 +632,7 @@ const hydrateUsers = (ids: ReadonlyArray<string>) =>
|
|
|
621
632
|
- Use `Config` and `ConfigProvider` for configuration loading and parsing.
|
|
622
633
|
- Keep direct `process.env` access out of domain code.
|
|
623
634
|
- Layer/provide config sources explicitly for tests and non-default environments.
|
|
624
|
-
- Reference:
|
|
635
|
+
- Reference: `packages/effect/CONFIG.md`, `packages/effect/src/Config.ts`, and `ConfigProvider.ts`.
|
|
625
636
|
|
|
626
637
|
Example:
|
|
627
638
|
|
|
@@ -638,7 +649,7 @@ const loadPort = Effect.fn('Config.loadPort')(function* () {
|
|
|
638
649
|
- Use `Config.redacted` for secret config values.
|
|
639
650
|
- Use `Redacted.make` for sensitive values coming from non-config sources.
|
|
640
651
|
- Never log secret values after unwrapping.
|
|
641
|
-
- Reference:
|
|
652
|
+
- Reference: `Config.redacted` in `packages/effect/src/Config.ts` and `packages/effect/src/Redacted.ts`.
|
|
642
653
|
|
|
643
654
|
Example:
|
|
644
655
|
|
|
@@ -681,7 +692,7 @@ const findUserOptional = (id: string) =>
|
|
|
681
692
|
- Unrecoverable infrastructure failures where surfacing the error provides no actionable recovery path (e.g., the data directory is unwritable).
|
|
682
693
|
- Discarding irrelevant upstream error types: when a consuming service cannot meaningfully recover from a dependency's error type and the error is not part of the consumer's own contract, `Effect.orDie` is legitimate. For example, a config loader that depends on an auth service may use `yield* authSvc.all().pipe(Effect.orDie)` because auth failures during config loading are unrecoverable.
|
|
683
694
|
- Do not model normal user-facing errors as defects.
|
|
684
|
-
- Reference:
|
|
695
|
+
- Reference: `die` and `orDie` in `packages/effect/src/Effect.ts`.
|
|
685
696
|
|
|
686
697
|
Example:
|
|
687
698
|
|
|
@@ -710,7 +721,7 @@ const validateInput = Effect.fn('Input.validate')(function* (value: string) {
|
|
|
710
721
|
- Document why isolation is necessary for behavior-sensitive paths.
|
|
711
722
|
- Compose `defaultLayer` values directly by default.
|
|
712
723
|
- Use `Layer.suspend(() => ...)` only when import evaluation order or a real circular dependency requires deferred composition.
|
|
713
|
-
- Reference:
|
|
724
|
+
- Reference: `Effect.provide` and `Layer.fresh` in `packages/effect/src/{Effect,Layer}.ts`.
|
|
714
725
|
|
|
715
726
|
Example:
|
|
716
727
|
|
|
@@ -751,7 +762,8 @@ export class CreateOrderInput extends Schema.Class<CreateOrderInput>(
|
|
|
751
762
|
- Put defaults in schema definitions, not in handler/service fallback object literals.
|
|
752
763
|
- Use `Schema.withConstructorDefault` for constructor-time defaults.
|
|
753
764
|
- Use `Schema.withDecodingDefault` / `Schema.withDecodingDefaultKey` for decode-time defaults.
|
|
754
|
-
- Constructor defaults may fail with `SchemaIssue.Issue`. Likewise, `
|
|
765
|
+
- Constructor defaults may fail with `SchemaIssue.Issue`. Likewise, `MySchema.makeEffect(fields)` returns validation failures directly as `SchemaIssue.Issue`, not wrapped in `Schema.SchemaError`.
|
|
766
|
+
- Constructor defaults (including `Schema.tag`) do not automatically apply during boundary decoding. Unknown input uses `Schema.decodeUnknownEffect`; `decodeSync` is not a constructor replacement.
|
|
755
767
|
|
|
756
768
|
Example:
|
|
757
769
|
|
|
@@ -982,6 +994,7 @@ const UnknownToString = Schema.Unknown.pipe(
|
|
|
982
994
|
- For invalidatable caches, use `Effect.cachedInvalidateWithTTL(effect, Duration.infinity)` which returns a `[cachedEffect, invalidate]` tuple. Call `yield* invalidate` to force re-computation on next access.
|
|
983
995
|
- For time-based caches, use `Effect.cachedWithTTL(effect, duration)`.
|
|
984
996
|
- Prefer `Effect.cachedInvalidateWithTTL` with `Duration.infinity` over mutable `let` rebinding of cached effects.
|
|
997
|
+
- For keyed scoped resources, rc.112 adds `RcMap.getOption` and `LayerMap.contextEffectOption`. They atomically retain already-cached entries and propagate acquisition failures; `None` means missing/closed, not failed. A `has` check followed by `get` is not equivalent.
|
|
985
998
|
|
|
986
999
|
Example:
|
|
987
1000
|
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
# Agent Rules
|
|
2
2
|
|
|
3
|
+
The bundled guidance targets **Effect 4.0.0-rc.112**. Read the consuming project's
|
|
4
|
+
version before applying an API: stable v3, older prereleases, and unreleased main
|
|
5
|
+
can have different contracts. Keep directly used Effect-family packages on
|
|
6
|
+
compatible release versions.
|
|
7
|
+
|
|
3
8
|
Load all relevant skills before writing or planning any code. Effect is a massive ecosystem — without loading skills you will write outdated v3 code or miss high-leverage libraries. Load AT LEAST 4 `effect-*` skills before any Effect work.
|
|
4
9
|
|
|
5
10
|
When skills leave any ambiguity, or when you encounter unfamiliar APIs during implementation, read the OpenCode `effect` reference at `~/.local/share/opencode/repos/github.com/Effect-TS/effect@main/`. Treat this reference as the source of truth over `node_modules`, stale external docs, or memory.
|
|
6
11
|
|
|
12
|
+
Check the reference revision too. For this baseline, inspect the
|
|
13
|
+
`effect@4.0.0-rc.112` tag (for example with `git show
|
|
14
|
+
effect@4.0.0-rc.112:packages/effect/src/Schema.ts`) when main has moved ahead.
|
|
15
|
+
Source symbols and signatures at that tag take precedence over stale prose or
|
|
16
|
+
line-number links. Public exports marked `@internal` in source are not application APIs.
|
|
17
|
+
|
|
7
18
|
## Skill routing
|
|
8
19
|
|
|
9
20
|
Load every branch that the task crosses:
|
|
10
21
|
|
|
11
22
|
- Schemas, brands, variants, optionality, or decoding: `effect-schema-v4`, `effect-schema-composition`, and `effect-domain-modeling`.
|
|
23
|
+
- Binary schema codecs and framed binary streams: `effect-schema-composition` and `effect-stream`; RPC serialization also needs `effect-rpc-client` / `effect-rpc-server`.
|
|
12
24
|
- Services, layers, runtime wiring, or scoped lifetimes: `effect-service-implementation`, `effect-layer-design`, `effect-scope`, and `effect-fiber`.
|
|
13
25
|
- Configuration or secrets: `effect-config`.
|
|
14
26
|
- Retry, repeat, polling, backoff, pacing, or recurrence: `effect-scheduling` plus the relevant error, HTTP, or testing skill.
|
|
15
27
|
- Memoization, keyed caches, or request batching: `effect-cache` and `effect-batching`.
|
|
28
|
+
- Retained keyed resources or pooled checkout: `effect-cache`, `effect-layer-design`, and `effect-scope`.
|
|
16
29
|
- Streams, queues, pubsubs, pagination, or backpressure: `effect-stream` and the relevant concurrency skill.
|
|
17
30
|
- Outgoing HTTP: `effect-http-client` plus the relevant platform-layer skill.
|
|
18
31
|
- Effect tests, virtual time, or concurrent synchronization: `effect-testing` and `effect-concurrency-testing`.
|