# Project export: OneContext

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: OneContext creates a shared project memory that gives AI assistants instant access to your project's context, reducing repetitive prompts and improving development productivity across all tools.
- Devpost: https://devpost.com/software/onecontext
- GitHub: https://github.com/varunkumar-2005/Onecontext
- Video: https://www.youtube.com/embed/u8SC5cXMLcU?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 2 GitHub contributor(s) — Varun Kumar S (8 commits), varunkumar-2005 (1 commits)

## Devpost submission (written by the team)

### Inspiration

The idea for OneContext came from our experience working on college projects as a team. When several teammates work on the same application, each person may use a different AI coding assistant or follow a different approach. It became difficult to keep track of decisions, task progress, project files, and the reasoning behind previous work. A teammate might plan a feature in ChatGPT, another might implement it with Codex, and someone else might continue in Claude without knowing the earlier discussion. This often led to repeated work, inconsistent decisions, and confusion about which files were already being changed. We created OneContext to solve this problem by giving the entire team one shared project memory. It allows developers and AI agents to stay aligned around the same goals, decisions, tasks, and project context without forcing everyone to use the same AI tool. AI coding assistants are powerful, but each assistant usually has its own isolated conversation history. When teammates use Codex, Claude, Cursor, or GitHub Copilot on the same project, important decisions can become scattered across different chats. We created OneContext to give the entire team one shared project memory. The goal is to help developers and AI agents stay aligned without forcing everyone to use the same tool.

### What it does

OneContext provides: A shared project brief, sources, decisions, and handoffs Memory Chat for asking questions about the project A knowledge graph connecting files, concepts, and decisions A Chrome extension for transferring project context between ChatGPT and Claude A VS Code extension for Team Codes, task intent, presence, and conflict warnings Realtime collaboration across multiple laptops An MCP server for Codex, GitHub Copilot, Cursor, and other agents A Codex CLI workflow for retrieving project-aware context A teammate can save a project handoff on one device, and another AI agent can retrieve it using the same project ID.

### How we built it

OneContext was built with Next.js, React, TypeScript, PostgreSQL, and WebSockets. Project sources are indexed into searchable chunks, while decisions, tasks, handoffs, file references, and activity are stored as structured project memory. The system retrieves relevant context instead of blindly copying complete conversations. The Chrome extension uses Manifest V3 content scripts to add context to ChatGPT and Claude. The VS Code extension uses the VS Code API to track active files, publish task intent, show teammates, and save handoffs. We also built a local MCP server that exposes tools such as: onecontext_get_context onecontext_check_conflicts onecontext_publish_update onecontext_save_handoff Codex with GPT-5.6 accelerated the build by helping design the architecture, implement the backend and extensions, debug networking and MCP issues, improve the interface, create tests, package the VSIX, and prepare the final demo.

### Challenges we ran into

The biggest challenges were making the system work across multiple tools and devices. We had to debug: Realtime communication between two laptops Local Wi-Fi and firewall configuration VS Code Extension Development Host behavior VSIX packaging and versioning MCP initialization and JSON-RPC communication Gateway authentication Chrome prompt detection Preventing unrelated prompts from receiving project context We also had to carefully decide what should become shared memory. Saving every raw chat would create noise and could expose private information, so we focused on concise project knowledge.

### Accomplishments we're proud of

We are proud that OneContext connects several independent workflows into one working system. The project demonstrates: ChatGPT-to-Claude project continuity Shared memory between two laptops Team Codes and live teammate presence Conflict warnings for overlapping work Persistent PostgreSQL project memory A working Chrome extension A packaged VS Code extension MCP-based retrieval for AI coding agents Privacy-aware storage of decisions and handoffs A polished dashboard with sources, chat, graph, timeline, and settings OneContext does not replace Git or any AI assistant. It gives the team a common context layer so everyone can work toward the same goal.

### What we learned

We learned that useful AI memory should be selective and structured. Project goals, decisions, tasks, file references, and concise summaries are more valuable than storing entire conversations. We also learned that provider independence is important. Teams should be able to use different AI assistants while still sharing the same project knowledge. Finally, live presence is most useful as a coordination signal. It can warn teammates about possible overlap, but it should not act as a hard lock that prevents developers from working.

### What's next

The next steps are: Deploy the web application and realtime service for remote teams Add stronger authentication and project-level authorization Support additional agents such as Claude Code, Cursor, Windsurf, and Antigravity Improve semantic memory extraction and deduplication Add richer file and symbol-level conflict detection Add GitHub synchronization for private repositories Add Redis-backed durable realtime presence Provide project analytics and memory-quality controls Improve privacy controls for individual memory items Add production-grade audit logs and team administration

## README (from the GitHub repository)

# OneContext

> A shared project memory and coordination layer for teams using different AI coding agents.

**Submission category:** Developer tools

OneContext helps a team of developers keep ChatGPT, Claude, Codex, GitHub Copilot, Cursor, and VS Code aligned around the same project. It stores useful project knowledge, retrieves only relevant context, shows live teammate intent, and warns when parallel work may overlap.

## Demo video

[Watch the OneContext demo on YouTube](https://www.youtube.com/watch?v=u8SC5cXMLcU)

## The problem

When four developers work on one repository with different AI assistants, each assistant sees a different conversation history. Important decisions stay trapped in one chat, teammates repeat work, and two people can unknowingly edit the same area.

OneContext creates a shared project layer between the team and their AI tools:

```text
Project sources, decisions, tasks, and live intent
                         |
                         v
              OneContext memory and gateway
                 /          |          \
                v           v           v
        Web dashboard   Chrome add-context   MCP / VS Code
        Memory Chat     ChatGPT + Claude     Codex + Copilot
```

The assistants remain independent. OneContext does not replace them or require the whole team to use the same provider.

## What is included

- **Project workspace:** Create/select projects and maintain a project goal and sprint brief.
- **Connected sources:** Upload Markdown/text notes and add a GitHub repository URL for indexing.
- **Memory Chat:** Ask questions about architecture, decisions, files, tasks, and project history.
- **Structured memory:** Keep concise decisions, handoffs, tasks, and project activity instead of blindly copying every conversation.
- **Knowledge Graph:** Visualize relationships between files, concepts, and decisions.
- **Decision timeline:** Review why important project choices were made.
- **Chrome extension:** Add relevant project context to ChatGPT and Claude with one button.
- **OneContext Live:** Create a Team Code, publish task intent, see active teammates, and detect overlapping work.
- **VS Code extension:** Join a team, automatically publish active-file/saved-file presence, ask Codex with team context, and save handoffs.
- **MCP server:** Give compatible coding agents a common interface for context, conflict checks, progress updates, and handoffs.
- **Codex-first CLI:** Print a context-enriched prompt for a terminal-callable Codex workflow.

## Architecture

| Layer | Implementation |
| --- | --- |
| Web application | Next.js 14, React, TypeScript |
| Persistent storage | PostgreSQL; the schema is in `infra/db/schema.sql` |
| Retrieval | Project-aware source chunking, local embeddings, optional OpenAI embeddings, and optional AI reranking |
| AI features | Optional OpenAI-powered routing, memory selection, answers, and conversation distillation |
| Live collaboration | Node/TypeScript WebSocket service; optional Redis-backed persistence |
| Browser adapter | Manifest V3 Chrome extension for ChatGPT and Claude |
| Editor adapter | VS Code extension packaged as `onecontext-vscode-0.1.2.vsix` |
| Agent adapter | MCP server plus Codex context wrapper |

### Runtime behavior

1. A user adds project sources, notes, decisions, or live intent.
2. OneContext stores project-scoped information in PostgreSQL.
3. A question is routed to the active project and relevant memories are retrieved.
4. The dashboard, Chrome extension, MCP server, or Codex wrapper receives a compact context block.
5. A teammate or AI agent can continue from the same decisions and active work.

The application works without an OpenAI API key by using local routing and retrieval fallbacks. OpenAI-powered features are optional and configured only on the server.

## Prerequisites

Install these before running the project:

- Node.js 18 or newer (Node.js 20 or 22 LTS is recommended)
- npm
- PostgreSQL 14 or newer
- Git
- Google Chrome, for the browser extension demo
- VS Code, for the live team and MCP demos
- Optional: Docker Desktop for Redis-backed realtime presence
- Optional: an OpenAI API key for AI routing, reranking, answers, or memory distillation

## Quick start: run the web app locally

### 1. Clone and install

```powershell
git clone https://github.com/varunkumar-2005/Onecontext.git
cd Onecontext
npm install
```

### 2. Create PostgreSQL

Create a database named `onecontext` in PostgreSQL. The database user must have permission to create tables and extensions used by the schema.

For a local PostgreSQL installation, a connection string looks like this:

```text
postgresql://postgres:<YOUR_PASSWORD>@localhost:5432/onecontext
```

Do not put a real password in this README or commit it to Git.

### 3. Create `.env.local`

Copy the template:

```powershell
Copy-Item .env.example .env.local
```

Then edit `.env.local`. A safe local example is:

```env
DATABASE_URL=postgresql://postgres:<YOUR_PASSWORD>@localhost:5432/onecontext
SESSION_SECRET=replace-with-a-long-random-secret

# Shared gateway authentication. Keep this private.
ONECONTEXT_GATEWAY_KEY=replace-with-a-local-gateway-key

# The project used by the demo.
ONECONTEXT_PROJECT_ID=atlas-project

# Optional AI features. Leave OPENAI_API_KEY empty to use local fallbacks.
OPENAI_API_KEY=
ONECONTEXT_USE_OPENAI_EMBEDDINGS=false
ONECONTEXT_USE_AI_ROUTING=true
ONECONTEXT_CONTEXT_ROUTER_MODEL=gpt-4o-mini
ONECONTEXT_USE_AI_RETRIEVAL=false
ONECONTEXT_USE_AI_ANSWERS=true
ONECONTEXT_USE_AI_CONVERSATION_MEMORY=false
ONECONTEXT_AI_MODEL=gpt-4o-mini

# Realtime service.
REALTIME_PORT=8787
ONECONTEXT_REALTIME_URL=ws://localhost:8787/live
REDIS_URL=redis://localhost:6379
```

The exact values in your `.env.local` are private. Never commit database passwords, OpenAI keys, session secrets, or gateway keys.

### 4. Initialize the schema

Run this once after PostgreSQL is available:

```powershell
npm run db:init
```

The initializer reads `DATABASE_URL`, creates the configured database if needed, and applies `infra/db/schema.sql`.

### 5. Start the app and realtime service

Use two PowerShell terminals from the repository root.

Terminal 1 - web application:

```powershell
npm run dev
```

Terminal 2 - live team presence:

```powershell
npm run realtime
```

Open:

- Dashboard: [http://localhost:3000](http://localhost:3000)
- Login: [http://localhost:3000/login](http://localhost:3000/login)
- Live team page: [http://localhost:3000/team](http://localhost:3000/team)

If the local seed is present, the demo account is:

```text
Email:    suresh@example.com
Password: demo1234
```

Change or remove demo credentials before deploying the project publicly.

## Dashboard walkthrough

After signing in, use the project navigation as follows:

| Page | Use |
| --- | --- |
| `/` | Project overview, memory metrics, connected sources, recent activity, and a quick project question |
| `/sources` | Upload Markdown/text files, add team notes, and connect a GitHub repository URL |
| `/brief` | Set the shared project goal and current sprint focus |
| `/chat` | Ask a grounded question about the active project memory |
| `/graph` | Explore relationships between files, concepts, and decisions |
| `/decisions` | Record decisions and their rationale |
| `/timeline` | Review project events in chronological order |
| `/team` | Create/share a Team Code, publish live intent, and see active teammates |
| `/settings` | Review project and provider configuration |

### Sample source data

For a first demo, upload or add notes containing content such as:

```markdown
# Sprint planning

Goal: Build one shared memory for a four-person AI-assisted team.
Current sprint: Capture activity and align the team's AI coding agents.

Decision: Keep retrieval provider-agnostic so each developer can keep using
their preferred coding assistant.
```

Then ask Memory Chat:

```text
What is the current project goal, what decision has the team made abo

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 77 recognized source files, 350 KB.
- CSS (language) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- PostgreSQL (technology) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- TypeScript (language) — detected in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- OpenAI (technology) — claimed on Devpost, not found in the code
- Redis (technology) — claimed on Devpost, not found in the code
- AI coding agent: Codex — evidence: config files committed to the repository
- AI coding agent: Cursor — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (100 of 100)

```
.codex/config.toml
.cursor/mcp.json
.env.example
.gitignore
.mcp.json
.onecontext/agent-workflow.md
.vscode/mcp.json
AGENTS.md
apps/realtime-sync/Dockerfile
apps/realtime-sync/package.json
apps/realtime-sync/src/presence.ts
apps/realtime-sync/src/server.ts
apps/realtime-sync/tsconfig.json
apps/vscode-extension/.vscode/launch.json
apps/vscode-extension/onecontext-vscode-0.1.0.vsix
apps/vscode-extension/onecontext-vscode-0.1.2.vsix
apps/vscode-extension/package.json
apps/vscode-extension/README.md
apps/vscode-extension/src/extension.ts
apps/vscode-extension/tsconfig.json
browser-extension/background.js
browser-extension/content.css
browser-extension/content.js
browser-extension/manifest.json
browser-extension/popup.css
browser-extension/popup.html
browser-extension/popup.js
browser-extension/README.md
DEVPOST_SUBMISSION.md
docker-compose.live.yml
infra/db/schema.sql
LICENSE
next-env.d.ts
next.config.mjs
OneContext_Live_Addon.md
OneContext_Live_BuildPlan.md
OneContext_SRD.md
package.json
README.md
scripts/init-db.mjs
scripts/onecontext-agent.mjs
scripts/onecontext-demo-teammate.mjs
scripts/onecontext-mcp.mjs
src/app/api/v1/auth/login/route.ts
src/app/api/v1/auth/logout/route.ts
src/app/api/v1/auth/me/route.ts
src/app/api/v1/auth/signup/route.ts
src/app/api/v1/chat/route.ts
src/app/api/v1/context/retrieve/route.ts
src/app/api/v1/gateway/[provider]/inject/route.ts
src/app/api/v1/gateway/agent-update/route.ts
src/app/api/v1/gateway/conversations/turns/route.ts
src/app/api/v1/gateway/handoff/route.ts
src/app/api/v1/gateway/verify/route.ts
src/app/api/v1/health/route.ts
src/app/api/v1/projects/[id]/activity/route.ts
src/app/api/v1/projects/[id]/brief/route.ts
src/app/api/v1/projects/[id]/context/route.ts
src/app/api/v1/projects/[id]/decisions/route.ts
src/app/api/v1/projects/[id]/graph/route.ts
src/app/api/v1/projects/[id]/route.ts
src/app/api/v1/projects/[id]/settings/route.ts
src/app/api/v1/projects/[id]/sources/route.ts
src/app/api/v1/projects/[id]/timeline/route.ts
src/app/api/v1/projects/route.ts
src/app/api/v1/teams/events/route.ts
src/app/api/v1/teams/join/route.ts
src/app/api/v1/teams/presence/route.ts
src/app/api/v1/teams/route.ts
src/app/brief/page.tsx
src/app/chat/page.tsx
src/app/decisions/page.tsx
src/app/globals.css
src/app/graph/page.tsx
src/app/layout.tsx
src/app/login/page.tsx
src/app/page.tsx
src/app/redesign.css
src/app/settings/page.tsx
src/app/sources/page.tsx
src/app/structured.css
src/app/team/page.tsx
src/app/timeline/page.tsx
src/components/project-ui.tsx
src/lib/ai-decisions.ts
src/lib/auth.ts
src/lib/chunking.test.ts
src/lib/chunking.ts
src/lib/context-routing.test.ts
src/lib/context-routing.ts
src/lib/db.ts
src/lib/embeddings.test.ts
src/lib/embeddings.ts
src/lib/github-source.ts
src/lib/hybrid.ts
src/lib/live.ts
src/lib/persistent-store.ts
src/lib/store.ts
src/middleware.ts
tsconfig.json
```

### Dependencies

- apps/vscode-extension/package.json: @types/node@^20.14.15, @types/vscode@^1.105.0, @types/ws@^8.18.1, typescript@^5.5.4, ws@^8.18.3
- package.json: @types/node@^20.14.15, @types/pg@^8.20.0, @types/react@^18.3.3, @types/react-dom@^18.3.0, @types/vscode@^1.125.0, @types/ws@^8.18.1, ioredis@^5.11.1, next@14.2.32, pg@^8.22.0, react@18.3.1, react-dom@18.3.1, tsx@^4.23.1, typescript@^5.5.4, ws@^8.21.1

### Recent commits (newest first)

- docs: add demo video link
- docs: add complete setup and submission guide
- Improve MCP API error handling
- Fix MCP API connection from VS Code
- Fix VS Code MCP initialization
- Fix authenticated VS Code handoffs
- Merge branch 'main' of https://github.com/varunkumar-2005/Onecontext
- Initial OneContext MVP
- Initial commit

## Key source files (fetched from GitHub, selected and truncated for size)

### AGENTS.md

```markdown
# OneContext team protocol

Before making architectural changes, read `.onecontext/live-context.md` when it exists. It contains current teammate activity generated by the OneContext VS Code extension.

For Codex-first project questions, use the shared-context wrapper so the prompt includes the current project brief, recent activity, live presence, decisions, and relevant sources:

```powershell
npm run onecontext:agent -- codex "your project question"
```

Do not treat live presence as a hard lock. Coordinate overlapping work and record important decisions in OneContext.

## Shared-agent workflow

When the local `onecontext` MCP server is configured, use it before meaningful implementation work:

1. Call `onecontext_get_context` with the task you are about to perform.
2. Call `onecontext_check_conflicts` before changing a file that may overlap with teammate work.
3. Call `onecontext_publish_update` after a meaningful decision or progress update.
4. Call `onecontext_save_handoff` after completing a substantive agent turn so the next teammate or agent receives distilled shared memory.

```

### DEVPOST_SUBMISSION.md

```markdown
# OneContext - Devpost submission copy

Use the following content when completing the Devpost form. Replace the repository URL, public demo URL, and Codex `/feedback` session ID with the final values before submitting.

## Category

Developer tools

## Project description

OneContext is a shared project memory and coordination layer for teams using different AI coding assistants. Four developers can work on the same repository with ChatGPT, Claude, Codex, GitHub Copilot, Cursor, or VS Code while sharing the same project brief, decisions, useful source material, task handoffs, and live work intent.

The project combines a Next.js dashboard, PostgreSQL memory, a Chrome extension for ChatGPT and Claude, a VS Code extension for live team presence, and an MCP server for AI coding agents. A teammate can create a Team Code, publish the file or area they are working on, and let others see active work before they edit the same area. The conflict radar is a coordination warning, while Git remains responsible for source control and merging.

The Chrome extension demonstrates continuity between AI assistants: a user asks a project question in ChatGPT, clicks **Add context**, then opens Claude and clicks **Add context** again. Claude receives the relevant project memory without requiring the user to manually copy the full previous conversation.

The VS Code and MCP demonstrations show the team workflow: one laptop saves a structured handoff, and another laptop's MCP-enabled agent retrieves that shared project context using the same project ID.

## How it works

1. Add a project goal, sprint brief, notes, Markdown files, decisions, or a GitHub source.
2. OneContext stores project-scoped information in PostgreSQL and retrieves relevant context for each question.
3. The dashboard, Chrome extension, VS Code extension, Codex wrapper, or MCP server provides the compact context block to the selected AI tool.
4. The VS Code extension publishes active-file and task intent, shows presence, and warns when teammates appear to overlap.
5. Handoffs and important decisions become reusable shared memory for the next person or agent.

## How Codex and GPT-5.6 Accelerated the Build

Codex with GPT-5.6 was used throughout the development of OneContext as the primary coding and reasoning partner. It helped transform the initial product specification into a working architecture, generate the Next.js and PostgreSQL implementation, build the Chrome and VS Code extensions, create the realtime team-presence service, and implement the MCP integration for AI coding agents.

Codex also accelerated debugging and iteration. It helped diagnose local-network issues between two laptops, VS Code extension activation problems, stale VSIX packages, MCP initialization failures, and authenticated handoff errors. It also helped create tests, improve the dashboard UI, write documentation, and prepare the final demo workflow.

Key technical decisions made during development included:

- Use provider
[truncated — 1752 more characters]
```

### package.json

```
{
  "name": "onecontext",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "db:init": "node scripts/init-db.mjs",
    "test": "tsx --test src/lib/*.test.ts",
    "realtime": "tsx apps/realtime-sync/src/server.ts",
    "vscode:compile": "tsc -p apps/vscode-extension"
    ,"onecontext:agent": "node scripts/onecontext-agent.mjs",
    "onecontext:codex": "node scripts/onecontext-agent.mjs codex",
    "demo:teammate": "node scripts/onecontext-demo-teammate.mjs"
  },
  "dependencies": {
    "ioredis": "^5.11.1",
    "next": "14.2.32",
    "pg": "^8.22.0",
    "react": "18.3.1",
    "react-dom": "18.3.1",
    "ws": "^8.21.1"
  },
  "devDependencies": {
    "@types/node": "^20.14.15",
    "@types/pg": "^8.20.0",
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "@types/vscode": "^1.125.0",
    "@types/ws": "^8.18.1",
    "tsx": "^4.23.1",
    "typescript": "^5.5.4"
  }
}

```

### apps/realtime-sync/package.json

```
{
  "name": "onecontext-realtime-sync",
  "private": true,
  "scripts": { "dev": "tsx src/server.ts", "start": "tsx src/server.ts" }
}

```

### apps/realtime-sync/Dockerfile

```
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY apps/realtime-sync ./apps/realtime-sync
CMD ["npm", "run", "realtime"]

```

### apps/vscode-extension/package.json

```
{
  "name": "onecontext-vscode",
  "displayName": "OneContext Live",
  "description": "Shared project memory and live teammate presence for OneContext.",
  "version": "0.1.2",
  "publisher": "onecontext-local",
  "engines": { "vscode": "^1.105.0" },
  "categories": ["Other"],
  "files": ["dist/**", "package.json", "README.md", "node_modules/ws/**"],
  "main": "./dist/extension.js",
  "activationEvents": ["onStartupFinished"],
  "contributes": {
    "commands": [
      { "command": "onecontext.joinTeam", "title": "OneContext: Join Team" },
      { "command": "onecontext.startTask", "title": "OneContext: Start Task" },
      { "command": "onecontext.completeTask", "title": "OneContext: Complete Task and Save Handoff" },
      { "command": "onecontext.configureGatewayKey", "title": "OneContext: Configure Gateway Key" },
      { "command": "onecontext.leaveTeam", "title": "OneContext: Leave Team" },
      { "command": "onecontext.askCodex", "title": "OneContext: Ask Codex with Team Context" }
    ],
    "configuration": {
      "title": "OneContext",
      "properties": {
        "onecontext.automaticPresence": { "type": "boolean", "default": true, "description": "Automatically broadcast active-editor and saved-file work after a short delay." },
        "onecontext.apiBaseUrl": { "type": "string", "default": "http://localhost:3000", "description": "OneContext API URL" },
        "onecontext.realtimeUrl": { "type": "string", "default": "ws://localhost:8787/live", "description": "OneContext realtime WebSocket URL" },
        "onecontext.projectRoot": { "type": "string", "default": "", "description": "Absolute OneContext project root when the extension is installed outside the repository" },
        "onecontext.codexCommand": { "type": "string", "default": "", "description": "Terminal-callable Codex command. Leave empty to preview enriched context." },
        "onecontext.codexArgs": { "type": "string", "default": "exec", "description": "Arguments passed to the configured Codex command" }
      }
    },
    "views": { "explorer": [{ "id": "onecontextPresence", "name": "OneContext Team", "type": "webview" }] }
  },
  "scripts": { "compile": "tsc -p .", "package": "npm run compile && npx @vscode/vsce package" },
  "dependencies": { "ws": "^8.18.3" },
  "devDependencies": { "@types/node": "^20.14.15", "@types/vscode": "^1.105.0", "@types/ws": "^8.18.1", "typescript": "^5.5.4" }
}

```

### src/app/layout.tsx

```typescript
import type { Metadata } from "next";
import "./globals.css";
import "./redesign.css";

export const metadata: Metadata = {
  title: "OneContext — Project memory for every AI",
  description: "A shared, searchable memory layer for your AI coding tools.",
};

export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

```

### src/app/page.tsx

```typescript
"use client";

import { ChangeEvent, FormEvent, useEffect, useMemo, useRef, useState } from "react";

type Source = { id?: string; name: string; type: "Markdown" | "GitHub" | "Notes"; status: "Indexed" | "Syncing" | "Ready" | "Pending"; detail: string };
type WorkspaceProject = { id: string; name: string; description: string; createdAt: string };

const navItems = [
  { icon: "⌂", label: "Overview", href: "/" },
  { icon: "◇", label: "Sources", href: "/sources" },
  { icon: "✦", label: "Memory chat", href: "/chat" },
  { icon: "⌘", label: "Knowledge Graph", href: "/graph" },
  { icon: "◷", label: "Decision timeline", href: "/timeline" },
  { icon: "◎", label: "OneContext Live", href: "/team" },
  { icon: "↗", label: "Share Project Brief", href: "/brief" },
  { icon: "⚙", label: "Project Settings", href: "/settings" },
];

function sourceIcon(type: Source["type"]) { return type === "GitHub" ? "GH" : type === "Notes" ? "N" : "M"; }

export default function Home() {
  const [projects, setProjects] = useState<WorkspaceProject[]>([]);
  const [activeProject, setActiveProject] = useState<WorkspaceProject>({ id: "atlas-project", name: "Atlas project", description: "", createdAt: "" });
  const [sources, setSources] = useState<Source[]>([]);
  const [query, setQuery] = useState("");
  const [notice, setNotice] = useState("");
  const [showSourceModal, setShowSourceModal] = useState(false);
  const [showProjectModal, setShowProjectModal] = useState(false);
  const [showUserMenu, setShowUserMenu] = useState(false);
  const [projectName, setProjectName] = useState("");
  const [projectGoal, setProjectGoal] = useState("");
  const [projectFile, setProjectFile] = useState<File | null>(null);
  const [creating, setCreating] = useState(false);
  const sourceFileRef = useRef<HTMLInputElement>(null);
  const userMenuRef = useRef<HTMLDivElement>(null);

  function announce(message: string) { setNotice(message); window.setTimeout(() => setNotice(""), 3500); }
  function persistProject(project: WorkspaceProject) { window.localStorage.setItem("onecontext.activeProjectId", project.id); window.localStorage.setItem("onecontext.activeProjectName", project.name); window.dispatchEvent(new Event("onecontext:project-changed")); }

  useEffect(() => {
    fetch("/api/v1/projects").then((response) => response.json()).then((data) => {
      if (!Array.isArray(data.projects)) return;
      setProjects(data.projects);
      const saved = data.projects.find((project: WorkspaceProject) => project.id === window.localStorage.getItem("onecontext.activeProjectId"));
      const next = saved || data.projects[0];
      if (next) { setActiveProject(next); persistProject(next); }
    }).catch(() => announce("Could not load your projects."));
  }, []);

  useEffect(() => {
    fetch(`/api/v1/projects/${encodeURIComponent(activeProject.id)}/sources`).then((response) => response.json()).then((data) => {
      if (!Array.isArray(data.sources)) return;
      setSources(data.sources.map((source: { id: string; name: string; type: string; status: string; chunkCount: number; lastIndexedAt: string | null }) => ({
        id: source.id, name: source.name, type: source.type === "github" ? "GitHub" : source.type === "notes" ? "Notes" : "Markdown",
        status: source.status === "parsing" ? "Syncing" : source.status === "indexed" ? "Indexed" : "Pending",
        detail: `${source.chunkCount} chunk${source.chunkCount === 1 ? "" : "s"}${source.lastIndexedAt ? " · indexed" : " · waiting"}`,
      })));
    }).catch(() => announce("Could not load project sources."));
  }, [activeProject.id]);

  useEffect(() => {
    const close = (event: MouseEvent) => { if (userMenuRef.current && !userMenuRef.current.contains(event.target as Node)) setShowUserMenu(false); };
    document.addEventListener("mousedown", close); return () => document.removeEventListener("mousedown", close);
  }, []);

  const indexedCount = useMemo(() => sources.filter((source) => source.status === "Indexed").length, [sources]);

  function switchProject(id: string) {
    const next = projects.find((project) => project.id === id); if (!next) return;
    setActiveProject(next); persistProject(next); announce(`Switched to ${next.name}.`);
  }

  async function uploadFile(projectId: string, file: File) {
    const form = new FormData(); form.append("file", file);
    const response = await fetch(`/api/v1/projects/${encodeURIComponent(projectId)}/sources`, { method: "POST", body: form });
    if (!response.ok) { const data = await response.json().catch(() => ({})); throw new Error(data.error?.message || "The file could not be indexed."); }
    return response.json();
  }

  async function createProject(event: FormEvent) {
    event.preventDefault(); if (!projectName.trim() || creating) return;
    setCreating(true);
    try {
      const response = await fetch("/api/v1/projects", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: projectName.trim(), description: projectGoal.trim() }) });
      const data = await response.json(); if (!response.ok) throw new Error(data.error?.message || "Could not create this project.");
      const project = data.project as WorkspaceProject;
      if (projectFile) await uploadFile(project.id, projectFile);
      setProjects((current) => [...current, project]); setActiveProject(project); persistProject(project);
      setProjectName(""); setProjectGoal(""); setProjectFile(null); setShowProjectModal(false);
      announce(`${project.name} is ready${projectFile ? " and its first file is indexed" : ""}. Open OneContext Live to invite teammates.`);
    } catch (error) { announce(error instanceof Error ? error.message : "Could not create this project."); }
    finally { setCreating(false); }
  }

  async function addSource(event: ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0]; if (!file) return;
    try { const data = await uploadFile(activeProject.id, file); setSources((current) => [{ i
[truncated — 9512 more characters]
```

### src/app/timeline/page.tsx

```typescript
"use client";

import "../structured.css";
import { useEffect, useState } from "react";
import { ProjectPageHeader, useActiveProject } from "@/components/project-ui";

type TimelineEvent = { id: string; type: string; title: string; detail: string; createdAt: string };
export default function TimelinePage() { const project = useActiveProject(); const [events, setEvents] = useState<TimelineEvent[]>([]); useEffect(() => { fetch(`/api/v1/projects/${encodeURIComponent(project.id)}/timeline`).then((response) => response.json()).then((data) => setEvents(data.events ?? [])); }, [project.id]); return <main className="structured-page"><ProjectPageHeader /><section className="structured-shell"><div className="structured-eyebrow">PROJECT TIMELINE</div><h1>What changed, and when.</h1><p>A chronological view of {project.name} memory as sources are indexed and decisions are recorded.</p><div className="timeline-list">{events.map((event) => <article className="timeline-item" key={event.id}><div className={`timeline-dot ${event.type}`} /><div className="timeline-content"><div className="decision-date">{new Date(event.createdAt).toLocaleString()}</div><h2>{event.title}</h2><p>{event.detail}</p></div></article>)}</div></section></main>; }

```

### src/app/login/page.tsx

```typescript
"use client";
import "../structured.css";
import { FormEvent, useState } from "react";

export default function LoginPage() {
  const [email, setEmail] = useState("suresh@example.com"); const [password, setPassword] = useState("demo1234"); const [error, setError] = useState(""); const [loading, setLoading] = useState(false);
  async function submit(event: FormEvent) { event.preventDefault(); setLoading(true); setError(""); try { const response = await fetch("/api/v1/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }) }); if (!response.ok) { const data = await response.json(); throw new Error(data.error?.message || "Unable to sign in"); } window.location.href = "/"; } catch (caught) { setError(caught instanceof Error ? caught.message : "Unable to sign in"); } finally { setLoading(false); } }
  return <main className="auth-page"><div className="auth-card"><div className="auth-brand"><span>◒</span> OneContext</div><div className="structured-eyebrow">PROJECT MEMORY</div><h1>Welcome back.</h1><p>Sign in to continue to your project workspace.</p><form onSubmit={submit}><label>Email<input type="email" value={email} onChange={(event) => setEmail(event.target.value)} /></label><label>Password<input type="password" value={password} onChange={(event) => setPassword(event.target.value)} /></label>{error && <div className="auth-error">{error}</div>}<button disabled={loading}>{loading ? "Signing in…" : "Sign in"}</button></form><div className="demo-hint">Demo account: <strong>suresh@example.com</strong> / <strong>demo1234</strong></div></div></main>;
}

```

[67 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]