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
2 changes: 1 addition & 1 deletion .github/workflows/projectbrain-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
env:
COGNEE_API_KEY: ${{ secrets.COGNEE_API_KEY }}
run: |
pip install git+https://github.com/topoteretes/cognee litellm
pip install git+https://github.com/topoteretes/cognee litellm fastembed python-dotenv

- name: Generate PR Diff
run: |
Expand Down
51 changes: 32 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# ProjectBrain

> **ProjectBrain not only remembers your project — it documents *how it was built*. Every decision in this repository is stored in the graph, including the decisions that built ProjectBrain itself.**

> *RAG gives your AI a library card. Cognee gives it a memory. ProjectBrain gives it a conscience.*

**ProjectBrain** is a persistent memory layer for your codebase, built on [Cognee](https://github.com/topoteretes/cognee) and the Model Context Protocol (MCP). It cures "Context Rot" by remembering your architectural decisions, fading out deprecated patterns, and enforcing rules across your team.
**ProjectBrain** is a self-improving project memory that documents its own creation. Built on [Cognee Cloud](https://github.com/topoteretes/cognee) and the Model Context Protocol (MCP), it cures "Context Rot" by remembering your architectural decisions, improving recall with each feedback cycle, and enforcing rules across your team.

**Live demo:** [https://brain-production-3699.up.railway.app/](https://brain-production-3699.up.railway.app/)

Built for the **WeMakeDevs × Cognee "Hangover Part AI" Hackathon** (Jun 29 – Jul 5, 2026).

Expand Down Expand Up @@ -62,11 +66,14 @@ npm run dev

## Features

### Dashboard (`localhost:3000`)
### Dashboard (`railway.app`)
- **Force-directed graph** — real-time visualization of knowledge nodes and relationships via SSE
- **Time-line slider** — drag to watch the project evolve from week 1 to week 8, seeing decisions being made and superseded
- **17 search modes** — dropdown selector for all Cognee `SearchType` modes (GRAPH_COMPLETION, GRAPH_COMPLETION_COT, KEYWORD, SIMILARITY, etc.)
- **Search panel** — query the knowledge graph, results shown below the graph
- **Metrics bar** — node/edge counts, memory composition, search latency, recall/review accuracy
- **Inline memory controls** — "Add Decision" form, "Strengthen Memory" button, Recent Activity log, all from the dashboard sidebar
- **Before/after metrics** — snapshot history showing recall improvement after every strengthen cycle
- **Metrics bar** — node/edge counts, memory composition, search latency, recall precision with delta badges
- **SSE auto-reconnect** — stale-data warning banner on disconnect

### MCP Server (stdio)
Expand All @@ -78,12 +85,15 @@ Connect to Cursor, Claude Code, or any MCP-compatible IDE:
- `memify_feedback` — strengthen/confirm a decision
- `forget` — remove a node

### REST API (`localhost:8000`)
- `GET /api/graph` — current knowledge graph
### REST API (`railway.app`)
- `GET /api/graph?week=N` — current knowledge graph (optional week filter for timeline)
- `GET /api/graph/weeks` — available week range for the timeline slider
- `GET /api/stream` — SSE stream of graph updates
- `GET /api/search?q=...&mode=...` — search with any of 17 modes
- `GET /api/search/modes` — list available search modes
- `GET /api/metrics` — live metrics (node/edge counts, composition, latency)
- `GET /api/metrics` — live metrics (node/edge counts, composition, latency, recall precision)
- `GET /api/metrics/history` — snapshot history of metrics after improve() calls
- `POST /api/improve` — trigger Cognee improve() to strengthen recall
- `POST /api/remember/session` — add to session memory
- `POST /api/remember/promote` — promote session to permanent

Expand All @@ -94,12 +104,12 @@ Connect to Cursor, Claude Code, or any MCP-compatible IDE:

| Criteria | How ProjectBrain delivers |
|---|---|
| **Impact** | Stops AI amnesia and architectural regression across the entire engineering team |
| **Creativity** | First of its kind: organizational memory wired directly into AI tools via MCP + CI/CD enforcement |
| **Technical Excellence** | Three-process architecture (SSE backend + MCP server + dashboard) over Cognee's graph-vector hybrid store |
| **Best Use of Cognee** | Maps all 4 verbs (add→cognify, search, improve, forget) across the full 17-mode search spectrum; dual-dataset session memory |
| **UX** | Developer never leaves IDE. MCP tools + real-time dashboard with zero-config SSE streaming |
| **Presentation** | This README, a 3-minute demo video, and a writeup of the architecture and results |
| **Potential Impact** | Kills "context rot" — the #1 productivity killer in AI-assisted development. Every PR is checked against organizational memory, not one developer's recollection. Meta-narrative demonstrates the tool documenting its own creation. |
| **Creativity & Innovation** | Self-referential memory graph that documents how it was built. Timeline slider to watch knowledge evolve. The tool that improves its own recall through usage. |
| **Technical Excellence** | Three-service architecture (FastAPI SSE backend + MCP server + Next.js dashboard) over Cognee Cloud. All 4 lifecycle verbs exposed from a single browser tab. Before/after recall precision metrics. |
| **Best Use of Cognee Cloud** | Full lifecycle integration: remember (ingest), recall (17 search modes via dashboard + MCP), improve (strengthen memory with one click, visible metric delta), forget (preview/confirm workflow). Two-dataset session/permanent memory architecture. |
| **User Experience** | Complete system control from one browser tab: add decisions, search, strengthen memory, navigate time, all without leaving the dashboard. Force-directed graph updates in real-time via SSE. |
| **Presentation Quality** | This criteria-mapped README. 90-second demo video. Live Railway URL. Meta-narrative demo script. |

## Tech Stack

Expand All @@ -111,14 +121,17 @@ Connect to Cursor, Claude Code, or any MCP-compatible IDE:
- **Groq (llama-3.3-70b-versatile)** — LLM for graph completion search
- **GitHub Actions** — CI/CD reviewer agent

## Demo
## Demo (90-second script)

1. **Meta framing** — "This is ProjectBrain. A self-improving project memory that documents its own creation." Graph shows 18 interconnected nodes.
2. **Time slider** — Drag from week 8 to week 1. Watch the architecture evolve: MongoDB → Postgres migration, JWT → session auth, v1 → v2 API.
3. **Search** — Type "Postgres" in GRAPH_COMPLETION mode. Results show the Postgres migration decision with full graph context.
4. **Add decision** — Switch to the Add tab. Type "We use Redis for caching" with rationale. Submit. Graph updates in real-time via SSE.
5. **Strengthen memory** — Click "Strengthen Memory". Watch the recall precision delta badge appear (e.g., "+5.2pp").
6. **Metrics history** — Switch to the Metrics tab. See the snapshot history showing recall improvement over time.
7. **Close** — "And the graph remembers building itself. Every PR, every decision, every superseded pattern is here. ProjectBrain doesn't just remember — it improves."

1. Open `localhost:3000` — seed data visible as a force-directed graph
2. Pick a search mode from the dropdown, type a query — results appear below the graph
3. Use the MCP tools via Cursor/Claude Code to `remember_decision` — graph updates in real-time via SSE
4. Add session context, then `promote_context` to permanent
5. Metrics bar shows node/edge counts, latency, and memory composition
6. CI/CD reviewer blocks PRs with deprecated patterns
[🎥 Demo video](https://youtube.com) (add link after recording)

## License

Expand Down
29 changes: 25 additions & 4 deletions api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@

STATE: dict = {"nodes": [], "links": []}

async def load_graph_from_cognee():
async def load_graph_from_cognee(week: int | None = None):
"""Build graph state from seed items (Cognee Cloud has no local node enumerator)."""
from seed import seed_items
items = [i for i in seed_items if week is None or i["week"] <= week]
nodes, links, file_ids, node_ids = [], [], {}, {}
for item in seed_items:
for item in items:
nid = f"decision:{item['title'].lower().replace(' ', '-')}"
node_ids[item['title']] = nid
group = "incident" if "incident" in item.get("tags", []) else "decision"
Expand All @@ -37,13 +38,14 @@ async def load_graph_from_cognee():
file_ids[fid] = True
nodes.append({"id": fid, "name": f, "group": "file", "val": 10})
links.append({"source": nid, "target": fid, "name": "LINKS_TO"})
for item in seed_items:
for item in items:
if item.get("supersedes") and item["supersedes"] in node_ids:
links.append({"source": node_ids[item["supersedes"]], "target": node_ids[item["title"]], "name": "SUPERSEDES"})
return {"nodes": nodes, "links": links}
search_latencies: deque = deque(maxlen=10)
search_total: int = 0
search_with_results: int = 0
metrics_history: deque = deque(maxlen=10)

async def notify_clients():
data = json.dumps(STATE)
Expand Down Expand Up @@ -72,9 +74,17 @@ async def serve_spa(path: str):
print(f"Serving static dashboard from {static_dir}")

@app.get("/api/graph")
async def get_graph():
async def get_graph(week: int | None = Query(None)):
if week is not None:
return await load_graph_from_cognee(week=week)
return STATE

@app.get("/api/graph/weeks")
async def graph_weeks():
from seed import seed_items
weeks = sorted(set(i["week"] for i in seed_items))
return {"weeks": weeks, "current": max(weeks)}

@app.get("/api/stream")
async def sse_stream(request: Request):
q = asyncio.Queue()
Expand Down Expand Up @@ -185,6 +195,17 @@ async def metrics():
"recall_precision": recall_precision,
}

@app.post("/api/improve")
async def improve():
await cognee.improve(dataset=DATASET, build_truth_subspace=True)
snapshot = await metrics()
metrics_history.append({"t": time.time(), "metrics": snapshot})
return snapshot

@app.get("/api/metrics/history")
async def metrics_history_endpoint():
return list(metrics_history)

class ForgetPreview(BaseModel):
query: str

Expand Down
2 changes: 1 addition & 1 deletion dashboard/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default function Home() {
<main className="max-w-6xl mx-auto flex flex-col gap-8">
<header className="border-b border-gray-800 pb-4">
<h1 className="text-3xl font-semibold tracking-tight">ProjectBrain <span className="text-gray-500">Memory Graph</span></h1>
<p className="text-sm text-gray-400 mt-1">Real-time visualization of your AI's context memory.</p>
<p className="text-sm text-gray-400 mt-1">A self-improving project memory that documents its own creation.</p>
</header>

<section className="flex flex-col gap-4">
Expand Down
Loading
Loading