Repository navigation
[Feature]: Pi-style extension API for lifecycle hooks, UI contributions, and settings #6837
Replies: 2 comments
|
A Pi status line and a plugin system, opened as a stack of ready PRs. This is a concrete answer to this request (and #6714, #14557), finished so you can judge real code instead of a sketch. No maintainer has agreed to the direction yet. If the answer is no, we close the plugin PRs; the Pi status PRs stand on their own. Each PR was tested at its own head, reviewed, and has real-client evidence: web and desktop, Android where mobile changes, live agent turns where a provider is involved, and a remote Pi extension statuses
Plugin system (local plugins, explicit consent, each in a supervised child process)
Out of scope: plugin administration from mobile, and a mobile view host for plugin views. Both are named in the PR bodies as follow-ups. |
|
Adding a concrete use case for the plugin stack above, from running the We supervise many threads with an external judge service and need:
Is plugin-initiated dispatch in scope for the plugin host, or is a |
Uh oh!
There was an error while loading. Please reload this page.
Before submitting
Area
packages/contracts or packages/shared
Problem or use case
I would like to make T3 Code extensible in a similar spirit to the Pi agent: extensions should be able to react to application and agent lifecycle events, expose their own settings, and contribute small pieces of UI without requiring every integration to be added to T3 Code itself.
A concrete example is an extension that reacts when a user-visible turn settles, performs a user-configured integration, exposes its configuration under Settings, and adds a status indicator or action to the thread UI. Today this requires modifying T3 Code and maintaining a fork.
There are related issues, but they cover separate parts of this problem:
What is missing is one small, coherent extension boundary connecting lifecycle hooks, extension-owned settings, and safe UI contributions.
Proposed solution
Introduce a versioned extension API with two sides:
A manifest could declare an extension ID, version, API version, required capabilities, settings fields, commands, lifecycle subscriptions, and UI contributions.
Initial lifecycle hooks could include:
Initial settings fields could include text, password/secret, boolean, number, textarea, and select. Values should be namespaced by extension ID, validated on the server, preserve disabled/unknown extension configuration, and keep secrets out of client-visible settings.
Initial UI contributions should be deliberately constrained and host-rendered, for example:
Extensions should invoke actions through fixed core RPC methods such as
extensions.list,extensions.getSettings,extensions.updateSettings, andextensions.invokeAction, rather than dynamically adding RPC methods.I do not think the first version should load arbitrary React components. Unlike Pi's single local TUI, T3 Code supports a potentially remote server plus web, desktop, and mobile clients that may be on different versions. A declarative contribution protocol would preserve the remote-ready and multi-surface architecture.
The existing scoped provider-driver registry appears to provide a useful lifecycle pattern for an
ExtensionRegistry, while the canonical provider runtime events and schema-driven provider settings UI provide much of the underlying machinery already.Why this matters
This would let users and organizations add internal integrations, notifications, accessibility helpers, workflow automations, and niche UI actions without requiring each one to become a core feature.
It would reduce pressure for large feature PRs and make it easier to keep private or experimental behavior isolated while still following upstream T3 Code releases.
Smallest useful scope
A narrow first implementation could include:
Non-goals for the first version:
Alternatives considered
Risks or tradeoffs
Project-local extensions should never execute without an explicit trust decision. Extensions should declare capabilities, be failure-isolated, use bounded event delivery, and receive redacted settings. A worker or child-process boundary would be preferable; any in-process first version should be described as trusted-only.
Examples or references
Contribution
I would be happy to start with a small contracts/registry proof of concept after maintainers confirm the desired boundary and smallest acceptable scope.
All reactions