* feat(ipynb): parse ANSI SGR sequences in notebook output
Tracebacks and stream output carry terminal colour codes that the notebook
printed raw. Splits text into styled runs (16/256/truecolor, bold, italic,
underline) and drops non-SGR escapes via the shared stripper.
* feat(ipynb): render notebooks like a notebook, not a form
- Prose inherits the app UI font instead of a bare terminal font name, which
Chromium could not resolve and fell back to Times (removes the now-dead
resolveEditorFontFamilyOrInherit).
- Markdown cells render by default; double-click or Enter edits them in the
same Monaco surface code cells use. Code cells activate on press so a
collapsing neighbour cannot swallow the click, which also retires the
root pointer-capture deactivation (Monaco blur already covers it).
- Code sits on its own tinted surface, the active cell gets a ring, and the
editor sizes to its content so activating a cell no longer jumps.
- The always-on 8-button toolbar and native select become a hover/focus
toolbar (move, delete, and a menu for insert and cell type); the Jupyter
[n] prompt turns into the run button.
- Outputs show only the richest MIME representation, HTML renders in a
script-less, no-network sandboxed frame sized to its content, and ANSI
colours use the default terminal palettes.
Adopts the MarkdownPreviewBody reuse, richest-MIME selection, extra raster
MIME ranks, and CSP-sandboxed auto-height HTML frame from #18542.
Co-authored-by: maxidiazbattan <maxidiazbattan@gmail.com>
* chore(ipynb): drop the nbformat label and BETA badge from the notebook header
parseIpynb already rejects notebooks without a v4 cells array, so the label
carried no actionable information; the parsed nbformat field goes with it.
Removes those catalog keys and the stale lowercase code/markdown ones.
* fix(ipynb): keep cells pixel-stable when they switch to editing
The preview and the live editor disagreed on four things, measured over CDP:
- Font: the excerpt painted the bare "SF Mono" name (or --font-mono via its
row class), while Monaco appended its own fallbacks and landed on Menlo.
Both now use resolveEditorFontStack, the editor font plus the terminal
fallback chain.
- Line height: 20px rows vs Monaco's 21px. Both read CODE_EXCERPT_LAYOUT.
- Gutter: a 48px line-number column plus 12px inset vs Monaco's 25px gutter.
Notebook cells drop line numbers (the Jupyter and VS Code notebook
default) and Monaco's decorations lane is the same 12px inset.
- Rows: colorized blank lines collapsed to 0px, and a trailing newline had
no preview row. Rows are fixed-height and a trailing newline opens an
empty last line, matching the Monaco model.
The [n] prompt and run icon now share one grid cell, so the hover swap keeps
the label's box and centre. The commented-line tint moves to a theme token.
* feat(ipynb): VS Code-style run gutter above a fixed execution count
Replaces the in-place [n]/play swap from 172b4f7937. The [n] count is always
shown and never moves; the run button sits above it in the same gutter
column, revealed on hover or focus from an invisible slot that keeps its
box. While a cell runs, the slot shows a spinner and the count reads [*].
* refactor(ipynb): give notebook code its own preview, keep MonacoCodeExcerpt unchanged
172b4f7937 bent the shared MonacoCodeExcerpt (used by PR comment code
context) to the notebook's layout, changing that surface's font, tracking
and highlight tint. The excerpt's rendering is now byte-identical to main;
only its colorizer is extracted as useMonacoColorizedLines. The notebook
renders its own rows from CODE_LAYOUT, the same metrics its Monaco editor
uses, so activation stays pixel-stable.
* fix(ipynb): open the cell editor with the caret where the user pressed
Monaco mounted with its caret at 1:1 and focus ran occurrence highlighting
on that first token, so clicking any line lit up every 'import'. The press
on the preview now maps to a model position (its rows mirror model lines)
and Monaco opens there before focusing; keyboard and markdown activation
open at the end. Occurrence highlighting stays on, as in VS Code notebooks.
* feat(ipynb): put the execution count on top and the run button below it
The [n] count now shares the first code line's box (the gutter mirrors the
code surface's border and padding, and the count is one line tall); the
run button slot sits beneath it and stays reserved while hidden.
* fix(editor): re-colorize code excerpts when the theme changes
Monaco's colorizer emits theme-specific token classes, so excerpts colorized
under one theme kept that theme's token colours after a switch (dark-theme
keywords rendered green on the light theme). Affects notebook previews and
PR comment code context.
* fix(ipynb): mount cell editors before paint so a click swaps in seamlessly
@monaco-editor/react waits on an async loader, shows "Loading..." and builds
the editor inside a display:none container. Every click on a cell therefore
painted a placeholder, then an editor laid out at 0x0 (one uncoloured line),
and the caret guess ran against the static preview, falling back to the end
of the cell whenever the press missed a text row (padding, gaps).
The cell editor is now created with monaco.editor.create in a layout effect:
sized, tokenized (restoring its view state marks the visible lines stable)
and placed before the first paint. Monaco hit-tests the press itself with
getTargetAtClientPoint, so the caret lands on the nearest position for text,
trailing whitespace, blank lines and padding; keyboard and markdown
activation open at the start. Indent guides stay off to match the preview.
Word and selection occurrence highlighting are off in cell editors, since
clicking a word lit up every other occurrence like a search.
Also drops wiring the rewrite made dead: the per-editor save shortcut (the
notebook's capture handler already owns Cmd+S), the callback refs, the
onSaveRequest prop, and the toolbar's positioning wrapper.
* fix(editor): follow OS theme flips when colorizing code excerpts
useMonacoColorizedLines read the theme once from settings, so a 'system'
theme flipping with the OS never re-colorized. It now uses
useDocumentDarkTheme, like the rest of the notebook; rendering is unchanged.
* fix(ipynb): let Escape close an open widget before it leaves the cell
The cell's Escape command had no context, so Escape with suggest, find or
parameter hints open closed the whole cell editor. It now only fires when
none of those widgets is visible.
* fix(ipynb): keep HTML output frames at an opaque origin
The output frame had allow-same-origin only so the viewer could measure its
content height. Notebook HTML is untrusted, so the frame is now sandbox=""
(opaque origin, no scripts) at a fixed height that fits a pandas head() or
describe() table and scrolls anything larger.
* refactor(fonts): move buildFontFamily into lib/monospace-font-family
lib/editor-font-zoom imported it from a terminal-pane component module. The
monospace fallback chain now lives in lib, and every importer, including the
terminal, points there. Pure move; the tests move with it.
* fix(editor): pass comma-separated editor font stacks through unchanged
resolveEditorFontStack quoted a value like "JetBrains Mono, monospace" as
one family name, which no font matches. A comma list is now used as-is;
only a single name gets the quoted fallback chain.
* chore(i18n): drop the Korean override for a removed notebook key
---------
Co-authored-by: maxidiazbattan <maxidiazbattan@gmail.com>