summaryrefslogtreecommitdiff
path: root/internal
AgeCommit message (Collapse)Author
2026-03-07Add KeePass migration command with text/password and binary attachment supportHEADmasterPaul Buetow
2026-03-02Release v0.5.3v0.5.3Paul Buetow
2026-03-02picker: extract fzf UI logic from store package (task 400)Paul Buetow
2026-03-02cli: add isolated dispatch routing tests (task 401)Paul Buetow
2026-03-02store/cli: move search output to CLI layer (task 400)Paul Buetow
2026-03-02store: make Data carry injected deps (task 402)Paul Buetow
2026-03-02store/cli: deduplicate shred helper (task 400)Paul Buetow
2026-03-02store: decouple crypto/git via interfaces (task 402)Paul Buetow
2026-03-02config: handle UserHomeDir failures (task 400)Paul Buetow
2026-02-23Release v0.5.2v0.5.2Paul Buetow
2026-02-22Bump version to v0.5.1, change default data_dir to ~/git/foostoredbv0.5.1Paul Buetow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Bump version to v0.5.0v0.5.0Paul Buetow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Replace all geheim path/name defaults with foostorePaul Buetow
- Default data_dir: ~/git/geheimlager → ~/git/foostore-data - Default export_dir: ~/.geheimlagerexport → ~/.foostore-export - Default key_file: ~/.geheimlager.key → ~/.foostore.key - Rename env var GEHEIM_SHELL → FOOSTORE_SHELL - Update package-level comments across cli, shell, store, git, config - Update Magefile and CLAUDE.md docs to reflect new paths Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Fix fish shell integration after binary rename to foostore (v0.4.0)v0.4.0Paul Buetow
- Rename completions/geheim.fish → completions/foostore.fish - Update all geheim references to foostore in ge.fish, install-fish.sh, FISH_INTEGRATION.md - Add fish shell integration section to README - Fix stale comment in internal/version/version.go Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Add unit tests to reach 63.3% coverage (task 335)Paul Buetow
- internal/shell/shell_internal_test.go (new): tests prefixCompleter.Do with table-driven cases covering empty prefix, partial match, no match, and multi-word line (prefix after space) - internal/cli/cli_test.go (new): tests pure helpers (logMsg, warn, printHelp, shredFile), dispatch paths with real store (ls, search, cat, rm, shred, get, paste, export, pathexport, open, edit, unknown command, empty argv), error paths for cmdAdd/cmdImport/cmdImportR, readPIN env-var path, completionFn commands-only path, makeActionFn nil cases - internal/store/store_test.go: added TestSearchActionPathExport, TestSearchActionWithCallback, TestSearchActionNilCallback, TestFzfEmpty, TestRemoveInteractiveInvalidThenDecline, TestImportForceOverwrite Total coverage: 44.8% → 63.3% Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Use \$EDITOR as default editor, falling back to vi (task 344)Paul Buetow
defaultConfig() now reads the \$EDITOR environment variable for EditCmd so users get their preferred editor automatically without touching the config file. Falls back to "vi" (universally available) when \$EDITOR is unset or empty. A JSON config value still takes precedence over \$EDITOR. Updated tests to: unset \$EDITOR where "vi" fallback is asserted, add TestLoad_editorEnvVar covering the three cases (\$EDITOR unset, \$EDITOR set, JSON override), and remove all stale "hx" references from comments. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Rename binary from geheim to foostorePaul Buetow
- go.mod: module path codeberg.org/snonux/geheim → codeberg.org/snonux/foostore - cmd/geheim/ → cmd/foostore/ - Magefile.go: binary/binaryName/mainPkg constants updated - internal/config: config file path ~/.config/geheim.json → ~/.config/foostore.json - All import paths and comments updated throughout - Delete geheim.rb (the original Ruby implementation, superseded by this Go rewrite) - CLAUDE.md rewritten to reflect the Go implementation, new binary name, build system (mage), and current package architecture Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Enforce Go best practices (task 344)Paul Buetow
- Magefile.go: add Default() target so bare `mage` builds the binary; fix Install()/Uninstall() to use $GOPATH/bin (default ~/go/bin) instead of the previous hardcoded ~/.local/bin path; use cp -v for visibility; fix 0755 -> 0o755 octal literal in createBinDir; extract binaryName const - cmd/geheim/main.go: add -version flag (prints version.Version and exits); pass flag.Args() instead of os.Args[1:] so flags are parsed cleanly - internal/cli/cli.go: remove dead fatal() and prompt() helpers that were never called anywhere in the codebase Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Fix PIN prompt and Ctrl+C behaviour in shellPaul Buetow
PIN prompt: replace readline.ReadPassword (which silently failed to display the prompt before the process was fully interactive) with golang.org/x/term.ReadPassword, which reliably disables echo and prints the prompt via a plain fmt.Print before reading. This fixes the root cause of the decryption failures — the user was never prompted for their PIN, so an empty/default PIN was used, producing a wrong IV. Ctrl+C: return io.EOF from Shell.ReadLine on readline.ErrInterrupt so that pressing Ctrl+C exits the shell loop, matching the Ruby behaviour where SIGINT terminates the process. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Update main.go and cli API for signal-cancellable context (task 352/main)Paul Buetow
main.go: set up signal.NotifyContext(SIGINT, SIGTERM) so long-running operations (fzf, external editors) terminate gracefully on interrupts. Call cli.New(ctx) explicitly and pass the context to c.Run(ctx, argv), matching the task spec and allowing the context to flow through all store/git/crypto operations. cli: expose New(ctx) and Run(ctx, argv) as the public API; remove the package-level Run() helper that created its own context.Background(). Verified: mage build produces ./bin/geheim; PIN=test ./bin/geheim version prints "> geheim v0.4.0". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Implement internal/cli package (task 352/cli)Paul Buetow
Full command dispatch, interactive shell loop, and all geheim commands mirroring the Ruby CLI class (geheim.rb lines 551-713). Key design points: - CLI struct holds all runtime deps; lastResult field enables Ruby-style fallback search term when a search command is given without an argument - dispatch → dispatchSimple (no-term commands) + dispatchSearch (term-based) kept under ~50 lines each per style guidelines - ActionOpen shreds the exported file immediately after opening, matching Ruby's shred_file(delay: 0) call - import implements Ruby's three-way dest_dir logic: nil→full src_path, contains-dot→literal dest, plain-dir→dir/basename(src) - completionFn notes $PIN limitation for description completion - openExported extends Ruby's OS detection with xdg-open, iTerm, Termux heuristics; comment documents the divergence from Ruby's evince default Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Address store package review findings (task 352/store)Paul Buetow
Fix CommitIndex to respect force=false by checking os.Stat before writing, mirroring the Data.Commit behaviour and keeping index/data pairs consistent. Skip .git directory in WalkIndexes via filepath.SkipDir to avoid spurious errors or false matches inside the git metadata tree. Make ShredAllExported continue past individual shred errors and return the last error, matching Ruby's best-effort shredding behaviour. Accept io.Reader in Store.Remove instead of hardwiring os.Stdin, enabling deterministic testing via strings.NewReader injection. Fix runFzf comment to state that any non-zero fzf exit is treated as no selection (not only exit 130). Document ImportRecursive divergence from Ruby basename-flattening behaviour. Add 14 new tests: Search, SearchActionCat, SearchActionCatBinarySkip, ShredAllExported, SearchActionExport, ImportRecursive, ReimportAfterExport, RemoveInteractive, RemoveInteractiveDecline, CommitIndexSkipsExisting, LoadIndexMissingFile, LoadIndexCorrupted, LoadDataMissingFile, LoadDataCorrupted, DataExportUnwritable, HashPathEdgeCases, ImportMissingSourceFile, WalkIndexesInvalidRegex. Improve TestIndexSort to call sort.Sort and assert final order. Remove orphaned section-header comment from store_test.go. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Implement store package with full test coverage (task 352/store)Paul Buetow
Adds internal/store with Index, Data, and Store types that mirror the Ruby Index, GeheimData, and Geheim classes. All 22 tests pass including AddAndSearch, Import, Export, Remove, HashPath, IsBinary, and sort interface. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Implement clipboard package with full test coverage (task 357)Paul Buetow
2026-02-22Implement git package with full test coverage incl Sync (task 355)Paul Buetow
2026-02-22Implement crypto package with AES-256-CBC and golden tests (task 354)Paul Buetow
Add internal/crypto/crypto.go with byte-identical AES-256-CBC encryption and decryption matching the Ruby OpenSSL reference in geheim.rb, including key doubling (enforceKeyLength), IV derivation (buildIV), PKCS7 pad/unpad, and NewCipher/Encrypt/Decrypt. Add internal/crypto/crypto_test.go with table-driven golden tests (6 vectors from Ruby), roundtrip tests (8 cases), enforceKeyLength/buildIV/PKCS7 unit tests, and error-path coverage (22 total). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Implement shell package with readline vi mode and tab completion (task 358)Paul Buetow
Replaces the stub in internal/shell/shell.go with a full implementation backed by github.com/ergochat/readline. The Shell struct wraps a readline instance configured with vi mode, a 500-entry in-memory history limit, and a custom prefixCompleter that delegates tab expansion to a caller-supplied function — mirroring the Ruby CLI#setup_readline / Readline.completion_proc pattern. History deduplication (skip empty lines and consecutive duplicate entries) matches the Ruby shell_loop behaviour by disabling auto-save and calling SaveToHistory only for non-empty, non-duplicate lines. A package- level ReadPassword helper handles PIN entry before the Shell is created. Tests skip gracefully when stdin is not a TTY. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Implement clipboard package (task 357)Paul Buetow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Implement git package (task 355)Paul Buetow
2026-02-22Implement version and config packages (task 353)Paul Buetow
2026-02-22Implement version and config packages (task 353)Paul Buetow
- internal/version: bump Version constant to v0.4.0 - internal/config: full Config struct with JSON snake_case fields matching Ruby Config::DEFAULTS; Load() merges ~/.config/geheim.json over defaults, tilde-expands path fields, and warns on stderr for parse errors - internal/config: table-driven tests covering defaults, overrides, tilde expansion, invalid JSON warning, and silent missing-file behaviour Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22Add Go project scaffold (task 352)Paul Buetow
- go.mod with module codeberg.org/snonux/geheim (go 1.22, mage dep) - Magefile.go with Build, Test, Install, Uninstall targets - cmd/geheim/main.go delegating to internal/cli - Stub packages: cli, version, config, crypto, git, store, clipboard, shell - go.sum generated; binary confirmed to build via mage build Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>