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
18 changes: 16 additions & 2 deletions crates/vfox/src/hooks/mise_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub struct MiseEnvResult {
pub cacheable: bool,
/// Files to watch for cache invalidation
pub watch_files: Vec<PathBuf>,
/// Whether the plugin wants its env vars to be redacted
/// When true, mise will redact these values unless the user explicitly opts out
pub redact: bool,
}

impl Plugin {
Expand Down Expand Up @@ -56,12 +59,13 @@ impl FromLua for MiseEnvResult {
match value {
// Extended format: { cacheable = true, watch_files = {...}, env = {...} }
Value::Table(table) => {
// Check if this is extended format by looking for 'env' or 'cacheable' key
// Check if this is extended format by looking for known keys
let has_env = table.contains_key("env")?;
let has_cacheable = table.contains_key("cacheable")?;
let has_watch_files = table.contains_key("watch_files")?;
let has_redact = table.contains_key("redact")?;

if has_env || has_cacheable || has_watch_files {
if has_env || has_cacheable || has_watch_files || has_redact {
// Extended format
let env: Vec<EnvKey> = table
.get::<Option<Vec<EnvKey>>>("env")
Expand All @@ -87,11 +91,20 @@ impl FromLua for MiseEnvResult {
))
})?
.unwrap_or_default();
let redact: bool = table
.get::<Option<bool>>("redact")
.map_err(|e| {
LuaError::RuntimeError(format!(
"Invalid 'redact' field in MiseEnv result: expected boolean. Error: {e}"
))
})?
.unwrap_or(false);
Comment on lines 62 to +101
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are unit tests for other hook result parsers in crates/vfox/src/hooks/ but none for MiseEnvResult::from_lua. Since this change adds new parsing logic and error messaging for the redact field (and alters extended-format detection), please add tests covering: default redact=false when omitted, redact=true when provided, and invalid types producing the expected runtime error.

Copilot uses AI. Check for mistakes.

Ok(MiseEnvResult {
env,
cacheable,
watch_files: watch_files.into_iter().map(PathBuf::from).collect(),
redact,
})
} else {
// Legacy format: table is actually an array of env keys
Expand All @@ -108,6 +121,7 @@ impl FromLua for MiseEnvResult {
env,
cacheable: false,
watch_files: vec![],
redact: false,
})
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/vfox/types/mise-plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ ARCH_TYPE = ""
---@field env? EnvKey[] Environment variables to set
---@field cacheable? boolean Whether the result can be cached (default false)
---@field watch_files? string[] Files to watch for cache invalidation
---@field redact? boolean Whether env vars should be redacted in output (default false)

---@class MisePathCtx
---@field options table Plugin options from mise.toml
Expand Down
11 changes: 1 addition & 10 deletions src/config/env_directive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,16 +552,7 @@ impl EnvResults {
}
env_map.insert(env::PATH_KEY.to_string(), path_env.to_string());
}
Self::module(
&mut r,
config,
source,
name,
&value,
redact.unwrap_or(false),
env_map,
)
.await?;
Self::module(&mut r, config, source, name, &value, redact, env_map).await?;
}
};
}
Expand Down
6 changes: 4 additions & 2 deletions src/config/env_directive/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl EnvResults {
source: PathBuf,
name: String,
value: &Value,
redact: bool,
redact: Option<bool>,
env: IndexMap<String, String>,
) -> Result<()> {
let path = dirs::PLUGINS.join(name.to_kebab_case());
Expand Down Expand Up @@ -49,8 +49,10 @@ impl EnvResults {
}

// Add env vars
// User's explicit redact setting takes priority, otherwise use plugin's preference
let should_redact = redact.unwrap_or(response.redact);
for (k, v) in response.env {
if redact {
if should_redact {
Comment on lines +52 to +55
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The override logic here depends on redact being populated from the user’s mise.toml, but module directives currently only extract tools into EnvDirectiveOptions (the redact key remains inside the plugin options table). As a result, redact will always be None for EnvDirective::Module, so users won’t be able to force redaction on/off or override a plugin’s redact=true preference as described. Consider parsing/removing a top-level redact boolean from the module’s TOML table (similar to tools) into EnvDirectiveOptions.redact, so redact = true/false works and correctly takes priority over the plugin’s preference.

Copilot uses AI. Check for mistakes.
r.redactions.push(k.clone());
}
r.env.insert(k, (v, source.clone()));
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/vfox_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub struct MiseEnvResponse {
pub cacheable: bool,
/// Files to watch for cache invalidation
pub watch_files: Vec<PathBuf>,
/// Whether the plugin wants its env vars to be redacted
pub redact: bool,
}
use xx::regex;

Expand Down Expand Up @@ -88,6 +90,7 @@ impl VfoxPlugin {
env: result_env,
cacheable: result.cacheable,
watch_files: result.watch_files,
redact: result.redact,
}))
}

Expand Down
Loading