MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / vault_intent_link

Method vault_intent_link

atomic-repository/src/repository/vault_intent.rs:597–678  ·  view source on GitHub ↗

Link a goal to an intent.

(
        &self,
        intent_id: &str,
        goal_name: &str,
    )

Source from the content-addressed store, hash-verified

595
596 /// Link a goal to an intent.
597 pub fn vault_intent_link(
598 &self,
599 intent_id: &str,
600 goal_name: &str,
601 ) -> Result<(), RepositoryError> {
602 let full_id = self.normalize_intent_id(intent_id)?;
603 let intent_file =
604 self.find_intent_path(&full_id)?
605 .ok_or_else(|| RepositoryError::InvalidOperation {
606 message: format!("Intent '{}' not found", full_id),
607 })?;
608
609 // Read from disk first so we pick up any user/agent edits to the
610 // markdown body (same pattern as vault_intent_update).
611 let disk_path = self.vault_dir().join(&intent_file);
612 let (content_bytes, frontmatter_json) = if disk_path.exists() {
613 let file_content = std::fs::read_to_string(&disk_path)?;
614 let (fm_json, body) = crate::repository::vault::parse_vault_frontmatter(&file_content);
615 (body.into_bytes(), fm_json)
616 } else {
617 let entry = self.vault_retrieve(&intent_file)?.ok_or_else(|| {
618 RepositoryError::InvalidOperation {
619 message: format!("Intent '{}' not found", full_id),
620 }
621 })?;
622 (entry.content_bytes.clone(), entry.frontmatter_json.clone())
623 };
624
625 // Verify goal exists
626 let goal_file = format!("goals/{}/_goal.md", goal_name);
627 if self.vault_retrieve(&goal_file)?.is_none() {
628 return Err(RepositoryError::InvalidOperation {
629 message: format!("Goal '{}' not found", goal_name),
630 });
631 }
632
633 // Update frontmatter to add goal to the list
634 let mut fm: serde_json::Map<String, serde_json::Value> =
635 serde_json::from_str(&frontmatter_json).unwrap_or_default();
636
637 let goals = fm
638 .entry("goals".to_string())
639 .or_insert_with(|| serde_json::Value::Array(Vec::new()));
640 let goals = goals
641 .as_array_mut()
642 .ok_or_else(|| RepositoryError::InvalidOperation {
643 message: format!("Intent '{}' has a non-array goals field", full_id),
644 })?;
645 let goal_val = serde_json::Value::String(goal_name.to_string());
646 if !goals.contains(&goal_val) {
647 goals.push(goal_val);
648 }
649 let goal_count = goals.len() as u32;
650 let new_fm = serde_json::to_string(&fm).unwrap_or_else(|_| "{}".to_string());
651
652 self.vault_store(&intent_file, VaultEntryType::Intent, content_bytes, new_fm)?;
653
654 // Update manifest goal count

Callers 5

runMethod · 0.80
runMethod · 0.80
test_intent_link_goalFunction · 0.80

Calls 15

parse_vault_frontmatterFunction · 0.85
normalize_intent_idMethod · 0.80
find_intent_pathMethod · 0.80
vault_dirMethod · 0.80
vault_retrieveMethod · 0.80
is_noneMethod · 0.80
vault_storeMethod · 0.80
write_txnMethod · 0.80
get_mutMethod · 0.80
put_vault_manifestMethod · 0.80
commitMethod · 0.80
vault_materializeMethod · 0.80