# Project export: Praxis

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: UC Berkeley AI Hackathon 2025
- Tagline: Praxis: AI-powered notes that write themselves. As you type, relevant content from your docs appears instantly. Built-in Claude 4. Upload PDFs, get cited answers, study smarter.
- Devpost: https://devpost.com/software/praxis-ak2vqg
- GitHub: https://github.com/seanesla/praxisforberkeley
- Team: 1 GitHub contributor(s) — sean esla (5 commits)

## Devpost submission (written by the team)

No Devpost description available.

## README (from the GitHub repository)

# Praxis: Your Ideas, Realized.

<div align="center">
  <h3>🚀 A Revolutionary AI-Powered Knowledge Management System</h3>
  
  <p>
    <strong>Built by:</strong> Sean Esla • Saif Alnaqbi • Kai Shinoda
  </p>
</div>

---

## Inspiration
In a world overflowing with powerful productivity tools, we found a strange paradox: the most feature-rich note-taking apps like Notion and Obsidian often come with a steep learning curve that alienates beginners. Users are forced to choose between overwhelming complexity and simplistic, uninspired design.
We asked: Why can't a note-taking app be both powerful and intuitive? Why can't it adapt to how we think, instead of forcing us to adapt to it?
Praxis is our answer. It's designed to be the ultimate thinking tool, a smart canvas that helps you transform theory into practice. It connects your ideas, grounds your research, and even talks back to you, all through a beautifully simple interface.

## What It Does
Praxis is a next-generation, AI-powered note-taking application designed for deep thinking and effortless learning. It seamlessly integrates several key innovations:

### Core Features

#### 🎯 Unified Workspace
No more hunting through tabs or complex navigation. Praxis features a revolutionary unified workspace where everything is accessible through:
- **Command Palette (⌘K)**: Natural language commands to navigate anywhere instantly
- **Smart Activity Feed**: Your recent work and AI-powered suggestions in one place
- **Floating AI Assistant**: Always-available help without leaving your current task

#### ✨ Instant Context Retrieval
The flagship feature that makes Praxis magical. As you write in Smart Notes:
- AI quietly monitors your typing patterns
- When you pause, relevant content from your documents appears as ghost text
- Press Tab to accept suggestions, keep typing to ignore
- Source attribution shows exactly where information comes from
- No popups or interruptions - just the right information at the right moment

#### 🧠 Grounded AI & Source-Based Learning
Eliminate AI hallucinations and get trustworthy answers. Our "Grounded AI" feature restricts the AI's knowledge base to only the documents you provide. Ask complex questions and get perfectly accurate, cited answers in seconds.

#### 🎙️ Interactive "Podcast Mode"
Your notes are no longer static. Engage in a real-time conversation with your personal AI about your documents and ideas. Use it to study for a test, rehearse a presentation, or explore a topic from a new perspective.

#### 🗺️ Visual-First Thinking (Interactive Mind Maps)
Don't just write notes—see them. Praxis can instantly transform your documents or brainstormed lists into interactive, aesthetically pleasing mind maps, helping you find hidden connections and grasp complex topics at a glance.

#### 🤖 Built-in Claude 4 Sonnet
Experience the power of Claude 4 Sonnet, one of the most advanced AI models available, built directly into Praxis - no API keys required.


### Advanced AI-Powered Features

#### Learning & Study Tools
- **Socratic Dialogue Method**: Engage in guided learning through AI-powered questioning that helps deepen understanding
- **Spaced Repetition System**: Scientifically-proven flashcard system using SM-2 algorithm for optimal memory retention
- **Interactive Exercise Engine**: Auto-generated quizzes with 8 different exercise types tailored to your content
- **Smart Note-Taking**: AI-powered note suggestions, Cornell notes support, and automatic organization
- **Knowledge Gap Detection**: AI identifies what you might be missing in your learning journey

#### Document Intelligence
- **Document DNA Fingerprinting**: Unique visual representation of document characteristics and complexity
- **Citation Network Analysis**: Visualize how your documents reference and relate to each other
- **Semantic Search 2.0**: Natural language search with query expansion and contextual understanding
- **Cross-Document Insights**: Discover hidden connections and patterns across your entire document collection
- **Auto-Summarization**: Get instant summaries at multiple levels (brief, comprehensive, technical)

#### Productivity & Workflow
- **Document Workspace**: Multi-document environment with synchronized scrolling and split-screen views
- **Smart Reports Generator**: Create professional reports from your documents with customizable templates
- **Workflow Automation**: Visual workflow builder to chain AI operations and automate repetitive tasks
- **Real-time Analytics**: Track your learning progress and document usage with detailed visualizations

### What Makes Praxis Different

#### Intelligent Interface Design
- **Adaptive UI**: The interface morphs based on what you're doing - no mode switching required
- **Progressive Disclosure**: Features appear when you need them, stay hidden when you don't
- **Context-Aware Actions**: Smart suggestions based on your current task
- **Natural Language Everything**: Talk to Praxis like a colleague, not a computer

#### Thoughtful Productivity Features
- **Smart Notes**: Write with AI-powered suggestions from your knowledge base
- **Semantic Search**: Find information using natural language, not just keywords
- **Visual Source Highlighting**: Automatically scrolls to and highlights exact passages used in AI responses
- **AI-Generated Flashcards**: Turn any document into a study session with one click
- **"Change Perspective" Mode**: Re-explain concepts from different viewpoints
- **Export Everything**: Markdown, PDF, images - your knowledge, your way

## How We Built It: The Tech Stack
- **Frontend**: Next.js 14, TypeScript, Tailwind CSS, Framer Motion, React DnD, ReactFlow
- **Backend**: Node.js, Express, Socket.io for real-time features
- **AI Integration**: Claude 4 Sonnet via Anthropic SDK, LangChain for RAG, Vapi for voice
- **Vector Storage**: ChromaDB for semantic search and document embeddings
- **Database**: Supabase for authentication and data persistence
- **UI Libraries**: Headless UI, Heroicons, Chart.js, D3.js
- **Performance**: Lazy loading, debouncing, web workers for heavy computations

## AI Model
Praxis is powered by **Claude 4 Sonnet**, Anthropic's most advanced AI model, providing:
- Exceptional reasoning and analysis capabilities
- Superior understanding of context and nuance
- Reliable, grounded responses based on your documents
- No API key management required

## 🎥 Demo

### See Praxis in Action

**Instant Context Retrieval** - Watch how Praxis helps you write:
1. Start typing in Smart Notes
2. Pause for a moment
3. Relevant content from your documents appears as ghost text
4. Press Tab to accept, keep typing to ignore

**Command Palette Navigation** - Everything at your fingertips:
- Press ⌘K from anywhere
- Type what you want: "write a note", "find climate papers", "create flashcards"
- Praxis understands and takes you there instantly

**Unified Workspace** - No more tab hunting:
- Activity feed shows your recent work
- Floating AI assistant for quick questions
- Context-aware actions based on what you're doing

## System Requirements

### Desktop-Only Application
Praxis is optimized for desktop use and requires:
- **Minimum screen width**: 1280px
- **Supported browsers**: Chrome, Firefox, Safari, Edge (latest versions)
- **Operating systems**: Windows, macOS, Linux
- **Note**: Mobile devices are not supported. The application requires a desktop or laptop computer for optimal experience.

## Getting Started

### Prerequisites
- Node.js 18+ and npm
- Supabase account and project
- No API keys needed (Claude 4 Sonnet is built-in)

### Installation
1. Clone the repository:
   ```bash
   git clone https://github.com/seanesla/praxisforberkeley.git
   cd praxisforberkeley
   ```

2. Install dependencies:
   ```bash
   # Backend
   cd backend
   npm install
   
   # Frontend
   cd ../frontend
   npm install
   ```

3. Set up environment variables:
   ```bash
   # Backend .env
   SUPABASE_URL=your_supabase_url
   SUPABASE_ANON_KE

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 56 recognized source files, 317 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- JavaScript (language) — detected in the code
- LangChain (technology) — detected in the code
- Next.js (technology) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- Supabase (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- HTML (language) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (79 of 79)

```
.github/workflows/ci.yml
.gitignore
.nvmrc
.vscode/extensions.json
.vscode/settings.json
backend/.env.example
backend/.eslintrc.json
backend/jest.config.js
backend/MIGRATION_COMPLETE.md
backend/MIGRATION_PHASE4.md
backend/nodemon.json
backend/package.json
backend/src/.gitkeep
backend/src/config/chromadb.ts
backend/src/config/supabase.ts
backend/src/middleware/auth.ts
backend/src/migrations/001_auth_tables.sql
backend/src/migrations/009_create_genesis_simulations.sql
backend/src/migrations/010_create_chat_summaries.sql
backend/src/migrations/011_add_document_columns.sql
backend/src/migrations/012_advanced_ai_features.sql
backend/src/migrations/013_create_api_keys_table.sql
backend/src/routes/auth.ts
backend/src/routes/flashcards.ts
backend/src/routes/mindmaps.ts
backend/src/services/ai/aiService.ts
backend/src/services/ai/providers/anthropic.ts
backend/src/services/autoSummarization.ts
backend/src/services/crossDocumentInsights.ts
backend/src/services/documentDNA.ts
backend/src/services/flashcardService.ts
backend/src/services/mindMapService.ts
backend/src/services/ragService.ts
backend/src/services/vectorStore.ts
backend/src/simple-server.ts
backend/src/types/ai-features.ts
backend/src/types/auth.ts
backend/src/types/index.ts
backend/src/utils/logger.ts
backend/src/utils/runMigration.ts
backend/src/utils/setupDatabase.ts
backend/src/utils/validation.ts
backend/test/.gitkeep
backend/tsconfig.json
CLAUDE.md
docs/.gitkeep
frontend/.env.local.example
frontend/.env.production.example
frontend/.eslintrc.json
frontend/app/.gitkeep
frontend/app/(auth)/layout.tsx
frontend/app/(auth)/login/page.tsx
frontend/app/(auth)/register/page.tsx
frontend/app/dashboard/page.tsx
frontend/app/globals.css
frontend/app/layout.tsx
frontend/app/page.tsx
frontend/components/.gitkeep
frontend/components/GlobalErrorHandler.tsx
frontend/components/Logo.tsx
frontend/components/Toast.tsx
frontend/contexts/auth.tsx
frontend/contexts/provider.tsx
frontend/lib/api.ts
frontend/middleware.ts
frontend/next.config.ts
frontend/package.json
frontend/playwright.config.ts
frontend/postcss.config.mjs
frontend/public/.gitkeep
frontend/tailwind.config.js
frontend/tsconfig.json
frontend/types/auth.ts
frontend/types/index.ts
LICENSE
package.json
README.md
scripts/setup-db.sh
test-new-features-ui.js
```

### Dependencies

- backend/package.json: @jest/globals@^30.0.2, @langchain/anthropic@^0.3.22, @langchain/community@^0.3.46, @supabase/supabase-js@^2.50.0, @types/bcryptjs@^2.4.6, @types/cors@^2.8.19, @types/crypto-js@^4.2.2, @types/express@^4.17.23, @types/express-rate-limit@^6.0.0, @types/jest@^30.0.0, @types/jsonwebtoken@^9.0.10, @types/mime-types@^3.0.1, @types/morgan@^1.9.9, @types/multer@^1.4.13, @types/node@^24.0.3, @types/node-cron@^3.0.11, @types/node-fetch@^2.6.12, @types/pdfkit@^0.14.0, @types/supertest@^6.0.3, @types/uuid@^10.0.0, @typescript-eslint/eslint-plugin@^7.0.0, @typescript-eslint/parser@^7.0.0, bcryptjs@^3.0.2, chromadb@^3.0.3, cors@^2.8.5, crypto-js@^4.2.0, dotenv@^16.5.0, eslint@^8.57.0, eslint-config-prettier@^9.1.0, eslint-plugin-prettier@^5.1.3, express@^5.1.0, express-rate-limit@^7.5.1, file-type@^21.0.0, helmet@^7.1.0, jest@^30.0.2, jest-environment-node@^30.0.2, joi@^17.11.0, jsonwebtoken@^9.0.2, langchain@^0.3.28, mammoth@^1.9.1, mime-types@^3.0.1, morgan@^1.10.0, multer@^2.0.1, node-cron@^4.1.0, node-fetch@^2.7.0, nodemon@^3.1.10, pdf-parse@^1.1.1, pdfkit@^0.17.1, prettier@^3.2.5, socket.io@^4.8.1, supertest@^7.1.1, ts-jest@^29.4.0, ts-node@^10.9.2, typescript@^5.8.3, uuid@^11.1.0, winston@^3.11.0
- frontend/package.json: @eslint/eslintrc@^3, @headlessui/react@^2.2.4, @heroicons/react@^2.2.0, @playwright/test@^1.53.0, @react-pdf/renderer@^4.3.0, @react-three/drei@^10.3.0, @react-three/fiber@^9.1.2, @supabase/ssr@^0.6.1, @supabase/supabase-js@^2.50.0, @tailwindcss/postcss@^4, @testing-library/jest-dom@^6.6.3, @testing-library/react@^16.3.0, @testing-library/user-event@^14.6.1, @types/d3@^7.4.3, @types/file-saver@^2.0.7, @types/lodash@^4.17.18, @types/node@^20, @types/react@^19, @types/react-dom@^19, @types/react-highlight-words@^0.20.0, @types/react-resizable@^3.0.8, @types/react-syntax-highlighter@^15.5.13, @vitejs/plugin-react@^4.5.2, @vitest/ui@^3.2.4, axe-playwright@^2.1.0, chart.js@^4.5.0, clsx@^2.1.1, critters@^0.0.23, d3@^7.9.0, date-fns@^4.1.0, eslint@^9, eslint-config-next@15.3.3, eslint-config-prettier@^9.1.0, file-saver@^2.0.5, framer-motion@^12.18.1, glob@^11.0.3, html2canvas@^1.4.1, jsdom@^26.1.0, keyv@^5.3.4, lodash@^4.17.21, next@15.3.3, open@^10.1.2, prettier@^3.2.5, react@^19.0.0, react-chartjs-2@^5.3.0, react-dnd@^16.0.1, react-dnd-html5-backend@^16.0.1, react-dom@^19.0.0, react-dropzone@^14.3.8, react-highlight-words@^0.21.0, react-markdown@^10.1.0, react-pdf@^9.2.1, react-resizable@^3.0.5, react-syntax-highlighter@^15.6.1, reactflow@^11.11.4, remark-gfm@^4.0.1, sharp@^0.34.2, socket.io-client@^4.8.1, tailwind-merge@^3.3.1, tailwindcss@^4, three@^0.177.0, typescript@^5, vitest@^3.2.4, vitest-axe@^0.1.0
- package.json: concurrently@^8.2.2

### Recent commits (newest first)

- Merge pull request #1 from seanesla/clean-main
- fix: implement proper BYOAK system - use user API keys from database
- early
- feat: implement authentication system and core components
- feat: initialize project structure with TypeScript, Next.js, and Express

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

### CLAUDE.md

```markdown
## Claude Behavior Guide

### Critical Reminders

1. Read this file fully before any work. Missing anything is FORBIDDEN.
2. Keep a mental checklist of requirements.
3. Pause after major changes to ensure you’re following guidelines and commit appropriately.
4. Ask for clarification on commit style, approach, scope, or missing details.
5. Never skip requirements—ask if unclear.

### User Context

* The user is an amateur programmer and may struggle with low-level details. Provide high-level plans and explanations.

### Logging

* Log all actions to the console: any new code generated, changes to existing code, and any operational steps taken.

### Documentation Standards

* No arbitrary statistics, mock data, or unsubstantiated claims.
* Be factual: describe actual functionality, not hypothetical benefits or outcomes.

### Context Awareness

* Before making changes, review the project’s README, key documentation, and overall architecture.
* Familiarize yourself with the folder structure, major modules, and coding patterns.
* Summarize your understanding and ask the user to confirm or correct your context if needed.
* On IDE restart or new session, reload this context to avoid losing project memory.

### Communication

* Proactively ask clear follow-up questions when requirements or patterns are ambiguous.
* Clarify commit preferences, implementation approach, scope of changes, or edge cases as needed.
* If a request is too broad or lacks detail, ask targeted clarifying questions to ensure edits are accurate and aligned with user expectations.

### Essential Commands

* **Development**: run appropriate dev scripts for the repository.
* **Testing**: run full-suite and targeted tests before commits.
* **Build & Lint**: build for production and enforce linting rules.

### Git Guidelines

* Commit often with clear messages (concise summary + detailed description).
* Never commit configuration or support files for AI tools.
* Never include console logs or mock data in code—runtime logs should go to console at execution time, not in files.
* Do not take credit for generating code: commit messages must never say “made by Claude” or claim authorship. Do not add yourself as a co-author.
* Stage only relevant files; unstage mistakes immediately.

### Testing & Debugging

#### Testing Principles

1. **Verify assumptions**: Read and trace the actual code paths before writing tests. Confirm that each feature exists and behaves as expected in the current codebase.
2. **Authenticate first**: Seed test users directly into the database or use fixtures. Ensure login flows work before testing protected functionality.
3. **Enable visible browser mode**: Run end-to-end tests (e.g., Cypress, Playwright) in headed mode first so you can observe interactions and debug UI issues.
4. **Test progressively**: Start with unit tests for individual functions, add integration tests for module interactions, then full end-to-end scenarios. Build complexity step-by-step.
5. **Monito
[truncated — 2413 more characters]
```

### backend/MIGRATION_PHASE4.md

```markdown
# Phase 4 Migration Summary

## Files Migrated from berkeleyAI2025 to praxisforberkeley

### Enhanced Services (with Winston Logger & Improvements)
1. **vectorStore.ts** - Enhanced chunking, metadata enrichment, reranking
2. **ragService.ts** - Context caching, relevance scoring, enhanced search
3. **autoSummarization.ts** - Summary caching, progressive summarization, batch generation
4. **crossDocumentInsights.ts** - TF-IDF similarity, embeddings, insight caching
5. **documentDNA.ts** - VectorStore embeddings, DNA caching, batch operations
6. **mindMapService.ts** - NEW: AI-powered mind map generation

### Updated Routes
1. **mindmaps.ts** - Updated to use MindMapService with Winston logger

### Configuration
1. **chromadb.ts** - Updated with Winston logger

### Type Definitions
1. **ai-features.ts** - Comprehensive TypeScript interfaces for all AI features

### Database Migrations
1. **012_advanced_ai_features.sql** - Complete schema for AI features
2. **013_create_api_keys_table.sql** - API keys table for providers

## Key Enhancements

### Logging
- Replaced all console.log/error statements with Winston logger
- Structured logging with context information

### Caching
- RAG context caching (7-day TTL)
- Summary caching with invalidation
- Cross-document insights caching
- DNA fingerprint caching

### Algorithms
- TF-IDF for text similarity
- Semantic embeddings for document similarity
- N-gram extraction for concepts
- SM-2 algorithm preparation for flashcards

### Performance
- Batch processing for multiple documents
- Parallel feature extraction
- Request deduplication
- Lazy loading support

## Next Steps
1. Create FlashcardService with SM-2 algorithm
2. Implement comprehensive error handling
3. Update frontend components
4. Add unit and integration tests

## Migration Date
June 21, 2025
```

### package.json

```
{
  "name": "praxisforberkeley",
  "version": "1.0.0",
  "private": true,
  "description": "Praxis: AI-Powered Knowledge Management System",
  "workspaces": [
    "frontend",
    "backend"
  ],
  "scripts": {
    "dev": "concurrently \"npm run dev:backend\" \"npm run dev:frontend\"",
    "dev:backend": "cd backend && npm run dev",
    "dev:frontend": "cd frontend && npm run dev",
    "build": "npm run build:backend && npm run build:frontend",
    "build:backend": "cd backend && npm run build",
    "build:frontend": "cd frontend && npm run build",
    "test": "npm run test:backend && npm run test:frontend",
    "test:backend": "cd backend && npm test",
    "test:frontend": "cd frontend && npm test",
    "lint": "npm run lint:backend && npm run lint:frontend",
    "lint:backend": "cd backend && npm run lint",
    "lint:frontend": "cd frontend && npm run lint",
    "setup": "npm install && npm run setup:backend && npm run setup:frontend",
    "setup:backend": "cd backend && npm install",
    "setup:frontend": "cd frontend && npm install",
    "clean": "npm run clean:backend && npm run clean:frontend",
    "clean:backend": "cd backend && rm -rf node_modules dist",
    "clean:frontend": "cd frontend && rm -rf node_modules .next"
  },
  "devDependencies": {
    "concurrently": "^8.2.2"
  },
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0"
  }
}
```

### backend/package.json

```
{
  "name": "backend",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "dev": "nodemon",
    "build": "tsc",
    "start": "node dist/simple-server.js",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "lint": "eslint src --ext .ts",
    "lint:fix": "eslint src --ext .ts --fix",
    "typecheck": "tsc --noEmit",
    "migrate": "ts-node src/utils/migrate.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "@langchain/anthropic": "^0.3.22",
    "@langchain/community": "^0.3.46",
    "@supabase/supabase-js": "^2.50.0",
    "@types/crypto-js": "^4.2.2",
    "@types/mime-types": "^3.0.1",
    "@types/multer": "^1.4.13",
    "@types/node-cron": "^3.0.11",
    "@types/node-fetch": "^2.6.12",
    "@types/pdfkit": "^0.14.0",
    "@types/uuid": "^10.0.0",
    "bcryptjs": "^3.0.2",
    "chromadb": "^3.0.3",
    "cors": "^2.8.5",
    "crypto-js": "^4.2.0",
    "dotenv": "^16.5.0",
    "express": "^5.1.0",
    "express-rate-limit": "^7.5.1",
    "file-type": "^21.0.0",
    "jsonwebtoken": "^9.0.2",
    "langchain": "^0.3.28",
    "mammoth": "^1.9.1",
    "mime-types": "^3.0.1",
    "multer": "^2.0.1",
    "node-cron": "^4.1.0",
    "node-fetch": "^2.7.0",
    "pdf-parse": "^1.1.1",
    "pdfkit": "^0.17.1",
    "socket.io": "^4.8.1",
    "uuid": "^11.1.0",
    "winston": "^3.11.0",
    "joi": "^17.11.0",
    "helmet": "^7.1.0",
    "morgan": "^1.10.0"
  },
  "devDependencies": {
    "@jest/globals": "^30.0.2",
    "@types/bcryptjs": "^2.4.6",
    "@types/cors": "^2.8.19",
    "@types/express": "^4.17.23",
    "@types/express-rate-limit": "^6.0.0",
    "@types/jest": "^30.0.0",
    "@types/jsonwebtoken": "^9.0.10",
    "@types/morgan": "^1.9.9",
    "@types/node": "^24.0.3",
    "@types/supertest": "^6.0.3",
    "@typescript-eslint/eslint-plugin": "^7.0.0",
    "@typescript-eslint/parser": "^7.0.0",
    "eslint": "^8.57.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.3",
    "jest": "^30.0.2",
    "jest-environment-node": "^30.0.2",
    "nodemon": "^3.1.10",
    "prettier": "^3.2.5",
    "supertest": "^7.1.1",
    "ts-jest": "^29.4.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.8.3"
  }
}
```

### frontend/package.json

```
{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "build:prod": "NODE_ENV=production next build",
    "build:analyze": "ANALYZE=true next build",
    "start": "next start",
    "start:prod": "NODE_ENV=production next start",
    "lint": "next lint",
    "lint:fix": "next lint --fix",
    "typecheck": "tsc --noEmit",
    "test:e2e": "playwright test",
    "test:e2e:ui": "playwright test --ui",
    "test:e2e:headed": "playwright test --headed",
    "test:e2e:debug": "playwright test --debug",
    "test:e2e:report": "playwright show-report",
    "test:e2e:manual": "playwright test real-user-journey.spec.ts --headed --reporter=list,html --timeout=300000",
    "test:e2e:manual:debug": "PWDEBUG=1 playwright test real-user-journey.spec.ts --headed",
    "test:sequential": "ts-node e2e/sequential-test-runner.ts",
    "test:sequential:no-pause": "ts-node e2e/sequential-test-runner.ts --no-pause",
    "test:sequential:verbose": "ts-node e2e/sequential-test-runner.ts --verbose",
    "test:visual": "./run-all-tests-visual.sh",
    "test:visual:update": "playwright test e2e/visual-regression/visual-regression.spec.ts --update-snapshots",
    "test:visual:ui": "npx playwright test --config=playwright-visual.config.ts --ui",
    "test:ct": "playwright test -c playwright-ct.config.ts",
    "test:ct:ui": "playwright test -c playwright-ct.config.ts --ui",
    "test:ct:headed": "playwright test -c playwright-ct.config.ts --headed",
    "lighthouse": "lhci autorun",
    "lighthouse:view": "lhci open",
    "perf:analyze": "npm run build && npm run lighthouse",
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest run --coverage",
    "test:watch": "vitest watch",
    "test:all": "npm run test:coverage && npm run test:e2e",
    "test:visual:debug": "./run-all-tests-visual.sh --debug",
    "test:visual:smoke": "./run-all-tests-visual.sh --grep @smoke",
    "test:visual:single": "npx playwright test --config=playwright-visual.config.ts --project=chromium-visual",
    "precommit": "npm run lint && npm run typecheck && npm run test:coverage"
  },
  "dependencies": {
    "@headlessui/react": "^2.2.4",
    "@heroicons/react": "^2.2.0",
    "@react-pdf/renderer": "^4.3.0",
    "@react-three/drei": "^10.3.0",
    "@react-three/fiber": "^9.1.2",
    "@supabase/ssr": "^0.6.1",
    "@supabase/supabase-js": "^2.50.0",
    "@types/d3": "^7.4.3",
    "@types/lodash": "^4.17.18",
    "@types/react-resizable": "^3.0.8",
    "@types/react-syntax-highlighter": "^15.5.13",
    "chart.js": "^4.5.0",
    "clsx": "^2.1.1",
    "d3": "^7.9.0",
    "date-fns": "^4.1.0",
    "file-saver": "^2.0.5",
    "framer-motion": "^12.18.1",
    "html2canvas": "^1.4.1",
    "lodash": "^4.17.21",
    "next": "15.3.3",
    "react": "^19.0.0",
    "react-chartjs-2": "^5.3.0",
    "react-dnd": "^16.0.1",
    "react-dnd-html5-backend": "^16.0.1",
    "react-dom": "^19.0.0",
    "react-dropzone": "^14.3.8",
    "react-highlight-words": "^0.21.0",
    "react-markdown": "^10.1.0",
    "react-pdf": "^9.2.1",
    "react-resizable": "^3.0.5",
    "react-syntax-highlighter": "^15.6.1",
    "reactflow": "^11.11.4",
    "remark-gfm": "^4.0.1",
    "sharp": "^0.34.2",
    "socket.io-client": "^4.8.1",
    "tailwind-merge": "^3.3.1",
    "three": "^0.177.0"
  },
  "devDependencies": {
    "@eslint/eslintrc": "^3",
    "@playwright/test": "^1.53.0",
    "@tailwindcss/postcss": "^4",
    "@testing-library/jest-dom": "^6.6.3",
    "@testing-library/react": "^16.3.0",
    "@testing-library/user-event": "^14.6.1",
    "@types/file-saver": "^2.0.7",
    "@types/node": "^20",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "@types/react-highlight-words": "^0.20.0",
    "@vitejs/plugin-react": "^4.5.2",
    "@vitest/ui": "^3.2.4",
    "axe-playwright": "^2.1.0",
    "critters": "^0.0.23",
    "eslint": "^9",
    "eslint-config-next": "15.3.3",
    "eslint-config-prettier": "^9.1.0",
    "glob": "^11.0.3",
    "jsdom": "^26.1.0",
    "keyv": "^5.3.4",
    "open": "^10.1.2",
    "prettier": "^3.2.5",
    "tailwindcss": "^4",
    "typescript": "^5",
    "vitest": "^3.2.4",
    "vitest-axe": "^0.1.0"
  }
}
```

### frontend/app/page.tsx

```typescript
'use client';

import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { useAuth } from '@/contexts/auth';

export default function HomePage() {
  const router = useRouter();
  const { user, loading } = useAuth();

  useEffect(() => {
    if (!loading) {
      if (user) {
        router.push('/dashboard');
      } else {
        router.push('/login');
      }
    }
  }, [user, loading, router]);

  return (
    <div className="min-h-screen bg-gray-900 flex items-center justify-center">
      <div className="text-center">
        <div className="flex justify-center mb-4">
          <div className="w-2 h-2 bg-purple-400 rounded-full animate-pulse mx-1"></div>
          <div
            className="w-2 h-2 bg-purple-400 rounded-full animate-pulse mx-1"
            style={{ animationDelay: '0.2s' }}
          ></div>
          <div
            className="w-2 h-2 bg-purple-400 rounded-full animate-pulse mx-1"
            style={{ animationDelay: '0.4s' }}
          ></div>
        </div>
        <div className="text-lg text-gray-300">Loading...</div>
      </div>
    </div>
  );
}
```

### frontend/app/layout.tsx

```typescript
import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import { AuthProvider } from '@/contexts/auth';
import { ProviderProvider } from '@/contexts/provider';
import { GlobalErrorHandler } from '@/components/GlobalErrorHandler';
import { ToastContainer, ToastProvider } from '@/components/Toast';
import './globals.css';

const geistSans = Geist({ 
  variable: '--font-geist-sans', 
  subsets: ['latin'] 
});

const geistMono = Geist_Mono({
  variable: '--font-geist-mono',
  subsets: ['latin'],
});

export const metadata: Metadata = {
  title: 'Praxis - Your Ideas, Realized',
  description: 'AI-powered knowledge management system',
};

export const viewport = {
  width: 'device-width',
  initialScale: 1,
  maximumScale: 1,
  userScalable: false,
};

export default function RootLayout({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="en">
      <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
        <ToastProvider>
          <AuthProvider>
            <ProviderProvider>
              <GlobalErrorHandler>
                {children}
              </GlobalErrorHandler>
              <ToastContainer />
            </ProviderProvider>
          </AuthProvider>
        </ToastProvider>
      </body>
    </html>
  );
}
```

### frontend/types/index.ts

```typescript
export interface User {
  id: string;
  email: string;
  created_at?: string;
  updated_at?: string;
}

export interface Session {
  access_token: string;
  refresh_token: string;
  expires_at: number;
  user: User;
}

export interface Document {
  id: string;
  user_id: string;
  title: string;
  content?: string;
  file_url?: string;
  file_type?: string;
  file_size?: number;
  created_at: string;
  updated_at: string;
}

export interface ApiKey {
  id: string;
  user_id: string;
  provider: 'anthropic' | 'openai' | 'google';
  encrypted_key?: string;
  masked_key?: string;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

export interface Chat {
  id: string;
  user_id: string;
  document_id: string;
  title: string;
  created_at: string;
  updated_at: string;
}

export interface Message {
  id: string;
  chat_id: string;
  role: 'user' | 'assistant' | 'system';
  content: string;
  sources?: SourceReference[];
  perspective?: string;
  created_at: string;
}

export interface SourceReference {
  document_id: string;
  passage: string;
  page?: number;
  start_index?: number;
  end_index?: number;
  startPosition?: number;
  endPosition?: number;
  relevance_score?: number;
  metadata?: {
    title?: string;
    chunkIndex?: number;
    totalChunks?: number;
  };
}

export interface MindMap {
  id: string;
  user_id: string;
  document_id?: string;
  title: string;
  data: MindMapNode;
  created_at: string;
  updated_at: string;
}

export interface MindMapNode {
  id: string;
  text: string;
  children?: MindMapNode[];
  x?: number;
  y?: number;
  metadata?: Record<string, any>;
}

export interface Flashcard {
  id: string;
  user_id: string;
  document_id?: string;
  question: string;
  answer: string;
  difficulty?: 'easy' | 'medium' | 'hard';
  tags?: string[];
  review_count?: number;
  last_reviewed?: string;
  next_review?: string;
  ease_factor?: number;
  created_at: string;
  updated_at?: string;
}

export interface UserPreferences {
  id: string;
  user_id: string;
  active_provider?: 'anthropic' | 'openai' | 'google';
  theme?: 'light' | 'dark' | 'system';
  language?: string;
  timezone?: string;
  created_at: string;
  updated_at: string;
}

export interface Perspective {
  id: string;
  name: string;
  description: string;
}

// API Response types
export interface ApiResponse<T = unknown> {
  data?: T;
  error?: ApiError;
}

export interface ApiError {
  message: string;
  code?: string;
  status?: number;
  details?: any;
}

// Pagination types
export interface PaginationParams {
  page?: number;
  limit?: number;
  sort_by?: string;
  sort_order?: 'asc' | 'desc';
}

export interface PaginatedResponse<T> {
  data: T[];
  pagination: {
    page: number;
    limit: number;
    total: number;
    total_pages: number;
  };
}
```

### frontend/app/dashboard/page.tsx

```typescript
'use client';

import { useAuth } from '@/contexts/auth';
import { Logo } from '@/components/Logo';

export default function DashboardPage() {
  const { user, logout } = useAuth();

  return (
    <div className="min-h-screen bg-gray-900">
      <header className="border-b border-gray-800">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <div className="flex items-center justify-between h-16">
            <Logo size="sm" />
            
            <div className="flex items-center gap-4">
              <span className="text-sm text-gray-400">
                {user?.email}
              </span>
              <button
                onClick={logout}
                className="text-sm text-gray-400 hover:text-white transition-colors"
              >
                Logout
              </button>
            </div>
          </div>
        </div>
      </header>

      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
        <div className="glass-card">
          <h1 className="text-2xl font-light mb-4">Welcome to Praxis</h1>
          <p className="text-gray-400">
            Your dashboard is being prepared. More features coming soon!
          </p>
        </div>
      </main>
    </div>
  );
}
```

### backend/src/types/index.ts

```typescript
export interface User {
  id: string;
  email: string;
  created_at: string;
  updated_at?: string;
}

export interface Document {
  id: string;
  user_id: string;
  title: string;
  content?: string;
  file_url?: string;
  file_type?: string;
  file_size?: number;
  created_at: string;
  updated_at: string;
}

export interface ApiKey {
  id: string;
  user_id: string;
  provider: 'anthropic';
  encrypted_key: string;
  masked_key?: string;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

export interface Chat {
  id: string;
  user_id: string;
  document_id: string;
  title: string;
  created_at: string;
  updated_at: string;
}

export interface Message {
  id: string;
  chat_id: string;
  role: 'user' | 'assistant' | 'system';
  content: string;
  sources?: SourceReference[];
  perspective?: string;
  created_at: string;
}

export interface SourceReference {
  document_id: string;
  passage: string;
  page?: number;
  start_index?: number;
  end_index?: number;
  relevance_score?: number;
}

export interface MindMap {
  id: string;
  user_id: string;
  document_id?: string;
  title: string;
  data: MindMapNode;
  created_at: string;
  updated_at: string;
}

export interface MindMapNode {
  id: string;
  text: string;
  children?: MindMapNode[];
  x?: number;
  y?: number;
  metadata?: Record<string, any>;
}

export interface Flashcard {
  id: string;
  user_id: string;
  document_id?: string;
  question: string;
  answer: string;
  difficulty?: 'easy' | 'medium' | 'hard';
  tags?: string[];
  review_count?: number;
  last_reviewed?: string;
  next_review?: string;
  ease_factor?: number;
  created_at: string;
  updated_at?: string;
}

export interface UserPreferences {
  id: string;
  user_id: string;
  active_provider?: 'anthropic' | 'openai' | 'google';
  theme?: 'light' | 'dark' | 'system';
  language?: string;
  timezone?: string;
  created_at: string;
  updated_at: string;
}

// Request/Response types for better type safety
export interface LoginRequest {
  email: string;
  password: string;
}

export interface RegisterRequest {
  email: string;
  password: string;
  name?: string;
}

export interface AuthResponse {
  user: User;
  session: {
    access_token: string;
    refresh_token?: string;
    expires_at: number;
  };
}

export interface ErrorResponse {
  error: {
    message: string;
    code?: string;
    status?: number;
  };
}

// Pagination types
export interface PaginationParams {
  page?: number;
  limit?: number;
  sort_by?: string;
  sort_order?: 'asc' | 'desc';
}

export interface PaginatedResponse<T> {
  data: T[];
  pagination: {
    page: number;
    limit: number;
    total: number;
    total_pages: number;
  };
}
```

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