diff --git a/crates/picloud-cli/src/cmds/pull.rs b/crates/picloud-cli/src/cmds/pull.rs index 628617c..bf2124f 100644 --- a/crates/picloud-cli/src/cmds/pull.rs +++ b/crates/picloud-cli/src/cmds/pull.rs @@ -49,6 +49,24 @@ pub async fn run(app_ident: &str, dir: &Path, force: bool, mode: OutputMode) -> .secrets_list(VarOwnerArg::App(app_ident), None) .await? .secrets; + // App's OWN env-agnostic vars become the manifest `[vars]` block. Inherited + // group vars and tombstones are excluded (pull exports own rows only, §4.6); + // a value TOML can't represent (e.g. JSON null) is skipped with a warning. + let mut manifest_vars = std::collections::BTreeMap::new(); + for v in client.vars_list(VarOwnerArg::App(app_ident)).await?.vars { + if v.env != "*" || v.is_tombstone { + continue; + } + match toml::Value::try_from(&v.value) { + Ok(tv) => { + manifest_vars.insert(v.key, tv); + } + Err(_) => eprintln!( + "warning: skipping var `{}` — its value can't be represented in TOML", + v.key + ), + } + } let name_by_id: HashMap = scripts.iter().map(|s| (s.id, s.name.clone())).collect(); @@ -204,7 +222,7 @@ pub async fn run(app_ident: &str, dir: &Path, force: bool, mode: OutputMode) -> secrets: ManifestSecrets { names: secrets.iter().map(|s| s.name.clone()).collect(), }, - vars: std::collections::BTreeMap::new(), + vars: manifest_vars, }; std::fs::write(&manifest_path, manifest.to_toml()?)