When mention_only is true, the bot only responds to messages that
@-mention the bot. Other messages in the guild are silently ignored.
Also strips the bot mention from content before processing.
Co-authored-by: Will Sarg <12886992+willsarg@users.noreply.github.com>
* fix(security): enhance shell redirection blocking in security policy
Block process substitution (<(...) and >(...)) and tee command in
is_command_allowed() to close shell escape vectors that bypass existing
redirect and subshell checks.
Closes#514
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: apply rustfmt to providers/mod.rs
Fix pre-existing formatting issue from main.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(security): expand git argument sanitization
Expand sanitize_git_args() blocklist to also reject --pager=, --editor=,
-c (config injection), --no-verify, and > in arguments. Apply validation
to git_add() paths and git_diff() files argument (previously only called
from git_checkout()). The -c check uses exact match to avoid
false-positives on --cached.
Closes#516
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: apply rustfmt to providers/mod.rs
Fix pre-existing formatting issue from main.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Pin ubuntu:22.04 to its current manifest digest to ensure
reproducible builds and prevent supply-chain mutations.
Closes#513
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Replace floating tag refs (@v1, @v2) with SHA-pinned refs to prevent
supply-chain attacks via tag mutation on third-party Actions.
Pinned:
- useblacksmith/setup-docker-builder@v1 → ef12d5b1
- useblacksmith/build-push-action@v2 → 30c71162
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(security): add config file permission hardening
Set 0o600 permissions on newly created config.toml files and warn if
an existing config file is world-readable. Prevents accidental exposure
of API keys on multi-user systems. Unix-only (#[cfg(unix)]).
Follows existing pattern from src/security/secrets.rs.
Closes#517
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: apply rustfmt formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(memory): add session_id isolation to Memory trait
Add optional session_id parameter to store(), recall(), and list()
methods across the Memory trait and all four backends (sqlite, markdown,
lucid, none). This enables per-session memory isolation so different
agent sessions cannot cross-read each other's stored memories.
Changes:
- traits.rs: Add session_id: Option<&str> to store/recall/list
- sqlite.rs: Schema migration (ALTER TABLE ADD COLUMN session_id),
index, persist/filter by session_id in all query paths
- markdown.rs, lucid.rs, none.rs: Updated signatures
- All callers pass None for backward compatibility
- 5 new tests: session-filtered recall, cross-session isolation,
session-filtered list, no-filter returns all, migration idempotency
Closes#518
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(channels): fix discord _channel_id typo and lark missing reply_to
Pre-existing compilation errors on main after reply_to was added to
ChannelMessage: discord.rs used _channel_id (underscore prefix) but
referenced channel_id, and lark.rs was missing the reply_to field.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add `lmstudio` / `lm-studio` as a built-in provider alias for local LM Studio instances
(`http://localhost:1234/v1`)
- Uses a dummy API key when none is provided, since LM Studio does not require authentication
- Users can connect to remote LM Studio instances via `custom:http://<ip>:1234/v1`
ChannelMessage.sender was used both for display (username) and as the
reply target in Channel::send(). For Telegram, sender is the username
(e.g. "unknown") while send() requires the numeric chat_id, causing
"Bad Request: chat not found" errors.
Add a dedicated reply_to field to ChannelMessage that stores the
channel-specific reply address (Telegram chat_id, Discord channel_id,
Slack channel, etc.). Update all channel implementations and dispatch
code to use reply_to for send/start_typing/stop_typing calls.
This also fixes the same latent bug in Discord and Slack channels where
sender (user ID) was incorrectly passed as the reply target.
`cargo install` places the binary in ~/.cargo/bin, which may not be in
the user's PATH by default. This adds an explicit export step so new
users don't hit a "not found" error after install.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ProviderCapabilities struct to enable runtime detection of
provider-specific features, starting with native tool calling support.
This is a foundational change that enables future PRs to implement
intelligent tool calling mode selection (native vs prompt-guided).
Changes:
- Add ProviderCapabilities struct with native_tool_calling field
- Add capabilities() method to Provider trait with default impl
- Add unit tests for capabilities equality and defaults
Why:
- Current design cannot distinguish providers with native tool calling
- Needed to enable Gemini/Anthropic/OpenAI native function calling
- Fully backward compatible (all providers inherit default)
What did NOT change:
- No existing Provider methods modified
- No behavior changes for existing code
- Zero breaking changes
Testing:
- cargo test: all tests passed
- cargo fmt: pass
- cargo clippy: pass
Replace bare .body() call with .singlepart(SinglePart::plain()) to ensure
outgoing emails have explicit Content-Type: text/plain; charset=utf-8
header. This fixes recipients seeing raw quoted-printable encoding
(e.g., =E2=80=99) instead of properly decoded UTF-8 characters.
- Move ZEROCLAW_WORKSPACE check to the start of load_or_init()
- Use custom workspace for both config and workspace directories
- Fixes issue where env var was applied AFTER config loading
Fixes#417
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>