Part 1 laid out the roadmap: here’s what’s gated, here’s what it would take to ungates it, and here’s a worked example of how an AI coding agent turns a spec into real code. This part is the actual fork. Not a thought experiment. Not a hypothetical. Real commands, real diffs, real output.
Cloning and Branching#
The starting point is the Meetily v0.4.0 MIT codebase. Clone it, create a branch with the fork’s name, and get ready to break things.
git clone https://github.com/Zackriya-Solutions/meetily.git libremeet
cd libremeet
git checkout -b libremeet-rebrand
The MIT license requires keeping the original copyright notice. Everything else is fair game.
The Rebrand: 69 Files, Zero Remainders#
The first thing any fork needs is its own name. The MIT license lets you take the code, but the project’s name, logo, and brand identity belong to the original authors. The first commit of any fork is a search-and-replace across the entire codebase.
I counted: 161 occurrences of “Meetily” across 55 files. That includes:
- The Tauri bundle identifier (
com.meetily.ai) - macOS Info.plist and entitlements
- The Docker compose service names
- Build scripts, installers, and CI workflows
- Rust struct names and module declarations
- Over a dozen frontend components and hooks
- Notification configuration, logging headers, debug strings
The replacement patterns:
| Pattern | Replacement |
|---|---|
Meetily | LibreMeet |
meetily | libremeet |
com.meetily.ai | com.libremeet.app |
I skipped the attribution files (README.md, CONTRIBUTING.md, PRIVACY_POLICY.md, LICENSE.md) because those reference the upstream project by name. Everything else got the treatment.
The result, in one commit:
73 files changed, 223 insertions, 223 deletions
Every replaced string was exactly the same length as its replacement. No formatting drift, no table alignment broken. That’s not always going to be the case, but it makes for a clean diff.
The moment of truth came after the last file was patched:
grep -rn '\bMeetily\b' --include='*.rs' --include='*.tsx' --include='*.ts'
--exclude='README.md' --exclude='CONTRIBUTING.md' --exclude='PRIVACY_POLICY.md'
Zero matches. The fork had its first commit.
Stripping PostHog: -928 Lines#
There’s an important early step that I missed in Part 1: the MIT codebase ships with PostHog analytics infrastructure. Three files in frontend/src-tauri/src/analytics/, 32KB of code, 24 Tauri command registrations, and a hardcoded API key pointing to us.i.posthog.com.
If your pitch is “privacy-first,” you can’t ship with telemetry built in, even if it’s disabled by default. This has to go.
Removing the analytics module meant:
- Delete the three analytics source files
- Remove
pub mod analytics;fromlib.rs - Strip all 24 analytics command registrations from the Tauri invoke handler
- Remove the
posthog-rsdependency fromCargo.toml
The commit diff tells the story:
5 files changed, 1 insertion(+), 928 deletions(-)
delete mode 100644 frontend/src-tauri/src/analytics/analytics.rs
delete mode 100644 frontend/src-tauri/src/analytics/commands.rs
delete mode 100644 frontend/src-tauri/src/analytics/mod.rs
928 lines of telemetry infrastructure, gone. The frontend analytics client library (analytics.ts) and its call sites remain. They invoke Tauri commands that no longer exist. That’s technical debt for the next commit. But the Rust backend, the Tauri command registry, and the build dependencies are clean.
This is the fork’s first real editorial decision. The original authors built telemetry because they needed product data to improve the app. The fork is saying: that’s a valid tradeoff, but it’s not ours. Our users get the inverse: no data leaves their machine, and in exchange they accept that we’re flying a bit more blind.
The First Feature: Template Editor, One Pass#
Part 1’s roadmap listed “Template editor UI” as a Low-Medium effort. The Rust scaffolding is complete: a three-tier fallback chain (custom templates on disk, bundled templates in app resources, built-in templates embedded in the binary), JSON validation, a validate_template command explicitly designed to support a frontend editor. Only the frontend UI was missing.
I wrote a spec:
# SDD: Template Editor UI for LibreMeet
## Goal
Add a visual template editor UI that lets users create, edit, preview,
and delete custom summary templates. The Rust backend already has the
complete template framework. This spec is for the frontend UI only.
## Scope
- New Tauri commands: `api_save_custom_template` and
`api_delete_custom_template`
- New dialog component: `TemplateEditorDialog.tsx`
- "Manage Templates" button in the existing button group
- Template sections: add, edit, reorder, delete
## Constraints
- Reuse existing shadcn/ui components
- No new npm packages
Then I fed it to droid:
droid exec --use-spec --auto high --worktree libremeet-template-editor \
-f /tmp/libremeet-template-editor-spec.md
It completed in one pass. Here’s what it produced:
Backend (4 files modified):
- Added a public
get_templates_dir()wrapper around the existing private function inloader.rs - Exported it through the templates module
- Added
api_save_custom_templateandapi_delete_custom_templatecommands totemplate_commands.rs, complete with validation before write and confirmation before delete - Registered the new commands in the Tauri invoke handler
Frontend (5 files modified + 1 new):
- A new
TemplateEditorDialog.tsxat 670 lines: two-panel layout with a template list on the left and an editor form on the right - The left panel shows all available templates with badges for built-in vs custom, edit and delete actions on hover, and a “New Template” button
- The right panel has fields for name, description, and a dynamic sections list where you can add, remove, reorder, and edit each section’s title, instruction, and format
- Local validation before save, backend validation via the existing
api_validate_templatecommand, and unsaved-changes protection on close - Wiring through the button group and summary panel to the existing template selector
The diff:
9 files changed, 249 insertions(+), 45 deletions(-)
One spec, one command, 670 lines of React, 155 lines of Rust, a complete feature that was locked behind the Pro paywall. This took less than an hour of my time and pennies of inference tokens. And now I own it forever. I’m not renting it. It’s mine. Bought and paid for.
The Build (or Lack Thereof)#
This is the part where theory meets practice. The rebrand was a string replacement. The analytics removal deleted dead code. The template editor commands are thin wrappers around existing infrastructure. But none of that matters if the code doesn’t compile.
Setting up the Rust toolchain takes exactly one command:
brew install rust
Then you run cargo check and watch it fail because the next missing dependency surfaces. In this case: cmake, needed by whisper.cpp to compile the speech-to-text engine.
brew install cmake
Then cargo check gets further but fails again. This time because the llama-helper sidecar binary doesn’t exist at the expected path. The rebrand renamed the app but not every reference to the build artifact. Another real fork friction point. The fix: compile the sidecar from the repo and place it where the build scripts expect it.
cd llama-helper && cargo build --release
mkdir -p frontend/src-tauri/binaries
cp target/release/llama-helper \
frontend/src-tauri/binaries/llama-helper-aarch64-apple-darwin
Then cargo check gets even further before revealing the last lingering reference to the deleted analytics module. One orphaned crate::analytics::commands::track_meeting_ended call in recording_commands.rs. A quick patch.
Then:
cargo check
No errors. 19 warnings, 14 of them auto-fixable. The fork compiles.
That’s the moment. The code has its own name, its own commits, its first new feature, and a clean build. Three missing tools, one orphaned reference, and about fifteen minutes of iteration. This is what actually happens when you fork a real codebase. It’s not magic. It’s just grinding through the dependency chain until the compiler is satisfied.
The next step (setting up CI, wrestling with macOS code signing, and turning the source into a shippable binary) belongs in the next article in this series.
What This Actually Proves#
Three hours of work produced:
- A rebranded codebase with zero remaining references to the original name
- A stripped analytics layer removing 928 lines of telemetry
- A complete template editor UI with backend save/delete, generated from a spec in one droid pass
None of this required access to the Pro codebase. None of it required reverse engineering. It was all there, in the MIT source, waiting for someone to connect the pieces. The vibe coding loop (write a spec, delegate to an AI agent, verify the output) turned a feature that was behind a paywall into a working implementation in the time it takes to watch a TV show.
The fork took longer to describe than to execute.
In Part 3, I’ll build the binary and tackle the genuinely hard problems: speaker diarization, meeting auto-detection, and the RAG pipeline that even Meetily Pro hasn’t shipped yet. The roadmap from Part 1 had those down as Very High effort. Let’s find out if that’s accurate.
Between now and then, if this is important to you, here are some things to think about: setting up CI for multi-platform Tauri builds, deciding whether to keep or replace the llama-helper sidecar for local AI, and whether the fork should stay a desktop app or grow a web UI for teams. The code is at /tmp/meetily-libremeet on my machine. Fork it, build it, make it yours.
