Files
optimclaw/tools-src/slack
97a7637f30 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
2026-02-20 01:17:44 +00:00
..

Slack WASM Tool

A standalone WASM component that provides Slack integration for IronClaw. This serves as both a functional tool and a template for building custom WASM tools.

Features

  • send_message: Send messages to channels or threads
  • list_channels: List channels the bot has access to
  • get_channel_history: Retrieve recent messages from a channel
  • post_reaction: Add emoji reactions to messages
  • get_user_info: Get information about Slack users

Prerequisites

  1. Rust toolchain with WASM target:

    rustup target add wasm32-wasip2
    
  2. cargo-component for building WASM components:

    cargo install cargo-component
    
  3. Slack Bot Token with the following OAuth scopes:

    • chat:write - Send messages
    • channels:read - List public channels
    • channels:history - Read channel history
    • groups:read - List private channels
    • groups:history - Read private channel history
    • reactions:write - Add reactions
    • users:read - Get user information

Building

cd tools-src/slack
cargo component build --release

The compiled WASM component will be at:

target/wasm32-wasip2/release/slack_tool.wasm

Installation

Option A: File-based (Development)

Copy the WASM and capabilities files to the agent's tools directory:

mkdir -p ~/.ironclaw/tools
cp target/wasm32-wasip2/release/slack_tool.wasm ~/.ironclaw/tools/slack.wasm
cp slack.capabilities.json ~/.ironclaw/tools/

Option B: Database Storage (Production)

Use the agent CLI or API to store the tool:

ironclaw tool install \
  --name slack \
  --wasm target/wasm32-wasip2/release/slack_tool.wasm \
  --capabilities slack.capabilities.json

Configuration

Store your Slack bot token as a secret:

ironclaw secret set slack_bot_token "xoxb-your-token-here"

Or via SQL:

INSERT INTO secrets (user_id, name, encrypted_value, key_salt)
VALUES ('your_user_id', 'slack_bot_token', ...);

Usage Examples

Send a Message

{
  "action": "send_message",
  "channel": "#general",
  "text": "Hello from IronClaw!"
}

Reply in a Thread

{
  "action": "send_message",
  "channel": "C1234567890",
  "text": "This is a thread reply",
  "thread_ts": "1234567890.123456"
}

List Channels

{
  "action": "list_channels",
  "limit": 50
}

Get Channel History

{
  "action": "get_channel_history",
  "channel": "C1234567890",
  "limit": 10
}

Add a Reaction

{
  "action": "post_reaction",
  "channel": "C1234567890",
  "timestamp": "1234567890.123456",
  "emoji": "thumbsup"
}

Get User Info

{
  "action": "get_user_info",
  "user_id": "U1234567890"
}

Security Model

This tool runs in a sandboxed WASM environment with strict capability controls:

  1. HTTP Allowlist: Can only access slack.com/api/*
  2. Credential Injection: The bot token is injected by the host runtime; the WASM code never sees it
  3. Rate Limiting: 50 requests/minute, 1000 requests/hour
  4. No Filesystem Access: Cannot read/write files except through workspace capability
  5. No Network Access: Beyond the allowlisted endpoints

Capabilities File

The slack.capabilities.json file declares what this tool needs:

{
  "http": {
    "allowlist": [
      { "host": "slack.com", "path_prefix": "/api/", "methods": ["GET", "POST"] }
    ],
    "credentials": {
      "slack_bot_token": {
        "secret_name": "slack_bot_token",
        "location": { "type": "bearer" },
        "host_patterns": ["slack.com"]
      }
    },
    "rate_limit": { "requests_per_minute": 50, "requests_per_hour": 1000 }
  },
  "secrets": {
    "allowed_names": ["slack_bot_token"]
  }
}

Building Your Own Tool

Use this as a template for creating new WASM tools:

  1. Copy this directory
  2. Update Cargo.toml with your tool name
  3. Modify src/types.rs with your action types
  4. Implement API calls in src/api.rs
  5. Update the action dispatch in src/lib.rs
  6. Create your *.capabilities.json file
  7. Build with cargo component build --release

Key Files

  • Cargo.toml - Rust package config with WASM target
  • src/lib.rs - WIT bindings and main dispatch
  • src/types.rs - Request/response types
  • src/api.rs - API implementation
  • *.capabilities.json - Security capabilities declaration

WIT Interface

Tools implement the sandboxed-tool world from wit/tool.wit:

world sandboxed-tool {
    import host;   // log, http-request, secret-exists, etc.
    export tool;   // execute, schema, description
}

Troubleshooting

"Slack bot token not configured"

Ensure you've stored the secret:

ironclaw secret set slack_bot_token "xoxb-..."

"Endpoint not in allowlist"

Check that slack.capabilities.json includes the endpoint you're trying to access.

"Rate limit exceeded"

The tool has a default rate limit of 50 requests/minute. Wait and retry.

Build errors

Ensure you have the WASM target and cargo-component installed:

rustup target add wasm32-wasip2
cargo install cargo-component

License

MIT OR Apache-2.0