Summary
afx attach fails to find a builder that afx status shows as active. The builder is visible in the Tower web UI and responds to afx send, but afx attach -p <id> says "Builder not found."
Root Cause
afx status (when Tower is running) queries the Tower API, which reads from global.db terminal_sessions. But afx attach only queries the local .agent-farm/state.db builders table via getBuilder() / getBuilders() in state.ts.
These are two separate databases with no synchronization. If the local builders row was never written (e.g., spawned by a different session, race condition during spawn, or state.db was cleared), the builder exists in Tower but is invisible to attach.
Reproduction
- Have a Tower running with an active builder (visible in
afx status and Tower web UI)
- Verify
.agent-farm/state.db builders table is empty: sqlite3 .agent-farm/state.db "SELECT * FROM builders;"
- Run
afx attach -p <builder-id> → "Builder not found"
- Run
afx send <builder-id> "hello" → works (routes through Tower API)
Expected Behavior
afx attach should fall back to querying Tower's terminal registry when the local builders table has no match, similar to how afx status already does.
Relevant Code
commands/attach.ts:41-63 — findBuilderById() only queries local state
commands/status.ts:26-62 — queries Tower API when Tower is running
servers/tower-terminals.ts:819-828 — Tower tracks builders by role_id
state.ts:75-111 — upsertBuilder() writes only to local state.db
Workaround
Use afx send <builder-id> "<message>" (routes through Tower) or interact via the Tower web UI at http://localhost:4100.
Summary
afx attachfails to find a builder thatafx statusshows as active. The builder is visible in the Tower web UI and responds toafx send, butafx attach -p <id>says "Builder not found."Root Cause
afx status(when Tower is running) queries the Tower API, which reads fromglobal.db terminal_sessions. Butafx attachonly queries the local.agent-farm/state.db builderstable viagetBuilder()/getBuilders()instate.ts.These are two separate databases with no synchronization. If the local
buildersrow was never written (e.g., spawned by a different session, race condition during spawn, or state.db was cleared), the builder exists in Tower but is invisible toattach.Reproduction
afx statusand Tower web UI).agent-farm/state.dbbuilders table is empty:sqlite3 .agent-farm/state.db "SELECT * FROM builders;"afx attach -p <builder-id>→ "Builder not found"afx send <builder-id> "hello"→ works (routes through Tower API)Expected Behavior
afx attachshould fall back to querying Tower's terminal registry when the local builders table has no match, similar to howafx statusalready does.Relevant Code
commands/attach.ts:41-63—findBuilderById()only queries local statecommands/status.ts:26-62— queries Tower API when Tower is runningservers/tower-terminals.ts:819-828— Tower tracks builders byrole_idstate.ts:75-111—upsertBuilder()writes only to local state.dbWorkaround
Use
afx send <builder-id> "<message>"(routes through Tower) or interact via the Tower web UI athttp://localhost:4100.