bw-menu/CLAUDE.md
Navid Sassan d621ebb81e Fix bugs, harden config validation, and clean up codebase
- Guard against empty ROFI_INFO before calling decode_info to prevent IndexError
- Use .get() chain for password field access to prevent KeyError
- Raise ValueError for unknown field names instead of silently returning empty string
- Validate config keybinding values against allowed fields (password, username, totp)
- Warn to stderr when config file exists but has invalid structure
- Set history file permissions to 0o600
- Extract shared prepare_entries() helper to deduplicate selector logic
- Add --version flag
- Delete legacy src/bitwarden.py and src/main.py
- Update CLAUDE.md to reflect pyyaml dependency
2026-02-17 20:27:15 +01:00

45 lines
2.0 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
bw-menu is a rofi/fzf frontend for Bitwarden via the `rbw` CLI. It lets users interactively search vault entries, select one, and copy a field (password, username, or TOTP) to the clipboard. It maintains a selection history so recent entries appear first.
## Commands
```bash
uv sync # install dependencies and set up virtualenv
bw-menu select # run with rofi (default)
bw-menu select --selector fzf # run with fzf
```
There are no tests or linting configured.
## Architecture
**Entry point:** `bw-menu` console script → `src/bw_menu/__main__.py:main()`
**Two subcommands:**
- `select` — interactive vault entry selection via rofi or fzf
- `history` — list/get from recently selected entries
**Key data flow for `select`:**
1. `cli.py` parses args → `__main__.py` creates a selector via `selector.create_selector()`
2. Selector fetches entries from `rbw.list_entries()` and history from `history.load()`
3. History entries appear first (marked distinctly per selector), then remaining entries sorted by folder/name
4. On selection, `rbw.get_field(entry, field)` retrieves the secret, entry is added to history
5. Result is printed or copied via `clipboard.copy()`
**Rofi script mode:** `RofiSelector` uses rofi's script mode protocol — rofi invokes `bw-menu select` repeatedly. `ROFI_RETV` env var distinguishes initial list generation (0) from selection handling (1). Entry identity survives the round-trip via `ROFI_INFO` using ASCII record separator (`\x1e`) encoding.
**External tools (called via subprocess):** `rbw` (vault access), `rofi`/`fzf` (selection UI), `wl-copy`/`xclip` (clipboard).
**Python dependency:** `pyyaml` (for config parsing). All external tool interaction is via subprocess calls.
## Build System
- `uv` for environment/package management
- `hatchling` as build backend
- Source layout: `src/bw_menu/`