feat(acp): auto-pin @latest plugin specs to installed versions after install

After a successful plugin install, read the actual installed version from
node_modules and replace @latest in opencode.json with the pinned version.
This prevents opencode from hitting the npm registry on every startup.

Also add a preflight warning when @latest specs are detected, guiding
the user to install via the plugin manager to auto-pin.
This commit is contained in:
xintaofei
2026-04-12 11:47:01 +08:00
parent 6459e5286a
commit 4397b0eae7
2 changed files with 123 additions and 1 deletions

View File

@@ -350,7 +350,7 @@ async fn check_binary_environment(
// OpenCode plugin checks
if agent_type == AgentType::OpenCode {
use crate::acp::opencode_plugins::{self, PluginStatus};
use crate::acp::opencode_plugins::{self, PluginStatus, spec_has_floating_version};
match opencode_plugins::check_opencode_plugins(None) {
Ok(summary) => {
let missing: Vec<_> = summary
@@ -395,6 +395,32 @@ async fn check_binary_environment(
});
}
// Warn about @latest specs that cause slow startup
let floating: Vec<&str> = summary
.plugins
.iter()
.filter(|p| spec_has_floating_version(&p.declared_spec))
.map(|p| p.name.as_str())
.collect();
if !floating.is_empty() {
checks.push(CheckItem {
check_id: "opencode_plugins_floating".into(),
label: "Plugin versions".into(),
status: CheckStatus::Warn,
message: format!(
"{} plugin(s) use @latest which forces a network check on every startup: {}. \
Install via the plugin manager to auto-pin versions.",
floating.len(),
floating.join(", ")
),
fixes: vec![FixAction {
label: "Install Plugins".into(),
kind: FixActionKind::InstallOpencodePlugins,
payload: String::new(),
}],
});
}
// Project-level config hint
if summary.has_project_config_hint {
checks.push(CheckItem {