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.
Files changed (118) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +278 -0
  3. package/guidance/effect-first-development.md +1247 -0
  4. package/guidance/post__effect-and-the-near-inexpressible-majesty-of-layers.md +490 -0
  5. package/guidance/post__parse-dont-validate.md +109 -0
  6. package/guidance/progressive-disclosure-guidance.md +38 -0
  7. package/package.json +63 -0
  8. package/patterns/avoid-any.md +37 -0
  9. package/patterns/avoid-data-tagged-error.md +34 -0
  10. package/patterns/avoid-direct-json.md +51 -0
  11. package/patterns/avoid-direct-tag-checks.md +54 -0
  12. package/patterns/avoid-expect-in-if.md +52 -0
  13. package/patterns/avoid-mutable-state.md +70 -0
  14. package/patterns/avoid-native-fetch.md +61 -0
  15. package/patterns/avoid-node-imports.md +86 -0
  16. package/patterns/avoid-non-null-assertion.md +44 -0
  17. package/patterns/avoid-object-type.md +46 -0
  18. package/patterns/avoid-option-getorthrow.md +39 -0
  19. package/patterns/avoid-platform-coupling.md +43 -0
  20. package/patterns/avoid-process-env.md +43 -0
  21. package/patterns/avoid-react-hooks.md +73 -0
  22. package/patterns/avoid-schema-suffix.md +45 -0
  23. package/patterns/avoid-sync-fs.md +68 -0
  24. package/patterns/avoid-try-catch.md +47 -0
  25. package/patterns/avoid-ts-ignore.md +38 -0
  26. package/patterns/avoid-untagged-errors.md +67 -0
  27. package/patterns/avoid-yield-ref.md +46 -0
  28. package/patterns/casting-awareness.md +46 -0
  29. package/patterns/context-tag-extends.md +84 -0
  30. package/patterns/effect-catchall-default.md +61 -0
  31. package/patterns/effect-promise-vs-trypromise.md +47 -0
  32. package/patterns/effect-run-in-body.md +58 -0
  33. package/patterns/imperative-loops.md +76 -0
  34. package/patterns/prefer-arr-sort.md +52 -0
  35. package/patterns/prefer-duration-values.md +56 -0
  36. package/patterns/prefer-effect-fn.md +161 -0
  37. package/patterns/prefer-match-over-switch.md +48 -0
  38. package/patterns/prefer-option-over-null.md +56 -0
  39. package/patterns/prefer-redacted-config.md +70 -0
  40. package/patterns/prefer-schema-class.md +54 -0
  41. package/patterns/require-effect-concurrency.md +83 -0
  42. package/patterns/stream-large-files.md +63 -0
  43. package/patterns/throw-in-effect-gen.md +62 -0
  44. package/patterns/use-clock-service.md +45 -0
  45. package/patterns/use-command-executor-service.md +54 -0
  46. package/patterns/use-console-service.md +54 -0
  47. package/patterns/use-filesystem-service.md +59 -0
  48. package/patterns/use-http-client-service.md +77 -0
  49. package/patterns/use-path-service.md +53 -0
  50. package/patterns/use-random-service.md +45 -0
  51. package/patterns/use-temp-file-scoped.md +66 -0
  52. package/patterns/vm-in-wrong-file.md +51 -0
  53. package/patterns/yield-in-for-loop.md +61 -0
  54. package/skills/effect-ai-chat/SKILL.md +472 -0
  55. package/skills/effect-ai-language-model/SKILL.md +652 -0
  56. package/skills/effect-ai-prompt/SKILL.md +752 -0
  57. package/skills/effect-ai-provider/SKILL.md +668 -0
  58. package/skills/effect-ai-streaming/SKILL.md +418 -0
  59. package/skills/effect-ai-tool/SKILL.md +1132 -0
  60. package/skills/effect-atom-rpc/SKILL.md +488 -0
  61. package/skills/effect-atom-state/SKILL.md +640 -0
  62. package/skills/effect-batching/SKILL.md +614 -0
  63. package/skills/effect-cache/SKILL.md +570 -0
  64. package/skills/effect-cli/SKILL.md +523 -0
  65. package/skills/effect-command-executor/SKILL.md +675 -0
  66. package/skills/effect-concurrency-testing/SKILL.md +612 -0
  67. package/skills/effect-config/SKILL.md +580 -0
  68. package/skills/effect-context-witness/SKILL.md +274 -0
  69. package/skills/effect-domain-modeling/SKILL.md +1212 -0
  70. package/skills/effect-domain-predicates/SKILL.md +867 -0
  71. package/skills/effect-error-handling/SKILL.md +1581 -0
  72. package/skills/effect-fiber/SKILL.md +731 -0
  73. package/skills/effect-filesystem/SKILL.md +624 -0
  74. package/skills/effect-graph/SKILL.md +571 -0
  75. package/skills/effect-http-api/SKILL.md +1760 -0
  76. package/skills/effect-http-client/SKILL.md +989 -0
  77. package/skills/effect-http-server/SKILL.md +920 -0
  78. package/skills/effect-incremental-migration/SKILL.md +362 -0
  79. package/skills/effect-layer-design/SKILL.md +642 -0
  80. package/skills/effect-managed-runtime/SKILL.md +395 -0
  81. package/skills/effect-mcp-server/SKILL.md +608 -0
  82. package/skills/effect-observability/SKILL.md +719 -0
  83. package/skills/effect-optics/SKILL.md +554 -0
  84. package/skills/effect-parallelization/SKILL.md +668 -0
  85. package/skills/effect-path/SKILL.md +296 -0
  86. package/skills/effect-pattern-matching/SKILL.md +914 -0
  87. package/skills/effect-platform-abstraction/SKILL.md +1175 -0
  88. package/skills/effect-platform-layers/SKILL.md +514 -0
  89. package/skills/effect-pubsub-event-bus/SKILL.md +384 -0
  90. package/skills/effect-react-composition/SKILL.md +986 -0
  91. package/skills/effect-react-vm/SKILL.md +675 -0
  92. package/skills/effect-rpc-api/SKILL.md +624 -0
  93. package/skills/effect-rpc-client/SKILL.md +666 -0
  94. package/skills/effect-rpc-cluster/SKILL.md +1623 -0
  95. package/skills/effect-rpc-server/SKILL.md +767 -0
  96. package/skills/effect-scheduling/SKILL.md +124 -0
  97. package/skills/effect-schema-composition/SKILL.md +975 -0
  98. package/skills/effect-schema-v4/SKILL.md +691 -0
  99. package/skills/effect-scope/SKILL.md +682 -0
  100. package/skills/effect-service-implementation/SKILL.md +656 -0
  101. package/skills/effect-socket/SKILL.md +703 -0
  102. package/skills/effect-sql/SKILL.md +781 -0
  103. package/skills/effect-stream/SKILL.md +765 -0
  104. package/skills/effect-testing/SKILL.md +1331 -0
  105. package/skills/effect-typeclass-design/SKILL.md +161 -0
  106. package/skills/effect-wide-events/Article.md +66 -0
  107. package/skills/effect-wide-events/SKILL.md +95 -0
  108. package/skills/effect-workflow/SKILL.md +810 -0
  109. package/src/agent-policy.ts +22 -0
  110. package/src/enforcer.ts +104 -0
  111. package/src/frontmatter.ts +34 -0
  112. package/src/guidance.ts +66 -0
  113. package/src/index.ts +38 -0
  114. package/src/pattern-catalog.ts +115 -0
  115. package/src/pattern-matcher.ts +178 -0
  116. package/src/pattern.ts +97 -0
  117. package/src/skills.ts +29 -0
  118. 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
+ [![npm version](https://img.shields.io/npm/v/opencode-effect-enforcer.svg)](https://www.npmjs.com/package/opencode-effect-enforcer)
4
+ [![license](https://img.shields.io/npm/l/opencode-effect-enforcer.svg)](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)