STATUS: ALPHA PREVIEW — StreamSuites Runtime Engine
The StreamSuites Runtime is the authoritative execution layer. Runtime exports are the single source of truth. Dashboards and overlays consume exported artifacts only and remain read-only until live runtime plumbing is explicitly enabled.
- Project status: Late Alpha (
0.3.0-alpha). The runtime is stable enough for export generation and local inspection, but active runtime ↔ UI coupling is still under construction. - Runtime authority: This repository is the authoritative home of the Python-based StreamSuites Runtime Engine. All execution, state, telemetry, exports, lifecycle control, and the Auth API originate here.
- Single source of truth: This repository is the only authoritative source for runtime execution, Auth API behavior, version/build metadata, manifests, and export artifacts. No downstream surface is allowed to override runtime outputs.
- Web surface separation: Public, Creator, and Admin web surfaces live in separate repositories and consume runtime-exported artifacts only. No web surface initiates runtime execution or mutates runtime state.
- What is live: Export generation, schemas, runtime metadata, versioning, and historical scaffolding. Existing exports remain authoritative for inspection.
- What is not live yet: Live chat ingestion, socket wiring, OBS overlay feeds, browser extension hydration, and real-time UI synchronization remain preview-only and are not wired to the runtime.
- Ownership boundary: The runtime guards data-plane correctness and lifecycle control. Web surfaces, overlays, and extensions must remain read-only and avoid mutation paths.
StreamSuites is a modular, multi-platform livestream automation system.
It is the single canonical runtime source for orchestrating streaming data-plane workers and control-plane automation across platforms such as Discord, YouTube, Twitch, Twitter/X, and Rumble.
Tallies are tracked as a first-class runtime concept alongside polls and clips. Schema-level scaffolding is in place for future dashboard and public visibility, but no live mutation paths are exposed.
- Current version:
0.3.0-alpha - Development stage: Late Alpha — features are present but still undergoing hardening, observability improvements, and lifecycle tightening prior to beta stabilization.
- Versioning model: Semantic Versioning with pre-release identifiers (
-alpha,-beta) to signal maturity. Pre-release versions do not guarantee API or schema stability. - Build identifiers: Build values stamp regenerated artifacts, exports, documentation, and binaries for traceability. Build changes may occur without feature changes.
- Authoritative source: This repository defines the authoritative version and build metadata for StreamSuites.
- Runtime authority: Runtime is the single source of truth for VERSION and BUILD.
- Web consumption: All web surfaces must consume
runtime/exports/version.json. - No downstream overrides: Web repositories must never define their own version numbers.
- Runtime/UI separation: Dashboards (including the web dashboard) do not execute runtime logic and are not coupled to runtime lifecycles.
- Export-driven surfaces: Runtime publishes state exclusively via file-based exports (JSON snapshots, manifests, and static HTML replay templates).
- Licensing: Proprietary. Redistribution or reuse outside authorized channels is not permitted.
- Production readiness: Not production-ready. Expect breaking changes, schema refinements, and operational adjustments throughout the late-alpha phase.
- The StreamSuites Runtime repository is the authoritative source for:
- runtime execution (Python runtime engine)
- platform workers
- state and telemetry
- export generation
- manifests and authoritative export metadata
- changelogs and version metadata
- the Auth API and session validation (Python
auth_api.py) - the WinForms Desktop Admin (C# / .NET) and runtime control plane
- All control-plane and data-plane sources originate here.
- The runtime does not serve web UI. Public, Creator, and Admin web surfaces are hosted in separate repositories and domains.
- Dashboards, overlays, and extensions are downstream consumers only.
- The Auth API in this runtime serves authentication and session validation for all surfaces.
The Python runtime engine is the authoritative execution layer for StreamSuites. It is responsible for:
- bootstrapping platform workers and schedulers (
core/) - ingestion, normalization, and telemetry for live platform events (
services/) - authoritative state snapshots and export generation (
runtime/exports/) - enforcing lifecycle control and shutdown ordering across runtimes
- emitting manifests and version metadata consumed by every downstream surface
- providing the Auth API that enforces sessions, roles, and tiers
Downstream surfaces never execute runtime logic and only consume runtime-exported artifacts.
The Auth API lives in this repository and is owned by the runtime. It:
- issues and validates sessions for all audiences (Public, Creator, Admin)
- enforces roles, tiers, and permissions after authentication
- provides authoritative account and audit exports for admin surfaces
- serves as the single source of truth for authentication flows and session state
All web surfaces depend on this API and must not define or override auth logic.
The WinForms Desktop Admin is a local, privileged control plane that runs alongside the runtime. It:
- provides operator access to runtime processes and lifecycle control
- reads runtime exports and snapshots directly from disk
- remains authoritative for local configuration and process management
This role is distinct from web Admin surfaces, which remain read-only.
Versioning, exports, and manifests are owned by the runtime in this repository. The runtime:
- defines the authoritative version/build metadata (
runtime/version.py) - emits export artifacts and manifests under
runtime/exports/ - publishes export snapshots for all downstream consumers
Web surfaces must consume exported artifacts and may not generate their own version/build values or manifests.
- The Discord bot supports per-guild configuration.
- All Discord configuration is scoped by
guild_id. - The runtime is the authoritative executor of Discord behavior.
Discord logging and notifications are configured per guild:
- Logging is disabled by default and must be explicitly enabled with a designated logging channel.
- Notification channels are optional and can be set for general events or per-platform clip notifications.
- Each Discord guild has isolated configuration keyed by
guild_id. - Logging is off by default and must be explicitly enabled with a target channel.
- Notification channels are optional and platform-specific.
Supported notification categories:
- General
- Rumble clips
- YouTube clips
- Kick clips
- Pilled clips
- Twitch clips
- Location:
desktop-admin/ - Lives in this repository.
- Runs locally on the same machine as the runtime.
- Local, privileged, and authoritative.
- Does not use Discord OAuth.
- Can configure all connected guilds without restriction.
- Retains direct filesystem access to runtime exports and snapshots.
- Reads runtime state directly from disk without additional services.
- Can launch and terminate runtime processes as part of a privileged local control plane.
- Manages local paths and configuration to align exports with operator expectations.
- Intended for operators with direct runtime access; this authority model is by design, not a missing security feature.
- Auth API endpoints live in this runtime repository and remain the single source of truth.
- OAuth redirects land on surface-specific domains (
streamsuites.app,creator.streamsuites.app,admin.streamsuites.app) to preserve security boundaries between audiences. - OAuth providers currently include Google, GitHub, and Discord, with surface-specific success pages per audience.
- Email/password signup and login are supported alongside OAuth.
- Roles and tiers (CORE / GOLD / PRO) are enforced after authentication by the runtime, with surface-specific gating layered on top.
- The runtime owns accounts, roles, tiers, permissions, and session validation. Web surfaces consume these decisions and never define their own authority.
- The Auth API serves all web surfaces (Public, Creator, Admin) from this runtime repository.
- Sessions are stored in
runtime/data/accounts.dband issued as thestreamsuites_sessioncookie scoped to.streamsuites.app(SameSite=None, Secure, HttpOnly). - Verification and email-change confirmation links resolve through
https://api.streamsuites.app(or the local auth host in dev).
- Provides an emergency-only admin fallback login to prevent total lockout.
- Disabled by default and requires explicit
.envconfiguration (ADMIN_FALLBACK_USER,ADMIN_FALLBACK_SECRET) on the runtime host. - Intended strictly for emergency access when OAuth providers or identity services are unavailable; normal OAuth remains the primary login method.
- Credentials must never be exposed to frontend code or shared with clients.
- Auth + sessions:
POST /auth/signup/email,POST /auth/signup/password,POST /auth/login/password,POST /auth/login/fallback,GET /auth/session,POST /auth/logout - OAuth login:
GET /auth/login,GET /auth/login/{google,github,discord},GET /auth/callback/{google,github},GET /auth/discord/login/callback - Email verification + changes:
GET /auth/verify/email,POST /auth/verify/resend,POST /auth/email/change/request,GET /auth/email/change/confirm,PATCH /account/email - Account management:
PATCH /account/password,POST /account/onboarding/complete - Billing:
POST /billing/donate/session,POST /billing/webhook - Admin:
GET /admin/users,GET /admin/audit,GET/POST /admin/auth/controls,GET /admin/tier-config,PUT /admin/tier-config,GET /admin/tier-catalog,PUT /admin/policy/admin-bypass,PATCH /admin/accounts/{uuid}/tier,POST /admin/accounts/{uuid}/{suspend|unsuspend|delete|invalidate-sessions|reset-onboarding|force-email-reverify|mark-email-verified},GET /admin/export/{users,audit}.{json,csv},GET /admin/metrics/api
- Transactional email is sent via Resend using
shared/utils/email.py. - Required environment:
RESEND_API_KEY,MAIL_FROM,MAIL_REPLY_TO. - Templates live in
shared/auth/email_templates.pyand cover verification, email-change confirmation, and security alerts. - Auth events capture Resend message IDs for telemetry export.
- Stripe Checkout is used for one-off donations via
POST /billing/donate/session. - Webhook validation uses
STRIPE_WEBHOOK_SECRETand acceptscheckout.session.completedandpayment_intent.payment_failed. - Donation records are appended to
runtime/exports/admin/donations/donations.json. - Stripe mode is inferred from
STRIPE_SECRET_KEY, with live charges gated bySTRIPE_LIVE_ENABLED.
- Web surfaces are not in this repository.
- They consume runtime-exported state only and remain read-only.
- The WinForms Desktop Admin (in this repo) is not replaced by the web surfaces and continues to operate alongside them.
- OAuth-gated surfaces (notably Admin) never gain process control or filesystem access.
- Runtime remains the authoritative executor for all behavior.
- Public, Creator, and Admin surfaces are split by audience and hosted in separate repositories and domains.
Historical note: multiple Pages-based surfaces were previously hosted from a single dashboard repository. That model has been replaced by distinct repositories and domains per audience (Public, Creator, Admin) while keeping the runtime as the central authority.
- StreamSuites (this repo): Runtime engine + Auth API + WinForms Desktop Admin + authoritative exports/version
- StreamSuites-Public: Public web surface @ https://streamsuites.app (GitHub Pages from repo root)
- StreamSuites-Creator: Creator web surface @ https://creator.streamsuites.app (GitHub Pages from repo root)
- StreamSuites-Dashboard (admin): Admin web surface @ https://admin.streamsuites.app (GitHub Pages from
/docs) - StreamSuites-Docs: Docusaurus based Documentation system @ https://docs.streamsuites.app
- StreamSuites-LiveChat-Launcher: Chromium + Firefox launcher extension
- StreamSuites-Creator-Dashboard: WebView2 Creator Dashboard desktop app
docs.streamsuites.apphosts the documentation site.- The docs live in the
StreamSuites-Docsrepository and deploy independently from runtime and web surface repositories. - This repository does not publish documentation content beyond runtime exports and API surfaces.
- Canonical public base: https://streamsuites.app
- Creator base: https://creator.streamsuites.app
- Admin base: https://admin.streamsuites.app
- Docs base: https://docs.streamsuites.app
- OAuth boundary: each domain is a separate OAuth redirect surface.
- Version endpoint (all surfaces): https://admin.streamsuites.app/version.json
runtime/version.py→scripts/update_version.py→runtime/exports/version.json(consumed by all web surfaces)runtime/exports/→ synced into each surface’s publishedshared/state/as needed (Public / Creator / Admin)runtime/exports/admin/-> admin-only account, audit, and donation exports.- Public/Creator/Admin sites remain static consumers unless explicit publishing is added in the future.
- VERSION (e.g.
0.3.0-alpha)- Represents semantic capability level.
- Changes indicate meaningful feature, behavior, or contract evolution.
- BUILD (e.g.
YYYY.MM.DD+NNN)- Represents generated artifacts and CI traceability.
- May change without functional differences.
Version changes imply project evolution.
Build changes imply refreshed artifacts.
- Runtime: Source of truth for version and build metadata.
- WinForms Desktop Admin: Reads and displays runtime version/build directly.
- Web surfaces: Read version/build from
runtime/exports/version.jsonand never define their own values.
runtime/exports/runtime_snapshot.jsonis the authoritative runtime snapshot.- The WinForms Desktop Admin reads snapshots directly from disk.
- Web surfaces read published/exported JSON artifacts only.
- Paths may be configured locally via admin tooling to align snapshot locations with operator needs.
The project emphasizes:
- deterministic behavior
- explicit lifecycle control
- platform-specific correctness
- forward extensibility without architectural rewrites
The first implemented and validated platform was Rumble.
Rumble support is currently paused, but all code remains intact and ready for re-enablement.
core/: runtime entrypoint (app.py), scheduler, job registry, snapshot export loopsauth_api.py: Auth API server (OAuth, email/password, sessions, billing webhook)services/rumble/: Rumble workers, browser client, SSE client, chat helpersshared/: platform-neutral configuration, state publishers, storage, logging (shared/auth/,shared/utils/email.py,shared/runtime/stripe_*)runtime/: exported snapshots, manifests, telemetry, and runtime metadatachangelog/+scripts/: version stamping and release utilitiesservices/{twitch,youtube,discord}/: additional platform runtimes and control-plane implementationsservices/kick/: Kick chat scaffolding (auth + chat stubs, normalized events) pending scheduler wiringservices/pilled/: ingest-only placeholders; no runtime wiring yetservices/chat_replay/: static chat replay scaffolding shipping exportable HTML surfaces (pop-out window and OBS overlay) with mock data onlycontracts/chat_message.schema.json: placeholder unified chat replay contracttemplates/chat_replay_window.html: standalone replay window (mock data)templates/chat_overlay_obs.html: transparent OBS browser-source overlaytemplates/partials/theme_selector.html: theme selection UI stubstatic/chat.css: shared replay stylingstatic/themes/: additive theme overridesstatic/chat_mock_data.js: labeled placeholder messagesREADME.md: scaffolding documentation and future integration path
Update note: This repo tree section has been refreshed to reflect the current file layout while omitting WinForms build artifacts and Visual Studio cache files (for readability and to match ignored output), so the README remains authoritative and consistent with repository contents.
StreamSuites/
├── .github
│ └── workflows
│ ├── auto-build.yml
│ └── publish-dashboard-state.yml
├── changelog
│ ├── changelog.runtime.json
│ ├── index.md
│ ├── README.md
│ └── v0.3.md
├── clips
│ └── output
│ └── .gitkeep
├── core
│ ├── tallies
│ │ ├── __init__.py
│ │ ├── models.py
│ │ └── README.md
│ ├── __init__.py
│ ├── app.py
│ ├── config_loader.py
│ ├── context.py
│ ├── discord_app.py
│ ├── jobs.py
│ ├── ratelimits.py
│ ├── README.md
│ ├── registry.py
│ ├── scheduler.py
│ ├── shutdown.py
│ ├── signals.py
│ └── state_exporter.py
├── data
│ ├── .gitkeep
│ └── streamsuites.db
├── desktop-admin
│ ├── StreamSuites.DesktopAdmin
│ │ ├── assets
│ │ │ ├── bg
│ │ │ │ └── aboutsplash.png
│ │ │ ├── adminshieldcon.ico
│ │ │ ├── adminshieldconwhite.png
│ │ │ ├── adminx.ico
│ │ │ ├── discord-0.svg
│ │ │ ├── discord-muted.svg
│ │ │ ├── discord.png
│ │ │ ├── discord.svg
│ │ │ ├── docscon3d.ico
│ │ │ ├── github-0.svg
│ │ │ ├── github-muted.svg
│ │ │ ├── github-silver.svg
│ │ │ ├── github-white.svg
│ │ │ ├── github.svg
│ │ │ ├── google-0.svg
│ │ │ ├── google-muted.svg
│ │ │ ├── google-silver.svg
│ │ │ ├── google-white.svg
│ │ │ ├── google.svg
│ │ │ ├── kick-0.svg
│ │ │ ├── kick-muted.svg
│ │ │ ├── kick.png
│ │ │ ├── kick.svg
│ │ │ ├── LOG2-3D.png
│ │ │ ├── LOG2TRIM.ico
│ │ │ ├── LOG2TRIM.png
│ │ │ ├── loghealth-green.ico
│ │ │ ├── loghealth-green.png
│ │ │ ├── loghealth-red.ico
│ │ │ ├── loghealth-red.png
│ │ │ ├── loghealth-yellow.ico
│ │ │ ├── loghealth-yellow.png
│ │ │ ├── logo.png
│ │ │ ├── logocircle.png
│ │ │ ├── logoshield-gold.ico
│ │ │ ├── logoshield-gold.png
│ │ │ ├── logoshield-white.ico
│ │ │ ├── logoshield-white.png
│ │ │ ├── logoshield.png
│ │ │ ├── logoshield.svg
│ │ │ ├── pilled-0.svg
│ │ │ ├── pilled-muted.svg
│ │ │ ├── pilled.png
│ │ │ ├── pilled.svg
│ │ │ ├── pubcon.ico
│ │ │ ├── rumble-0.svg
│ │ │ ├── rumble-muted.svg
│ │ │ ├── rumble.png
│ │ │ ├── rumble.svg
│ │ │ ├── sscmattesilver.ico
│ │ │ ├── sscmattex.ico
│ │ │ ├── ssconchrome.ico
│ │ │ ├── ssconchrome.png
│ │ │ ├── ssconchromeblue.ico
│ │ │ ├── ssnewcon.ico
│ │ │ ├── ssnewfavicon.ico
│ │ │ ├── ssxshieldblack.ico
│ │ │ ├── ssxshieldblue.ico
│ │ │ ├── ssxshieldred.ico
│ │ │ ├── ssxshieldsilver.ico
│ │ │ ├── streamsuites.ico
│ │ │ ├── studioconmain.ico
│ │ │ ├── twitch-0.svg
│ │ │ ├── twitch-muted.svg
│ │ │ ├── twitch.png
│ │ │ ├── twitch.svg
│ │ │ ├── twitter-0.svg
│ │ │ ├── twitter-muted.svg
│ │ │ ├── twitter.svg
│ │ │ ├── win1.ico
│ │ │ ├── youtube-0.svg
│ │ │ ├── youtube-muted.svg
│ │ │ ├── youtube.png
│ │ │ └── youtube.svg
│ │ ├── Bridge
│ │ │ ├── BridgeServer.cs
│ │ │ ├── BridgeState.cs
│ │ │ └── RuntimeLifecycleController.cs
│ │ ├── Properties
│ │ │ └── PublishProfiles
│ │ │ ├── FolderProfile.pubxml
│ │ │ └── FolderProfile.pubxml.user
│ │ ├── Runtime
│ │ │ ├── Processes
│ │ │ │ ├── JobObject.cs
│ │ │ │ ├── RuntimeProcessArgs.cs
│ │ │ │ ├── RuntimeProcessConfig.cs
│ │ │ │ ├── RuntimeProcessConfigService.cs
│ │ │ │ ├── RuntimeProcessDefinition.cs
│ │ │ │ ├── RuntimeProcessInstance.cs
│ │ │ │ ├── RuntimeProcessLogEntry.cs
│ │ │ │ ├── RuntimeProcessManager.cs
│ │ │ │ └── RuntimeProcessStatus.cs
│ │ │ └── Services
│ │ │ ├── AuthApiServiceController.cs
│ │ │ ├── CloudflareTunnelServiceController.cs
│ │ │ └── RuntimeServiceController.cs
│ │ ├── Telemetry
│ │ │ └── TimeSeriesWindow.cs
│ │ ├── AboutDialog.cs
│ │ ├── ApiWidgetForm.cs
│ │ ├── App.config
│ │ ├── MainForm.cs
│ │ ├── MainForm.Designer.cs
│ │ ├── MainForm.resx
│ │ ├── Program.cs
│ │ ├── runtime-processes.json
│ │ ├── StreamSuites.DesktopAdmin.csproj
│ │ └── StreamSuites.DesktopAdmin.csproj.user
│ ├── StreamSuites.DesktopAdmin.Core
│ │ ├── AppState.cs
│ │ ├── ModeContext.cs
│ │ ├── PathConfigService.cs
│ │ └── StreamSuites.DesktopAdmin.Core.csproj
│ ├── StreamSuites.DesktopAdmin.Models
│ │ ├── AboutExport.cs
│ │ ├── AdminExports.cs
│ │ ├── ApiMetricsSnapshot.cs
│ │ ├── ApiUsageSeriesSnapshot.cs
│ │ ├── CreatorsExports.cs
│ │ ├── DataSignalsExports.cs
│ │ ├── DiscordConfigExport.cs
│ │ ├── PlatformExports.cs
│ │ ├── PlatformStatus.cs
│ │ ├── RuntimeSnapshot.cs
│ │ ├── StreamSuites.DesktopAdmin.Models.csproj
│ │ ├── TelemetryExports.cs
│ │ ├── TelemetrySnapshot.cs
│ │ └── TriggerCounter.cs
│ ├── StreamSuites.DesktopAdmin.RuntimeBridge
│ │ ├── AdminCommandDispatcher.cs
│ │ ├── FileSnapshotReader.cs
│ │ ├── JsonExportReader.cs
│ │ ├── RuntimeConnector.cs
│ │ └── StreamSuites.DesktopAdmin.RuntimeBridge.csproj
│ ├── Output-Build.txt
│ └── StreamSuites.DesktopAdmin.sln
├── docs
│ ├── assets
│ │ ├── icons
│ │ │ └── ui
│ │ │ ├── profile.svg
│ │ │ └── send.svg
│ │ └── placeholders
│ │ ├── daniel-badge.svg
│ │ ├── daniel.svg
│ │ ├── hotdog.svg
│ │ └── streamsuites.svg
│ ├── creator-guide
│ │ └── billing.md
│ ├── POST_MORTEM.md
│ └── support-metrics.md
├── exports
│ └── public
│ └── .gitkeep
├── livechat
│ ├── index.html
│ ├── livechat.css
│ └── livechat.js
├── media
│ ├── capture
│ │ ├── rumble.py
│ │ ├── twitch.py
│ │ └── youtube.py
│ ├── jobs
│ │ ├── base.py
│ │ ├── clip_job.py
│ │ └── upload_job.py
│ ├── processing
│ │ ├── metadata.py
│ │ ├── transcode.py
│ │ └── trim.py
│ ├── storage
│ │ ├── buffer.py
│ │ ├── cleanup.py
│ │ └── clips.py
│ └── __init__.py
├── rumble_poc
│ ├── BrowserMetrics
│ ├── component_crx_cache
│ │ └── metadata.json
│ ├── Crashpad
│ │ └── settings.dat
│ ├── Default
│ │ ├── AutofillAiModelCache
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── AutofillStrikeDatabase
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── BudgetDatabase
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── Cache
│ │ │ ├── Cache_Data
│ │ │ │ ├── data_0
│ │ │ │ ├── data_1
│ │ │ │ ├── data_2
│ │ │ │ ├── data_3
│ │ │ │ └── index
│ │ │ └── No_Vary_Search
│ │ │ ├── journal.baj
│ │ │ └── snapshot.baf
│ │ ├── chrome_cart_db
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── ClientCertificates
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── Code Cache
│ │ │ ├── js
│ │ │ │ ├── index-dir
│ │ │ │ │ └── the-real-index
│ │ │ │ └── index
│ │ │ └── wasm
│ │ │ ├── index-dir
│ │ │ │ └── the-real-index
│ │ │ └── index
│ │ ├── commerce_subscription_db
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── DawnGraphiteCache
│ │ │ ├── data_0
│ │ │ ├── data_1
│ │ │ ├── data_2
│ │ │ ├── data_3
│ │ │ └── index
│ │ ├── DawnWebGPUCache
│ │ │ ├── data_0
│ │ │ ├── data_1
│ │ │ ├── data_2
│ │ │ ├── data_3
│ │ │ └── index
│ │ ├── discount_infos_db
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── discounts_db
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── Extension Rules
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── MANIFEST-000001
│ │ ├── Extension Scripts
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── MANIFEST-000001
│ │ ├── Extension State
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ ├── LOG.old
│ │ │ └── MANIFEST-000001
│ │ ├── Feature Engagement Tracker
│ │ │ ├── AvailabilityDB
│ │ │ │ ├── LOCK
│ │ │ │ ├── LOG
│ │ │ │ └── LOG.old
│ │ │ └── EventDB
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── GCM Store
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ ├── LOG.old
│ │ │ └── MANIFEST-000001
│ │ ├── GPUCache
│ │ │ ├── data_0
│ │ │ ├── data_1
│ │ │ ├── data_2
│ │ │ ├── data_3
│ │ │ └── index
│ │ ├── Local Storage
│ │ │ └── leveldb
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ ├── LOG.old
│ │ │ └── MANIFEST-000001
│ │ ├── Network
│ │ │ ├── Cookies
│ │ │ ├── Cookies-journal
│ │ │ ├── Network Persistent State
│ │ │ ├── NetworkDataMigrated
│ │ │ ├── Reporting and NEL
│ │ │ ├── Reporting and NEL-journal
│ │ │ ├── SCT Auditing Pending Reports
│ │ │ ├── TransportSecurity
│ │ │ ├── Trust Tokens
│ │ │ └── Trust Tokens-journal
│ │ ├── parcel_tracking_db
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── PersistentOriginTrials
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── Safe Browsing Network
│ │ │ ├── NetworkDataMigrated
│ │ │ ├── Safe Browsing Cookies
│ │ │ └── Safe Browsing Cookies-journal
│ │ ├── Segmentation Platform
│ │ │ ├── SegmentInfoDB
│ │ │ │ ├── LOCK
│ │ │ │ ├── LOG
│ │ │ │ └── LOG.old
│ │ │ ├── SignalDB
│ │ │ │ ├── LOCK
│ │ │ │ ├── LOG
│ │ │ │ └── LOG.old
│ │ │ └── SignalStorageConfigDB
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ └── LOG.old
│ │ ├── Session Storage
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ ├── LOG.old
│ │ │ └── MANIFEST-000001
│ │ ├── Sessions
│ │ │ ├── Session_13410274656979123
│ │ │ ├── Session_13410274819950971
│ │ │ ├── Tabs_13410274665103366
│ │ │ └── Tabs_13410274820063927
│ │ ├── Shared Dictionary
│ │ │ ├── cache
│ │ │ │ ├── index-dir
│ │ │ │ │ └── the-real-index
│ │ │ │ └── index
│ │ │ ├── db
│ │ │ └── db-journal
│ │ ├── shared_proto_db
│ │ │ ├── metadata
│ │ │ │ ├── CURRENT
│ │ │ │ ├── LOCK
│ │ │ │ ├── LOG
│ │ │ │ ├── LOG.old
│ │ │ │ └── MANIFEST-000001
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ ├── LOG.old
│ │ │ └── MANIFEST-000001
│ │ ├── Site Characteristics Database
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ ├── LOG.old
│ │ │ └── MANIFEST-000001
│ │ ├── Sync Data
│ │ │ └── LevelDB
│ │ │ ├── CURRENT
│ │ │ ├── LOCK
│ │ │ ├── LOG
│ │ │ ├── LOG.old
│ │ │ └── MANIFEST-000001
│ │ ├── Account Web Data
│ │ ├── Account Web Data-journal
│ │ ├── Affiliation Database
│ │ ├── Affiliation Database-journal
│ │ ├── BookmarkMergedSurfaceOrdering
│ │ ├── DIPS
│ │ ├── Favicons
│ │ ├── Favicons-journal
│ │ ├── heavy_ad_intervention_opt_out.db
│ │ ├── heavy_ad_intervention_opt_out.db-journal
│ │ ├── History
│ │ ├── History-journal
│ │ ├── LOCK
│ │ ├── LOG
│ │ ├── LOG.old
│ │ ├── Login Data
│ │ ├── Login Data For Account
│ │ ├── Login Data For Account-journal
│ │ ├── Login Data-journal
│ │ ├── Network Action Predictor
│ │ ├── Network Action Predictor-journal
│ │ ├── Preferences
│ │ ├── PreferredApps
│ │ ├── README
│ │ ├── Secure Preferences
│ │ ├── ServerCertificate
│ │ ├── ServerCertificate-journal
│ │ ├── SharedStorage
│ │ ├── Shortcuts
│ │ ├── Shortcuts-journal
│ │ ├── Top Sites
│ │ ├── Top Sites-journal
│ │ ├── trusted_vault.pb
│ │ ├── Web Data
│ │ └── Web Data-journal
│ ├── extensions_crx_cache
│ │ └── metadata.json
│ ├── GraphiteDawnCache
│ │ ├── data_0
│ │ ├── data_1
│ │ ├── data_2
│ │ ├── data_3
│ │ └── index
│ ├── GrShaderCache
│ │ ├── data_0
│ │ ├── data_1
│ │ ├── data_2
│ │ ├── data_3
│ │ └── index
│ ├── segmentation_platform
│ │ ├── ukm_db
│ │ └── ukm_db-wal
│ ├── ShaderCache
│ │ ├── data_0
│ │ ├── data_1
│ │ ├── data_2
│ │ ├── data_3
│ │ └── index
│ ├── first_party_sets.db
│ ├── first_party_sets.db-journal
│ ├── Last Browser
│ ├── Last Version
│ ├── Local State
│ └── Variations
├── runtime
│ ├── admin
│ │ ├── auth_controls.json
│ │ ├── chat_triggers.json
│ │ ├── creators.json
│ │ ├── integrations.json
│ │ ├── jobs.json
│ │ ├── permissions.json
│ │ ├── rate_limits.json
│ │ └── tiers.json
│ ├── data
│ │ └── accounts.db
│ ├── exports
│ │ ├── admin
│ │ │ ├── audit
│ │ │ │ ├── audit.json
│ │ │ │ └── tmpu8gnpp5u
│ │ │ └── users
│ │ │ ├── tmpc7dpld6s
│ │ │ └── users.json
│ │ ├── telemetry
│ │ │ ├── auth_events.json
│ │ │ ├── errors.json
│ │ │ ├── events.json
│ │ │ ├── rates.json
│ │ │ ├── tmp076fi3_5
│ │ │ ├── tmp51uhqc6_
│ │ │ ├── tmp_1s4idh9
│ │ │ ├── tmpjhws_z56
│ │ │ ├── tmppj2dq2z0
│ │ │ ├── tmpqx_cbo9m
│ │ │ └── tmptwfxz_hg
│ │ ├── about.admin.json
│ │ ├── about.public.json
│ │ ├── changelog.json
│ │ ├── changelog.runtime.json
│ │ ├── clips.json
│ │ ├── meta.json
│ │ ├── platforms.json
│ │ ├── polls.json
│ │ ├── README.md
│ │ ├── roadmap.json
│ │ ├── runtime_snapshot.json
│ │ ├── scoreboards.json
│ │ ├── tallies.json
│ │ ├── tmp7y_po37m
│ │ ├── tmpwc9v6sjt
│ │ └── version.json
│ ├── signals
│ │ ├── chat_events.json
│ │ ├── poll_votes.json
│ │ ├── score_events.json
│ │ └── tally_events.json
│ └── version.py
├── schemas
│ ├── creators.schema.json
│ ├── discord.schema.json
│ ├── platforms.schema.json
│ ├── system.schema.json
│ ├── tiers.schema.json
│ └── triggers.schema.json
├── scripts
│ ├── bootstrap.py
│ ├── publish_dashboard_state.ps1
│ ├── publish_state.py
│ ├── test_ses_send.py
│ ├── update_version.py
│ └── validate_config.py
├── services
│ ├── chat_api
│ │ ├── __init__.py
│ │ └── server.py
│ ├── chat_replay
│ │ ├── contracts
│ │ │ └── chat_message.schema.json
│ │ ├── static
│ │ │ ├── themes
│ │ │ │ ├── theme-default.css
│ │ │ │ ├── theme-midnight.css
│ │ │ │ └── theme-slate.css
│ │ │ ├── chat.css
│ │ │ ├── chat_live_input.css
│ │ │ └── chat_mock_data.js
│ │ ├── templates
│ │ │ ├── partials
│ │ │ │ ├── footer_live.html
│ │ │ │ ├── footer_replay.html
│ │ │ │ ├── theme_menu.html
│ │ │ │ └── theme_selector.html
│ │ │ ├── chat_overlay_obs.html
│ │ │ ├── chat_replay_window.html
│ │ │ └── chat_window.html
│ │ └── README.md
│ ├── clips
│ │ ├── __init__.py
│ │ ├── encoder.py
│ │ ├── exporter.py
│ │ ├── manager.py
│ │ ├── models.py
│ │ ├── storage.py
│ │ ├── uploader.py
│ │ └── worker.py
│ ├── discord
│ │ ├── commands
│ │ │ ├── __init__.py
│ │ │ ├── admin.py
│ │ │ ├── admin_commands.py
│ │ │ ├── creators.py
│ │ │ ├── public.py
│ │ │ ├── README.md
│ │ │ └── services.py
│ │ ├── runtime
│ │ │ ├── __init__.py
│ │ │ ├── lifecycle.py
│ │ │ ├── README.md
│ │ │ └── supervisor.py
│ │ ├── tasks
│ │ │ ├── pilled_live.py
│ │ │ ├── README.md
│ │ │ ├── rumble_live.py
│ │ │ ├── twitch_live.py
│ │ │ ├── twitter_posting.py
│ │ │ └── youtube_live.py
│ │ ├── announcements.py
│ │ ├── client.py
│ │ ├── embeds.py
│ │ ├── guild_logging.py
│ │ ├── heartbeat.py
│ │ ├── logging.py
│ │ ├── permissions.py
│ │ ├── README.md
│ │ └── status.py
│ ├── kick
│ │ ├── api
│ │ │ ├── __init__.py
│ │ │ └── chat.py
│ │ ├── models
│ │ │ ├── __init__.py
│ │ │ └── message.py
│ │ ├── workers
│ │ │ ├── __init__.py
│ │ │ ├── chat_worker.py
│ │ │ └── livestream_worker.py
│ │ ├── __init__.py
│ │ └── README.md
│ ├── pilled
│ │ ├── api
│ │ │ ├── chat.py
│ │ │ └── livestream.py
│ │ └── README.md
│ ├── rumble
│ │ ├── api
│ │ │ ├── channel_page.py
│ │ │ ├── chat.py
│ │ │ └── chat_post.py
│ │ ├── browser
│ │ │ ├── __init__.py
│ │ │ └── browser_client.py
│ │ ├── chat
│ │ │ ├── rest_client.py
│ │ │ ├── sse.py
│ │ │ └── tombi_stream.py
│ │ ├── models
│ │ │ ├── chat_event.py
│ │ │ ├── message.py
│ │ │ └── stream.py
│ │ ├── workers
│ │ │ ├── chat_worker.py
│ │ │ └── livestream_worker.py
│ │ └── chat_client.py
│ ├── triggers
│ │ ├── __init__.py
│ │ ├── actions.py
│ │ ├── base.py
│ │ ├── README.md
│ │ ├── registry.py
│ │ └── validation.py
│ ├── twitch
│ │ ├── api
│ │ │ ├── chat.py
│ │ │ └── livestream.py
│ │ ├── models
│ │ │ └── message.py
│ │ ├── workers
│ │ │ └── chat_worker.py
│ │ └── README.md
│ ├── twitter
│ │ ├── api
│ │ │ ├── auth.py
│ │ │ └── posting.py
│ │ └── workers
│ │ └── posting_worker.py
│ └── youtube
│ ├── api
│ │ ├── chat.py
│ │ └── livestream.py
│ ├── models
│ │ ├── message.py
│ │ └── stream.py
│ ├── workers
│ │ ├── chat_worker.py
│ │ └── livestream_worker.py
│ └── README.md
├── shared
│ ├── auth
│ │ ├── __init__.py
│ │ ├── accounts.py
│ │ └── email_templates.py
│ ├── chat
│ │ └── events.py
│ ├── config
│ │ ├── chat_behaviour.json
│ │ ├── clip_rules.json
│ │ ├── creators.json
│ │ ├── discord.json
│ │ ├── discord.py
│ │ ├── logging.json
│ │ ├── monetization.json
│ │ ├── platform_overrides.json
│ │ ├── platforms.json
│ │ ├── posting_rules.json
│ │ ├── ratelimits.json
│ │ ├── ratelimits.schema.json
│ │ ├── services.json
│ │ ├── services.py
│ │ ├── system.json
│ │ ├── system.py
│ │ ├── tiers.json
│ │ └── triggers.json
│ ├── logging
│ │ ├── levels.py
│ │ └── logger.py
│ ├── platforms
│ │ ├── __init__.py
│ │ └── state.py
│ ├── public_exports
│ │ ├── __init__.py
│ │ ├── clips.py
│ │ ├── polls.py
│ │ └── publisher.py
│ ├── ratelimiter
│ │ └── governor.py
│ ├── runtime
│ │ ├── __init__.py
│ │ ├── admin_contract.py
│ │ ├── chat_context.py
│ │ ├── hot_reload.py
│ │ ├── quotas.py
│ │ ├── quotas_snapshot.py
│ │ ├── scoreboards_snapshot.py
│ │ ├── stripe_client.py
│ │ ├── stripe_webhook_store.py
│ │ └── telemetry.py
│ ├── scoreboards
│ │ ├── placeholders.py
│ │ ├── README.md
│ │ ├── registry.py
│ │ ├── schema.json
│ │ └── snapshot.py
│ ├── state
│ │ ├── chat_logs
│ │ │ ├── rumble
│ │ │ │ └── .gitkeep
│ │ │ └── .gitkeep
│ │ ├── creators
│ │ │ └── daniel.json
│ │ ├── discord
│ │ │ ├── guilds
│ │ │ │ └── .gitkeep
│ │ │ ├── README.md
│ │ │ └── runtime.json
│ │ ├── scoreboards
│ │ │ ├── creators
│ │ │ │ └── .gitkeep
│ │ │ ├── snapshots
│ │ │ │ └── .gitkeep
│ │ │ └── .gitkeep
│ │ ├── jobs.json
│ │ ├── quotas.json
│ │ └── system.json
│ ├── storage
│ │ ├── chat_events
│ │ │ ├── __init__.py
│ │ │ ├── index.py
│ │ │ ├── reader.py
│ │ │ ├── schema.json
│ │ │ ├── store.py
│ │ │ └── writer.py
│ │ ├── scoreboards
│ │ │ ├── exporter.py
│ │ │ ├── importer.py
│ │ │ └── README.md
│ │ ├── state
│ │ │ └── discord
│ │ │ └── discord_status.json
│ │ ├── atomic.py
│ │ ├── file_lock.py
│ │ ├── paths.py
│ │ ├── state_publisher.py
│ │ └── state_store.py
│ └── utils
│ ├── email.py
│ ├── files.py
│ ├── hashing.py
│ ├── retry.py
│ └── time.py
├── src
│ └── pages
│ └── index.tsx
├── tests
│ ├── __init__.py
│ └── test_auth_accounts.py
├── .env.example
├── .gitignore
├── auth_api.py
├── COMMERCIAL-LICENSE-NOTICE.md
├── EULA.md
├── LICENSE
├── README.md
├── requirements.txt
├── rumble_chat_poc.py
├── RUNTIME_AUDIT_REPORT.md
├── test_rumble_api.py
└── twitch_chat_poc.py
StreamSuites Desktop Admin is a WinForms-based administrator console that reads
runtime-exported snapshots and surfaces platform health, platform enablement,
and telemetry freshness in a native desktop experience. The admin app uses a
Runtime Bridge layer (StreamSuites.DesktopAdmin.RuntimeBridge) to read
runtime_snapshot.json from the runtime's export directory and projects the
data into a grid with tray-aware health indicators, per-platform inspectors,
and configurable refresh cadences.
- Purpose: give operators a lightweight desktop UI that mirrors runtime
exports without adding new mutation paths. Snapshot reading is isolated in the
Runtime Bridge (
FileSnapshotReader+RuntimeConnector), and all computations are held inStreamSuites.DesktopAdmin.Core(AppState,ModeContext). - Runtime interaction: reads snapshot files written by the Python runtime; no direct sockets or API calls are required. Platform counts, staleness thresholds, and snapshot metadata are displayed inline with color-coded health badges and a tray icon.
- Progress:
[██████░░░░]Snapshot reading, grid rendering, and health/tray surfacing are live. Runtime lifecycle controls (reserved inRuntimeExecutablePath) are staged for a later milestone.
- Start the runtime exports loop: launch the Python runtime so it keeps
writing
runtime/exports/runtime_snapshot.json(for examplepython -m core.appor the scheduler entrypoint used in your environment). - Point Desktop Admin at the snapshot directory: update
desktop-admin/StreamSuites.DesktopAdmin/App.configSnapshotDirectoryto the absolute path of the runtime export root (e.g., theruntime/exportsdirectory in this repo or a published admin web surface checkout such as../StreamSuites-Admin/docs/shared/state). The default file name remainsruntime_snapshot.jsonbut can be overridden viaSnapshotFileName. - Build and run the WinForms app: open
desktop-admin/StreamSuites.DesktopAdmin.slnin Visual Studio on Windows and run theStreamSuites.DesktopAdminproject. The app will refresh snapshots on the interval defined bySnapshotRefreshIntervalMsand mark stale states usingSnapshotStaleAfterSeconds.
When both processes are active, the desktop admin presents live platform and telemetry status sourced from the runtime exports while keeping the runtime the sole authority for state changes.
The Desktop Admin includes a Runtimes page for launching and monitoring local runtime processes with inline log streaming (stdout/stderr). This is a log viewer with lifecycle controls, not an interactive terminal.
Config file locations (first match wins):
%LOCALAPPDATA%\\StreamSuites\\runtime-processes.jsondesktop-admin/StreamSuites.DesktopAdmin/runtime-processes.json(next to the app executable; used as the dev fallback in this repo)
Schema (runtime-processes.json):
{
"stop_all_on_exit": false,
"processes": [
{
"id": "runtime",
"display_name": "StreamSuites Runtime",
"working_dir": "..\\\\..\\\\..\\\\runtime",
"exe": "python",
"args": ["-m", "core.app"],
"env": { "STREAMSUITES_ENV": "dev" },
"auto_start": false,
"show_in_ui": true,
"start_in_external_terminal_by_default": false
}
]
}Adding a new runtime:
- Add a new object to the
processesarray. - Use a stable
id(used for tab keys and log file naming). - Use
argsas either a string or an array; arrays are passed as discrete arguments. - Relative
working_dirvalues resolve from the Desktop Admin executable directory.
Known limitations:
- Inline consoles are log viewers only (stdout/stderr). Interactive input
requires
Open Terminal. - External terminal launches are not log-captured by the inline viewer.
- Logs are capped in-memory (default 10,000 lines; adjustable per runtime tab).
- SSE_BEST_EFFORT (default): connects to
https://web7.rumble.com/chat/api/chat/<CHAT_ID>/streamwith the live browser cookies/headers. HTTP 204 responses are treated as keepalives, not failures, and do not trigger exponential backoff. Onlytext/event-streampayloads are parsed; non-SSE responses cap retries and cause a downgrade. - DOM_MUTATION (authoritative fallback): attaches a MutationObserver inside the chat iframe to capture newly added message nodes. Each captured node is normalized into the runtime message record (username, text, timestamp when present) so ingest stays deterministic even when the SSE endpoint is silent or blocked. This mode is activated automatically when SSE stays quiet beyond the configured window or explicitly fails to connect.
- DISABLED: terminal state used when no ingest path can be attached (e.g., chat iframe missing). The worker logs the disabled state but keeps the process alive.
The worker logs the active ingest mode at startup and every downgrade event. DOM send remains isolated and continues regardless of ingest path.
- Iframe-scoped DOM send: outbound chat messages target the chat iframe
directly. The bot focuses
#chat-message-text-input, dispatches React-safe DOM events, and clicks thebutton.chat--sendcontrol. Enter is never pressed to avoid monetization modals or key-capture side effects. - Payment / monetization guard: known Rumble monetization modals are detected and closed before sending. All selectors used for sending are logged for observability and the send will abort (not fall back to Enter) if required elements are missing.
- No REST chat sends: outbound chat remains DOM-driven; no REST chat send endpoints are used.
Rumble chat handling is split into two independent, cooperating paths so that send reliability is preserved even when ingest requirements change:
- DOM send (Playwright): authenticated browser session drives the chat input and button click. This path relies on Playwright only and is unaffected by SSE headers or cookies.
- SSE ingest (httpx): authoritative read path that mirrors the browser
session. The SSE request must include the browser's cookies, user-agent,
Origin
https://rumble.com, and Referer set to the livestream watch URL. Missing any of these headers causes Rumble to return HTTP 204 withcontent-type=text/html, which prevents events from flowing.
- Rumble's SSE endpoint validates the authenticated session using both cookies and CSRF-style headers derived from the browser context. Cookies alone no longer authorize the stream, and requests without the proper User-Agent, Origin, and Referer are rejected with empty responses.
- The runtime now exports cookies directly from the Playwright context and
injects them as both structured cookie jars and
Cookieheaders to match the browser.
- A 204 response with
content-type=text/htmloften means the server is not ready to emit events yet. The runtime now treats these as keepalives rather than failures and holds the connection without exponential backoff. Only repeated non-SSE responses or stream errors trigger a downgrade to the DOM mutation ingest path.
- Rumble SSE availability is environment-dependent; repeated non-SSE responses will trigger a downgrade to DOM mutation ingest while HTTP 204 responses are treated as keepalives.
- A logged-in Rumble profile is still required in the persistent Playwright context before runtime start.
- DOM chat sending requires the chat iframe (
#chat-message-text-inputandbutton.chat--send) to be present; if Rumble ships DOM changes, selectors may need to be updated before send succeeds. - Baseline cutoffs prefer DOM-visible timestamps; if both DOM and the
livestream API are unreachable, the worker falls back to
now()without crashing and keeps ingest mode stateful. - APIRequestContext is intentionally avoided during ingest to prevent TLS/X509
crashes and cross-talk with the Playwright automation session; HTTP calls use
isolated
httpxclients with browser-derived cookies/headers instead.
- Status: Alpha preview, export-driven. Runtime stays authoritative for data snapshots but is not yet connected to the dashboard UI or any live chat socket feeds.
- Current snapshot: 0.3.0-alpha (Build 2025.04) remains the active late-alpha reference state.
- Operational impact: chat runtime plumbing, live socket ingestion, and overlay feeds are not live; dashboard and overlay views are preview-only and rely on exported/mock data.
- Dashboard and exports: schemas and exports continue to be maintained for read-only consumption; UI consumers must not assume live connectivity until runtime wiring is delivered.
The runtime is the authoritative data source, signal processor, and
export generator for the Data & Signals admin surface
(StreamSuites-Admin dashboard). It owns raw events and controls how they are shaped
for consumption while keeping admin access strictly read-only. Snapshot files
under runtime/exports/, runtime/signals/, and runtime/admin/ are
deterministic, timestamped JSON documents that can be mirrored into the admin
surface repository or any static host. Public and Creator surfaces are separate
consumers and never mutate runtime state.
- Authoritative data source: runtime workers own the canonical state for clips, polls, tallies, scoreboards, creators, and quotas.
- Signal processor: normalized chat, poll, tally, and score events are captured for dashboard inspection without enabling writes or action execution.
- Export generator: deterministic JSON snapshots are produced for public galleries, dashboard-only operations, and internal integration surfaces.
- Telemetry snapshots:
runtime/exports/telemetry/surfaces read-only operational events, rolling rate aggregates, and trimmed error records so the dashboard can poll live health signals from static hosting surfaces.
- Source of truth:
runtime/version.pyremains the canonical version declaration. All downstream JSON surfaces derive from this value. - Changelog + roadmap alignment:
scripts/update_version.pystamps the runtime version acrosschangelog/changelog.runtime.json, exported changelog files, and the admin surfaceversion.jsonmanifest when available. - About documentation: the runtime owns version stamping for the admin
surface's JSON-driven About content (e.g.,
docs/about/about_part*.json).scripts/update_version.pyupdates theversionfield for every About JSON document it can find under<dashboard-root>/about/while keeping runtime execution paths free of About dependencies.- Usage:
python scripts/update_version.py 0.3.0-alpha --build 2025.04 --dashboard-root ../StreamSuites-Admin/docs - If the admin surface checkout is absent, the script safely skips admin updates while keeping runtime metadata in sync.
- Usage:
- Admin surface consumption is read-only. Snapshots are written by the runtime
and optionally mirrored into the admin surface
docs/data/root or another hosting path. - Snapshots include a
metablock with timestamps, source identifiers, and visibility tags (public,dashboard-only,internal-only) so the dashboard can filter without relying on file placement alone. - Future sync paths (e.g., file-based or HTTP) must continue to respect the read-only boundary; no live mutation from dashboard surfaces is permitted.
| File | Location | Visibility | Notes |
|---|---|---|---|
clips.json |
runtime/exports/ |
Public | Published clips snapshot, safe for public galleries. |
polls.json |
runtime/exports/ |
Public | Poll questions + aggregated votes, no voter identifiers. |
tallies.json |
runtime/exports/ |
Public | Aggregate tally counts only. |
scoreboards.json |
runtime/exports/ |
Public | Ranked scoreboard entries with scores. |
meta.json |
runtime/exports/ |
Public | Manifest describing the export surface. |
telemetry/events.json |
runtime/exports/telemetry/ |
Public | High-level runtime events (timestamp, source, severity, message). |
telemetry/rates.json |
runtime/exports/telemetry/ |
Public | Rolling activity counters for chat, triggers, and actions (60s + 5m windows). |
telemetry/errors.json |
runtime/exports/telemetry/ |
Public | Lightweight error records scoped to subsystem/error type without stack traces. |
telemetry/auth_events.json |
runtime/exports/telemetry/ |
Dashboard-only | Auth and security event summaries with redacted identifiers. |
chat_events.json |
runtime/signals/ |
Dashboard-only | Normalized chat events for inspection. |
poll_votes.json |
runtime/signals/ |
Dashboard-only | Individual poll vote events without personal data. |
tally_events.json |
runtime/signals/ |
Dashboard-only | Increment events for tallies. |
score_events.json |
runtime/signals/ |
Dashboard-only | Score adjustments feeding scoreboards. |
creators.json |
runtime/admin/ |
Dashboard-only | Creator registry snapshot. |
chat_triggers.json |
runtime/admin/ |
Dashboard-only | Trigger definitions for reference only. |
jobs.json |
runtime/admin/ |
Dashboard-only | Job queue visibility (read-only). |
rate_limits.json |
runtime/admin/ |
Dashboard-only | Rate limit policies visible to operators. |
auth_controls.json |
runtime/admin/ |
Dashboard-only | Auth kill switches and signup controls for operators. |
tiers.json |
runtime/admin/ |
Dashboard-only | Tier configuration snapshot (authoritative for policy). |
integrations.json |
runtime/admin/ |
Internal-only | Integration endpoints and statuses. |
permissions.json |
runtime/admin/ |
Internal-only | Placeholder for future principal/role mapping. |
admin/users/users.json |
runtime/exports/admin/ |
Admin-only | Account snapshot export for admin surfaces. |
admin/audit/audit.json |
runtime/exports/admin/ |
Admin-only | Audit trail export for admin surfaces. |
admin/donations/donations.json |
runtime/exports/admin/ |
Admin-only | Stripe donation records (created by billing webhook). |
- Runtime authors maintain the canonical changelog structure in
changelog/changelog.runtime.json; this file defines the authoritative JSON shape expected by the dashboard. - Exports for distribution live under
runtime/exports/changelog.runtime.jsonand must be produced manually or by CI tooling — the runtime does not emit changelog files during execution. - The admin web surface repository merges and renders runtime and admin changelog surfaces client-side; no manual merging is required once the export is updated.
- Public changelog views remain a merged surface while the runtime stays authoritative over runtime-originated entries.
- The runtime remains the authoritative source for changelog data, while the dashboard stays read-only and presentational when rendering the merged public surface.
StreamSuites is evolving into a multi-runtime architecture while remaining a single repository. Runtimes are explicitly isolated by responsibility and started by a shared scheduler:
- Streaming runtimes (per platform) live under
core/app.pyand platform services. They own ingestion, publishing, and data-plane orchestration. - The Discord control-plane runtime lives under
core/discord_app.py(standalone entrypoint) and is optionally started by the scheduler. It offers admin/status commands and notification routing without embedding ingestion. - Shared configuration and state live under
shared/, with platform-neutral helpers underservices/. - Rumble Playwright ownership is centralized:
RumbleLivestreamWorkerstarts a single persistent browser instance, andRumbleChatWorkerreuses that page and chat iframe without opening extra tabs.
Both entrypoints are independent runtime processes. The scheduler coordinates lifecycles while keeping control-plane behavior separate from streaming logic.
The runtime owns a deterministic, SQLite-backed clipping module that runs in the background with bounded concurrency. Core properties:
- Purpose: accept clip requests, encode with FFmpeg, upload to a default Rumble destination, and export state for the dashboard.
- Lifecycle states (persisted and exported):
queued,encoding,encoded,uploading,published,failed. - Encoding model: background worker (
services/clips/worker.py) with default concurrency of2(configurable viashared/config/system.json). Output naming is deterministic:clips/output/{clip_id}.mp4withclip_idas a 6-character alphanumeric token. - SQLite usage: tables
clips,clip_jobs, andclip_state_historylive indata/streamsuites.dband are created on boot if missing. State changes are recorded atomically for observability. - FFmpeg dependency: the runtime defaults to
X:\\ffmpeg\\bin\\ffmpeg.exe(Windows-first) and falls back toffmpegon PATH if that path does not exist locally. No auto-installation is attempted. - Export surface: snapshots are written to
shared/state/clips.jsonevery 30 seconds and immediately on state changes, mirroring to the dashboard publish root when configured. - Destination resolution: the default upload target is read dynamically
from
shared/config/system.json(clips.default_destination.channel_url) and currently points tohttps://rumble.com/c/StreamSuites. Architecture permits future per-creator overrides without changing the runtime contract.
- Platform-agnostic trigger registry lives under
services/triggers/. - Triggers evaluate normalized chat events and emit action descriptors (pure data). Execution of any action is intentionally deferred to a later phase.
- Trigger types are design-locked, even when partially scaffolded:
- Command triggers (e.g.,
!clip,!ping) - Regex-based triggers
- Keyword-based triggers
- Cooldowns across user / creator / global scopes
- Command triggers (e.g.,
- The registry is creator-scoped and platform-neutral so chat workers can publish uniformly shaped events without embedding business logic.
- QuotaTracker (enforcement only): in-process daily quota enforcement with buffer + hard-cap handling; tracks usage per creator/platform without writing files or persisting state.
- QuotaRegistry (authoritative, in-memory): global registry that owns all QuotaTrackers for the running process; exposes snapshots for aggregation.
- Snapshot merge: runtime cadence aggregates all registered trackers via
shared/runtime/quotas_snapshot.pyand writes a singleshared/state/quotas.jsondocument throughDashboardStatePublisher(optionally mirrored to the dashboard publish root).
- Runtime ownership: control-plane + streaming runtimes own authoritative
state generation (jobs, triggers, quotas) under
shared/state/and publish viaDashboardStatePublisher. Quota enforcement and cadence loops live only in the runtime. - Admin dashboard consumption: the admin dashboard is read-only; it reads published state snapshots (jobs, runtime status, quotas) and never mutates runtime state. Overrides are handled through query parameters and static hosting roots without changing runtime behavior.
The Discord control-plane runtime emits live snapshots for the admin dashboard under
shared/state/discord/runtime.json (runtime + heartbeat state) and
shared/state/jobs.json (job queue/timestamps). The streaming runtime exports
shared/state/runtime_snapshot.json via core/state_exporter.py, reflecting
platform enablement, telemetry toggles, creator registry status, and recent
heartbeats. Snapshots are written
atomically and can optionally be mirrored into the dashboard hosting root by
setting DASHBOARD_STATE_PUBLISH_ROOT (or STREAMSUITES_STATE_PUBLISH_ROOT)
to the Pages/bucket checkout path. If unset, the runtime will auto-detect a
local ../StreamSuites-Admin checkout (docs root) when present. A helper
script is available for cron or CI runs when the runtime is not active:
python scripts/publish_state.py --target ../StreamSuites-Admin/docsThe admin dashboard now resolves state roots in the following order:
stateRootquery parameter (persisted tolocalStorageasstreamsuites.stateRootOverridefor future loads)- The published
./shared/state/directory within the dashboard hosting root - Fallback to the runtime repository's raw URL:
https://raw.githubusercontent.com/BSMediaGroup/StreamSuites/main/shared/state/
To serve snapshots from another host or bucket, open the dashboard with
?stateRoot=<your-url>/ (ensure the trailing slash) and the override will be
remembered. The fallback works only when this repository publishes current
snapshots under shared/state/discord/runtime.json (and optional
shared/state/jobs.json) so the raw GitHub URL always contains valid data.
- Purpose: process-scoped control-plane runtime for operational commands, status surfaces, and notifications. It is not a streaming bot and never launches ingestion workers.
- Modes:
- Standalone:
python -m core.discord_app. - Integrated: started by
core.schedulerwhen Discord is enabled in config.
- Standalone:
- Responsibilities: DiscordClient ownership, DiscordSupervisor lifecycle, heartbeat loop, and shared-state status persistence.
- Separation: does not create its own event loop in integrated mode, does not own scheduler logic, and runs alongside streaming runtimes without coupling shutdown.
- Configuration: feature-gated per creator via
shared/config/creators.jsonplatform flags and runtime settings undershared/config/.
The single source of truth for per-guild Discord configuration is
shared/config/discord.json and is formally defined in
schemas/discord.schema.json. All Discord guild-scoped values are nested
under discord.guilds, and missing keys default safely (logging disabled,
no channels). Malformed entries are ignored at runtime, and new notification
types can be added without breaking existing configs.
discord:
guilds:
"123456789012345678":
logging:
enabled: false
channel_id: null
notifications:
general: null
rumble_clips: null
youtube_clips: null
kick_clips: null
pilled_clips: null
twitch_clips: null- Application bootstraps environment and creator contexts
- Scheduler launches per-creator runtimes
- Platform workers manage platform-specific logic
- Shared browser and job systems are centrally controlled
- Clean shutdown propagates through all active tasks
+-------------------+
| shared/ config |
+---------+---------+
|
+-------+-------+
| services/ |
+-------+-------+
|
+---------------+---------------+
| |
+------+-------+ +-----+------+
| core/app.py | | core/ |
| (streaming | | discord_ |
| runtime) | | app.py |
+------+-------+ | (Discord |
| | control |
| | plane) |
| +-----+------+
+-----+------+ |
| streaming | | (no ingestion workers)
| workers | |
+------------+ +-----+------+
Discord bots &
control flows
The streaming runtime (core/app.py) continues to operate as a long-running
asynchronous process orchestrated by a central scheduler and composed of
platform-specific workers.
High-level streaming flow:
- Application bootstraps environment and creator contexts
- Scheduler launches per-creator streaming runtimes
- Platform workers manage platform-specific ingestion and publishing logic
- Shared browser and job systems are centrally controlled
- Clean shutdown propagates through all active tasks
- Twitch and YouTube chat workers connect to their respective platforms,
normalize incoming messages, and pass normalized events into the
TriggerRegistryfor evaluation. - Workers log emitted trigger actions for observability. They do not execute actions, dispatch jobs, or persist cooldowns.
- Business logic is intentionally deferred; workers remain limited to transport ownership, normalization, and trigger evaluation.
core/app.pyremains the streaming runtime authority for event loops, scheduler control, and shutdown.- The scheduler may start the Discord runtime but does so in isolation so it can be independently restarted without interrupting streaming workers.
- Discord control-plane behavior belongs under
services/discord/and its runtime scaffolding; no Discord logic should live insidecore/app.py. - Dashboard integration is planned (GitHub Pages first, Wix Studio later) and will share interfaces with the Discord control-plane for parity.
- Owns lifecycle of platform workers per creator, based on platform flags in
shared/config/creators.json. - Starts chat workers; does not evaluate triggers and does not execute trigger actions.
- Coordinates shutdown and resource cleanup across runtimes.
- Discord: ACTIVE — control-plane only, separate runtime, not part of the chat-trigger pipeline.
- YouTube: SCAFFOLDED — polling-based chat worker is trigger-ready; API calls and livestream discovery are deferred pending credentials/quota.
- Twitch: FOUNDATION — IRC-based chat worker implemented, architecture is complete and trigger-ready; temporarily untestable due to external account issues.
- Twitter/X: PLANNED — control-plane tasks exist; runtime worker scaffold is not yet implemented.
- Rumble: PAUSED — browser/DOM-based approach retained and documented; execution is paused due to upstream API protection. Architecture remains intact for reactivation.
- Transport: polling via
liveChatMessages.list(no push/webhook support) - Poll cadence: honor
pollingIntervalMillis; default scaffold assumes ~2–3s while API hints are wired - Rate limits:
liveChatMessages.listcosts 5 units/request; current quota is 200,000 units/day with ~50,000 reserved for overhead/other tasks, so keep intervals above 2s to avoid churn - Latency: expect a few seconds between message send and API availability; downstream triggers must tolerate slight delays and deduplicate by message ID
- Lifecycle: scheduler-owned workers will resolve
liveChatIdand poll chat; implementation is deferred until the scaffold is validated - Normalization: chat messages are normalized into platform-agnostic events,
evaluated by the
TriggerRegistry, and any emitted trigger actions are logged only (execution deferred)
Environment:
YOUTUBE_API_KEY_DANIEL— Data API key used for livestream discovery and chat polling
All Rumble chat workers, models, and browser helpers remain in the repository. Execution is paused solely due to upstream API protection and DDoS mitigation. The architecture and code paths are intentionally preserved to allow rapid re-enablement once official API access or platform whitelisting is available.
-
Authoritative data sources Platform APIs are used where available; browser automation is used only when required.
-
Single responsibility per component Browsers do browser things. Workers do platform things. The scheduler controls lifecycle.
-
No hidden background state All long-running tasks are tracked and cancellable.
-
Windows-first compatibility Signal handling, shutdown, and event loops are designed to behave correctly on Windows.
-
Configuration over code Behavior is being progressively externalized into JSON-based config.
StreamSuites may optionally capture chat events while platform bots are active to support historical replay and downstream analysis. Any future logging will be append-only, non-blocking, and explicitly optional so that failures never affect live chat operations. Logged data is intended for external consumers such as the StreamSuites dashboard, browser extensions, or moderation tools.
Planned scaffolding includes:
- A storage placeholder at
shared/storage/chat_events/for future writers, readers, and indexing utilities - A runtime state root at
shared/state/chat_logs/(with a Rumble namespace atshared/state/chat_logs/rumble/) reserved for generated data and kept gitignored - A
services/rumble/models/chat_event.pyplaceholder for describing Rumble chat event shapes without impacting current integrations
No logging logic is implemented yet.
Twitch connectivity uses the native IRC-over-TLS transport to keep behavior deterministic and scheduler-friendly. Foundational pieces live under:
services/twitch/api/chat.py— Twitch IRC client (connect/read/send, PING/PONG)services/twitch/workers/chat_worker.py— worker lifecycle wrapper for scheduler ownership (no side effects on import); normalizes chat events and routes them into the platform-agnosticTriggerRegistry, logging emitted trigger actions without executing them.services/twitch/models/message.py— normalized chat message + trigger-ready event shape
Twitch tokens live in .env:
TWITCH_OAUTH_TOKEN_DANIEL(required for IRC chat)TWITCH_BOT_NICK_DANIEL(chat nickname; defaults to channel name if omitted)TWITCH_CHANNEL_DANIEL(channel to join without the#prefix)TWITCH_CLIENT_ID_DANIEL/TWITCH_CLIENT_SECRET_DANIEL(documented for future Helix usage; not required for IRC chat)
A minimal Twitch chat validation script lives at the repo root:
python twitch_chat_poc.py --channel <channel> --nick <bot-nick>
# or rely on env vars: TWITCH_OAUTH_TOKEN_DANIEL, TWITCH_CHANNEL_DANIEL, TWITCH_BOT_NICK_DANIELThe script connects to irc.chat.twitch.tv:6697, prints incoming messages, and
responds to !ping with pong. Scheduler integration will attach the same
worker/client lifecycle when Twitch is enabled for a creator. Discord and other
runtimes remain unchanged.
- Quota enforcement (per-creator/platform, daily, buffer + hard cap)
- Quota snapshot export (runtime cadence →
shared/state/quotas.json) - Discord control-plane runtime scaffolding + dashboard state publish
- Twitch and YouTube chat trigger scaffolds (evaluation-only)
- Rumble chat workers (paused, preserved)
- Harden quota registry wiring across platform workers
- Expand dashboard quota surface for observability only
- Tighten shutdown ordering across runtimes
- Validate YouTube/Twitch trigger scaffolds with live credentials
- Chat runtime plumbing — Not yet live; dashboard chat/overlay views render preview/mock data only.
- Browser extension feed hydration — In planning / not started; extensions continue showing placeholder content until runtime feeds exist.
- OBS overlay runtime feeds — UI ready / runtime pending; overlay templates ship mock data only.
- Live chat socket ingestion — Planned; no active socket ingestion is wired yet.
- Multi-platform identity routing — Planned; identity mapping across platforms is not connected to runtime exports.
- Deterministic replay ingestion — Planned; chat replay overlays remain mock-data driven until ingestion wiring lands.
- Config-driven trigger definitions and cooldown persistence
- Dashboard tooling for creator config introspection (read-only first)
- Additional platform workers (Twitter/X control-plane parity)
- Scheduler telemetry + alert surfaces
- Trigger action execution + job dispatch
- Operator tooling (desktop control, runtime start/stop)
- Historical chat logging + replay (opt-in)
- Dashboard trigger editing and live controls
This repository intentionally prioritizes correctness and clarity over rapid feature accumulation. All new functionality is expected to respect the existing lifecycle and architectural boundaries.