[codex] Move plugin implementations out of repo#2979
Conversation
- centralize plugin client asset resolution and catalog URLs - move automation runtime wiring into a dedicated adapter - add command palette actions for plugin placements
- Add plugin discovery, activation, and cache/runtime isolation - Introduce automations and voice input plugins - Harden Electron launch and thread bootstrap cleanup
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| const displacedPluginIds = yield* activationRegistration.commitActive.pipe( | ||
| Effect.catch((error) => | ||
| Scope.close(pluginScope, Exit.void).pipe(Effect.andThen(Effect.fail(error))), | ||
| ), | ||
| ); |
There was a problem hiding this comment.
🟡 Medium plugins/PluginHost.ts:167
At line 169, if Scope.close(pluginScope, Exit.void) fails, the original commitActive error is lost. The catch handler uses Effect.andThen to chain Effect.fail(error), but if the scope close fails, andThen never executes and the scope-close error propagates instead. This is inconsistent with other Scope.close calls in this function (lines 113, 147, 157, 174) which use Effect.ignoreCause({ log: true }) to ensure cleanup errors don't mask the original failure. Consider using ignoreCause here as well, or at least ensuring the original error is preserved.
- const displacedPluginIds = yield* activationRegistration.commitActive.pipe(
- Effect.catch((error) =>
- Scope.close(pluginScope, Exit.void).pipe(Effect.andThen(Effect.fail(error))),
- ),
- );🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/plugins/PluginHost.ts around lines 167-171:
At line 169, if `Scope.close(pluginScope, Exit.void)` fails, the original `commitActive` error is lost. The catch handler uses `Effect.andThen` to chain `Effect.fail(error)`, but if the scope close fails, `andThen` never executes and the scope-close error propagates instead. This is inconsistent with other `Scope.close` calls in this function (lines 113, 147, 157, 174) which use `Effect.ignoreCause({ log: true })` to ensure cleanup errors don't mask the original failure. Consider using `ignoreCause` here as well, or at least ensuring the original error is preserved.
Evidence trail:
apps/server/src/plugins/PluginHost.ts lines 167-171 (REVIEWED_COMMIT): `Effect.catch((error) => Scope.close(pluginScope, Exit.void).pipe(Effect.andThen(Effect.fail(error))))` — if Scope.close fails, andThen doesn't execute and original error is lost.
apps/server/src/plugins/PluginHost.ts line 113 (REVIEWED_COMMIT): `Scope.close(previousScope, Exit.void).pipe(Effect.ignoreCause({ log: true }))` — uses ignoreCause.
apps/server/src/plugins/PluginHost.ts line 147 (REVIEWED_COMMIT): `Scope.close(pluginScope, Exit.void).pipe(Effect.ignoreCause({ log: true }))` — uses ignoreCause.
apps/server/src/plugins/PluginHost.ts line 157 (REVIEWED_COMMIT): `Scope.close(previousScope, Exit.void).pipe(Effect.ignoreCause({ log: true }))` — uses ignoreCause.
apps/server/src/plugins/PluginHost.ts line 174 (REVIEWED_COMMIT): `Scope.close(previousScope, Exit.void).pipe(Effect.ignoreCause({ log: true }))` — uses ignoreCause.
| documentId: string, | ||
| schema: CollectionSchema<A, I>, | ||
| document: A, | ||
| ) => |
There was a problem hiding this comment.
🟡 Medium plugins/PluginStore.ts:188
In encodeDocument, line 189 calls Schema.decodeUnknownEffect(schema)(document) where document is already of type A (the decoded type). However, decodeUnknownEffect expects input matching the schema's Encoded type I. For schemas with transformations (e.g., NumberFromString where Type=number, Encoded=string), this causes decoding to fail because the function receives number when it expects string. Remove the intermediate decode step and encode directly.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/plugins/PluginStore.ts around line 188:
In `encodeDocument`, line 189 calls `Schema.decodeUnknownEffect(schema)(document)` where `document` is already of type `A` (the decoded type). However, `decodeUnknownEffect` expects input matching the schema's `Encoded` type `I`. For schemas with transformations (e.g., `NumberFromString` where `Type=number`, `Encoded=string`), this causes decoding to fail because the function receives `number` when it expects `string`. Remove the intermediate decode step and encode directly.
Evidence trail:
- apps/server/src/plugins/PluginStore.ts lines 52, 182-208 (at REVIEWED_COMMIT): `CollectionSchema<A, I> = Schema.Codec<A, I>`; `encodeDocument` takes `document: A` and calls `Schema.decodeUnknownEffect(schema)(document)` on line 189
- pnpm-workspace.yaml line 18: effect version is 4.0.0-beta.73
- Effect Schema documentation (https://effect.website/docs/schema/introduction/): Diagram shows `decodeUnknown` goes from right-side `unknown` (expected `I` format) to `A`; `validate` goes from left-side `unknown` (expected `A` format) to `A`
- Web task confirmation: `decodeUnknown` expects Encoded (`I`) format input; calling with Type (`A`) when `A ≠ I` causes ParseError
What changed
plugins:install-devsymlink helper and the installer script.~/dev/<plugin_name>and manual/plugin-local installation.docs/; it now lives with the local~/dev/voice-inputplugin checkout.Why
The T3 Code repository should keep the plugin host, setup contracts, and shared SDK only. Plugin implementations can evolve outside this monorepo without being part of the core workspace or lockfile.
Validation
pnpm exec vp checkpnpm exec vp run typecheckNote
Add plugin host infrastructure with server lifecycle, RPC endpoints, and UI rendering
@t3tools/plugin-apipackage with contracts for server plugins, UI components, manifest schemas, and a test harness.PluginRegistry,PluginStore,PluginHost,PluginPackageResolver, andPluginRuntimeAdapterto manage plugin lifecycle, typed key-value storage, and command invocation.plugins.list,plugins.invoke, andplugins.subscribewith authorization scopes, and a new HTTP routeGET /plugins/assets/*serving plugin client bundles.plugin_documentstable) to persist typed plugin collection data.PluginHostBootstrap, registers UI factories viawindow.T3PluginHost, and renders plugin views at/plugins/$pluginIdand/settings/plugins/$pluginIdroutes.insertComposerTextWithBoundaries, and plugin keybinding dispatch inChatView.📊 Macroscope summarized bf1993c. 40 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted
🗂️ Filtered Issues
No issues evaluated.