Commit Graph
2 Commits
Author SHA1 Message Date
Paul BakausandClaude Opus 4.7 a4832adf2f fix(live-wrap): JSX/TSX correctness — multi-line tags, className, tag narrowing
Five related bugs that surfaced in a real Next.js App Router project
(EAC) all rooted in live-wrap.mjs treating source as line-anchored HTML:

1. findElement matched on raw substring anywhere, so it landed on a
   className continuation line of a multi-line JSX tag whose class
   happened to collide with a later target. The wrong tag got wrapped
   (really, its attribute line got wrapped, producing broken JSX).
2. findClosingLine's opener regex required whitespace or `>` after the
   tag name, so a bare `<section\n  className="..."\n>` opener was
   unrecognised; it returned `start` silently, capturing only one line.
3. buildSearchQueries only emitted `class="..."`, missing React's
   `className="..."`. The full-combo query never fired in JSX, so
   search silently degraded to single-class substring matching.
4. Wrapper output used `style="display: contents"` unconditionally,
   which is invalid JSX (type error in strict setups, parser hazard
   in production transforms).
5. --tag was ignored during the primary class search. Ambiguous class
   hits inside the wrong element type weren't filtered out.

## Fixes

- New OPENER_RE `/<([A-Za-z][A-Za-z0-9]*)(?=[\s/>]|$)/` recognises
  tag openers at end-of-line too.
- New findOpenerLine(lines, matchLine, tag): walks up to 10 lines
  backward to the enclosing opener when the match lands on a
  continuation line. Aborts the walk if it hits a different tag.
- findElement now iterates all matches (not just the first), takes
  a tag parameter, and routes through findOpenerLine; wrapCli passes
  --tag through.
- buildSearchQueries emits both `class="..."` and `className="..."`
  for multi-class queries, and both `<tag class="..."` /
  `<tag className="..."` for tag+class combos.
- Wrapper builder emits `style={{ display: "contents" }}` when
  commentSyntax is JSX and `style="display: contents"` otherwise.
- findClosingLine uses the same OPENER_RE so its tag-name extraction
  works on multi-line openers too.

## Tests

Five new regression tests in tests/live-wrap.test.mjs, all failing
before the fix, all passing after:

- wraps the correct <section> when a class collides with a multi-line
  tag elsewhere
- emits JSX-safe style attribute ({{ }}) in .tsx files
- finds elements via className= (React) when the exact class combo is
  unique there
- respects --tag to reject matches inside the wrong element type
- findClosingLine recognises an opener line where the tag sits at
  end-of-line (multi-line JSX)

31/31 in tests/live-wrap.test.mjs and 54/54 in
tests/framework-fixtures.test.mjs pass.

Credit: precise bug report from the other agent in the EAC session
made diagnosis and test design straightforward.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 00:19:32 -07:00
Paul BakausandClaude Opus 4.6 455fe39155 Add 41 tests for live-wrap and live-server, add auto-execute guards
Tests:
- tests/live-wrap.test.mjs (26 tests): unit tests for buildSearchQueries,
  findElement, findClosingLine, detectCommentSyntax (20 pure function
  tests) + integration tests for the full wrapCli on HTML and JSX
  fixtures with temp dirs (6 tests covering wrapping, ID/class lookup,
  error handling, content preservation).

- tests/live-server.test.mjs (15 tests): integration tests that start a
  real server on port 8499, then test /health, /live.js, /detect.js,
  /poll (timeout + auth), /events POST (validation + auth), browser→agent
  event flow (POST event → poll receives it), agent→browser SSE flow
  (POST reply → SSE stream delivers it), /source (read, path traversal
  rejection, auth, 404).

Also:
- Added auto-execute guards to live-wrap.mjs and live-poll.mjs so they
  work when run directly with `node live-wrap.mjs ...` (needed for both
  skill instructions and integration tests).
- Exported buildSearchQueries, findElement, findClosingLine,
  detectCommentSyntax from live-wrap.mjs for unit testing.
- Updated package.json test script to include the new test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 19:35:26 -07:00