Codebase Overview
A file map of the whole repository. Machine-readable counterpart:
high_signal_file_index.json, validated by
npm run lint:docs.
Shape
youtube-transcript-to-pdf/
├── manifest.json MV3 declaration — the entry point Chrome reads
├── icons/ 16/32/48/128px PNGs, real dimensions enforced by CI
├── src/
│ ├── lib/ pure modules, no chrome.* — pure logic tests target these
│ ├── background/ service worker: network and tabs
│ ├── content/ injected transcript-panel reader
│ ├── popup/ the UI
│ └── viewer/ printable page for the Chrome print-to-PDF path
├── scripts/ validation, doc index checks, packaging
├── test/ unit tests, Node built-in runner
├── docs/ this suite
└── store-assets/ Chrome Web Store screenshots and their sources
Root
| File |
What it is |
manifest.json |
Manifest V3: permissions, host permissions, service worker, popup, icons, minimum_chrome_version. Chrome’s entry point. |
package.json |
npm scripts only — no dependencies, runtime or dev. |
README.md |
Project overview and quick start. |
CLAUDE.md |
Rules for Claude Code in this repo. |
AGENTS.md |
Agents that operate on this repo and the conventions binding them. |
GEMINI.md |
Short-form rules for Gemini CLI. |
CONTRIBUTING.md |
Setup, the PR bar, and what good change looks like here. |
CODE_OF_CONDUCT.md |
Behaviour expectations. |
LICENSE |
MIT. |
PRIVACY.md |
Privacy policy, published via GitHub Pages as the Chrome Web Store policy URL. |
CHROMEWEBSTORE.md |
Store listing copy, permission justifications, data disclosure, and submission blockers. |
.editorconfig, .gitattributes, .gitignore, .nvmrc |
Formatting, line endings, ignores, pinned Node. |
src/lib/ — pure modules
No chrome.* anywhere in this directory. That is what makes these testable
under plain Node, and it is the codebase’s most important structural rule.
| File |
Role |
src/lib/youtube.js |
URL parsing across every accepted YouTube shape, hostname allowlisting, watch-page scraping, caption-track selection. |
src/lib/transcript.js |
Caption parsing for both payload formats, timestamp formatting, paragraph grouping, plain-text rendering. |
src/lib/pdf.js |
Hand-written PDF 1.4 writer: WinAnsi transliteration, metric-accurate word wrap, pagination, cross-reference table. |
src/background/ — service worker
| File |
Role |
src/background/service-worker.js |
Owns every outbound request and tab interaction. Runs the direct-download strategy, then the transcript-panel strategy. Defines the message contract and the error-code vocabulary. Holds no state in module scope. |
src/content/ — injected script
| File |
Role |
src/content/scrape-transcript.js |
Opens YouTube’s transcript panel and reads its cues. Handles both markup generations plus a structural fallback for obfuscated class names. Injected on demand, never declared, so it does not run on every YouTube page. The most fragile file here — see runbooks/transcript-panel-broke.md. |
| File |
Role |
src/popup/popup.html |
Markup. Module script, no inline handlers — the extension CSP forbids them. |
src/popup/popup.css |
Styles, with a dark palette under prefers-color-scheme. |
src/popup/popup.js |
Controller: prefill from the active tab, one message to the worker, preview rendering, PDF build and download, print handoff, clipboard, persisted options. |
src/viewer/ — printable page
| File |
Role |
src/viewer/viewer.html |
Markup for the printable transcript. |
src/viewer/viewer.css |
Document styling plus print rules that strip the toolbar. |
src/viewer/viewer.js |
Reads its unique handoff key from session storage, renders, and deletes that key. This is the path that handles scripts Latin-1 cannot encode. |
| File |
Role |
scripts/check-syntax.mjs |
Syntax-checks all maintained JavaScript with Node, without installing a linter. |
scripts/generate-doc-index.mjs |
Regenerates retrieval metadata and llms snapshots; --check detects drift. |
scripts/validate-manifest.mjs |
Manifest shape, referenced files exist, icon PNG signatures and real pixel dimensions match their declared size, no Manifest V2 keys, no <all_urls>. |
scripts/check-doc-indexes.mjs |
Every path in the doc indexes resolves, and no source file is missing from the index. --prune drops dead entries. |
scripts/package-extension.mjs |
Builds dist/<name>-<version>.zip from only the files Chrome loads. |
scripts/build-store-assets.mjs |
Renders the real popup and viewer markup into screenshot harness pages, and generates a genuine PDF, for Chrome Web Store assets. |
scripts/compose-store-screenshots.py |
Composes the captured harness renders into 1280×800 store screenshots and the 440×280 promo tile. |
scripts/generate-icons.py |
Draws the icon set — a document mark on the project’s red field — at every declared size, dropping text lines below 32px where they would blur. |
test/ — unit tests
114 tests on the Node built-in runner, plus four optional Pillow tests. Core tests require no install. The optional artwork tests use Pillow in a disposable environment.
| File |
Covers |
test/youtube.test.js |
URL shapes, hostname-allowlist rejection, watch-page parsing, the bare-captionTracks fallback, the parsed flag, regex-literal escaping, track-selection precedence. |
test/transcript.test.js |
Both caption formats, the empty body YouTube returns when blocking, format dispatch, timestamps, paragraph grouping, render options. |
test/pdf.test.js |
Transliteration, word wrap including hard-split of over-long words, PDF structural validity with byte-accurate cross-reference offsets, pagination, escaping, filename sanitisation. |
test/content-script.test.js |
Executes the shipping injected script with synthetic DOM rows and deterministic timers. |
test/service-worker.test.js |
Imports the actual worker with disposable APIs; bounds response bodies, ownership and language behavior. |
test/popup.test.js |
Imports the actual popup; checks request ordering, exports, downloads and preference errors. |
test/viewer.test.js |
Executes the shipping viewer; checks handoff identity and storage failures. |
test/tooling.test.js |
Runs actual CLI tools in disposable filesystem fixtures. |
test/store_assets_test.py |
Optional Pillow tests with synthetic local images; no committed assets are rewritten. |
icons/
icons/icon-16.png, icons/icon-32.png, icons/icon-48.png,
icons/icon-128.png, all generated by scripts/generate-icons.py. The mark is
a page with a turned-down corner and lines of text; it replaced an earlier play
triangle that read as YouTube’s logo. Each must be exactly the size it is
declared under —
lint:manifest verifies PNG data and dimensions rather than trusting
the filename.
docs/
| File |
Covers |
docs/ARCHITECTURE.md |
System context, the proof-of-origin constraint, the two strategies, four ADRs. |
docs/COMPONENTS.md |
Every module with its exports and dependencies. |
docs/DEVELOPMENT.md |
Setup, commands, the reload matrix, debugging, troubleshooting. |
docs/SECURITY.md |
Permission justifications, threat model, STRIDE. |
docs/TESTING.md |
Strategy, suites, coverage target, the manual test plan. |
docs/INSTALLATION.md |
Prerequisites, unpacked install, verification, upgrade, uninstall. |
docs/requirements.md |
Functional and non-functional requirements, and what is out of scope. |
docs/logging.md |
Levels, what is logged, and what must never be. |
docs/caching-and-optimization.md |
What is cached, what deliberately is not, where the time goes. |
docs/external-calls.md |
Network, browser API and local tool boundaries with timeout, retry, error handling and test status. |
docs/integrations-and-assumptions.md |
Every load-bearing assumption about YouTube and Chrome. |
docs/known-issues.md |
Active limitations, videos that will never work, and what is not a bug. |
docs/onboarding.md |
A first-hour path through the codebase. |
docs/codebase-overview.md |
This file. |
docs/wiki/index.md |
Maintained documentation entry point. |
docs/MCP.md |
Explicit MCP non-applicability. |
docs/repo-bootstrap-audit-2026-11-12.md |
Current standards audit and delivery boundary. |
docs/code-deep-optimizer-2026-11-12.md |
Full optimizer findings, gates and rollback. |
docs/maintenance-coverage-2026-11-12.md |
File universe, exclusions and per-file review accounting. |
docs/high_signal_file_index.json |
Machine-readable retrieval index. |
docs/runbooks/transcript-panel-broke.md |
Diagnosing and fixing a YouTube markup change. |
docs/runbooks/chrome-web-store-submission.md |
Field-by-field walkthrough of a store submission, and what to do if it is rejected. |
docs/runbooks/release.md |
Cutting a release. |
docs/repo-bootstrap-audit-2026-08-27.md |
Standard-compliance audit and the deliberate exclusions. |
.github/
copilot-instructions.md (Copilot CLI rules), workflows/ci.yml (checks on
Node 22/24/26, then packaging), dependabot.yml (Actions only — there are no
npm deps), CODEOWNERS, SECURITY.md, PULL_REQUEST_TEMPLATE.md, and issue
templates.
store-assets/
Chrome Web Store graphics and the inputs that produce them. Excluded from the
packaged archive — scripts/package-extension.mjs ships only manifest.json,
icons/, src/, and LICENSE.
| File |
What it is |
store-assets/sample-transcript.json |
Authored sample content used to render the screenshots, so the store assets carry no third-party text. |
store-assets/sample-transcript.pdf |
A genuine PDF produced by the shipping writer from that sample. |
store-assets/screenshot-1-popup.png |
1280×800 — the popup mid-export. |
store-assets/screenshot-2-pdf.png |
1280×800 — the exported document. |
store-assets/screenshot-3-viewer.png |
1280×800 — the Print path. |
store-assets/promo-tile-small.png |
440×280 small promo tile. |
store-assets/raw-popup-live.png |
A hand-taken capture of the running popup, cropped to the popup alone. Preferred over the harness render for screenshot 1. |
store-assets/raw-popup.jpg, raw-viewer.jpg, raw-pdf.png |
The captures the composer crops from, kept so the screenshots can be rebuilt without a browser pass. |
Regenerate the sources with npm run store:assets, then recompose with
python3 scripts/compose-store-screenshots.py. Recapturing the raw renders
needs a browser — see CHROMEWEBSTORE.md.