fix: address code review findings on the bundle lifecycle
The user-origin marker on replaced mcp.json entries is now sticky: re-records and cross-bundle transfers only upgrade replaced to transferred when the prior record proves bundle origin, so updating a bundle can no longer make uninstall delete a key the user had before the bundle replaced it. Canonical source URLs lowercase only the host, since self-hosted forges treat repository paths as case-sensitive and collapsing distinct repos misdirects updates and uninstalls. git clone invocations pass '--' before the URL so a crafted source cannot be parsed as a git flag. Lifecycle flags (--install, --install-builtins, --update-bundle, --uninstall) and their companions now conflict explicitly instead of first-match dispatch silently dropping actions. --install-from returns as a hidden tombstone that errors with the replacement instead of feeding the flag to the LLM as prompt text. --list-bundles dispatches before config load so a pure read no longer boots MCP servers. write_file_atomic fsyncs before the rename so a crash cannot persist a truncated store. REPL: .uninstall accepts --yes, .install rejects trailing tokens after a category, and .install remote gets a migration hint. Plus polish: host validation rejects '#' and '?', renamed_to no longer serializes null, derived names get a debug assert against the validator, completions share DEFAULT_GIT_HOST, README mentions skills.
This commit is contained in:
+8
-4
@@ -107,7 +107,6 @@ async fn main() -> Result<()> {
|
||||
|| cli.list_rags
|
||||
|| cli.list_macros
|
||||
|| cli.list_skills
|
||||
|| cli.list_bundles
|
||||
|| cli.list_sessions;
|
||||
let vault_flags = cli.add_secret.is_some()
|
||||
|| cli.get_secret.is_some()
|
||||
@@ -128,6 +127,10 @@ async fn main() -> Result<()> {
|
||||
return sandbox::launch(name.clone(), cli.fresh);
|
||||
}
|
||||
|
||||
if cli.install_from.is_some() {
|
||||
bail!("--install-from was removed; use --install <GIT_URL|OWNER/REPO> instead");
|
||||
}
|
||||
|
||||
install_builtins()?;
|
||||
|
||||
if let Some(category) = cli.install_builtins {
|
||||
@@ -151,6 +154,10 @@ async fn main() -> Result<()> {
|
||||
return config::uninstall_bundle(name, cli.yes);
|
||||
}
|
||||
|
||||
if cli.list_bundles {
|
||||
return config::list_installed_bundles();
|
||||
}
|
||||
|
||||
if let Some(client_arg) = &cli.authenticate {
|
||||
let cfg = Config::load_with_interpolation(true).await?;
|
||||
let app_config = AppConfig::from_config(cfg)?;
|
||||
@@ -323,9 +330,6 @@ async fn run(
|
||||
println!("{skills}");
|
||||
return Ok(());
|
||||
}
|
||||
if cli.list_bundles {
|
||||
return config::list_installed_bundles();
|
||||
}
|
||||
let skills = cli.skills();
|
||||
if skills.len() == 1 {
|
||||
let name = &skills[0];
|
||||
|
||||
Reference in New Issue
Block a user