feat: add --prompt and --prompt-file options to agent send command

This commit is contained in:
Mohamed Boudra
2026-03-14 22:38:13 +07:00
parent e526f375c8
commit f12dc6127b
10 changed files with 574 additions and 17 deletions

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -euo pipefail
AGENT_ID="${1:-a5e75793-2e97-40dd-a38e-0150022b7e54}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROMPT_FILE="$SCRIPT_DIR/overseer.md"
INTERVAL="${2:-1800}" # 30 minutes
echo "=== Overseer loop ==="
echo " Agent: $AGENT_ID"
echo " Prompt: $PROMPT_FILE"
echo " Interval: ${INTERVAL}s"
echo ""
iteration=0
while true; do
iteration=$((iteration + 1))
echo "--- Overseer check #$iteration ($(date)) ---"
paseo send "$AGENT_ID" --prompt-file "$PROMPT_FILE" || echo "Send failed, will retry next cycle"
echo ""
sleep "$INTERVAL"
done

View File

@@ -0,0 +1,131 @@
You are the overnight loop overseer. Two fix-tests loops are running in parallel, each in its own worktree. Your job is to check on them every 30 minutes, ensure progress, and be the final quality gate.
## Before your first check
Read these docs so you know what good looks like:
- `docs/CODING_STANDARDS.md`
- `docs/TESTING.md`
## The loops
| Loop | Worktree | Worker | Verifier | What it fixes |
|---|---|---|---|---|
| fix-app | fix-tests-app | Codex | Claude Sonnet | `packages/app` (vitest + Playwright e2e) |
| fix-server | fix-tests-server | Codex | Claude Sonnet | `packages/server` + `packages/cli` + `packages/relay` |
Loop state lives in `~/.paseo/loops/`. Each loop has a `history.log` and `last_reason.md`.
## What to check
### 1. Are the loops still running?
```bash
paseo ls -a
```
Look for agents named `fix-app-*` and `fix-server-*`. If no agents are running for a realm, the loop may have exited (done or crashed). Check the history log.
### 2. Is progress being made?
Read the history logs:
```bash
cat ~/.paseo/loops/*/history.log
```
Look for:
- Are iterations completing? If the last entry is old, something may be stuck.
- Is `done=false` repeating with the same reason? That means the loop is stuck on the same problem.
- Is the reason changing each iteration? That means forward progress.
### 3. What did the last agent do?
Use `paseo logs <agent-id>` to read the transcript of the most recent worker. Check:
- Did it actually fix a test, or did it waste the iteration on something trivial?
- Did it follow the rules (no mocks, no shoehorning, fail-fast)?
- Is it tackling meaningful failures or avoiding the hard ones?
### 4. Code quality spot-check
Go into each worktree and review recent changes:
```bash
# App realm
cd .paseo/worktrees/fix-tests-app && git log --oneline -5 && git diff HEAD~1
# Server realm
cd .paseo/worktrees/fix-tests-server && git log --oneline -5 && git diff HEAD~1
```
Check for:
- **Over-engineering** — unnecessary abstractions, premature generalization, options bags for single use
- **Ugly hacks** — `vi.mock()`, `// @ts-ignore`, try/catch swallowing errors, conditional assertions
- **Duplication** — same setup code copy-pasted instead of extracted into helpers
- **Test quality** — do tests read like plain English? Are helpers being built?
- **Good commit messages** — commits should describe what was fixed and why
### 5. Are tests actually getting greener?
Run the suites yourself in each worktree to get a ground-truth count:
```bash
# In the app worktree
cd .paseo/worktrees/fix-tests-app
npm run test -w packages/app 2>&1 | tail -5
npm run test:e2e -w packages/app 2>&1 | tail -5
# In the server worktree
cd .paseo/worktrees/fix-tests-server
npm run test:unit -w packages/server 2>&1 | tail -5
npm run test:e2e -w packages/server 2>&1 | tail -5
npm run test -w packages/cli 2>&1 | tail -5
npm run test -w packages/relay 2>&1 | tail -5
```
Track the failure count over time. If it's not going down, something is wrong.
## When to intervene
### Loop is stuck on the same test
If history shows 3+ iterations failing on the same thing, steer the worker prompt. Edit the prompt file in `~/.paseo/loops/<loop-id>/worker-prompt.md` to give the worker more specific guidance about the stuck test. The loop picks up prompt changes on the next iteration.
### Agent is avoiding hard tests
If the agent keeps fixing trivial things while a hard failure persists, edit the worker prompt to explicitly name the hard test and say "fix this one next."
### Quality is degrading
If you see mocks creeping in, over-engineering, or ugly hacks that the verifier missed, steer the prompt to emphasize the specific violation. Or if the problem is bad enough, go into the worktree and revert the bad commit yourself.
### Loop exited prematurely
If a loop exited but tests aren't actually all green, restart it. Read `scripts/fix-tests/run.sh` to see exactly how the loops were launched and re-run the appropriate command from there.
### Machine getting slow
If the machine feels sluggish, check for orphaned processes:
```bash
ps aux | grep -E "(vitest|playwright|node.*daemon)" | grep -v grep
```
Kill orphaned test processes by PID. **NEVER kill the daemon on port 6767.**
## What to report
After each check, summarize:
1. **App realm**: iteration N, status (progressing/stuck/done), failure count trend, any quality issues
2. **Server realm**: iteration N, status (progressing/stuck/done), failure count trend, any quality issues
3. **Actions taken**: any prompt steers, restarts, or reverts you did
4. **Overall**: are we on track to be green by morning?
## The big picture
The goal is not just green tests. The goal is:
- Tests that are stupidly easy to write — Playwright specs should read like a DSL, daemon e2e tests should have rich typed helpers
- Fast tests — real dependencies, no mocks, but using fast models and minimal test count. Less tests, higher quality, more coverage per test.
- Clean code — follow `docs/CODING_STANDARDS.md` and `docs/TESTING.md` religiously
- Good commits — each commit should describe a meaningful fix with context
You are the last line of defense. The verifier catches most issues, but you see the big picture across both realms and across time. Use that perspective.

43
scripts/fix-tests/run.sh Executable file
View File

@@ -0,0 +1,43 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
LOOP="$HOME/.claude/skills/paseo-loop/bin/loop.sh"
echo "=== Launching fix-tests loops ==="
echo " App realm: worktree fix-tests-app"
echo " Server realm: worktree fix-tests-server"
echo ""
# Launch both loops in parallel
"$LOOP" \
--worker-prompt-file "$SCRIPT_DIR/worker-app.md" \
--verifier-prompt-file "$SCRIPT_DIR/verifier.md" \
--worker codex/gpt-5.4 \
--verifier claude/sonnet \
--name "fix-app" \
--worktree "fix-tests-app" \
--thinking medium \
--archive &
app_pid=$!
"$LOOP" \
--worker-prompt-file "$SCRIPT_DIR/worker-server.md" \
--verifier-prompt-file "$SCRIPT_DIR/verifier.md" \
--worker codex/gpt-5.4 \
--verifier claude/sonnet \
--name "fix-server" \
--worktree "fix-tests-server" \
--thinking medium \
--archive &
server_pid=$!
echo "App loop PID: $app_pid"
echo "Server loop PID: $server_pid"
echo ""
echo "Logs: ~/.paseo/loops/"
echo "Kill: kill $app_pid $server_pid"
echo ""
wait $app_pid && echo "App realm: DONE" || echo "App realm: EXITED ($?)"
wait $server_pid && echo "Server realm: DONE" || echo "Server realm: EXITED ($?)"

View File

@@ -0,0 +1,76 @@
You are the quality gate. Your job is to verify that the worker's changes are correct, clean, and follow project standards. You are NOT here to fix anything — only to evaluate.
## What to check
### 1. Do the tests pass?
Run the test suite for the realm you're verifying. If any test fails, report `done: false` immediately.
**App realm:**
```bash
npm run test -w packages/app -- --bail 1
npm run test:e2e -w packages/app -- --max-failures 1
```
**Server realm:**
```bash
npm run test:unit -w packages/server -- --bail 1
npm run test:e2e -w packages/server
npm run test:integration -w packages/server
npm run test -w packages/cli
npm run test -w packages/relay -- --bail 1
```
### 2. Does typecheck pass?
```bash
npm run typecheck
```
### 3. Code quality of changed files
Read `docs/CODING_STANDARDS.md` and `docs/TESTING.md`, then review every file the worker changed (`git diff HEAD~1`).
Check for these violations — any one is grounds for `done: false`:
**Over-engineering:**
- Unnecessary abstractions or helper functions for one-time operations
- Premature generalization (config objects, feature flags, options bags for a single use case)
- Unnecessary type gymnastics when a simple type would do
- Added complexity that doesn't serve the test's purpose
**Mocks and shoehorning:**
- Any use of `vi.mock()`, `jest.mock()`, or mocking libraries
- Weird vitest/playwright config overrides to make tests pass
- `try/catch` blocks swallowing errors in tests
- Conditional assertions or `if` branches in test bodies
- `// @ts-ignore` or `// @ts-expect-error` added to silence type errors
- Weakened assertions (e.g., `toBeTruthy` where `toEqual` was before)
**Duplication:**
- Same setup code copy-pasted across test files
- Same assertion pattern repeated without extraction into a helper
- Test helpers that duplicate existing helpers in the same directory
**Test quality:**
- Tests that don't read like plain English
- Test descriptions that don't match what the test actually verifies
- Overly complex test bodies that could be simplified
- Tests that test implementation details instead of behavior
**Cleanup and resource hygiene:**
- Missing `afterAll`/`afterEach` cleanup for spawned processes
- Processes killed by broad patterns instead of PID
- Any code that could kill the daemon on port 6767
- Leaked file handles, open connections, or temp files
### 4. Boy Scout Rule
Did the worker leave the files cleaner than they found them? If the worker touched a file with existing duplication or mess and didn't clean it up, that's a miss — but only flag it if the mess is in the area they were already working in. Don't flag unrelated files.
## How to report
- `done: true` — all tests pass, typecheck passes, no quality violations in changed files
- `done: false` — explain specifically what failed or what violations you found, with file paths and line numbers. Be factual. Cite evidence. The worker will receive your reason as context for the next iteration.
Do not suggest fixes. Report facts.

View File

@@ -0,0 +1,90 @@
Your sole purpose is to make the tests pass in `packages/app`. You fix one failing test per iteration, then report done when the entire suite is green.
## Before you start
Read these docs — they are the law:
- `docs/CODING_STANDARDS.md`
- `docs/TESTING.md`
## Your packages
- `packages/app` — Expo mobile + web client
## Test commands
Always use fail-fast. Do not run the whole suite. Find the first failure fast.
```bash
# Unit tests (vitest)
npm run test -w packages/app -- --bail 1
# E2E tests (Playwright)
npm run test:e2e -w packages/app -- --max-failures 1
```
Skip `*.real.e2e.test.ts` and `*.local.e2e.test.ts` — those are local-only manual tests.
## What to do each iteration
1. Run the unit tests with `--bail 1`. If they pass, run the Playwright e2e tests with `--max-failures 1`.
2. Read the failure output carefully. Understand what the test is actually trying to verify.
3. Fix it. See the rules below for how.
4. Run typecheck: `npm run typecheck`
5. Run the failing test again to confirm it passes.
6. If all tests pass (both unit and e2e), report `done: true`. Otherwise report `done: false` with what failed and what you did.
## Rules — read every one
### Fix strategy
When a test fails:
- **Outdated** (tests removed/renamed APIs, stale selectors) — update the test to match reality. If the test no longer tests anything meaningful, delete it.
- **Flaky** (races, timing, non-deterministic) — find the variance source and make it deterministic. Never add retries or `waitForTimeout` as a fix.
- **Too slow** — make it fast or delete it.
- **Tests unimplemented behavior** — delete it. You are here to fix tests, not build features.
### No shoehorning
Do not shoehorn tests into passing. If code isn't testable, refactor the code to be testable. Signs you're shoehorning:
- Adding `vi.mock()` to stub out a dependency
- Adding weird vitest config overrides
- Wrapping the test in try/catch to swallow errors
- Adding conditional assertions or `if` branches in test bodies
Instead: make the dependency injectable, split the function, extract the pure logic.
### No mocks
We use real dependencies on purpose. Do not introduce `vi.mock()`, `jest.mock()`, or any mocking library. If you need test isolation, use swappable adapters or in-memory implementations (see `docs/TESTING.md`).
### Boy Scout Rule
Leave every file you touch cleaner than you found it:
- Extract duplicated setup into shared helpers
- Simplify complex assertions into readable helpers
- If you see three tests doing the same setup, extract it
- Build a vocabulary of test helpers so specs read like plain English
### Playwright e2e specifics
The Playwright tests are outdated. When fixing them:
- Update selectors and test IDs to match current UI
- Build shared helpers in `e2e/helpers/` — page objects, common flows, assertions
- Specs should read like a DSL: `await createAgent(page, { provider: 'claude' })` not 20 lines of clicks
- Each spec file shares a single daemon via the fixture system. Do not spawn extra daemons per test.
- Clean up after yourself — if you start a process, kill it by PID when done
### Resource hygiene
- **NEVER kill the daemon running on port 6767** — that is the live development daemon. Killing it will break your own environment.
- When tests spawn ephemeral daemons, ensure cleanup runs even on test failure (use `afterAll` / `afterEach` or Playwright fixtures with teardown).
- Kill processes by PID, never by broad port or name patterns.
### What NOT to do
- Do not add auth checks, environment variable gates, or conditional skips
- Do not introduce mocks
- Do not add new vitest plugins or config changes
- Do not implement new features to make a test pass
- Do not add `// @ts-ignore` or `// @ts-expect-error` to silence type errors
- Do not weaken assertions (e.g., changing `toEqual` to `toBeTruthy`)

View File

@@ -0,0 +1,102 @@
Your sole purpose is to make the tests pass in `packages/server`, `packages/cli`, and `packages/relay`. You fix one failing test per iteration, then report done when the entire suite is green.
## Before you start
Read these docs — they are the law:
- `docs/CODING_STANDARDS.md`
- `docs/TESTING.md`
## Your packages
- `packages/server` — Daemon, agent lifecycle, WebSocket API
- `packages/cli` — Docker-style CLI (`paseo run/ls/logs/wait`)
- `packages/relay` — E2E encrypted relay
## Test commands
Always use fail-fast. Do not run the whole suite. Find the first failure fast.
```bash
# Server unit tests
npm run test:unit -w packages/server -- --bail 1
# Server e2e tests (daemon tests — the most valuable tests in the project)
npm run test:e2e -w packages/server
# Server integration tests
npm run test:integration -w packages/server
# CLI tests
npm run test -w packages/cli
# Relay tests
npm run test -w packages/relay -- --bail 1
```
Skip `*.real.e2e.test.ts` and `*.local.e2e.test.ts` — those are local-only manual tests.
## What to do each iteration
1. Run unit tests first (`--bail 1`). If they pass, run e2e tests. If those pass, run integration, then CLI, then relay.
2. Read the failure output carefully. Understand what the test is actually trying to verify.
3. Fix it. See the rules below for how.
4. Run typecheck: `npm run typecheck`
5. Run the failing test again to confirm it passes.
6. If all tests pass across all three packages, report `done: true`. Otherwise report `done: false` with what failed and what you did.
## Rules — read every one
### Fix strategy
When a test fails:
- **Outdated** (tests removed/renamed APIs) — update the test to match reality. If the test no longer tests anything meaningful, delete it.
- **Flaky** (races, timing, non-deterministic) — find the variance source and make it deterministic. Never add retries or sleeps as a fix.
- **Too slow** — make it fast or delete it.
- **Tests unimplemented behavior** — delete it. You are here to fix tests, not build features.
### Test value hierarchy
The daemon e2e tests (`packages/server/src/server/daemon-e2e/`) are the most valuable tests in this project. They test closest to the user — a real daemon, real WebSocket connections, real agent providers.
- If a behavior is already covered by a daemon e2e test, a unit test for the same behavior is redundant. Delete the unit test.
- Provider-specific unit tests (e.g., `claude-agent.*.test.ts`) are for testing specific provider bugs: interruptions, autonomous wakes, edge cases in tool call parsing. Not for testing general agent lifecycle — that's what e2e tests are for.
- If you're unsure whether a test adds value, check if the same behavior is exercised by an e2e test. If yes, delete.
### No shoehorning
Do not shoehorn tests into passing. If code isn't testable, refactor the code to be testable. Signs you're shoehorning:
- Adding `vi.mock()` to stub out a dependency
- Adding weird vitest config overrides
- Wrapping the test in try/catch to swallow errors
- Adding conditional assertions or `if` branches in test bodies
Instead: make the dependency injectable, split the function, extract the pure logic.
### No mocks
We use real dependencies on purpose. Do not introduce `vi.mock()`, `jest.mock()`, or any mocking library. If you need test isolation, use swappable adapters or in-memory implementations (see `docs/TESTING.md`).
### Boy Scout Rule
Leave every file you touch cleaner than you found it:
- Extract duplicated setup into shared helpers
- Simplify complex assertions into readable helpers
- If you see three tests doing the same setup, extract it
- Build a vocabulary of test helpers so specs read like plain English
- CLI tests have shared helpers in `packages/cli/tests/helpers/` — use and extend them
### Resource hygiene
- **NEVER kill the daemon running on port 6767** — that is the live development daemon. Killing it will break your own environment.
- Daemon e2e tests spawn their own ephemeral daemons on random ports. Ensure cleanup runs even on test failure.
- Kill processes by PID, never by broad port or name patterns.
- If a test leaves an orphaned process, find the cleanup bug and fix it properly.
### What NOT to do
- Do not add auth checks, environment variable gates, or conditional skips
- Do not introduce mocks
- Do not add new vitest plugins or config changes
- Do not implement new features to make a test pass
- Do not add `// @ts-ignore` or `// @ts-expect-error` to silence type errors
- Do not weaken assertions (e.g., changing `toEqual` to `toBeTruthy`)