|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Development Commands |
| 6 | + |
| 7 | +### Build & Watch |
| 8 | + |
| 9 | +- `jlpm dev:install` - Full development install (install dependencies, build, and link extension) |
| 10 | +- `jlpm build` - Build TypeScript and create labextension for development |
| 11 | +- `jlpm build:prod` - Production build (clean first, build optimized) |
| 12 | +- `jlpm watch` - Watch TypeScript source and auto-rebuild |
| 13 | +- `jlpm watch:src` - Watch TypeScript source only |
| 14 | +- `jlpm watch:labextension` - Watch and rebuild labextension |
| 15 | + |
| 16 | +### Testing |
| 17 | + |
| 18 | +- `pytest -vv -r ap --cov jupyter_ai_persona_manager` - Run Python tests with coverage |
| 19 | +- `jlpm test` - Run TypeScript tests with Jest |
| 20 | +- Playwright integration tests are in `ui-tests/` directory |
| 21 | + |
| 22 | +### Code Quality |
| 23 | + |
| 24 | +- `jlpm lint` - Run all linters (stylelint + prettier + eslint) with fixes |
| 25 | +- `jlpm lint:check` - Check without fixing |
| 26 | +- `jlpm eslint` - ESLint with fixes |
| 27 | +- `jlpm prettier` - Prettier with fixes |
| 28 | +- `jlpm stylelint` - Stylelint with fixes |
| 29 | + |
| 30 | +### Development Lifecycle |
| 31 | + |
| 32 | +- `jlpm dev:uninstall` - Uninstall development extension |
| 33 | +- `jlpm clean:all` - Clean all build artifacts |
| 34 | + |
| 35 | +## Architecture Overview |
| 36 | + |
| 37 | +This is a JupyterLab extension that provides AI persona management for Jupyter AI. It's a hybrid TypeScript/Python package with both frontend extension and server extension components. |
| 38 | + |
| 39 | +### Core Components |
| 40 | + |
| 41 | +**BasePersona** (`jupyter_ai_persona_manager/base_persona.py`): |
| 42 | + |
| 43 | +- Abstract base class for all AI personas |
| 44 | +- Handles chat integration, awareness management, and message processing |
| 45 | +- Provides utilities for file attachment processing and workspace access |
| 46 | +- Key methods: `process_message()`, `stream_message()`, `send_message()` |
| 47 | + |
| 48 | +**PersonaManager** (`jupyter_ai_persona_manager/persona_manager.py`): |
| 49 | + |
| 50 | +- Central registry and lifecycle manager for personas |
| 51 | +- Loads personas from both Python entry points and local `.jupyter/personas/` directory |
| 52 | +- Routes messages to appropriate personas based on @-mentions and chat context |
| 53 | +- Handles multi-user vs single-user chat scenarios differently |
| 54 | + |
| 55 | +**Persona Discovery**: |
| 56 | + |
| 57 | +- Entry points: Uses `jupyter_ai.personas` entry point group for installed packages |
| 58 | +- Local loading: Scans `.jupyter/personas/` for Python files containing "persona" in filename |
| 59 | +- Supports `/refresh-personas` command for development iteration |
| 60 | + |
| 61 | +### Extension Structure |
| 62 | + |
| 63 | +**Frontend** (`src/`): |
| 64 | + |
| 65 | +- TypeScript JupyterLab extension |
| 66 | +- Minimal frontend - most logic is server-side |
| 67 | +- Registers server extension and handles activation |
| 68 | + |
| 69 | +**Server Extension** (`jupyter_ai_persona_manager/`): |
| 70 | + |
| 71 | +- Python server extension that integrates with JupyterLab Chat |
| 72 | +- Manages persona instances per chat room |
| 73 | +- Handles message routing and persona lifecycle |
| 74 | + |
| 75 | +### Key Integration Points |
| 76 | + |
| 77 | +**Chat Integration**: |
| 78 | + |
| 79 | +- Integrates with `jupyterlab_chat` for message handling |
| 80 | +- Uses `YChat` (Yjs-based collaborative chat) for real-time messaging |
| 81 | +- Persona awareness uses pycrdt for collaborative state management |
| 82 | + |
| 83 | +**File System Access**: |
| 84 | + |
| 85 | +- Personas can access workspace directory and .jupyter directory |
| 86 | +- File attachment processing with multiple resolution strategies |
| 87 | +- Integration with `jupyter_server_fileid` for file ID management |
| 88 | + |
| 89 | +**Entry Point System**: |
| 90 | + |
| 91 | +- Personas registered via `[project.entry-points."jupyter_ai.personas"]` in pyproject.toml |
| 92 | +- Automatic discovery and loading of persona classes from installed packages |
| 93 | + |
| 94 | +### Development Patterns |
| 95 | + |
| 96 | +**Persona Development**: |
| 97 | + |
| 98 | +- Inherit from `BasePersona` and implement `defaults` property and `process_message()` method |
| 99 | +- Use `self.send_message()` or `self.stream_message()` for responses |
| 100 | +- Access file attachments via `self.process_attachments(message)` |
| 101 | +- Use `self.awareness` for collaborative state (typing indicators, etc.) |
| 102 | + |
| 103 | +**Local Development**: |
| 104 | + |
| 105 | +- Place persona files in `.jupyter/personas/` directory |
| 106 | +- Use `/refresh-personas` command to reload without server restart |
| 107 | +- Files must contain "persona" in name and not start with `_` or `.` |
| 108 | + |
| 109 | +### Configuration |
| 110 | + |
| 111 | +**Traitlets Configuration**: |
| 112 | + |
| 113 | +- `PersonaManager.default_persona_id` - Sets which persona responds in single-user chats |
| 114 | +- Inherits JupyterLab's configurable system via `LoggingConfigurable` |
| 115 | + |
| 116 | +**Code Style**: |
| 117 | + |
| 118 | +- TypeScript: ESLint + Prettier with interface naming convention (must start with 'I') |
| 119 | +- Python: Standard conventions with pytest for testing |
| 120 | +- Single quotes preferred, no trailing commas in TypeScript |
0 commit comments