Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions skills/mc-prompter/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
---
name: mc-prompter
description: Browser teleprompter for the record stage and standalone shows. A service skill like mc-audio, no stage, no gate, no project.json state. Launch a local prompter server, feed it the project script.md or any text, and the creator records at their own pace with a phone remote over LAN. Classic teleprompter only in this version; voice-follow and producer mode are planned tiers.
description: Browser teleprompter for the record stage and standalone shows. A service skill like mc-audio, no stage, no gate, no project.json state. Launch a local prompter server, feed it the project script.md or any text, and the creator records at their own pace with a phone remote over LAN. Voice-follow scrolling (local streaming ASR, consent-gated model download) tracks the speaker through the script; producer mode is a planned tier.
---

# mc-prompter

The record stage is creator-owned; this skill hands the creator a teleprompter for it. It is a service skill: it owns no stage, stops at no gate, and writes no project state. It launches a local web server that serves a fullscreen prompter display, a phone remote, a home page for loading and editing the script, and an OBS overlay placeholder. Everything runs offline on the creator's machine; no models, no downloads, no external requests.
The record stage is creator-owned; this skill hands the creator a teleprompter for it. It is a service skill: it owns no stage, stops at no gate, and writes no project state. It launches a local web server that serves a fullscreen prompter display, a phone remote, a home page for loading and editing the script, and an OBS overlay placeholder. The classic prompter runs offline with no models and no downloads. Voice-follow is an optional tier on top: local streaming ASR follows the speaker through the script and scrolls to match; it needs the prompter-lab workspace, whose one-time model download is consent-gated below.

## Steps

1. Load this skill's own surface (`uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root}`; run `{workflow.activation_steps_prepend}` now, `{workflow.activation_steps_append}` after this step, and hold `{workflow.persistent_facts}` as standing context). Take the default port from `[prompter] port`. If a studio config exists, also load it (`uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root} --key modules.manticore`) and take `[prompter] port` and `[owner] wpm` when present; a missing studio config is fine here, unlike the stage skills, because standalone shows need no studio.
1. Load this skill's own surface (`uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root}`; run `{workflow.activation_steps_prepend}` now, `{workflow.activation_steps_append}` after this step, and hold `{workflow.persistent_facts}` as standing context). Take the defaults from `[prompter]`: `port`, `asr-provider`, and `workspace`. If a studio config exists, also load it (`uv run {project-root}/_bmad/scripts/resolve_config.py --project-root {project-root} --key modules.manticore`) and take `[prompter]` values, `[owner] wpm`, and `engines-path` when present; a missing studio config is fine here, unlike the stage skills, because standalone shows need no studio.
2. Locate the script. Inside a pipeline project ("record with the teleprompter"), it is the project's `script.md` under the project folder. Standalone, it is any file path the creator names, markdown or plain text. No file at all is also valid: launch without `--script` and the creator pastes text on the home page.
3. Launch: `uv run {skill-root}/scripts/run_prompter.py --script <path>` with `--port <N>` when the config or the creator sets one and `--owner-wpm <N>` when `[owner] wpm` is known. Add `--lan` only when the creator wants the phone remote or a tablet display; it binds the LAN and on Windows triggers a firewall consent dialog. The launcher probes the port, prints the local URL, the remote URL with its session token, and the session file path, then keeps the server running until Ctrl-C.
4. Give the creator the URLs from the launcher output: the prompt page for the recording display, and the remote URL (token included) to open on a phone when `--lan` is on. Briefly explain the pages: `/` is home (load a file, paste text, edit in place, copy the remote URL), `/prompt` is the fullscreen scroller with keyboard controls and a settings drawer (press `?` there for all shortcuts), `/remote` is the phone controller, `/overlay` is an OBS browser-source placeholder for now.
5. Explain what the display does with pipeline markers: paragraphs carrying a `[TAKE ...]` marker render dimmed with a "have it already" badge because that line was already spoken well in the interview footage, and a toggle hides them entirely; sentences flagged `[INVENTED]` get a subtle badge, toggleable off; other bracketed text renders as a dimmed note and is never counted in timing.
6. If the creator edits the script from the home page and saves, the server first copies the current file to a timestamped backup under the temp session directory, then writes the edit back to the source file, so the prompted text and the pipeline artifact never silently diverge. "Session only" applies the edit without touching the file.
7. When the creator asks for voice-follow scrolling or producer mode, say plainly that those are planned tiers that have not landed yet and the classic prompter is what works today. Never pretend they work and never improvise a substitute.
3. Workspace check, only when the creator wants voice-follow or asks about it (the classic prompter needs none of this; when `asr-provider` is `none`, skip to launch). Resolve the workspace as `{engines-path}/{prompter.workspace}` when a studio config exists; otherwise ask the creator for a location or default to `~/mc-prompter-lab`. Run `uv run {skill-root}/scripts/ensure_workspace.py --workspace <resolved> --check`. Ready (exit 0): proceed. Not ready (exit 4): tell the creator plainly that a bootstrap downloads about 465 MB of ASR model files plus a small Python venv, ask for their explicit go-ahead, and only then run the same command without `--check`. Declining is fine: launch the classic prompter without `--workspace`. The bootstrap is idempotent; an existing validated workspace is reused, never rebuilt, and downloads run long, so report progress rather than going silent.
4. Launch: `uv run {skill-root}/scripts/run_prompter.py --script <path>` with `--port <N>` when the config or the creator sets one and `--owner-wpm <N>` when `[owner] wpm` is known. Add `--workspace <resolved>` when the workspace is ready and `--asr-provider <value>` when the config sets one; the launcher verifies readiness itself and falls back to the classic prompter with a printed notice when the workspace is missing or incomplete. Add `--lan` only when the creator wants the phone remote or a tablet display; it binds the LAN and on Windows triggers a firewall consent dialog. The launcher probes the port, prints the local URL, the remote URL with its session token, whether voice-follow is available, and the session file path, then keeps the server running until Ctrl-C.
5. Give the creator the URLs from the launcher output: the prompt page for the recording display, and the remote URL (token included) to open on a phone when `--lan` is on. Briefly explain the pages: `/` is home (load a file, paste text, edit in place, copy the remote URL), `/prompt` is the fullscreen scroller with keyboard controls and a settings drawer (press `?` there for all shortcuts), `/remote` is the phone controller, `/overlay` is an OBS browser-source placeholder for now.
6. When voice-follow is available, explain how it works on `/prompt`: it is off by default; the toggle lives in the settings drawer and as a HUD chip, and it only appears in a browser on the server machine itself, because the microphone is captured there (a tablet or phone pointed at the page is display-only). The first enable opens a preflight panel: pick the microphone, watch the live level meter, confirm the applied audio settings, and read a few words until the tracking check passes. After that the scroll follows the voice; silence or off-script ad-libs hold the scroll (HOLD chip) and it resumes when the speaker returns to the script; clicking any word re-anchors instantly; a BEHIND chip means ASR is lagging real time on this machine. Manual controls keep working throughout, and toggling voice-follow off returns to normal wpm scrolling at the current position.
7. Explain what the display does with pipeline markers: paragraphs carrying a `[TAKE ...]` marker render dimmed with a "have it already" badge because that line was already spoken well in the interview footage, and a toggle hides them entirely; sentences flagged `[INVENTED]` get a subtle badge, toggleable off; other bracketed text renders as a dimmed note and is never counted in timing or matched by voice-follow.
8. If the creator edits the script from the home page and saves, the server first copies the current file to a timestamped backup under the temp session directory, then writes the edit back to the source file, so the prompted text and the pipeline artifact never silently diverge. "Session only" applies the edit without touching the file.
9. When the creator asks for producer mode (rundown, timing cues), say plainly that it is a planned tier that has not landed yet. The same honesty applies to `asr-provider` values: `nemotron-streaming` and `none` work today; `zipformer-small` is a planned lane and the server exits with a pointer if it is selected. Never pretend a planned lane works and never improvise a substitute.

## Rules

- The prompter never advances pipeline state; when a pipeline project is being recorded, the record stage remains the creator's, and mc-pipeline stays the source of truth.
- The workspace bootstrap downloads about 465 MB; it runs only after the creator's explicit consent, and declining always leaves a working classic prompter.
- The server binds localhost by default; `--lan` is opt-in and the remote URL carries a per-session token so a random LAN device cannot drive the prompter mid-show.
- Loading files by path and saving edits work only from the server machine, never from a LAN device.
- Loading files by path and saving edits work only from the server machine, never from a LAN device. Microphone capture likewise happens only on the server machine.
- Stop and relay the launcher's guidance when it exits nonzero: a missing or unreadable script path, an explicit port already held by another session, or a server that failed to start are all creator-facing problems, not things to retry silently.

## Checklist

- The port and wpm came from config when a studio config exists; defaults otherwise.
- The port, wpm, provider, and workspace came from config when a studio config exists; defaults otherwise.
- Any workspace bootstrap was consented to before anything was downloaded; an existing workspace was reused, not rebuilt.
- The creator got both URLs (prompt page, remote with token) and knows the pages.
- If voice-follow was requested, the creator knows it is toggled on `/prompt`, that preflight must pass before a take, and how HOLD, BEHIND, and click-to-anchor behave.
- Take and invented markers were explained if the script contains them.
- Any in-place save was backed up first (the server does this; confirm the backup path in its response).
- No planned tier was presented as working.
- No planned tier or provider lane was presented as working.
14 changes: 14 additions & 0 deletions skills/mc-prompter/customize.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,17 @@ persistent_facts = []
# Default port for the prompter server; the studio config's
# [prompter] port overrides this when set.
port = 8770

# Voice-follow ASR provider. Working values: "nemotron-streaming"
# (default, streaming English ASR via sherpa-onnx) and "none" (classic
# prompter, no ASR). "zipformer-small" is a planned lane for low-end
# hardware; selecting it makes the server exit with a pointer, it never
# pretends to run. The studio config's [prompter] asr-provider overrides
# this when set.
asr-provider = "nemotron-streaming"

# Engine workspace folder for voice-follow, resolved by the skill as
# {engines-path}/{workspace} when a studio config exists. Holds the ASR
# venv and model files; the first bootstrap downloads ~465 MB and is
# consent-gated by the skill. The classic prompter needs no workspace.
workspace = "prompter-lab"
Loading
Loading