From bd323d8b1b0c80439c5a6d84806794da0986303d Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Sat, 20 Jun 2026 21:13:26 -0400 Subject: [PATCH] feat(cli/org): org add document with collection-scoped attachment --- crates/relicario-cli/src/commands/org.rs | 24 +++++++++++++++++------- crates/relicario-cli/src/main.rs | 12 ++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/crates/relicario-cli/src/commands/org.rs b/crates/relicario-cli/src/commands/org.rs index 675b7b5..7b85aa7 100644 --- a/crates/relicario-cli/src/commands/org.rs +++ b/crates/relicario-cli/src/commands/org.rs @@ -793,7 +793,7 @@ pub enum OrgAddKind { digits: u8, algorithm: String, }, - // Document is added later by Dev-C. + Document { title: String, file: std::path::PathBuf }, } fn build_org_item(kind: OrgAddKind) -> Result { @@ -816,6 +816,7 @@ fn build_org_item(kind: OrgAddKind) -> Result { OrgAddKind::Totp { title, issuer, label, secret, secret_stdin, period, digits, algorithm } => { ib::build_totp(title, issuer, label, secret, secret_stdin, period, digits, &algorithm) } + OrgAddKind::Document { .. } => unreachable!("Document handled in run_add before build_org_item"), } } @@ -833,7 +834,16 @@ pub fn run_add(dir: &Path, collection: &str, kind: OrgAddKind, tags: Vec // …and the caller must hold a grant for it. UnlockedOrgVault::ensure_grant(&caller, collection)?; - let mut item = build_org_item(kind)?; + // Build the item; Document additionally yields an encrypted attachment to persist. + let (mut item, attachment_rel): (relicario_core::Item, Option) = match kind { + OrgAddKind::Document { title, file } => { + let (item, enc) = ib::build_document( + title, file, vault.key(), crate::org_session::DEFAULT_ORG_ATTACHMENT_MAX_BYTES)?; + let rel = vault.save_attachment(collection, &item.id, &enc)?; + (item, Some(rel)) + } + other => (build_org_item(other)?, None), + }; item.tags = tags; let item_rel = vault.save_item(collection, &item)?; @@ -855,11 +865,11 @@ pub fn run_add(dir: &Path, collection: &str, kind: OrgAddKind, tags: Vec collection, item.id.as_str() ); - crate::org_session::org_git_run( - &vault.root, - &["add", &item_rel, "manifest.enc"], - "org add: git add", - )?; + let mut add_args: Vec<&str> = vec!["add", &item_rel, "manifest.enc"]; + if let Some(ref rel) = attachment_rel { + add_args.insert(1, rel); + } + crate::org_session::org_git_run(&vault.root, &add_args, "org add: git add")?; crate::org_session::org_git_run(&vault.root, &["commit", "-m", &commit_msg], "org add: git commit")?; println!("Added {} ({}) to `{}`", item.title, item.id.as_str(), collection); diff --git a/crates/relicario-cli/src/main.rs b/crates/relicario-cli/src/main.rs index a52c153..e7069ee 100644 --- a/crates/relicario-cli/src/main.rs +++ b/crates/relicario-cli/src/main.rs @@ -614,6 +614,13 @@ pub(crate) enum OrgAddKind { #[arg(long, value_delimiter = ',')] tags: Vec, #[arg(long)] secret_stdin: bool, }, + /// A document (file payload encrypted into a collection-scoped attachment). + Document { + #[arg(long)] collection: String, + #[arg(long)] title: String, + #[arg(long)] file: std::path::PathBuf, + #[arg(long, value_delimiter = ',')] tags: Vec, + }, } fn main() -> Result<()> { @@ -737,6 +744,11 @@ fn main() -> Result<()> { commands::org::OrgAddKind::Totp { title, issuer, label, secret, secret_stdin, period, digits, algorithm }, tags, ), + OrgAddKind::Document { collection, title, file, tags } => ( + collection, + commands::org::OrgAddKind::Document { title, file }, + tags, + ), }; commands::org::run_add(&d, &collection, add_kind, tags)?; }