opencode-effect-enforcer 0.2.0
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/LICENSE +21 -0
- package/README.md +278 -0
- package/guidance/effect-first-development.md +1247 -0
- package/guidance/post__effect-and-the-near-inexpressible-majesty-of-layers.md +490 -0
- package/guidance/post__parse-dont-validate.md +109 -0
- package/guidance/progressive-disclosure-guidance.md +38 -0
- package/package.json +63 -0
- package/patterns/avoid-any.md +37 -0
- package/patterns/avoid-data-tagged-error.md +34 -0
- package/patterns/avoid-direct-json.md +51 -0
- package/patterns/avoid-direct-tag-checks.md +54 -0
- package/patterns/avoid-expect-in-if.md +52 -0
- package/patterns/avoid-mutable-state.md +70 -0
- package/patterns/avoid-native-fetch.md +61 -0
- package/patterns/avoid-node-imports.md +86 -0
- package/patterns/avoid-non-null-assertion.md +44 -0
- package/patterns/avoid-object-type.md +46 -0
- package/patterns/avoid-option-getorthrow.md +39 -0
- package/patterns/avoid-platform-coupling.md +43 -0
- package/patterns/avoid-process-env.md +43 -0
- package/patterns/avoid-react-hooks.md +73 -0
- package/patterns/avoid-schema-suffix.md +45 -0
- package/patterns/avoid-sync-fs.md +68 -0
- package/patterns/avoid-try-catch.md +47 -0
- package/patterns/avoid-ts-ignore.md +38 -0
- package/patterns/avoid-untagged-errors.md +67 -0
- package/patterns/avoid-yield-ref.md +46 -0
- package/patterns/casting-awareness.md +46 -0
- package/patterns/context-tag-extends.md +84 -0
- package/patterns/effect-catchall-default.md +61 -0
- package/patterns/effect-promise-vs-trypromise.md +47 -0
- package/patterns/effect-run-in-body.md +58 -0
- package/patterns/imperative-loops.md +76 -0
- package/patterns/prefer-arr-sort.md +52 -0
- package/patterns/prefer-duration-values.md +56 -0
- package/patterns/prefer-effect-fn.md +161 -0
- package/patterns/prefer-match-over-switch.md +48 -0
- package/patterns/prefer-option-over-null.md +56 -0
- package/patterns/prefer-redacted-config.md +70 -0
- package/patterns/prefer-schema-class.md +54 -0
- package/patterns/require-effect-concurrency.md +83 -0
- package/patterns/stream-large-files.md +63 -0
- package/patterns/throw-in-effect-gen.md +62 -0
- package/patterns/use-clock-service.md +45 -0
- package/patterns/use-command-executor-service.md +54 -0
- package/patterns/use-console-service.md +54 -0
- package/patterns/use-filesystem-service.md +59 -0
- package/patterns/use-http-client-service.md +77 -0
- package/patterns/use-path-service.md +53 -0
- package/patterns/use-random-service.md +45 -0
- package/patterns/use-temp-file-scoped.md +66 -0
- package/patterns/vm-in-wrong-file.md +51 -0
- package/patterns/yield-in-for-loop.md +61 -0
- package/skills/effect-ai-chat/SKILL.md +472 -0
- package/skills/effect-ai-language-model/SKILL.md +652 -0
- package/skills/effect-ai-prompt/SKILL.md +752 -0
- package/skills/effect-ai-provider/SKILL.md +668 -0
- package/skills/effect-ai-streaming/SKILL.md +418 -0
- package/skills/effect-ai-tool/SKILL.md +1132 -0
- package/skills/effect-atom-rpc/SKILL.md +488 -0
- package/skills/effect-atom-state/SKILL.md +640 -0
- package/skills/effect-batching/SKILL.md +614 -0
- package/skills/effect-cache/SKILL.md +570 -0
- package/skills/effect-cli/SKILL.md +523 -0
- package/skills/effect-command-executor/SKILL.md +675 -0
- package/skills/effect-concurrency-testing/SKILL.md +612 -0
- package/skills/effect-config/SKILL.md +580 -0
- package/skills/effect-context-witness/SKILL.md +274 -0
- package/skills/effect-domain-modeling/SKILL.md +1212 -0
- package/skills/effect-domain-predicates/SKILL.md +867 -0
- package/skills/effect-error-handling/SKILL.md +1581 -0
- package/skills/effect-fiber/SKILL.md +731 -0
- package/skills/effect-filesystem/SKILL.md +624 -0
- package/skills/effect-graph/SKILL.md +571 -0
- package/skills/effect-http-api/SKILL.md +1760 -0
- package/skills/effect-http-client/SKILL.md +989 -0
- package/skills/effect-http-server/SKILL.md +920 -0
- package/skills/effect-incremental-migration/SKILL.md +362 -0
- package/skills/effect-layer-design/SKILL.md +642 -0
- package/skills/effect-managed-runtime/SKILL.md +395 -0
- package/skills/effect-mcp-server/SKILL.md +608 -0
- package/skills/effect-observability/SKILL.md +719 -0
- package/skills/effect-optics/SKILL.md +554 -0
- package/skills/effect-parallelization/SKILL.md +668 -0
- package/skills/effect-path/SKILL.md +296 -0
- package/skills/effect-pattern-matching/SKILL.md +914 -0
- package/skills/effect-platform-abstraction/SKILL.md +1175 -0
- package/skills/effect-platform-layers/SKILL.md +514 -0
- package/skills/effect-pubsub-event-bus/SKILL.md +384 -0
- package/skills/effect-react-composition/SKILL.md +986 -0
- package/skills/effect-react-vm/SKILL.md +675 -0
- package/skills/effect-rpc-api/SKILL.md +624 -0
- package/skills/effect-rpc-client/SKILL.md +666 -0
- package/skills/effect-rpc-cluster/SKILL.md +1623 -0
- package/skills/effect-rpc-server/SKILL.md +767 -0
- package/skills/effect-scheduling/SKILL.md +124 -0
- package/skills/effect-schema-composition/SKILL.md +975 -0
- package/skills/effect-schema-v4/SKILL.md +691 -0
- package/skills/effect-scope/SKILL.md +682 -0
- package/skills/effect-service-implementation/SKILL.md +656 -0
- package/skills/effect-socket/SKILL.md +703 -0
- package/skills/effect-sql/SKILL.md +781 -0
- package/skills/effect-stream/SKILL.md +765 -0
- package/skills/effect-testing/SKILL.md +1331 -0
- package/skills/effect-typeclass-design/SKILL.md +161 -0
- package/skills/effect-wide-events/Article.md +66 -0
- package/skills/effect-wide-events/SKILL.md +95 -0
- package/skills/effect-workflow/SKILL.md +810 -0
- package/src/agent-policy.ts +22 -0
- package/src/enforcer.ts +104 -0
- package/src/frontmatter.ts +34 -0
- package/src/guidance.ts +66 -0
- package/src/index.ts +38 -0
- package/src/pattern-catalog.ts +115 -0
- package/src/pattern-matcher.ts +178 -0
- package/src/pattern.ts +97 -0
- package/src/skills.ts +29 -0
- package/src/write-projection.ts +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Marc Suesser
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# opencode-effect-enforcer
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/opencode-effect-enforcer)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
An opinionated OpenCode V2 plugin that gives coding agents current Effect v4
|
|
7
|
+
guidance and reviews their TypeScript edits for common Effect anti-patterns.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Add the npm package to your global or project `opencode.jsonc`:
|
|
12
|
+
|
|
13
|
+
```jsonc
|
|
14
|
+
{
|
|
15
|
+
"$schema": "https://opencode.ai/config.json",
|
|
16
|
+
"plugins": ["opencode-effect-enforcer"],
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
That is the complete installation. OpenCode resolves published package entries
|
|
21
|
+
for you; there is no separate `npm install` step. Use the global config at
|
|
22
|
+
`~/.config/opencode/opencode.jsonc` to enable it everywhere, or a project config
|
|
23
|
+
to enable it only for that project. You can also pin a release, for example
|
|
24
|
+
`"opencode-effect-enforcer@0.2.0"`.
|
|
25
|
+
|
|
26
|
+
Start a new OpenCode session, then verify the plugin if needed:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
opencode2 api get /api/plugin
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## What You Get
|
|
33
|
+
|
|
34
|
+
- **54 focused skills** registered in OpenCode's native skill catalog, covering
|
|
35
|
+
Effect's core, platform, AI, RPC, SQL, frontend, and testing APIs.
|
|
36
|
+
- **4 guidance documents** injected into model context so Effect-first
|
|
37
|
+
boundaries, domain modeling, dependency design, and skill routing stay
|
|
38
|
+
visible while the agent works.
|
|
39
|
+
- **46 tested patterns** run after successful `write`, `edit`, `patch`, and
|
|
40
|
+
`apply_patch` calls, reporting only violations in newly added text.
|
|
41
|
+
- **Advisory remediation** appended to the completed tool result so the model
|
|
42
|
+
reviews and fixes valid findings without a detector blocking the underlying
|
|
43
|
+
write.
|
|
44
|
+
|
|
45
|
+
## Source Catalog
|
|
46
|
+
|
|
47
|
+
Every bundled skill, pattern, and guidance document is linked below. Open only
|
|
48
|
+
the area relevant to your task, or expand a catalog to browse everything
|
|
49
|
+
available.
|
|
50
|
+
|
|
51
|
+
### Guidance (4)
|
|
52
|
+
|
|
53
|
+
- [Effect-First Development](guidance/effect-first-development.md): Defines the Effect-first operating model, laws, templates, boundaries, and review checklist.
|
|
54
|
+
- [Agent Rules](guidance/progressive-disclosure-guidance.md): Routes agents to the right skills and authoritative Effect v4 source references.
|
|
55
|
+
- [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.
|
|
56
|
+
- [Parse, don't validate](guidance/post__parse-dont-validate.md): Shows how refined types preserve validation knowledge and make illegal states unrepresentable.
|
|
57
|
+
|
|
58
|
+
<details>
|
|
59
|
+
<summary><strong>Skills (54)</strong></summary>
|
|
60
|
+
|
|
61
|
+
#### Modeling And Core APIs
|
|
62
|
+
|
|
63
|
+
- [`effect-error-handling`](skills/effect-error-handling/SKILL.md): Model typed failures, inspect causes, report errors, and recover precisely.
|
|
64
|
+
- [`effect-schema-v4`](skills/effect-schema-v4/SKILL.md): Use current Effect Schema v4 APIs and migrate away from v3 patterns.
|
|
65
|
+
- [`effect-schema-composition`](skills/effect-schema-composition/SKILL.md): Compose schemas with transformations, filters, validation, and `Schema.decodeTo`.
|
|
66
|
+
- [`effect-domain-modeling`](skills/effect-domain-modeling/SKILL.md): Build schema-backed domain entities, ADTs, guards, orders, and matchers.
|
|
67
|
+
- [`effect-domain-predicates`](skills/effect-domain-predicates/SKILL.md): Derive reusable predicates and orderings for domain types.
|
|
68
|
+
- [`effect-pattern-matching`](skills/effect-pattern-matching/SKILL.md): Match discriminated unions and Effect results exhaustively.
|
|
69
|
+
- [`effect-optics`](skills/effect-optics/SKILL.md): Read and immutably update nested data with lenses, prisms, and traversals.
|
|
70
|
+
- [`effect-typeclass-design`](skills/effect-typeclass-design/SKILL.md): Design typeclasses with curried signatures and dual data-first/data-last APIs.
|
|
71
|
+
- [`effect-graph`](skills/effect-graph/SKILL.md): Construct, traverse, analyze, and render immutable graphs.
|
|
72
|
+
|
|
73
|
+
#### Services, Lifecycle, And Concurrency
|
|
74
|
+
|
|
75
|
+
- [`effect-context-witness`](skills/effect-context-witness/SKILL.md): Choose between service witnesses and capability-based dependency injection.
|
|
76
|
+
- [`effect-service-implementation`](skills/effect-service-implementation/SKILL.md): Implement focused Effect services without monolithic interfaces.
|
|
77
|
+
- [`effect-layer-design`](skills/effect-layer-design/SKILL.md): Design and compose Layers with explicit dependency wiring.
|
|
78
|
+
- [`effect-scope`](skills/effect-scope/SKILL.md): Manage resource acquisition, finalization, and scope ownership safely.
|
|
79
|
+
- [`effect-fiber`](skills/effect-fiber/SKILL.md): Fork, supervise, interrupt, and coordinate fibers and keyed fiber collections.
|
|
80
|
+
- [`effect-parallelization`](skills/effect-parallelization/SKILL.md): Run, race, gate, and concurrency-limit Effect computations.
|
|
81
|
+
- [`effect-scheduling`](skills/effect-scheduling/SKILL.md): Define retries, repeats, polling, backoff, pacing, and timeouts with `Schedule`.
|
|
82
|
+
- [`effect-cache`](skills/effect-cache/SKILL.md): Cache effectful lookups with TTL, invalidation, deduplication, and scoped entries.
|
|
83
|
+
- [`effect-batching`](skills/effect-batching/SKILL.md): Batch and deduplicate requests with `Request`, `RequestResolver`, and `SqlResolver`.
|
|
84
|
+
- [`effect-stream`](skills/effect-stream/SKILL.md): Build resource-safe streaming pipelines with transformations, concurrency, and codecs.
|
|
85
|
+
- [`effect-pubsub-event-bus`](skills/effect-pubsub-event-bus/SKILL.md): Implement typed publish/subscribe event buses with PubSub and Stream.
|
|
86
|
+
- [`effect-workflow`](skills/effect-workflow/SKILL.md): Build durable workflows, activities, queues, clocks, and compensating transactions.
|
|
87
|
+
|
|
88
|
+
#### Platform And Runtime Integration
|
|
89
|
+
|
|
90
|
+
- [`effect-platform-abstraction`](skills/effect-platform-abstraction/SKILL.md): Keep filesystem, process, HTTP, crypto, and terminal code portable.
|
|
91
|
+
- [`effect-platform-layers`](skills/effect-platform-layers/SKILL.md): Provide platform implementations cleanly at application boundaries.
|
|
92
|
+
- [`effect-managed-runtime`](skills/effect-managed-runtime/SKILL.md): Run Effect services inside frameworks and runtimes Effect does not own.
|
|
93
|
+
- [`effect-filesystem`](skills/effect-filesystem/SKILL.md): Perform platform-independent file I/O through Effect's `FileSystem`.
|
|
94
|
+
- [`effect-path`](skills/effect-path/SKILL.md): Join, resolve, normalize, and convert paths through Effect's `Path` service.
|
|
95
|
+
- [`effect-command-executor`](skills/effect-command-executor/SKILL.md): Spawn, stream, pipe, and safely manage child processes.
|
|
96
|
+
- [`effect-socket`](skills/effect-socket/SKILL.md): Build TCP, Unix-domain, and WebSocket clients, servers, and framed transports.
|
|
97
|
+
- [`effect-cli`](skills/effect-cli/SKILL.md): Build type-safe command-line interfaces with arguments, options, commands, and Layers.
|
|
98
|
+
|
|
99
|
+
#### HTTP, RPC, And Persistence
|
|
100
|
+
|
|
101
|
+
- [`effect-http-api`](skills/effect-http-api/SKILL.md): Define typed HTTP APIs with schemas, security, handlers, clients, and OpenAPI.
|
|
102
|
+
- [`effect-http-client`](skills/effect-http-client/SKILL.md): Make typed outgoing HTTP requests with decoding, retries, streaming, and test transports.
|
|
103
|
+
- [`effect-http-server`](skills/effect-http-server/SKILL.md): Serve routes, middleware, uploads, static files, streams, and WebSockets.
|
|
104
|
+
- [`effect-rpc-api`](skills/effect-rpc-api/SKILL.md): Define shared typed RPC contracts, middleware, errors, and streaming procedures.
|
|
105
|
+
- [`effect-rpc-client`](skills/effect-rpc-client/SKILL.md): Consume RPC contracts over HTTP, WebSocket, TCP, workers, or in-memory transports.
|
|
106
|
+
- [`effect-rpc-server`](skills/effect-rpc-server/SKILL.md): Implement and serve RPC handlers with middleware, streaming, and interruption support.
|
|
107
|
+
- [`effect-rpc-cluster`](skills/effect-rpc-cluster/SKILL.md): Build clustered RPC entities, sharding, singletons, cron jobs, and workflows.
|
|
108
|
+
- [`effect-sql`](skills/effect-sql/SKILL.md): Query databases and build schemas, models, resolvers, repositories, and migrations.
|
|
109
|
+
|
|
110
|
+
#### AI And MCP
|
|
111
|
+
|
|
112
|
+
- [`effect-ai-language-model`](skills/effect-ai-language-model/SKILL.md): Generate text, structured output, streams, and tool calls through `LanguageModel`.
|
|
113
|
+
- [`effect-ai-prompt`](skills/effect-ai-prompt/SKILL.md): Construct and compose prompts from messages and multimodal parts.
|
|
114
|
+
- [`effect-ai-tool`](skills/effect-ai-tool/SKILL.md): Define type-safe AI tools, toolkits, schemas, and handlers.
|
|
115
|
+
- [`effect-ai-provider`](skills/effect-ai-provider/SKILL.md): Configure provider Layers, models, runtime overrides, and fallback execution plans.
|
|
116
|
+
- [`effect-ai-streaming`](skills/effect-ai-streaming/SKILL.md): Consume AI start/delta/end streams with safe accumulation and history updates.
|
|
117
|
+
- [`effect-ai-chat`](skills/effect-ai-chat/SKILL.md): Build persistent multi-turn chats and agentic tool-calling loops.
|
|
118
|
+
- [`effect-mcp-server`](skills/effect-mcp-server/SKILL.md): Expose MCP tools, resources, and prompts over stdio or HTTP.
|
|
119
|
+
|
|
120
|
+
#### Frontend State And Composition
|
|
121
|
+
|
|
122
|
+
- [`effect-atom-state`](skills/effect-atom-state/SKILL.md): Manage reactive React state with Effect Atom.
|
|
123
|
+
- [`effect-atom-rpc`](skills/effect-atom-rpc/SKILL.md): Build cached, invalidating, SSR-aware RPC atoms for React clients.
|
|
124
|
+
- [`effect-react-composition`](skills/effect-react-composition/SKILL.md): Compose React components around explicit Effect Atom state and behavior.
|
|
125
|
+
- [`effect-react-vm`](skills/effect-react-vm/SKILL.md): Implement testable View Models that bridge Effect services and React views.
|
|
126
|
+
|
|
127
|
+
#### Configuration, Operations, And Testing
|
|
128
|
+
|
|
129
|
+
- [`effect-config`](skills/effect-config/SKILL.md): Load, validate, compose, and test typed configuration sources.
|
|
130
|
+
- [`effect-observability`](skills/effect-observability/SKILL.md): Add structured logs, traces, metrics, and OTLP or Prometheus export.
|
|
131
|
+
- [`effect-wide-events`](skills/effect-wide-events/SKILL.md): Design information-rich canonical log events for observability.
|
|
132
|
+
- [`effect-testing`](skills/effect-testing/SKILL.md): Test Effect programs, services, Layers, time, errors, and properties.
|
|
133
|
+
- [`effect-concurrency-testing`](skills/effect-concurrency-testing/SKILL.md): Test fibers, PubSub, Deferred, Latch, SubscriptionRef, and concurrent streams.
|
|
134
|
+
- [`effect-incremental-migration`](skills/effect-incremental-migration/SKILL.md): Migrate Promise-based modules incrementally while preserving required compatibility.
|
|
135
|
+
|
|
136
|
+
</details>
|
|
137
|
+
|
|
138
|
+
<details>
|
|
139
|
+
<summary><strong>Patterns (46)</strong></summary>
|
|
140
|
+
|
|
141
|
+
#### Types, Modeling, And Collections
|
|
142
|
+
|
|
143
|
+
- [`avoid-any`](patterns/avoid-any.md): Flags assertions to `any` or `unknown` that erase type safety.
|
|
144
|
+
- [`casting-awareness`](patterns/casting-awareness.md): Reviews type assertions and suggests decoding, guards, or `satisfies`.
|
|
145
|
+
- [`avoid-ts-ignore`](patterns/avoid-ts-ignore.md): Detects `@ts-ignore` and `@ts-expect-error` suppressions.
|
|
146
|
+
- [`avoid-non-null-assertion`](patterns/avoid-non-null-assertion.md): Detects TypeScript non-null assertions.
|
|
147
|
+
- [`avoid-object-type`](patterns/avoid-object-type.md): Rejects imprecise `Object` and `{}` type annotations.
|
|
148
|
+
- [`prefer-option-over-null`](patterns/prefer-option-over-null.md): Reviews nullable unions that may be better represented by `Option`.
|
|
149
|
+
- [`avoid-option-getorthrow`](patterns/avoid-option-getorthrow.md): Replaces unsafe `Option.getOrThrow` calls with explicit handling.
|
|
150
|
+
- [`avoid-schema-suffix`](patterns/avoid-schema-suffix.md): Encourages schema constants named after their domain concepts.
|
|
151
|
+
- [`prefer-schema-class`](patterns/prefer-schema-class.md): Reviews `Schema.Struct` where decoded values need class identity.
|
|
152
|
+
- [`avoid-direct-json`](patterns/avoid-direct-json.md): Reviews direct JSON methods in favor of schema JSON codecs.
|
|
153
|
+
- [`prefer-match-over-switch`](patterns/prefer-match-over-switch.md): Replaces native `switch` statements with exhaustive Effect matching.
|
|
154
|
+
- [`avoid-direct-tag-checks`](patterns/avoid-direct-tag-checks.md): Replaces direct `_tag` comparisons with exported refinements or predicates.
|
|
155
|
+
- [`imperative-loops`](patterns/imperative-loops.md): Replaces imperative loops with functional collection transformations.
|
|
156
|
+
- [`prefer-arr-sort`](patterns/prefer-arr-sort.md): Replaces native array sorting with `Arr.sort` and explicit `Order`.
|
|
157
|
+
|
|
158
|
+
#### Errors And Effect Boundaries
|
|
159
|
+
|
|
160
|
+
- [`avoid-data-tagged-error`](patterns/avoid-data-tagged-error.md): Reviews public or serialized `Data.TaggedError` values for schema-backed errors.
|
|
161
|
+
- [`avoid-untagged-errors`](patterns/avoid-untagged-errors.md): Reviews raw `Error` construction and discrimination in recoverable code.
|
|
162
|
+
- [`avoid-try-catch`](patterns/avoid-try-catch.md): Replaces `try`/`catch` in Effect code with typed Effect constructors.
|
|
163
|
+
- [`throw-in-effect-gen`](patterns/throw-in-effect-gen.md): Detects thrown exceptions inside Effect generators and functions.
|
|
164
|
+
- [`effect-catchall-default`](patterns/effect-catchall-default.md): Reviews broad catch-and-default recovery that may hide failures.
|
|
165
|
+
- [`effect-promise-vs-trypromise`](patterns/effect-promise-vs-trypromise.md): Uses `Effect.tryPromise` when Promise rejection must enter the error channel.
|
|
166
|
+
- [`effect-run-in-body`](patterns/effect-run-in-body.md): Keeps `Effect.runSync`, `runPromise`, and `runFork` at runtime boundaries.
|
|
167
|
+
- [`prefer-effect-fn`](patterns/prefer-effect-fn.md): Wraps service methods with named, traced `Effect.fn` definitions.
|
|
168
|
+
- [`avoid-yield-ref`](patterns/avoid-yield-ref.md): Replaces direct yielding of Ref, Deferred, Fiber, and Latch with explicit operations.
|
|
169
|
+
|
|
170
|
+
#### Services, Concurrency, And Time
|
|
171
|
+
|
|
172
|
+
- [`context-tag-extends`](patterns/context-tag-extends.md): Replaces legacy service-tag APIs with `Context.Service`.
|
|
173
|
+
- [`avoid-mutable-state`](patterns/avoid-mutable-state.md): Reviews mutable `let` state inside Effect services in favor of `Ref`.
|
|
174
|
+
- [`yield-in-for-loop`](patterns/yield-in-for-loop.md): Replaces effectful loop bodies with Effect or STM collection combinators.
|
|
175
|
+
- [`require-effect-concurrency`](patterns/require-effect-concurrency.md): Requires explicit concurrency for Effect collection combinators.
|
|
176
|
+
- [`prefer-duration-values`](patterns/prefer-duration-values.md): Replaces numeric time literals with typed `Duration` values.
|
|
177
|
+
- [`use-clock-service`](patterns/use-clock-service.md): Replaces JavaScript `Date` operations with testable DateTime or Clock effects.
|
|
178
|
+
- [`use-random-service`](patterns/use-random-service.md): Replaces `Math.random()` with Effect's testable Random service.
|
|
179
|
+
- [`use-console-service`](patterns/use-console-service.md): Replaces native console calls with Effect logging or Console services.
|
|
180
|
+
|
|
181
|
+
#### Platform, I/O, And Configuration
|
|
182
|
+
|
|
183
|
+
- [`avoid-native-fetch`](patterns/avoid-native-fetch.md): Replaces native `fetch` with Effect HTTP client modules.
|
|
184
|
+
- [`use-http-client-service`](patterns/use-http-client-service.md): Replaces `node:http` and `node:https` with Effect `HttpClient`.
|
|
185
|
+
- [`use-filesystem-service`](patterns/use-filesystem-service.md): Replaces Node filesystem imports with Effect `FileSystem`.
|
|
186
|
+
- [`avoid-sync-fs`](patterns/avoid-sync-fs.md): Detects synchronous filesystem operations.
|
|
187
|
+
- [`stream-large-files`](patterns/stream-large-files.md): Reviews whole-file reads of likely large or unbounded inputs.
|
|
188
|
+
- [`use-path-service`](patterns/use-path-service.md): Replaces Node path imports with Effect's `Path` service.
|
|
189
|
+
- [`use-temp-file-scoped`](patterns/use-temp-file-scoped.md): Requires scoped temporary files and directories with automatic cleanup.
|
|
190
|
+
- [`use-command-executor-service`](patterns/use-command-executor-service.md): Replaces `node:child_process` with Effect process services.
|
|
191
|
+
- [`avoid-node-imports`](patterns/avoid-node-imports.md): Catches Node imports not covered by a more specific platform rule.
|
|
192
|
+
- [`avoid-platform-coupling`](patterns/avoid-platform-coupling.md): Prevents binding packages from hardwiring Bun or Node platform Layers.
|
|
193
|
+
- [`avoid-process-env`](patterns/avoid-process-env.md): Replaces direct environment access with Effect Config.
|
|
194
|
+
- [`prefer-redacted-config`](patterns/prefer-redacted-config.md): Requires secret-like configuration values to remain redacted.
|
|
195
|
+
|
|
196
|
+
#### React And Testing Conventions
|
|
197
|
+
|
|
198
|
+
- [`avoid-react-hooks`](patterns/avoid-react-hooks.md): Directs React state and effects into Effect Atom View Models.
|
|
199
|
+
- [`vm-in-wrong-file`](patterns/vm-in-wrong-file.md): Enforces dedicated `.vm.ts` files for View Model definitions.
|
|
200
|
+
- [`avoid-expect-in-if`](patterns/avoid-expect-in-if.md): Prevents conditional assertions that allow tests to pass without checking behavior.
|
|
201
|
+
|
|
202
|
+
</details>
|
|
203
|
+
|
|
204
|
+
## Per-Agent Opt-Out
|
|
205
|
+
|
|
206
|
+
Set `opencode-effect-enforcer: false` in an agent's `request.body` when that
|
|
207
|
+
agent does not write Effect code. The plugin consumes the setting before the
|
|
208
|
+
request reaches the model provider.
|
|
209
|
+
|
|
210
|
+
```jsonc
|
|
211
|
+
{
|
|
212
|
+
"agents": {
|
|
213
|
+
"researcher": {
|
|
214
|
+
"description": "Handles non-code research",
|
|
215
|
+
"mode": "subagent",
|
|
216
|
+
"request": {
|
|
217
|
+
"body": {
|
|
218
|
+
"opencode-effect-enforcer": false,
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
For opted-out agents, the plugin does not inject guidance, advertise or allow
|
|
227
|
+
its `effect-*` skills, or run post-write pattern enforcement.
|
|
228
|
+
|
|
229
|
+
To disable the plugin entirely without removing its package entry, add a later
|
|
230
|
+
selector using the exported plugin ID:
|
|
231
|
+
|
|
232
|
+
```jsonc
|
|
233
|
+
{
|
|
234
|
+
"plugins": ["opencode-effect-enforcer", "-opencode.effect-enforcer"],
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Enforcement Semantics
|
|
239
|
+
|
|
240
|
+
Patterns run only after successful writes. For edits and patches, the plugin
|
|
241
|
+
captures the original files and computes changed spans from the final output,
|
|
242
|
+
so it does not report a pre-existing violation outside newly added text.
|
|
243
|
+
Full-file writes and new files treat the complete result as changed.
|
|
244
|
+
|
|
245
|
+
The matcher supports TypeScript and TSX ast-grep rules, regex detectors with
|
|
246
|
+
comment filtering, include and ignore globs, severity ordering, and targeted
|
|
247
|
+
skill suggestions. Inspection failures remain advisory and never convert a
|
|
248
|
+
successful write into a failed tool call.
|
|
249
|
+
|
|
250
|
+
## Development
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
bun install
|
|
254
|
+
bun run check
|
|
255
|
+
bun run test
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The tests enforce a bidirectional pattern/test inventory and require every
|
|
259
|
+
skill, pattern, and guidance source to remain linked from this README.
|
|
260
|
+
|
|
261
|
+
GitHub releases are automatically verified and published to npm with provenance.
|
|
262
|
+
The release tag must exactly match the package version, such as `v0.2.0` for
|
|
263
|
+
`"version": "0.2.0"`.
|
|
264
|
+
|
|
265
|
+
There is no generated `dist` tree. OpenCode imports the TypeScript entrypoint,
|
|
266
|
+
and npm publishes the authoritative `src/`, `skills/`, `guidance/`, and
|
|
267
|
+
`patterns/` directories directly.
|
|
268
|
+
|
|
269
|
+
## Credits
|
|
270
|
+
|
|
271
|
+
This project is the OpenCode V2 port of
|
|
272
|
+
[`pi-effect-harness`](https://github.com/mpsuesser/pi-effect-harness). It keeps
|
|
273
|
+
the source guidance and pattern policy while using OpenCode's native skills,
|
|
274
|
+
context hooks, and package loading.
|
|
275
|
+
|
|
276
|
+
## License
|
|
277
|
+
|
|
278
|
+
[MIT](LICENSE)
|