| Age | Commit message (Collapse) | Author |
|
|
|
Change default backend from "geheim" to "keepass" and default KDBXPath
from ~/Documents/Keepass/master to ~/Documents/Keepass/master.kdbx.
Existing geheim users must set backend="geheim" in ~/.config/foostore.json.
Update resolveBackend fallback, struct comments, and test assertions to match.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
flag.Parse() rejected --backend and --kdbx-path as undefined flags before
the CLI could handle them. Replace with a manual -version / --version check
and pass os.Args[1:] directly to cli.New and cli.Run.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Allows specifying the .kdbx file path without editing the config file:
foostore --backend keepass --kdbx-path /path/to/db.kdbx ls
The flag overrides cfg.KDBXPath for the process lifetime. Implemented by
extracting a shared parseFlagValue helper used by both parseBackendFlag and
the new parseKDBXPathFlag. Help text updated to document both global flags.
Table-driven tests added for parseKDBXPathFlag (mirrors TestParseBackendFlag).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
(task q4)
Add 430 lines of new integration tests covering WriteBack edit round-trip,
Search action handlers (cat/export), ShredAllExported, ImportRecursive,
TestParsePickerAction (all 10 fzf keys), TestBuildPickerEntries with RowID
assertions, ImportForce, ensureRootGroup edge cases, and a captureStdout
helper. Add TTY-unavailability comment to FzfInteractive explaining why
Fzf/FzfInteractive/runFzfInteractive have no automated tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
lines
Extracts a 3-line buildGeheimGit(cfg) helper from buildGeheimBackend,
mirroring the existing buildKeepassGit pattern and satisfying the project
guideline of keeping functions under 30 lines. Also includes the full
o4 backend-abstraction changeset: Gitter interface, git.NoOp, --backend
flag parsing, keepass backend wiring, and effectiveBackend guard for
migrate-kdbx.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
(tasks k4+l4)
Remove ~90 lines of duplicated code from kdbx_store.go by delegating
to EnsureGroup, UpsertEntryByTitle, SetEntryField, SplitDescriptionPath,
SanitizeRelativePath exported from internal/keepass. kdbxStore.Save()
now delegates to keepass.AtomicSave, eliminating the double-close risk.
migrate_kdbx.go updated to use the exported helpers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
k4+l4+m4)
Read-write KeePass backend implementing backend.Backend:
- WalkIndexes flattens groups into 'Group/Title' virtual entries
- LoadData returns formatted Password/User/URL/Notes for text entries
or raw bytes for binary attachments
- WriteBack hook enables edit round-trip through the kdbx file
- Add/Import/ImportRecursive/Remove with atomic tmp+rename save
- Binary attachments surface as virtual 'Group/Title/filename' entries;
Add to such a path creates/replaces the attachment on the parent entry
- AtomicSave exported for reuse by cli/kdbx_store.go
- parseContent is the tolerant inverse of formatContent
- Helpers EnsureGroup, UpsertEntryByTitle, SetEntryField, SplitDescriptionPath,
SanitizeRelativePath exported so cli/kdbx_store.go avoids duplication
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
(tasks i4+l4)
Add optional WriteBack func([]byte) error field to Data struct.
ReimportAfterExport calls WriteBack(newContent) when set, otherwise
falls back to Commit. applyAction now calls s.LoadData (exported) so
the geheim and KeePass edit paths are symmetric. Tests cover nil,
non-nil, and error-propagation paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Add Backend (default 'geheim'), KDBXPath, KDBXKeyFile, KDBXPassFile
fields to Config. Defaults mirror migrate_kdbx.go hardcoded values.
Extend expandPathFieldsWithHome for the three path fields. Table-driven
tests cover defaults, JSON override, and tilde expansion.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Add internal/backend/backend.go with a Backend interface covering all
10 CLI-facing methods. Change CLI.st field type to backend.Backend.
Compile-time guard var _ Backend = (*store.Store)(nil) prevents drift.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
The comment at the force=false import test said "should succeed and add
the entry" but the test actually verifies that a duplicate entry is
silently skipped (entry count must not change). Updated to say "should
skip silently because Work/Email already exists."
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- 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>
|
|
- 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>
|
|
- 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>
|
|
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>
|
|
- 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>
|
|
- 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>
|
|
Reflect the migration from geheim.rb (Ruby) to the Go rewrite:
- rename title to foostore
- update description to say Go tool instead of Ruby script
- update editor mention: Helix / $EDITOR instead of NeoVim
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
|
|
|
|
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>
|
|
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>
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|
|
- 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>
|
|
gitignore, go 1.24 (task 352)
|
|
|
|
- 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>
|
|
Amp-Thread-ID: https://ampcode.com/threads/T-9aec59d6-cd27-4607-ac11-baac5f2ca758
Co-authored-by: Amp <amp@ampcode.com>
|
|
- Add frozen_string_literal and modernize path handling
- Fix Config method_missing and respond_to_missing? signatures
- Modernize OpenSSL usage (remove deprecated Cipher::Cipher)
- Use Dir.chdir blocks for safer directory handling
- Improve Log module output logic
- Fix Clipboard IO pipe handling
- Use File.write instead of File.open blocks
- Extract COMMANDS constant and use squiggly heredoc
- DRY CLI case statement with SEARCH_ACTIONS mapping
- Add readline support with vi editing mode
- Add tab completion for commands and entries
- Add command history support
Amp-Thread-ID: https://ampcode.com/threads/T-9aec59d6-cd27-4607-ac11-baac5f2ca758
Co-authored-by: Amp <amp@ampcode.com>
|