Skip to content

Repository files navigation

tapedeck

evals

Your local video brain. Point it at a YouTube video and it downloads it, transcribes it on your own machine, archives it as readable markdown, and makes every spoken moment searchable — then answers your questions with citations that deep-link to the exact second someone said the thing.

tapedeck add "https://www.youtube.com/watch?v=..."
tapedeck search "verification bottleneck"
tapedeck ask "what did anyone say about pricing agent work?"

Nothing leaves your machine except the download itself. Your videos, transcripts, and index live in a plain folder you own; delete the tool and your library is still there, still readable.

What you get

  • add — the whole pipeline in one command: download (with a progress bar), local transcription, a markdown archive page where every paragraph is one click from its moment in the video, and full-text indexing. Your terminal is back in a couple of minutes.
  • Local files too. tapedeck add ./lecture.mp4 adds footage you already have — meeting recordings, lecture captures, anything on disk — into the same library, searchable the same way. Your file is linked, not copied, and citations point back at it.
  • search — ranked full-text search over everything ever said, each result carrying a timestamp and a deep link that opens YouTube right at that moment.
  • ask — questions answered from your library, with every citation mechanically verified against the videos before you see it. If it can't back an answer, it says "not in the library" instead of guessing.
  • The wiki — an optional layer where an AI maintainer files each video into an interlinked knowledge base: one page per video, notes for ideas that recur across videos, every link verified. It reads beautifully in Obsidian and compounds as your library grows. Filings run in the background under your own claude account and cost real money — typically a few dollars of agent work per video — so auto-filing ships off: one deliberate line turns it on ([wiki] auto = true in config.toml — see tapedeck help manual), and until then add never spends a cent.

Install (macOS, Apple Silicon)

brew install uv          # if you don't have uv yet
uv tool install tapedeck-cli
tapedeck setup

setup checks your machine and prints the exact command for anything missing — nothing installs without your say-so (tapedeck setup --yes runs the printed commands for you). When YouTube inevitably changes something, tapedeck setup --refresh updates your tools the same way.

On an Intel Mac, point the transcriber at a non-MLX tool via config.tomltapedeck help manual covers it.

Quickstart

tapedeck add "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
tapedeck list                      # what's in your library
tapedeck search "never gonna"      # find the moment
tapedeck ask "what is this video actually about?"
tapedeck help manual               # the full manual, in your pager

Everything is a plain file: videos and transcripts under your library home (default ~/Tapedeck), archive pages as markdown, the index as one SQLite database. Every derived file can be rebuilt from the one before it.

Staying healthy

  • tapedeck doctor — read-only diagnosis of your setup
  • tapedeck setup --refresh — update the underlying tools (yt-dlp et al.)
  • tapedeck help manual — the complete manual, including a troubleshooting reference for the failures YouTube likes to invent

How this codebase was built

Not one line under src/ was written by hand. All ~6,900 lines of it were generated by an AI model working from the specifications and tests in system/, and every one of them is disposable: delete a component's source, run the regeneration, and an implementation that satisfies the same specs and passes the same tests comes back. This is regenerative software engineering — the code is an artifact of the specification, the way a compiled binary is an artifact of its source.

The approach follows Chad Fowler's Phoenix Architecture, which argues that generative AI coding demands what good engineering always wanted anyway — "modularity, clear boundaries, disposable components" — and that code was never the asset in the first place. Specifications, tests, schemas and documented behavior are what survive; implementations are regenerated and replaced. Its sharpest line is the one this repository is organized around: the architecture of a regenerative system is defined entirely by what you can't delete. Here, what you can't delete is system/. Everything else is output.

That inverts the usual arrangement. In most repositories the code is the asset and the docs drift away from it. Here the durable layer is the asset and the code is the output:

system/ what it holds
spec/ 47 clauses — one behavioral requirement each, stating a constraint and why it exists, never an implementation
contracts/ 6 shared vocabularies — the library's layout, the CLI surface, file schemas — so independently generated components can't drift apart
evals/ 43 test files, 306 tests driving each component's real command-line boundary, never its internals
lessons/ 6 production incidents distilled into durable constraints (YouTube's format quirks, a transcription failure mode, a concurrency race)
provenance/ 83 signed records of every generation: which spec state produced which code, how many attempts, what it cost
components/ the 7 component definitions — owned paths, boundaries, budgets

How a change happens

Every change moves through the same loop, and the order matters:

  1. Amend the durable layer. Write or revise a spec clause. Specs argue for constraints; they never dictate code.
  2. Write failing tests first. New tests are added to system/evals/ and run before any implementation exists, to confirm they fail for the intended reason. A test that passes before the feature is built is testing nothing.
  3. Commit the ticket — spec plus red tests, in one commit, before a line of implementation exists. The repository history is therefore a record of intent preceding code, not a reconstruction after the fact.
  4. Regenerate the component. A headless model rewrites the whole component from the assembled context — specs, contracts, tests, lessons — inside a sandbox that rolls back cleanly if it writes outside the component's declared paths or leaves the tests red.
  5. Verify and ship. Full suite green, then deploy and smoke-test the real binary.

The harness that runs step 4 is a private tool and isn't published, which has one consequence worth knowing: hand-edits to src/ can't be merged — the next regeneration erases them. Contributions land in the durable layer instead; see CONTRIBUTING.md.

What this buys

  • External reality lives behind seams. yt-dlp, the transcriber, the question-answering agent are all shell commands in config.toml with documented environment inputs. When YouTube broke downloads twice in one week, both fixes were config edits promoted into shipped defaults — no code changed. The tests fake those same seams, so the suite needs no network and installs nothing.
  • Behavior can't drift from its documentation, because the documentation is what generates the behavior. A test pins every user-facing verb to the manual.
  • Every decision has a paper trail. Why does a rejected wiki filing leave no log entry? The clause says, and the commit that introduced it carries the argument.

The test suite runs with just eval-all; CI runs it on macOS for every push.

License

MIT — see LICENSE.

About

Your local video brain: download YouTube videos, transcribe them on your own machine, search every spoken moment, and ask questions answered with verified timestamped citations.

Topics

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages