Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
efe1a26
Orchestrating jobs and running them in sandboxes
ilblackdragon Feb 7, 2026
33e08fd
Merge main into sandbox-jobs
ilblackdragon Feb 7, 2026
81619dc
Fix heartbeat: dynamic max_tokens, empty content guard, notification …
ilblackdragon Feb 7, 2026
e4bb215
Add job detail view with drill-down from jobs list
ilblackdragon Feb 7, 2026
c2573d6
Strip model-internal XML tags from LLM responses, fix Telegram parse_…
ilblackdragon Feb 7, 2026
13887bf
Add SystemCommand submission type for thread-state-independent commands
ilblackdragon Feb 7, 2026
fa52d39
Add per-tool execution timeouts, auto-create sandbox project dirs, se…
ilblackdragon Feb 9, 2026
60423ce
Merge remote-tracking branch 'origin/main' into sandbox-jobs
ilblackdragon Feb 9, 2026
c4381ec
Apply cargo fmt to wizard.rs after merge
ilblackdragon Feb 9, 2026
aa56471
Persist sandbox jobs in DB, fix web UI, unify job model
ilblackdragon Feb 9, 2026
b8f4c2b
Secure in-chat auth: tokens never touch the LLM or chat history
ilblackdragon Feb 9, 2026
e65193b
Merge remote-tracking branch 'origin/main' into sandbox-jobs
ilblackdragon Feb 9, 2026
8e8017b
feat: Add Claude Code mode for sandbox jobs
ilblackdragon Feb 9, 2026
5faee3d
fix: Skip create_job tool when sandbox is enabled to prevent duplicat…
ilblackdragon Feb 9, 2026
9a3e747
feat: Web gateway UI quality-of-life improvements
ilblackdragon Feb 9, 2026
2d1c8c7
feat: Add routines system, remove non-sandbox job mode from web UI
ilblackdragon Feb 9, 2026
ca46f8e
fix: Re-enable chat input on agent completion, auto-auth on tool_acti…
ilblackdragon Feb 9, 2026
2314d09
feat: Add routines web UI tab, update docs for sandbox-jobs branch
ilblackdragon Feb 9, 2026
120aadb
fix: Bind Telegram bot to owner account during setup
ilblackdragon Feb 10, 2026
9ca771e
feat: Move settings from disk to PostgreSQL database
ilblackdragon Feb 10, 2026
0c1ac0d
feat: Seed workspace on boot, fix gateway duplicate logs and URL auto…
ilblackdragon Feb 10, 2026
c5748c7
fix: Harden sandbox security (path traversal + orchestrator auth)
ilblackdragon Feb 10, 2026
14bf67c
feat: Rework gateway chat with pinned assistant, pagination, and NEAR…
ilblackdragon Feb 10, 2026
2b1df88
fix: Add per-request HTTP timeout to WASM host, redact credentials in…
ilblackdragon Feb 10, 2026
d08c610
chore: Fix clippy warnings in WASM tools and channels
ilblackdragon Feb 10, 2026
3aac6fd
Fix approval flow
ilblackdragon Feb 10, 2026
76f58b2
fix: Rebuild bundled telegram.wasm with updated WIT interface
ilblackdragon Feb 10, 2026
698222b
refactor: Load WASM channels from disk instead of bundling in binary
ilblackdragon Feb 10, 2026
f34e996
fix: Persist gateway auth token, fix thread hydration race, polish au…
ilblackdragon Feb 10, 2026
3a439f6
fix: Use bindgen! for WASM tool wrapper, add dev tool loading
ilblackdragon Feb 11, 2026
f0b4bb4
feat: Wire main startup and CLI to use DB-backed settings
ilblackdragon Feb 11, 2026
537d082
Merge remote-tracking branch 'origin/main' into sandbox-jobs
ilblackdragon Feb 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
target/
.git/
.env
.env.*
*.md
!CLAUDE.md
node_modules/
tools-src/
89 changes: 78 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@
- **Always available** - Multi-channel access with proactive background execution

### Features
- **Multi-channel input**: TUI (Ratatui), HTTP webhooks, Telegram, WhatsApp, Slack (WASM channels)
- **Multi-channel input**: TUI (Ratatui), HTTP webhooks, WASM channels (Telegram, Slack), web gateway
- **Parallel job execution** with state machine and self-repair for stuck jobs
- **Sandbox execution**: Docker container isolation with orchestrator/worker pattern
- **Claude Code mode**: Delegate jobs to Claude CLI inside containers
- **Routines**: Scheduled (cron) and reactive (event, webhook) task execution
- **Web gateway**: Browser UI with SSE/WebSocket real-time streaming
- **Extension management**: Install, auth, activate MCP/WASM extensions
- **Extensible tools**: Built-in tools, WASM sandbox, MCP client, dynamic builder
- **Persistent memory**: Workspace with hybrid search (FTS + vector via RRF)
- **Prompt injection defense**: Sanitizer, validator, policy rules, leak detection
Expand Down Expand Up @@ -59,7 +64,9 @@ src/
│ ├── context_monitor.rs # Memory pressure detection
│ ├── undo.rs # Turn-based undo/redo with checkpoints
│ ├── submission.rs # Submission parsing (undo, redo, compact, clear, etc.)
│ └── task.rs # Sub-task execution framework
│ ├── task.rs # Sub-task execution framework
│ ├── routine.rs # Routine types (Trigger, Action, Guardrails)
│ └── routine_engine.rs # Routine execution (cron ticker, event matcher)
├── channels/ # Multi-channel input
│ ├── channel.rs # Channel trait, IncomingMessage, OutgoingResponse
Expand All @@ -72,8 +79,33 @@ src/
│ │ ├── overlay.rs # Approval overlays
│ │ └── composer.rs # Message composition
│ ├── http.rs # HTTP webhook (axum) with secret validation
│ ├── slack.rs # Stub
│ └── telegram.rs # Stub
│ ├── repl.rs # Simple REPL (for testing)
│ ├── web/ # Web gateway (browser UI)
│ │ ├── mod.rs # Gateway builder, startup
│ │ ├── server.rs # Axum router, 40+ API endpoints
│ │ ├── sse.rs # SSE broadcast manager
│ │ ├── ws.rs # WebSocket gateway + connection tracking
│ │ ├── types.rs # Request/response types, SseEvent enum
│ │ ├── auth.rs # Bearer token auth middleware
│ │ ├── log_layer.rs # Tracing layer for log streaming
│ │ └── static/ # HTML, CSS, JS (single-page app)
│ └── wasm/ # WASM channel runtime
│ ├── mod.rs
│ ├── bundled.rs # Bundled channel discovery
│ └── wrapper.rs # Channel trait wrapper for WASM modules
├── orchestrator/ # Internal HTTP API for sandbox containers
│ ├── mod.rs
│ ├── api.rs # Axum endpoints (LLM proxy, events, prompts)
│ ├── auth.rs # Per-job bearer token store
│ └── job_manager.rs # Container lifecycle (create, stop, cleanup)
├── worker/ # Runs inside Docker containers
│ ├── mod.rs
│ ├── runtime.rs # Worker execution loop (tool calls, LLM)
│ ├── claude_bridge.rs # Claude Code bridge (spawns claude CLI)
│ ├── api.rs # HTTP client to orchestrator
│ └── proxy_llm.rs # LlmProvider that proxies through orchestrator
├── safety/ # Prompt injection defense
│ ├── sanitizer.rs # Pattern detection, content escaping
Expand All @@ -96,6 +128,9 @@ src/
│ │ ├── file.rs # ReadFile, WriteFile, ListDir, ApplyPatch
│ │ ├── shell.rs # Shell command execution
│ │ ├── memory.rs # Memory tools (search, write, read, tree)
│ │ ├── job.rs # CreateJob, ListJobs, JobStatus, CancelJob
│ │ ├── routine.rs # routine_create/list/update/delete/history
│ │ ├── extension_tools.rs # Extension install/auth/activate/remove
│ │ └── marketplace.rs, ecommerce.rs, taskrabbit.rs, restaurant.rs (stubs)
│ ├── builder/ # Dynamic tool building
│ │ ├── core.rs # BuildRequirement, SoftwareType, Language
Expand Down Expand Up @@ -236,6 +271,30 @@ HEARTBEAT_ENABLED=true
HEARTBEAT_INTERVAL_SECS=1800 # 30 minutes
HEARTBEAT_NOTIFY_CHANNEL=tui
HEARTBEAT_NOTIFY_USER=default

# Web gateway
GATEWAY_ENABLED=true
GATEWAY_HOST=127.0.0.1
GATEWAY_PORT=3001
GATEWAY_AUTH_TOKEN=changeme # Required for API access
GATEWAY_USER_ID=default

# Docker sandbox
SANDBOX_ENABLED=true
SANDBOX_IMAGE=ironclaw-worker:latest
SANDBOX_MEMORY_LIMIT_MB=512
SANDBOX_TIMEOUT_SECS=1800

# Claude Code mode (runs inside sandbox containers)
CLAUDE_CODE_ENABLED=false
CLAUDE_CODE_MODEL=claude-sonnet-4-20250514
CLAUDE_CODE_MAX_TURNS=50
CLAUDE_CODE_CONFIG_DIR=/home/worker/.claude

# Routines (scheduled/reactive execution)
ROUTINES_ENABLED=true
ROUTINES_CRON_INTERVAL=60 # Tick interval in seconds
ROUTINES_MAX_CONCURRENT=3
```

### NEAR AI Provider
Expand Down Expand Up @@ -297,13 +356,14 @@ Key test patterns:

## Current Limitations / TODOs

1. **Slack/Telegram channels** - Stubs only, need implementation
2. **Domain-specific tools** - `marketplace.rs`, `restaurant.rs`, `taskrabbit.rs`, `ecommerce.rs` return placeholder responses; need real API integrations
3. **Integration tests** - Need testcontainers setup for PostgreSQL
4. **MCP stdio transport** - Only HTTP transport implemented
5. **WIT bindgen integration** - Auto-extract tool description/schema from WASM modules (stubbed)
6. **Capability granting after tool build** - Built tools get empty capabilities; need UX for granting HTTP/secrets access
7. **Tool versioning workflow** - No version tracking or rollback for dynamically built tools
1. **Domain-specific tools** - `marketplace.rs`, `restaurant.rs`, `taskrabbit.rs`, `ecommerce.rs` return placeholder responses; need real API integrations
2. **Integration tests** - Need testcontainers setup for PostgreSQL
3. **MCP stdio transport** - Only HTTP transport implemented
4. **WIT bindgen integration** - Auto-extract tool description/schema from WASM modules (stubbed)
5. **Capability granting after tool build** - Built tools get empty capabilities; need UX for granting HTTP/secrets access
6. **Tool versioning workflow** - No version tracking or rollback for dynamically built tools
7. **Webhook trigger endpoint** - Routines webhook trigger not yet exposed in web gateway
8. **Full channel status view** - Gateway status widget exists, but no per-channel connection dashboard

### Completed

Expand All @@ -320,6 +380,13 @@ Key test patterns:
- ✅ **Tool approval enforcement** - Tools with `requires_approval()` (shell, http, file write/patch, build_software) now gate execution, track auto-approved tools per session
- ✅ **Tool definition refresh** - Tool definitions refreshed each iteration so newly built tools become visible in same session
- ✅ **Worker tool call handling** - Uses `respond_with_tools()` to properly execute tool calls when `select_tools()` returns empty
- ✅ **Gateway control plane** - Web gateway with 40+ API endpoints, SSE/WebSocket
- ✅ **Web Control UI** - Browser-based dashboard with chat, memory, jobs, logs, extensions, routines
- ✅ **Slack/Telegram channels** - Implemented as WASM tools
- ✅ **Docker sandbox** - Orchestrator/worker containers with per-job auth
- ✅ **Claude Code mode** - Delegate jobs to Claude CLI inside containers
- ✅ **Routines system** - Cron, event, webhook, and manual triggers with guardrails
- ✅ **Extension management** - Install, auth, activate MCP/WASM extensions via CLI and web UI

## Adding a New Tool

Expand Down
45 changes: 45 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ axum = { version = "0.8", features = ["ws"] }
tower = "0.5"
tower-http = { version = "0.6", features = ["trace", "cors"] }

# Cron scheduling for routines
cron = "0.13"

# Safety/sanitization
regex = "1"
aho-corasick = "1"
Expand Down Expand Up @@ -99,6 +102,7 @@ hyper-util = { version = "0.1", features = ["server", "tokio", "http1", "http2"]
http-body-util = "0.1"
bytes = "1"
base64 = "0.22.1"
mime_guess = "2.0.5"

# macOS keychain
[target.'cfg(target_os = "macos")'.dependencies]
Expand Down
63 changes: 63 additions & 0 deletions Dockerfile.worker
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Multi-stage Dockerfile for the IronClaw worker container.
#
# This image runs the ironclaw binary in worker mode inside Docker containers.
# The orchestrator creates instances of this image for sandboxed job execution.
#
# Build:
# docker build -f Dockerfile.worker -t ironclaw-worker .
#
# The image includes common development tools so workers can build software,
# run tests, and execute shell commands.

FROM rust:1.85-bookworm AS builder

WORKDIR /build
COPY . .

# Build only the ironclaw binary (release mode)
RUN cargo build --release --bin ironclaw

# ---

FROM debian:bookworm-slim

# Install common development tools
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
build-essential \
pkg-config \
libssl-dev \
nodejs \
npm \
python3 \
python3-pip \
python3-venv \
&& rm -rf /var/lib/apt/lists/*

# Install Rust toolchain for the sandbox user
ENV RUSTUP_HOME=/usr/local/rustup \
CARGO_HOME=/usr/local/cargo \
PATH=/usr/local/cargo/bin:$PATH
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.85.0 \
&& chmod -R a+r /usr/local/rustup /usr/local/cargo

# Install Claude Code CLI (for claude-bridge mode)
RUN npm install -g @anthropic-ai/claude-code@latest

# Copy the binary
COPY --from=builder /build/target/release/ironclaw /usr/local/bin/ironclaw

# Create non-root user (UID 1000 matches the orchestrator's container config)
RUN useradd -m -u 1000 -s /bin/bash sandbox \
&& mkdir -p /workspace \
&& chown sandbox:sandbox /workspace \
&& mkdir -p /home/sandbox/.claude \
&& chown sandbox:sandbox /home/sandbox/.claude

USER sandbox
WORKDIR /workspace

# The orchestrator passes the full command via Docker cmd.
ENTRYPOINT ["ironclaw"]
Loading