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

Method vault_intent_link

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

1024
1025 /// Link a goal to an intent.
1026 pub fn vault_intent_link(
1027 &self,
1028 intent_id: &str,
1029 goal_name: &str,
1030 ) -> Result<(), RepositoryError> {
1031 let full_id = self.normalize_intent_id(intent_id)?;
1032 let intent_file =
1033 self.find_intent_path(&full_id)?
1034 .ok_or_else(|| RepositoryError::InvalidOperation {
1035 message: format!("Intent '{}' not found", full_id),
1036 })?;
1037
1038 // Read from disk first so we pick up any user/agent edits to the
1039 // markdown body (same pattern as vault_intent_update).
1040 let disk_path = self.vault_dir().join(&intent_file);
1041 let (content_bytes, frontmatter_json) = if disk_path.exists() {
1042 let file_content = std::fs::read_to_string(&disk_path)?;
1043 let (fm_json, body) = crate::repository::vault::parse_vault_frontmatter(&file_content);
1044 (body.into_bytes(), fm_json)
1045 } else {
1046 let entry = self.vault_retrieve(&intent_file)?.ok_or_else(|| {
1047 RepositoryError::InvalidOperation {
1048 message: format!("Intent '{}' not found", full_id),
1049 }
1050 })?;
1051 (entry.content_bytes.clone(), entry.frontmatter_json.clone())
1052 };
1053
1054 // Verify goal exists
1055 let goal_file = format!("goals/{}/_goal.md", goal_name);
1056 if self.vault_retrieve(&goal_file)?.is_none() {
1057 return Err(RepositoryError::InvalidOperation {
1058 message: format!("Goal '{}' not found", goal_name),
1059 });
1060 }
1061
1062 // Update frontmatter to add goal to the list
1063 let mut fm: serde_json::Map<String, serde_json::Value> =
1064 serde_json::from_str(&frontmatter_json).unwrap_or_default();
1065
1066 let goals = fm
1067 .entry("goals".to_string())
1068 .or_insert_with(|| serde_json::Value::Array(Vec::new()));
1069 let goals = goals
1070 .as_array_mut()
1071 .ok_or_else(|| RepositoryError::InvalidOperation {
1072 message: format!("Intent '{}' has a non-array goals field", full_id),
1073 })?;
1074 let goal_val = serde_json::Value::String(goal_name.to_string());
1075 if !goals.contains(&goal_val) {
1076 goals.push(goal_val);
1077 }
1078 let goal_count = goals.len() as u32;
1079 let new_fm = serde_json::to_string(&fm).unwrap_or_else(|_| "{}".to_string());
1080
1081 self.vault_store(&intent_file, VaultEntryType::Intent, content_bytes, new_fm)?;
1082
1083 // 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