mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
refactor: remove ExtensionSource::Bundled, use download-only install for WASM channels (#293)
The Bundled variant and its local-artifacts fallback are superseded by the embedded registry catalog which provides WasmDownload entries with GitHub release URLs. The in-chat extension manager now always downloads channel WASM binaries from releases, simplifying the install path. The setup wizard retains its own local install_bundled_channel path for dev builds where build artifacts exist on disk. Co-authored-by: Claude Opus 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
37c0158765
commit
c1f3b83c98
@@ -246,7 +246,6 @@ fn extract_url(source: &ExtensionSource) -> String {
|
||||
ExtensionSource::Discovered { url } => url.clone(),
|
||||
ExtensionSource::WasmDownload { wasm_url, .. } => wasm_url.clone(),
|
||||
ExtensionSource::WasmBuildable { repo_url, .. } => repo_url.clone(),
|
||||
ExtensionSource::Bundled { name } => name.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -521,9 +521,6 @@ impl ExtensionManager {
|
||||
entry.name, entry.name
|
||||
)))
|
||||
}
|
||||
ExtensionSource::Bundled { name } => {
|
||||
self.install_bundled_channel_from_artifacts(name).await
|
||||
}
|
||||
_ => Err(ExtensionError::InstallFailed(
|
||||
"WASM channel entry has no download URL".to_string(),
|
||||
)),
|
||||
@@ -829,39 +826,6 @@ impl ExtensionManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn install_bundled_channel_from_artifacts(
|
||||
&self,
|
||||
name: &str,
|
||||
) -> Result<InstallResult, ExtensionError> {
|
||||
// Check if already installed
|
||||
let channel_wasm = self.wasm_channels_dir.join(format!("{}.wasm", name));
|
||||
if channel_wasm.exists() {
|
||||
return Err(ExtensionError::AlreadyInstalled(name.to_string()));
|
||||
}
|
||||
|
||||
crate::channels::wasm::install_bundled_channel(name, &self.wasm_channels_dir, false)
|
||||
.await
|
||||
.map_err(ExtensionError::InstallFailed)?;
|
||||
|
||||
tracing::info!(
|
||||
"Installed bundled channel '{}' to {}",
|
||||
name,
|
||||
self.wasm_channels_dir.display()
|
||||
);
|
||||
|
||||
Ok(InstallResult {
|
||||
name: name.to_string(),
|
||||
kind: ExtensionKind::WasmChannel,
|
||||
message: format!(
|
||||
"Channel '{}' installed to {}. Restart IronClaw for the channel to activate. \
|
||||
Run tool_auth('{}') to configure authentication before restarting.",
|
||||
name,
|
||||
self.wasm_channels_dir.display(),
|
||||
name,
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
async fn auth_mcp(
|
||||
&self,
|
||||
name: &str,
|
||||
|
||||
@@ -85,11 +85,6 @@ pub enum ExtensionSource {
|
||||
},
|
||||
/// Discovered online (not yet validated for a specific source type).
|
||||
Discovered { url: String },
|
||||
/// Bundled with the application (pre-built WASM, copied from build artifacts).
|
||||
Bundled {
|
||||
/// Channel or tool name used to locate build artifacts.
|
||||
name: String,
|
||||
},
|
||||
}
|
||||
|
||||
/// Hint about what authentication method is needed.
|
||||
|
||||
+5
-108
@@ -380,72 +380,9 @@ fn builtin_entries() -> Vec<RegistryEntry> {
|
||||
},
|
||||
auth_hint: AuthHint::Dcr,
|
||||
},
|
||||
// -- WASM Channels (bundled) --
|
||||
RegistryEntry {
|
||||
name: "telegram".to_string(),
|
||||
display_name: "Telegram".to_string(),
|
||||
kind: ExtensionKind::WasmChannel,
|
||||
description: "Telegram Bot API channel for receiving and sending messages via Telegram"
|
||||
.to_string(),
|
||||
keywords: vec![
|
||||
"chat".into(),
|
||||
"messaging".into(),
|
||||
"bot".into(),
|
||||
"channel".into(),
|
||||
],
|
||||
source: ExtensionSource::Bundled {
|
||||
name: "telegram".to_string(),
|
||||
},
|
||||
auth_hint: AuthHint::CapabilitiesAuth,
|
||||
},
|
||||
RegistryEntry {
|
||||
name: "slack".to_string(),
|
||||
display_name: "Slack".to_string(),
|
||||
kind: ExtensionKind::WasmChannel,
|
||||
description: "Slack Events API channel for receiving and sending messages via Slack"
|
||||
.to_string(),
|
||||
keywords: vec![
|
||||
"chat".into(),
|
||||
"messaging".into(),
|
||||
"team".into(),
|
||||
"channel".into(),
|
||||
],
|
||||
source: ExtensionSource::Bundled {
|
||||
name: "slack".to_string(),
|
||||
},
|
||||
auth_hint: AuthHint::CapabilitiesAuth,
|
||||
},
|
||||
RegistryEntry {
|
||||
name: "discord".to_string(),
|
||||
display_name: "Discord".to_string(),
|
||||
kind: ExtensionKind::WasmChannel,
|
||||
description:
|
||||
"Discord Gateway channel for handling slash commands, buttons, and messages"
|
||||
.to_string(),
|
||||
keywords: vec![
|
||||
"chat".into(),
|
||||
"messaging".into(),
|
||||
"gaming".into(),
|
||||
"channel".into(),
|
||||
],
|
||||
source: ExtensionSource::Bundled {
|
||||
name: "discord".to_string(),
|
||||
},
|
||||
auth_hint: AuthHint::CapabilitiesAuth,
|
||||
},
|
||||
RegistryEntry {
|
||||
name: "whatsapp".to_string(),
|
||||
display_name: "WhatsApp".to_string(),
|
||||
kind: ExtensionKind::WasmChannel,
|
||||
description:
|
||||
"WhatsApp Business API channel for receiving and sending WhatsApp messages"
|
||||
.to_string(),
|
||||
keywords: vec!["chat".into(), "messaging".into(), "channel".into()],
|
||||
source: ExtensionSource::Bundled {
|
||||
name: "whatsapp".to_string(),
|
||||
},
|
||||
auth_hint: AuthHint::CapabilitiesAuth,
|
||||
},
|
||||
// WASM channels (telegram, slack, discord, whatsapp) come from the embedded
|
||||
// registry catalog (registry/channels/*.json) with WasmDownload URLs pointing
|
||||
// to GitHub release artifacts. See new_with_catalog() for merging.
|
||||
]
|
||||
}
|
||||
|
||||
@@ -701,46 +638,6 @@ mod tests {
|
||||
assert_eq!(entry.unwrap().display_name, "Slack MCP");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_search_finds_telegram_channel() {
|
||||
let registry = ExtensionRegistry::new();
|
||||
let results = registry.search("telegram").await;
|
||||
|
||||
assert!(!results.is_empty(), "Should find telegram in registry");
|
||||
assert_eq!(results[0].entry.name, "telegram");
|
||||
assert_eq!(results[0].entry.kind, ExtensionKind::WasmChannel);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_search_channel_by_keyword() {
|
||||
let registry = ExtensionRegistry::new();
|
||||
let results = registry.search("bot messaging").await;
|
||||
|
||||
let has_telegram = results.iter().any(|r| r.entry.name == "telegram");
|
||||
assert!(
|
||||
has_telegram,
|
||||
"Telegram should appear in bot messaging search"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_bundled_channels() {
|
||||
let registry = ExtensionRegistry::new();
|
||||
|
||||
let telegram = registry.get("telegram").await;
|
||||
assert!(telegram.is_some());
|
||||
assert_eq!(telegram.unwrap().kind, ExtensionKind::WasmChannel);
|
||||
|
||||
let slack = registry.get("slack").await;
|
||||
assert!(slack.is_some());
|
||||
assert_eq!(slack.unwrap().kind, ExtensionKind::WasmChannel);
|
||||
|
||||
let discord = registry.get("discord").await;
|
||||
assert!(discord.is_some());
|
||||
assert_eq!(discord.unwrap().kind, ExtensionKind::WasmChannel);
|
||||
|
||||
let whatsapp = registry.get("whatsapp").await;
|
||||
assert!(whatsapp.is_some());
|
||||
assert_eq!(whatsapp.unwrap().kind, ExtensionKind::WasmChannel);
|
||||
}
|
||||
// Channel tests (telegram, slack, discord, whatsapp) require the embedded catalog
|
||||
// to be loaded via new_with_catalog(). See test_new_with_catalog for catalog coverage.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user