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.
Files changed (142) hide show
  1. package/README.md +110 -16
  2. package/dist/assets/errorwidget-Wy5ajPiM.js +5 -0
  3. package/dist/assets/fa-brands-400-CEJbCg16.woff +0 -0
  4. package/dist/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
  5. package/dist/assets/fa-brands-400-DnkPfk3o.eot +0 -0
  6. package/dist/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
  7. package/dist/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
  8. package/dist/assets/fa-regular-400-BhTwtT8w.eot +0 -0
  9. package/dist/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
  10. package/dist/assets/fa-regular-400-DFnMcJPd.woff +0 -0
  11. package/dist/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
  12. package/dist/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
  13. package/dist/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
  14. package/dist/assets/fa-solid-900-B6Axprfb.eot +0 -0
  15. package/dist/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
  16. package/dist/assets/fa-solid-900-DOXgCApm.woff +0 -0
  17. package/dist/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
  18. package/dist/assets/index-B_Bs5koo.js +1 -0
  19. package/dist/assets/index-BtWv4MIT.css +7 -0
  20. package/dist/assets/index-DK4nS74r.js +829 -0
  21. package/dist/assets/index-DeQN03nW.js +81 -0
  22. package/dist/assets/index-DzjpmUak.css +32 -0
  23. package/dist/assets/index-g6MjT-VG.js +1 -0
  24. package/dist/assets/services-shim-BirHVsih.js +33 -0
  25. package/dist/assets/viewlist-uomDf7I7.js +1 -0
  26. package/dist/assets/widgets-X7J3NxEn.css +1 -0
  27. package/dist/index.html +2 -2
  28. package/node-server/dist/auth/auth-middleware.js +22 -4
  29. package/node-server/dist/auth/auth-service.js +37 -7
  30. package/node-server/dist/cluster/client-registration.d.ts +12 -1
  31. package/node-server/dist/cluster/client-registration.js +38 -2
  32. package/node-server/dist/cluster/kernel-proxy.js +43 -12
  33. package/node-server/dist/cluster/server-registry.d.ts +17 -0
  34. package/node-server/dist/cluster/server-registry.js +57 -7
  35. package/node-server/dist/discovery/conda-locations.d.ts +73 -0
  36. package/node-server/dist/discovery/conda-locations.js +427 -0
  37. package/node-server/dist/discovery/discovery-service.d.ts +73 -4
  38. package/node-server/dist/discovery/discovery-service.js +211 -127
  39. package/node-server/dist/discovery/types.d.ts +0 -1
  40. package/node-server/dist/discovery/types.js +1 -2
  41. package/node-server/dist/environment.d.ts +12 -0
  42. package/node-server/dist/environment.js +104 -0
  43. package/node-server/dist/fs/fs-service.d.ts +86 -8
  44. package/node-server/dist/fs/fs-service.js +640 -99
  45. package/node-server/dist/fs/notebook-formats/percent.d.ts +25 -0
  46. package/node-server/dist/fs/notebook-formats/percent.js +286 -0
  47. package/node-server/dist/fs/notebook-formats/qmd.d.ts +29 -0
  48. package/node-server/dist/fs/notebook-formats/qmd.js +307 -0
  49. package/node-server/dist/fs/notebook-formats/registry.d.ts +12 -0
  50. package/node-server/dist/fs/notebook-formats/registry.js +77 -0
  51. package/node-server/dist/fs/notebook-formats/types.d.ts +37 -0
  52. package/node-server/dist/fs/notebook-formats/types.js +13 -0
  53. package/node-server/dist/fs/types.d.ts +9 -0
  54. package/node-server/dist/fs/types.js +8 -0
  55. package/node-server/dist/idle-exit.d.ts +52 -0
  56. package/node-server/dist/idle-exit.js +83 -0
  57. package/node-server/dist/index.js +198 -8
  58. package/node-server/dist/kernel/kernel-service.d.ts +130 -2
  59. package/node-server/dist/kernel/kernel-service.js +834 -64
  60. package/node-server/dist/kernel/kernelspec.d.ts +27 -0
  61. package/node-server/dist/kernel/kernelspec.js +75 -4
  62. package/node-server/dist/notebook/headless-handler.d.ts +12 -0
  63. package/node-server/dist/notebook/headless-handler.js +125 -29
  64. package/node-server/dist/notebook/operation-router.js +7 -2
  65. package/node-server/dist/notebook/undoRedoManager.d.ts +12 -1
  66. package/node-server/dist/notebook/undoRedoManager.js +49 -18
  67. package/node-server/dist/output/display-data.js +2 -0
  68. package/node-server/dist/private-tmp.d.ts +14 -0
  69. package/node-server/dist/private-tmp.js +70 -0
  70. package/node-server/dist/routes/autocomplete.d.ts +19 -0
  71. package/node-server/dist/routes/autocomplete.js +294 -0
  72. package/node-server/dist/routes/cluster.js +2 -2
  73. package/node-server/dist/routes/compute.d.ts +8 -0
  74. package/node-server/dist/routes/compute.js +136 -0
  75. package/node-server/dist/routes/fs.js +23 -6
  76. package/node-server/dist/routes/kernel.js +156 -3
  77. package/node-server/dist/routes/notebook.js +37 -3
  78. package/node-server/dist/routes/python.d.ts +1 -2
  79. package/node-server/dist/routes/python.js +139 -3
  80. package/node-server/dist/scheduler/allocation-service.d.ts +63 -0
  81. package/node-server/dist/scheduler/allocation-service.js +285 -0
  82. package/node-server/dist/scheduler/job-template.d.ts +30 -0
  83. package/node-server/dist/scheduler/job-template.js +85 -0
  84. package/node-server/dist/scheduler/mock-scheduler.d.ts +30 -0
  85. package/node-server/dist/scheduler/mock-scheduler.js +125 -0
  86. package/node-server/dist/scheduler/slurm-scheduler.d.ts +31 -0
  87. package/node-server/dist/scheduler/slurm-scheduler.js +406 -0
  88. package/node-server/dist/scheduler/types.d.ts +118 -0
  89. package/node-server/dist/scheduler/types.js +8 -0
  90. package/node-server/dist/scheduler/util.d.ts +7 -0
  91. package/node-server/dist/scheduler/util.js +20 -0
  92. package/node-server/dist/terminal/agent-registry.d.ts +87 -0
  93. package/node-server/dist/terminal/agent-registry.js +246 -0
  94. package/node-server/dist/terminal/binding-store.d.ts +57 -0
  95. package/node-server/dist/terminal/binding-store.js +0 -0
  96. package/node-server/dist/terminal/pty-manager.d.ts +23 -6
  97. package/node-server/dist/terminal/pty-manager.js +138 -19
  98. package/node-server/dist/terminal/server.js +155 -23
  99. package/node-server/dist/terminal/types.d.ts +2 -0
  100. package/node-server/dist/update-check.d.ts +20 -0
  101. package/node-server/dist/update-check.js +114 -0
  102. package/node-server/package.json +2 -0
  103. package/node_modules/nebula-autocomplete/README.md +145 -0
  104. package/node_modules/nebula-autocomplete/dist/backends/claude.d.ts +69 -0
  105. package/node_modules/nebula-autocomplete/dist/backends/claude.js +449 -0
  106. package/node_modules/nebula-autocomplete/dist/backends/codex.d.ts +45 -0
  107. package/node_modules/nebula-autocomplete/dist/backends/codex.js +108 -0
  108. package/node_modules/nebula-autocomplete/dist/client/fetcher.d.ts +16 -0
  109. package/node_modules/nebula-autocomplete/dist/client/fetcher.js +41 -0
  110. package/node_modules/nebula-autocomplete/dist/codemirror/ghostText.d.ts +43 -0
  111. package/node_modules/nebula-autocomplete/dist/codemirror/ghostText.js +175 -0
  112. package/node_modules/nebula-autocomplete/dist/core/engine.d.ts +17 -0
  113. package/node_modules/nebula-autocomplete/dist/core/engine.js +135 -0
  114. package/node_modules/nebula-autocomplete/dist/core/lru.d.ts +7 -0
  115. package/node_modules/nebula-autocomplete/dist/core/lru.js +26 -0
  116. package/node_modules/nebula-autocomplete/dist/core/prompt.d.ts +12 -0
  117. package/node_modules/nebula-autocomplete/dist/core/prompt.js +0 -0
  118. package/node_modules/nebula-autocomplete/dist/core/text.d.ts +53 -0
  119. package/node_modules/nebula-autocomplete/dist/core/text.js +169 -0
  120. package/node_modules/nebula-autocomplete/dist/index.d.ts +7 -0
  121. package/node_modules/nebula-autocomplete/dist/index.js +5 -0
  122. package/node_modules/nebula-autocomplete/dist/server/fastify.d.ts +40 -0
  123. package/node_modules/nebula-autocomplete/dist/server/fastify.js +52 -0
  124. package/node_modules/nebula-autocomplete/dist/transport.d.ts +55 -0
  125. package/node_modules/nebula-autocomplete/dist/transport.js +66 -0
  126. package/node_modules/nebula-autocomplete/dist/types.d.ts +103 -0
  127. package/node_modules/nebula-autocomplete/dist/types.js +1 -0
  128. package/node_modules/nebula-autocomplete/package.json +58 -0
  129. package/node_modules/nebula-autocomplete/server.d.ts +3 -0
  130. package/node_modules/nebula-autocomplete/server.js +3 -0
  131. package/package.json +18 -5
  132. package/scripts/postinstall.cjs +25 -5
  133. package/dist/assets/index-BvrHu37J.js +0 -648
  134. package/dist/assets/index-Dfj_xsKU.css +0 -32
  135. package/node-server/dist/llm/index.d.ts +0 -5
  136. package/node-server/dist/llm/index.js +0 -21
  137. package/node-server/dist/llm/llm-service.d.ts +0 -77
  138. package/node-server/dist/llm/llm-service.js +0 -454
  139. package/node-server/dist/llm/types.d.ts +0 -40
  140. package/node-server/dist/llm/types.js +0 -15
  141. package/node-server/dist/routes/llm.d.ts +0 -8
  142. 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 computing environment built for what's coming next: real Jupyter kernels, real filesystem access, and a notebook that agents (Claude Code, Codex, …) can drive end-to-end through MCP — while staying a fast, polished notebook even if you never touch the AI features.
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
- ![Nebula Notebook — agents drive the notebook via MCP](https://raw.githubusercontent.com/jzthree/nebula-notebook/main/docs/assets/nebula-hero.svg)
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
- On first start, a QR code will appear in the terminal. Scan it with an authenticator app (Google Authenticator, Authy, etc.) to set up 2FA.
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
- Open http://localhost:3000 and enter your 6-digit code.
82
+ ### Let agents in
16
83
 
17
- To let agents (Claude Code, Codex, Cursor, Gemini CLI, …) drive your notebooks, register the Nebula MCP on the machine where your agent runs:
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/jzthree/nebula-notebook.git
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
- npm run start
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
- - Real Jupyter kernel execution (Python, Julia, R, etc.)
51
- - Real filesystem access - open notebooks from anywhere
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
- - Undo/redo with full edit history
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
- - Full MCP toolset ([`nebula-notebook-mcp`](https://www.npmjs.com/package/nebula-notebook-mcp)): read/edit/execute cells, manage kernels and files from any agent on any machine
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 18+
91
- - Python 3.10+ with Jupyter kernels (`pip install ipykernel`)
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`) driven by Claude Code, Codex, and other agent CLIs
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};