This is the streamspace-plugins sibling of streamspace-dev/streamspace. It hosts the official + community plugin catalog for StreamSpace.
Plugins extend the platform with optional integrations (auth, storage, observability, billing, communication, etc.) without bloating the core. The control plane discovers plugins via the catalog defined here and consumes them at runtime.
streamspace-plugins/
├── official/ # Officially maintained plugins
├── community/ # Community submissions
├── streamspace-slack/ # Top-level layout for legacy plugins
├── streamspace-teams/ # (mid-migration into official/community split)
├── streamspace-discord/
├── streamspace-pagerduty/
├── streamspace-email/
├── streamspace-calendar/
├── streamspace-datadog/
├── streamspace-newrelic/
├── streamspace-sentry/
├── streamspace-elastic-apm/
├── streamspace-honeycomb/
├── streamspace-compliance/
├── streamspace-dlp/
├── streamspace-audit-advanced/
├── streamspace-recording/
├── streamspace-snapshots/
├── streamspace-multi-monitor/
├── streamspace-workflows/
├── streamspace-analytics-advanced/
├── streamspace-auth-saml/
├── streamspace-auth-oauth/
├── streamspace-storage-s3/
├── streamspace-storage-azure/
├── streamspace-storage-gcs/
├── streamspace-billing/
├── streamspace-node-manager/
├── catalog.yaml # Plugin discovery metadata
├── README.md
├── CONTRIBUTING.md
└── claude.md # This file
Most existing plugin directories are stubs (manifest.json + a small *_plugin.go skeleton + README.md). Fleshing them out into working implementations is tracked work — see the project board.
- Extension — UI widgets, dashboard panels, custom session actions
- Webhook — react to lifecycle events (
session.created,user.login,template.updated,audit.violation, …) - Integration — push data out to Slack/Teams/Discord/PagerDuty/Jira/etc.
- Theme — branding, color tokens, accessibility presets
my-plugin/
├── manifest.json # REQUIRED — metadata, permissions, entrypoints
├── index.js (or *.go) # REQUIRED — lifecycle hooks
├── README.md # REQUIRED — what it does, config keys
├── config.schema.json # optional — config validation
├── package.json # optional — Node deps
└── assets/ # optional — icons, screenshots
manifest.json (minimum):
{
"name": "my-plugin",
"version": "1.0.0",
"displayName": "My Plugin",
"description": "What it does",
"type": "extension",
"author": "Your Name",
"license": "MIT",
"permissions": ["read:sessions"],
"entrypoints": { "main": "index.js" }
}index.js lifecycle skeleton:
module.exports = {
async onLoad({ api, config }) {
// initialization
},
async onUnload() {
// cleanup
}
};Available via the streamspace global (or the equivalent injected api for the JS shape):
api.sessions— list, get, terminate, hibernate, wakeapi.users— list, get, group membershipapi.templates— list, getapi.plugins— list, getapi.webhooks.on(event, handler)— subscribe to lifecycle eventsapi.notify(...)— toast/banner the userapi.email,api.storage,api.commands,api.logconfig.get(key),config.set(key, value)
Plugins must declare what they need:
read:sessions/write:sessionsread:users/write:usersread:templates/write:templatesadmin(dangerous — only for genuine admin tooling)network(dangerous — required for any external HTTP call)
Principle of least privilege: ask for the minimum and document why in the README.
The platform is Selkies-GStreamer (WebRTC) only as of April 2026. Plugins that touch the streaming surface (recording, multi-monitor, etc.) should target the Selkies HTTP/WebRTC proxy at /api/v1/http/<session-id>/. The legacy /api/v1/vnc/ and /api/v1/vnc-viewer/ endpoints have been removed from the control plane.
# Helm values
repositories:
plugins:
enabled: true
url: https://github.com/streamspace-dev/streamspace-plugins
branch: main
syncInterval: "1h"streamspace plugin install <name>
streamspace plugin enable <name>
streamspace plugin configure <name>kubectl apply -f https://raw.githubusercontent.com/streamspace-dev/streamspace-plugins/main/<plugin>/manifest.yamlCentral registry consumed by the control plane and the in-product plugin marketplace. Keep it in sync with the directory contents — every plugin needs an entry, with category, type, permissions, and a stable name.
- Fork or branch this repo.
- Create
community/<name>/(orofficial/<name>/if you have commit access and own maintenance). - Implement the required files:
manifest.json, the entry-point file,README.md. - Add an entry to
catalog.yaml. - Open a PR. CI validates the manifest schema and the plugin's basic structure.
- After review and merge, the catalog sync picks it up on the next interval.
Every plugin is reviewed before inclusion in official/. The bar:
- Sandboxed runtime — JS plugins run in an isolated context; Go plugins run in their own goroutine with limited control-plane access
- Rate-limited API access — plugins can't DoS the control plane
- No bundled secrets — config keys must come from the user, not be hard-coded
- Vetted dependencies —
npm audit/go vetclean - Signed releases — official plugins are signed with cosign keyless
streamspace-dev/streamspace— Control Plane API, K8s/Docker agents, Web UI, Helm chartstreamspace-dev/streamspace-templates— Application templates and image build pipelinestreamspace-dev/streamspace.wiki— End-user documentation
When you make changes here:
- One plugin per PR, ideally — small reviewable scope.
- Validate the manifest against the schema before opening the PR.
- Never edit
catalog.yamlby hand if the project has a generation script (checkscripts/); regenerate it from the directory. - Update the README when adding or removing a plugin.
- Don't commit
node_modules/or compiled binaries; the gitignore should already handle this but double-check. - Don't reference the retired wave-based dev workflow (
Wave 28,agent3-validator, …) in PRs or commit messages.
The bulk of the directories above are skeletons. To turn one into a working plugin:
- Read
<plugin>/manifest.jsonto see what permissions and config it claims. - Implement the lifecycle in
<plugin>/<name>_plugin.go(orindex.js):OnLoad/OnEnable— register handlers, validate configOnDisable/OnUnload— deregister, flush state
- Add real test coverage (
<name>_plugin_test.go). - Update the plugin's
README.mdwith usage and config docs. - Open a PR titled
feat(<plugin>): implement <feature>.