feat: added tab completions to --update-bundle flag

This commit is contained in:
Dark-Alex-17 committed 2026-09-01 12:53:24 -06:00
1 parent affa5e7cef
commit c0a17031c5
5 files changed
+30 -19

No files matched your search

+9
View File
@@ -105,6 +105,15 @@ pub(super) fn macro_completer(current: &OsStr) -> Vec<CompletionCandidate> {
.collect() .collect()
} }
pub(super) fn bundle_completer(current: &OsStr) -> Vec<CompletionCandidate> {
let cur = current.to_string_lossy();
crate::config::installed_bundle_names()
.into_iter()
.filter(|b| b.starts_with(&*cur))
.map(CompletionCandidate::new)
.collect()
}
fn extract_agent_from_args() -> Option<String> { fn extract_agent_from_args() -> Option<String> {
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let mut i = 0; let mut i = 0;
+3 -2
View File
@@ -1,8 +1,8 @@
mod completer; mod completer;
use crate::cli::completer::{ use crate::cli::completer::{
ShellCompletion, agent_completer, macro_completer, mcp_server_completer, model_completer, ShellCompletion, agent_completer, bundle_completer, macro_completer, mcp_server_completer,
rag_completer, role_completer, secrets_completer, session_completer, model_completer, rag_completer, role_completer, secrets_completer, session_completer,
}; };
use crate::config::{AssetCategory, InstallFilter, MemoryScope}; use crate::config::{AssetCategory, InstallFilter, MemoryScope};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@@ -230,6 +230,7 @@ pub struct Cli {
value_name = "NAME", value_name = "NAME",
group = "yes_scope", group = "yes_scope",
conflicts_with_all = ["uninstall"], conflicts_with_all = ["uninstall"],
add = ArgValueCompleter::new(bundle_completer),
help_heading = "Installation & Updates" help_heading = "Installation & Updates"
)] )]
pub update_bundle: Option<String>, pub update_bundle: Option<String>,
+15
View File
@@ -9,6 +9,7 @@ use crate::utils::IS_STDOUT_TERMINAL;
use anyhow::{Context, Result, bail}; use anyhow::{Context, Result, bail};
use chrono::{SecondsFormat, Utc}; use chrono::{SecondsFormat, Utc};
use inquire::Confirm; use inquire::Confirm;
use log::warn;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use std::collections::BTreeMap; use std::collections::BTreeMap;
@@ -637,6 +638,20 @@ pub(crate) fn bundle_list_rows(store: &BundleStore, config_dir: &Path) -> Vec<Bu
.collect() .collect()
} }
pub(crate) fn installed_bundle_names() -> Vec<String> {
match BundleStore::load() {
Ok(store) => store
.bundle_names()
.into_iter()
.map(str::to_string)
.collect(),
Err(e) => {
warn!("skipping bundle-name completion: {e:#}");
Vec::new()
}
}
}
pub fn list_installed_bundles() -> Result<()> { pub fn list_installed_bundles() -> Result<()> {
let store = BundleStore::load()?; let store = BundleStore::load()?;
let rows = bundle_list_rows(&store, &paths::config_dir()); let rows = bundle_list_rows(&store, &paths::config_dir());
+1
View File
@@ -33,6 +33,7 @@ pub use self::agent::{
pub use self::app_config::AppConfig; pub use self::app_config::AppConfig;
#[allow(unused_imports)] #[allow(unused_imports)]
pub use self::app_state::AppState; pub use self::app_state::AppState;
pub(crate) use self::bundles::installed_bundle_names;
pub use self::bundles::list_installed_bundles; pub use self::bundles::list_installed_bundles;
pub use self::input::Input; pub use self::input::Input;
pub use self::install_remote::{ pub use self::install_remote::{
+2 -17
View File
@@ -1,4 +1,4 @@
use super::bundles::BundleStore; use super::bundles::installed_bundle_names;
use super::mcp_tool_policy::{McpToolPolicy, SkillMcpLayer, ToolFilter, expand_mcp_server_alias}; use super::mcp_tool_policy::{McpToolPolicy, SkillMcpLayer, ToolFilter, expand_mcp_server_alias};
use super::rag_cache::{RagCache, RagKey}; use super::rag_cache::{RagCache, RagKey};
use super::session::{INTERRUPTED_RESPONSE_TEXT, Session}; use super::session::{INTERRUPTED_RESPONSE_TEXT, Session};
@@ -67,22 +67,6 @@ use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use std::{env, fs}; use std::{env, fs};
/// Completion must degrade rather than break the prompt, but a corrupt store
/// should not vanish silently: the failure is logged before returning empty.
fn installed_bundle_names() -> Vec<String> {
match BundleStore::load() {
Ok(store) => store
.bundle_names()
.into_iter()
.map(str::to_string)
.collect(),
Err(e) => {
warn!("skipping bundle-name completion: {e:#}");
Vec::new()
}
}
}
pub(crate) fn expand_enabled_mcp_server_ids( pub(crate) fn expand_enabled_mcp_server_ids(
app: &AppConfig, app: &AppConfig,
mcp_config: &McpServersConfig, mcp_config: &McpServersConfig,
@@ -5210,6 +5194,7 @@ mod tests {
use super::*; use super::*;
use crate::config::AppState; use crate::config::AppState;
use crate::config::agent::AgentConfig; use crate::config::agent::AgentConfig;
use crate::config::bundles::BundleStore;
use crate::config::mcp_tool_policy::LayerSource; use crate::config::mcp_tool_policy::LayerSource;
use crate::config::tool_scope::test_fixtures::{FixtureServer, fixture_runtime}; use crate::config::tool_scope::test_fixtures::{FixtureServer, fixture_runtime};
use crate::function::jobs::RingBuf; use crate::function::jobs::RingBuf;