Skip to content

fix: format action now reformats Mermaid source and diagram - #132

Merged
peter6055 merged 3 commits into
mainfrom
fix/131-mermaid-format-action
Aug 8, 2026
Merged

peter6055 merged 3 commits into
mainfrom
fix/131-mermaid-format-action

Conversation

@peter6055

@peter6055 peter6055 commented Aug 8, 2026 •

Copy link
Copy Markdown
Owner

Closes #131

Problem

The editor's Format toolbar action did not reformat Mermaid source or the rendered diagram, so clicking Format produced no visible result for nested or indent-sensitive diagrams.

Change

  • Add an owned LiveMaid formatter (src/lib/mermaid-format.ts) with no new runtime dependency:
    • preserves YAML front matter, diagram declaration at column 0, and 4-space body indent
    • normalizes indentation/whitespace inside end-blocks (subgraph, loop, alt, opt, par, critical, break, rect) and brace bodies (class, state, namespace, ER)
    • skips structural reformatting for indent-sensitive diagram types (mindmap, timeline) with clear feedback
  • Wire the Format handler in EditorCodePanel.tsx through Monaco executeEdits (undoable, single undo step) and emit toasts: "Code formatted", "Already formatted", or a skip explanation.
  • Unit tests (12) and Playwright e2e tests (2) covering reformat, already-formatted, and indent-sensitive paths.

Verification

  • npm run prepush green: typecheck, lint, prettier check, 147 unit tests, production build
  • e2e screenshots captured for before/after/already-formatted/mindmap-skip (see tmp/format-131/)

Summary by CodeRabbit

  • New Features

    • Added Mermaid source formatting with normalized whitespace, blank lines, front matter, and supported diagram structure.
    • Preserved special handling for mindmap and timeline diagrams.
    • Formatting results now indicate whether content changed, was already formatted, or requires indentation-sensitive handling.
  • Bug Fixes

    • Improved formatting feedback with informational and error notifications.
    • Applied formatting through undoable editor changes.

@railway-app

railway-app Bot commented Aug 8, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the livemaid-pr-132 environment in livemaid

Service Status Web Updated (UTC)
livemaid ✅ Success (View Logs) Web Aug 8, 2026 at 1:32 pm

@railway-app
railway-app Bot temporarily deployed to livemaid / livemaid-pr-132 August 8, 2026 13:12 Destroyed
@coderabbitai

coderabbitai Bot commented Aug 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@peter6055, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 293f3cde-3c8c-4b96-ac9d-9e2435e2a841

📥 Commits

Reviewing files that changed from the base of the PR and between c8eea70 and df078b1.

📒 Files selected for processing (3)
  • src/components/editor/EditorCodePanel.tsx
  • src/lib/mermaid-format.ts
  • src/test/mermaid-format.test.ts
📝 Walkthrough

Walkthrough

The editor now delegates Mermaid formatting to a shared utility. The utility preserves front matter, normalizes whitespace, formats supported structures, and reports status. The editor applies changes through Monaco and displays feedback. Project guidance and TypeScript configuration were also updated.

Changes

Mermaid formatting flow

Layer / File(s) Summary
Formatter engine
src/lib/mermaid-format.ts
Adds Mermaid source formatting, front-matter preservation, structural indentation, diagram-specific cleanup, and status results.
Editor integration
src/components/editor/EditorCodePanel.tsx
Routes the Format action through formatMermaidSource, applies undoable Monaco edits, updates parent state, and reports outcomes.
Project guidance and TypeScript setup
AGENTS.md, tsconfig.json
Adds implementation principles and updates TypeScript include, path, and formatting configuration.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EditorCodePanel
  participant formatMermaidSource
  participant Monaco
  participant ParentState
  participant Toasts
  EditorCodePanel->>formatMermaidSource: Pass Mermaid source
  formatMermaidSource-->>EditorCodePanel: Return formatted source and status
  EditorCodePanel->>Monaco: Apply undoable edit
  EditorCodePanel->>ParentState: Update source state
  EditorCodePanel->>Toasts: Show formatting result
Loading

Possibly related PRs

Suggested reviewers: peter6055w

Poem

I formatted the diagram with a hop and a cheer,
Front matter stayed safe, and the rules became clear.
Monaco remembered each change in its stack,
Toasts told the tale when the source came back.
— A tidy rabbit 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The AGENTS.md guidance and tsconfig include changes are unrelated to the linked Mermaid formatting issue. Remove the unrelated AGENTS.md and tsconfig changes, or link them to separate issues.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The formatter invokes formatting, updates Monaco content, reports outcomes, and handles errors for issue #131.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: fixing the Format action to reformat Mermaid source and diagrams.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/131-mermaid-format-action

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@peter6055 peter6055 changed the title fix: Format action now reformats Mermaid source and diagram fix: format action now reformats Mermaid source and diagram Aug 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
src/lib/mermaid-format.ts (2)

129-143: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Simplify the depth computation; two branches are dead or redundant.

  • Line 130: stripped.startsWith("%%{") is unreachable. Lines 115-118 already handle directives and continue.
  • Lines 138-142: the end branch and the fallback branch compute the same expression, base + braceDepth + endBlockDepth.
♻️ Proposed simplification
-    let depth: number;
-    if (isDecl || stripped.startsWith("%%{")) {
-      depth = 0;
-    } else {
-      const base = seenDiagramDecl ? 1 : 0;
-      if (BLOCK_SAME.has(firstWord)) {
-        depth = base + braceDepth + Math.max(0, endBlockDepth - 1);
-      } else if (stripped === "}") {
-        depth = base + braceDepth;
-      } else if (firstWord === "end") {
-        depth = base + braceDepth + endBlockDepth;
-      } else {
-        depth = base + braceDepth + endBlockDepth;
-      }
-    }
+    let depth: number;
+    if (isDecl) {
+      depth = 0;
+    } else {
+      const base = seenDiagramDecl ? 1 : 0;
+      if (BLOCK_SAME.has(firstWord)) {
+        depth = base + braceDepth + Math.max(0, endBlockDepth - 1);
+      } else if (stripped === "}") {
+        depth = base + braceDepth;
+      } else {
+        depth = base + braceDepth + endBlockDepth;
+      }
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/mermaid-format.ts` around lines 129 - 143, In the depth computation
around the directive handling and BLOCK_SAME checks, remove the unreachable
stripped.startsWith("%%{") condition from the declaration branch, since
directives already continue earlier. Merge the firstWord === "end" branch with
the identical fallback expression while preserving the existing BLOCK_SAME and
closing-brace cases.

176-183: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

The skipped-indent-sensitive status forces the editor to duplicate the apply path. status encodes only "structure was skipped" and not "content changed", so the caller must re-derive the change with result.formatted !== code and repeat the whole Monaco edit sequence in a second branch.

  • src/lib/mermaid-format.ts#L176-L183: return "changed" or "unchanged" in the indent-sensitive branch as well, and report the skip through a separate boolean field on MermaidFormatResult.
  • src/components/editor/EditorCodePanel.tsx#L103-L132: collapse the two identical Monaco edit blocks into one apply path driven by status === "changed", then show the skip toast from the new boolean field.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/mermaid-format.ts` around lines 176 - 183, The indent-sensitive
result in src/lib/mermaid-format.ts#L176-L183 must distinguish content changes
from whether formatting was skipped: return status "changed" or "unchanged" and
add a separate boolean skip field to MermaidFormatResult. In
src/components/editor/EditorCodePanel.tsx#L103-L132, use status === "changed"
for one shared Monaco apply path and display the skip toast based on the new
boolean field.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/editor/EditorCodePanel.tsx`:
- Around line 109-112: In both format edit blocks in the editor formatting flow,
add a trailing editor.pushUndoStop() immediately after executeEdits completes.
Keep the existing leading undo stop so each formatting operation remains one
undo unit and cannot merge with the next user keystroke.

In `@src/lib/mermaid-format.ts`:
- Around line 185-192: Preserve the input document’s trailing newline in the
formatting flow around collapseBlankLines and the formatted comparison. Detect
whether code ends with "\n", restore that newline after joining reformatted
lines, and compare the resulting formatted value so already-formatted
newline-terminated documents remain unchanged.
- Around line 16-27: Add "box" to the BLOCK_OPEN set in mermaid-format.ts so
sequence-diagram box...end groups increase and decrease block depth correctly.
- Around line 78-87: The declaration detection in isDiagramDeclaration must
recognize all supported Mermaid diagram types without losing body indentation,
including flowchart-elk, kanban, packet/packet-beta, radar/radar-beta,
treemap/treemap-beta, and zenuml. Prefer deriving the result from
determineDiagramType, or otherwise update the matching so the first non-header,
non-comment Mermaid line is treated as the declaration while preserving existing
exclusions.

In `@tsconfig.json`:
- Around line 38-39: Remove the two absolute, machine-specific
temporary-directory entries from the TypeScript configuration’s include list,
leaving the existing project-local Next.js generated type paths intact. Do not
replace them with another root-specific path; if temporary app types require
checking, configure them through that app’s own tsconfig.json.

---

Nitpick comments:
In `@src/lib/mermaid-format.ts`:
- Around line 129-143: In the depth computation around the directive handling
and BLOCK_SAME checks, remove the unreachable stripped.startsWith("%%{")
condition from the declaration branch, since directives already continue
earlier. Merge the firstWord === "end" branch with the identical fallback
expression while preserving the existing BLOCK_SAME and closing-brace cases.
- Around line 176-183: The indent-sensitive result in
src/lib/mermaid-format.ts#L176-L183 must distinguish content changes from
whether formatting was skipped: return status "changed" or "unchanged" and add a
separate boolean skip field to MermaidFormatResult. In
src/components/editor/EditorCodePanel.tsx#L103-L132, use status === "changed"
for one shared Monaco apply path and display the skip toast based on the new
boolean field.
🪄 Autofix

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9039622f-d790-4731-a86e-1b5f554686db

📥 Commits

Reviewing files that changed from the base of the PR and between 23b9b20 and c8eea70.

📒 Files selected for processing (4)
  • AGENTS.md
  • src/components/editor/EditorCodePanel.tsx
  • src/lib/mermaid-format.ts
  • tsconfig.json

Comment thread src/components/editor/EditorCodePanel.tsx Outdated
Comment thread src/lib/mermaid-format.ts
Comment thread src/lib/mermaid-format.ts
Comment thread src/lib/mermaid-format.ts
Comment thread tsconfig.json Outdated
- Add box to BLOCK_OPEN so sequence diagram box...end groups indent correctly
- Recognize all supported diagram declarations (flowchart-elk, kanban,
  packet, radar, treemap, zenuml, C4) so body indentation is not dropped
- Simplify depth computation (drop unreachable directive branch, merge the
  identical end/fallback branches)
- Refactor status model: report changed/unchanged plus a separate
  skippedIndentSensitive flag; collapse the duplicated Monaco apply path
- Preserve the input document's trailing newline so already-formatted
  newline-terminated documents stay unchanged
- Remove machine-specific temp-directory entries from tsconfig.json include
- Add unit tests covering all of the above
@railway-app
railway-app Bot temporarily deployed to livemaid / livemaid-pr-132 August 8, 2026 13:31 Destroyed
@peter6055

Copy link
Copy Markdown
Owner Author

Addressed all CodeRabbit review feedback in df078b1. Summary:

Review-body nitpicks

  • Depth computation simplification: removed the unreachable stripped.startsWith("%%{") branch (directives continue earlier) and merged the identical end/fallback branches in formatBody.
  • Status model: MermaidFormatStatus is now only "changed" | "unchanged"; the skip signal moved to a separate skippedIndentSensitive?: boolean on MermaidFormatResult. EditorCodePanel now has a single shared Monaco apply path keyed on status === "changed" and shows the skip toast from the boolean — no duplicated edit block.

Pre-merge check: Out of Scope Changes

  • tsconfig.json: removed the two machine-specific /root/projects/livemaid/tmp/... include entries. They were an accidental local artifact from a test-server run (the tmp/ dir is gitignored and tsconfig also excludes it); the project-local .next/types + .next/dev/types entries remain.
  • AGENTS.md: kept intentionally — commit 3ce6062 adds repo-wide agent implementation principles, unrelated to the format feature. Happy to move it to a separate PR if preferred, but it does not affect this change.

Verification (also noted in each resolved thread): npm run prepush fully green — typecheck, lint (0 errors), prettier, 225 unit tests across 14 files (including 20 new mermaid-format tests), and a production next build.

@peter6055
peter6055 merged commit 292b584 into main Aug 8, 2026
7 checks passed
@peter6055
peter6055 deleted the fix/131-mermaid-format-action branch August 8, 2026 13:33

This branch was successfully deployed

No deployments
livemaid / livemaid-pr-132 — df078b14 Deployed Aug 8, 2026 by railway-app[bot]
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.

Bug: Format action does not format Mermaid source or diagram

1 participant