Commit graph

641 commits

Author SHA1 Message Date
Will Sarg
6f36dca481
ci: add lint-first PR feedback gate (#556)
* fix(workflows): standardize runner configuration for security jobs

* ci(actionlint): add Blacksmith runner label to config

Add blacksmith-2vcpu-ubuntu-2404 to actionlint self-hosted-runner labels config
to suppress "unknown label" warnings during workflow linting.

This label is used across all workflows after the Blacksmith migration.

* fix(actionlint): adjust indentation for self-hosted runner labels

* feat(security): enhance security workflow with CodeQL analysis steps

* fix(security): update CodeQL action to version 4 for improved analysis

* fix(security): remove duplicate permissions in security workflow

* fix(security): revert CodeQL action to v3 for stability

The v4 version was causing workflow file validation failures.
Reverting to proven v3 version that is working on main branch.

* fix(security): remove duplicate permissions causing workflow validation failure

The permissions block had duplicate security-events and actions keys,
which caused YAML validation errors and prevented workflow execution.

Fixes: workflow file validation failures on main branch

* fix(security): remove pull_request trigger to reduce costs

* fix(security): restore PR trigger but skip codeql on PRs

* fix(security): resolve YAML syntax error in security workflow

* refactor(security): split CodeQL into dedicated scheduled workflow

* fix(security): update workflow name to Rust Package Security Audit

* fix(codeql): remove push trigger, keep schedule and on-demand only

* feat(codeql): add CodeQL configuration file to ignore specific paths

* Potential fix for code scanning alert no. 39: Hard-coded cryptographic value

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix(ci): resolve auto-response workflow merge markers

* fix(build): restore ChannelMessage reply_target usage

* ci(workflows): run workflow sanity on workflow pushes for all branches

* ci(workflows): rename auto-response workflow to PR Auto Responder

* ci(workflows): require owner approval for workflow file changes

* ci: add lint-first PR feedback gate

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-02-17 11:20:08 -05:00
Chummy
62eba544e2 fix(channels): satisfy strict delta lint in Mattermost reply routing 2026-02-18 00:19:20 +08:00
Chummy
318e0fa9a7 fix(core): align CLI channel send call with SendMessage 2026-02-18 00:19:20 +08:00
Vernon Stinebaker
7e3f5ff497 feat(channels): add Mattermost integration for sovereign communication 2026-02-18 00:19:20 +08:00
Chummy
0aa35eb669 fix(build): complete strict lint and test cleanup (replacement for #476) 2026-02-18 00:18:54 +08:00
Chummy
fc6e8eb521
fix(provider): follow-up CN/global consistency for Z.AI and aliases (#554)
* fix(provider): harden CN/global routing consistency for Chinese vendors

* fix(agent): migrate CLI channel send to SendMessage

* fix(onboard): deduplicate Z.AI key URL match arms
2026-02-18 00:04:56 +08:00
Chummy
cd0dd13476 fix(channels): complete SendMessage migration after rebase 2026-02-17 23:28:08 +08:00
Kieran
dbebd48dfe refactor(channel): accept SendMessage struct in Channel::send()
Refactor the Channel trait to accept a SendMessage struct instead of
separate message and recipient string parameters. This enables passing
additional metadata like email subjects.

Changes:
- Add SendMessage struct with content, recipient, and optional subject
- Update Channel::send() signature to accept &SendMessage
- Update all 12 channel implementations
- Update call sites in channels/mod.rs and gateway/mod.rs

Subject field usage:
- Email: uses subject for email subject line
- DingTalk: uses subject as markdown message title
- All others: ignore subject (no native platform support)
2026-02-17 23:28:08 +08:00
Chummy
b8ed42edbb fix(channels,memory): normalize Discord mentions and repair lucid test args 2026-02-17 23:26:53 +08:00
Will Sarg
500e6bd0ec
chore: merge devsecops into main (#546)
* fix(workflows): standardize runner configuration for security jobs

* ci(actionlint): add Blacksmith runner label to config

Add blacksmith-2vcpu-ubuntu-2404 to actionlint self-hosted-runner labels config
to suppress "unknown label" warnings during workflow linting.

This label is used across all workflows after the Blacksmith migration.

* fix(actionlint): adjust indentation for self-hosted runner labels

* feat(security): enhance security workflow with CodeQL analysis steps

* fix(security): update CodeQL action to version 4 for improved analysis

* fix(security): remove duplicate permissions in security workflow

* fix(security): revert CodeQL action to v3 for stability

The v4 version was causing workflow file validation failures.
Reverting to proven v3 version that is working on main branch.

* fix(security): remove duplicate permissions causing workflow validation failure

The permissions block had duplicate security-events and actions keys,
which caused YAML validation errors and prevented workflow execution.

Fixes: workflow file validation failures on main branch

* fix(security): remove pull_request trigger to reduce costs

* fix(security): restore PR trigger but skip codeql on PRs

* fix(security): resolve YAML syntax error in security workflow

* refactor(security): split CodeQL into dedicated scheduled workflow

* fix(security): update workflow name to Rust Package Security Audit

* fix(codeql): remove push trigger, keep schedule and on-demand only

* feat(codeql): add CodeQL configuration file to ignore specific paths

* Potential fix for code scanning alert no. 39: Hard-coded cryptographic value

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix(ci): resolve auto-response workflow merge markers

* fix(build): restore ChannelMessage reply_target usage

* ci(workflows): run workflow sanity on workflow pushes for all branches

* ci(workflows): rename auto-response workflow to PR Auto Responder

* ci(workflows): require owner approval for workflow file changes

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-02-17 10:10:14 -05:00
Chummy
bb641d28c2 fix(approval): harden CLI approval flow and summaries 2026-02-17 23:06:12 +08:00
stawky
ab561baa97 feat(approval): interactive approval workflow for supervised mode (#215)
- Add auto_approve / always_ask fields to AutonomyConfig
- New src/approval/ module: ApprovalManager with session-scoped allowlist,
  ApprovalRequest/Response types, audit logging, CLI interactive prompt
- Insert approval hook in agent_turn before tool execution
- Non-CLI channels auto-approve; CLI shows Y/N/A prompt
- Skip approval for read-only tools (file_read, memory_recall) by default
- 15 unit tests covering all approval logic
2026-02-17 23:06:12 +08:00
Chummy
f489971889 style(channels): align module ordering in channels mod 2026-02-17 22:55:21 +08:00
Chummy
94ec351d73 fix(channels): set qq reply_target for strict delta lint 2026-02-17 22:55:21 +08:00
Chummy
14d93c075e fix(channels): tighten qq listener lifecycle and english labels 2026-02-17 22:55:21 +08:00
elonf
ed71bce447 feat(channels): add QQ Official channel via Tencent Bot SDK
Implement QQ Official messaging channel using OAuth2 authentication
with Discord-like WebSocket gateway protocol for events.

- Add QQChannel with send/listen/health_check support
- Add QQConfig (app_id, app_secret, allowed_users)
- OAuth2 token refresh and WebSocket heartbeat management
- Message deduplication with capacity-based eviction
- Support both C2C (private) and group AT messages
- Integrate with onboard wizard, integrations registry, and channel
  list/doctor commands
- Include unit tests for user allowlist, deduplication, and config
2026-02-17 22:55:21 +08:00
Chummy
d94d7baa14 feat(ollama): unify local and remote endpoint routing
Integrate cloud endpoint behavior into existing ollama provider flow, avoid a separate standalone doc, and keep configuration minimal via api_url/api_key.

Also align reply_target and memory trait call sites needed for current baseline compatibility.
2026-02-17 22:52:09 +08:00
Chummy
85de9b5625
fix(provider): split CN/global endpoints for Chinese provider variants (#542)
* fix(providers): add CN/global endpoint variants for Chinese vendors

* fix(onboard): deduplicate provider key-url match arms

* chore(i18n): normalize non-English literals to English
2026-02-17 22:51:51 +08:00
leon
93d9d0de06 docs(telegram): document bind flow and polling conflict guidance 2026-02-17 22:48:40 +08:00
leon
62eadec274 fix(telegram): surface getUpdates API conflicts in logs 2026-02-17 22:48:40 +08:00
leon
c59dea3755 fix(channels): auto-reload managed daemon after telegram bind 2026-02-17 22:48:40 +08:00
leon
fa94117269 feat(telegram): add operator bind command for unauthorized users 2026-02-17 22:48:40 +08:00
leon
bfc67c9c29 feat(telegram): add bind-code pairing and fix reply routing 2026-02-17 22:48:40 +08:00
Chummy
b2690f6809 feat(provider): add native tool calling API (supersedes #450)
Co-authored-by: YubinghanBai <baiyubinghan@gmail.com>
2026-02-17 22:47:10 +08:00
Chummy
767c66f3c8 fix(channel/signal): harden target routing and SSE stability 2026-02-17 22:35:33 +08:00
bhagwan
55f2637cfe feat(channel): add Signal channel via signal-cli JSON-RPC daemon
Adds a new Signal messaging channel that connects to a running
signal-cli daemon's native HTTP API (JSON-RPC + SSE).

  [channels_config.signal]
  http_url = "http://127.0.0.1:8686"
  account = "+1234567890"
  group_id = "group_id"  # optional, omit for all
  allowed_from = ["+1111111111"]
  ignore_attachments = true
  ignore_stories = true

Implementation:
- SSE listener at /api/v1/events for incoming messages
- JSON-RPC sends via /api/v1/rpc (method: send)
- Health check via /api/v1/check
- Typing indicators via sendTyping RPC
- Supports DMs and group messages (room_id filtering)
- Allowlist-based sender filtering (E.164 or wildcard)
- Optional attachment/story filtering
- Fixed has_supervised_channels() to include signal + irc/lark/dingtalk

Registered in channel list, doctor, start, integrations registry, and
daemon supervisor gate. Includes unit tests for config serde, sender
filtering, room matching, envelope processing, and deserialization.

No new dependencies (uses existing uuid, futures-util, reqwest).
2026-02-17 22:35:33 +08:00
Will Sarg
acfdc34be2
Merge pull request #535 from zeroclaw-labs/pr-484-clean
fix: Discord channel replies and parking_lot::Mutex migration
2026-02-17 09:29:28 -05:00
Will Sarg
a62c7a5893 fix(clippy): satisfy strict delta lints in SSE streaming path 2026-02-17 09:26:21 -05:00
Will Sarg
98d06cba6b perf(docker): align builder toolchain with rust-toolchain and persist artifact 2026-02-17 09:23:01 -05:00
Will Sarg
b8bef379e2 fix(channels): reply via reply_target and improve local Docker cache reuse 2026-02-17 09:22:01 -05:00
Will Sarg
9e0958dee5 fix(ci): repair parking_lot migration regressions in PR #535 2026-02-17 09:10:40 -05:00
Will Sarg
ee05d62ce4
Merge branch 'main' into pr-484-clean 2026-02-17 08:54:24 -05:00
Chummy
01c419bb57 test(providers): keep unicode boundary test in English text 2026-02-17 21:51:58 +08:00
Khoi Tran
3c62b59a72 fix(copilot): add proper OAuth device-flow authentication
The existing Copilot provider passes a static Bearer token, but the
Copilot API requires short-lived session tokens obtained via GitHub's
OAuth device code flow, plus mandatory editor headers.

This replaces the stub with a dedicated CopilotProvider that:

- Runs the OAuth device code flow on first use (same client ID as VS Code)
- Exchanges the OAuth token for a Copilot API key via
  api.github.com/copilot_internal/v2/token
- Sends required Editor-Version/Editor-Plugin-Version headers
- Caches tokens to disk (~/.config/zeroclaw/copilot/) with auto-refresh
- Uses Mutex to prevent concurrent refresh races / duplicate device prompts
- Writes token files with 0600 permissions (owner-only)
- Respects GitHub's polling interval and code expiry from device flow
- Sanitizes error messages to prevent token leakage
- Uses async filesystem I/O (tokio::fs) throughout
- Optionally accepts a pre-supplied GitHub token via config api_key

Fixes: 403 'Access to this endpoint is forbidden'
Fixes: 400 'missing Editor-Version header for IDE auth'
2026-02-17 21:51:58 +08:00
Will Sarg
a2f29838b4
fix(build): restore ChannelMessage reply_target usage (#541) 2026-02-17 08:41:02 -05:00
Will Sarg
7ebc98d8d0
fix(ci): sync devsecops with main and repair auto-response workflow (#538)
* fix(workflows): standardize runner configuration for security jobs

* ci(actionlint): add Blacksmith runner label to config

Add blacksmith-2vcpu-ubuntu-2404 to actionlint self-hosted-runner labels config
to suppress "unknown label" warnings during workflow linting.

This label is used across all workflows after the Blacksmith migration.

* fix(actionlint): adjust indentation for self-hosted runner labels

* feat(security): enhance security workflow with CodeQL analysis steps

* fix(security): update CodeQL action to version 4 for improved analysis

* fix(security): remove duplicate permissions in security workflow

* fix(security): revert CodeQL action to v3 for stability

The v4 version was causing workflow file validation failures.
Reverting to proven v3 version that is working on main branch.

* fix(security): remove duplicate permissions causing workflow validation failure

The permissions block had duplicate security-events and actions keys,
which caused YAML validation errors and prevented workflow execution.

Fixes: workflow file validation failures on main branch

* fix(security): remove pull_request trigger to reduce costs

* fix(security): restore PR trigger but skip codeql on PRs

* fix(security): resolve YAML syntax error in security workflow

* refactor(security): split CodeQL into dedicated scheduled workflow

* fix(security): update workflow name to Rust Package Security Audit

* fix(codeql): remove push trigger, keep schedule and on-demand only

* feat(codeql): add CodeQL configuration file to ignore specific paths

* Potential fix for code scanning alert no. 39: Hard-coded cryptographic value

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix(ci): resolve auto-response workflow merge markers

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-02-17 08:34:09 -05:00
Chummy
a35d1e37c8
chore(labeler): normalize module labels and backfill contributor tiers (#462)
Co-authored-by: Will Sarg <12886992+willsarg@users.noreply.github.com>
2026-02-17 08:25:50 -05:00
Vernon Stinebaker
df31359ec4
feat(agent): scrub credentials from tool output (#532)
* feat(channels): add channel capabilities to system prompt

Add channel capabilities section to system prompt so the agent knows
it can send Discord messages directly without asking permission.
Also reminds agent not to repeat or echo credentials.

Co-authored-by: Vernon Stinebaker <vernon.stinebaker@gmail.com>

* feat(agent): scrub credentials from tool output

* chore: fix clippy and formatting for scrubbing
2026-02-17 08:23:11 -05:00
beee003
8ad5b6146b
feat: add Astrai as a named provider (#486)
Add Astrai (https://as-trai.com) as a first-class OpenAI-compatible
provider. Astrai is an AI inference router with built-in cost
optimization, PII stripping, and compliance logging.

- Register ASTRAI_API_KEY env var in resolve_api_key
- Add "astrai" entry in provider factory → as-trai.com/v1
- Add factory_astrai unit test
- Add Astrai to compatible provider test list
- Update README provider count (22+ → 23+) and list

Co-authored-by: Maya Walcher <maya.walcher@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:22:38 -05:00
ehu shubham shaw
d7c1fd7bf8
security(deps): remove vulnerable xmas-elf dependency via embuild (#414)
* security(deps): remove vulnerable xmas-elf dependency via embuild

* chore(deps): update dependencies and improve ESP-IDF compatibility

- Updated `bindgen`, `embassy-sync`, `embedded-svc`, and `embuild` versions in `Cargo.lock`.
- Added patch section in `Cargo.toml` to use latest esp-rs crates for better compatibility with ESP-IDF 5.x.
- Enhanced README with updated prerequisites and build instructions for Python and Rust tools.
- Introduced `rust-toolchain.toml` to pin nightly Rust and added necessary components.
- Modified GPIO handling in `main.rs` to improve pin management and added support for 64-bit time_t in ESP-IDF.
- Updated `.cargo/config.toml` for new linker and runner configurations.

* docs: add detailed setup guide for ESP32 firmware and link in README

- Introduced a new `SETUP.md` file with comprehensive step-by-step instructions for building and flashing the ZeroClaw ESP32 firmware.
- Updated `README.md` to include a link to the new setup guide for easier access to installation and troubleshooting information.

* chore: update .gitignore and refactor main.rs for improved readability

- Added .embuild/ to .gitignore to exclude ESP32 build cache.
- Refactored code in main.rs for better readability by adjusting the formatting of the handle_request function call.

* docs: add newline for better readability in README.md

- Added a newline in the protocol section of README.md to enhance clarity and formatting.

* chore: configure workspace settings in Cargo.toml

- Added workspace configuration to `Cargo.toml` with members and resolver settings for improved project management.

---------

Co-authored-by: ehushubhamshaw <eshaw1@wpi.edu>
Co-authored-by: Will Sarg <12886992+willsarg@users.noreply.github.com>
2026-02-17 08:18:41 -05:00
fettpl
55b3c2c00c
test(security): add HTTP hostname canonicalization edge-case tests (#522)
* test(security): add HTTP hostname canonicalization edge-case tests

Document that Rust's IpAddr::parse() rejects non-standard IP notations
(octal, hex, decimal integer, zero-padded) which provides defense-in-depth
against SSRF bypass attempts. Tests only — no production code changes.

Closes #515

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>
2026-02-17 08:16:00 -05:00
fettpl
e3f00e82b9
fix(ci): add pull-requests write permission to contributor-tier-issues job (#501)
The contributor-tier-issues job triggers on pull_request_target events
but only had issues:write permission. GitHub API requires
pull-requests:write to set labels on pull requests, causing a 403
"Resource not accessible by integration" error.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:14:41 -05:00
Rin
9ec1106f53
security: fix argument injection in shell command validation (#465) 2026-02-17 08:11:20 -05:00
Alex Gorevski
529a3d0242
fix(cli): respect config gateway.port and gateway.host for Gateway/Daemon commands (#456)
The CLI --port and --host args had hardcoded defaults (8080, 127.0.0.1)
that always overrode the user's config.toml [gateway] settings (port=3000,
host=127.0.0.1). Changed both args to Option types and fall back to
config.gateway.port / config.gateway.host when not explicitly provided.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-17 08:10:32 -05:00
Lawyered
02711b315b
fix(git-ops): avoid panic truncating unicode commit messages (#401)
* fix(git-ops): avoid panic truncating unicode commit messages

* chore: satisfy rustfmt in git_operations test module

---------

Co-authored-by: Clawyered <clawyered@macbookair.home>
2026-02-17 08:08:57 -05:00
Argenis
b09e77c8c9
chore: change license from Apache-2.0 to MIT (#534)
Changed the project license from Apache-2.0 to MIT for maximum
permissiveness and openness.

Changes:
- Cargo.toml: Updated license field from "Apache-2.0" to "MIT"
- LICENSE: Replaced Apache-2.0 text with MIT license text
- README.md: Updated license badge and section from Apache 2.0 to MIT

MIT is a simpler, more permissive license that allows for maximum
flexibility while still requiring attribution and disclaiming warranty.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:08:15 -05:00
Chummy
ae37e59423
fix(channels): resolve telegram reply target and media delivery (#525)
Co-authored-by: Will Sarg <12886992+willsarg@users.noreply.github.com>
2026-02-17 08:07:23 -05:00
argenis de la rosa
1908af3248 fix(discord): use channel_id instead of sender for replies (fixes #483)
fix(misc): complete parking_lot::Mutex migration (fixes #505)

- DiscordChannel: store actual channel_id in ChannelMessage.channel
  instead of hardcoded "discord" string
- channels/mod.rs: use msg.channel instead of msg.sender for replies
- Migrate all std::sync::Mutex to parking_lot::Mutex:
  * src/security/audit.rs
  * src/memory/sqlite.rs
  * src/memory/response_cache.rs
  * src/memory/lucid.rs
  * src/channels/email_channel.rs
  * src/gateway/mod.rs
  * src/observability/traits.rs
  * src/providers/reliable.rs
  * src/providers/router.rs
  * src/agent/agent.rs
- Remove all .lock().unwrap() and .map_err(PoisonError) patterns
  since parking_lot::Mutex never poisons

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:05:25 -05:00
Vernon Stinebaker
efa6e5aa4a
feat(channel): add capabilities to system prompt (#531)
* feat(channels): add channel capabilities to system prompt

Add channel capabilities section to system prompt so the agent knows
it can send Discord messages directly without asking permission.
Also reminds agent not to repeat or echo credentials.

Co-authored-by: Vernon Stinebaker <vernon.stinebaker@gmail.com>

* chore: fix formatting and clippy warnings
2026-02-17 08:02:11 -05:00
Vernon Stinebaker
5b5d9fe77f
feat(discord): add mention_only config for @-mention trigger (#529)
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>
2026-02-17 08:01:27 -05:00