JupyterManager/README.md

112 lines
3.4 KiB
Markdown
Raw Permalink Normal View History

# JupyterManager
Cross-project Jupyter instance manager. Discovers, monitors, and controls JupyterLab instances across multiple projects on the same machine.
## The Problem
You have multiple projects with Jupyter notebooks. Each runs its own JupyterLab server. Without coordination:
- Projects fight over port 8888
- Closing a terminal leaves orphan Jupyter processes
- Orphans block ports for other projects
- You can't tell what's running or which project owns which port
## What JupyterManager Does
**`jupyter-hub`** is a single command that manages everything:
```bash
jupyter-hub status # Show all projects (running/stopped)
jupyter-hub ports # Port allocation map (8888-8899)
jupyter-hub stop-all # Stop all Jupyter instances
jupyter-hub orphans # Find untracked processes
jupyter-hub kill-orphans # Kill them
jupyter-hub which 8889 # Which project owns this port?
jupyter-hub config # Show configuration
```
It discovers projects automatically by scanning configured directories for the `scripts/app.sh` convention.
## Installation
```bash
git clone https://github.com/saymrwulf/JupyterManager.git
cd JupyterManager
bash install.sh
```
This creates a symlink at `~/bin/jupyter-hub` pointing to the repo's `bin/jupyter-hub`. Updates are just `git pull`.
Ensure `~/bin` is in your PATH:
```bash
# Add to ~/.zshrc or ~/.bashrc
export PATH="$HOME/bin:$PATH"
```
## Configuration
Configuration lives at `~/.config/jupyter-hub/config.sh` (created by `install.sh`):
```bash
# Port range to scan
PORT_RANGE_START=8888
PORT_RANGE_END=8899
# Directories to scan for Jupyter projects
SCAN_DIRS=(
"$HOME/GitClone/ClaudeCodeProjects"
"$HOME/GitClone/CodexProjects"
"$HOME/Projects"
)
```
A project is recognized if it has `scripts/app.sh` AND either a `notebooks/` directory or `jupyter` in its `pyproject.toml`.
## Client Project Requirements
For a project to be managed by `jupyter-hub`, it must follow the **Lifecycle Specification** documented in [`docs/LIFECYCLE_SPEC.md`](docs/LIFECYCLE_SPEC.md). The key requirements:
1. `scripts/app.sh` with: `bootstrap`, `start`, `stop`, `restart`, `status`, `logs`
2. Isolated Jupyter directories under the project root (not system-global)
3. Kernel installed with `--sys-prefix` (not `--user`)
4. Auto port allocation (scan 8888-8899 for free port)
5. PID file at `.logs/jupyter.pid`
6. Background + foreground modes
7. Graceful stop protocol (SIGTERM, wait, SIGKILL fallback)
### Current Client Projects
| Project | Location | Status |
|---------|----------|--------|
| autoresearch-quantum | `ClaudeCodeProjects/` | Fully compliant |
| QuantumLearning | `CodexProjects/` | Detected, partial compliance |
| NTT-learning | `CodexProjects/` | Detected, partial compliance |
## For Coding Agents
When instructing an AI coding agent to align a project with this specification, use the prompt in [`docs/AGENT_PROMPT.md`](docs/AGENT_PROMPT.md).
## Project Structure
```
JupyterManager/
├── bin/
│ └── jupyter-hub The CLI tool
├── config/
│ └── defaults.sh Default scan dirs, port range
├── docs/
│ ├── LIFECYCLE_SPEC.md Client project specification
│ └── AGENT_PROMPT.md Prompt for coding agents
├── tests/
│ └── test_jupyter_hub.sh Functional tests
├── install.sh Symlink installer
└── README.md
```
## Running Tests
```bash
bash tests/test_jupyter_hub.sh
```