“Plugin” currently means a reviewed connector
The name can easily imply a marketplace where arbitrary packages are downloaded and executed at runtime. That is not what has shipped. The current implementation keeps manifests and adapters in the Timeline Studio source tree, registers them during the build and reviews them with the rest of the application. There is no third-party code loader, runtime permission prompt or compatibility negotiation yet.
That limitation is a security feature until those missing pieces exist. A generation connector can touch remote accounts, local AI servers and media bytes. Calling any JavaScript bundle a plugin before defining its permissions would turn an extension label into ambient authority. The development contract is explicit: today, adding a plugin means contributing a reviewed provider adapter to the repository.
provider-session auth
text-to-image · text-to-video
workflow-image · workflow-video
text-to-image · image-to-image
A manifest declares capability; an adapter performs transport
Each provider has two deliberately different responsibilities. Its manifest describes stable identity, runtime class, authentication mode, capabilities, output types and default endpoint. Its adapter connects to the actual SDK or HTTP API, converts the shared request into provider-specific calls and returns normalized outputs. React state is not part of that transport layer.
The shared registry contains exactly three manifests. The hook looks up the corresponding adapter, coordinates connection and generation attempts with AbortController, and passes the result to the host. Adding a fourth provider therefore does not require another provider-specific network branch inside the shared hook.
manifest = identity + runtime + capabilities + auth adapter = connect() + generate() + cancel() + normalizeError() host = validate bytes + decode media + commit My assets hook = lifecycle + supersession + visible job state
The separation matters during failure. A malformed provider response should fail in its adapter or at the host boundary. It should not leave half-created React state, a guessed timeline object or a success message backed only by a URL.
Three providers, three real connection models
Puter.js owns a browser session and popup authorization flow. Connection waits for the provider's actual sign-in result instead of optimistically changing a badge. Image generation calls puter.ai.txt2img; video generation calls puter.ai.txt2vid. The adapter then resolves or downloads the returned media. The Grok image path uses a temporary provider file and removes it after the bytes have been read.
ComfyUI and Stable Diffusion WebUI are local services, but “local” is verified rather than assumed. Their endpoint parser accepts only localhost, 127.0.0.1 or ::1 over HTTP or HTTPS. ComfyUI checks /system_stats; WebUI checks /sdapi/v1/samplers. A network failure is translated into a message that tells the user to check whether the service is running and whether CORS permits the editor origin.
Once connected, ComfyUI submits a workflow to /prompt, polls /history/{prompt_id} and downloads every reported output through /view. WebUI calls either /sdapi/v1/txt2img or /sdapi/v1/img2img and decodes every returned base64 image. The adapter does not silently keep the first file when a provider returns a batch.
A temporary URL is not a completed asset
Generation APIs often return URLs that are signed, session-bound or short-lived. If an editor stores that URL as its result, the thumbnail may work during the session and disappear after a refresh—or expire before export. Timeline Studio defines completion more strictly: the provider must return usable media bytes, and the host must be able to inspect them.
For images, the host reads the file signature, reconciles the declared MIME type, creates an ImageBitmap and rejects a file with no dimensions. PNG, JPEG, WebP and AVIF signatures are recognized. For video, the host creates a temporary object URL and waits for browser metadata so duration and dimensions can be recorded. Object URLs used only for inspection are revoked.
Only after that validation does the host assign asset IDs, create browser-local URLs and prepend the entire result batch to My assets. This is a small but important definition of truth: “complete” means the editor owns decodable media, not that a provider once returned something that looked like a file location.
Generation is not permission to edit
The host commits results to My assets and selects the latest imported item. It does not create a clip, choose a track, move the playhead or infer how long a generated image should remain visible. Those are editorial decisions, even when the prompt was entered from inside an editor.
This boundary also makes batch results legible. If ComfyUI emits several images or videos, all valid outputs become library assets. A user can compare them, reject them, rename them and deliberately insert the chosen media. Automatic placement would collapse generation and editing into one irreversible-looking action and make failure recovery harder.
| Provider adapter may | Provider adapter may not | Host remains responsible for |
|---|---|---|
| Connect to its declared runtime | Read or mutate timeline state | Arbitrating the active job |
| Translate shared requests | Call setUserAssets directly | Validating all returned media |
| Report provider-backed state | Fabricate progress or success | Creating asset IDs and object URLs |
| Return normalized outputs | Insert clips automatically | Committing every valid output |
Cancellation needs an honest verb
The shared hook creates an AbortController for each connection or generation attempt, ignores late callbacks from superseded attempts and prevents two jobs from owning the same inspector surface. Cancelling always stops the editor from waiting. It only claims remote cancellation when the provider exposes a real operation for it.
ComfyUI has an /interrupt endpoint, so its adapter can request cancellation from the local server. Other adapters may only stop client-side work. The difference belongs in user-facing language because “cancelled” can mean two materially different things: the compute stopped, or the editor stopped listening while remote compute may continue.
Progress follows the same discipline. A percentage is shown only when a provider supplies meaningful progress; otherwise the running state remains indeterminate. A polished progress animation is not evidence that an external system knows how much work remains.
What this architecture proves—and what it does not
The code establishes a narrow provider architecture: validated manifests, isolated adapters, loopback restrictions, host-owned output validation, lifecycle coordination and a My assets destination. It provides a repeatable place to add another generation provider without moving transport logic back into a monolithic hook.
It does not prove that every model is available in every region, that Puter account terms or model prices will remain unchanged, that a user's local ComfyUI workflow is safe, or that generated media is accurate or publishable. Provider availability, cost, browser support and content restrictions remain provider-specific. Local endpoints also remain software running on the user's machine and should not be exposed beyond loopback without a separate security design.
Most importantly, this is not yet a general plugin marketplace. Runtime installation would require signed or otherwise attributable packages, permission declarations, version negotiation, sandboxing, revocation and a review model. Until those controls exist, source integration is the honest name for what ships.