A prompt library for the Mac menu bar
Keep the short prompt.
Generate the long one.
You keep seeds like fix this bug and test. Seedbed feeds each seed, plus the prompting
guidance for a target model, to an enhancer, and stores the tailored expansion as a file in git.
Press ⌥⌘P anywhere, pick the model, and the long version is on your clipboard.
Free and open source (MIT) · macOS 14 or later · Apple silicon and Intel · Developer ID signed and notarized · updates itself
fix this bug and test
You have this repository open and can read files, run commands, and execute the test suite.
Fix the bug described below, and cover it with a test.
Reproduce it first: find the failing behavior in the actual code and confirm you can trigger it before changing anything. If you cannot reproduce it, say so and describe what you tried instead of guessing at a fix.
Fix the underlying cause, not the symptom. Keep the change minimal: no refactoring, no extra error handling, and no restructuring of code the bug does not touch.
Add a test that fails against the old code and passes against the fix, written in the style and location of the existing tests for that area.
Done means: the bug is reproduced, the cause is fixed, a regression test exists, and the relevant tests pass. Report in a few sentences…
{{PLACEHOLDER}} blanksclaude CLI already on your Mac; any OpenAI-compatible endpoint worksA good prompt is long, specific and model-shaped.
Writing one every time is why you don't.
So in practice you type the short version and accept a worse answer. Seedbed splits the two jobs: you own
the seeds, and the tool owns the expansions. Rendering happens in build, not between
⌘C and ⌘V.
Copy is a file read
The render already exists, so copying is instant, works on a plane, and puts no API call between you and the paste. A bad render is caught before it reaches a worker agent, not after.
One file per seed per model
Editing a seed marks its renders stale; it never overwrites them. Each render records the seed hash, the guidance hash, the enhancer and the date, so build only spends on what moved.
Placeholders survive
A seed like fix {{BUG}} in {{PROJECT}} keeps its blanks through the render. Copying opens a small form, one field per blank, each remembering the values you used before.
Why files and git
Prompts change slowly and need to exist on more than one computer. Git gives sharing, history, backup and
conflict resolution with no server, and it works away from your own network. Renders are committed too,
so when a vendor's guidance moves, git diff shows exactly how the expansion changed. You review
a diff rather than trusting a black box.
- No dependencies. Standard library only; TOML frontmatter parsed with
tomllib. Python 3.11 or newer. - Degraded guidance is refused, not absorbed. If a vendor page cannot be read,
buildstops rather than quietly rendering on less input than it had. - Machine-local by design. Copy counts and the values you typed into placeholders stay out of the repository, so two Macs never fight over them.
# illustrative: what a guidance change looks like in review
$ git diff rendered/claude-opus-5/fix-bug-and-test.md
@@ -2,4 +2,4 @@
seed = "fix-bug-and-test"
model = "claude-opus-5"
-guide_hash = "9a4c1e0b2d7f"
+guide_hash = "45195e0f127e"
@@ -12,3 +12,3 @@
-Work through the following steps in order, and report each one.
+Done means: the bug is reproduced, the cause is fixed, a regression
+test exists, and the relevant tests pass. Skip the narration.
Four models, four different prompts.
That difference is the point.
A frontier model degrades when you over-specify; an open-weight model needs numbered steps, an output format and an example. The same five words render as 182 words of outcome-focused prose for one and 698 words of procedure for another. A target is data, not a vendor account: rendering for GPT or Llama never calls OpenAI or Meta.
You have this repository open and can read files, run commands, and execute the test suite.
Fix the bug described below, and cover it with a test.
Reproduce it first: find the failing behavior in the actual code and confirm you can trigger it before changing anything. If you cannot reproduce it, say so and describe what you tried instead of guessing at a fix.
Fix the underlying cause, not the symptom. Keep the change minimal: no refactoring, no extra error handling, and no restructuring of code the bug does not touch.
Add a test that fails against the old code and passes against the fix, written in the style and location of the existing tests for that area. Run the tests covering the affected area, plus the fix's own test.
Done means: the bug is reproduced, the cause is fixed, a regression test exists, and the relevant tests pass. Report in a few sentences: the root cause, the change, the test you added, and the test command with its result. Keep the report brief; skip the step-by-step narration.
Bug:
You are a software engineering agent working in a repository you can read and modify. Fix the bug described below, and add a test that covers it.
Work in this order, and do not skip ahead:
1. **Reproduce first.** Locate the relevant code by searching the repo. Run the failing case, the existing test, the command, or a minimal script you write, and capture the actual output. Do not edit any source file until you have observed the failure yourself.
2. **Diagnose.** Read the surrounding code, not just the failing line. State the root cause in one or two sentences before changing anything.
3. **Fix.** Make the smallest change that addresses the root cause. Match the conventions already in the file.
4. **Test.** Add a regression test in the project's existing test suite and style. It must fail against the original code and pass against your fix: verify this by reverting the fix and running the new test. A test that passes either way proves nothing.
5. **Verify.** Run the new test plus the existing suite for the affected area, and paste the actual command output.
Before each tool call that changes a file or runs a command, say in one line why you are doing it.
You are done when: the failure reproduces before the fix and not after, the new test is confirmed to fail without the fix, the affected suite passes…
You are fixing a bug in a repository you have open. Work through the numbered steps in order. Do not skip a step.
1. Read the bug report at the end of this prompt. Restate the bug in one sentence: what happens now, and what should happen instead. If the report does not say what the expected behaviour is, write down the expected behaviour you inferred and say that you inferred it.
2. Locate the code. Search the repository for the file, function, error message, or symbol named in the bug report. List every file path you opened and why. Do not guess at file contents: read the files.
3. Reproduce the bug BEFORE changing any code. Run the failing command, test, or script and paste the exact output you got. If you cannot reproduce it, stop and report what you ran, what happened instead, and what you would need in order to reproduce it.
4. Find the root cause. State the specific line or lines that cause the wrong behaviour, and explain in two or three sentences why that code produces the observed output. Do not describe the symptom again: name the defect.
5. Write a failing test first. Add a test that fails because of this bug, in the repository's existing test framework and in the directory where its tests already live. Run it. Paste the output showing it fails.
6. Fix the bug. Change only the code needed to fix this defect…
You are working in a repository you have full access to: you can read files, run shell commands, and run the test suite. Fix the bug described below. Follow these steps in order. Do not skip a step.
STEP 1: REPRODUCE THE BUG BEFORE CHANGING ANY CODE.
1a. Read the bug report at the end of this prompt.
1b. Locate the relevant files. Use search commands (`grep -rn "<symbol>" .`, `rg "<symbol>"`, `find . -name "<file>"`) to find the code named in the report.
1c. Run the failing case: run the existing test suite, or the specific test, or the exact command from the report.
1d. Paste the real, unedited failure output into your answer. If you cannot reproduce the failure, STOP and report exactly what you ran and what happened instead.
STEP 2: FIND THE ROOT CAUSE.
2a. Read the failing function and the code that calls it.
2b. State, in one or two sentences, the exact line or lines that cause the wrong behaviour and why they are wrong. Name the file and line number.
STEP 3: WRITE A FAILING TEST FIRST.
…
OUTPUT FORMAT: use exactly these six headings, in this order:
## 1. Reproduction
## 2. Root cause
## 3. Failing test
## 4. Fix
## 5. Verification
## 6. Summary
EXAMPLE of the level of detail expected (abbreviated, for shape only):
## 1. Reproduction
`$ pytest tests/test_cart.py::test_total -q`
E assert 0 == 10.0 …
Openings of the real renders in the starter library, counted on the prompt body. Claude Sonnet 5 is a fifth registered target; add your own with promptlib model.
Does a tailored prompt beat the raw seed?
It depends on the model, and that is the finding.
The premise was checked before this page was written: four tasks with known right answers, each given to the same model twice, once as the five-word seed and once as that model's render. Criteria were registered before anything ran. Both results are published, including the one that did not support the tool.
Both conditions found the true mechanism wherever it was findable. The render explained more thoroughly and refused more; the seed delivered more working code. On a strong model, tailoring changed risk posture, not correctness.
If you already pay for a frontier model, the honest advice is: type the short prompt. Seedbed is not going to make it answer better.
The raw seed produced five confident fabrications on one task and skipped the requested test on both fix tasks. The render invented nothing, named nine things it could not see, wrote real tests both times, and did it in 44% fewer words.
"likely using SHA-256 … the file format is likely YAML-like … the save method would likely…""The Render class is declared but not defined in the provided code." Nine times, in different words.swift build and
swift test refused by the permission system. That falls harder on the render
than on the seed, because only the render asks for a test run. Those two tasks have since been re-run with
the toolchain permitted: on one the render and the seed tied, and the other turned out to have no
defect in the code it supplied, so it is withdrawn as evidence either way.
On both models the render went looking for code
that was not there, which led to a design change: a seed now declares whether it will be pasted into an agent with a checkout or a chat
window with a snippet, and the render is built for that context. The raw outputs, inputs and scoring are on
the evidence page, so the scoring can be disagreed with rather than taken on trust.
Summon it over anything.
Type, pick, paste.
The menu-bar app is a SwiftUI panel that appears over any window on any Space. It shells out to the same Python package the command line and the web page use, so staleness, guidance and the enhancer have exactly one implementation.
⌥⌘P anywhere. Type to filter, ⏎ pastes into the app you came from, ⌘1 to ⌘9 picks a model and builds the render first if it has never been made. A stale dot means the seed or the guidance changed since.
The web page · python3 -m promptlib serve --open
Every seed on a row, a model dropdown beside it. Bound to localhost, for your own library.
Your agent fetches the prompt it needs,
instead of you copying one across.
The Mac app can run an MCP server. Switch it on in Settings, press Copy configuration, paste that into Claude Code, Cursor or Claude Desktop, and the agent has a library it can search.
find_prompt takes a description, not a name. An agent asking for "something for
reviewing a diff before I merge" gets the prompt titled Review my diff. A text match answers most
asks on its own in well under a tenth of a second; only when it cannot choose does the ask go to the
enhancer to be settled. Every prompt is also exposed through MCP's own prompts/list and
prompts/get.
find_promptget_promptlist_promptslist_modelsbuild_prompt
- Loopback only, and a bearer token. Both, not either. Nothing on your network can reach it, and every request must carry the token, which lives in the login Keychain.
- A second, read-only token can look prompts up but can never call
build_prompt, so a client you have not decided to trust cannot spend an LLM call. It is not even shown that tool. - Wrong tokens lock out after ten tries, doubling from one minute to fifteen, while a correct token is still always served. A request whose Host or Origin is not this Mac is refused, with the reason in the response.
Seedbed 0.1.32 · universal DMG · signed and notarized · updates itself through Sparkle
Plant it.
Or with Homebrew, from the public repository, which is also the tap:
brew tap anatoliv/seedbed https://github.com/anatoliv/seedbed
brew trust anatoliv/seedbed # Homebrew 6 and later requires this for third-party taps
brew install --cask seedbed
The app creates your library
Seedbed is a front end and does not carry the prompts. On first launch it clones the public library if no valid checkout exists. This needs internet access and Git. You also need Python 3.11 or newer for tomllib. If automatic setup fails, you can clone the library yourself:
mkdir -p "$HOME/Library/Application Support/Seedbed"
git clone https://github.com/anatoliv/seedbed \
"$HOME/Library/Application Support/Seedbed/Library"
What it asks for, and what it never sends
Pasting into the app you came from needs the Accessibility permission, which macOS asks for the first time you use it. Without it Seedbed copies to the clipboard and tells you why it did not paste.
Crash reports are off. If you turn them on, they carry the stack trace and the versions, and never a prompt, a render, a value you filled in, or a token. Your home folder path is rewritten to a tilde before anything leaves this Mac. There is no other telemetry, and no account.
- MIT licence
- macOS 14 Sonoma or later
- Apple silicon and Intel
- Git for setup and Python 3.11 to run
- CLI and web page work without the app
Free, and staying free.
Seedbed is MIT-licensed and costs nothing. There is no paid tier, no trial and no account, so a tip unlocks nothing: it is a way to say the tool was worth something to you, and that is all it is.
Supporters who ask to be named appear in the app's About page. Reporting a bug or telling me what did not work is worth more than a tip, and costs you less.
The questions worth asking first.
Why not paste the short prompt and let the model work it out?+
Does targeting GPT or Llama call OpenAI or Meta?+
claude CLI already on your Mac, so there is no API key and no extra spend. --enhancer anthropic uses the official SDK; --enhancer openai takes any OpenAI-compatible endpoint, including one on your own machine.What does it cost?+
build skips anything whose seed and guidance have not changed.What leaves my Mac?+
Can I use it without the app?+
python3 -m promptlib gives you list, build, copy, match and the local web page, with no dependencies beyond the standard library. The app adds the global hotkey, pasting into the frontmost window, and the MCP server.