Commit 6fa9b9b
feat: night-shift roadmap — streamable HTTP, cell sync, terminal interrupt, review fixes
* test: add platformUtils unit tests
* docs: refresh MCP guide for current tools, add pluto-cli skill
- PLUTO_GUIDE.md's workflow section now teaches wait_for_notebook_idle
(instead of read_cell/list_cells polling loops), the 5-minute
timed_out semantics of execution tools, adoption of already-open
notebooks, and export_notebook_html
- new .claude/skills/pluto-cli skill teaches the CLI validation
workflow to Claude Code sessions in this repo
* feat: speak streamable HTTP (modern MCP transport) alongside legacy SSE
- POST /mcp handles streamable HTTP sessions (initialize creates one,
mcp-session-id routes follow-ups); GET /mcp with a session header
serves the streamable event stream, plain GET stays legacy SSE, and
DELETE /mcp ends a session — old configs and the CLI's own client
keep working unchanged
- install and the extension's config commands write type 'http' again,
now that the server actually speaks it; /health reports session
counts per transport
- verified live: SDK StreamableHTTPClientTransport lists all 23 tools
and calls get_notebook_status; legacy 'cli tools' works in parallel
* feat: sync external cell adds/removes/reorders into the VSCode view
Implements the long-stubbed _handleCellReorder. Any cell_order patch
(add/remove/replace) schedules a coalesced sync that rebuilds the
VSCode cell list from Pluto's state: cells present in both keep their
VSCode content and outputs, cells created via MCP tools or Pluto's
browser UI are materialized (markdown unwrapping, code_folded and
pluto_cell_id metadata), and remotely deleted cells disappear.
Feedback-loop protection: a per-notebook suppression counter makes
handleVsCodeNotebookChange ignore the change events our own applyEdit
produces (released on the next tick), and the sync defers while a
local cell add is mid-round-trip (a cell without pluto_cell_id would
otherwise be destroyed by the rebuild).
Needs manual verification in the Extension Development Host — CI
covers types/lint/units only.
* feat: terminal Ctrl+C interrupts the running Julia computation
Previously Ctrl+C only reclaimed the terminal prompt; the Julia-side
computation kept running. Now it also sends worker.interrupt()
(best-effort) so the kernel actually stops.
* test: real integration tests, wired into CI via xvfb
Replaces the scaffold sample with tests that exercise the extension
host: activation, command registration, and opening a real .pluto.jl
file through the serializer (type, cell parsing, metadata). New
Integration Test CI job runs them under xvfb-run — this is the check
that was commented out with a TODO since the beginning.
* chore: npm audit fix — resolve both critical advisories
Semver-compatible bumps only (no --force): 45 -> 23 advisories, the
remaining ones live inside dev tooling (vsce/npm internals) and need
major bumps there. Runtime deps ws and @modelcontextprotocol/sdk are
now clean; full suite, both builds, and CLI smoke verified.
* docs: bond-status findings, upstream rainbow notes, README consistency
- README Dev TODO documents exactly what works and what's stubbed in
the PlutoUI bond path (set_bond round trip works; state distribution
and js-link interop need controller→renderer plumbing + manual UI
verification)
- docs/UPSTREAM_RAINBOW_NOTES.md: paste-ready upstream issue drafts for
the waitSnippet listener race and the nbpkg serialize round-trip gap,
each with cause analysis and our local workaround
- renderer: bond acks no longer logged as unknown messages
- README: Claude Desktop → Claude Code (matches the relabeled command)
* chore(deps): bump all deps to latest, pin Julia at 1.12.6
Runtime: @modelcontextprotocol/sdk 1.30.0, uuid 14.0.1, ws 8.21.3,
zod 4.4.3 (rainbow already latest at 0.6.21). Dev tooling to latest
compatible; npm audit 23 -> 11, all remaining inside dev tooling.
Held back: eslint 10 / typescript 7 (typescript-eslint v8 peer range),
@types/vscode (must match engines ^1.75.0), @types/node (extension
host is Node 22).
juliaup pin 1.11.7 -> 1.12.6 (CLI default, docs, config example);
CI now sets up Julia 1.12. Three files reformatted by prettier 3.9.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: react to all Pluto updates, stop autosave echo duplicating cells
Execution lifecycle: executions now end on the running:false patch
(as the design intended) instead of on the first output patch, which
ended cells prematurely — 'using PlutoUI' reported success while nbpkg
was still installing. Streaming output while running no longer closes
the execution, and a late duplicate output patch can no longer clobber
the displayed duration with a ~0s synthetic execution (per-cell
last_run_timestamp guard).
Patch-less update events (cells_updated after a reactive re-run,
cell_local_update) carry the full notebook state but were dropped as
UNHANDLED — stale errors survived a successful re-run and the tree view
never refreshed. They now reconcile every settled cell whose result
changed since it was last rendered.
Cell duplication: Pluto autosaves the notebook file while VSCode has it
open; the resulting document revert fired contentChanges that were
re-applied to Pluto as user edits, minting new UUIDs for cells Pluto
already had (three copies of 'using PlutoUI' per Run All). Added cells
whose id Pluto already knows are skipped as echoes, cells with unknown
ids keep their identity through addSnippet, and removals whose id still
exists in the document are ignored.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore: add release workflow docs, license placeholder, test notebooks
LICENSE currently reads 'Not licensed yet (bear with us!)' which
contradicts the MIT declared in both package.jsons — committed as-is,
reconcile before publishing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat: sync Pluto-side code edits into VSCode cell text
cell_inputs.<id>.code replace patches (browser UI edits, MCP
update_cell) were logged UNHANDLED — the switch case listened for
'cell_input' (singular) which never matches. The patch now rewrites the
matching cell's text, unwrapping md""" wrappers for markup cells.
Echoes of our own executeCell push are dropped by text equality, and
the remote-edit suppression (now shared via beginRemoteEdit/
endRemoteEditSoon) guards the applyEdit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* style: prettier formatting for controller, test notebook state
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: release workflow runs in with-commit mode, document secret requirements
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: address review findings in controller execution and cell sync
- finishExecution renders the final state before ending, so a
running:false patch ordered before the output patch in one batch can
no longer strand the run-start placeholder (stamp dedupe would have
discarded the later output patch)
- pasted cells carry the source cell's pluto_cell_id; when the id maps
to more than one document cell the copy gets a fresh identity instead
of silently aliasing (and overwriting) the original Pluto cell
- drag-reorders surface as remove+add of the same id; they now route to
moveSnippets instead of being swallowed by the echo guards and later
reverted by the order sync
- state-reset path guard was '!queued || !running' (always true),
ending mid-run executions with stale results
- deferred order syncs reschedule with backoff and re-fire once a cell
gains its id, instead of dropping remote structural changes forever;
sync also defers while executions are in flight so replaceCells
cannot orphan them
- notebook close clears rendered-output stamps and re-subscribing
reconciles from worker state, so reopening a notebook with a live
worker renders existing results instead of staying blank
- remote cells materialize via createVsCodeCellFromPlutoCell (keeps
metadata and outputs) instead of a drifted hand-rolled copy
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(mcp): 404 for unknown streamable sessions, sweep idle sessions
Unknown session ids on POST /mcp returned 400/-32000, so restarted
clients could not tell 'session expired, re-initialize' from a bad
request; now 404/-32001 per spec, matching the GET/DELETE handler.
Streamable sessions were only removed on explicit DELETE — clients
that crash leak a transport+McpServer pair each; sessions idle past
2h are now swept every 10 minutes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(terminal): ctrl-c while queued no longer interrupts the whole notebook
Pluto only offers a notebook-wide interrupt; firing it while the
terminal snippet was still waiting in waitForIdle killed unrelated
editor executions. The interrupt is now sent only while the snippet is
actually running — a queued snippet is cancelled by the generation
bump alone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(ci): integration tests were compiled with noEmit and never ran
tsc -p . --outDir out emitted nothing (tsconfig sets noEmit:true, which
--outDir does not override), so the vscode-test runner found zero test
files and exited 0 — the Integration Test job has been green without
executing a single test. compile-tests now uses tsconfig.tests.json
(noEmit off, rewriteRelativeImportExtensions for the .ts-extension
imports). Suite verified locally: 3 passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: remove duplicate releaserc, fix phantom no-commit references
.releaserc.with-commit.json was byte-identical to .releaserc.json, and
both docs described a mode switch via a .releaserc.no-commit.json that
never existed. Mode switching is now documented as adding/removing the
@semantic-release/git plugin block.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore(release): prepare 0.3.0 (extension) and 0.6.0 (cli)
Versions bumped ahead of the squash-merge; CHANGELOG entry written
manually. @plutojl/cli npm publishing is switched to manual
(npmPublish: false) — the mcp-release workflow still tags and creates
the GitHub release.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 9235840 commit 6fa9b9b
32 files changed
Lines changed: 12558 additions & 10653 deletions
File tree
- .claude/skills/pluto-cli
- .github/workflows
- docs
- packages/advanced-pluto-mcp
- renderer/components
- src
- __tests__
- cli
- commands
- test
- treeView
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
80 | | - | |
| 80 | + | |
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| |||
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
93 | | - | |
94 | | - | |
95 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
96 | 115 | | |
97 | 116 | | |
98 | 117 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
1 | 27 | | |
2 | 28 | | |
3 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
79 | | - | |
| 79 | + | |
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| |||
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
72 | | - | |
| 72 | + | |
73 | 73 | | |
74 | | - | |
| 74 | + | |
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
| |||
110 | 110 | | |
111 | 111 | | |
112 | 112 | | |
113 | | - | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
114 | 116 | | |
115 | 117 | | |
116 | 118 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
0 commit comments