Commit graph

100 commits

Author SHA1 Message Date
Chummy
639032c952
Merge pull request #331 from stakeswky/feat/lark-channel
feat(channels): add Lark/Feishu IM channel support
2026-02-17 00:08:05 +08:00
Chummy
e4944a5fc2
feat(cost): add budget tracking core and harden storage reliability (#292) 2026-02-16 23:40:47 +08:00
Chummy
8882746ced
fix(onboard): refresh MiniMax defaults and endpoint (#299) 2026-02-16 23:40:44 +08:00
Chummy
23b0f360c2
fix(composio): align v3 execute path and honor configured entity_id (#322) 2026-02-16 23:40:37 +08:00
Chummy
80da3e64e9
feat: unify scheduled tasks from #337 and #338 with security-first integration
Unifies scheduled task capabilities and consolidates overlapping implementations from #337 and #338 into a single security-first integration path.\n\nCo-authored-by: Edvard <ecschoye@stud.ntnu.no>\nCo-authored-by: stawky <stakeswky@gmail.com>
2026-02-16 23:38:29 +08:00
stawky
760728d038 feat(channels): add Lark/Feishu IM channel support
Implement Lark/Feishu as a new channel for ZeroClaw (Issue #164).

- Add LarkChannel with Channel trait impl (name, listen, send)
- listen: HTTP server (axum) for event callback with URL verification
  (challenge response) and im.message.receive_v1 text message parsing
- send: POST /open-apis/im/v1/messages with tenant_access_token auth
- get_tenant_access_token with caching and auto-refresh on 401
- Allowlist filtering by open_id (same pattern as other channels)
- Add LarkConfig to schema (app_id, app_secret, verification_token, port, allowed_users)
- Register lark in channel list, doctor, and start_channels
- 18 unit tests: config serde, allowlist, channel name, message parsing,
  edge cases (unicode, missing fields, invalid JSON, wrong event type)
- Fix pre-existing SchedulerConfig compile error on main
2026-02-16 22:54:45 +08:00
Chummy
c842ece12c
feat(onboard): refresh model discovery and canonicalize provider aliases (#341)
* feat(onboard): add model refresh command with ttl cache

* fix(onboard): refresh curated models and canonicalize provider aliases

* fix(channels): align agent_turn call signature

* fix(channels): call run_tool_call_loop for stable channel runtime
2026-02-16 22:32:30 +08:00
Chummy
fa0c77385c
Merge pull request #266 from chumyin/fix/provider-chatresponse-unification
fix(provider): complete ChatResponse integration across runtime surfaces
2026-02-16 21:21:43 +08:00
Will Sarg
b76a3879a9
fix(ci): mitigate GitHub API rate-limit failures (#334)
* fix(ci): mitigate GitHub API rate-limit failures in workflows

* fix(ci): resolve signature drift blocking Docker smoke
2026-02-16 08:05:52 -05:00
chumyin
2d6ec2fb71 fix(rebase): resolve PR #266 conflicts against latest main 2026-02-16 19:33:04 +08:00
Mgrsc
b3fcdad3b5
fix: use consistent <tool_call> tag in channel system prompt (#305)
The tool use protocol in channels/mod.rs was using <invoke> tags,
but the parser in agent/loop_.rs only recognizes <tool_call> tags.
This ensures consistency across all entry points.
2026-02-16 05:59:40 -05:00
Chummy
b5d9f72023
test(channels): neutralize UTF-8 truncation regression fixture (#289)
* test(channels): neutralize UTF-8 truncation regression fixture

* fix(ci): resolve fmt drift and discord test config init
2026-02-16 05:58:35 -05:00
Chummy
9d29f30a31
fix(channels): execute tool calls in channel runtime (#302)
* fix(channels): execute tool calls in channel runtime (#302)

* chore(fmt): align repo formatting with rustfmt 1.92
2026-02-16 05:07:01 -05:00
Argenis
9bdbc1287c
fix: add tool use protocol to channel/daemon/gateway system prompts
Fixes #284 - Tool call format was missing from the system prompt in
channel, daemon, and gateway modes. This caused LLMs to not know how
to properly invoke tools when using these modes.

The tool use protocol with <invoke> tags and JSON payload format now
matches the implementation in agent loop mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 02:36:21 -05:00
不做了睡大觉
21dc22f249
test(channels): add regression for UTF-8 truncation panic in channel logs (#262) 2026-02-16 02:30:26 -05:00
Vernon Stinebaker
40c41cf3d2
feat(discord): add listen_to_bots config and fix model IDs across codebase (#280)
* fix(config): apply env overrides at runtime and fix Docker compose defaults

- Call apply_env_overrides() after Config::load_or_init() in main.rs so
  environment variables (API_KEY, PROVIDER, ZEROCLAW_GATEWAY_PORT, etc.)
  are actually applied at runtime, not just in tests
- Add ZEROCLAW_ALLOW_PUBLIC_BIND env var support for gateway bind policy
- Fix docker-compose.yml: correct volume path (/zeroclaw-data not /data),
  add ZEROCLAW_ALLOW_PUBLIC_BIND=true for container networking, make host
  port configurable via HOST_PORT env var
- Add docker-compose.override.yml to .gitignore for local dev overrides

* feat(discord): add listen_to_bots config and fix model IDs across codebase

Add listen_to_bots field to DiscordConfig so bot messages are processed
when explicitly enabled (defaults to false for backward compat). Remove
ZEROCLAW_MODEL from Dockerfile release stage so config.toml is the
source of truth for model selection. Fix all hardcoded model IDs from
the dated anthropic/claude-sonnet-4-20250514 to the valid OpenRouter
identifier anthropic/claude-sonnet-4.
2026-02-16 02:13:36 -05:00
Chummy
c481f5298a
fix(channels): process inbound messages concurrently (#267)
Fixes #235
2026-02-16 01:58:01 -05:00
Chummy
b442a07530
fix(memory): prevent autosave key collisions across runtime flows
Fixes #221 - SQLite Memory Override bug.

This PR resolves memory overwrite behavior in autosave paths by replacing fixed memory keys with unique keys, and improves short-horizon recall quality in channel runtime.

**Root Cause**
SQLite memory uses a unique constraint on `memories.key` and writes with `ON CONFLICT(key) DO UPDATE`.
Several autosave paths reused fixed keys (or sender-stable keys), so newer messages overwrote earlier conversation entries.

**Changes**
- Channel runtime: autosave key changed from `channel_sender` to `channel_sender_messageId`
- Added memory-context injection before provider calls (aligned with agent loop behavior)
- Agent loop: autosave keys changed from fixed `user_msg`/`assistant_resp` to UUID-suffixed keys
- Gateway: Webhook/WhatsApp autosave keys changed to UUID-suffixed keys

All CI checks passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:55:52 -05:00
jereanon
2f78c5e1b7 feat(channel): add typing indicator for Discord
Spawns a repeating task that fires the Discord typing endpoint every
8 seconds while the LLM processes a response. Adds start_typing and
stop_typing to the Channel trait with default no-op impls so other
channels can opt in later.
2026-02-15 15:34:10 -07:00
Edvard Schøyen
49bb20f961
fix(providers): use Bearer auth for Gemini CLI OAuth tokens
* fix(providers): use Bearer auth for Gemini CLI OAuth tokens

When credentials come from ~/.gemini/oauth_creds.json (Gemini CLI),
send them as Authorization: Bearer header instead of ?key= query
parameter. API keys from env vars or config continue using ?key=.

Fixes #194

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(gemini): harden OAuth bearer auth flow and tests

* fix(gemini): granular auth source tracking and review fixes

Build on chumyin's auth model refactor with:
- Expand GeminiAuth to 4 variants (ExplicitKey/EnvGeminiKey/EnvGoogleKey/
  OAuthToken) so auth_source() uses stored discriminant without re-reading
  env vars at call time
- Add is_api_key()/credential() helpers on the enum
- Upgrade expired OAuth token log from debug to warn
- Add tests: provider_rejects_empty_key, auth_source_explicit_key,
  auth_source_none_without_credentials

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: apply rustfmt to fix CI lint failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: root <root@instance-20220913-1738.vcn09131738.oraclevcn.com>
Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com>
2026-02-15 14:32:33 -05:00
Edvard Schøyen
e057bf4128
fix: remove unused import and correct WhatsApp/Email registry status
- Remove unused `std::fmt::Write` import in `load_openclaw_bootstrap_files`
  (eliminates compiler warning)
- Update WhatsApp integration status from ComingSoon to config-driven
  (implementation exists in channels/whatsapp.rs)
- Update Email integration status from ComingSoon to config-driven
  (implementation exists in channels/email_channel.rs)
- Update tests to reflect corrected integration statuses

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:28:44 -05:00
Argenis
dca95cac7a
fix: add channel message timeouts, Telegram fallback, and fix identity/observer tests
Closes #184
2026-02-15 12:31:40 -05:00
Argenis
f1e3b1166d
feat: implement AIEOS identity support (#168)
Fixes #168

AIEOS (AI Entity Object Specification) v1.1 is now fully supported.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:46:02 -05:00
Argenis
ced4d70814
feat(channels): wire up email channel (IMAP/SMTP) into config and registration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:58:30 -05:00
Argenis
efe7ae53ce
fix: use UTF-8 safe truncation in bootstrap file preview
Fix panic when displaying workspace files containing multibyte UTF-8 characters by using char_indices().nth() to find safe character boundaries
2026-02-15 10:36:03 -05:00
Argenis
722c99604c
fix(daemon): reset supervisor backoff after successful component run
Reset supervisor backoff after successful component run to prevent excessive delays.

- Reset backoff to initial value when component exits cleanly (Ok(()))
- Move backoff doubling to AFTER sleep so first error uses initial_backoff
- Applied to both channel listener and daemon component supervisors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:16:17 -05:00
Argenis
b208cc940e
feat: add IRC channel support
Add comprehensive IRC over TLS channel implementation with:
- TLS support with optional certificate verification
- SASL PLAIN authentication (IRCv3)
- NickServ IDENTIFY authentication
- Server password support (for bouncers like ZNC)
- Channel and private message (DM) support
- Message splitting for IRC 512-byte line limit
- UTF-8 safe splitting at character boundaries
- Case-insensitive nickname allowlist
- IRC style prefix for LLM responses (plain text only)
- Configurable via TOML or onboard wizard

All 959 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:00:15 -05:00
Argenis
e89415fc9a
chore: add .wt-pr37 Windsurf directory to gitignore
Also removes dead inject_openclaw_identity function and replaces unreachable macros with anyhow bail for cleaner error handling.
2026-02-15 07:44:50 -05:00
argenis de la rosa
9aaa5bfef1 fix: use safe Unicode string truncation to prevent panics (CWE-119)
Fixes Issue #55: Unicode string truncation causes panics with non-ASCII input

Previously, code used byte-index slicing (`&s[..n]`) which panics when the
slice boundary falls in the middle of a multi-byte UTF-8 character (emoji,
CJK, accented characters).

Changes:
- Added `truncate_with_ellipsis()` helper in `src/util.rs` that uses
  `char_indices()` to find safe character boundaries
- Replaced 2 unsafe truncations in `src/channels/mod.rs` with the safe helper
- Added 12 comprehensive tests covering emoji, CJK, accented chars, and edge cases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 06:46:37 -05:00
argenis de la rosa
47c5006de4 Merge remote-tracking branch 'origin/feat/whatsapp-email-channels'
# Conflicts:
#	Cargo.lock
#	src/config/schema.rs
#	src/cron/mod.rs
#	src/security/secrets.rs
#	src/service/mod.rs
2026-02-15 06:37:51 -05:00
Argenis
026a917544
Merge pull request #76 from ecschoye/fix/provider-warmup-cold-start
fix: add provider warmup to prevent cold-start timeout on first channel message
2026-02-14 22:40:51 -05:00
argenis de la rosa
04a35144e8 feat: integrate open-skills library and cleanup clippy warnings
- Add open-skills auto-clone/pull/sync support in skills loader
  - Clone https://github.com/besoeasy/open-skills to ~/open-skills
  - Weekly sync via .zeroclaw-open-skills-sync marker
  - Env controls: ZEROCLAW_OPEN_SKILLS_ENABLED, ZEROCLAW_OPEN_SKILLS_DIR
  - Load open-skills markdown files before workspace skills
  - Track Skill.location for accurate prompt rendering

- Update system prompt to render skill.location with fallback
  - Use actual file path when available
  - Maintain backward compatibility with workspace SKILL.md path

- Fix clippy warnings across tests and supporting files
  - Readable timestamp literals
  - Remove underscore bindings in tests
  - Use struct update syntax for Config::default() patterns
  - Fix module inception, duplicate attributes, manual strip
  - Clean raw string hashes and empty string construction

Resolves: #77
2026-02-14 20:25:07 -05:00
Edvard
cc13fec16d fix: add provider warmup to prevent cold-start timeout on first channel message
The first API request after daemon startup consistently timed out (120s)
when using channels (Telegram, Discord, etc.), requiring a retry before
succeeding. This happened because the reqwest HTTP client's connection
pool was cold — no TLS handshake, DNS resolution, or HTTP/2 negotiation
had occurred yet.

The fix adds a `warmup()` method to the Provider trait that establishes
the connection pool on startup by hitting a lightweight endpoint
(`/api/v1/auth/key` for OpenRouter). The channel server calls this
immediately after creating the provider, before entering the message
processing loop.

Tested on Raspberry Pi 5 (aarch64) with OpenRouter + DeepSeek v3.2 via
Telegram channel. Before: first message took 2-7 minutes (120s timeout +
retries). After: first message responds in <30s with no retries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 18:43:26 -05:00
argenis de la rosa
a310e178db fix: add missing port/host fields to GatewayConfig and apply_env_overrides method
- Add port and host fields to GatewayConfig struct
- Add default_gateway_port() and default_gateway_host() functions
- Add apply_env_overrides() method to Config for env var support
- Fix test to include new GatewayConfig fields

All tests pass.
2026-02-14 16:05:13 -05:00
argenis de la rosa
153d6ff149 fix: resolve clippy warnings and formatting issues for CI
- Fix doc_markdown warnings in WhatsApp channel
- Fix needless_pass_by_value in cron, health, migration, service modules
- Fix match_same_arms in migration.rs
- Fix too_many_lines in skills/mod.rs
- Fix manual_let_else in tools/file_write.rs
- Apply cargo fmt formatting fixes

All 435 tests pass, clippy clean.
2026-02-14 15:36:19 -05:00
argenis de la rosa
d7769340a3 feat: add WhatsApp channel to mod.rs and update Cargo.lock
- Register WhatsApp channel in start_channels()
- Add WhatsApp status display in channel doctor
- Update dependencies after merge
2026-02-14 14:59:22 -05:00
argenis de la rosa
4e6da51924 merge: resolve conflicts between feat/whatsapp-email-channels and main
- Keep main's WhatsApp implementation (webhook-based, simpler)
- Preserve email channel fixes from our branch
- Merge all main branch updates (daemon, cron, health, etc.)
- Resolve Cargo.lock conflicts
2026-02-14 14:59:16 -05:00
argenis de la rosa
3bb5deff37 feat: add Google Gemini provider with CLI token reuse support
- Add src/providers/gemini.rs with support for:
  - Direct API key (GEMINI_API_KEY env var or config)
  - Gemini CLI OAuth token reuse (~/.gemini/oauth_creds.json)
  - GOOGLE_API_KEY environment variable fallback
- Register gemini provider in src/providers/mod.rs with aliases: gemini, google, google-gemini
- Add Gemini to onboarding wizard with:
  - Auto-detection of existing Gemini CLI credentials
  - Model selection (gemini-2.0-flash, gemini-1.5-pro, etc.)
  - API key URL and env var guidance
- Add comprehensive tests for Gemini provider
- Fix pre-existing clippy warnings in email_channel.rs and whatsapp.rs

Closes #XX (Gemini CLI token reuse feature request)
2026-02-14 14:58:19 -05:00
argenis de la rosa
1862c18d10 fix: address PR #37 review issues
- Add missing EmailConfig struct with serde derives and defaults
- Register email_channel module in mod.rs with exports
- Fix IMAP tag reuse (RFC 3501 violation) using incrementing counter
- Fix email sender validation logic (clearer domain vs full email matching)
- Fix mail_parser API usage (MessageParser::default().parse())
- Fix WhatsApp allowlist matching (normalize phone numbers)
- Fix WhatsApp health_check (don't treat 404 as healthy)
- Fix WhatsApp listen() to keep task alive (prevent channel bus closing)
- Add missing dependencies: lettre, mail-parser, rustls-pki-types, tokio-rustls, webpki-roots
- Remove unused imports

All 665 tests pass.
2026-02-14 14:39:43 -05:00
argenis de la rosa
5476195a7f refactor: remove AIEOS identity support
- Remove src/identity/ directory (aieos.rs, mod.rs)
- Remove IdentityConfig struct and identity field from Config
- Remove build_system_prompt_with_identity and load_aieos_from_config functions
- Remove AIEOS-related imports from channels/mod.rs
- Remove identity module declarations from main.rs and lib.rs
- Remove AIEOS tests from config/schema.rs
- Keep OpenClaw markdown-based identity as the only supported format

This simplifies the codebase by removing unused AIEOS complexity.
All 832 tests pass.
2026-02-14 14:05:14 -05:00
argenis de la rosa
ef4444ba43 fix: resolve build errors and add comprehensive symlink tests
- Fixed E0425 error in src/skills/mod.rs by moving println! inside #[cfg(unix)] block where 'dest' variable is in scope
- Added missing 'identity' field to Config struct initializations in src/onboard/wizard.rs
- Fixed import paths for AIEOS identity functions in src/channels/mod.rs
- Added comprehensive symlink edge case tests in src/skills/symlink_tests.rs
- All 840 tests passing, 0 clippy warnings

Resolves issue #28: skills symlink functionality now works correctly on Unix platforms with proper error handling on non-Unix platforms
2026-02-14 13:37:27 -05:00
argenis de la rosa
76074cb789 fix: run Docker container as non-root user (closes #34)
- Switch to gcr.io/distroless/cc-debian12:nonroot
- Add explicit USER 65534:65534 directive
- Add Docker security CI job verifying non-root UID, :nonroot base, and USER directive
- Document CIS Docker Benchmark compliance in SECURITY.md
- Add tests and edge cases for container security
2026-02-14 13:16:33 -05:00
argenis de la rosa
cc08f4bfff feat: Add full WhatsApp Business Cloud API integration
- Add WhatsApp channel module with Cloud API v18.0 support
- Implement webhook-based message reception and API sending
- Add allowlist for phone numbers (E.164 format or wildcard)
- Add WhatsApp webhook endpoints to gateway (/whatsapp GET/POST)
- Add WhatsApp config schema with TOML support
- Wire WhatsApp into channel factory, CLI, and doctor commands
- Add WhatsApp to setup wizard with connection testing
- Add comprehensive test coverage (47 channel tests + 9 URL decoding tests)
- Update README with detailed WhatsApp setup instructions
- Support text messages only, skip media/status updates
- Normalize phone numbers with + prefix
- Handle webhook verification with Meta challenge-response

All 756 tests pass. Ready for production use.
2026-02-14 13:10:16 -05:00
argenis de la rosa
ec2d5cc93d feat: enhance agent personality, tool guidance, and memory hygiene
- Expand communication style presets (professional, expressive, custom)
- Enrich SOUL.md with human-like tone and emoji-awareness guidance
- Add crash recovery and sub-task scoping guidance to AGENTS.md scaffold
- Add 'Use when / Don't use when' guidance to TOOLS.md and runtime prompts
- Implement memory hygiene system with configurable archiving and retention
- Add MemoryConfig options: hygiene_enabled, archive_after_days, purge_after_days, conversation_retention_days
- Archive old daily memory and session files to archive subdirectories
- Purge old archives and prune stale SQLite conversation rows
- Add comprehensive tests for new features
2026-02-14 11:28:39 -05:00
AARTE
cc2f85058e feat: add WhatsApp and Email channel integrations
- WhatsApp Cloud API channel (Meta Business Platform)
  - Webhook verification, text/media messages, rate limiting
  - Phone number allowlist (empty=deny, *=allow, specific numbers)
  - Health check via API

- Email channel (IMAP/SMTP over TLS)
  - IMAP polling for inbound messages
  - SMTP sending with TLS
  - Sender allowlist (email, domain, wildcard)
  - HTML stripping, duplicate detection

Both implement ZeroClaw's Channel trait directly.
Includes inline unit tests.
2026-02-14 16:14:25 +00:00
argenis de la rosa
3d91c40970 refactor: simplify CLI commands and update architecture docs
1. Simplify CLI:
   - Make 'onboard' quick setup default (remove --quick)
   - Add --interactive flag for full wizard
   - Make 'status' detailed by default (remove --verbose)
   - Remove 'tools list/test' and 'integrations list' commands
   - Add 'channel doctor' command
2. Update Docs:
   - Update architecture.svg with Channel allowlists, Browser allowlist, and latest stats
   - Update README.md with new command usage and browser/channel config details
3. Polish:
   - Browser tool integration
   - Channel allowlist logic (empty = deny all)
2026-02-14 05:17:16 -05:00
argenis de la rosa
0e7f501fd6 feat: full-stack search engine — FTS5, vector search, hybrid merge, embedding cache, chunker
The Full Stack (All Custom):
- Vector DB: embeddings stored as BLOB, cosine similarity in pure Rust
- Keyword Search: FTS5 virtual tables with BM25 scoring + auto-sync triggers
- Hybrid Merge: weighted fusion of vector + keyword results (configurable weights)
- Embeddings: provider abstraction (OpenAI, custom URL, noop fallback)
- Chunking: line-based markdown chunker with heading preservation
- Caching: embedding_cache table with LRU eviction
- Safe Reindex: rebuild FTS5 + re-embed missing vectors

New modules:
- src/memory/embeddings.rs — EmbeddingProvider trait + OpenAI + Noop + factory
- src/memory/vector.rs — cosine similarity, vec↔bytes, ScoredResult, hybrid_merge
- src/memory/chunker.rs — markdown-aware document splitting

Upgraded:
- src/memory/sqlite.rs — FTS5 schema, embedding column, hybrid recall, cache, reindex
- src/config/schema.rs — MemoryConfig expanded with embedding/search settings
- All callers updated to pass api_key for embedding provider

739 tests passing, 0 clippy warnings (Rust 1.93.1), cargo-deny clean
2026-02-14 00:00:23 -05:00
argenis de la rosa
bc31e4389b style: cargo fmt — fix all formatting for CI
Ran cargo fmt across entire codebase to pass CI's cargo fmt --check.
No logic changes, only whitespace/formatting.
2026-02-13 16:03:50 -05:00
argenis de la rosa
542bb80743 security: harden architecture against Moltbot security model
- Discord: add allowed_users field + sender validation in listen()
- Slack: add allowed_users field + sender validation in listen()
- Webhook: add X-Webhook-Secret header auth (401 on mismatch)
- SecurityPolicy: add ActionTracker with sliding-window rate limiting
  - record_action() enforces max_actions_per_hour
  - is_rate_limited() checks without recording
- Gateway: print auth status on startup (ENABLED/DISABLED)
- 22 new tests (Discord/Slack allowlists, gateway header extraction,
  rate limiter: starts at zero, records, allows within limit,
  blocks over limit, clone independence)
- 554 tests passing, 0 clippy warnings
2026-02-13 15:31:21 -05:00
argenis de la rosa
05cb353f7f feat: initial release — ZeroClaw v0.1.0
- 22 AI providers (OpenRouter, Anthropic, OpenAI, Mistral, etc.)
- 7 channels (CLI, Telegram, Discord, Slack, iMessage, Matrix, Webhook)
- 5-step onboarding wizard with Project Context personalization
- OpenClaw-aligned system prompt (SOUL.md, IDENTITY.md, USER.md, AGENTS.md, etc.)
- SQLite memory backend with auto-save
- Skills system with on-demand loading
- Security: autonomy levels, command allowlists, cost limits
- 532 tests passing, 0 clippy warnings
2026-02-13 12:19:14 -05:00