Skip to content

Commit 97a7637

Browse files
feat: extension registry with metadata catalog and onboarding integration (#238)
* feat: add extension registry with metadata catalog, CLI, and onboarding integration Adds a central registry that catalogs all 14 available extensions (10 tools, 4 channels) with their capabilities, auth requirements, and artifact references. The onboarding wizard now shows installable channels from the registry and offers tool installation as a new Step 7. - registry/ folder with per-extension JSON manifests and bundle definitions - src/registry/ module: manifest structs, catalog loader, installer - `ironclaw registry list|info|install|install-defaults` CLI commands - Setup wizard enhanced: channels from registry, new extensions step (8 steps) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(setup): resolve workspace errors for tool crates and channels-only onboarding Tool crates in tools-src/ and channels-src/ failed `cargo metadata` during onboard install because Cargo resolved them as part of the root workspace. Add `[workspace]` table to each standalone crate and extend the root `workspace.exclude` list so they build independently. Channels-only mode (`onboard --channels-only`) failed with "Secrets not configured" and "No database connection" because it skipped database and security setup. Add `reconnect_existing_db()` to establish the DB connection and load saved settings before running channel configuration. Also improve the tunnel "already configured" display to show full provider details (domain, mode, command) instead of just the provider name. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(registry): address PR review feedback on installer and catalog - Use manifest.name (not crate_name) for installed filenames so discovery, auth, and CLI commands all agree on the stem (#1) - Add AlreadyInstalled error variant instead of misleading ExtensionNotFound (#2) - Add DownloadFailed error variant with URL context instead of stuffing URLs into PathBuf (#3) - Validate HTTP status with error_for_status() before reading response bytes in artifact downloads (#4) - Switch build_wasm_component to tokio::process::Command with status() so build output streams to the terminal (#6) - Find WASM artifact by crate_name specifically instead of picking the first .wasm file in the release directory (#7) - Add is_file() guard in catalog loader to skip directories (#8) - Detect ambiguous bare-name lookups when both tools/<name> and channels/<name> exist, with get_strict() returning an error (#9) - Fix wizard step_extensions to check tool.name for installed detection, consistent with the new naming (#11, #12) - Fix redundant closures and map_or clippy warnings in changed files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(setup): restore DB connection fields after settings reload reconnect_postgres() and reconnect_libsql() called Settings::from_db_map() which overwrote database_url / libsql_path / libsql_url set from env vars. Also use get_strict() in cmd_info to surface ambiguous bare-name errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: fix clippy collapsible_if and print_literal warnings Collapse nested if-let chains and inline string literals in format macros to satisfy CI clippy lint checks (deny warnings). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(registry): prefer artifacts for install-defaults and improve dir lookup - InstallDefaults now defaults to downloading pre-built artifacts (matching `registry install` behavior), with --build flag for source builds. - find_registry_dir() walks up 3 ancestor levels from the exe and adds a CARGO_MANIFEST_DIR fallback, matching load_registry_catalog() logic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent dae26d6 commit 97a7637

42 files changed

Lines changed: 2671 additions & 29 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
[workspace]
22
members = [".", "benchmarks"]
33
exclude = [
4+
"channels-src/discord",
45
"channels-src/telegram",
56
"channels-src/slack",
67
"channels-src/whatsapp",
8+
"tools-src/github",
79
"tools-src/gmail",
10+
"tools-src/google-calendar",
11+
"tools-src/google-docs",
12+
"tools-src/google-drive",
13+
"tools-src/google-sheets",
14+
"tools-src/google-slides",
15+
"tools-src/okta",
16+
"tools-src/slack",
17+
"tools-src/telegram",
818
]
919

1020
[package]

channels-src/discord/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ lto = true
2121
codegen-units = 1
2222

2323

24+
25+
[workspace]

channels-src/slack/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ opt-level = "s"
2727
lto = true
2828
strip = true
2929
codegen-units = 1
30+
31+
[workspace]

channels-src/telegram/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ opt-level = "s"
2525
lto = true
2626
strip = true
2727
codegen-units = 1
28+
29+
[workspace]

channels-src/whatsapp/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ serde_json = "1"
1616
opt-level = "s"
1717
lto = true
1818
strip = true
19+
20+
[workspace]

registry/_bundles.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"bundles": {
3+
"google": {
4+
"display_name": "Google Suite",
5+
"description": "Gmail, Calendar, Drive, Docs, Sheets, Slides",
6+
"extensions": [
7+
"tools/gmail",
8+
"tools/google-calendar",
9+
"tools/google-docs",
10+
"tools/google-drive",
11+
"tools/google-sheets",
12+
"tools/google-slides"
13+
],
14+
"shared_auth": "google_oauth_token"
15+
},
16+
"messaging": {
17+
"display_name": "Messaging Channels",
18+
"description": "Discord, Telegram, Slack, and WhatsApp channels",
19+
"extensions": [
20+
"channels/discord",
21+
"channels/telegram",
22+
"channels/slack",
23+
"channels/whatsapp"
24+
],
25+
"shared_auth": null
26+
},
27+
"default": {
28+
"display_name": "Recommended Set",
29+
"description": "Core tools and channels for a productive setup",
30+
"extensions": [
31+
"tools/github",
32+
"tools/gmail",
33+
"tools/google-calendar",
34+
"tools/google-drive",
35+
"tools/slack",
36+
"channels/telegram",
37+
"channels/slack"
38+
],
39+
"shared_auth": null
40+
}
41+
}
42+
}

registry/channels/discord.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "discord",
3+
"display_name": "Discord",
4+
"kind": "channel",
5+
"version": "0.1.0",
6+
"description": "Discord Gateway/Webhook channel for slash commands, buttons, and messages",
7+
"keywords": ["messaging", "chat", "discord", "bot"],
8+
9+
"source": {
10+
"dir": "channels-src/discord",
11+
"capabilities": "discord.capabilities.json",
12+
"crate_name": "discord-channel"
13+
},
14+
15+
"artifacts": {
16+
"wasm32-wasip2": {
17+
"url": null,
18+
"sha256": null
19+
}
20+
},
21+
22+
"auth_summary": {
23+
"method": "manual",
24+
"provider": "Discord",
25+
"secrets": ["discord_bot_token"],
26+
"shared_auth": null,
27+
"setup_url": "https://discord.com/developers/applications"
28+
},
29+
30+
"tags": ["messaging"]
31+
}

registry/channels/slack.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "slack",
3+
"display_name": "Slack",
4+
"kind": "channel",
5+
"version": "0.1.0",
6+
"description": "Slack Events API channel for receiving and responding to Slack messages",
7+
"keywords": ["messaging", "chat", "workspace", "slack"],
8+
9+
"source": {
10+
"dir": "channels-src/slack",
11+
"capabilities": "slack.capabilities.json",
12+
"crate_name": "slack-channel"
13+
},
14+
15+
"artifacts": {
16+
"wasm32-wasip2": {
17+
"url": null,
18+
"sha256": null
19+
}
20+
},
21+
22+
"auth_summary": {
23+
"method": "manual",
24+
"provider": "Slack",
25+
"secrets": ["slack_bot_token", "slack_signing_secret"],
26+
"shared_auth": null,
27+
"setup_url": "https://api.slack.com/apps"
28+
},
29+
30+
"tags": ["default", "messaging"]
31+
}

registry/channels/telegram.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "telegram",
3+
"display_name": "Telegram",
4+
"kind": "channel",
5+
"version": "0.1.0",
6+
"description": "Telegram Bot API channel for receiving and responding to messages",
7+
"keywords": ["messaging", "bot", "chat", "telegram"],
8+
9+
"source": {
10+
"dir": "channels-src/telegram",
11+
"capabilities": "telegram.capabilities.json",
12+
"crate_name": "telegram-channel"
13+
},
14+
15+
"artifacts": {
16+
"wasm32-wasip2": {
17+
"url": null,
18+
"sha256": null
19+
}
20+
},
21+
22+
"auth_summary": {
23+
"method": "manual",
24+
"provider": "Telegram",
25+
"secrets": ["telegram_bot_token"],
26+
"shared_auth": null,
27+
"setup_url": "https://t.me/BotFather"
28+
},
29+
30+
"tags": ["default", "messaging"]
31+
}

registry/channels/whatsapp.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "whatsapp",
3+
"display_name": "WhatsApp",
4+
"kind": "channel",
5+
"version": "0.1.0",
6+
"description": "WhatsApp Cloud API channel for receiving and responding to messages",
7+
"keywords": ["messaging", "chat", "whatsapp", "meta"],
8+
9+
"source": {
10+
"dir": "channels-src/whatsapp",
11+
"capabilities": "whatsapp.capabilities.json",
12+
"crate_name": "whatsapp-channel"
13+
},
14+
15+
"artifacts": {
16+
"wasm32-wasip2": {
17+
"url": null,
18+
"sha256": null
19+
}
20+
},
21+
22+
"auth_summary": {
23+
"method": "manual",
24+
"provider": "Meta",
25+
"secrets": ["whatsapp_access_token", "whatsapp_verify_token"],
26+
"shared_auth": null,
27+
"setup_url": "https://developers.facebook.com/apps/"
28+
},
29+
30+
"tags": ["messaging"]
31+
}

0 commit comments

Comments
 (0)