Perry Coding Agents
Flagged@gricha
{"isSafe":false,"isSuspicious":true,"riskLevel":"medium","findings":[{"category":"system_harm","severity":"high","description":"Use of SSH with StrictHostKeyChecking=no disables host key verification, increasing susceptibility to man-in-the-middle attacks in automated deployments.","evidence":"ssh -o StrictHostKeyChecking=no workspace@<IP> \"cd ~/<project> && /home/workspace/.opencode/bin/opencode run 'task'\""},{"category":"shell_command","severity":"medium","description":"Background dispatch of remote commands (ending with &) and no explicit timeout can lead to unbounded resource usage or unattended, long-running tasks.","evidence":"\"ssh -o StrictHostKeyChecking=no workspace@<IP> \\\"cd ~/<project> && /home/workspace/.opencode/bin/opencode run 'task'\\\" &\""},{"category":"data_exfiltration","severity":"medium","description":"Completion notification posts data to a wake endpoint via curl, potentially leaking task results to an endpoint (IP-based). Ensure the endpoint is trusted and communications are secured.","evidence":"When done: curl -X POST http://${WAKE_IP}:18789/hooks/wake -H \"Content-Type: application/json\" -H \"Authorization: Bearer <hooks-token>\" -d \"{\\\\\\\"text\\\\\\\": \\\\\\\"Done: summary\\\\\\\", \\\\\\\"mode\\\\\\\": \\\\\\\"now\\\\\\\"}\""},{"category":"suspicious_url","severity":"low","description":"Usage of bare IP addresses for endpoints (e.g., 100.109.173.45, 18789) rather than domain names; common in internal automation, but review endpoints to ensure they are trusted and not exposed externally.","evidence":"Example block references WAKE_IP and endpoints such as 100.109.173.45 and http://${WAKE_IP}:18789/hooks/wake"},{"category":"prompt_injection","severity":"low","description":"No explicit prompt-injection attempt detected, but task strings are passed to remote agents (e.g., opencode run 'Your task') which could be abused if inputs aren’t properly sanitized by the agent.","evidence":"/home/workspace/.opencode/bin/opencode run 'Your task.'"},{"category":"data_exfiltration","severity":"low","description":"Small data payloads (e.g., JSON with text: 'Done: summary') are sent after completion; risk increases if endpoints are external or not TLS-protected.","evidence":"When done: curl -X POST http://${WAKE_IP}:18789/hooks/wake -H \"Content-Type: application/json\" -H \"Authorization: Bearer <token>\" -d \"{\\\\\\\"text\\\\\\\": \\\\\\\"Done: summary\\\\\\\", \\\\\\\"mode\\\\\\\": \\\\\\"}],"summary":"The content describes an automation workflow to dispatch tasks to remote agents via SSH and post-completion notifications to a wake endpoint. It includes security-risk patterns such as bypassing SSH host key verification and transmitting completion data to an endpoint. Mitigate by removing host key checks, enforcing TLS, validating endpoints, and sanitizing inputs."}
npx machina-cli add skill @gricha/perry-coding-agents --openclawPerry Coding Agents
Dispatch tasks to OpenCode/Claude Code on Perry workspaces.
Rules
- Always create dex task FIRST — before any dispatch, no exceptions
- No hard timeouts — background dispatch, let agent run
- Use IPs — MagicDNS broken in containers (
tailscale statusfor IPs) - One task per PR — same session continues until done
- Reuse sessions — OpenCode keeps context in
~/.opencode/ - Never code directly — always dispatch to agents
Commands
# OpenCode (primary)
ssh -o StrictHostKeyChecking=no workspace@<IP> "cd ~/<project> && /home/workspace/.opencode/bin/opencode run 'task'" &
# Claude Code (needs TTY)
ssh -t workspace@<IP> "cd ~/<project> && /home/workspace/.local/bin/claude 'task'"
Dispatch Pattern
WAKE_IP=$(tailscale status --self --json | jq -r '.Self.TailscaleIPs[0]')
ssh -o StrictHostKeyChecking=no workspace@<IP> "cd ~/<project> && /home/workspace/.opencode/bin/opencode run 'Your task.
When done: curl -X POST http://${WAKE_IP}:18789/hooks/wake -H \"Content-Type: application/json\" -H \"Authorization: Bearer <hooks-token>\" -d \"{\\\"text\\\": \\\"Done: summary\\\", \\\"mode\\\": \\\"now\\\"}\"
'" &
Task Tracking
Create task before dispatch with: workspace IP, branch, goal, done criteria. Same task until CI green. Complete with result summary.
Example: Full PR Flow
# 1. Create task
# Track: workspace feat1 (100.109.173.45), branch feat/auth, goal: add auth
# 2. Get wake info
WAKE_IP=$(tailscale status --self --json | jq -r '.Self.TailscaleIPs[0]')
# 3. Dispatch (background, no timeout)
ssh -o StrictHostKeyChecking=no workspace@100.109.173.45 "cd ~/perry && /home/workspace/.opencode/bin/opencode run 'Add bearer token auth to all API endpoints. Create PR when done.
When finished: curl -X POST http://${WAKE_IP}:18789/hooks/wake -H \"Content-Type: application/json\" -H \"Authorization: Bearer <token>\" -d \"{\\\"text\\\": \\\"Done: Auth PR created\\\", \\\"mode\\\": \\\"now\\\"}\"
'" &
# 4. Wake received → check CI
ssh workspace@100.109.173.45 "cd ~/perry && gh pr checks 145"
# 5. CI fails → dispatch follow-up (same task, agent has context)
ssh -o StrictHostKeyChecking=no workspace@100.109.173.45 "cd ~/perry && /home/workspace/.opencode/bin/opencode run 'CI failing: test/auth.test.ts line 42. Fix and push.
When fixed: curl -X POST http://${WAKE_IP}:18789/hooks/wake ...'" &
# 6. CI green → complete task with result
Troubleshooting
- Can't reach:
tailscale status | grep <name> - Commands not found: Use full paths (
/home/workspace/.opencode/bin/opencode) - Wake not firing: Check IP/token, test with curl
Overview
Perry Coding Agents lets you dispatch development tasks to OpenCode or Claude Code running on Perry workspaces. It enforces a dex task first, keeps a single task per PR, and runs in the background so your main workspace stays isolated. Tasks are executed in isolated agent environments, with progress tracked until completion.
How This Skill Works
You create a dex task before dispatching. Then you obtain the target IP with tailscale status and SSH into the Perry workspace to run OpenCode or Claude Code in the background. Sessions are persisted for the PR, and a wake webhook signals completion when the task finishes, avoiding hard timeouts.
When to Use It
- Starting a new feature or bugfix in a Perry workspace that requires an isolated environment.
- Reviewing a PR and applying changes without polluting the main workspace.
- Running heavy builds, tests, or experiments in the background using OpenCode or Claude Code.
- Delegating coding work to agents for development or CI-related tasks.
- Continuing a task across multiple dispatches until CI green.
Quick Start
- Step 1: Create a dex task with workspace IP, branch, and goal for the task.
- Step 2: Get WAKE_IP via tailscale status and prepare the dispatch command.
- Step 3: Dispatch to OpenCode or Claude Code in background; monitor wake and CI results.
Best Practices
- Always create a dex task first before any dispatch.
- Use IPs discovered via tailscale status; avoid relying on MagicDNS in containers.
- Keep one task per PR; the same session continues until completion.
- Reuse OpenCode context by preserving sessions in ~/.opencode/.
- Never code directly in the workspace; dispatch everything to an agent.
Example Use Cases
- Create a task for feature work on workspace 100.109.173.45, then dispatch to OpenCode to implement authentication.
- For a PR, create a dex task, wake the agent, and run deployment checks in OpenCode.
- If CI fails, dispatch a follow-up task against the same dex task to fix tests.
- Use Claude Code to draft a refactor in an isolated session and open a PR when complete.
- Monitor the wake webhook and verify CI status before marking the task complete.