AI-powered README generator — interview your project, scan your codebase, generate a complete README
Project description
WriteMe — AI-powered README generator
WriteMe is an AI-powered CLI tool for developers who want to generate complete, production-grade README files without spending time writing them manually. It solves the problem of projects shipping with poor or missing documentation by interviewing the developer about their project, scanning the codebase, and using Google Gemini to generate a comprehensive README.md automatically.
What This Does
WriteMe provides a comprehensive solution for generating high-quality READMEs for developer projects, offering a range of features to streamline the documentation process:
- Progressive 3-phase interview — Guides the user through 30 questions across 3 optional depth layers to capture full project context.
- Codebase scanner — Reads the entire project directory and feeds source code directly to Gemini for a more accurate README.
- AI-powered generation — Sends interview answers and codebase to Gemini 2.5 Flash with the v5 system prompt to generate a production-grade README.
- README writer — Creates a new
README.mdor overwrites/appends an existing one with collision detection. - API key management — Stores the Gemini API key securely in the user config directory, prompting once and never again.
- Sensitive file protection — Automatically skips
.envfiles, keys, certificates, and credentials during codebase scanning. - Token budget management — Truncates large files and prioritises key source files to stay within Gemini's context window.
- Retry logic — Automatically retries on 429 rate limit errors with exponential backoff.
- SKIP keyword — Skips a question entirely, sending no answer to Gemini for that question.
- TLDR keyword — Sends a generic answer to Gemini, allowing it to infer context from the codebase.
- RTFM keyword — Shows detailed help and examples for the current question.
- QUIT keyword — Exits the interview with confirmation, cancelling README generation.
--resetflag — Clears the saved API key so the user can rotate credentials.--versionflag — Prints the current installed version.- Rich terminal UI — Features styled panels, colored output, and an ASCII logo banner for an improved user experience.
Requirements
To run WriteMe, ensure you have:
- Python 3.12+
- The following Python packages (automatically installed via
pip install writeme-ai):google-genai>=1.67.0python-dotenv>=1.2.2platformdirs>=4.0.0rich>=14.3.3pip-audit>=2.10.0pyasn1>=0.6.3pathspec>=1.0.4
Quick Start
- Install the project dependencies using pip:
pip install writeme-ai
- Run the WriteMe CLI tool. On the first run, you will be prompted to enter your Google Gemini API key.
writeme
Setup
Follow these steps to get WriteMe up and running from a clean slate:
- Clone the repository:
git clone https://github.com/ushiecodes/writeme.git
- Navigate into the project directory:
cd writeme
- Install the project dependencies using pip:
pip install writeme-ai
- Run the WriteMe CLI tool. On the first run, you will be prompted to enter your Google Gemini API key.
writeme
Usage
The primary workflow for using WriteMe involves launching the CLI tool in your project directory, answering a series of questions, and then letting the AI generate your README.md file.
- User navigates to their project directory in the terminal.
- User runs
writeme. - The tool displays a banner and an information panel.
- The tool checks for a saved Gemini API key in
~/.config/writeme/config.json. - If no key exists, the user is prompted to enter their Gemini API key, which is then saved for future use.
- The Phase 1 interview begins, asking 5 initial questions about the project.
- The user answers questions; they can type
SKIP,TLDR,RTFM, orQUITat any time for specific interactions. - A layer prompt appears, allowing the user to choose to complete "done" (finish), "layer 2" (add usage, config, architecture), "layer 3" (add security, deployment, changelog, contributing), or "more" (both layer 2 and 3).
- If Layer 2 is chosen, Batch A (Q6-Q11) and then Batch B (Q12-Q16) questions are asked.
- If Layer 3 is chosen, Groups A (Q17-Q22), B (Q23-Q25), and C (Q26-Q30) questions are asked.
- The interview completes, and the tool scans the project codebase.
- Sensitive files, binary files, and oversized files are automatically skipped.
- Interview answers and the codebase are assembled into a single prompt.
- The prompt is sent to Gemini 2.5 Flash with the v5 system prompt as a system instruction.
- Gemini generates the
README.mdcontent and returns it. - The tool strips any markdown code fences from the response.
- If
README.mdalready exists in the current directory, the user is asked to overwrite, append, or cancel. - The generated
README.mdis written to the current working directory. - The user sees a final success message: "Done. Your README is ready."
Configuration Reference
WriteMe uses the following configuration options:
| Variable | Purpose | Default | Valid Values | Required |
|---|---|---|---|---|
API_KEY |
🔑 Gemini API key used to authenticate requests | none |
any valid Gemini API key string | required |
MODEL |
Gemini model used for generation | gemini-2.5-flash |
any model returned by client.models.list() |
optional |
MAX_FILE_SIZE_KB |
maximum size of a single file the scanner will read | 150 |
any positive integer | optional |
MAX_TOTAL_CHARS |
maximum total characters sent to Gemini from codebase scan | 400000 |
any positive integer | optional |
These variables are loaded in the following order of precedence:
- Config file:
API_KEYis primarily stored and loaded from a JSON file at~/.config/writeme/config.json. - .env file: A local
.env.localfile (for development only) can also provideAPI_KEYviapython-dotenv. - Hardcoded defaults with environment override:
MODEL,MAX_FILE_SIZE_KB, andMAX_TOTAL_CHARShave hardcoded defaults in the source, but can be overridden by environment variables set before launch.
Architecture
Folder Tree
.
├── .gitignore # Specifies intentionally untracked files to ignore.
├── cli.py # Entry point, argument parsing, orchestrates the full run sequence.
├── config.py # API key storage, retrieval, and reset logic.
├── display.py # All Rich terminal UI rendering, panels, banner, and styled output.
├── gemini.py # Assembles the prompt and handles all Gemini API communication.
├── interview.py # Runs the 3-phase question flow and formats answers for Gemini.
├── LICENSE # Contains the project's open-source license.
├── prompt.py # Stores the v5 system prompt as a single string constant.
├── pyproject.toml # Package metadata, dependencies, and CLI entry point definition.
├── README.md # The project's primary documentation file.
├── scanner.py # Walks the project directory, filters sensitive and binary files,
| enforces token budget, formats codebase for Gemini.
├── writer.py # Writes or updates README.md with collision detection and output cleaning.
└── __init__.py # Marks the directory as a Python package.
Critical Execution Path
This sequence describes the critical path from a user running writeme to the final README.md being generated:
- User runs
writemein terminal. cli.main()is called via thepyproject.tomlentry point.argparseparses--resetor--versionflags if present.display.print_banner()renders the ASCII logo panel.config.load_api_key()checks~/.config/writeme/config.jsonfor a saved key.display.print_info_box()renders the info panel with running directory and API key status.config.get_api_key()prompts for key if not found, saves viaconfig.save_api_key().interview.run_interview()starts the phase controller.interview.run_phase_one()asks Q1-Q5 viainput()and collects answers into a dict.interview._ask_layer_prompt()shows the styled layer options panel.interview._parse_layer_intent()parses the user response.interview.run_phase_two()asks Q6-Q16 if layer 2 was chosen.interview.run_phase_three()asks Q17-Q30 if layer 3 was chosen.run_interview()returns the complete answers dict orNoneif user quit.gemini.generate_readme()is called with the answers dict.config.get_api_key()loads the saved API key.genai.Client()initialises the Gemini client.scanner.scan_codebase()walks the current directory withos.walk().scannerappliesIGNORED_DIRS,ALWAYS_IGNORE,IGNORED_FILES,IGNORED_SUFFIXES,IGNORED_PREFIXES,TEXT_EXTENSIONSwhitelist, andis_binary_file()check.scannerreads each allowed file withfilepath.read_text().scanner.format_codebase_for_prompt()assembles priority files first then remaining files within token budget.interview.format_answers()converts the answers dict into a labeled plain text string.- The full prompt is assembled combining
formatted_answersandcodebase_context. gemini._call_with_retry()sends the prompt to Gemini with the v5 system prompt as system instruction.client.models.generate_content()makes the API call to Gemini 2.5 Flash.- On 429 error, exponential backoff waits and retries up to 3 times.
response.textis returned togenerate_readme().writer.write_readme()receives the generated markdown.writer._clean_output()finds the first top-level heading and strips everything before it.- If
README.mdexists, user is prompted to overwrite, append, or cancel. Path.write_text()writes the finalREADME.mdto the current directory.cli.main()callsdisplay.print_success()with "Done. Your README is ready."
Component Communication Model
All modules communicate via direct Python function calls and return values. The only external communication is an outbound HTTPS call to the Gemini API at generativelanguage.googleapis.com via the google-genai SDK. Rich display functions from display.py are called throughout all modules for consistent terminal output. There is no inter-process communication, message queue, or shared database communication within the application itself.
Design Decision Log
- API key stored in
~/.config/writeme/config.jsoninstead of per-project.envfiles: This allows the user to set their Gemini API key once and use it across all projects without re-entering it each time, improving the user experience for a global CLI tool. - Codebase injected directly into the Gemini prompt instead of summarising it: This approach significantly reduces the risk of hallucination and ensures that the generated README accurately reflects the actual code and structure, rather than relying solely on the developer's memory or description.
- Progressive 3-phase interview with optional depth layers: This design prevents user overwhelm by breaking down the extensive questionnaire into manageable phases. Phase 1 provides a publishable draft, allowing users to choose additional depth only if needed for comprehensive documentation.
QUIT_SENTINELpattern for quit handling: This allows for a clear quit confirmation while preserving any answers already collected. It cleanly signals tocli.pyto cancel README generation without losing previously entered data.- Plain text format for answers sent to Gemini instead of JSON or TOML: This was chosen to reduce token count and because Gemini generally handles labeled plain text more effectively for this specific use case, minimizing parsing errors or misinterpretations.
SKIPandTLDRare distinct keywords:SKIPstores nothing for a given question, instructing Gemini to infer entirely from the codebase.TLDRsends a generic placeholder answer, providing Gemini with an explicit fallback signal for inference, which can be useful when specific details are known but concise.TEXT_EXTENSIONSwhitelist inscanner: Blocks binary files from being sent to Gemini by default, without relying solely on extension matching. Theis_binary_file()null-byte sniff acts as an additional safety net.- Priority file bucketing before token budget loop: Ensures key files like
cli.py,pyproject.tomlalways appear in the prompt even on large codebases, preventing important architectural context from being excluded due to token budget starvation. - All terminal output routed through
display.pyRich functions: Ensures consistent styling across all modules and centralizes UI management, making it easy to restyle the entire terminal interface from one file.
Security
Data Handling and Storage
WriteMe handles the Gemini API key as its only sensitive data. This key is stored in plaintext JSON at ~/.config/writeme/config.json on the user's local machine. The security of this key relies on the operating system's file permissions for the user's home directory. WriteMe does not handle passwords, personally identifiable information (PII), financial data, or session state.
Authentication Model
There is no authentication or authorisation model within WriteMe itself. It operates as a local CLI tool, and access to its functionality is entirely controlled by the operating system user running the application. The only credential involved is the Gemini API key, which is read by config.get_api_key() at runtime to authenticate requests to the Google Gemini API.
Network Exposure
WriteMe is a local-only application. It does not open any inbound network ports, run a server, or expose any services to the local area network (LAN) or the internet. Its only network interaction is a single outbound HTTPS call to the Google Gemini API at generativelanguage.googleapis.com to facilitate README generation.
Safe to Commit / Never Commit
Safe to commit:
- All application source code files (
.py) pyproject.tomlLICENSEREADME.md(the generated output, and this documentation itself)
Never commit:
Files listed in .gitignore should never be committed to the repository. This includes:
- Python-generated files (
__pycache__/,*.py[oc],build/,dist/,wheels/,*.egg-info) - Virtual environments (
.venv,.env.local) uvpackage lock files (.python-version,uv.lock)- Any other files containing credentials, secrets, or local environment variables (e.g., your Gemini API key,
.envfiles).
.gitignore Contents
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
.ruff_cache/
# Virtual environments
.venv
.env.local
# uv packages
.python-version
uv.lock
# OS / Editors
.DS_Store
Thumbs.db
.idea/
.vscode/
Dependency Audit Output
No known vulnerabilities found
Name Skip Reason
------- ----------------------------------------------------------------------
writeme Dependency not found on PyPI and could not be audited: writeme (0.1.0)
Known Security Limitations and Assumptions
- The Gemini API key is stored in plaintext JSON at
~/.config/writeme/config.json. Its security relies on the operating system's file permissions for the user's home directory. - The tool reads the entire project codebase and sends it to the Google Gemini API. Do not run this tool on codebases containing sensitive data beyond what is already covered by the sensitive file filters (e.g., highly confidential algorithms, proprietary business logic that cannot leave the local machine without approval).
- The sensitive file scanner covers common patterns but is not exhaustive. Users should verify their
.gitignorefile and scanner configurations cover all sensitive files before running WriteMe on projects containing highly sensitive data.
Deployment
WriteMe is a local-only CLI tool. It is not containerized, and there are no differences between local development and production environments. Users install it via pip install writeme-ai and run writeme in their project directory. No production-specific setup steps are required beyond the initial installation.
Troubleshooting
ModuleNotFoundError: No module named 'google'
Cause: Required Python dependencies, specifically the google-genai library, are not installed or are not accessible in your Python environment.
Fix:
pip install writeme-ai
google.genai.errors.ClientError: 429 RESOURCE_EXHAUSTED
Cause: You have exceeded the free tier quota for the Gemini API.
Fix:
Wait until midnight Pacific time for your quota to reset. Alternatively, generate a fresh API key at aistudio.google.com/apikey and clear your saved key by running:
writeme --reset
Then, re-run writeme and enter the new API key when prompted.
RuntimeError: Gemini rate limit hit after all retries. Wait a few minutes and try again, or use a different API key.
Cause: The daily free tier limit for the Gemini API has been exhausted, even after WriteMe's internal retry logic.
Fix:
Wait for the daily quota to reset (typically at midnight Pacific time). If you need to proceed immediately, generate a fresh API key at aistudio.google.com/apikey and reset your current key:
writeme --reset
Then, re-run writeme and enter the fresh API key.
Changelog
[0.1.2] — 2026-03-22
Fixed
- API key not persisting between sessions due to key name mismatch in config.json
Changelog generated from git log --oneline -20.
[0.1.0] — 2026-03-21
Added
- Enhanced prompt and message display with Rich text and dedicated helpers.
- Implemented comprehensive file filtering using .gitignore.
- Improved console output with Rich tables.
- Enhanced CLI output with banner and styling.
- Added Rich-based console display module.
- Added
QUIT_SENTINELfor explicit exit handling in interviews. - Integrated
ruffandtwinefor dev workflow, cleaned up imports and CLI entry. - Added
pip-auditand build dev dependencies. - Improved CLI info display and API key handling.
- Consolidated display functions for phase and controls printing.
- Added MIT license.
- Refined scanner file filtering and size limits.
- Improved configuration module's use of display functions for API key messages.
- Improved writer module's use of display functions for user output.
Fixed
- Reliably found the first top-level heading in generated output.
- Handled skipped interviews and improved prompts.
Security
- Updated
pyasn1dependency to addressCVE-2026-30922.
Contributing
Yes, WriteMe is open to contributions! We welcome developers to help improve the tool.
Branching Strategy:
Fork the repository, then create a feature branch from main for your changes.
Pull Request Process:
- Open a Pull Request (PR) against the
mainbranch. - Provide a clear and concise description of your changes.
- Ensure each PR focuses on a single feature or bug fix.
Code Style:
Adhere to PEP8 standards. Before submitting a PR, run a linter like ruff to ensure your code complies with the project's style guidelines.
Bug Reporting: Report bugs via GitHub Issues at https://github.com/ushiecodes/writeme/issues. Please include:
- The exact error message.
- Your operating system.
- Your Python version.
- Detailed steps to reproduce the bug.
Feature Requests: Submit feature requests via GitHub Issues. Describe the problem your proposed feature solves, rather than just the solution itself.
License & Credits
This project is licensed under the MIT License.
Maintainer: Utkarsh Kamat
- Email: work.utkarshkamat@gmail.com
- GitHub: ushiecodes
Third-party Libraries:
WriteMe uses the following third-party libraries, installed via pip and listed in pyproject.toml, each under its respective open-source license:
google-genai(Apache 2.0 License)python-dotenv(BSD License)platformdirs(MIT License)rich(MIT License)pip-audit(Apache 2.0 License)pyasn1(BSD 3-Clause License)pathspec(MIT License)
Project details
Release history Release notifications | RSS feed
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 writeme_ai-0.1.2.tar.gz.
File metadata
- Download URL: writeme_ai-0.1.2.tar.gz
- Upload date:
- Size: 37.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94b42121f2548fdf5930dcbdd1837d3e20acb56466391d80354bf67cee197926
|
|
| MD5 |
2b1b83f60eeb51a41f8162174860a629
|
|
| BLAKE2b-256 |
694b09da3eca6f428a4eb603d10fb941e1a6c60bb017027615cb5d7f9f48bc99
|
File details
Details for the file writeme_ai-0.1.2-py3-none-any.whl.
File metadata
- Download URL: writeme_ai-0.1.2-py3-none-any.whl
- Upload date:
- Size: 32.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ee1e6e6e40512a095f46b80143d44e89566d60c54e3d461643a05d0daf764dc
|
|
| MD5 |
f63a5f27528bada90fa4fb3184b490ff
|
|
| BLAKE2b-256 |
41a4829af11fde1696a7f8bc5b2fad2aaa3f8ca4c54819003b58fd0d6bde87e2
|