Skip to content

feat(cli): stream block outputs in real-time during deepnote run#304

Draft
jamesbhobbs wants to merge 3 commits intomainfrom
feat/cli-streaming-output
Draft

feat(cli): stream block outputs in real-time during deepnote run#304
jamesbhobbs wants to merge 3 commits intomainfrom
feat/cli-streaming-output

Conversation

@jamesbhobbs
Copy link
Contributor

@jamesbhobbs jamesbhobbs commented Feb 19, 2026

Summary

  • Wire the existing onOutput callback from the execution engine to render block outputs immediately as they arrive from the Jupyter kernel, instead of batching them after block completion
  • For long-running blocks (e.g., training loops with print() updates), users now see output in real-time instead of waiting until the block finishes
  • Machine output modes (-o json, -o toon) are unchanged — they still collect outputs via result.outputs in onBlockDone

Test plan

  • All 1918 existing tests pass
  • TypeScript typecheck passes
  • Biome lint passes
  • -o json output includes outputs in blocks array (tested: does not render output via onOutput in machine output mode)
  • Blocks with no output show [1/3] label ✓ (50ms) on one line (tested: keeps status on same line as label for blocks with no output)
  • Manual test: run a notebook with a long-running block that prints incrementally and verify output streams in real-time

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved streaming output display with strategic newline formatting before first outputs and after blocks containing streamed content
    • Enhanced output handling in JSON mode to correctly preserve streamed outputs
  • Tests

    • Added comprehensive test coverage for streaming output behavior across different output modes and result formatting options

jamesbhobbs and others added 2 commits February 19, 2026 16:54
…ution

CLI --input values were being ignored because input blocks unconditionally
assigned from their saved metadata during execution, overwriting the
CLI-provided values. This patches the in-memory DeepnoteFile to inject
CLI input values into input block metadata before execution begins.

Also adds a test documenting that empty projects return exit code 0.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Previously, `deepnote run` waited until each block finished executing
before rendering all outputs at once. For long-running blocks (e.g.,
training loops with print() updates), users saw nothing until completion.

Wire the existing `onOutput` callback from the execution engine to
render outputs immediately as they arrive from the Jupyter kernel.
Machine output modes (-o json, -o toon) are unchanged.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@codecov
Copy link

codecov bot commented Feb 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.48%. Comparing base (9a0551a) to head (9949ada).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #304      +/-   ##
==========================================
+ Coverage   82.45%   82.48%   +0.02%     
==========================================
  Files         112      112              
  Lines        6807     6816       +9     
  Branches     1821     1823       +2     
==========================================
+ Hits         5613     5622       +9     
  Misses       1194     1194              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jamesbhobbs jamesbhobbs changed the base branch from main to fix/cli-input-overrides February 19, 2026 17:27
Base automatically changed from fix/cli-input-overrides to main February 20, 2026 08:27
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

The changes add streaming output coordination to the CLI run command. When blocks execute, the command now tracks which blocks need a newline before their first streamed output and which blocks produced streamed output. It inserts a newline before the first output from each block and a blank line after blocks with streamed output. Tests verify this behavior across different output modes and validate that the onOutput callback is properly forwarded to the engine.

Sequence Diagram

sequenceDiagram
    participant Engine as engine.runProject
    participant BlockEvent as Block Events
    participant Handler as Handler (run.ts)
    participant Console as Console Output

    Engine->>BlockEvent: emit block_start
    BlockEvent->>Handler: onBlockStart(blockId)
    Handler->>Handler: mark blockId in needsNewlineBeforeOutput

    Engine->>BlockEvent: emit onOutput(content)
    BlockEvent->>Handler: onOutput(blockId, content)
    alt Has pending newline
        Handler->>Console: render newline
    end
    Handler->>Console: render output content
    Handler->>Handler: mark blockId in blocksWithStreamedOutput
    Handler->>Handler: remove from needsNewlineBeforeOutput

    Engine->>BlockEvent: emit block_done
    BlockEvent->>Handler: onBlockComplete(blockId)
    Handler->>Handler: check hadStreamedOutput
    alt Had streamed output
        Handler->>Console: render blank line
    end
    Handler->>Handler: clear tracking for blockId
Loading
🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Updates Docs ⚠️ Warning PR implements streaming output feature for deepnote run command but lacks documentation updates to describe this user-facing behavior change. Update packages/cli/README.md to document streaming behavior and consider adding or updating docs/ guides for long-running block output handling.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly and specifically describes the main change: streaming block outputs in real-time during the deepnote run command, matching the core feature implemented across both test and production files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants