diff --git a/src/cli/handlers.rs b/src/cli/handlers.rs index 9a3f231..19ef08e 100644 --- a/src/cli/handlers.rs +++ b/src/cli/handlers.rs @@ -520,18 +520,35 @@ fn handle_add(cli: &Cli, mode: &OutputMode, args: &AddArgs) -> Result<()> { let actual_bookmark_id = db.insert_bookmark(&bookmark)?; let is_new = actual_bookmark_id == bookmark_id; - // Insert annotation with notes and context if provided - if args.note.is_some() || args.context.is_some() { - let annotation = Annotation { - id: uuid::Uuid::new_v4().to_string(), - bookmark_id: actual_bookmark_id.clone(), - added_at: now_iso(), - added_by: Some(args.created_by.clone()), - notes: args.note.clone(), - context: args.context.clone(), - source: Some("cli".to_string()), - }; - db.insert_annotation(&annotation)?; + // Insert annotations with notes and context if provided + if !args.note.is_empty() || args.context.is_some() { + // If context is provided, attach it to the first note + let first_note = args.note.first(); + if first_note.is_some() || args.context.is_some() { + let annotation = Annotation { + id: uuid::Uuid::new_v4().to_string(), + bookmark_id: actual_bookmark_id.clone(), + added_at: now_iso(), + added_by: Some(args.created_by.clone()), + notes: first_note.cloned(), + context: args.context.clone(), + source: Some("cli".to_string()), + }; + db.insert_annotation(&annotation)?; + } + // Additional notes without context + for note in args.note.iter().skip(1) { + let annotation = Annotation { + id: uuid::Uuid::new_v4().to_string(), + bookmark_id: actual_bookmark_id.clone(), + added_at: now_iso(), + added_by: Some(args.created_by.clone()), + notes: Some(note.clone()), + context: None, + source: Some("cli".to_string()), + }; + db.insert_annotation(&annotation)?; + } } // Insert tags if provided @@ -684,18 +701,35 @@ fn handle_add_from_snippet(cli: &Cli, mode: &OutputMode, args: &AddFromSnippetAr let actual_bookmark_id = db.insert_bookmark(&bookmark)?; let is_new = actual_bookmark_id == bookmark_id; - // Insert annotation with notes and context if provided - if args.note.is_some() || args.context.is_some() { - let annotation = Annotation { - id: uuid::Uuid::new_v4().to_string(), - bookmark_id: actual_bookmark_id.clone(), - added_at: now_iso(), - added_by: Some(args.created_by.clone()), - notes: args.note.clone(), - context: args.context.clone(), - source: Some("cli".to_string()), - }; - db.insert_annotation(&annotation)?; + // Insert annotations with notes and context if provided + if !args.note.is_empty() || args.context.is_some() { + // If context is provided, attach it to the first note + let first_note = args.note.first(); + if first_note.is_some() || args.context.is_some() { + let annotation = Annotation { + id: uuid::Uuid::new_v4().to_string(), + bookmark_id: actual_bookmark_id.clone(), + added_at: now_iso(), + added_by: Some(args.created_by.clone()), + notes: first_note.cloned(), + context: args.context.clone(), + source: Some("cli".to_string()), + }; + db.insert_annotation(&annotation)?; + } + // Additional notes without context + for note in args.note.iter().skip(1) { + let annotation = Annotation { + id: uuid::Uuid::new_v4().to_string(), + bookmark_id: actual_bookmark_id.clone(), + added_at: now_iso(), + added_by: Some(args.created_by.clone()), + notes: Some(note.clone()), + context: None, + source: Some("cli".to_string()), + }; + db.insert_annotation(&annotation)?; + } } // Insert tags if provided @@ -852,18 +886,35 @@ fn handle_add_from_query(cli: &Cli, mode: &OutputMode, args: &AddFromQueryArgs) let actual_bookmark_id = db.insert_bookmark(&bookmark)?; let is_new = actual_bookmark_id == bookmark_id; - // Insert annotation with notes and context if provided - if args.note.is_some() || args.context.is_some() { - let annotation = Annotation { - id: uuid::Uuid::new_v4().to_string(), - bookmark_id: actual_bookmark_id.clone(), - added_at: now_iso(), - added_by: Some(args.created_by.clone()), - notes: args.note.clone(), - context: args.context.clone(), - source: Some("cli".to_string()), - }; - db.insert_annotation(&annotation)?; + // Insert annotations with notes and context if provided + if !args.note.is_empty() || args.context.is_some() { + // If context is provided, attach it to the first note + let first_note = args.note.first(); + if first_note.is_some() || args.context.is_some() { + let annotation = Annotation { + id: uuid::Uuid::new_v4().to_string(), + bookmark_id: actual_bookmark_id.clone(), + added_at: now_iso(), + added_by: Some(args.created_by.clone()), + notes: first_note.cloned(), + context: args.context.clone(), + source: Some("cli".to_string()), + }; + db.insert_annotation(&annotation)?; + } + // Additional notes without context + for note in args.note.iter().skip(1) { + let annotation = Annotation { + id: uuid::Uuid::new_v4().to_string(), + bookmark_id: actual_bookmark_id.clone(), + added_at: now_iso(), + added_by: Some(args.created_by.clone()), + notes: Some(note.clone()), + context: None, + source: Some("cli".to_string()), + }; + db.insert_annotation(&annotation)?; + } } // Insert tags if provided @@ -1163,7 +1214,7 @@ fn handle_annotate(cli: &Cli, mode: &OutputMode, args: &AnnotateArgs) -> Result< let db = open_db_for_write(cli)?; // Validate that at least one of note, context, or tag is provided - if args.note.is_none() && args.context.is_none() && args.tag.is_empty() { + if args.note.is_empty() && args.context.is_none() && args.tag.is_empty() { return Err(Error::Input( "At least one of --note, --context, or --tag must be provided".to_string(), )); @@ -1173,18 +1224,35 @@ fn handle_annotate(cli: &Cli, mode: &OutputMode, args: &AnnotateArgs) -> Result< let id = extract_id(&args.id); let mut bm = find_bookmark(&db, id)?; - // Create annotation if note or context is provided - if args.note.is_some() || args.context.is_some() { - let annotation = Annotation { - id: uuid::Uuid::new_v4().to_string(), - bookmark_id: bm.id.clone(), - added_at: now_iso(), - added_by: Some(args.added_by.clone()), - notes: args.note.clone(), - context: args.context.clone(), - source: Some(args.source.clone()), - }; - db.insert_annotation(&annotation)?; + // Create annotations if notes or context is provided + if !args.note.is_empty() || args.context.is_some() { + // If context is provided, attach it to the first note + let first_note = args.note.first(); + if first_note.is_some() || args.context.is_some() { + let annotation = Annotation { + id: uuid::Uuid::new_v4().to_string(), + bookmark_id: bm.id.clone(), + added_at: now_iso(), + added_by: Some(args.added_by.clone()), + notes: first_note.cloned(), + context: args.context.clone(), + source: Some(args.source.clone()), + }; + db.insert_annotation(&annotation)?; + } + // Additional notes without context + for note in args.note.iter().skip(1) { + let annotation = Annotation { + id: uuid::Uuid::new_v4().to_string(), + bookmark_id: bm.id.clone(), + added_at: now_iso(), + added_by: Some(args.added_by.clone()), + notes: Some(note.clone()), + context: None, + source: Some(args.source.clone()), + }; + db.insert_annotation(&annotation)?; + } // Re-fetch bookmark to get updated annotations bm = find_bookmark(&db, id)?; diff --git a/src/cli/mod.rs b/src/cli/mod.rs index fa8ca7a..71f1cf0 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -129,9 +129,9 @@ pub struct AddArgs { #[arg(long)] pub tag: Vec, - /// Semantic annotation + /// Semantic annotation; repeatable for multiple notes #[arg(long)] - pub note: Option, + pub note: Vec, /// Agent context at time of bookmarking #[arg(long)] @@ -164,9 +164,9 @@ pub struct AddFromSnippetArgs { #[arg(long)] pub tag: Vec, - /// Semantic annotation + /// Semantic annotation; repeatable #[arg(long)] - pub note: Option, + pub note: Vec, /// Agent context #[arg(long)] @@ -203,9 +203,9 @@ pub struct AddFromQueryArgs { #[arg(long)] pub tag: Vec, - /// Semantic annotation + /// Semantic annotation; repeatable for multiple notes #[arg(long)] - pub note: Option, + pub note: Vec, /// Agent context at time of bookmarking #[arg(long)] @@ -566,9 +566,9 @@ pub struct AnnotateArgs { /// Bookmark ID (full UUID or unambiguous prefix) pub id: String, - /// Semantic annotation to add + /// Semantic annotation to add; repeatable for multiple notes #[arg(long)] - pub note: Option, + pub note: Vec, /// Agent context to add #[arg(long)]