@kontourai/survey 7.0.0 → 8.1.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.
Files changed (40) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +2 -1
  3. package/dist/src/calibration.d.ts +15 -0
  4. package/dist/src/calibration.js +11 -0
  5. package/dist/src/canonical-reviewed-trust-input.d.ts +10 -0
  6. package/dist/src/canonical-reviewed-trust-input.js +15 -0
  7. package/dist/src/console/review-console-server.d.ts +20 -0
  8. package/dist/src/console/review-console-server.js +75 -4
  9. package/dist/src/decision-carry-forward.d.ts +157 -0
  10. package/dist/src/decision-carry-forward.js +295 -0
  11. package/dist/src/extraction-envelope.d.ts +4 -3
  12. package/dist/src/extraction-envelope.js +3 -3
  13. package/dist/src/field-states.d.ts +100 -0
  14. package/dist/src/field-states.js +169 -0
  15. package/dist/src/index.d.ts +3 -1
  16. package/dist/src/index.js +2 -0
  17. package/dist/src/mcp/review-mcp.js +44 -13
  18. package/dist/src/review-resource.d.ts +29 -0
  19. package/dist/src/review-session-file.d.ts +6 -0
  20. package/dist/src/review-session-file.js +2 -0
  21. package/dist/src/review-workbench/audit-sample.d.ts +32 -0
  22. package/dist/src/review-workbench/audit-sample.js +53 -0
  23. package/dist/src/review-workbench/extraction-inspector.d.ts +1 -1
  24. package/dist/src/review-workbench/extraction-inspector.js +1 -1
  25. package/dist/src/review-workbench/field-state-view.d.ts +15 -0
  26. package/dist/src/review-workbench/field-state-view.js +84 -0
  27. package/dist/src/review-workbench/review-queue-session.d.ts +46 -1
  28. package/dist/src/review-workbench/review-queue-session.js +74 -3
  29. package/dist/src/review-workbench/review-session-replay.d.ts +1 -1
  30. package/dist/src/review-workbench/review-session-replay.js +15 -1
  31. package/dist/src/review-workbench/review-workbench-css.generated.d.ts +9 -0
  32. package/dist/src/review-workbench/review-workbench-css.generated.js +453 -43
  33. package/dist/src/review-workbench/review-workbench-element.js +68 -212
  34. package/dist/src/review-workbench/review-workbench.css +386 -42
  35. package/dist/src/review-workbench/review-workbench.d.ts +13 -1
  36. package/dist/src/review-workbench/review-workbench.js +41 -15
  37. package/dist/src/review-workbench/review-workbench.standalone.css +37 -23
  38. package/dist/src/review-workbench/vendor/kontourai-ui/tokens/themes.css +189 -10
  39. package/dist/src/review-workbench/vendor/kontourai-ui/tokens/tokens.css +156 -5
  40. package/package.json +13 -8
@@ -34,56 +34,13 @@
34
34
  */
35
35
  import { mountReviewWorkbench, } from "./review-workbench.js";
36
36
  import { buildExtractionInspectorModel, mountExtractionInspector, } from "./extraction-inspector.js";
37
- import { REVIEW_WORKBENCH_CSS } from "./review-workbench-css.generated.js";
38
- /** @internal Second adopted stylesheet: host token defaults + inheritance delegation.
39
- *
40
- * This sheet is adopted AFTER the main workbench CSS (adoptedStyleSheets[1]).
41
- * It serves two purposes:
42
- *
43
- * 1. :host literal defaults — non-self-referential literal values for all --k-* tokens.
44
- * These provide a baseline when the host page does not load Console Kit.
45
- * Because they are literal (not var()), there is no self-reference cycle.
46
- * Inline styles on the host element always win over :host rules, so setting
47
- * `--k-brand: hotpink` on the element naturally overrides the #5ce0c6 default.
48
- *
49
- * 2. .survey-workbench-embed[class] inherit delegation — using specificity (0,2,0)
50
- * to match the theme class selectors (e.g. .survey-workbench-embed.theme-survey).
51
- * Source order (after the workbench sheet) makes these inherit rules win, so the
52
- * embed's tokens propagate upward to :host, picking up any host overrides.
53
- */
54
- const TOKEN_INHERIT_CSS = `/* 1. Host token defaults — literal values, not var() self-references.
55
- Inline styles on the host element always win over :host rules so external
56
- overrides (e.g. style="--k-brand: hotpink") propagate through automatically. */
57
- :host {
58
- display: block;
59
- container-type: inline-size;
60
- --k-bg: #060a10;
61
- --k-panel: #101822;
62
- --k-panel-raised: #161e2b;
63
- --k-text: #e8eaf0;
64
- --k-text-muted: #8b93a8;
65
- --k-text-faint: #4e5870;
66
- --k-line: rgba(255,255,255,0.08);
67
- --k-line-strong: rgba(255,255,255,0.14);
68
- --k-brand: #5ce0c6;
69
- --k-brand-contrast: #06080b;
70
- --k-active: #7aa2ff;
71
- --k-positive: #34d399;
72
- --k-caution: #f3b14b;
73
- --k-negative: #ff6f6f;
74
- --k-neutral: #8b93a8;
75
- --k-positive-soft: rgba(52,211,153,0.14);
76
- --k-caution-soft: rgba(243,177,75,0.14);
77
- --k-negative-soft: rgba(255,111,111,0.14);
78
- --k-active-soft: rgba(122,162,255,0.14);
79
- --k-radius-md: 10px;
80
- --k-radius-sm: 6px;
81
- --k-shadow: 0 26px 60px -42px rgba(0, 0, 0, 0.95);
82
- --k-font-ui: "Hanken Grotesk", system-ui, sans-serif;
83
- /* Field-diff card aliases (Theming section of docs/consumer-integration-guide.md).
84
- Derived from the tokens above by default; a host may override any of these
85
- directly for finer control without touching the base token it derives from. */
86
- --k-muted: var(--k-text-muted);
37
+ import { REVIEW_WORKBENCH_CSS, REVIEW_WORKBENCH_DARK_TOKEN_DECLARATIONS, REVIEW_WORKBENCH_LIGHT_TOKEN_DECLARATIONS, REVIEW_WORKBENCH_THEME_TOKEN_DECLARATIONS, } from "./review-workbench-css.generated.js";
38
+ /** @internal Field-diff card aliases (Theming section of
39
+ * docs/consumer-integration-guide.md), derived from the base tokens. Declared
40
+ * on :host only: a var() alias resolves on the element that declares it, and
41
+ * every mode and preset below also lands on :host, so the aliases always see
42
+ * the final base values there and the embed inherits the result. */
43
+ const DERIVED_TOKEN_DECLARATIONS = ` --k-muted: var(--k-text-muted);
87
44
  --k-faint: var(--k-text-faint);
88
45
  --k-raised: var(--k-panel-raised);
89
46
  --k-sunken: color-mix(in srgb, var(--k-bg) 55%, var(--k-panel) 45%);
@@ -92,73 +49,53 @@ const TOKEN_INHERIT_CSS = `/* 1. Host token defaults — literal values, not var
92
49
  --k-positive-wash: var(--k-positive-soft);
93
50
  --k-caution-wash: var(--k-caution-soft);
94
51
  --k-negative-wash: var(--k-negative-soft);
95
- --k-radius: var(--k-radius-md);
52
+ --k-radius: var(--k-radius-md);`;
53
+ /** @internal Token names the embed root inherits from :host: every base token
54
+ * :host always declares, plus the derived aliases. */
55
+ const INHERITED_TOKEN_NAMES = [
56
+ ...`${REVIEW_WORKBENCH_DARK_TOKEN_DECLARATIONS}\n${DERIVED_TOKEN_DECLARATIONS}`.matchAll(/^\s*(--k-[\w-]+)\s*:/gm),
57
+ ].map((match) => match[1]);
58
+ /** @internal Preset selectors per theme. A missing `theme` attribute renders as
59
+ * "survey" (see #applyThemeClasses), so it takes the survey preset too. */
60
+ function presetHostRules(theme, declarations) {
61
+ const dark = theme === "survey" ? `:host(:not([theme])), :host([theme="survey"])` : `:host([theme="${theme}"])`;
62
+ const light = theme === "survey"
63
+ ? `:host(:not([theme])[color-scheme="light"]), :host([theme="survey"][color-scheme="light"])`
64
+ : `:host([theme="${theme}"][color-scheme="light"])`;
65
+ return `${dark} {\n${declarations.dark}\n}\n${light} {\n${declarations.light}\n}`;
96
66
  }
97
- /* 2. Token inheritance delegation — re-delegate --k-* tokens on the embed root
98
- to inherit from :host, so external overrides set on the host element propagate
99
- through the shadow boundary. The [class] attribute selector raises specificity
100
- to (0,2,0) — matching the theme class selectors — and this sheet comes AFTER
101
- the workbench defaults, so source order makes these rules win. Every token the
102
- workbench CSS reads is listed here so a host can override ANY of them (the full
103
- --k-* set, not just a fixed subset) without forking styles or picking a preset. */
104
- .survey-workbench-embed[class] {
105
- --k-bg: inherit;
106
- --k-panel: inherit;
107
- --k-panel-raised: inherit;
108
- --k-text: inherit;
109
- --k-text-muted: inherit;
110
- --k-text-faint: inherit;
111
- --k-line: inherit;
112
- --k-line-strong: inherit;
113
- --k-brand: inherit;
114
- --k-brand-contrast: inherit;
115
- --k-active: inherit;
116
- --k-positive: inherit;
117
- --k-caution: inherit;
118
- --k-negative: inherit;
119
- --k-neutral: inherit;
120
- --k-positive-soft: inherit;
121
- --k-caution-soft: inherit;
122
- --k-negative-soft: inherit;
123
- --k-active-soft: inherit;
124
- --k-radius-md: inherit;
125
- --k-radius-sm: inherit;
126
- --k-shadow: inherit;
127
- --k-font-ui: inherit;
128
- --k-font-mono: inherit;
129
- --k-font-display: inherit;
130
- --k-muted: inherit;
131
- --k-faint: inherit;
132
- --k-raised: inherit;
133
- --k-sunken: inherit;
134
- --k-brand-ink: inherit;
135
- --k-brand-wash: inherit;
136
- --k-positive-wash: inherit;
137
- --k-caution-wash: inherit;
138
- --k-negative-wash: inherit;
139
- --k-radius: inherit;
67
+ /** @internal Token sheet: every --k-* value the workbench reads is decided on
68
+ * :host, and the embed root only inherits it.
69
+ *
70
+ * Adopted AFTER the main workbench CSS (adoptedStyleSheets[1]); appended after it
71
+ * as a <style> where adoptedStyleSheets is unavailable.
72
+ *
73
+ * 1. :host carries the defaults, the light mode and the preset values, all as
74
+ * literals from @kontourai/ui (emitted by the CSS generator; never
75
+ * `var(--k-x, …)`, which would be a self-reference cycle). A declaration from
76
+ * the host document — the element's inline style, or any page rule targeting
77
+ * the element — beats every :host rule, whatever its specificity, so a host
78
+ * override of a base token or an alias wins in both modes and every preset.
79
+ * Values set on an ancestor of the element do not: the :host declaration
80
+ * beats inheritance.
81
+ * 2. The embed root inherits those tokens from :host. The generated sheet also
82
+ * sets them on the embed (its scoped :root, [data-theme="light"] and
83
+ * [data-theme="light"].theme-* rules, up to (0,3,0)); `:host >` plus the
84
+ * doubled [class] lifts this rule to (0,4,0) so it wins regardless of order.
85
+ */
86
+ const TOKEN_INHERIT_CSS = `:host {
87
+ display: block;
88
+ container-type: inline-size;
89
+ ${REVIEW_WORKBENCH_DARK_TOKEN_DECLARATIONS}
90
+ ${DERIVED_TOKEN_DECLARATIONS}
140
91
  }
141
- /* 3. Light mode token overrides — applied when color-scheme="light" sets data-theme="light"
142
- on the embed root. These are literal values (not var()) to avoid self-reference cycles.
143
- The [data-theme="light"] selector has specificity (0,1,0) which is overridden by the
144
- .survey-workbench-embed[class] inheritance block above for the embed container,
145
- but the override chain means host-level --k-* tokens still win. */
146
- .survey-workbench-embed[data-theme="light"] {
92
+ :host([color-scheme="light"]) {
147
93
  color-scheme: light;
148
- --k-bg: #f5f4ef;
149
- --k-panel: #ffffff;
150
- --k-panel-raised: #fbfaf7;
151
- --k-line: rgba(36, 40, 46, 0.12);
152
- --k-line-strong: rgba(36, 40, 46, 0.20);
153
- --k-text: #202124;
154
- --k-text-muted: #5b626b;
155
- --k-text-faint: #707782;
156
- --k-brand: #16806f;
157
- --k-brand-contrast: #ffffff;
158
- --k-positive: #168257;
159
- --k-caution: #8a5a00;
160
- --k-negative: #c83b3b;
161
- --k-active: #3f6fd6;
94
+ ${REVIEW_WORKBENCH_LIGHT_TOKEN_DECLARATIONS}
95
+ }
96
+ ${Object.entries(REVIEW_WORKBENCH_THEME_TOKEN_DECLARATIONS).map(([theme, declarations]) => presetHostRules(theme, declarations)).join("\n")}
97
+ :host > .survey-workbench-embed[class][class] {
98
+ ${INHERITED_TOKEN_NAMES.map((name) => ` ${name}: inherit;`).join("\n")}
162
99
  }`;
163
100
  /** The four built-in theme presets from vendor kontourai-ui/tokens/themes.css. Any
164
101
  * other `theme` attribute value (including the documented `"custom"`) opts out of
@@ -182,110 +119,32 @@ export class SurveyReviewWorkbenchElement extends HTMLElement {
182
119
  // `import "@kontourai/survey/review-workbench/element"` is all that's needed.
183
120
  const sheet = this.#adoptCss();
184
121
  if (!sheet) {
185
- const styleEl = document.createElement("style");
186
- styleEl.textContent = REVIEW_WORKBENCH_CSS;
187
- this.#root.appendChild(styleEl);
122
+ // No adoptedStyleSheets: the same two sheets, in the same order, as <style>.
123
+ for (const css of [REVIEW_WORKBENCH_CSS, TOKEN_INHERIT_CSS]) {
124
+ const styleEl = document.createElement("style");
125
+ styleEl.textContent = css;
126
+ this.#root.appendChild(styleEl);
127
+ }
188
128
  }
189
- // Fallback <style> element for browsers that do not support adoptedStyleSheets.
190
- // When adoptedStyleSheets are available, TOKEN_INHERIT_CSS (the second adopted
191
- // sheet) handles :host defaults and embed token delegation — and wins over this
192
- // <style> element in the cascade. This <style> is only active in the fallback
193
- // path, so using literal values here is safe: there is no self-reference cycle.
194
- const hostStyle = document.createElement("style");
195
- hostStyle.textContent = `
196
- :host {
197
- display: block;
198
- container-type: inline-size;
199
- /* Literal token defaults (no var() self-references) so the values resolve
200
- correctly even when the adopted inheritance sheet is unavailable. */
201
- --k-bg: #060a10;
202
- --k-panel: #101822;
203
- --k-panel-raised: #161e2b;
204
- --k-text: #e8eaf0;
205
- --k-text-muted: #8b93a8;
206
- --k-text-faint: #4e5870;
207
- --k-line: rgba(255,255,255,0.08);
208
- --k-line-strong: rgba(255,255,255,0.14);
209
- --k-brand: #5ce0c6;
210
- --k-brand-contrast: #06080b;
211
- --k-active: #7aa2ff;
212
- --k-positive: #34d399;
213
- --k-caution: #f3b14b;
214
- --k-negative: #ff6f6f;
215
- --k-positive-soft: rgba(52,211,153,0.14);
216
- --k-caution-soft: rgba(243,177,75,0.14);
217
- --k-negative-soft: rgba(255,111,111,0.14);
218
- --k-radius-md: 10px;
219
- --k-radius-sm: 6px;
220
- --k-shadow: 0 26px 60px -42px rgba(0, 0, 0, 0.95);
221
- --k-font-ui: "Hanken Grotesk", system-ui, sans-serif;
222
- --k-muted: var(--k-text-muted);
223
- --k-faint: var(--k-text-faint);
224
- --k-raised: var(--k-panel-raised);
225
- --k-sunken: color-mix(in srgb, var(--k-bg) 55%, var(--k-panel) 45%);
226
- --k-brand-ink: var(--k-brand-contrast);
227
- --k-brand-wash: color-mix(in srgb, var(--k-brand) 14%, transparent);
228
- --k-positive-wash: var(--k-positive-soft);
229
- --k-caution-wash: var(--k-caution-soft);
230
- --k-negative-wash: var(--k-negative-soft);
231
- --k-radius: var(--k-radius-md);
232
- }
129
+ const stateStyle = document.createElement("style");
130
+ stateStyle.textContent = `
233
131
  .workbench-empty, .workbench-error {
234
132
  display: flex;
235
133
  align-items: center;
236
134
  justify-content: center;
237
135
  min-height: 6rem;
238
136
  padding: 1.5rem;
239
- font-family: var(--k-font-ui, system-ui, sans-serif);
137
+ font-family: var(--k-font-ui);
240
138
  font-size: 0.9rem;
241
- color: var(--k-text-muted, #8b93a8);
242
- background: var(--k-panel, #101822);
243
- border-radius: var(--k-radius-md, 10px);
139
+ color: var(--k-text-muted);
140
+ background: var(--k-panel);
141
+ border-radius: var(--k-radius-md);
244
142
  }
245
143
  .workbench-error {
246
- color: var(--k-negative, #ff6f6f);
247
- }
248
- /* Delegate k-tokens from :host to the embed container so host-element inline
249
- style overrides propagate through the shadow boundary. This rule has same
250
- specificity as the workbench CSS token defaults but comes after them in
251
- document order, so it wins and allows inheritance from :host. */
252
- .survey-workbench-embed {
253
- --k-bg: inherit;
254
- --k-panel: inherit;
255
- --k-panel-raised: inherit;
256
- --k-text: inherit;
257
- --k-text-muted: inherit;
258
- --k-text-faint: inherit;
259
- --k-line: inherit;
260
- --k-line-strong: inherit;
261
- --k-brand: inherit;
262
- --k-brand-contrast: inherit;
263
- --k-active: inherit;
264
- --k-positive: inherit;
265
- --k-caution: inherit;
266
- --k-negative: inherit;
267
- --k-positive-soft: inherit;
268
- --k-caution-soft: inherit;
269
- --k-negative-soft: inherit;
270
- --k-radius-md: inherit;
271
- --k-radius-sm: inherit;
272
- --k-shadow: inherit;
273
- --k-font-ui: inherit;
274
- --k-font-mono: inherit;
275
- --k-font-display: inherit;
276
- --k-muted: inherit;
277
- --k-faint: inherit;
278
- --k-raised: inherit;
279
- --k-sunken: inherit;
280
- --k-brand-ink: inherit;
281
- --k-brand-wash: inherit;
282
- --k-positive-wash: inherit;
283
- --k-caution-wash: inherit;
284
- --k-negative-wash: inherit;
285
- --k-radius: inherit;
144
+ color: var(--k-negative);
286
145
  }
287
146
  `;
288
- this.#root.appendChild(hostStyle);
147
+ this.#root.appendChild(stateStyle);
289
148
  this.#mountRoot = document.createElement("div");
290
149
  this.#mountRoot.className = "workbench survey-workbench-embed";
291
150
  this.#root.appendChild(this.#mountRoot);
@@ -462,12 +321,9 @@ export class SurveyReviewWorkbenchElement extends HTMLElement {
462
321
  }
463
322
  /** Attempt to inject the workbench CSS via constructable CSSStyleSheet.
464
323
  *
465
- * Two sheets are adopted: the main workbench CSS first, then a
466
- * token-inheritance sheet that resets all --k-* tokens to `inherit`
467
- * on .survey-workbench-embed. Because later entries in adoptedStyleSheets
468
- * win over earlier ones at equal specificity, the inheritance rules
469
- * override the workbench token defaults. This allows host-element inline
470
- * style overrides (or any ancestor's CSS custom properties) to propagate
324
+ * Two sheets are adopted: the main workbench CSS first, then the token sheet
325
+ * (TOKEN_INHERIT_CSS), which decides every --k-* token on :host and makes the
326
+ * embed root inherit it, so host-document overrides on the element propagate
471
327
  * through the shadow boundary.
472
328
  */
473
329
  #adoptCss() {