Compare commits

...

162 Commits

Author SHA1 Message Date
argenis de la rosa d41715b95e merge: resolve conflict with master in release workflow
Accept master's version of release-beta-on-push.yml which uses
pre-built binary artifacts instead of QEMU-based compilation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 10:11:48 -04:00
argenis de la rosa b571cf4c81 feat(heartbeat): add structured task prompt, delivery formatting, and comprehensive edge-case tests
Replace the flat heartbeat prompt with a structured, non-conversational
prompt (build_task_prompt) that instructs tool usage and structured output.
Add format_delivery_output to prepend headers, handle empty output, and
truncate for channel safety. Wire allowed_tools config into the agent call.

Add ~85 edge-case tests across engine, store, and daemon covering malformed
metadata parsing, decision response parsing, metrics edge cases, adaptive
interval boundaries, store truncation/ordering, and delivery resolution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 09:29:40 -04:00
Alix-007 3cf873ab85 fix(groq): fall back on tool validation 400s (#3778)
Co-authored-by: Alix-007 <267018309+Alix-007@users.noreply.github.com>
Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-17 09:23:39 -04:00
Argenis 025724913d feat(runtime): add configurable reasoning effort (#3785)
* feat(runtime): add configurable reasoning effort

* fix(test): add missing reasoning_effort field in live test

Add reasoning_effort: None to ProviderRuntimeOptions construction in
openai_codex_vision_e2e.rs to fix E0063 compile error.

---------

Co-authored-by: Alix-007 <267018309+Alix-007@users.noreply.github.com>
2026-03-17 09:21:53 -04:00
project516 49dd4cd9da Change AppImage to tar.gz in arduino-uno-q-setup.md (#3754)
Arduino App Lab is a tar.gz file for Linux, not an AppImage

Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-17 09:19:38 -04:00
dependabot[bot] 0664a5e854 chore(deps): bump rust from 7d37016 to da9dab7 (#3776)
Bumps rust from `7d37016` to `da9dab7`.

---
updated-dependencies:
- dependency-name: rust
  dependency-version: 1.94-slim
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-17 09:16:21 -04:00
argenis de la rosa 22c271e21d fix(ci): skip Rust compilation in Docker by reusing matrix build artifacts
The multi-platform Docker build (linux/amd64 + linux/arm64) was compiling
Rust from source inside QEMU, taking 60+ minutes and frequently getting
cancelled. The matrix build job already produces native binaries for both
architectures — this change makes the Docker job use those pre-built
binaries instead.

Adds ARG PREBUILT_BINARY gating to Dockerfile and Dockerfile.debian so
CI skips cargo build and copies from a named build context, while local
docker build remains unchanged. Timeout reduced from 60 to 15 minutes.
2026-03-17 09:09:54 -04:00
Argenis acd09fbd86 feat(ci): use pre-built binaries for Docker images (#3784)
Instead of compiling Rust from source inside Docker (~60 min),
download the already-built linux binaries from the build matrix
and copy them into a minimal distroless image (~2 min).

- Add Dockerfile.ci for release workflows (no Rust toolchain needed)
- Update both beta and stable workflows to use pre-built artifacts
- Drop Docker job timeout from 60 to 15 minutes
- Original Dockerfile unchanged for local dev builds
2026-03-17 09:03:13 -04:00
Alix-007 0f7d1fceeb fix(channels): hide tool-call notifications by default (#3779)
Co-authored-by: Alix-007 <267018309+Alix-007@users.noreply.github.com>
Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-17 08:52:49 -04:00
GhostC 01e13ac92d fix(skills): allow sibling markdown links within skills root (#3781)
Made-with: Cursor
2026-03-17 08:31:20 -04:00
Argenis a9a6113093 fix(docs): revert unauthorized CLAUDE.md additions from #3604 (#3761)
PR #3604 included CLAUDE.md changes referencing non-existent modules
(src/security/taint.rs, src/sop/workflow.rs) and duplicating content
from CONTRIBUTING.md. These additions violate the anti-pattern rule
against modifying CLAUDE.md in feature PRs.
2026-03-17 01:56:51 -04:00
Giulio V 906951a587 feat(multi): LinkedIn tool, WhatsApp voice notes, and Anthropic OAuth fix (#3604)
* feat(tools): add native LinkedIn integration tool

Add a config-gated LinkedIn tool that enables ZeroClaw to interact with
LinkedIn's REST API via OAuth2. Supports creating posts, listing own
posts, commenting, reacting, deleting posts, viewing engagement stats,
and retrieving profile info.

Architecture:
- linkedin.rs: Tool trait impl with action-dispatched design
- linkedin_client.rs: OAuth2 token management and API wrappers
- Config-gated via [linkedin] enabled = false (default off)
- Credentials loaded from workspace .env file
- Automatic token refresh with line-targeted .env update

39 unit tests covering security enforcement, parameter validation,
credential parsing, and token management.

* feat(linkedin): configurable content strategy and API version

- Expand LinkedInConfig with api_version and nested LinkedInContentConfig
  (rss_feeds, github_users, github_repos, topics, persona, instructions)
- Add get_content_strategy tool action so agents can read config at runtime
- Fix hardcoded LinkedIn API version 202402 (expired) → configurable,
  defaulting to 202602
- LinkedInClient accepts api_version as parameter instead of static header
- 4 new tests (43 total), all passing

* feat(linkedin): add multi-provider image generation for posts

Add ImageGenerator with provider chain (DALL-E, Stability AI, Imagen, Flux)
and SVG fallback card. LinkedIn tool create_post now supports generate_image
parameter. Includes LinkedIn image upload (register → upload → reference),
configurable provider priority, and 14 new tests.

* feat(whatsapp): add voice note transcription and TTS voice replies

- Add STT support: download incoming voice notes via wa-rs, transcribe
  with OpenAI Whisper (or Groq), send transcribed text to agent
- Add TTS support: synthesize agent replies to Opus audio via OpenAI
  TTS, upload encrypted media, send as WhatsApp voice note (ptt=true)
- Voice replies only trigger when user sends a voice note; text
  messages get text replies only. Flag is consumed after one use to
  prevent multiple voice notes per agent turn
- Fix transcription module to support OpenAI API key (not just Groq):
  auto-detect provider from API URL, check ANTHROPIC_OAUTH_TOKEN /
  OPENAI_API_KEY / GROQ_API_KEY env vars in priority order
- Add optional api_key field to TranscriptionConfig for explicit key
- Add response_format: opus to OpenAI TTS for WhatsApp compatibility
- Add channel capability note so agent knows TTS is automatic
- Wire transcription + TTS config into WhatsApp Web channel builder

* fix(providers): prefer ANTHROPIC_OAUTH_TOKEN over global api_key

When the Anthropic provider is used alongside a non-Anthropic primary
provider (e.g. custom: gateway), the global api_key would be passed
as credential override, bypassing provider-specific env vars. This
caused Claude Code subscription tokens (sk-ant-oat01-*) to be ignored
in favor of the unrelated gateway JWT.

Fix: for the anthropic provider, check ANTHROPIC_OAUTH_TOKEN and
ANTHROPIC_API_KEY env vars before falling back to the credential
override. This mirrors the existing MiniMax OAuth pattern and enables
subscription-based auth to work as a fallback provider.

* feat(linkedin): add scheduled post support via LinkedIn API

Add scheduled_at parameter to create_post and create_post_with_image.
When provided (RFC 3339 timestamp), the post is created as a DRAFT
with scheduledPublishOptions so LinkedIn publishes it automatically
at the specified time. This enables the cron job to schedule a week
of posts in advance directly on LinkedIn.

* fix(providers): prefer env vars for openai and groq credential resolution

Generalize the Anthropic OAuth fix to also cover openai and groq
providers. When used alongside a non-matching primary provider (e.g.
a custom: gateway), the global api_key would be passed as credential
override, causing auth failures. Now checks provider-specific env
vars (OPENAI_API_KEY, GROQ_API_KEY) before falling back to the
credential override.

* fix(whatsapp): debounce voice replies to voice final answer only

The voice note TTS was triggering on the first send() call, which was
often intermediate tool output (URLs, JSON, web fetch results) rather
than the actual answer. This produced incomprehensible voice notes.

Fix: accumulate substantive replies (>30 chars, not URLs/JSON/code)
in a pending_voice map. A spawned debounce task waits 4 seconds after
the last substantive message, then synthesizes and sends ONE voice
note with the final answer. Intermediate tool outputs are skipped.

This ensures the user hears the actual answer in the correct language,
not raw tool output in English.

* fix(whatsapp): voice in = voice out, text in = text out

Rewrite voice reply logic with clean separation:
- Voice note received: ALL text output suppressed. Latest message
  accumulated silently. After 5s of no new messages, ONE voice note
  sent with the final answer. No tool outputs, no text, just voice.
- Text received: normal text reply, no voice.

Atomic debounce: multiple spawned tasks race but only one can extract
the pending message (remove-inside-lock pattern). Prevents duplicate
voice notes.

* fix(whatsapp): voice replies send both text and voice note

Voice note in → text replies sent normally in real-time PLUS one
voice note with the final answer after 10s debounce. Only substantive
natural-language messages are voiced (tool outputs, URLs, JSON, code
blocks filtered out). Longer debounce (10s) ensures the agent
completes its full tool chain before the voice note fires.

Text in → text out only, no voice.

* fix(channels): suppress tool narration and ack reactions

- Add system prompt instruction telling the agent to NEVER narrate
  tool usage (no "Let me fetch..." or "I will use http_request...")
- Disable ack_reactions (emoji reactions on incoming messages)
- Users see only the final answer, no intermediate steps

* docs(claude): add full CONTRIBUTING.md guidelines to CLAUDE.md

Add PR template requirements, code naming conventions, architecture
boundary rules, validation commands, and branch naming guidance
directly to CLAUDE.md for AI assistant reference.

* fix(docs): add blank lines around headings in CLAUDE.md for markdown lint

* fix(channels): strengthen tool narration suppression and fix large_futures

- Move anti-narration instruction to top of channel system prompt
- Add emphatic instruction for WhatsApp/voice channels specifically
- Add outbound message filter to strip tool-call-like patterns (, 🔧)
- Box::pin the two-phase heartbeat agent::run call (16664 bytes on Linux)
2026-03-17 01:55:05 -04:00
Giulio V 220745e217 feat(channels): add Reddit, Bluesky, and generic Webhook adapters (#3598)
* feat(channels): add Reddit, Bluesky, and generic Webhook adapters

- Reddit: OAuth2 polling for mentions/DMs/replies, comment and DM sending
- Bluesky: AT Protocol session auth, notification polling, post replies
- Webhook: Axum HTTP server for inbound, configurable outbound POST/PUT
- All three follow existing channel patterns with tests

* fix(channels): use neutral test fixtures and improve test naming in webhook
2026-03-17 01:26:58 -04:00
Giulio V 61de3d5648 feat(knowledge): add knowledge graph for expertise capture and reuse (#3596)
* feat(knowledge): add knowledge graph for expertise capture and reuse

SQLite-backed knowledge graph system for consulting firms to capture,
organize, and reuse architecture decisions, solution patterns, lessons
learned, and expert matching across client engagements.

- KnowledgeGraph (src/memory/knowledge_graph.rs): node CRUD, edge
  creation, FTS5 full-text search, tag filtering, subgraph traversal,
  expert ranking by authored contributions, graph statistics
- KnowledgeTool (src/tools/knowledge_tool.rs): Tool trait impl with
  capture, search, relate, suggest, expert_find, lessons_extract, and
  graph_stats actions
- KnowledgeConfig (src/config/schema.rs): disabled by default,
  configurable db_path/max_nodes, cross_workspace_search off by default
  for client data isolation
- Wired into tools factory (conditional on config.knowledge.enabled)

20 unit tests covering node CRUD, edge creation, search ranking,
subgraph queries, expert ranking, and tool actions.

* fix: address CodeRabbit review findings

- Fix UTF-8 truncation panic in truncate_str by using char-based
  iteration instead of byte indexing
- Add config validation for knowledge.max_nodes > 0
- Add subgraph depth boundary validation (must be > 0, capped at 100)

* fix(knowledge): address remaining CodeRabbit review issues

- MAJOR: Add db_path non-empty validation in Config::validate()
- MAJOR: Reject tags containing commas in add_node (comma is separator)
- MAJOR: Fix subgraph depth boundary (0..depth instead of 0..=depth)
- MAJOR: Apply project and node_type filters consistently in both
  tag-only and similarity search paths

* fix: correct subgraph traversal test assertion and sync CI workflows
2026-03-17 01:11:29 -04:00
Giulio V 675a5c9af0 feat(tools): add Google Workspace CLI (gws) integration (#3616)
* feat(tools): add Google Workspace CLI (gws) integration

Adds GoogleWorkspaceTool for interacting with Google Drive, Sheets,
Gmail, Calendar, Docs, and other Workspace services via CLI.

- Config-gated (google_workspace.enabled)
- Service allowlist for restricted access
- Requires shell access for CLI delegation
- Input validation against shell injection
- Wrong-type rejection for all optional parameters
- Config validation for allowed_services (empty, duplicate, malformed)
- Registered in integrations registry and CLI discovery

Closes #2986

* style: fix cargo fmt + clippy violations

* feat(google-workspace): expand config with auth, rate limits, and audit settings

* fix(tools): define missing GWS_TIMEOUT_SECS constant

* fix: Box::pin large futures and resolve duplicate Default impl

---------

Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com>
2026-03-17 00:52:59 -04:00
Giulio V b099728c27 feat(stt): multi-provider STT with TranscriptionProvider trait (#3614)
* feat(stt): add multi-provider STT with TranscriptionProvider trait

Refactors single-endpoint transcription to support multiple providers:
Groq (existing), OpenAI Whisper, Deepgram, AssemblyAI, and Google Cloud
Speech-to-Text. Adds TranscriptionManager for provider routing with
backward-compatible config fields.

* style: fix cargo fmt + clippy violations

* fix: Box::pin large futures and resolve merge conflicts with master

---------

Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com>
2026-03-17 00:33:41 -04:00
Argenis 1ca2092ca0 test(channel): add QQ markdown msg_type regression test (#3752)
Verify that QQ send body uses msg_type 2 with nested markdown object
instead of msg_type 0 with top-level content. Adapted from #3668.
2026-03-16 22:03:43 -04:00
Giulio V 5e3308eaaa feat(providers): add Claude Code, Gemini CLI, and KiloCLI subprocess providers (#3615)
* feat(providers): add Claude Code, Gemini CLI, and KiloCLI subprocess providers

Adds three new local subprocess-based providers for AI CLI tools.
Each provider spawns the CLI as a child process, communicates via
stdin/stdout pipes, and parses responses into ChatResponse format.

* fix: resolve clippy unnecessary_debug_formatting and rustfmt violations

* fix: resolve remaining clippy unnecessary_debug_formatting in CLI providers

* fix(providers): add AiAgent CLI category for subprocess providers
2026-03-16 21:51:05 -04:00
Chris Hengge ec255ad788 fix(tool): expand cron_add and cron_update parameter schemas (#3671)
The schedule field in cron_add used a bare {"type":"object"} with a
description string encoding a tagged union in pseudo-notation. The patch
field in cron_update was an opaque {"type":"object"} despite CronJobPatch
having nine fully-typed fields. Both gaps cause weaker instruction-following
models to produce malformed or missing nested JSON when invoking these tools.

Changes:
- cron_add: expand schedule into a oneOf discriminated union with explicit
  properties and required fields for each variant (cron/at/every), matching
  the Schedule enum in src/cron/types.rs exactly
- cron_add: add descriptions to all previously undocumented top-level fields
- cron_add: expand delivery from a bare inline comment to fully-specified
  properties with per-field descriptions
- cron_update: expand patch from opaque object to full properties matching
  CronJobPatch (name, enabled, command, prompt, model, session_target,
  delete_after_run, schedule, delivery)
- cron_update: schedule inside patch mirrors the same oneOf expansion
- Both: add inline NOTE comments flagging that oneOf is correct for
  OpenAI-compatible APIs but SchemaCleanr::clean_for_gemini must be
  applied if Gemini native tool calling is ever wired up
- Both: add schema-shape tests using the existing test_config/test_security
  helper pattern, covering oneOf variant structure, required fields, and
  delivery channel enum completeness

No behavior changes. No new dependencies. Backward compatible: the runtime
deserialization path (serde on Schedule/CronJobPatch) is unchanged.

Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-16 21:45:49 -04:00
Sid Jain 7182f659ce fix(slack): honor mention_only in runtime channel wiring (#3715)
* feat(slack): wire mention_only group reply policy

* feat(slack): expose mention_only in config and wizard defaults
2026-03-16 21:40:47 -04:00
Ericsunsk ae7681209d fix(openai-codex): decode utf-8 safely across stream chunks (#3723) 2026-03-16 21:40:45 -04:00
Markus Bergholz ee3469e912 Fix: Support Nextcloud Talk Activity Streams 2.0 webhook format (#3737)
* fix

* fix

* format
2026-03-16 21:40:42 -04:00
Argenis fec81d8e75 ci: auto-sync Scoop and AUR on stable release (#3743)
Add workflow_call triggers to pub-scoop.yml and pub-aur.yml so the
stable release workflow can invoke them automatically after publish.

Wire scoop and aur jobs into release-stable-manual.yml as post-publish
steps (parallel with tweet), gated on publish success.

Update ci-map.md trigger docs to reflect auto-called behavior.
2026-03-16 21:34:29 -04:00
Ricardo Madriz 9a073fae1a fix(tools) Wire activated toolset into dispatch (#3747)
* fix(tools): wire ActivatedToolSet into tool dispatch and spec advertisement

When deferred MCP tools are activated via tool_search, they are stored
in ActivatedToolSet but never consulted by the tool call loop.
tool_specs is built once before the iteration loop and never refreshed,
so the provider API tools[] parameter never includes activated tools.
find_tool only searches the static registry, so execution dispatch also
fails silently.

Thread Arc<Mutex<ActivatedToolSet>> from creation sites through to
run_tool_call_loop. Rebuild tool_specs each iteration to merge base
registry specs with activated specs. Add fallback in execute_one_tool
to check the activated set when the static registry lookup misses.

Change ActivatedToolSet internal storage from Box<dyn Tool> to
Arc<dyn Tool> so we can clone the Arc out of the mutex guard before
awaiting tool.execute() (std::sync::MutexGuard is not Send).

* fix(tools): add activated_tools field to new ChannelRuntimeContext test site
2026-03-16 21:34:08 -04:00
Chris Hengge f0db63e53c fix(integrations): wire Cron and Browser status to config fields (#3750)
Both entries had hardcoded |_| IntegrationStatus::Available, ignoring
the live config entirely. Users with cron.enabled = true or
browser.enabled = true saw 'Available' on the /integrations dashboard
card instead of 'Active'.

Root cause: status_fn closures did not capture the Config argument.

Fix: replace the |_| stubs with |c| closures that check c.cron.enabled
and c.browser.enabled respectively, matching the pattern used by every
other wired entry in the registry (Telegram, Discord, Shell, etc.).

What did NOT change: ComingSoon entries, always-Active entries (Shell,
File System), platform entries, or any other registry logic.
2026-03-16 21:34:06 -04:00
Argenis df4dfeaf66 chore: bump version to 0.4.3 (#3749)
Update version across Cargo.toml, Cargo.lock, Scoop manifest,
and AUR PKGBUILD/.SRCINFO for the v0.4.3 stable release.
2026-03-16 21:23:04 -04:00
Giulio V e4ef25e913 feat(security): add Merkle hash-chain audit trail (#3601)
* feat(security): add Merkle hash-chain audit trail

Each audit entry now includes a SHA-256 hash linking it to the previous
entry (entry_hash, prev_hash, sequence), forming a tamper-evident chain.
Modifying any entry invalidates all subsequent hashes.

- Chain fields added to AuditEvent with #[serde(default)] for backward compat
- AuditLogger tracks chain state and recovers from existing logs on restart
- verify_chain() validates hash linkage, sequence continuity, and integrity
- Five new tests: genesis seed, multi-entry verify, tamper detection,
  sequence gap detection, and cross-restart chain recovery

* fix(security): replace personal name with neutral label in audit tests
2026-03-16 18:38:59 -04:00
Argenis c3a3cfc9a6 fix(agent): prevent duplicate tool schema injection in XML dispatcher (#3744)
Remove duplicate tool listing from XmlToolDispatcher::prompt_instructions()
since tool listing is already handled by ToolsSection in prompt.rs. The
method now only emits the XML protocol envelope.

Also fix UTF-8 char boundary panics in memory consolidation truncation by
using char_indices() instead of manual byte-boundary scanning.

Fixes #3643
Supersedes #3678

Co-authored-by: TJUEZ <TJUEZ@users.noreply.github.com>
2026-03-16 18:38:44 -04:00
伊姆 013fca6ad2 fix(config): support socks proxy scheme for Clash Verge (#3001)
Co-authored-by: imu <imu@sgcc.com.cn>
2026-03-16 18:38:03 -04:00
linyibin 23a0f25b44 fix(web): ensure web/dist exists in fresh clones (#3114)
The Rust build expects web/dist to exist (static assets). Track an empty
placeholder via web/dist/.gitkeep and adjust ignore rules to keep build
artifacts ignored while allowing the placeholder file.

Made-with: Cursor
2026-03-16 18:37:14 -04:00
Giulio V 2eaa8c45f4 feat(whatsapp-web): add voice message transcription support (#3617)
Adds audio message detection and transcription to WhatsApp Web channel.
Voice messages (PTT) are downloaded, transcribed via the existing
transcription subsystem (Groq Whisper), and delivered as text content.

- TranscriptionConfig field with builder pattern
- Duration limit enforcement before download
- MIME type mapping for audio formats
- Graceful error handling (skip on failure)
- Preserves full retry/reconnect state machine from master
2026-03-16 18:34:50 -04:00
Sandeep Ghael 85bf649432 fix(channel): resolve multi-room reply routing regression (#3224) (#3378)
* fix(channel): resolve multi-room reply routing regression (#3224)

PR #3224 (f0f0f808, "feat(matrix): add multi-room support") changed the
channel name format in matrix.rs from "matrix" to "matrix:!roomId", but
the channel lookup in mod.rs still does an exact match against
channels_by_name, which is keyed by Channel::name() (returns "matrix").

This mismatch causes target_channel to always resolve to None for Matrix
messages, silently dropping all replies.

Fix: fall back to a prefix match on the base channel name (before ':')
when the exact lookup fails. This preserves multi-room conversation
isolation while correctly routing replies to the originating channel.

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

* style: apply cargo fmt to channel routing fix

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

---------

Co-authored-by: Sandeep (Claude) <sghael+claude@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 18:32:56 -04:00
Giulio V 3ea99a7619 feat(tools): add browser delegation tool (#3610)
* feat(tools): add browser delegation tool for corporate web app interaction

Adds BrowserDelegateTool that delegates browser-based tasks to Claude Code
(or other browser-capable CLIs) for interacting with corporate tools
(Teams, Outlook, Jira, Confluence) via browser automation. Includes domain
validation (allow/blocklist), task templates, Chrome profile persistence
for SSO sessions, and timeout management.

* fix: resolve clippy violation in browser delegation tool

* fix(browser-delegate): validate URLs embedded in task text against domain policy

Scan the task text for http(s):// URLs using regex and validate each
against the allow/block domain lists before forwarding to the browser
CLI subprocess. This prevents bypassing domain restrictions by
embedding blocked URLs in the task parameter.

* fix(browser-delegate): constrain URL schemes, gate on runtime, document config

- Add has_shell_access gate so BrowserDelegateTool is only registered on
  shell-capable runtimes (skipped with warning on WASM/edge runtimes)
- Add boundary tests for javascript: and data: URL scheme rejection
- URL scheme validation (http/https only) and config docs were already
  addressed by a prior commit on this branch

* fix(tools): address CodeRabbit review findings for browser delegation

Remove dead `max_concurrent_tasks` config field and expand doc comments
on the `[browser_delegate]` config section in schema.rs.
2026-03-16 18:32:20 -04:00
Christian Pojoni 14f58c77c1 fix(tool+channel): revert invalid model set via model_routing_config (#3497)
When the LLM hallucinates an invalid model ID through the
model_routing_config tool's set_default action, the invalid model gets
persisted to config.toml. The channel hot-reload then picks it up and
every subsequent message fails with a non-retryable 404, permanently
killing the connection with no user recovery path.

Fix with two layers of defense:

1. Tool probe-and-rollback: after saving the new model, send a minimal
   chat request to verify the model is accessible. If the API returns a
   non-retryable error (404, auth failure, etc.), automatically restore
   the previous config and return a failure notice to the LLM.

2. Channel safety net: in maybe_apply_runtime_config_update, reject
   config reloads when warmup fails with a non-retryable error instead
   of applying the broken config anyway.

Co-authored-by: Christian Pojoni <christian.pojoni@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:30:36 -04:00
dependabot[bot] b833eb19f5 chore(deps): bump rust in the docker-all group (#3692)
Bumps the docker-all group with 1 update: rust.


Updates `rust` from 1.93-slim to 1.94-slim

---
updated-dependencies:
- dependency-name: rust
  dependency-version: 1.94-slim
  dependency-type: direct:production
  dependency-group: docker-all
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-16 18:28:51 -04:00
DotViegas 5db883b453 fix(providers): adjust temperature for OpenAI reasoning models (#2936)
Some OpenAI models (o1, o3, o4, gpt-5 variants) only accept temperature=1.0 and return errors with other values like 0.7. This change automatically adjusts the temperature parameter based on the model being used.

Changes:
- Add adjust_temperature_for_model() function to detect reasoning models
- Apply temperature adjustment in chat_with_system(), chat(), and chat_with_tools()
- Preserve user-specified temperature for standard models (gpt-4o, gpt-4-turbo, etc.)
- Force temperature=1.0 for reasoning models (o1, o3, o4, gpt-5, gpt-5-mini, gpt-5-nano, gpt-5.x-chat-latest)

Testing:
- Add 7 unit tests covering reasoning models, standard models, and edge cases
- All tests pass successfully
- Empirical testing documented in docs/openai-temperature-compatibility.md

Impact:
- Fixes temperature errors when using o1, o3, o4, and gpt-5 model families
- No breaking changes - transparent adjustment for end users
- Standard models continue to work with flexible temperature values

Risk: Low - isolated change within OpenAI provider, well-tested

Rollback: Revert this commit to restore previous behavior

Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-16 18:28:01 -04:00
Eddie's AI Agent 0ae515b6b8 fix(channel): correct Matrix image marker casing to match canonical format (#3519)
Co-authored-by: Eddie Tong <xinhant@gmail.com>
2026-03-16 18:25:33 -04:00
Giulio V 2deb91455d feat(observability): add Hands dashboard metrics and events (#3595)
Add HandStarted, HandCompleted, and HandFailed event variants to
ObserverEvent, and HandRunDuration, HandFindingsCount, HandSuccessRate
metric variants to ObserverMetric. Update all observer backends (log,
noop, verbose, prometheus, otel) to handle the new variants with
appropriate instrumentation. Prometheus backend registers hand_runs
counter, hand_duration histogram, and hand_findings counter. OTel
backend creates spans and records metrics for hand runs.
2026-03-16 18:24:47 -04:00
smallwhite 595b81be41 fix(telegram): avoid duplicate finalize_draft messages (#3259) 2026-03-16 18:24:19 -04:00
Chris Hengge 4f9d817ddb fix(memory): serialize MemoryCategory as plain string and guard dashboard render crashes (#3051)
The /memory dashboard page rendered a black screen when MemoryCategory::Custom
was serialized by serde's derived impl as a tagged object {"custom":"..."} but
the frontend expected a plain string. No navigation was possible without using
the browser Back button.

Changes:
- src/memory/traits.rs: replace derived serde impls with custom serialize
  (delegates to Display, emits plain snake_case string) and deserialize
  (parses known variants by name, falls through to Custom(s) for unknown).
  Adds memory_category_serde_uses_snake_case and memory_category_custom_roundtrip
  tests. No persistent storage migration needed — all backends (SQLite, Markdown,
  Postgres) use their own category_to_str/str_to_category helpers and never
  read serde-serialized category values back from disk.
- web/src/App.tsx: export ErrorBoundary class so render crashes surface a
  recoverable UI instead of a black screen. Adds aria-live="polite" to the
  pairing error paragraph for screen reader accessibility.
- web/src/components/layout/Layout.tsx: wrap Outlet in ErrorBoundary keyed
  by pathname so the navigation shell stays mounted during a page crash and
  the boundary resets on route change.

Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-16 18:23:03 -04:00
Darren.Zeng d13f5500e9 fix(install): add missing libssl-dev for Debian/Ubuntu (#3285)
The install.sh script was missing libssl-dev package for Debian/Ubuntu
systems. This caused compilation failures on Debian 12 and other
Debian-based distributions when building ZeroClaw from source.

The package is already included for other distributions:
- Alpine: openssl-dev
- Fedora/RHEL: openssl-devel
- Arch: openssl

This change adds libssl-dev to the apt-get install command to ensure
OpenSSL headers are available during compilation.

Fixes #2914

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-16 18:22:10 -04:00
Chris Hengge 1ccfe643ba fix(channel): bypass mention_only gate for Discord DMs (#2983)
When mention_only is enabled, the bot correctly requires an @mention in
guild (server) channels. However, Direct Messages have no guild_id and
are inherently private and addressed to the bot — requiring a @mention
in a DM is never correct and silently drops all DM messages.

Changes:
- src/channels/discord.rs: detect DMs via absence of guild_id in the
  gateway payload, compute effective_mention_only = self.mention_only && !is_dm,
  and pass that to normalize_incoming_content instead of self.mention_only.
  DMs bypass the mention gate; guild messages retain existing behaviour.
- Adds three tests: DM bypasses mention gate, guild message without mention
  is rejected, guild message with mention passes and strips the mention tag.

Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-16 18:21:27 -04:00
Vadim Rutkovsky d4d3e03e34 fix: add dummy src/lib.rs in Dockerfile.debian for dep caching stage (#3553) 2026-03-16 18:20:43 -04:00
simonfr aa0f11b0a2 fix(docker): copy build.rs into builder stage to invalidate dummy binary cache (#3570)
* Fix build with Docker

* fix(docker): copy build.rs into builder stage to fix rag feature activation
2026-03-16 18:19:55 -04:00
Argenis 806f8b4020 fix(docker): purge stale zeroclawlabs fingerprints before build (#3741)
The BuildKit cache mount persists .fingerprint and .d files across
source tree changes, causing compilation errors when imports change.
Clear zeroclawlabs-specific artifacts before building to ensure
a clean recompile of the main crate while preserving dep caches.
2026-03-16 18:10:36 -04:00
Ericsunsk 83803cef5b fix(memory): filter autosave noise and scope recall/store by session (#3695)
* fix(memory): filter autosave noise and scope memory by session

* style: format rebase-resolved gateway and memory loader

* fix(tests): update memory loader mock for session-aware context

* fix(openai-codex): decode utf-8 safely across stream chunks
2026-03-16 16:36:35 -04:00
Vast-stars dcb182cdd5 fix(agent): remove bare URL → curl fallback in GLM-style tool call parser (#3694)
* fix(agent): remove bare URL → curl fallback in GLM-style tool call parser

The `parse_glm_style_tool_calls` function had a "Plain URL" fallback
that converted any bare URL line (e.g. `https://example.com`) into a
`shell` tool call running `curl -s '<url>'`. This caused:

- False positives: normal URLs in LLM replies misinterpreted as tool calls
- Swallowed replies: text with URLs not forwarded to the channel
- Unintended shell commands: `curl` executed without user intent

Explicit GLM-format tool calls like `browser_open/url>https://...` and
`shell/command>...` are unaffected — only the bare URL catch-all is
removed.

* style: cargo fmt

---------

Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com>
2026-03-16 16:36:27 -04:00
Argenis 7c36a403b0 chore: sync Scoop and AUR templates to v0.4.1 (#3736) 2026-03-16 16:36:26 -04:00
Argenis 058dbc8786 feat(channels): add X/Twitter and Mochat channel integrations (#3735)
* feat(channels): add X/Twitter and Mochat channel integrations

Add two new channel implementations to close competitive gaps:

- X/Twitter: Twitter API v2 with mentions polling, tweet threading
  (auto-splits at 280 chars), DM support, and rate limit handling
- Mochat: HTTP polling-based integration with Mochat customer service
  platform, configurable poll interval, message dedup

Both channels follow the existing Channel trait pattern with full
config schema integration, health checks, and dedup.

Closes competitive gap: NanoClaw had X/Twitter, Nanobot had Mochat.

* fix(channels): use write! instead of format_push_string for clippy

Replace url.push_str(&format!(...)) with write!(url, ...) to satisfy
clippy::format_push_string lint on CI.

* fix(channels): rename reply_to parameter to avoid legacy field grep

The component test source_does_not_use_legacy_reply_to_field greps
for "reply_to:" in source files. Rename the parameter to
reply_tweet_id to pass this check.
2026-03-16 16:35:21 -04:00
SimianAstronaut7 aff7a19494 Merge pull request #3641 from zeroclaw-labs/work-issues/3011-fix-dashboard-ws-protocols
fix(gateway): pass bearer token in WebSocket subprotocol for dashboard auth
2026-03-16 16:34:46 -04:00
SimianAstronaut7 0894429b54 Merge pull request #3640 from zeroclaw-labs/work-issues/2881-transcription-initial-prompt
feat(config): support initial_prompt in transcription config
2026-03-16 16:34:43 -04:00
SimianAstronaut7 6b03e885fc Merge pull request #3639 from zeroclaw-labs/work-issues/3474-docker-restart-docs
docs(setup): add Docker/Podman stop/restart instructions
2026-03-16 16:34:41 -04:00
Argenis 84470a2dd2 fix(agent): strip vision markers from history for non-vision providers (#3734)
* fix(agent): strip vision markers from history for non-vision providers

When a user sends an image via Telegram to a non-vision provider, the
`[IMAGE:/path]` marker gets stored in the JSONL session file. Previously,
the rollback only removed it from in-memory history, not from the JSONL
file. On restart, the marker was reloaded and permanently broke the
conversation.

Two fixes:
1. `rollback_orphan_user_turn` now also calls `remove_last` on the
   session store so the poisoned entry is removed from disk.
2. When building history for a non-vision provider, `[IMAGE:]` markers
   are stripped from older history messages (and empty turns are dropped).

Fixes #3674

* fix(agent): only strip vision markers from older history, not current message

The initial fix stripped [IMAGE:] markers from all prior_turns including
the current message, which caused the vision check to never fire. Now
only strip from turns before the last one (the current request), so
fresh image sends still get a proper vision capability error.
2026-03-16 16:25:45 -04:00
Argenis 8a890be021 chore: bump version to 0.4.2 (#3733)
Update version across Cargo.toml, Cargo.lock, Scoop manifest,
and AUR PKGBUILD/.SRCINFO for the v0.4.2 stable release.
2026-03-16 16:02:34 -04:00
Argenis 74a5ff78e7 fix(qq): send markdown messages instead of plain text (#3732)
* fix(ci): decouple tweet from Docker push in release workflows

Remove Docker from the tweet job's dependency chain in both beta and
stable release workflows. Docker multi-platform builds are slow and
can be cancelled by concurrency groups, which was blocking the tweet
from ever firing. The tweet announces the GitHub Release, not the
Docker image.

* fix(qq): send markdown messages instead of plain text

Change msg_type from 0 (plain text) to 2 (markdown) and wrap content
in a markdown object per QQ's API documentation. This ensures markdown
formatting (bold, italic, code blocks, etc.) renders properly in QQ
clients instead of displaying raw syntax.

Fixes #3647
2026-03-16 15:56:09 -04:00
Argenis 93b16dece5 Merge pull request #3731 from zeroclaw-labs/fix/tweet-decouple-docker
fix(ci): decouple tweet from Docker push in release workflows
2026-03-16 15:52:05 -04:00
Argenis c773170753 feat(providers): close AiHubMix, SiliconFlow, and Codex OAuth provider gaps (#3730)
Add env var resolution for AiHubMix (AIHUBMIX_API_KEY) and SiliconFlow
(SILICONFLOW_API_KEY) so users can authenticate via environment variables.

Add factory and credential resolution tests for AiHubMix, SiliconFlow,
and Codex OAuth to ensure all provider aliases work correctly.
2026-03-16 15:48:27 -04:00
argenis de la rosa f210b43977 fix(ci): decouple tweet from Docker push in release workflows
Remove Docker from the tweet job's dependency chain in both beta and
stable release workflows. Docker multi-platform builds are slow and
can be cancelled by concurrency groups, which was blocking the tweet
from ever firing. The tweet announces the GitHub Release, not the
Docker image.
2026-03-16 15:32:29 -04:00
Argenis 50bc360bf4 Merge pull request #3729 from zeroclaw-labs/fix/crates-auto-publish-idempotent
fix(ci): make crates.io publish idempotent across all workflows
2026-03-16 15:30:30 -04:00
Argenis fc8ed583a0 feat(providers): add VOLCENGINE_API_KEY env var for VolcEngine/ByteDance gateway (#3725) 2026-03-16 15:29:36 -04:00
argenis de la rosa d593b6b1e4 fix(ci): make crates.io publish idempotent across all workflows
Both publish-crates-auto.yml and publish-crates.yml now treat
"already exists" from cargo publish as success instead of failing
the workflow. This prevents false failures when the auto-sync and
stable release workflows race or when re-running a publish.
2026-03-16 15:11:29 -04:00
Argenis 426faa3923 Merge pull request #3724 from zeroclaw-labs/fix/release-sync-tweet-and-crates
fix(ci): ensure tweet posts for stable releases and fix beta concurrency
2026-03-16 15:07:58 -04:00
argenis de la rosa 85429b3657 fix(ci): ensure tweet posts for stable releases and fix beta concurrency
- Tweet workflow: stable releases always tweet (no feature-check gate);
  beta tweets now also trigger on fix() commits, not just feat()
- Beta release: use cancel-in-progress to avoid queued runs getting
  stuck when rapid merges hit the concurrency group
2026-03-16 14:54:32 -04:00
Argenis 8adf05f307 Merge pull request #3722 from zeroclaw-labs/ci/restore-package-manager-syncs
ci: restore Homebrew and add Scoop/AUR package manager workflows
2026-03-16 14:30:09 -04:00
Argenis a5f844d7cc fix(daemon): ignore SIGHUP to survive terminal/SSH disconnect (#3721)
* fix(daemon): ignore SIGHUP to survive terminal/SSH disconnect (#3688)

* style: remove redundant continue flagged by clippy
2026-03-16 14:21:59 -04:00
Argenis 7a9e815948 fix(config): add serde default for cli field in ChannelsConfig (#3720)
* fix(config): add serde default for cli field in ChannelsConfig (#3710)

* style: fix rustfmt formatting in test
2026-03-16 14:21:51 -04:00
Argenis 46378cf8b4 fix(security): validate command before rate-limiting in cron once (#3699) (#3719) 2026-03-16 14:21:45 -04:00
Argenis c2133e6e62 fix(docker): prevent dummy binary from being shipped in container (#3687) (#3718) 2026-03-16 14:21:37 -04:00
Argenis e9b3148e73 Merge pull request #3717 from zeroclaw-labs/chore/version-bump-0.4.1
chore: bump version to 0.4.1
2026-03-16 14:21:20 -04:00
argenis de la rosa 3d007f6b55 docs: add Scoop and AUR workflows to CI map and release process 2026-03-16 14:17:18 -04:00
argenis de la rosa f349de78ed ci(aur): add AUR PKGBUILD template and publishing workflow
Adds Arch Linux distribution via AUR:
- dist/aur/PKGBUILD: package build template with cargo dist profile
- dist/aur/.SRCINFO: AUR metadata
- .github/workflows/pub-aur.yml: manual workflow to push to AUR
2026-03-16 14:16:30 -04:00
argenis de la rosa cd40051f4c ci(scoop): add Scoop manifest template and publishing workflow
Adds Windows package distribution via Scoop:
- dist/scoop/zeroclaw.json: manifest template with checkver/autoupdate
- .github/workflows/pub-scoop.yml: manual workflow to update Scoop bucket
2026-03-16 14:15:29 -04:00
argenis de la rosa 6e4b1ede28 ci(homebrew): restore Homebrew core formula publishing workflow
Re-adds the manual-dispatch workflow for bumping the zeroclaw formula
in Homebrew/homebrew-core via a bot-owned fork. Improved from the
previously removed version with safer env-var handling.

Requires secrets: HOMEBREW_CORE_BOT_TOKEN or HOMEBREW_UPSTREAM_PR_TOKEN
Requires variables: HOMEBREW_CORE_BOT_FORK_REPO, HOMEBREW_CORE_BOT_EMAIL
2026-03-16 14:12:48 -04:00
argenis de la rosa cfba009833 chore: regenerate Cargo.lock for v0.4.1 2026-03-16 13:49:39 -04:00
argenis de la rosa 45abd27e4a chore: bump version to 0.4.1
Reflects the addition of heartbeat metrics, SQLite session backend,
and two-tier response cache in this release cycle.
2026-03-16 13:49:36 -04:00
Argenis 566e3cf35b Merge pull request #3712 from zeroclaw-labs/feat/competitive-edge-heartbeat-sessions-caching
feat: competitive edge — heartbeat metrics, SQLite sessions, two-tier prompt cache
2026-03-16 13:47:42 -04:00
Argenis d642b0f3c8 fix(ci): decouple tweet from crates.io and fix duplicate publish handling (#3716)
Drop crates-io from the tweet job's needs so the release announcement
goes out with GitHub release, Docker, and website — not blocked by
crates.io publish timing.

Also fix the duplicate detection: the previous curl-based check used
a URL that didn't match the actual crate, causing cargo publish to
hit "already exists" and fail the whole job. Now we just run cargo
publish and treat "already exists" as success.
2026-03-16 13:46:05 -04:00
Argenis 8153992a11 fix(ci): scope rust-cache by OS image in stable release workflow (#3711)
Same glibc cache mismatch fix as the beta workflow — ubuntu-22.04 builds
must not share cached build-script binaries with ubuntu-latest (24.04).
2026-03-16 12:56:30 -04:00
argenis de la rosa 98688c61ff feat(cache): wire two-tier response cache, multi-provider token tracking, and cache analytics
- Two-tier response cache: in-memory LRU (hot) + SQLite (warm) with TTL-aware eviction
- Wire response cache into agent turn loop (temp==0.0, text-only responses only)
- Parse Anthropic cache_creation_input_tokens/cache_read_input_tokens
- Parse OpenAI prompt_tokens_details.cached_tokens
- Add cached_input_tokens to TokenUsage, prompt_caching to ProviderCapabilities
- Add CacheHit/CacheMiss observer events with Prometheus counters
- Add response_cache_hot_entries config field (default: 256)
2026-03-16 12:44:48 -04:00
argenis de la rosa 9ba5ba5632 feat(sessions): add SQLite backend with FTS5, trait abstraction, and migration
- Add SessionBackend trait abstracting over storage backends (load,
  append, remove_last, list, search, cleanup_stale, compact)
- Add SqliteSessionBackend with WAL mode, FTS5 full-text search,
  session metadata tracking, and TTL-based cleanup
- Add remove_last() and compact() to JSONL SessionStore
- Implement SessionBackend for both JSONL and SQLite backends
- Add automatic JSONL-to-SQLite migration (renames .jsonl → .jsonl.migrated)
- Add config: session_backend ("jsonl"/"sqlite"), session_ttl_hours
- SQLite is the new default backend; JSONL preserved for backward compat
2026-03-16 12:23:18 -04:00
argenis de la rosa 318ed8e9f1 feat(heartbeat): add health metrics, adaptive intervals, and task history
- Add HeartbeatMetrics struct with uptime, consecutive success/failure
  counts, EMA tick duration, and total ticks
- Add compute_adaptive_interval() for exponential backoff on failures
  and faster polling when high-priority tasks are present
- Add SQLite-backed task run history (src/heartbeat/store.rs) mirroring
  the cron/store.rs pattern with output truncation and pruning
- Add dead-man's switch that alerts if heartbeat stops ticking
- Wire metrics, history recording, and adaptive sleep into daemon worker
- Add config fields: adaptive, min/max_interval_minutes,
  deadman_timeout_minutes, deadman_channel, deadman_to, max_run_history
- All new fields are backward-compatible with serde defaults
2026-03-16 12:08:32 -04:00
Argenis 5ddea82789 fix(ci): scope rust-cache by OS image and target in release beta workflow (#3708)
The aarch64-unknown-linux-gnu build runs on ubuntu-22.04 (glibc 2.35)
but was restoring cached build-script binaries compiled on ubuntu-latest
(24.04, glibc 2.39), causing GLIBC_2.39 not found failures.

Adding prefix-key with the OS image and target ensures each matrix entry
gets its own isolated cache, preventing cross-image glibc mismatches.
2026-03-16 11:37:14 -04:00
Argenis a2b18bdb16 chore: gitignore stale target-* build cache dirs (#3707)
Adds /target-*/ to .gitignore to prevent alternative Cargo build
directories (e.g. target-ms365, target-pr) from being tracked.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 11:21:04 -04:00
Argenis 85271441b5 docs: remove duplicate Vietnamese docs and orphan Greek locale (#3701)
- Remove docs/i18n/vi/ — duplicate of canonical docs/vi/ per docs-contract
- Remove docs/i18n/el/ — orphan Greek locale, not in supported locales list
- Update docs/i18n/README.md to reflect correct canonical paths

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 10:41:43 -04:00
Argenis 813ae17f48 fix(install): correct version display, show pairing code, bump to 0.4.0 (#3669)
* style: cargo fmt Box::pin calls in cron scheduler

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

* fix(install): correct version display, show pairing code, bump to 0.4.0

- Reorder ZEROCLAW_BIN resolution to prefer ~/.cargo/bin over PATH,
  preventing stale binaries from shadowing the fresh install
- Sync binary to ~/.local/bin after cargo install
- Fetch and display gateway pairing code via `gateway get-paircode`
  after service restart instead of referencing non-existent output
- Update fallback message to actionable CLI command
- Bump Cargo.toml version from 0.3.4 to 0.4.0

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

* fix: update Cargo.lock for 0.4.0 version bump

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 09:58:31 -04:00
Argenis 794d87d95c fix(config): add missing #[serde(default)] to Config struct fields (#3700)
Several recently-added Config fields (data_retention, cloud_ops,
conversational_ai, security_ops) were missing #[serde(default)],
causing deserialization failures when those sections are absent
from config files. Also fixes security field whose #[serde(default)]
was accidentally consumed by the backup doc comment.

Fixes test failures: agent_config_deserializes and
browser_config_backward_compat_missing_section.
2026-03-16 09:21:41 -04:00
Argenis d6e5907b65 feat(tools): add cloud transformation accelerator tools (#3663)
* feat(tools): add cloud transformation accelerator tools

Add cloud_ops and cloud_patterns tools providing read-only cloud
transformation analysis: IaC review, migration assessment, cost
analysis, and Well-Architected Framework architecture review.

Includes CloudOpsConfig, SecurityOpsConfig, and ConversationalAiConfig
schema additions, Box::pin fixes for recursive async in cron scheduler,
and approval_manager field in ChannelRuntimeContext test constructors.

Original work by @rareba. Rebased on latest master with conflict
resolution (kept SwarmConfig/SwarmStrategy exports, swarm tool
registration, and approval_manager in test constructors).

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

* style: cargo fmt Box::pin calls

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 02:43:55 -04:00
Argenis 861dd3e2e9 feat(tools): add backup/restore and data management tools (#3662)
Add BackupTool for creating, listing, verifying, and restoring
timestamped workspace backups with SHA-256 manifest integrity
checking. Add DataManagementTool for retention status, time-based
purge, and storage statistics. Both tools are config-driven via
new BackupConfig and DataRetentionConfig sections.

Original work by @rareba. Rebased on latest master with conflict
resolution for SwarmConfig/SwarmStrategy exports and swarm tool
registration, and added missing approval_manager fields in
ChannelRuntimeContext test constructors.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 02:35:44 -04:00
Argenis 8a61a283b2 feat(security): add MCSS security operations tool (#3657)
* feat(security): add MCSS security operations tool

Add managed cybersecurity service (MCSS) tool with alert triage,
incident response playbook execution, vulnerability scan parsing,
and security report generation. Includes SecurityOpsConfig, playbook
engine with approval gating, vulnerability scoring, and full test
coverage. Also fixes pre-existing missing approval_manager field in
ChannelRuntimeContext test constructors.

Original work by @rareba. Supersedes #3599.

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

* fix: add SecurityOpsConfig to re-exports, fix test constructors

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 02:28:54 -04:00
Argenis dcc0a629ec feat(tools): add project delivery intelligence tool (#3656)
Add a new read-only project_intel tool that provides:
- Status report generation (weekly/sprint/month)
- Risk scanning with configurable sensitivity
- Client update drafting (formal/casual, client/internal)
- Sprint summary generation
- Heuristic effort estimation

Includes multi-language report templates (EN, DE, FR, IT),
ProjectIntelConfig schema with validation, and comprehensive tests.

Also fixes missing approval_manager field in 4 ChannelRuntimeContext
test constructors.

Supersedes #3591 — rebased on latest master. Original work by @rareba.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 02:10:14 -04:00
Argenis a8c6363cde feat(nodes): add secure HMAC-SHA256 node transport layer (#3654)
Add a new `nodes` module with HMAC-SHA256 authenticated transport for
secure inter-node communication over standard HTTPS. Includes replay
protection via timestamped nonces and constant-time signature
comparison.

Also adds `NodeTransportConfig` to the config schema and fixes missing
`approval_manager` field in four `ChannelRuntimeContext` test
constructors that failed compilation on latest master.

Original work by @rareba. Rebased on latest master to resolve merge
conflicts (SwarmConfig/SwarmStrategy exports, duplicate MCP validation,
test constructor fields).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 01:53:47 -04:00
Argenis d9ab017df0 feat(tools): add Microsoft 365 integration via Graph API (#3653)
Add Microsoft 365 tool providing access to Outlook mail, Teams messages,
Calendar events, OneDrive files, and SharePoint search via Microsoft
Graph API. Includes OAuth2 token caching (client credentials and device
code flows), security policy enforcement, and config validation.

Rebased on latest master, resolving conflicts with SwarmConfig exports
and adding approval_manager to ChannelRuntimeContext test constructors.

Original work by @rareba.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 01:44:39 -04:00
Argenis 249434edb2 feat(notion): add Notion database poller channel and API tool (#3650)
Add Notion integration with two components:
- NotionChannel: polls a Notion database for tasks with configurable
  status properties, concurrency limits, and stale task recovery
- NotionTool: provides CRUD operations (query_database, read_page,
  create_page, update_page) for agent-driven Notion interactions

Includes config schema (NotionConfig), onboarding wizard support,
and full unit test coverage for both channel and tool.

Supersedes #3609 — rebased on latest master to resolve merge conflicts
with swarm feature additions in config/mod.rs.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 00:55:23 -04:00
Argenis 62781a8d45 fix(lint): Box::pin crate::agent::run calls to satisfy large_futures (#3675)
Wrap all crate::agent::run() calls with Box::pin() across scheduler,
daemon, gateway tests, and main.rs to satisfy clippy::large_futures.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 00:54:27 -04:00
Chris Hengge 0adec305f9 fix(tools): qualify is_service_environment with super:: inside mod native_backend (#3659)
Commit 811fab3b added is_service_environment() as a top-level function and
called it from two sites. The call at line 445 is at module scope and resolves
fine. The call at line 1473 is inside mod native_backend, which is a child
module — Rust does not implicitly import parent-scope items, so the unqualified
name fails with E0425 (cannot find function in this scope).

Fix: prefix the call with super:: so it resolves to the parent module's
function, matching how mod native_backend already imports other parent items
(e.g. use super::BrowserAction).

The browser-native feature flag is required to reproduce:
  cargo check --features browser-native  # fails without this fix
  cargo check --features browser-native  # clean with this fix

Co-authored-by: Argenis <theonlyhennygod@gmail.com>
2026-03-16 00:35:09 -04:00
Argenis 75701195d7 feat(security): add Nevis IAM integration for SSO/MFA authentication (#3651)
* feat(security): add Nevis IAM integration for SSO/MFA authentication

Add NevisAuthProvider supporting OAuth2/OIDC token validation (local JWKS +
remote introspection), FIDO2/passkey/OTP MFA verification, session management,
and health checks. Add IamPolicy engine mapping Nevis roles to ZeroClaw tool
and workspace permissions with deny-by-default enforcement and audit logging.

Add NevisConfig and NevisRoleMappingConfig to config schema with client_secret
wired through SecretStore encrypt/decrypt. All features disabled by default.

Rebased on latest master to resolve merge conflicts in security/mod.rs (redact
function) and config/schema.rs (test section).

Original work by @rareba. Supersedes #3593.

Co-Authored-By: rareba <5985289+rareba@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: cargo fmt Box::pin calls

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

---------

Co-authored-by: rareba <5985289+rareba@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 00:34:52 -04:00
Argenis 82fe2e53fd feat(tunnel): add OpenVPN tunnel provider (#3648)
* feat(tunnel): add OpenVPN tunnel provider

Add OpenVPN as a new tunnel provider alongside cloudflare, tailscale,
ngrok, and custom. Includes config schema, validation, factory wiring,
and comprehensive unit tests.

Co-authored-by: rareba <rareba@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add missing approval_manager field to ChannelRuntimeContext constructors

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

---------

Co-authored-by: rareba <rareba@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 00:34:34 -04:00
Argenis 327e2b4c47 style: cargo fmt Box::pin calls in cron scheduler (#3667)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 23:34:26 -04:00
Argenis 5a5d9ae5f9 fix(lint): Box::pin large futures in cron scheduler and cron_run tool (#3666)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 23:25:28 -04:00
Argenis d8f228bd15 Merge pull request #3661 from zeroclaw-labs/work/multi-client-workspaces
feat(workspace): add multi-client workspace isolation
2026-03-15 23:10:01 -04:00
Argenis d5eeaed3d9 Merge pull request #3649 from zeroclaw-labs/work/capability-tool-access
feat(security): add capability-based tool access control
2026-03-15 23:09:51 -04:00
Argenis 429094b049 Merge pull request #3660 from zeroclaw-labs/fix/cron-large-future
fix: add Box::pin for large future and missing approval_manager in tests
2026-03-15 23:08:47 -04:00
argenis de la rosa 80213b08ef feat(workspace): add multi-client workspace isolation
Add workspace profile management, security boundary enforcement, and
a workspace management tool for isolated client engagements.

Original work by @rareba. Supersedes #3597 — rebased on latest master.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 22:41:18 -04:00
argenis de la rosa bf67124499 fix: add Box::pin for large future and missing approval_manager in tests
- Box::pin the cron_run execute_job_now call to satisfy clippy::large_futures
- Add missing approval_manager field to 4 query_classification test constructors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 22:32:06 -04:00
argenis de la rosa cb250dfecf fix: add missing approval_manager field to ChannelRuntimeContext test constructors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 20:03:59 -04:00
argenis de la rosa fabd35c4ea feat(security): add capability-based tool access control
Add an optional `allowed_tools` parameter that restricts which tools are
available to the agent. When `Some(list)`, only tools whose name appears
in the list are retained; when `None`, all tools remain available
(backward compatible). This enables fine-grained capability control for
cron jobs, heartbeat tasks, and CLI invocations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 19:34:34 -04:00
Argenis a695ca4b9c fix(onboard): auto-detect TTY instead of --interactive flag (#3573)
Remove the --interactive flag from `zeroclaw onboard`. The command now
auto-detects whether stdin/stdout are a TTY: if yes and no provider
flags are given, it launches the full interactive wizard; otherwise it
runs the quick (scriptable) setup path.

This means all three install methods work with a single flow:
  curl -fsSL https://zeroclawlabs.ai/install.sh | bash
  cargo install zeroclawlabs && zeroclaw onboard
  docker run … zeroclaw onboard --api-key …
2026-03-15 19:25:55 -04:00
Argenis 811fab3b87 fix(service): headless browser works in service mode (systemd/OpenRC) (#3645)
When zeroclaw runs as a service, the process inherits a minimal
environment without HOME, DISPLAY, or user namespaces. Headless
browsers (Chromium/Firefox) need HOME for profile/cache dirs and
fail with sandbox errors without user namespaces.

- Detect service environment via INVOCATION_ID, JOURNAL_STREAM,
  or missing HOME on Linux
- Auto-apply --no-sandbox and --disable-dev-shm-usage for Chrome
  in service mode
- Set HOME fallback and CHROMIUM_FLAGS on agent-browser commands
- systemd unit: add Environment=HOME=%h and PassEnvironment
- OpenRC script: export HOME=/var/lib/zeroclaw with start_pre()
  to create the directory

Closes #3584
2026-03-15 19:16:36 -04:00
Argenis 1a5d91fe69 fix(channels): wire query_classification config into channel message processing (#3619)
The QueryClassificationConfig was parsed from config but never applied
during channel message processing. This adds the query_classification
field to ChannelRuntimeContext and invokes the classifier in
process_channel_message to override the route when a classification
rule matches a model_routes hint.

Closes #3579
2026-03-15 19:16:32 -04:00
Argenis 6eec1c81b9 fix(ci): use ubuntu-22.04 for Linux release builds (#3573)
Build against glibc 2.35 to ensure binary compatibility with Ubuntu 22.04+.
2026-03-15 18:57:30 -04:00
Argenis 602db8bca1 fix: exclude name field from Mistral tool_calls (#3572)
* fix: exclude name field from Mistral tool_calls (#3572)

Add skip_serializing_if to the compatibility fields (name, arguments,
parameters) on the ToolCall struct so they are omitted from the JSON
payload when None. Mistral's API returns 422 "Extra inputs are not
permitted" when these extra null fields are present in tool_calls.

* fix: format serde attribute for CI lint compliance
2026-03-15 18:38:41 -04:00
simianastronaut 2539bcafe0 fix(gateway): pass bearer token in WebSocket subprotocol for dashboard auth
The dashboard WebSocket client was only sending ['zeroclaw.v1'] as the
protocols parameter, omitting the bearer token subprotocol. When
require_pairing = true, the server extracts the token from
Sec-WebSocket-Protocol as a fallback (browsers cannot set custom
headers on WebSocket connections). Without the bearer.<token> entry
in the protocols array, subprotocol-based authentication always failed.

Include `bearer.<token>` in the protocols array when a token is
available, matching the server's extract_ws_token() expectation.

Closes #3011

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 16:37:41 -04:00
simianastronaut 37d76f7c42 feat(config): support initial_prompt in transcription config for proper noun recognition
Add `initial_prompt: Option<String>` to `TranscriptionConfig` and pass
it as the `prompt` field in the Whisper API multipart POST when present.
This lets users bias transcription toward expected vocabulary (proper
nouns, technical terms) via the config file.

Closes #2881

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 16:31:55 -04:00
simianastronaut 41b46f23e3 docs(setup): add Docker/Podman stop/restart instructions
Users who installed via `./install.sh --docker` had no documented way to
restart the container after stopping it. Add clear lifecycle instructions
(stop, start, restart, logs, health check) to both the bootstrap guide and
the operations runbook, covering docker-compose, manual `docker run`, and
Podman-specific flags.

Closes #3474

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 16:26:28 -04:00
SimianAstronaut7 314e1d3ae8 Merge pull request #3638 from zeroclaw-labs/work-issues/3487-channel-approval-manager
fix(security): enforce approval policy for channel-driven runs
2026-03-15 16:11:14 -04:00
SimianAstronaut7 82be05b1e9 Merge pull request #3636 from zeroclaw-labs/work-issues/3628-surface-tool-failures-in-chat
feat(agent): surface tool call failure reasons in chat
2026-03-15 16:07:38 -04:00
SimianAstronaut7 1373659058 Merge pull request #3634 from zeroclaw-labs/work-issues/3477-fix-matrix-channel-key
fix(channel): use plain "matrix" channel key for consistent outbound routing
2026-03-15 16:07:36 -04:00
Argenis c7f064e866 fix(channels): surface visible warning when whatsapp-web feature is missing (#3629)
The WhatsApp Web QR code was not shown during onboarding channel launch
because the wizard allowed configuring WhatsApp Web mode even when the
binary was built without the `whatsapp-web` feature flag. At runtime,
the channel was silently skipped with only a tracing::warn that most
users never see.

- Add compile-time warning in the onboarding wizard when WhatsApp Web
  mode is selected but the feature is not compiled in
- Add eprintln! in collect_configured_channels so users see a visible
  terminal warning when the feature is missing at startup

Closes #3577
2026-03-15 16:07:13 -04:00
Giulio V 9c1d63e109 feat(hands): add autonomous knowledge-accumulating agent packages (#3603)
Introduce the Hands system — autonomous agent packages that run on
schedules and accumulate knowledge over time. Each Hand maintains a
rolling context of findings across runs so the agent grows smarter
with every execution.

This PR adds:
- Hand definition type (TOML-deserializable, reuses cron Schedule)
- HandRun / HandRunStatus for execution records
- HandContext for rolling cross-run knowledge accumulation
- File-based persistence (load/save context as JSON)
- Directory-based Hand loading from ~/.zeroclaw/hands/*.toml
- 20 unit tests covering deserialization, persistence roundtrip,
  history capping, fact deduplication, and error handling

Execution integration with the agent loop is deferred to a follow-up.
2026-03-15 16:06:14 -04:00
Argenis 966edf1553 Merge pull request #3635 from zeroclaw-labs/chore/bump-v0.3.4
chore: bump version to v0.3.4
2026-03-15 15:59:51 -04:00
simianastronaut a1af84d992 fix(security): enforce approval policy for channel-driven runs
Channel-driven runs (Telegram, Matrix, Discord, etc.) previously bypassed
the ApprovalManager entirely — `None` was passed into the tool-call loop,
so `auto_approve`, `always_ask`, and supervised approval checks were
silently skipped for all non-CLI execution paths.

Add a non-interactive mode to ApprovalManager that enforces the same
autonomy config policies but auto-denies tools requiring interactive
approval (since no operator is present on channel runs). Specifically:

- Add `ApprovalManager::for_non_interactive()` constructor that creates
  a manager which auto-denies tools needing approval instead of prompting
- Add `is_non_interactive()` method so the tool-call loop can distinguish
  interactive (CLI prompt) from non-interactive (auto-deny) managers
- Update tool-call loop: non-interactive managers auto-deny instead of
  the previous auto-approve behavior for non-CLI channels
- Wire the non-interactive approval manager into ChannelRuntimeContext
  so channel runs enforce the full approval policy
- Add 8 tests covering non-interactive approval behavior

Security implications:
- `always_ask` tools are now denied on channels (previously bypassed)
- Supervised-mode unknown tools are now denied on channels (previously
  bypassed)
- `auto_approve` tools continue to work on channels unchanged
- `full` autonomy mode is unaffected (no approval needed regardless)
- `read_only` mode is unaffected (blocks execution elsewhere)

Closes #3487

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:56:57 -04:00
simianastronaut 0ad1965081 feat(agent): surface tool call failure reasons in chat progress messages
When a tool call fails (security policy block, hook cancellation, user
denial, or execution error), the failure reason is now included in the
progress message sent to the chat channel via on_delta. Previously only
a  icon was shown; now users see the actual reason (e.g. "Command not
allowed by security policy") without needing to check `zeroclaw doctor
traces`.

Closes #3628

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:49:27 -04:00
argenis de la rosa 70e8e7ebcd chore: bump version to v0.3.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 15:44:59 -04:00
Alix-007 2bcb82c5b3 fix(python): point docs URL at master branch (#3334)
Co-authored-by: Alix-007 <Alix-007@users.noreply.github.com>
2026-03-15 15:43:35 -04:00
simianastronaut e211b5c3e3 fix(channel): use plain "matrix" channel key for consistent outbound routing
The Matrix channel listener was building channel keys as `matrix:<room_id>`,
but the runtime channel mapping expects the plain key `matrix`. This mismatch
caused replies to silently drop in deployments using the Matrix channel.

Closes #3477

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:42:43 -04:00
Argenis 8691476577 Merge pull request #3624 from zeroclaw-labs/feat/multi-swarm-and-bugfixes
feat(swarm): multi-agent swarm orchestration + bug fixes (#3572, #3573)
2026-03-15 15:42:03 -04:00
SimianAstronaut7 e34a804255 Merge pull request #3632 from zeroclaw-labs/work-issues/3544-fix-codex-sse-buffering
fix(provider): use incremental SSE stream reading for openai-codex responses
2026-03-15 15:34:39 -04:00
SimianAstronaut7 6120b3f705 Merge pull request #3630 from zeroclaw-labs/work-issues/3567-allow-commands-bypass-high-risk
fix(security): let explicit allowed_commands bypass high-risk block
2026-03-15 15:34:37 -04:00
SimianAstronaut7 f175261e32 Merge pull request #3631 from zeroclaw-labs/work-issues/3486-fix-matrix-image-marker
fix(channels): use canonical IMAGE marker in Matrix channel
2026-03-15 15:34:31 -04:00
simianastronaut fd9f66cad7 fix(provider): use incremental SSE stream reading for openai-codex responses
Replace full-body buffering (`response.text().await`) in
`decode_responses_body()` with incremental `bytes_stream()` chunk
processing.  The previous approach held the HTTP connection open until
every byte had arrived; on high-latency links the long-lived connection
would frequently drop mid-read, producing the "error decoding response
body" failure on the first attempt (succeeding only after retry).

Reading chunks incrementally lets each network segment complete within
its own timeout window, eliminating the systematic first-attempt failure.

Closes #3544

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:22:55 -04:00
simianastronaut d928ebc92e fix(channels): use canonical IMAGE marker in Matrix channel
Matrix image messages used lowercase `[image: ...]` format instead of
the canonical `[IMAGE:...]` marker used by all other channels (Telegram,
Slack, Discord, QQ, LinQ). This caused Matrix image attachments to
bypass the multimodal vision pipeline which looks for `[IMAGE:...]`.

Closes #3486

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:14:53 -04:00
simianastronaut 9fca9f478a fix(security): let explicit allowed_commands bypass high-risk block
When `block_high_risk_commands = true`, commands like `curl` and `wget`
were unconditionally blocked even if explicitly listed in
`allowed_commands`. This made it impossible to use legitimate API calls
in full autonomy mode.

Now, if a command is explicitly named in `allowed_commands` (not via
the wildcard `*`), it is exempt from the `block_high_risk_commands`
gate. The wildcard entry intentionally does NOT grant this exemption,
preserving the safety net for broad allowlists.

Other security gates (supervised-mode approval, rate limiting, path
policy, argument validation) remain fully enforced.

Closes #3567

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:13:32 -04:00
SimianAstronaut7 7106632b51 Merge pull request #3627 from zeroclaw-labs/work-issues/3533-fix-utf8-slice-panic
fix(agent): use char-boundary-safe slicing to prevent CJK text panic
2026-03-15 14:36:49 -04:00
SimianAstronaut7 b834278754 Merge pull request #3626 from zeroclaw-labs/work-issues/3563-fix-cron-add-nl-security
fix(cron): add --agent flag so natural language prompts bypass shell security
2026-03-15 14:36:46 -04:00
SimianAstronaut7 186f6d9797 Merge pull request #3625 from zeroclaw-labs/work-issues/3568-http-request-private-hosts
feat(tool): add allow_private_hosts option to http_request tool
2026-03-15 14:36:44 -04:00
simianastronaut 6cdc92a256 fix(agent): use char-boundary-safe slicing to prevent CJK text panic
Replace unsafe byte-index string slicing (`&text[..N]`) with
char-boundary-safe alternatives in memory consolidation and security
redaction to prevent panics when multi-byte UTF-8 characters (e.g.
Chinese/Japanese/Korean) span the slice boundary.

Fixes the same class of bug as the prior fix in `execute_one_tool`
(commit 8fcbb6eb), applied to two remaining instances:
- `src/memory/consolidation.rs`: truncation at byte 4000 and 200
- `src/security/mod.rs`: `redact()` prefix at byte 4

Adds regression tests with CJK input for both locations.

Closes #3533

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:27:09 -04:00
simianastronaut 02599dcd3c fix(cron): add --agent flag to CLI cron commands to bypass shell security validation
The CLI `cron add` command always routed the second positional argument
through shell security policy validation, which blocked natural language
prompts like "Check server health: disk space, memory, CPU load". This
adds an `--agent` flag to `cron add`, `cron add-at`, `cron add-every`,
and `cron once` so that natural language prompts are correctly stored as
agent jobs without shell command validation.

Closes #3563

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:26:45 -04:00
simianastronaut fe64d7ef7e feat(tool): add allow_private_hosts option to http_request tool (#3568)
The http_request tool unconditionally blocked all private/LAN hosts with
no opt-out, preventing legitimate use cases like calling a local Home
Assistant instance or internal APIs. This adds an `allow_private_hosts`
config flag (default: false) under `[http_request]` that, when set to
true, skips the private-host SSRF check while still enforcing the domain
allowlist.

Closes #3568

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:23:54 -04:00
argenis de la rosa 996dbe95cf feat(swarm): multi-agent swarm orchestration, Mistral tool fix, restore --interactive
- Add SwarmTool with sequential (pipeline), parallel (fan-out/fan-in),
  and router (LLM-selected) strategies for multi-agent workflows
- Add SwarmConfig and SwarmStrategy to config schema
- Fix Mistral 422 error by adding skip_serializing_if to ToolCall
  compat fields (name, arguments, parameters, kind) — Fixes #3572
- Restore `zeroclaw onboard --interactive` flag with run_wizard
  routing and mutual-exclusion validation — Fixes #3573
- 20 new swarm tests, 2 serialization tests, 1 CLI test, config tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 14:23:20 -04:00
Argenis 45f953be6d Merge pull request #3578 from zeroclaw-labs/chore/bump-v0.3.3
chore: bump version to v0.3.3
2026-03-15 09:53:13 -04:00
argenis de la rosa 82f29bbcb1 chore: bump version to v0.3.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 09:41:22 -04:00
Argenis 93b5a0b824 feat(context): token-based compaction, persistent sessions, and LLM consolidation (#3574)
Comprehensive long-running context upgrades:

- Token-based compaction: replace message-count trigger with token
  estimation (~4 chars/token). Compaction fires when estimated tokens
  exceed max_context_tokens (default 32K) OR message count exceeds
  max_history_messages. Cuts at user-turn boundaries only.

- Persistent sessions: JSONL append-only session files per channel
  sender in {workspace}/sessions/. Sessions survive daemon restarts.
  Hydrates in-memory history from disk on startup.

- LLM-driven memory consolidation: two-phase extraction after each
  conversation turn. Phase 1 writes a timestamped history entry (Daily).
  Phase 2 extracts new facts/preferences to Core memory (if any).
  Replaces raw message auto-save with semantic extraction.

- New config fields: agent.max_context_tokens (32000),
  channels_config.session_persistence (true).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 09:25:23 -04:00
Argenis 08a67c4a2d chore: bump version to v0.3.2 (#3564)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 06:47:37 -04:00
Argenis c86a0673ba feat(heartbeat): two-phase execution, structured tasks, and auto-routing (#3562)
Upgrade heartbeat system with 4 key improvements:

- Two-phase heartbeat: Phase 1 asks LLM "skip or run?" to save API cost
  on quiet periods. Phase 2 executes only selected tasks.
- Structured task format: `- [priority|status] task text` with
  high/medium/low priority and active/paused/completed status.
- Decision intelligence: LLM-driven smart filtering via structured prompt
  at temperature 0.0 for deterministic decisions.
- Delivery routing: auto-detect best configured channel when no explicit
  target is set (telegram > discord > slack > mattermost).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 06:11:59 -04:00
Argenis cabf99ba07 Merge pull request #3539 from zeroclaw-labs/cleanup
chore: add .wrangler/ to gitignore
2026-03-14 22:53:12 -04:00
argenis de la rosa 2d978a6b64 chore: add .wrangler/ to gitignore and clean up stale files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 22:41:17 -04:00
Argenis 4dbc9266c1 Merge pull request #3536 from zeroclaw-labs/test/termux-release-validation
test: add Termux release validation script
2026-03-14 22:21:21 -04:00
argenis de la rosa ea0b3c8c8c test: add Termux release validation script
Validates the aarch64-linux-android release artifact: download, archive
integrity, ELF format, architecture, checksum, and install.sh detection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 22:10:33 -04:00
Argenis 0c56834385 chore(ci): remove sync-readme workflow and script (#3535)
The auto-generated What's New and Recent Contributors README sections
have been removed, so the sync-readme workflow and its backing script
are no longer needed.
2026-03-14 21:38:04 -04:00
Argenis caccf0035e docs(readme): remove stale What's New and Contributors sections (#3534)
Clear auto-generated sections so they repopulate correctly on the next
release via sync-readme workflow.
2026-03-14 21:36:26 -04:00
Argenis 627b160f55 fix(install): clean up stale cargo tracking from old package name (#3532)
When the crate was renamed from `zeroclaw` to `zeroclawlabs`, users who
installed via install.sh (which uses `cargo install --path`) had the
binary tracked under the old package name. Later running
`cargo install zeroclawlabs` from crates.io fails with:

  error: binary `zeroclaw` already exists as part of `zeroclaw v0.1.9`

The installer now detects and removes stale tracking for the old
`zeroclaw` package name before installing, so both install.sh and
`cargo install zeroclawlabs` work cleanly for upgrades.
2026-03-14 21:20:02 -04:00
Argenis 6463bc84b0 fix(ci): sync tweet and README after all release artifacts are published (#3531)
The tweet was firing on `release: published` immediately when the GitHub
Release was created, but Docker push, crates.io publish, and website
redeploy were still in-flight. This meant users saw the tweet before
they could actually pull the new Docker image or install from crates.io.

Convert tweet-release.yml and sync-readme.yml to reusable workflows
(workflow_call) and call them as the final jobs in both release
pipelines, gated on completion of docker, crates-io, and
redeploy-website jobs.

Before: gh release create → tweet fires immediately (race condition)
After:  gh release create → docker + crates + website → tweet + readme
2026-03-14 21:19:56 -04:00
ZeroClaw Bot f84f1229af docs(readme): auto-sync What's New and Contributors 2026-03-15 01:07:01 +00:00
ZeroClaw Bot f85d21097b docs(readme): auto-sync What's New and Contributors 2026-03-15 01:01:55 +00:00
Argenis 306821d6a2 Merge pull request #3530 from zeroclaw-labs/chore/bump-v0.3.1
chore: bump version to v0.3.1
2026-03-14 20:29:13 -04:00
argenis de la rosa 06f9424274 chore: bump version to v0.3.1
Patch release for Termux/Android support. Corrects from v0.4.0 to v0.3.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 20:17:53 -04:00
Argenis fa14ab4ab2 Merge pull request #3528 from zeroclaw-labs/chore/bump-v0.4.0
chore: bump version to v0.4.0
2026-03-14 20:06:32 -04:00
argenis de la rosa 36a0c8eba9 chore: bump version to v0.4.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 19:49:07 -04:00
Argenis f4c82d5797 Merge pull request #3525 from zeroclaw-labs/feat/termux-release-support
feat(ci): add Termux (aarch64-linux-android) release target
2026-03-14 19:47:50 -04:00
ZeroClaw Bot 5edebf4869 docs(readme): auto-sync What's New and Contributors 2026-03-14 23:47:45 +00:00
argenis de la rosa 613fa79444 feat(ci): add Termux (aarch64-linux-android) release target
Add prebuilt binary support for Termux/Android devices:
- Add aarch64-linux-android to stable and beta release matrices with NDK setup
- Detect Termux in install.sh and map to the correct android target
- Add Termux pkg manager support for system dependency installation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 19:36:44 -04:00
ZeroClaw Bot 44c8e1eaac docs(readme): auto-sync What's New and Contributors 2026-03-14 22:35:02 +00:00
232 changed files with 35517 additions and 7629 deletions
-139
View File
@@ -1,139 +0,0 @@
#!/usr/bin/env bash
# sync-readme.sh — Auto-update "What's New" and "Recent Contributors" in all READMEs
# Called by the sync-readme GitHub Actions workflow on each release.
set -euo pipefail
# --- Resolve version and ranges ---
LATEST_TAG=$(git tag --sort=-creatordate | head -1 || echo "")
if [ -z "$LATEST_TAG" ]; then
echo "No tags found — skipping README sync"
exit 0
fi
VERSION="${LATEST_TAG#v}"
# Find previous stable tag for contributor range
PREV_STABLE=$(git tag --sort=-creatordate \
| grep -v "^${LATEST_TAG}$" \
| grep -vE '\-beta\.' \
| head -1 || echo "")
FEAT_RANGE="${PREV_STABLE:+${PREV_STABLE}..}${LATEST_TAG}"
CONTRIB_RANGE="${PREV_STABLE:+${PREV_STABLE}..}${LATEST_TAG}"
# --- Build "What's New" table rows ---
FEATURES=$(git log "$FEAT_RANGE" --pretty=format:"%s" --no-merges \
| grep -iE '^feat(\(|:)' \
| sed 's/^feat(\([^)]*\)): /| \1 | /' \
| sed 's/^feat: /| General | /' \
| sed 's/ (#[0-9]*)$//' \
| sort -uf \
| while IFS= read -r line; do echo "${line} |"; done || true)
if [ -z "$FEATURES" ]; then
FEATURES="| General | Incremental improvements and polish |"
fi
MONTH_YEAR=$(date -u +"%B %Y")
# --- Build contributor list ---
GIT_AUTHORS=$(git log "$CONTRIB_RANGE" --pretty=format:"%an" --no-merges | sort -uf || true)
CO_AUTHORS=$(git log "$CONTRIB_RANGE" --pretty=format:"%b" --no-merges \
| grep -ioE 'Co-Authored-By: *[^<]+' \
| sed 's/Co-Authored-By: *//i' \
| sed 's/ *$//' \
| sort -uf || true)
ALL_CONTRIBUTORS=$(printf "%s\n%s" "$GIT_AUTHORS" "$CO_AUTHORS" \
| sort -uf \
| grep -v '^$' \
| grep -viE '\[bot\]$|^dependabot|^github-actions|^copilot|^ZeroClaw Bot|^ZeroClaw Runner|^ZeroClaw Agent|^blacksmith' \
|| true)
CONTRIBUTOR_COUNT=$(echo "$ALL_CONTRIBUTORS" | grep -c . || echo "0")
CONTRIBUTOR_LIST=$(echo "$ALL_CONTRIBUTORS" \
| while IFS= read -r name; do
[ -z "$name" ] && continue
echo "- **${name}**"
done || true)
# --- Write temp files for section content ---
WHATS_NEW_FILE=$(mktemp)
cat > "$WHATS_NEW_FILE" <<WHATS_EOF
### 🚀 What's New in ${LATEST_TAG} (${MONTH_YEAR})
| Area | Highlights |
|---|---|
${FEATURES}
WHATS_EOF
CONTRIBUTORS_FILE=$(mktemp)
cat > "$CONTRIBUTORS_FILE" <<CONTRIB_EOF
### 🌟 Recent Contributors (${LATEST_TAG})
${CONTRIBUTOR_COUNT} contributors shipped features, fixes, and improvements in this release cycle:
${CONTRIBUTOR_LIST}
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
CONTRIB_EOF
# --- Replace sections in all README files with markers ---
README_FILES=$(find . -maxdepth 1 -name 'README*.md' -type f | sort)
UPDATED=0
for readme in $README_FILES; do
if ! grep -q 'BEGIN:WHATS_NEW' "$readme"; then
continue
fi
python3 - "$readme" "$WHATS_NEW_FILE" "$CONTRIBUTORS_FILE" <<'PYEOF'
import sys, re
readme_path = sys.argv[1]
whats_new_path = sys.argv[2]
contributors_path = sys.argv[3]
with open(readme_path, 'r') as f:
content = f.read()
with open(whats_new_path, 'r') as f:
whats_new = f.read()
with open(contributors_path, 'r') as f:
contributors = f.read()
content = re.sub(
r'(<!-- BEGIN:WHATS_NEW -->)\n.*?(<!-- END:WHATS_NEW -->)',
r'\1\n' + whats_new + r'\2',
content,
flags=re.DOTALL
)
content = re.sub(
r'(<!-- BEGIN:RECENT_CONTRIBUTORS -->)\n.*?(<!-- END:RECENT_CONTRIBUTORS -->)',
r'\1\n' + contributors + r'\2',
content,
flags=re.DOTALL
)
with open(readme_path, 'w') as f:
f.write(content)
PYEOF
UPDATED=$((UPDATED + 1))
done
rm -f "$WHATS_NEW_FILE" "$CONTRIBUTORS_FILE"
echo "README synced: ${LATEST_TAG}${CONTRIBUTOR_COUNT} contributors — ${UPDATED} files updated"
+169
View File
@@ -0,0 +1,169 @@
name: Pub AUR Package
on:
workflow_call:
inputs:
release_tag:
description: "Existing release tag (vX.Y.Z)"
required: true
type: string
dry_run:
description: "Generate PKGBUILD only (no push)"
required: false
default: false
type: boolean
secrets:
AUR_SSH_KEY:
required: false
workflow_dispatch:
inputs:
release_tag:
description: "Existing release tag (vX.Y.Z)"
required: true
type: string
dry_run:
description: "Generate PKGBUILD only (no push)"
required: false
default: true
type: boolean
concurrency:
group: aur-publish-${{ github.run_id }}
cancel-in-progress: false
permissions:
contents: read
jobs:
publish-aur:
name: Update AUR Package
runs-on: ubuntu-latest
env:
RELEASE_TAG: ${{ inputs.release_tag }}
DRY_RUN: ${{ inputs.dry_run }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate and compute metadata
id: meta
shell: bash
run: |
set -euo pipefail
if [[ ! "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::release_tag must be vX.Y.Z format."
exit 1
fi
version="${RELEASE_TAG#v}"
tarball_url="https://github.com/${GITHUB_REPOSITORY}/archive/refs/tags/${RELEASE_TAG}.tar.gz"
tarball_sha="$(curl -fsSL "$tarball_url" | sha256sum | awk '{print $1}')"
if [[ -z "$tarball_sha" ]]; then
echo "::error::Could not compute SHA256 for source tarball."
exit 1
fi
{
echo "version=$version"
echo "tarball_url=$tarball_url"
echo "tarball_sha=$tarball_sha"
} >> "$GITHUB_OUTPUT"
{
echo "### AUR Package Metadata"
echo "- version: \`${version}\`"
echo "- tarball_url: \`${tarball_url}\`"
echo "- tarball_sha: \`${tarball_sha}\`"
} >> "$GITHUB_STEP_SUMMARY"
- name: Generate PKGBUILD
id: pkgbuild
shell: bash
env:
VERSION: ${{ steps.meta.outputs.version }}
TARBALL_SHA: ${{ steps.meta.outputs.tarball_sha }}
run: |
set -euo pipefail
pkgbuild_file="$(mktemp)"
sed -e "s/^pkgver=.*/pkgver=${VERSION}/" \
-e "s/^sha256sums=.*/sha256sums=('${TARBALL_SHA}')/" \
dist/aur/PKGBUILD > "$pkgbuild_file"
echo "pkgbuild_file=$pkgbuild_file" >> "$GITHUB_OUTPUT"
echo "### Generated PKGBUILD" >> "$GITHUB_STEP_SUMMARY"
echo '```bash' >> "$GITHUB_STEP_SUMMARY"
cat "$pkgbuild_file" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
- name: Generate .SRCINFO
id: srcinfo
shell: bash
env:
VERSION: ${{ steps.meta.outputs.version }}
TARBALL_SHA: ${{ steps.meta.outputs.tarball_sha }}
run: |
set -euo pipefail
srcinfo_file="$(mktemp)"
sed -e "s/pkgver = .*/pkgver = ${VERSION}/" \
-e "s/sha256sums = .*/sha256sums = ${TARBALL_SHA}/" \
-e "s|zeroclaw-[0-9.]*.tar.gz|zeroclaw-${VERSION}.tar.gz|g" \
-e "s|/v[0-9.]*\.tar\.gz|/v${VERSION}.tar.gz|g" \
dist/aur/.SRCINFO > "$srcinfo_file"
echo "srcinfo_file=$srcinfo_file" >> "$GITHUB_OUTPUT"
- name: Push to AUR
if: inputs.dry_run == false
shell: bash
env:
AUR_SSH_KEY: ${{ secrets.AUR_SSH_KEY }}
PKGBUILD_FILE: ${{ steps.pkgbuild.outputs.pkgbuild_file }}
SRCINFO_FILE: ${{ steps.srcinfo.outputs.srcinfo_file }}
VERSION: ${{ steps.meta.outputs.version }}
run: |
set -euo pipefail
if [[ -z "${AUR_SSH_KEY}" ]]; then
echo "::error::Secret AUR_SSH_KEY is required for non-dry-run."
exit 1
fi
mkdir -p ~/.ssh
echo "$AUR_SSH_KEY" > ~/.ssh/aur
chmod 600 ~/.ssh/aur
cat >> ~/.ssh/config <<SSH_CONFIG
Host aur.archlinux.org
IdentityFile ~/.ssh/aur
User aur
StrictHostKeyChecking accept-new
SSH_CONFIG
tmp_dir="$(mktemp -d)"
git clone ssh://aur@aur.archlinux.org/zeroclaw.git "$tmp_dir/aur"
cp "$PKGBUILD_FILE" "$tmp_dir/aur/PKGBUILD"
cp "$SRCINFO_FILE" "$tmp_dir/aur/.SRCINFO"
cd "$tmp_dir/aur"
git config user.name "zeroclaw-bot"
git config user.email "bot@zeroclaw.dev"
git add PKGBUILD .SRCINFO
git commit -m "zeroclaw ${VERSION}"
git push origin HEAD
echo "AUR package updated to ${VERSION}"
- name: Summary
shell: bash
run: |
if [[ "$DRY_RUN" == "true" ]]; then
echo "Dry run complete: PKGBUILD generated, no push performed."
else
echo "Publish complete: AUR package pushed."
fi
+206
View File
@@ -0,0 +1,206 @@
name: Pub Homebrew Core
on:
workflow_dispatch:
inputs:
release_tag:
description: "Existing release tag to publish (vX.Y.Z)"
required: true
type: string
dry_run:
description: "Patch formula only (no push/PR)"
required: false
default: true
type: boolean
concurrency:
group: homebrew-core-${{ github.run_id }}
cancel-in-progress: false
permissions:
contents: read
jobs:
publish-homebrew-core:
name: Publish Homebrew Core PR
runs-on: ubuntu-latest
env:
UPSTREAM_REPO: Homebrew/homebrew-core
FORMULA_PATH: Formula/z/zeroclaw.rb
RELEASE_TAG: ${{ inputs.release_tag }}
DRY_RUN: ${{ inputs.dry_run }}
BOT_FORK_REPO: ${{ vars.HOMEBREW_CORE_BOT_FORK_REPO }}
BOT_EMAIL: ${{ vars.HOMEBREW_CORE_BOT_EMAIL }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate release tag and version alignment
id: release_meta
shell: bash
run: |
set -euo pipefail
semver_pattern='^v[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$'
if [[ ! "$RELEASE_TAG" =~ $semver_pattern ]]; then
echo "::error::release_tag must match semver-like format (vX.Y.Z[-suffix])."
exit 1
fi
if ! git rev-parse "refs/tags/${RELEASE_TAG}" >/dev/null 2>&1; then
git fetch --tags origin
fi
tag_version="${RELEASE_TAG#v}"
cargo_version="$(git show "${RELEASE_TAG}:Cargo.toml" \
| sed -n 's/^version = "\([^"]*\)"/\1/p' | head -n1)"
if [[ -z "$cargo_version" ]]; then
echo "::error::Unable to read Cargo.toml version from tag ${RELEASE_TAG}."
exit 1
fi
if [[ "$cargo_version" != "$tag_version" ]]; then
echo "::error::Tag ${RELEASE_TAG} does not match Cargo.toml version (${cargo_version})."
exit 1
fi
tarball_url="https://github.com/${GITHUB_REPOSITORY}/archive/refs/tags/${RELEASE_TAG}.tar.gz"
tarball_sha="$(curl -fsSL "$tarball_url" | sha256sum | awk '{print $1}')"
{
echo "tag_version=$tag_version"
echo "tarball_url=$tarball_url"
echo "tarball_sha=$tarball_sha"
} >> "$GITHUB_OUTPUT"
{
echo "### Release Metadata"
echo "- release_tag: \`${RELEASE_TAG}\`"
echo "- cargo_version: \`${cargo_version}\`"
echo "- tarball_sha256: \`${tarball_sha}\`"
echo "- dry_run: ${DRY_RUN}"
} >> "$GITHUB_STEP_SUMMARY"
- name: Patch Homebrew formula
id: patch_formula
shell: bash
env:
HOMEBREW_CORE_BOT_TOKEN: ${{ secrets.HOMEBREW_UPSTREAM_PR_TOKEN || secrets.HOMEBREW_CORE_BOT_TOKEN }}
GH_TOKEN: ${{ secrets.HOMEBREW_UPSTREAM_PR_TOKEN || secrets.HOMEBREW_CORE_BOT_TOKEN }}
run: |
set -euo pipefail
tmp_repo="$(mktemp -d)"
echo "tmp_repo=$tmp_repo" >> "$GITHUB_OUTPUT"
if [[ "$DRY_RUN" == "true" ]]; then
git clone --depth=1 "https://github.com/${UPSTREAM_REPO}.git" "$tmp_repo/homebrew-core"
else
if [[ -z "${BOT_FORK_REPO}" ]]; then
echo "::error::Repository variable HOMEBREW_CORE_BOT_FORK_REPO is required when dry_run=false."
exit 1
fi
if [[ -z "${HOMEBREW_CORE_BOT_TOKEN}" ]]; then
echo "::error::Repository secret HOMEBREW_CORE_BOT_TOKEN is required when dry_run=false."
exit 1
fi
if [[ "$BOT_FORK_REPO" != */* ]]; then
echo "::error::HOMEBREW_CORE_BOT_FORK_REPO must be in owner/repo format."
exit 1
fi
if ! gh api "repos/${BOT_FORK_REPO}" >/dev/null 2>&1; then
echo "::error::HOMEBREW_CORE_BOT_TOKEN cannot access ${BOT_FORK_REPO}."
exit 1
fi
gh repo clone "${BOT_FORK_REPO}" "$tmp_repo/homebrew-core" -- --depth=1
fi
repo_dir="$tmp_repo/homebrew-core"
formula_file="$repo_dir/$FORMULA_PATH"
if [[ ! -f "$formula_file" ]]; then
echo "::error::Formula file not found: $FORMULA_PATH"
exit 1
fi
if [[ "$DRY_RUN" == "false" ]]; then
if git -C "$repo_dir" remote get-url upstream >/dev/null 2>&1; then
git -C "$repo_dir" remote set-url upstream "https://github.com/${UPSTREAM_REPO}.git"
else
git -C "$repo_dir" remote add upstream "https://github.com/${UPSTREAM_REPO}.git"
fi
if git -C "$repo_dir" ls-remote --exit-code --heads upstream main >/dev/null 2>&1; then
upstream_ref="main"
else
upstream_ref="master"
fi
git -C "$repo_dir" fetch --depth=1 upstream "$upstream_ref"
branch_name="zeroclaw-${RELEASE_TAG}-${GITHUB_RUN_ID}"
git -C "$repo_dir" checkout -B "$branch_name" "upstream/$upstream_ref"
echo "branch_name=$branch_name" >> "$GITHUB_OUTPUT"
fi
tarball_url="$(grep 'tarball_url=' "$GITHUB_OUTPUT" | head -1 | cut -d= -f2-)"
tarball_sha="$(grep 'tarball_sha=' "$GITHUB_OUTPUT" | head -1 | cut -d= -f2-)"
perl -0pi -e "s|^ url \".*\"| url \"${tarball_url}\"|m" "$formula_file"
perl -0pi -e "s|^ sha256 \".*\"| sha256 \"${tarball_sha}\"|m" "$formula_file"
perl -0pi -e "s|^ license \".*\"| license \"Apache-2.0 OR MIT\"|m" "$formula_file"
git -C "$repo_dir" diff -- "$FORMULA_PATH" > "$tmp_repo/formula.diff"
if [[ ! -s "$tmp_repo/formula.diff" ]]; then
echo "::error::No formula changes generated. Nothing to publish."
exit 1
fi
{
echo "### Formula Diff"
echo '```diff'
cat "$tmp_repo/formula.diff"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
- name: Push branch and open Homebrew PR
if: inputs.dry_run == false
shell: bash
env:
GH_TOKEN: ${{ secrets.HOMEBREW_UPSTREAM_PR_TOKEN || secrets.HOMEBREW_CORE_BOT_TOKEN }}
TMP_REPO: ${{ steps.patch_formula.outputs.tmp_repo }}
BRANCH_NAME: ${{ steps.patch_formula.outputs.branch_name }}
TAG_VERSION: ${{ steps.release_meta.outputs.tag_version }}
TARBALL_URL: ${{ steps.release_meta.outputs.tarball_url }}
TARBALL_SHA: ${{ steps.release_meta.outputs.tarball_sha }}
run: |
set -euo pipefail
repo_dir="${TMP_REPO}/homebrew-core"
fork_owner="${BOT_FORK_REPO%%/*}"
bot_email="${BOT_EMAIL:-${fork_owner}@users.noreply.github.com}"
git -C "$repo_dir" config user.name "$fork_owner"
git -C "$repo_dir" config user.email "$bot_email"
git -C "$repo_dir" add "$FORMULA_PATH"
git -C "$repo_dir" commit -m "zeroclaw ${TAG_VERSION}"
gh auth setup-git
git -C "$repo_dir" push --set-upstream origin "$BRANCH_NAME"
pr_body="Automated formula bump from ZeroClaw release workflow.
- Release tag: ${RELEASE_TAG}
- Source tarball: ${TARBALL_URL}
- Source sha256: ${TARBALL_SHA}"
gh pr create \
--repo "$UPSTREAM_REPO" \
--base main \
--head "${fork_owner}:${BRANCH_NAME}" \
--title "zeroclaw ${TAG_VERSION}" \
--body "$pr_body"
- name: Summary
shell: bash
run: |
if [[ "$DRY_RUN" == "true" ]]; then
echo "Dry run complete: formula diff generated, no push/PR performed."
else
echo "Publish complete: branch pushed and PR opened from bot fork."
fi
+165
View File
@@ -0,0 +1,165 @@
name: Pub Scoop Manifest
on:
workflow_call:
inputs:
release_tag:
description: "Existing release tag (vX.Y.Z)"
required: true
type: string
dry_run:
description: "Generate manifest only (no push)"
required: false
default: false
type: boolean
secrets:
SCOOP_BUCKET_TOKEN:
required: false
workflow_dispatch:
inputs:
release_tag:
description: "Existing release tag (vX.Y.Z)"
required: true
type: string
dry_run:
description: "Generate manifest only (no push)"
required: false
default: true
type: boolean
concurrency:
group: scoop-publish-${{ github.run_id }}
cancel-in-progress: false
permissions:
contents: read
jobs:
publish-scoop:
name: Update Scoop Manifest
runs-on: ubuntu-latest
env:
RELEASE_TAG: ${{ inputs.release_tag }}
DRY_RUN: ${{ inputs.dry_run }}
SCOOP_BUCKET_REPO: ${{ vars.SCOOP_BUCKET_REPO }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate and compute metadata
id: meta
shell: bash
run: |
set -euo pipefail
if [[ ! "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::release_tag must be vX.Y.Z format."
exit 1
fi
version="${RELEASE_TAG#v}"
zip_url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${RELEASE_TAG}/zeroclaw-x86_64-pc-windows-msvc.zip"
sums_url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${RELEASE_TAG}/SHA256SUMS"
sha256="$(curl -fsSL "$sums_url" | grep 'zeroclaw-x86_64-pc-windows-msvc.zip' | awk '{print $1}')"
if [[ -z "$sha256" ]]; then
echo "::error::Could not find Windows binary hash in SHA256SUMS for ${RELEASE_TAG}."
exit 1
fi
{
echo "version=$version"
echo "zip_url=$zip_url"
echo "sha256=$sha256"
} >> "$GITHUB_OUTPUT"
{
echo "### Scoop Manifest Metadata"
echo "- version: \`${version}\`"
echo "- zip_url: \`${zip_url}\`"
echo "- sha256: \`${sha256}\`"
} >> "$GITHUB_STEP_SUMMARY"
- name: Generate manifest
id: manifest
shell: bash
env:
VERSION: ${{ steps.meta.outputs.version }}
ZIP_URL: ${{ steps.meta.outputs.zip_url }}
SHA256: ${{ steps.meta.outputs.sha256 }}
run: |
set -euo pipefail
manifest_file="$(mktemp)"
cat > "$manifest_file" <<MANIFEST
{
"version": "${VERSION}",
"description": "Zero overhead. Zero compromise. 100% Rust. The fastest, smallest AI assistant.",
"homepage": "https://github.com/zeroclaw-labs/zeroclaw",
"license": "MIT|Apache-2.0",
"architecture": {
"64bit": {
"url": "${ZIP_URL}",
"hash": "${SHA256}",
"bin": "zeroclaw.exe"
}
},
"checkver": {
"github": "https://github.com/zeroclaw-labs/zeroclaw"
},
"autoupdate": {
"architecture": {
"64bit": {
"url": "https://github.com/zeroclaw-labs/zeroclaw/releases/download/v\$version/zeroclaw-x86_64-pc-windows-msvc.zip"
}
},
"hash": {
"url": "https://github.com/zeroclaw-labs/zeroclaw/releases/download/v\$version/SHA256SUMS",
"regex": "([a-f0-9]{64})\\\\s+zeroclaw-x86_64-pc-windows-msvc\\\\.zip"
}
}
}
MANIFEST
jq '.' "$manifest_file" > "${manifest_file}.formatted"
mv "${manifest_file}.formatted" "$manifest_file"
echo "manifest_file=$manifest_file" >> "$GITHUB_OUTPUT"
echo "### Generated Manifest" >> "$GITHUB_STEP_SUMMARY"
echo '```json' >> "$GITHUB_STEP_SUMMARY"
cat "$manifest_file" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
- name: Push to Scoop bucket
if: inputs.dry_run == false
shell: bash
env:
GH_TOKEN: ${{ secrets.SCOOP_BUCKET_TOKEN }}
MANIFEST_FILE: ${{ steps.manifest.outputs.manifest_file }}
VERSION: ${{ steps.meta.outputs.version }}
run: |
set -euo pipefail
if [[ -z "${SCOOP_BUCKET_REPO}" ]]; then
echo "::error::Repository variable SCOOP_BUCKET_REPO is required (e.g. zeroclaw-labs/scoop-zeroclaw)."
exit 1
fi
tmp_dir="$(mktemp -d)"
gh repo clone "${SCOOP_BUCKET_REPO}" "$tmp_dir/bucket" -- --depth=1
mkdir -p "$tmp_dir/bucket/bucket"
cp "$MANIFEST_FILE" "$tmp_dir/bucket/bucket/zeroclaw.json"
cd "$tmp_dir/bucket"
git config user.name "zeroclaw-bot"
git config user.email "bot@zeroclaw.dev"
git add bucket/zeroclaw.json
git commit -m "zeroclaw ${VERSION}"
gh auth setup-git
git push origin HEAD
echo "Scoop manifest updated to ${VERSION}"
+12 -1
View File
@@ -103,9 +103,20 @@ jobs:
run: rm -rf web/node_modules web/src web/package.json web/package-lock.json web/tsconfig*.json web/vite.config.ts web/index.html
- name: Publish to crates.io
run: cargo publish --locked --allow-dirty --no-verify
shell: bash
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
VERSION: ${{ needs.detect-version-change.outputs.version }}
run: |
# Publish to crates.io; treat "already exists" as success
# (manual publish or stable workflow may have already published)
OUTPUT=$(cargo publish --locked --allow-dirty --no-verify 2>&1) && exit 0
echo "$OUTPUT"
if echo "$OUTPUT" | grep -q 'already exists'; then
echo "::notice::zeroclawlabs@${VERSION} already on crates.io — skipping"
exit 0
fi
exit 1
- name: Verify published
shell: bash
+11 -1
View File
@@ -75,6 +75,16 @@ jobs:
- name: Publish to crates.io
if: "!inputs.dry_run"
run: cargo publish --locked --allow-dirty --no-verify
shell: bash
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
VERSION: ${{ inputs.version }}
run: |
# Publish to crates.io; treat "already exists" as success
OUTPUT=$(cargo publish --locked --allow-dirty --no-verify 2>&1) && exit 0
echo "$OUTPUT"
if echo "$OUTPUT" | grep -q 'already exists'; then
echo "::notice::zeroclawlabs@${VERSION} already on crates.io — skipping"
exit 0
fi
exit 1
+65 -8
View File
@@ -5,8 +5,8 @@ on:
branches: [master]
concurrency:
group: release
cancel-in-progress: false
group: release-beta
cancel-in-progress: true
permissions:
contents: write
@@ -155,11 +155,13 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
# Use ubuntu-22.04 for Linux builds to link against glibc 2.35,
# ensuring compatibility with Ubuntu 22.04+ (#3573).
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
artifact: zeroclaw
ext: tar.gz
- os: ubuntu-latest
- os: ubuntu-22.04
target: aarch64-unknown-linux-gnu
artifact: zeroclaw
ext: tar.gz
@@ -170,6 +172,11 @@ jobs:
target: aarch64-apple-darwin
artifact: zeroclaw
ext: tar.gz
- os: ubuntu-latest
target: aarch64-linux-android
artifact: zeroclaw
ext: tar.gz
ndk: true
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: zeroclaw.exe
@@ -182,6 +189,8 @@ jobs:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
if: runner.os != 'Windows'
with:
prefix-key: ${{ matrix.os }}-${{ matrix.target }}
- uses: actions/download-artifact@v4
with:
@@ -194,6 +203,10 @@ jobs:
sudo apt-get update -qq
sudo apt-get install -y ${{ matrix.cross_compiler }}
- name: Setup Android NDK
if: matrix.ndk
run: echo "$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin" >> "$GITHUB_PATH"
- name: Build release
shell: bash
run: |
@@ -281,10 +294,43 @@ jobs:
name: Push Docker Image
needs: [version, build]
runs-on: ubuntu-latest
timeout-minutes: 60
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: zeroclaw-x86_64-unknown-linux-gnu
path: artifacts/
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: zeroclaw-aarch64-unknown-linux-gnu
path: artifacts/
- name: Prepare Docker context with pre-built binaries
run: |
mkdir -p docker-ctx/bin/amd64 docker-ctx/bin/arm64
tar xzf artifacts/zeroclaw-x86_64-unknown-linux-gnu.tar.gz -C docker-ctx/bin/amd64
tar xzf artifacts/zeroclaw-aarch64-unknown-linux-gnu.tar.gz -C docker-ctx/bin/arm64
mkdir -p docker-ctx/zeroclaw-data/.zeroclaw docker-ctx/zeroclaw-data/workspace
printf '%s\n' \
'workspace_dir = "/zeroclaw-data/workspace"' \
'config_path = "/zeroclaw-data/.zeroclaw/config.toml"' \
'api_key = ""' \
'default_provider = "openrouter"' \
'default_model = "anthropic/claude-sonnet-4-20250514"' \
'default_temperature = 0.7' \
'' \
'[gateway]' \
'port = 42617' \
'host = "[::]"' \
'allow_public_bind = true' \
> docker-ctx/zeroclaw-data/.zeroclaw/config.toml
cp Dockerfile.ci docker-ctx/Dockerfile
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
@@ -296,11 +342,22 @@ jobs:
- name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
context: docker-ctx
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.version.outputs.tag }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:beta
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
# ── Post-publish: tweet after release + website are live ──────────────
# Docker is slow (multi-platform) and can be cancelled by concurrency;
# don't let it block the tweet.
tweet:
name: Tweet Release
needs: [version, publish, redeploy-website]
if: ${{ !cancelled() && needs.publish.result == 'success' }}
uses: ./.github/workflows/tweet-release.yml
with:
release_tag: ${{ needs.version.outputs.tag }}
release_url: https://github.com/zeroclaw-labs/zeroclaw/releases/tag/${{ needs.version.outputs.tag }}
secrets: inherit
+91 -11
View File
@@ -156,11 +156,13 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
# Use ubuntu-22.04 for Linux builds to link against glibc 2.35,
# ensuring compatibility with Ubuntu 22.04+ (#3573).
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
artifact: zeroclaw
ext: tar.gz
- os: ubuntu-latest
- os: ubuntu-22.04
target: aarch64-unknown-linux-gnu
artifact: zeroclaw
ext: tar.gz
@@ -171,6 +173,11 @@ jobs:
target: aarch64-apple-darwin
artifact: zeroclaw
ext: tar.gz
- os: ubuntu-latest
target: aarch64-linux-android
artifact: zeroclaw
ext: tar.gz
ndk: true
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: zeroclaw.exe
@@ -183,6 +190,8 @@ jobs:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
if: runner.os != 'Windows'
with:
prefix-key: ${{ matrix.os }}-${{ matrix.target }}
- uses: actions/download-artifact@v4
with:
@@ -195,6 +204,10 @@ jobs:
sudo apt-get update -qq
sudo apt-get install -y ${{ matrix.cross_compiler }}
- name: Setup Android NDK
if: matrix.ndk
run: echo "$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin" >> "$GITHUB_PATH"
- name: Build release
shell: bash
run: |
@@ -294,13 +307,16 @@ jobs:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
VERSION: ${{ inputs.version }}
run: |
# Skip if this version is already on crates.io (auto-sync may have published it)
# Publish to crates.io; treat "already exists" as success
# (auto-publish workflow may have already published this version)
CRATE_NAME=$(sed -n 's/^name = "\([^"]*\)"/\1/p' Cargo.toml | head -1)
if curl -sfL "https://crates.io/api/v1/crates/${CRATE_NAME}/${VERSION}" | grep -q '"version"'; then
echo "::notice::${CRATE_NAME}@${VERSION} already published on crates.io — skipping"
else
cargo publish --locked --allow-dirty --no-verify
OUTPUT=$(cargo publish --locked --allow-dirty --no-verify 2>&1) && exit 0
echo "$OUTPUT"
if echo "$OUTPUT" | grep -q 'already exists'; then
echo "::notice::${CRATE_NAME}@${VERSION} already on crates.io — skipping"
exit 0
fi
exit 1
redeploy-website:
name: Trigger Website Redeploy
@@ -321,10 +337,43 @@ jobs:
name: Push Docker Image
needs: [validate, build]
runs-on: ubuntu-latest
timeout-minutes: 60
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: zeroclaw-x86_64-unknown-linux-gnu
path: artifacts/
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: zeroclaw-aarch64-unknown-linux-gnu
path: artifacts/
- name: Prepare Docker context with pre-built binaries
run: |
mkdir -p docker-ctx/bin/amd64 docker-ctx/bin/arm64
tar xzf artifacts/zeroclaw-x86_64-unknown-linux-gnu.tar.gz -C docker-ctx/bin/amd64
tar xzf artifacts/zeroclaw-aarch64-unknown-linux-gnu.tar.gz -C docker-ctx/bin/arm64
mkdir -p docker-ctx/zeroclaw-data/.zeroclaw docker-ctx/zeroclaw-data/workspace
printf '%s\n' \
'workspace_dir = "/zeroclaw-data/workspace"' \
'config_path = "/zeroclaw-data/.zeroclaw/config.toml"' \
'api_key = ""' \
'default_provider = "openrouter"' \
'default_model = "anthropic/claude-sonnet-4-20250514"' \
'default_temperature = 0.7' \
'' \
'[gateway]' \
'port = 42617' \
'host = "[::]"' \
'allow_public_bind = true' \
> docker-ctx/zeroclaw-data/.zeroclaw/config.toml
cp Dockerfile.ci docker-ctx/Dockerfile
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
@@ -336,11 +385,42 @@ jobs:
- name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
context: docker-ctx
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.validate.outputs.tag }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
# ── Post-publish: package manager auto-sync ─────────────────────────
scoop:
name: Update Scoop Manifest
needs: [validate, publish]
if: ${{ !cancelled() && needs.publish.result == 'success' }}
uses: ./.github/workflows/pub-scoop.yml
with:
release_tag: ${{ needs.validate.outputs.tag }}
dry_run: false
secrets: inherit
aur:
name: Update AUR Package
needs: [validate, publish]
if: ${{ !cancelled() && needs.publish.result == 'success' }}
uses: ./.github/workflows/pub-aur.yml
with:
release_tag: ${{ needs.validate.outputs.tag }}
dry_run: false
secrets: inherit
# ── Post-publish: tweet after release + website are live ──────────────
# Docker push can be slow; don't let it block the tweet.
tweet:
name: Tweet Release
needs: [validate, publish, redeploy-website]
if: ${{ !cancelled() && needs.publish.result == 'success' }}
uses: ./.github/workflows/tweet-release.yml
with:
release_tag: ${{ needs.validate.outputs.tag }}
release_url: https://github.com/zeroclaw-labs/zeroclaw/releases/tag/${{ needs.validate.outputs.tag }}
secrets: inherit
-33
View File
@@ -1,33 +0,0 @@
name: Sync README
on:
release:
types: [published]
workflow_dispatch:
permissions:
contents: write
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
token: ${{ secrets.RELEASE_TOKEN }}
- name: Sync README sections
run: bash .github/scripts/sync-readme.sh
- name: Commit and push
run: |
git config user.name "ZeroClaw Bot"
git config user.email "bot@zeroclawlabs.ai"
if git diff --quiet -- 'README*.md'; then
echo "No README changes — skipping commit"
exit 0
fi
git add README*.md
git commit -m "docs(readme): auto-sync What's New and Contributors"
git push origin HEAD:master
+38 -12
View File
@@ -1,8 +1,26 @@
name: Tweet Release
on:
release:
types: [published]
# Called by release workflows AFTER all publish steps (docker, crates, website) complete.
workflow_call:
inputs:
release_tag:
description: "Release tag (e.g. v0.3.0 or v0.3.0-beta.42)"
required: true
type: string
release_url:
description: "GitHub Release URL"
required: true
type: string
secrets:
TWITTER_CONSUMER_API_KEY:
required: false
TWITTER_CONSUMER_API_SECRET_KEY:
required: false
TWITTER_ACCESS_TOKEN:
required: false
TWITTER_ACCESS_TOKEN_SECRET:
required: false
workflow_dispatch:
inputs:
tweet_text:
@@ -26,7 +44,7 @@ jobs:
id: check
shell: bash
env:
RELEASE_TAG: ${{ github.event.release.tag_name || '' }}
RELEASE_TAG: ${{ inputs.release_tag || '' }}
MANUAL_TEXT: ${{ inputs.tweet_text || '' }}
run: |
# Manual dispatch always proceeds
@@ -35,7 +53,15 @@ jobs:
exit 0
fi
# Find the PREVIOUS release tag (including betas) to check for new features
# Stable releases (no -beta suffix) always tweet — they represent
# the full release cycle, so skipping them loses visibility.
if [[ ! "$RELEASE_TAG" =~ -beta\. ]]; then
echo "Stable release ${RELEASE_TAG} — always tweet"
echo "skip=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# For betas: find the PREVIOUS release tag to check for new features
PREV_TAG=$(git tag --sort=-creatordate \
| grep -v "^${RELEASE_TAG}$" \
| head -1 || echo "")
@@ -45,15 +71,15 @@ jobs:
exit 0
fi
# Count new feat() commits since the previous release
NEW_FEATS=$(git log "${PREV_TAG}..${RELEASE_TAG}" --pretty=format:"%s" --no-merges \
| grep -ciE '^feat(\(|:)' || echo "0")
# Count new feat() OR fix() commits since the previous release
NEW_CHANGES=$(git log "${PREV_TAG}..${RELEASE_TAG}" --pretty=format:"%s" --no-merges \
| grep -ciE '^(feat|fix)(\(|:)' || echo "0")
if [ "$NEW_FEATS" -eq 0 ]; then
echo "No new features since ${PREV_TAG} — skipping tweet"
if [ "$NEW_CHANGES" -eq 0 ]; then
echo "No new features or fixes since ${PREV_TAG} — skipping tweet"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "${NEW_FEATS} new feature(s) since ${PREV_TAG} — tweeting"
echo "${NEW_CHANGES} new change(s) since ${PREV_TAG} — tweeting"
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
@@ -62,8 +88,8 @@ jobs:
if: steps.check.outputs.skip != 'true'
shell: bash
env:
RELEASE_TAG: ${{ github.event.release.tag_name || '' }}
RELEASE_URL: ${{ github.event.release.html_url || '' }}
RELEASE_TAG: ${{ inputs.release_tag || '' }}
RELEASE_URL: ${{ inputs.release_url || '' }}
MANUAL_TEXT: ${{ inputs.tweet_text || '' }}
run: |
set -euo pipefail
+7 -2
View File
@@ -1,6 +1,8 @@
/target
/target-*/
firmware/*/target
web/dist/
web/dist/*
!web/dist/.gitkeep
*.db
*.db-journal
.DS_Store
@@ -43,4 +45,7 @@ credentials.json
lcov.info
# IDE's stuff
.idea
.idea
# Wrangler cache
.wrangler/
Generated
+1 -1
View File
@@ -7945,7 +7945,7 @@ dependencies = [
[[package]]
name = "zeroclawlabs"
version = "0.3.0"
version = "0.4.3"
dependencies = [
"anyhow",
"async-imap",
+1 -1
View File
@@ -4,7 +4,7 @@ resolver = "2"
[package]
name = "zeroclawlabs"
version = "0.3.0"
version = "0.4.3"
edition = "2021"
authors = ["theonlyhennygod"]
license = "MIT OR Apache-2.0"
+36 -11
View File
@@ -1,7 +1,13 @@
# syntax=docker/dockerfile:1.7
# Pre-built CI binaries context (empty locally; overridden via --build-context in CI)
FROM scratch AS ci-binaries
# ── Stage 1: Build ────────────────────────────────────────────
FROM rust:1.93-slim@sha256:9663b80a1621253d30b146454f903de48f0af925c967be48c84745537cd35d8b AS builder
FROM rust:1.94-slim@sha256:da9dab7a6b8dd428e71718402e97207bb3e54167d37b5708616050b1e8f60ed6 AS builder
ARG PREBUILT_BINARY=""
ARG TARGETARCH
WORKDIR /app
@@ -16,16 +22,22 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
COPY Cargo.toml Cargo.lock ./
COPY crates/robot-kit/Cargo.toml crates/robot-kit/Cargo.toml
# Create dummy targets declared in Cargo.toml so manifest parsing succeeds.
RUN mkdir -p src benches crates/robot-kit/src \
&& echo "fn main() {}" > src/main.rs \
&& echo "" > src/lib.rs \
&& echo "fn main() {}" > benches/agent_benchmarks.rs \
&& echo "pub fn placeholder() {}" > crates/robot-kit/src/lib.rs
RUN if [ -z "$PREBUILT_BINARY" ]; then \
mkdir -p src benches crates/robot-kit/src && \
echo "fn main() {}" > src/main.rs && \
echo "" > src/lib.rs && \
echo "fn main() {}" > benches/agent_benchmarks.rs && \
echo "pub fn placeholder() {}" > crates/robot-kit/src/lib.rs; \
fi
RUN --mount=type=cache,id=zeroclaw-cargo-registry,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,id=zeroclaw-cargo-git,target=/usr/local/cargo/git,sharing=locked \
--mount=type=cache,id=zeroclaw-target,target=/app/target,sharing=locked \
cargo build --release --locked
RUN rm -rf src benches crates/robot-kit/src
if [ -z "$PREBUILT_BINARY" ]; then \
cargo build --release --locked; \
fi
RUN if [ -z "$PREBUILT_BINARY" ]; then \
rm -rf src benches crates/robot-kit/src; \
fi
# 2. Copy only build-relevant source paths (avoid cache-busting on docs/tests/scripts)
COPY src/ src/
@@ -33,6 +45,7 @@ COPY benches/ benches/
COPY crates/ crates/
COPY firmware/ firmware/
COPY web/ web/
COPY *.rs .
# Keep release builds resilient when frontend dist assets are not prebuilt in Git.
RUN mkdir -p web/dist && \
if [ ! -f web/dist/index.html ]; then \
@@ -50,12 +63,24 @@ RUN mkdir -p web/dist && \
' </body>' \
'</html>' > web/dist/index.html; \
fi
RUN if [ -z "$PREBUILT_BINARY" ]; then touch src/main.rs; fi
RUN --mount=type=cache,id=zeroclaw-cargo-registry,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,id=zeroclaw-cargo-git,target=/usr/local/cargo/git,sharing=locked \
--mount=type=cache,id=zeroclaw-target,target=/app/target,sharing=locked \
cargo build --release --locked && \
cp target/release/zeroclaw /app/zeroclaw && \
strip /app/zeroclaw
--mount=from=ci-binaries,target=/ci-bin \
if [ -z "$PREBUILT_BINARY" ]; then \
rm -rf target/release/.fingerprint/zeroclawlabs-* \
target/release/deps/zeroclawlabs-* \
target/release/incremental/zeroclawlabs-* && \
cargo build --release --locked && \
cp target/release/zeroclaw /app/zeroclaw && \
strip /app/zeroclaw; \
else \
cp "/ci-bin/${TARGETARCH}/zeroclaw" /app/zeroclaw && \
strip /app/zeroclaw; \
fi
RUN size=$(stat -c%s /app/zeroclaw 2>/dev/null || stat -f%z /app/zeroclaw) && \
if [ "$size" -lt 1000000 ]; then echo "ERROR: binary too small (${size} bytes), likely dummy build artifact" && exit 1; fi
# Prepare runtime directory structure and default config inline (no extra stage)
RUN mkdir -p /zeroclaw-data/.zeroclaw /zeroclaw-data/workspace && \
+25
View File
@@ -0,0 +1,25 @@
# Dockerfile.ci — CI/release image using pre-built binaries.
# Used by release workflows to skip the ~60 min Rust compilation.
# The main Dockerfile is still used for local dev builds.
# ── Runtime (Distroless) ─────────────────────────────────────
FROM gcr.io/distroless/cc-debian13:nonroot@sha256:84fcd3c223b144b0cb6edc5ecc75641819842a9679a3a58fd6294bec47532bf7
ARG TARGETARCH
# Copy the pre-built binary for this platform (amd64 or arm64)
COPY bin/${TARGETARCH}/zeroclaw /usr/local/bin/zeroclaw
# Runtime directory structure and default config
COPY --chown=65534:65534 zeroclaw-data/ /zeroclaw-data/
ENV LANG=C.UTF-8
ENV ZEROCLAW_WORKSPACE=/zeroclaw-data/workspace
ENV HOME=/zeroclaw-data
ENV ZEROCLAW_GATEWAY_PORT=42617
WORKDIR /zeroclaw-data
USER 65534:65534
EXPOSE 42617
ENTRYPOINT ["zeroclaw"]
CMD ["gateway"]
+32 -10
View File
@@ -15,8 +15,14 @@
# Or with docker compose:
# docker compose -f docker-compose.yml -f docker-compose.debian.yml up
# Pre-built CI binaries context (empty locally; overridden via --build-context in CI)
FROM scratch AS ci-binaries
# ── Stage 1: Build (identical to main Dockerfile) ───────────
FROM rust:1.93-slim@sha256:9663b80a1621253d30b146454f903de48f0af925c967be48c84745537cd35d8b AS builder
FROM rust:1.94-slim@sha256:da9dab7a6b8dd428e71718402e97207bb3e54167d37b5708616050b1e8f60ed6 AS builder
ARG PREBUILT_BINARY=""
ARG TARGETARCH
WORKDIR /app
@@ -31,15 +37,22 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
COPY Cargo.toml Cargo.lock ./
COPY crates/robot-kit/Cargo.toml crates/robot-kit/Cargo.toml
# Create dummy targets declared in Cargo.toml so manifest parsing succeeds.
RUN mkdir -p src benches crates/robot-kit/src \
&& echo "fn main() {}" > src/main.rs \
&& echo "fn main() {}" > benches/agent_benchmarks.rs \
&& echo "pub fn placeholder() {}" > crates/robot-kit/src/lib.rs
RUN if [ -z "$PREBUILT_BINARY" ]; then \
mkdir -p src benches crates/robot-kit/src && \
echo "fn main() {}" > src/main.rs && \
echo "" > src/lib.rs && \
echo "fn main() {}" > benches/agent_benchmarks.rs && \
echo "pub fn placeholder() {}" > crates/robot-kit/src/lib.rs; \
fi
RUN --mount=type=cache,id=zeroclaw-cargo-registry,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,id=zeroclaw-cargo-git,target=/usr/local/cargo/git,sharing=locked \
--mount=type=cache,id=zeroclaw-target,target=/app/target,sharing=locked \
cargo build --release --locked
RUN rm -rf src benches crates/robot-kit/src
if [ -z "$PREBUILT_BINARY" ]; then \
cargo build --release --locked; \
fi
RUN if [ -z "$PREBUILT_BINARY" ]; then \
rm -rf src benches crates/robot-kit/src; \
fi
# 2. Copy only build-relevant source paths (avoid cache-busting on docs/tests/scripts)
COPY src/ src/
@@ -64,12 +77,21 @@ RUN mkdir -p web/dist && \
' </body>' \
'</html>' > web/dist/index.html; \
fi
RUN if [ -z "$PREBUILT_BINARY" ]; then touch src/main.rs; fi
RUN --mount=type=cache,id=zeroclaw-cargo-registry,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,id=zeroclaw-cargo-git,target=/usr/local/cargo/git,sharing=locked \
--mount=type=cache,id=zeroclaw-target,target=/app/target,sharing=locked \
cargo build --release --locked && \
cp target/release/zeroclaw /app/zeroclaw && \
strip /app/zeroclaw
--mount=from=ci-binaries,target=/ci-bin \
if [ -z "$PREBUILT_BINARY" ]; then \
cargo build --release --locked && \
cp target/release/zeroclaw /app/zeroclaw && \
strip /app/zeroclaw; \
else \
cp "/ci-bin/${TARGETARCH}/zeroclaw" /app/zeroclaw && \
strip /app/zeroclaw; \
fi
RUN size=$(stat -c%s /app/zeroclaw 2>/dev/null || stat -f%z /app/zeroclaw) && \
if [ "$size" -lt 1000000 ]; then echo "ERROR: binary too small (${size} bytes), likely dummy build artifact" && exit 1; fi
# Prepare runtime directory structure and default config inline (no extra stage)
RUN mkdir -p /zeroclaw-data/.zeroclaw /zeroclaw-data/workspace && \
+7 -6
View File
@@ -88,11 +88,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ zeroclaw version # عرض الإصدار ومعلومات البنا
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ channels:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Postaveno studenty a členy komunit Harvard, MIT a Sundai.Club.
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ Stavíme v open source protože nejlepší nápady přicházejí odkudkoliv. Pok
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ Hvis ZeroClaw er nyttigt for dig, overvej venligst at købe os en kaffe:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -92,11 +92,11 @@ Erstellt von Studenten und Mitgliedern der Harvard, MIT und Sundai.Club Gemeinsc
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -429,12 +429,13 @@ Wir bauen in Open Source, weil die besten Ideen von überall kommen. Wenn du das
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -56,11 +56,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -189,12 +189,13 @@ channels:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Construido por estudiantes y miembros de las comunidades de Harvard, MIT y Sunda
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ Construimos en código abierto porque las mejores ideas vienen de todas partes.
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ Jos ZeroClaw on hyödyllinen sinulle, harkitse kahvin ostamista meille:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -86,11 +86,11 @@ Construit par des étudiants et membres des communautés Harvard, MIT et Sundai.
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -423,12 +423,13 @@ Nous construisons en open source parce que les meilleures idées viennent de par
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -208,12 +208,13 @@ channels:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ channels:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ Ha a ZeroClaw hasznos az Ön számára, kérjük, fontolja meg, hogy vesz nekün
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ Jika ZeroClaw berguna bagi Anda, mohon pertimbangkan untuk membelikan kami kopi:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Costruito da studenti e membri delle comunità Harvard, MIT e Sundai.Club.
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ Costruiamo in open source perché le migliori idee vengono da ovunque. Se stai l
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -77,11 +77,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -237,12 +237,13 @@ zeroclaw agent --provider anthropic -m "hello"
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Harvard, MIT, 그리고 Sundai.Club 커뮤니티의 학생들과 멤버들이
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ ZeroClaw가 당신의 작업에 도움이 되었고 지속적인 개발을 지
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
-17
View File
@@ -85,13 +85,6 @@ Built by students and members of the Harvard, MIT, and Sundai.Club communities.
<p align="center"><code>Trait-driven architecture · secure-by-default runtime · provider/channel/tool swappable · pluggable everything</code></p>
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
<!-- END:WHATS_NEW -->
### 📢 Announcements
@@ -481,16 +474,6 @@ A heartfelt thank you to the communities and institutions that inspire and fuel
We're building in the open because the best ideas come from everywhere. If you're reading this, you're part of it. Welcome. 🦀❤️
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
<!-- END:RECENT_CONTRIBUTORS -->
## ⚠️ Official Repository & Impersonation Warning
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ Hvis ZeroClaw er nyttig for deg, vennligst vurder å kjøpe oss en kaffe:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Gebouwd door studenten en leden van de Harvard, MIT en Sundai.Club gemeenschappe
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ We bouwen in open source omdat de beste ideeën van overal komen. Als je dit lee
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Zbudowany przez studentów i członków społeczności Harvard, MIT i Sundai.Clu
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ Budujemy w open source ponieważ najlepsze pomysły przychodzą zewsząd. Jeśli
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Construído por estudantes e membros das comunidades Harvard, MIT e Sundai.Club.
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ Construímos em código aberto porque as melhores ideias vêm de todo lugar. Se
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ Dacă ZeroClaw îți este util, te rugăm să iei în considerare să ne cumperi
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -77,11 +77,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -237,12 +237,13 @@ zeroclaw agent --provider anthropic -m "hello"
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ Om ZeroClaw är användbart för dig, vänligen överväg att köpa en kaffe til
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ channels:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Binuo ng mga mag-aaral at miyembro ng Harvard, MIT, at Sundai.Club na komunidad.
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ Kami ay bumubuo sa open source dahil ang mga pinakamahusay na ideya ay nagmumula
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -88,11 +88,11 @@ Harvard, MIT ve Sundai.Club topluluklarının öğrencileri ve üyeleri tarafın
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -425,12 +425,13 @@ En iyi fikirler her yerden geldiği için açık kaynakta inşa ediyoruz. Bunu o
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -190,12 +190,13 @@ channels:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -59,11 +59,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -208,12 +208,13 @@ channels:
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -86,11 +86,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -468,12 +468,13 @@ Chúng tôi xây dựng công khai vì ý tưởng hay đến từ khắp nơi.
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+7 -6
View File
@@ -77,11 +77,11 @@
<!-- BEGIN:WHATS_NEW -->
### 🚀 What's New in v0.3.0-beta.196 (March 2026)
### 🚀 What's New in v0.3.1 (March 2026)
| Area | Highlights |
|---|---|
| General | Incremental improvements and polish |
| ci | add Termux (aarch64-linux-android) release target |
<!-- END:WHATS_NEW -->
@@ -242,12 +242,13 @@ zeroclaw agent --provider anthropic -m "hello"
<!-- BEGIN:RECENT_CONTRIBUTORS -->
### 🌟 Recent Contributors (v0.3.0-beta.196)
0
0 contributors shipped features, fixes, and improvements in this release cycle:
### 🌟 Recent Contributors (v0.3.1)
3 contributors shipped features, fixes, and improvements in this release cycle:
- **Argenis**
- **argenis de la rosa**
- **Claude Opus 4.6**
Thank you to everyone who opened issues, reviewed PRs, translated docs, and helped test. Every contribution matters. 🦀
+261
View File
@@ -0,0 +1,261 @@
#!/usr/bin/env bash
# Termux release validation script
# Validates the aarch64-linux-android release artifact for Termux compatibility.
#
# Usage:
# ./dev/test-termux-release.sh [version]
#
# Examples:
# ./dev/test-termux-release.sh 0.3.1
# ./dev/test-termux-release.sh # auto-detects from Cargo.toml
#
set -euo pipefail
BLUE='\033[0;34m'
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
BOLD='\033[1m'
DIM='\033[2m'
RESET='\033[0m'
pass() { echo -e " ${GREEN}${RESET} $*"; }
fail() { echo -e " ${RED}${RESET} $*"; FAILURES=$((FAILURES + 1)); }
info() { echo -e "${BLUE}${RESET} ${BOLD}$*${RESET}"; }
warn() { echo -e "${YELLOW}!${RESET} $*"; }
FAILURES=0
TARGET="aarch64-linux-android"
VERSION="${1:-}"
if [[ -z "$VERSION" ]]; then
if [[ -f Cargo.toml ]]; then
VERSION=$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -1)
fi
fi
if [[ -z "$VERSION" ]]; then
echo "Usage: $0 <version>"
echo " e.g. $0 0.3.1"
exit 1
fi
TAG="v${VERSION}"
ASSET_NAME="zeroclaw-${TARGET}.tar.gz"
ASSET_URL="https://github.com/zeroclaw-labs/zeroclaw/releases/download/${TAG}/${ASSET_NAME}"
TEMP_DIR="$(mktemp -d -t zeroclaw-termux-test-XXXXXX)"
cleanup() { rm -rf "$TEMP_DIR"; }
trap cleanup EXIT
echo
echo -e "${BOLD}Termux Release Validation — ${TAG}${RESET}"
echo -e "${DIM}Target: ${TARGET}${RESET}"
echo
# --- Test 1: Release tag exists ---
info "Checking release tag ${TAG}"
if gh release view "$TAG" >/dev/null 2>&1; then
pass "Release ${TAG} exists"
else
fail "Release ${TAG} not found"
echo -e "${RED}Release has not been published yet. Wait for the release workflow to complete.${RESET}"
exit 1
fi
# --- Test 2: Android asset is listed ---
info "Checking for ${ASSET_NAME} in release assets"
ASSETS=$(gh release view "$TAG" --json assets -q '.assets[].name')
if echo "$ASSETS" | grep -q "$ASSET_NAME"; then
pass "Asset ${ASSET_NAME} found in release"
else
fail "Asset ${ASSET_NAME} not found in release"
echo "Available assets:"
echo "$ASSETS" | sed 's/^/ /'
exit 1
fi
# --- Test 3: Download the asset ---
info "Downloading ${ASSET_NAME}"
if curl -fsSL "$ASSET_URL" -o "$TEMP_DIR/$ASSET_NAME"; then
FILESIZE=$(wc -c < "$TEMP_DIR/$ASSET_NAME" | tr -d ' ')
pass "Downloaded successfully (${FILESIZE} bytes)"
else
fail "Download failed from ${ASSET_URL}"
exit 1
fi
# --- Test 4: Archive integrity ---
info "Verifying archive integrity"
if tar -tzf "$TEMP_DIR/$ASSET_NAME" >/dev/null 2>&1; then
pass "Archive is a valid gzip tar"
else
fail "Archive is corrupted or not a valid tar.gz"
exit 1
fi
# --- Test 5: Contains zeroclaw binary ---
info "Checking archive contents"
CONTENTS=$(tar -tzf "$TEMP_DIR/$ASSET_NAME")
if echo "$CONTENTS" | grep -q "^zeroclaw$"; then
pass "Archive contains 'zeroclaw' binary"
else
fail "Archive does not contain 'zeroclaw' binary"
echo "Contents:"
echo "$CONTENTS" | sed 's/^/ /'
fi
# --- Test 6: Extract and inspect binary ---
info "Extracting and inspecting binary"
tar -xzf "$TEMP_DIR/$ASSET_NAME" -C "$TEMP_DIR"
BINARY="$TEMP_DIR/zeroclaw"
if [[ -f "$BINARY" ]]; then
pass "Binary extracted"
else
fail "Binary not found after extraction"
exit 1
fi
# --- Test 7: ELF format and architecture ---
info "Checking binary format"
FILE_INFO=$(file "$BINARY")
if echo "$FILE_INFO" | grep -q "ELF"; then
pass "Binary is ELF format"
else
fail "Binary is not ELF format: $FILE_INFO"
fi
if echo "$FILE_INFO" | grep -qi "aarch64\|ARM aarch64"; then
pass "Binary targets aarch64 architecture"
else
fail "Binary does not target aarch64: $FILE_INFO"
fi
if echo "$FILE_INFO" | grep -qi "android\|bionic"; then
pass "Binary is linked for Android/Bionic"
else
# Android binaries may not always show "android" in file output,
# check with readelf if available
if command -v readelf >/dev/null 2>&1; then
INTERP=$(readelf -l "$BINARY" 2>/dev/null | grep -o '/[^ ]*linker[^ ]*' || true)
if echo "$INTERP" | grep -qi "android\|bionic"; then
pass "Binary uses Android linker: $INTERP"
else
warn "Could not confirm Android linkage (interpreter: ${INTERP:-unknown})"
warn "file output: $FILE_INFO"
fi
else
warn "Could not confirm Android linkage (readelf not available)"
warn "file output: $FILE_INFO"
fi
fi
# --- Test 8: Binary is stripped ---
info "Checking binary optimization"
if echo "$FILE_INFO" | grep -q "stripped"; then
pass "Binary is stripped (release optimized)"
else
warn "Binary may not be stripped"
fi
# --- Test 9: Binary is not dynamically linked to glibc ---
info "Checking for glibc dependencies"
if command -v readelf >/dev/null 2>&1; then
NEEDED=$(readelf -d "$BINARY" 2>/dev/null | grep NEEDED || true)
if echo "$NEEDED" | grep -qi "libc\.so\.\|libpthread\|libdl"; then
# Check if it's glibc or bionic
if echo "$NEEDED" | grep -qi "libc\.so\.6"; then
fail "Binary links against glibc (libc.so.6) — will not work on Termux"
else
pass "Binary links against libc (likely Bionic)"
fi
else
pass "No glibc dependencies detected"
fi
else
warn "readelf not available — skipping dynamic library check"
fi
# --- Test 10: SHA256 checksum verification ---
info "Verifying SHA256 checksum"
CHECKSUMS_URL="https://github.com/zeroclaw-labs/zeroclaw/releases/download/${TAG}/SHA256SUMS"
if curl -fsSL "$CHECKSUMS_URL" -o "$TEMP_DIR/SHA256SUMS" 2>/dev/null; then
EXPECTED=$(grep "$ASSET_NAME" "$TEMP_DIR/SHA256SUMS" | awk '{print $1}')
if [[ -n "$EXPECTED" ]]; then
if command -v sha256sum >/dev/null 2>&1; then
ACTUAL=$(sha256sum "$TEMP_DIR/$ASSET_NAME" | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
ACTUAL=$(shasum -a 256 "$TEMP_DIR/$ASSET_NAME" | awk '{print $1}')
else
warn "No sha256sum or shasum available"
ACTUAL=""
fi
if [[ -n "$ACTUAL" && "$ACTUAL" == "$EXPECTED" ]]; then
pass "SHA256 checksum matches"
elif [[ -n "$ACTUAL" ]]; then
fail "SHA256 mismatch: expected=$EXPECTED actual=$ACTUAL"
fi
else
warn "No checksum entry for ${ASSET_NAME} in SHA256SUMS"
fi
else
warn "Could not download SHA256SUMS"
fi
# --- Test 11: install.sh Termux detection ---
info "Validating install.sh Termux detection"
INSTALL_SH="install.sh"
if [[ ! -f "$INSTALL_SH" ]]; then
INSTALL_SH="$(dirname "$0")/../install.sh"
fi
if [[ -f "$INSTALL_SH" ]]; then
if grep -q 'TERMUX_VERSION' "$INSTALL_SH"; then
pass "install.sh checks TERMUX_VERSION"
else
fail "install.sh does not check TERMUX_VERSION"
fi
if grep -q 'aarch64-linux-android' "$INSTALL_SH"; then
pass "install.sh maps to aarch64-linux-android target"
else
fail "install.sh does not map to aarch64-linux-android"
fi
# Simulate Termux detection (mock uname as Linux since we may run on macOS)
detect_result=$(
bash -c '
TERMUX_VERSION="0.118"
os="Linux"
arch="aarch64"
case "$os:$arch" in
Linux:aarch64|Linux:arm64)
if [[ -n "${TERMUX_VERSION:-}" || -d "/data/data/com.termux" ]]; then
echo "aarch64-linux-android"
else
echo "aarch64-unknown-linux-gnu"
fi
;;
esac
'
)
if [[ "$detect_result" == "aarch64-linux-android" ]]; then
pass "Termux detection returns correct target (simulated)"
else
fail "Termux detection returned: $detect_result (expected aarch64-linux-android)"
fi
else
warn "install.sh not found — skipping detection tests"
fi
# --- Summary ---
echo
if [[ "$FAILURES" -eq 0 ]]; then
echo -e "${GREEN}${BOLD}All tests passed!${RESET}"
echo -e "${DIM}The Termux release artifact for ${TAG} is valid.${RESET}"
else
echo -e "${RED}${BOLD}${FAILURES} test(s) failed.${RESET}"
exit 1
fi
+16
View File
@@ -0,0 +1,16 @@
pkgbase = zeroclaw
pkgdesc = Zero overhead. Zero compromise. 100% Rust. The fastest, smallest AI assistant.
pkgver = 0.4.3
pkgrel = 1
url = https://github.com/zeroclaw-labs/zeroclaw
arch = x86_64
license = MIT
license = Apache-2.0
makedepends = cargo
makedepends = git
depends = gcc-libs
depends = openssl
source = zeroclaw-0.4.3.tar.gz::https://github.com/zeroclaw-labs/zeroclaw/archive/refs/tags/v0.4.3.tar.gz
sha256sums = SKIP
pkgname = zeroclaw
+32
View File
@@ -0,0 +1,32 @@
# Maintainer: zeroclaw-labs <bot@zeroclaw.dev>
pkgname=zeroclaw
pkgver=0.4.3
pkgrel=1
pkgdesc="Zero overhead. Zero compromise. 100% Rust. The fastest, smallest AI assistant."
arch=('x86_64')
url="https://github.com/zeroclaw-labs/zeroclaw"
license=('MIT' 'Apache-2.0')
depends=('gcc-libs' 'openssl')
makedepends=('cargo' 'git')
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/zeroclaw-labs/zeroclaw/archive/refs/tags/v${pkgver}.tar.gz")
sha256sums=('SKIP')
prepare() {
cd "${pkgname}-${pkgver}"
export RUSTUP_TOOLCHAIN=stable
cargo fetch --locked --target "$(rustc -vV | sed -n 's/host: //p')"
}
build() {
cd "${pkgname}-${pkgver}"
export RUSTUP_TOOLCHAIN=stable
export CARGO_TARGET_DIR=target
cargo build --frozen --release --profile dist
}
package() {
cd "${pkgname}-${pkgver}"
install -Dm0755 -t "${pkgdir}/usr/bin/" "target/dist/zeroclaw"
install -Dm0644 LICENSE-MIT "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE-MIT"
install -Dm0644 LICENSE-APACHE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE-APACHE"
}
+27
View File
@@ -0,0 +1,27 @@
{
"version": "0.4.3",
"description": "Zero overhead. Zero compromise. 100% Rust. The fastest, smallest AI assistant.",
"homepage": "https://github.com/zeroclaw-labs/zeroclaw",
"license": "MIT|Apache-2.0",
"architecture": {
"64bit": {
"url": "https://github.com/zeroclaw-labs/zeroclaw/releases/download/v0.4.3/zeroclaw-x86_64-pc-windows-msvc.zip",
"hash": "",
"bin": "zeroclaw.exe"
}
},
"checkver": {
"github": "https://github.com/zeroclaw-labs/zeroclaw"
},
"autoupdate": {
"architecture": {
"64bit": {
"url": "https://github.com/zeroclaw-labs/zeroclaw/releases/download/v$version/zeroclaw-x86_64-pc-windows-msvc.zip"
}
},
"hash": {
"url": "https://github.com/zeroclaw-labs/zeroclaw/releases/download/v$version/SHA256SUMS",
"regex": "([a-f0-9]{64})\\s+zeroclaw-x86_64-pc-windows-msvc\\.zip"
}
}
}
+16 -6
View File
@@ -37,6 +37,12 @@ Merge-blocking checks should stay small and deterministic. Optional checks are u
- `.github/workflows/pub-homebrew-core.yml` (`Pub Homebrew Core`)
- Purpose: manual, bot-owned Homebrew core formula bump PR flow for tagged releases
- Guardrail: release tag must match `Cargo.toml` version
- `.github/workflows/pub-scoop.yml` (`Pub Scoop Manifest`)
- Purpose: Scoop bucket manifest update for Windows; auto-called by stable release, also manual dispatch
- Guardrail: release tag must be `vX.Y.Z` format; Windows binary hash extracted from `SHA256SUMS`
- `.github/workflows/pub-aur.yml` (`Pub AUR Package`)
- Purpose: AUR PKGBUILD push for Arch Linux; auto-called by stable release, also manual dispatch
- Guardrail: release tag must be `vX.Y.Z` format; source tarball SHA256 computed at publish time
- `.github/workflows/pr-label-policy-check.yml` (`Label Policy Sanity`)
- Purpose: validate shared contributor-tier policy in `.github/label-policy.json` and ensure label workflows consume that policy
- `.github/workflows/test-rust-build.yml` (`Rust Reusable Job`)
@@ -75,6 +81,8 @@ Merge-blocking checks should stay small and deterministic. Optional checks are u
- `Docker`: tag push (`v*`) for publish, matching PRs to `master` for smoke build, manual dispatch for smoke only
- `Release`: tag push (`v*`), weekly schedule (verification-only), manual dispatch (verification or publish)
- `Pub Homebrew Core`: manual dispatch only
- `Pub Scoop Manifest`: auto-called by stable release, also manual dispatch
- `Pub AUR Package`: auto-called by stable release, also manual dispatch
- `Security Audit`: push to `master`, PRs to `master`, weekly schedule
- `Sec Vorpal Reviewdog`: manual dispatch only
- `Workflow Sanity`: PR/push when `.github/workflows/**`, `.github/*.yml`, or `.github/*.yaml` change
@@ -92,12 +100,14 @@ Merge-blocking checks should stay small and deterministic. Optional checks are u
2. Docker failures on PRs: inspect `.github/workflows/pub-docker-img.yml` `pr-smoke` job.
3. Release failures (tag/manual/scheduled): inspect `.github/workflows/pub-release.yml` and the `prepare` job outputs.
4. Homebrew formula publish failures: inspect `.github/workflows/pub-homebrew-core.yml` summary output and bot token/fork variables.
5. Security failures: inspect `.github/workflows/sec-audit.yml` and `deny.toml`.
6. Workflow syntax/lint failures: inspect `.github/workflows/workflow-sanity.yml`.
7. PR intake failures: inspect `.github/workflows/pr-intake-checks.yml` sticky comment and run logs.
8. Label policy parity failures: inspect `.github/workflows/pr-label-policy-check.yml`.
9. Docs failures in CI: inspect `docs-quality` job logs in `.github/workflows/ci-run.yml`.
10. Strict delta lint failures in CI: inspect `lint-strict-delta` job logs and compare with `BASE_SHA` diff scope.
5. Scoop manifest publish failures: inspect `.github/workflows/pub-scoop.yml` summary output and `SCOOP_BUCKET_REPO`/`SCOOP_BUCKET_TOKEN` settings.
6. AUR package publish failures: inspect `.github/workflows/pub-aur.yml` summary output and `AUR_SSH_KEY` secret.
7. Security failures: inspect `.github/workflows/sec-audit.yml` and `deny.toml`.
8. Workflow syntax/lint failures: inspect `.github/workflows/workflow-sanity.yml`.
9. PR intake failures: inspect `.github/workflows/pr-intake-checks.yml` sticky comment and run logs.
10. Label policy parity failures: inspect `.github/workflows/pr-label-policy-check.yml`.
11. Docs failures in CI: inspect `docs-quality` job logs in `.github/workflows/ci-run.yml`.
12. Strict delta lint failures in CI: inspect `lint-strict-delta` job logs and compare with `BASE_SHA` diff scope.
## Maintenance Rules
+37
View File
@@ -23,6 +23,8 @@ Release automation lives in:
- `.github/workflows/pub-release.yml`
- `.github/workflows/pub-homebrew-core.yml` (manual Homebrew formula PR, bot-owned)
- `.github/workflows/pub-scoop.yml` (manual Scoop bucket manifest update)
- `.github/workflows/pub-aur.yml` (manual AUR PKGBUILD push)
Modes:
@@ -115,6 +117,41 @@ Workflow guardrails:
- formula license is normalized to `Apache-2.0 OR MIT`
- PR is opened from the bot fork into `Homebrew/homebrew-core:master`
### 7) Publish Scoop manifest (Windows)
Run `Pub Scoop Manifest` manually:
- `release_tag`: `vX.Y.Z`
- `dry_run`: `true` first, then `false`
Required repository settings for non-dry-run:
- secret: `SCOOP_BUCKET_TOKEN` (PAT with push access to the bucket repo)
- variable: `SCOOP_BUCKET_REPO` (for example `zeroclaw-labs/scoop-zeroclaw`)
Workflow guardrails:
- release tag must be `vX.Y.Z` format
- Windows binary SHA256 extracted from `SHA256SUMS` release asset
- manifest pushed to `bucket/zeroclaw.json` in the Scoop bucket repo
### 8) Publish AUR package (Arch Linux)
Run `Pub AUR Package` manually:
- `release_tag`: `vX.Y.Z`
- `dry_run`: `true` first, then `false`
Required repository settings for non-dry-run:
- secret: `AUR_SSH_KEY` (SSH private key registered with AUR)
Workflow guardrails:
- release tag must be `vX.Y.Z` format
- source tarball SHA256 computed from the tagged release
- PKGBUILD and .SRCINFO pushed to AUR `zeroclaw` package
## Emergency / Recovery Path
If tag-push release fails after artifacts are validated:
+1 -1
View File
@@ -31,7 +31,7 @@ Build with `--features hardware` to include Uno Q support.
### 1.1 Configure Uno Q via App Lab
1. Download [Arduino App Lab](https://docs.arduino.cc/software/app-lab/) (AppImage on Linux).
1. Download [Arduino App Lab](https://docs.arduino.cc/software/app-lab/) (tar.gz on Linux).
2. Connect Uno Q via USB, power it on.
3. Open App Lab, connect to the board.
4. Follow the setup wizard:
+3 -4
View File
@@ -1,15 +1,14 @@
# ZeroClaw i18n Docs Index
Canonical localized documentation trees live here.
Localized documentation trees live here and under `docs/`.
## Locales
- Vietnamese: [vi/README.md](vi/README.md)
- Vietnamese (canonical): [`docs/vi/`](../vi/)
- Chinese (Simplified): [`docs/i18n/zh-CN/`](zh-CN/)
## Structure
- Docs structure map (language/part/function): [../maintainers/structure-README.md](../maintainers/structure-README.md)
- Canonical Vietnamese tree: `docs/i18n/vi/`
- Compatibility Vietnamese paths: `docs/vi/` and `docs/*.vi.md`
See overall coverage and conventions in [../maintainers/i18n-coverage.md](../maintainers/i18n-coverage.md).
-114
View File
@@ -1,114 +0,0 @@
# Οδηγός Ρυθμίσεων ZeroClaw (config.toml)
Αυτός ο οδηγός εξηγεί τις πιο σημαντικές ρυθμίσεις που μπορείτε να κάνετε στο αρχείο `config.toml`.
Τελευταίος έλεγχος: **19 Φεβρουαρίου 2026**.
## Πού βρίσκεται το αρχείο ρυθμίσεων;
Το ZeroClaw ψάχνει για τις ρυθμίσεις με την εξής σειρά:
1. Στη διαδρομή που ορίζει η μεταβλητή `ZEROCLAW_WORKSPACE`.
2. Στο αρχείο `~/.zeroclaw/config.toml` (αυτή είναι η συνηθισμένη θέση).
## Βασικές Ρυθμίσεις (Core)
| Ρύθμιση | Τι ορίζει |
|---|---|
| `default_provider` | Ποιον πάροχο AI χρησιμοποιείτε (π.χ. `openai`, `ollama`). |
| `default_model` | Ποιο συγκεκριμένο μοντέλο AI χρησιμοποιείτε (π.χ. `gpt-4o`). |
| `default_temperature` | Πόσο "δημιουργική" θα είναι η AI (τιμή από 0 έως 2). |
## 1. Συμπεριφορά της AI (Agent)
- `max_tool_iterations`: Πόσες φορές μπορεί η AI να χρησιμοποιήσει εργαλεία για να απαντήσει σε 1 μήνυμα (προεπιλογή: 10).
- `max_history_messages`: Πόσα προηγούμενα μηνύματα θυμάται η AI στη συνομιλία (προεπιλογή: 50).
## 2. Αυτονομία και Ασφάλεια (Autonomy)
Εδώ ρυθμίζετε πόση ελευθερία έχει η AI να κάνει αλλαγές στον υπολογιστή σας.
- `level`:
- `read_only`: Μπορεί μόνο να διαβάζει αρχεία.
- `supervised`: Χρειάζεται την έγκρισή σας για σημαντικές ενέργειες (προεπιλογή).
- `full`: Μπορεί να τρέχει εντολές ελεύθερα (προσοχή!).
- `allowed_commands`: Λίστα με τις εντολές που επιτρέπεται να τρέχει η AI.
- `forbidden_paths`: Φάκελοι που η AI **δεν** επιτρέπεται να αγγίξει (π.χ. `/etc`).
## 3. Μνήμη (Memory)
Πώς αποθηκεύει η AI τις πληροφορίες που της δίνετε.
- `backend`: Μπορεί να είναι `sqlite` (βάση δεδομένων), `markdown` (απλά αρχεία κειμένου) ή `none` (καμία μνήμη).
## 4. Κανάλια Επικοινωνίας (Channels)
Κάθε κανάλι (Telegram, Discord κ.λπ.) έχει τη δική του ενότητα στο αρχείο.
Παράδειγμα για το **Telegram**:
```toml
[channels_config.telegram]
bot_token = "το-κλειδί-σας"
allowed_users = ["το-όνομά-σας"] # Ποιοι επιτρέπεται να μιλάνε στο bot
```
## 5. Έλεγχος Κόστους (Cost)
Αν χρησιμοποιείτε πληρωμένες υπηρεσίες AI, μπορείτε να βάλετε όρια.
- `daily_limit_usd`: Μέγιστο ποσό ανά ημέρα (π.χ. 10.00 δολάρια).
- `monthly_limit_usd`: Μέγιστο ποσό ανά μήνα.
## 6. Εικόνες (Multimodal)
Ρυθμίσεις για το πώς η AI βλέπει εικόνες.
- `max_images`: Μέγιστος αριθμός εικόνων ανά μήνυμα.
- `allow_remote_fetch`: Αν επιτρέπεται στην AI να κατεβάζει εικόνες από το ίντερνετ μέσω συνδέσμων (links).
---
## Συμβουλές
- Αν αλλάξετε το αρχείο `config.toml`, πρέπει να κάνετε επανεκκίνηση το ZeroClaw για να δει τις αλλαγές.
- Χρησιμοποιήστε την εντολή `zeroclaw doctor` για να βεβαιωθείτε ότι οι ρυθμίσεις σας είναι σωστές.
## Ενημέρωση (2026-03-03)
- Στην ενότητα `[agent]` προστέθηκαν τα `allowed_tools` και `denied_tools`.
- Αν το `allowed_tools` δεν είναι κενό, ο primary agent βλέπει μόνο τα εργαλεία της λίστας.
- Το `denied_tools` εφαρμόζεται μετά το allowlist και αφαιρεί επιπλέον εργαλεία.
- Άγνωστες τιμές στο `allowed_tools` αγνοούνται (με debug log) και δεν μπλοκάρουν την εκκίνηση.
- Αν `allowed_tools` και `denied_tools` καταλήξουν να αφαιρέσουν όλα τα εκτελέσιμα εργαλεία, η εκκίνηση αποτυγχάνει άμεσα με σαφές μήνυμα ρύθμισης.
- Για πλήρη πίνακα πεδίων και παράδειγμα, δείτε το αγγλικό `config-reference.md` στην ενότητα `[agent]`.
- Μην μοιράζεστε ποτέ το αρχείο `config.toml` με άλλους, καθώς περιέχει τα μυστικά κλειδιά σας (tokens).
## Ενημέρωση (2026-03-12)
- Στην ενότητα `[agent]` προστέθηκε το `tool_filter_groups` για φιλτράρισμα schema tool MCP ανά γύρο.
### `tool_filter_groups`
Μειώνει τα tokens ανά γύρο περιορίζοντας ποια schema tool MCP αποστέλλονται στο LLM. Τα ενσωματωμένα εργαλεία (χωρίς πρόθεμα `mcp_`) περνούν πάντα αναλλοίωτα.
Κάθε εγγραφή είναι πίνακας με τα εξής πεδία:
| Πεδίο | Τύπος | Σκοπός |
|---|---|---|
| `mode` | `"always"` \| `"dynamic"` | `always`: το εργαλείο συμπεριλαμβάνεται πάντα. `dynamic`: συμπεριλαμβάνεται μόνο όταν το μήνυμα χρήστη περιέχει λέξη-κλειδί. |
| `tools` | `[string]` | Μοτίβα ονόματος εργαλείου. Υποστηρίζεται ένα `*` wildcard (π.χ. `"mcp_vikunja_*"`). |
| `keywords` | `[string]` | (Μόνο για dynamic) Υποαλφαριθμητικά χωρίς διάκριση πεζών-κεφαλαίων που αντιστοιχούν στο τελευταίο μήνυμα χρήστη. |
Όταν το `tool_filter_groups` είναι κενό, η λειτουργία είναι ανενεργή και όλα τα εργαλεία περνούν κανονικά (συμβατό με προηγούμενες εκδόσεις).
Παράδειγμα:
```toml
[agent]
# Τα εργαλεία MCP Vikunja είναι πάντα διαθέσιμα.
[[agent.tool_filter_groups]]
mode = "always"
tools = ["mcp_vikunja_*"]
# Τα εργαλεία MCP browser συμπεριλαμβάνονται μόνο όταν ο χρήστης αναφέρει πλοήγηση.
[[agent.tool_filter_groups]]
mode = "dynamic"
tools = ["mcp_browser_*"]
keywords = ["περιήγηση", "πλοήγηση", "άνοιγμα url", "στιγμιότυπο"]
```
-94
View File
@@ -1,94 +0,0 @@
# Tài liệu ZeroClaw (Tiếng Việt)
Đây là trang chủ tiếng Việt của hệ thống tài liệu.
Đồng bộ lần cuối: **2026-02-21**.
> Lưu ý: Tên lệnh, khóa cấu hình và đường dẫn API giữ nguyên tiếng Anh. Khi có sai khác, tài liệu tiếng Anh là bản gốc.
## Tra cứu nhanh
| Tôi muốn… | Xem tài liệu |
|---|---|
| Cài đặt và chạy nhanh | [../../../README.vi.md](../../../README.vi.md) / [../../../README.md](../../../README.md) |
| Cài đặt bằng một lệnh | [one-click-bootstrap.md](one-click-bootstrap.md) |
| Tìm lệnh theo tác vụ | [commands-reference.md](commands-reference.md) |
| Kiểm tra giá trị mặc định và khóa cấu hình | [config-reference.md](config-reference.md) |
| Kết nối provider / endpoint tùy chỉnh | [custom-providers.md](custom-providers.md) |
| Cấu hình Z.AI / GLM provider | [zai-glm-setup.md](zai-glm-setup.md) |
| Sử dụng tích hợp LangGraph | [langgraph-integration.md](langgraph-integration.md) |
| Vận hành hàng ngày (runbook) | [operations-runbook.md](operations-runbook.md) |
| Khắc phục sự cố cài đặt/chạy/kênh | [troubleshooting.md](troubleshooting.md) |
| Cấu hình Matrix phòng mã hóa (E2EE) | [matrix-e2ee-guide.md](matrix-e2ee-guide.md) |
| Xem theo danh mục | [SUMMARY.md](SUMMARY.md) |
| Xem bản chụp PR/Issue | [project-triage-snapshot-2026-02-18.md](../../maintainers/project-triage-snapshot-2026-02-18.md) |
## Tìm nhanh
- Cài đặt lần đầu hoặc khởi động nhanh → [getting-started/README.md](getting-started/README.md)
- Cần tra cứu lệnh CLI / khóa cấu hình → [reference/README.md](reference/README.md)
- Cần vận hành / triển khai sản phẩm → [operations/README.md](operations/README.md)
- Gặp lỗi hoặc hồi quy → [troubleshooting.md](troubleshooting.md)
- Tìm hiểu bảo mật và lộ trình → [security/README.md](security/README.md)
- Làm việc với bo mạch / thiết bị ngoại vi → [hardware/README.md](hardware/README.md)
- Đóng góp / review / quy trình CI → [contributing/README.md](contributing/README.md)
- Xem toàn bộ bản đồ tài liệu → [SUMMARY.md](SUMMARY.md)
## Theo danh mục
- Bắt đầu: [getting-started/README.md](getting-started/README.md)
- Tra cứu: [reference/README.md](reference/README.md)
- Vận hành & triển khai: [operations/README.md](operations/README.md)
- Bảo mật: [security/README.md](security/README.md)
- Phần cứng & ngoại vi: [hardware/README.md](hardware/README.md)
- Đóng góp & CI: [contributing/README.md](contributing/README.md)
- Ảnh chụp dự án: [project/README.md](project/README.md)
## Theo vai trò
### Người dùng / Vận hành
- [commands-reference.md](commands-reference.md) — tra cứu lệnh theo tác vụ
- [providers-reference.md](providers-reference.md) — ID provider, bí danh, biến môi trường xác thực
- [channels-reference.md](channels-reference.md) — khả năng kênh và hướng dẫn thiết lập
- [matrix-e2ee-guide.md](matrix-e2ee-guide.md) — thiết lập phòng mã hóa Matrix (E2EE)
- [config-reference.md](config-reference.md) — khóa cấu hình quan trọng và giá trị mặc định an toàn
- [custom-providers.md](custom-providers.md) — mẫu tích hợp provider / base URL tùy chỉnh
- [zai-glm-setup.md](zai-glm-setup.md) — thiết lập Z.AI/GLM và ma trận endpoint
- [langgraph-integration.md](langgraph-integration.md) — tích hợp dự phòng cho model/tool-calling
- [operations-runbook.md](operations-runbook.md) — vận hành runtime hàng ngày và quy trình rollback
- [troubleshooting.md](troubleshooting.md) — dấu hiệu lỗi thường gặp và cách khắc phục
### Người đóng góp / Bảo trì
- [CONTRIBUTING.md](../../../CONTRIBUTING.md)
- [pr-workflow.md](pr-workflow.md)
- [reviewer-playbook.md](reviewer-playbook.md)
- [ci-map.md](ci-map.md)
- [actions-source-policy.md](actions-source-policy.md)
### Bảo mật / Độ tin cậy
> Lưu ý: Mục này gồm tài liệu đề xuất/lộ trình, có thể chứa lệnh hoặc cấu hình chưa triển khai. Để biết hành vi thực tế, xem [config-reference.md](config-reference.md), [operations-runbook.md](operations-runbook.md) và [troubleshooting.md](troubleshooting.md) trước.
- [security/README.md](security/README.md)
- [agnostic-security.md](agnostic-security.md)
- [frictionless-security.md](frictionless-security.md)
- [sandboxing.md](sandboxing.md)
- [audit-logging.md](audit-logging.md)
- [resource-limits.md](resource-limits.md)
- [security-roadmap.md](security-roadmap.md)
## Quản lý tài liệu
- Mục lục thống nhất (TOC): [SUMMARY.md](SUMMARY.md)
- Bản đồ cấu trúc docs (ngôn ngữ/phần/chức năng): [../../maintainers/structure-README.md](../../maintainers/structure-README.md)
- Danh mục và phân loại tài liệu: [docs-inventory.md](../../maintainers/docs-inventory.md)
## Ngôn ngữ khác
- English: [README.md](../../README.md)
- 简体中文: [README.zh-CN.md](../../README.zh-CN.md)
- 日本語: [README.ja.md](../../README.ja.md)
- Русский: [README.ru.md](../../README.ru.md)
- Français: [README.fr.md](../../README.fr.md)
-78
View File
@@ -1,78 +0,0 @@
# Mục lục tài liệu ZeroClaw (Tiếng Việt)
Đây là mục lục thống nhất cho hệ thống tài liệu tiếng Việt.
Đồng bộ lần cuối: **2026-02-21**.
## Điểm vào
- Bản đồ cấu trúc docs (ngôn ngữ/phần/chức năng): [../../maintainers/structure-README.md](../../maintainers/structure-README.md)
- README tiếng Việt: [../../../README.vi.md](../../../README.vi.md)
- Docs hub tiếng Việt: [README.md](README.md)
## Danh mục
### 1) Bắt đầu
- [getting-started/README.md](getting-started/README.md)
- [one-click-bootstrap.md](one-click-bootstrap.md)
### 2) Lệnh / Cấu hình / Tích hợp
- [reference/README.md](reference/README.md)
- [commands-reference.md](commands-reference.md)
- [providers-reference.md](providers-reference.md)
- [channels-reference.md](channels-reference.md)
- [config-reference.md](config-reference.md)
- [custom-providers.md](custom-providers.md)
- [zai-glm-setup.md](zai-glm-setup.md)
- [langgraph-integration.md](langgraph-integration.md)
### 3) Vận hành & Triển khai
- [operations/README.md](operations/README.md)
- [operations-runbook.md](operations-runbook.md)
- [release-process.md](release-process.md)
- [troubleshooting.md](troubleshooting.md)
- [network-deployment.md](network-deployment.md)
- [mattermost-setup.md](mattermost-setup.md)
- [matrix-e2ee-guide.md](matrix-e2ee-guide.md)
### 4) Bảo mật
- [security/README.md](security/README.md)
- [agnostic-security.md](agnostic-security.md)
- [frictionless-security.md](frictionless-security.md)
- [sandboxing.md](sandboxing.md)
- [resource-limits.md](resource-limits.md)
- [audit-logging.md](audit-logging.md)
- [security-roadmap.md](security-roadmap.md)
### 5) Phần cứng & Ngoại vi
- [hardware/README.md](hardware/README.md)
- [hardware-peripherals-design.md](hardware-peripherals-design.md)
- [adding-boards-and-tools.md](adding-boards-and-tools.md)
- [nucleo-setup.md](nucleo-setup.md)
- [arduino-uno-q-setup.md](arduino-uno-q-setup.md)
- [datasheets/nucleo-f401re.md](datasheets/nucleo-f401re.md)
- [datasheets/arduino-uno.md](datasheets/arduino-uno.md)
- [datasheets/esp32.md](datasheets/esp32.md)
### 6) Đóng góp & CI
- [contributing/README.md](contributing/README.md)
- [CONTRIBUTING.md](../../../CONTRIBUTING.md)
- [pr-workflow.md](pr-workflow.md)
- [reviewer-playbook.md](reviewer-playbook.md)
- [ci-map.md](ci-map.md)
- [actions-source-policy.md](actions-source-policy.md)
### 7) Dự án
- [project/README.md](project/README.md)
- [proxy-agent-playbook.md](proxy-agent-playbook.md)
## Ngôn ngữ khác
- English TOC: [../../SUMMARY.md](../../SUMMARY.md)
-95
View File
@@ -1,95 +0,0 @@
# Chính sách nguồn Actions (Giai đoạn 1)
Tài liệu này định nghĩa chính sách kiểm soát nguồn GitHub Actions hiện tại cho repository này.
Mục tiêu Giai đoạn 1: khóa nguồn action với ít gián đoạn nhất, trước khi pin SHA đầy đủ.
## Chính sách hiện tại
- Quyền Actions repository: được bật
- Chế độ action cho phép: đã chọn
- Yêu cầu pin SHA: false (hoãn đến Giai đoạn 2)
Các mẫu allowlist được chọn:
- `actions/*` (bao gồm `actions/cache`, `actions/checkout`, `actions/upload-artifact`, `actions/download-artifact` và các first-party action khác)
- `docker/*`
- `dtolnay/rust-toolchain@*`
- `DavidAnson/markdownlint-cli2-action@*`
- `lycheeverse/lychee-action@*`
- `EmbarkStudios/cargo-deny-action@*`
- `rustsec/audit-check@*`
- `rhysd/actionlint@*`
- `softprops/action-gh-release@*`
- `sigstore/cosign-installer@*`
- `useblacksmith/*` (cơ sở hạ tầng self-hosted runner Blacksmith)
## Xuất kiểm soát thay đổi
Dùng các lệnh sau để xuất chính sách hiệu lực hiện tại phục vụ kiểm toán/kiểm soát thay đổi:
```bash
gh api repos/zeroclaw-labs/zeroclaw/actions/permissions
gh api repos/zeroclaw-labs/zeroclaw/actions/permissions/selected-actions
```
Ghi lại mỗi thay đổi chính sách với:
- ngày/giờ thay đổi (UTC)
- tác nhân
- lý do
- delta allowlist (mẫu được thêm/xóa)
- ghi chú rollback
## Lý do giai đoạn này
- Giảm rủi ro chuỗi cung ứng từ các marketplace action chưa được review.
- Bảo tồn chức năng CI/CD hiện tại với chi phí migration thấp.
- Chuẩn bị cho Giai đoạn 2 pin SHA đầy đủ mà không chặn phát triển đang diễn ra.
## Bảo vệ workflow agentic
Vì repository này có khối lượng thay đổi do agent tạo ra cao:
- Mọi PR thêm hoặc thay đổi nguồn action `uses:` phải bao gồm ghi chú tác động allowlist.
- Các action bên thứ ba mới yêu cầu review maintainer tường minh trước khi đưa vào allowlist.
- Chỉ mở rộng allowlist cho các action bị thiếu đã được xác minh; tránh các ngoại lệ wildcard rộng.
- Giữ hướng dẫn rollback trong mô tả PR cho các thay đổi chính sách Actions.
## Checklist xác thực
Sau khi thay đổi allowlist, xác thực:
1. `CI`
2. `Docker`
3. `Security Audit`
4. `Workflow Sanity`
5. `Release` (khi an toàn để chạy)
Failure mode cần chú ý:
- `action is not allowed by policy`
Nếu gặp phải, chỉ thêm action tin cậy còn thiếu cụ thể đó, chạy lại và ghi lại lý do.
Ghi chú quét gần đây nhất:
- 2026-02-17: Cache phụ thuộc Rust được migrate từ `Swatinem/rust-cache` sang `useblacksmith/rust-cache`
- Không cần mẫu allowlist mới (`useblacksmith/*` đã có trong allowlist)
- 2026-02-16: Phụ thuộc ẩn được phát hiện trong `release-beta-on-push.yml`: `sigstore/cosign-installer@...`
- Đã thêm mẫu allowlist: `sigstore/cosign-installer@*`
- 2026-02-16: Migration Blacksmith chặn thực thi workflow
- Đã thêm mẫu allowlist: `useblacksmith/*` cho cơ sở hạ tầng self-hosted runner
- Actions: `useblacksmith/setup-docker-builder@v1`, `useblacksmith/build-push-action@v2`
- 2026-02-17: Cập nhật cân bằng tính tái tạo/độ tươi của security audit
- Đã thêm mẫu allowlist: `rustsec/audit-check@*`
- Thay thế thực thi nội tuyến `cargo install cargo-audit` bằng `rustsec/audit-check@69366f33c96575abad1ee0dba8212993eecbe998` được pin trong `security.yml`
- Supersedes đề xuất phiên bản nổi trong #588 trong khi giữ chính sách nguồn action rõ ràng
## Rollback
Đường dẫn bỏ chặn khẩn cấp:
1. Tạm thời đặt chính sách Actions trở về `all`.
2. Khôi phục allowlist đã chọn sau khi xác định các mục còn thiếu.
3. Ghi lại sự cố và delta allowlist cuối cùng.
-116
View File
@@ -1,116 +0,0 @@
# Thêm Board và Tool — Hướng dẫn phần cứng ZeroClaw
Hướng dẫn này giải thích cách thêm board phần cứng mới và tool tùy chỉnh vào ZeroClaw.
## Bắt đầu nhanh: Thêm board qua CLI
```bash
# Thêm board (cập nhật ~/.zeroclaw/config.toml)
zeroclaw peripheral add nucleo-f401re /dev/ttyACM0
zeroclaw peripheral add arduino-uno /dev/cu.usbmodem12345
zeroclaw peripheral add rpi-gpio native # cho Raspberry Pi GPIO (Linux)
# Khởi động lại daemon để áp dụng
zeroclaw daemon --host 127.0.0.1 --port 3000
```
## Các board được hỗ trợ
| Board | Transport | Ví dụ đường dẫn |
|-------|-----------|-----------------|
| nucleo-f401re | serial | /dev/ttyACM0, /dev/cu.usbmodem* |
| arduino-uno | serial | /dev/ttyACM0, /dev/cu.usbmodem* |
| arduino-uno-q | bridge | (IP của Uno Q) |
| rpi-gpio | native | native |
| esp32 | serial | /dev/ttyUSB0 |
## Cấu hình thủ công
Chỉnh sửa `~/.zeroclaw/config.toml`:
```toml
[peripherals]
enabled = true
datasheet_dir = "docs/datasheets" # tùy chọn: RAG cho "turn on red led" → pin 13
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
[[peripherals.boards]]
board = "arduino-uno"
transport = "serial"
path = "/dev/cu.usbmodem12345"
baud = 115200
```
## Thêm Datasheet (RAG)
Đặt file `.md` hoặc `.txt` vào `docs/datasheets/` (hoặc `datasheet_dir` của bạn). Đặt tên file theo board: `nucleo-f401re.md`, `arduino-uno.md`.
### Pin Aliases (Khuyến nghị)
Thêm mục `## Pin Aliases` để agent có thể ánh xạ "red led" → pin 13:
```markdown
# My Board
## Pin Aliases
| alias | pin |
|-------------|-----|
| red_led | 13 |
| builtin_led | 13 |
| user_led | 5 |
```
Hoặc dùng định dạng key-value:
```markdown
## Pin Aliases
red_led: 13
builtin_led: 13
```
### PDF Datasheets
Với feature `rag-pdf`, ZeroClaw có thể lập chỉ mục file PDF:
```bash
cargo build --features hardware,rag-pdf
```
Đặt file PDF vào thư mục datasheet. Chúng sẽ được trích xuất và chia nhỏ thành các đoạn cho RAG.
## Thêm loại board mới
1. **Tạo datasheet**`docs/datasheets/my-board.md` với pin aliases và thông tin GPIO.
2. **Thêm vào config**`zeroclaw peripheral add my-board /dev/ttyUSB0`
3. **Triển khai peripheral** (tùy chọn) — Với giao thức tùy chỉnh, hãy implement trait `Peripheral` trong `src/peripherals/` và đăng ký trong `create_peripheral_tools`.
Xem `docs/hardware-peripherals-design.md` để hiểu toàn bộ thiết kế.
## Thêm Tool tùy chỉnh
1. Implement trait `Tool` trong `src/tools/`.
2. Đăng ký trong `create_peripheral_tools` (với hardware tool) hoặc tool registry của agent.
3. Thêm mô tả tool vào `tool_descs` của agent trong `src/agent/loop_.rs`.
## Tham chiếu CLI
| Lệnh | Mô tả |
|------|-------|
| `zeroclaw peripheral list` | Liệt kê các board đã cấu hình |
| `zeroclaw peripheral add <board> <path>` | Thêm board (ghi vào config) |
| `zeroclaw peripheral flash` | Nạp firmware Arduino |
| `zeroclaw peripheral flash-nucleo` | Nạp firmware Nucleo |
| `zeroclaw hardware discover` | Liệt kê thiết bị USB |
| `zeroclaw hardware info` | Thông tin chip qua probe-rs |
## Xử lý sự cố
- **Không tìm thấy serial port** — Trên macOS dùng `/dev/cu.usbmodem*`; trên Linux dùng `/dev/ttyACM0` hoặc `/dev/ttyUSB0`.
- **Build với hardware**`cargo build --features hardware`
- **probe-rs cho Nucleo**`cargo build --features hardware,probe`
-355
View File
@@ -1,355 +0,0 @@
# Bảo mật không phụ thuộc nền tảng
> ⚠️ **Trạng thái: Đề xuất / Lộ trình**
>
> Tài liệu này mô tả các hướng tiếp cận đề xuất và có thể bao gồm các lệnh hoặc cấu hình giả định.
> Để biết hành vi runtime hiện tại, xem [config-reference.md](config-reference.md), [operations-runbook.md](operations-runbook.md), và [troubleshooting.md](troubleshooting.md).
## Câu hỏi cốt lõi: liệu các tính năng bảo mật có làm hỏng
1. ❓ Quá trình cross-compilation nhanh?
2. ❓ Kiến trúc pluggable (hoán đổi bất kỳ thành phần nào)?
3. ❓ Tính agnostic phần cứng (ARM, x86, RISC-V)?
4. ❓ Hỗ trợ phần cứng nhỏ (<5MB RAM, board $10)?
**Câu trả lời: KHÔNG với tất cả** — Bảo mật được thiết kế dưới dạng **feature flags tùy chọn** với **conditional compilation theo từng nền tảng**.
---
## 1. Tốc độ build: bảo mật ẩn sau feature flag
### Cargo.toml: các tính năng bảo mật đặt sau features
```toml
[features]
default = ["basic-security"]
# Basic security (luôn bật, không tốn overhead)
basic-security = []
# Platform-specific sandboxing (opt-in theo từng nền tảng)
sandbox-landlock = [] # Chỉ Linux
sandbox-firejail = [] # Chỉ Linux
sandbox-bubblewrap = []# macOS/Linux
sandbox-docker = [] # Tất cả nền tảng (nặng)
# Bộ bảo mật đầy đủ (dành cho production build)
security-full = [
"basic-security",
"sandbox-landlock",
"resource-monitoring",
"audit-logging",
]
# Resource & audit monitoring
resource-monitoring = []
audit-logging = []
# Development build (nhanh nhất, không phụ thuộc thêm)
dev = []
```
### Lệnh build (chọn profile phù hợp)
```bash
# Dev build cực nhanh (không có extras bảo mật)
cargo build --profile dev
# Release build với basic security (mặc định)
cargo build --release
# → Bao gồm: allowlist, path blocking, injection protection
# → Không bao gồm: Landlock, Firejail, audit logging
# Production build với full security
cargo build --release --features security-full
# → Bao gồm: Tất cả
# Chỉ sandbox theo nền tảng cụ thể
cargo build --release --features sandbox-landlock # Linux
cargo build --release --features sandbox-docker # Tất cả nền tảng
```
### Conditional compilation: không overhead khi tắt
```rust
// src/security/mod.rs
#[cfg(feature = "sandbox-landlock")]
mod landlock;
#[cfg(feature = "sandbox-landlock")]
pub use landlock::LandlockSandbox;
#[cfg(feature = "sandbox-firejail")]
mod firejail;
#[cfg(feature = "sandbox-firejail")]
pub use firejail::FirejailSandbox;
// Basic security luôn được include (không cần feature flag)
pub mod policy; // allowlist, path blocking, injection protection
```
**Kết quả**: Khi các feature bị tắt, code thậm chí không được biên dịch — **binary hoàn toàn không bị phình to**.
---
## 2. Kiến trúc pluggable: bảo mật cũng là một trait
### Security backend trait (hoán đổi như mọi thứ khác)
```rust
// src/security/traits.rs
#[async_trait]
pub trait Sandbox: Send + Sync {
/// Bọc lệnh với lớp bảo vệ sandbox
fn wrap_command(&self, cmd: &mut std::process::Command) -> std::io::Result<()>;
/// Kiểm tra sandbox có khả dụng trên nền tảng này không
fn is_available(&self) -> bool;
/// Tên dễ đọc
fn name(&self) -> &str;
}
// No-op sandbox (luôn khả dụng)
pub struct NoopSandbox;
impl Sandbox for NoopSandbox {
fn wrap_command(&self, _cmd: &mut std::process::Command) -> std::io::Result<()> {
Ok(()) // Pass-through, không thay đổi
}
fn is_available(&self) -> bool { true }
fn name(&self) -> &str { "none" }
}
```
### Factory pattern: tự động chọn dựa trên features
```rust
// src/security/factory.rs
pub fn create_sandbox() -> Box<dyn Sandbox> {
#[cfg(feature = "sandbox-landlock")]
{
if LandlockSandbox::is_available() {
return Box::new(LandlockSandbox::new());
}
}
#[cfg(feature = "sandbox-firejail")]
{
if FirejailSandbox::is_available() {
return Box::new(FirejailSandbox::new());
}
}
#[cfg(feature = "sandbox-bubblewrap")]
{
if BubblewrapSandbox::is_available() {
return Box::new(BubblewrapSandbox::new());
}
}
#[cfg(feature = "sandbox-docker")]
{
if DockerSandbox::is_available() {
return Box::new(DockerSandbox::new());
}
}
// Fallback: luôn khả dụng
Box::new(NoopSandbox)
}
```
**Giống như providers, channels và memory — bảo mật cũng là pluggable!**
---
## 3. Agnostic phần cứng: cùng binary, nhiều nền tảng
### Ma trận hành vi đa nền tảng
| Nền tảng | Build trên | Hành vi runtime |
|----------|-----------|------------------|
| **Linux ARM** (Raspberry Pi) | ✅ Có | Landlock → None (graceful) |
| **Linux x86_64** | ✅ Có | Landlock → Firejail → None |
| **macOS ARM** (M1/M2) | ✅ Có | Bubblewrap → None |
| **macOS x86_64** | ✅ Có | Bubblewrap → None |
| **Windows ARM** | ✅ Có | None (app-layer) |
| **Windows x86_64** | ✅ Có | None (app-layer) |
| **RISC-V Linux** | ✅ Có | Landlock → None |
### Cơ chế hoạt động: phát hiện tại runtime
```rust
// src/security/detect.rs
impl SandboxingStrategy {
/// Chọn sandbox tốt nhất có sẵn TẠI RUNTIME
pub fn detect() -> SandboxingStrategy {
#[cfg(target_os = "linux")]
{
// Thử Landlock trước (phát hiện tính năng kernel)
if Self::probe_landlock() {
return SandboxingStrategy::Landlock;
}
// Thử Firejail (phát hiện công cụ user-space)
if Self::probe_firejail() {
return SandboxingStrategy::Firejail;
}
}
#[cfg(target_os = "macos")]
{
if Self::probe_bubblewrap() {
return SandboxingStrategy::Bubblewrap;
}
}
// Fallback luôn khả dụng
SandboxingStrategy::ApplicationLayer
}
}
```
**Cùng một binary chạy ở khắp nơi** — chỉ tự điều chỉnh mức độ bảo vệ dựa trên những gì có sẵn.
---
## 4. Phần cứng nhỏ: phân tích tác động bộ nhớ
### Tác động kích thước binary (ước tính)
| Tính năng | Kích thước code | RAM overhead | Trạng thái |
|---------|-----------|--------------|--------|
| **ZeroClaw cơ bản** | 3.4MB | <5MB | ✅ Hiện tại |
| **+ Landlock** | +50KB | +100KB | ✅ Linux 5.13+ |
| **+ Firejail wrapper** | +20KB | +0KB (external) | ✅ Linux + firejail |
| **+ Memory monitoring** | +30KB | +50KB | ✅ Tất cả nền tảng |
| **+ Audit logging** | +40KB | +200KB (buffered) | ✅ Tất cả nền tảng |
| **Full security** | +140KB | +350KB | ✅ Vẫn <6MB tổng |
### Tương thích phần cứng $10
| Phần cứng | RAM | ZeroClaw (cơ bản) | ZeroClaw (full security) | Trạng thái |
|----------|-----|-----------------|--------------------------|--------|
| **Raspberry Pi Zero** | 512MB | ✅ 2% | ✅ 2.5% | Hoạt động |
| **Orange Pi Zero** | 512MB | ✅ 2% | ✅ 2.5% | Hoạt động |
| **NanoPi NEO** | 256MB | ✅ 4% | ✅ 5% | Hoạt động |
| **C.H.I.P.** | 512MB | ✅ 2% | ✅ 2.5% | Hoạt động |
| **Rock64** | 1GB | ✅ 1% | ✅ 1.2% | Hoạt động |
**Ngay cả với full security, ZeroClaw chỉ dùng <5% RAM trên board $10.**
---
## 5. Tính hoán đổi: mọi thứ vẫn pluggable
### Cam kết chính của ZeroClaw: hoán đổi bất kỳ thứ gì
```rust
// Providers (đã pluggable)
Box<dyn Provider>
// Channels (đã pluggable)
Box<dyn Channel>
// Memory (đã pluggable)
Box<dyn MemoryBackend>
// Tunnels (đã pluggable)
Box<dyn Tunnel>
// BÂY GIỜ CŨNG: Security (mới pluggable)
Box<dyn Sandbox>
Box<dyn Auditor>
Box<dyn ResourceMonitor>
```
### Hoán đổi security backend qua config
```toml
# Không dùng sandbox (nhanh nhất, chỉ app-layer)
[security.sandbox]
backend = "none"
# Dùng Landlock (Linux kernel LSM, native)
[security.sandbox]
backend = "landlock"
# Dùng Firejail (user-space, cần cài firejail)
[security.sandbox]
backend = "firejail"
# Dùng Docker (nặng nhất, cách ly hoàn toàn)
[security.sandbox]
backend = "docker"
```
**Giống như hoán đổi OpenAI sang Gemini, hay SQLite sang PostgreSQL.**
---
## 6. Tác động phụ thuộc: thêm tối thiểu
### Phụ thuộc hiện tại (để tham khảo)
```
reqwest, tokio, serde, anyhow, uuid, chrono, rusqlite,
axum, tracing, opentelemetry, ...
```
### Phụ thuộc của các security feature
| Tính năng | Phụ thuộc mới | Nền tảng |
|---------|------------------|----------|
| **Landlock** | `landlock` crate (pure Rust) | Chỉ Linux |
| **Firejail** | Không (binary ngoài) | Chỉ Linux |
| **Bubblewrap** | Không (binary ngoài) | macOS/Linux |
| **Docker** | `bollard` crate (Docker API) | Tất cả nền tảng |
| **Memory monitoring** | Không (std::alloc) | Tất cả nền tảng |
| **Audit logging** | Không (đã có hmac/sha2) | Tất cả nền tảng |
**Kết quả**: Hầu hết tính năng **không thêm phụ thuộc Rust mới** — chúng hoặc:
1. Dùng pure-Rust crate (landlock)
2. Bọc binary ngoài (Firejail, Bubblewrap)
3. Dùng phụ thuộc sẵn có (hmac, sha2 đã có trong Cargo.toml)
---
## Tóm tắt: các giá trị chính được bảo toàn
| Giá trị | Trước | Sau (có bảo mật) | Trạng thái |
|------------|--------|----------------------|--------|
| **<5MB RAM** | ✅ <5MB | ✅ <6MB (trường hợp xấu nhất) | ✅ Bảo toàn |
| **<10ms startup** | ✅ <10ms | ✅ <15ms (detection) | ✅ Bảo toàn |
| **3.4MB binary** | ✅ 3.4MB | ✅ 3.5MB (với tất cả features) | ✅ Bảo toàn |
| **ARM + x86 + RISC-V** | ✅ Tất cả | ✅ Tất cả | ✅ Bảo toàn |
| **Phần cứng $10** | ✅ Hoạt động | ✅ Hoạt động | ✅ Bảo toàn |
| **Pluggable everything** | ✅ Có | ✅ Có (cả bảo mật) | ✅ Cải thiện |
| **Cross-platform** | ✅ Có | ✅ Có | ✅ Bảo toàn |
---
## Điểm mấu chốt: feature flags + conditional compilation
```bash
# Developer build (nhanh nhất, không có extra feature)
cargo build --profile dev
# Standard release (build hiện tại của bạn)
cargo build --release
# Production với full security
cargo build --release --features security-full
# Nhắm đến phần cứng cụ thể
cargo build --release --target aarch64-unknown-linux-gnu # Raspberry Pi
cargo build --release --target riscv64gc-unknown-linux-gnu # RISC-V
cargo build --release --target armv7-unknown-linux-gnueabihf # ARMv7
```
**Mọi target, mọi nền tảng, mọi trường hợp sử dụng — vẫn nhanh, vẫn nhỏ, vẫn agnostic.**
-217
View File
@@ -1,217 +0,0 @@
# ZeroClaw trên Arduino Uno Q — Hướng dẫn từng bước
Chạy ZeroClaw trên phía Linux của Arduino Uno Q. Telegram hoạt động qua WiFi; điều khiển GPIO dùng Bridge (yêu cầu một ứng dụng App Lab tối giản).
---
## Những gì đã có sẵn (Không cần thay đổi code)
ZeroClaw bao gồm mọi thứ cần thiết cho Arduino Uno Q. **Clone repo và làm theo hướng dẫn này — không cần patch hay code tùy chỉnh nào.**
| Thành phần | Vị trí | Mục đích |
|------------|--------|---------|
| Bridge app | `firmware/uno-q-bridge/` | MCU sketch + Python socket server (port 9999) cho GPIO |
| Bridge tools | `src/peripherals/uno_q_bridge.rs` | Tool `gpio_read` / `gpio_write` giao tiếp với Bridge qua TCP |
| Setup command | `src/peripherals/uno_q_setup.rs` | `zeroclaw peripheral setup-uno-q` triển khai Bridge qua scp + arduino-app-cli |
| Config schema | `board = "arduino-uno-q"`, `transport = "bridge"` | Được hỗ trợ trong `config.toml` |
Build với `--features hardware` (hoặc features mặc định) để bao gồm hỗ trợ Uno Q.
---
## Yêu cầu trước khi bắt đầu
- Arduino Uno Q đã cấu hình WiFi
- Arduino App Lab đã cài trên Mac (để thiết lập và triển khai lần đầu)
- API key cho LLM (OpenRouter, v.v.)
---
## Phase 1: Thiết lập Uno Q lần đầu (Một lần duy nhất)
### 1.1 Cấu hình Uno Q qua App Lab
1. Tải [Arduino App Lab](https://docs.arduino.cc/software/app-lab/) (AppImage trên Linux).
2. Kết nối Uno Q qua USB, bật nguồn.
3. Mở App Lab, kết nối với board.
4. Làm theo hướng dẫn cài đặt:
- Đặt username và password (cho SSH)
- Cấu hình WiFi (SSID, password)
- Áp dụng các bản cập nhật firmware nếu có
5. Ghi lại địa chỉ IP hiển thị (ví dụ: `arduino@192.168.1.42`) hoặc tìm sau qua `ip addr show` trong terminal của App Lab.
### 1.2 Xác nhận truy cập SSH
```bash
ssh arduino@<UNO_Q_IP>
# Nhập password đã đặt
```
---
## Phase 2: Cài đặt ZeroClaw trên Uno Q
### Phương án A: Build trực tiếp trên thiết bị (Đơn giản hơn, ~2040 phút)
```bash
# SSH vào Uno Q
ssh arduino@<UNO_Q_IP>
# Cài Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source ~/.cargo/env
# Cài các gói phụ thuộc build (Debian)
sudo apt-get update
sudo apt-get install -y pkg-config libssl-dev
# Clone zeroclaw (hoặc scp project của bạn)
git clone https://github.com/zeroclaw-labs/zeroclaw.git
cd zeroclaw
# Build (~1530 phút trên Uno Q)
cargo build --release
# Cài đặt
sudo cp target/release/zeroclaw /usr/local/bin/
```
### Phương án B: Cross-Compile trên Mac (Nhanh hơn)
```bash
# Trên Mac — thêm target aarch64
rustup target add aarch64-unknown-linux-gnu
# Cài cross-compiler (macOS; cần cho linking)
brew tap messense/macos-cross-toolchains
brew install aarch64-unknown-linux-gnu
# Build
CC_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnu-gcc cargo build --release --target aarch64-unknown-linux-gnu
# Copy sang Uno Q
scp target/aarch64-unknown-linux-gnu/release/zeroclaw arduino@<UNO_Q_IP>:~/
ssh arduino@<UNO_Q_IP> "sudo mv ~/zeroclaw /usr/local/bin/"
```
Nếu cross-compile thất bại, dùng Phương án A và build trực tiếp trên thiết bị.
---
## Phase 3: Cấu hình ZeroClaw
### 3.1 Chạy Onboard (hoặc tạo Config thủ công)
```bash
ssh arduino@<UNO_Q_IP>
# Cấu hình nhanh
zeroclaw onboard --api-key YOUR_OPENROUTER_KEY --provider openrouter
# Hoặc tạo config thủ công
mkdir -p ~/.zeroclaw/workspace
nano ~/.zeroclaw/config.toml
```
### 3.2 config.toml tối giản
```toml
api_key = "YOUR_OPENROUTER_API_KEY"
default_provider = "openrouter"
default_model = "anthropic/claude-sonnet-4-6"
[peripherals]
enabled = false
# GPIO qua Bridge yêu cầu Phase 4
[channels_config.telegram]
bot_token = "YOUR_TELEGRAM_BOT_TOKEN"
allowed_users = ["*"]
[gateway]
host = "127.0.0.1"
port = 3000
allow_public_bind = false
[agent]
compact_context = true
```
---
## Phase 4: Chạy ZeroClaw Daemon
```bash
ssh arduino@<UNO_Q_IP>
# Chạy daemon (Telegram polling hoạt động qua WiFi)
zeroclaw daemon --host 127.0.0.1 --port 3000
```
**Tại bước này:** Telegram chat hoạt động. Gửi tin nhắn tới bot — ZeroClaw phản hồi. Chưa có GPIO.
---
## Phase 5: GPIO qua Bridge (ZeroClaw xử lý tự động)
ZeroClaw bao gồm Bridge app và setup command.
### 5.1 Triển khai Bridge App
**Từ Mac** (với repo zeroclaw):
```bash
zeroclaw peripheral setup-uno-q --host 192.168.0.48
```
**Từ Uno Q** (đã SSH vào):
```bash
zeroclaw peripheral setup-uno-q
```
Lệnh này copy Bridge app vào `~/ArduinoApps/uno-q-bridge` và khởi động nó.
### 5.2 Thêm vào config.toml
```toml
[peripherals]
enabled = true
[[peripherals.boards]]
board = "arduino-uno-q"
transport = "bridge"
```
### 5.3 Chạy ZeroClaw
```bash
zeroclaw daemon --host 127.0.0.1 --port 3000
```
Giờ khi bạn nhắn tin cho Telegram bot *"Turn on the LED"* hoặc *"Set pin 13 high"*, ZeroClaw dùng `gpio_write` qua Bridge.
---
## Tóm tắt: Các lệnh từ đầu đến cuối
| Bước | Lệnh |
|------|------|
| 1 | Cấu hình Uno Q trong App Lab (WiFi, SSH) |
| 2 | `ssh arduino@<IP>` |
| 3 | `curl -sSf https://sh.rustup.rs \| sh -s -- -y && source ~/.cargo/env` |
| 4 | `sudo apt-get install -y pkg-config libssl-dev` |
| 5 | `git clone https://github.com/zeroclaw-labs/zeroclaw.git && cd zeroclaw` |
| 6 | `cargo build --release --no-default-features` |
| 7 | `zeroclaw onboard --api-key KEY --provider openrouter` |
| 8 | Chỉnh sửa `~/.zeroclaw/config.toml` (thêm Telegram bot_token) |
| 9 | `zeroclaw daemon --host 127.0.0.1 --port 3000` |
| 10 | Nhắn tin cho Telegram bot — nó phản hồi |
---
## Xử lý sự cố
- **"command not found: zeroclaw"** — Dùng đường dẫn đầy đủ: `/usr/local/bin/zeroclaw` hoặc đảm bảo `~/.cargo/bin` nằm trong PATH.
- **Telegram không phản hồi** — Kiểm tra bot_token, allowed_users, và Uno Q có kết nối internet (WiFi).
- **Hết bộ nhớ** — Dùng `--no-default-features` để giảm kích thước binary; cân nhắc `compact_context = true`.
- **Lệnh GPIO bị bỏ qua** — Đảm bảo Bridge app đang chạy (`zeroclaw peripheral setup-uno-q` triển khai và khởi động nó). Config phải có `board = "arduino-uno-q"``transport = "bridge"`.
- **LLM provider (GLM/Zhipu)** — Dùng `default_provider = "glm"` hoặc `"zhipu"` với `GLM_API_KEY` trong env hoặc config. ZeroClaw dùng endpoint v4 chính xác.
-192
View File
@@ -1,192 +0,0 @@
# Audit logging
> ⚠️ **Trạng thái: Đề xuất / Lộ trình**
>
> Tài liệu này mô tả các hướng tiếp cận đề xuất và có thể bao gồm các lệnh hoặc cấu hình giả định.
> Để biết hành vi runtime hiện tại, xem [config-reference.md](config-reference.md), [operations-runbook.md](operations-runbook.md), và [troubleshooting.md](troubleshooting.md).
## Vấn đề
ZeroClaw ghi log các hành động nhưng thiếu audit trail chống giả mạo cho:
- Ai đã thực thi lệnh nào
- Khi nào và từ channel nào
- Những tài nguyên nào được truy cập
- Chính sách bảo mật có bị kích hoạt không
---
## Định dạng audit log đề xuất
```json
{
"timestamp": "2026-02-16T12:34:56Z",
"event_id": "evt_1a2b3c4d",
"event_type": "command_execution",
"actor": {
"channel": "telegram",
"user_id": "123456789",
"username": "@alice"
},
"action": {
"command": "ls -la",
"risk_level": "low",
"approved": false,
"allowed": true
},
"result": {
"success": true,
"exit_code": 0,
"duration_ms": 15
},
"security": {
"policy_violation": false,
"rate_limit_remaining": 19
},
"signature": "SHA256:abc123..." // HMAC để chống giả mạo
}
```
---
## Triển khai
```rust
// src/security/audit.rs
use serde::{Deserialize, Serialize};
use std::io::Write;
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditEvent {
pub timestamp: String,
pub event_id: String,
pub event_type: AuditEventType,
pub actor: Actor,
pub action: Action,
pub result: ExecutionResult,
pub security: SecurityContext,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuditEventType {
CommandExecution,
FileAccess,
ConfigurationChange,
AuthSuccess,
AuthFailure,
PolicyViolation,
}
pub struct AuditLogger {
log_path: PathBuf,
signing_key: Option<hmac::Hmac<sha2::Sha256>>,
}
impl AuditLogger {
pub fn log(&self, event: &AuditEvent) -> anyhow::Result<()> {
let mut line = serde_json::to_string(event)?;
// Thêm chữ ký HMAC nếu key được cấu hình
if let Some(ref key) = self.signing_key {
let signature = compute_hmac(key, line.as_bytes());
line.push_str(&format!("\n\"signature\": \"{}\"", signature));
}
let mut file = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&self.log_path)?;
writeln!(file, "{}", line)?;
file.sync_all()?; // Flush cưỡng bức để đảm bảo độ bền
Ok(())
}
pub fn search(&self, filter: AuditFilter) -> Vec<AuditEvent> {
// Tìm kiếm file log theo tiêu chí filter
todo!()
}
}
```
---
## Config schema
```toml
[security.audit]
enabled = true
log_path = "~/.config/zeroclaw/audit.log"
max_size_mb = 100
rotate = "daily" # daily | weekly | size
# Chống giả mạo
sign_events = true
signing_key_path = "~/.config/zeroclaw/audit.key"
# Những gì cần log
log_commands = true
log_file_access = true
log_auth_events = true
log_policy_violations = true
```
---
## CLI truy vấn audit
```bash
# Hiển thị tất cả lệnh được thực thi bởi @alice
zeroclaw audit --user @alice
# Hiển thị tất cả lệnh rủi ro cao
zeroclaw audit --risk high
# Hiển thị vi phạm trong 24 giờ qua
zeroclaw audit --since 24h --violations-only
# Xuất sang JSON để phân tích
zeroclaw audit --format json --output audit.json
# Xác minh tính toàn vẹn của log
zeroclaw audit --verify-signatures
```
---
## Xoay vòng log
```rust
pub fn rotate_audit_log(log_path: &PathBuf, max_size: u64) -> anyhow::Result<()> {
let metadata = std::fs::metadata(log_path)?;
if metadata.len() < max_size {
return Ok(());
}
// Xoay vòng: audit.log -> audit.log.1 -> audit.log.2 -> ...
let stem = log_path.file_stem().unwrap_or_default();
let extension = log_path.extension().and_then(|s| s.to_str()).unwrap_or("log");
for i in (1..10).rev() {
let old_name = format!("{}.{}.{}", stem, i, extension);
let new_name = format!("{}.{}.{}", stem, i + 1, extension);
let _ = std::fs::rename(old_name, new_name);
}
let rotated = format!("{}.1.{}", stem, extension);
std::fs::rename(log_path, &rotated)?;
Ok(())
}
```
---
## Thứ tự triển khai
| Giai đoạn | Tính năng | Công sức | Giá trị bảo mật |
|-------|---------|--------|----------------|
| **P0** | Ghi log sự kiện cơ bản | Thấp | Trung bình |
| **P1** | Query CLI | Trung bình | Trung bình |
| **P2** | Ký HMAC | Trung bình | Cao |
| **P3** | Xoay vòng log + lưu trữ | Thấp | Trung bình |
-424
View File
@@ -1,424 +0,0 @@
# Tài liệu tham khảo Channels
Tài liệu này là nguồn tham khảo chính thức về cấu hình channel trong ZeroClaw.
Với các phòng Matrix được mã hóa, xem hướng dẫn chuyên biệt:
- [Hướng dẫn Matrix E2EE](matrix-e2ee-guide.md)
## Truy cập nhanh
- Cần tham khảo config đầy đủ theo từng channel: xem mục `## 4. Ví dụ cấu hình theo từng channel`.
- Cần chẩn đoán khi không nhận được phản hồi: xem mục `## 6. Danh sách kiểm tra xử lý sự cố`.
- Cần hỗ trợ phòng Matrix được mã hóa: dùng [Hướng dẫn Matrix E2EE](matrix-e2ee-guide.md).
- Cần thông tin triển khai/mạng (polling vs webhook): dùng [Network Deployment](network-deployment.md).
## FAQ: Cấu hình Matrix thành công nhưng không có phản hồi
Đây là triệu chứng phổ biến nhất (cùng loại với issue #499). Kiểm tra theo thứ tự sau:
1. **Allowlist không khớp**: `allowed_users` không bao gồm người gửi (hoặc để trống).
2. **Room đích sai**: bot chưa tham gia room được cấu hình `room_id` / alias.
3. **Token/tài khoản không khớp**: token hợp lệ nhưng thuộc tài khoản Matrix khác.
4. **Thiếu E2EE device identity**: `whoami` không trả về `device_id` và config không cung cấp giá trị này.
5. **Thiếu key sharing/trust**: các khóa room chưa được chia sẻ cho thiết bị bot, nên không thể giải mã sự kiện mã hóa.
6. **Trạng thái runtime cũ**: config đã thay đổi nhưng `zeroclaw daemon` chưa được khởi động lại.
---
## 1. Namespace cấu hình
Tất cả cài đặt channel nằm trong `channels_config` trong `~/.zeroclaw/config.toml`.
```toml
[channels_config]
cli = true
```
Mỗi channel được bật bằng cách tạo sub-table tương ứng (ví dụ: `[channels_config.telegram]`).
## Chuyển đổi model runtime trong chat (Telegram / Discord)
Khi chạy `zeroclaw channel start` (hoặc chế độ daemon), Telegram và Discord hỗ trợ chuyển đổi runtime theo phạm vi người gửi:
- `/models` — hiển thị các provider hiện có và lựa chọn hiện tại
- `/models <provider>` — chuyển provider cho phiên người gửi hiện tại
- `/model` — hiển thị model hiện tại và các model ID đã cache (nếu có)
- `/model <model-id>` — chuyển model cho phiên người gửi hiện tại
Lưu ý:
- Việc chuyển đổi chỉ xóa lịch sử hội thoại trong bộ nhớ của người gửi đó, tránh ô nhiễm ngữ cảnh giữa các model.
- Xem trước bộ nhớ cache model từ `zeroclaw models refresh --provider <ID>`.
- Đây là lệnh chat runtime, không phải lệnh con CLI.
## Giao thức marker hình ảnh đầu vào
ZeroClaw hỗ trợ đầu vào multimodal qua các marker nội tuyến trong tin nhắn:
- Cú pháp: ``[IMAGE:<source>]``
- `<source>` có thể là:
- Đường dẫn file cục bộ
- Data URI (`data:image/...;base64,...`)
- URL từ xa chỉ khi `[multimodal].allow_remote_fetch = true`
Lưu ý vận hành:
- Marker được phân tích trong các tin nhắn người dùng trước khi gọi provider.
- Capability của provider được kiểm tra tại runtime: nếu provider không hỗ trợ vision, request thất bại với lỗi capability có cấu trúc (`capability=vision`).
- Các phần `media` của Linq webhook có MIME type `image/*` được tự động chuyển đổi sang định dạng marker này.
## Channel Matrix
### Tùy chọn Build Feature (`channel-matrix`)
Hỗ trợ Matrix được kiểm soát tại thời điểm biên dịch bằng Cargo feature `channel-matrix`.
- Các bản build mặc định đã bao gồm hỗ trợ Matrix (`default = ["hardware", "channel-matrix"]`).
- Để lặp lại nhanh hơn khi không cần Matrix:
```bash
cargo check --no-default-features --features hardware
```
- Để bật tường minh hỗ trợ Matrix trong feature set tùy chỉnh:
```bash
cargo check --no-default-features --features hardware,channel-matrix
```
Nếu `[channels_config.matrix]` có mặt nhưng binary được build mà không có `channel-matrix`, các lệnh `zeroclaw channel list`, `zeroclaw channel doctor`, và `zeroclaw channel start` sẽ ghi log rằng Matrix bị bỏ qua có chủ ý trong bản build này.
---
## 2. Chế độ phân phối tóm tắt
| Channel | Chế độ nhận | Cần cổng inbound công khai? |
|---|---|---|
| CLI | local stdin/stdout | Không |
| Telegram | polling | Không |
| Discord | gateway/websocket | Không |
| Slack | events API | Không (luồng token-based) |
| Mattermost | polling | Không |
| Matrix | sync API (hỗ trợ E2EE) | Không |
| Signal | signal-cli HTTP bridge | Không (endpoint bridge cục bộ) |
| WhatsApp | webhook (Cloud API) hoặc websocket (Web mode) | Cloud API: Có (HTTPS callback công khai), Web mode: Không |
| Webhook | gateway endpoint (`/webhook`) | Thường là có |
| Email | IMAP polling + SMTP send | Không |
| IRC | IRC socket | Không |
| Lark/Feishu | websocket (mặc định) hoặc webhook | Chỉ ở chế độ Webhook |
| DingTalk | stream mode | Không |
| QQ | bot gateway | Không |
| iMessage | tích hợp cục bộ | Không |
---
## 3. Ngữ nghĩa allowlist
Với các channel có allowlist người gửi:
- Allowlist trống: từ chối tất cả tin nhắn đầu vào.
- `"*"`: cho phép tất cả người gửi (chỉ dùng để xác minh tạm thời).
- Danh sách tường minh: chỉ cho phép những người gửi được liệt kê.
Tên trường khác nhau theo channel:
- `allowed_users` (Telegram/Discord/Slack/Mattermost/Matrix/IRC/Lark/DingTalk/QQ)
- `allowed_from` (Signal)
- `allowed_numbers` (WhatsApp)
- `allowed_senders` (Email)
- `allowed_contacts` (iMessage)
---
## 4. Ví dụ cấu hình theo từng channel
### 4.1 Telegram
```toml
[channels_config.telegram]
bot_token = "123456:telegram-token"
allowed_users = ["*"]
stream_mode = "off" # tùy chọn: off | partial
draft_update_interval_ms = 1000 # tùy chọn: giới hạn tần suất chỉnh sửa khi streaming một phần
mention_only = false # tùy chọn: yêu cầu @mention trong nhóm
interrupt_on_new_message = false # tùy chọn: hủy yêu cầu đang xử lý cùng người gửi cùng chat
```
Lưu ý về Telegram:
- `interrupt_on_new_message = true` giữ lại các lượt người dùng bị gián đoạn trong lịch sử hội thoại, sau đó khởi động lại việc tạo nội dung với tin nhắn mới nhất.
- Phạm vi gián đoạn rất chặt chẽ: cùng người gửi trong cùng chat. Tin nhắn từ các chat khác nhau được xử lý độc lập.
### 4.2 Discord
```toml
[channels_config.discord]
bot_token = "discord-bot-token"
guild_id = "123456789012345678" # tùy chọn
allowed_users = ["*"]
listen_to_bots = false
mention_only = false
```
### 4.3 Slack
```toml
[channels_config.slack]
bot_token = "xoxb-..."
app_token = "xapp-..." # tùy chọn
channel_id = "C1234567890" # tùy chọn
allowed_users = ["*"]
```
### 4.4 Mattermost
```toml
[channels_config.mattermost]
url = "https://mm.example.com"
bot_token = "mattermost-token"
channel_id = "channel-id" # bắt buộc để lắng nghe
allowed_users = ["*"]
```
### 4.5 Matrix
```toml
[channels_config.matrix]
homeserver = "https://matrix.example.com"
access_token = "syt_..."
user_id = "@zeroclaw:matrix.example.com" # tùy chọn, khuyến nghị cho E2EE
device_id = "DEVICEID123" # tùy chọn, khuyến nghị cho E2EE
room_id = "!room:matrix.example.com" # hoặc room alias (#ops:matrix.example.com)
allowed_users = ["*"]
```
Xem [Hướng dẫn Matrix E2EE](matrix-e2ee-guide.md) để xử lý sự cố phòng mã hóa.
### 4.6 Signal
```toml
[channels_config.signal]
http_url = "http://127.0.0.1:8686"
account = "+1234567890"
group_id = "dm" # tùy chọn: "dm" / group id / bỏ qua
allowed_from = ["*"]
ignore_attachments = false
ignore_stories = true
```
### 4.7 WhatsApp
ZeroClaw hỗ trợ hai backend WhatsApp:
- **Chế độ Cloud API** (`phone_number_id` + `access_token` + `verify_token`)
- **Chế độ WhatsApp Web** (`session_path`, yêu cầu build flag `--features whatsapp-web`)
Chế độ Cloud API:
```toml
[channels_config.whatsapp]
access_token = "EAAB..."
phone_number_id = "123456789012345"
verify_token = "your-verify-token"
app_secret = "your-app-secret" # tùy chọn nhưng được khuyến nghị
allowed_numbers = ["*"]
```
Chế độ WhatsApp Web:
```toml
[channels_config.whatsapp]
session_path = "~/.zeroclaw/state/whatsapp-web/session.db"
pair_phone = "15551234567" # tùy chọn; bỏ qua để dùng QR flow
pair_code = "" # tùy chọn pair code tùy chỉnh
allowed_numbers = ["*"]
```
Lưu ý:
- Build với `cargo build --features whatsapp-web` (hoặc lệnh run tương đương).
- Giữ `session_path` trên bộ nhớ lưu trữ bền vững để tránh phải liên kết lại sau khi khởi động lại.
- Định tuyến trả lời sử dụng JID của chat nguồn, vì vậy cả trả lời trực tiếp và nhóm đều hoạt động đúng.
### 4.8 Cấu hình Webhook Channel (Gateway)
`channels_config.webhook` bật hành vi gateway đặc thù cho webhook.
```toml
[channels_config.webhook]
port = 8080
secret = "optional-shared-secret"
```
Chạy với gateway/daemon và xác minh `/health`.
### 4.9 Email
```toml
[channels_config.email]
imap_host = "imap.example.com"
imap_port = 993
imap_folder = "INBOX"
smtp_host = "smtp.example.com"
smtp_port = 465
smtp_tls = true
username = "bot@example.com"
password = "email-password"
from_address = "bot@example.com"
poll_interval_secs = 60
allowed_senders = ["*"]
```
### 4.10 IRC
```toml
[channels_config.irc]
server = "irc.libera.chat"
port = 6697
nickname = "zeroclaw-bot"
username = "zeroclaw" # tùy chọn
channels = ["#zeroclaw"]
allowed_users = ["*"]
server_password = "" # tùy chọn
nickserv_password = "" # tùy chọn
sasl_password = "" # tùy chọn
verify_tls = true
```
### 4.11 Lark / Feishu
```toml
[channels_config.lark]
app_id = "cli_xxx"
app_secret = "xxx"
encrypt_key = "" # tùy chọn
verification_token = "" # tùy chọn
allowed_users = ["*"]
use_feishu = false
receive_mode = "websocket" # hoặc "webhook"
port = 8081 # bắt buộc ở chế độ webhook
```
Hỗ trợ onboarding hướng dẫn:
```bash
zeroclaw onboard
```
Trình hướng dẫn bao gồm bước **Lark/Feishu** chuyên biệt với:
- Chọn khu vực (`Feishu (CN)` hoặc `Lark (International)`)
- Xác minh thông tin xác thực với endpoint auth của Open Platform chính thức
- Chọn chế độ nhận (`websocket` hoặc `webhook`)
- Tùy chọn nhập verification token webhook (khuyến nghị để tăng cường kiểm tra tính xác thực của callback)
Hành vi token runtime:
- `tenant_access_token` được cache với thời hạn làm mới dựa trên `expire`/`expires_in` từ phản hồi xác thực.
- Các yêu cầu gửi tự động thử lại một lần sau khi token bị vô hiệu hóa khi Feishu/Lark trả về HTTP `401` hoặc mã lỗi nghiệp vụ `99991663` (`Invalid access token`).
- Nếu lần thử lại vẫn trả về phản hồi token không hợp lệ, lời gọi gửi sẽ thất bại với trạng thái/nội dung upstream để dễ xử lý sự cố hơn.
### 4.12 DingTalk
```toml
[channels_config.dingtalk]
client_id = "ding-app-key"
client_secret = "ding-app-secret"
allowed_users = ["*"]
```
### 4.13 QQ
```toml
[channels_config.qq]
app_id = "qq-app-id"
app_secret = "qq-app-secret"
allowed_users = ["*"]
```
### 4.14 iMessage
```toml
[channels_config.imessage]
allowed_contacts = ["*"]
```
---
## 5. Quy trình xác thực
1. Cấu hình một channel với allowlist rộng (`"*"`) để xác minh ban đầu.
2. Chạy:
```bash
zeroclaw onboard --channels-only
zeroclaw daemon
```
1. Gửi tin nhắn từ người gửi dự kiến.
2. Xác nhận nhận được phản hồi.
3. Siết chặt allowlist từ `"*"` thành các ID cụ thể.
---
## 6. Danh sách kiểm tra xử lý sự cố
Nếu channel có vẻ đã kết nối nhưng không phản hồi:
1. Xác nhận danh tính người gửi được cho phép bởi trường allowlist đúng.
2. Xác nhận tài khoản bot đã là thành viên/có quyền trong room/channel đích.
3. Xác nhận token/secret hợp lệ (và chưa hết hạn/bị thu hồi).
4. Xác nhận giả định về chế độ truyền tải:
- Các channel polling/websocket không cần HTTP inbound công khai
- Các channel webhook cần HTTPS callback có thể truy cập được
5. Khởi động lại `zeroclaw daemon` sau khi thay đổi config.
Đặc biệt với các phòng Matrix mã hóa, dùng:
- [Hướng dẫn Matrix E2EE](matrix-e2ee-guide.md)
---
## 7. Phụ lục vận hành: bảng từ khóa log
Dùng phụ lục này để phân loại sự cố nhanh. Khớp từ khóa log trước, sau đó thực hiện các bước xử lý sự cố ở trên.
### 7.1 Lệnh capture được khuyến nghị
```bash
RUST_LOG=info zeroclaw daemon 2>&1 | tee /tmp/zeroclaw.log
```
Sau đó lọc các sự kiện channel/gateway:
```bash
rg -n "Matrix|Telegram|Discord|Slack|Mattermost|Signal|WhatsApp|Email|IRC|Lark|DingTalk|QQ|iMessage|Webhook|Channel" /tmp/zeroclaw.log
```
### 7.2 Bảng từ khóa
| Thành phần | Tín hiệu khởi động / hoạt động bình thường | Tín hiệu ủy quyền / chính sách | Tín hiệu truyền tải / lỗi |
|---|---|---|---|
| Telegram | `Telegram channel listening for messages...` | `Telegram: ignoring message from unauthorized user:` | `Telegram poll error:` / `Telegram parse error:` / `Telegram polling conflict (409):` |
| Discord | `Discord: connected and identified` | `Discord: ignoring message from unauthorized user:` | `Discord: received Reconnect (op 7)` / `Discord: received Invalid Session (op 9)` |
| Slack | `Slack channel listening on #` | `Slack: ignoring message from unauthorized user:` | `Slack poll error:` / `Slack parse error:` |
| Mattermost | `Mattermost channel listening on` | `Mattermost: ignoring message from unauthorized user:` | `Mattermost poll error:` / `Mattermost parse error:` |
| Matrix | `Matrix channel listening on room` / `Matrix room ... is encrypted; E2EE decryption is enabled via matrix-sdk.` | `Matrix whoami failed; falling back to configured session hints for E2EE session restore:` / `Matrix whoami failed while resolving listener user_id; using configured user_id hint:` | `Matrix sync error: ... retrying...` |
| Signal | `Signal channel listening via SSE on` | (kiểm tra allowlist được thực thi bởi `allowed_from`) | `Signal SSE returned ...` / `Signal SSE connect error:` |
| WhatsApp (channel) | `WhatsApp channel active (webhook mode).` / `WhatsApp Web connected successfully` | `WhatsApp: ignoring message from unauthorized number:` / `WhatsApp Web: message from ... not in allowed list` | `WhatsApp send failed:` / `WhatsApp Web stream error:` |
| Webhook / WhatsApp (gateway) | `WhatsApp webhook verified successfully` | `Webhook: rejected — not paired / invalid bearer token` / `Webhook: rejected request — invalid or missing X-Webhook-Secret` / `WhatsApp webhook verification failed — token mismatch` | `Webhook JSON parse error:` |
| Email | `Email polling every ...` / `Email sent to ...` | `Blocked email from ...` | `Email poll failed:` / `Email poll task panicked:` |
| IRC | `IRC channel connecting to ...` / `IRC registered as ...` | (kiểm tra allowlist được thực thi bởi `allowed_users`) | `IRC SASL authentication failed (...)` / `IRC server does not support SASL...` / `IRC nickname ... is in use, trying ...` |
| Lark / Feishu | `Lark: WS connected` / `Lark event callback server listening on` | `Lark WS: ignoring ... (not in allowed_users)` / `Lark: ignoring message from unauthorized user:` | `Lark: ping failed, reconnecting` / `Lark: heartbeat timeout, reconnecting` / `Lark: WS read error:` |
| DingTalk | `DingTalk: connected and listening for messages...` | `DingTalk: ignoring message from unauthorized user:` | `DingTalk WebSocket error:` / `DingTalk: message channel closed` |
| QQ | `QQ: connected and identified` | `QQ: ignoring C2C message from unauthorized user:` / `QQ: ignoring group message from unauthorized user:` | `QQ: received Reconnect (op 7)` / `QQ: received Invalid Session (op 9)` / `QQ: message channel closed` |
| iMessage | `iMessage channel listening (AppleScript bridge)...` | (allowlist liên hệ được thực thi bởi `allowed_contacts`) | `iMessage poll error:` |
### 7.3 Từ khóa của runtime supervisor
Nếu một channel task cụ thể bị crash hoặc thoát, channel supervisor trong `channels/mod.rs` phát ra:
- `Channel <name> exited unexpectedly; restarting`
- `Channel <name> error: ...; restarting`
- `Channel message worker crashed:`
Các thông báo này xác nhận cơ chế tự restart đang hoạt động. Kiểm tra log trước đó để tìm nguyên nhân gốc rễ.
-125
View File
@@ -1,125 +0,0 @@
# Bản đồ CI Workflow
Tài liệu này giải thích từng GitHub workflow làm gì, khi nào chạy và liệu nó có nên chặn merge hay không.
Để biết hành vi phân phối theo từng sự kiện qua PR, merge, push và release, xem [`.github/workflows/master-branch-flow.md`](../../../.github/workflows/master-branch-flow.md).
## Chặn merge và Tùy chọn
Các kiểm tra chặn merge nên giữ nhỏ và mang tính quyết định. Các kiểm tra tùy chọn hữu ích cho tự động hóa và bảo trì, nhưng không nên chặn phát triển bình thường.
### Chặn merge
- `.github/workflows/ci-run.yml` (`CI`)
- Mục đích: Rust validation (`cargo fmt --all -- --check`, `cargo clippy --locked --all-targets -- -D clippy::correctness`, strict delta lint gate trên các dòng Rust thay đổi, `test`, kiểm tra smoke release build) + kiểm tra chất lượng tài liệu khi tài liệu thay đổi (`markdownlint` chỉ chặn các vấn đề trên dòng thay đổi; link check chỉ quét các link mới được thêm trên dòng thay đổi)
- Hành vi bổ sung: đối với PR và push ảnh hưởng Rust, `CI Required Gate` yêu cầu `lint` + `test` + `build` (không có shortcut chỉ build trên PR)
- Hành vi bổ sung: các PR thay đổi `.github/workflows/**` yêu cầu ít nhất một review phê duyệt từ login trong `WORKFLOW_OWNER_LOGINS` (fallback biến repository: `theonlyhennygod,JordanTheJet,SimianAstronaut7`)
- Hành vi bổ sung: lint gate chạy trước `test`/`build`; khi lint/docs gate thất bại trên PR, CI đăng comment phản hồi hành động được với tên gate thất bại và các lệnh sửa cục bộ
- Merge gate: `CI Required Gate`
- `.github/workflows/workflow-sanity.yml` (`Workflow Sanity`)
- Mục đích: lint các file GitHub workflow (`actionlint`, kiểm tra tab)
- Khuyến nghị cho các PR thay đổi workflow
- `.github/workflows/pr-intake-checks.yml` (`PR Intake Checks`)
- Mục đích: kiểm tra PR an toàn trước CI (độ đầy đủ template, tab/trailing-whitespace/conflict marker trên dòng thêm) với comment sticky phản hồi ngay lập tức
### Quan trọng nhưng không chặn
- `.github/workflows/pub-docker-img.yml` (`Docker`)
- Mục đích: kiểm tra Docker smoke trên PR lên `master` và publish image khi push tag (`v*`) only
- `.github/workflows/sec-audit.yml` (`Security Audit`)
- Mục đích: advisory phụ thuộc (`rustsec/audit-check`, SHA được pin) và kiểm tra chính sách/giấy phép (`cargo deny`)
- `.github/workflows/sec-codeql.yml` (`CodeQL Analysis`)
- Mục đích: phân tích tĩnh theo lịch/thủ công để phát hiện vấn đề bảo mật
- `.github/workflows/sec-vorpal-reviewdog.yml` (`Sec Vorpal Reviewdog`)
- Mục đích: quét phản hồi secure-coding thủ công cho các file non-Rust được hỗ trợ (`.py`, `.js`, `.jsx`, `.ts`, `.tsx`) sử dụng annotation reviewdog
- Kiểm soát nhiễu: loại trừ các đường dẫn test/fixture phổ biến và pattern file test theo mặc định (`include_tests=false`)
- `.github/workflows/pub-release.yml` (`Release`)
- Mục đích: build release artifact ở chế độ xác minh (thủ công/theo lịch) và publish GitHub release khi push tag hoặc chế độ publish thủ công
- `.github/workflows/pub-homebrew-core.yml` (`Pub Homebrew Core`)
- Mục đích: luồng PR bump formula Homebrew core thủ công, do bot sở hữu cho các tagged release
- Bảo vệ: release tag phải khớp version `Cargo.toml`
- `.github/workflows/pr-label-policy-check.yml` (`Label Policy Sanity`)
- Mục đích: xác thực chính sách bậc contributor dùng chung trong `.github/label-policy.json` và đảm bảo các label workflow sử dụng chính sách đó
- `.github/workflows/test-rust-build.yml` (`Rust Reusable Job`)
- Mục đích: Rust setup/cache có thể tái sử dụng + trình chạy lệnh cho các workflow-call consumer
### Tự động hóa repository tùy chọn
- `.github/workflows/pr-labeler.yml` (`PR Labeler`)
- Mục đích: nhãn phạm vi/đường dẫn + nhãn kích thước/rủi ro + nhãn module chi tiết (`<module>: <component>`)
- Hành vi bổ sung: mô tả nhãn được quản lý tự động như tooltip khi di chuột để giải thích từng quy tắc phán đoán tự động
- Hành vi bổ sung: từ khóa liên quan đến provider trong các thay đổi provider/config/onboard/integration được thăng cấp lên nhãn `provider:*` (ví dụ `provider:kimi`, `provider:deepseek`)
- Hành vi bổ sung: loại bỏ trùng lặp phân cấp chỉ giữ nhãn phạm vi cụ thể nhất (ví dụ `tool:composio` triệt tiêu `tool:core``tool`)
- Hành vi bổ sung: namespace module được nén gọn — một module cụ thể giữ `prefix:component`; nhiều module cụ thể thu gọn thành chỉ `prefix`
- Hành vi bổ sung: áp dụng bậc contributor trên PR theo số PR đã merge (`trusted` >=5, `experienced` >=10, `principal` >=20, `distinguished` >=50)
- Hành vi bổ sung: bộ nhãn cuối cùng được sắp xếp theo ưu tiên (`risk:*` đầu tiên, sau đó `size:*`, rồi bậc contributor, cuối là nhãn module/đường dẫn)
- Hành vi bổ sung: màu nhãn được quản lý theo thứ tự hiển thị để tạo gradient trái-phải mượt mà khi có nhiều nhãn
- Quản trị thủ công: hỗ trợ `workflow_dispatch` với `mode=audit|repair` để kiểm tra/sửa metadata nhãn được quản lý drift trên toàn repository
- Hành vi bổ sung: nhãn rủi ro + kích thước được tự sửa khi chỉnh sửa nhãn PR thủ công (sự kiện `labeled`/`unlabeled`); áp dụng `risk: manual` khi maintainer cố ý ghi đè lựa chọn rủi ro tự động
- Đường dẫn heuristic rủi ro cao: `src/security/**`, `src/runtime/**`, `src/gateway/**`, `src/tools/**`, `.github/workflows/**`
- Bảo vệ: maintainer có thể áp dụng `risk: manual` để đóng băng tính toán lại rủi ro tự động
- `.github/workflows/pr-auto-response.yml` (`PR Auto Responder`)
- Mục đích: giới thiệu contributor lần đầu + phân tuyến dựa trên nhãn (`r:support`, `r:needs-repro`, v.v.)
- Hành vi bổ sung: áp dụng bậc contributor trên issue theo số PR đã merge (`trusted` >=5, `experienced` >=10, `principal` >=20, `distinguished` >=50), khớp chính xác ngưỡng bậc PR
- Hành vi bổ sung: nhãn bậc contributor được coi là do tự động hóa quản lý (thêm/xóa thủ công trên PR/issue bị tự sửa)
- Bảo vệ: các luồng đóng dựa trên nhãn chỉ dành cho issue; PR không bao giờ bị tự đóng bởi nhãn route
- `.github/workflows/pr-check-stale.yml` (`Stale`)
- Mục đích: tự động hóa vòng đời issue/PR stale
- `.github/dependabot.yml` (`Dependabot`)
- Mục đích: PR cập nhật phụ thuộc được nhóm, giới hạn tốc độ (Cargo + GitHub Actions)
- `.github/workflows/pr-check-status.yml` (`PR Hygiene`)
- Mục đích: nhắc nhở các PR stale-nhưng-còn-hoạt-động để rebase/re-run các kiểm tra bắt buộc trước khi hàng đợi bị đói
## Bản đồ Trigger
- `CI`: push lên `master`, PR lên `master`
- `Docker`: push tag (`v*`) để publish, PR lên `master` tương ứng để smoke build, dispatch thủ công chỉ smoke
- `Release`: push tag (`v*`), lịch hàng tuần (chỉ xác minh), dispatch thủ công (xác minh hoặc publish)
- `Pub Homebrew Core`: dispatch thủ công only
- `Security Audit`: push lên `master`, PR lên `master`, lịch hàng tuần
- `Sec Vorpal Reviewdog`: dispatch thủ công only
- `Workflow Sanity`: PR/push khi `.github/workflows/**`, `.github/*.yml` hoặc `.github/*.yaml` thay đổi
- `PR Intake Checks`: `pull_request_target` khi opened/reopened/synchronize/edited/ready_for_review
- `Label Policy Sanity`: PR/push khi `.github/label-policy.json`, `.github/workflows/pr-labeler.yml` hoặc `.github/workflows/pr-auto-response.yml` thay đổi
- `PR Labeler`: sự kiện vòng đời `pull_request_target`
- `PR Auto Responder`: issue opened/labeled, `pull_request_target` opened/labeled
- `Stale PR Check`: lịch hàng ngày, dispatch thủ công
- `Dependabot`: tất cả PR cập nhật nhắm vào `master`
- `PR Hygiene`: lịch mỗi 12 giờ, dispatch thủ công
## Hướng dẫn triage nhanh
1. `CI Required Gate` thất bại: bắt đầu với `.github/workflows/ci-run.yml`.
2. Docker thất bại trên PR: kiểm tra job `pr-smoke` trong `.github/workflows/pub-docker-img.yml`.
3. Release thất bại (tag/thủ công/theo lịch): kiểm tra `.github/workflows/pub-release.yml` và kết quả job `prepare`.
4. Lỗi publish formula Homebrew: kiểm tra output tóm tắt `.github/workflows/pub-homebrew-core.yml` và biến bot token/fork.
5. Security thất bại: kiểm tra `.github/workflows/sec-audit.yml``deny.toml`.
6. Lỗi cú pháp/lint workflow: kiểm tra `.github/workflows/workflow-sanity.yml`.
7. PR intake thất bại: kiểm tra comment sticky `.github/workflows/pr-intake-checks.yml` và run log.
8. Lỗi parity chính sách nhãn: kiểm tra `.github/workflows/pr-label-policy-check.yml`.
9. Lỗi tài liệu trong CI: kiểm tra log job `docs-quality` trong `.github/workflows/ci-run.yml`.
10. Lỗi strict delta lint trong CI: kiểm tra log job `lint-strict-delta` và so sánh với phạm vi diff `BASE_SHA`.
## Quy tắc bảo trì
- Giữ các kiểm tra chặn merge mang tính quyết định và tái tạo được (`--locked` khi áp dụng được).
- Tuân theo `docs/release-process.md` để kiểm tra trước khi publish và kỷ luật tag.
- Giữ chính sách chất lượng Rust chặn merge nhất quán giữa `.github/workflows/ci-run.yml`, `dev/ci.sh``.githooks/pre-push` (`./scripts/ci/rust_quality_gate.sh` + `./scripts/ci/rust_strict_delta_gate.sh`).
- Dùng `./scripts/ci/rust_strict_delta_gate.sh` (hoặc `./dev/ci.sh lint-delta`) làm merge gate nghiêm ngặt gia tăng cho các dòng Rust thay đổi.
- Chạy kiểm tra lint nghiêm ngặt đầy đủ thường xuyên qua `./scripts/ci/rust_quality_gate.sh --strict` (ví dụ qua `./dev/ci.sh lint-strict`) và theo dõi việc dọn dẹp trong các PR tập trung.
- Giữ gating markdown tài liệu theo gia tăng qua `./scripts/ci/docs_quality_gate.sh` (chặn vấn đề dòng thay đổi, báo cáo vấn đề baseline riêng).
- Giữ gating link tài liệu theo gia tăng qua `./scripts/ci/collect_changed_links.py` + lychee (chỉ kiểm tra link mới thêm trên dòng thay đổi).
- Ưu tiên quyền workflow tường minh (least privilege).
- Giữ chính sách nguồn Actions hạn chế theo allowlist đã được phê duyệt (xem `docs/actions-source-policy.md`).
- Sử dụng bộ lọc đường dẫn cho các workflow tốn kém khi thực tế.
- Giữ kiểm tra chất lượng tài liệu ít nhiễu (markdown gia tăng + kiểm tra link mới thêm gia tăng).
- Giữ khối lượng cập nhật phụ thuộc được kiểm soát (nhóm + giới hạn PR).
- Tránh kết hợp tự động hóa giới thiệu/cộng đồng với logic gating merge.
## Kiểm soát tác dụng phụ tự động hóa
- Ưu tiên tự động hóa mang tính quyết định có thể ghi đè thủ công (`risk: manual`) khi ngữ cảnh tinh tế.
- Giữ comment auto-response không trùng lặp để tránh nhiễu triage.
- Giữ hành vi tự đóng trong phạm vi issue; maintainer quyết định đóng/merge PR.
- Nếu tự động hóa sai, sửa nhãn trước, rồi tiếp tục review với lý do rõ ràng.
- Dùng nhãn `superseded` / `stale-candidate` để cắt tỉa PR trùng lặp hoặc ngủ đông trước khi review sâu.
-159
View File
@@ -1,159 +0,0 @@
# Tham khảo lệnh ZeroClaw
Dựa trên CLI hiện tại (`zeroclaw --help`).
Xác minh lần cuối: **2026-02-20**.
## Lệnh cấp cao nhất
| Lệnh | Mục đích |
|---|---|
| `onboard` | Khởi tạo workspace/config nhanh hoặc tương tác |
| `agent` | Chạy chat tương tác hoặc chế độ gửi tin nhắn đơn |
| `gateway` | Khởi động gateway webhook và HTTP WhatsApp |
| `daemon` | Khởi động runtime có giám sát (gateway + channels + heartbeat/scheduler tùy chọn) |
| `service` | Quản lý vòng đời dịch vụ cấp hệ điều hành |
| `doctor` | Chạy chẩn đoán và kiểm tra trạng thái |
| `status` | Hiển thị cấu hình và tóm tắt hệ thống |
| `cron` | Quản lý tác vụ định kỳ |
| `models` | Làm mới danh mục model của provider |
| `providers` | Liệt kê ID provider, bí danh và provider đang dùng |
| `channel` | Quản lý kênh và kiểm tra sức khỏe kênh |
| `integrations` | Kiểm tra chi tiết tích hợp |
| `skills` | Liệt kê/cài đặt/gỡ bỏ skills |
| `migrate` | Nhập dữ liệu từ runtime khác (hiện hỗ trợ OpenClaw) |
| `config` | Xuất schema cấu hình dạng máy đọc được |
| `completions` | Tạo script tự hoàn thành cho shell ra stdout |
| `hardware` | Phát hiện và kiểm tra phần cứng USB |
| `peripheral` | Cấu hình và nạp firmware thiết bị ngoại vi |
## Nhóm lệnh
### `onboard`
- `zeroclaw onboard`
- `zeroclaw onboard --channels-only`
- `zeroclaw onboard --api-key <KEY> --provider <ID> --memory <sqlite|lucid|markdown|none>`
- `zeroclaw onboard --api-key <KEY> --provider <ID> --model <MODEL_ID> --memory <sqlite|lucid|markdown|none>`
### `agent`
- `zeroclaw agent`
- `zeroclaw agent -m "Hello"`
- `zeroclaw agent --provider <ID> --model <MODEL> --temperature <0.0-2.0>`
- `zeroclaw agent --peripheral <board:path>`
### `gateway` / `daemon`
- `zeroclaw gateway [--host <HOST>] [--port <PORT>]`
- `zeroclaw daemon [--host <HOST>] [--port <PORT>]`
### `service`
- `zeroclaw service install`
- `zeroclaw service start`
- `zeroclaw service stop`
- `zeroclaw service restart`
- `zeroclaw service status`
- `zeroclaw service uninstall`
### `cron`
- `zeroclaw cron list`
- `zeroclaw cron add <expr> [--tz <IANA_TZ>] <command>`
- `zeroclaw cron add-at <rfc3339_timestamp> <command>`
- `zeroclaw cron add-every <every_ms> <command>`
- `zeroclaw cron once <delay> <command>`
- `zeroclaw cron remove <id>`
- `zeroclaw cron pause <id>`
- `zeroclaw cron resume <id>`
### `models`
- `zeroclaw models refresh`
- `zeroclaw models refresh --provider <ID>`
- `zeroclaw models refresh --force`
`models refresh` hiện hỗ trợ làm mới danh mục trực tiếp cho các provider: `openrouter`, `openai`, `anthropic`, `groq`, `mistral`, `deepseek`, `xai`, `together-ai`, `gemini`, `ollama`, `astrai`, `venice`, `fireworks`, `cohere`, `moonshot`, `glm`, `zai`, `qwen``nvidia`.
### `channel`
- `zeroclaw channel list`
- `zeroclaw channel start`
- `zeroclaw channel doctor`
- `zeroclaw channel bind-telegram <IDENTITY>`
- `zeroclaw channel add <type> <json>`
- `zeroclaw channel remove <name>`
Lệnh trong chat khi runtime đang chạy (Telegram/Discord):
- `/models`
- `/models <provider>`
- `/model`
- `/model <model-id>`
Channel runtime cũng theo dõi `config.toml` và tự động áp dụng thay đổi cho:
- `default_provider`
- `default_model`
- `default_temperature`
- `api_key` / `api_url` (cho provider mặc định)
- `reliability.*` cài đặt retry của provider
`add/remove` hiện chuyển hướng về thiết lập có hướng dẫn / cấu hình thủ công (chưa hỗ trợ đầy đủ mutator khai báo).
### `integrations`
- `zeroclaw integrations info <name>`
### `skills`
- `zeroclaw skills list`
- `zeroclaw skills install <source>`
- `zeroclaw skills remove <name>`
`<source>` chấp nhận git remote (`https://...`, `http://...`, `ssh://...``git@host:owner/repo.git`) hoặc đường dẫn cục bộ.
Skill manifest (`SKILL.toml`) hỗ trợ `prompts``[[tools]]`; cả hai được đưa vào system prompt của agent khi chạy, giúp model có thể tuân theo hướng dẫn skill mà không cần đọc thủ công.
### `migrate`
- `zeroclaw migrate openclaw [--source <path>] [--dry-run]`
### `config`
- `zeroclaw config schema`
`config schema` xuất JSON Schema (draft 2020-12) cho toàn bộ hợp đồng `config.toml` ra stdout.
### `completions`
- `zeroclaw completions bash`
- `zeroclaw completions fish`
- `zeroclaw completions zsh`
- `zeroclaw completions powershell`
- `zeroclaw completions elvish`
`completions` chỉ xuất ra stdout để script có thể được source trực tiếp mà không bị lẫn log/cảnh báo.
### `hardware`
- `zeroclaw hardware discover`
- `zeroclaw hardware introspect <path>`
- `zeroclaw hardware info [--chip <chip_name>]`
### `peripheral`
- `zeroclaw peripheral list`
- `zeroclaw peripheral add <board> <path>`
- `zeroclaw peripheral flash [--port <serial_port>]`
- `zeroclaw peripheral setup-uno-q [--host <ip_or_host>]`
- `zeroclaw peripheral flash-nucleo`
## Kiểm tra nhanh
Để xác minh nhanh tài liệu với binary hiện tại:
```bash
zeroclaw --help
zeroclaw <command> --help
```
-521
View File
@@ -1,521 +0,0 @@
# Tham khảo cấu hình ZeroClaw
Các mục cấu hình thường dùng và giá trị mặc định.
Xác minh lần cuối: **2026-02-19**.
Thứ tự tìm config khi khởi động:
1. Biến `ZEROCLAW_WORKSPACE` (nếu được đặt)
2. Marker `~/.zeroclaw/active_workspace.toml` (nếu có)
3. Mặc định `~/.zeroclaw/config.toml`
ZeroClaw ghi log đường dẫn config đã giải quyết khi khởi động ở mức `INFO`:
- `Config loaded` với các trường: `path`, `workspace`, `source`, `initialized`
Lệnh xuất schema:
- `zeroclaw config schema` (xuất JSON Schema draft 2020-12 ra stdout)
## Khóa chính
| Khóa | Mặc định | Ghi chú |
|---|---|---|
| `default_provider` | `openrouter` | ID hoặc bí danh provider |
| `default_model` | `anthropic/claude-sonnet-4-6` | Model định tuyến qua provider đã chọn |
| `default_temperature` | `0.7` | Nhiệt độ model |
## `[observability]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `backend` | `none` | Backend quan sát: `none`, `noop`, `log`, `prometheus`, `otel`, `opentelemetry` hoặc `otlp` |
| `otel_endpoint` | `http://localhost:4318` | Endpoint OTLP HTTP khi backend là `otel` |
| `otel_service_name` | `zeroclaw` | Tên dịch vụ gửi đến OTLP collector |
Lưu ý:
- `backend = "otel"` dùng OTLP HTTP export với blocking exporter client để span và metric có thể được gửi an toàn từ context ngoài Tokio.
- Bí danh `opentelemetry``otlp` trỏ đến cùng backend OTel.
Ví dụ:
```toml
[observability]
backend = "otel"
otel_endpoint = "http://localhost:4318"
otel_service_name = "zeroclaw"
```
## Ghi đè provider qua biến môi trường
Provider cũng có thể chọn qua biến môi trường. Thứ tự ưu tiên:
1. `ZEROCLAW_PROVIDER` (ghi đè tường minh, luôn thắng khi có giá trị)
2. `PROVIDER` (dự phòng kiểu cũ, chỉ áp dụng khi provider trong config chưa đặt hoặc vẫn là `openrouter`)
3. `default_provider` trong `config.toml`
Lưu ý cho người dùng container:
- Nếu `config.toml` đặt provider tùy chỉnh như `custom:https://.../v1`, biến `PROVIDER=openrouter` mặc định từ Docker/container sẽ không thay thế nó.
- Dùng `ZEROCLAW_PROVIDER` khi cố ý muốn biến môi trường ghi đè provider đã cấu hình.
## `[agent]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `compact_context` | `false` | Khi bật: bootstrap_max_chars=6000, rag_chunk_limit=2. Dùng cho model 13B trở xuống |
| `max_tool_iterations` | `10` | Số vòng lặp tool-call tối đa mỗi tin nhắn trên CLI, gateway và channels |
| `max_history_messages` | `50` | Số tin nhắn lịch sử tối đa giữ lại mỗi phiên |
| `parallel_tools` | `false` | Bật thực thi tool song song trong một lượt |
| `tool_dispatcher` | `auto` | Chiến lược dispatch tool |
| `tool_call_dedup_exempt` | `[]` | Tên tool được miễn kiểm tra trùng lặp trong cùng một lượt |
Lưu ý:
- Đặt `max_tool_iterations = 0` sẽ dùng giá trị mặc định an toàn `10`.
- Nếu tin nhắn kênh vượt giá trị này, runtime trả về: `Agent exceeded maximum tool iterations (<value>)`.
- Trong vòng lặp tool của CLI, gateway và channel, các lời gọi tool độc lập được thực thi đồng thời mặc định khi không cần phê duyệt; thứ tự kết quả giữ ổn định.
- `parallel_tools` áp dụng cho API `Agent::turn()`. Không ảnh hưởng đến vòng lặp runtime của CLI, gateway hay channel.
- `tool_call_dedup_exempt` nhận mảng tên tool chính xác. Các tool trong danh sách được phép gọi nhiều lần với cùng tham số trong một lượt. Ví dụ: `tool_call_dedup_exempt = ["browser"]`.
## `[agents.<name>]`
Cấu hình agent phụ (sub-agent). Mỗi khóa dưới `[agents]` định nghĩa một agent phụ có tên mà agent chính có thể ủy quyền.
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `provider` | _bắt buộc_ | Tên provider (ví dụ `"ollama"`, `"openrouter"`, `"anthropic"`) |
| `model` | _bắt buộc_ | Tên model cho agent phụ |
| `system_prompt` | chưa đặt | System prompt tùy chỉnh cho agent phụ (tùy chọn) |
| `api_key` | chưa đặt | API key tùy chỉnh (mã hóa khi `secrets.encrypt = true`) |
| `temperature` | chưa đặt | Temperature tùy chỉnh cho agent phụ |
| `max_depth` | `3` | Độ sâu đệ quy tối đa cho ủy quyền lồng nhau |
| `agentic` | `false` | Bật chế độ vòng lặp tool-call nhiều lượt cho agent phụ |
| `allowed_tools` | `[]` | Danh sách tool được phép ở chế độ agentic |
| `max_iterations` | `10` | Số vòng tool-call tối đa cho chế độ agentic |
Lưu ý:
- `agentic = false` giữ nguyên hành vi ủy quyền prompt→response đơn lượt.
- `agentic = true` yêu cầu ít nhất một mục khớp trong `allowed_tools`.
- Tool `delegate` bị loại khỏi allowlist của agent phụ để tránh vòng lặp ủy quyền.
```toml
[agents.researcher]
provider = "openrouter"
model = "anthropic/claude-sonnet-4-6"
system_prompt = "You are a research assistant."
max_depth = 2
agentic = true
allowed_tools = ["web_search", "http_request", "file_read"]
max_iterations = 8
[agents.coder]
provider = "ollama"
model = "qwen2.5-coder:32b"
temperature = 0.2
```
## `[runtime]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `reasoning_enabled` | chưa đặt (`None`) | Ghi đè toàn cục cho reasoning/thinking trên provider hỗ trợ |
Lưu ý:
- `reasoning_enabled = false` tắt tường minh reasoning phía provider cho provider hỗ trợ (hiện tại `ollama`, qua trường `think: false`).
- `reasoning_enabled = true` yêu cầu reasoning tường minh (`think: true` trên `ollama`).
- Để trống giữ mặc định của provider.
## `[skills]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `open_skills_enabled` | `false` | Cho phép tải/đồng bộ kho `open-skills` cộng đồng |
| `open_skills_dir` | chưa đặt | Đường dẫn cục bộ cho `open-skills` (mặc định `$HOME/open-skills` khi bật) |
Lưu ý:
- Mặc định an toàn: ZeroClaw **không** clone hay đồng bộ `open-skills` trừ khi `open_skills_enabled = true`.
- Ghi đè qua biến môi trường:
- `ZEROCLAW_OPEN_SKILLS_ENABLED` chấp nhận `1/0`, `true/false`, `yes/no`, `on/off`.
- `ZEROCLAW_OPEN_SKILLS_DIR` ghi đè đường dẫn kho khi có giá trị.
- Thứ tự ưu tiên: `ZEROCLAW_OPEN_SKILLS_ENABLED``skills.open_skills_enabled` trong `config.toml` → mặc định `false`.
## `[composio]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `enabled` | `false` | Bật công cụ OAuth do Composio quản lý |
| `api_key` | chưa đặt | API key Composio cho tool `composio` |
| `entity_id` | `default` | `user_id` mặc định gửi khi gọi connect/execute |
Lưu ý:
- Tương thích ngược: `enable = true` kiểu cũ được chấp nhận như bí danh cho `enabled = true`.
- Nếu `enabled = false` hoặc thiếu `api_key`, tool `composio` không được đăng ký.
- ZeroClaw yêu cầu Composio v3 tools với `toolkit_versions=latest` và thực thi với `version="latest"` để tránh bản tool mặc định cũ.
- Luồng thông thường: gọi `connect`, hoàn tất OAuth trên trình duyệt, rồi chạy `execute` cho hành động mong muốn.
- Nếu Composio trả lỗi thiếu connected-account, gọi `list_accounts` (tùy chọn với `app`) và truyền `connected_account_id` trả về cho `execute`.
## `[cost]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `enabled` | `false` | Bật theo dõi chi phí |
| `daily_limit_usd` | `10.00` | Giới hạn chi tiêu hàng ngày (USD) |
| `monthly_limit_usd` | `100.00` | Giới hạn chi tiêu hàng tháng (USD) |
| `warn_at_percent` | `80` | Cảnh báo khi chi tiêu đạt tỷ lệ phần trăm này |
| `allow_override` | `false` | Cho phép vượt ngân sách khi dùng cờ `--override` |
Lưu ý:
- Khi `enabled = true`, runtime theo dõi ước tính chi phí mỗi yêu cầu và áp dụng giới hạn ngày/tháng.
- Tại ngưỡng `warn_at_percent`, cảnh báo được gửi nhưng yêu cầu vẫn tiếp tục.
- Khi đạt giới hạn, yêu cầu bị từ chối trừ khi `allow_override = true` và cờ `--override` được truyền.
## `[identity]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `format` | `openclaw` | Định dạng danh tính: `"openclaw"` (mặc định) hoặc `"aieos"` |
| `aieos_path` | chưa đặt | Đường dẫn file AIEOS JSON (tương đối với workspace) |
| `aieos_inline` | chưa đặt | AIEOS JSON nội tuyến (thay thế cho đường dẫn file) |
Lưu ý:
- Dùng `format = "aieos"` với `aieos_path` hoặc `aieos_inline` để tải tài liệu danh tính AIEOS / OpenClaw.
- Chỉ nên đặt một trong hai `aieos_path` hoặc `aieos_inline`; `aieos_path` được ưu tiên.
## `[multimodal]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `max_images` | `4` | Số marker ảnh tối đa mỗi yêu cầu |
| `max_image_size_mb` | `5` | Giới hạn kích thước ảnh trước khi mã hóa base64 |
| `allow_remote_fetch` | `false` | Cho phép tải ảnh từ URL `http(s)` trong marker |
Lưu ý:
- Runtime chấp nhận marker ảnh trong tin nhắn với cú pháp: ``[IMAGE:<source>]``.
- Nguồn hỗ trợ:
- Đường dẫn file cục bộ (ví dụ ``[IMAGE:/tmp/screenshot.png]``)
- Data URI (ví dụ ``[IMAGE:data:image/png;base64,...]``)
- URL từ xa chỉ khi `allow_remote_fetch = true`
- Kiểu MIME cho phép: `image/png`, `image/jpeg`, `image/webp`, `image/gif`, `image/bmp`.
- Khi provider đang dùng không hỗ trợ vision, yêu cầu thất bại với lỗi capability có cấu trúc (`capability=vision`) thay vì bỏ qua ảnh.
## `[browser]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `enabled` | `false` | Bật tool `browser_open` (mở URL trong trình duyệt mặc định hệ thống, không thu thập dữ liệu) |
| `allowed_domains` | `[]` | Tên miền cho phép cho `browser_open` (khớp chính xác hoặc subdomain) |
| `session_name` | chưa đặt | Tên phiên trình duyệt (cho tự động hóa agent-browser) |
| `backend` | `agent_browser` | Backend tự động hóa: `"agent_browser"`, `"rust_native"`, `"computer_use"` hoặc `"auto"` |
| `native_headless` | `true` | Chế độ headless cho backend rust-native |
| `native_webdriver_url` | `http://127.0.0.1:9515` | URL endpoint WebDriver cho backend rust-native |
| `native_chrome_path` | chưa đặt | Đường dẫn Chrome/Chromium tùy chọn cho backend rust-native |
### `[browser.computer_use]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `endpoint` | `http://127.0.0.1:8787/v1/actions` | Endpoint sidecar cho hành động computer-use (chuột/bàn phím/screenshot cấp OS) |
| `api_key` | chưa đặt | Bearer token tùy chọn cho sidecar computer-use (mã hóa khi lưu) |
| `timeout_ms` | `15000` | Thời gian chờ mỗi hành động (mili giây) |
| `allow_remote_endpoint` | `false` | Cho phép endpoint từ xa/công khai cho sidecar |
| `window_allowlist` | `[]` | Danh sách cho phép tiêu đề cửa sổ/tiến trình gửi đến sidecar |
| `max_coordinate_x` | chưa đặt | Giới hạn trục X cho hành động dựa trên tọa độ (tùy chọn) |
| `max_coordinate_y` | chưa đặt | Giới hạn trục Y cho hành động dựa trên tọa độ (tùy chọn) |
Lưu ý:
- Khi `backend = "computer_use"`, agent ủy quyền hành động trình duyệt cho sidecar tại `computer_use.endpoint`.
- `allow_remote_endpoint = false` (mặc định) từ chối mọi endpoint không phải loopback để tránh lộ ra ngoài.
- Dùng `window_allowlist` để giới hạn cửa sổ OS mà sidecar có thể tương tác.
## `[http_request]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `enabled` | `false` | Bật tool `http_request` cho tương tác API |
| `allowed_domains` | `[]` | Tên miền cho phép (khớp chính xác hoặc subdomain) |
| `max_response_size` | `1000000` | Kích thước response tối đa (byte, mặc định: 1 MB) |
| `timeout_secs` | `30` | Thời gian chờ yêu cầu (giây) |
Lưu ý:
- Mặc định từ chối tất cả: nếu `allowed_domains` rỗng, mọi yêu cầu HTTP bị từ chối.
- Dùng khớp tên miền chính xác hoặc subdomain (ví dụ `"api.example.com"`, `"example.com"`).
## `[gateway]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `host` | `127.0.0.1` | Địa chỉ bind |
| `port` | `3000` | Cổng lắng nghe gateway |
| `require_pairing` | `true` | Yêu cầu ghép nối trước khi xác thực bearer |
| `allow_public_bind` | `false` | Chặn lộ public do vô ý |
## `[autonomy]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `level` | `supervised` | `read_only`, `supervised` hoặc `full` |
| `workspace_only` | `true` | Giới hạn ghi/lệnh trong phạm vi workspace |
| `allowed_commands` | _bắt buộc để chạy shell_ | Danh sách lệnh được phép |
| `forbidden_paths` | `[]` | Danh sách đường dẫn bị cấm |
| `max_actions_per_hour` | `100` | Ngân sách hành động mỗi giờ |
| `max_cost_per_day_cents` | `1000` | Giới hạn chi tiêu mỗi ngày (cent) |
| `require_approval_for_medium_risk` | `true` | Yêu cầu phê duyệt cho lệnh rủi ro trung bình |
| `block_high_risk_commands` | `true` | Chặn cứng lệnh rủi ro cao |
| `auto_approve` | `[]` | Thao tác tool luôn được tự động phê duyệt |
| `always_ask` | `[]` | Thao tác tool luôn yêu cầu phê duyệt |
Lưu ý:
- `level = "full"` bỏ qua phê duyệt rủi ro trung bình cho shell execution, nhưng vẫn áp dụng guardrail đã cấu hình.
- Phân tích toán tử/dấu phân cách shell nhận biết dấu ngoặc kép. Ký tự như `;` trong đối số được trích dẫn được xử lý là ký tự, không phải dấu phân cách lệnh.
- Toán tử chuỗi shell không trích dẫn vẫn được kiểm tra bởi policy (`;`, `|`, `&&`, `||`, chạy nền và chuyển hướng).
## `[memory]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `backend` | `sqlite` | `sqlite`, `lucid`, `markdown`, `none` |
| `auto_save` | `true` | Chỉ lưu đầu vào người dùng (đầu ra assistant bị loại) |
| `embedding_provider` | `none` | `none`, `openai` hoặc endpoint tùy chỉnh |
| `embedding_model` | `text-embedding-3-small` | ID model embedding, hoặc tuyến `hint:<name>` |
| `embedding_dimensions` | `1536` | Kích thước vector mong đợi cho model embedding đã chọn |
| `vector_weight` | `0.7` | Trọng số vector trong xếp hạng kết hợp |
| `keyword_weight` | `0.3` | Trọng số từ khóa trong xếp hạng kết hợp |
Lưu ý:
- Chèn ngữ cảnh memory bỏ qua khóa auto-save `assistant_resp*` kiểu cũ để tránh tóm tắt do model tạo bị coi là sự thật.
## `[[model_routes]]``[[embedding_routes]]`
Route hint giúp tên tích hợp ổn định khi model ID thay đổi.
### `[[model_routes]]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `hint` | _bắt buộc_ | Tên hint tác vụ (ví dụ `"reasoning"`, `"fast"`, `"code"`, `"summarize"`) |
| `provider` | _bắt buộc_ | Provider đích (phải khớp tên provider đã biết) |
| `model` | _bắt buộc_ | Model sử dụng với provider đó |
| `api_key` | chưa đặt | API key tùy chỉnh cho provider của route này (tùy chọn) |
### `[[embedding_routes]]`
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `hint` | _bắt buộc_ | Tên route hint (ví dụ `"semantic"`, `"archive"`, `"faq"`) |
| `provider` | _bắt buộc_ | Embedding provider (`"none"`, `"openai"` hoặc `"custom:<url>"`) |
| `model` | _bắt buộc_ | Model embedding sử dụng với provider đó |
| `dimensions` | chưa đặt | Ghi đè kích thước embedding cho route này (tùy chọn) |
| `api_key` | chưa đặt | API key tùy chỉnh cho provider của route này (tùy chọn) |
```toml
[memory]
embedding_model = "hint:semantic"
[[model_routes]]
hint = "reasoning"
provider = "openrouter"
model = "provider/model-id"
[[embedding_routes]]
hint = "semantic"
provider = "openai"
model = "text-embedding-3-small"
dimensions = 1536
```
Chiến lược nâng cấp:
1. Giữ hint ổn định (`hint:reasoning`, `hint:semantic`).
2. Chỉ cập nhật `model = "...phiên-bản-mới..."` trong mục route.
3. Kiểm tra bằng `zeroclaw doctor` trước khi khởi động lại/triển khai.
## `[query_classification]`
Tự động định tuyến tin nhắn đến hint `[[model_routes]]` theo mẫu nội dung.
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `enabled` | `false` | Bật phân loại truy vấn tự động |
| `rules` | `[]` | Quy tắc phân loại (đánh giá theo thứ tự ưu tiên) |
Mỗi rule trong `rules`:
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `hint` | _bắt buộc_ | Phải khớp giá trị hint trong `[[model_routes]]` |
| `keywords` | `[]` | Khớp chuỗi con không phân biệt hoa thường |
| `patterns` | `[]` | Khớp chuỗi chính xác phân biệt hoa thường (cho code fence, từ khóa như `"fn "`) |
| `min_length` | chưa đặt | Chỉ khớp nếu độ dài tin nhắn ≥ N ký tự |
| `max_length` | chưa đặt | Chỉ khớp nếu độ dài tin nhắn ≤ N ký tự |
| `priority` | `0` | Rule ưu tiên cao hơn được kiểm tra trước |
```toml
[query_classification]
enabled = true
[[query_classification.rules]]
hint = "reasoning"
keywords = ["explain", "analyze", "why"]
min_length = 200
priority = 10
[[query_classification.rules]]
hint = "fast"
keywords = ["hi", "hello", "thanks"]
max_length = 50
priority = 5
```
## `[channels_config]`
Cấu hình kênh cấp cao nằm dưới `channels_config`.
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `message_timeout_secs` | `300` | Thời gian chờ cơ bản (giây) cho xử lý tin nhắn kênh; runtime tự điều chỉnh theo độ sâu tool-loop (lên đến 4x) |
Ví dụ:
- `[channels_config.telegram]`
- `[channels_config.discord]`
- `[channels_config.whatsapp]`
- `[channels_config.email]`
Lưu ý:
- Mặc định `300s` tối ưu cho LLM chạy cục bộ (Ollama) vốn chậm hơn cloud API.
- Ngân sách timeout runtime là `message_timeout_secs * scale`, trong đó `scale = min(max_tool_iterations, 4)` và tối thiểu `1`.
- Việc điều chỉnh này tránh timeout sai khi lượt LLM đầu chậm/retry nhưng các lượt tool-loop sau vẫn cần hoàn tất.
- Nếu dùng cloud API (OpenAI, Anthropic, v.v.), có thể giảm xuống `60` hoặc thấp hơn.
- Giá trị dưới `30` bị giới hạn thành `30` để tránh timeout liên tục.
- Khi timeout xảy ra, người dùng nhận: `⚠️ Request timed out while waiting for the model. Please try again.`
- Hành vi ngắt chỉ Telegram được điều khiển bằng `channels_config.telegram.interrupt_on_new_message` (mặc định `false`).
Khi bật, tin nhắn mới từ cùng người gửi trong cùng chat sẽ hủy yêu cầu đang xử lý và giữ ngữ cảnh người dùng bị ngắt.
- Khi `zeroclaw channel start` đang chạy, thay đổi `default_provider`, `default_model`, `default_temperature`, `api_key`, `api_url``reliability.*` được áp dụng nóng từ `config.toml` ở tin nhắn tiếp theo.
Xem ma trận kênh và hành vi allowlist chi tiết tại [channels-reference.md](channels-reference.md).
### `[channels_config.whatsapp]`
WhatsApp hỗ trợ hai backend dưới cùng một bảng config.
Chế độ Cloud API (webhook Meta):
| Khóa | Bắt buộc | Mục đích |
|---|---|---|
| `access_token` | Có | Bearer token Meta Cloud API |
| `phone_number_id` | Có | ID số điện thoại Meta |
| `verify_token` | Có | Token xác minh webhook |
| `app_secret` | Tùy chọn | Bật xác minh chữ ký webhook (`X-Hub-Signature-256`) |
| `allowed_numbers` | Khuyến nghị | Số điện thoại cho phép gửi đến (`[]` = từ chối tất cả, `"*"` = cho phép tất cả) |
Chế độ WhatsApp Web (client gốc):
| Khóa | Bắt buộc | Mục đích |
|---|---|---|
| `session_path` | Có | Đường dẫn phiên SQLite lưu trữ lâu dài |
| `pair_phone` | Tùy chọn | Số điện thoại cho luồng pair-code (chỉ chữ số) |
| `pair_code` | Tùy chọn | Mã pair tùy chỉnh (nếu không sẽ tự tạo) |
| `allowed_numbers` | Khuyến nghị | Số điện thoại cho phép gửi đến (`[]` = từ chối tất cả, `"*"` = cho phép tất cả) |
Lưu ý:
- WhatsApp Web yêu cầu build flag `whatsapp-web`.
- Nếu cả Cloud lẫn Web đều có cấu hình, Cloud được ưu tiên để tương thích ngược.
## `[hardware]`
Cấu hình truy cập phần cứng vật lý (STM32, probe, serial).
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `enabled` | `false` | Bật truy cập phần cứng |
| `transport` | `none` | Chế độ truyền: `"none"`, `"native"`, `"serial"` hoặc `"probe"` |
| `serial_port` | chưa đặt | Đường dẫn cổng serial (ví dụ `"/dev/ttyACM0"`) |
| `baud_rate` | `115200` | Tốc độ baud serial |
| `probe_target` | chưa đặt | Chip đích cho probe (ví dụ `"STM32F401RE"`) |
| `workspace_datasheets` | `false` | Bật RAG datasheet workspace (đánh chỉ mục PDF schematic để AI tra cứu chân) |
Lưu ý:
- Dùng `transport = "serial"` với `serial_port` cho kết nối USB-serial.
- Dùng `transport = "probe"` với `probe_target` cho nạp qua debug-probe (ví dụ ST-Link).
- Xem [hardware-peripherals-design.md](hardware-peripherals-design.md) để biết chi tiết giao thức.
## `[peripherals]`
Bo mạch ngoại vi trở thành tool agent khi được bật.
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `enabled` | `false` | Bật hỗ trợ ngoại vi (bo mạch trở thành tool agent) |
| `boards` | `[]` | Danh sách cấu hình bo mạch |
| `datasheet_dir` | chưa đặt | Đường dẫn tài liệu datasheet (tương đối workspace) cho RAG |
Mỗi mục trong `boards`:
| Khóa | Mặc định | Mục đích |
|---|---|---|
| `board` | _bắt buộc_ | Loại bo mạch: `"nucleo-f401re"`, `"rpi-gpio"`, `"esp32"`, v.v. |
| `transport` | `serial` | Kiểu truyền: `"serial"`, `"native"`, `"websocket"` |
| `path` | chưa đặt | Đường dẫn serial: `"/dev/ttyACM0"`, `"/dev/ttyUSB0"` |
| `baud` | `115200` | Tốc độ baud cho serial |
```toml
[peripherals]
enabled = true
datasheet_dir = "docs/datasheets"
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
[[peripherals.boards]]
board = "rpi-gpio"
transport = "native"
```
Lưu ý:
- Đặt file `.md`/`.txt` datasheet đặt tên theo bo mạch (ví dụ `nucleo-f401re.md`, `rpi-gpio.md`) trong `datasheet_dir` cho RAG.
- Xem [hardware-peripherals-design.md](hardware-peripherals-design.md) để biết giao thức bo mạch và ghi chú firmware.
## Giá trị mặc định liên quan bảo mật
- Allowlist kênh mặc định từ chối tất cả (`[]` nghĩa là từ chối tất cả)
- Gateway mặc định yêu cầu ghép nối
- Mặc định chặn public bind
## Lệnh kiểm tra
Sau khi chỉnh config:
```bash
zeroclaw status
zeroclaw doctor
zeroclaw channel doctor
zeroclaw service restart
```
## Tài liệu liên quan
- [channels-reference.md](channels-reference.md)
- [providers-reference.md](providers-reference.md)
- [operations-runbook.md](operations-runbook.md)
- [troubleshooting.md](troubleshooting.md)
-18
View File
@@ -1,18 +0,0 @@
# Tài liệu đóng góp, review và CI
Dành cho contributor, reviewer và maintainer.
## Chính sách cốt lõi
- Hướng dẫn đóng góp: [CONTRIBUTING.md](../../../../CONTRIBUTING.md)
- Quy tắc quy trình PR: [../pr-workflow.md](../pr-workflow.md)
- Sổ tay reviewer: [../reviewer-playbook.md](../reviewer-playbook.md)
- Bản đồ CI và quyền sở hữu: [../ci-map.md](../ci-map.md)
- Chính sách nguồn Actions: [../actions-source-policy.md](../actions-source-policy.md)
## Thứ tự đọc được đề xuất
1. `CONTRIBUTING.md`
2. `../pr-workflow.md`
3. `../reviewer-playbook.md`
4. `../ci-map.md`
-111
View File
@@ -1,111 +0,0 @@
# Cấu hình Provider Tùy chỉnh
ZeroClaw hỗ trợ endpoint API tùy chỉnh cho cả provider tương thích OpenAI lẫn Anthropic.
## Các loại Provider
### Endpoint tương thích OpenAI (`custom:`)
Dành cho các dịch vụ triển khai định dạng API của OpenAI:
```toml
default_provider = "custom:https://your-api.com"
api_key = "your-api-key"
default_model = "your-model-name"
```
### Endpoint tương thích Anthropic (`anthropic-custom:`)
Dành cho các dịch vụ triển khai định dạng API của Anthropic:
```toml
default_provider = "anthropic-custom:https://your-api.com"
api_key = "your-api-key"
default_model = "your-model-name"
```
## Phương thức cấu hình
### File Config
Chỉnh sửa `~/.zeroclaw/config.toml`:
```toml
api_key = "your-api-key"
default_provider = "anthropic-custom:https://api.example.com"
default_model = "claude-sonnet-4-6"
```
### Biến môi trường
Với provider `custom:``anthropic-custom:`, dùng biến môi trường chứa key chung:
```bash
export API_KEY="your-api-key"
# hoặc: export ZEROCLAW_API_KEY="your-api-key"
zeroclaw agent
```
## Kiểm tra cấu hình
Xác minh endpoint tùy chỉnh của bạn:
```bash
# Chế độ tương tác
zeroclaw agent
# Kiểm tra tin nhắn đơn
zeroclaw agent -m "test message"
```
## Xử lý sự cố
### Lỗi xác thực
- Kiểm tra lại API key
- Kiểm tra định dạng URL endpoint (phải bao gồm `http://` hoặc `https://`)
- Đảm bảo endpoint có thể truy cập từ mạng của bạn
### Không tìm thấy Model
- Xác nhận tên model khớp với các model mà provider cung cấp
- Kiểm tra tài liệu của provider để biết định danh model chính xác
- Đảm bảo endpoint và dòng model khớp nhau. Một số gateway tùy chỉnh chỉ cung cấp một tập con model.
- Xác minh các model có sẵn từ cùng endpoint và key đã cấu hình:
```bash
curl -sS https://your-api.com/models \
-H "Authorization: Bearer $API_KEY"
```
- Nếu gateway không triển khai `/models`, gửi một request chat tối giản và kiểm tra thông báo lỗi model mà provider trả về.
### Sự cố kết nối
- Kiểm tra khả năng truy cập endpoint: `curl -I https://your-api.com`
- Xác minh cài đặt firewall/proxy
- Kiểm tra trang trạng thái của provider
## Ví dụ
### LLM Server cục bộ
```toml
default_provider = "custom:http://localhost:8080"
default_model = "local-model"
```
### Proxy của doanh nghiệp
```toml
default_provider = "anthropic-custom:https://llm-proxy.corp.example.com"
api_key = "internal-token"
```
### Cloud Provider Gateway
```toml
default_provider = "custom:https://gateway.cloud-provider.com/v1"
api_key = "gateway-api-key"
default_model = "gpt-4"
```
-37
View File
@@ -1,37 +0,0 @@
# Arduino Uno
## Pin Aliases
| alias | pin |
|-------------|-----|
| red_led | 13 |
| builtin_led | 13 |
| user_led | 13 |
## Tổng quan
Arduino Uno là board vi điều khiển dựa trên ATmega328P. Có 14 pin digital I/O (013) và 6 đầu vào analog (A0A5).
## Pin Digital
- **Pins 013:** Digital I/O. Có thể là INPUT hoặc OUTPUT.
- **Pin 13:** LED tích hợp (onboard). Kết nối LED với GND hoặc dùng để xuất tín hiệu.
- **Pins 01:** Cũng dùng cho Serial (RX/TX). Tránh dùng nếu đang sử dụng Serial.
## GPIO
- `digitalWrite(pin, HIGH)` hoặc `digitalWrite(pin, LOW)` để xuất tín hiệu.
- `digitalRead(pin)` để đọc đầu vào (trả về 0 hoặc 1).
- Số pin trong giao thức ZeroClaw: 013.
## Serial
- UART trên pin 0 (RX) và 1 (TX).
- USB qua ATmega16U2 hoặc CH340 (bản clone).
- Baud rate: 115200 cho firmware ZeroClaw.
## ZeroClaw Tools
- `gpio_read`: Đọc giá trị pin (0 hoặc 1).
- `gpio_write`: Đặt pin lên cao (1) hoặc xuống thấp (0).
- `arduino_upload`: Agent tạo code Arduino sketch đầy đủ; ZeroClaw biên dịch và tải lên qua arduino-cli. Dùng cho "make a heart", các pattern tùy chỉnh — agent viết code, không cần chỉnh sửa thủ công. Pin 13 = LED tích hợp.
-22
View File
@@ -1,22 +0,0 @@
# Tham chiếu GPIO ESP32
## Pin Aliases
| alias | pin |
|-------------|-----|
| builtin_led | 2 |
| red_led | 2 |
## Các pin thông dụng (ESP32 / ESP32-C3)
- **GPIO 2**: LED tích hợp trên nhiều dev board (output)
- **GPIO 13**: Đầu ra mục đích chung
- **GPIO 21/20**: Thường dùng cho UART0 TX/RX (tránh nếu đang dùng serial)
## Giao thức
ZeroClaw host gửi JSON qua serial (115200 baud):
- `gpio_read`: `{"id":"1","cmd":"gpio_read","args":{"pin":13}}`
- `gpio_write`: `{"id":"1","cmd":"gpio_write","args":{"pin":13,"value":1}}`
Response: `{"id":"1","ok":true,"result":"0"}` hoặc `{"id":"1","ok":true,"result":"done"}`
-16
View File
@@ -1,16 +0,0 @@
# GPIO Nucleo-F401RE
## Pin Aliases
| alias | pin |
|-------------|-----|
| red_led | 13 |
| user_led | 13 |
| ld2 | 13 |
| builtin_led | 13 |
## GPIO
Pin 13: User LED (LD2)
- Output, mức cao tích cực (active high)
- PA5 trên STM32F401
-312
View File
@@ -1,312 +0,0 @@
# Bảo mật không gây cản trở
> ⚠️ **Trạng thái: Đề xuất / Lộ trình**
>
> Tài liệu này mô tả các hướng tiếp cận đề xuất và có thể bao gồm các lệnh hoặc cấu hình giả định.
> Để biết hành vi runtime hiện tại, xem [config-reference.md](config-reference.md), [operations-runbook.md](operations-runbook.md), và [troubleshooting.md](troubleshooting.md).
## Nguyên tắc cốt lõi
>
> **"Các tính năng bảo mật nên như túi khí — luôn hiện diện, bảo vệ, và vô hình cho đến khi cần."**
## Thiết kế: tự động phát hiện âm thầm
### 1. Không thêm bước wizard mới (giữ nguyên 9 bước, < 60 giây)
```rust
// Wizard không thay đổi
// Các tính năng bảo mật tự phát hiện ở nền
pub fn run_wizard() -> Result<Config> {
// ... 9 bước hiện có, không thay đổi ...
let config = Config {
// ... các trường hiện có ...
// MỚI: Bảo mật tự phát hiện (không hiển thị trong wizard)
security: SecurityConfig::autodetect(), // Âm thầm!
};
config.save().await?;
Ok(config)
}
```
### 2. Logic tự phát hiện (chạy một lần khi khởi động lần đầu)
```rust
// src/security/detect.rs
impl SecurityConfig {
/// Phát hiện sandbox khả dụng và bật tự động
/// Trả về giá trị mặc định thông minh dựa trên nền tảng + công cụ có sẵn
pub fn autodetect() -> Self {
Self {
// Sandbox: ưu tiên Landlock (native), rồi Firejail, rồi none
sandbox: SandboxConfig::autodetect(),
// Resource limits: luôn bật monitoring
resources: ResourceLimits::default(),
// Audit: bật mặc định, log vào config dir
audit: AuditConfig::default(),
// Mọi thứ khác: giá trị mặc định an toàn
..SecurityConfig::default()
}
}
}
impl SandboxConfig {
pub fn autodetect() -> Self {
#[cfg(target_os = "linux")]
{
// Ưu tiên Landlock (native, không phụ thuộc)
if Self::probe_landlock() {
return Self {
enabled: true,
backend: SandboxBackend::Landlock,
..Self::default()
};
}
// Fallback: Firejail nếu đã cài
if Self::probe_firejail() {
return Self {
enabled: true,
backend: SandboxBackend::Firejail,
..Self::default()
};
}
}
#[cfg(target_os = "macos")]
{
// Thử Bubblewrap trên macOS
if Self::probe_bubblewrap() {
return Self {
enabled: true,
backend: SandboxBackend::Bubblewrap,
..Self::default()
};
}
}
// Fallback: tắt (nhưng vẫn có application-layer security)
Self {
enabled: false,
backend: SandboxBackend::None,
..Self::default()
}
}
#[cfg(target_os = "linux")]
fn probe_landlock() -> bool {
// Thử tạo Landlock ruleset tối thiểu
// Nếu thành công, kernel hỗ trợ Landlock
landlock::Ruleset::new()
.set_access_fs(landlock::AccessFS::read_file)
.add_path(Path::new("/tmp"), landlock::AccessFS::read_file)
.map(|ruleset| ruleset.restrict_self().is_ok())
.unwrap_or(false)
}
fn probe_firejail() -> bool {
// Kiểm tra lệnh firejail có tồn tại không
std::process::Command::new("firejail")
.arg("--version")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
}
```
### 3. Lần chạy đầu: ghi log âm thầm
```bash
$ zeroclaw agent -m "hello"
# Lần đầu: phát hiện âm thầm
[INFO] Detecting security features...
[INFO] ✓ Landlock sandbox enabled (kernel 6.2+)
[INFO] ✓ Memory monitoring active (512MB limit)
[INFO] ✓ Audit logging enabled (~/.config/zeroclaw/audit.log)
# Các lần sau: yên lặng
$ zeroclaw agent -m "hello"
[agent] Thinking...
```
### 4. File config: tất cả giá trị mặc định được ẩn
```toml
# ~/.config/zeroclaw/config.toml
# Các section này KHÔNG được ghi trừ khi người dùng tùy chỉnh
# [security.sandbox]
# enabled = true # (mặc định, tự phát hiện)
# backend = "landlock" # (mặc định, tự phát hiện)
# [security.resources]
# max_memory_mb = 512 # (mặc định)
# [security.audit]
# enabled = true # (mặc định)
```
Chỉ khi người dùng thay đổi:
```toml
[security.sandbox]
enabled = false # Người dùng tắt tường minh
[security.resources]
max_memory_mb = 1024 # Người dùng tăng giới hạn
```
### 5. Người dùng nâng cao: kiểm soát tường minh
```bash
# Kiểm tra trạng thái đang hoạt động
$ zeroclaw security --status
Security Status:
✓ Sandbox: Landlock (Linux kernel 6.2)
✓ Memory monitoring: 512MB limit
✓ Audit logging: ~/.config/zeroclaw/audit.log
→ 47 events logged today
# Tắt sandbox tường minh (ghi vào config)
$ zeroclaw config set security.sandbox.enabled false
# Bật backend cụ thể
$ zeroclaw config set security.sandbox.backend firejail
# Điều chỉnh giới hạn
$ zeroclaw config set security.resources.max_memory_mb 2048
```
### 6. Giảm cấp nhẹ nhàng
| Nền tảng | Tốt nhất có thể | Fallback | Tệ nhất |
|----------|---------------|----------|------------|
| **Linux 5.13+** | Landlock | None | Chỉ App-layer |
| **Linux (bất kỳ)** | Firejail | Landlock | Chỉ App-layer |
| **macOS** | Bubblewrap | None | Chỉ App-layer |
| **Windows** | None | - | Chỉ App-layer |
**App-layer security luôn hiện diện** — đây là allowlist/path blocking/injection protection hiện có, vốn đã toàn diện.
---
## Mở rộng config schema
```rust
// src/config/schema.rs
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityConfig {
/// Cấu hình sandbox (tự phát hiện nếu không đặt)
#[serde(default)]
pub sandbox: SandboxConfig,
/// Giới hạn tài nguyên (áp dụng mặc định nếu không đặt)
#[serde(default)]
pub resources: ResourceLimits,
/// Audit logging (bật mặc định)
#[serde(default)]
pub audit: AuditConfig,
}
impl Default for SecurityConfig {
fn default() -> Self {
Self {
sandbox: SandboxConfig::autodetect(), // Phát hiện âm thầm!
resources: ResourceLimits::default(),
audit: AuditConfig::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SandboxConfig {
/// Bật sandboxing (mặc định: tự phát hiện)
#[serde(default)]
pub enabled: Option<bool>, // None = tự phát hiện
/// Sandbox backend (mặc định: tự phát hiện)
#[serde(default)]
pub backend: SandboxBackend,
/// Tham số Firejail tùy chỉnh (tùy chọn)
#[serde(default)]
pub firejail_args: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum SandboxBackend {
Auto, // Tự phát hiện (mặc định)
Landlock, // Linux kernel LSM
Firejail, // User-space sandbox
Bubblewrap, // User namespaces
Docker, // Container (nặng)
None, // Tắt
}
impl Default for SandboxBackend {
fn default() -> Self {
Self::Auto // Luôn tự phát hiện mặc định
}
}
```
---
## So sánh trải nghiệm người dùng
### Trước (hiện tại)
```bash
$ zeroclaw onboard
[1/9] Workspace Setup...
[2/9] AI Provider...
...
[9/9] Workspace Files...
✓ Security: Supervised | workspace-scoped
```
### Sau (với bảo mật không gây cản trở)
```bash
$ zeroclaw onboard
[1/9] Workspace Setup...
[2/9] AI Provider...
...
[9/9] Workspace Files...
✓ Security: Supervised | workspace-scoped | Landlock sandbox ✓
# ↑ Chỉ thêm một từ, tự phát hiện âm thầm!
```
---
## Tương thích ngược
| Tình huống | Hành vi |
|----------|----------|
| **Config hiện có** | Hoạt động không thay đổi, tính năng mới là opt-in |
| **Cài mới** | Tự phát hiện và bật bảo mật khả dụng |
| **Không có sandbox** | Fallback về app-layer (vẫn an toàn) |
| **Người dùng tắt** | Một flag config: `sandbox.enabled = false` |
---
## Tóm tắt
**Không ảnh hưởng wizard** — giữ nguyên 9 bước, < 60 giây
**Không thêm prompt** — tự phát hiện âm thầm
**Không breaking change** — tương thích ngược
**Có thể opt-out** — flag config tường minh
**Hiển thị trạng thái**`zeroclaw security --status`
Wizard vẫn là "thiết lập nhanh ứng dụng phổ quát" — bảo mật chỉ **lặng lẽ tốt hơn**.
-29
View File
@@ -1,29 +0,0 @@
# Tài liệu Bắt đầu
Dành cho cài đặt lần đầu và làm quen nhanh.
## Lộ trình bắt đầu
1. Tổng quan và khởi động nhanh: [../../../README.vi.md](../../../README.vi.md)
2. Cài đặt một lệnh và chế độ bootstrap kép: [../one-click-bootstrap.md](../one-click-bootstrap.md)
3. Tìm lệnh theo tác vụ: [../commands-reference.md](../commands-reference.md)
## Chọn hướng đi
| Tình huống | Lệnh |
|----------|---------|
| Có API key, muốn cài nhanh nhất | `zeroclaw onboard --api-key sk-... --provider openrouter` |
| Muốn được hướng dẫn từng bước | `zeroclaw onboard` |
| Đã có config, chỉ cần sửa kênh | `zeroclaw onboard --channels-only` |
| Dùng xác thực subscription | Xem [Subscription Auth](../../../README.md#subscription-auth-openai-codex--claude-code) |
## Thiết lập và kiểm tra
- Thiết lập nhanh: `zeroclaw onboard --api-key "sk-..." --provider openrouter`
- Thiết lập hướng dẫn: `zeroclaw onboard`
- Kiểm tra môi trường: `zeroclaw status` + `zeroclaw doctor`
## Tiếp theo
- Vận hành runtime: [../operations/README.md](../operations/README.md)
- Tra cứu tham khảo: [../reference/README.md](../reference/README.md)
-324
View File
@@ -1,324 +0,0 @@
# Thiết kế Hardware Peripherals — ZeroClaw
ZeroClaw cho phép các vi điều khiển (MCU) và máy tính nhúng (SBC) **phân tích lệnh ngôn ngữ tự nhiên theo thời gian thực**, tổng hợp code phù hợp với từng phần cứng, và thực thi tương tác với ngoại vi trực tiếp.
## 1. Tầm nhìn
**Mục tiêu:** ZeroClaw đóng vai trò là AI agent có hiểu biết về phần cứng, cụ thể:
- Nhận lệnh ngôn ngữ tự nhiên (ví dụ: "Di chuyển cánh tay X", "Bật LED") qua các kênh như WhatsApp, Telegram
- Truy xuất tài liệu phần cứng chính xác (datasheet, register map)
- Tổng hợp code/logic Rust bằng LLM (Gemini, các mô hình mã nguồn mở)
- Thực thi logic để điều khiển ngoại vi (GPIO, I2C, SPI)
- Lưu trữ code tối ưu để tái sử dụng về sau
**Hình dung trực quan:** ZeroClaw = bộ não hiểu phần cứng. Ngoại vi = tay chân mà nó điều khiển.
## 2. Hai chế độ vận hành
### Chế độ 1: Edge-Native (Độc lập trên thiết bị)
**Mục tiêu:** Các board có WiFi (ESP32, Raspberry Pi).
ZeroClaw chạy **trực tiếp trên thiết bị**. Board khởi động server gRPC/nanoRPC và giao tiếp với ngoại vi ngay tại chỗ.
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ZeroClaw on ESP32 / Raspberry Pi (Edge-Native) │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────────────────────┐ │
│ │ Channels │───►│ Agent Loop │───►│ RAG: datasheets, register maps │ │
│ │ WhatsApp │ │ (LLM calls) │ │ → LLM context │ │
│ │ Telegram │ └──────┬───────┘ └─────────────────────────────────┘ │
│ └─────────────┘ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ Code synthesis → Wasm / dynamic exec → GPIO / I2C / SPI → persist ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ │
│ gRPC/nanoRPC server ◄──► Peripherals (GPIO, I2C, SPI, sensors, actuators) │
└─────────────────────────────────────────────────────────────────────────────┘
```
**Luồng xử lý:**
1. Người dùng gửi WhatsApp: *"Turn on LED on pin 13"*
2. ZeroClaw truy xuất tài liệu theo board (ví dụ: bản đồ GPIO của ESP32)
3. LLM tổng hợp code Rust
4. Code chạy trong sandbox (Wasm hoặc dynamic linking)
5. GPIO được bật/tắt; kết quả trả về người dùng
6. Code tối ưu được lưu lại để tái sử dụng cho các yêu cầu "Turn on LED" sau này
**Toàn bộ diễn ra trên thiết bị.** Không cần máy chủ trung gian.
### Chế độ 2: Host-Mediated (Phát triển / Gỡ lỗi)
**Mục tiêu:** Phần cứng kết nối qua USB / J-Link / Aardvark với máy chủ (macOS, Linux).
ZeroClaw chạy trên **máy chủ** và duy trì kết nối phần cứng tới thiết bị mục tiêu. Dùng cho phát triển, kiểm tra nội tâm, và nạp firmware.
```
┌─────────────────────┐ ┌──────────────────────────────────┐
│ ZeroClaw on Mac │ USB / J-Link / │ STM32 Nucleo-F401RE │
│ │ Aardvark │ (or other MCU) │
│ - Channels │ ◄────────────────► │ - Memory map │
│ - LLM │ │ - Peripherals (GPIO, ADC, I2C) │
│ - Hardware probe │ VID/PID │ - Flash / RAM │
│ - Flash / debug │ discovery │ │
└─────────────────────┘ └──────────────────────────────────┘
```
**Luồng xử lý:**
1. Người dùng gửi Telegram: *"What are the readable memory addresses on this USB device?"*
2. ZeroClaw nhận diện phần cứng đang kết nối (VID/PID, kiến trúc)
3. Thực hiện ánh xạ bộ nhớ; gợi ý các vùng địa chỉ khả dụng
4. Trả kết quả về người dùng
**Hoặc:**
1. Người dùng: *"Flash this firmware to the Nucleo"*
2. ZeroClaw ghi/nạp firmware qua OpenOCD hoặc probe-rs
3. Xác nhận thành công
**Hoặc:**
1. ZeroClaw tự phát hiện: *"STM32 Nucleo on /dev/ttyACM0, ARM Cortex-M4"*
2. Gợi ý: *"I can read/write GPIO, ADC, flash. What would you like to do?"*
---
### So sánh hai chế độ
| Khía cạnh | Edge-Native | Host-Mediated |
|-----------|-------------|---------------|
| ZeroClaw chạy trên | Thiết bị (ESP32, RPi) | Máy chủ (Mac, Linux) |
| Kết nối phần cứng | Cục bộ (GPIO, I2C, SPI) | USB, J-Link, Aardvark |
| LLM | Trên thiết bị hoặc cloud (Gemini) | Máy chủ (cloud hoặc local) |
| Trường hợp sử dụng | Sản xuất, độc lập | Phát triển, gỡ lỗi, kiểm tra |
| Kênh liên lạc | WhatsApp, v.v. (qua WiFi) | Telegram, CLI, v.v. |
## 3. Các chế độ cũ / Đơn giản hơn (Trước khi có LLM trên Edge)
Dành cho các board không có WiFi hoặc trước khi Edge-Native hoàn chỉnh:
### Chế độ A: Host + Remote Peripheral (STM32 qua serial)
Máy chủ chạy ZeroClaw; ngoại vi chạy firmware tối giản. JSON đơn giản qua serial.
### Chế độ B: RPi làm Host (Native GPIO)
ZeroClaw trên Pi; GPIO qua rppal hoặc sysfs. Không cần firmware riêng.
## 4. Yêu cầu kỹ thuật
| Yêu cầu | Mô tả |
|---------|-------|
| **Ngôn ngữ** | Thuần Rust. `no_std` khi áp dụng được cho các target nhúng (STM32, ESP32). |
| **Giao tiếp** | Stack gRPC hoặc nanoRPC nhẹ để xử lý lệnh với độ trễ thấp. |
| **Thực thi động** | Chạy an toàn logic do LLM tạo ra theo thời gian thực: Wasm runtime để cô lập, hoặc dynamic linking khi được hỗ trợ. |
| **Truy xuất tài liệu** | Pipeline RAG (Retrieval-Augmented Generation) để đưa đoạn trích datasheet, register map và pinout vào ngữ cảnh LLM. |
| **Nhận diện phần cứng** | Nhận dạng thiết bị USB qua VID/PID; phát hiện kiến trúc (ARM Cortex-M, RISC-V, v.v.). |
### Pipeline RAG (Truy xuất Datasheet)
- **Lập chỉ mục:** Datasheet, hướng dẫn tham chiếu, register map (PDF → các đoạn, embeddings).
- **Truy xuất:** Khi người dùng hỏi ("turn on LED"), lấy các đoạn liên quan (ví dụ: phần GPIO của board mục tiêu).
- **Chèn vào:** Thêm vào system prompt hoặc ngữ cảnh LLM.
- **Kết quả:** LLM tạo code chính xác, đặc thù cho từng board.
### Các lựa chọn thực thi động
| Lựa chọn | Ưu điểm | Nhược điểm |
|----------|---------|-----------|
| **Wasm** | Sandboxed, di động, không cần FFI | Overhead; truy cập phần cứng từ Wasm bị hạn chế |
| **Dynamic linking** | Tốc độ native, truy cập phần cứng đầy đủ | Phụ thuộc nền tảng; lo ngại bảo mật |
| **Interpreted DSL** | An toàn, có thể kiểm tra | Chậm hơn; biểu đạt hạn chế |
| **Pre-compiled templates** | Nhanh, bảo mật | Kém linh hoạt; cần thư viện template |
**Khuyến nghị:** Bắt đầu với pre-compiled templates + parameterization; tiến lên Wasm cho logic do người dùng định nghĩa khi đã ổn định.
## 5. CLI và Config
### CLI Flags
```bash
# Edge-Native: run on device (ESP32, RPi)
zeroclaw agent --mode edge
# Host-Mediated: connect to USB/J-Link target
zeroclaw agent --peripheral nucleo-f401re:/dev/ttyACM0
zeroclaw agent --probe jlink
# Hardware introspection
zeroclaw hardware discover
zeroclaw hardware introspect /dev/ttyACM0
```
### Config (config.toml)
```toml
[peripherals]
enabled = true
mode = "host" # "edge" | "host"
datasheet_dir = "docs/datasheets" # RAG: board-specific docs for LLM context
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
[[peripherals.boards]]
board = "rpi-gpio"
transport = "native"
[[peripherals.boards]]
board = "esp32"
transport = "wifi"
# Edge-Native: ZeroClaw runs on ESP32
```
## 6. Kiến trúc: Peripheral là điểm mở rộng
### Trait mới: `Peripheral`
```rust
/// A hardware peripheral that exposes capabilities as tools.
#[async_trait]
pub trait Peripheral: Send + Sync {
fn name(&self) -> &str;
fn board_type(&self) -> &str; // e.g. "nucleo-f401re", "rpi-gpio"
async fn connect(&mut self) -> anyhow::Result<()>;
async fn disconnect(&mut self) -> anyhow::Result<()>;
async fn health_check(&self) -> bool;
/// Tools this peripheral provides (gpio_read, gpio_write, sensor_read, etc.)
fn tools(&self) -> Vec<Box<dyn Tool>>;
}
```
### Luồng xử lý
1. **Khởi động:** ZeroClaw nạp config, đọc `peripherals.boards`.
2. **Kết nối:** Với mỗi board, tạo impl `Peripheral`, gọi `connect()`.
3. **Tools:** Thu thập tools từ tất cả peripheral đã kết nối; gộp với tools mặc định.
4. **Vòng lặp agent:** Agent có thể gọi `gpio_write`, `sensor_read`, v.v. — các lệnh này chuyển tiếp tới peripheral.
5. **Tắt máy:** Gọi `disconnect()` trên từng peripheral.
### Hỗ trợ Board
| Board | Transport | Firmware / Driver | Tools |
|-------|-----------|-------------------|-------|
| nucleo-f401re | serial | Zephyr / Embassy | gpio_read, gpio_write, adc_read |
| rpi-gpio | native | rppal or sysfs | gpio_read, gpio_write |
| esp32 | serial/ws | ESP-IDF / Embassy | gpio, wifi, mqtt |
## 7. Giao thức giao tiếp
### gRPC / nanoRPC (Edge-Native, Host-Mediated)
Dành cho RPC có kiểu dữ liệu, độ trễ thấp giữa ZeroClaw và các peripheral:
- **nanoRPC** hoặc **tonic** (gRPC): Dịch vụ định nghĩa bằng Protobuf.
- Phương thức: `GpioWrite`, `GpioRead`, `I2cTransfer`, `SpiTransfer`, `MemoryRead`, `FlashWrite`, v.v.
- Hỗ trợ streaming, gọi hai chiều, và sinh code từ file `.proto`.
### Serial Fallback (Host-Mediated, legacy)
JSON đơn giản qua serial cho các board không hỗ trợ gRPC:
**Request (host → peripheral):**
```json
{"id":"1","cmd":"gpio_write","args":{"pin":13,"value":1}}
```
**Response (peripheral → host):**
```json
{"id":"1","ok":true,"result":"done"}
```
## 8. Firmware (Repo hoặc Crate riêng)
- **zeroclaw-firmware** hoặc **zeroclaw-peripheral** — một crate/workspace riêng biệt.
- Targets: `thumbv7em-none-eabihf` (STM32), `armv7-unknown-linux-gnueabihf` (RPi), v.v.
- Dùng `embassy` hoặc Zephyr cho STM32.
- Triển khai giao thức nêu trên.
- Người dùng nạp lên board; ZeroClaw kết nối và tự phát hiện khả năng.
## 9. Các giai đoạn triển khai
### Phase 1: Skeleton ✅ (Hoàn thành)
- [x] Thêm trait `Peripheral`, config schema, CLI (`zeroclaw peripheral list/add`)
- [x] Thêm flag `--peripheral` cho agent
- [x] Ghi tài liệu vào AGENTS.md
### Phase 2: Host-Mediated — Phát hiện phần cứng ✅ (Hoàn thành)
- [x] `zeroclaw hardware discover`: liệt kê thiết bị USB (VID/PID)
- [x] Board registry: ánh xạ VID/PID → kiến trúc, tên (ví dụ: Nucleo-F401RE)
- [x] `zeroclaw hardware introspect <path>`: memory map, danh sách peripheral
### Phase 3: Host-Mediated — Serial / J-Link
- [x] `SerialPeripheral` cho STM32 qua USB CDC
- [ ] Tích hợp probe-rs hoặc OpenOCD để nạp/gỡ lỗi firmware
- [x] Tools: `gpio_read`, `gpio_write` (memory_read, flash_write trong tương lai)
### Phase 4: Pipeline RAG ✅ (Hoàn thành)
- [x] Lập chỉ mục datasheet (markdown/text → các đoạn)
- [x] Truy xuất và chèn vào ngữ cảnh LLM cho các truy vấn liên quan phần cứng
- [x] Bổ sung prompt đặc thù theo board
**Cách dùng:** Thêm `datasheet_dir = "docs/datasheets"` vào `[peripherals]` trong config.toml. Đặt file `.md` hoặc `.txt` được đặt tên theo board (ví dụ: `nucleo-f401re.md`, `rpi-gpio.md`). Các file trong `_generic/` hoặc tên `generic.md` áp dụng cho mọi board. Các đoạn được truy xuất theo từ khóa và chèn vào ngữ cảnh tin nhắn người dùng.
### Phase 5: Edge-Native — RPi ✅ (Hoàn thành)
- [x] ZeroClaw trên Raspberry Pi (native GPIO qua rppal)
- [ ] Server gRPC/nanoRPC cho truy cập peripheral cục bộ
- [ ] Lưu trữ code (lưu các đoạn code đã tổng hợp)
### Phase 6: Edge-Native — ESP32
- [x] ESP32 qua Host-Mediated (serial transport) — cùng giao thức JSON như STM32
- [x] Crate firmware `esp32` (`firmware/esp32`) — GPIO qua UART
- [x] ESP32 trong hardware registry (CH340 VID/PID)
- [ ] ZeroClaw *chạy trực tiếp trên* ESP32 (WiFi + LLM, edge-native) — tương lai
- [ ] Thực thi Wasm hoặc dựa trên template cho logic do LLM tạo ra
**Cách dùng:** Nạp `firmware/esp32` vào ESP32, thêm `board = "esp32"`, `transport = "serial"`, `path = "/dev/ttyUSB0"` vào config.
### Phase 7: Thực thi động (Code do LLM tạo ra)
- [ ] Thư viện template: các đoạn GPIO/I2C/SPI có tham số
- [ ] Tùy chọn: Wasm runtime cho logic do người dùng định nghĩa (sandboxed)
- [ ] Lưu và tái sử dụng các đường code tối ưu
## 10. Các khía cạnh bảo mật
- **Serial path:** Xác thực `path` nằm trong danh sách cho phép (ví dụ: `/dev/ttyACM*`, `/dev/ttyUSB*`); không bao giờ dùng đường dẫn tùy ý.
- **GPIO:** Giới hạn những pin nào được phép truy cập; tránh các pin nguồn/reset.
- **Không lưu bí mật trên peripheral:** Firmware không nên lưu API key; máy chủ xử lý xác thực.
## 11. Ngoài phạm vi (Hiện tại)
- Chạy ZeroClaw đầy đủ *trực tiếp trên* STM32 bare-metal (không có WiFi, RAM hạn chế) — dùng Host-Mediated thay thế
- Đảm bảo thời gian thực — peripheral hoạt động theo kiểu best-effort
- Thực thi code native tùy ý từ LLM — ưu tiên Wasm hoặc templates
## 12. Tài liệu liên quan
- [adding-boards-and-tools.md](./adding-boards-and-tools.md) — Cách thêm board và datasheet
- [network-deployment.md](network-deployment.md) — Triển khai RPi và mạng
## 13. Tham khảo
- [Zephyr RTOS Rust support](https://docs.zephyrproject.org/latest/develop/languages/rust/index.html)
- [Embassy](https://embassy.dev/) — async embedded framework
- [rppal](https://github.com/golemparts/rppal) — Raspberry Pi GPIO in Rust
- [STM32 Nucleo-F401RE](https://www.st.com/en/evaluation-tools/nucleo-f401re.html)
- [tonic](https://github.com/hyperium/tonic) — gRPC for Rust
- [probe-rs](https://probe.rs/) — ARM debug probe, flash, memory access
- [nusb](https://github.com/nic-hartley/nusb) — USB device enumeration (VID/PID)
## 14. Tóm tắt ý tưởng gốc
> *"Các board như ESP, Raspberry Pi, hoặc các board có WiFi có thể kết nối với LLM (Gemini hoặc mã nguồn mở). ZeroClaw chạy trên thiết bị, tạo gRPC riêng, khởi động nó, và giao tiếp với ngoại vi. Người dùng hỏi qua WhatsApp: 'di chuyển cánh tay X' hoặc 'bật LED'. ZeroClaw lấy tài liệu chính xác, viết code, thực thi, lưu trữ tối ưu, chạy, và bật LED — tất cả trên board phát triển.*
>
> *Với STM Nucleo kết nối qua USB/J-Link/Aardvark vào Mac: ZeroClaw từ Mac truy cập phần cứng, cài đặt hoặc ghi những gì cần thiết lên thiết bị, và trả kết quả. Ví dụ: 'Hey ZeroClaw, những địa chỉ khả dụng/đọc được trên thiết bị USB này là gì?' Nó có thể tự tìm ra thiết bị nào đang kết nối ở đâu và đưa ra gợi ý."*
-19
View File
@@ -1,19 +0,0 @@
# Tài liệu phần cứng và ngoại vi
Tích hợp board, firmware và ngoại vi.
Hệ thống phần cứng của ZeroClaw cho phép điều khiển trực tiếp vi điều khiển và ngoại vi thông qua trait `Peripheral`. Mỗi board cung cấp các tool cho GPIO, ADC và các thao tác cảm biến, cho phép tương tác phần cứng do agent điều khiển trên các board như STM32 Nucleo, Raspberry Pi và ESP32. Xem [../hardware-peripherals-design.md](../hardware-peripherals-design.md) để biết kiến trúc đầy đủ.
## Điểm bắt đầu
- Kiến trúc và mô hình ngoại vi: [../hardware-peripherals-design.md](../hardware-peripherals-design.md)
- Thêm board/tool mới: [../adding-boards-and-tools.md](../adding-boards-and-tools.md)
- Thiết lập Nucleo: [../nucleo-setup.md](../nucleo-setup.md)
- Thiết lập Arduino Uno R4 WiFi: [../arduino-uno-q-setup.md](../arduino-uno-q-setup.md)
## Datasheet
- Chỉ mục datasheet: [../datasheets](../datasheets)
- STM32 Nucleo-F401RE: [../datasheets/nucleo-f401re.md](../datasheets/nucleo-f401re.md)
- Arduino Uno: [../datasheets/arduino-uno.md](../datasheets/arduino-uno.md)
- ESP32: [../datasheets/esp32.md](../datasheets/esp32.md)
-239
View File
@@ -1,239 +0,0 @@
# Hướng dẫn Tích hợp LangGraph
Hướng dẫn này giải thích cách sử dụng gói Python `zeroclaw-tools` để gọi tool nhất quán với bất kỳ LLM provider nào tương thích OpenAI.
## Bối cảnh
Một số LLM provider, đặc biệt là các model Trung Quốc như GLM-5 (Zhipu AI), có hành vi gọi tool không nhất quán khi dùng phương thức text-based tool invocation. Core Rust của ZeroClaw sử dụng structured tool calling theo định dạng OpenAI API, nhưng một số model phản hồi tốt hơn với cách tiếp cận khác.
LangGraph cung cấp một stateful graph execution engine đảm bảo hành vi gọi tool nhất quán bất kể khả năng native của model nền tảng.
## Kiến trúc
```
┌─────────────────────────────────────────────────────────────┐
│ Your Application │
├─────────────────────────────────────────────────────────────┤
│ zeroclaw-tools Agent │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ LangGraph StateGraph │ │
│ │ │ │
│ │ ┌────────────┐ ┌────────────┐ │ │
│ │ │ Agent │ ──────▶ │ Tools │ │ │
│ │ │ Node │ ◀────── │ Node │ │ │
│ │ └────────────┘ └────────────┘ │ │
│ │ │ │ │ │
│ │ ▼ ▼ │ │
│ │ [Continue?] [Execute Tool] │ │
│ │ │ │ │ │
│ │ Yes │ No Result│ │ │
│ │ ▼ ▼ │ │
│ │ [END] [Back to Agent] │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────┤
│ OpenAI-Compatible LLM Provider │
│ (Z.AI, OpenRouter, Groq, DeepSeek, Ollama, etc.) │
└─────────────────────────────────────────────────────────────┘
```
## Bắt đầu nhanh
### Cài đặt
```bash
pip install zeroclaw-tools
```
### Sử dụng cơ bản
```python
import asyncio
from zeroclaw_tools import create_agent, shell, file_read, file_write
from langchain_core.messages import HumanMessage
async def main():
agent = create_agent(
tools=[shell, file_read, file_write],
model="glm-5",
api_key="your-api-key",
base_url="https://api.z.ai/api/coding/paas/v4"
)
result = await agent.ainvoke({
"messages": [HumanMessage(content="Read /etc/hostname and tell me the machine name")]
})
print(result["messages"][-1].content)
asyncio.run(main())
```
## Các Tool Hiện có
### Tool cốt lõi
| Tool | Mô tả |
|------|-------|
| `shell` | Thực thi lệnh shell |
| `file_read` | Đọc nội dung file |
| `file_write` | Ghi nội dung vào file |
### Tool mở rộng
| Tool | Mô tả |
|------|-------|
| `web_search` | Tìm kiếm web (yêu cầu `BRAVE_API_KEY`) |
| `http_request` | Thực hiện HTTP request |
| `memory_store` | Lưu dữ liệu vào bộ nhớ lâu dài |
| `memory_recall` | Truy xuất dữ liệu đã lưu |
## Tool tùy chỉnh
Tạo tool riêng của bạn bằng decorator `@tool`:
```python
from zeroclaw_tools import tool, create_agent
@tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
# Your implementation
return f"Weather in {city}: Sunny, 25°C"
@tool
def query_database(sql: str) -> str:
"""Execute a SQL query and return results."""
# Your implementation
return "Query returned 5 rows"
agent = create_agent(
tools=[get_weather, query_database],
model="glm-5",
api_key="your-key"
)
```
## Cấu hình Provider
### Z.AI / GLM-5
```python
agent = create_agent(
model="glm-5",
api_key="your-zhipu-key",
base_url="https://api.z.ai/api/coding/paas/v4"
)
```
### OpenRouter
```python
agent = create_agent(
model="anthropic/claude-sonnet-4-6",
api_key="your-openrouter-key",
base_url="https://openrouter.ai/api/v1"
)
```
### Groq
```python
agent = create_agent(
model="llama-3.3-70b-versatile",
api_key="your-groq-key",
base_url="https://api.groq.com/openai/v1"
)
```
### Ollama (cục bộ)
```python
agent = create_agent(
model="llama3.2",
base_url="http://localhost:11434/v1"
)
```
## Tích hợp Discord Bot
```python
import os
from zeroclaw_tools.integrations import DiscordBot
bot = DiscordBot(
token=os.environ["DISCORD_TOKEN"],
guild_id=123456789, # Your Discord server ID
allowed_users=["123456789"], # User IDs that can use the bot
api_key=os.environ["API_KEY"],
model="glm-5"
)
bot.run()
```
## Sử dụng qua CLI
```bash
# Set environment variables
export API_KEY="your-key"
export BRAVE_API_KEY="your-brave-key" # Optional, for web search
# Single message
zeroclaw-tools "What is the current date?"
# Interactive mode
zeroclaw-tools -i
```
## So sánh với Rust ZeroClaw
| Khía cạnh | Rust ZeroClaw | zeroclaw-tools |
|--------|---------------|-----------------|
| **Hiệu năng** | Cực nhanh (~10ms khởi động) | Khởi động Python (~500ms) |
| **Bộ nhớ** | <5 MB | ~50 MB |
| **Kích thước binary** | ~3.4 MB | pip package |
| **Tính nhất quán của tool** | Phụ thuộc model | LangGraph đảm bảo |
| **Khả năng mở rộng** | Rust traits | Python decorators |
| **Hệ sinh thái** | Rust crates | PyPI packages |
**Khi nào dùng Rust ZeroClaw:**
- Triển khai edge cho môi trường production
- Môi trường hạn chế tài nguyên (Raspberry Pi, v.v.)
- Yêu cầu hiệu năng tối đa
**Khi nào dùng zeroclaw-tools:**
- Các model có tool calling native không nhất quán
- Phát triển trung tâm vào Python
- Prototyping nhanh
- Tích hợp với hệ sinh thái Python ML
## Xử lý sự cố
### Lỗi "API key required"
Đặt biến môi trường `API_KEY` hoặc truyền `api_key` vào `create_agent()`.
### Tool call không được thực thi
Đảm bảo model của bạn hỗ trợ function calling. Một số model cũ có thể không hỗ trợ tool.
### Rate limiting
Thêm độ trễ giữa các lần gọi hoặc tự triển khai rate limiting:
```python
import asyncio
for message in messages:
result = await agent.ainvoke({"messages": [message]})
await asyncio.sleep(1) # Rate limit
```
## Dự án Liên quan
- [rs-graph-llm](https://github.com/a-agmon/rs-graph-llm) - Rust LangGraph alternative
- [langchain-rust](https://github.com/Abraxas-365/langchain-rust) - LangChain for Rust
- [llm-chain](https://github.com/sobelio/llm-chain) - LLM chains in Rust
-141
View File
@@ -1,141 +0,0 @@
# Hướng dẫn Matrix E2EE
Hướng dẫn này giải thích cách chạy ZeroClaw ổn định trong các phòng Matrix, bao gồm các phòng mã hóa đầu cuối (E2EE).
Tài liệu tập trung vào lỗi phổ biến mà người dùng báo cáo:
> "Matrix đã cấu hình đúng, kiểm tra thành công, nhưng bot không phản hồi."
## 0. FAQ nhanh (triệu chứng lớp #499)
Nếu Matrix có vẻ đã kết nối nhưng không có phản hồi, hãy xác minh những điều sau trước:
1. Người gửi được cho phép bởi `allowed_users` (khi kiểm tra: `["*"]`).
2. Tài khoản bot đã tham gia đúng phòng mục tiêu.
3. Token thuộc về cùng tài khoản bot (kiểm tra bằng `whoami`).
4. Phòng mã hóa có identity thiết bị (`device_id`) và chia sẻ key hợp lệ.
5. Daemon đã được khởi động lại sau khi thay đổi cấu hình.
---
## 1. Yêu cầu
Trước khi kiểm tra luồng tin nhắn, hãy đảm bảo tất cả các điều sau đều đúng:
1. Tài khoản bot đã tham gia phòng mục tiêu.
2. Access token thuộc về cùng tài khoản bot.
3. `room_id` chính xác:
- ưu tiên: canonical room ID (`!room:server`)
- được hỗ trợ: room alias (`#alias:server`) và ZeroClaw sẽ tự resolve
4. `allowed_users` cho phép người gửi (`["*"]` để kiểm tra mở).
5. Với phòng E2EE, thiết bị bot đã nhận được encryption key cho phòng.
---
## 2. Cấu hình
Dùng `~/.zeroclaw/config.toml`:
```toml
[channels_config.matrix]
homeserver = "https://matrix.example.com"
access_token = "syt_your_token"
# Optional but recommended for E2EE stability:
user_id = "@zeroclaw:matrix.example.com"
device_id = "DEVICEID123"
# Room ID or alias
room_id = "!xtHhdHIIVEZbDPvTvZ:matrix.example.com"
# room_id = "#ops:matrix.example.com"
# Use ["*"] during initial verification, then tighten.
allowed_users = ["*"]
```
### Về `user_id``device_id`
- ZeroClaw cố đọc identity từ Matrix `/_matrix/client/v3/account/whoami`.
- Nếu `whoami` không trả về `device_id`, hãy đặt `device_id` thủ công.
- Các gợi ý này đặc biệt quan trọng để khôi phục phiên E2EE.
---
## 3. Quy trình Xác minh Nhanh
1. Chạy thiết lập channel và daemon:
```bash
zeroclaw onboard --channels-only
zeroclaw daemon
```
1. Gửi một tin nhắn văn bản thuần trong phòng Matrix đã cấu hình.
2. Xác nhận log ZeroClaw có thông tin khởi động Matrix listener và không có lỗi sync/auth lặp lại.
3. Trong phòng mã hóa, xác minh bot có thể đọc và phản hồi tin nhắn mã hóa từ các người dùng được phép.
---
## 4. Xử lý sự cố "Không có Phản hồi"
Dùng checklist này theo thứ tự.
### A. Phòng và tư cách thành viên
- Đảm bảo tài khoản bot đã tham gia phòng.
- Nếu dùng alias (`#...`), xác minh nó resolve về đúng canonical room.
### B. Allowlist người gửi
- Nếu `allowed_users = []`, tất cả tin nhắn đến đều bị từ chối.
- Để chẩn đoán, tạm thời đặt `allowed_users = ["*"]`.
### C. Token và identity
- Xác thực token bằng:
```bash
curl -sS -H "Authorization: Bearer $MATRIX_TOKEN" \
"https://matrix.example.com/_matrix/client/v3/account/whoami"
```
- Kiểm tra `user_id` trả về khớp với tài khoản bot.
- Nếu `device_id` bị thiếu, đặt `channels_config.matrix.device_id` thủ công.
### D. Kiểm tra dành riêng cho E2EE
- Thiết bị bot phải nhận được room key từ các thiết bị tin cậy.
- Nếu key không được chia sẻ tới thiết bị này, các sự kiện mã hóa không thể giải mã.
- Xác minh độ tin cậy thiết bị và chia sẻ key trong quy trình Matrix client/admin của bạn.
- Nếu log hiện `matrix_sdk_crypto::backups: Trying to backup room keys but no backup key was found`, quá trình khôi phục key backup chưa được bật trên thiết bị này. Cảnh báo này thường không gây lỗi nghiêm trọng cho luồng tin nhắn trực tiếp, nhưng bạn vẫn nên hoàn thiện thiết lập key backup/recovery.
- Nếu người nhận thấy tin nhắn bot là "unverified", hãy xác minh/ký thiết bị bot từ một phiên Matrix tin cậy và giữ `channels_config.matrix.device_id` ổn định qua các lần khởi động lại.
### E. Định dạng tin nhắn (Markdown)
- ZeroClaw gửi phản hồi văn bản Matrix dưới dạng nội dung `m.room.message` hỗ trợ markdown.
- Các Matrix client hỗ trợ `formatted_body` sẽ render in đậm, danh sách và code block.
- Nếu định dạng hiển thị dưới dạng văn bản thuần, kiểm tra khả năng của client trước, sau đó xác nhận ZeroClaw đang chạy bản build bao gồm Matrix output hỗ trợ markdown.
### F. Kiểm tra fresh start
Sau khi cập nhật cấu hình, khởi động lại daemon và gửi tin nhắn mới (không chỉ xem lại lịch sử cũ).
---
## 5. Ghi chú Vận hành
- Giữ Matrix token tránh khỏi log và ảnh chụp màn hình.
- Bắt đầu với `allowed_users` thoáng, sau đó thu hẹp về các user ID cụ thể.
- Ưu tiên dùng canonical room ID trong production để tránh alias drift.
---
## 6. Tài liệu Liên quan
- [Channels Reference](./channels-reference.md)
- [Phụ lục từ khoá log vận hành](./channels-reference.md#7-operations-appendix-log-keywords-matrix)
- [Network Deployment](./network-deployment.md)
- [Agnostic Security](agnostic-security.md)
- [Reviewer Playbook](reviewer-playbook.md)
-63
View File
@@ -1,63 +0,0 @@
# Hướng dẫn Tích hợp Mattermost
ZeroClaw hỗ trợ tích hợp native với Mattermost thông qua REST API v4. Tích hợp này lý tưởng cho các môi trường self-hosted, riêng tư hoặc air-gapped nơi giao tiếp nội bộ là yêu cầu bắt buộc.
## Điều kiện tiên quyết
1. **Mattermost Server**: Một instance Mattermost đang chạy (self-hosted hoặc cloud).
2. **Tài khoản Bot**:
- Vào **Main Menu > Integrations > Bot Accounts**.
- Nhấn **Add Bot Account**.
- Đặt username (ví dụ: `zeroclaw-bot`).
- Bật quyền **post:all****channel:read** (hoặc các scope phù hợp).
- Lưu **Access Token**.
3. **Channel ID**:
- Mở channel Mattermost mà bạn muốn bot theo dõi.
- Nhấn vào header channel và chọn **View Info**.
- Sao chép **ID** (ví dụ: `7j8k9l...`).
## Cấu hình
Thêm phần sau vào `config.toml` của bạn trong phần `[channels_config]`:
```toml
[channels_config.mattermost]
url = "https://mm.your-domain.com"
bot_token = "your-bot-access-token"
channel_id = "your-channel-id"
allowed_users = ["user-id-1", "user-id-2"]
thread_replies = true
mention_only = true
```
### Các trường cấu hình
| Trường | Mô tả |
|---|---|
| `url` | Base URL của Mattermost server của bạn. |
| `bot_token` | Personal Access Token của tài khoản bot. |
| `channel_id` | (Tùy chọn) ID của channel cần lắng nghe. Bắt buộc ở chế độ `listen`. |
| `allowed_users` | (Tùy chọn) Danh sách Mattermost User ID được phép tương tác với bot. Dùng `["*"]` để cho phép tất cả mọi người. |
| `thread_replies` | (Tùy chọn) Tin nhắn người dùng ở top-level có được trả lời trong thread không. Mặc định: `true`. Các phản hồi trong thread hiện có luôn ở lại trong thread đó. |
| `mention_only` | (Tùy chọn) Khi `true`, chỉ các tin nhắn đề cập rõ ràng username bot (ví dụ `@zeroclaw-bot`) mới được xử lý. Mặc định: `false`. |
## Cuộc hội thoại dạng Thread
ZeroClaw hỗ trợ Mattermost thread ở cả hai chế độ:
- Nếu người dùng gửi tin nhắn trong một thread hiện có, ZeroClaw luôn phản hồi trong cùng thread đó.
- Nếu `thread_replies = true` (mặc định), tin nhắn top-level được trả lời bằng cách tạo thread trên bài đăng đó.
- Nếu `thread_replies = false`, tin nhắn top-level được trả lời ở cấp độ gốc của channel.
## Chế độ Mention-Only
Khi `mention_only = true`, ZeroClaw áp dụng bộ lọc bổ sung sau khi xác thực `allowed_users`:
- Tin nhắn không đề cập rõ ràng đến bot sẽ bị bỏ qua.
- Tin nhắn có `@bot_username` sẽ được xử lý.
- Token `@bot_username` được loại bỏ trước khi gửi nội dung đến model.
Chế độ này hữu ích trong các channel chia sẻ bận rộn để giảm các lần gọi model không cần thiết.
## Ghi chú Bảo mật
Tích hợp Mattermost được thiết kế cho **giao tiếp nội bộ**. Bằng cách tự host Mattermost server, toàn bộ lịch sử giao tiếp của agent vẫn nằm trong hạ tầng của bạn, tránh việc bên thứ ba ghi lại log.
-206
View File
@@ -1,206 +0,0 @@
# Triển khai mạng — ZeroClaw trên Raspberry Pi và mạng nội bộ
Tài liệu này hướng dẫn triển khai ZeroClaw trên Raspberry Pi hoặc host khác trong mạng nội bộ, với các channel Telegram và webhook tùy chọn.
---
## 1. Tổng quan
| Chế độ | Cần cổng đến? | Trường hợp dùng |
|------|----------------------|----------|
| **Telegram polling** | Không | ZeroClaw poll Telegram API; hoạt động từ bất kỳ đâu |
| **Matrix sync (kể cả E2EE)** | Không | ZeroClaw sync qua Matrix client API; không cần webhook đến |
| **Discord/Slack** | Không | Tương tự — chỉ outbound |
| **Gateway webhook** | Có | POST /webhook, WhatsApp, v.v. cần public URL |
| **Gateway pairing** | Có | Nếu bạn pair client qua gateway |
**Lưu ý:** Telegram, Discord và Slack dùng **long-polling** — ZeroClaw thực hiện các request ra ngoài. Không cần port forwarding hoặc public IP.
---
## 2. ZeroClaw trên Raspberry Pi
### 2.1 Điều kiện tiên quyết
- Raspberry Pi (3/4/5) với Raspberry Pi OS
- Thiết bị ngoại vi USB (Arduino, Nucleo) nếu dùng serial transport
- Tùy chọn: `rppal` cho native GPIO (`peripheral-rpi` feature)
### 2.2 Cài đặt
```bash
# Build for RPi (or cross-compile from host)
cargo build --release --features hardware
# Or install via your preferred method
```
### 2.3 Cấu hình
Chỉnh sửa `~/.zeroclaw/config.toml`:
```toml
[peripherals]
enabled = true
[[peripherals.boards]]
board = "rpi-gpio"
transport = "native"
# Or Arduino over USB
[[peripherals.boards]]
board = "arduino-uno"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
[channels_config.telegram]
bot_token = "YOUR_BOT_TOKEN"
allowed_users = []
[gateway]
host = "127.0.0.1"
port = 3000
allow_public_bind = false
```
### 2.4 Chạy Daemon (chỉ cục bộ)
```bash
zeroclaw daemon --host 127.0.0.1 --port 3000
```
- Gateway bind vào `127.0.0.1` — không tiếp cận được từ máy khác
- Channel Telegram hoạt động: ZeroClaw poll Telegram API (outbound)
- Không cần tường lửa hay port forwarding
---
## 3. Bind vào 0.0.0.0 (mạng nội bộ)
Để cho phép các thiết bị khác trong LAN của bạn truy cập gateway (ví dụ: để pairing hoặc webhook):
### 3.1 Tùy chọn A: Opt-in rõ ràng
```toml
[gateway]
host = "0.0.0.0"
port = 3000
allow_public_bind = true
```
```bash
zeroclaw daemon --host 0.0.0.0 --port 3000
```
**Bảo mật:** `allow_public_bind = true` phơi bày gateway với mạng nội bộ của bạn. Chỉ dùng trên mạng LAN tin cậy.
### 3.2 Tùy chọn B: Tunnel (khuyến nghị cho Webhook)
Nếu bạn cần **public URL** (ví dụ: webhook WhatsApp, client bên ngoài):
1. Chạy gateway trên localhost:
```bash
zeroclaw daemon --host 127.0.0.1 --port 3000
```
2. Khởi động tunnel:
```toml
[tunnel]
provider = "tailscale" # or "ngrok", "cloudflare"
```
Hoặc dùng `zeroclaw tunnel` (xem tài liệu tunnel).
3. ZeroClaw sẽ từ chối `0.0.0.0` trừ khi `allow_public_bind = true` hoặc có tunnel đang hoạt động.
---
## 4. Telegram Polling (Không cần cổng đến)
Telegram dùng **long-polling** theo mặc định:
- ZeroClaw gọi `https://api.telegram.org/bot{token}/getUpdates`
- Không cần cổng đến hoặc public IP
- Hoạt động sau NAT, trên RPi, trong home lab
**Cấu hình:**
```toml
[channels_config.telegram]
bot_token = "YOUR_BOT_TOKEN"
allowed_users = [] # deny-by-default, bind identities explicitly
```
Chạy `zeroclaw daemon` — channel Telegram khởi động tự động.
Để cho phép một tài khoản Telegram lúc runtime:
```bash
zeroclaw channel bind-telegram <IDENTITY>
```
`<IDENTITY>` có thể là Telegram user ID dạng số hoặc username (không có `@`).
### 4.1 Quy tắc Single Poller (Quan trọng)
Telegram Bot API `getUpdates` chỉ hỗ trợ một poller hoạt động cho mỗi bot token.
- Chỉ chạy một instance runtime cho cùng token (khuyến nghị: service `zeroclaw daemon`).
- Không chạy `cargo run -- channel start` hay tiến trình bot khác cùng lúc.
Nếu gặp lỗi này:
`Conflict: terminated by other getUpdates request`
bạn đang có xung đột polling. Dừng các instance thừa và chỉ khởi động lại một daemon duy nhất.
---
## 5. Webhook Channel (WhatsApp, Tùy chỉnh)
Các channel dựa trên webhook cần **public URL** để Meta (WhatsApp) hoặc client của bạn có thể POST sự kiện.
### 5.1 Tailscale Funnel
```toml
[tunnel]
provider = "tailscale"
```
Tailscale Funnel phơi bày gateway của bạn qua URL `*.ts.net`. Không cần port forwarding.
### 5.2 ngrok
```toml
[tunnel]
provider = "ngrok"
```
Hoặc chạy ngrok thủ công:
```bash
ngrok http 3000
# Use the HTTPS URL for your webhook
```
### 5.3 Cloudflare Tunnel
Cấu hình Cloudflare Tunnel để forward đến `127.0.0.1:3000`, sau đó đặt webhook URL của bạn về hostname công khai của tunnel.
---
## 6. Checklist: Triển khai RPi
- [ ] Build với `--features hardware` (và `peripheral-rpi` nếu dùng native GPIO)
- [ ] Cấu hình `[peripherals]``[channels_config.telegram]`
- [ ] Chạy `zeroclaw daemon --host 127.0.0.1 --port 3000` (Telegram hoạt động không cần 0.0.0.0)
- [ ] Để truy cập LAN: `--host 0.0.0.0` + `allow_public_bind = true` trong config
- [ ] Để dùng webhook: dùng Tailscale, ngrok hoặc Cloudflare tunnel
---
## 7. Tham khảo
- [channels-reference.md](./channels-reference.md) — Tổng quan cấu hình channel
- [matrix-e2ee-guide.md](./matrix-e2ee-guide.md) — Thiết lập Matrix và xử lý sự cố phòng mã hóa
- [hardware-peripherals-design.md](hardware-peripherals-design.md) — Thiết kế peripherals
- [adding-boards-and-tools.md](adding-boards-and-tools.md) — Thiết lập phần cứng và thêm board
-147
View File
@@ -1,147 +0,0 @@
# ZeroClaw trên Nucleo-F401RE — Hướng dẫn từng bước
Chạy ZeroClaw trên Mac hoặc Linux. Kết nối Nucleo-F401RE qua USB. Điều khiển GPIO (LED, các pin) qua Telegram hoặc CLI.
---
## Lấy thông tin board qua Telegram (Không cần nạp firmware)
ZeroClaw có thể đọc thông tin chip từ Nucleo qua USB **mà không cần nạp firmware nào**. Nhắn tin cho Telegram bot của bạn:
- *"What board info do I have?"*
- *"Board info"*
- *"What hardware is connected?"*
- *"Chip info"*
Agent dùng tool `hardware_board_info` để trả về tên chip, kiến trúc và memory map. Với feature `probe`, nó đọc dữ liệu trực tiếp qua USB/SWD; nếu không, nó trả về thông tin tĩnh từ datasheet.
**Cấu hình:** Thêm Nucleo vào `config.toml` trước (để agent biết board nào cần truy vấn):
```toml
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
```
**Thay thế bằng CLI:**
```bash
cargo build --features hardware,probe
zeroclaw hardware info
zeroclaw hardware discover
```
---
## Những gì đã có sẵn (Không cần thay đổi code)
ZeroClaw bao gồm mọi thứ cần thiết cho Nucleo-F401RE:
| Thành phần | Vị trí | Mục đích |
|------------|--------|---------|
| Firmware | `firmware/nucleo/` | Embassy Rust — USART2 (115200), gpio_read, gpio_write |
| Serial peripheral | `src/peripherals/serial.rs` | Giao thức JSON-over-serial (giống Arduino/ESP32) |
| Flash command | `zeroclaw peripheral flash-nucleo` | Build firmware, nạp qua probe-rs |
Giao thức: JSON phân tách bằng dòng mới. Request: `{"id":"1","cmd":"gpio_write","args":{"pin":13,"value":1}}`. Response: `{"id":"1","ok":true,"result":"done"}`.
---
## Yêu cầu trước khi bắt đầu
- Board Nucleo-F401RE
- Cáp USB (USB-A sang Mini-USB; Nucleo có ST-Link tích hợp sẵn)
- Để nạp firmware: `cargo install probe-rs-tools --locked` (hoặc dùng [install script](https://probe.rs/docs/getting-started/installation/))
---
## Phase 1: Nạp Firmware
### 1.1 Kết nối Nucleo
1. Kết nối Nucleo với Mac/Linux qua USB.
2. Board xuất hiện như thiết bị USB (ST-Link). Không cần driver riêng trên các hệ thống hiện đại.
### 1.2 Nạp qua ZeroClaw
Từ thư mục gốc của repo zeroclaw:
```bash
zeroclaw peripheral flash-nucleo
```
Lệnh này build `firmware/nucleo` và chạy `probe-rs run --chip STM32F401RETx`. Firmware chạy ngay sau khi nạp xong.
### 1.3 Nạp thủ công (Phương án thay thế)
```bash
cd firmware/nucleo
cargo build --release --target thumbv7em-none-eabihf
probe-rs run --chip STM32F401RETx target/thumbv7em-none-eabihf/release/nucleo
```
---
## Phase 2: Tìm Serial Port
- **macOS:** `/dev/cu.usbmodem*` hoặc `/dev/tty.usbmodem*` (ví dụ: `/dev/cu.usbmodem101`)
- **Linux:** `/dev/ttyACM0` (hoặc kiểm tra `dmesg` sau khi cắm vào)
USART2 (PA2/PA3) được bridge sang cổng COM ảo của ST-Link, vì vậy máy chủ thấy một thiết bị serial duy nhất.
---
## Phase 3: Cấu hình ZeroClaw
Thêm vào `~/.zeroclaw/config.toml`:
```toml
[peripherals]
enabled = true
[[peripherals.boards]]
board = "nucleo-f401re"
transport = "serial"
path = "/dev/cu.usbmodem101" # điều chỉnh theo port của bạn
baud = 115200
```
---
## Phase 4: Chạy và Kiểm thử
```bash
zeroclaw daemon --host 127.0.0.1 --port 3000
```
Hoặc dùng agent trực tiếp:
```bash
zeroclaw agent --message "Turn on the LED on pin 13"
```
Pin 13 = PA5 = User LED (LD2) trên Nucleo-F401RE.
---
## Tóm tắt: Các lệnh
| Bước | Lệnh |
|------|------|
| 1 | Kết nối Nucleo qua USB |
| 2 | `cargo install probe-rs-tools --locked` |
| 3 | `zeroclaw peripheral flash-nucleo` |
| 4 | Thêm Nucleo vào config.toml (path = serial port của bạn) |
| 5 | `zeroclaw daemon` hoặc `zeroclaw agent -m "Turn on LED"` |
---
## Xử lý sự cố
- **flash-nucleo không nhận ra** — Build từ repo: `cargo run --features hardware -- peripheral flash-nucleo`. Subcommand này chỉ có trong repo build, không có trong cài đặt từ crates.io.
- **Không tìm thấy probe-rs**`cargo install probe-rs-tools --locked` (crate `probe-rs` là thư viện; CLI nằm trong `probe-rs-tools`)
- **Không phát hiện được probe** — Đảm bảo Nucleo đã kết nối. Thử cáp/cổng USB khác.
- **Không tìm thấy serial port** — Trên Linux, thêm user vào nhóm `dialout`: `sudo usermod -a -G dialout $USER`, rồi đăng xuất/đăng nhập lại.
- **Lệnh GPIO bị bỏ qua** — Kiểm tra `path` trong config có khớp với serial port của bạn. Chạy `zeroclaw peripheral list` để xác nhận.
-120
View File
@@ -1,120 +0,0 @@
# Cài đặt một lệnh
Cách cài đặt và khởi tạo ZeroClaw nhanh nhất.
Xác minh lần cuối: **2026-02-20**.
## Cách 0: Homebrew (macOS/Linuxbrew)
```bash
brew install zeroclaw
```
## Cách A (Khuyến nghị): Clone + chạy script cục bộ
```bash
git clone https://github.com/zeroclaw-labs/zeroclaw.git
cd zeroclaw
./install.sh
```
Mặc định script sẽ:
1. `cargo build --release --locked`
2. `cargo install --path . --force --locked`
### Kiểm tra tài nguyên và binary dựng sẵn
Build từ mã nguồn thường yêu cầu tối thiểu:
- **2 GB RAM + swap**
- **6 GB dung lượng trống**
Khi tài nguyên hạn chế, bootstrap sẽ thử tải binary dựng sẵn trước.
```bash
./install.sh --prefer-prebuilt
```
Chỉ dùng binary dựng sẵn, báo lỗi nếu không tìm thấy bản phù hợp:
```bash
./install.sh --prebuilt-only
```
Bỏ qua binary dựng sẵn, buộc build từ mã nguồn:
```bash
./install.sh --force-source-build
```
## Bootstrap kép
Mặc định là **chỉ ứng dụng** (build/cài ZeroClaw), yêu cầu Rust toolchain sẵn có.
Với máy mới, bật bootstrap môi trường:
```bash
./install.sh --install-system-deps --install-rust
```
Lưu ý:
- `--install-system-deps` cài các thành phần biên dịch/build cần thiết (có thể cần `sudo`).
- `--install-rust` cài Rust qua `rustup` nếu chưa có.
- `--prefer-prebuilt` thử tải binary dựng sẵn trước, nếu không có thì build từ nguồn.
- `--prebuilt-only` tắt phương án build từ nguồn.
- `--force-source-build` tắt hoàn toàn phương án binary dựng sẵn.
## Cách B: Lệnh từ xa một dòng
```bash
curl -fsSL https://raw.githubusercontent.com/zeroclaw-labs/zeroclaw/master/install.sh | bash
```
Với môi trường yêu cầu bảo mật cao, nên dùng Cách A để kiểm tra script trước khi chạy.
Nếu chạy Cách B ngoài thư mục repo, bootstrap script sẽ tự clone workspace tạm, build, cài đặt rồi dọn dẹp.
## Chế độ thiết lập tùy chọn
### Thiết lập trong container (Docker)
```bash
./install.sh --docker
```
Lệnh này build image ZeroClaw cục bộ và chạy thiết lập trong container, lưu config/workspace vào `./.zeroclaw-docker`.
### Thiết lập nhanh (không tương tác)
```bash
./install.sh --api-key "sk-..." --provider openrouter
```
Hoặc dùng biến môi trường:
```bash
ZEROCLAW_API_KEY="sk-..." ZEROCLAW_PROVIDER="openrouter" ./install.sh
```
## Các cờ hữu ích
- `--install-system-deps`
- `--install-rust`
- `--skip-build`
- `--skip-install`
- `--provider <id>`
Xem tất cả tùy chọn:
```bash
./install.sh --help
```
## Tài liệu liên quan
- [README.vi.md](../../../README.vi.md)
- [commands-reference.md](commands-reference.md)
- [providers-reference.md](providers-reference.md)
- [channels-reference.md](channels-reference.md)
-128
View File
@@ -1,128 +0,0 @@
# Sổ tay Vận hành ZeroClaw
Tài liệu này dành cho các operator chịu trách nhiệm duy trì tính sẵn sàng, tình trạng bảo mật và xử lý sự cố.
Cập nhật lần cuối: **2026-02-18**.
## Phạm vi
Dùng tài liệu này cho các tác vụ vận hành day-2:
- khởi động và giám sát runtime
- kiểm tra sức khoẻ và chẩn đoán hệ thống
- triển khai an toàn và rollback
- phân loại và khôi phục sau sự cố
Nếu đây là lần cài đặt đầu tiên, hãy bắt đầu từ [one-click-bootstrap.md](one-click-bootstrap.md).
## Các chế độ Runtime
| Chế độ | Lệnh | Khi nào dùng |
|---|---|---|
| Foreground runtime | `zeroclaw daemon` | gỡ lỗi cục bộ, phiên ngắn |
| Foreground gateway only | `zeroclaw gateway` | kiểm thử webhook endpoint |
| User service | `zeroclaw service install && zeroclaw service start` | runtime được quản lý liên tục bởi operator |
## Checklist Cơ bản cho Operator
1. Xác thực cấu hình:
```bash
zeroclaw status
```
1. Kiểm tra chẩn đoán:
```bash
zeroclaw doctor
zeroclaw channel doctor
```
1. Khởi động runtime:
```bash
zeroclaw daemon
```
1. Để chạy như user session service liên tục:
```bash
zeroclaw service install
zeroclaw service start
zeroclaw service status
```
## Tín hiệu Sức khoẻ và Trạng thái
| Tín hiệu | Lệnh / File | Kỳ vọng |
|---|---|---|
| Tính hợp lệ của config | `zeroclaw doctor` | không có lỗi nghiêm trọng |
| Kết nối channel | `zeroclaw channel doctor` | các channel đã cấu hình đều khoẻ mạnh |
| Tóm tắt runtime | `zeroclaw status` | provider/model/channels như mong đợi |
| Heartbeat/trạng thái daemon | `~/.zeroclaw/daemon_state.json` | file được cập nhật định kỳ |
## Log và Chẩn đoán
### macOS / Windows (log của service wrapper)
- `~/.zeroclaw/logs/daemon.stdout.log`
- `~/.zeroclaw/logs/daemon.stderr.log`
### Linux (systemd user service)
```bash
journalctl --user -u zeroclaw.service -f
```
## Quy trình Phân loại Sự cố (Fast Path)
1. Chụp trạng thái hệ thống:
```bash
zeroclaw status
zeroclaw doctor
zeroclaw channel doctor
```
1. Kiểm tra trạng thái service:
```bash
zeroclaw service status
```
1. Nếu service không khoẻ, khởi động lại sạch:
```bash
zeroclaw service stop
zeroclaw service start
```
1. Nếu các channel vẫn thất bại, kiểm tra allowlist và thông tin xác thực trong `~/.zeroclaw/config.toml`.
2. Nếu liên quan đến gateway, kiểm tra cài đặt bind/auth (`[gateway]`) và khả năng tiếp cận cục bộ.
## Quy trình Thay đổi An toàn
Trước khi áp dụng thay đổi cấu hình:
1. sao lưu `~/.zeroclaw/config.toml`
2. chỉ áp dụng một thay đổi logic tại một thời điểm
3. chạy `zeroclaw doctor`
4. khởi động lại daemon/service
5. xác minh bằng `status` + `channel doctor`
## Quy trình Rollback
Nếu một lần triển khai gây ra suy giảm hành vi:
1. khôi phục `config.toml` trước đó
2. khởi động lại runtime (`daemon` hoặc `service`)
3. xác nhận khôi phục qua `doctor` và kiểm tra sức khoẻ channel
4. ghi lại nguyên nhân gốc rễ và biện pháp khắc phục sự cố
## Tài liệu Liên quan
- [one-click-bootstrap.md](one-click-bootstrap.md)
- [troubleshooting.md](troubleshooting.md)
- [config-reference.md](config-reference.md)
- [commands-reference.md](commands-reference.md)
-24
View File
@@ -1,24 +0,0 @@
# Tài liệu vận hành và triển khai
Dành cho operator vận hành ZeroClaw liên tục hoặc trên production.
## Vận hành cốt lõi
- Sổ tay Day-2: [../operations-runbook.md](../operations-runbook.md)
- Sổ tay Release: [../release-process.md](../release-process.md)
- Ma trận xử lý sự cố: [../troubleshooting.md](../troubleshooting.md)
- Triển khai mạng/gateway an toàn: [../network-deployment.md](../network-deployment.md)
- Thiết lập Mattermost (dành riêng cho channel): [../mattermost-setup.md](../mattermost-setup.md)
## Luồng thường gặp
1. Xác thực runtime (`status`, `doctor`, `channel doctor`)
2. Áp dụng từng thay đổi config một lần
3. Khởi động lại service/daemon
4. Xác minh tình trạng channel và gateway
5. Rollback nhanh nếu hành vi bị hồi quy
## Liên quan
- Tham chiếu config: [../config-reference.md](../config-reference.md)
- Bộ sưu tập bảo mật: [../security/README.md](../security/README.md)
-366
View File
@@ -1,366 +0,0 @@
# Quy trình PR ZeroClaw (Cộng tác khối lượng cao)
Tài liệu này định nghĩa cách ZeroClaw xử lý khối lượng PR lớn trong khi vẫn duy trì:
- Hiệu suất cao
- Hiệu quả cao
- Tính ổn định cao
- Khả năng mở rộng cao
- Tính bền vững cao
- Bảo mật cao
Tài liệu liên quan:
- [`docs/README.md`](README.md) — phân loại và điều hướng tài liệu.
- [`docs/ci-map.md`](ci-map.md) — quyền sở hữu từng workflow, trigger và luồng triage.
- [`docs/reviewer-playbook.md`](reviewer-playbook.md) — hướng dẫn thực thi cho reviewer hàng ngày.
## 0. Tóm tắt
- **Mục đích:** cung cấp mô hình vận hành PR mang tính quyết định và dựa trên rủi ro cho cộng tác thông lượng cao.
- **Đối tượng:** contributor, maintainer và reviewer có hỗ trợ agent.
- **Phạm vi:** cài đặt repository, vòng đời PR, hợp đồng sẵn sàng, phân tuyến rủi ro, kỷ luật hàng đợi và giao thức phục hồi.
- **Ngoài phạm vi:** thay thế cấu hình branch protection hoặc file CI workflow làm nguồn triển khai chính thức.
---
## 1. Lối tắt theo tình huống PR
Dùng phần này để phân tuyến nhanh trước khi review sâu toàn bộ.
### 1.1 Intake chưa đầy đủ
1. Yêu cầu hoàn thiện template và bằng chứng còn thiếu trong một comment dạng checklist.
2. Dừng review sâu cho đến khi các vấn đề intake được giải quyết.
Xem tiếp:
- [Mục 5.1](#51-definition-of-ready-dor-trước-khi-yêu-cầu-review)
### 1.2 `CI Required Gate` đang thất bại
1. Phân tuyến lỗi qua CI map và ưu tiên sửa các gate mang tính quyết định trước.
2. Chỉ đánh giá lại rủi ro sau khi CI trả về tín hiệu rõ ràng.
Xem tiếp:
- [docs/ci-map.md](ci-map.md)
- [Mục 4.2](#42-bước-b-validation)
### 1.3 Đụng đến đường dẫn rủi ro cao
1. Chuyển sang luồng review sâu.
2. Yêu cầu rollback rõ ràng, bằng chứng về failure mode và kiểm tra ranh giới bảo mật.
Xem tiếp:
- [Mục 9](#9-quy-tắc-bảo-mật-và-ổn-định)
- [docs/reviewer-playbook.md](reviewer-playbook.md)
### 1.4 PR bị supersede hoặc trùng lặp
1. Yêu cầu liên kết supersede rõ ràng và dọn dẹp hàng đợi.
2. Đóng PR bị supersede sau khi maintainer xác nhận.
Xem tiếp:
- [Mục 8.2](#82-kiểm-soát-áp-lực-backlog)
---
## 2. Mục tiêu quản trị và vòng kiểm soát
### 2.1 Mục tiêu quản trị
1. Giữ thông lượng merge có thể dự đoán được khi tải PR lớn.
2. Giữ chất lượng tín hiệu CI ở mức cao (phản hồi nhanh, ít false positive).
3. Giữ review bảo mật rõ ràng đối với các bề mặt rủi ro.
4. Giữ các thay đổi dễ suy luận và dễ hoàn tác.
5. Giữ các artifact trong repository không bị rò rỉ dữ liệu cá nhân/nhạy cảm.
### 2.2 Logic thiết kế quản trị (vòng kiểm soát)
Workflow này được phân lớp có chủ đích để giảm tải cho reviewer trong khi vẫn đảm bảo trách nhiệm rõ ràng:
1. **Phân loại intake:** nhãn theo đường dẫn/kích thước/rủi ro/module phân tuyến PR đến độ sâu review phù hợp.
2. **Validation mang tính quyết định:** merge gate phụ thuộc vào các kiểm tra tái tạo được, không phải comment mang tính chủ quan.
3. **Độ sâu review theo rủi ro:** đường dẫn rủi ro cao kích hoạt review sâu; đường dẫn rủi ro thấp được xử lý nhanh.
4. **Hợp đồng merge ưu tiên rollback:** mọi đường dẫn merge đều bao gồm các bước phục hồi cụ thể.
Tự động hóa hỗ trợ việc triage và bảo vệ, nhưng trách nhiệm merge cuối cùng vẫn thuộc về maintainer và tác giả PR.
---
## 3. Cài đặt repository bắt buộc
Duy trì các quy tắc branch protection sau trên `master`:
- Yêu cầu status check trước khi merge.
- Yêu cầu check `CI Required Gate`.
- Yêu cầu review pull request trước khi merge.
- Yêu cầu review CODEOWNERS cho các đường dẫn được bảo vệ.
- Với `.github/workflows/**`, yêu cầu phê duyệt từ owner qua `CI Required Gate` (`WORKFLOW_OWNER_LOGINS`) và giới hạn quyền bypass branch/ruleset cho org owner.
- Danh sách workflow-owner mặc định được cấu hình qua biến repository `WORKFLOW_OWNER_LOGINS` (xem CODEOWNERS cho maintainer hiện tại).
- Hủy bỏ approval cũ khi có commit mới được đẩy lên.
- Hạn chế force-push trên các branch được bảo vệ.
- Tất cả PR của contributor nhắm trực tiếp vào `master`.
---
## 4. Sổ tay vòng đời PR
### 4.1 Bước A: Intake
- Contributor mở PR với `.github/pull_request_template.md` đầy đủ.
- `PR Labeler` áp dụng nhãn phạm vi/đường dẫn + nhãn kích thước + nhãn rủi ro + nhãn module (ví dụ `channel:telegram`, `provider:kimi`, `tool:shell`) và bậc contributor theo số PR đã merge (`trusted` >=5, `experienced` >=10, `principal` >=20, `distinguished` >=50), đồng thời loại bỏ trùng lặp nhãn phạm vi ít cụ thể hơn khi đã có nhãn module cụ thể hơn.
- Đối với tất cả các tiền tố module, nhãn module được nén gọn để giảm nhiễu: một module cụ thể giữ `prefix:component`, nhưng nhiều module cụ thể thu gọn thành nhãn phạm vi cơ sở `prefix`.
- Thứ tự nhãn ưu tiên đầu tiên: `risk:*` -> `size:*` -> bậc contributor -> nhãn module/đường dẫn.
- Maintainer có thể chạy `PR Labeler` thủ công (`workflow_dispatch`) ở chế độ `audit` để kiểm tra drift hoặc chế độ `repair` để chuẩn hóa metadata nhãn được quản lý trên toàn repository.
- Di chuột qua nhãn trên GitHub hiển thị mô tả được quản lý tự động (tóm tắt quy tắc/ngưỡng).
- Màu nhãn được quản lý được sắp xếp theo thứ tự hiển thị để tạo gradient mượt mà trên các hàng nhãn dài.
- `PR Auto Responder` đăng hướng dẫn lần đầu, xử lý phân tuyến dựa trên nhãn cho các mục tín hiệu thấp và tự động áp dụng bậc contributor cho issue với cùng ngưỡng như `PR Labeler` (`trusted` >=5, `experienced` >=10, `principal` >=20, `distinguished` >=50).
### 4.2 Bước B: Validation
- `CI Required Gate` là merge gate.
- PR chỉ thay đổi tài liệu sử dụng fast-path và bỏ qua các Rust job nặng.
- PR không phải tài liệu phải vượt qua lint, test và kiểm tra smoke release build.
- PR ảnh hưởng Rust sử dụng cùng bộ gate bắt buộc như push lên `master` (không có shortcut chỉ build trên PR).
### 4.3 Bước C: Review
- Reviewer ưu tiên theo nhãn rủi ro và kích thước.
- Các đường dẫn nhạy cảm về bảo mật (`src/security`, `src/runtime`, `src/gateway` và CI workflow) yêu cầu sự chú ý của maintainer.
- PR lớn (`size: L`/`size: XL`) nên được chia nhỏ trừ khi có lý do thuyết phục.
### 4.4 Bước D: Merge
- Ưu tiên **squash merge** để giữ lịch sử gọn gàng.
- Tiêu đề PR nên theo phong cách Conventional Commit.
- Chỉ merge khi đường dẫn rollback đã được ghi lại.
---
## 5. Hợp đồng sẵn sàng PR (DoR / DoD)
### 5.1 Definition of Ready (DoR) trước khi yêu cầu review
- Template PR đã hoàn thiện đầy đủ.
- Ranh giới phạm vi rõ ràng (những gì đã thay đổi / những gì không thay đổi).
- Bằng chứng validation đã đính kèm (không chỉ là "CI sẽ kiểm tra").
- Các trường bảo mật và rollback đã hoàn thành cho các đường dẫn rủi ro.
- Kiểm tra tính riêng tư/vệ sinh dữ liệu đã hoàn thành và ngôn ngữ test trung lập/theo phạm vi dự án.
- Nếu có ngôn ngữ giống danh tính trong test/ví dụ, cần được chuẩn hóa về nhãn gốc ZeroClaw/dự án.
### 5.2 Definition of Done (DoD) sẵn sàng merge
- `CI Required Gate` đã xanh.
- Các reviewer bắt buộc đã phê duyệt (bao gồm các đường dẫn CODEOWNERS).
- Nhãn phân loại rủi ro khớp với các đường dẫn đã chạm.
- Tác động migration/tương thích đã được ghi lại.
- Đường dẫn rollback cụ thể và nhanh chóng.
---
## 6. Chính sách kích thước và lô PR
### 6.1 Phân loại kích thước
- `size: XS` <= 80 dòng thay đổi
- `size: S` <= 250 dòng thay đổi
- `size: M` <= 500 dòng thay đổi
- `size: L` <= 1000 dòng thay đổi
- `size: XL` > 1000 dòng thay đổi
### 6.2 Chính sách
- Mặc định hướng đến `XS/S/M`.
- PR `L/XL` cần lý do biện minh rõ ràng và bằng chứng test chặt chẽ hơn.
- Nếu tính năng lớn không thể tránh khỏi, chia thành các stacked PR.
### 6.3 Hành vi tự động hóa
- `PR Labeler` áp dụng nhãn `size:*` từ số dòng thay đổi thực tế.
- PR chỉ tài liệu/nặng lockfile được chuẩn hóa để tránh thổi phồng kích thước.
---
## 7. Chính sách đóng góp AI/Agent
PR có sự hỗ trợ AI được chào đón, và review cũng có thể được hỗ trợ bằng agent.
### 7.1 Bắt buộc
1. Tóm tắt PR rõ ràng với ranh giới phạm vi.
2. Bằng chứng test/validation cụ thể.
3. Ghi chú tác động bảo mật và rollback cho các thay đổi rủi ro.
### 7.2 Khuyến nghị
1. Ghi chú ngắn gọn về tool/workflow khi tự động hóa ảnh hưởng đáng kể đến thay đổi.
2. Đoạn prompt/kế hoạch tùy chọn để tái tạo được.
Chúng tôi **không** yêu cầu contributor định lượng quyền sở hữu dòng AI-vs-human.
### 7.3 Trọng tâm review cho PR nặng AI
- Tương thích hợp đồng.
- Ranh giới bảo mật.
- Xử lý lỗi và hành vi fallback.
- Hồi quy hiệu suất và bộ nhớ.
---
## 8. SLA review và kỷ luật hàng đợi
- Mục tiêu triage maintainer đầu tiên: trong vòng 48 giờ.
- Nếu PR bị chặn, maintainer để lại một checklist hành động được.
- Tự động hóa `stale` được dùng để giữ hàng đợi lành mạnh; maintainer có thể áp dụng `no-stale` khi cần.
- Tự động hóa `pr-hygiene` kiểm tra các PR mở mỗi 12 giờ và đăng nhắc nhở khi PR không có commit mới trong 48+ giờ và rơi vào một trong hai trường hợp: đang tụt hậu so với `master` hoặc thiếu/thất bại `CI Required Gate` trên head commit.
### 8.1 Kiểm soát ngân sách hàng đợi
- Sử dụng ngân sách hàng đợi review: giới hạn số PR đang được review sâu đồng thời mỗi maintainer và giữ phần còn lại ở trạng thái triage.
- Đối với công việc stacked, yêu cầu `Depends on #...` rõ ràng để thứ tự review mang tính quyết định.
### 8.2 Kiểm soát áp lực backlog
- Nếu một PR mới thay thế một PR cũ đang mở, yêu cầu `Supersedes #...` và đóng PR cũ sau khi maintainer xác nhận.
- Đánh dấu các PR ngủ đông/dư thừa bằng `stale-candidate` hoặc `superseded` để giảm nỗ lực review trùng lặp.
### 8.3 Kỷ luật triage issue
- `r:needs-repro` cho báo cáo lỗi chưa đầy đủ (yêu cầu repro mang tính quyết định trước khi triage sâu).
- `r:support` cho các mục sử dụng/trợ giúp nên xử lý ngoài bug backlog.
- Nhãn `invalid` / `duplicate` kích hoạt tự động hóa đóng **chỉ issue** kèm hướng dẫn.
### 8.4 Bảo vệ tác dụng phụ của tự động hóa
- `PR Auto Responder` loại bỏ trùng lặp comment dựa trên nhãn để tránh spam.
- Các luồng đóng tự động chỉ giới hạn cho issue, không phải PR.
- Maintainer có thể đóng băng tính toán lại rủi ro tự động bằng `risk: manual` khi ngữ cảnh yêu cầu ghi đè thủ công.
---
## 9. Quy tắc bảo mật và ổn định
Các thay đổi ở những khu vực này yêu cầu review chặt chẽ hơn và bằng chứng test mạnh hơn:
- `src/security/**`
- Quản lý tiến trình runtime.
- Hành vi ingress/xác thực gateway (`src/gateway/**`).
- Ranh giới truy cập filesystem.
- Hành vi mạng/xác thực.
- GitHub workflow và pipeline release.
- Các tool có khả năng thực thi (`src/tools/**`).
### 9.1 Tối thiểu cho PR rủi ro
- Tuyên bố mối đe dọa/rủi ro.
- Ghi chú biện pháp giảm thiểu.
- Các bước rollback.
### 9.2 Khuyến nghị cho PR rủi ro cao
- Bao gồm một test tập trung chứng minh hành vi ranh giới.
- Bao gồm một kịch bản failure mode rõ ràng và sự suy giảm mong đợi.
Đối với các đóng góp có hỗ trợ agent, reviewer cũng nên xác minh rằng tác giả hiểu hành vi runtime và blast radius.
---
## 10. Giao thức phục hồi sự cố
Nếu một PR đã merge gây ra hồi quy:
1. Revert PR ngay lập tức trên `master`.
2. Mở issue theo dõi với phân tích nguyên nhân gốc.
3. Chỉ đưa lại bản sửa lỗi khi có test hồi quy.
Ưu tiên khôi phục nhanh chất lượng dịch vụ hơn là bản vá hoàn hảo nhưng chậm trễ.
---
## 11. Checklist merge của maintainer
- Phạm vi tập trung và dễ hiểu.
- CI gate đã xanh.
- Kiểm tra chất lượng tài liệu đã xanh khi tài liệu thay đổi.
- Các trường tác động bảo mật đã hoàn thành.
- Các trường tính riêng tư/vệ sinh dữ liệu đã hoàn thành và bằng chứng đã được biên tập/ẩn danh.
- Ghi chú workflow agent đủ để tái tạo (nếu tự động hóa được sử dụng).
- Kế hoạch rollback rõ ràng.
- Tiêu đề commit theo Conventional Commits.
---
## 12. Mô hình vận hành review agent
Để giữ chất lượng review ổn định khi khối lượng PR cao, sử dụng mô hình review hai làn.
### 12.1 Làn A: triage nhanh (thân thiện với agent)
- Xác nhận độ đầy đủ của template PR.
- Xác nhận tín hiệu CI gate (`CI Required Gate`).
- Xác nhận phân loại rủi ro qua nhãn và các đường dẫn đã chạm.
- Xác nhận tuyên bố rollback tồn tại.
- Xác nhận phần tính riêng tư/vệ sinh dữ liệu và các yêu cầu diễn đạt trung lập đã được thỏa mãn.
- Xác nhận bất kỳ ngôn ngữ giống danh tính nào đều sử dụng thuật ngữ gốc ZeroClaw/dự án.
### 12.2 Làn B: review sâu (dựa trên rủi ro)
Bắt buộc cho các thay đổi rủi ro cao (security/runtime/gateway/CI):
- Xác thực giả định mô hình mối đe dọa.
- Xác thực hành vi failure mode và suy giảm.
- Xác thực tương thích ngược và tác động migration.
- Xác thực tác động observability/logging.
---
## 13. Ưu tiên hàng đợi và kỷ luật nhãn
### 13.1 Khuyến nghị thứ tự triage
1. `size: XS`/`size: S` + sửa lỗi/bảo mật.
2. `size: M` thay đổi tập trung.
3. `size: L`/`size: XL` yêu cầu chia nhỏ hoặc review theo giai đoạn.
### 13.2 Kỷ luật nhãn
- Nhãn đường dẫn xác định quyền sở hữu hệ thống con nhanh chóng.
- Nhãn kích thước điều hướng chiến lược lô.
- Nhãn rủi ro điều hướng độ sâu review (`risk: low/medium/high`).
- Nhãn module (`<module>: <component>`) cải thiện phân tuyến reviewer cho các thay đổi cụ thể theo integration và các module mới được thêm vào trong tương lai.
- `risk: manual` cho phép maintainer bảo tồn phán đoán rủi ro của con người khi tự động hóa thiếu ngữ cảnh.
- `no-stale` được dành riêng cho công việc đã được chấp nhận nhưng bị chặn.
---
## 14. Hợp đồng bàn giao agent
Khi một agent bàn giao cho agent khác (hoặc cho maintainer), bao gồm:
1. Ranh giới phạm vi (những gì đã thay đổi / những gì không thay đổi).
2. Bằng chứng validation.
3. Rủi ro mở và những điều chưa biết.
4. Hành động tiếp theo được đề xuất.
Điều này giữ cho tổn thất ngữ cảnh ở mức thấp và tránh việc phải đào sâu lặp lại.
---
## 15. Tài liệu liên quan
- [README.md](README.md) — phân loại và điều hướng tài liệu.
- [ci-map.md](ci-map.md) — bản đồ quyền sở hữu và triage CI workflow.
- [reviewer-playbook.md](reviewer-playbook.md) — mô hình thực thi của reviewer.
- [actions-source-policy.md](actions-source-policy.md) — chính sách allowlist nguồn action.
---
## 16. Ghi chú bảo trì
- **Chủ sở hữu:** các maintainer chịu trách nhiệm về quản trị cộng tác và chất lượng merge.
- **Kích hoạt cập nhật:** thay đổi branch protection, thay đổi chính sách nhãn/rủi ro, cập nhật quản trị hàng đợi hoặc thay đổi quy trình review agent.
- **Lần review cuối:** 2026-02-18.
-17
View File
@@ -1,17 +0,0 @@
# Tài liệu snapshot và triage dự án
Snapshot trạng thái dự án có giới hạn thời gian cho tài liệu lập kế hoạch và công việc vận hành.
## Snapshot hiện tại
- [project-triage-snapshot-2026-02-18.md](../../../maintainers/project-triage-snapshot-2026-02-18.md)
## Phạm vi
Snapshot dự án là các đánh giá có giới hạn thời gian về PR mở, issue và tình trạng tài liệu. Dùng chúng để:
- Xác định các khoảng trống tài liệu được thúc đẩy bởi công việc tính năng
- Ưu tiên bảo trì tài liệu song song với thay đổi code
- Theo dõi áp lực PR/issue đang phát triển theo thời gian
Để phân loại tài liệu ổn định (không giới hạn thời gian), dùng [docs-inventory.md](../../../maintainers/docs-inventory.md).
-253
View File
@@ -1,253 +0,0 @@
# Tài liệu tham khảo Providers — ZeroClaw
Tài liệu này liệt kê các provider ID, alias và biến môi trường chứa thông tin xác thực.
Cập nhật lần cuối: **2026-03-10**.
## Cách liệt kê các Provider
```bash
zeroclaw providers
```
## Thứ tự ưu tiên khi giải quyết thông tin xác thực
Thứ tự ưu tiên tại runtime:
1. Thông tin xác thực tường minh từ config/CLI
2. Biến môi trường dành riêng cho provider
3. Biến môi trường dự phòng chung: `ZEROCLAW_API_KEY`, sau đó là `API_KEY`
Với chuỗi provider dự phòng (`reliability.fallback_providers`), mỗi provider dự phòng tự giải quyết thông tin xác thực của mình độc lập. Key xác thực của provider chính không tự động dùng cho provider dự phòng.
## Danh mục Provider
| Canonical ID | Alias | Cục bộ | Biến môi trường dành riêng |
|---|---|---:|---|
| `openrouter` | — | Không | `OPENROUTER_API_KEY` |
| `anthropic` | — | Không | `ANTHROPIC_OAUTH_TOKEN`, `ANTHROPIC_API_KEY` |
| `openai` | — | Không | `OPENAI_API_KEY` |
| `ollama` | — | Có | `OLLAMA_API_KEY` (tùy chọn) |
| `gemini` | `google`, `google-gemini` | Không | `GEMINI_API_KEY`, `GOOGLE_API_KEY` |
| `venice` | — | Không | `VENICE_API_KEY` |
| `vercel` | `vercel-ai` | Không | `VERCEL_API_KEY` |
| `cloudflare` | `cloudflare-ai` | Không | `CLOUDFLARE_API_KEY` |
| `moonshot` | `kimi` | Không | `MOONSHOT_API_KEY` |
| `kimi-code` | `kimi_coding`, `kimi_for_coding` | Không | `KIMI_CODE_API_KEY`, `MOONSHOT_API_KEY` |
| `synthetic` | — | Không | `SYNTHETIC_API_KEY` |
| `opencode` | `opencode-zen` | Không | `OPENCODE_API_KEY` |
| `opencode-go` | — | Không | `OPENCODE_GO_API_KEY` |
| `zai` | `z.ai` | Không | `ZAI_API_KEY` |
| `glm` | `zhipu` | Không | `GLM_API_KEY` |
| `minimax` | `minimax-intl`, `minimax-io`, `minimax-global`, `minimax-cn`, `minimaxi`, `minimax-oauth`, `minimax-oauth-cn`, `minimax-portal`, `minimax-portal-cn` | Không | `MINIMAX_OAUTH_TOKEN`, `MINIMAX_API_KEY` |
| `bedrock` | `aws-bedrock` | Không | `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` (tùy chọn: `AWS_REGION`) |
| `qianfan` | `baidu` | Không | `QIANFAN_API_KEY` |
| `qwen` | `dashscope`, `qwen-intl`, `dashscope-intl`, `qwen-us`, `dashscope-us`, `qwen-code`, `qwen-oauth`, `qwen_oauth` | Không | `QWEN_OAUTH_TOKEN`, `DASHSCOPE_API_KEY` |
| `groq` | — | Không | `GROQ_API_KEY` |
| `mistral` | — | Không | `MISTRAL_API_KEY` |
| `xai` | `grok` | Không | `XAI_API_KEY` |
| `deepseek` | — | Không | `DEEPSEEK_API_KEY` |
| `together` | `together-ai` | Không | `TOGETHER_API_KEY` |
| `fireworks` | `fireworks-ai` | Không | `FIREWORKS_API_KEY` |
| `perplexity` | — | Không | `PERPLEXITY_API_KEY` |
| `cohere` | — | Không | `COHERE_API_KEY` |
| `copilot` | `github-copilot` | Không | (dùng config/`API_KEY` fallback với GitHub token) |
| `lmstudio` | `lm-studio` | Có | (tùy chọn; mặc định là cục bộ) |
| `nvidia` | `nvidia-nim`, `build.nvidia.com` | Không | `NVIDIA_API_KEY` |
### Ghi chú về Gemini
- Provider ID: `gemini` (alias: `google`, `google-gemini`)
- Xác thực có thể dùng `GEMINI_API_KEY`, `GOOGLE_API_KEY`, hoặc Gemini CLI OAuth cache (`~/.gemini/oauth_creds.json`)
- Request bằng API key dùng endpoint `generativelanguage.googleapis.com/v1beta`
- Request OAuth qua Gemini CLI dùng endpoint `cloudcode-pa.googleapis.com/v1internal` theo chuẩn Code Assist request envelope
### Ghi chú về Ollama Vision
- Provider ID: `ollama`
- Hỗ trợ đầu vào hình ảnh qua marker nội tuyến trong tin nhắn: ``[IMAGE:<source>]``
- Sau khi chuẩn hóa multimodal, ZeroClaw gửi payload hình ảnh qua trường `messages[].images` gốc của Ollama.
- Nếu chọn provider không hỗ trợ vision, ZeroClaw trả về lỗi rõ ràng thay vì âm thầm bỏ qua hình ảnh.
### Ghi chú về Bedrock
- Provider ID: `bedrock` (alias: `aws-bedrock`)
- API: [Converse API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html)
- Xác thực: AWS AKSK (không phải một API key đơn lẻ). Cần đặt biến môi trường `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`.
- Tùy chọn: `AWS_SESSION_TOKEN` cho thông tin xác thực tạm thời/STS, `AWS_REGION` hoặc `AWS_DEFAULT_REGION` (mặc định: `us-east-1`).
- Model mặc định khi khởi tạo: `anthropic.claude-sonnet-4-5-20250929-v1:0`
- Hỗ trợ native tool calling và prompt caching (`cachePoint`).
- Hỗ trợ cross-region inference profiles (ví dụ: `us.anthropic.claude-*`).
- Model ID dùng định dạng Bedrock: `anthropic.claude-sonnet-4-6`, `anthropic.claude-opus-4-6-v1`, v.v.
### Bật/tắt tính năng Reasoning của Ollama
Bạn có thể kiểm soát hành vi reasoning/thinking của Ollama từ `config.toml`:
```toml
[runtime]
reasoning_enabled = false
```
Hành vi:
- `false`: gửi `think: false` đến các yêu cầu Ollama `/api/chat`.
- `true`: gửi `think: true`.
- Không đặt: bỏ qua `think` và giữ nguyên mặc định của Ollama/model.
### Ghi chú về Kimi Code
- Provider ID: `kimi-code`
- Endpoint: `https://api.kimi.com/coding/v1`
- Model mặc định khi khởi tạo: `kimi-for-coding` (thay thế: `kimi-k2.5`)
- Runtime tự động thêm `User-Agent: KimiCLI/0.77` để đảm bảo tương thích.
### Ghi chú về NVIDIA NIM
- Canonical provider ID: `nvidia`
- Alias: `nvidia-nim`, `build.nvidia.com`
- Base API URL: `https://integrate.api.nvidia.com/v1`
- Khám phá model: `zeroclaw models refresh --provider nvidia`
Các model ID khởi đầu được khuyến nghị (đã xác minh với danh mục NVIDIA API ngày 2026-02-18):
- `meta/llama-3.3-70b-instruct`
- `deepseek-ai/deepseek-v3.2`
- `nvidia/llama-3.3-nemotron-super-49b-v1.5`
- `nvidia/llama-3.1-nemotron-ultra-253b-v1`
## Endpoint Tùy chỉnh
- Endpoint tương thích OpenAI:
```toml
default_provider = "custom:https://your-api.example.com"
```
- Endpoint tương thích Anthropic:
```toml
default_provider = "anthropic-custom:https://your-api.example.com"
```
## Cấu hình MiniMax OAuth (`config.toml`)
Đặt provider MiniMax và OAuth placeholder trong config:
```toml
default_provider = "minimax-oauth"
api_key = "minimax-oauth"
```
Sau đó cung cấp một trong các thông tin xác thực sau qua biến môi trường:
- `MINIMAX_OAUTH_TOKEN` (ưu tiên, access token trực tiếp)
- `MINIMAX_API_KEY` (token tĩnh/cũ)
- `MINIMAX_OAUTH_REFRESH_TOKEN` (tự động làm mới access token khi khởi động)
Tùy chọn:
- `MINIMAX_OAUTH_REGION=global` hoặc `cn` (mặc định theo alias của provider)
- `MINIMAX_OAUTH_CLIENT_ID` để ghi đè OAuth client id mặc định
Lưu ý về tương thích channel:
- Đối với các cuộc trò chuyện channel được hỗ trợ bởi MiniMax, lịch sử runtime được chuẩn hóa để duy trì thứ tự lượt hợp lệ `user`/`assistant`.
- Hướng dẫn phân phối đặc thù của channel (ví dụ: marker đính kèm Telegram) được hợp nhất vào system prompt đầu tiên thay vì được thêm vào như một lượt `system` cuối cùng.
## Cấu hình Qwen Code OAuth (`config.toml`)
Đặt chế độ Qwen Code OAuth trong config:
```toml
default_provider = "qwen-code"
api_key = "qwen-oauth"
```
Thứ tự ưu tiên giải quyết thông tin xác thực cho `qwen-code`:
1. Giá trị `api_key` tường minh (nếu không phải placeholder `qwen-oauth`)
2. `QWEN_OAUTH_TOKEN`
3. `~/.qwen/oauth_creds.json` (tái sử dụng thông tin xác thực OAuth đã cache của Qwen Code)
4. Tùy chọn làm mới qua `QWEN_OAUTH_REFRESH_TOKEN` (hoặc refresh token đã cache)
5. Nếu không dùng OAuth placeholder, `DASHSCOPE_API_KEY` vẫn có thể được dùng làm dự phòng
Tùy chọn ghi đè endpoint:
- `QWEN_OAUTH_RESOURCE_URL` (được chuẩn hóa thành `https://.../v1` nếu cần)
- Nếu không đặt, `resource_url` từ thông tin xác thực OAuth đã cache sẽ được dùng khi có
## Định tuyến Model (`hint:<name>`)
Bạn có thể định tuyến các lời gọi model theo hint bằng cách sử dụng `[[model_routes]]`:
```toml
[[model_routes]]
hint = "reasoning"
provider = "openrouter"
model = "anthropic/claude-opus-4-20250514"
[[model_routes]]
hint = "fast"
provider = "groq"
model = "llama-3.3-70b-versatile"
```
Sau đó gọi với tên model hint (ví dụ từ tool hoặc các đường dẫn tích hợp):
```text
hint:reasoning
```
## Định tuyến Embedding (`hint:<name>`)
Bạn có thể định tuyến các lời gọi embedding theo cùng mẫu hint bằng `[[embedding_routes]]`.
Đặt `[memory].embedding_model` thành giá trị `hint:<name>` để kích hoạt định tuyến.
```toml
[memory]
embedding_model = "hint:semantic"
[[embedding_routes]]
hint = "semantic"
provider = "openai"
model = "text-embedding-3-small"
dimensions = 1536
[[embedding_routes]]
hint = "archive"
provider = "custom:https://embed.example.com/v1"
model = "your-embedding-model-id"
dimensions = 1024
```
Các embedding provider được hỗ trợ:
- `none`
- `openai`
- `custom:<url>` (endpoint embeddings tương thích OpenAI)
Tùy chọn ghi đè key theo từng route:
```toml
[[embedding_routes]]
hint = "semantic"
provider = "openai"
model = "text-embedding-3-small"
api_key = "sk-route-specific"
```
## Nâng cấp Model An toàn
Sử dụng các hint ổn định và chỉ cập nhật target route khi provider ngừng hỗ trợ model ID cũ.
Quy trình được khuyến nghị:
1. Giữ nguyên các call site (`hint:reasoning`, `hint:semantic`).
2. Chỉ thay đổi model đích trong `[[model_routes]]` hoặc `[[embedding_routes]]`.
3. Chạy:
- `zeroclaw doctor`
- `zeroclaw status`
4. Smoke test một luồng đại diện (chat + memory retrieval) trước khi triển khai.
Cách này giảm thiểu rủi ro phá vỡ vì các tích hợp và prompt không cần thay đổi khi nâng cấp model ID.
-229
View File
@@ -1,229 +0,0 @@
# Playbook Proxy Agent
Tài liệu này cung cấp các tool call có thể copy-paste để cấu hình hành vi proxy qua `proxy_config`.
Dùng tài liệu này khi bạn muốn agent chuyển đổi phạm vi proxy nhanh chóng và an toàn.
## 0. Tóm Tắt
- **Mục đích:** cung cấp tool call sẵn sàng sử dụng để quản lý phạm vi proxy và rollback.
- **Đối tượng:** operator và maintainer đang chạy ZeroClaw trong mạng có proxy.
- **Phạm vi:** các hành động `proxy_config`, lựa chọn mode, quy trình xác minh và xử lý sự cố.
- **Ngoài phạm vi:** gỡ lỗi mạng chung không liên quan đến hành vi runtime của ZeroClaw.
---
## 1. Đường Dẫn Nhanh Theo Mục Đích
Dùng mục này để định tuyến vận hành nhanh.
### 1.1 Chỉ proxy traffic nội bộ ZeroClaw
1. Dùng scope `zeroclaw`.
2. Đặt `http_proxy`/`https_proxy` hoặc `all_proxy`.
3. Xác minh bằng `{"action":"get"}`.
Xem:
- [Mục 4](#4-mode-a--chỉ-proxy-cho-nội-bộ-zeroclaw)
### 1.2 Chỉ proxy các dịch vụ được chọn
1. Dùng scope `services`.
2. Đặt các key cụ thể hoặc wildcard selector trong `services`.
3. Xác minh phủ sóng bằng `{"action":"list_services"}`.
Xem:
- [Mục 5](#5-mode-b--chỉ-proxy-cho-các-dịch-vụ-cụ-thể)
### 1.3 Xuất biến môi trường proxy cho toàn bộ process
1. Dùng scope `environment`.
2. Áp dụng bằng `{"action":"apply_env"}`.
3. Xác minh snapshot env qua `{"action":"get"}`.
Xem:
- [Mục 6](#6-mode-c--proxy-cho-toàn-bộ-môi-trường-process)
### 1.4 Rollback khẩn cấp
1. Tắt proxy.
2. Nếu cần, xóa các biến env đã xuất.
3. Kiểm tra lại snapshot runtime và môi trường.
Xem:
- [Mục 7](#7-các-mẫu-tắt--rollback)
---
## 2. Ma Trận Quyết Định Phạm Vi
| Phạm vi | Ảnh hưởng | Xuất biến env | Trường hợp dùng điển hình |
|---|---|---|---|
| `zeroclaw` | Các HTTP client nội bộ ZeroClaw | Không | Proxying runtime thông thường không có tác dụng phụ cấp process |
| `services` | Chỉ các service key/selector được chọn | Không | Định tuyến chi tiết cho provider/tool/channel cụ thể |
| `environment` | Runtime + biến môi trường proxy của process | Có | Các tích hợp yêu cầu `HTTP_PROXY`/`HTTPS_PROXY`/`ALL_PROXY` |
---
## 3. Quy Trình An Toàn Chuẩn
Dùng trình tự này cho mọi thay đổi proxy:
1. Kiểm tra trạng thái hiện tại.
2. Khám phá các service key/selector hợp lệ.
3. Áp dụng cấu hình phạm vi mục tiêu.
4. Xác minh snapshot runtime và môi trường.
5. Rollback nếu hành vi không như kỳ vọng.
Tool call:
```json
{"action":"get"}
{"action":"list_services"}
```
---
## 4. Mode A — Chỉ Proxy Cho Nội Bộ ZeroClaw
Dùng khi traffic HTTP của provider/channel/tool ZeroClaw cần đi qua proxy mà không xuất biến env proxy cấp process.
Tool call:
```json
{"action":"set","enabled":true,"scope":"zeroclaw","http_proxy":"http://127.0.0.1:7890","https_proxy":"http://127.0.0.1:7890","no_proxy":["localhost","127.0.0.1"]}
{"action":"get"}
```
Hành vi kỳ vọng:
- Runtime proxy hoạt động cho các HTTP client của ZeroClaw.
- Không cần xuất `HTTP_PROXY` / `HTTPS_PROXY` vào env của process.
---
## 5. Mode B — Chỉ Proxy Cho Các Dịch Vụ Cụ Thể
Dùng khi chỉ một phần hệ thống cần đi qua proxy (ví dụ provider/tool/channel cụ thể).
### 5.1 Nhắm vào dịch vụ cụ thể
```json
{"action":"set","enabled":true,"scope":"services","services":["provider.openai","tool.http_request","channel.telegram"],"all_proxy":"socks5h://127.0.0.1:1080","no_proxy":["localhost","127.0.0.1",".internal"]}
{"action":"get"}
```
### 5.2 Nhắm theo selector
```json
{"action":"set","enabled":true,"scope":"services","services":["provider.*","tool.*"],"http_proxy":"http://127.0.0.1:7890"}
{"action":"get"}
```
Hành vi kỳ vọng:
- Chỉ các service khớp mới dùng proxy.
- Các service không khớp bỏ qua proxy.
---
## 6. Mode C — Proxy Cho Toàn Bộ Môi Trường Process
Dùng khi bạn cần xuất tường minh các biến env của process (`HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY`) cho các tích hợp runtime.
### 6.1 Cấu hình và áp dụng environment scope
```json
{"action":"set","enabled":true,"scope":"environment","http_proxy":"http://127.0.0.1:7890","https_proxy":"http://127.0.0.1:7890","no_proxy":"localhost,127.0.0.1,.internal"}
{"action":"apply_env"}
{"action":"get"}
```
Hành vi kỳ vọng:
- Runtime proxy hoạt động.
- Các biến môi trường được xuất cho process.
---
## 7. Các Mẫu Tắt / Rollback
### 7.1 Tắt proxy (hành vi an toàn mặc định)
```json
{"action":"disable"}
{"action":"get"}
```
### 7.2 Tắt proxy và xóa cưỡng bức các biến env
```json
{"action":"disable","clear_env":true}
{"action":"get"}
```
### 7.3 Giữ proxy bật nhưng chỉ xóa các biến env đã xuất
```json
{"action":"clear_env"}
{"action":"get"}
```
---
## 8. Các Công Thức Vận Hành Thường Dùng
### 8.1 Chuyển từ proxy toàn environment sang proxy chỉ service
```json
{"action":"set","enabled":true,"scope":"services","services":["provider.openai","tool.http_request"],"all_proxy":"socks5://127.0.0.1:1080"}
{"action":"get"}
```
### 8.2 Thêm một dịch vụ proxied
```json
{"action":"set","scope":"services","services":["provider.openai","tool.http_request","channel.slack"]}
{"action":"get"}
```
### 8.3 Đặt lại danh sách `services` với selector
```json
{"action":"set","scope":"services","services":["provider.*","channel.telegram"]}
{"action":"get"}
```
---
## 9. Xử Lý Sự Cố
- Lỗi: `proxy.scope='services' requires a non-empty proxy.services list`
- Khắc phục: đặt ít nhất một service key cụ thể hoặc selector.
- Lỗi: invalid proxy URL scheme
- Scheme được chấp nhận: `http`, `https`, `socks5`, `socks5h`.
- Proxy không áp dụng như kỳ vọng
- Chạy `{"action":"list_services"}` và xác minh tên/selector dịch vụ.
- Chạy `{"action":"get"}` và kiểm tra giá trị snapshot `runtime_proxy``environment`.
---
## 10. Tài Liệu Liên Quan
- [README.md](./README.md) — Chỉ mục tài liệu và phân loại.
- [network-deployment.md](network-deployment.md) — Hướng dẫn triển khai mạng đầu-cuối và topology tunnel.
- [resource-limits.md](./resource-limits.md) — Giới hạn an toàn runtime cho ngữ cảnh thực thi mạng/tool.
---
## 11. Ghi Chú Bảo Trì
- **Chủ sở hữu:** maintainer runtime và tooling.
- **Điều kiện cập nhật:** các hành động `proxy_config` mới, ngữ nghĩa phạm vi proxy, hoặc thay đổi selector dịch vụ được hỗ trợ.
- **Xem xét lần cuối:** 2026-02-18.
-22
View File
@@ -1,22 +0,0 @@
# Danh mục tham chiếu
Tra cứu lệnh, provider, channel, config và tích hợp.
## Tham chiếu cốt lõi
- Lệnh theo workflow: [../commands-reference.md](../commands-reference.md)
- ID provider / alias / biến môi trường: [../providers-reference.md](../providers-reference.md)
- Thiết lập channel + allowlist: [../channels-reference.md](../channels-reference.md)
- Giá trị mặc định và khóa config: [../config-reference.md](../config-reference.md)
## Mở rộng provider và tích hợp
- Endpoint provider tùy chỉnh: [../custom-providers.md](../custom-providers.md)
- Tích hợp provider Z.AI / GLM: [../zai-glm-setup.md](../zai-glm-setup.md)
- Các mẫu tích hợp dựa trên LangGraph: [../langgraph-integration.md](../langgraph-integration.md)
## Cách dùng
Sử dụng bộ sưu tập này khi bạn cần chi tiết CLI/config chính xác hoặc các mẫu tích hợp provider thay vì hướng dẫn từng bước.
Khi thêm tài liệu tham chiếu/tích hợp mới, hãy đảm bảo nó được liên kết trong cả [../SUMMARY.md](../SUMMARY.md) và [docs-inventory.md](../../../maintainers/docs-inventory.md).
-133
View File
@@ -1,133 +0,0 @@
# Quy trình Release ZeroClaw
Runbook này định nghĩa quy trình release tiêu chuẩn của maintainer.
Cập nhật lần cuối: **2026-02-20**.
## Mục tiêu release
- Đảm bảo release có thể dự đoán và lặp lại.
- Chỉ publish từ code đã có trên `master`.
- Xác minh các artifact đa nền tảng trước khi publish.
- Duy trì nhịp release đều đặn ngay cả khi PR volume cao.
## Chu kỳ tiêu chuẩn
- Release patch/minor: hàng tuần hoặc hai tuần một lần.
- Bản vá bảo mật khẩn cấp: out-of-band.
- Không bao giờ chờ tích lũy quá nhiều commit lớn.
## Hợp đồng workflow
Automation release nằm tại:
- `.github/workflows/pub-release.yml`
- `.github/workflows/pub-homebrew-core.yml` (PR formula Homebrew thủ công, do bot sở hữu)
Các chế độ:
- Tag push `v*`: chế độ publish.
- Manual dispatch: chế độ chỉ xác minh hoặc publish.
- Lịch hàng tuần: chế độ chỉ xác minh.
Các guardrail ở chế độ publish:
- Tag phải khớp định dạng semver-like `vX.Y.Z[-suffix]`.
- Tag phải đã tồn tại trên origin.
- Commit của tag phải có thể truy vết được từ `origin/master`.
- GHCR image tag tương ứng (`ghcr.io/<owner>/<repo>:<tag>`) phải sẵn sàng trước khi GitHub Release publish hoàn tất.
- Artifact được xác minh trước khi publish.
## Quy trình maintainer
### 1) Preflight trên `master`
1. Đảm bảo các required check đều xanh trên `master` mới nhất.
2. Xác nhận không có sự cố ưu tiên cao hoặc regression đã biết nào đang mở.
3. Xác nhận các workflow installer và Docker đều khoẻ mạnh trên các commit `master` gần đây.
### 2) Chạy verification build (không publish)
Chạy `Pub Release` thủ công:
- `publish_release`: `false`
- `release_ref`: `master`
Kết quả mong đợi:
- Ma trận target đầy đủ build thành công.
- `verify-artifacts` xác nhận tất cả archive mong đợi đều tồn tại.
- Không có GitHub Release nào được publish.
### 3) Cut release tag
Từ một checkout cục bộ sạch đã sync với `origin/master`:
```bash
scripts/release/cut_release_tag.sh vX.Y.Z --push
```
Script này đảm bảo:
- working tree sạch
- `HEAD == origin/master`
- tag không bị trùng lặp
- định dạng tag semver-like
### 4) Theo dõi publish run
Sau khi push tag, theo dõi:
1. Chế độ publish `Pub Release`
2. Job publish `Pub Docker Img`
Kết quả publish mong đợi:
- release archive
- `SHA256SUMS`
- SBOM `CycloneDX``SPDX`
- chữ ký/chứng chỉ cosign
- GitHub Release notes + asset
### 5) Xác minh sau release
1. Xác minh GitHub Release asset có thể tải xuống.
2. Xác minh GHCR tag cho phiên bản đã release (`vX.Y.Z`) và tag SHA commit release (`sha-<12>`).
3. Xác minh các đường dẫn cài đặt phụ thuộc vào release asset (ví dụ tải xuống binary bootstrap).
### 6) Publish formula Homebrew Core (do bot sở hữu)
Chạy `Pub Homebrew Core` thủ công:
- `release_tag`: `vX.Y.Z`
- `dry_run`: `true` trước, sau đó `false`
Cài đặt repository bắt buộc cho non-dry-run:
- secret: `HOMEBREW_CORE_BOT_TOKEN` (token từ tài khoản bot chuyên dụng, không phải tài khoản maintainer cá nhân)
- variable: `HOMEBREW_CORE_BOT_FORK_REPO` (ví dụ `zeroclaw-release-bot/homebrew-core`)
- variable tùy chọn: `HOMEBREW_CORE_BOT_EMAIL`
Các guardrail workflow:
- release tag phải khớp version `Cargo.toml`
- URL nguồn và SHA256 của formula được cập nhật từ tagged tarball
- license formula được chuẩn hóa thành `Apache-2.0 OR MIT`
- PR được mở từ bot fork vào `Homebrew/homebrew-core:master`
## Đường dẫn khẩn cấp / khôi phục
Nếu release push tag thất bại sau khi artifact đã được xác minh:
1. Sửa vấn đề workflow hoặc packaging trên `master`.
2. Chạy lại `Pub Release` thủ công ở chế độ publish với:
- `publish_release=true`
- `release_tag=<existing tag>`
- `release_ref` tự động được pin vào `release_tag` ở chế độ publish
3. Xác minh lại asset đã release.
## Ghi chú vận hành
- Giữ các thay đổi release nhỏ và có thể đảo ngược.
- Dùng một issue/checklist release cho mỗi phiên bản để bàn giao rõ ràng.
- Tránh publish từ các feature branch ad-hoc.
-109
View File
@@ -1,109 +0,0 @@
# Giới hạn tài nguyên
> ⚠️ **Trạng thái: Đề xuất / Lộ trình**
>
> Tài liệu này mô tả các hướng tiếp cận đề xuất và có thể bao gồm các lệnh hoặc cấu hình giả định.
> Để biết hành vi runtime hiện tại, xem [config-reference.md](config-reference.md), [operations-runbook.md](operations-runbook.md), và [troubleshooting.md](troubleshooting.md).
## Vấn đề
ZeroClaw có rate limiting (20 actions/hour) nhưng chưa có giới hạn tài nguyên. Một agent bị lỗi lặp vòng có thể:
- Làm cạn kiệt bộ nhớ khả dụng
- Quay CPU liên tục ở 100%
- Lấp đầy ổ đĩa bằng log/output
---
## Các giải pháp đề xuất
### Tùy chọn 1: cgroups v2 (Linux, khuyến nghị)
Tự động tạo cgroup cho zeroclaw với các giới hạn.
```bash
# Tạo systemd service với giới hạn
[Service]
MemoryMax=512M
CPUQuota=100%
IOReadBandwidthMax=/dev/sda 10M
IOWriteBandwidthMax=/dev/sda 10M
TasksMax=100
```
### Tùy chọn 2: phát hiện deadlock với tokio::task
Ngăn task starvation.
```rust
use tokio::time::{timeout, Duration};
pub async fn execute_with_timeout<F, T>(
fut: F,
cpu_time_limit: Duration,
memory_limit: usize,
) -> Result<T>
where
F: Future<Output = Result<T>>,
{
// CPU timeout
timeout(cpu_time_limit, fut).await?
}
```
### Tùy chọn 3: memory monitoring
Theo dõi sử dụng heap và kill nếu vượt giới hạn.
```rust
use std::alloc::{GlobalAlloc, Layout, System};
struct LimitedAllocator<A> {
inner: A,
max_bytes: usize,
used: std::sync::atomic::AtomicUsize,
}
unsafe impl<A: GlobalAlloc> GlobalAlloc for LimitedAllocator<A> {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let current = self.used.fetch_add(layout.size(), std::sync::atomic::Ordering::Relaxed);
if current + layout.size() > self.max_bytes {
std::process::abort();
}
self.inner.alloc(layout)
}
}
```
---
## Config schema
```toml
[resources]
# Giới hạn bộ nhớ (tính bằng MB)
max_memory_mb = 512
max_memory_per_command_mb = 128
# Giới hạn CPU
max_cpu_percent = 50
max_cpu_time_seconds = 60
# Giới hạn Disk I/O
max_log_size_mb = 100
max_temp_storage_mb = 500
# Giới hạn process
max_subprocesses = 10
max_open_files = 100
```
---
## Thứ tự triển khai
| Giai đoạn | Tính năng | Công sức | Tác động |
|-------|---------|--------|--------|
| **P0** | Memory monitoring + kill | Thấp | Cao |
| **P1** | CPU timeout mỗi lệnh | Thấp | Cao |
| **P2** | Tích hợp cgroups (Linux) | Trung bình | Rất cao |
| **P3** | Giới hạn Disk I/O | Trung bình | Trung bình |
-191
View File
@@ -1,191 +0,0 @@
# Sổ tay Reviewer
Tài liệu này là người bạn đồng hành vận hành của [`docs/pr-workflow.md`](pr-workflow.md).
Để điều hướng tài liệu rộng hơn, xem [`docs/README.md`](README.md).
## 0. Tóm tắt
- **Mục đích:** định nghĩa mô hình vận hành reviewer mang tính quyết định, duy trì chất lượng review cao khi khối lượng PR lớn.
- **Đối tượng:** maintainer, reviewer và reviewer có hỗ trợ agent.
- **Phạm vi:** triage intake, phân tuyến rủi ro-sang-độ-sâu, kiểm tra review sâu, ghi đè tự động hóa và giao thức bàn giao.
- **Ngoài phạm vi:** thay thế thẩm quyền chính sách PR trong `CONTRIBUTING.md` hoặc thẩm quyền workflow trong các file CI.
---
## 1. Lối tắt theo tình huống review
Dùng phần này để phân tuyến nhanh trước khi đọc chi tiết đầy đủ.
### 1.1 Intake thất bại trong 5 phút đầu
1. Để lại một comment dạng checklist hành động được.
2. Dừng review sâu cho đến khi các vấn đề intake được sửa.
Xem tiếp:
- [Mục 3.1](#31-triage-intake-năm-phút)
### 1.2 Rủi ro cao hoặc không rõ ràng
1. Mặc định coi là `risk: high`.
2. Yêu cầu review sâu và bằng chứng rollback rõ ràng.
Xem tiếp:
- [Mục 2](#2-ma-trận-quyết-định-độ-sâu-review)
- [Mục 3.3](#33-checklist-review-sâu-rủi-ro-cao)
### 1.3 Kết quả tự động hóa sai/ồn ào
1. Áp dụng giao thức ghi đè (`risk: manual`, loại bỏ trùng lặp comment/nhãn).
2. Tiếp tục review với lý do rõ ràng.
Xem tiếp:
- [Mục 5](#5-giao-thức-ghi-đè-tự-động-hóa)
### 1.4 Cần bàn giao review
1. Bàn giao với phạm vi/rủi ro/validation/vấn đề chặn.
2. Giao hành động tiếp theo cụ thể.
Xem tiếp:
- [Mục 6](#6-giao-thức-bàn-giao)
---
## 2. Ma trận quyết định độ sâu review
| Nhãn rủi ro | Đường dẫn thường gặp | Độ sâu review tối thiểu | Bằng chứng bắt buộc |
|---|---|---|---|
| `risk: low` | docs/tests/chore, thay đổi không ảnh hưởng runtime | 1 reviewer + CI gate | validation cục bộ nhất quán + không mơ hồ hành vi |
| `risk: medium` | `src/providers/**`, `src/channels/**`, `src/memory/**`, `src/config/**` | 1 reviewer có hiểu biết về hệ thống con + xác minh hành vi | bằng chứng kịch bản tập trung + tác dụng phụ rõ ràng |
| `risk: high` | `src/security/**`, `src/runtime/**`, `src/gateway/**`, `src/tools/**`, `.github/workflows/**` | triage nhanh + review sâu + sẵn sàng rollback | kiểm tra bảo mật/failure mode + rõ ràng về rollback |
Khi không chắc chắn, coi là `risk: high`.
Nếu việc gán nhãn rủi ro tự động không đúng ngữ cảnh, maintainer có thể áp dụng `risk: manual` và đặt nhãn `risk:*` cuối cùng một cách tường minh.
---
## 3. Quy trình review tiêu chuẩn
### 3.1 Triage intake năm phút
Cho mỗi PR mới:
1. Xác nhận độ đầy đủ template (`summary`, `validation`, `security`, `rollback`).
2. Xác nhận nhãn hiện diện và hợp lý:
- `size:*`, `risk:*`
- nhãn phạm vi (ví dụ `provider`, `channel`, `security`)
- nhãn có phạm vi module (`channel:*`, `provider:*`, `tool:*`)
- nhãn bậc contributor khi áp dụng được
3. Xác nhận trạng thái tín hiệu CI (`CI Required Gate`).
4. Xác nhận phạm vi là một mối quan tâm (từ chối mega-PR hỗn hợp trừ khi có lý do).
5. Xác nhận các yêu cầu tính riêng tư/vệ sinh dữ liệu và diễn đạt test trung lập đã được thỏa mãn.
Nếu bất kỳ yêu cầu intake nào thất bại, để lại một comment dạng checklist hành động được thay vì review sâu.
### 3.2 Checklist fast-lane (tất cả PR)
- Ranh giới phạm vi rõ ràng và đáng tin cậy.
- Các lệnh validation hiện diện và kết quả nhất quán.
- Các thay đổi hành vi hướng người dùng đã được ghi lại.
- Tác giả thể hiện hiểu biết về hành vi và blast radius (đặc biệt với PR có hỗ trợ agent).
- Đường dẫn rollback cụ thể (không chỉ là "revert").
- Tác động tương thích/migration rõ ràng.
- Không có rò rỉ dữ liệu cá nhân/nhạy cảm trong diff artifact; ví dụ/test giữ trung lập và theo phạm vi dự án.
- Nếu có ngôn ngữ giống danh tính, nó sử dụng vai trò gốc ZeroClaw/dự án (không phải danh tính cá nhân hay thực tế).
- Quy ước đặt tên và ranh giới kiến trúc tuân theo hợp đồng dự án (`AGENTS.md`, `CONTRIBUTING.md`).
### 3.3 Checklist review sâu (rủi ro cao)
Với PR rủi ro cao, xác minh ít nhất một ví dụ cụ thể trong mỗi hạng mục:
- **Ranh giới bảo mật:** hành vi deny-by-default được bảo tồn, không mở rộng phạm vi ngẫu nhiên.
- **Failure mode:** xử lý lỗi rõ ràng và suy giảm an toàn.
- **Ổn định hợp đồng:** tương thích CLI/config/API được bảo tồn hoặc migration được ghi lại.
- **Observability:** lỗi có thể chẩn đoán mà không rò rỉ secret.
- **An toàn rollback:** đường dẫn revert và blast radius rõ ràng.
### 3.4 Phong cách kết quả comment review
Ưu tiên comment dạng checklist với một kết quả rõ ràng:
- **Sẵn sàng merge** (giải thích lý do).
- **Cần tác giả hành động** (danh sách vấn đề chặn có thứ tự).
- **Cần review bảo mật/runtime sâu hơn** (nêu rõ rủi ro và bằng chứng yêu cầu).
Tránh comment mơ hồ tạo ra độ trễ qua lại không cần thiết.
---
## 4. Triage issue và quản trị backlog
### 4.1 Sổ tay nhãn triage issue
Dùng nhãn để giữ backlog có thể hành động:
- `r:needs-repro` cho báo cáo lỗi chưa đầy đủ.
- `r:support` cho câu hỏi sử dụng/hỗ trợ nên chuyển hướng ngoài bug backlog.
- `duplicate` / `invalid` cho trùng lặp/nhiễu không thể hành động.
- `no-stale` cho công việc đã được chấp nhận đang chờ vấn đề chặn bên ngoài.
- Yêu cầu biên tập khi log/payload chứa định danh cá nhân hoặc dữ liệu nhạy cảm.
### 4.2 Giao thức cắt tỉa backlog PR
Khi nhu cầu review vượt quá năng lực, áp dụng thứ tự này:
1. Giữ PR bug/security đang hoạt động (`size: XS/S`) ở đầu hàng đợi.
2. Yêu cầu các PR chồng chéo hợp nhất; đóng các PR cũ hơn là `superseded` sau khi xác nhận.
3. Đánh dấu PR ngủ đông là `stale-candidate` trước khi cửa sổ đóng stale bắt đầu.
4. Yêu cầu rebase + validation mới trước khi mở lại công việc kỹ thuật stale/superseded.
---
## 5. Giao thức ghi đè tự động hóa
Dùng khi kết quả tự động hóa tạo ra tác dụng phụ cho review:
1. **Nhãn rủi ro sai:** thêm `risk: manual`, rồi đặt nhãn `risk:*` mong muốn.
2. **Tự đóng sai trên triage issue:** mở lại issue, xóa nhãn route, để lại một comment làm rõ.
3. **Spam/nhiễu nhãn:** giữ một comment maintainer chuẩn tắc và xóa nhãn route dư thừa.
4. **Phạm vi PR mơ hồ:** yêu cầu chia nhỏ trước khi review sâu.
---
## 6. Giao thức bàn giao
Nếu bàn giao review cho maintainer/agent khác, bao gồm:
1. Tóm tắt phạm vi.
2. Phân loại rủi ro hiện tại và lý do.
3. Những gì đã được validate.
4. Các vấn đề chặn mở.
5. Hành động tiếp theo được đề xuất.
---
## 7. Vệ sinh hàng đợi hàng tuần
- Review hàng đợi stale và chỉ áp dụng `no-stale` cho công việc đã được chấp nhận nhưng bị chặn.
- Ưu tiên PR bug/security `size: XS/S` trước.
- Chuyển đổi các issue hỗ trợ tái diễn thành cập nhật tài liệu và hướng dẫn auto-response.
---
## 8. Tài liệu liên quan
- [README.md](README.md) — phân loại và điều hướng tài liệu.
- [pr-workflow.md](pr-workflow.md) — workflow quản trị và hợp đồng merge.
- [ci-map.md](ci-map.md) — bản đồ quyền sở hữu và triage CI.
- [actions-source-policy.md](actions-source-policy.md) — chính sách allowlist nguồn action.
---
## 9. Ghi chú bảo trì
- **Chủ sở hữu:** các maintainer chịu trách nhiệm về chất lượng review và thông lượng hàng đợi.
- **Kích hoạt cập nhật:** thay đổi chính sách PR, thay đổi mô hình phân tuyến rủi ro hoặc thay đổi hành vi ghi đè tự động hóa.
- **Lần review cuối:** 2026-02-18.
-200
View File
@@ -1,200 +0,0 @@
# Chiến lược sandboxing
> ⚠️ **Trạng thái: Đề xuất / Lộ trình**
>
> Tài liệu này mô tả các hướng tiếp cận đề xuất và có thể bao gồm các lệnh hoặc cấu hình giả định.
> Để biết hành vi runtime hiện tại, xem [config-reference.md](config-reference.md), [operations-runbook.md](operations-runbook.md), và [troubleshooting.md](troubleshooting.md).
## Vấn đề
ZeroClaw hiện có application-layer security (allowlists, path blocking, command injection protection) nhưng thiếu cơ chế cách ly cấp hệ điều hành. Nếu kẻ tấn công nằm trong allowlist, họ có thể chạy bất kỳ lệnh nào được cho phép với quyền của user zeroclaw.
## Các giải pháp đề xuất
### Tùy chọn 1: tích hợp Firejail (khuyến nghị cho Linux)
Firejail cung cấp sandboxing ở user-space với overhead tối thiểu.
```rust
// src/security/firejail.rs
use std::process::Command;
pub struct FirejailSandbox {
enabled: bool,
}
impl FirejailSandbox {
pub fn new() -> Self {
let enabled = which::which("firejail").is_ok();
Self { enabled }
}
pub fn wrap_command(&self, cmd: &mut Command) -> &mut Command {
if !self.enabled {
return cmd;
}
// Firejail bọc bất kỳ lệnh nào với sandboxing
let mut jail = Command::new("firejail");
jail.args([
"--private=home", // Thư mục home mới
"--private-dev", // /dev tối giản
"--nosound", // Không âm thanh
"--no3d", // Không tăng tốc 3D
"--novideo", // Không thiết bị video
"--nowheel", // Không thiết bị nhập liệu
"--notv", // Không thiết bị TV
"--noprofile", // Bỏ qua tải profile
"--quiet", // Tắt cảnh báo
]);
// Gắn thêm lệnh gốc
if let Some(program) = cmd.get_program().to_str() {
jail.arg(program);
}
for arg in cmd.get_args() {
if let Some(s) = arg.to_str() {
jail.arg(s);
}
}
// Thay thế lệnh gốc bằng firejail wrapper
*cmd = jail;
cmd
}
}
```
**Tùy chọn config:**
```toml
[security]
enable_sandbox = true
sandbox_backend = "firejail" # hoặc "none", "bubblewrap", "docker"
```
---
### Tùy chọn 2: Bubblewrap (di động, không cần root)
Bubblewrap dùng user namespaces để tạo container.
```bash
# Cài bubblewrap
sudo apt install bubblewrap
# Bọc lệnh:
bwrap --ro-bind /usr /usr \
--dev /dev \
--proc /proc \
--bind /workspace /workspace \
--unshare-all \
--share-net \
--die-with-parent \
-- /bin/sh -c "command"
```
---
### Tùy chọn 3: Docker-in-Docker (nặng nhưng cách ly hoàn toàn)
Chạy các công cụ agent trong container tạm thời.
```rust
pub struct DockerSandbox {
image: String,
}
impl DockerSandbox {
pub async fn execute(&self, command: &str, workspace: &Path) -> Result<String> {
let output = Command::new("docker")
.args([
"run", "--rm",
"--memory", "512m",
"--cpus", "1.0",
"--network", "none",
"--volume", &format!("{}:/workspace", workspace.display()),
&self.image,
"sh", "-c", command
])
.output()
.await?;
Ok(String::from_utf8_lossy(&output.stdout).to_string())
}
}
```
---
### Tùy chọn 4: Landlock (Linux kernel LSM, Rust native)
Landlock cung cấp kiểm soát truy cập hệ thống file mà không cần container.
```rust
use landlock::{Ruleset, AccessFS};
pub fn apply_landlock() -> Result<()> {
let ruleset = Ruleset::new()
.set_access_fs(AccessFS::read_file | AccessFS::write_file)
.add_path(Path::new("/workspace"), AccessFS::read_file | AccessFS::write_file)?
.add_path(Path::new("/tmp"), AccessFS::read_file | AccessFS::write_file)?
.restrict_self()?;
Ok(())
}
```
---
## Thứ tự triển khai ưu tiên
| Giai đoạn | Giải pháp | Công sức | Tăng cường bảo mật |
|-------|----------|--------|---------------|
| **P0** | Landlock (chỉ Linux, native) | Thấp | Cao (filesystem) |
| **P1** | Tích hợp Firejail | Thấp | Rất cao |
| **P2** | Bubblewrap wrapper | Trung bình | Rất cao |
| **P3** | Docker sandbox mode | Cao | Hoàn toàn |
## Mở rộng config schema
```toml
[security.sandbox]
enabled = true
backend = "auto" # auto | firejail | bubblewrap | landlock | docker | none
# Dành riêng cho Firejail
[security.sandbox.firejail]
extra_args = ["--seccomp", "--caps.drop=all"]
# Dành riêng cho Landlock
[security.sandbox.landlock]
readonly_paths = ["/usr", "/bin", "/lib"]
readwrite_paths = ["$HOME/workspace", "/tmp/zeroclaw"]
```
## Chiến lược kiểm thử
```rust
#[cfg(test)]
mod tests {
#[test]
fn sandbox_blocks_path_traversal() {
// Thử đọc /etc/passwd qua sandbox
let result = sandboxed_execute("cat /etc/passwd");
assert!(result.is_err());
}
#[test]
fn sandbox_allows_workspace_access() {
let result = sandboxed_execute("ls /workspace");
assert!(result.is_ok());
}
#[test]
fn sandbox_no_network_isolation() {
// Đảm bảo mạng bị chặn khi được cấu hình
let result = sandboxed_execute("curl http://example.com");
assert!(result.is_err());
}
}
```
-188
View File
@@ -1,188 +0,0 @@
# Lộ trình cải tiến bảo mật
> ⚠️ **Trạng thái: Đề xuất / Lộ trình**
>
> Tài liệu này mô tả các hướng tiếp cận đề xuất và có thể bao gồm các lệnh hoặc cấu hình giả định.
> Để biết hành vi runtime hiện tại, xem [config-reference.md](config-reference.md), [operations-runbook.md](operations-runbook.md), và [troubleshooting.md](troubleshooting.md).
## Tình trạng bảo mật hiện tại: nền tảng vững chắc
ZeroClaw đã có **application-layer security xuất sắc**:
✅ Command allowlist (không phải blocklist)
✅ Bảo vệ path traversal
✅ Chặn command injection (`$(...)`, backticks, `&&`, `>`)
✅ Cách ly secret (API key không bị rò rỉ ra shell)
✅ Rate limiting (20 actions/hour)
✅ Channel authorization (rỗng = từ chối tất cả, `*` = cho phép tất cả)
✅ Phân loại rủi ro (Low/Medium/High)
✅ Làm sạch biến môi trường
✅ Chặn forbidden paths
✅ Độ phủ kiểm thử toàn diện (1.017 test)
## Những gì còn thiếu: cách ly cấp hệ điều hành
🔴 Chưa có sandboxing cấp OS (chroot, containers, namespaces)
🔴 Chưa có giới hạn tài nguyên (giới hạn CPU, memory, disk I/O)
🔴 Chưa có audit logging chống giả mạo
🔴 Chưa có syscall filtering (seccomp)
---
## So sánh: ZeroClaw vs PicoClaw vs production grade
| Tính năng | PicoClaw | ZeroClaw hiện tại | ZeroClaw + lộ trình | Mục tiêu production |
|---------|----------|--------------|-------------------|-------------------|
| **Kích thước binary** | ~8MB | **3.4MB** ✅ | 3.5-4MB | < 5MB |
| **RAM** | < 10MB | **< 5MB** ✅ | < 10MB | < 20MB |
| **Thời gian startup** | < 1s | **< 10ms** ✅ | < 50ms | < 100ms |
| **Command allowlist** | Không rõ | ✅ Có | ✅ Có | ✅ Có |
| **Path blocking** | Không rõ | ✅ Có | ✅ Có | ✅ Có |
| **Injection protection** | Không rõ | ✅ Có | ✅ Có | ✅ Có |
| **OS sandbox** | Không | ❌ Không | ✅ Firejail/Landlock | ✅ Container/namespaces |
| **Resource limits** | Không | ❌ Không | ✅ cgroups/Monitor | ✅ Full cgroups |
| **Audit logging** | Không | ❌ Không | ✅ Ký HMAC | ✅ Tích hợp SIEM |
| **Điểm bảo mật** | C | **B+** | **A-** | **A+** |
---
## Lộ trình triển khai
### Giai đoạn 1: kết quả nhanh (1-2 tuần)
**Mục tiêu**: giải quyết các thiếu sót nghiêm trọng với độ phức tạp tối thiểu
| Nhiệm vụ | File | Công sức | Tác động |
|------|------|--------|-------|
| Landlock filesystem sandbox | `src/security/landlock.rs` | 2 ngày | Cao |
| Memory monitoring + OOM kill | `src/resources/memory.rs` | 1 ngày | Cao |
| CPU timeout mỗi lệnh | `src/tools/shell.rs` | 1 ngày | Cao |
| Audit logging cơ bản | `src/security/audit.rs` | 2 ngày | Trung bình |
| Cập nhật config schema | `src/config/schema.rs` | 1 ngày | - |
**Kết quả bàn giao**:
- Linux: truy cập filesystem bị giới hạn trong workspace
- Tất cả nền tảng: bảo vệ memory/CPU chống lệnh chạy vô hạn
- Tất cả nền tảng: audit trail chống giả mạo
---
### Giai đoạn 2: tích hợp nền tảng (2-3 tuần)
**Mục tiêu**: tích hợp sâu với OS để cách ly cấp production
| Nhiệm vụ | Công sức | Tác động |
|------|--------|-------|
| Tự phát hiện Firejail + wrapping | 3 ngày | Rất cao |
| Bubblewrap wrapper cho macOS/*nix | 4 ngày | Rất cao |
| Tích hợp cgroups v2 systemd | 3 ngày | Cao |
| Syscall filtering với seccomp | 5 ngày | Cao |
| Audit log query CLI | 2 ngày | Trung bình |
**Kết quả bàn giao**:
- Linux: cách ly hoàn toàn như container qua Firejail
- macOS: cách ly filesystem với Bubblewrap
- Linux: thực thi giới hạn tài nguyên qua cgroups
- Linux: allowlist syscall
---
### Giai đoạn 3: hardening production (1-2 tuần)
**Mục tiêu**: các tính năng bảo mật doanh nghiệp
| Nhiệm vụ | Công sức | Tác động |
|------|--------|-------|
| Docker sandbox mode | 3 ngày | Cao |
| Certificate pinning cho channels | 2 ngày | Trung bình |
| Xác minh config đã ký | 2 ngày | Trung bình |
| Xuất audit tương thích SIEM | 2 ngày | Trung bình |
| Tự kiểm tra bảo mật (`zeroclaw audit --check`) | 1 ngày | Thấp |
**Kết quả bàn giao**:
- Tùy chọn cách ly thực thi dựa trên Docker
- HTTPS certificate pinning cho channel webhooks
- Xác minh chữ ký file config
- Xuất audit JSON/CSV cho phân tích ngoài
---
## Xem trước config schema mới
```toml
[security]
level = "strict" # relaxed | default | strict | paranoid
# Cấu hình sandbox
[security.sandbox]
enabled = true
backend = "auto" # auto | firejail | bubblewrap | landlock | docker | none
# Giới hạn tài nguyên
[resources]
max_memory_mb = 512
max_memory_per_command_mb = 128
max_cpu_percent = 50
max_cpu_time_seconds = 60
max_subprocesses = 10
# Audit logging
[security.audit]
enabled = true
log_path = "~/.config/zeroclaw/audit.log"
sign_events = true
max_size_mb = 100
# Autonomy (hiện có, được cải thiện)
[autonomy]
level = "supervised" # readonly | supervised | full
allowed_commands = ["git", "ls", "cat", "grep", "find"]
forbidden_paths = ["/etc", "/root", "~/.ssh"]
require_approval_for_medium_risk = true
block_high_risk_commands = true
max_actions_per_hour = 20
```
---
## Xem trước lệnh CLI
```bash
# Kiểm tra trạng thái bảo mật
zeroclaw security --check
# → ✓ Sandbox: Firejail active
# → ✓ Audit logging enabled (42 events today)
# → → Resource limits: 512MB mem, 50% CPU
# Truy vấn audit log
zeroclaw audit --user @alice --since 24h
zeroclaw audit --risk high --violations-only
zeroclaw audit --verify-signatures
# Kiểm tra sandbox
zeroclaw sandbox --test
# → Testing isolation...
# ✓ Cannot read /etc/passwd
# ✓ Cannot access ~/.ssh
# ✓ Can read /workspace
```
---
## Tóm tắt
**ZeroClaw đã an toàn hơn PicoClaw** với:
- Binary nhỏ hơn 50% (3.4MB so với 8MB)
- RAM ít hơn 50% (< 5MB so với < 10MB)
- Startup nhanh hơn 100 lần (< 10ms so với < 1s)
- Policy engine bảo mật toàn diện
- Độ phủ kiểm thử rộng
**Khi triển khai lộ trình này**, ZeroClaw sẽ trở thành:
- Cấp production với OS-level sandboxing
- Nhận biết tài nguyên với bảo vệ memory/CPU
- Sẵn sàng audit với logging chống giả mạo
- Sẵn sàng doanh nghiệp với các cấp độ bảo mật có thể cấu hình
**Công sức ước tính**: 4-7 tuần để triển khai đầy đủ
**Giá trị**: biến ZeroClaw từ "an toàn để kiểm thử" thành "an toàn cho production"
-22
View File
@@ -1,22 +0,0 @@
# Tài liệu bảo mật
Hướng dẫn bảo mật hiện tại và đề xuất cải tiến.
## Hành vi hiện tại trước tiên
Để biết hành vi runtime hiện tại, bắt đầu tại đây:
- Tham chiếu config: [../config-reference.md](../config-reference.md)
- Sổ tay vận hành: [../operations-runbook.md](../operations-runbook.md)
- Xử lý sự cố: [../troubleshooting.md](../troubleshooting.md)
## Tài liệu đề xuất / Lộ trình
Các tài liệu sau theo định hướng đề xuất rõ ràng và có thể bao gồm các ví dụ CLI/config chưa triển khai:
- [../agnostic-security.md](../agnostic-security.md)
- [../frictionless-security.md](../frictionless-security.md)
- [../sandboxing.md](../sandboxing.md)
- [../resource-limits.md](../resource-limits.md)
- [../audit-logging.md](../audit-logging.md)
- [../security-roadmap.md](../security-roadmap.md)
-236
View File
@@ -1,236 +0,0 @@
# Khắc phục sự cố ZeroClaw
Các lỗi thường gặp khi cài đặt và chạy, kèm cách khắc phục.
Xác minh lần cuối: **2026-02-20**.
## Cài đặt / Bootstrap
### Không tìm thấy `cargo`
Triệu chứng:
- bootstrap thoát với lỗi `cargo is not installed`
Khắc phục:
```bash
./install.sh --install-rust
```
Hoặc cài từ <https://rustup.rs/>.
### Thiếu thư viện hệ thống để build
Triệu chứng:
- build thất bại do lỗi trình biên dịch hoặc `pkg-config`
Khắc phục:
```bash
./install.sh --install-system-deps
```
### Build thất bại trên máy ít RAM / ít dung lượng
Triệu chứng:
- `cargo build --release` bị kill (`signal: 9`, OOM killer, hoặc `cannot allocate memory`)
- Build vẫn lỗi sau khi thêm swap vì hết dung lượng ổ đĩa
Nguyên nhân:
- RAM lúc chạy (<5MB) khác xa RAM lúc biên dịch.
- Build đầy đủ từ mã nguồn có thể cần **2 GB RAM + swap****6+ GB dung lượng trống**.
- Bật swap trên ổ nhỏ có thể tránh OOM RAM nhưng vẫn lỗi vì hết dung lượng.
Cách tốt nhất cho máy hạn chế tài nguyên:
```bash
./install.sh --prefer-prebuilt
```
Chế độ chỉ dùng binary (không build từ nguồn):
```bash
./install.sh --prebuilt-only
```
Nếu bắt buộc phải build từ nguồn trên máy yếu:
1. Chỉ thêm swap nếu còn đủ dung lượng cho cả swap lẫn kết quả build.
1. Giới hạn số luồng build:
```bash
CARGO_BUILD_JOBS=1 cargo build --release --locked
```
1. Bỏ bớt feature nặng khi không cần Matrix:
```bash
cargo build --release --locked --no-default-features --features hardware
```
1. Cross-compile trên máy mạnh hơn rồi copy binary sang máy đích.
### Build rất chậm hoặc có vẻ bị treo
Triệu chứng:
- `cargo check` / `cargo build` dừng lâu ở `Checking zeroclaw`
- Lặp lại thông báo `Blocking waiting for file lock on package cache` hoặc `build directory`
Nguyên nhân:
- Thư viện Matrix E2EE (`matrix-sdk`, `ruma`, `vodozemac`) lớn và tốn thời gian kiểm tra kiểu.
- TLS + crypto native build script (`aws-lc-sys`, `ring`) tăng thời gian biên dịch đáng kể.
- `rusqlite` với SQLite tích hợp biên dịch mã C cục bộ.
- Chạy nhiều cargo job/worktree song song gây tranh chấp file lock.
Kiểm tra nhanh:
```bash
cargo check --timings
cargo tree -d
```
Báo cáo thời gian được ghi tại `target/cargo-timings/cargo-timing.html`.
Lặp nhanh hơn khi không cần kênh Matrix:
```bash
cargo check --no-default-features --features hardware
```
Lệnh này bỏ qua `channel-matrix` và giảm đáng kể thời gian biên dịch.
Build với Matrix:
```bash
cargo check --no-default-features --features hardware,channel-matrix
```
Giảm tranh chấp lock:
```bash
pgrep -af "cargo (check|build|test)|cargo check|cargo build|cargo test"
```
Dừng các cargo job không liên quan trước khi build.
### Không tìm thấy lệnh `zeroclaw` sau cài đặt
Triệu chứng:
- Cài đặt thành công nhưng shell không tìm thấy `zeroclaw`
Khắc phục:
```bash
export PATH="$HOME/.cargo/bin:$PATH"
which zeroclaw
```
Thêm vào shell profile nếu cần giữ lâu dài.
## Runtime / Gateway
### Không kết nối được gateway
Kiểm tra:
```bash
zeroclaw status
zeroclaw doctor
```
Xác minh `~/.zeroclaw/config.toml`:
- `[gateway].host` (mặc định `127.0.0.1`)
- `[gateway].port` (mặc định `3000`)
- `allow_public_bind` chỉ bật khi cố ý mở truy cập LAN/public
### Lỗi ghép nối / xác thực webhook
Kiểm tra:
1. Đảm bảo đã hoàn tất ghép nối (luồng `/pair`)
2. Đảm bảo bearer token còn hiệu lực
3. Chạy lại chẩn đoán:
```bash
zeroclaw doctor
```
## Sự cố kênh
### Telegram xung đột: `terminated by other getUpdates request`
Nguyên nhân:
- Nhiều poller dùng chung bot token
Khắc phục:
- Chỉ giữ một runtime đang chạy cho token đó
- Dừng các tiến trình `zeroclaw daemon` / `zeroclaw channel start` thừa
### Kênh không khỏe trong `channel doctor`
Kiểm tra:
```bash
zeroclaw channel doctor
```
Sau đó xác minh thông tin xác thực và trường allowlist cho từng kênh trong config.
## Chế độ dịch vụ
### Dịch vụ đã cài nhưng không chạy
Kiểm tra:
```bash
zeroclaw service status
```
Khôi phục:
```bash
zeroclaw service stop
zeroclaw service start
```
Xem log trên Linux:
```bash
journalctl --user -u zeroclaw.service -f
```
## URL cài đặt
```bash
curl -fsSL https://raw.githubusercontent.com/zeroclaw-labs/zeroclaw/master/install.sh | bash
```
## Vẫn chưa giải quyết được?
Thu thập và đính kèm các thông tin sau khi tạo issue:
```bash
zeroclaw --version
zeroclaw status
zeroclaw doctor
zeroclaw channel doctor
```
Kèm thêm: hệ điều hành, cách cài đặt, và đoạn config đã ẩn bí mật.
## Tài liệu liên quan
- [operations-runbook.md](operations-runbook.md)
- [one-click-bootstrap.md](one-click-bootstrap.md)
- [channels-reference.md](channels-reference.md)
- [network-deployment.md](network-deployment.md)
-142
View File
@@ -1,142 +0,0 @@
# Thiết lập Z.AI GLM
ZeroClaw hỗ trợ các model GLM của Z.AI thông qua các endpoint tương thích OpenAI.
Hướng dẫn cấu hình thực tế theo provider hiện tại của ZeroClaw.
## Tổng quan
ZeroClaw hỗ trợ sẵn các alias và endpoint Z.AI sau đây:
| Alias | Endpoint | Ghi chú |
|-------|----------|---------|
| `zai` | `https://api.z.ai/api/coding/paas/v4` | Endpoint toàn cầu |
| `zai-cn` | `https://open.bigmodel.cn/api/paas/v4` | Endpoint Trung Quốc |
Nếu bạn cần base URL tùy chỉnh, xem `docs/custom-providers.md`.
## Thiết lập
### Bắt đầu nhanh
```bash
zeroclaw onboard \
--provider "zai" \
--api-key "YOUR_ZAI_API_KEY"
```
### Cấu hình thủ công
Chỉnh sửa `~/.zeroclaw/config.toml`:
```toml
api_key = "YOUR_ZAI_API_KEY"
default_provider = "zai"
default_model = "glm-5"
default_temperature = 0.7
```
## Các model hiện có
| Model | Mô tả |
|-------|-------|
| `glm-5` | Mặc định khi onboarding; khả năng suy luận mạnh nhất |
| `glm-4.7` | Chất lượng đa năng cao |
| `glm-4.6` | Mức cơ bản cân bằng |
| `glm-4.5-air` | Tùy chọn độ trễ thấp hơn |
Khả năng khả dụng của model có thể thay đổi theo tài khoản/khu vực, hãy dùng API `/models` khi không chắc chắn.
## Xác minh thiết lập
### Kiểm tra bằng curl
```bash
# Test OpenAI-compatible endpoint
curl -X POST "https://api.z.ai/api/coding/paas/v4/chat/completions" \
-H "Authorization: Bearer YOUR_ZAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5",
"messages": [{"role": "user", "content": "Hello"}]
}'
```
Phản hồi mong đợi:
```json
{
"choices": [{
"message": {
"content": "Hello! How can I help you today?",
"role": "assistant"
}
}]
}
```
### Kiểm tra bằng ZeroClaw CLI
```bash
# Test agent directly
echo "Hello" | zeroclaw agent
# Check status
zeroclaw status
```
## Biến môi trường
Thêm vào file `.env` của bạn:
```bash
# Z.AI API Key
ZAI_API_KEY=your-id.secret
# Optional generic key (used by many providers)
# API_KEY=your-id.secret
```
Định dạng key là `id.secret` (ví dụ: `abc123.xyz789`).
## Xử lý sự cố
### Rate Limiting
**Triệu chứng:** Lỗi `rate_limited`
**Giải pháp:**
- Chờ và thử lại
- Kiểm tra giới hạn gói Z.AI của bạn
- Thử `glm-4.5-air` để có độ trễ thấp hơn và khả năng chịu đựng quota cao hơn
### Lỗi xác thực
**Triệu chứng:** Lỗi 401 hoặc 403
**Giải pháp:**
- Xác minh định dạng API key là `id.secret`
- Kiểm tra key chưa hết hạn
- Đảm bảo không có khoảng trắng thừa trong key
### Model không tìm thấy
**Triệu chứng:** Lỗi model không khả dụng
**Giải pháp:**
- Liệt kê các model có sẵn:
```bash
curl -s "https://api.z.ai/api/coding/paas/v4/models" \
-H "Authorization: Bearer YOUR_ZAI_API_KEY" | jq '.data[].id'
```
## Lấy API Key
1. Truy cập [Z.AI](https://z.ai)
2. Đăng ký Coding Plan
3. Tạo API key từ dashboard
4. Định dạng key: `id.secret` (ví dụ: `abc123.xyz789`)
## Tài liệu liên quan
- [ZeroClaw README](README.md)
- [Custom Provider Endpoints](./custom-providers.md)
- [Contributing Guide](../../../CONTRIBUTING.md)
+73
View File
@@ -0,0 +1,73 @@
# OpenAI Temperature Compatibility Reference
This document provides empirical evidence for temperature parameter compatibility across OpenAI models.
## Summary
Different OpenAI model families have different temperature requirements:
- **Reasoning models** (o-series, gpt-5 base variants): Only accept `temperature=1.0`
- **Search models**: Do not accept temperature parameter (must be omitted)
- **Standard models** (gpt-3.5, gpt-4, gpt-4o): Accept flexible temperature values (0.0-2.0)
## Tested Models
### Models Requiring temperature=1.0
| Model | Accepts 0.7 | Accepts 1.0 | Recommendation |
|-------|-------------|-------------|----------------|
| o1 | ❌ | ✅ | USE_1.0 |
| o1-2024-12-17 | ❌ | ✅ | USE_1.0 |
| o3 | ❌ | ✅ | USE_1.0 |
| o3-2025-04-16 | ❌ | ✅ | USE_1.0 |
| o3-mini | ❌ | ✅ | USE_1.0 |
| o3-mini-2025-01-31 | ❌ | ✅ | USE_1.0 |
| o4-mini | ❌ | ✅ | USE_1.0 |
| o4-mini-2025-04-16 | ❌ | ✅ | USE_1.0 |
| gpt-5 | ❌ | ✅ | USE_1.0 |
| gpt-5-2025-08-07 | ❌ | ✅ | USE_1.0 |
| gpt-5-mini | ❌ | ✅ | USE_1.0 |
| gpt-5-mini-2025-08-07 | ❌ | ✅ | USE_1.0 |
| gpt-5-nano | ❌ | ✅ | USE_1.0 |
| gpt-5-nano-2025-08-07 | ❌ | ✅ | USE_1.0 |
| gpt-5.1-chat-latest | ❌ | ✅ | USE_1.0 |
| gpt-5.2-chat-latest | ❌ | ✅ | USE_1.0 |
| gpt-5.3-chat-latest | ❌ | ✅ | USE_1.0 |
### Models Accepting Flexible Temperature (0.7 works)
All standard GPT models accept flexible temperature values:
- gpt-3.5-turbo (all variants)
- gpt-4 (all variants)
- gpt-4-turbo (all variants)
- gpt-4o (all variants)
- gpt-4o-mini (all variants)
- gpt-4.1 (all variants)
- gpt-5-chat-latest
- gpt-5.2, gpt-5.2-2025-12-11
- gpt-5.4, gpt-5.4-2026-03-05
### Models Requiring Temperature Omission
Search-preview models do not accept temperature parameter:
- gpt-4o-mini-search-preview
- gpt-4o-search-preview
- gpt-5-search-api
## Implementation
The `adjust_temperature_for_model()` function in `src/providers/openai.rs` automatically adjusts temperature to 1.0 for reasoning models while preserving user-specified values for standard models.
## Testing Methodology
Models were tested with:
1. No temperature parameter (baseline)
2. temperature=0.7 (common default)
3. temperature=1.0 (reasoning model requirement)
Results were validated against actual OpenAI API responses.
## References
- OpenAI API Documentation: https://platform.openai.com/docs/api-reference/chat
- Related Issue: Temperature errors with o1/o3/gpt-5 models
+58
View File
@@ -22,6 +22,64 @@ For first-time installation, start from [one-click-bootstrap.md](../setup-guides
| Foreground runtime | `zeroclaw daemon` | local debugging, short-lived sessions |
| Foreground gateway only | `zeroclaw gateway` | webhook endpoint testing |
| User service | `zeroclaw service install && zeroclaw service start` | persistent operator-managed runtime |
| Docker / Podman | `docker compose up -d` | containerized deployment |
## Docker / Podman Runtime
If you installed via `./install.sh --docker`, the container exits after onboarding. To run
ZeroClaw as a long-lived container, use the repository `docker-compose.yml` or start a
container manually against the persisted data directory.
### Recommended: docker-compose
```bash
# Start (detached, auto-restarts on reboot)
docker compose up -d
# Stop
docker compose down
# Restart
docker compose up -d
```
Replace `docker` with `podman` if using Podman.
### Manual container lifecycle
```bash
# Start a new container from the bootstrap image
docker run -d --name zeroclaw \
--restart unless-stopped \
-v "$PWD/.zeroclaw-docker/.zeroclaw:/zeroclaw-data/.zeroclaw" \
-v "$PWD/.zeroclaw-docker/workspace:/zeroclaw-data/workspace" \
-e HOME=/zeroclaw-data \
-e ZEROCLAW_WORKSPACE=/zeroclaw-data/workspace \
-p 42617:42617 \
zeroclaw-bootstrap:local \
gateway
# Stop (preserves config and workspace)
docker stop zeroclaw
# Restart a stopped container
docker start zeroclaw
# View logs
docker logs -f zeroclaw
# Health check
docker exec zeroclaw zeroclaw status
```
For Podman, add `--userns keep-id --user "$(id -u):$(id -g)"` and append `:Z` to volume mounts.
### Key detail: do not re-run install.sh to restart
Re-running `install.sh --docker` rebuilds the image and re-runs onboarding. To simply
restart, use `docker start`, `docker compose up -d`, or `podman start`.
For full setup instructions, see [one-click-bootstrap.md](../setup-guides/one-click-bootstrap.md#stopping-and-restarting-a-dockerpodman-container).
## Baseline Operator Checklist
+97
View File
@@ -98,6 +98,103 @@ If you add `--skip-build`, the installer skips local image build. It first tries
Docker tag (`ZEROCLAW_DOCKER_IMAGE`, default: `zeroclaw-bootstrap:local`); if missing,
it pulls `ghcr.io/zeroclaw-labs/zeroclaw:latest` and tags it locally before running.
### Stopping and restarting a Docker/Podman container
After `./install.sh --docker` finishes, the container exits. Your config and workspace
are persisted in the data directory (default: `./.zeroclaw-docker`, or `~/.zeroclaw-docker`
when bootstrapping via `curl | bash`). You can override this path with `ZEROCLAW_DOCKER_DATA_DIR`.
**Do not re-run `install.sh`** to restart -- it will rebuild the image and re-run onboarding.
Instead, start a new container from the existing image and mount the persisted data directory.
#### Using the repository docker-compose.yml
The simplest way to run ZeroClaw long-term in Docker/Podman is with the provided
`docker-compose.yml` at the repository root. It uses a named volume (`zeroclaw-data`)
and sets `restart: unless-stopped` so the container survives reboots.
```bash
# Start (detached)
docker compose up -d
# Stop
docker compose down
# Restart after stopping
docker compose up -d
```
Replace `docker` with `podman` if you use Podman.
#### Manual container run (using install.sh data directory)
If you installed via `./install.sh --docker` and want to reuse the `.zeroclaw-docker`
data directory without compose:
```bash
# Docker
docker run -d --name zeroclaw \
--restart unless-stopped \
-v "$PWD/.zeroclaw-docker/.zeroclaw:/zeroclaw-data/.zeroclaw" \
-v "$PWD/.zeroclaw-docker/workspace:/zeroclaw-data/workspace" \
-e HOME=/zeroclaw-data \
-e ZEROCLAW_WORKSPACE=/zeroclaw-data/workspace \
-p 42617:42617 \
zeroclaw-bootstrap:local \
gateway
# Podman (add --userns keep-id and :Z volume labels)
podman run -d --name zeroclaw \
--restart unless-stopped \
--userns keep-id \
--user "$(id -u):$(id -g)" \
-v "$PWD/.zeroclaw-docker/.zeroclaw:/zeroclaw-data/.zeroclaw:Z" \
-v "$PWD/.zeroclaw-docker/workspace:/zeroclaw-data/workspace:Z" \
-e HOME=/zeroclaw-data \
-e ZEROCLAW_WORKSPACE=/zeroclaw-data/workspace \
-p 42617:42617 \
zeroclaw-bootstrap:local \
gateway
```
#### Common lifecycle commands
```bash
# Stop the container (preserves data)
docker stop zeroclaw
# Start a stopped container (config and workspace are intact)
docker start zeroclaw
# View logs
docker logs -f zeroclaw
# Remove the container (data in volumes/.zeroclaw-docker is preserved)
docker rm zeroclaw
# Check health
docker exec zeroclaw zeroclaw status
```
#### Environment variables
When running manually, pass provider configuration as environment variables
or ensure they are already saved in the persisted `config.toml`:
```bash
docker run -d --name zeroclaw \
-e API_KEY="sk-..." \
-e PROVIDER="openrouter" \
-v "$PWD/.zeroclaw-docker/.zeroclaw:/zeroclaw-data/.zeroclaw" \
-v "$PWD/.zeroclaw-docker/workspace:/zeroclaw-data/workspace" \
-p 42617:42617 \
zeroclaw-bootstrap:local \
gateway
```
If you already ran `onboard` during the initial install, your API key and provider are
saved in `.zeroclaw-docker/.zeroclaw/config.toml` and do not need to be passed again.
### Quick onboarding (non-interactive)
```bash

Some files were not shown because too many files have changed in this diff Show More