mesurer-solid 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2911,7 +2911,7 @@ var Gn = "mesurer:capture-bridge-ping", Kn = "mesurer:capture-bridge-request", q
2911
2911
  S = !0, y += 1, u.removeEventListener("pointerdown", L), u.removeEventListener("pointermove", R), u.removeEventListener("pointerup", z), u.removeEventListener("pointercancel", B), i.removeEventListener("keydown", V, !0), v && i.clearTimeout(v), ee.dispose(), O(), cr(i), a.finishCapture(), a.dispose(), o.dispose();
2912
2912
  });
2913
2913
  }
2914
- }), Rr = "0.1.4", zr = wr, Br = xr, Vr = Sr, Hr = Cr, Ur = 4, Wr = dr, Gr = (e, t) => Xn(e, t), Kr = (e = /* @__PURE__ */ new Date()) => Zn(e), qr = (e, t, n, r) => Yn(e, t, n, r), Jr = (e, t, n) => Jn(e, t, n), Yr = (e, t) => ur(e, t), Xr = (e) => cr(e), Zr = (e = {}) => ({
2914
+ }), Rr = "0.1.6", zr = wr, Br = xr, Vr = Sr, Hr = Cr, Ur = 4, Wr = dr, Gr = (e, t) => Xn(e, t), Kr = (e = /* @__PURE__ */ new Date()) => Zn(e), qr = (e, t, n, r) => Yn(e, t, n, r), Jr = (e, t, n) => Jn(e, t, n), Yr = (e, t) => ur(e, t), Xr = (e) => cr(e), Zr = (e = {}) => ({
2915
2915
  ...Lr(e),
2916
2916
  version: Rr
2917
2917
  }), Qr = (e) => $n(e);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mesurer-solid",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Framework-agnostic UI measurement and inspection tools for browser apps and coding agents.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: mesurer-ui
3
- description: Use Mesurer when implementing, reviewing, debugging, or fixing frontend UI in a browser. Load for visual alignment, spacing, sizing, layout, CSS, responsive work, design/Figma implementation, screenshots, pixel discrepancies, human Mesurer selections/measurements/guides/annotations, Arrange intents, or any request to check Mesurer/Measure context. A broad Mesurer/context request means inventory all existing human visual intent before narrowing. Consume existing human visual intent before editing and obtain fresh rendered evidence before claiming completion.
3
+ description: Use Mesurer when implementing, reviewing, debugging, or fixing frontend UI in a browser. Load for visual alignment, spacing, sizing, layout, CSS, responsive work, design/Figma implementation, screenshots, pixel discrepancies, human Mesurer selections/measurements/guides/annotations, Arrange intents, direct text/style Desired edits, or any request to check Mesurer/Measure context. A broad Mesurer/context request means inventory all existing human visual intent before narrowing. Consume existing human visual intent before editing and obtain fresh rendered evidence before claiming completion.
4
4
  ---
5
5
 
6
6
  # Mesurer UI workflow
@@ -13,12 +13,12 @@ The central rule is:
13
13
 
14
14
  > A meaningful Mesurer step must return evidence the agent actually consumes.
15
15
 
16
- That evidence may be `MesurerContextV1`, `MesurerReviewV1`, an Arrange intent/review, or a focused low-level measurement. Do not merely draw a highlight and continue from memory.
16
+ That evidence may be `MesurerContextV1`, `MesurerReviewV1`, an Arrange intent/review, a text-edit intent, or a focused low-level measurement. Do not merely draw a highlight or preview a change and continue from memory.
17
17
 
18
18
  ```text
19
19
  human visual intent or agent UI change
20
20
  → preserve existing Mesurer state
21
- → consume Arrange / annotation / selection evidence
21
+ → consume Arrange / text edit / annotation / selection evidence
22
22
  → reason from exact rendered state
23
23
  → edit normal source
24
24
  → wait for the real render
@@ -28,7 +28,7 @@ human visual intent or agent UI change
28
28
 
29
29
  ## 1. Reuse the live Mesurer instance
30
30
 
31
- Never reinject, dispose, or replace Mesurer just because this skill loaded. The person may already have selected elements, placed guides, measured gaps, held distances, enabled rulers/X-ray, created annotations, arranged elements into a desired layout, or kept a screenshot thumbnail/viewer open. That state is part of the user's message.
31
+ Never reinject, dispose, or replace Mesurer just because this skill loaded. The person may already have selected elements, placed guides, measured gaps, held distances, enabled rulers/X-ray, created annotations, arranged elements into a desired layout, edited text or typography into a Desired state, or kept a screenshot thumbnail/viewer open. That state is part of the user's message.
32
32
 
33
33
  Discover the current page first:
34
34
 
@@ -74,8 +74,18 @@ select
74
74
  annotations
75
75
  review
76
76
  capturePlan
77
+ textEdits
78
+ textEdit
77
79
  ```
78
80
 
81
+ When direct text editing is available, capabilities reports:
82
+
83
+ ```text
84
+ textEdit
85
+ ```
86
+
87
+ `textEdits()` lists saved human text/style Desired intents. `textEdit(id)` resolves one intent by id.
88
+
79
89
  When the first-party Arrange plugin is mounted, capabilities also reports:
80
90
 
81
91
  ```text
@@ -96,7 +106,7 @@ The optional screenshot plugin remains a separate human tool/service. It is not
96
106
 
97
107
  ### Treat broad Mesurer/context requests as a full intent sweep
98
108
 
99
- If the user says “check Mesurer,” “check Measure,” “look at Mesurer context,” “see what I highlighted/moved/annotated,” or otherwise asks generally about Mesurer state without naming one specific tool, do **not** assume `context()` alone is the whole message.
109
+ If the user says “check Mesurer,” “check Measure,” “look at Mesurer context,” “see what I highlighted/moved/annotated/edited,” or otherwise asks generally about Mesurer state without naming one specific tool, do **not** assume `context()` alone is the whole message.
100
110
 
101
111
  Inventory the live human-intent channels before narrowing:
102
112
 
@@ -107,6 +117,9 @@ const annotations = await window.__MESURER__.annotations()
107
117
  const arrangements = capabilities.arrange
108
118
  ? await window.__MESURER__.arrangements()
109
119
  : []
120
+ const textEdits = capabilities.textEdit
121
+ ? await window.__MESURER__.textEdits()
122
+ : []
110
123
 
111
124
  let selection = null
112
125
  try {
@@ -126,9 +139,13 @@ const annotationContexts = await Promise.all(
126
139
  const arrangeIntents = await Promise.all(
127
140
  arrangements.map((intent) => window.__MESURER__.arrange(intent.id)),
128
141
  )
142
+
143
+ const textEditIntents = await Promise.all(
144
+ textEdits.map((intent) => window.__MESURER__.textEdit(intent.id)),
145
+ )
129
146
  ```
130
147
 
131
- Bring forward whatever is relevant from the combined state: current selection, target-bound annotations and notes, Arrange Before/Desired geometry, guides, measurements, held distances, layout/style inspection, rulers/X-ray state, and any existing human screenshot preview that should be preserved. A person may use several Mesurer tools in one review; treat the combined state as one visual message rather than asking them to restate intent that is already encoded in the page.
148
+ Bring forward whatever is relevant from the combined state: current selection, target-bound annotations and notes, Arrange Before/Desired geometry, text Before/Desired copy and typography/style deltas, guides, measurements, held distances, layout/style inspection, rulers/X-ray state, and any existing human screenshot preview that should be preserved. A person may use several Mesurer tools in one review; treat the combined state as one visual message rather than asking them to restate intent that is already encoded in the page.
132
149
 
133
150
  Do not clear or replace any of those channels until their relevant evidence has been consumed.
134
151
 
@@ -221,9 +238,105 @@ If review reports `stale` or `partial`, do not silently transfer the intent to a
221
238
 
222
239
  Do not clear, overwrite, or discard a human Arrange intent merely to make validation pass.
223
240
 
224
- ## 3. Acquire ordinary context in the right order
241
+ ## 3. Consume direct text/style Desired edits before source edits
242
+
243
+ Direct text editing is human copy and typography intent. It extends the existing page-targeting interaction instead of adding a competing top-level Text Edit tool.
244
+
245
+ ### Understand the human editing surface
246
+
247
+ The human-facing inspection tool is **Typography**. Its existing internal compatibility id and stable command remain `text-inspector` / `builtin.text-inspector`; do not automate normal application work by guessing toolbar labels.
248
+
249
+ A person can open direct editing while **Select** or **Typography** is active. Arrange keeps Select active, so this also works while Arrange remains selected. Starting the edit contextually activates Typography for the field while preserving Select/Arrange.
250
+
251
+ ```text
252
+ double-click ordinary direct text
253
+ (or double-tap with touch/pen)
254
+ ↓
255
+ current text selected in full
256
+ ↓
257
+ in-place editor using the target's rendered typography
258
+ ↓
259
+ Mesurer-style direct typography toolbar
260
+ B / I / U / Font / Size / Weight / Color
261
+ + separate semantic Text/H1/H2/H3 preset popup
262
+ + contextual Typography information for the exact field
263
+ ↓
264
+ Enter keeps Desired / Shift+Enter inserts newline
265
+ ```
266
+
267
+ The direct toolbar and semantic preset popup have different jobs. **B**, **I**, **U**, Font, Size, Weight, rendered-page text colors, and custom color are direct controls. The semantic popup contains only **Text** plus Heading 1/2/3 for semantic levels actually rendered by visible direct-text page elements.
268
+
269
+ Each semantic preset represents the **dominant rendered typography bundle** for that level—font family, size, weight, style, line height, tracking, text transform, and color. The Text preset uses dominant visible direct-text paragraph/span typography. Heading levels absent from the page are not invented.
270
+
271
+ Pages may contain multiple visual variants of one semantic level. A special non-dominant heading/body variant remains available through the direct Font, Size, Weight, rendered color, and custom color controls. Semantic presets therefore express the canonical rendered style without hiding existing application variants.
272
+
273
+ The semantic popup must not contain the direct Font/Size/Weight/color controls. Its CSS chevron is part of the UI contract and rotates with popup state.
274
+
275
+ While the editor owns focus, `Cmd/Ctrl+B`, `Cmd/Ctrl+I`, and `Cmd/Ctrl+U` toggle formatting. Text/H1/H2/H3 expose `Option+Cmd+0/1/2/3` on macOS and `Alt+Ctrl+0/1/2/3` elsewhere. A heading shortcut only applies when that heading level exists in the page-derived catalog.
276
+
277
+ If the semantic preset popup is open, the first **Escape** closes the popup and keeps editing; Escape with it closed cancels the edit session. Link creation and numbered/bulleted lists are intentionally not exposed as fake typography controls because those require a future structural/rich-text intent model.
278
+
279
+ The contextual Typography card reports Family, Size, Weight, Line, Tracking, tag/text information, and CSS-variable references when available. It updates during the edit session, but it is **transient human UI**: it does not replace Select, turn Arrange off, create a persistent pin, or become another durable agent context channel.
280
+
281
+ The current target contract is deliberately narrow. Direct editing targets ordinary page elements with one unambiguous non-empty **direct text node**. It is not a generic rich-text/form editor. Native `<input>`, `<textarea>`, `<select>`, `contenteditable`, and ambiguous mixed/nested rich-text structures retain their normal browser/application behavior.
282
+
283
+ For normal application work, do not automate this editor UI just to discover intent that has already been saved. Read `textEdits()` / `textEdit(id)` directly. Automate the editor itself only when the task is testing or changing Mesurer's direct-edit feature.
284
+
285
+ ### Read durable text intent
286
+
287
+ When `capabilities.capabilities.textEdit` is true, inspect saved edits before changing source:
288
+
289
+ ```js
290
+ const textEdits = await window.__MESURER__.textEdits()
291
+ ```
292
+
293
+ For a relevant edit:
294
+
295
+ ```js
296
+ const intent = await window.__MESURER__.textEdit(textEditId)
297
+ ```
298
+
299
+ A text-edit intent contains:
300
+
301
+ ```text
302
+ id / createdAt / pageUrl
303
+ selector / nodeIndex
304
+ before
305
+ original text
306
+ desired
307
+ requested text
308
+ styles[]
309
+ property
310
+ before
311
+ desired
312
+ ```
313
+
314
+ Treat `desired` and `styles[]` as the requested visual outcome, not as an implementation prescription. Mesurer may preview a font, size, weight, line height, tracking, text transform, color, underline, or other text property with a temporary DOM style. Production code should use the application's real component props, classes, CSS variables, design tokens, theme values, or stylesheet rules where appropriate.
315
+
316
+ Page-derived semantic presets and font/size/color/weight choices are useful evidence because the person selected from styles already rendered by the application. They are not a source-code token scanner and still do **not** mean the agent should blindly add inline styles with sampled computed values. Inspect the source and reuse the semantic source-level token/class when it exists.
317
+
318
+ Preserve each relevant intent id, selector, Before text, Desired text, and style deltas before HMR can replace the target.
319
+
320
+ ### Verify text edits against Live source, not Mesurer's preview
321
+
322
+ While Select or Typography is active, Mesurer can render the saved Desired copy/style as a reversible preview. Do not inspect that preview and claim the source implementation is complete.
323
+
324
+ After making source changes:
325
+
326
+ 1. wait for the application to render;
327
+ 2. preserve the text-edit intent;
328
+ 3. ensure Mesurer's text Desired preview is not masking the target by deactivating the active Select/Typography mode without clearing the saved intent;
329
+ 4. inspect the target's actual rendered text and computed typography;
330
+ 5. compare those Live values with the saved Desired text/style changes;
331
+ 6. reactivate Select only if continued Mesurer review is useful.
225
332
 
226
- After preserving any relevant Arrange intent, use this order for the rest of the visual evidence.
333
+ Mesurer relinquishes ownership when the application itself changes a text/style value, so a correct source implementation must survive with the preview inactive.
334
+
335
+ Do not clear text-edit history just to reveal Live. Deactivate the previewing tool, inspect the real application render, and keep the human intent available for comparison.
336
+
337
+ ## 4. Acquire ordinary context in the right order
338
+
339
+ After preserving relevant Arrange and text-edit intent, use this order for the rest of the visual evidence.
227
340
 
228
341
  ### A. Existing human selection or annotation
229
342
 
@@ -249,7 +362,7 @@ const annotationContext = await window.__MESURER__.context({
249
362
  })
250
363
  ```
251
364
 
252
- Treat annotation notes and Arrange Desired state as human intent. Treat selection, guides, distances, measurements, exact geometry, computed styles, and screenshots as evidence supporting that intent.
365
+ Treat annotation notes, Arrange Desired state, and text/style Desired edits as human intent. Treat selection, guides, distances, measurements, exact geometry, computed styles, and screenshots as evidence supporting that intent.
253
366
 
254
367
  Do not overwrite a meaningful human selection until its context has been retained in the current task.
255
368
 
@@ -286,7 +399,7 @@ Use the returned object. Do not call `select()` only for the highlight.
286
399
 
287
400
  Every supplied selector must resolve to exactly one page target. Missing, invalid, or ambiguous selectors throw. Refine the selector or ask the user to select the target rather than guessing.
288
401
 
289
- ## 4. Read rendered context, not source assumptions
402
+ ## 5. Read rendered context, not source assumptions
290
403
 
291
404
  `MesurerContextV1` is JSON-safe and uses `viewport-css-px` coordinates. Relevant fields include:
292
405
 
@@ -324,7 +437,7 @@ Examples:
324
437
  - rendered width is `318px` → do not report `320px` until the browser measures it;
325
438
  - overflow flags are true → the rendered component is overflowing even if source math looked correct.
326
439
 
327
- ## 5. Treat multi-selection as relational evidence
440
+ ## 6. Treat multi-selection as relational evidence
328
441
 
329
442
  When several elements are selected, inspect every relevant target and their relationships. Do not summarize the state as only “3 selected.”
330
443
 
@@ -348,9 +461,9 @@ const pair = window.__MESURER__.distance(selectorA, selectorB)
348
461
 
349
462
  For a small selection, report useful unique pair relationships. For a large repeated set, focus on adjacent/repeated/user-relevant relationships rather than dumping O(n²) pairs.
350
463
 
351
- ## 6. Preserve the baseline before editing
464
+ ## 7. Preserve the baseline before editing
352
465
 
353
- If the human supplied selection, measurements, an annotation, or Arrange state, retain the relevant baseline before source changes or HMR can replace nodes.
466
+ If the human supplied selection, measurements, an annotation, Arrange state, or text/style edits, retain the relevant baseline before source changes or HMR can replace nodes.
354
467
 
355
468
  Annotation:
356
469
 
@@ -366,9 +479,15 @@ const before = await window.__MESURER__.context({ scope: "selection" })
366
479
 
367
480
  Arrange: capture the intent plus Before/Desired states as described above.
368
481
 
369
- Do not mutate human guides, measurements, held distances, annotations, Arrange history, or screenshot preview/viewer state merely to make the implementation appear correct.
482
+ Text edit:
483
+
484
+ ```js
485
+ const textIntent = await window.__MESURER__.textEdit(textEditId)
486
+ ```
370
487
 
371
- ## 7. Edit the real implementation
488
+ Do not mutate human guides, measurements, held distances, annotations, Arrange history, text-edit history, or screenshot preview/viewer state merely to make the implementation appear correct.
489
+
490
+ ## 8. Edit the real implementation
372
491
 
373
492
  Make the smallest source change that addresses the rendered issue. Use the project's normal source, build, and dev-server workflow.
374
493
 
@@ -380,7 +499,9 @@ After HMR/render:
380
499
  await window.__MESURER__.stable()
381
500
  ```
382
501
 
383
- ## 8. Fresh rendered evidence is part of completion
502
+ For text/style intents, inspect the source-rendered Live state with Mesurer's Desired preview inactive before claiming the implementation matches.
503
+
504
+ ## 9. Fresh rendered evidence is part of completion
384
505
 
385
506
  Lint, typecheck, tests, and build are implementation checks. They do not prove a visual result.
386
507
 
@@ -396,6 +517,18 @@ const review = await window.__MESURER__.reviewArrange(arrangeId)
396
517
 
397
518
  Continue until the live source-rendered geometry matches Desired within the expected tolerance, and use a fresh screenshot when visual composition matters.
398
519
 
520
+ ### Text/style Desired intent
521
+
522
+ With the saved intent retained and the temporary text preview inactive:
523
+
524
+ ```js
525
+ await window.__MESURER__.stable()
526
+ const intent = await window.__MESURER__.textEdit(textEditId)
527
+ const live = window.__MESURER__.inspect(intent.selector)
528
+ ```
529
+
530
+ Compare the actual text and relevant `live.typography` values with `intent.desired` and `intent.styles`. If the target no longer resolves uniquely after HMR, do not silently transfer the intent to another element.
531
+
399
532
  ### Human annotation
400
533
 
401
534
  ```js
@@ -422,7 +555,7 @@ const after = await window.__MESURER__.select([
422
555
 
423
556
  If target identity is ambiguous after the change, ask the user to select the intended result. Do not manufacture confidence from a guessed selector.
424
557
 
425
- ## 9. Human screenshots and agent screenshots are different paths
558
+ ## 10. Human screenshots and agent screenshots are different paths
426
559
 
427
560
  The optional `mesurer.screenshot` plugin gives the person a camera tool. It can copy/download a HiDPI-aware PNG and keep a draggable preview/viewer. Do not treat it as an agent-delivery transport or destroy a human preview unless the task explicitly requires it.
428
561
 
@@ -438,29 +571,34 @@ try {
438
571
  }
439
572
  ```
440
573
 
441
- Arrange follows the same ownership model through `arrangeCapturePlan()`. The important difference is that Arrange can deliberately present Before, Desired, or Live before the harness captures.
574
+ Active direct-editor controls, the semantic preset popup, and its contextual Typography card are Mesurer chrome, not application evidence. Arrange follows the same ownership model through `arrangeCapturePlan()`. The important difference is that Arrange can deliberately present Before, Desired, or Live before the harness captures.
442
575
 
443
- Use both signals:
576
+ Use all relevant signals:
444
577
 
445
578
  ```text
446
579
  Mesurer context/review → exact geometry, styles, distances, overflow
580
+ saved human intent → annotation / Arrange / text Desired state
447
581
  real screenshot → composition, hierarchy, clipping, color, visual judgment
448
582
  ```
449
583
 
450
584
  Screenshots do not replace exact Mesurer measurements, and Mesurer numbers do not replace visual judgment.
451
585
 
452
- ## 10. HMR and stale-target rules
586
+ ## 11. HMR and stale-target rules
453
587
 
454
- Annotations and Arrange intents rebind conservatively after DOM replacement. If review reports `stale` or `partial`, do not silently bind human intent to a different element.
588
+ Annotations, Arrange intents, and text-edit intents use conservative target identity. If a target becomes stale or ambiguous, do not silently bind human intent to a different element.
455
589
 
456
590
  An unsaved selection can disappear when HMR replaces nodes. Preserve initial context before editing. After render, use original exact selectors when still valid, `select()` known replacement targets when unambiguous, or ask the user to reselect when identity is uncertain.
457
591
 
458
- ## 11. Completion standard
592
+ If the application now renders a text/style value that matches a saved Desired edit, Mesurer must not keep claiming ownership of that value or later restore stale Before state over the application's source-rendered result.
593
+
594
+ ## 12. Completion standard
459
595
 
460
596
  A valid visual completion statement is grounded in fresh rendered evidence, for example:
461
597
 
462
598
  ```text
463
599
  - Arrange Live now matches Desired within 1px
600
+ - edited copy is source-rendered as "Start free trial"
601
+ - edited text uses the requested 700 weight and page token color with Mesurer preview inactive
464
602
  - selected cards measure 320px wide
465
603
  - rendered horizontal gap is 24px
466
604
  - selected top edges differ by 0px
@@ -480,7 +618,7 @@ build passed
480
618
 
481
619
  If Mesurer is available and the affected UI can be identified, finishing without fresh Mesurer evidence is a workflow failure.
482
620
 
483
- ## 12. Low-level helpers
621
+ ## 13. Low-level helpers
484
622
 
485
623
  Use these only when scoped context/review is not enough:
486
624
 
@@ -493,12 +631,14 @@ window.__MESURER__.distance(".a", ".b")
493
631
  window.__MESURER__.viewport()
494
632
  await window.__MESURER__.feedback([".selector"])
495
633
  await window.__MESURER__.state()
634
+ await window.__MESURER__.textEdits()
635
+ await window.__MESURER__.textEdit(textEditId)
496
636
  await window.__MESURER__.stable()
497
637
  ```
498
638
 
499
- Prefer `arrangements()`, `context()`, `select()`, `reviewArrange()`, and `review()` for human-in-the-loop work because they preserve visual meaning and return evidence that can be carried directly into reasoning.
639
+ Prefer `arrangements()`, `textEdits()`, `context()`, `select()`, `reviewArrange()`, and `review()` for human-in-the-loop work because they preserve visual meaning and return evidence that can be carried directly into reasoning.
500
640
 
501
- ## 13. Do not do these things
641
+ ## 14. Do not do these things
502
642
 
503
643
  - do not look for an MCP/WebMCP tool;
504
644
  - do not start a local feedback server;
@@ -510,7 +650,13 @@ Prefer `arrangements()`, `context()`, `select()`, `reviewArrange()`, and `review
510
650
  - do not reinject over live human Mesurer state;
511
651
  - do not overwrite human selection before reading it;
512
652
  - do not clear or alter human Arrange history to make validation pass;
653
+ - do not clear text-edit history merely to reveal or validate Live source state;
513
654
  - do not implement Arrange offsets as production transforms unless the source layout genuinely calls for that;
655
+ - do not implement a text/style Desired preview as arbitrary production inline styles when the source design system has a semantic token/class/component API;
656
+ - do not treat page-derived computed font/size/weight/color values or semantic presets as automatic source-token instructions;
657
+ - do not treat the contextual direct-edit Typography card as another saved context/intent channel;
658
+ - do not automate the direct editor for normal application work when saved `textEdit` intent already describes the human request;
659
+ - do not add or infer Link/List structural intent from the current typography-only direct-edit contract;
514
660
  - do not capture only Desired after source editing; preserve Before and Desired first when screenshot comparison matters;
515
661
  - do not close/destroy a human screenshot preview merely to clean up agent state;
516
662
  - do not use `select()` with a knowingly ambiguous selector;
@@ -519,6 +665,7 @@ Prefer `arrangements()`, `context()`, `select()`, `reviewArrange()`, and `review
519
665
  - do not ignore context returned by `select()`;
520
666
  - do not alter human measurements/guides to make validation pass;
521
667
  - do not infer exact geometry from screenshots when Mesurer reports the number;
668
+ - do not inspect Mesurer's temporary text Desired preview and claim the source implementation is complete;
522
669
  - do not claim visual completion from source/build output alone.
523
670
 
524
671
  The direct integration remains intentionally small:
@@ -529,8 +676,8 @@ existing agent harness
529
676
  existing rendered page
530
677
  ↕
531
678
  window.__MESURER__
532
- ↳ arrangements() / context() / select()
533
- ↳ reviewArrange() / review()
679
+ ↳ arrangements() / textEdits() / context() / select()
680
+ ↳ reviewArrange() / textEdit() / review()
534
681
  ```
535
682
 
536
- **Rendered evidence is the output.**
683
+ **Rendered evidence is the output.**