@lotics/ui 7.19.3 → 8.0.0

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.
package/AGENTS.md CHANGED
@@ -153,18 +153,22 @@ Pick by capability, not by name. (→ the source file for the API.)
153
153
  - **AI surfaces** — `Composer` (the adaptive command/chat composer — a compact pill when empty that
154
154
  expands for long text + attachments; the surface that triggers agent work),
155
155
  `AgentRun` (the live streaming work feed) + `AgentProgress` (its compact, floating, expandable
156
- form — a composer's "working" state), `ReviewCard` (THE single-proposal review card — compositional
157
- body via `children`: a `RecordFields` record (header-first) or a `MatchSides` pairing (body-first))
158
- + `Confidence`; `ChangeReview` (the BATCH review list whole-set OR 1-by-1; compositional via
159
- `renderItem`, with `ChangeDiff` for the before→after body) + `ChangeReviewActions` (its commit bar,
160
- pinned by the host in a `DialogFooter`/`DrawerFooter` or inline),
156
+ form — a composer's "working" state) + `Confidence`;
157
+ **`ChangeReview` THE one review-before-apply surface, a COMPOUND family** (frame: `ChangeReview`
158
+ · `ChangeReviewHeader` · `ChangeReviewActions`; sections: `Change` · `ChangeLabel` ·
159
+ `ChangeSummary` · `ChangeReasoning`; the grammar: `ChangeFields` + `ChangeField` ·
160
+ `ChangeRecord` · `ChangeBand` + `ChangeValueInput`): adds, updates, removals, conflicts, whole
161
+ records, display-only findings are all compositions — see §AI workflows for the laws;
161
162
  `Clarify` (the agent asks back — selectable `ChoiceList` options),
162
- `Sources` (provenance chips for AI output). For STRUCTURED AI output the review
163
- surfaces above don't cover: `SpecList` (the "exact breakdown"a labeled-value spec sheet, the
164
- panel of an answer),
165
- `Finding` (one ranked briefing/audit insight severity + metric + sources + action), `Discrepancy`
166
- (a field whose value disagrees across sources pick the truth), `TriageRow` (an incoming item the
167
- agent classified + routed), `ScoredOption` (an AI-ranked candidatescore + rationale + specs).
163
+ `Sources` (provenance chips for AI output at review scale, `label={null}` slots the chips at a
164
+ section's bottom), `Finding` (one ranked insight from an AI check localized severity word ·
165
+ title · detail · `Sources` chips · a `children` slot; **`FindingComparison`** is the
166
+ expected-vs-actual body: each disagreeing side a labeled row, the DELTA emphasized under a
167
+ hairline (localized "Difference") quantities, totals, dates; a plain `metric` prop remains for
168
+ one-number findings. The children slot composes ANY visual result a compact `Table` for
169
+ per-line detail (danger color on the offending cells), `ProgressBar` for
170
+ consumption-toward-a-cliff (free time, credit), dot `Badge`s for a present/missing checklist,
171
+ `Confidence` for judgment calls — the AI-page demos show each. Display-only — it informs the verdict the host records; `finding` slice).
168
172
  See §AI workflows.
169
173
 
170
174
  ---
@@ -406,6 +410,27 @@ accepts / edits / dismisses, the deterministic app applies. The agent owns judgm
406
410
  (recognition, estimation, intent→parameters); the app owns geometry, math, and the write.
407
411
  Compose the surfaces as a loop, and reach for the right one by job:
408
412
 
413
+ **Which AI surface — decide by the OUTCOME's shape, not the task's topic.** Three shapes:
414
+
415
+ 1. **Field writes** (extract, match, rank, classify → the record changes) → **in-app agent**
416
+ (`useAgentRun`) + **`ChangeReview`**. The commits must obey the diff law (Keep/Drop per
417
+ change, app-workflow writes, bounded app authority), and the operator wants one button +
418
+ a review — never a prompt box.
419
+ 2. **Evidence for an in-app decision** (cross-check, audit, tie-out → nothing is written; the
420
+ operator acts on what was found) → **in-app agent** + **`Finding`**. Still bounded and
421
+ prompt-free (an optional instructions brief at most): the brief is fixed, the output is
422
+ structured display-only findings read IN the record's context, and there is no conversation
423
+ to have — the loop closes when the operator acts in the app. Chat would add prompting and
424
+ tear the findings away from the record they judge.
425
+ 3. **A file or an open-ended answer** (edit this document, draft from context, explain) →
426
+ **hand off to the chat agent** (`askAi` in `@lotics/app-sdk`). The loop is multi-turn with
427
+ no output schema, judged by looking — and the chat harness already owns it: preview beside
428
+ the thread, version chains, branching, session memory. An in-app "edit chat" would
429
+ re-implement all of that inside every app.
430
+
431
+ The Document desk's Use-AI fork IS this table as UI: Extract data (1) · Cross-check (2) ·
432
+ Edit with AI (3) — one entry point, three outcome shapes.
433
+
409
434
  - **Command / compose** — `Composer`, the adaptive command surface. Empty + minimal (no `footerRight`
410
435
  model picker, no `pills`, no `files`), it's a COMPACT PILL: an optional `actionsButton` (attach) left,
411
436
  the input, a send arrow right (Enter sends, Shift+Enter for a newline) — the same geometry
@@ -439,28 +464,47 @@ Compose the surfaces as a loop, and reach for the right one by job:
439
464
  free — no hand-assembly). Transparent work, NEVER a bare spinner. On a canvas/composer app reach for
440
465
  `AgentProgress` — `AgentRun` collapsed into a floating pill (avatar + current step) that EXPANDS on
441
466
  press; the composer morphs into it while running, and reveals again when done.
442
- - **Review before apply — ONE card + the batch engine, the BODY is compositional.** Every "the agent
443
- proposes → the human accepts / edits / dismisses → nothing auto-applies" surface wears the same
444
- `reviewCardStyle` + an optional `Confidence`. There are two primitives:
445
- - **`ReviewCard`** THE single-proposal review card. It owns the chrome (eyebrow + `Confidence`,
446
- rationale, a generic `actions` footer Accept/Edit/Dismiss, Confirm/Remove, Accept/Reassign,
447
- whatever the verbs are and a collapse-to-a-row resolved state); the BODY is `children`. **Layout
448
- follows the props**: give it an `eyebrow`/`title` and the chrome LEADS (header-first a value or
449
- record proposal, e.g. a `RecordFields` `tpl_extract`); give it only `children` and the BODY leads,
450
- the confidence + reason beneath it (body-first a `MatchSides` pairing where the link is the hero
451
- `tpl_match`). Stack several (rank by confidence) for a shortlist or a document's records.
452
- - **`ChangeReview`** THE batch engine for a SET you decide each then commit together. `renderItem`
453
- draws each proposal (a `ChangeDiff` before→after body, a record, an editable form), 1-by-1
454
- Keep/Drop collapses each (e.g. ingested rate lines `tpl_ratedesk`); whole-set mode reviews the
455
- lot. It is the LIST only the commit bar (Accept all / Apply / Discard) is the SEPARATE
456
- **`ChangeReviewActions`**, which the host places where commit bars belong (a `DialogFooter` /
457
- `DrawerFooter`, or inline under the list). Don't bundle a commit into a scroll bodylike every
458
- other footer in the kit it's the container's to pin (`tpl_ratedesk` puts it in the `DialogFooter`).
459
- `ChangeReviewActions` reads the same `items`/`statusOf`, so it owns Accept-all + the kept count —
460
- never re-derive them in the host.
461
- The body atoms (`RecordFields`, `MatchSides`, `ChangeDiff`) are pure presentation usable inside
462
- either engine OR standalone (a live-edit field card). The decide / accept-all / apply mechanics are
463
- never re-implemented per surface.
467
+ - **Review before apply — ONE surface, the compound `ChangeReview` family.** Every "the agent
468
+ proposes → the human accepts / edits / dismisses → nothing auto-applies" surface composes from
469
+ twelve pieces in three groups. **Frame**: `ChangeReview` (context provider + stack; hairline
470
+ dividers between `Change` sections and `ChangeFields` rules between fields) ·
471
+ `ChangeReviewHeader` (the SECTION headingmd semibold; keep it lean: never repeat the record
472
+ the dialog is already about) · `ChangeReviewActions` (the commit bar pin it in the
473
+ `DialogFooter`/`DrawerFooter`; **Keep all** bottom-left presses every pending decision pass
474
+ `onAcceptAll` when field state lives in the host; the "N of M kept" counter reads HERE beside it,
475
+ never in the header; Apply disables at 0 kept or via `applyDisabled`). **Sections**: `Change`
476
+ (heading + free body + optional verbs + collapse omit both callbacks for display-only) ·
477
+ `ChangeLabel` · `ChangeSummary` (the collapsed row's content) · `ChangeReasoning` (the agent's
478
+ quiet hairline aside only when not self-explanatory). **The grammar**:
479
+ - **`ChangeFields` + `ChangeField`** THE field unit. `ChangeFields` is the OPEN form (the
480
+ section IS the recordan extract dialog's one order: no card chrome). Each `ChangeField`:
481
+ label (sm, muted — the DetailRow convention) · the `−` band when replacing (`before`) · the value — `ChangeValueInput`
482
+ by default (the green `+` band; pressing it edits IN THE BANDa borderless input with
483
+ identical type metrics, so nothing shifts; `unit="pcs"` fixes the suffix outside the editable
484
+ core type the number, never the unit) or any input · conflict `candidates` as full-width decision rows + the localized
485
+ "Type another value" third option (`custom*` props; the outcome band is read-only via
486
+ `valueReadOnly` the decision comes from picking, never from editing the band; gate with
487
+ `keepDisabled`) · row `reasoning` LAST · per-field **Keep/Drop** bottom-right
488
+ (`status`/`onKeep`/`onDrop`/`onUndo`). A pure REMOVAL is `before` with an empty value — the
489
+ `−` band alone. A decided field collapses to the compact one-row card (mark · label →
490
+ `summary` · Undo).
491
+ - **`ChangeRecord`** — THE item card for SETS of records (order lines): `id` (it registers in
492
+ the review context like a `Change`), `tone` add/edit/remove, the tinted header band with the
493
+ localized op word (Add/Edit/Delete · Thêm/Sửa/Xóa) + title, body = its `ChangeField`s, and
494
+ **the verb level follows the decision level**: add/remove carry ONE card Keep/Drop (fields
495
+ none — editable parts, one write); edit carries NO card verbs (only its changed fields, each
496
+ deciding for itself — dropping a field narrows the update diff). Collapses via `summary`.
497
+ - **`ChangeBand`** — the raw diff band (aligned `+`/`−` marker column, light emerald/red, dark
498
+ text) every piece builds from; reach for it directly for custom strokes.
499
+ **The scaling boundary (known, deliberate)**: `ChangeFields` + `ChangeRecord` cards cover one
500
+ record through ~10; a BULK review (30+ imported rows — a bank statement, an Excel import) needs a
501
+ dense form that does not exist yet — design it against the first real migration, not
502
+ speculatively.
503
+ **The laws**: ONE verb pair everywhere — Keep/Drop, localized; never rename per shape (Apply is
504
+ the only outcome-named button). Candidate rows carry the VALUE only; provenance = `Sources` at
505
+ the VERY bottom of the review (after every change; or omit it — lean beats decorated). The HOST owns every decision in plain `useState`; the family owns the
506
+ mechanics (collapse + Undo, the counter, Keep-all, apply gating). Never apply a field with no
507
+ value — gate unresolved conflicts. Editing IS the review.
464
508
  - **Ask back** — `Clarify`: when the agent is unsure, it asks a question with quick-reply options
465
509
  and PAUSES, instead of guessing wrong. Human-in-the-loop input mid-run.
466
510
  - **Provenance** — `Sources`: openable chips saying where the output came FROM (records, a
@@ -476,54 +520,43 @@ a conversation, a single pass, or generated prose:
476
520
  - **Canvas** (`tpl_dieline`) — the page IS the design on a pannable/zoomable surface: it stays
477
521
  CENTRED at every zoom (a floating zoom pill bottom-left), the FLOATING composer at the bottom (a
478
522
  `Composer`: attach a photo → review/remove it → add a note → send, with `sendDisabled` allowing a
479
- file-and/or-text submit — NOT auto-run on attach) morphs into `AgentProgress` while running, and a pinned PARAMS PANEL (a `RecordFields` field-card
523
+ file-and/or-text submit — NOT auto-run on attach) morphs into `AgentProgress` while running, and a pinned PARAMS PANEL (a label/value field-card
480
524
  in live-edit mode, carrying the single Download; minimizes to a pill) floats centre-right. Panel, zoom pill and composer
481
525
  float ON TOP — they never shift the design. (Floating layers use a `pointerEvents:"none"` wrapper
482
526
  with the interactive child set `"auto"`; RN-Web ignores `"box-none"` in style, so a full-width
483
527
  wrapper would otherwise eat clicks on the canvas behind it.) Change the design by prompt ("5 mm
484
528
  taller") OR by editing a param directly — either re-flows it in place. For a design/document the
485
529
  user shapes over time.
486
- - **Chat** (`tpl_assistant`) — a conversation where the agent's answer carries suggested edits the
487
- user approves/rejects **1-by-1** (`ChangeReview` per-item), applying only the accepted set. An AI
488
- copilot that proposes changes to a record and never commits on its own.
489
- - **One-shot** (`tpl_extract`) — read an image → the agent extracts the records → review each as a
490
- `ReviewCard` wrapping a `RecordFields` body (fields click-to-edit, Confirm collapses it to a
491
- checklist row) → Save all to the table. A data-capture pass; nothing stored until confirmed.
492
- - **Bulk ingest desk** (`tpl_ratedesk`) — the page IS a filterable register (a From → To route picker
493
- + `ColumnFilter` pills → `Card padding:0` + full-bleed `Table`), the register the hero. Updating
494
- prices is ONE header CTA that opens a Dialog wizard: drop SEVERAL source docs at once → the agent
495
- reads them all (`AgentRun`) → a `ChangeReview` 1-by-1 (each proposal a Keep/Drop card, New / Updated
496
- with old→new delta, "Accept all" + Apply) → the kept rows land in the register. Pairs `tpl_extract`'s
497
- ingest with `tpl_directory`'s register. For a maintained reference table — rate card, price list,
498
- tariff, catalogue: re-ingest the source sheets beats hand-typing.
499
- - **Draft** (`tpl_draft`) — the agent writes a first draft from context; the OUTPUT itself streams
500
- (the text fills in live), then becomes an editable surface the human refines before sending.
501
- Tone/length steer it. For generated prose — a reply, a quote, a listing.
530
+
502
531
 
503
532
  The next six output STRUCTURE the first four can't — when the answer is a panel of facts, a queue of
504
533
  decisions, or a ranked set, don't cram it into chat prose. Each pairs a template with a primitive:
505
- - **Answer desk** (`tpl_lookup`, `SpecList`) — describe the goods on the LEFT → the agent RANKS the
534
+ - **Answer desk** (`tpl_lookup`) — describe the goods on the LEFT → the agent RANKS the
506
535
  matching codes (NEAREST MATCHES, the top one Recommended) → pick one and its STRUCTURED answer pins on
507
536
  the RIGHT (a verdict header + an exact breakdown + the policies + sources). Input → matches → pick,
508
537
  NOT a single confident verdict: classification is ambiguous, so the alternatives are first-class and
509
538
  picking a different one changes the duty; refining the description re-ranks. For look-up-and-explain:
510
539
  tariff/HS, fee lookup, policy Q&A, a spec/compliance desk. (NOT a chat with the answer in a bubble.)
511
- - **Match** (`tpl_match`, body-first `ReviewCard` + `MatchSides`) — the agent proposes PAIRINGS with
512
- its reasoning; each is a `ReviewCard` (no title, so body-first) whose body is a two-sided `MatchSides`
513
- pairing (source proposed counterpart), with the confidence + reason beneath, accept / reassign /
514
- reject, high-confidence batch-accept. The AI reconciliation / dedup / correlation queue. (Strip the agent's
515
- reasoning and it would be a plain deterministic match register the reasoning is the tell for when
516
- you need this.)
517
- - **Briefing** (`tpl_briefing`, `Finding`) — a generated narrative over the data + a RANKED list of
518
- what needs attention, each finding carrying a severity, a metric, its sources, and one action. The
519
- leadership digest / anomaly scanthe agent's COMMENTARY, not a raw dashboard.
520
- - **Cross-check** (`tpl_crosscheck`, `Discrepancy`)the agent compares the documents of one
521
- transaction and surfaces every field that DISAGREES; resolve each to a source of truth or flag it.
522
- The audit / 3-way-match desk. Symmetric (N sources), unlike a before→after edit.
523
- - **Triage** (`tpl_triage`, `TriageRow`) an inbox the agent classified + routed; accept the call,
524
- override, or dismiss, high-confidence in bulk. Leads, tickets, documents, emails.
525
- - **Compare** (`tpl_compare`, `ScoredOption`) the agent SCORES and ranks options with its rationale
526
- and the key specs; the human picks one. Quotes, carriers, suppliers, plans.
540
+
541
+ - **Document desk** (`tpl_documents` THE go-to for document-driven records) the record's files
542
+ block feeds ONE "Use AI" entry that FORKS into the two document tasks, each a specialized run with
543
+ a task-pure result: **Extract** (files read fields already matching fold into one quiet line →
544
+ every add / update / conflict a `ChangeField` (struck before · bordered input · candidate chips),
545
+ the record's current value a first-class choice — plus proposed new lines as record-body `Change`s
546
+ one outcome-named `ChangeReviewActions` commit) and
547
+ **Cross-check** (documents compared against the record and each other ranked `Finding`s
548
+ severity · title · the prominent metric · sources separated by hairlines; the findings ARE
549
+ the outcome the human acts on no phantom "record verdict" write, a persisted check-status
550
+ goes stale on the next edit). The fork carries an OPTIONAL instructions field the user steers what the agent
551
+ checks or extracts, so `Finding` serves ANY file-based AI request, not just the stock
552
+ cross-check. Every file list in the flow opens the full-page `FileGalleryModal`. Plus **Create documents**: a readiness checklist (unchecked by
553
+ default, missing inputs called out) generate the files land back on the record. Never merge the
554
+ two AI tasks into one mixed output the fork is the design.
555
+ - **Triage** an inbox the agent classified + routed is a `ChangeReview` of `Change`s (body: the
556
+ item + the agent's call; verbs Accept / Dismiss; Accept-all covers the high-confidence sweep).
557
+ - **Compare / ranked pick** — one `ChangeField` whose `candidates` carry the ranked options
558
+ (`description` = the score/reason, `source` where it came from); the human picks one. Quotes,
559
+ carriers, suppliers, plans.
527
560
 
528
561
  The AI vocabulary has **no purple accent and no gimmick glyphs** (no sparkles) — but it is NOT
529
562
  monochrome: **colour is used where it carries meaning, not for decoration.** What the violet sparkle
@@ -533,17 +566,16 @@ a left-ruled margin note (a hairline rule + muted text), quoted apart from the f
533
566
  controls — while **status/severity/diffs use functional colour** the way the rest of the kit does:
534
567
  - **Confidence** — a 3-tick meter + the full phrase ("High confidence" / "Medium" / "Low"), emerald /
535
568
  amber / zinc by level; `labels` to translate (one phrase per level).
536
- - **Finding severity** — a coloured dot `Badge` + metric: red critical, amber warning, blue note,
537
- emerald on-track (+ stacking order, most severe first). The badge words localize through
538
- `LoticsLocaleProvider` (`locale.finding`, override per-instance via `labels`) — never hardcode them.
539
569
  - **Stepper / AgentRun nodes** — progress dots on a spine: `current` a **pulsing accent ring** (white
540
570
  centre), `done` a filled accent dot + **white check**, `upcoming` a faint **grey** ring, the terminal
541
571
  `complete` a **blackish ring + black check**, `warning` **amber**. Default accent is neutral ink
542
572
  (`color` themes it); `AgentRun` keeps the neutral default — an active group's tail pulses (`current`),
543
573
  a settled group is a `done`/`warning` row, and there is no global terminal node (the run ends on text).
544
- - **ChangeReview diffs** — the old value struck in **red**, the new value in **green**.
545
- - **Discrepancy** the agent's pick gets a **blue** highlight; `Mismatch` reads amber, `Resolved`
546
- emerald.
574
+ - **ChangeBand** — the removed value on the light **red** band with the `−` marker, the incoming
575
+ value on the light **emerald** band with `+` (the GitHub-diff idiom, markers in one aligned
576
+ column); everything else in a review stays neutral — a decided row reads a single emerald check,
577
+ an add/remove record card wears the quiet tone wash (50 body · 100 header · 200 border). Colour
578
+ marks the change, never the chrome.
547
579
 
548
580
  Card chrome (borders, microlabels) stays neutral — colour marks the *state*, never the container.
549
581
  The **composer keeps its icons**: `Composer` compact is a single-row pill with an optional circular
@@ -726,7 +758,9 @@ was only ever about the review surfaces' sparkles/severity glyphs, not functiona
726
758
  `Drawer` (above). (2) **Act on many** — a flat list with a leading `CheckboxInput` per row + a
727
759
  select-all `CardHeader` band, plus a bottom-pinned `<FloatingActionBar count label onClear>`
728
760
  carrying the bulk action(s) while ≥1 row is ticked (`tpl_item_list`); a row
729
- that can't take the action has NO checkbox. When a region genuinely must sit beside the list (a
761
+ that can't take the action has NO checkbox. Bar weight gradient, left right: the built-in
762
+ Clear is muted (the quietest act), destructive bulk = `danger-secondary` + icon, secondary
763
+ bulk = `secondary` + icon, ONE primary CTA last — never repeat the count in a CTA title; the bar's label already carries it. When a region genuinely must sit beside the list (a
730
764
  source/remainder summary, a capacity picker) make it a TOP summary header or move it into a
731
765
  Popover/sheet at the decision point — not a standing column.
732
766
  - **One control radius** — every interactive control (`Button`, the inputs/selects/pickers,
@@ -863,17 +897,12 @@ recipe for a screen JOB; copy and adapt). Pick by the job:
863
897
  - **AI workflows** — *produce*: `tpl_dieline` (the design CANVAS: photo → stream → the dieline
864
898
  reveals CENTRED on a pannable/zoomable surface, the floating composer morphing into `AgentProgress`,
865
899
  a pinned live-edit params panel centre-right; prompt OR edit a param to iterate) ·
866
- `tpl_assistant` (a chat copilot: the agent's answer carries suggested edits approved/rejected
867
- 1-by-1) · `tpl_extract` (read an image extract records → review/edit each (`ReviewCard` +
868
- `RecordFields`) Save all) · `tpl_ratedesk` (BULK INGEST desk: a register-as-hero with an "Import
869
- prices" CTA a Dialog wizard: drop several sheets → `ChangeReview` 1-by-1 → kept rows land in the
870
- register; for a maintained rate card / price list / tariff) · `tpl_draft` (draft generation: context the reply text streams into an editable surface
871
- refine send; tone/length steer it). *Structure*: `tpl_lookup` (the ANSWER desk: converse left,
872
- a pinned `SpecList` verdict panel right; a follow-up refines it) · `tpl_match` (AI reconciliation:
873
- body-first `ReviewCard` + `MatchSides` pairings with reasoning, accept/reassign/reject) · `tpl_briefing` (a generated narrative
874
- + a ranked `Finding` attention list) · `tpl_crosscheck` (the audit desk: `Discrepancy` cards where
875
- the documents disagree) · `tpl_triage` (an inbox of `TriageRow`s the agent classified + routed) ·
876
- `tpl_compare` (ranked `ScoredOption` candidates the agent scored).
900
+ *Structure*: `tpl_lookup` (the ANSWER desk: converse left,
901
+ a pinned verdict panel right; a follow-up refines it) ·
902
+ `tpl_documents` (the DOCUMENT DESK files on a record the Use-AI fork: extract = the open
903
+ `ChangeFields` review (adds/updates/removal/conflict) + proposed order lines as `ChangeRecord`
904
+ cards, Keep-all + one outcome-named Apply; cross-check = display-only `Change` findingsa
905
+ recorded verdict; plus the Create-documents readiness checklist).
877
906
 
878
907
  ---
879
908
 
@@ -910,14 +939,21 @@ file_gallery_modal · image_gallery · use_selection (useSelection — always-on
910
939
  spacer · stack · section_card · page_header · page_content · calendar (calendar/index.ts) · gantt ·
911
940
  comments_thread · agent_run (live streaming work feed) · agent_progress (its compact floating
912
941
  expandable form — a composer's working state) · composer (Composer — the adaptive command/chat
913
- composer: a compact pill that expands for long text + attachments) · review_card (ReviewCard — THE single-proposal review card; compositional body via children + a generic actions footer; header-first with a title/eyebrow, body-first without) · confidence (calibrated high/med/low) ·
914
- record_fields (RecordFields — the editable extracted-record BODY for a ReviewCard, or a standalone live-edit field card) · change_review (ChangeReview — the BATCH review LIST, whole-set OR 1-by-1; compositional `renderItem` body + the `ChangeDiff` before→after helper, `labels` localizes Undo/Applied/Discarded/counter PLUS `ChangeReviewActions`, the separate commit bar the host pins in a `DialogFooter`/`DrawerFooter` or inline so it never scrolls away) ·
942
+ composer: a compact pill that expands for long text + attachments) · confidence (calibrated high/med/low) ·
943
+ change_review (the COMPOUND review family frame: ChangeReview provider/stack · ChangeReviewHeader
944
+ (auto kept-counter over decidable entries) · ChangeReviewActions (the commit bar in the
945
+ DialogFooter/DrawerFooter: Keep-all bottom-left (onAcceptAll for host-held field state) + Apply
946
+ gating); sections: Change (host-owned status, labeled verbs, collapses to its ChangeSummary + Undo;
947
+ no callbacks = display-only) · ChangeLabel · ChangeSummary · ChangeReasoning (the quiet why);
948
+ grammar: ChangeFields (the open record form) + ChangeField (THE field: − band · value · candidates
949
+ + type-another-value · reasoning · per-field Keep/Drop · collapse) · ChangeRecord (THE item card:
950
+ registers like a Change; tone wash + localized op word; verb level follows the decision level) ·
951
+ ChangeBand (the raw ± band) · ChangeValueInput (the diff-at-rest editor); the `changeReview`
952
+ locale slice) ·
915
953
  clarify (the agent asks back, via ChoiceList) · choice_list (ChoiceList — selectable answer options,
916
- the agent's quick-reply surface) · sources (provenance chips, per-kind glyphs) · spec_list (SpecListthe exact
917
- labeled-value breakdown, the panel of an answer) · match_sides (MatchSides — the two-sided pairing BODY for a body-first ReviewCard reconciliation; composable side slots + the MatchSideText default) ·
918
- finding (Finding one ranked briefing/audit insight) · discrepancy (Discrepancy — a field that
919
- disagrees across sources) · triage_row (TriageRow — an item the agent classified + routed) ·
920
- scored_option (ScoredOption — an AI-ranked candidate) ·
954
+ the agent's quick-reply surface) · sources (provenance chips, per-kind glyphs) · finding (Findingone ranked AI-check insight: severity word · title · detail · Sources ·
955
+ children slot with FindingComparison, the expected-vs-actual body: labeled sides + emphasized
956
+ delta; the `finding` locale slice) ·
921
957
  format_money · format_date · colors (solid · tint · ramp · ColorName ·
922
958
  isColorName · asColorName — coerce a stored option/status token to a ColorName, neutral fallback) ·
923
959
  use_focus_ring (useFocusRing — keyboard-aware focus state for painting a control's own ring; see Focus rings) ·
@@ -24,8 +24,8 @@ const MOCK_PHOTO: DisplayFile = {
24
24
  // ─────────────────────────────────────────────────────────────────────────────
25
25
  // Template · AI design canvas (the carton "dieline" app) — the FLAGSHIP shape:
26
26
  // the page IS the design. The dieline fills the centre, a FLOATING composer sits
27
- // at the bottom, and a pinned PARAMS PANEL (a RecordFields field-card, here in
28
- // live-edit mode) floats at the centre-right. Empty → drop a photo in the
27
+ // at the bottom, and a pinned PARAMS PANEL (a hand-composed label/value field-card
28
+ // in live-edit mode) floats at the centre-right. Empty → drop a photo in the
29
29
  // composer → the centre processes while the composer MORPHS into a progress pill
30
30
  // (AgentProgress) → the dieline reveals, the params panel appears, the composer
31
31
  // returns. Two ways to change it: prompt the agent ("5 mm taller"), or edit a
@@ -229,7 +229,7 @@ export function TplDieline() {
229
229
  );
230
230
  }
231
231
 
232
- // The pinned right-rail — a RecordFields field-card in live-edit mode: each
232
+ // The pinned right-rail — a label/value field-card in live-edit mode: each
233
233
  // parameter is click-to-edit and re-flows the design on save; one primary
234
234
  // Download. Floats over the canvas, so it carries the composer's lift.
235
235
  const PARAMS: { key: keyof Dims; label: string }[] = [