Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions binding-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jacs-binding-core"
version = "0.9.7"
version = "0.9.8"
edition = "2024"
rust-version = "1.93"
resolver = "3"
Expand All @@ -19,7 +19,7 @@ attestation = ["jacs/attestation"]
pq-tests = []

[dependencies]
jacs = { version = "0.9.7", path = "../jacs" }
jacs = { version = "0.9.8", path = "../jacs" }
serde_json = "1.0"
base64 = "0.22.1"
serde = { version = "1.0", features = ["derive"] }
Expand Down
59 changes: 35 additions & 24 deletions binding-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,44 +373,55 @@ impl AgentWrapper {
}

/// Load agent configuration from a file path.
///
/// Uses `Config::from_file` + `apply_env_overrides` + `Agent::from_config`
/// to avoid deprecated `load_by_config` and env var side-channels.
pub fn load(&self, config_path: String) -> BindingResult<String> {
self.with_private_key_password(|| {
let mut agent = self.lock()?;
agent.load_by_config(config_path).map_err(|e| {
BindingCoreError::agent_load(format!("Failed to load agent: {}", e))
})?;
Ok("Agent loaded".to_string())
})
let password = self.configured_private_key_password()?;
let new_agent = self.load_agent_from_config(&config_path, true, password.as_deref())?;
*self.lock()? = new_agent;
Ok("Agent loaded".to_string())
}

/// Load agent configuration from file only, **without** applying env/jenv
/// overrides. This is the isolation-safe counterpart of [`load`] — the
/// caller constructs a pristine config file and does not want ambient JACS_*
/// environment variables to pollute it (Issue 008).
pub fn load_file_only(&self, config_path: String) -> BindingResult<String> {
let mut agent = self.lock()?;
agent
.load_by_config_file_only(config_path)
.map_err(|e| BindingCoreError::agent_load(format!("Failed to load agent: {}", e)))?;
let new_agent = self.load_agent_from_config(&config_path, false, None)?;
*self.lock()? = new_agent;
Ok("Agent loaded (file-only)".to_string())
}

/// Load agent configuration and return canonical loaded-agent metadata.
pub fn load_with_info(&self, config_path: String) -> BindingResult<String> {
let resolved_config_path = resolve_existing_config_path(&config_path)?;
self.with_private_key_password(|| {
let mut agent = self.lock()?;
agent
.load_by_config(resolved_config_path.clone())
.map_err(|e| {
BindingCoreError::agent_load(format!("Failed to load agent: {}", e))
})?;
let info = jacs::simple::build_loaded_agent_info(&agent, &resolved_config_path)
.map_err(|e| {
BindingCoreError::agent_load(format!("Failed to load agent: {}", e))
})?;
serialize_agent_info(&info)
})
let password = self.configured_private_key_password()?;
let new_agent =
self.load_agent_from_config(&resolved_config_path, true, password.as_deref())?;
let info = jacs::simple::build_loaded_agent_info(&new_agent, &resolved_config_path)
.map_err(|e| BindingCoreError::agent_load(format!("Failed to load agent: {}", e)))?;
*self.lock()? = new_agent;
serialize_agent_info(&info)
}

/// Internal helper: load an agent from config using the new pattern.
///
/// * `apply_env` - Whether to call `config.apply_env_overrides()` (false for file-only)
/// * `password` - Optional password to pass directly to Agent::from_config
fn load_agent_from_config(
&self,
config_path: &str,
apply_env: bool,
password: Option<&str>,
) -> BindingResult<Agent> {
let mut config = Config::from_file(config_path)
.map_err(|e| BindingCoreError::agent_load(format!("Failed to load config: {}", e)))?;
if apply_env {
config.apply_env_overrides();
}
Agent::from_config(config, password)
.map_err(|e| BindingCoreError::agent_load(format!("Failed to load agent: {}", e)))
}

/// Re-root the internal file storage at `root`.
Expand Down
6 changes: 3 additions & 3 deletions jacs-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jacs-cli"
version = "0.9.7"
version = "0.9.8"
edition = "2024"
rust-version = "1.93"
description = "JACS CLI: command-line interface for JSON AI Communication Standard"
Expand All @@ -23,8 +23,8 @@ attestation = ["jacs/attestation"]
keychain = ["jacs/keychain"]

[dependencies]
jacs = { version = "0.9.7", path = "../jacs" }
jacs-mcp = { version = "0.9.7", path = "../jacs-mcp", features = ["mcp", "full-tools"], optional = true }
jacs = { version = "0.9.8", path = "../jacs" }
jacs-mcp = { version = "0.9.8", path = "../jacs-mcp", features = ["mcp", "full-tools"], optional = true }
clap = { version = "4.5.4", features = ["derive", "cargo"] }
rpassword = "7.3.1"
reqwest = { version = "0.13.2", default-features = false, features = ["blocking", "json", "rustls"] }
Expand Down
Loading
Loading