Skip to content

Editable story code view with validation#692

Open
Bl3f wants to merge 4 commits intomainfrom
cursor/editable-story-code-view-124b
Open

Editable story code view with validation#692
Bl3f wants to merge 4 commits intomainfrom
cursor/editable-story-code-view-124b

Conversation

@Bl3f
Copy link
Copy Markdown
Contributor

@Bl3f Bl3f commented Apr 30, 2026

Summary

Makes the story side panel's "code" view editable. Users can now modify the raw markdown of a story and save it as a new version, with live syntax validation to prevent saving invalid chart/table/grid blocks.

Walkthrough

story_code_view_editable_demo.mp4

End-to-end: open the side-panel Code view, type an invalid tag → validation banner appears and Save is disabled → fix the error → Save re-enables → click Save returns to preview mode.

Red validation banner with disabled Save button

Red banner lists validation errors; Monaco shows inline red markers on offending lines; Save button disabled with "Fix validation errors to save".

Preview mode after saving shows updated content and new version

After saving, the view returns to preview mode and the version counter increments.

What changed

  • @nao/shared/story-validation: new validateStoryCode utility that walks a story's markdown and returns structured errors for:
    • <chart> blocks missing query_id, chart_type, or x_axis_key
    • Invalid chart_type / x_axis_type values
    • Malformed / empty / missing series or data_key
    • <table> blocks missing query_id
    • Unterminated or unclosed <grid> / <chart> / <table> tags
    • Out-of-range cols on grids
  • Errors carry 1-based line/column so they can drive Monaco markers.
  • StoryCodeView: swapped from a read-only Monaco to an editable one with
    • local draft state
    • live validation markers (red squiggles + hover messages)
    • an error banner summarising issues
    • ⌘S / Ctrl+S save shortcut
    • theme handling via useEditorTheme
    • still read-only in shared story views (readonly mode)
  • StoryViewer + StoryHeader: new "Editing code" sub-header with Cancel / Save. Save is disabled while validation errors are present and wired through the existing createVersion tRPC mutation (identical flow to the tiptap editor).
  • Tests: 16 new test cases in apps/shared/tests/story-validation.test.ts.

Testing

  • npm run -w @nao/shared test — 28 passed (includes 16 new validation tests)
  • npm run lint -w @nao/shared
  • npm run lint -w @nao/frontend
  • npm run lint -w @nao/backend
  • ✅ Manual end-to-end test in the browser (see walkthrough above)

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

- StoryCodeView now supports editing story code with Monaco editor
- validateStoryCode utility in @nao/shared checks chart/table/grid syntax
- Invalid attributes surface as inline Monaco markers and a banner
- Save is disabled while validation errors are present
- Saving creates a new story version via the existing createVersion mutation
- Editing is disabled in readonly mode (shared story view)
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

🚀 Preview Deployment

URL https://pr-692-c6a4882.preview.getnao.io
Commit c6a4882

⚠️ No LLM API keys configured - you'll see the API key setup flow when trying to chat.


Preview will be automatically removed when this PR is closed.

@Bl3f Bl3f marked this pull request as ready for review April 30, 2026 14:07
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 7 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/shared/src/story-validation.ts">

<violation number="1" location="apps/shared/src/story-validation.ts:199">
P2: `isMarkdownTable` can misclassify real `<table>` tags by checking the full prior document instead of the current line, which may skip table validation.</violation>

<violation number="2" location="apps/shared/src/story-validation.ts:269">
P2: Malformed `<chart>`/`<table>` tags that end with `>` instead of `/>` are not detected, so invalid story code can pass validation.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread apps/shared/src/story-validation.ts Outdated
Comment thread apps/shared/src/story-validation.ts
The previous isMarkdownTable used a regex against the full preceding document
(/\|\s*$/.test(code.slice(0, index))) without the multiline flag, so any
prior markdown table row anywhere earlier in the document would cause
subsequent <table /> tags to be silently skipped during validation.

Now we only inspect the prefix of the current line and check whether it
starts with a pipe character.
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/shared/src/story-validation.ts">

<violation number="1" location="apps/shared/src/story-validation.ts:201">
P2: Markdown table detection is now too strict and misses valid rows without a leading `|`, which can produce false table-attribute validation errors.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread apps/shared/src/story-validation.ts Outdated
cursoragent and others added 2 commits April 30, 2026 15:03
… slash

The chart/table regexes treated the slash before the closing > as optional
(/<chart\\b([^/>]*?)\\/?>/), so a tag like <chart ... title="t"> (no slash)
silently passed validation even though the embed convention requires
self-closing tags (per apps/shared/src/tools/story.ts).

Now we capture the slash and emit a dedicated error message when it is
absent, while still happily accepting the canonical <chart ... />.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Signed-off-by: Christophe Blefari <christophe.blefari@gmail.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/shared/src/story-validation.ts">

<violation number="1" location="apps/shared/src/story-validation.ts:220">
P2: The new trailing-pipe heuristic can misclassify non-table lines as markdown tables, causing `<table>` validation to be skipped.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

function isMarkdownTable(code: string, index: number): boolean {
const lineStart = code.lastIndexOf('\n', index - 1) + 1;
const linePrefix = code.slice(lineStart, index);
return /^\s*\|/.test(linePrefix) || /\|\s*$/.test(linePrefix);
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.

P2: The new trailing-pipe heuristic can misclassify non-table lines as markdown tables, causing <table> validation to be skipped.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/shared/src/story-validation.ts, line 220:

<comment>The new trailing-pipe heuristic can misclassify non-table lines as markdown tables, causing `<table>` validation to be skipped.</comment>

<file context>
@@ -217,7 +217,7 @@ function validateTableBlocks(code: string): StoryValidationError[] {
 	const lineStart = code.lastIndexOf('\n', index - 1) + 1;
 	const linePrefix = code.slice(lineStart, index);
-	return /^\s*\|/.test(linePrefix);
+	return /^\s*\|/.test(linePrefix) || /\|\s*$/.test(linePrefix);
 }
 
</file context>
Suggested change
return /^\s*\|/.test(linePrefix) || /\|\s*$/.test(linePrefix);
const lineEnd = code.indexOf('\n', index);
const currentLine = code.slice(lineStart, lineEnd === -1 ? code.length : lineEnd);
return /^\s*\|/.test(linePrefix) || (/\|\s*$/.test(linePrefix) && /\|/.test(currentLine.slice(index - lineStart)));

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