AI coding tools are incredibly useful. They can read your codebase, understand context across dozens of files, and make changes in seconds. They can also read your .env file. Your secrets/ directory. Not because they're malicious — but because nothing stops them by default. I built uignore to fix th
Geekfarmer
AI coding tools are incredibly useful. They can read your codebase, understand context across dozens of files, and make changes in seconds.
They can also read your .env file. Your secrets/ directory.
Your SSH keys. Your AWS credentials.
Not because they're malicious — but because nothing stops them by default.
I built uignore to fix this.
What is uignore?
uignore gives you a single .uignore file — same syntax as .gitignore — that blocks file access across all supported AI tools simultaneously.
gitignore
# .uignore
secrets/
.env
.env.*
*.pem
*.key
Add a path once. Claude Code, Gemini CLI, Cursor, and Windsurf all respect it automatically.
How it works
Each AI tool has a native hook system:
┌─────────────┬────────────────┬─────────────────┐
│ Tool │ Hook │ Block mechanism │
├─────────────┼────────────────┼─────────────────┤
│ Claude Code │ PreToolUse │ exit code 2 │
├─────────────┼────────────────┼─────────────────┤
│ Gemini CLI │ BeforeTool │ exit code 2 │
├─────────────┼────────────────┼─────────────────┤
│ Cursor │ beforeReadFile │ exit code 2 │
├─────────────┼────────────────┼─────────────────┤
│ Windsurf │ pre_read_code │ exit code 2 │
└─────────────┴────────────────┴─────────────────┘
uignore registers a hook with each tool. Before every file read or write, the hook resolves the target path against your .uignore rules.
If it matches — the operation is blocked. The file content never reaches the model.
Getting started
No global install required:
npx @ottoai/uignore init # creates a .uignore template
npx @ottoai/uignore install # registers hooks for all tools
Then commit to git:
git add .uignore .claude/settings.json .gemini/settings.json \
.cursor/hooks.json .windsurf/hooks.json
git commit -m "chore: add uignore"
Your whole team now has the same protection automatically.
No per-developer setup required.
Syntax
uignore follows .gitignore conventions:
# Block a directory
secrets/
# Block specific file types
*.pem
*.key
# Block .env and all variants
.env
.env.*
# Block everything except README
*.md
!README.md
Hierarchical .uignore files are supported — place one in any subdirectory for subtree-specific rules. A global ~/.uignore applies personal rules across every project.
CLI
uignore check secrets/apikey.txt # test if a file would be blocked
uignore list # show all active rules
uignore diff # show which tracked files are blocked
uignore doctor # diagnose config problems
uignore add *.pem # add a pattern
uignore remove *.pem # remove a pattern
Open source
MIT licensed. Contributions welcome.
If you use an AI tool that isn't supported yet, PRs are open.
Found this useful? Share it!
Read the Full Story
Continue reading on Dev.to
Related Stories
Majority Element
about 2 hours ago
Building a SQL Tokenizer and Formatter From Scratch — Supporting 6 Dialects
about 2 hours ago
Markdown Knowledge Graph for Humans and Agents
about 2 hours ago

Moving Beyond Disk: How Redis Supercharges Your App Performance
about 2 hours ago

