Synaplan
开源 AI 软件平台,面向企业:自托管 AI 代理,符合 GDPR 的聊天机器人小部件,RAG 知识库,WhatsApp 与 Outlook AI,MCP,多模型路由。支持 Docker、Kubernetes 或在 Germ 托管。
AI 翻译
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证The full live-show workflow in one app: plan the lineup, import the schedule from a photo, and run the show in a full-screen live mode with cue timers and walk-on music. React + TypeScript PWA with client-side encryption.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Live-show management for comedians, drag promoters, and variety producers — build the lineup, import the schedule, and run the show.
One tool for the full live-show lifecycle: plan the lineup, attach walk-on music, import a printed schedule by photo, then operate the show in a full-screen live mode with per-cue countdowns — and broadcast the on-stage state to a public viewer link.查看完整 README ↗Book the lineup, collect signed contracts, and run the live show from one phone, with everything encrypted before it leaves the device.
Live app · Product tour · Docs
Dashboard → show page → Run Show: the clock counts down, cues advance, and walk-on music plays from each performer's button.
App Store screenshots (iPhone 6.9", 1320x2868) and a 1920x1080 banner. Source files in docs/promo.
Producers of recurring comedy, drag and variety nights tend to run them from a spreadsheet, a notes app, a group chat and whatever music player is open. Each of those breaks at the worst moment: in a venue basement with no signal, while a performer is walking on. This app puts booking, paperwork and the live run of the night in one tool that works offline and is built for a phone.
#k=…), which browsers never send; the viewer page's walk-on audio works the same way. An E2E test asserts no request carries the key.UPDATE … WHERE token = ? AND signed_at IS NULL makes a replayed or racing submit harmless, and each signature records a SHA-256 of the exact document shown.409 save_conflict on a mismatch, so a stale tab can't erase a newer edit. Saves are debounced at 1s and blocked until the initial load succeeds.| Area | What it does |
|---|---|
| Run Show | Full-screen live mode: cue countdown with ahead/behind indicator, running order, and a soundboard with one button per performer (their face, their walk-on track, configurable fades). Screen wake lock and fullscreen for the length of the show. |
| Stage remote | Pair any Bluetooth clicker; the app learns its key so live mode can be driven from the stage. |
| Lineup and Rolodex | Performer profiles with headshot, socials, credits and walk-on music. Save once, and edits sync to every show they're on. |
| Schedule import | Photo, PDF or pasted text → running order, on the device: PDF.js, Tesseract OCR and a time-aware line parser. |
| Contracts | Send a PDF; performers read and sign from a link with no account. Track who has signed. |
| Live viewer | A public, read-only page showing who's on stage and who's next, updated live. |
| Season report | Shows, audience, net, regulars and top rooms for the year, plus a venue pitch composed from those numbers. |
| Show admin | Flyers, budget and expenses, staff and hosts, deadlines, PDF runsheet export, announcement captions, recurring shows. |
Full list: docs/FEATURES.md
Screenshots are generated from a production build with sample data by npm run screenshots (how).
flowchart LR
subgraph Browser["Browser / iOS app (all crypto here)"]
UI["React 19 UI"]
Crypto["PBKDF2 key + AES<br/>key never leaves device"]
Local["Service worker cache<br/>+ pending local edits"]
Import["PDF.js + Tesseract OCR<br/>schedule import"]
UI <--> Crypto
UI <--> Local
UI --> Import
end
subgraph API["Vercel serverless /api"]
Auth["auth"]
Data["shows · settings · media"]
Live["live · live-media"]
Sign["sign · sign-doc"]
end
DB[("Turso (libSQL)<br/>ciphertext only")]
Viewer["Public viewer page"]
Signer["Performer signing page"]
Crypto -- "ciphertext + expected hash" --> Data
UI -- "derived id + auth hash" --> Auth
UI -- "on-stage / up-next snapshot<br/>(public by design)" --> Live
UI -- "contract, encrypted per request" --> Sign
Auth & Data & Live & Sign <--> DB
Live --> Viewer
Sign --> Signer
Key["Per-share key in the link's #fragment<br/>(contract, viewer audio)<br/>never sent to the server"]
Key -.-> Viewer
Key -.-> Signer
Design decisions
Referer.<audio>. HTMLAudioElement was unreliable under iOS Safari's autoplay rules after auto-advance; one AudioContext unlocked on the first tap, with preloaded buffers and explicit resume(), is not.data-theme swap. Two self-hosted typefaces, precached for offline use: Cormorant Garamond for names (shows, performers, signers) and the Inter variable font for controls and data. The look is ink and ivory with no accent colour, so the only colour on screen means something (status).More, including the bugs that shaped these: docs/ARCHITECTURE.md · docs/SECURITY.md
| Layer | Choice |
|---|---|
| Frontend | React 19, TypeScript 5.9 (strict), hand-written CSS on design tokens |
| Build / PWA | Vite 8, vite-plugin-pwa (Workbox), self-hosted Inter and Cormorant Garamond |
| API | Vercel serverless functions (Node, TypeScript) in api/ |
| Database | Turso (libSQL) via @libsql/client, server-side only |
| Crypto | crypto-js: PBKDF2-SHA256 key derivation, AES, SHA-256 |
| Documents | PDF.js 5, Tesseract.js 7, client-side PDF export |
| Native | Capacitor 8 iOS wrapper |
| Testing / CI | Vitest 4, Playwright, ESLint, GitHub Actions |
Requires Node 20+ and a Turso database.
git clone https://github.com/taylordrew4u2/Showrunner-ICanRunAShow.git
cd Showrunner-ICanRunAShow
npm install
cp .env.example .env.local # set TURSO_DATABASE_URL and TURSO_AUTH_TOKEN
npm run dev
The Turso variables have no VITE_ prefix, so they never reach the browser bundle. For the iOS app (macOS + Xcode): npm run ios:sync, then npm run ios:open (docs/IOS.md).
The Producer plan is billed through Stripe Checkout and the Stripe customer portal. Card details only ever touch Stripe's hosted pages; the app stores the subscription status the webhook reports, keyed by the account's opaque id (usernames never go to Stripe). Without the keys below, the app runs exactly as before and the Plan card in Settings says paid plans aren't open.
https://<your domain>/api/stripe-webhook for checkout.session.completed, customer.subscription.created, customer.subscription.updated and customer.subscription.deleted, and copy its signing secret.STRIPE_SECRET_KEY, STRIPE_PRICE_ID, STRIPE_WEBHOOK_SECRET and APP_URL, then redeploy. Use test-mode keys first; card 4242 4242 4242 4242 completes a test checkout.Producer unlocks sending contracts for signature, reading a schedule off a photo or PDF, making a live audience link, the Season report, and pairing a stage remote. On the free plan each of these shows what it is and an Upgrade button in place of the control. Locks only apply once the server has Stripe keys and has confirmed the account is on the free plan; if the plan can't be checked (offline, say), nothing is locked. A lapsed plan never breaks a show in progress: links already shared, contracts already signed and a remote already paired keep working. Accounts created before the locks shipped (SUBSCRIPTIONS_STARTED_AT in api/billing.ts, 2026-10-06 23:31:58 UTC) are founding members: the server reports them as on the Producer plan, so nothing is ever locked for them and they are never sent to checkout. The switch is PAID_FEATURES_LOCKED in src/utils/billing.ts. The locks are in the app, not enforced by the API.
npm test # 1,045 Vitest unit tests across 104 files
npm run lint # ESLint
npm run build # env check + type-check (app and API) + production build
npm run e2e:install # once: fetch Playwright's Chromium
npm run e2e # 120 Playwright tests: 23 specs × desktop and phone
The E2E suite builds and serves the production bundle itself and runs against an in-memory API (e2e/support/fake-api.mjs) that reproduces the server rules that matter, including sign-once. It needs no database or secrets. CI runs lint, unit tests and build in one job and E2E in a second. Details: docs/TESTING.md
src/components/ Screens: ShowDetail, RunShow, LiveViewer, Contracts, SigningPage, SeasonReport, ...
src/utils/ Pure logic with a test beside each module (encryption, audio engine, import, media GC)
api/ Vercel serverless routes: auth, shows, settings, media, live, sign
e2e/ Playwright specs + in-memory API stand-in
ios/ Capacitor iOS project
docs/ Architecture, features, testing, security, iOS
Built by Taylor Drew · github.com/taylordrew4u2
Released under the MIT License.