Add `capabilities()` method to HookHandler trait so the runner can check
whether a hook has ModifyToolResults permission before allowing it to
mutate tool results. Without this, any registered hook could flip success,
rewrite output, or suppress errors with no gate.
The generic `API_KEY` environment variable unconditionally overwrote the
api_key loaded from config.toml, even when a valid key was already
configured. Since `API_KEY` is a very common env var name set by many
unrelated tools, this caused silent auth failures when the unrelated
value was sent to the configured provider.
Change the precedence so that `ZEROCLAW_API_KEY` always wins (explicit
intent), while `API_KEY` is only used as a fallback when the config has
no api_key set.
- Switch from sessionWebhook to /v1.0/robot/oToMessages/batchSend API
- Add access_token caching with automatic refresh (60s buffer)
- Enable cron job delivery to DingTalk (no user interaction required)
This change allows DingTalk to actively send messages (e.g., cron
reminders) without requiring the user to send a message first.
Add SkillToolHandler that converts SKILL.toml definitions into native
tool schemas, enabling skills to be invoked as standard tools through
the agent's tool-use protocol.
Made-with: Cursor
- Replace brittle split("state=") with parse_query_params utility
- Use const PROFILE_MISMATCH_PREFIX with starts_with instead of fragile contains
Made-with: Cursor
Add stale pending login detection (auto-cleanup after 24h), improved
device-code flow error messages with Cloudflare/403 detection, shared
OAuth helpers, and Box::pin fixes for large async futures.
Made-with: Cursor
Add `hooks: Option<&crate::hooks::HookRunner>` as the last parameter
to the public `agent::run()` (re-exported from `loop_::run`).
This enables library consumers to inject custom HookHandler
implementations (before_tool_call, on_after_tool_call) without
patching the crate. The hooks are threaded through to
`run_tool_call_loop` which already accepts and dispatches them.
All existing call sites pass `None`, preserving backward compatibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two root causes were addressed:
1. `wasm-tools` (wasmtime 28 + cranelift JIT) was listed in `default`
features. wasmtime's JIT backend has macOS version dependencies that
break builds and/or runtime on Catalina. The feature is now opt-in;
the default build is free of JIT dependencies and Catalina-safe.
Users on macOS 11+ can still enable it with `--features wasm-tools`.
2. `.cargo/config.toml` had no macOS target entries, so the binary's
minimum deployment version was left to toolchain defaults (which can
be set to macOS 11+ on newer hosts). Added explicit
`-mmacosx-version-min=10.15` for `x86_64-apple-darwin` and
`-mmacosx-version-min=11.0` for `aarch64-apple-darwin` (no Catalina
hardware exists for Apple Silicon).
Also added a "macOS Catalina (10.15) Compatibility" section to
`docs/troubleshooting.md` covering symptoms, root causes, and fixes.
https://claude.ai/code/session_01L2arD1QmRH1cRejbCmhyRf