[GH-ISSUE #19] feat: External plugin system for standalone binary plugins #3

Closed
opened 2026-03-02 05:12:20 +03:00 by kerem · 0 comments
Owner

Originally created by @dviejokfs on GitHub (Feb 26, 2026).
Original GitHub issue: https://github.com/gotempsh/temps/issues/19

Summary

Temps needs an external plugin architecture where users can drop a compiled binary into ~/.temps/plugins/ and have it automatically discovered, started, and integrated — providing both API endpoints and UI navigation entries.

Motivation

The internal plugin system (TempsPlugin trait) works well for first-party domain crates, but there is no way for third parties (or self-hosted operators) to extend Temps with custom functionality without forking the codebase. An external plugin system would allow:

  • Custom integrations: cron jobs, CI/CD runners, monitoring dashboards, etc.
  • Drop-in deployment: copy a binary to ~/.temps/plugins/, restart Temps, done.
  • Full platform access: plugins get direct database access (same Postgres as Temps) and authenticated API proxying.
  • UI integration: plugins declare nav entries and routes via a manifest, and the frontend dynamically renders them.

Design

Protocol

  • Plugin binaries use a stdout-based JSON handshake: manifestready, then serve HTTP over a Unix domain socket.
  • Temps reverse-proxies requests from /api/x/{plugin_name}/* to the plugin's socket.
  • The frontend fetches /api/x/plugins to get manifests and dynamically adds routes/nav entries.

Architecture

  • Manifest types live in temps-core::external_plugin::manifest (shared by SDK and management crate).
  • Plugin management lives in temps-external-plugins crate, following the standard TempsPlugin pattern with proper service layer, handler, and OpenAPI schema.
  • Plugin authors depend on temps-plugin-sdk, implement the ExternalPlugin trait, and use the temps_plugin_sdk::main!() macro.

Crates

Crate Purpose
temps-core (ext) Shared manifest types (PluginManifest, NavEntry, HandshakeMessage, etc.)
temps-external-plugins Discovery, lifecycle, proxying, API handler — implements TempsPlugin
temps-plugin-sdk SDK for plugin authors: ExternalPlugin trait, main!() macro, PluginContext, TempsAuth extractor

Acceptance Criteria

  • Plugin binaries in ~/.temps/plugins/ are auto-discovered and started on Temps boot
  • Handshake protocol (manifest + ready) works over stdout
  • HTTP requests to /api/x/{plugin_name}/* are proxied to the plugin's Unix socket
  • /api/x/plugins returns all running plugin manifests
  • Frontend dynamically renders plugin nav entries in sidebar, command palette, and project detail
  • Graceful shutdown stops all plugin processes
  • OpenAPI schema includes external plugin endpoints
  • temps-external-plugins follows standard TempsPlugin pattern (no special-casing in console.rs)
  • Example plugin demonstrates full CRUD API
  • All tests pass

Out of Scope (Future Work)

  • UI asset extraction/serving (manifest supports ui: Option<UiManifest> but Temps-side extraction not yet implemented)
  • Plugin hot-reloading
  • Plugin marketplace / registry
Originally created by @dviejokfs on GitHub (Feb 26, 2026). Original GitHub issue: https://github.com/gotempsh/temps/issues/19 ## Summary Temps needs an external plugin architecture where users can drop a compiled binary into `~/.temps/plugins/` and have it automatically discovered, started, and integrated — providing both API endpoints and UI navigation entries. ## Motivation The internal plugin system (`TempsPlugin` trait) works well for first-party domain crates, but there is no way for third parties (or self-hosted operators) to extend Temps with custom functionality without forking the codebase. An external plugin system would allow: - **Custom integrations**: cron jobs, CI/CD runners, monitoring dashboards, etc. - **Drop-in deployment**: copy a binary to `~/.temps/plugins/`, restart Temps, done. - **Full platform access**: plugins get direct database access (same Postgres as Temps) and authenticated API proxying. - **UI integration**: plugins declare nav entries and routes via a manifest, and the frontend dynamically renders them. ## Design ### Protocol - Plugin binaries use a stdout-based JSON handshake: `manifest` → `ready`, then serve HTTP over a Unix domain socket. - Temps reverse-proxies requests from `/api/x/{plugin_name}/*` to the plugin's socket. - The frontend fetches `/api/x/plugins` to get manifests and dynamically adds routes/nav entries. ### Architecture - Manifest types live in `temps-core::external_plugin::manifest` (shared by SDK and management crate). - Plugin management lives in `temps-external-plugins` crate, following the standard `TempsPlugin` pattern with proper service layer, handler, and OpenAPI schema. - Plugin authors depend on `temps-plugin-sdk`, implement the `ExternalPlugin` trait, and use the `temps_plugin_sdk::main!()` macro. ### Crates | Crate | Purpose | |---|---| | `temps-core` (ext) | Shared manifest types (`PluginManifest`, `NavEntry`, `HandshakeMessage`, etc.) | | `temps-external-plugins` | Discovery, lifecycle, proxying, API handler — implements `TempsPlugin` | | `temps-plugin-sdk` | SDK for plugin authors: `ExternalPlugin` trait, `main!()` macro, `PluginContext`, `TempsAuth` extractor | ## Acceptance Criteria - [ ] Plugin binaries in `~/.temps/plugins/` are auto-discovered and started on Temps boot - [ ] Handshake protocol (manifest + ready) works over stdout - [ ] HTTP requests to `/api/x/{plugin_name}/*` are proxied to the plugin's Unix socket - [ ] `/api/x/plugins` returns all running plugin manifests - [ ] Frontend dynamically renders plugin nav entries in sidebar, command palette, and project detail - [ ] Graceful shutdown stops all plugin processes - [ ] OpenAPI schema includes external plugin endpoints - [ ] `temps-external-plugins` follows standard `TempsPlugin` pattern (no special-casing in `console.rs`) - [ ] Example plugin demonstrates full CRUD API - [ ] All tests pass ## Out of Scope (Future Work) - UI asset extraction/serving (manifest supports `ui: Option<UiManifest>` but Temps-side extraction not yet implemented) - Plugin hot-reloading - Plugin marketplace / registry
kerem closed this issue 2026-03-02 05:12:23 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/temps#3
No description provided.