# Working on Tourwright (for coding agents and contributors) Using Tourwright from an agent (MCP tools, script format) is in [docs/AGENTS.md](docs/AGENTS.md). This file is about changing Tourwright itself. ## Architecture `src/` is split by domain. Each domain is a folder with an alias in `package.json` (`imports`), and a domain imports only from the ones below it: ```text cli, server entry points: everything below authoring explore, record, check/fix (repair) → ai, render, script, video, voice, core ai, install the user's AI; tourwright install → render, script, video, voice, core render the browser and what it films → plugins, script, video, voice, core plugins extra steps, engines and voices → script, voice, core video ffmpeg: compose, loudness, review → voice, core script, voice script formats; text-to-speech → core core config, util, secrets, locks, paths → nothing ``` | Path | What | |---|---| | `bin/tourwright.js` | Calls `#cli/index.js` | | `src/index.js` | The library API (`import { render } from 'tourwright'`) | | `src/core/` | `config.js` (every setting: defaults < the user's `config.json` < `tourwright.config.json` < `TOURWRIGHT_*` env), `util.js`, `secrets.js`, `lock.js` (`--lock`: one browser at a time), `locate.js` (programs outside PATH), `paths.js` (the package root, its docs and version) | | `src/script/` | Script formats: `schema.js` (zod, declarative), `expand.js` (vars, blocks, repeat), `load.js` (files, JS modules, secrets), `mask-rule.js` | | `src/voice/` | Text-to-speech: `voices.js` (which voice, aliases, auto), `text.js` (pauses, marks, pronunciation), `sound.js` (polish presets, prosody filters), `narrate.js` (synthesis and sentence cache), `samples.js` (listing, samples), `engines.js`, `lexicon.js`, `effects.js` (built-in sounds), `python.js` (the Python helpers' processes), `piper_voice.py` (Piper kept loaded), `pocket.py`, `piper-voices.js`, `calibrated.json` (loudness per voice) | | `src/video/` | ffmpeg: `compose.js` (raw recording → mp4: cuts, mix, subtitles, chapters), `loudness.js` (each sentence leveled, true-peak limiter), `timeline.js`, `frame-filter.js`, `review.js` (blank screens, silence, loudness, clipping), `recompose.js` (`--keep` and `tourwright recompose`), `ffmpeg.js` (running ffmpeg), `quality.js` (encoding presets) | | `src/plugins/` | Loads plugins: extra step actions, TTS engines, voices | | `src/render/` | `index.js` (one entry for every kind of video), `slides.js` | | `src/render/walkthrough/` | A filmed walkthrough, one stage per module: `index.js` (runs them in order), `plan.js` (size, device, voice, capture; `DEVICES`), `studio.js` (browser, off-camera login, dressed page, recording), `clock.js` (captions, chapters, cuts, narration, effects), `stage.js` (what every filmed step shares), `helpers/` (the `v` helpers: `navigation`, `narration`, `pointer`, `camera`), `deliver.js` (compose, review, `--keep`) | | `src/render/steps/` | `index.js` (step interpreter, `if`/`try`), `targets.js` (finding elements: exact and visible first, `mask`, errors that list what the page offers), `lists.js` (lists that are not a `