feat(docker): add persistent bootstrap script for agent-managed capabilities

Add workspace/bootstrap.sh, a script that runs on every container start,
allowing the agent (or user) to persist tool installations across restarts
without rebuilding the image. Errors are logged to bootstrap.error.log and
surfaced in the agent's system prompt so it can self-diagnose and fix the
script.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sushi30 2026-03-08 19:17:01 +01:00
parent d5370c9605
commit 86bf19edc4
4 changed files with 39 additions and 1 deletions

View file

@ -12,4 +12,20 @@ if [ ! -d "${HOME}/.picoclaw/workspace" ] && [ ! -f "${HOME}/.picoclaw/config.js
exit 0 exit 0
fi fi
# Run bootstrap on every start
BOOTSTRAP="${HOME}/.picoclaw/workspace/bootstrap.sh"
ERROR_LOG="${HOME}/.picoclaw/workspace/bootstrap.error.log"
if [ -f "$BOOTSTRAP" ]; then
echo "[bootstrap] Running bootstrap.sh..."
if sh "$BOOTSTRAP" 2>"$ERROR_LOG"; then
# Success — clear any previous error log
rm -f "$ERROR_LOG"
else
echo "[bootstrap] WARNING: bootstrap.sh failed. See $ERROR_LOG for details."
echo "[bootstrap] Some capabilities may be missing. The agent will attempt to fix bootstrap.sh."
# Do NOT exit — continue starting the gateway so the agent can be reached
fi
fi
exec picoclaw gateway "$@" exec picoclaw gateway "$@"

View file

@ -349,6 +349,12 @@ func (cb *ContextBuilder) LoadBootstrapFiles() string {
} }
} }
// Surface bootstrap errors so the agent can diagnose and fix bootstrap.sh
errorLogPath := filepath.Join(cb.workspace, "bootstrap.error.log")
if data, err := os.ReadFile(errorLogPath); err == nil && len(data) > 0 {
fmt.Fprintf(&sb, "## BOOTSTRAP ERROR WARNING\n\nThe last container start ran `bootstrap.sh` and it FAILED. Some capabilities may be missing. You should read `bootstrap.sh`, identify the issue, fix it, and tell the user to restart the container.\n\nError output:\n```\n%s\n```\n\n", data)
}
return sb.String() return sb.String()
} }

View file

@ -10,3 +10,9 @@ You are a helpful AI assistant. Be concise, accurate, and friendly.
- Remember important information in your memory files - Remember important information in your memory files
- Be proactive and helpful - Be proactive and helpful
- Learn from user feedback - Learn from user feedback
## Docker Bootstrap
If the user asks you to install a tool, add a library, or persist a capability in the Docker environment, edit the file at `{workspace}/bootstrap.sh`. This script runs on every container start. Use `apk add` for Alpine packages. Check if the tool is already installed before installing (use `command -v`).
If you see a bootstrap error in your context (from `bootstrap.error.log`), it means the last bootstrap run failed and some capabilities may be missing. Read the error, fix `bootstrap.sh`, and inform the user they should restart the container to apply the fix.

10
workspace/bootstrap.sh Normal file
View file

@ -0,0 +1,10 @@
#!/bin/sh
# bootstrap.sh — runs on every container start.
# Edit this file to persist capabilities across restarts.
# The agent will modify this file when you ask it to install tools.
# Example: GitHub CLI (gh)
if ! command -v gh >/dev/null 2>&1; then
echo "[bootstrap] Installing gh CLI..."
apk add --no-cache github-cli
fi