summaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md50
1 files changed, 30 insertions, 20 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 0a5d9b1..4e5a5c8 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -4,19 +4,30 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## What this is
-`geheim.rb` is a single-file Ruby CLI for AES-256-CBC encryption of files and text. All secrets are stored in a Git repository with encrypted filenames (via SHA-256-hashed paths) and encrypted indices. The tool is designed for personal use on macOS, Linux, Android (Termux), and Windows.
+`foostore` is a Go CLI for AES-256-CBC encryption of files and text. All secrets are stored in a Git repository with encrypted filenames (via SHA-256-hashed paths) and encrypted indices. The tool is designed for personal use on macOS, Linux, Android (Termux), and Windows.
-## Running
+## Building and running
```bash
-ruby geheim.rb [command] [args]
+mage # build (produces ./bin/foostore)
+mage install # install to $GOPATH/bin (default ~/go/bin)
+mage test # run all tests
+mage vet # run go vet
```
-No build step. No gems beyond Ruby's standard library (openssl, readline, etc. are all stdlib). No Gemfile.
+Or run directly after building:
+
+```bash
+./bin/foostore [command] [args]
+```
## Testing
-There is no test suite. Manual testing is done by running the script directly.
+```bash
+go test ./...
+```
+
+Table-driven unit tests exist for all internal packages.
## Fish shell integration
@@ -26,7 +37,7 @@ There is no test suite. Manual testing is done by running the script directly.
## Configuration
-Config is read from `~/.config/geheim.json` at startup (merged over defaults in `Config::DEFAULTS`). Key fields:
+Config is read from `~/.config/foostore.json` at startup (merged over defaults). Key fields:
- `data_dir`: Git repo where encrypted `.index` / `.data` file pairs are stored (default: `~/git/geheimlager`)
- `key_file`: Path to the raw encryption key file (default: `~/.geheimlager.key`)
- `export_dir`: Temporary directory for decrypted exports (default: `~/.geheimlagerexport`)
@@ -37,29 +48,28 @@ The PIN (entered at startup or via `$PIN` env var) is used to derive the AES IV;
## Architecture
-All code lives in `geheim.rb`. The class/module hierarchy:
-
```
-Log (module) – formatted output: log/warn/prompt/fatal
-Git (module) – git add/rm/commit/status/sync operations
-Encryption (module) – AES-256-CBC encrypt/decrypt; reads PIN once into @@key/@@iv
-Clipboard (module) – paste password field to OS clipboard (macOS/GNOME)
-CommitFile – writes a file and git-adds it
- GeheimData – one encrypted secret; encrypt/decrypt/export/reimport
- Index – encrypted filename index; maps description → .data file via SHA256 hash
-Geheim – main logic: fzf picker, search/add/import/rm/shred/walk_indexes
-CLI – parses argv, runs the interactive shell loop (readline, vi mode)
+cmd/foostore/main.go – thin entry point: -version flag, signal context, calls cli.Run
+internal/version/ – Version constant
+internal/config/ – load ~/.config/foostore.json, merge over defaults
+internal/crypto/ – AES-256-CBC encrypt/decrypt (byte-identical to Ruby reference)
+internal/git/ – git add/rm/commit/status/sync subprocess wrappers
+internal/store/ – secret store: add/import/remove/search/export over .index+.data pairs
+internal/clipboard/ – paste password field to OS clipboard (macOS/GNOME)
+internal/shell/ – readline shell with vi mode, tab completion, history dedup
+internal/cli/ – command dispatch, interactive shell loop
```
Data storage: every entry is a pair of files in `data_dir`:
- `<sha256(dir)>/<sha256(name)>.index` – encrypted human-readable description/filename
- `<sha256(dir)>/<sha256(name)>.data` – encrypted file content
-Search (`walk_indexes`) decrypts every `.index` file and regex-matches against the description. `fzf` is used for interactive fuzzy selection.
+Search (`WalkIndexes`) decrypts every `.index` file and regex-matches against the description. `fzf` is used for interactive fuzzy selection.
## Key design constraints
-- Encryption key and IV are class-level (`@@key`, `@@iv`) — initialized once per process from the key file and PIN.
+- Encryption key and IV are initialised once per process from the key file and PIN (`internal/crypto.Cipher`).
- Commit messages are intentionally generic ("Changing stuff, not telling what in commit history") to avoid leaking metadata into git history.
-- Binary vs text detection in `Index#binary?` is extension-based; known text extensions (`.txt`, `.README`, `.conf`, `.csv`, `.md`) are whitelisted.
+- Binary vs text detection in `Index.IsBinary()` is extension-based; known text extensions (`.txt`, `.README`, `.conf`, `.csv`, `.md`) are whitelisted.
- The `shred` command (GNU coreutils) is used when available; falls back to `rm -Pfv`.
+- AES-256-CBC implementation is byte-identical to the original Ruby `geheim.rb` so existing encrypted databases remain readable.