โ† Blog
|feature|By Dmitry Savvinov|

Modular takeover: from vibe-coded app to spec-driven development

โš ๏ธ CodeSpeak is in Alpha Preview: many things are rough around the edges. Please use at your own risk and report any issues to our Discord. Thank you!

Vibe coding is great for getting started. You describe what you want, the agent fills in the gaps, and something real materializes โ€” no architecture docs, no upfront planning, just a running conversation until you have something working. Folio โ€” our demo project โ€” is exactly that: a dual-pane terminal file manager in Go, built entirely through natural-language prompting, without reading a line of generated code.

For those who remember the glory days of FAR Manager and Norton Commander, Folio should feel like coming home โ€” with a tribute theme that makes it look the part. For those who don't: imagine a world where the mouse hadn't won yet.

Folio in FAR-inspired theme: a vibe-coded dual-pane terminal file manager

But every vibe coding session ends the same way. You have a working prototype, a long chat history, and a nagging feeling that the next change might break something you can't easily reconstruct. The agent doesn't remember what you discussed last week. The code doesn't capture the decisions you made along the way. Adding a new feature means re-explaining context you've already explained.

This is the gap between exploration and evolution. Vibe coding excels at exploration โ€” at understanding what you want. Evolving a vibe-coded app carefully is a different problem.

The upcoming release of CodeSpeak introduces modular takeover to bridge that gap.

What's new: modular takeover

codespeak takeover has been able to extract specs from existing code for a while โ€” reconstructing intent from implementation and giving you something to evolve instead of a raw codebase. The new mode goes further: when you point takeover at a full application, it analyzes the whole codebase and proposes a modular decomposition. Not one big spec โ€” a set of focused specs, each covering a coherent part of the system.

The proposal surfaces through a web-based modularization wizard, where you can inspect and refine the structure before any specs are written. The wizard starts coarse-grained on purpose: it gives you a starting point, and you drive the refinement.

The workflow:

  1. Vibe-code your app. Have fun. Figure out what you want.
  2. When the dust settles, run codespeak takeover
  3. The modularization wizard opens in your browser โ€” inspect the proposed module structure
  4. Refine it interactively: ask for finer-grained splits, merge modules, or rearrange where responsibilities live
  5. Select which modules to hand over and confirm the plan
  6. CodeSpeak generates specs and takes over โ€” from here, you evolve specs, not code

Let's walk through this with Folio.

Folio: the vibe-coded baseline

Folio started as a conversation. A few sessions later, it had two panels, file navigation, copy/move/delete, archive browsing, an integrated terminal emulator, themes, context menus, and prefix search. The git log tells the story:

624aee6 Support archives
48deb41 Fix swallowed keypresses in terminal + provide kill escape hatch
3be8b2f Introduce context menu
8d2186d Better symlink detection
5a66c78 Added FAR-inspired theme
d9f4020 Quick-search modal doesnt eat Enter
23a5be8 Fix broken terminal key inputs
0f88f04 The horrors of terminal emulation persist but so do we

No architectural planning. Just a running conversation with an agent that could hold each feature in mind long enough to implement it.

The result is nearly 3,000 lines of Go across model.go, panel.go, terminal.go, styles.go, fs.go, archive.go, and a few others. It works. But those files are dense with implementation detail, and next time you want to add something, you're reading code, not intent.

Running the modularization wizard

After running codespeak init to register the project, we're ready to take over:

codespeak takeover

CodeSpeak analyzes the codebase and opens the modularization wizard in your browser. The initial proposal is deliberately coarse โ€” it reflects the gross structure of the app, not every file boundary.

Modularization wizard: initial coarse module proposal for Folio

You can inspect each proposed module: which source files it covers, what responsibilities it's been assigned, and how it relates to the others.

The wizard is interactive โ€” you can ask for finer-grained splits, merge modules that feel too similar, or rearrange where a responsibility lives. Here's what asking for a refinement looks like:

Modularization wizard: asking for a refinement

In Folio's case, the initial proposal already matches how we think about the app, so we go straight to selecting modules. You don't have to take over everything at once โ€” pick the parts you want to bring under spec management now and leave others for later.

Modularization wizard: selecting modules for the takeover plan

Confirming the plan generates the spec files directly โ€” CodeSpeak writes them out, wires up the imports, and registers them with the project.

The result: four specs

For Folio, we ended up with four modules:

specs/
  app.cs.md           โ€” core model, panels, context menu, settings
  file-ops.cs.md      โ€” filesystem operations and archive support
  presentation.cs.md  โ€” theming and file formatting
  terminal.cs.md      โ€” the integrated terminal panel

app.cs.md imports the other three, so when you run a build, CodeSpeak knows to process them in dependency order โ€” filesystem, presentation, and terminal first; then the core model that ties them together.

specs/app.cs.md
---
import specs/file-ops.cs.md
import specs/terminal.cs.md
import specs/presentation.cs.md
---
# Core Model, Panels, Context Menu, and Settings
...

The four spec files total 430 lines of Markdown describing a codebase of 2,938 lines of Go โ€” about a 7ร— reduction in what you need to read and edit to understand the system.

Intent that code doesn't preserve

Specs are shorter than code โ€” but the real value isn't the length, it's what's in them.

With your permission, codespeak takeover reads your agent sessions to surface intent invisible to anyone reading the code cold. A good example from Folio: the keyboard passthrough rules for the terminal panel.

specs/terminal.cs.md
...

## Keyboard passthrough

When the terminal panel is focused, only the following keys are handled by the application
itself rather than forwarded to the terminal process:
- Ctrl+T (toggle terminal visibility)
- Ctrl+\ (kill terminal session)
- Ctrl+Up / Ctrl+Down (resize terminal panel)

All other keypresses are forwarded to the shell.

This exists because the author wanted to run htop, claude, and vim inside the terminal โ€” so nearly everything had to pass through unchanged. The exact list matters. Without session reading, takeover would either be too vague ("Folio shortcuts are not forwarded") or miss individual keys. F10, for instance: it opens Folio's settings, but it also exits htop. Since there's no reason to intercept it when the terminal is focused, it was deliberately left out. A spec that got this wrong would silently break htop, and you'd only find out when someone actually tried.

The sessions capture what you said. The spec makes sure it isn't forgotten.

Evolving with specs: adding mkdir

Here's where the payoff becomes concrete.

Folio was missing something a file manager really should have: the ability to create a new folder. In the FAR Manager tradition, this should be F7.

In the old world, this means finding the right place in model.go, understanding how input routing is layered, writing the handler, wiring it to the filesystem, and making sure the active panel refreshes. You'd read several hundred lines of model logic to find the right hook.

In the spec world, the change looks like this:

specs/file-ops.cs.md (diff)
 ### Delete (`deleteEntries`)

 - Uses `os.RemoveAll` โ€” removes files and directories recursively

+### Create folder
+
+- Creates a new folder
+
 ### Clash detection (`findClashes`)

And one row added to the keybindings table in app.cs.md:

specs/app.cs.md (diff)
 | F6              | Move to opposite panel                                |
+| F7              | Create a new folder                                   |
 | F2              | Open context menu for focused entry                   |

That's it. Then:

codespeak build specs/app.cs.md
Processing spec 1/2: specs/file-ops.cs.md

   โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•—
  โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•”โ•
  โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•
  โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•  โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ• โ–ˆโ–ˆโ•”โ•โ•โ•  โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•—
  โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•—
   โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•     โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•  โ•šโ•โ•

โ•ญโ”€ CodeSpeak Progress: Folio adding F7 keybinding for creating new foldโ€ฆโ”€โ•ฎ
โ”‚ โœ“ Process specification (0.0s)                                         โ”‚
โ”‚ โœ“ Collect project information (0.2s)                                   โ”‚
โ”‚ โœ“ Implement specification (2m 12s)                                     โ”‚
โ”‚ โ•ฐโ”€ โœ“ Collect context & plan work (2m 11s)                              โ”‚
โ”‚    โ•ฐโ”€ โœ“ Running all tests (invocation 1) (0.1s)                        โ”‚
โ”‚ โŠ˜ Ensure all tests pass (0.0s) - No tests found                        โ”‚
โ”‚ โœ“ Finalize spec build (0.0s)                                           โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    Alpha Preview    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
Processing spec 2/2: specs/app.cs.md
Built successfully.

CodeSpeak generates the createFolder function in fs.go, the keyboard handler in model.go, the input routing, and the panel refresh โ€” all consistent with the rest of the codebase's conventions.

Folio with F7 mkdir working โ€” folder creation prompt visible

You didn't have to read a line of Go to add a new feature to a 3,000-line codebase.

What this unlocks

The modular takeover changes the economics of vibe coding. Right now, every vibe-coded project reaches a point where you either slow down โ€” because you're afraid to break things โ€” or you keep going fast and things break. There's no natural off-ramp.

Modular takeover gives you one. You don't have to start with specs. You don't have to plan your architecture upfront. Vibe-code to explore, take over when you're ready to evolve carefully. The wizard meets you where the code is, and helps you find the structure that was always implied by it.

The specs you get aren't just for feeding back into CodeSpeak. They're documentation โ€” concise, structured, and human-readable. You can share them with a teammate, review them in a PR, or read them to understand your own system faster than you'd read the code.

Coming soon

Modular takeover is in active development. We're working on making the initial modularization proposals smarter, improving how specs handle the boundaries between modules, and making sure a spec edit produces a focused, predictable code change every time.

If you want to dig into the demo, Folio is on GitHub. The modular-takeover branch has the full results โ€” the generated specs, the takeover state, and the mkdir feature built on top.

We'll share more as it comes together.