Repository navigation
Put report_tools blocks and table rows on their own lines (ENG-3358) - #550
Merged
Merged
Conversation
…-3358) Pages built with report_tools were one long line after </style>, so line-based tools (read_text_file ranges, html_lint line numbers, diffs) could not address a single section. Block helpers now end their markup with a line break, one table row, list item, chart bar and option per line. Line breaks go only where the browser shows no whitespace; rendering is pixel-identical. update and insert keep that layout: a kept section heading keeps its line break, a whole-element replacement does not double the break, and insert(after=) puts a block after the element's line break. New markup uses the page's line endings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-updates (ENG-3358) - Take the page's line break from its first one: a "\r\n" inside a shown value no longer turns all new markup into CRLF on an LF page. Computed once per update. - insert(after=) moves past the element's line break only for Html blocks; plain text always stays next to the element. - update with rt.table(..., id=) replaces the table's scroll wrapper too, instead of nesting a new wrapper on every update. - Docstrings describe the placement and line-ending rules; tests cover CRLF pages, mixed pages, plain-text inserts and repeated table updates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…G-3358) - One _EOL pattern for page line-ending detection and conversion. - update (whole element) and insert(after=) both extend the span over the line break that ends a block (_block_end) instead of trimming new markup in one place and moving the insert point in another. - update converts new markup to the page's line ending once per edit. - Rename _table_wrap to _table_html so it does not read like _TABLE_WRAP. - Simpler layout assertion in the tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Pages built with
report_toolsput everything after</style>on one line: a 9 KB dashboard had a 6,558-character line holding the whole visible page. Line-based tools get nothing useful from that:read_text_filecannot read one section by line range (and shortens a very long line),html_lintreports every console error on the same line, and a diff shows the whole page as one changed line.Result: each block and each table row, list item, chart bar and select option is on its own line. The rendered page is pixel-identical to before.
rt.update/rt.insertkeep this layout and still work on existing single-line pages.Changes
section,para,bullets,table,bar_chart,filter_table,data) end their markup with\n;page()puts head tags,<body>,<main>and the closing tags on their own lines."": a line break between two inline parts (text and a link in a section) would render as a space. For the same reason the filter's</label><select>stay together.update/insertkeep the layout:insert(after=)puts anHtmlblock after the element's line break; inline content and plain text stay right next to the element.\r\ninside a shown value does not count).updatewithrt.table(..., id=)now replaces the table'stable-wrapdiv too. Before, every such update nested one more wrapper (pre-existing bug).tableandfilter_tableshare one_table_wraphelper.Example of the new layout:
Existing pages stay single-line until rebuilt; nothing migrates them.
Testing
tests/test_report_tools.py: 41 passed. Six tests that pinned exact markup were updated. New tests check that:update+insertproduce the same bytes as rebuilding the page;\n, and a CRLF inside text does not make new markup CRLF;updateof a table yields the same page as a rebuild (one wrapper).update/insertcalls. Both were rendered in headless Electron in light and dark themes, at 1200 px and 375 px, with three filter selections. All 12 bitmaps are identical. A control run with one extra line break between</label>and<select>was reported as different in all 6 affected cases.Evals (cowork_evals, quick check)
baseline=origin/staging2727d049,eng-3358= this branch925aa781; same cowork-server (2fe11f41),mindshub_air, LLM judgesonnet, 2 repeats per variant. The variants differ only inreport_tools.pyand its tests. Two repeats are a smoke check for regressions, not a statistical comparison.dialog-dashboard-refine(5 turns, built withrt.page/rt.section/rt.bar_chart, extended withrt.insert)dialog-incremental-report-01(control: builds a Python script, does not use report_tools)dialog-dashboard-refine: all four repeats produced a dashboard. The baseline 0.12 is a wrong final answer (Europe instead of APAC), unrelated to report_tools. Program checks pass in 3 of 4 repeats (the failure is that same baseline answer).eng-3358dashboard built with report_tools has 292 lines, the longest 288 characters. In the othereng-3358repeat the agent wrote its own SVG chart, which keeps its own long line.rt.checkerror ("HTML tags shown as text" after passing raw HTML as a plain string) and recovered. No new errors fromrt.insert/rt.check.dialog-incremental-report-01spread is the known permission-question noise of that task.🤖 Generated with Claude Code