hypernote 0.3.0__tar.gz → 0.4.1__tar.gz

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 (53) hide show
  1. {hypernote-0.3.0 → hypernote-0.4.1}/.gitignore +3 -1
  2. hypernote-0.4.1/AGENTS.md +56 -0
  3. {hypernote-0.3.0 → hypernote-0.4.1}/CHANGELOG.md +53 -0
  4. {hypernote-0.3.0 → hypernote-0.4.1}/CONTEXT.md +15 -0
  5. {hypernote-0.3.0 → hypernote-0.4.1}/PKG-INFO +32 -9
  6. {hypernote-0.3.0 → hypernote-0.4.1}/README.md +31 -8
  7. hypernote-0.4.1/SKILL.md +267 -0
  8. hypernote-0.4.1/dev/agent-contributor.md +197 -0
  9. {hypernote-0.3.0 → hypernote-0.4.1}/dev/current-architecture.md +3 -0
  10. {hypernote-0.3.0 → hypernote-0.4.1}/dev/release.md +22 -0
  11. {hypernote-0.3.0 → hypernote-0.4.1}/docs/README.md +16 -3
  12. hypernote-0.4.1/docs/cli.md +209 -0
  13. hypernote-0.4.1/docs/getting-started.md +199 -0
  14. {hypernote-0.3.0 → hypernote-0.4.1}/docs/runtime-model.md +13 -0
  15. {hypernote-0.3.0 → hypernote-0.4.1}/docs/sdk.md +44 -13
  16. {hypernote-0.3.0 → hypernote-0.4.1}/pyproject.toml +1 -1
  17. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/cli/main.py +213 -21
  18. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/sdk.py +48 -6
  19. {hypernote-0.3.0 → hypernote-0.4.1}/tests/conftest.py +4 -5
  20. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_cli.py +431 -4
  21. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_live_server.py +15 -0
  22. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_sdk.py +47 -0
  23. {hypernote-0.3.0 → hypernote-0.4.1}/uv.lock +1 -1
  24. hypernote-0.3.0/AGENTS.md +0 -186
  25. hypernote-0.3.0/SKILL.md +0 -183
  26. hypernote-0.3.0/docs/cli.md +0 -120
  27. hypernote-0.3.0/docs/getting-started.md +0 -95
  28. {hypernote-0.3.0 → hypernote-0.4.1}/.github/workflows/release.yml +0 -0
  29. {hypernote-0.3.0 → hypernote-0.4.1}/CLAUDE.md +0 -0
  30. {hypernote-0.3.0 → hypernote-0.4.1}/dev/README.md +0 -0
  31. {hypernote-0.3.0 → hypernote-0.4.1}/dev/cli-agent-ergonomics-rollout.md +0 -0
  32. {hypernote-0.3.0 → hypernote-0.4.1}/dev/module-map.md +0 -0
  33. {hypernote-0.3.0 → hypernote-0.4.1}/dev/testing-and-verification.md +0 -0
  34. {hypernote-0.3.0 → hypernote-0.4.1}/docs/browser-regression-spec.md +0 -0
  35. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/__init__.py +0 -0
  36. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/actor_ledger.py +0 -0
  37. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/cli/__init__.py +0 -0
  38. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/errors.py +0 -0
  39. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/execution_orchestrator.py +0 -0
  40. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/runtime_manager.py +0 -0
  41. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/server/__init__.py +0 -0
  42. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/server/extension.py +0 -0
  43. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/server/handlers.py +0 -0
  44. {hypernote-0.3.0 → hypernote-0.4.1}/src/hypernote/server/subshell.py +0 -0
  45. {hypernote-0.3.0 → hypernote-0.4.1}/tests/__init__.py +0 -0
  46. {hypernote-0.3.0 → hypernote-0.4.1}/tests/helpers.py +0 -0
  47. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_actor_ledger.py +0 -0
  48. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_browser_regression.py +0 -0
  49. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_package_metadata.py +0 -0
  50. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_runtime_manager.py +0 -0
  51. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_server_extension.py +0 -0
  52. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_shared_notebook_accessor.py +0 -0
  53. {hypernote-0.3.0 → hypernote-0.4.1}/tests/test_subshell.py +0 -0
@@ -18,4 +18,6 @@ lib/
18
18
  .jupyter/
19
19
  .agent-repl/
20
20
  tmp/
21
- vscode-extension/out/
21
+ vscode-extension/
22
+ dev/vscode-extension.md
23
+ docs/vscode-extension.md
@@ -0,0 +1,56 @@
1
+ # Hypernote
2
+
3
+ Notebook-first execution system built on top of Jupyter shared documents.
4
+
5
+ ## Operator Quick Start
6
+
7
+ Use this path when you are creating, running, recovering, or opening notebooks.
8
+ You can stop after this section unless you are changing Hypernote itself.
9
+
10
+ ```bash
11
+ uv run hypernote setup doctor
12
+ # If no Hypernote API is reachable, start the server from this repo.
13
+ # Omit --no-browser when you want setup to open JupyterLab immediately.
14
+ uv run hypernote setup serve --no-browser > tmp/hypernote-serve.log 2>&1 &
15
+ for _ in 1 2 3 4 5 6 7 8 9 10; do
16
+ uv run hypernote setup doctor | grep -q '"hypernote_api"[[:space:]]*:[[:space:]]*"ok"' && break
17
+ sleep 0.5
18
+ done
19
+ uv run hypernote setup doctor
20
+ notebook_path="tmp/demo-$(date +%Y%m%d-%H%M%S).ipynb"
21
+ uv run hypernote create "$notebook_path" --empty --brief
22
+ uv run hypernote ix "$notebook_path" -s 'value = 20 + 22; print(value)' --brief
23
+ uv run hypernote status "$notebook_path" --brief
24
+ ```
25
+
26
+ Use the notebook path the task actually needs. The `tmp/demo-...` path above is
27
+ only a disposable example for tests and agent smoke checks.
28
+
29
+ `--brief` keeps cell `output_preview` while omitting command hints, snapshot
30
+ tokens, and bulky raw output payloads. If the preview is too small, use a
31
+ focused read instead of reading the whole notebook:
32
+
33
+ ```bash
34
+ uv run hypernote cat "$notebook_path" --output CELL_ID --brief --full-output
35
+ ```
36
+
37
+ To hand the notebook to a browser, open:
38
+
39
+ ```text
40
+ <server-from-setup-doctor>/lab/tree/<notebook-path>
41
+ ```
42
+
43
+ ## Operator Docs
44
+
45
+ - [SKILL.md](SKILL.md)
46
+ - [docs/README.md](docs/README.md)
47
+ - [docs/getting-started.md](docs/getting-started.md)
48
+ - [docs/cli.md](docs/cli.md)
49
+ - [docs/sdk.md](docs/sdk.md)
50
+
51
+ ## Contributor Docs
52
+
53
+ If you are editing Hypernote code, tests, architecture, releases, or project
54
+ guidance, read [dev/agent-contributor.md](dev/agent-contributor.md). That file
55
+ contains the architecture map, code ownership notes, verification matrix, and
56
+ release rules intentionally omitted from this operator-facing quick path.
@@ -4,6 +4,59 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.4.1 - 2026-05-25
8
+
9
+ Hypernote now has a low-noise operator path for agents: create notebooks,
10
+ execute cells, inspect focused outputs, and hand off to JupyterLab without
11
+ filling context with server logs, hints, snapshots, or raw notebook payloads.
12
+
13
+ ### Added
14
+
15
+ - `--brief` output for `create`, `ix`, `exec`, `status`, `cat`, and
16
+ `edit replace`, preserving useful cell output previews while omitting bulky
17
+ command hints, snapshots, raw payloads, and per-cell batch chatter.
18
+ - `CellStatus.from_handle(cell)` for SDK-owned cell observation shaping from a
19
+ live `CellHandle`.
20
+ - Focused operator guidance for headless notebook setup, execution, recovery,
21
+ batch mode, SDK use, and browser handoff.
22
+
23
+ ### Changed
24
+
25
+ - `SKILL.md` and `AGENTS.md` now prioritize operator workflows; contributor
26
+ architecture, release, and verification guidance moved to
27
+ `dev/agent-contributor.md`.
28
+ - Headless setup recipes now redirect long-running server logs and wait briefly
29
+ for `setup doctor` readiness after backgrounding `setup serve`.
30
+ - Deferred VS Code extension artifacts are ignored until that surface is ready
31
+ to ship.
32
+
33
+ ### Fixed
34
+
35
+ - Stream output previews now normalize list-shaped Jupyter stream text and
36
+ strip ANSI color sequences.
37
+ - Brief execution output avoids presenting stale cell outputs as fresh when a
38
+ job was launched with `--no-wait`.
39
+ - `ix --brief` and `exec --brief` reject incompatible streaming or human output
40
+ modes before mutating notebook state.
41
+
42
+ ## 0.4.0 - 2026-05-10
43
+
44
+ Hypernote now treats Jupyter's real-time collaboration journal as temporary
45
+ server-local state for `setup serve`, keeping the `.ipynb` notebook file as the
46
+ only durable project artifact.
47
+
48
+ ### Changed
49
+
50
+ - `hypernote setup serve` now configures Jupyter RTC to use temporary
51
+ collaboration journal storage instead of Jupyter's default project-root
52
+ `.jupyter_ystore.db` SQLite database.
53
+ - Live-server and browser regression fixtures now launch with the same
54
+ temporary journal policy as `setup serve`, including coverage that notebook
55
+ execution does not create `.jupyter_ystore.db` in the server root.
56
+ - Project guidance now distinguishes the durable **Notebook File** from the
57
+ temporary **Collaboration Journal**, and documents the crash-recovery tradeoff
58
+ for unsaved live shared-document changes.
59
+
7
60
  ## 0.3.0 - 2026-05-10
8
61
 
9
62
  Hypernote is now a JupyterLab-first integration: the default install carries the
@@ -9,6 +9,14 @@ server so agents and humans can work against one notebook truth.
9
9
  The server-side notebook document that all Hypernote operations use as the live notebook truth.
10
10
  _Avoid_: file-only notebook truth
11
11
 
12
+ **Notebook File**:
13
+ The `.ipynb` artifact that persists notebook contents and outputs after the Shared Document is saved.
14
+ _Avoid_: Hypernote database, collaboration store, job history
15
+
16
+ **Collaboration Journal**:
17
+ The Jupyter real-time collaboration update store used as recoverability cache for live Shared Document state.
18
+ _Avoid_: notebook primary storage, Hypernote job history, attribution store
19
+
12
20
  **Hypernote JupyterLab Server**:
13
21
  A JupyterLab server launched or verified with Hypernote's required server and collaboration extensions.
14
22
  _Avoid_: plain Jupyter server, separate agent server
@@ -24,6 +32,8 @@ _Avoid_: separate runtime mode
24
32
  ## Relationships
25
33
 
26
34
  - A **Hypernote JupyterLab Server** owns the **Shared Document**.
35
+ - A **Shared Document** saves durable notebook contents and outputs into one **Notebook File**.
36
+ - A **Collaboration Journal** is temporary server-local state; Hypernote does not make it a durable project artifact or product choice.
27
37
  - An **Open Lab Tab** and **Agent Automation** must attach to the same **Hypernote JupyterLab Server**.
28
38
  - **Agent Automation** does not require an **Open Lab Tab**, but it still requires the **Hypernote JupyterLab Server**.
29
39
 
@@ -31,8 +41,13 @@ _Avoid_: separate runtime mode
31
41
 
32
42
  > **Dev:** "Can agents run notebooks without JupyterLab?"
33
43
  > **Domain expert:** "No separate mode: agents use the **Hypernote JupyterLab Server** even if nobody has an **Open Lab Tab**."
44
+ >
45
+ > **Dev:** "Is the collaboration database part of Hypernote's durable state?"
46
+ > **Domain expert:** "No — durability means the **Shared Document** has saved back to the **Notebook File**."
34
47
 
35
48
  ## Flagged Ambiguities
36
49
 
37
50
  - Agent work without an **Open Lab Tab** was previously described as a separate product mode; resolved: Hypernote only distinguishes whether an **Open Lab Tab** exists.
38
51
  - "Jupyter server" was used broadly; resolved: the supported product server is a **Hypernote JupyterLab Server**.
52
+ - Jupyter's real-time collaboration store was treated as possible Hypernote state; resolved: it is a **Collaboration Journal**, not primary notebook storage or Hypernote job history.
53
+ - Persistent collaboration-store configuration was considered as a user-facing choice; resolved: Hypernote treats the **Collaboration Journal** as temporary server-local state only.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hypernote
3
- Version: 0.3.0
3
+ Version: 0.4.1
4
4
  Summary: Thin control plane for Jupyter notebook execution with jobs, attribution, and runtime lifecycle
5
5
  Project-URL: Homepage, https://github.com/gilad-rubin/hypernote
6
6
  Project-URL: Repository, https://github.com/gilad-rubin/hypernote
@@ -29,6 +29,7 @@ Description-Content-Type: text/markdown
29
29
  - **One notebook truth** - notebook edits, execution, and late-open JupyterLab views all operate on the same logical document.
30
30
  - **Agent-first surface** - the Python SDK is primary, and the CLI is a thin shell over it.
31
31
  - **Ephemeral control plane** - Jupyter owns durable `.ipynb` contents and outputs; Hypernote owns in-memory runtimes, jobs, and attribution.
32
+ - **Temporary collaboration journal** - `setup serve` keeps Jupyter RTC updates in server-local temp storage, not repo-root databases.
32
33
 
33
34
  ## What it ships
34
35
 
@@ -44,22 +45,34 @@ Description-Content-Type: text/markdown
44
45
 
45
46
  ```bash
46
47
  uv sync
47
- uv run hypernote --help
48
- uv run hypernote setup serve
49
48
  uv run hypernote setup doctor
50
- uv run hypernote create tmp/demo.ipynb
51
- uv run hypernote ix tmp/demo.ipynb -s 'value = 20 + 22\nprint(value)'
52
- uv run hypernote status tmp/demo.ipynb --full
49
+ # If no Hypernote API is reachable, start the server from this repo.
50
+ # Omit --no-browser when you want setup to open JupyterLab immediately.
51
+ uv run hypernote setup serve --no-browser > tmp/hypernote-serve.log 2>&1 &
52
+ for _ in 1 2 3 4 5 6 7 8 9 10; do
53
+ uv run hypernote setup doctor | grep -q '"hypernote_api"[[:space:]]*:[[:space:]]*"ok"' && break
54
+ sleep 0.5
55
+ done
56
+ uv run hypernote setup doctor
57
+ notebook_path="tmp/demo-$(date +%Y%m%d-%H%M%S).ipynb"
58
+ uv run hypernote create "$notebook_path" --empty --brief
59
+ uv run hypernote ix "$notebook_path" -s 'value = 20 + 22; print(value)' --brief
60
+ uv run hypernote status "$notebook_path" --brief
53
61
  ```
54
62
 
63
+ Use the notebook path you actually want. The `tmp/demo-...` path above is only a
64
+ disposable example that avoids overwriting an existing notebook.
65
+ `--brief` keeps the cell's `output_preview` while omitting hints, snapshot
66
+ tokens, and bulky raw output payloads.
67
+
55
68
  For another repo's environment, install Hypernote there (`uv add hypernote --dev`) and run
56
- the same bootstrap command from that repo.
69
+ `setup doctor` / `setup serve` from that repo so kernels and notebook paths line up.
57
70
 
58
71
  ## Install
59
72
 
60
73
  The default install includes the JupyterLab integration stack Hypernote needs:
61
74
  JupyterLab, shared-document support, server-side notebook execution, and the
62
- collaboration/docprovider frontend packages.
75
+ Hypernote server extension.
63
76
 
64
77
  Use `hypernote[dev]` only for local development and CI tooling.
65
78
 
@@ -76,6 +89,7 @@ Jupyter owns:
76
89
 
77
90
  - notebook persistence
78
91
  - shared YDoc document state
92
+ - temporary collaboration journal state for live RTC updates
79
93
  - kernel and session primitives
80
94
  - notebook rendering in JupyterLab
81
95
 
@@ -86,7 +100,7 @@ Hypernote owns:
86
100
  - actor attribution
87
101
  - SDK, CLI, and thin REST handlers
88
102
 
89
- ## Design discipline
103
+ ## Contributor discipline
90
104
 
91
105
  - shared behavior should have one owner, usually the SDK for agent-facing observation rules
92
106
  - command and payload variants should preserve one contract unless a difference is explicit and documented
@@ -95,12 +109,21 @@ Hypernote owns:
95
109
 
96
110
  ## Documentation
97
111
 
112
+ Operator docs:
113
+
98
114
  - [Getting Started](docs/getting-started.md)
99
115
  - [CLI Reference](docs/cli.md)
100
116
  - [SDK Reference](docs/sdk.md)
117
+
118
+ Contributor and advanced behavior docs:
119
+
120
+ - [Agent Contributor Guide](dev/agent-contributor.md)
101
121
  - [Runtime Model](docs/runtime-model.md)
102
122
  - [Browser Regression Spec](docs/browser-regression-spec.md)
103
123
 
124
+ Agents that only need to create, run, recover, or open notebooks can stop after
125
+ the operator docs.
126
+
104
127
  ## Verification
105
128
 
106
129
  For local development and CI, install the dev tier first:
@@ -4,6 +4,7 @@
4
4
  - **One notebook truth** - notebook edits, execution, and late-open JupyterLab views all operate on the same logical document.
5
5
  - **Agent-first surface** - the Python SDK is primary, and the CLI is a thin shell over it.
6
6
  - **Ephemeral control plane** - Jupyter owns durable `.ipynb` contents and outputs; Hypernote owns in-memory runtimes, jobs, and attribution.
7
+ - **Temporary collaboration journal** - `setup serve` keeps Jupyter RTC updates in server-local temp storage, not repo-root databases.
7
8
 
8
9
  ## What it ships
9
10
 
@@ -19,22 +20,34 @@
19
20
 
20
21
  ```bash
21
22
  uv sync
22
- uv run hypernote --help
23
- uv run hypernote setup serve
24
23
  uv run hypernote setup doctor
25
- uv run hypernote create tmp/demo.ipynb
26
- uv run hypernote ix tmp/demo.ipynb -s 'value = 20 + 22\nprint(value)'
27
- uv run hypernote status tmp/demo.ipynb --full
24
+ # If no Hypernote API is reachable, start the server from this repo.
25
+ # Omit --no-browser when you want setup to open JupyterLab immediately.
26
+ uv run hypernote setup serve --no-browser > tmp/hypernote-serve.log 2>&1 &
27
+ for _ in 1 2 3 4 5 6 7 8 9 10; do
28
+ uv run hypernote setup doctor | grep -q '"hypernote_api"[[:space:]]*:[[:space:]]*"ok"' && break
29
+ sleep 0.5
30
+ done
31
+ uv run hypernote setup doctor
32
+ notebook_path="tmp/demo-$(date +%Y%m%d-%H%M%S).ipynb"
33
+ uv run hypernote create "$notebook_path" --empty --brief
34
+ uv run hypernote ix "$notebook_path" -s 'value = 20 + 22; print(value)' --brief
35
+ uv run hypernote status "$notebook_path" --brief
28
36
  ```
29
37
 
38
+ Use the notebook path you actually want. The `tmp/demo-...` path above is only a
39
+ disposable example that avoids overwriting an existing notebook.
40
+ `--brief` keeps the cell's `output_preview` while omitting hints, snapshot
41
+ tokens, and bulky raw output payloads.
42
+
30
43
  For another repo's environment, install Hypernote there (`uv add hypernote --dev`) and run
31
- the same bootstrap command from that repo.
44
+ `setup doctor` / `setup serve` from that repo so kernels and notebook paths line up.
32
45
 
33
46
  ## Install
34
47
 
35
48
  The default install includes the JupyterLab integration stack Hypernote needs:
36
49
  JupyterLab, shared-document support, server-side notebook execution, and the
37
- collaboration/docprovider frontend packages.
50
+ Hypernote server extension.
38
51
 
39
52
  Use `hypernote[dev]` only for local development and CI tooling.
40
53
 
@@ -51,6 +64,7 @@ Jupyter owns:
51
64
 
52
65
  - notebook persistence
53
66
  - shared YDoc document state
67
+ - temporary collaboration journal state for live RTC updates
54
68
  - kernel and session primitives
55
69
  - notebook rendering in JupyterLab
56
70
 
@@ -61,7 +75,7 @@ Hypernote owns:
61
75
  - actor attribution
62
76
  - SDK, CLI, and thin REST handlers
63
77
 
64
- ## Design discipline
78
+ ## Contributor discipline
65
79
 
66
80
  - shared behavior should have one owner, usually the SDK for agent-facing observation rules
67
81
  - command and payload variants should preserve one contract unless a difference is explicit and documented
@@ -70,12 +84,21 @@ Hypernote owns:
70
84
 
71
85
  ## Documentation
72
86
 
87
+ Operator docs:
88
+
73
89
  - [Getting Started](docs/getting-started.md)
74
90
  - [CLI Reference](docs/cli.md)
75
91
  - [SDK Reference](docs/sdk.md)
92
+
93
+ Contributor and advanced behavior docs:
94
+
95
+ - [Agent Contributor Guide](dev/agent-contributor.md)
76
96
  - [Runtime Model](docs/runtime-model.md)
77
97
  - [Browser Regression Spec](docs/browser-regression-spec.md)
78
98
 
99
+ Agents that only need to create, run, recover, or open notebooks can stop after
100
+ the operator docs.
101
+
79
102
  ## Verification
80
103
 
81
104
  For local development and CI, install the dev tier first:
@@ -0,0 +1,267 @@
1
+ ---
2
+ name: hypernote
3
+ description: Work against Hypernote's notebook-first SDK and agent-first CLI. Use this when an agent needs to create notebooks, insert or edit cells, run code without an open Lab tab, inspect notebook status or diffs, or verify JupyterLab attach/streaming behavior.
4
+ ---
5
+
6
+ # hypernote
7
+
8
+ `hypernote` is the notebook runtime surface. The SDK is the core API. The CLI is a thin shell over that SDK.
9
+
10
+ Run `uv run hypernote` for a live workspace dashboard when you need
11
+ orientation. Use `--help` only as an explicit discovery fallback when the task
12
+ is not covered by this skill or the docs.
13
+
14
+ ## Prerequisite
15
+
16
+ Hypernote CLI requires two things:
17
+
18
+ 1. **`hypernote` installed in the current repo's environment.**
19
+ If `uv run hypernote setup doctor` fails because the command is missing,
20
+ install it first:
21
+ ```bash
22
+ uv add hypernote --dev
23
+ ```
24
+
25
+ 2. **A running Hypernote-enabled JupyterLab server.**
26
+ See "Server lifecycle" below.
27
+
28
+ Once both are in place, all commands are just `uv run hypernote ...`.
29
+
30
+ ## Server lifecycle
31
+
32
+ One server serves all notebooks and all agents in a workspace. Do not start multiple servers.
33
+
34
+ **Check if a server is already running:**
35
+
36
+ ```bash
37
+ uv run hypernote setup doctor
38
+ ```
39
+
40
+ For headless CLI/SDK work, the important fields are `hypernote_api`,
41
+ `jupyter_server_nbmodel`, `jupyter_server_ydoc`, and `jobs_endpoint`. If those
42
+ are usable and `default_kernel` is plausible for the repo, use the server.
43
+ `default_kernel` may be a kernelspec name such as `python` or an interpreter
44
+ path. `jupyter_collaboration` or `jupyter_docprovider` showing `missing` is not
45
+ by itself a blocker for headless execution; investigate those only when browser
46
+ or JupyterLab collaboration behavior is failing.
47
+
48
+ **If no server is running, start one from the repo that owns the notebook:**
49
+
50
+ ```bash
51
+ uv run hypernote setup serve --no-browser > tmp/hypernote-serve.log 2>&1 &
52
+ ```
53
+
54
+ `setup serve` is a foreground process. Agents that need to keep working should
55
+ background it and redirect logs. The default address is `http://127.0.0.1:8888`.
56
+ Omit `--no-browser` when the user wants JupyterLab opened as part of setup; use
57
+ `--no-browser` only for quiet headless automation or when you will open a
58
+ specific notebook URL yourself.
59
+
60
+ Servers launched by `setup serve` use temporary Jupyter collaboration journal storage.
61
+ Notebook contents and outputs still persist through the `.ipynb` file once the
62
+ shared document is saved.
63
+
64
+ **If the server is running but `default_kernel` points to the wrong Python** (e.g., a
65
+ different repo's `.venv`), stop the old server and start a new one with `setup serve`
66
+ from this repo. This is the only case where you should restart a running server.
67
+
68
+ To stop the server: press `Ctrl+C` in the terminal where `setup serve` is running, or
69
+ if it's backgrounded, find its pid with `lsof -ti :8888` and kill it.
70
+
71
+ **If port 8888 is taken**, use a different port and point all commands at it:
72
+
73
+ ```bash
74
+ uv run hypernote setup serve --port 8889 --no-browser > tmp/hypernote-serve-8889.log 2>&1 &
75
+ uv run hypernote --server http://127.0.0.1:8889 setup doctor
76
+ ```
77
+
78
+ ## Quick Start
79
+
80
+ Pick the notebook path from the user's request. If the user did not ask for a
81
+ specific path, use a unique disposable path under `tmp/` so examples and agent
82
+ runs do not overwrite each other.
83
+
84
+ ```bash
85
+ uv run hypernote # live workspace dashboard and hints
86
+ uv run hypernote setup doctor # check for existing server
87
+ uv run hypernote setup serve --no-browser > tmp/hypernote-serve.log 2>&1 & # only if the API is unreachable and quiet headless setup is desired
88
+ for _ in 1 2 3 4 5 6 7 8 9 10; do
89
+ uv run hypernote setup doctor | grep -q '"hypernote_api"[[:space:]]*:[[:space:]]*"ok"' && break
90
+ sleep 0.5
91
+ done
92
+ uv run hypernote setup doctor # readiness check after a cold start
93
+ notebook_path="tmp/demo-$(date +%Y%m%d-%H%M%S).ipynb"
94
+ uv run hypernote create "$notebook_path" --empty --brief
95
+ uv run hypernote ix "$notebook_path" -s 'value = 20 + 22' --brief
96
+ uv run hypernote status "$notebook_path" --brief
97
+ ```
98
+
99
+ ## Fast Agent Smoke Test
100
+
101
+ When the task is simply to prove headless execution and optionally open the
102
+ result in JupyterLab, keep the workflow to the product path. Use the path the
103
+ user requested; the `tmp/` path below is only for disposable smoke tests:
104
+
105
+ ```bash
106
+ uv run hypernote setup doctor
107
+ # only if the Hypernote API is unreachable and you do not want setup to open Lab:
108
+ uv run hypernote setup serve --no-browser > tmp/hypernote-serve.log 2>&1 &
109
+ for _ in 1 2 3 4 5 6 7 8 9 10; do
110
+ uv run hypernote setup doctor | grep -q '"hypernote_api"[[:space:]]*:[[:space:]]*"ok"' && break
111
+ sleep 0.5
112
+ done
113
+ uv run hypernote setup doctor
114
+ notebook_path="tmp/demo-$(date +%Y%m%d-%H%M%S).ipynb"
115
+ uv run hypernote create "$notebook_path" --empty --brief
116
+ uv run hypernote ix "$notebook_path" -s 'value = 20 + 22; print(value)' --brief
117
+ ```
118
+
119
+ Run `setup serve` only when `setup doctor` shows the Hypernote API is
120
+ unreachable or the server belongs to the wrong environment. If you start the
121
+ server from an agent, redirect its output to `tmp/*.log`; Jupyter startup,
122
+ autosave, kernel, and 404 messages are operational noise unless the server
123
+ failed to start.
124
+
125
+ If the user asks to open JupyterLab during setup, omit `--no-browser`. If they
126
+ ask to open the resulting notebook, use the browser handoff URL below after the
127
+ headless command succeeds.
128
+
129
+ To hand the notebook to a browser or UI surface, open:
130
+
131
+ ```text
132
+ <server-from-setup-doctor>/lab/tree/<notebook-path>
133
+ ```
134
+
135
+ URL-encode path segments that contain spaces or special URL characters. Simple
136
+ workspace-relative paths such as `tmp/demo.ipynb` can be used directly.
137
+
138
+ For a smoke test, do not inspect broad docs, run command help, or stream server
139
+ logs unless the direct path fails and that information is needed for recovery.
140
+ Browser automation is only the final handoff step; Hypernote work should happen
141
+ through `setup serve`, `create`, and `ix`.
142
+
143
+ ## Common Agent Recipes
144
+
145
+ Use these compact paths before reaching for `--help` or broad notebook reads.
146
+ For agent loops, add `--brief` to `create`, `ix`, `exec`, `status`,
147
+ `edit replace`, and focused `cat` reads when you want the cell result without
148
+ command hints, snapshot tokens, raw output payloads, or per-cell batch chatter.
149
+ `--brief` still preserves `output_preview`; use the full command or
150
+ `cat --output CELL_ID --brief --full-output` when the preview is not enough.
151
+
152
+ - **Iterative multi-line work:** `create --empty`, then pipe each substantial
153
+ cell into `ix` with a heredoc. Inspect the just-run cell with
154
+ `cat --output CELL_ID --brief` before deciding the next `ix`. If the output
155
+ preview is truncated or the full result matters, use
156
+ `cat --output CELL_ID --brief --full-output`; this is still a focused cell read.
157
+ `CELL_ID` is the id reported by the preceding `ix` result. In `--brief`
158
+ output, use `cell_ids[0]` or `cells[].id`; in the full output, use
159
+ `inserted_cells[].id` or `job.cell_ids`. If automating extraction, parse that
160
+ JSON field; do not infer the id from notebook order.
161
+ - **Failed cell recovery:** read the failed cell output, replace the same cell,
162
+ then execute it again:
163
+ ```bash
164
+ uv run hypernote cat nb.ipynb --output CELL_ID --brief
165
+ uv run hypernote edit replace nb.ipynb CELL_ID -s 'print("fixed")' --brief
166
+ uv run hypernote exec nb.ipynb CELL_ID --brief
167
+ ```
168
+ `edit replace` changes source without running it; old outputs may remain until
169
+ the following `exec`.
170
+ - **Known-good batch:** use `ix --cells-file` only when intermediate inspection
171
+ is unnecessary. Batch output may contain one compact result for each executed
172
+ code cell plus a final aggregate; markdown cells are represented in the final
173
+ aggregate. The file is a JSON array of cell objects:
174
+ ```json
175
+ [
176
+ {"id": "setup", "type": "code", "source": "value = 21 * 2\nprint(value)"},
177
+ {"type": "code", "source": "print('batch-ok')"}
178
+ ]
179
+ ```
180
+ Each object supports `source`, optional `type` or `cell_type` (`code` or
181
+ `markdown`), and optional `id`.
182
+ ```bash
183
+ uv run hypernote ix "$notebook_path" --cells-file tmp/cells.json --brief
184
+ ```
185
+ - **SDK happy path:** use one short Python script that connects, inserts,
186
+ runs, waits, and prints `nb.status().summary`. Use `nb.status(full=True)` only
187
+ when you need full source/output details. For proof of a single cell's output,
188
+ call `nb.status().cell(cell.id).output_preview(full_output=True)`.
189
+
190
+ ## Core Workflow
191
+
192
+ The normal way to build and run a notebook is one cell at a time:
193
+
194
+ ```text
195
+ ix → read output → decide next cell → ix → repeat
196
+ ```
197
+
198
+ This is the happy path. Insert a cell, run it, observe the output, then decide what comes next.
199
+ Do not pre-plan all cells and batch-insert them. Work iteratively.
200
+
201
+ ### Passing cell source
202
+
203
+ Three input modes, from simplest to most robust:
204
+
205
+ 1. **Inline** for short single-line cells:
206
+ ```bash
207
+ uv run hypernote ix nb.ipynb -s 'print("hello")'
208
+ ```
209
+
210
+ 2. **Stdin with heredoc** for multi-line cells (preferred for anything non-trivial):
211
+ ```bash
212
+ cat <<'EOF' | uv run hypernote ix nb.ipynb
213
+ import pandas as pd
214
+ df = pd.read_csv("data.csv")
215
+ print(df.head())
216
+ EOF
217
+ ```
218
+
219
+ 3. **Source file** when the cell is very large or already on disk:
220
+ ```bash
221
+ uv run hypernote ix nb.ipynb --source-file path/to/cell.py
222
+ ```
223
+
224
+ Do not use `-s` for multi-line code. Shell quoting will corrupt newlines.
225
+
226
+ ### Commands
227
+
228
+ - `ix` — insert a cell and run it. This is the primary command.
229
+ - `exec` — re-run an existing cell by id (useful after editing a failed cell)
230
+ - `edit` — mutate cell source or structure without executing
231
+ - `run-all` / `restart` / `restart-run-all` — notebook-wide execution
232
+ - `status` / `diff` / `cat` — inspect notebook state and outputs with summary-first reads, filtered cells, and focused output flags
233
+
234
+ ### When a cell fails
235
+
236
+ 1. Read the error output from `ix`.
237
+ 2. Use `cat --cell <cell-id>` or `cat --output <cell-id>` if you need a compact view of the failure.
238
+ 3. Fix the source with `edit replace PATH CELL_ID -s '...'` or pipe new source through stdin.
239
+ 4. Re-run with `exec <cell-id>`.
240
+ 5. Continue with the next `ix`.
241
+
242
+ Do not re-insert a failed cell. Edit it in place and re-execute.
243
+
244
+ ### `--cells-file` (batch mode)
245
+
246
+ `ix --cells-file` inserts and runs multiple cells sequentially. Use it only for known-good
247
+ cell sequences where you do not need to inspect intermediate outputs.
248
+
249
+ If batch mode halts early (cell failure, interrupt, or input prompt), the output includes
250
+ `halt_reason`, `last_processed_cell_id`, `cells_inserted`, and `cells_remaining` so you
251
+ know exactly where to resume. Cells after the halt point were never inserted into the notebook.
252
+
253
+ ## Operator Practices
254
+
255
+ 1. Work iteratively: `ix` one cell, read the output, then decide the next cell.
256
+ 2. Use `create --empty` so you start with a clean notebook, not a Jupyter-inserted blank cell.
257
+ 3. Use heredoc or `--source-file` for multi-line cells. Never pass multi-line code through `-s`.
258
+ 4. Prefer the SDK and CLI over raw HTTP for notebook operation.
259
+ 5. Treat Jupyter shared documents as the source of truth. Open or closed JupyterLab tabs should show the same notebook result.
260
+ 6. For agents, prefer `--brief` output unless you intentionally need the fuller JSON payload.
261
+ 7. Start with `hypernote` itself when you need workspace context and the next best action.
262
+ 8. Use `--stream-json` only when you plan to watch the process; otherwise it wastes context.
263
+ 9. Start the server with `hypernote setup serve` instead of hand-writing Jupyter flags.
264
+ 10. Skip large rich outputs such as `graph.visualize()` in agent automation unless the visualization is the point of the run.
265
+ 11. Use unique notebook paths in smoke tests and demos.
266
+ 12. Move durable notes into `docs/` or `dev/`; keep `tmp/` disposable.
267
+ 13. Treat Hypernote jobs, runtime state, and cell attribution as ephemeral coordination state, not durable history.