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

Method vault_intent_link

atomic-repository/src/repository/vault_intent.rs:1003–1084  ·  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

1001
1002 /// Link a goal to an intent.
1003 pub fn vault_intent_link(
1004 &self,
1005 intent_id: &str,
1006 goal_name: &str,
1007 ) -> Result<(), RepositoryError> {
1008 let full_id = self.normalize_intent_id(intent_id)?;
1009 let intent_file =
1010 self.find_intent_path(&full_id)?
1011 .ok_or_else(|| RepositoryError::InvalidOperation {
1012 message: format!("Intent '{}' not found", full_id),
1013 })?;
1014
1015 // Read from disk first so we pick up any user/agent edits to the
1016 // markdown body (same pattern as vault_intent_update).
1017 let disk_path = self.vault_dir().join(&intent_file);
1018 let (content_bytes, frontmatter_json) = if disk_path.exists() {
1019 let file_content = std::fs::read_to_string(&disk_path)?;
1020 let (fm_json, body) = crate::repository::vault::parse_vault_frontmatter(&file_content);
1021 (body.into_bytes(), fm_json)
1022 } else {
1023 let entry = self.vault_retrieve(&intent_file)?.ok_or_else(|| {
1024 RepositoryError::InvalidOperation {
1025 message: format!("Intent '{}' not found", full_id),
1026 }
1027 })?;
1028 (entry.content_bytes.clone(), entry.frontmatter_json.clone())
1029 };
1030
1031 // Verify goal exists
1032 let goal_file = format!("goals/{}/_goal.md", goal_name);
1033 if self.vault_retrieve(&goal_file)?.is_none() {
1034 return Err(RepositoryError::InvalidOperation {
1035 message: format!("Goal '{}' not found", goal_name),
1036 });
1037 }
1038
1039 // Update frontmatter to add goal to the list
1040 let mut fm: serde_json::Map<String, serde_json::Value> =
1041 serde_json::from_str(&frontmatter_json).unwrap_or_default();
1042
1043 let goals = fm
1044 .entry("goals".to_string())
1045 .or_insert_with(|| serde_json::Value::Array(Vec::new()));
1046 let goals = goals
1047 .as_array_mut()
1048 .ok_or_else(|| RepositoryError::InvalidOperation {
1049 message: format!("Intent '{}' has a non-array goals field", full_id),
1050 })?;
1051 let goal_val = serde_json::Value::String(goal_name.to_string());
1052 if !goals.contains(&goal_val) {
1053 goals.push(goal_val);
1054 }
1055 let goal_count = goals.len() as u32;
1056 let new_fm = serde_json::to_string(&fm).unwrap_or_else(|_| "{}".to_string());
1057
1058 self.vault_store(&intent_file, VaultEntryType::Intent, content_bytes, new_fm)?;
1059
1060 // Update manifest goal count

Callers 4

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