One coherent CLI completeness pass driven by the 2026-04-27 state-of-the-
project audit. All TDD; 6 new integration tests (workspace 158→164).
Stubs and dead state fixed:
- TOTP edit was an explicit stub at main.rs:925 ("delete and re-add for
now"). Now supports editing issuer, label, and rotating the secret;
rotated secrets are pushed to field_history under core:totp_secret.
- VaultSettings.generator_defaults was stored but never read by the CLI.
cmd_generate now consults it when invoked inside an initialized vault;
explicit flags override. Behavior outside a vault unchanged.
New commands:
- relicario settings generator-defaults [--random|--bip39] [--length |
--words | --symbols | --separator] — view/edit the stored generator
defaults.
- relicario history <query> [--show] [--field <name>] — view captured
field history. Values masked by default.
- relicario detach <query> <aid> — remove an individual attachment +
blob. Refuses to drop a Document item's primary attachment.
- relicario status — vault summary: root path, item counts (active /
trashed), attachment count + total bytes, registered device count,
last commit (%h %s).
Internal refactor (pure mechanical, no behavior change):
- cmd_add: 217-line match split into one build_<type>_item helper per
ItemCore variant + a 7-arm dispatcher.
- cmd_edit: same treatment — edit_login, edit_card, edit_totp, etc. The
history-tracking ones take a &mut FieldHistory alias for clarity.
Existing tests cover the refactor; the new helpers are tested through
the same integration paths.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds RELICARIO_TEST_ITEM_SECRET env hatch for rpassword calls in
cmd_add / cmd_edit so piped-stdin tests can exercise the password
prompt paths without a TTY.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Uses assert_cmd + tempfile to spin up a fresh vault per test.
Covers init layout, add/list/get mask semantics, rm/restore/purge cycle,
and generate smoke. Adds RELICARIO_TEST_PASSPHRASE env-var hatch in
unlock_interactive and cmd_init so tests don't need a TTY.
Also fixes read_params in session.rs to correctly parse the nested
params.json format (kdf sub-object) rather than trying to deserialize
the whole file as KdfParams.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CLI no longer has its own charset-sampling path — uses the CSPRNG
generate_password / generate_passphrase in relicario-core, which use
rand::distributions::Uniform internally.
Extracted purge_item helper so cmd_trash_empty loops over it without
re-prompting for passphrase per item. Single git commit per trash empty
summarizing the count. Caught in Task 12 review.
Soft-delete sets trashed_at via Item::soft_delete; restore clears it.
Purge deletes item + attachment dir and removes manifest entry.
Trash empty scans for items past settings.trash_retention.
Title/group/tags always optional. Per-type prompts for core secret
fields (Login.password, Card.number, Key.material, SecureNote.body)
push the old value to field_history via a synthetic core:<key>
FieldId so rotation is audit-traceable.
Secrets masked by default (audit M7). --show reveals plaintext.
--copy writes to clipboard and spawns a detached 30s auto-clear
thread holding a Zeroizing copy that wipes on drop (audit M6).
SecureNote, Identity, Card, Key, Document (with inline attachment),
and Totp with base32 secret decoding. Document widens the commit
to include the attachment blob path.
Unlocks vault, builds LoginCore from flags (password via rpassword if
--password-prompt), saves item + manifest, commits via hardened git.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1. Add .relicario/salt to the initial git commit so it syncs across
devices (Argon2 salt must match at unlock time).
2. Return a proper error instead of panicking when --output has no
filename component (e.g., trailing ..).
3. Wrap the generated 32-byte image_secret in Zeroizing for
consistency with the passphrase + master_key handling in Task 4.
Caught in Task 6 review.
Prompts for a strong passphrase (zxcvbn gate via core), generates a
32-byte image secret, embeds it in the carrier JPEG, writes the
standard vault skeleton, and makes an initial git commit via the
hardened git_command helper.
Every subcommand from the Plan 1B CLI spec present; bodies return
'not yet implemented' so subsequent tasks land one command at a time.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Provides load/save helpers for Manifest/Settings/Item; atomic_write keeps
vault files consistent across crashes. main.rs is transiently broken
against the old Entry API — Task 5+ rewrites the command handlers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves conflicts from merging origin/main (idfoto→relicario rename):
- Kept Plan 1A's typed-item vault.rs, lib.rs, integration.rs over main's
old entry-based versions
- Took main's relicario_dir() fix in CLI main.rs (sed had missed idfoto_dir)
- Kept Plan 1A's UnsupportedFormatVersion error variant in crypto.rs
- Kept Plan 1A's opaque Decrypt message (audit M4) in error.rs
- Deleted entry.rs (replaced by item.rs + typed modules in Plan 1A)
- Resolved Cargo.toml description to main's "relicario password manager"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Renames crate directories and sweeps identifiers so Plan 1B can reference
the post-rename names throughout.
- git mv crates/idfoto-{core,cli,wasm} → crates/relicario-{core,cli,wasm}
- sed sweep: idfoto_core/idfoto-core/IdfotoError/IDFOTO_IMAGE/.idfoto/ etc.
- All 128 relicario-core tests pass post-sweep
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>