specfill
An interactive TUI that fills the gaps in your project specification prompts.
You paste a long project specification prompt that you intend to hand to a coding agent, or load it from a file. An LLM agent researches the topic with model-native web search and finds the aspects that are underspecified enough that the coding agent would have to guess. It then interviews you about them in plan-mode style: one question at a time, with concrete arrow-key options, multi-select where it makes sense, a free-text "Other" option, and skipping. Questions come in adaptive rounds and match the language of your prompt. The interview continues until the specification is complete, or until you press Finish now.
The result is your original prompt with the newly acquired information woven in, faithfully preserving your style and structure. If an answer contradicts the original prompt, the latest answer wins. Decisions you left unresolved stay exactly as ambiguous as you wrote them; nothing is invented.
How is this different from plan mode?
Plan modes, as implemented in common coding agent CLIs, are less thorough and don't explicitly look for gaps in your specification. They produce a plan for the task at hand, but that plan can hardly be used to define the original project specification, which can serve as a valuable documentation artifact on its own. specfill borrows the question UX from plan mode, but its output is the specification itself: complete, in your own words, and reusable.
Installation
Requires Python ≥ 3.12 on macOS or Linux. Install as a uv tool:
uv tool install specfill # from a checkout: uv tool install .
On first launch, a configuration wizard collects your provider preset (OpenAI, OpenAI-compatible, Anthropic, or Google), model identifier, API key, and an optional custom base URL. The API key is stored in the system keyring. If no keyring backend is available, it falls back to the config file (chmod 600).
Usage
specfill # paste your prompt into the editor
specfill my-prompt.md # or prefill it from a file
Flow:
- Paste your project specification prompt and press
Ctrl+Sto analyze it. The agent researches with web search before asking questions, and the progress is shown live. If your model has no native search, or search fails during a session, specfill warns and continues without it. - Answer the questions. Use the arrow keys plus
EnterorSpaceto select, or type into Other / details… for a free-text answer.Ctrl+Nanswers,Ctrl+Kskips,Ctrl+Ffinishes early. - The result streams into a scrollable preview. Press
cto copy it to the clipboard (with confirmation),rto regenerate it from the same answers, andpto quit and print the revised prompt, and only that, to stdout.
Skipped questions are treated as "implementer's discretion" and are never asked again.
Configuration
Settings live in ~/.config/specfill/config.toml (honors $XDG_CONFIG_HOME).
They can be edited in three ways: the in-app settings screen (Ctrl+O on the
paste screen), the CLI, or the file itself.
specfill config show # current configuration
specfill config path # config file location
specfill config set provider anthropic # provider | model | base-url | web-search
specfill config set model claude-opus-5
specfill config set-key # store the API key (hidden prompt)
Every setting can also be overridden per invocation via SPECFILL_*
environment variables, for example SPECFILL_MODEL or
SPECFILL_WEB_SEARCH=false. API keys resolve from the keyring first, then the
config file or $SPECFILL_API_KEY, then the provider's conventional variable
(OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY).
LLM inference is provider-agnostic via Pydantic AI (default model: OpenAI GPT-5.6 Sol). The UI is built with Textual.
Development
uv sync
uv run pytest # offline tests (scripted models, no network)
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file specfill-0.1.1.tar.gz.
File metadata
- Download URL: specfill-0.1.1.tar.gz
- Upload date:
- Size: 96.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
491007a2a86656f18bf373f97b975e4be155ee99becadb164368a59f0b61dd43
|
|
| MD5 |
1162cc0fbb0f6e5215f8ec0f24eb7fed
|
|
| BLAKE2b-256 |
dd3145ef7fe44049988f7ae7255b95a1ac5bb7ed137f80b504d97708409edfd5
|
File details
Details for the file specfill-0.1.1-py3-none-any.whl.
File metadata
- Download URL: specfill-0.1.1-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67f38bf14e7ca2b4df4c38a7e552b15129e4e42e69ea65e722eff164d3a5a2a7
|
|
| MD5 |
5ec4904c22c30799dc0b18ee34776638
|
|
| BLAKE2b-256 |
e573e9aec4ce0a4b03ad5e2ec10ceb12238acd8185dab7abfd69ab37dc071b0d
|