doma v0.4.1

Put your directories on the cutting board
doma Logo

Directory tag manager — put your directories on the cutting board.

InstallationShell integrationPipelinesAI agentsContributingReleases


doma is a Crystal CLI for tagging directories so you can recall, browse, or batch-execute across them. Tag your projects once (crystal, work/proj-a, bookmark), then jump to them, list them, or run a command across the whole set without re-typing paths.

doma add ~/Projects/my-app -t crystal -t web
doma list -t crystal --paths | xargs -I{} sh -c 'cd {} && shards build'
doma cd crystal                # interactive picker, then cd  (needs `doma setup install`)
doma mark spike                # bookmark cwd for 7 days
Features

Tagging

  • Multiple tags per directory; tags are reusable across paths
  • Auto-tag from basename and Git remote (--auto-tag, --git-tag)
  • Glob filter on tags (list -t 'work/*', run 'work/*' -- cmd) — shell-style: * matches within one segment, ** crosses /, ? is a single non-/ character
  • Hierarchical tag display (tags --tree)
  • TTL on tags: --ttl 30m | 1h | 7d | 2w, --tmp for the 7-day default, mark for the cwd + 7-day shortcut
  • Stable 7-char short_id per directory — survives renames; usable via rm <id> and trash restore <id>

Navigation & operations

  • tui — full-screen fuzzy finder over your registered directories, and the default when you run doma with no subcommand. Fuzzy match on paths with match highlighting, narrow with a small query syntax (tag:crystal, -tag:archived, id:0d, path:src), register a directory with Ctrl-A or copy a path with Ctrl-Y without leaving it. Enter prints the path so the shell wrapper cds into it
  • list --pick resolves to a single path (Crystal-native picker, no fzf dependency); the doma cd <tag> shell wrapper from doma setup install builds on it
  • run <tag> -- <cmd> to execute a command in every tagged directory; --parallel (with --jobs N, default CPU count) and --fail-fast available
  • status <tag> for a one-glance git dashboard across a tagged set — branch, ahead/behind, dirty count; --dirty to show only repos with uncommitted work, --json for scripting
  • move to follow a path that moved on disk; tags carry over
  • rename to merge or relabel tags
  • Recency tracking — most-used directories surface first in pickers and list --by recent
  • Substring search across path / basename / tag (doma list <query>)
  • Single-entry detail view (doma info defaults to cwd) — tags, TTLs, last-used, exists check
  • Dead-path detection: list --check, prune --gone; expiry purge: prune --expired

Pipelines & scripting

  • list -t TAG --paths — newline-separated paths for while read / xargs
  • list -t TAG -0 — NUL-separated for xargs -0, safe for paths with spaces
  • list --json, tags --json, stats --json, export --json|--yaml
  • "Did you mean ..." hints (Levenshtein) for typos
  • Output stays color-free when piped; SIGPIPE-safe

Storage & safety

  • SQLite-backed (WAL, foreign keys, busy_timeout) — handles concurrent doma calls across multiple shells
  • Path canonicalization: ~, symlinks, and trailing slashes all collapse to one stable key
  • Transactional writes; atomic snapshot import/export
  • Schema migrations via PRAGMA user_version — old DBs upgrade transparently
  • Strict tag validation; sanitized auto-tags so a .dotfiles repo doesn't break --auto-tag

Distribution & integration

  • Single static binary (musl + sqlite-static); no runtime dependencies
  • Packaged for Homebrew, AUR, Snap, .deb, .rpm, .apk
  • Multi-arch container image at ghcr.io/hahwul/doma
  • CycloneDX SBOM published with every release
  • Shell integration installer (doma setup install) for bash, zsh, fish
  • AI skill for Claude / Cursor / etc. — see skills/doma/SKILL.md

Installation

Homebrew

brew tap hahwul/doma
brew install doma

From source

git clone https://github.com/hahwul/doma.git
cd doma
shards install
shards build --release --no-debug --production

Pre-built binaries

Static Linux and macOS binaries are attached to every release. .deb / .rpm / .apk / .snap packages are published alongside.

Container

docker pull ghcr.io/hahwul/doma:latest
docker run --rm -it -v "$HOME/.config/doma:/root/.config/doma" \
  ghcr.io/hahwul/doma list

Shell integration

doma cd lives in a shell function rather than the binary — a child process can't change its parent shell's working directory. The function calls doma list -t <tag> --pick (the binary's single-pick primitive) and runs cd on the result. One-shot install:

doma setup install                    # auto-detects $SHELL, appends to your rc
exec $SHELL                           # or `source ~/.zshrc`
doma cd crystal                       # interactive picker, then cd
doma                                  # bare doma opens the fuzzy finder, then cd

The wrapper also makes bare doma and doma tui cd into whatever you pick in the finder.

If you'd rather wire it manually:

eval "$(doma setup init zsh)"         # bash / zsh
doma setup init fish | source         # fish

Without the wrapper, the equivalent inline form works everywhere:

cd "$(doma list -t crystal --pick)"

Pipelines

doma is designed to compose with the rest of your shell. A few common shapes:

# Update CI files across every Crystal project
doma list -t crystal --paths | while read -r d; do
  (cd "$d" && sed -i 's/crystal: 1.20/crystal: 1.21/' .github/workflows/*.yml)
done

# Status across work repos (paths-with-spaces safe)
doma list -t 'work/*' -0 | xargs -0 -I{} sh -c 'cd "{}" && git status -s | head'

# Structured access via jq
doma list --json | jq -r '.[] | "\(.short_id)\t\(.path)\t\(.tags|join(","))"'

# Ad-hoc bookmarks during a code review session
doma mark auth-review
# ... cd around ...
doma list -t auth-review --paths

AI agents

doma ships a Claude Code skill that teaches an agent when to query the database for a path list ("update CI for all my Crystal projects") and when to register or bookmark a directory ("track this", "remember this for later").

Install via Vercel Skills:

npx skills add hahwul/doma

Or copy the file by hand into your agent's skill directory:

cp -r skills/doma ~/.claude/skills/
# or symlink so updates land automatically:
ln -s "$(pwd)/skills/doma" ~/.claude/skills/doma

Contributing

doma is open-source and PRs are welcome. Please check CONTRIBUTING.md before sending a patch.

Why "doma"?

Doma (도마) is the Korean word for cutting board — the workbench where ingredients are gathered, grouped, and chopped before going into the pan. doma aims to be the same kind of workbench for your directories: pull the ones you care about onto a single board, group them by category (crystal, work/proj-a, bookmark), and run bulk operations across the piles as if they were mise en place.

Repository

doma

Owner
Statistic
  • 4
  • 0
  • 0
  • 0
  • 3
  • about 4 hours ago
  • April 25, 2026
License

MIT License

Links
Synced at

Sat, 04 Jul 2026 05:26:24 GMT

Languages