Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,34 @@ Perry creates isolated Docker-in-Docker development environments. Distributed ar

If modifying Dockerfile/init scripts, run `perry build` first.

### Manual Agent Testing

When manually testing agent changes, use a dedicated test port to avoid conflicts with any running production agent:

```bash
# Kill any existing agents and start test agent on port 7391
pkill -f "perry agent" 2>/dev/null
perry agent run --port 7391 &

# Configure CLI to use test agent
perry config worker localhost:7391

# Test your changes
perry list
perry sync <workspace-name>

# Verify in container (example: testing perry worker binary)
docker exec -u workspace workspace-<name> perry --version
docker exec -u workspace workspace-<name> perry worker sessions list

# Test API directly
curl -s -X POST "http://localhost:7391/rpc/sessions/list" \
-H "Content-Type: application/json" \
-d '{"json":{"workspaceName":"<name>"}}'
```

**Important**: Always kill the test agent when done, or it will conflict with automated tests.

### UI Testing

**Critical**: UI (Web, mobile) MUST have e2e tests. Unit/integration tests miss rendering bugs, event binding issues, and framework regressions.
Expand Down
69 changes: 69 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,75 @@ Currently none (Tailscale-trusted). Future options if needed:

---

## Appendix: perry worker Pattern

### Overview

The `perry worker` subcommand runs inside containers to handle container-specific operations like session discovery. It's designed to be updated independently of the Docker image - the compiled binary is copied during `perry sync`, avoiding the need to rebuild images for bug fixes.

### Architecture

```
src/
├── index.ts # Main CLI with 'worker' subcommand
├── sessions/agents/
│ ├── opencode-storage.ts # Shared session reading logic
│ └── opencode.ts # Container provider (calls perry worker)
└── workspace/
└── manager.ts # copyPerryWorker() syncs binary to container

dist/
├── index.js # Main perry CLI
└── perry-worker # Compiled standalone binary (bun build --compile)
```

### Key Principle: No Bifurcation

The same code (`opencode-storage.ts`) handles OpenCode session reading everywhere:
- **Host**: Imported directly in `router.ts`
- **Container**: Called via `perry worker sessions list/messages`

This eliminates duplicate implementations and ensures consistent behavior.

### Build & Sync

The worker binary is compiled during build and copied during sync:

```bash
# Build (in package.json scripts)
bun build src/index.ts --compile --outfile dist/perry-worker --target=bun

# Sync copies binary to container (in WorkspaceManager.copyPerryWorker)
docker cp dist/perry-worker container:/usr/local/bin/perry
```

### Usage

```bash
# List all OpenCode sessions (JSON output)
perry worker sessions list

# Get messages for a session (JSON output)
perry worker sessions messages <session_id>
```

### Why This Pattern?

1. **Independent Updates**: Fix bugs in session reading, rebuild, sync - no Docker image rebuild needed
2. **Single Source of Truth**: Same TypeScript code used on host and in container
3. **Instant Propagation**: `perry sync` updates all workspaces immediately
4. **No External Dependencies**: Self-contained binary, no npm install in container

### Adding New Commands

To add new functionality:

1. Add shared logic to `src/sessions/agents/` or appropriate module
2. Add subcommand to `perry worker` in `src/index.ts`
3. Import shared module in both host code and worker command

---

## Appendix: Port Selection

Default port: **7391**
Expand Down
4 changes: 4 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
"dist"
],
"scripts": {
"build": "rm -rf ./dist && bun run build:ts && bun run build:web && bun link",
"build": "rm -rf ./dist && bun run build:ts && bun run build:worker && bun run build:web && bun link",
"build:ts": "tsc && chmod +x dist/index.js",
"build:worker": "bun build src/index.ts --compile --outfile dist/perry-worker --target=bun",
"build:web": "cp src/shared/client-types.ts web/src/lib/types.ts && cd web && bun run build && cp -r dist ../dist/agent/web",
"test": "vitest run",
"test:web": "playwright test",
Expand Down
1 change: 0 additions & 1 deletion perry/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ RUN cd /opt/workspace/internal && bun install --production
COPY internal /opt/workspace/internal
RUN chmod +x /opt/workspace/scripts/dockerd-entrypoint.sh \
&& install -m 0755 /opt/workspace/scripts/dockerd-entrypoint.sh /usr/local/bin/dockerd-entrypoint.sh \
&& install -m 0755 /opt/workspace/scripts/perry-session-reader.sh /usr/local/bin/perry-session-reader \
&& chmod +x /opt/workspace/internal/src/index.ts \
&& printf '#!/bin/sh\nexec bun /opt/workspace/internal/src/index.ts "$@"\n' > /usr/local/bin/workspace-internal \
&& chmod +x /usr/local/bin/workspace-internal
Expand Down
132 changes: 0 additions & 132 deletions perry/scripts/perry-session-reader.sh

This file was deleted.

Loading