summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoropencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>2026-03-22 00:51:19 +0000
committeropencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>2026-03-22 00:51:19 +0000
commite82c5a9a28a6ef47927138893e79c22ccb9588ab (patch)
tree75ba524ccb62050cb3d37aed5f80cee245e9451c
parent3236f228fbfbb6255716737a1eea30f060f339fd (diff)
downloadopencode-e82c5a9a28a6ef47927138893e79c22ccb9588ab.tar.gz
opencode-e82c5a9a28a6ef47927138893e79c22ccb9588ab.zip
chore: generate
-rw-r--r--packages/opencode/specs/effect-migration.md33
-rw-r--r--packages/opencode/src/plugin/index.ts4
2 files changed, 22 insertions, 15 deletions
diff --git a/packages/opencode/specs/effect-migration.md b/packages/opencode/specs/effect-migration.md
index 37c70814a..d00bc766b 100644
--- a/packages/opencode/specs/effect-migration.md
+++ b/packages/opencode/specs/effect-migration.md
@@ -82,24 +82,33 @@ The `InstanceState.make` init callback receives a `Scope`, so you can use `Effec
- **Subscriptions**: Use `Effect.acquireRelease` to subscribe and auto-unsubscribe:
```ts
-const cache = yield* InstanceState.make<State>(
- Effect.fn("Foo.state")(function* (ctx) {
- // ... load state ...
-
- yield* Effect.acquireRelease(
- Effect.sync(() => Bus.subscribeAll((event) => { /* handle */ })),
- (unsub) => Effect.sync(unsub),
- )
-
- return { /* state */ }
- }),
-)
+const cache =
+ yield *
+ InstanceState.make<State>(
+ Effect.fn("Foo.state")(function* (ctx) {
+ // ... load state ...
+
+ yield* Effect.acquireRelease(
+ Effect.sync(() =>
+ Bus.subscribeAll((event) => {
+ /* handle */
+ }),
+ ),
+ (unsub) => Effect.sync(unsub),
+ )
+
+ return {
+ /* state */
+ }
+ }),
+ )
```
- **Background fibers**: Use `Effect.forkScoped` — the fiber is interrupted on disposal.
- **Side effects at init**: Config notification, event wiring, etc. all belong in the init closure. Callers just do `InstanceState.get(cache)` to trigger everything, and `ScopedCache` deduplicates automatically.
The key insight: don't split init into a separate method with a `started` flag. Put everything in the `InstanceState.make` closure and let `ScopedCache` handle the run-once semantics.
+
## Scheduled Tasks
For loops or periodic work, use `Effect.repeat` or `Effect.schedule` with `Effect.forkScoped` in the layer definition.
diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts
index 1aed1d5f5..57dcff8f6 100644
--- a/packages/opencode/src/plugin/index.ts
+++ b/packages/opencode/src/plugin/index.ts
@@ -24,9 +24,7 @@ export namespace Plugin {
// Hook names that follow the (input, output) => Promise<void> trigger pattern
type TriggerName = {
- [K in keyof Hooks]-?: NonNullable<Hooks[K]> extends (input: any, output: any) => Promise<void>
- ? K
- : never
+ [K in keyof Hooks]-?: NonNullable<Hooks[K]> extends (input: any, output: any) => Promise<void> ? K : never
}[keyof Hooks]
export interface Interface {