Files
optimclaw/tools-src/slack
04c5c3fe9f feat: WASM extension versioning with WIT compat checks (#592)
* feat: add WASM extension versioning with WIT compat checks and CI enforcement

Phase 1 — WIT Versioning & Compatibility Checks:
- Version WIT packages as `package near:[email protected];`
- Add `semver` crate for version parsing and comparison
- Add `WIT_TOOL_VERSION` / `WIT_CHANNEL_VERSION` host constants
- Add `version` and `wit_version` fields to capabilities schemas
- Add `wit_version` column to `wasm_tools` DB table (both backends)
- Add load-time `check_wit_version_compat()` with semver rules
- Add `IncompatibleWitVersion` error variants for tools and channels
- Enhance instantiation errors with WIT version mismatch hints
- Update all 14 capabilities JSON and 14 registry JSON files

Phase 2 — Upgrade-in-Place & Channel DB Storage:
- Change tool store to DELETE-before-INSERT (one version per extension)
- Create `wasm_channels` table (PostgreSQL migration + libSQL schema)
- Add `WasmChannelStore` trait with PostgreSQL and libSQL backends
- Add `extension_info` tool showing version, WIT version, and status
- Wire `ExtensionInfoTool` into tool registry (7 extension tools)

Phase 3 — CI Version-Bump Enforcement:
- Add `scripts/check-version-bumps.sh` checking WIT/tool/channel versions
- Add `version-check` CI job (PR-only) to `.github/workflows/test.yml`
- Support `[skip-version-check]` label/commit message bypass

Includes 7 regression tests for WIT version compatibility checking
and 2 integration tests for WIT version annotation verification.

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: address PR review feedback for WASM extension versioning

- Wrap PostgreSQL DELETE+INSERT in transactions for both tool and channel
  store() methods to prevent data loss on partial failure (Gemini, Copilot)
- Rename StoredWasmChannelWithBinary.tool → .channel (copy-paste fix)
- Remove unused WasmError::IncompatibleWitVersion variant (dead code)
- Map channel loader WIT mismatch to IncompatibleWitVersion instead of
  generic Config error, simplify variant to single String message
- Fix extension_info description to match actual returned fields
- Add schema test for ExtensionInfoTool matching existing test pattern
- Fix CI script to fail fast on git errors instead of silent bypass

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
2026-03-06 04:38:07 +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