Fixes#430 - Prevents duplicate memories after restart by using platform message IDs instead of random UUIDs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use Path::components() to check for actual .. path components instead of
simple string matching (which was too conservative)
- Block URL-encoded traversal attempts (e.g., ..%2f)
- Expand tilde (~) for comparison
- Use path-component-aware matching for forbidden paths
- Update test to allow .. in filenames but block actual path traversal
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add open-skills auto-clone/pull/sync support in skills loader
- Clone https://github.com/besoeasy/open-skills to ~/open-skills
- Weekly sync via .zeroclaw-open-skills-sync marker
- Env controls: ZEROCLAW_OPEN_SKILLS_ENABLED, ZEROCLAW_OPEN_SKILLS_DIR
- Load open-skills markdown files before workspace skills
- Track Skill.location for accurate prompt rendering
- Update system prompt to render skill.location with fallback
- Use actual file path when available
- Maintain backward compatibility with workspace SKILL.md path
- Fix clippy warnings across tests and supporting files
- Readable timestamp literals
- Remove underscore bindings in tests
- Use struct update syntax for Config::default() patterns
- Fix module inception, duplicate attributes, manual strip
- Clean raw string hashes and empty string construction
Resolves: #77
The Docker image uses rust:1.83-slim where is_multiple_of is unstable.
Also regenerates Cargo.lock to include the sha2 dependency.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use bitwise & instead of && to avoid short-circuit timing leak
- Use get().unwrap_or(&0) instead of if/else for branchless byte access
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Check for empty USERNAME env var before running icacls to avoid a
doomed invocation with ":F" grant argument
- Log a clear warning when USERNAME is empty
- Add tracing::debug on successful permission set
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace manual hex encoding loop with `format!("{:x}", Sha256::digest(...))`,
which is more idiomatic and concise.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add missing assertion for variant_match (byte[8] UUID v4 variant bits)
which was computed but never checked.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the early return on length mismatch that leaked length
information via timing. Now iterates over max(a.len(), b.len()),
padding the shorter input with zeros, and checks both byte-level
differences and length equality at the end.
Closes#57
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace silently discarded icacls result with proper error handling
that logs a tracing::warn! on failure. Previously, if icacls failed
(binary not found, permission denied), the key file would remain
world-readable on Windows with no indication of the problem.
Closes#56
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hash paired bearer tokens with SHA-256 before storing in config and
in-memory. When authenticating, hash the incoming token and compare
against stored hashes. Backward compatible: existing plaintext tokens
(zc_ prefix) are detected and hashed on load; already-hashed tokens
(64-char hex) are stored as-is.
Closes#58
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Log full error details server-side with tracing::error! and return
generic messages to clients. Previously, the raw anyhow error chain
(which could include provider URLs, HTTP status codes, or partial
request bodies) was forwarded to end users.
Closes#59
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use ChaCha20Poly1305::generate_key(&mut OsRng) to generate encryption
keys directly from the OS CSPRNG, providing full 256-bit entropy without
the fixed version/variant bits that UUID v4 introduces (6 fixed bits
per 128-bit UUID = only 244 effective bits from two UUIDs).
Closes#54
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add port and host fields to GatewayConfig with defaults (3000, 127.0.0.1)
- Enhanced apply_env_overrides() to support:
- ZEROCLAW_GATEWAY_PORT or PORT - Gateway server port
- ZEROCLAW_GATEWAY_HOST or HOST - Gateway bind address
- ZEROCLAW_TEMPERATURE - Default temperature (0.0-2.0)
- Add comprehensive tests for all new env var overrides
- Fix clippy warnings (is_multiple_of, too_many_lines)
Closes#45
The is_multiple_of is a new, experimental feature introduced to the Rust standard library, but it is not yet stabilized. It requires the nightly compiler to work. Therefore, replacing it with the equivalent modulo operator (%) from stable release.
- Add Windows symlink support in skills/mod.rs with fallback chain:
1. symlink_dir (requires admin/developer mode)
2. mklink /J junction (works without admin)
3. copy_dir_recursive fallback
- Add Windows file permissions in security/secrets.rs using icacls
- Add copy_dir_recursive helper function for non-Unix platforms
Fixes#28