Contributing
Recommended Workflow
Fork + clone the repo
Create a branch from
dev:bashgit checkout -b feat/my-featureImplement with strict TypeScript typing
Pass the quality gates:
bashpnpm typecheck pnpm lint pnpm build pnpm test:ws-smokeCommit using Conventional Commits
Open a PR to
devwith context and manual verification
Technical Rules
- Renderer ↔ Main: only via preload (
window.streamoos) - never directipcRenderer - IPC types: centralized in
app/src/shared/ipc.ts - Handlers: implement
FeatureHandlerfromapp/src/main/handlers/types.ts - Logs: use
app/src/main/observability/logger.tsin main - neverconsole.log - Tokens:
safeStorageonly - never plaintext in SQLite or localStorage - Migrations: SQLite schema changes step-by-step, no unnecessary coupling
PR Checklist
- [ ] Functional impact described in the PR description
- [ ] Important logs are visible and understandable
- [ ] No log spam on frequent interactions (volume, progress)
- [ ] WS smoke test passing (
pnpm test:ws-smoke) - [ ] No TypeScript strict regression (
pnpm typecheck)
CI / Workflows
GitHub Actions workflows are in .github/workflows/:
| Workflow | Trigger | Actions |
|---|---|---|
ci.yml | Push / PR | typecheck, lint, build, tests |
release.yml | Tag v* | Build dist Windows + Linux, create GitHub release |
Code Areas by Feature
| Feature | Main | Renderer | Shared |
|---|---|---|---|
| KHInsider | app/src/main/handlers/khinsider/ | app/src/renderer/components/khinsider/ | app/src/shared/ipc.ts |
| Timer | app/src/main/handlers/timer/ | app/src/renderer/components/timer/ | - |
| Twitch | app/src/main/handlers/twitch/ | app/src/renderer/components/twitch/ | app/src/shared/planning.ts |
| Discord | app/src/main/handlers/discord/ | app/src/renderer/components/discord/ | - |
| SMTC | app/src/main/handlers/smtc/ | app/src/renderer/components/smtc/ | - |
| Remote | app/src/main/remote/ | app/src/renderer/remote/ (PWA) | - |
| Overlays | app/overlays/ | - | app/overlays/shared/ |
Architecture Quick Reference
app/src/
├── main/ # Electron main process (Node.js)
│ ├── handlers/ # Feature handlers (one per feature)
│ ├── ws/ # WebSocket server + router + broadcaster
│ ├── remote/ # Fastify HTTPS server for mobile PWA
│ ├── storage/ # better-sqlite3 preferences store
│ ├── windows/ # BrowserWindow management
│ └── observability/ # pino logger (logger.ts)
├── preload/ # contextBridge (window.streamoos)
├── renderer/ # React 19 + Vite 6 dashboard
└── shared/ # Types only (no runtime deps)
├── ipc.ts # IPC channels, feature types, state contracts
└── planning.ts # Twitch planning typesi18n
All user-visible strings must be localized. Languages: fr (default), en, de.
- Translation files:
locales/<lang>/translation.json - Never hardcode UI text in JSX -- use
t("key")from the i18n system - Detection order: querystring > localStorage
