Build and Push Docker Image / build (push) Successful in 2m32sDetails
- Add REGISTRATION_TOKEN env var (replaces legacy AGENT_TOKEN for new registrations)
- Add CREDENTIALS_PATH=/home/agent/.letsbe-agent/credentials.json to fix
path mismatch (agent runs as root, ~ expands to /root, but volume is
mounted at /home/agent/.letsbe-agent)
- Reduce CIRCUIT_BREAKER_COOLDOWN from 300s to 30s for faster recovery
- Update comments to clarify credential persistence behavior
This fixes the issue where agents would fail to reconnect after container
restarts because credentials were being saved to /root/.letsbe-agent/
instead of the persisted volume at /home/agent/.letsbe-agent/
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 2m37sDetails
5 minutes was too long for typical orchestrator restarts that take seconds.
30 seconds is more reasonable for quick recovery.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 1m56sDetails
Previously, the agent would clear credentials on ANY heartbeat failure,
causing infinite re-registration loops when:
- Agent container was updated while orchestrator was running
- Orchestrator was restarted while agent was running
Changes:
- Add HeartbeatStatus enum and HeartbeatResult dataclass
- Modify heartbeat() to return status info instead of just bool
- Only clear credentials on 401/403 (AUTH_FAILED)
- Keep credentials on transient errors (NETWORK_ERROR, SERVER_ERROR)
- Handle AUTH_FAILED in heartbeat_loop() for mid-session invalidation
Scenarios now handled:
- Agent restart: keeps creds, retries until orchestrator responds
- Orchestrator restart: keeps creds, retries with backoff
- Admin deletes agent: clears creds, breaks out for re-registration
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 1m54sDetails
- Add poste_initial_setup scenario for mail server wizard automation
- Configures mailserver hostname, creates admin account
- Auto-generates 24-char password if not provided
- Returns credentials in result data
- Add chatwoot_initial_setup scenario for super admin creation
- Fills name, company, email, password fields
- Unchecks newsletter subscription checkbox
- Clicks "Finish Setup" to complete wizard
- Auto-generates password if not provided
Both scenarios include health checks and return generated credentials
for storage in task results.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Build and Push Docker Image / build (push) Successful in 51sDetails
Bug: After registration, credentials were set directly on private
attributes (_agent_id, _agent_secret) instead of using property
setters. This bypassed _invalidate_client(), so the HTTP client
kept using old headers without X-Agent-Id/X-Agent-Secret.
Fix: Use property setters (self.agent_id, self.agent_secret) which
trigger _invalidate_client() to recreate the client with new headers.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Build and Push Docker Image / build (push) Failing after 34sDetails
Image will be pushed to: code.letsbe.solutions/letsbe/sysadmin-agent
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Automatically builds and pushes to Docker Hub on:
- Push to main/master branch
- Version tags (v*)
Image: letsbesolutions/sysadmin-agent
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add REGISTRATION_TOKEN config for new secure registration flow
- Add agent_secret and credentials_path config options
- Update HTTP client to use X-Agent-Id/X-Agent-Secret headers
- Add credential persistence to ~/.letsbe-agent/credentials.json
- Load persisted credentials on startup to survive restarts
- Verify credentials via heartbeat before skipping registration
- Maintain backward compatibility with legacy Bearer token auth
The agent now:
1. First tries to load persisted credentials
2. Validates them via heartbeat
3. Falls back to registration if invalid/missing
4. Persists new credentials after successful registration
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add tenant_id field to Settings (via TENANT_ID env var)
- Include tenant_id in registration payload when configured
- Add TENANT_ID to docker-compose.yml with documentation
- Add ROADMAP.md tracking project progress
Agents can now be associated with a specific tenant at startup.
Required in production, optional in development.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements a Nextcloud-specific executor that accepts a high-level
public_url payload and runs the appropriate occ config:system:set
commands via docker compose exec. The Orchestrator remains unaware
of container names, occ paths, and docker-compose syntax.
Features:
- Task type: NEXTCLOUD_SET_DOMAIN
- Payload: { "public_url": "https://cloud.example.com" }
- Parses URL into scheme and host, defaults to https if not provided
- Strips trailing slashes from URLs
- Runs three occ commands: overwritehost, overwriteprotocol, overwrite.cli.url
- Returns partial results with failed_args for debugging on failure
- Configurable constants for stack dir, service name, occ path, and user
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add EnvInspectExecutor to read ENV files and return key-value pairs
- Add FileInspectExecutor to read portions of text files (up to 1MB)
- Add FileExecutor tests including /opt/letsbe/config path verification
- Register new executors in EXECUTOR_REGISTRY
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
docker-compose-plugin isn't in Debian repos, need to download
the binary directly from Docker's GitHub releases.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
docker-cli alone doesn't include 'docker compose' subcommand.
Need docker-compose-plugin for 'docker compose -f' to work.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
docker.io on Debian Trixie only installs the daemon (dockerd), not the CLI.
The docker CLI is in the separate docker-cli package.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace named volume (agent_data) with bind mounts for /opt/letsbe/{env,stacks,nginx}
- Update ALLOWED_FILE_ROOT default from /opt/agent_data to /opt/letsbe
- Add startup validation that warns (but doesn't block) if host dirs missing
This fixes ENV_UPDATE writes going to container filesystem instead of host,
and DOCKER_RELOAD failing with "File does not exist" errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>