- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
check / check (push) Failing after 14s
Press E on a contact: claude researches it in a background worker (UI stays responsive), a review modal shows the proposed fills + confidence/source, a/Enter applies (fill-blank + tags + sync), Esc cancels. Reuses build_prompt/run_claude/ parse_response/apply_enrichment. New EnrichReview modal. 4 tests (worker glue thin). Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
| .forgejo/workflows | ||
| kard | ||
| tests | ||
| .gitignore | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
kard
A Textual contacts TUI built on khard's vCard store. Adds Tokyo Night theming,
Space-leader/which-key keys, multi-select, category management, and duplicate
detection/merge — while reusing khard for new-contact creation and $EDITOR
for edits. Sync stays with vdirsyncer.
How it works
kard/engine.py is the only module that touches the contact store. It reads
.vcf files directly via vobject (reads all addressbooks), exposes a frozen
Contact dataclass, and performs category writes and merge construction
in-place via vobject. new shells out to khard so UIDs and file naming are
correct. edit opens the known file path in $EDITOR (more precise than
khard edit which can match multiple). delete removes the file. Sync runs
vdirsyncer on demand and auto-syncs after every write.
Every other module (widgets, screens, app) depends only on the Contact DTO
and the Engine API — fully decoupled from vobject internals.
Install
pipx install ~/src/kard # or: pipx install git+ssh://forgejo/jmz/kard.git
kard --version
kard # launch the TUI
kard reads your existing ~/.config/khard/khard.conf for addressbook paths.
Its own UI state lives in ~/.config/kard/kard.toml. If khard isn't
configured, kard exits with a message pointing you at
https://github.com/lucc/khard rather than a traceback.
Keys
Press Space for the which-key menu:
Leader chords (Space then):
| Chord | Action |
|---|---|
Space a |
add contact (opens khard new in terminal) |
Space e |
edit contact ($EDITOR on the vCard file) |
Space d |
delete contact (confirm prompt) |
Space c f |
filter by category |
Space c t |
tag / untag category (applies to selected or current) |
Space c m |
manage categories (rename / delete across all contacts) |
Space M |
merge / duplicates (auto-detect or merge multi-selected) |
Space s |
sync now (runs vdirsyncer sync, then refreshes) |
Space y |
copy primary email to clipboard (macOS pbcopy) |
Space / |
search contacts |
Direct keys:
| Key | Action |
|---|---|
j / k (↓/↑) |
move cursor |
E |
enrich current contact (claude research → review modal → apply) |
x |
toggle multi-select on current contact |
X |
clear selection |
? |
show help screen (all keybindings) |
q |
quit |
Configuration
~/.config/kard/kard.toml (optional):
[keys] # remap leader or direct actions (action = key)
sync = "S"
[theme] # override Tokyo Night palette tokens (#rrggbb)
accent = "#bb9af7"
Remappable actions: add, edit, delete, cat_filter, cat_tag,
cat_manage, merge, sync, copy_email, search (leader chords);
show_help, quit (direct keys). Theme tokens: background, surface,
panel, foreground, primary, accent, secondary, warning, error,
success, dim. Invalid entries are ignored with a warning toast and fall
back to defaults.
Enrich (LLM-assisted)
kard enrich researches contacts via the claude CLI (which uses your
mail-archive MCP + web) and proposes fill-blank field/tag enrichments for
review. Two phases, human-gated:
# 1) propose — research thin contacts (no title and no note) -> a review file
kard enrich --thin --file ~/contacts-enrich.toml # also: --all / --uid U… / --category TAG
# --batch N contacts per claude call (default 5)
# --limit N cap how many are processed
# 2) review ~/contacts-enrich.toml — flip `apply = false` to skip, or edit values
# 3) apply — fill ONLY blank fields + union tags (additive), then vdirsyncer sync
kard enrich --apply --file ~/contacts-enrich.toml
kard enrich --apply --dry-run --file ~/contacts-enrich.toml # preview, write nothing
Safety: never overwrites a non-blank field; tags are additive only (Archive
only ever added); nothing applies without your review; --dry-run previews. Tags
are constrained to kard's fixed taxonomy. Requires the claude CLI on PATH (only
for enrich; the TUI never needs it) — enrichment research tools are pre-allowed
for headless runs.
Runtime dependencies
- khard — used for
kard add(runskhard new -a <addressbook>) - vdirsyncer — used for
kard sync/ auto-sync after writes - vobject — vCard parsing and in-place CATEGORIES / merge writes (Python library, installed automatically)
Development
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest # runs all tests