@thehammer/template-verification 0.2.1 → 0.2.2

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/README.md CHANGED
@@ -2,12 +2,27 @@
2
2
 
3
3
  A read-write **verification overlay** for rendered template apps. It overlays a
4
4
  trust layer on top of an already-rendered document template: per-data-point
5
- confidence/status icons, discrepancy indicators, a click-through detail modal,
6
- inline editing, and a recursive comparison page.
7
-
8
- The library **fetches nothing** — the host passes in the rendered `data` (with an
9
- embedded `__meta` sidecar) and a `saveOverride` transport via a single
10
- `initVerification()` call. It is backend-agnostic and unit-testable standalone.
5
+ confidence pills + verified check chips, discrepancy indicators, and a
6
+ click-through **Inspector** dialog — a hero strip (resolved value, gradient
7
+ confidence meter, discrepancy alert) over three tabs:
8
+
9
+ - **Evidence** — readonly-markdown reasoning, cited-text quote, an embedded
10
+ `DanxFileViewer` over the cited source pages, and per-document drill-down
11
+ to the FULL parent PDF in a stacked dialog.
12
+ - **Candidates** — the resolution flow: one card per candidate
13
+ (override/extracted/claim) with Accept actions + custom-value entry;
14
+ saves toast and flip the in-document pill to a verified chip.
15
+ - **Audit trail** — the LLM calls behind the data point (model, status,
16
+ timing, collapsible JSON request/response), lazy-fetched from the host's
17
+ token-sealed `audit_url`. Tab hidden when the host mints none.
18
+
19
+ `VerificationChrome` adds a review-progress meter (X of Y human-verified),
20
+ a needs-review jump button, and completion celebration.
21
+
22
+ Render data + `__meta` arrive via a single `initVerification()` call — the
23
+ only network the library touches is the host-supplied `saveOverride`
24
+ transport and the optional `auditUrl` endpoint. Backend-agnostic and
25
+ unit-testable standalone.
11
26
 
12
27
  ## Install
13
28
 
@@ -51,7 +66,9 @@ async function saveOverride(args) {
51
66
  initVerification({
52
67
  data: props.data,
53
68
  saveOverride,
54
- workflowInputId: props.data.workflow_input_id
69
+ workflowInputId: props.data.__verification?.workflow_input_id,
70
+ // Token-sealed audit endpoint (optional) — enables the Inspector's Audit tab.
71
+ auditUrl: props.data.__verification?.audit_url ?? null
55
72
  })
56
73
  </script>
57
74
 
@@ -18,8 +18,10 @@ export interface SourceGroup {
18
18
  }
19
19
  /**
20
20
  * Group an extracted candidate's sources by file identity so the modal can render
21
- * one block per file with its pages beneath. Links a group only when a `file_url`
22
- * is present on any of its sources.
21
+ * one block per file with its pages beneath. Links a group when a `file_url` (the
22
+ * idealized shape) is present on any of its sources, falling back to the resolved
23
+ * `file.url` (the live gpt-manager backend shape — `TemplateDataResource` never
24
+ * emits `file_url`, only `file: {id,name,url,mime,size,thumb}`).
23
25
  */
24
26
  export declare function groupSources(sources?: VerificationSource[] | null): SourceGroup[];
25
27
  /** Human page/citation label for a single source row. */
@@ -1,4 +1,4 @@
1
- import { ref as U, watch as ce, defineComponent as K, computed as u, openBlock as l, createElementBlock as i, normalizeClass as A, createElementVNode as n, toDisplayString as y, createCommentVNode as _, createBlock as N, unref as r, withCtx as I, createTextVNode as T, createVNode as V, Fragment as L, renderList as M, withKeys as Te, withModifiers as Ue, renderSlot as Ne, withDirectives as Ae, isRef as ge, vModelCheckbox as Re } from "vue";
1
+ import { ref as U, watch as ce, defineComponent as K, computed as d, openBlock as l, createElementBlock as o, normalizeClass as A, createElementVNode as r, toDisplayString as y, createCommentVNode as _, createBlock as N, unref as i, withCtx as I, createTextVNode as T, createVNode as V, Fragment as L, renderList as M, withKeys as Te, withModifiers as Ue, renderSlot as Ne, withDirectives as Ae, isRef as ge, vModelCheckbox as Re } from "vue";
2
2
  import { DanxChip as J, CodeViewer as xe, useToast as _e, DanxDialog as re, DanxProgressBar as we, DanxAlert as ye, DanxTabs as Le, MarkdownEditor as je, DanxFileViewer as be, DanxButton as se, DanxInput as Ee, DanxSkeleton as ze, DanxTooltip as Pe, DanxIcon as Me, gearIcon as Be, DanxBadge as Fe, DanxToastContainer as qe } from "@thehammer/danx-ui";
3
3
  const P = "tv-chrome", ke = "template-verification:enabled";
4
4
  let te = null;
@@ -84,15 +84,15 @@ function Qe(e) {
84
84
  return { value: null, source: "none" };
85
85
  }
86
86
  function ie(e) {
87
- var g, d;
88
- const t = (d = (g = e == null ? void 0 : e.candidates) == null ? void 0 : g.extracted) == null ? void 0 : d.reasoning;
87
+ var g, m;
88
+ const t = (m = (g = e == null ? void 0 : e.candidates) == null ? void 0 : g.extracted) == null ? void 0 : m.reasoning;
89
89
  if (t == null) return null;
90
90
  const a = String(t).trim();
91
91
  return a === "" ? null : a;
92
92
  }
93
93
  function oe(e) {
94
- var g, d;
95
- const t = (d = (g = e == null ? void 0 : e.candidates) == null ? void 0 : g.extracted) == null ? void 0 : d.cited_text;
94
+ var g, m;
95
+ const t = (m = (g = e == null ? void 0 : e.candidates) == null ? void 0 : g.extracted) == null ? void 0 : m.cited_text;
96
96
  if (t == null) return null;
97
97
  const a = String(t).trim();
98
98
  return a === "" ? null : a;
@@ -109,18 +109,18 @@ function Xe(e) {
109
109
  return JSON.stringify(e ?? null);
110
110
  }
111
111
  function Ze(e, t, a) {
112
- var c;
113
- const g = (c = t.value) == null ? void 0 : c.anchor;
112
+ var s;
113
+ const g = (s = t.value) == null ? void 0 : s.anchor;
114
114
  if (!e.saveOverride || !g) return null;
115
- const d = e.saveOverride;
116
- return async (m, s) => {
117
- const b = await d({
115
+ const m = e.saveOverride;
116
+ return async (f, n) => {
117
+ const b = await m({
118
118
  workflow_input_id: e.workflowInputId,
119
119
  object_ids: g.object_ids,
120
120
  field: g.field,
121
121
  field_path: g.field_path,
122
- value: m,
123
- source_choice: s
122
+ value: f,
123
+ source_choice: n
124
124
  });
125
125
  return a(b), b;
126
126
  };
@@ -139,7 +139,7 @@ const et = ["data-status", "title"], tt = {
139
139
  showLabel: { type: Boolean }
140
140
  },
141
141
  setup(e) {
142
- const t = e, a = u(
142
+ const t = e, a = d(
143
143
  () => t.status ?? ve(t.confidence)
144
144
  ), g = {
145
145
  high: "✔",
@@ -149,14 +149,14 @@ const et = ["data-status", "title"], tt = {
149
149
  low: "✕",
150
150
  // x
151
151
  unverifiable: "?"
152
- }, d = u(() => g[a.value]), c = u(() => Ge[a.value]), m = u(() => ae[a.value]);
153
- return (s, b) => (l(), i("span", {
154
- class: A(["tv-confidence-icon inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-semibold leading-none", c.value]),
152
+ }, m = d(() => g[a.value]), s = d(() => Ge[a.value]), f = d(() => ae[a.value]);
153
+ return (n, b) => (l(), o("span", {
154
+ class: A(["tv-confidence-icon inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-semibold leading-none", s.value]),
155
155
  "data-status": a.value,
156
- title: m.value
156
+ title: f.value
157
157
  }, [
158
- n("span", tt, y(d.value), 1),
159
- e.showLabel ? (l(), i("span", at, y(m.value), 1)) : _("", !0)
158
+ r("span", tt, y(m.value), 1),
159
+ e.showLabel ? (l(), o("span", at, y(f.value), 1)) : _("", !0)
160
160
  ], 10, et));
161
161
  }
162
162
  });
@@ -164,25 +164,26 @@ async function lt(e, t) {
164
164
  const a = t.object_ids.at(-1), g = new URLSearchParams({
165
165
  object_id: String(a),
166
166
  field: t.field
167
- }), d = e.includes("?") ? "&" : "?", c = await fetch(`${e}${d}${g}`);
168
- if (!c.ok)
167
+ }), m = e.includes("?") ? "&" : "?", s = await fetch(`${e}${m}${g}`);
168
+ if (!s.ok)
169
169
  throw new Error(
170
- `data-point-audit ${c.status}: ${await c.text()}`
170
+ `data-point-audit ${s.status}: ${await s.text()}`
171
171
  );
172
- return (await c.json()).data ?? [];
172
+ return (await s.json()).data ?? [];
173
173
  }
174
174
  function De(e) {
175
+ var a, g, m;
175
176
  if (!e || e.length === 0) return [];
176
177
  const t = /* @__PURE__ */ new Map();
177
- for (const a of e) {
178
- const g = nt(a);
179
- let d = t.get(g);
180
- d || (d = {
181
- fileLabel: st(a),
182
- fileUrl: a.file_url,
183
- file: a.file,
178
+ for (const s of e) {
179
+ const f = nt(s);
180
+ let n = t.get(f);
181
+ n || (n = {
182
+ fileLabel: st(s),
183
+ fileUrl: s.file_url ?? ((a = s.file) == null ? void 0 : a.url),
184
+ file: s.file,
184
185
  sources: []
185
- }, t.set(g, d)), !d.fileUrl && a.file_url && (d.fileUrl = a.file_url), !d.file && a.file && (d.file = a.file), d.sources.push(a);
186
+ }, t.set(f, n)), !n.fileUrl && (s.file_url ?? ((g = s.file) == null ? void 0 : g.url)) && (n.fileUrl = s.file_url ?? ((m = s.file) == null ? void 0 : m.url)), !n.file && s.file && (n.file = s.file), n.sources.push(s);
186
187
  }
187
188
  return [...t.values()];
188
189
  }
@@ -195,7 +196,8 @@ function st(e) {
195
196
  return (t = e.file) != null && t.name ? e.file.name : e.file_name ? e.file_name : e.file_id !== void 0 && e.file_id !== null ? `File ${e.file_id}` : e.stored_file_id !== void 0 && e.stored_file_id !== null ? `File ${e.stored_file_id}` : e.source_type ? e.source_type : "Source";
196
197
  }
197
198
  function rt(e) {
198
- return e.page !== void 0 && e.page !== null ? `Page ${e.page}` : e.explanation ? String(e.explanation) : e.source_type ? String(e.source_type) : "Citation";
199
+ const t = e.page ?? e.page_number;
200
+ return t != null ? `Page ${t}` : e.explanation ? String(e.explanation) : e.source_type ? String(e.source_type) : "Citation";
199
201
  }
200
202
  const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm" }, ot = { class: "tv-audit-call-header flex flex-wrap items-center gap-2 border-b border-gray-100 bg-gray-50 px-3 py-2" }, ut = {
201
203
  key: 2,
@@ -212,24 +214,24 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
212
214
  call: {}
213
215
  },
214
216
  setup(e) {
215
- const t = e, a = u(() => {
216
- const s = t.call.status_code;
217
- return s == null ? "muted" : s >= 200 && s < 300 ? "success" : s >= 400 ? "danger" : "warning";
218
- }), g = u(() => {
219
- const s = t.call.run_time_ms;
220
- return s == null ? null : s >= 1e3 ? `${(s / 1e3).toFixed(1)}s` : `${s}ms`;
221
- }), d = u(() => {
217
+ const t = e, a = d(() => {
218
+ const n = t.call.status_code;
219
+ return n == null ? "muted" : n >= 200 && n < 300 ? "success" : n >= 400 ? "danger" : "warning";
220
+ }), g = d(() => {
221
+ const n = t.call.run_time_ms;
222
+ return n == null ? null : n >= 1e3 ? `${(n / 1e3).toFixed(1)}s` : `${n}ms`;
223
+ }), m = d(() => {
222
224
  if (!t.call.started_at) return null;
223
- const s = new Date(t.call.started_at);
224
- return Number.isNaN(s.getTime()) ? t.call.started_at : s.toLocaleString();
225
- }), c = u(
225
+ const n = new Date(t.call.started_at);
226
+ return Number.isNaN(n.getTime()) ? t.call.started_at : n.toLocaleString();
227
+ }), s = d(
226
228
  () => JSON.stringify(t.call.request ?? null, null, 2)
227
- ), m = u(
229
+ ), f = d(
228
230
  () => JSON.stringify(t.call.response ?? null, null, 2)
229
231
  );
230
- return (s, b) => (l(), i("div", it, [
231
- n("div", ot, [
232
- e.call.model ? (l(), N(r(J), {
232
+ return (n, b) => (l(), o("div", it, [
233
+ r("div", ot, [
234
+ e.call.model ? (l(), N(i(J), {
233
235
  key: 0,
234
236
  variant: "info",
235
237
  size: "xs",
@@ -240,7 +242,7 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
240
242
  ]),
241
243
  _: 1
242
244
  })) : _("", !0),
243
- e.call.service ? (l(), N(r(J), {
245
+ e.call.service ? (l(), N(i(J), {
244
246
  key: 1,
245
247
  variant: "muted",
246
248
  size: "xxs"
@@ -250,9 +252,9 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
250
252
  ]),
251
253
  _: 1
252
254
  })) : _("", !0),
253
- e.call.endpoint ? (l(), i("span", ut, y(e.call.endpoint), 1)) : _("", !0),
254
- b[0] || (b[0] = n("span", { class: "flex-1" }, null, -1)),
255
- V(r(J), {
255
+ e.call.endpoint ? (l(), o("span", ut, y(e.call.endpoint), 1)) : _("", !0),
256
+ b[0] || (b[0] = r("span", { class: "flex-1" }, null, -1)),
257
+ V(i(J), {
256
258
  variant: a.value,
257
259
  size: "xxs",
258
260
  class: "tv-audit-status"
@@ -262,24 +264,24 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
262
264
  ]),
263
265
  _: 1
264
266
  }, 8, ["variant"]),
265
- g.value ? (l(), i("span", dt, y(g.value), 1)) : _("", !0),
266
- d.value ? (l(), i("span", ct, y(d.value), 1)) : _("", !0)
267
+ g.value ? (l(), o("span", dt, y(g.value), 1)) : _("", !0),
268
+ m.value ? (l(), o("span", ct, y(m.value), 1)) : _("", !0)
267
269
  ]),
268
- n("div", vt, [
269
- n("div", null, [
270
- b[1] || (b[1] = n("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Request ", -1)),
271
- V(r(xe), {
272
- "model-value": c.value,
270
+ r("div", vt, [
271
+ r("div", null, [
272
+ b[1] || (b[1] = r("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Request ", -1)),
273
+ V(i(xe), {
274
+ "model-value": s.value,
273
275
  format: "json",
274
276
  collapsible: "",
275
277
  "default-collapsed": "",
276
278
  class: "tv-audit-request"
277
279
  }, null, 8, ["model-value"])
278
280
  ]),
279
- n("div", null, [
280
- b[2] || (b[2] = n("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Response ", -1)),
281
- V(r(xe), {
282
- "model-value": m.value,
281
+ r("div", null, [
282
+ b[2] || (b[2] = r("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Response ", -1)),
283
+ V(i(xe), {
284
+ "model-value": f.value,
283
285
  format: "json",
284
286
  collapsible: "",
285
287
  "default-collapsed": "",
@@ -338,29 +340,29 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
338
340
  },
339
341
  emits: ["update:modelValue", "saved"],
340
342
  setup(e, { emit: t }) {
341
- const a = e, g = t, d = le(), c = _e(), m = u({
343
+ const a = e, g = t, m = le(), s = _e(), f = d({
342
344
  get: () => a.modelValue,
343
- set: (f) => g("update:modelValue", f)
344
- }), s = u(() => fe(a.meta)), b = u(() => a.meta.candidates.extracted), $ = u(() => a.meta.candidates.claim), h = u(() => a.meta.candidates.override), x = u(() => {
345
- var f;
346
- return ((f = b.value) == null ? void 0 : f.confidence) ?? null;
347
- }), k = u(() => ve(x.value)), S = u(() => ie(a.meta)), R = u(() => oe(a.meta)), O = u(() => {
348
- var f;
349
- return De((f = b.value) == null ? void 0 : f.sources);
350
- }), j = u(() => (a.meta.anchor.field_path || a.label || "Data point").split(".").map(
351
- (o) => o.replace(/\[\d+\]/g, "").replace(/_/g, " ").replace(/^\w/, (C) => C.toUpperCase())
345
+ set: (v) => g("update:modelValue", v)
346
+ }), n = d(() => fe(a.meta)), b = d(() => a.meta.candidates.extracted), $ = d(() => a.meta.candidates.claim), h = d(() => a.meta.candidates.override), x = d(() => {
347
+ var v;
348
+ return ((v = b.value) == null ? void 0 : v.confidence) ?? null;
349
+ }), k = d(() => ve(x.value)), S = d(() => ie(a.meta)), R = d(() => oe(a.meta)), O = d(() => {
350
+ var v;
351
+ return De((v = b.value) == null ? void 0 : v.sources);
352
+ }), j = d(() => (a.meta.anchor.field_path || a.label || "Data point").split(".").map(
353
+ (u) => u.replace(/\[\d+\]/g, "").replace(/_/g, " ").replace(/^\w/, (C) => C.toUpperCase())
352
354
  ).join(" › ")), H = {
353
355
  high: "success",
354
356
  medium: "warning",
355
357
  low: "danger",
356
358
  unverifiable: "muted"
357
- }, E = U("evidence"), W = u(() => !!d.auditUrl), X = u(() => {
358
- var o;
359
- const f = [
359
+ }, E = U("evidence"), W = d(() => !!m.auditUrl), X = d(() => {
360
+ var u;
361
+ const v = [
360
362
  {
361
363
  value: "evidence",
362
364
  label: "Evidence",
363
- count: O.value.reduce((C, v) => C + v.sources.length, 0)
365
+ count: O.value.reduce((C, c) => C + c.sources.length, 0)
364
366
  },
365
367
  {
366
368
  value: "candidates",
@@ -368,38 +370,38 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
368
370
  count: Q.value.length
369
371
  }
370
372
  ];
371
- return W.value && f.push({
373
+ return W.value && v.push({
372
374
  value: "audit",
373
375
  label: "Audit trail",
374
- count: ((o = F.value) == null ? void 0 : o.length) ?? void 0
375
- }), f;
376
- }), q = u(
377
- () => O.value.map((f) => f.file).filter((f) => !!f)
378
- ), p = U(null), w = u(() => {
379
- const f = p.value ?? q.value[0];
380
- if (!f) return null;
381
- const o = O.value.find(
382
- (v) => v.file && String(v.file.id) === String(f.id)
376
+ count: ((u = F.value) == null ? void 0 : u.length) ?? void 0
377
+ }), v;
378
+ }), q = d(
379
+ () => O.value.map((v) => v.file).filter((v) => !!v)
380
+ ), p = U(null), w = d(() => {
381
+ const v = p.value ?? q.value[0];
382
+ if (!v) return null;
383
+ const u = O.value.find(
384
+ (c) => c.file && String(c.file.id) === String(v.id)
383
385
  );
384
- if (!o) return null;
385
- const C = o.sources.find((v) => v.explanation);
386
+ if (!u) return null;
387
+ const C = u.sources.find((c) => c.explanation);
386
388
  return (C == null ? void 0 : C.explanation) ?? null;
387
- }), D = u(() => {
388
- const f = /* @__PURE__ */ new Map();
389
- for (const o of O.value)
390
- for (const C of o.sources) {
391
- const v = C.original_file;
392
- v && !f.has(String(v.id)) && f.set(String(v.id), v);
389
+ }), D = d(() => {
390
+ const v = /* @__PURE__ */ new Map();
391
+ for (const u of O.value)
392
+ for (const C of u.sources) {
393
+ const c = C.original_file;
394
+ c && !v.has(String(c.id)) && v.set(String(c.id), c);
393
395
  }
394
- return [...f.values()];
395
- }), z = U(null), G = u({
396
+ return [...v.values()];
397
+ }), z = U(null), G = d({
396
398
  get: () => z.value !== null,
397
- set: (f) => {
398
- f || (z.value = null);
399
+ set: (v) => {
400
+ v || (z.value = null);
399
401
  }
400
- }), Q = u(() => {
401
- const f = [];
402
- return h.value && f.push({
402
+ }), Q = d(() => {
403
+ const v = [];
404
+ return h.value && v.push({
403
405
  key: "override",
404
406
  title: "Human override",
405
407
  variant: "success",
@@ -408,60 +410,60 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
408
410
  h.value.source_choice ? `basis: ${h.value.source_choice}` : null,
409
411
  h.value.set_at ? new Date(h.value.set_at).toLocaleString() : null
410
412
  ].filter(Boolean).join(" · "),
411
- winner: s.value.source === "override"
412
- }), b.value && f.push({
413
+ winner: n.value.source === "override"
414
+ }), b.value && v.push({
413
415
  key: "extracted",
414
416
  title: "Extracted",
415
417
  variant: H[k.value],
416
418
  value: b.value.value,
417
419
  detail: x.value != null ? `Confidence ${x.value}/5 · ${ae[k.value]}` : "No confidence recorded",
418
420
  accept: a.save ? () => {
419
- var o;
420
- return ne(pe((o = b.value) == null ? void 0 : o.value), "extracted");
421
+ var u;
422
+ return ne(pe((u = b.value) == null ? void 0 : u.value), "extracted");
421
423
  } : void 0,
422
- winner: s.value.source === "extracted"
423
- }), $.value && f.push({
424
+ winner: n.value.source === "extracted"
425
+ }), $.value && v.push({
424
426
  key: "claim",
425
427
  title: "Claim",
426
428
  variant: "info",
427
429
  value: $.value.value,
428
430
  detail: $.value.claim_set_label ?? "Reference output",
429
431
  accept: a.save ? () => {
430
- var o;
431
- return ne(pe((o = $.value) == null ? void 0 : o.value), "claim");
432
+ var u;
433
+ return ne(pe((u = $.value) == null ? void 0 : u.value), "claim");
432
434
  } : void 0,
433
- winner: s.value.source === "claim"
434
- }), f;
435
+ winner: n.value.source === "claim"
436
+ }), v;
435
437
  }), B = U(""), Y = U(!1);
436
- async function ne(f, o) {
438
+ async function ne(v, u) {
437
439
  if (!(!a.save || Y.value)) {
438
440
  Y.value = !0;
439
441
  try {
440
- const C = await a.save(f, o);
441
- g("saved", C), c.success(`Verified — ${j.value} locked in`);
442
+ const C = await a.save(v, u);
443
+ g("saved", C), s.success(`Verified — ${j.value} locked in`);
442
444
  } catch {
443
- c.danger(`Could not save ${j.value} — try again`);
445
+ s.danger(`Could not save ${j.value} — try again`);
444
446
  } finally {
445
447
  Y.value = !1;
446
448
  }
447
449
  }
448
450
  }
449
451
  const Ie = () => ne(B.value, "custom");
450
- function pe(f) {
451
- return f == null ? null : String(f);
452
+ function pe(v) {
453
+ return v == null ? null : String(v);
452
454
  }
453
- function me(f) {
454
- return f == null ? "—" : String(f);
455
+ function me(v) {
456
+ return v == null ? "—" : String(v);
455
457
  }
456
458
  const F = U(null), Z = U(!1), ee = U(null);
457
459
  return ce(
458
- [E, m],
459
- async ([f, o]) => {
460
- if (!(f !== "audit" || !o || F.value !== null || Z.value) && d.auditUrl) {
460
+ [E, f],
461
+ async ([v, u]) => {
462
+ if (!(v !== "audit" || !u || F.value !== null || Z.value) && m.auditUrl) {
461
463
  Z.value = !0, ee.value = null;
462
464
  try {
463
465
  F.value = await lt(
464
- d.auditUrl,
466
+ m.auditUrl,
465
467
  a.meta.anchor
466
468
  );
467
469
  } catch (C) {
@@ -472,34 +474,34 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
472
474
  }
473
475
  },
474
476
  { immediate: !0 }
475
- ), (f, o) => (l(), i(L, null, [
476
- V(r(re), {
477
- modelValue: m.value,
478
- "onUpdate:modelValue": o[3] || (o[3] = (C) => m.value = C),
477
+ ), (v, u) => (l(), o(L, null, [
478
+ V(i(re), {
479
+ modelValue: f.value,
480
+ "onUpdate:modelValue": u[3] || (u[3] = (C) => f.value = C),
479
481
  title: j.value,
480
482
  width: 90,
481
483
  height: 90,
482
484
  "close-x": "",
483
- class: A(r(P))
485
+ class: A(i(P))
484
486
  }, {
485
487
  default: I(() => {
486
488
  var C;
487
489
  return [
488
- n("div", pt, [
489
- n("section", mt, [
490
- n("div", gt, [
491
- n("div", xt, [
492
- o[6] || (o[6] = n("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Resolved value ", -1)),
493
- n("div", yt, y(me(s.value.value)), 1),
494
- n("div", bt, [
495
- o[5] || (o[5] = T(" source of truth: ", -1)),
496
- n("span", ht, y(s.value.source), 1)
490
+ r("div", pt, [
491
+ r("section", mt, [
492
+ r("div", gt, [
493
+ r("div", xt, [
494
+ u[6] || (u[6] = r("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Resolved value ", -1)),
495
+ r("div", yt, y(me(n.value.value)), 1),
496
+ r("div", bt, [
497
+ u[5] || (u[5] = T(" source of truth: ", -1)),
498
+ r("span", ht, y(n.value.source), 1)
497
499
  ])
498
500
  ]),
499
- n("div", _t, [
500
- o[7] || (o[7] = n("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Extraction confidence ", -1)),
501
- n("div", wt, [
502
- x.value != null ? (l(), N(r(we), {
501
+ r("div", _t, [
502
+ u[7] || (u[7] = r("div", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Extraction confidence ", -1)),
503
+ r("div", wt, [
504
+ x.value != null ? (l(), N(i(we), {
503
505
  key: 0,
504
506
  value: x.value,
505
507
  max: 5,
@@ -510,65 +512,65 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
510
512
  "show-text": "",
511
513
  "text-position": "beside",
512
514
  label: `${x.value}/5`
513
- }, null, 8, ["value", "variant", "label"])) : (l(), i("div", kt, " No confidence recorded "))
515
+ }, null, 8, ["value", "variant", "label"])) : (l(), o("div", kt, " No confidence recorded "))
514
516
  ]),
515
- n("div", {
517
+ r("div", {
516
518
  class: A(["tv-confidence-label mt-1 text-right text-xs font-medium", {
517
519
  "text-green-600": k.value === "high",
518
520
  "text-yellow-600": k.value === "medium",
519
521
  "text-red-600": k.value === "low",
520
522
  "text-gray-400": k.value === "unverifiable"
521
523
  }])
522
- }, y(r(ae)[k.value]), 3)
524
+ }, y(i(ae)[k.value]), 3)
523
525
  ])
524
526
  ]),
525
- e.meta.discrepancy ? (l(), N(r(ye), {
527
+ e.meta.discrepancy ? (l(), N(i(ye), {
526
528
  key: 0,
527
529
  variant: "warning",
528
530
  class: "tv-discrepancy"
529
531
  }, {
530
- default: I(() => [...o[8] || (o[8] = [
532
+ default: I(() => [...u[8] || (u[8] = [
531
533
  T(" Sources disagree on this value — review the candidates and pick a winner. ", -1)
532
534
  ])]),
533
535
  _: 1
534
536
  })) : _("", !0)
535
537
  ]),
536
- V(r(Le), {
538
+ V(i(Le), {
537
539
  modelValue: E.value,
538
- "onUpdate:modelValue": o[0] || (o[0] = (v) => E.value = v),
540
+ "onUpdate:modelValue": u[0] || (u[0] = (c) => E.value = c),
539
541
  tabs: X.value,
540
542
  class: "tv-modal-tabs"
541
543
  }, null, 8, ["modelValue", "tabs"]),
542
- E.value === "evidence" ? (l(), i("section", $t, [
543
- S.value ? (l(), i("div", St, [
544
- o[9] || (o[9] = n("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Reasoning ", -1)),
545
- V(r(je), {
544
+ E.value === "evidence" ? (l(), o("section", $t, [
545
+ S.value ? (l(), o("div", St, [
546
+ u[9] || (u[9] = r("div", { class: "mb-1 text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, " Reasoning ", -1)),
547
+ V(i(je), {
546
548
  "model-value": S.value,
547
549
  readonly: "",
548
550
  class: "tv-reasoning"
549
551
  }, null, 8, ["model-value"])
550
552
  ])) : _("", !0),
551
- R.value ? (l(), i("blockquote", Ct, [
553
+ R.value ? (l(), o("blockquote", Ct, [
552
554
  T(" “" + y(R.value) + "” ", 1),
553
- V(r(J), {
555
+ V(i(J), {
554
556
  variant: (C = b.value) != null && C.cited_text_verified ? "success" : "muted",
555
557
  size: "xxs",
556
558
  class: "tv-cited-verified ml-2 not-italic"
557
559
  }, {
558
560
  default: I(() => {
559
- var v;
561
+ var c;
560
562
  return [
561
- T(y((v = b.value) != null && v.cited_text_verified ? "✔ verified in source" : "unverified"), 1)
563
+ T(y((c = b.value) != null && c.cited_text_verified ? "✔ verified in source" : "unverified"), 1)
562
564
  ];
563
565
  }),
564
566
  _: 1
565
567
  }, 8, ["variant"])
566
568
  ])) : _("", !0),
567
- q.value.length ? (l(), i("div", Vt, [
568
- V(r(be), {
569
+ q.value.length ? (l(), o("div", Vt, [
570
+ V(i(be), {
569
571
  file: q.value[0],
570
572
  "file-in-preview": p.value,
571
- "onUpdate:fileInPreview": o[1] || (o[1] = (v) => p.value = v),
573
+ "onUpdate:fileInPreview": u[1] || (u[1] = (c) => p.value = c),
572
574
  "related-files": q.value,
573
575
  "layout-toggles": ["sidebar", "continuous"],
574
576
  "default-sidebar": "",
@@ -576,84 +578,84 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
576
578
  "storage-key": "tv-evidence-viewer",
577
579
  class: "h-full min-h-0 flex-1"
578
580
  }, null, 8, ["file", "file-in-preview", "related-files"]),
579
- w.value ? (l(), i("div", Dt, y(w.value), 1)) : _("", !0)
580
- ])) : (l(), i("div", Ot, " No source pages recorded for this data point ")),
581
- D.value.length ? (l(), i("div", It, [
582
- o[10] || (o[10] = n("span", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, "Full documents:", -1)),
583
- (l(!0), i(L, null, M(D.value, (v) => (l(), N(r(se), {
584
- key: String(v.id),
581
+ w.value ? (l(), o("div", Dt, y(w.value), 1)) : _("", !0)
582
+ ])) : (l(), o("div", Ot, " No source pages recorded for this data point ")),
583
+ D.value.length ? (l(), o("div", It, [
584
+ u[10] || (u[10] = r("span", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, "Full documents:", -1)),
585
+ (l(!0), o(L, null, M(D.value, (c) => (l(), N(i(se), {
586
+ key: String(c.id),
585
587
  size: "sm",
586
588
  variant: "info",
587
589
  class: "tv-open-document",
588
- onClick: (xa) => z.value = v
590
+ onClick: (xa) => z.value = c
589
591
  }, {
590
592
  default: I(() => [
591
- T(y(v.name), 1)
593
+ T(y(c.name), 1)
592
594
  ]),
593
595
  _: 2
594
596
  }, 1032, ["onClick"]))), 128))
595
597
  ])) : _("", !0)
596
598
  ])) : _("", !0),
597
- E.value === "candidates" ? (l(), i("section", Tt, [
598
- (l(!0), i(L, null, M(Q.value, (v) => (l(), i("div", {
599
- key: v.key,
599
+ E.value === "candidates" ? (l(), o("section", Tt, [
600
+ (l(!0), o(L, null, M(Q.value, (c) => (l(), o("div", {
601
+ key: c.key,
600
602
  class: A(["tv-candidate-row rounded-lg border p-4 transition-shadow", [
601
- v.winner ? "border-gray-300 bg-gray-50 shadow-sm" : "border-gray-200",
602
- e.meta.discrepancy && !v.winner ? "tv-candidate-disagrees border-amber-200" : ""
603
+ c.winner ? "border-gray-300 bg-gray-50 shadow-sm" : "border-gray-200",
604
+ e.meta.discrepancy && !c.winner ? "tv-candidate-disagrees border-amber-200" : ""
603
605
  ]])
604
606
  }, [
605
- n("div", Ut, [
606
- n("div", Nt, [
607
- n("div", At, [
608
- V(r(J), {
609
- variant: v.variant,
607
+ r("div", Ut, [
608
+ r("div", Nt, [
609
+ r("div", At, [
610
+ V(i(J), {
611
+ variant: c.variant,
610
612
  size: "xs"
611
613
  }, {
612
614
  default: I(() => [
613
- T(y(v.title), 1)
615
+ T(y(c.title), 1)
614
616
  ]),
615
617
  _: 2
616
618
  }, 1032, ["variant"]),
617
- v.winner ? (l(), N(r(J), {
619
+ c.winner ? (l(), N(i(J), {
618
620
  key: 0,
619
621
  variant: "success",
620
622
  size: "xxs",
621
623
  class: "tv-winner-chip"
622
624
  }, {
623
- default: I(() => [...o[11] || (o[11] = [
625
+ default: I(() => [...u[11] || (u[11] = [
624
626
  T("current value", -1)
625
627
  ])]),
626
628
  _: 1
627
629
  })) : _("", !0)
628
630
  ]),
629
- n("div", Rt, y(me(v.value)), 1),
630
- n("div", Lt, y(v.detail), 1)
631
+ r("div", Rt, y(me(c.value)), 1),
632
+ r("div", Lt, y(c.detail), 1)
631
633
  ]),
632
- v.accept && !v.winner ? (l(), N(r(se), {
634
+ c.accept && !c.winner ? (l(), N(i(se), {
633
635
  key: 0,
634
636
  size: "sm",
635
- variant: v.variant,
637
+ variant: c.variant,
636
638
  loading: Y.value,
637
- class: A(`tv-accept-${v.key}`),
638
- onClick: v.accept
639
+ class: A(`tv-accept-${c.key}`),
640
+ onClick: c.accept
639
641
  }, {
640
- default: I(() => [...o[12] || (o[12] = [
642
+ default: I(() => [...u[12] || (u[12] = [
641
643
  T("Accept this value", -1)
642
644
  ])]),
643
645
  _: 1
644
646
  }, 8, ["variant", "loading", "class", "onClick"])) : _("", !0)
645
647
  ])
646
648
  ], 2))), 128)),
647
- e.save ? (l(), i("div", jt, [
648
- V(r(Ee), {
649
+ e.save ? (l(), o("div", jt, [
650
+ V(i(Ee), {
649
651
  modelValue: B.value,
650
- "onUpdate:modelValue": o[2] || (o[2] = (v) => B.value = v),
652
+ "onUpdate:modelValue": u[2] || (u[2] = (c) => B.value = c),
651
653
  size: "sm",
652
654
  class: "tv-custom-input flex-1",
653
655
  placeholder: "Type the correct value…",
654
656
  disabled: Y.value
655
657
  }, null, 8, ["modelValue", "disabled"]),
656
- V(r(se), {
658
+ V(i(se), {
657
659
  variant: "success",
658
660
  size: "sm",
659
661
  class: "tv-accept-custom",
@@ -661,19 +663,19 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
661
663
  disabled: !B.value,
662
664
  onClick: Ie
663
665
  }, {
664
- default: I(() => [...o[13] || (o[13] = [
666
+ default: I(() => [...u[13] || (u[13] = [
665
667
  T("Save custom value", -1)
666
668
  ])]),
667
669
  _: 1
668
670
  }, 8, ["loading", "disabled"])
669
- ])) : (l(), i("div", Et, " Read-only render — corrections are disabled here "))
671
+ ])) : (l(), o("div", Et, " Read-only render — corrections are disabled here "))
670
672
  ])) : _("", !0),
671
- E.value === "audit" ? (l(), i("section", zt, [
672
- Z.value ? (l(), i(L, { key: 0 }, M(2, (v) => V(r(ze), {
673
- key: v,
673
+ E.value === "audit" ? (l(), o("section", zt, [
674
+ Z.value ? (l(), o(L, { key: 0 }, M(2, (c) => V(i(ze), {
675
+ key: c,
674
676
  shape: "rounded",
675
677
  class: "tv-audit-skeleton h-24 w-full"
676
- })), 64)) : ee.value ? (l(), N(r(ye), {
678
+ })), 64)) : ee.value ? (l(), N(i(ye), {
677
679
  key: 1,
678
680
  variant: "danger",
679
681
  class: "tv-audit-error"
@@ -682,9 +684,9 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
682
684
  T(" Could not load the audit trail: " + y(ee.value), 1)
683
685
  ]),
684
686
  _: 1
685
- })) : F.value && F.value.length === 0 ? (l(), i("div", Pt, " No LLM calls recorded for this data point ")) : F.value ? (l(!0), i(L, { key: 3 }, M(F.value, (v) => (l(), N(ft, {
686
- key: String(v.id),
687
- call: v
687
+ })) : F.value && F.value.length === 0 ? (l(), o("div", Pt, " No LLM calls recorded for this data point ")) : F.value ? (l(!0), o(L, { key: 3 }, M(F.value, (c) => (l(), N(ft, {
688
+ key: String(c.id),
689
+ call: c
688
690
  }, null, 8, ["call"]))), 128)) : _("", !0)
689
691
  ])) : _("", !0)
690
692
  ])
@@ -692,18 +694,18 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
692
694
  }),
693
695
  _: 1
694
696
  }, 8, ["modelValue", "title", "class"]),
695
- z.value ? (l(), N(r(re), {
697
+ z.value ? (l(), N(i(re), {
696
698
  key: 0,
697
699
  modelValue: G.value,
698
- "onUpdate:modelValue": o[4] || (o[4] = (C) => G.value = C),
700
+ "onUpdate:modelValue": u[4] || (u[4] = (C) => G.value = C),
699
701
  title: z.value.name,
700
702
  width: 90,
701
703
  height: 90,
702
704
  "close-x": "",
703
- class: A(r(P))
705
+ class: A(i(P))
704
706
  }, {
705
707
  default: I(() => [
706
- V(r(be), {
708
+ V(i(be), {
707
709
  file: z.value,
708
710
  downloadable: "",
709
711
  zoomable: "",
@@ -731,33 +733,33 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
731
733
  format: { type: Function }
732
734
  },
733
735
  setup(e) {
734
- const t = e, a = le(), g = u(() => a.enabled.value), d = U(null), c = u(() => {
736
+ const t = e, a = le(), g = d(() => a.enabled.value), m = U(null), s = d(() => {
735
737
  var p;
736
- return d.value ? d.value : t.source && t.field ? ((p = t.source.__meta) == null ? void 0 : p[t.field]) ?? null : null;
737
- }), m = u(() => fe(c.value)), s = u(() => {
738
+ return m.value ? m.value : t.source && t.field ? ((p = t.source.__meta) == null ? void 0 : p[t.field]) ?? null : null;
739
+ }), f = d(() => fe(s.value)), n = d(() => {
738
740
  if (t.original !== void 0 && t.original !== null)
739
741
  return t.original;
740
- if (c.value && m.value.value !== null && m.value.value !== void 0)
741
- return m.value.value;
742
+ if (s.value && f.value.value !== null && f.value.value !== void 0)
743
+ return f.value.value;
742
744
  if (t.source && t.field) return t.source[t.field];
743
- }), b = u(() => {
744
- const p = s.value;
745
- return p == null ? "" : t.format ? t.format(p) : String(p);
746
- }), $ = u(
745
+ }), b = d(() => {
746
+ const p = n.value;
747
+ return p == null ? "" : typeof t.format == "function" ? t.format(p) : String(p);
748
+ }), $ = d(
747
749
  () => {
748
750
  var p, w, D;
749
- return ve((D = (w = (p = c.value) == null ? void 0 : p.candidates) == null ? void 0 : w.extracted) == null ? void 0 : D.confidence);
751
+ return ve((D = (w = (p = s.value) == null ? void 0 : p.candidates) == null ? void 0 : w.extracted) == null ? void 0 : D.confidence);
750
752
  }
751
- ), h = u(() => Ve(c.value)), x = u(() => {
753
+ ), h = d(() => Ve(s.value)), x = d(() => {
752
754
  var p, w;
753
- return !!((w = (p = c.value) == null ? void 0 : p.candidates) != null && w.override);
754
- }), k = u(() => {
755
+ return !!((w = (p = s.value) == null ? void 0 : p.candidates) != null && w.override);
756
+ }), k = d(() => {
755
757
  var w;
756
- const p = (w = c.value) == null ? void 0 : w.candidates;
758
+ const p = (w = s.value) == null ? void 0 : w.candidates;
757
759
  return !!(p != null && p.override || p != null && p.extracted || p != null && p.claim);
758
- }), S = u(() => g.value && !!c.value), R = u(() => {
760
+ }), S = d(() => g.value && !!s.value), R = d(() => {
759
761
  var G, Q, B;
760
- const p = (Q = (G = c.value) == null ? void 0 : G.candidates) == null ? void 0 : Q.extracted;
762
+ const p = (Q = (G = s.value) == null ? void 0 : G.candidates) == null ? void 0 : Q.extracted;
761
763
  if (!p) return "No verification data";
762
764
  const w = [], D = ae[$.value];
763
765
  w.push(
@@ -768,19 +770,19 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
768
770
  });
769
771
  function O(p) {
770
772
  var w;
771
- d.value = p, (w = t.source) != null && w.__meta && t.field && (t.source.__meta[t.field] = p);
773
+ m.value = p, (w = t.source) != null && w.__meta && t.field && (t.source.__meta[t.field] = p);
772
774
  }
773
- const j = u(() => Ze(a, c, O)), H = u(() => !!j.value), E = U(!1), W = U(!1);
775
+ const j = d(() => Ze(a, s, O)), H = d(() => !!j.value), E = U(!1), W = U(!1);
774
776
  function X() {
775
- c.value && (E.value = !0);
777
+ s.value && (E.value = !0);
776
778
  }
777
779
  async function q(p) {
778
780
  W.value = !1;
779
781
  const D = (p.target.textContent ?? "").trim();
780
782
  !j.value || D === b.value || await j.value(D, "custom");
781
783
  }
782
- return (p, w) => (l(), i("span", Bt, [
783
- n("span", {
784
+ return (p, w) => (l(), o("span", Bt, [
785
+ r("span", {
784
786
  class: A([
785
787
  "tv-field-value",
786
788
  S.value && !k.value ? "tv-field-unverified cursor-pointer border-b border-dotted border-gray-300" : ""
@@ -793,37 +795,37 @@ const it = { class: "tv-audit-call rounded-lg border border-gray-200 shadow-sm"
793
795
  onClick: w[2] || (w[2] = (D) => S.value && !k.value ? X() : void 0)
794
796
  }, [
795
797
  Ne(p.$slots, "default", {
796
- value: s.value,
798
+ value: n.value,
797
799
  formatted: b.value
798
800
  }, () => [
799
801
  T(y(b.value), 1)
800
802
  ])
801
803
  ], 42, Ft),
802
- S.value && k.value ? (l(), N(r(Pe), {
804
+ S.value && k.value ? (l(), N(i(Pe), {
803
805
  key: 0,
804
806
  tooltip: R.value,
805
807
  placement: "top"
806
808
  }, {
807
809
  trigger: I(() => [
808
- n("button", {
810
+ r("button", {
809
811
  type: "button",
810
- class: A(["tv-overlay inline-flex cursor-pointer items-center align-middle transition-transform duration-150 hover:scale-110", r(P)]),
812
+ class: A(["tv-overlay inline-flex cursor-pointer items-center align-middle transition-transform duration-150 hover:scale-110", i(P)]),
811
813
  onClick: X
812
814
  }, [
813
- x.value ? (l(), i("span", qt, "✔")) : (l(), N(ue, {
815
+ x.value ? (l(), o("span", qt, "✔")) : (l(), N(ue, {
814
816
  key: 0,
815
817
  status: $.value
816
818
  }, null, 8, ["status"])),
817
- h.value && !x.value ? (l(), i("span", Yt, "⚠")) : _("", !0)
819
+ h.value && !x.value ? (l(), o("span", Yt, "⚠")) : _("", !0)
818
820
  ], 2)
819
821
  ]),
820
822
  _: 1
821
823
  }, 8, ["tooltip"])) : _("", !0),
822
- c.value ? (l(), N(Mt, {
824
+ s.value ? (l(), N(Mt, {
823
825
  key: 1,
824
826
  modelValue: E.value,
825
827
  "onUpdate:modelValue": w[3] || (w[3] = (D) => E.value = D),
826
- meta: c.value,
828
+ meta: s.value,
827
829
  label: e.field,
828
830
  save: j.value
829
831
  }, null, 8, ["modelValue", "meta", "label", "save"])) : _("", !0)
@@ -836,24 +838,24 @@ function Oe(e, t = "") {
836
838
  }
837
839
  function de(e, t, a) {
838
840
  if (Array.isArray(e)) {
839
- e.forEach((c, m) => de(c, `${t}[${m}]`, a));
841
+ e.forEach((s, f) => de(s, `${t}[${f}]`, a));
840
842
  return;
841
843
  }
842
844
  if (!he(e)) return;
843
- const d = e.__meta ?? {};
844
- for (const [c, m] of Object.entries(e)) {
845
- if (c === "__meta") continue;
846
- const s = t ? `${t}.${c}` : c;
847
- if (Array.isArray(m) || he(m)) {
848
- de(m, s, a);
845
+ const m = e.__meta ?? {};
846
+ for (const [s, f] of Object.entries(e)) {
847
+ if (s === "__meta") continue;
848
+ const n = t ? `${t}.${s}` : s;
849
+ if (Array.isArray(f) || he(f)) {
850
+ de(f, n, a);
849
851
  continue;
850
852
  }
851
- const b = d[c];
852
- !b && Jt.has(c) || a.push({
853
- path: s,
854
- label: c,
853
+ const b = m[s];
854
+ !b && Jt.has(s) || a.push({
855
+ path: n,
856
+ label: s,
855
857
  meta: b ?? null,
856
- value: m,
858
+ value: f,
857
859
  unanchored: !b
858
860
  });
859
861
  }
@@ -862,23 +864,23 @@ function he(e) {
862
864
  return typeof e == "object" && e !== null && !Array.isArray(e);
863
865
  }
864
866
  function Kt(e) {
865
- var c;
867
+ var s;
866
868
  const t = Oe(e).filter(
867
- (m) => m.meta !== null
869
+ (f) => f.meta !== null
868
870
  ), a = t.length;
869
- let g = 0, d = 0;
870
- for (const m of t) {
871
- if (m.meta.candidates.override) {
871
+ let g = 0, m = 0;
872
+ for (const f of t) {
873
+ if (f.meta.candidates.override) {
872
874
  g++;
873
875
  continue;
874
876
  }
875
- const s = (c = m.meta.candidates.extracted) == null ? void 0 : c.confidence;
876
- (m.meta.discrepancy || s == null || s <= 2) && d++;
877
+ const n = (s = f.meta.candidates.extracted) == null ? void 0 : s.confidence;
878
+ (f.meta.discrepancy || n == null || n <= 2) && m++;
877
879
  }
878
880
  return {
879
881
  total: a,
880
882
  verified: g,
881
- needsReview: d,
883
+ needsReview: m,
882
884
  percent: a === 0 ? 100 : Math.round(g / a * 100)
883
885
  };
884
886
  }
@@ -903,15 +905,15 @@ const Ht = { class: "tv-comparison-page flex flex-col gap-4" }, Gt = {
903
905
  }, da = { class: "tv-datapoint-path font-mono text-xs text-gray-500" }, ca = { class: "tv-datapoint-value" }, va = /* @__PURE__ */ K({
904
906
  __name: "ComparisonPage",
905
907
  setup(e) {
906
- const t = le(), a = u(() => Oe(t.data)), g = u(() => a.value.filter(($) => !$.unanchored)), d = u(() => a.value.filter(($) => $.unanchored));
907
- function c($) {
908
+ const t = le(), a = d(() => Oe(t.data)), g = d(() => a.value.filter(($) => !$.unanchored)), m = d(() => a.value.filter(($) => $.unanchored));
909
+ function s($) {
908
910
  const h = fe($).value;
909
911
  return h == null ? "" : String(h);
910
912
  }
911
- function m($) {
913
+ function f($) {
912
914
  return $ == null ? "" : String($);
913
915
  }
914
- function s($) {
916
+ function n($) {
915
917
  var h, x, k;
916
918
  return (k = (x = (h = $.meta) == null ? void 0 : h.candidates) == null ? void 0 : x.extracted) == null ? void 0 : k.confidence;
917
919
  }
@@ -922,62 +924,62 @@ const Ht = { class: "tv-comparison-page flex flex-col gap-4" }, Gt = {
922
924
  const x = [];
923
925
  return h.override && x.push({ source: "override", value: h.override.value }), h.extracted && x.push({ source: "extracted", value: h.extracted.value }), h.claim && x.push({ source: "claim", value: h.claim.value }), x;
924
926
  }
925
- return ($, h) => (l(), i("div", Ht, [
926
- h[1] || (h[1] = n("h2", { class: "tv-comparison-title text-lg font-semibold" }, "Verification comparison", -1)),
927
- a.value.length === 0 ? (l(), i("p", Gt, " No data points to compare. ")) : _("", !0),
928
- g.value.length ? (l(), i("section", Qt, [
929
- (l(!0), i(L, null, M(g.value, (x) => {
927
+ return ($, h) => (l(), o("div", Ht, [
928
+ h[1] || (h[1] = r("h2", { class: "tv-comparison-title text-lg font-semibold" }, "Verification comparison", -1)),
929
+ a.value.length === 0 ? (l(), o("p", Gt, " No data points to compare. ")) : _("", !0),
930
+ g.value.length ? (l(), o("section", Qt, [
931
+ (l(!0), o(L, null, M(g.value, (x) => {
930
932
  var k, S, R;
931
- return l(), i("div", {
933
+ return l(), o("div", {
932
934
  key: x.path,
933
935
  class: "tv-datapoint border-t border-gray-100 pt-2"
934
936
  }, [
935
- n("div", Wt, [
936
- n("span", Xt, y(x.path), 1),
937
- n("span", Zt, y(c(x.meta)), 1),
937
+ r("div", Wt, [
938
+ r("span", Xt, y(x.path), 1),
939
+ r("span", Zt, y(s(x.meta)), 1),
938
940
  V(ue, {
939
- confidence: s(x),
941
+ confidence: n(x),
940
942
  "show-label": ""
941
943
  }, null, 8, ["confidence"]),
942
- r(Ve)(x.meta) ? (l(), i("span", ea, "⚠ discrepancy")) : _("", !0)
944
+ i(Ve)(x.meta) ? (l(), o("span", ea, "⚠ discrepancy")) : _("", !0)
943
945
  ]),
944
- n("ul", ta, [
945
- (l(!0), i(L, null, M(b(x), (O) => (l(), i("li", {
946
+ r("ul", ta, [
947
+ (l(!0), o(L, null, M(b(x), (O) => (l(), o("li", {
946
948
  key: O.source,
947
949
  class: "tv-candidate"
948
950
  }, [
949
- n("span", aa, y(O.source) + ":", 1),
950
- T(" " + y(m(O.value)), 1)
951
+ r("span", aa, y(O.source) + ":", 1),
952
+ T(" " + y(f(O.value)), 1)
951
953
  ]))), 128))
952
954
  ]),
953
- r(ie)(x.meta) ? (l(), i("p", la, y(r(ie)(x.meta)), 1)) : _("", !0),
954
- r(oe)(x.meta) ? (l(), i("p", na, " “" + y(r(oe)(x.meta)) + "” ", 1)) : _("", !0),
955
- n("ul", sa, [
956
- (l(!0), i(L, null, M(r(De)((R = (S = (k = x.meta) == null ? void 0 : k.candidates) == null ? void 0 : S.extracted) == null ? void 0 : R.sources), (O, j) => (l(), i("li", {
955
+ i(ie)(x.meta) ? (l(), o("p", la, y(i(ie)(x.meta)), 1)) : _("", !0),
956
+ i(oe)(x.meta) ? (l(), o("p", na, " “" + y(i(oe)(x.meta)) + "” ", 1)) : _("", !0),
957
+ r("ul", sa, [
958
+ (l(!0), o(L, null, M(i(De)((R = (S = (k = x.meta) == null ? void 0 : k.candidates) == null ? void 0 : S.extracted) == null ? void 0 : R.sources), (O, j) => (l(), o("li", {
957
959
  key: j,
958
960
  class: "tv-source-group"
959
961
  }, [
960
- O.fileUrl ? (l(), i("a", {
962
+ O.fileUrl ? (l(), o("a", {
961
963
  key: 0,
962
964
  href: O.fileUrl,
963
965
  class: "tv-source-link text-blue-600 underline",
964
966
  target: "_blank",
965
967
  rel: "noopener"
966
- }, y(O.fileLabel), 9, ra)) : (l(), i("span", ia, y(O.fileLabel), 1)),
967
- n("span", oa, "(" + y(O.sources.map(r(rt)).join(", ")) + ")", 1)
968
+ }, y(O.fileLabel), 9, ra)) : (l(), o("span", ia, y(O.fileLabel), 1)),
969
+ r("span", oa, "(" + y(O.sources.map(i(rt)).join(", ")) + ")", 1)
968
970
  ]))), 128))
969
971
  ])
970
972
  ]);
971
973
  }), 128))
972
974
  ])) : _("", !0),
973
- d.value.length ? (l(), i("section", ua, [
974
- h[0] || (h[0] = n("h3", { class: "tv-unanchored-title text-sm font-semibold text-gray-500" }, " Unanchored / not from source ", -1)),
975
- (l(!0), i(L, null, M(d.value, (x) => (l(), i("div", {
975
+ m.value.length ? (l(), o("section", ua, [
976
+ h[0] || (h[0] = r("h3", { class: "tv-unanchored-title text-sm font-semibold text-gray-500" }, " Unanchored / not from source ", -1)),
977
+ (l(!0), o(L, null, M(m.value, (x) => (l(), o("div", {
976
978
  key: x.path,
977
979
  class: "tv-unanchored-datapoint flex items-center gap-2 text-sm"
978
980
  }, [
979
- n("span", da, y(x.path), 1),
980
- n("span", ca, y(m(x.value)), 1),
981
+ r("span", da, y(x.path), 1),
982
+ r("span", ca, y(f(x.value)), 1),
981
983
  V(ue, { status: "unverifiable" })
982
984
  ]))), 128))
983
985
  ])) : _("", !0)
@@ -986,11 +988,11 @@ const Ht = { class: "tv-comparison-page flex flex-col gap-4" }, Gt = {
986
988
  }), fa = { class: "tv-enable-toggle flex items-center justify-between text-sm font-medium text-gray-700" }, pa = { class: "tv-progress-block" }, ma = { class: "mb-1 flex items-baseline justify-between" }, ga = { class: "tv-progress-count text-xs font-semibold text-gray-600" }, wa = /* @__PURE__ */ K({
987
989
  __name: "VerificationChrome",
988
990
  setup(e) {
989
- const t = le(), { enabled: a, openComparison: g } = t, d = He(), c = _e(), m = U(!1), s = u(() => Kt(t.data)), b = U(!1);
991
+ const t = le(), { enabled: a, openComparison: g } = t, m = He(), s = _e(), f = U(!1), n = d(() => Kt(t.data)), b = U(!1);
990
992
  ce(
991
- () => s.value.percent,
993
+ () => n.value.percent,
992
994
  (k) => {
993
- k === 100 && s.value.total > 0 && !b.value && (b.value = !0, c.success("All data points verified 🎯"));
995
+ k === 100 && n.value.total > 0 && !b.value && (b.value = !0, s.success("All data points verified 🎯"));
994
996
  }
995
997
  );
996
998
  let $ = 0;
@@ -1010,88 +1012,88 @@ const Ht = { class: "tv-comparison-page flex flex-col gap-4" }, Gt = {
1010
1012
  );
1011
1013
  }
1012
1014
  function x() {
1013
- g(), m.value = !1;
1015
+ g(), f.value = !1;
1014
1016
  }
1015
- return (k, S) => (l(), i(L, null, [
1016
- n("button", {
1017
+ return (k, S) => (l(), o(L, null, [
1018
+ r("button", {
1017
1019
  type: "button",
1018
- class: A(["tv-settings-button fixed bottom-4 right-4 z-50 flex h-11 w-11 items-center justify-center rounded-full bg-gray-900 text-white shadow-lg transition-transform hover:scale-105", r(P)]),
1020
+ class: A(["tv-settings-button fixed bottom-4 right-4 z-50 flex h-11 w-11 items-center justify-center rounded-full bg-gray-900 text-white shadow-lg transition-transform hover:scale-105", i(P)]),
1019
1021
  title: "Verification",
1020
- onClick: S[0] || (S[0] = (R) => m.value = !m.value)
1022
+ onClick: S[0] || (S[0] = (R) => f.value = !f.value)
1021
1023
  }, [
1022
- V(r(Me), {
1023
- icon: r(Be),
1024
+ V(i(Me), {
1025
+ icon: i(Be),
1024
1026
  class: "h-5 w-5"
1025
1027
  }, null, 8, ["icon"]),
1026
- r(a) && s.value.needsReview > 0 ? (l(), N(r(Fe), {
1028
+ i(a) && n.value.needsReview > 0 ? (l(), N(i(Fe), {
1027
1029
  key: 0,
1028
- value: s.value.needsReview,
1030
+ value: n.value.needsReview,
1029
1031
  variant: "warning",
1030
1032
  class: "tv-needs-review-badge absolute -right-1 -top-1"
1031
1033
  }, null, 8, ["value"])) : _("", !0)
1032
1034
  ], 2),
1033
- m.value ? (l(), i("div", {
1035
+ f.value ? (l(), o("div", {
1034
1036
  key: 0,
1035
- class: A(["tv-settings-panel fixed bottom-20 right-4 z-50 flex w-72 flex-col gap-4 rounded-xl bg-white p-4 shadow-2xl ring-1 ring-gray-200", r(P)])
1037
+ class: A(["tv-settings-panel fixed bottom-20 right-4 z-50 flex w-72 flex-col gap-4 rounded-xl bg-white p-4 shadow-2xl ring-1 ring-gray-200", i(P)])
1036
1038
  }, [
1037
- n("label", fa, [
1038
- S[3] || (S[3] = n("span", null, "Verification overlay", -1)),
1039
- Ae(n("input", {
1039
+ r("label", fa, [
1040
+ S[3] || (S[3] = r("span", null, "Verification overlay", -1)),
1041
+ Ae(r("input", {
1040
1042
  "onUpdate:modelValue": S[1] || (S[1] = (R) => ge(a) ? a.value = R : null),
1041
1043
  type: "checkbox",
1042
1044
  class: "tv-enable-checkbox h-4 w-4 accent-gray-900"
1043
1045
  }, null, 512), [
1044
- [Re, r(a)]
1046
+ [Re, i(a)]
1045
1047
  ])
1046
1048
  ]),
1047
- r(a) && s.value.total > 0 ? (l(), i(L, { key: 0 }, [
1048
- n("div", pa, [
1049
- n("div", ma, [
1050
- S[4] || (S[4] = n("span", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, "Review progress", -1)),
1051
- n("span", ga, y(s.value.verified) + " / " + y(s.value.total), 1)
1049
+ i(a) && n.value.total > 0 ? (l(), o(L, { key: 0 }, [
1050
+ r("div", pa, [
1051
+ r("div", ma, [
1052
+ S[4] || (S[4] = r("span", { class: "text-[11px] font-semibold uppercase tracking-wider text-gray-400" }, "Review progress", -1)),
1053
+ r("span", ga, y(n.value.verified) + " / " + y(n.value.total), 1)
1052
1054
  ]),
1053
- V(r(we), {
1054
- value: s.value.verified,
1055
- max: s.value.total,
1055
+ V(i(we), {
1056
+ value: n.value.verified,
1057
+ max: n.value.total,
1056
1058
  size: "md",
1057
- variant: s.value.percent === 100 ? "success" : "info",
1058
- striped: s.value.percent < 100,
1059
- "animate-stripes": s.value.percent < 100,
1060
- glow: s.value.percent === 100,
1059
+ variant: n.value.percent === 100 ? "success" : "info",
1060
+ striped: n.value.percent < 100,
1061
+ "animate-stripes": n.value.percent < 100,
1062
+ glow: n.value.percent === 100,
1061
1063
  gradient: ""
1062
1064
  }, null, 8, ["value", "max", "variant", "striped", "animate-stripes", "glow"])
1063
1065
  ]),
1064
- s.value.needsReview > 0 ? (l(), i("button", {
1066
+ n.value.needsReview > 0 ? (l(), o("button", {
1065
1067
  key: 0,
1066
1068
  type: "button",
1067
- class: A(["tv-next-flagged flex items-center justify-between rounded-lg bg-amber-50 px-3 py-2 text-left text-xs font-medium text-amber-700 ring-1 ring-inset ring-amber-600/20 transition hover:bg-amber-100", r(P)]),
1069
+ class: A(["tv-next-flagged flex items-center justify-between rounded-lg bg-amber-50 px-3 py-2 text-left text-xs font-medium text-amber-700 ring-1 ring-inset ring-amber-600/20 transition hover:bg-amber-100", i(P)]),
1068
1070
  onClick: h
1069
1071
  }, [
1070
- n("span", null, y(s.value.needsReview) + " need" + y(s.value.needsReview === 1 ? "s" : "") + " review", 1),
1071
- S[5] || (S[5] = n("span", { "aria-hidden": "true" }, "→", -1))
1072
+ r("span", null, y(n.value.needsReview) + " need" + y(n.value.needsReview === 1 ? "s" : "") + " review", 1),
1073
+ S[5] || (S[5] = r("span", { "aria-hidden": "true" }, "→", -1))
1072
1074
  ], 2)) : _("", !0)
1073
1075
  ], 64)) : _("", !0),
1074
- n("button", {
1076
+ r("button", {
1075
1077
  type: "button",
1076
- class: A(["tv-open-comparison rounded-lg border border-gray-200 px-3 py-2 text-sm font-medium text-gray-600 transition hover:bg-gray-50", r(P)]),
1078
+ class: A(["tv-open-comparison rounded-lg border border-gray-200 px-3 py-2 text-sm font-medium text-gray-600 transition hover:bg-gray-50", i(P)]),
1077
1079
  onClick: x
1078
1080
  }, " Open comparison page ", 2)
1079
1081
  ], 2)) : _("", !0),
1080
- V(r(re), {
1081
- modelValue: r(d),
1082
- "onUpdate:modelValue": S[2] || (S[2] = (R) => ge(d) ? d.value = R : null),
1082
+ V(i(re), {
1083
+ modelValue: i(m),
1084
+ "onUpdate:modelValue": S[2] || (S[2] = (R) => ge(m) ? m.value = R : null),
1083
1085
  title: "Verification comparison",
1084
1086
  width: 80,
1085
1087
  "close-x": "",
1086
- class: A(r(P))
1088
+ class: A(i(P))
1087
1089
  }, {
1088
1090
  default: I(() => [
1089
1091
  V(va)
1090
1092
  ]),
1091
1093
  _: 1
1092
1094
  }, 8, ["modelValue", "class"]),
1093
- V(r(qe), {
1094
- class: A(r(P))
1095
+ V(i(qe), {
1096
+ class: A(i(P))
1095
1097
  }, null, 8, ["class"])
1096
1098
  ], 64));
1097
1099
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thehammer/template-verification",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Read-write verification overlay for rendered template apps — per-data-point confidence, discrepancy, 3-source resolution (override > extracted > claim), inline edit, and a recursive comparison page. Consumes the host's __meta sidecar; fetches nothing.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,7 +25,9 @@
25
25
  "engines": {
26
26
  "node": ">=18"
27
27
  },
28
- "sideEffects": false,
28
+ "sideEffects": [
29
+ "**/*.css"
30
+ ],
29
31
  "scripts": {
30
32
  "build": "vite build && vue-tsc --declaration --emitDeclarationOnly -p tsconfig.build.json",
31
33
  "test": "vitest run",