uidex 0.9.0 → 0.11.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 (45) hide show
  1. package/dist/cli/cli.cjs +4117 -2902
  2. package/dist/cli/cli.cjs.map +1 -1
  3. package/dist/headless/index.cjs +3 -0
  4. package/dist/headless/index.cjs.map +1 -1
  5. package/dist/headless/index.d.cts +55 -16
  6. package/dist/headless/index.d.ts +55 -16
  7. package/dist/headless/index.js +3 -0
  8. package/dist/headless/index.js.map +1 -1
  9. package/dist/index.cjs +7 -1
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +55 -16
  12. package/dist/index.d.ts +55 -16
  13. package/dist/index.js +7 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/playwright/index.cjs +40 -7
  16. package/dist/playwright/index.cjs.map +1 -1
  17. package/dist/playwright/index.d.cts +15 -1
  18. package/dist/playwright/index.d.ts +15 -1
  19. package/dist/playwright/index.js +39 -7
  20. package/dist/playwright/index.js.map +1 -1
  21. package/dist/playwright/states-reporter.cjs +36 -7
  22. package/dist/playwright/states-reporter.cjs.map +1 -1
  23. package/dist/playwright/states-reporter.d.cts +15 -0
  24. package/dist/playwright/states-reporter.d.ts +15 -0
  25. package/dist/playwright/states-reporter.js +36 -7
  26. package/dist/playwright/states-reporter.js.map +1 -1
  27. package/dist/playwright/states.cjs +8 -0
  28. package/dist/playwright/states.cjs.map +1 -1
  29. package/dist/playwright/states.d.cts +44 -1
  30. package/dist/playwright/states.d.ts +44 -1
  31. package/dist/playwright/states.js +7 -0
  32. package/dist/playwright/states.js.map +1 -1
  33. package/dist/react/index.cjs +7 -1
  34. package/dist/react/index.cjs.map +1 -1
  35. package/dist/react/index.d.cts +55 -16
  36. package/dist/react/index.d.ts +55 -16
  37. package/dist/react/index.js +7 -1
  38. package/dist/react/index.js.map +1 -1
  39. package/dist/scan/index.cjs +1533 -294
  40. package/dist/scan/index.cjs.map +1 -1
  41. package/dist/scan/index.d.cts +459 -112
  42. package/dist/scan/index.d.ts +459 -112
  43. package/dist/scan/index.js +1517 -290
  44. package/dist/scan/index.js.map +1 -1
  45. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -17,8 +17,8 @@ interface EntityRef {
17
17
  /**
18
18
  * The four kinds every captured route is expected to render — the state-matrix
19
19
  * axis. A capture that only shoots the happy path leaves most of the value on
20
- * the table, so a missing core kind must be captured, waived (the page CANNOT
21
- * render it), or acknowledged in the MISSING_KINDS baseline.
20
+ * the table, so a missing core kind must be captured or ACKNOWLEDGED (see
21
+ * `Metadata.acknowledge`).
22
22
  */
23
23
  declare const CORE_STATE_KINDS: readonly ["loading", "empty", "populated", "error"];
24
24
  type CoreStateKind = (typeof CORE_STATE_KINDS)[number];
@@ -36,34 +36,60 @@ interface StateDecl {
36
36
  name: string;
37
37
  /** Canonical kind for the state-matrix axis (defaults to `variant`). */
38
38
  kind?: StateKind;
39
- /** Acceptance criteria that only this state can evidence. */
40
- acceptance?: string[];
39
+ /**
40
+ * Acceptance criteria that only this state can evidence. Normalized into the
41
+ * same `{ id, rev, text }` regime as entity-level `acceptance` (one
42
+ * criterion-id namespace per entity), so per-state criteria are claimable by
43
+ * `uidexCovers` and visible to every acceptance gate.
44
+ */
45
+ acceptance?: AcceptanceCriterion[];
41
46
  description?: string;
42
47
  }
48
+ /**
49
+ * A normalized acceptance criterion. Authored either as a bare string (sugar:
50
+ * `id` is a deterministic kebab slug of the text, `rev` is 1) or as an object
51
+ * `{ id, rev?, text }`; parse-time normalization means everything downstream —
52
+ * audit, scaffold, the devtools — always sees this object shape. `rev` is the
53
+ * pin flows cover against (`uidexCovers("entity", "id@rev")`): bumping it when
54
+ * the criterion's meaning changes is what makes outdated-coverage detectable.
55
+ */
56
+ interface AcceptanceCriterion {
57
+ id: string;
58
+ rev: number;
59
+ text: string;
60
+ }
43
61
  interface Metadata {
44
62
  name?: string;
45
63
  description?: string;
46
- acceptance?: string[];
64
+ acceptance?: AcceptanceCriterion[];
47
65
  notes?: string;
48
66
  composes?: EntityRef[];
49
67
  flows?: readonly string[];
50
68
  features?: string[];
51
69
  widgets?: string[];
70
+ /** Page ids a feature declares it must be mounted on (feature kind only). */
71
+ surfaces?: string[];
52
72
  /** Declared render states (see StateDecl); the capture-completeness gate. */
53
73
  states?: StateDecl[];
54
74
  /**
55
- * `false` opts this page/feature/widget out of visual-states capture forever
56
- * (a redirect, a static notice, an internal target). The page-coverage gate
57
- * treats an opted-out route as accounted-for. Reason belongs in `description`.
75
+ * The ONE way to say "don't complain about this gap": scope typed reason.
76
+ *
77
+ * - scope `"*"` covers the whole entity (a redirect page that can never be
78
+ * captured, a component whose states are not gated here);
79
+ * - a core-kind scope covers that one cell of this page's route matrix.
80
+ *
81
+ * `type: "impossible"` is a permanent design statement and needs a `reason`;
82
+ * `type: "backlog"` is debt and does not. Keeping both as values of one field
83
+ * is what makes mislabeling debt as impossible a visible, reviewable edit.
84
+ * `captured-elsewhere` is computed by the workspace and never authored here.
58
85
  */
59
- capture?: boolean;
60
- /**
61
- * Per-core-kind waivers: a core kind this page's route legitimately CANNOT
62
- * render (a create form has no `empty`), mapped to a substantive reason. The
63
- * state-matrix gate treats a waived kind as accounted-for. A waiver is a
64
- * permanent design statement — unlike MISSING_KINDS backlog, which is debt.
65
- */
66
- waivers?: Partial<Record<CoreStateKind, string>>;
86
+ acknowledge?: Partial<Record<AcknowledgeScope, MetaAcknowledgment>>;
87
+ }
88
+ /** Scope of an acknowledgment: one core kind, or the whole entity. */
89
+ type AcknowledgeScope = CoreStateKind | "*";
90
+ interface MetaAcknowledgment {
91
+ type: "impossible" | "backlog";
92
+ reason?: string;
67
93
  }
68
94
  interface EntityWithMetaBase {
69
95
  id: string;
@@ -80,12 +106,25 @@ interface FlowStep {
80
106
  entityId: string;
81
107
  action?: string;
82
108
  }
109
+ /**
110
+ * A per-criterion coverage claim a flow makes via
111
+ * `uidexCovers("<entityId>", "<criterionId>@<rev>")`. The rev is REQUIRED at
112
+ * the claim site — a rev-less claim could never go stale, which would defeat
113
+ * the outdated-detection the pin exists for.
114
+ */
115
+ interface FlowCover {
116
+ entity: string;
117
+ criterion: string;
118
+ rev: number;
119
+ }
83
120
  interface Flow {
84
121
  kind: "flow";
85
122
  id: string;
86
123
  loc: Location;
87
124
  touches: string[];
88
125
  steps: FlowStep[];
126
+ /** Acceptance-criterion coverage claims made inside this flow's describe. */
127
+ covers?: FlowCover[];
89
128
  }
90
129
  interface Page extends EntityWithMetaBase {
91
130
  kind: "page";
package/dist/index.d.ts CHANGED
@@ -17,8 +17,8 @@ interface EntityRef {
17
17
  /**
18
18
  * The four kinds every captured route is expected to render — the state-matrix
19
19
  * axis. A capture that only shoots the happy path leaves most of the value on
20
- * the table, so a missing core kind must be captured, waived (the page CANNOT
21
- * render it), or acknowledged in the MISSING_KINDS baseline.
20
+ * the table, so a missing core kind must be captured or ACKNOWLEDGED (see
21
+ * `Metadata.acknowledge`).
22
22
  */
23
23
  declare const CORE_STATE_KINDS: readonly ["loading", "empty", "populated", "error"];
24
24
  type CoreStateKind = (typeof CORE_STATE_KINDS)[number];
@@ -36,34 +36,60 @@ interface StateDecl {
36
36
  name: string;
37
37
  /** Canonical kind for the state-matrix axis (defaults to `variant`). */
38
38
  kind?: StateKind;
39
- /** Acceptance criteria that only this state can evidence. */
40
- acceptance?: string[];
39
+ /**
40
+ * Acceptance criteria that only this state can evidence. Normalized into the
41
+ * same `{ id, rev, text }` regime as entity-level `acceptance` (one
42
+ * criterion-id namespace per entity), so per-state criteria are claimable by
43
+ * `uidexCovers` and visible to every acceptance gate.
44
+ */
45
+ acceptance?: AcceptanceCriterion[];
41
46
  description?: string;
42
47
  }
48
+ /**
49
+ * A normalized acceptance criterion. Authored either as a bare string (sugar:
50
+ * `id` is a deterministic kebab slug of the text, `rev` is 1) or as an object
51
+ * `{ id, rev?, text }`; parse-time normalization means everything downstream —
52
+ * audit, scaffold, the devtools — always sees this object shape. `rev` is the
53
+ * pin flows cover against (`uidexCovers("entity", "id@rev")`): bumping it when
54
+ * the criterion's meaning changes is what makes outdated-coverage detectable.
55
+ */
56
+ interface AcceptanceCriterion {
57
+ id: string;
58
+ rev: number;
59
+ text: string;
60
+ }
43
61
  interface Metadata {
44
62
  name?: string;
45
63
  description?: string;
46
- acceptance?: string[];
64
+ acceptance?: AcceptanceCriterion[];
47
65
  notes?: string;
48
66
  composes?: EntityRef[];
49
67
  flows?: readonly string[];
50
68
  features?: string[];
51
69
  widgets?: string[];
70
+ /** Page ids a feature declares it must be mounted on (feature kind only). */
71
+ surfaces?: string[];
52
72
  /** Declared render states (see StateDecl); the capture-completeness gate. */
53
73
  states?: StateDecl[];
54
74
  /**
55
- * `false` opts this page/feature/widget out of visual-states capture forever
56
- * (a redirect, a static notice, an internal target). The page-coverage gate
57
- * treats an opted-out route as accounted-for. Reason belongs in `description`.
75
+ * The ONE way to say "don't complain about this gap": scope typed reason.
76
+ *
77
+ * - scope `"*"` covers the whole entity (a redirect page that can never be
78
+ * captured, a component whose states are not gated here);
79
+ * - a core-kind scope covers that one cell of this page's route matrix.
80
+ *
81
+ * `type: "impossible"` is a permanent design statement and needs a `reason`;
82
+ * `type: "backlog"` is debt and does not. Keeping both as values of one field
83
+ * is what makes mislabeling debt as impossible a visible, reviewable edit.
84
+ * `captured-elsewhere` is computed by the workspace and never authored here.
58
85
  */
59
- capture?: boolean;
60
- /**
61
- * Per-core-kind waivers: a core kind this page's route legitimately CANNOT
62
- * render (a create form has no `empty`), mapped to a substantive reason. The
63
- * state-matrix gate treats a waived kind as accounted-for. A waiver is a
64
- * permanent design statement — unlike MISSING_KINDS backlog, which is debt.
65
- */
66
- waivers?: Partial<Record<CoreStateKind, string>>;
86
+ acknowledge?: Partial<Record<AcknowledgeScope, MetaAcknowledgment>>;
87
+ }
88
+ /** Scope of an acknowledgment: one core kind, or the whole entity. */
89
+ type AcknowledgeScope = CoreStateKind | "*";
90
+ interface MetaAcknowledgment {
91
+ type: "impossible" | "backlog";
92
+ reason?: string;
67
93
  }
68
94
  interface EntityWithMetaBase {
69
95
  id: string;
@@ -80,12 +106,25 @@ interface FlowStep {
80
106
  entityId: string;
81
107
  action?: string;
82
108
  }
109
+ /**
110
+ * A per-criterion coverage claim a flow makes via
111
+ * `uidexCovers("<entityId>", "<criterionId>@<rev>")`. The rev is REQUIRED at
112
+ * the claim site — a rev-less claim could never go stale, which would defeat
113
+ * the outdated-detection the pin exists for.
114
+ */
115
+ interface FlowCover {
116
+ entity: string;
117
+ criterion: string;
118
+ rev: number;
119
+ }
83
120
  interface Flow {
84
121
  kind: "flow";
85
122
  id: string;
86
123
  loc: Location;
87
124
  touches: string[];
88
125
  steps: FlowStep[];
126
+ /** Acceptance-criterion coverage claims made inside this flow's describe. */
127
+ covers?: FlowCover[];
89
128
  }
90
129
  interface Page extends EntityWithMetaBase {
91
130
  kind: "page";
package/dist/index.js CHANGED
@@ -1018,6 +1018,9 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1018
1018
  .flex-1 {
1019
1019
  flex: 1;
1020
1020
  }
1021
+ .shrink {
1022
+ flex-shrink: 1;
1023
+ }
1021
1024
  .shrink-0 {
1022
1025
  flex-shrink: 0;
1023
1026
  }
@@ -7326,7 +7329,10 @@ function createEntityDetailView(config) {
7326
7329
  sections.push({ id: "description", text: meta.description });
7327
7330
  }
7328
7331
  if (offerAcceptance && meta?.acceptance?.length) {
7329
- sections.push({ id: "acceptance", items: meta.acceptance });
7332
+ sections.push({
7333
+ id: "acceptance",
7334
+ items: meta.acceptance.map((c) => c.text)
7335
+ });
7330
7336
  }
7331
7337
  if (entity) {
7332
7338
  for (const s of config.extraSections?.(ctx, entity) ?? []) {