- write config and cron store with 0600 instead of 0644
- check allow list in Slack slash commands and app mentions
- pass workspace restrict flag to cron exec tool
Closes#179
Replace --profile flags with explicit service names in build commands.
The 'docker compose build' command does not support --profile flag;
profiles are only used for runtime operations like 'up' and 'run'.
Changes:
- docker-build: specify picoclaw-agent picoclaw-gateway
- docker-build-full: specify picoclaw-agent picoclaw-gateway
Fixes: unknown flag: --profile error
Add --profile gateway --profile agent flags to docker build commands
to ensure services are built even when using profiles in compose files.
Without profiles specified, docker compose build skips all services
that have a profile defined, resulting in 'No services to build' warning.
Changes:
- docker-build: add --profile flags
- docker-build-full: add --profile flags
Fixes: WARN[0000] No services to build
Fix uv symlink path from /root/.cargo/bin to /root/.local/bin.
The uv installer puts binaries in ~/.local/bin, not ~/.cargo/bin.
Changes:
- Update uv symlink source: /root/.local/bin/uv
- Add uvx symlink as well (installed alongside uv)
Fixes: /bin/sh: 1: uv: not found error during build
Symlink uv from /root/.cargo/bin to /usr/local/bin to make it
accessible without relying on ENV PATH setting. Add version check
to verify successful installation during build.
Changes:
- Symlink uv to /usr/local/bin/uv
- Add 'uv --version' validation step
- Remove ENV PATH setting (no longer needed)
Fixes: uv: not found error in test script
Replace docker-compose (v1) with docker compose (v2) command syntax
across all files. Docker Compose v2 is now the default in modern
Docker installations and uses 'docker compose' instead of 'docker-compose'.
Changes:
- scripts/test-docker-mcp.sh: update all 8 docker-compose commands
- Makefile: update all 8 docker-compose commands in docker-* targets
- No changes to file names (docker-compose.full.yml remains as-is)
Compatibility: Requires Docker with Compose v2 plugin (Docker Desktop
or docker-compose-plugin package)
Add --entrypoint sh flag to docker-compose run commands in test script
to bypass picoclaw agent's interactive mode. This allows direct command
execution for testing MCP tools.
Changes:
- Add --entrypoint sh to all docker-compose run commands
- Use SERVICE variable for better maintainability
- Simplify command syntax: sh -c 'cmd' → -c 'cmd'
This platform has a growing desktop and embedded user base, and is fully
supported by Go. The only necessary change is the mapping between
`uname -m` output and GOARCH.
Due to non-technical reasons [1], there is currently no Docker official
image that provides linux/loong64 support, so Docker-based builds are
not included in this commit for now.
[1]: https://github.com/docker-library/official-images/issues/16404
Add Dockerfile.full with Debian-based runtime including git, nodejs, npm, python3, and uv for MCP servers. Add docker-compose.full.yml with npm cache optimization. Add Makefile targets for docker-build-full, docker-run-full, and docker-test. Add test script for MCP tools validation.
* feat: add Codex CLI provider for OpenAI subprocess integration
Add CodexCliProvider that wraps `codex exec --json` as a subprocess,
analogous to the existing ClaudeCliProvider pattern. This enables using
OpenAI's Codex CLI tool as a local LLM backend.
- CodexCliProvider: subprocess wrapper parsing JSONL event stream
- Credential reader for ~/.codex/auth.json with token expiry detection
- Factory integration: provider "codex-cli" and auth_method "codex-cli"
- Fix tilde expansion in workspace path for CLI providers
- 37 unit tests covering parsing, prompt building, credentials, and mocks
* fix: add tool call extraction to Codex CLI provider
- Extract shared tool call parsing into tool_call_extract.go
(extractToolCallsFromText, stripToolCallsFromText, findMatchingBrace)
- Both ClaudeCliProvider and CodexCliProvider now share the same
tool call extraction logic for PicoClaw-specific tools
- Fix cache token accounting: include cached_input_tokens in total
- Add 2 new tests for tool call extraction from JSONL events
- Update existing tests for corrected token calculations
* fix(docker): update Go version to match go.mod requirement
Dockerfile used golang:1.24-alpine but go.mod requires go >= 1.25.7.
This caused Docker builds to fail on all branches with:
"go: go.mod requires go >= 1.25.7 (running go 1.24.13)"
Update to golang:1.25-alpine to match the project requirement.
* fix: handle codex CLI stderr noise without losing valid stdout
Codex writes diagnostic messages to stderr (e.g. rollout errors) which
cause non-zero exit codes even when valid JSONL output exists on stdout.
Parse stdout first before checking exit code to avoid false errors.
* style: fix gofmt formatting and update web search API in tests
- Remove trailing whitespace in web.go and base_test.go
- Update config_test.go and web_test.go for WebSearchToolOptions API
Add validation logic for SkillInfo to ensure name and description meet requirements
Include test cases covering various validation scenarios
Add testify dependency for testing assertions
Add a new configuration option `exec_timeout_minutes` under the `tools.cron`
section to control the maximum execution time for cron jobs. The default
timeout is set to 5 minutes, which is appropriate for LLM operations.
The configuration can be set in the config file or via the
`PICOCLAW_TOOLS_CRON_EXEC_TIMEOUT_MINUTES` environment variable. A value of
0 disables the timeout entirely.
This change improves system reliability by preventing cron jobs from running
indefinitely in case of unexpected failures or hanging processes.
Implement comprehensive MCP support with stdio/HTTP/SSE transports, environment variable configuration (env and envFile), custom headers, tool registration, and automatic resource cleanup. Includes full test coverage and VSCode-compatible configuration.
- Added pkg/mcp/manager.go for server lifecycle management
- Added pkg/tools/mcp_tool.go for tool wrapping
- Integrated into agent loop with cleanup
- Support for envFile loading (.env format)
- Headers injection for HTTP/SSE authentication
- Example configs for filesystem, github, brave-search, postgres
Fixes four issues identified in the community code review:
- Session persistence broken on Windows: session keys like
"telegram:123456" contain ':', which is illegal in Windows
filenames. filepath.Base() strips drive-letter prefixes on Windows,
causing Save() to silently fail. Added sanitizeFilename() to
replace invalid chars in the filename while keeping the original
key in the JSON payload.
- HTTP client with no timeout: HTTPProvider used Timeout: 0 (infinite
wait), which can hang the entire agent if an API endpoint becomes
unresponsive. Set a 120s safety timeout.
- Slack AllowFrom type mismatch: SlackConfig used plain []string
while every other channel uses FlexibleStringSlice, so numeric
user IDs in Slack config would fail to parse.
- Token estimation wrong for CJK: estimateTokens() divided byte
length by 4, but CJK characters are 3 bytes each, causing ~3x
overestimation and premature summarization. Switched to
utf8.RuneCountInString() / 3 for better cross-language accuracy.
Also added unit tests for the session filename sanitization.
Ref #116