Resolve App.tsx header conflict: keep main's "Privacy-limited" badge AND the
"Team memory" graph button (both in the header action group). server.ts and
backend/package.json auto-merged cleanly — main's closeMemory/shutdown and the
graph:seed script are both preserved.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolve conflicts:
- backend/src/server.ts: keep main's getPresence + closeRoom (room auto-cleanup)
and add the graph imports/routes (additive).
- frontend/src/App.tsx: take main's shadcn command-center UI and re-integrate
GraphView — import, graphPodId state, an early-return render branch, and a
shadcn "Team memory" button next to Refresh.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- reachFrom now returns the direct outbound edges PLUS the recursive
$graphLookup reaches, de-duped by edge id, with maxDepth to bound cycles.
It was dropping edges straight off the start node. [review P2]
- GraphView SVG nodes are keyboard-accessible: role/tabIndex/aria-label +
Enter/Space handler alongside onClick. [review P3]
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the team_model graph layer (the "it learned" view) and its visualization,
per docs/graph.md. Demo-backed first; built on origin/main conventions.
- shared: PodGraph / node / edge / metric types + GraphNodeDoc / GraphEdgeDoc
- backend/src/graph: demo graph data; Mongo store (loadPodGraph w/ demo
fallback, seedGraph, reachFrom via $graphLookup); graph:seed script
- backend/src/server.ts: additive GET /api/pods/:id/graph + /graph/reach/:node
- frontend: dark-Bauhaus GraphView + fetch helper, reachable from a
"Team memory" toggle in App.tsx
- docs/graph.md: spec (data model, $graphLookup, API, demo-first plan)
Demo-backed: the route serves a grounded demo graph when team_model has no
graph yet; graph:seed writes team_model + graph_nodes/graph_edges so the
$graphLookup traversal is real. Swap loadPodGraph to live team_model later.
Known follow-ups before merge: branch is based on 65a0791; origin/main is now
at 1294b84, so this needs a rebase + App.tsx conflict resolution (teammate
rewrote App.tsx with live room view / one-click join).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DELETE /api/pods/:id now also calls closeRoom (RoomServiceClient.deleteRoom)
to end the live LiveKit room and disconnect anyone connected. PodView listens
for RoomEvent.Disconnected and returns the user to the pod list, so a deleted
pod cleanly kicks everyone out instead of stranding them in a dead room.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Use the member name as the LiveKit identity (was random per join) so a
refresh/rejoin replaces the existing session instead of leaving a ghost
participant in the room. Set roomConfig on the token (emptyTimeout 60s,
departureTimeout 20s) so empty rooms and departed participants clean up
promptly. Pods map 1:1 to a deterministic room name, so joins reuse the
same room rather than spawning new ones.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>