nebula-notebook 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -16
- package/dist/assets/errorwidget-Wy5ajPiM.js +5 -0
- package/dist/assets/fa-brands-400-CEJbCg16.woff +0 -0
- package/dist/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
- package/dist/assets/fa-brands-400-DnkPfk3o.eot +0 -0
- package/dist/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
- package/dist/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
- package/dist/assets/fa-regular-400-BhTwtT8w.eot +0 -0
- package/dist/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
- package/dist/assets/fa-regular-400-DFnMcJPd.woff +0 -0
- package/dist/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
- package/dist/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
- package/dist/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
- package/dist/assets/fa-solid-900-B6Axprfb.eot +0 -0
- package/dist/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
- package/dist/assets/fa-solid-900-DOXgCApm.woff +0 -0
- package/dist/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
- package/dist/assets/index-B_Bs5koo.js +1 -0
- package/dist/assets/index-BtWv4MIT.css +7 -0
- package/dist/assets/index-DK4nS74r.js +829 -0
- package/dist/assets/index-DeQN03nW.js +81 -0
- package/dist/assets/index-DzjpmUak.css +32 -0
- package/dist/assets/index-g6MjT-VG.js +1 -0
- package/dist/assets/services-shim-BirHVsih.js +33 -0
- package/dist/assets/viewlist-uomDf7I7.js +1 -0
- package/dist/assets/widgets-X7J3NxEn.css +1 -0
- package/dist/index.html +2 -2
- package/node-server/dist/auth/auth-middleware.js +22 -4
- package/node-server/dist/auth/auth-service.js +37 -7
- package/node-server/dist/cluster/client-registration.d.ts +12 -1
- package/node-server/dist/cluster/client-registration.js +38 -2
- package/node-server/dist/cluster/kernel-proxy.js +43 -12
- package/node-server/dist/cluster/server-registry.d.ts +17 -0
- package/node-server/dist/cluster/server-registry.js +57 -7
- package/node-server/dist/discovery/conda-locations.d.ts +73 -0
- package/node-server/dist/discovery/conda-locations.js +427 -0
- package/node-server/dist/discovery/discovery-service.d.ts +73 -4
- package/node-server/dist/discovery/discovery-service.js +211 -127
- package/node-server/dist/discovery/types.d.ts +0 -1
- package/node-server/dist/discovery/types.js +1 -2
- package/node-server/dist/environment.d.ts +12 -0
- package/node-server/dist/environment.js +104 -0
- package/node-server/dist/fs/fs-service.d.ts +86 -8
- package/node-server/dist/fs/fs-service.js +640 -99
- package/node-server/dist/fs/notebook-formats/percent.d.ts +25 -0
- package/node-server/dist/fs/notebook-formats/percent.js +286 -0
- package/node-server/dist/fs/notebook-formats/qmd.d.ts +29 -0
- package/node-server/dist/fs/notebook-formats/qmd.js +307 -0
- package/node-server/dist/fs/notebook-formats/registry.d.ts +12 -0
- package/node-server/dist/fs/notebook-formats/registry.js +77 -0
- package/node-server/dist/fs/notebook-formats/types.d.ts +37 -0
- package/node-server/dist/fs/notebook-formats/types.js +13 -0
- package/node-server/dist/fs/types.d.ts +9 -0
- package/node-server/dist/fs/types.js +8 -0
- package/node-server/dist/idle-exit.d.ts +52 -0
- package/node-server/dist/idle-exit.js +83 -0
- package/node-server/dist/index.js +198 -8
- package/node-server/dist/kernel/kernel-service.d.ts +130 -2
- package/node-server/dist/kernel/kernel-service.js +834 -64
- package/node-server/dist/kernel/kernelspec.d.ts +27 -0
- package/node-server/dist/kernel/kernelspec.js +75 -4
- package/node-server/dist/notebook/headless-handler.d.ts +12 -0
- package/node-server/dist/notebook/headless-handler.js +125 -29
- package/node-server/dist/notebook/operation-router.js +7 -2
- package/node-server/dist/notebook/undoRedoManager.d.ts +12 -1
- package/node-server/dist/notebook/undoRedoManager.js +49 -18
- package/node-server/dist/output/display-data.js +2 -0
- package/node-server/dist/private-tmp.d.ts +14 -0
- package/node-server/dist/private-tmp.js +70 -0
- package/node-server/dist/routes/autocomplete.d.ts +19 -0
- package/node-server/dist/routes/autocomplete.js +294 -0
- package/node-server/dist/routes/cluster.js +2 -2
- package/node-server/dist/routes/compute.d.ts +8 -0
- package/node-server/dist/routes/compute.js +136 -0
- package/node-server/dist/routes/fs.js +23 -6
- package/node-server/dist/routes/kernel.js +156 -3
- package/node-server/dist/routes/notebook.js +37 -3
- package/node-server/dist/routes/python.d.ts +1 -2
- package/node-server/dist/routes/python.js +139 -3
- package/node-server/dist/scheduler/allocation-service.d.ts +63 -0
- package/node-server/dist/scheduler/allocation-service.js +285 -0
- package/node-server/dist/scheduler/job-template.d.ts +30 -0
- package/node-server/dist/scheduler/job-template.js +85 -0
- package/node-server/dist/scheduler/mock-scheduler.d.ts +30 -0
- package/node-server/dist/scheduler/mock-scheduler.js +125 -0
- package/node-server/dist/scheduler/slurm-scheduler.d.ts +31 -0
- package/node-server/dist/scheduler/slurm-scheduler.js +406 -0
- package/node-server/dist/scheduler/types.d.ts +118 -0
- package/node-server/dist/scheduler/types.js +8 -0
- package/node-server/dist/scheduler/util.d.ts +7 -0
- package/node-server/dist/scheduler/util.js +20 -0
- package/node-server/dist/terminal/agent-registry.d.ts +87 -0
- package/node-server/dist/terminal/agent-registry.js +246 -0
- package/node-server/dist/terminal/binding-store.d.ts +57 -0
- package/node-server/dist/terminal/binding-store.js +0 -0
- package/node-server/dist/terminal/pty-manager.d.ts +23 -6
- package/node-server/dist/terminal/pty-manager.js +138 -19
- package/node-server/dist/terminal/server.js +155 -23
- package/node-server/dist/terminal/types.d.ts +2 -0
- package/node-server/dist/update-check.d.ts +20 -0
- package/node-server/dist/update-check.js +114 -0
- package/node-server/package.json +2 -0
- package/node_modules/nebula-autocomplete/README.md +145 -0
- package/node_modules/nebula-autocomplete/dist/backends/claude.d.ts +69 -0
- package/node_modules/nebula-autocomplete/dist/backends/claude.js +449 -0
- package/node_modules/nebula-autocomplete/dist/backends/codex.d.ts +45 -0
- package/node_modules/nebula-autocomplete/dist/backends/codex.js +108 -0
- package/node_modules/nebula-autocomplete/dist/client/fetcher.d.ts +16 -0
- package/node_modules/nebula-autocomplete/dist/client/fetcher.js +41 -0
- package/node_modules/nebula-autocomplete/dist/codemirror/ghostText.d.ts +43 -0
- package/node_modules/nebula-autocomplete/dist/codemirror/ghostText.js +175 -0
- package/node_modules/nebula-autocomplete/dist/core/engine.d.ts +17 -0
- package/node_modules/nebula-autocomplete/dist/core/engine.js +135 -0
- package/node_modules/nebula-autocomplete/dist/core/lru.d.ts +7 -0
- package/node_modules/nebula-autocomplete/dist/core/lru.js +26 -0
- package/node_modules/nebula-autocomplete/dist/core/prompt.d.ts +12 -0
- package/node_modules/nebula-autocomplete/dist/core/prompt.js +0 -0
- package/node_modules/nebula-autocomplete/dist/core/text.d.ts +53 -0
- package/node_modules/nebula-autocomplete/dist/core/text.js +169 -0
- package/node_modules/nebula-autocomplete/dist/index.d.ts +7 -0
- package/node_modules/nebula-autocomplete/dist/index.js +5 -0
- package/node_modules/nebula-autocomplete/dist/server/fastify.d.ts +40 -0
- package/node_modules/nebula-autocomplete/dist/server/fastify.js +52 -0
- package/node_modules/nebula-autocomplete/dist/transport.d.ts +55 -0
- package/node_modules/nebula-autocomplete/dist/transport.js +66 -0
- package/node_modules/nebula-autocomplete/dist/types.d.ts +103 -0
- package/node_modules/nebula-autocomplete/dist/types.js +1 -0
- package/node_modules/nebula-autocomplete/package.json +58 -0
- package/node_modules/nebula-autocomplete/server.d.ts +3 -0
- package/node_modules/nebula-autocomplete/server.js +3 -0
- package/package.json +18 -5
- package/scripts/postinstall.cjs +25 -5
- package/dist/assets/index-BvrHu37J.js +0 -648
- package/dist/assets/index-Dfj_xsKU.css +0 -32
- package/node-server/dist/llm/index.d.ts +0 -5
- package/node-server/dist/llm/index.js +0 -21
- package/node-server/dist/llm/llm-service.d.ts +0 -77
- package/node-server/dist/llm/llm-service.js +0 -454
- package/node-server/dist/llm/types.d.ts +0 -40
- package/node-server/dist/llm/types.js +0 -15
- package/node-server/dist/routes/llm.d.ts +0 -8
- package/node-server/dist/routes/llm.js +0 -105
package/README.md
CHANGED
|
@@ -1,39 +1,120 @@
|
|
|
1
1
|
# Nebula Notebook
|
|
2
2
|
|
|
3
|
-
Nebula is an agent-native notebook
|
|
3
|
+
Nebula is an agent-native notebook — built for you and your AI to work in the same cells, and a fast, polished one even if you never touch the AI.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<!-- 2½-min product tour. Uploaded into the `demo-assets` release description, so GitHub
|
|
7
|
+
transcodes it and streams it inline via the user-attachments URL below (video/mp4,
|
|
8
|
+
range requests, no attachment disposition). The 12 MB original also stays attached to
|
|
9
|
+
that release as a downloadable asset. Neither is committed to the repo, so clones stay
|
|
10
|
+
lean. Renderers that strip <video> (npm, some mirrors) fall back to the link inside. -->
|
|
11
|
+
<video src="https://github.com/user-attachments/assets/4a9ec9ce-9ac0-4540-b35a-27c1b97a20b1" controls muted width="940" poster="https://raw.githubusercontent.com/jzhoulab/nebula-notebook/main/docs/assets/nebula-hero.svg">
|
|
12
|
+
<a href="https://github.com/jzhoulab/nebula-notebook/releases/download/demo-assets/nebula-demo-16x9-v10-hq.mp4">Watch the 2½-minute product tour</a>
|
|
13
|
+
</video>
|
|
14
|
+
</p>
|
|
15
|
+
<p align="center"><sub>▶ <a href="https://github.com/user-attachments/assets/4a9ec9ce-9ac0-4540-b35a-27c1b97a20b1">Watch the 2½-minute tour</a> · or skim the autoplay clips below</sub></p>
|
|
16
|
+
|
|
17
|
+
## Highlights
|
|
18
|
+
|
|
19
|
+
- **Your notebook and your agent, at the same time** — Claude Code, Codex, Cursor & friends drive notebooks through the **MCP** server or the **`nebula` CLI** (also installable as a Claude Code skill), and every notebook has a built-in agent terminal, one-click launched and pre-briefed. You keep editing *while* the agent edits: per-cell optimistic concurrency hands a conflicting agent your current content to retry against — nothing is silently overwritten. **"Fix with agent"** sits on every failing cell, and any cell takes a plain-English prompt
|
|
20
|
+
- **Never lose work** — **infinite undo/redo**, journaled to disk and surviving reloads — every edit, yours and the agent's; the History panel time-travels to any past moment with diff highlighting and one-click restore; autosave that notices when the file changed underneath you
|
|
21
|
+
- **Everything smoother** — big notebooks open instantly (virtualized cells), Run All shows live queue positions and per-cell timings, `tqdm` renders as one clean bar, and there's real whole-notebook search & replace (regex included) plus a keyboard-first cell navigator
|
|
22
|
+
- **Rich outputs, no widget plumbing** — Plotly MIME rendering and Nebula-native interactive JS outputs that respond to clicks
|
|
23
|
+
- **Notebooks your git history will thank you for** — first-class **`.qmd` and `.py` (percent)** notebooks: clean text diffs, outputs never serialized
|
|
24
|
+
- **Meets your environment where it is** — detects conda / venv / uv / pixi / system Pythons with one-click kernel registration (and exact guidance when `ipykernel` is missing); Jupyter kernels over ZeroMQ (Python, Julia, R, …) survive server restarts and reattach
|
|
25
|
+
- **Runs anywhere — including where your compute lives** — `npx nebula-notebook`, TOTP 2FA, multi-server clusters behind one UI; on an HPC login node, allocate a scheduler job right from the kernel menu (partition/QoS/GPU, live queue-load monitor) and your kernel runs on the compute node — no sbatch script, no SSH tunnel, invisible off-cluster
|
|
26
|
+
|
|
27
|
+
## See it in action
|
|
28
|
+
|
|
29
|
+
**A failing cell, fixed by the agent live** — the cell errors, the agent rewrites it (presence ring on the cell it's touching) and reruns it clean:
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<img src="https://raw.githubusercontent.com/jzhoulab/nebula-notebook/main/docs/assets/demo/scene-agent.gif" alt="A code cell throws a KeyError; an agent session starts, rewrites the cell live with a purple presence ring, reruns it, and the clean output appears" width="760">
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
**Interactive outputs, no widget plumbing** — `application/vnd.nebula.web+json` widgets respond to clicks:
|
|
36
|
+
|
|
37
|
+
<p align="center">
|
|
38
|
+
<img src="https://raw.githubusercontent.com/jzhoulab/nebula-notebook/main/docs/assets/demo/scene-widget.gif" alt="A Nebula-native interactive web output: clicking Resample re-rolls the bar chart live" width="760">
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
**Time-travel through your edit history** — preview any past moment with diff highlighting, then restore:
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<img src="https://raw.githubusercontent.com/jzhoulab/nebula-notebook/main/docs/assets/demo/scene-history.gif" alt="The History panel: clicking a past edit previews the notebook at that moment with an orange modified-cell highlight and a Restore option" width="760">
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
**Find across the whole notebook** — regex search with live match counts:
|
|
48
|
+
|
|
49
|
+
<p align="center">
|
|
50
|
+
<img src="https://raw.githubusercontent.com/jzhoulab/nebula-notebook/main/docs/assets/demo/scene-search.gif" alt="Notebook-wide search: typing a query highlights every match across cells with a running match count" width="760">
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
<sub>All clips captured headlessly from the running app — regenerate with <code>python scripts/demo-shoot.py all</code>.</sub>
|
|
6
54
|
|
|
7
55
|
## Quick Start
|
|
8
56
|
|
|
57
|
+
### On your machine
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx nebula-notebook
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
On first start a QR code appears in the terminal — scan it with an authenticator app (Google Authenticator, Authy, …), then open http://localhost:3000 and enter the 6-digit code. A startup banner shows the URLs and what was detected.
|
|
64
|
+
|
|
65
|
+
Nebula itself is pure Node — but running notebooks needs a Python (3.10+) with `ipykernel` on the server machine. If none is found, the kernel menu detects your Python environments (venv, conda, uv, pixi, system) and shows the exact setup command for each; environments that already have `ipykernel` register with one click.
|
|
66
|
+
|
|
67
|
+
### On a cluster / remote server
|
|
68
|
+
|
|
69
|
+
Run the server where your files and compute live; browse it through one SSH tunnel:
|
|
70
|
+
|
|
9
71
|
```bash
|
|
72
|
+
# on the cluster login node (inside tmux so it outlives your session)
|
|
73
|
+
tmux new -s nebula
|
|
10
74
|
npx nebula-notebook
|
|
75
|
+
|
|
76
|
+
# from your laptop
|
|
77
|
+
ssh -L 3000:localhost:3000 <login-node> # then open http://localhost:3000
|
|
11
78
|
```
|
|
12
79
|
|
|
13
|
-
|
|
80
|
+
If a SLURM scheduler is present, the kernel menu gains **New compute allocation** — your kernels run on compute nodes, no sbatch script, no extra tunnels. Full guide (bastions, persistent runs, agent placements, troubleshooting): [docs/CLUSTER_SETUP.md](docs/CLUSTER_SETUP.md).
|
|
14
81
|
|
|
15
|
-
|
|
82
|
+
### Let agents in
|
|
16
83
|
|
|
17
|
-
To let agents (Claude Code, Codex, Cursor, Gemini CLI, …)
|
|
84
|
+
To let agents (Claude Code, Codex, Cursor, Gemini CLI, …) operate your notebooks, register the Nebula MCP on the machine where your agent runs:
|
|
18
85
|
|
|
19
86
|
```bash
|
|
20
87
|
npx nebula-notebook-mcp setup-mcp
|
|
21
88
|
```
|
|
22
89
|
|
|
23
|
-
Then open a notebook, click **Agent**, and launch Claude Code or Codex right in the notebook's terminal.
|
|
90
|
+
Then open a notebook, click **Agent**, and launch Claude Code or Codex right in the notebook's terminal. Prefer a command line? The same package ships the shell-first `nebula` CLI (`npx -p nebula-notebook-mcp nebula --help`); run `nebula setup-skill` to install it as a **Claude Code skill** so agents outside a Nebula terminal know how to drive it.
|
|
91
|
+
|
|
92
|
+
**Prerequisite when the agent runs on your own machine** (Agent tab → *on: my machine*, or any terminal outside Nebula): that machine needs the `nebula` CLI available. Node.js ≥ 20 is enough — the agent is briefed to fall back to `npx -p nebula-notebook-mcp nebula …` when `nebula` isn't on PATH; installing `npm i -g nebula-notebook-mcp` skips the npx download. Agents launched in a Nebula terminal on the server need nothing extra — the CLI is pre-wired there.
|
|
24
93
|
|
|
25
94
|
### From source (latest)
|
|
26
95
|
|
|
27
96
|
npm releases are point-in-time snapshots — to get the latest changes, install from source:
|
|
28
97
|
|
|
29
98
|
```bash
|
|
30
|
-
git clone https://github.com/
|
|
99
|
+
git clone https://github.com/jzhoulab/nebula-notebook.git
|
|
31
100
|
cd nebula-notebook
|
|
32
|
-
npm install
|
|
101
|
+
npm install # dependencies only (root + subpackages) — no build yet
|
|
102
|
+
```
|
|
33
103
|
|
|
34
|
-
|
|
104
|
+
> Building from source needs devDependencies. If your shell sets `NODE_ENV=production`
|
|
105
|
+
> (common on servers), use `npm install --include=dev` — otherwise the build tools
|
|
106
|
+
> (`tsc`, `vite`) are skipped and the build steps below fail with "command not found".
|
|
107
|
+
|
|
108
|
+
To run the same production server `npx nebula-notebook` gives you (UI + API on :3000), build both halves once, then start it:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npm run build # frontend → dist/
|
|
112
|
+
npm run node-server:build # backend → node-server/dist/
|
|
113
|
+
node bin/nebula-notebook.js # accepts the same flags, e.g. --workdir
|
|
35
114
|
```
|
|
36
115
|
|
|
116
|
+
For hacking on Nebula itself there's also a dev mode with hot reload (`npm run start` — Vite on :3000, API on :8000); rebuild with the two build commands above after `git pull` to refresh a production install.
|
|
117
|
+
|
|
37
118
|
## Root Directory
|
|
38
119
|
|
|
39
120
|
Set the server root directory (default is your home directory):
|
|
@@ -47,10 +128,10 @@ This root is used for the file browser and terminals. You can also change it fro
|
|
|
47
128
|
## Features
|
|
48
129
|
|
|
49
130
|
**Core**
|
|
50
|
-
-
|
|
51
|
-
-
|
|
131
|
+
- Jupyter kernel execution (Python, Julia, R, etc.)
|
|
132
|
+
- Built-in file browser — open notebooks anywhere on disk
|
|
52
133
|
- Autosave with crash recovery
|
|
53
|
-
-
|
|
134
|
+
- Infinite undo/redo, journaled to disk (survives reloads) — time-travel to any past state with diff preview and one-click restore
|
|
54
135
|
|
|
55
136
|
**Navigation**
|
|
56
137
|
- Table of Contents breadcrumb - auto-generated from markdown headers
|
|
@@ -60,7 +141,8 @@ This root is used for the file browser and terminals. You can also change it fro
|
|
|
60
141
|
**Agents**
|
|
61
142
|
- Agent terminal built into every notebook — one click launches Claude Code or Codex, pre-briefed with the server URL and notebook path
|
|
62
143
|
- "Fix with agent" on any failing cell, and per-cell prompts, injected straight into the agent's terminal
|
|
63
|
-
-
|
|
144
|
+
- Two ways for agents to plug in, same operations under the hood — **MCP** ([`nebula-notebook-mcp`](https://www.npmjs.com/package/nebula-notebook-mcp)) for tool-calling agents, and the shell-first **`nebula` CLI** (`nb read/edit/run`, `kernel`, `session`, `compute`) for scripting; the CLI also installs as a **Claude Code skill** (`nebula setup-skill`) for agents running outside a Nebula terminal
|
|
145
|
+
- Full toolset on both: read/edit/execute cells, manage kernels and files, and allocate cluster compute — from any agent on any machine
|
|
64
146
|
- Agent sessions lock the notebook during edits and sync live into the UI
|
|
65
147
|
|
|
66
148
|
**Editor**
|
|
@@ -87,8 +169,12 @@ See [docs/RICH_OUTPUTS.md](docs/RICH_OUTPUTS.md) for examples, payload format, s
|
|
|
87
169
|
|
|
88
170
|
## Prerequisites
|
|
89
171
|
|
|
90
|
-
- Node.js
|
|
91
|
-
- Python 3.10+ with Jupyter kernels
|
|
172
|
+
- Node.js 20+
|
|
173
|
+
- Python 3.10+ with `ipykernel`, on the machine running the server (other Jupyter kernels — Julia, R, … — work too)
|
|
174
|
+
|
|
175
|
+
No ipykernel yet? Open the kernel menu in the UI: it detects your Python environments (venv, conda, uv, pixi, Homebrew, system), registers ready ones with one click, and shows the exact install command for the rest — including the PEP 668 "externally managed" cases (uv/Homebrew/system Python) where `pip install` is blocked and an isolated env is the right move.
|
|
176
|
+
|
|
177
|
+
Using **R** (or another non-Python kernel)? See [docs/R_KERNEL.md](docs/R_KERNEL.md) — registering IRkernel and the one-line fix for the common headless-server plotting error.
|
|
92
178
|
|
|
93
179
|
## Project Structure
|
|
94
180
|
|
|
@@ -222,6 +308,14 @@ Servers without the correct secret will be rejected during registration.
|
|
|
222
308
|
- Client servers need access to the same filesystem paths as the main server (for notebook files)
|
|
223
309
|
- Each server runs its own Jupyter kernels locally
|
|
224
310
|
|
|
311
|
+
### Scheduler-backed compute (HPC)
|
|
312
|
+
|
|
313
|
+
On an HPC login node you don't launch client servers by hand — the scheduler does it for you. When Nebula detects a scheduler (SLURM first — `sbatch`/`squeue` on `PATH`), the kernel menu's **Server** section grows a **+ New compute allocation** entry:
|
|
314
|
+
|
|
315
|
+
- **Allocate from the notebook.** Pick a partition + QoS (only the ones your account may actually submit to), CPUs, memory, GPUs, and walltime. A **live cluster-load panel** sits beside the form — idle CPUs, idle GPUs *by type*, and per-queue backlog with your own jobs highlighted — and recommends the queue you'll land on soonest. Choosing a GPU queue narrows the GPU-type list to the models that queue actually has, so you can't request one it doesn't offer.
|
|
316
|
+
- **It just becomes a server.** Nebula submits the job; the allocation shows up in the Server list as *"Queued · waiting…"*, then flips to a normal online server the moment the job starts. Select it and your kernels run on the compute node — proxied over the same WebSocket path as any remote kernel, so ZeroMQ never crosses the network. One allocation hosts **many** kernels: queue once, run several notebooks in it. When the walltime ends (or you cancel), the server drops out of the list and its kernels are marked done.
|
|
317
|
+
- **Nothing changes off-cluster.** The whole feature is detection-gated — no scheduler on the machine, no compute UI. Design and internals in [docs/SLURM_COMPUTE.md](docs/SLURM_COMPUTE.md).
|
|
318
|
+
|
|
225
319
|
## Tips
|
|
226
320
|
|
|
227
321
|
**Persistent Terminals**: Access standalone terminals via URL:
|
|
@@ -236,7 +330,7 @@ Terminals persist as long as the server runs. Bookmark different terminals for q
|
|
|
236
330
|
- **Frontend**: React 19, TypeScript, Vite, Tailwind CSS, CodeMirror
|
|
237
331
|
- **Backend**: Node.js, Fastify, ZeroMQ (Jupyter kernel protocol)
|
|
238
332
|
- **Auth**: TOTP (otplib), JWT (jsonwebtoken)
|
|
239
|
-
- **Agents**: MCP (`nebula-notebook-mcp`)
|
|
333
|
+
- **Agents**: MCP and the `nebula` CLI (also installable as a Claude Code skill), both in [`nebula-notebook-mcp`](https://www.npmjs.com/package/nebula-notebook-mcp), used by Claude Code, Codex, and other agent CLIs
|
|
240
334
|
|
|
241
335
|
## License
|
|
242
336
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{a as d,L as c,D as l,E as a}from"./services-shim-BirHVsih.js";function h(t,s){class n extends l{constructor(r,i){r=Object.assign(Object.assign({},r),{_view_name:"ErrorWidgetView",_view_module:"@jupyter-widgets/base",_model_module_version:a,_view_module_version:a,msg:s,error:t}),super(r,i),this.comm_live=!0}}return n}class g extends d{generateErrorMessage(){return{msg:this.model.get("msg"),stack:String(this.model.get("error").stack)}}render(){const{msg:s,stack:n}=this.generateErrorMessage();this.el.classList.add("jupyter-widgets");const e=document.createElement("div");e.classList.add("jupyter-widgets-error-widget","icon-error"),e.innerHTML=c;const r=document.createElement("pre");r.style.textAlign="center",r.innerText="Click to show javascript error.",e.append(r),this.el.appendChild(e);let i,o;this.el.onclick=()=>{e.classList.contains("icon-error")&&(o=o||e.clientHeight,i=i||e.clientWidth,e.classList.remove("icon-error"),e.innerHTML=`
|
|
2
|
+
<pre>[Open Browser Console for more detailed log - Double click to close this message]
|
|
3
|
+
${s}
|
|
4
|
+
${n}</pre>
|
|
5
|
+
`,e.style.height=`${o}px`,e.style.width=`${i}px`,e.classList.add("text-error"))},this.el.ondblclick=()=>{e.classList.contains("text-error")&&(e.classList.remove("text-error"),e.innerHTML=c,e.append(r),e.classList.add("icon-error"))}}}function E(t,s){return class extends g{generateErrorMessage(){return{msg:s,stack:String(t instanceof Error?t.stack:t)}}}}export{g as E,E as a,h as c};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|