hypernote 0.4.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.4.0 → hypernote-0.4.1}/.gitignore +3 -1
  2. hypernote-0.4.1/AGENTS.md +56 -0
  3. {hypernote-0.4.0 → hypernote-0.4.1}/CHANGELOG.md +35 -0
  4. {hypernote-0.4.0 → hypernote-0.4.1}/PKG-INFO +30 -9
  5. {hypernote-0.4.0 → hypernote-0.4.1}/README.md +29 -8
  6. hypernote-0.4.1/SKILL.md +267 -0
  7. hypernote-0.4.1/dev/agent-contributor.md +197 -0
  8. {hypernote-0.4.0 → hypernote-0.4.1}/docs/README.md +16 -3
  9. hypernote-0.4.1/docs/cli.md +209 -0
  10. hypernote-0.4.1/docs/getting-started.md +199 -0
  11. {hypernote-0.4.0 → hypernote-0.4.1}/docs/sdk.md +44 -13
  12. {hypernote-0.4.0 → hypernote-0.4.1}/pyproject.toml +1 -1
  13. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/cli/main.py +211 -21
  14. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/sdk.py +48 -6
  15. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_cli.py +427 -4
  16. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_sdk.py +47 -0
  17. {hypernote-0.4.0 → hypernote-0.4.1}/uv.lock +1 -1
  18. hypernote-0.4.0/AGENTS.md +0 -186
  19. hypernote-0.4.0/SKILL.md +0 -187
  20. hypernote-0.4.0/docs/cli.md +0 -121
  21. hypernote-0.4.0/docs/getting-started.md +0 -101
  22. {hypernote-0.4.0 → hypernote-0.4.1}/.github/workflows/release.yml +0 -0
  23. {hypernote-0.4.0 → hypernote-0.4.1}/CLAUDE.md +0 -0
  24. {hypernote-0.4.0 → hypernote-0.4.1}/CONTEXT.md +0 -0
  25. {hypernote-0.4.0 → hypernote-0.4.1}/dev/README.md +0 -0
  26. {hypernote-0.4.0 → hypernote-0.4.1}/dev/cli-agent-ergonomics-rollout.md +0 -0
  27. {hypernote-0.4.0 → hypernote-0.4.1}/dev/current-architecture.md +0 -0
  28. {hypernote-0.4.0 → hypernote-0.4.1}/dev/module-map.md +0 -0
  29. {hypernote-0.4.0 → hypernote-0.4.1}/dev/release.md +0 -0
  30. {hypernote-0.4.0 → hypernote-0.4.1}/dev/testing-and-verification.md +0 -0
  31. {hypernote-0.4.0 → hypernote-0.4.1}/docs/browser-regression-spec.md +0 -0
  32. {hypernote-0.4.0 → hypernote-0.4.1}/docs/runtime-model.md +0 -0
  33. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/__init__.py +0 -0
  34. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/actor_ledger.py +0 -0
  35. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/cli/__init__.py +0 -0
  36. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/errors.py +0 -0
  37. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/execution_orchestrator.py +0 -0
  38. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/runtime_manager.py +0 -0
  39. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/server/__init__.py +0 -0
  40. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/server/extension.py +0 -0
  41. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/server/handlers.py +0 -0
  42. {hypernote-0.4.0 → hypernote-0.4.1}/src/hypernote/server/subshell.py +0 -0
  43. {hypernote-0.4.0 → hypernote-0.4.1}/tests/__init__.py +0 -0
  44. {hypernote-0.4.0 → hypernote-0.4.1}/tests/conftest.py +0 -0
  45. {hypernote-0.4.0 → hypernote-0.4.1}/tests/helpers.py +0 -0
  46. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_actor_ledger.py +0 -0
  47. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_browser_regression.py +0 -0
  48. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_live_server.py +0 -0
  49. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_package_metadata.py +0 -0
  50. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_runtime_manager.py +0 -0
  51. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_server_extension.py +0 -0
  52. {hypernote-0.4.0 → hypernote-0.4.1}/tests/test_shared_notebook_accessor.py +0 -0
  53. {hypernote-0.4.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,41 @@ 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
+
7
42
  ## 0.4.0 - 2026-05-10
8
43
 
9
44
  Hypernote now treats Jupyter's real-time collaboration journal as temporary
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hypernote
3
- Version: 0.4.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
@@ -45,22 +45,34 @@ Description-Content-Type: text/markdown
45
45
 
46
46
  ```bash
47
47
  uv sync
48
- uv run hypernote --help
49
- uv run hypernote setup serve
50
48
  uv run hypernote setup doctor
51
- uv run hypernote create tmp/demo.ipynb
52
- uv run hypernote ix tmp/demo.ipynb -s 'value = 20 + 22\nprint(value)'
53
- 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
54
61
  ```
55
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
+
56
68
  For another repo's environment, install Hypernote there (`uv add hypernote --dev`) and run
57
- the same bootstrap command from that repo.
69
+ `setup doctor` / `setup serve` from that repo so kernels and notebook paths line up.
58
70
 
59
71
  ## Install
60
72
 
61
73
  The default install includes the JupyterLab integration stack Hypernote needs:
62
74
  JupyterLab, shared-document support, server-side notebook execution, and the
63
- collaboration/docprovider frontend packages.
75
+ Hypernote server extension.
64
76
 
65
77
  Use `hypernote[dev]` only for local development and CI tooling.
66
78
 
@@ -88,7 +100,7 @@ Hypernote owns:
88
100
  - actor attribution
89
101
  - SDK, CLI, and thin REST handlers
90
102
 
91
- ## Design discipline
103
+ ## Contributor discipline
92
104
 
93
105
  - shared behavior should have one owner, usually the SDK for agent-facing observation rules
94
106
  - command and payload variants should preserve one contract unless a difference is explicit and documented
@@ -97,12 +109,21 @@ Hypernote owns:
97
109
 
98
110
  ## Documentation
99
111
 
112
+ Operator docs:
113
+
100
114
  - [Getting Started](docs/getting-started.md)
101
115
  - [CLI Reference](docs/cli.md)
102
116
  - [SDK Reference](docs/sdk.md)
117
+
118
+ Contributor and advanced behavior docs:
119
+
120
+ - [Agent Contributor Guide](dev/agent-contributor.md)
103
121
  - [Runtime Model](docs/runtime-model.md)
104
122
  - [Browser Regression Spec](docs/browser-regression-spec.md)
105
123
 
124
+ Agents that only need to create, run, recover, or open notebooks can stop after
125
+ the operator docs.
126
+
106
127
  ## Verification
107
128
 
108
129
  For local development and CI, install the dev tier first:
@@ -20,22 +20,34 @@
20
20
 
21
21
  ```bash
22
22
  uv sync
23
- uv run hypernote --help
24
- uv run hypernote setup serve
25
23
  uv run hypernote setup doctor
26
- uv run hypernote create tmp/demo.ipynb
27
- uv run hypernote ix tmp/demo.ipynb -s 'value = 20 + 22\nprint(value)'
28
- 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
29
36
  ```
30
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
+
31
43
  For another repo's environment, install Hypernote there (`uv add hypernote --dev`) and run
32
- the same bootstrap command from that repo.
44
+ `setup doctor` / `setup serve` from that repo so kernels and notebook paths line up.
33
45
 
34
46
  ## Install
35
47
 
36
48
  The default install includes the JupyterLab integration stack Hypernote needs:
37
49
  JupyterLab, shared-document support, server-side notebook execution, and the
38
- collaboration/docprovider frontend packages.
50
+ Hypernote server extension.
39
51
 
40
52
  Use `hypernote[dev]` only for local development and CI tooling.
41
53
 
@@ -63,7 +75,7 @@ Hypernote owns:
63
75
  - actor attribution
64
76
  - SDK, CLI, and thin REST handlers
65
77
 
66
- ## Design discipline
78
+ ## Contributor discipline
67
79
 
68
80
  - shared behavior should have one owner, usually the SDK for agent-facing observation rules
69
81
  - command and payload variants should preserve one contract unless a difference is explicit and documented
@@ -72,12 +84,21 @@ Hypernote owns:
72
84
 
73
85
  ## Documentation
74
86
 
87
+ Operator docs:
88
+
75
89
  - [Getting Started](docs/getting-started.md)
76
90
  - [CLI Reference](docs/cli.md)
77
91
  - [SDK Reference](docs/sdk.md)
92
+
93
+ Contributor and advanced behavior docs:
94
+
95
+ - [Agent Contributor Guide](dev/agent-contributor.md)
78
96
  - [Runtime Model](docs/runtime-model.md)
79
97
  - [Browser Regression Spec](docs/browser-regression-spec.md)
80
98
 
99
+ Agents that only need to create, run, recover, or open notebooks can stop after
100
+ the operator docs.
101
+
81
102
  ## Verification
82
103
 
83
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.