Skip to content

feat(blocks): add indent support for bullet text blocks in Markdown#347

Merged
equiet merged 1 commit into
mainfrom
jj/indentable-bullet-blocks
Mar 25, 2026
Merged

feat(blocks): add indent support for bullet text blocks in Markdown#347
equiet merged 1 commit into
mainfrom
jj/indentable-bullet-blocks

Conversation

@equiet

@equiet equiet commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added support for indented bullet points in text blocks with configurable nesting levels, enabling proper formatting of hierarchical bullet item structures.

@equiet equiet requested a review from a team as a code owner March 24, 2026 22:30
@equiet equiet requested a review from saltenasl March 24, 2026 22:30
@coderabbitai

coderabbitai Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Added support for indentation levels in bullet text blocks. A new BulletTextBlockMetadata interface with optional indent_level property was introduced. The markdown generation for bullet text blocks now reads this property and prefixes the bullet with repeated spaces accordingly, enabling hierarchical indentation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 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 adds indent support for bullet text blocks but lacks documentation updates in blocks-text.md and related docs. Update blocks-text.md and docs/text-editing.md with indent_level functionality, usage examples, and constraints.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding indent support for bullet text blocks via the new indent_level property in the Markdown generation logic.

✏️ 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.

@codecov

codecov Bot commented Mar 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.70%. Comparing base (bd2eff7) to head (d0eb14f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #347   +/-   ##
=======================================
  Coverage   82.70%   82.70%           
=======================================
  Files         126      126           
  Lines        7614     7616    +2     
  Branches     2053     2118   +65     
=======================================
+ Hits         6297     6299    +2     
  Misses       1316     1316           
  Partials        1        1           

☔ 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/blocks/src/blocks/text-blocks.ts`:
- Around line 113-115: The bullet emitter uses an indent prefix (`const indent =
'  '.repeat(metadata?.indent_level ?? 0)`) and returns `${indent}-
${escapeMarkdown(content)}`, but the normalization step only strips `- ` at
column 0 and will leave `- ` for indented bullets; update the normalization code
to remove a leading bullet with any amount of whitespace (e.g. strip
`/^\s*-\s+/`) so that indented bullets emitted by the
BulletTextBlockMetadata/indent logic are normalized correctly, and ensure
escapeMarkdown(content) behavior is preserved when matching and removing the
bullet prefix.
- Around line 113-115: The code unsafely casts block.metadata to
BulletTextBlockMetadata and calls 'indent_level' with .repeat(), which will
throw for negative or non-integer values; instead narrow/validate metadata
without an unchecked cast (avoid 'as'), check that metadata?.indent_level is a
finite non-negative integer (e.g., Number.isFinite and Number.isInteger) and
clamp or default to 0 (e.g., let level = Math.max(0, Math.floor(parsedValue ||
0))), then compute indent = '  '.repeat(level) and return `${indent}-
${escapeMarkdown(content)}`; update the code paths around the metadata variable
(the metadata binding in this snippet) and any helper that reads indent_level to
enforce this validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8833b10f-538d-4f4d-ab77-11fda8d9f81d

📥 Commits

Reviewing files that changed from the base of the PR and between bd2eff7 and d0eb14f.

📒 Files selected for processing (1)
  • packages/blocks/src/blocks/text-blocks.ts

Comment on lines +113 to +115
const metadata = block.metadata as BulletTextBlockMetadata
const indent = ' '.repeat(metadata?.indent_level ?? 0)
return `${indent}- ${escapeMarkdown(content)}`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Keep bullet markdown round-trip consistent with indentation.

This change emits indented bullets, but Line 153 only strips bullets at column 0. Indented bullet text may retain - when normalized.

Suggested fix (outside this hunk)
   if (block.type === 'text-cell-bullet') {
-    return content.replace(/^-+\s+/, '').trim()
+    return content.replace(/^\s*-\s+/, '').trim()
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/blocks/src/blocks/text-blocks.ts` around lines 113 - 115, The bullet
emitter uses an indent prefix (`const indent = ' 
'.repeat(metadata?.indent_level ?? 0)`) and returns `${indent}-
${escapeMarkdown(content)}`, but the normalization step only strips `- ` at
column 0 and will leave `- ` for indented bullets; update the normalization code
to remove a leading bullet with any amount of whitespace (e.g. strip
`/^\s*-\s+/`) so that indented bullets emitted by the
BulletTextBlockMetadata/indent logic are normalized correctly, and ensure
escapeMarkdown(content) behavior is preserved when matching and removing the
bullet prefix.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find schema/type definitions relevant to bullet metadata.
fd 'deepnote-file-schema.*' packages

# Inspect typing/usage of TextCellBulletBlock metadata and indent_level.
rg -n -C3 --type=ts '\bTextCellBulletBlock\b|\bindent_level\b|\bmetadata\b' packages

Repository: deepnote/deepnote

Length of output: 50374


🏁 Script executed:

rg -n 'BulletTextBlockMetadata' packages --type=ts -A 5 -B 2

Repository: deepnote/deepnote

Length of output: 1283


🏁 Script executed:

fd 'deepnote-file-schema' packages --exec head -100 {}

Repository: deepnote/deepnote

Length of output: 3899


🏁 Script executed:

cat -n packages/blocks/src/blocks/text-blocks.ts | sed -n '105,120p'

Repository: deepnote/deepnote

Length of output: 687


🏁 Script executed:

rg -n 'text-cell-bullet|text.cell.bullet' packages --type=ts -A 3 -B 1

Repository: deepnote/deepnote

Length of output: 3642


🏁 Script executed:

rg -n 'indent_level' packages --type=ts -B 2 -A 2

Repository: deepnote/deepnote

Length of output: 836


Guard indent_level before .repeat() and avoid unchecked cast.

indent_level is typed as number with no constraints ensuring it's non-negative. A negative value will cause .repeat() to throw RangeError at runtime. Remove the unsafe cast and validate the value:

Suggested fix
-    const metadata = block.metadata as BulletTextBlockMetadata
-    const indent = '  '.repeat(metadata?.indent_level ?? 0)
+    const metadata = block.metadata
+    const rawIndentLevel = metadata?.indent_level
+    const indentLevel =
+      Number.isInteger(rawIndentLevel) && rawIndentLevel >= 0 ? rawIndentLevel : 0
+    const indent = '  '.repeat(indentLevel)
     return `${indent}- ${escapeMarkdown(content)}`

Per coding guidelines: "Use strict type checking in TypeScript files" and "Prefer type safety over convenience in TypeScript".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const metadata = block.metadata as BulletTextBlockMetadata
const indent = ' '.repeat(metadata?.indent_level ?? 0)
return `${indent}- ${escapeMarkdown(content)}`
const metadata = block.metadata
const rawIndentLevel = metadata?.indent_level
const indentLevel =
Number.isInteger(rawIndentLevel) && rawIndentLevel >= 0 ? rawIndentLevel : 0
const indent = ' '.repeat(indentLevel)
return `${indent}- ${escapeMarkdown(content)}`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/blocks/src/blocks/text-blocks.ts` around lines 113 - 115, The code
unsafely casts block.metadata to BulletTextBlockMetadata and calls
'indent_level' with .repeat(), which will throw for negative or non-integer
values; instead narrow/validate metadata without an unchecked cast (avoid 'as'),
check that metadata?.indent_level is a finite non-negative integer (e.g.,
Number.isFinite and Number.isInteger) and clamp or default to 0 (e.g., let level
= Math.max(0, Math.floor(parsedValue || 0))), then compute indent = ' 
'.repeat(level) and return `${indent}- ${escapeMarkdown(content)}`; update the
code paths around the metadata variable (the metadata binding in this snippet)
and any helper that reads indent_level to enforce this validation.

@equiet equiet merged commit 72a25a6 into main Mar 25, 2026
19 of 21 checks passed
@equiet equiet deleted the jj/indentable-bullet-blocks branch March 25, 2026 05:55
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