Add getGitStates(podId) to db.ts — queries the engineer_states collection
written by scripts/podman-agent.mjs and returns a map keyed by engineer name.
In PodMan.onScreenFrame(), fuse before detectCollisions(): if an engineer has
changedFiles in engineer_states, force hasUnpushedChanges=true on their context.
This overrides Gemini vision's unreliable pixel-based guess with deterministic
local git state — preventing the money-moment collision from silently not firing.
Key assumption: LiveKit participant identity matches the --name arg used when
running the git watcher (e.g. identity "alice" → --name alice).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AaCFWMkYQmTcuPsxaaACft
Join UX: click a member's name to join directly, or type a name and "Join"
(adds to roster + joins) — removes the redundant dropdown step. "Add" still
adds to the roster without joining.
Presence: new GET /api/presence (LiveKit RoomServiceClient) reports who's
connected per pod. The pod list polls it and shows a "N in room" badge plus a
green dot on members currently connected, so people can see active pods and jump in.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backend: atomic create with insert-retry-on-duplicate-key (removes slug
TOCTOU race + wrong 400s), resilient per-index creation so a unique-index
failure can't silently drop the constraint or block seeding, idempotent
race-safe seeding via $setOnInsert, type validation + size caps on all pod
fields/members, removeMember no-ops without a write, /api/outcome guarded.
Frontend: per-pod busy state (one mutation no longer disables every card),
joined pod derived from the list (can't go stale), create keeps inputs on error.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pods are persisted in MongoDB and CRUD'd via /api/pods (list/create/get/
update/delete + add/remove member). Shared Pod reshaped to a persisted entity
(members: string[], description, timestamps) + PodInput. Backend seeds Demo/
Frontend/Backend Pods on first run (Squad -> Pod rename). Frontend replaces
hardcoded teams with live data: PodCard (member chips add/remove, inline edit,
delete, join) + CreatePodForm; App fetches+mutates via API. Removes teams.ts/
TeamCard; gitignores test artifacts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the in-memory store with a real MongoDB-backed store. Adds memory/db.ts
(client singleton, typed collections, startup ping + indexes) and rewrites
record{Observation,Collision,Intervention,Outcome} to insert into Mongo
(best-effort — failures log, don't crash). Server connects on startup and
exposes GET /api/memory/stats for verification.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The canonical-architecture rewrite dropped app.use(cors()) and moved the
token route to POST /api/token ({room,identity,name}), but the frontend
still called the old /pods/:id/token — causing "Failed to fetch" in the
browser. Re-add CORS and update fetchPodToken to the new contract.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Express server with /health and a LiveKit token endpoint. Module skeletons
for the full loop: vision (Gemini), GitHub fusion, collision detector (pure,
testable), intervention engine, and continual-learning memory store. Approve
native build scripts (esbuild/genai/protobufjs) at the workspace root.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set up top-level structure (backend, frontend, database, infra, shared,
docs) with .gitkeep placeholders, root README, and .gitignore.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>