{"slug": "i-lost-my-best-ai-prompt-after-40-tweaks-so-i-built-a-tiny-git-for-prompts", "title": "I lost my best AI prompt after 40 tweaks. So I built a tiny git for prompts.", "summary": "A developer built PromptVault, a Rust-based version control tool for AI prompts that borrows git's model but is purpose-built for prompt files. The tool, which runs locally as a single static binary, offers branching, diffing, and A/B testing without calling any model, addressing the pain of tracking prompt iterations.", "body_md": "You're iterating on a prompt for an LLM. You tweak one word, the output gets better. You tweak another, it gets worse. You paste it into ChatGPT, it kind of works. You change \"concisely\" to \"in 3 bullets\", and suddenly the summaries are perfect.\n\nThen tomorrow comes. And you have **no idea which version was the good one.**\n\nYour folder looks like this:\n\n```\nprompts/\n├── summarize.txt\n├── summarize_old.txt\n├── summarize_v2.txt\n├── summarize_v2_final.txt\n├── summarize_v2_final_FINAL.txt\n├── summarize_REALLY_final.txt\n└── summarize_use_this_one.txt\n```\n\nAnd the worst part? The \"good\" one might be any of them. 😭\n\nYou can't diff them. You can't tell what changed between `v2_final`\n\nand `v2_final_FINAL`\n\n. You can't roll back to the version that actually worked.\n\nGood question. I asked myself the same thing.\n\nYou can. And technically, PromptVault borrows git's entire model — content-addressed objects, trees, commits. But in practice, prompts live next to code. They're mixed into repos, notebooks, chat exports, and random `.txt`\n\nfiles on your desktop.\n\nPrompts deserve their own version control that:\n\n`.txt/.md/.prompt/.j2/.yaml`\n\nfiles specifically`.pv/`\n\nfolder that doesn't collide with your code repo's `.git/`\n\nSo I built it. 🛠️\n\nPromptVault is `git`\n\n, but purpose-built for prompts. It's written in Rust, ships as a single ~2MB static binary, and runs entirely on your machine. No account, no cloud, no telemetry.\n\n``` bash\n$ pv init\nInitialized empty prompt vault in ./.pv\n\n$ pv add prompts/summarize.md\nadded: prompts/summarize.md\n\n$ pv commit -m \"refine: summarize now reports tone + title\"\n[main 791151d] refine: summarize now reports tone + title\n 1 prompt\n```\n\nNow iterate. See exactly what changed:\n\n``` bash\n$ pv diff prompts/summarize.md\ndiff -- prompts/summarize.md\n You are a precise summarizer.\n\n-Summarize the text below in 3 concise bullets, then propose a title.\n+Summarize the text below in 3 concise bullets, propose a title, and note the tone.\n\n {{text}}\n```\n\nWalk back through every iteration:\n\n``` bash\n$ pv log\ncommit 791151d…\nparent 4100199…\nDate:   Mon Aug 10 10:04:33 2026 +0000\n\n    refine: summarize now reports tone + title\n\ncommit 4100199…\nDate:   Mon Aug 10 10:04:33 2026 +0000\n\n    feat: initial prompt set\n```\n\nRestore any past version by hash, tag, or branch:\n\n``` bash\n$ pv show 4100199   # prefix works too 🔍\n$ pv revert v1.0    # restore working tree to a tagged version ⏪\n```\n\nThis is the killer feature for prompt engineering. You want to test two variants of the same prompt? Branch it.\n\n``` bash\n$ pv branch experiment\n$ pv checkout experiment\n# ... tweak the prompt, commit it ...\n$ pv checkout main       # working tree restores to main's version\n$ pv checkout experiment # ...and back to experiment's version\n```\n\nSwitch branches and the working tree restores instantly. No copying files, no renaming, no \"wait, which folder was the experiment in?\" 🎯\n\nWhen you're done, compare them against a dataset:\n\n``` bash\n$ pv ab main:summarize.md experiment:summarize.md -d cases.jsonl --show\nA/B:  A=main:summarize.md  B=experiment:summarize.md  (3 cases)\n\n[1/3] DIFF  differs\n--- A vs B ---\n-A You are a precise summarizer.\n+B You are a concise summarizer.\n\n  hello world\n--- end ---\n\nSummary: 0 identical, 3 differing (of 3)\n```\n\nPure local. No model calls. No API keys. 🔒\n\nOne thing that annoyed me about existing prompt tooling: **everything wants to call a model.** Every eval run costs money. Every test sends data to OpenAI.\n\nPromptVault takes a different stance: **it never calls a model.** It only renders templates and checks assertions.\n\n``` bash\n$ pv eval summarize.md --dataset cases.jsonl --show\nEval: summarize.md  (3 cases)\n\n[1/3] PASS  contains \"3 concise bullets\"\n--- rendered prompt ---\nYou are a precise summarizer.\n...\n--- end ---\n\nSummary: 2/2 passed (100%)\n```\n\nYou write a JSON Lines dataset, each line fills the prompt's `{{variables}}`\n\n, and PromptVault renders + asserts. ✅\n\nIf you want to actually run the prompt through a model, pipe the rendered output to whatever runner you trust (curl, the OpenAI CLI, ollama, your own script).\n\nThis separates two concerns that existing tools conflate:\n\nPromptVault does (1). You choose how to do (2).\n\nFor a \"tiny git for prompts\", it ended up with more than I planned:\n\n`pv diff --stat`\n\nfor a one-line summary per file.`pv branch experiment`\n\n, `pv merge experiment`\n\n(fast-forward or three-way, with conflict markers)`pv tag v1.0`\n\n, `pv revert v1.0`\n\n`.pvignore`\n\n`pv diff v1 v2`\n\ncompares any two commits/tags/branches`pv show HEAD:summarize.md`\n\nreads any file at any ref`pv tui`\n\nlaunches an interactive commit browser`pv push`\n\n/ `pv pull`\n\nsyncs the vault to any git host as a backing store`--features run`\n\n)`pv run`\n\nagainst OpenAI/Anthropic/Ollama. `pv ab main:x experiment:x -d dataset.jsonl`\n\nrenders two versions against the same dataset and diffs themPromptVault is a tiny git. On `pv init`\n\nit creates:\n\n```\n.pv/\n├── HEAD              → \"ref: refs/heads/main\"\n├── index.json        → staging area (path → blob hash)\n├── objects/          → content-addressed store (SHA-256)\n│   └── ab/cdef…      → \"<type>\\0<data>\"  (blob / tree / commit)\n└── refs/heads/main   → latest commit hash\n```\n\nEvery prompt version is a **blob** addressed by the SHA-256 of `blob\\0<content>`\n\n. A **tree** maps paths to blobs. A **commit** points to a tree + parent + message. Identical content is stored once. Nothing ever leaves your machine unless you explicitly `pv push`\n\n. 📦\n\nIt uses **Myers diff** for line-level changes (same algorithm as git), and the glob matcher for `.pvignore`\n\nis a dynamic-programming implementation to avoid the exponential backtracking that naive recursive matchers hit on patterns like `*a*a*a*`\n\n. 🧠\n\nThree options:\n\n```\n# 1. Prebuilt binary (no Rust toolchain needed) 📥\n#    Download from https://github.com/lululuhu/PromptVault/releases\n#    Available for: Linux/macOS/Windows, x86_64 and aarch64\n\n# 2. cargo 🦀\ncargo install promptvault\n\n# 3. From source 🔧\ngit clone https://github.com/lululuhu/PromptVault\ncd PromptVault\ncargo build --release\n# binary: target/release/pv  (put it on your PATH)\n```\n\nThen, in any folder where you keep prompts:\n\n```\npv init\n```\n\nThat's it. You're versioning prompts. 🎉\n\nA quick word on this, because I think it matters.\n\nPromptVault is **local-first**. Everything lives in `.pv/`\n\non your machine. No account, no cloud, no telemetry, no analytics, no \"phone home\". The only network calls are the ones *you* explicitly make:\n\n`pv push`\n\n/ `pv pull`\n\nto sync to a git remote you configured`pv run`\n\n(opt-in feature) to send a rendered prompt to a model APIThe `pv run`\n\ncommand reads API keys **only** from environment variables. Nothing is logged. Nothing is stored beyond the rendered prompt itself. 🔐\n\n**Important caveat:** if your prompts contain secrets, PII, or confidential information, committing them to a vault stores that data on disk in plaintext (content-addressed, but unencrypted). Pushing to a remote sends it to that git host. Same rule as git — don't commit secrets you wouldn't commit to git. ⚠️\n\nThis is v0.2.0. The roadmap ahead:\n\n`pv mergetool`\n\nis planned)`{{var}}`\n\nsubstitution)If you have opinions, the issue tracker is open. 🚪\n\nIf you've ever lost a good prompt to \"v2_final_FINAL.txt\" syndrome, give it a spin:\n\n`cargo install promptvault`\n\n⭐ Star it if it's useful.\n\n🐛 Open issues if it's not.\n\nI'm building this in the open and good ideas ship fast.\n\n*PromptVault is MIT-licensed, written in Rust 🦀, and runs on Linux/macOS/Windows. The author has no affiliation with any AI lab.*", "url": "https://wpnews.pro/news/i-lost-my-best-ai-prompt-after-40-tweaks-so-i-built-a-tiny-git-for-prompts", "canonical_source": "https://dev.to/lululuhu/i-lost-my-best-ai-prompt-after-40-tweaks-so-i-built-a-tiny-git-for-prompts-1d5j", "published_at": "2026-08-11 09:16:54+00:00", "updated_at": "2026-08-11 09:46:53.728773+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "large-language-models"], "entities": ["PromptVault", "Rust", "OpenAI"], "alternates": {"html": "https://wpnews.pro/news/i-lost-my-best-ai-prompt-after-40-tweaks-so-i-built-a-tiny-git-for-prompts", "markdown": "https://wpnews.pro/news/i-lost-my-best-ai-prompt-after-40-tweaks-so-i-built-a-tiny-git-for-prompts.md", "text": "https://wpnews.pro/news/i-lost-my-best-ai-prompt-after-40-tweaks-so-i-built-a-tiny-git-for-prompts.txt", "jsonld": "https://wpnews.pro/news/i-lost-my-best-ai-prompt-after-40-tweaks-so-i-built-a-tiny-git-for-prompts.jsonld"}}