@contentful/experience-design-system-cli 2.37.1-dev-build-f22bf3b7.0 → 2.37.1-dev-build-0b7e3e1f.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/dist/app.js CHANGED
@@ -9648,8 +9648,8 @@ function extractAccessorProperties(classDecl, applyRuntimeFieldDenylist = false)
9648
9648
  accessors.set(name, entry);
9649
9649
  }
9650
9650
  for (const [name, { getter, setter }] of accessors) {
9651
- const hasPropertyDecorator2 = getter?.getDecorators().some((decorator) => decorator.getName() === "property") || setter?.getDecorators().some((decorator) => decorator.getName() === "property");
9652
- if (!hasPropertyDecorator2 && !(getter && setter))
9651
+ const hasPropertyDecorator = getter?.getDecorators().some((decorator) => decorator.getName() === "property") || setter?.getDecorators().some((decorator) => decorator.getName() === "property");
9652
+ if (!hasPropertyDecorator && !(getter && setter))
9653
9653
  continue;
9654
9654
  const type = getter?.getReturnTypeNode()?.getText() ?? setter?.getParameters()[0]?.getTypeNode()?.getText() ?? "any";
9655
9655
  const accessorNode = getter ?? setter;
@@ -12919,9 +12919,9 @@ function generateUlid(now = Date.now()) {
12919
12919
  tsBytes[i] = n & 255;
12920
12920
  n = Math.floor(n / 256);
12921
12921
  }
12922
- const ts6 = encodeBase32(tsBytes, 10);
12922
+ const ts3 = encodeBase32(tsBytes, 10);
12923
12923
  const rand = encodeBase32(randomBytes2(10), 16);
12924
- return (ts6 + rand).toUpperCase();
12924
+ return (ts3 + rand).toUpperCase();
12925
12925
  }
12926
12926
 
12927
12927
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/runs/repositories/read-runs-file.js
@@ -15335,610 +15335,7 @@ async function runMapTokens(request) {
15335
15335
  import { mkdir as mkdir4 } from "node:fs/promises";
15336
15336
  import { relative as relative2 } from "node:path";
15337
15337
 
15338
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/astro/helpers/collect-astro-props-bindings.js
15339
- import { Node as Node10, Project as Project7 } from "ts-morph";
15340
-
15341
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/shared/helpers/tsx-shared.js
15342
- import { Project as Project8 } from "ts-morph";
15343
-
15344
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/shared/helpers/tsx-node-utils.js
15345
- import { Node as Node12, SyntaxKind as SyntaxKind7 } from "ts-morph";
15346
-
15347
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/shared/helpers/resolve-tsx-workspace-imports.js
15348
- import { Node as Node11 } from "ts-morph";
15349
-
15350
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/shared/helpers/resolve-tsx-tsconfig-path.js
15351
- import ts3 from "typescript";
15352
-
15353
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/shared/helpers/tsx-renderable-exports.js
15354
- import { Node as Node13 } from "ts-morph";
15355
-
15356
- // packages/experience-design-system-extraction/dist/src/extract/helpers/evidence/collect-jsx-component-references.js
15357
- import { Node as Node15, SyntaxKind as SyntaxKind9 } from "ts-morph";
15358
-
15359
- // packages/experience-design-system-extraction/dist/src/extract/helpers/evidence/ast/get-jsx-ast-data.js
15360
- import { Node as Node14 } from "ts-morph";
15361
-
15362
- // packages/experience-design-system-extraction/dist/src/extract/helpers/evidence/ast/collect-structural-jsx-evidence.js
15363
- import { SyntaxKind as SyntaxKind8 } from "ts-morph";
15364
-
15365
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/extract-from-react-source-file.js
15366
- import { SyntaxKind as SyntaxKind14 } from "ts-morph";
15367
-
15368
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/extract-react-component-from-export.js
15369
- import { Node as Node32 } from "ts-morph";
15370
-
15371
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/collect-prop-dataflow.js
15372
- import { Node as Node17, SyntaxKind as SyntaxKind10 } from "ts-morph";
15373
-
15374
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/resolve-component-function.js
15375
- import { Node as Node16 } from "ts-morph";
15376
-
15377
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/extract-react-props-from-type.js
15378
- import { Node as Node24 } from "ts-morph";
15379
-
15380
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/dom-attribute-surfaces.js
15381
- import { Node as Node18 } from "ts-morph";
15382
- function createTextControlSurface2(onChangeType, specificProps) {
15383
- return [
15384
- { name: "autoComplete", type: "string", required: false },
15385
- ...specificProps,
15386
- { name: "disabled", type: "boolean", required: false },
15387
- { name: "name", type: "string", required: false },
15388
- { name: "onChange", type: onChangeType, required: false },
15389
- { name: "placeholder", type: "string", required: false },
15390
- { name: "readOnly", type: "boolean", required: false },
15391
- { name: "required", type: "boolean", required: false },
15392
- {
15393
- name: "value",
15394
- type: "string | number | readonly string[]",
15395
- required: false
15396
- }
15397
- ];
15398
- }
15399
- var DOM_ATTRIBUTE_PROP_SURFACES2 = {
15400
- HTMLProps: [],
15401
- HTMLAttributes: [
15402
- { name: "className", type: "string", required: false },
15403
- { name: "hidden", type: "boolean", required: false },
15404
- { name: "id", type: "string", required: false },
15405
- {
15406
- name: "onClick",
15407
- type: "MouseEventHandler<HTMLElement>",
15408
- required: false
15409
- },
15410
- { name: "style", type: "CSSProperties", required: false },
15411
- { name: "tabIndex", type: "number", required: false },
15412
- { name: "title", type: "string", required: false }
15413
- ],
15414
- ImgHTMLAttributes: [
15415
- { name: "alt", type: "string", required: false },
15416
- { name: "crossOrigin", type: "string", required: false },
15417
- { name: "height", type: "number | string", required: false },
15418
- {
15419
- name: "loading",
15420
- type: "string",
15421
- required: false,
15422
- allowedValues: ["eager", "lazy"]
15423
- },
15424
- { name: "sizes", type: "string", required: false },
15425
- { name: "src", type: "string", required: false },
15426
- { name: "srcSet", type: "string", required: false },
15427
- { name: "width", type: "number | string", required: false }
15428
- ],
15429
- LiHTMLAttributes: [],
15430
- AnchorHTMLAttributes: [
15431
- { name: "download", type: "boolean | string", required: false },
15432
- { name: "href", type: "string", required: false },
15433
- { name: "hrefLang", type: "string", required: false },
15434
- { name: "referrerPolicy", type: "string", required: false },
15435
- { name: "rel", type: "string", required: false },
15436
- {
15437
- name: "target",
15438
- type: "string",
15439
- required: false,
15440
- allowedValues: ["_blank", "_parent", "_self", "_top"]
15441
- }
15442
- ],
15443
- ButtonHTMLAttributes: [
15444
- { name: "autoFocus", type: "boolean", required: false },
15445
- { name: "disabled", type: "boolean", required: false },
15446
- { name: "form", type: "string", required: false },
15447
- { name: "formAction", type: "string", required: false },
15448
- { name: "formMethod", type: "string", required: false },
15449
- { name: "formNoValidate", type: "boolean", required: false },
15450
- { name: "formTarget", type: "string", required: false },
15451
- { name: "name", type: "string", required: false },
15452
- {
15453
- name: "type",
15454
- type: "string",
15455
- required: false,
15456
- allowedValues: ["button", "reset", "submit"]
15457
- },
15458
- {
15459
- name: "value",
15460
- type: "string | number | readonly string[]",
15461
- required: false
15462
- }
15463
- ],
15464
- InputHTMLAttributes: createTextControlSurface2("ChangeEventHandler<HTMLInputElement>", [
15465
- { name: "checked", type: "boolean", required: false },
15466
- { name: "max", type: "number | string", required: false },
15467
- { name: "maxLength", type: "number", required: false },
15468
- { name: "min", type: "number | string", required: false },
15469
- { name: "minLength", type: "number", required: false },
15470
- { name: "type", type: "string", required: false }
15471
- ]),
15472
- FieldsetHTMLAttributes: [
15473
- { name: "disabled", type: "boolean", required: false },
15474
- { name: "form", type: "string", required: false },
15475
- { name: "name", type: "string", required: false }
15476
- ],
15477
- LabelHTMLAttributes: [
15478
- { name: "form", type: "string", required: false },
15479
- { name: "htmlFor", type: "string", required: false }
15480
- ],
15481
- SelectHTMLAttributes: [
15482
- { name: "autoComplete", type: "string", required: false },
15483
- { name: "disabled", type: "boolean", required: false },
15484
- { name: "form", type: "string", required: false },
15485
- { name: "multiple", type: "boolean", required: false },
15486
- { name: "name", type: "string", required: false },
15487
- {
15488
- name: "onChange",
15489
- type: "ChangeEventHandler<HTMLSelectElement>",
15490
- required: false
15491
- },
15492
- { name: "required", type: "boolean", required: false },
15493
- { name: "size", type: "number", required: false },
15494
- {
15495
- name: "value",
15496
- type: "string | number | readonly string[]",
15497
- required: false
15498
- }
15499
- ],
15500
- SVGAttributes: [
15501
- {
15502
- name: "focusable",
15503
- type: 'boolean | "auto"',
15504
- required: false,
15505
- allowedValues: ["auto"]
15506
- },
15507
- { name: "height", type: "number | string", required: false },
15508
- { name: "viewBox", type: "string", required: false },
15509
- { name: "width", type: "number | string", required: false }
15510
- ],
15511
- SVGProps: [],
15512
- TextareaHTMLAttributes: createTextControlSurface2("ChangeEventHandler<HTMLTextAreaElement>", [
15513
- { name: "cols", type: "number", required: false },
15514
- { name: "rows", type: "number", required: false },
15515
- { name: "wrap", type: "string", required: false }
15516
- ]),
15517
- TdHTMLAttributes: [
15518
- {
15519
- name: "align",
15520
- type: "string",
15521
- required: false,
15522
- allowedValues: ["center", "char", "justify", "left", "right"]
15523
- },
15524
- { name: "colSpan", type: "number", required: false },
15525
- { name: "headers", type: "string", required: false },
15526
- { name: "rowSpan", type: "number", required: false },
15527
- { name: "scope", type: "string", required: false }
15528
- ]
15529
- };
15530
-
15531
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/collect-dom-wrapper-contexts.js
15532
- import { Node as Node19 } from "ts-morph";
15533
-
15534
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/detect-dom-is-pure-wrapper.js
15535
- import { Node as Node20 } from "ts-morph";
15536
-
15537
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/detect-omit-wrapped-custom-props.js
15538
- import { Node as Node21 } from "ts-morph";
15539
-
15540
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/detect-pick-type-patterns.js
15541
- import { Node as Node22 } from "ts-morph";
15542
-
15543
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/detect-react-polymorphic.js
15544
- import { Node as Node23 } from "ts-morph";
15545
-
15546
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/resolve-react-props-type.js
15547
- import { Node as Node25 } from "ts-morph";
15548
-
15549
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/extract-react-binding-defaults.js
15550
- import { Node as Node28 } from "ts-morph";
15551
-
15552
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/filter-impl-alias-props.js
15553
- import { Node as Node26 } from "ts-morph";
15554
-
15555
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/extract-binding-fallback-props.js
15556
- import { Node as Node27, SyntaxKind as SyntaxKind11 } from "ts-morph";
15557
-
15558
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/collect-react-impl-hints.js
15559
- import { Node as Node30, SyntaxKind as SyntaxKind13 } from "ts-morph";
15560
-
15561
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/infer-primitive-dom-props.js
15562
- import { Node as Node29, SyntaxKind as SyntaxKind12 } from "ts-morph";
15563
-
15564
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/react/helpers/extract-react-prop-types.js
15565
- import { Node as Node31 } from "ts-morph";
15566
-
15567
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/stencil/extractor.js
15568
- import { Project as Project9, Node as Node37 } from "ts-morph";
15569
-
15570
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/stencil/helpers/detect-stencil-class.js
15571
- import { Node as Node33 } from "ts-morph";
15572
-
15573
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/stencil/helpers/extract-stencil-props.js
15574
- import { Node as Node35 } from "ts-morph";
15575
-
15576
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/stencil/helpers/stencil-prop-helpers.js
15577
- import { Node as Node34, SyntaxKind as SyntaxKind15 } from "ts-morph";
15578
-
15579
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/stencil/helpers/extract-stencil-slots.js
15580
- import { Node as Node36 } from "ts-morph";
15581
-
15582
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-unresolved-retry.js
15583
- import { Project as Project12, ScriptTarget as ScriptTarget4, ModuleKind as ModuleKind4, ts as ts5 } from "ts-morph";
15584
-
15585
- // packages/experience-design-system-extraction/dist/src/extract/services/quality/helpers/scoring/collect-scoring-inputs.js
15586
- var OPAQUE_TYPES2 = /* @__PURE__ */ new Set(["any", "unknown", "object", "Record<string, unknown>", "Record<string, any>"]);
15587
- var OBVIOUS_PROP_NAMES2 = /* @__PURE__ */ new Set([
15588
- "className",
15589
- "style",
15590
- "id",
15591
- "children",
15592
- "disabled",
15593
- "hidden",
15594
- "onClick",
15595
- "onChange",
15596
- "onSubmit",
15597
- "onBlur",
15598
- "onFocus",
15599
- "href",
15600
- "src",
15601
- "alt",
15602
- "type",
15603
- "value",
15604
- "checked",
15605
- "placeholder",
15606
- "label",
15607
- "title",
15608
- "name",
15609
- "required",
15610
- "readOnly",
15611
- "autoFocus",
15612
- "tabIndex",
15613
- "role",
15614
- "aria-label",
15615
- "aria-describedby"
15616
- ]);
15617
- function isWidePrimitiveUnion2(type) {
15618
- const parts = type.split("|").map((p) => p.trim());
15619
- if (parts.length < 3)
15620
- return false;
15621
- const basePrimitives = /* @__PURE__ */ new Set(["string", "number", "boolean"]);
15622
- const nullability = /* @__PURE__ */ new Set(["null", "undefined"]);
15623
- const baseCount = parts.filter((p) => basePrimitives.has(p)).length;
15624
- const nullabilityCount = parts.filter((p) => nullability.has(p)).length;
15625
- return baseCount >= 3 || baseCount >= 2 && nullabilityCount > 0 && baseCount + nullabilityCount >= 3;
15626
- }
15627
- function countExtractionIssues(component, options = {}) {
15628
- let count = 0;
15629
- const reasons = [];
15630
- if (component.props.length === 0 && component.slots.length === 0) {
15631
- count++;
15632
- reasons.push("no-props-or-slots");
15633
- }
15634
- if (component.props.length > 50) {
15635
- count++;
15636
- reasons.push(`high-prop-count:${component.props.length}`);
15637
- }
15638
- for (const prop of component.props) {
15639
- if (OPAQUE_TYPES2.has(prop.type.trim())) {
15640
- count++;
15641
- reasons.push(`opaque-type:${prop.name}`);
15642
- break;
15643
- }
15644
- if (isWidePrimitiveUnion2(prop.type)) {
15645
- count++;
15646
- reasons.push(`wide-union:${prop.name}`);
15647
- break;
15648
- }
15649
- if (!prop.description && !OBVIOUS_PROP_NAMES2.has(prop.name)) {
15650
- count++;
15651
- reasons.push("props-missing-description");
15652
- break;
15653
- }
15654
- }
15655
- count += options.additionalIssueCount ?? 0;
15656
- if (options.additionalReasons && options.additionalReasons.length > 0) {
15657
- reasons.push(...options.additionalReasons);
15658
- }
15659
- return { count, reasons: [...new Set(reasons)] };
15660
- }
15661
- function mapIssueCountToConfidence(count) {
15662
- if (count === 0)
15663
- return 5;
15664
- if (count === 1)
15665
- return 4;
15666
- if (count === 2)
15667
- return 3;
15668
- if (count === 3)
15669
- return 2;
15670
- return 1;
15671
- }
15672
-
15673
- // packages/experience-design-system-extraction/dist/src/extract/services/quality/helpers/scoring/compute-extraction-score.js
15674
- function computeExtractionScore2(component, options = {}) {
15675
- const { count, reasons } = countExtractionIssues(component, options);
15676
- return {
15677
- confidence: mapIssueCountToConfidence(count),
15678
- reasons
15679
- };
15680
- }
15681
- function deriveNeedsReview2(confidence) {
15682
- return confidence <= 2;
15683
- }
15684
-
15685
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-type-checker.js
15686
- import { Project as Project10, ScriptTarget as ScriptTarget2, ModuleKind as ModuleKind2, ts as ts4 } from "ts-morph";
15687
-
15688
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-declaration-data.js
15689
- import { Node as Node38 } from "ts-morph";
15690
-
15691
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-external-type-readers.js
15692
- import { Node as Node40, Project as Project11, ScriptTarget as ScriptTarget3, ModuleKind as ModuleKind3 } from "ts-morph";
15693
-
15694
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-external-type-members.js
15695
- import { Node as Node39 } from "ts-morph";
15696
-
15697
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/svelte/helpers/extract-from-svelte-file.js
15698
- import { parse as parseSvelte2 } from "svelte/compiler";
15699
-
15700
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue-tsx/extractor.js
15701
- import { Node as Node44 } from "ts-morph";
15702
-
15703
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue-tsx/helpers/extract-vue-tsx-props.js
15704
- import { Node as Node42 } from "ts-morph";
15705
-
15706
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue-tsx/helpers/resolve-ast-object.js
15707
- import { Node as Node41, SyntaxKind as SyntaxKind16 } from "ts-morph";
15708
-
15709
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue-tsx/helpers/extract-vue-tsx-slots.js
15710
- import { Node as Node43, SyntaxKind as SyntaxKind17 } from "ts-morph";
15711
-
15712
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue/extractor.js
15713
- import { parse as parseSFC3 } from "@vue/compiler-sfc";
15714
-
15715
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue/helpers/extract-vue-setup-props.js
15716
- import { Project as Project14, Node as Node47 } from "ts-morph";
15717
-
15718
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue/helpers/extract-vue-setup-object-props.js
15719
- import { Project as Project13, Node as Node46 } from "ts-morph";
15720
-
15721
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue/helpers/extract-vue-object-props.js
15722
- import { Node as Node45 } from "ts-morph";
15723
-
15724
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/vue/helpers/extract-vue-options-props.js
15725
- import { parse as parseSFC2 } from "@vue/compiler-sfc";
15726
- import { Node as Node48, Project as Project15 } from "ts-morph";
15727
-
15728
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/extractor.js
15729
- import { Project as Project16 } from "ts-morph";
15730
-
15731
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-observed-attrs.js
15732
- import { Node as Node49 } from "ts-morph";
15733
-
15734
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-class-properties.js
15735
- import { Node as Node50 } from "ts-morph";
15736
-
15737
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-decorator-tag.js
15738
- import { Node as Node51 } from "ts-morph";
15739
-
15740
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-sibling-definition.js
15741
- import { Node as Node54, SyntaxKind as SyntaxKind19 } from "ts-morph";
15742
-
15743
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-import.js
15744
- import { Node as Node53, SyntaxKind as SyntaxKind18 } from "ts-morph";
15745
-
15746
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-import-source.js
15747
- import { Node as Node52 } from "ts-morph";
15748
-
15749
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-template-content.js
15750
- import { Node as Node56 } from "ts-morph";
15751
-
15752
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/collect-wc-html-templates.js
15753
- import { Node as Node55 } from "ts-morph";
15754
-
15755
- // packages/experience-design-system-extraction/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-base-class.js
15756
- import { Node as Node57, SyntaxKind as SyntaxKind20 } from "ts-morph";
15757
-
15758
- // packages/experience-design-system-extraction/dist/src/extract/services/classification/helpers/check-prop-types.js
15759
- function isStringLiteralUnion(type) {
15760
- return type.includes("|") && type.includes("'");
15761
- }
15762
- function isSimpleType(type) {
15763
- const t = type.trim();
15764
- if (t === "string" || t === "boolean" || t === "number")
15765
- return true;
15766
- return isStringLiteralUnion(t);
15767
- }
15768
- function isBooleanType(type) {
15769
- return type.trim() === "boolean";
15770
- }
15771
- function isStringType(type) {
15772
- return type.trim() === "string";
15773
- }
15774
- function isNumberType(type) {
15775
- return type.trim() === "number";
15776
- }
15777
- function isComplexType(type) {
15778
- return !isSimpleType(type);
15779
- }
15780
-
15781
- // packages/experience-design-system-extraction/dist/src/extract/services/classification/helpers/detect-dom-props.js
15782
- var DOM_PASS_THROUGH_PROPS = /* @__PURE__ */ new Set([
15783
- // Bare HTML / framework styling pass-through
15784
- "className",
15785
- "class",
15786
- "classes",
15787
- "classNames",
15788
- "rootClassName",
15789
- "prefixCls",
15790
- "style",
15791
- "styles",
15792
- // Bare HTML attributes
15793
- "id",
15794
- "role",
15795
- "tabIndex",
15796
- "tabindex",
15797
- "htmlFor",
15798
- "for",
15799
- "slot",
15800
- "is",
15801
- "lang",
15802
- "dir",
15803
- "hidden",
15804
- "draggable",
15805
- "spellCheck",
15806
- "spellcheck",
15807
- "contentEditable",
15808
- "contenteditable",
15809
- "inputMode",
15810
- "inputmode",
15811
- "autoComplete",
15812
- "autocomplete",
15813
- "autoFocus",
15814
- "autofocus",
15815
- "translate",
15816
- "part",
15817
- "exportparts",
15818
- "aria",
15819
- // Framework theming / pass-through escape hatches — dev-facing, never marketer-configurable
15820
- "dt",
15821
- "pt",
15822
- "ptOptions",
15823
- "unstyled",
15824
- "sx",
15825
- // Polymorphic component props — change rendered HTML/component, not marketer-visible behavior
15826
- "as",
15827
- "element",
15828
- "component",
15829
- // QA / vendor test attributes
15830
- "dataQa",
15831
- "data-qa",
15832
- // Vue v-model internals — framework wiring, never marketer-configurable
15833
- "modelValue",
15834
- "modelModifiers"
15835
- ]);
15836
- function isDomPassThroughProp(name) {
15837
- if (DOM_PASS_THROUGH_PROPS.has(name))
15838
- return true;
15839
- if (/^aria[-A-Z]/.test(name))
15840
- return true;
15841
- return name.startsWith("data-");
15842
- }
15843
-
15844
- // packages/experience-design-system-extraction/dist/src/extract/services/classification/classify-component-props.js
15845
- function preClassifyProp(prop) {
15846
- const { name, type } = prop;
15847
- if (/^on[A-Z]/.test(name) || type.includes("=> void") || type.includes("EventHandler")) {
15848
- return { category: "exclude" };
15849
- }
15850
- if (name === "ref" || name === "innerRef" || type.includes("Ref<") || type.includes("RefObject<")) {
15851
- return { category: "exclude" };
15852
- }
15853
- if (name === "testId" || name === "data-testid" || name === "dataTestId") {
15854
- return { category: "exclude" };
15855
- }
15856
- if (name === "key") {
15857
- return { category: "exclude" };
15858
- }
15859
- if (type.includes("Dispatch<") || type.includes("SetStateAction")) {
15860
- return { category: "exclude" };
15861
- }
15862
- if (isDomPassThroughProp(name)) {
15863
- return { category: "exclude" };
15864
- }
15865
- if (name === "name" && prop.domAttribute) {
15866
- return { category: "exclude" };
15867
- }
15868
- if (isStringLiteralUnion(type)) {
15869
- return { category: "design", cdfTypeHint: "enum" };
15870
- }
15871
- if (!isComplexType(type)) {
15872
- const designNameStart = /^(variant|size|spacing|gap|color|bg|theme|align|layout|orientation|position)/i;
15873
- const designNameEnd = /(Color|Size|Variant|Style)$/;
15874
- if (designNameStart.test(name) || designNameEnd.test(name)) {
15875
- return { category: "design", cdfTypeHint: "string" };
15876
- }
15877
- }
15878
- if (isBooleanType(type)) {
15879
- const stateNames = ["disabled", "loading", "expanded", "isOpen", "selected", "checked", "active", "preview"];
15880
- if (stateNames.includes(name)) {
15881
- return { category: "state", cdfTypeHint: "boolean" };
15882
- }
15883
- }
15884
- if (isBooleanType(type)) {
15885
- const visualToggle = /^(hide|show|enable|disable|vertical|horizontal|reverse|bold|italic|imageOn|with)/i;
15886
- if (visualToggle.test(name)) {
15887
- return { category: "design", cdfTypeHint: "boolean" };
15888
- }
15889
- }
15890
- if (name === "componentId" || name === "sectionKey" || name === "locale" || name === "variantIndex") {
15891
- return { category: "state", cdfTypeHint: "string" };
15892
- }
15893
- if (isStringType(type)) {
15894
- const urlNameStart = /^(href|url|link|src)/i;
15895
- const urlNameEnd = /(Url|Href|Link|Src)$/;
15896
- if (urlNameStart.test(name) || urlNameEnd.test(name)) {
15897
- return { category: "content", cdfTypeHint: "string" };
15898
- }
15899
- }
15900
- if (isStringType(type)) {
15901
- const textNameStart = /^(label|title|text|description|caption|heading|subheading|body|alt|name|placeholder|summary)/i;
15902
- const textNameEnd = /(Text|Label|Title|Name)$/;
15903
- if (textNameStart.test(name) || textNameEnd.test(name)) {
15904
- return { category: "content", cdfTypeHint: "string" };
15905
- }
15906
- }
15907
- if (isStringType(type)) {
15908
- return { category: "content", cdfTypeHint: "string" };
15909
- }
15910
- if (isBooleanType(type)) {
15911
- return { category: "design", cdfTypeHint: "boolean" };
15912
- }
15913
- if (isNumberType(type)) {
15914
- return { category: "design", cdfTypeHint: "string" };
15915
- }
15916
- return void 0;
15917
- }
15918
- function preClassifyComponent(component) {
15919
- const props = component.props.flatMap((prop) => {
15920
- const result = preClassifyProp(prop);
15921
- if (result?.category === "exclude") {
15922
- return [];
15923
- }
15924
- const { domAttribute: _domAttribute, ...authorableProp } = prop;
15925
- if (prop.category) {
15926
- return [authorableProp];
15927
- }
15928
- if (!result) {
15929
- return [authorableProp];
15930
- }
15931
- return [
15932
- {
15933
- ...authorableProp,
15934
- category: result.category
15935
- }
15936
- ];
15937
- });
15938
- return { ...component, props };
15939
- }
15940
-
15941
- // packages/experience-design-system-extraction/dist/src/extract/services/quality/helpers/authorability/evaluate-authorability.js
15338
+ // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/helpers/quality/non-authorable-filter.js
15942
15339
  var HANDLER_TYPE_PATTERN = /=>|EventHandler|Dispatch<|SetStateAction/;
15943
15340
  var REF_TYPE_PATTERN = /Ref<|RefObject<|MutableRefObject/;
15944
15341
  function isHandlerOrRefProp(prop) {
@@ -15991,10 +15388,15 @@ function hasNoAuthoringSurface(component) {
15991
15388
  return { skip: false };
15992
15389
  }
15993
15390
 
15994
- // packages/experience-design-system-extraction/dist/src/extract/services/quality/helpers/inspection/inspect-component-source.js
15391
+ // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/helpers/evidence/source-inspection.js
15995
15392
  import { readFile as readFile15 } from "node:fs/promises";
15996
15393
 
15997
- // packages/experience-design-system-extraction/dist/src/extract/helpers/evidence/parse-source-imports.js
15394
+ // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/constants/review-reasons.js
15395
+ var HIGH_CONFIDENCE_DATA_FETCH_WRAPPER_REASON = "data-fetch-wrapper";
15396
+ var POSSIBLE_DATA_FETCH_WRAPPER_REASON = "possible-data-fetch-wrapper";
15397
+ var ZERO_SURFACE_RENDERED_UI_REASON = "zero-surface:rendered-ui";
15398
+
15399
+ // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/framework-adapters/shared/parse-imported-names.js
15998
15400
  function parseImportedNames(importClause) {
15999
15401
  const trimmed = importClause.trim();
16000
15402
  if (!trimmed)
@@ -16019,7 +15421,7 @@ function parseImportedNames(importClause) {
16019
15421
  return names;
16020
15422
  }
16021
15423
 
16022
- // packages/experience-design-system-extraction/dist/src/extract/services/quality/helpers/inspection/detect-data-wrapper-patterns.js
15424
+ // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/helpers/evidence/source-inspection.js
16023
15425
  var INFRA_PROP_NAMES = /* @__PURE__ */ new Set(["id", "locale", "preview", "slug", "topic", "previousComponent", "__typename"]);
16024
15426
  var VISIBLE_UI_TAG_PATTERN = /<(?:[A-Z][A-Za-z0-9_.]*|div|span|section|main|article|header|footer|nav|aside|img|video|p|h[1-6]|ul|ol|li|button|input|textarea|select|form|label|table|tbody|thead|tr|td|th)\b/;
16025
15427
  var GENERATED_IMPORT_PATTERN = /from\s+['"][^'"]*__generated[^'"]*['"]/;
@@ -16061,11 +15463,11 @@ function hasSiblingForwardRender(sourceText, siblingImports) {
16061
15463
  function hasVisibleUiRender(sourceText) {
16062
15464
  return /return\s*(?:\(|<)/.test(sourceText) && VISIBLE_UI_TAG_PATTERN.test(sourceText);
16063
15465
  }
16064
- function collectInfraPropNames(component) {
15466
+ function infraPropNames(component) {
16065
15467
  const props = component.props.map((prop) => prop.name);
16066
15468
  return props.length > 0 && props.every((prop) => INFRA_PROP_NAMES.has(prop)) ? props : [];
16067
15469
  }
16068
- function mapScoreToWrapperConfidence(score) {
15470
+ function scoreToConfidence(score) {
16069
15471
  if (score <= 0)
16070
15472
  return 0;
16071
15473
  if (score <= 2)
@@ -16076,14 +15478,9 @@ function mapScoreToWrapperConfidence(score) {
16076
15478
  return 4;
16077
15479
  return 5;
16078
15480
  }
16079
- function dedupeStrings(values) {
16080
- return [...new Set(values)];
15481
+ function dedupeReasons(reasons) {
15482
+ return [...new Set(reasons)];
16081
15483
  }
16082
-
16083
- // packages/experience-design-system-extraction/dist/src/extract/services/quality/helpers/inspection/inspect-component-source.js
16084
- var HIGH_CONFIDENCE_DATA_FETCH_WRAPPER_REASON = "data-fetch-wrapper";
16085
- var POSSIBLE_DATA_FETCH_WRAPPER_REASON = "possible-data-fetch-wrapper";
16086
- var ZERO_SURFACE_RENDERED_UI_REASON = "zero-surface:rendered-ui";
16087
15484
  async function inspectComponentSource(component) {
16088
15485
  let sourceText = "";
16089
15486
  try {
@@ -16098,7 +15495,7 @@ async function inspectComponentSource(component) {
16098
15495
  const reviewReasons = [];
16099
15496
  let wrapperScore = 0;
16100
15497
  const hasGeneratedQueryHook = GENERATED_IMPORT_PATTERN.test(sourceText) && GENERATED_QUERY_HOOK_PATTERN.test(sourceText);
16101
- const infraProps = collectInfraPropNames(component);
15498
+ const infraProps = infraPropNames(component);
16102
15499
  const siblingImports = collectSiblingRendererImports(sourceText);
16103
15500
  if (GQL_FILENAME_PATTERN.test(component.source)) {
16104
15501
  reviewReasons.push("data-wrapper:gql-filename");
@@ -16128,7 +15525,7 @@ async function inspectComponentSource(component) {
16128
15525
  reviewReasons.push("data-wrapper:loading-null-guard");
16129
15526
  wrapperScore += 1;
16130
15527
  }
16131
- const wrapperConfidence = mapScoreToWrapperConfidence(wrapperScore);
15528
+ const wrapperConfidence = scoreToConfidence(wrapperScore);
16132
15529
  if (wrapperConfidence >= 4) {
16133
15530
  reviewReasons.unshift(HIGH_CONFIDENCE_DATA_FETCH_WRAPPER_REASON);
16134
15531
  } else if (wrapperConfidence === 3) {
@@ -16140,7 +15537,7 @@ async function inspectComponentSource(component) {
16140
15537
  }
16141
15538
  return {
16142
15539
  wrapperConfidence,
16143
- reviewReasons: dedupeStrings(reviewReasons),
15540
+ reviewReasons: dedupeReasons(reviewReasons),
16144
15541
  keepDespiteZeroSurface
16145
15542
  };
16146
15543
  }
@@ -16171,123 +15568,235 @@ function describeReviewReason(reason) {
16171
15568
  }
16172
15569
  }
16173
15570
  function describeReviewReasons(reasons) {
16174
- return dedupeStrings(reasons.map(describeReviewReason));
15571
+ return dedupeReasons(reasons.map(describeReviewReason));
16175
15572
  }
16176
15573
 
16177
- // packages/experience-design-system-extraction/dist/src/extract/services/quality/helpers/inspection/validate-extracted-components.js
16178
- function validateExtractedComponents2(components) {
16179
- const nameCounts = /* @__PURE__ */ new Map();
16180
- for (const component of components) {
16181
- const key = component.name.trim();
16182
- nameCounts.set(key, (nameCounts.get(key) ?? 0) + 1);
16183
- }
16184
- return components.map((component) => {
16185
- const issues = [];
16186
- if (!component.name.trim()) {
16187
- issues.push({
16188
- severity: "error",
16189
- code: "EMPTY_COMPONENT_NAME",
16190
- message: "Component name must not be empty"
16191
- });
15574
+ // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/helpers/quality/evaluate-extraction-quality.js
15575
+ function wrapperConfidenceToIssueCount(confidence) {
15576
+ if (confidence >= 4)
15577
+ return 2;
15578
+ if (confidence === 3)
15579
+ return 1;
15580
+ return 0;
15581
+ }
15582
+ async function evaluateExtractionQuality(components, initialWarnings = []) {
15583
+ const inspectedComponents = await Promise.all(components.map(async (component) => ({
15584
+ component,
15585
+ inspection: await inspectComponentSource(component)
15586
+ })));
15587
+ const scoredComponents = [];
15588
+ const warnings = [...initialWarnings];
15589
+ for (const { component, inspection } of inspectedComponents) {
15590
+ const verdict = hasNoAuthoringSurface(component);
15591
+ const keepDespiteZeroSurface = verdict.skip && verdict.reason === "component has no props and no slots" && inspection.keepDespiteZeroSurface;
15592
+ const retainedForReview = verdict.skip && !keepDespiteZeroSurface;
15593
+ if (retainedForReview) {
15594
+ warnings.push(`${component.name}: requires operator review (${verdict.reason})`);
16192
15595
  }
16193
- for (let i = 0; i < component.props.length; i++) {
16194
- if (!component.props[i].name.trim()) {
16195
- issues.push({
16196
- severity: "error",
16197
- code: "EMPTY_PROP_NAME",
16198
- message: `Prop at index ${i} has an empty name`,
16199
- field: `props[${i}].name`
16200
- });
16201
- }
15596
+ if (keepDespiteZeroSurface) {
15597
+ warnings.push(`${component.name}: retained despite 0 props/slots because the source renders visible or compositional UI`);
16202
15598
  }
16203
- for (let i = 0; i < component.slots.length; i++) {
16204
- if (!component.slots[i].name.trim()) {
16205
- issues.push({
16206
- severity: "warning",
16207
- code: "EMPTY_SLOT_NAME",
16208
- message: `Slot at index ${i} has an empty name`,
16209
- field: `slots[${i}].name`
16210
- });
16211
- }
15599
+ if (inspection.reviewReasons.length > 0) {
15600
+ const reviewNotes = describeReviewReasons(inspection.reviewReasons).filter((note) => note !== "high-confidence data-fetch wrapper").join("; ");
15601
+ if (reviewNotes)
15602
+ warnings.push(`${component.name}: ${reviewNotes}`);
16212
15603
  }
16213
- const propNames = new Set(component.props.map((p) => p.name.trim()).filter(Boolean));
16214
- for (let i = 0; i < component.slots.length; i++) {
16215
- const slotName = component.slots[i].name.trim();
16216
- if (slotName && propNames.has(slotName)) {
16217
- issues.push({
16218
- severity: "error",
16219
- code: "PROP_SLOT_NAME_COLLISION",
16220
- message: `"${slotName}" is used as both a prop name and a slot name`,
16221
- field: `slots[${i}].name`
16222
- });
16223
- }
15604
+ const extractorReasons = component.reviewReasons ?? [];
15605
+ const nonAuthorableReason = retainedForReview ? [`non-authorable:${verdict.reason}`] : [];
15606
+ const { confidence, reasons } = computeExtractionScore(component, {
15607
+ additionalIssueCount: wrapperConfidenceToIssueCount(inspection.wrapperConfidence) + extractorReasons.length + nonAuthorableReason.length,
15608
+ additionalReasons: [...extractorReasons, ...inspection.reviewReasons, ...nonAuthorableReason]
15609
+ });
15610
+ scoredComponents.push({
15611
+ ...component,
15612
+ extractionConfidence: confidence,
15613
+ reviewReasons: reasons,
15614
+ needsReview: deriveNeedsReview(confidence) || inspection.wrapperConfidence >= 4 || inspection.keepDespiteZeroSurface || retainedForReview || extractorReasons.includes("props-type-unresolved") || (component.needsReview ?? false)
15615
+ });
15616
+ }
15617
+ return {
15618
+ components: validateExtractedComponents(scoredComponents),
15619
+ warnings
15620
+ };
15621
+ }
15622
+
15623
+ // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/helpers/pre-classify.js
15624
+ function isStringLiteralUnion(type) {
15625
+ return type.includes("|") && type.includes("'");
15626
+ }
15627
+ function isSimpleType(type) {
15628
+ const t = type.trim();
15629
+ if (t === "string" || t === "boolean" || t === "number")
15630
+ return true;
15631
+ return isStringLiteralUnion(t);
15632
+ }
15633
+ function isBooleanType(type) {
15634
+ return type.trim() === "boolean";
15635
+ }
15636
+ function isStringType(type) {
15637
+ return type.trim() === "string";
15638
+ }
15639
+ function isNumberType(type) {
15640
+ return type.trim() === "number";
15641
+ }
15642
+ function isComplexType(type) {
15643
+ return !isSimpleType(type);
15644
+ }
15645
+ var DOM_PASS_THROUGH_PROPS = /* @__PURE__ */ new Set([
15646
+ // Bare HTML / framework styling pass-through
15647
+ "className",
15648
+ "class",
15649
+ "classes",
15650
+ "classNames",
15651
+ "rootClassName",
15652
+ "prefixCls",
15653
+ "style",
15654
+ "styles",
15655
+ // Bare HTML attributes
15656
+ "id",
15657
+ "role",
15658
+ "tabIndex",
15659
+ "tabindex",
15660
+ "htmlFor",
15661
+ "for",
15662
+ "slot",
15663
+ "is",
15664
+ "lang",
15665
+ "dir",
15666
+ "hidden",
15667
+ "draggable",
15668
+ "spellCheck",
15669
+ "spellcheck",
15670
+ "contentEditable",
15671
+ "contenteditable",
15672
+ "inputMode",
15673
+ "inputmode",
15674
+ "autoComplete",
15675
+ "autocomplete",
15676
+ "autoFocus",
15677
+ "autofocus",
15678
+ "translate",
15679
+ "part",
15680
+ "exportparts",
15681
+ "aria",
15682
+ // Framework theming / pass-through escape hatches — dev-facing, never marketer-configurable
15683
+ "dt",
15684
+ "pt",
15685
+ "ptOptions",
15686
+ "unstyled",
15687
+ "sx",
15688
+ // Polymorphic component props — change rendered HTML/component, not marketer-visible behavior
15689
+ "as",
15690
+ "element",
15691
+ "component",
15692
+ // QA / vendor test attributes
15693
+ "dataQa",
15694
+ "data-qa",
15695
+ // Vue v-model internals — framework wiring, never marketer-configurable
15696
+ "modelValue",
15697
+ "modelModifiers"
15698
+ ]);
15699
+ function isDomPassThroughProp(name) {
15700
+ if (DOM_PASS_THROUGH_PROPS.has(name))
15701
+ return true;
15702
+ if (/^aria[-A-Z]/.test(name))
15703
+ return true;
15704
+ return name.startsWith("data-");
15705
+ }
15706
+ function preClassifyProp(prop) {
15707
+ const { name, type } = prop;
15708
+ if (/^on[A-Z]/.test(name) || type.includes("=> void") || type.includes("EventHandler")) {
15709
+ return { category: "exclude" };
15710
+ }
15711
+ if (name === "ref" || name === "innerRef" || type.includes("Ref<") || type.includes("RefObject<")) {
15712
+ return { category: "exclude" };
15713
+ }
15714
+ if (name === "testId" || name === "data-testid" || name === "dataTestId") {
15715
+ return { category: "exclude" };
15716
+ }
15717
+ if (name === "key") {
15718
+ return { category: "exclude" };
15719
+ }
15720
+ if (type.includes("Dispatch<") || type.includes("SetStateAction")) {
15721
+ return { category: "exclude" };
15722
+ }
15723
+ if (isDomPassThroughProp(name)) {
15724
+ return { category: "exclude" };
15725
+ }
15726
+ if (name === "name" && prop.domAttribute) {
15727
+ return { category: "exclude" };
15728
+ }
15729
+ if (isStringLiteralUnion(type)) {
15730
+ return { category: "design", cdfTypeHint: "enum" };
15731
+ }
15732
+ if (!isComplexType(type)) {
15733
+ const designNameStart = /^(variant|size|spacing|gap|color|bg|theme|align|layout|orientation|position)/i;
15734
+ const designNameEnd = /(Color|Size|Variant|Style)$/;
15735
+ if (designNameStart.test(name) || designNameEnd.test(name)) {
15736
+ return { category: "design", cdfTypeHint: "string" };
16224
15737
  }
16225
- const nameKey = component.name.trim();
16226
- if (nameKey && (nameCounts.get(nameKey) ?? 0) > 1) {
16227
- issues.push({
16228
- severity: "error",
16229
- code: "DUPLICATE_COMPONENT_NAME",
16230
- message: `Component name "${component.name}" appears more than once in the extracted set`
16231
- });
15738
+ }
15739
+ if (isBooleanType(type)) {
15740
+ const stateNames = ["disabled", "loading", "expanded", "isOpen", "selected", "checked", "active", "preview"];
15741
+ if (stateNames.includes(name)) {
15742
+ return { category: "state", cdfTypeHint: "boolean" };
15743
+ }
15744
+ }
15745
+ if (isBooleanType(type)) {
15746
+ const visualToggle = /^(hide|show|enable|disable|vertical|horizontal|reverse|bold|italic|imageOn|with)/i;
15747
+ if (visualToggle.test(name)) {
15748
+ return { category: "design", cdfTypeHint: "boolean" };
16232
15749
  }
16233
- if (component.props.length === 0 && component.slots.length === 0) {
16234
- issues.push({
16235
- severity: "warning",
16236
- code: "EMPTY_COMPONENT",
16237
- message: "Component has no props or slots and will be filtered out during generation"
16238
- });
15750
+ }
15751
+ if (name === "componentId" || name === "sectionKey" || name === "locale" || name === "variantIndex") {
15752
+ return { category: "state", cdfTypeHint: "string" };
15753
+ }
15754
+ if (isStringType(type)) {
15755
+ const urlNameStart = /^(href|url|link|src)/i;
15756
+ const urlNameEnd = /(Url|Href|Link|Src)$/;
15757
+ if (urlNameStart.test(name) || urlNameEnd.test(name)) {
15758
+ return { category: "content", cdfTypeHint: "string" };
16239
15759
  }
16240
- return { ...component, validationIssues: issues };
16241
- });
16242
- }
16243
-
16244
- // packages/experience-design-system-extraction/dist/src/extract/services/quality/evaluate-extraction-quality.js
16245
- function wrapperConfidenceToIssueCount(confidence) {
16246
- if (confidence >= 4)
16247
- return 2;
16248
- if (confidence === 3)
16249
- return 1;
16250
- return 0;
15760
+ }
15761
+ if (isStringType(type)) {
15762
+ const textNameStart = /^(label|title|text|description|caption|heading|subheading|body|alt|name|placeholder|summary)/i;
15763
+ const textNameEnd = /(Text|Label|Title|Name)$/;
15764
+ if (textNameStart.test(name) || textNameEnd.test(name)) {
15765
+ return { category: "content", cdfTypeHint: "string" };
15766
+ }
15767
+ }
15768
+ if (isStringType(type)) {
15769
+ return { category: "content", cdfTypeHint: "string" };
15770
+ }
15771
+ if (isBooleanType(type)) {
15772
+ return { category: "design", cdfTypeHint: "boolean" };
15773
+ }
15774
+ if (isNumberType(type)) {
15775
+ return { category: "design", cdfTypeHint: "string" };
15776
+ }
15777
+ return void 0;
16251
15778
  }
16252
- async function evaluateExtractionQuality(components, initialWarnings = []) {
16253
- const inspectedComponents = await Promise.all(components.map(async (component) => ({
16254
- component,
16255
- inspection: await inspectComponentSource(component)
16256
- })));
16257
- const scoredComponents = [];
16258
- const warnings = [...initialWarnings];
16259
- for (const { component, inspection } of inspectedComponents) {
16260
- const verdict = hasNoAuthoringSurface(component);
16261
- const keepDespiteZeroSurface = verdict.skip && verdict.reason === "component has no props and no slots" && inspection.keepDespiteZeroSurface;
16262
- const retainedForReview = verdict.skip && !keepDespiteZeroSurface;
16263
- if (retainedForReview) {
16264
- warnings.push(`${component.name}: requires operator review (${verdict.reason})`);
15779
+ function preClassifyComponent(component) {
15780
+ const props = component.props.flatMap((prop) => {
15781
+ const result = preClassifyProp(prop);
15782
+ if (result?.category === "exclude") {
15783
+ return [];
16265
15784
  }
16266
- if (keepDespiteZeroSurface) {
16267
- warnings.push(`${component.name}: retained despite 0 props/slots because the source renders visible or compositional UI`);
15785
+ const { domAttribute: _domAttribute, ...authorableProp } = prop;
15786
+ if (prop.category) {
15787
+ return [authorableProp];
16268
15788
  }
16269
- if (inspection.reviewReasons.length > 0) {
16270
- const reviewNotes = describeReviewReasons(inspection.reviewReasons).filter((note) => note !== "high-confidence data-fetch wrapper").join("; ");
16271
- if (reviewNotes)
16272
- warnings.push(`${component.name}: ${reviewNotes}`);
15789
+ if (!result) {
15790
+ return [authorableProp];
16273
15791
  }
16274
- const extractorReasons = component.reviewReasons ?? [];
16275
- const nonAuthorableReason = retainedForReview ? [`non-authorable:${verdict.reason}`] : [];
16276
- const { confidence, reasons } = computeExtractionScore2(component, {
16277
- additionalIssueCount: wrapperConfidenceToIssueCount(inspection.wrapperConfidence) + extractorReasons.length + nonAuthorableReason.length,
16278
- additionalReasons: [...extractorReasons, ...inspection.reviewReasons, ...nonAuthorableReason]
16279
- });
16280
- scoredComponents.push({
16281
- ...component,
16282
- extractionConfidence: confidence,
16283
- reviewReasons: reasons,
16284
- needsReview: deriveNeedsReview2(confidence) || inspection.wrapperConfidence >= 4 || inspection.keepDespiteZeroSurface || retainedForReview || extractorReasons.includes("props-type-unresolved") || (component.needsReview ?? false)
16285
- });
16286
- }
16287
- return {
16288
- components: validateExtractedComponents2(scoredComponents),
16289
- warnings
16290
- };
15792
+ return [
15793
+ {
15794
+ ...authorableProp,
15795
+ category: result.category
15796
+ }
15797
+ ];
15798
+ });
15799
+ return { ...component, props };
16291
15800
  }
16292
15801
 
16293
15802
  // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-extract-and-compose-session/helpers/emit-pre-classification-exclusions.js
@@ -28565,44 +28074,68 @@ function SettingsScreen({
28565
28074
 
28566
28075
  // packages/experience-design-system-cli/src/tui/settings/configuration/ConfigurationScreen.tsx
28567
28076
  import { useState as useState33 } from "react";
28568
- import { Box as Box48, Text as Text51, useInput as useInput14 } from "ink";
28077
+ import { Box as Box48, Text as Text51, useInput as useInput13 } from "ink";
28569
28078
 
28570
28079
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentsScreen.tsx
28571
- import { useEffect as useEffect23, useRef as useRef13, useState as useState31 } from "react";
28080
+ import { useEffect as useEffect23, useState as useState31 } from "react";
28572
28081
  import { Box as Box46, Text as Text49, useInput as useInput12 } from "ink";
28573
28082
  init_debug_store();
28574
28083
 
28575
- // packages/experience-design-system-cli/src/tui/settings/shared/debug-trail.ts
28084
+ // packages/experience-design-system-cli/src/tui/settings/shared/v1-store.ts
28576
28085
  init_config();
28577
- import { existsSync as existsSync10 } from "node:fs";
28578
- function diffSnapshots(before, after) {
28579
- const names = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])];
28580
- const changed_fields = names.filter((name) => before[name] !== after[name]);
28581
- return { changed: changed_fields.length > 0, changed_fields };
28582
- }
28583
- var DEFAULT_TRAIL_LIMIT = 30;
28584
- function createTrail(limit = DEFAULT_TRAIL_LIMIT) {
28585
- const actions = [];
28586
- return {
28587
- record(action) {
28588
- actions.push(action);
28589
- if (actions.length > limit) actions.shift();
28590
- },
28591
- entries: () => [...actions]
28592
- };
28086
+ var readV1Store = readSettings2;
28087
+ var writeV1Store = writeSettings2;
28088
+
28089
+ // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-store.ts
28090
+ var AGENT_LABELS = {
28091
+ claude: "Claude Code",
28092
+ codex: "OpenAI Codex",
28093
+ opencode: "OpenCode",
28094
+ cursor: "Cursor",
28095
+ copilot: "GitHub Copilot"
28096
+ };
28097
+ var asString = (value) => typeof value === "string" ? value : "";
28098
+ function emptyAgents() {
28099
+ return Object.fromEntries(AGENT_NAMES.map((name) => [name, { model: "", binary: "" }]));
28593
28100
  }
28594
- var MIN_SECRET_LENGTH = 6;
28595
- function scrubError(error, secrets) {
28596
- let message = error instanceof Error ? error.message : String(error);
28597
- for (const secret of secrets) {
28598
- if (secret.length < MIN_SECRET_LENGTH) continue;
28599
- for (const form of /* @__PURE__ */ new Set([secret, encodeURIComponent(secret)])) message = message.split(form).join("[redacted]");
28101
+ async function readAgentConfig() {
28102
+ const store = await readV1Store();
28103
+ const stored = asString(store["agent"]);
28104
+ const defaultChosen = isAgentName(stored);
28105
+ const defaultAgent = defaultChosen ? stored : DEFAULT_AGENT_NAME;
28106
+ const agents = emptyAgents();
28107
+ const saved = store["agents"];
28108
+ if (saved && typeof saved === "object") {
28109
+ for (const name of AGENT_NAMES) {
28110
+ const entry = saved[name];
28111
+ if (entry && typeof entry === "object") {
28112
+ const fields2 = entry;
28113
+ agents[name] = { model: asString(fields2["model"]), binary: asString(fields2["binary"]) };
28114
+ }
28115
+ }
28600
28116
  }
28601
- return message;
28117
+ const legacyModel = asString(store["agentModel"]);
28118
+ if (legacyModel && !agents[defaultAgent].model)
28119
+ agents[defaultAgent] = { ...agents[defaultAgent], model: legacyModel };
28120
+ return { defaultAgent, defaultChosen, agents };
28602
28121
  }
28603
- function describeSettingsFile() {
28604
- const path5 = configFilePath2();
28605
- return { path: path5, eds_home_set: Boolean(process.env["EDS_HOME"]), exists: existsSync10(path5) };
28122
+ async function writeAgentConfig(config) {
28123
+ const existing = await readV1Store();
28124
+ const merged = { ...existing };
28125
+ const agents = {};
28126
+ for (const name of AGENT_NAMES) {
28127
+ const model = config.agents[name].model.trim();
28128
+ const binary = config.agents[name].binary.trim();
28129
+ if (model || binary) agents[name] = { ...model ? { model } : {}, ...binary ? { binary } : {} };
28130
+ }
28131
+ const defaultModel = config.defaultChosen ? agents[config.defaultAgent]?.model : void 0;
28132
+ if (config.defaultChosen) merged["agent"] = config.defaultAgent;
28133
+ else delete merged["agent"];
28134
+ if (defaultModel) merged["agentModel"] = defaultModel;
28135
+ else delete merged["agentModel"];
28136
+ if (Object.keys(agents).length > 0) merged["agents"] = agents;
28137
+ else delete merged["agents"];
28138
+ await writeV1Store(merged);
28606
28139
  }
28607
28140
 
28608
28141
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-status.ts
@@ -28808,94 +28341,6 @@ async function withBinaryEnv(name, binary, run) {
28808
28341
  }
28809
28342
  }
28810
28343
 
28811
- // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-debug.ts
28812
- function agentSnapshot(config) {
28813
- const snapshot = { default_agent: config.defaultAgent };
28814
- for (const name of AGENT_NAMES) {
28815
- snapshot[`${name}.model`] = config.agents[name].model;
28816
- snapshot[`${name}.binary`] = config.agents[name].binary;
28817
- }
28818
- return snapshot;
28819
- }
28820
- function environmentFrom(checks, savedBinary, envValue) {
28821
- const path5 = checks.find((check) => check.step === "path");
28822
- const version = checks.find((check) => check.step === "version");
28823
- const overridden = envValue !== void 0 && envValue !== "" && envValue !== savedBinary.trim();
28824
- return {
28825
- found: path5?.ok === true,
28826
- resolved_path: path5?.ok ? path5.detail : "",
28827
- version: version?.ok ? version.detail : "",
28828
- env_override: overridden ? envValue : ""
28829
- };
28830
- }
28831
- async function describeAgents(config) {
28832
- const entries = await Promise.all(
28833
- AGENT_NAMES.map(async (name) => {
28834
- const saved = config.agents[name].binary;
28835
- const checks = await inspectAgent(name, saved);
28836
- return [name, environmentFrom(checks, saved, process.env[`EDS_AGENT_BINARY_${name.toUpperCase()}`])];
28837
- })
28838
- );
28839
- return Object.fromEntries(entries);
28840
- }
28841
-
28842
- // packages/experience-design-system-cli/src/tui/settings/shared/v1-store.ts
28843
- init_config();
28844
- var readV1Store = readSettings2;
28845
- var writeV1Store = writeSettings2;
28846
-
28847
- // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-store.ts
28848
- var AGENT_LABELS = {
28849
- claude: "Claude Code",
28850
- codex: "OpenAI Codex",
28851
- opencode: "OpenCode",
28852
- cursor: "Cursor",
28853
- copilot: "GitHub Copilot"
28854
- };
28855
- var asString = (value) => typeof value === "string" ? value : "";
28856
- function emptyAgents() {
28857
- return Object.fromEntries(AGENT_NAMES.map((name) => [name, { model: "", binary: "" }]));
28858
- }
28859
- async function readAgentConfig() {
28860
- const store = await readV1Store();
28861
- const stored = asString(store["agent"]);
28862
- const defaultChosen = isAgentName(stored);
28863
- const defaultAgent = defaultChosen ? stored : DEFAULT_AGENT_NAME;
28864
- const agents = emptyAgents();
28865
- const saved = store["agents"];
28866
- if (saved && typeof saved === "object") {
28867
- for (const name of AGENT_NAMES) {
28868
- const entry = saved[name];
28869
- if (entry && typeof entry === "object") {
28870
- const fields2 = entry;
28871
- agents[name] = { model: asString(fields2["model"]), binary: asString(fields2["binary"]) };
28872
- }
28873
- }
28874
- }
28875
- const legacyModel = asString(store["agentModel"]);
28876
- if (legacyModel && !agents[defaultAgent].model)
28877
- agents[defaultAgent] = { ...agents[defaultAgent], model: legacyModel };
28878
- return { defaultAgent, defaultChosen, agents };
28879
- }
28880
- async function writeAgentConfig(config) {
28881
- const existing = await readV1Store();
28882
- const merged = { ...existing };
28883
- const agents = {};
28884
- for (const name of AGENT_NAMES) {
28885
- const model = config.agents[name].model.trim();
28886
- const binary = config.agents[name].binary.trim();
28887
- if (model || binary) agents[name] = { ...model ? { model } : {}, ...binary ? { binary } : {} };
28888
- }
28889
- const defaultModel = config.defaultChosen ? agents[config.defaultAgent]?.model : void 0;
28890
- if (config.defaultChosen) merged["agent"] = config.defaultAgent;
28891
- else delete merged["agent"];
28892
- if (defaultModel) merged["agentModel"] = defaultModel;
28893
- else delete merged["agentModel"];
28894
- if (Object.keys(agents).length > 0) merged["agents"] = agents;
28895
- else delete merged["agents"];
28896
- await writeV1Store(merged);
28897
- }
28898
-
28899
28344
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentDetail.tsx
28900
28345
  import { useEffect as useEffect22, useState as useState30 } from "react";
28901
28346
  import { Box as Box45, Text as Text48 } from "ink";
@@ -29097,8 +28542,7 @@ function AgentDetail({
29097
28542
  name,
29098
28543
  config,
29099
28544
  setConfig,
29100
- onBack,
29101
- record: record3
28545
+ onBack
29102
28546
  }) {
29103
28547
  const settings = config.agents[name];
29104
28548
  const [saving, setSaving] = useState30(false);
@@ -29121,12 +28565,10 @@ function AgentDetail({
29121
28565
  setNotice(null);
29122
28566
  writeAgentConfig(config).then(() => {
29123
28567
  applyBinaryOverrides(config);
29124
- record3(`saved ${name}`);
29125
28568
  setNotice({ kind: "success", text: `Saved: ${AGENT_LABELS[name]} settings are written to config.json` });
29126
- }).catch((err) => {
29127
- record3(`saving ${name} failed`, err);
29128
- setNotice({ kind: "error", text: `Not saved: ${err instanceof Error ? err.message : String(err)}` });
29129
- }).finally(() => setSaving(false));
28569
+ }).catch(
28570
+ (err) => setNotice({ kind: "error", text: `Not saved: ${err instanceof Error ? err.message : String(err)}` })
28571
+ ).finally(() => setSaving(false));
29130
28572
  };
29131
28573
  const runTest = () => {
29132
28574
  setTesting(true);
@@ -29134,15 +28576,12 @@ function AgentDetail({
29134
28576
  testAgent(name, settings.binary, settings.model).then((result) => {
29135
28577
  setChecks(result);
29136
28578
  const outcome = testOutcome(result);
29137
- if (!outcome || !outcome.ok)
29138
- record3(`test of ${name} failed: ${outcome?.text ?? "the agent could not be started"}`);
29139
28579
  setNotice(
29140
28580
  outcome ? { kind: outcome.ok ? "success" : "error", text: outcome.text } : { kind: "error", text: "Test not run: the agent could not be started (see Status)" }
29141
28581
  );
29142
- }).catch((err) => {
29143
- record3(`test of ${name} could not run`, err);
29144
- setNotice({ kind: "error", text: `Test could not run: ${err instanceof Error ? err.message : String(err)}` });
29145
- }).finally(() => setTesting(false));
28582
+ }).catch(
28583
+ (err) => setNotice({ kind: "error", text: `Test could not run: ${err instanceof Error ? err.message : String(err)}` })
28584
+ ).finally(() => setTesting(false));
29146
28585
  };
29147
28586
  const action = {
29148
28587
  label: "Run test",
@@ -29163,7 +28602,6 @@ function AgentDetail({
29163
28602
  onChange: (key, value) => {
29164
28603
  setConfig({ ...config, agents: { ...config.agents, [name]: { ...settings, [key]: value } } });
29165
28604
  setNotice(null);
29166
- record3(`edited ${name}.${key}`);
29167
28605
  },
29168
28606
  onSave: save,
29169
28607
  onQuit: onBack,
@@ -29190,12 +28628,6 @@ function AgentsScreen({ onDone }) {
29190
28628
  const [saving, setSaving] = useState31(false);
29191
28629
  const [loadError, setLoadError] = useState31(null);
29192
28630
  const [checks, setChecks] = useState31({});
29193
- const visit = useRef13({
29194
- trail: createTrail(),
29195
- before: void 0,
29196
- environment: void 0,
29197
- error: ""
29198
- }).current;
29199
28631
  const inspectAll = (loaded) => {
29200
28632
  for (const name of AGENT_NAMES) {
29201
28633
  void inspectAgent(name, loaded.agents[name].binary).then(
@@ -29207,38 +28639,14 @@ function AgentsScreen({ onDone }) {
29207
28639
  readAgentConfig().then((loaded) => {
29208
28640
  setConfig(loaded);
29209
28641
  inspectAll(loaded);
29210
- visit.before = agentSnapshot(loaded);
29211
28642
  startDebugRun({
29212
28643
  flow: "settings/agents",
29213
28644
  step: "01-agents",
29214
28645
  menuOption: "Configuration > Agents",
29215
- inputs: { ...visit.before, default_chosen: loaded.defaultChosen ?? false }
28646
+ inputs: { default_agent: loaded.defaultAgent }
29216
28647
  });
29217
- void describeAgents(loaded).then((found) => {
29218
- visit.environment = found;
29219
- });
29220
- }).catch((err) => {
29221
- visit.error = scrubError(err, []);
29222
- startDebugRun({ flow: "settings/agents", step: "01-agents", menuOption: "Configuration > Agents", inputs: {} });
29223
- setLoadError(visit.error);
29224
- });
28648
+ }).catch((err) => setLoadError(err instanceof Error ? err.message : String(err)));
29225
28649
  }, []);
29226
- const endVisit = (current) => {
29227
- const after = current ? agentSnapshot(current) : void 0;
29228
- const change = visit.before && after ? diffSnapshots(visit.before, after) : { changed: false, changed_fields: [] };
29229
- void finishDebugRun({
29230
- outputs: {
29231
- ...after ?? {},
29232
- ...change,
29233
- actions: visit.trail.entries(),
29234
- // Missing only when the user left before the probes finished.
29235
- ...visit.environment ? { agents: visit.environment } : {},
29236
- ...visit.error ? { error: visit.error } : {}
29237
- },
29238
- status: visit.error ? "error" : "success",
29239
- exitMethod: change.changed ? "saved" : "discarded"
29240
- });
29241
- };
29242
28650
  const makeDefault = (name) => {
29243
28651
  if (!config || saving) return;
29244
28652
  if (name === config.defaultAgent) {
@@ -29250,16 +28658,15 @@ function AgentsScreen({ onDone }) {
29250
28658
  writeAgentConfig({ ...config, defaultAgent: name, defaultChosen: true }).then(() => {
29251
28659
  setConfig((current) => current ? { ...current, defaultAgent: name, defaultChosen: true } : current);
29252
28660
  setNotice({ kind: "success", text: `Default agent is now ${AGENT_LABELS[name]}` });
29253
- visit.trail.record(`made ${name} the default`);
29254
- }).catch((err) => {
29255
- visit.error = scrubError(err, []);
29256
- visit.trail.record(`making ${name} the default failed`);
29257
- setNotice({ kind: "error", text: `Default agent not changed: ${visit.error}` });
29258
- }).finally(() => setSaving(false));
28661
+ }).catch(
28662
+ (err) => setNotice({
28663
+ kind: "error",
28664
+ text: `Default agent not changed: ${err instanceof Error ? err.message : String(err)}`
28665
+ })
28666
+ ).finally(() => setSaving(false));
29259
28667
  };
29260
28668
  useInput12((input, key) => {
29261
28669
  if (loadError && (key.escape || input === "q")) {
29262
- endVisit(null);
29263
28670
  onDone();
29264
28671
  return;
29265
28672
  }
@@ -29284,7 +28691,7 @@ function AgentsScreen({ onDone }) {
29284
28691
  return;
29285
28692
  }
29286
28693
  if (key.escape || input === "q") {
29287
- endVisit(config);
28694
+ void finishDebugRun({ outputs: { default_agent: config.defaultAgent }, status: "success", exitMethod: "saved" });
29288
28695
  onDone();
29289
28696
  }
29290
28697
  });
@@ -29309,10 +28716,6 @@ function AgentsScreen({ onDone }) {
29309
28716
  name: open,
29310
28717
  config,
29311
28718
  setConfig,
29312
- record: (action, error) => {
29313
- visit.trail.record(action);
29314
- if (error !== void 0) visit.error = scrubError(error, []);
29315
- },
29316
28719
  onBack: () => {
29317
28720
  setOpen(null);
29318
28721
  void readAgentConfig().then((saved) => {
@@ -29379,8 +28782,8 @@ function AgentsScreen({ onDone }) {
29379
28782
  }
29380
28783
 
29381
28784
  // packages/experience-design-system-cli/src/tui/settings/configuration/project/ProjectScreen.tsx
29382
- import { useEffect as useEffect24, useRef as useRef14, useState as useState32 } from "react";
29383
- import { Box as Box47, Text as Text50, useInput as useInput13 } from "ink";
28785
+ import { useEffect as useEffect24, useState as useState32 } from "react";
28786
+ import { Box as Box47, Text as Text50 } from "ink";
29384
28787
  init_debug_store();
29385
28788
 
29386
28789
  // packages/experience-design-system-cli/src/tui/settings/configuration/project/project-store.ts
@@ -29409,7 +28812,7 @@ async function writeCredentials(config) {
29409
28812
  }
29410
28813
 
29411
28814
  // packages/experience-design-system-cli/src/tui/settings/configuration/project/ProjectScreen.tsx
29412
- import { Fragment as Fragment19, jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
28815
+ import { jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
29413
28816
  var FIELDS2 = [
29414
28817
  { key: "spaceId", label: "Space ID" },
29415
28818
  { key: "environmentId", label: "Environment ID" },
@@ -29430,94 +28833,45 @@ function debugFields(config) {
29430
28833
  contentful_base_dir: config?.contentfulBaseDir ?? ""
29431
28834
  };
29432
28835
  }
29433
- var snapshotOf = (config) => Object.fromEntries(FIELDS2.map(({ key }) => [key, config[key] || ""]));
29434
28836
  var valuesOf = (config) => Object.fromEntries(FIELDS2.map(({ key }) => [key, config[key] || ""]));
29435
28837
  function ProjectScreen({ onDone }) {
29436
28838
  const [config, setConfig] = useState32(null);
29437
28839
  const [saving, setSaving] = useState32(false);
29438
28840
  const [notice, setNotice] = useState32(null);
29439
- const [loadError, setLoadError] = useState32(null);
29440
- const visit = useRef14({
29441
- trail: createTrail(),
29442
- before: void 0,
29443
- persisted: void 0,
29444
- error: ""
29445
- }).current;
29446
- const scrub = (err) => scrubError(err, [config?.cmaToken ?? ""]);
28841
+ const [lastSaved, setLastSaved] = useState32(null);
29447
28842
  useEffect24(() => {
29448
- readCredentials().then((cfg) => {
28843
+ void readCredentials().then((cfg) => {
29449
28844
  setConfig(cfg);
29450
- visit.before = snapshotOf(cfg);
29451
- visit.persisted = visit.before;
29452
- startDebugRun({
29453
- flow: "settings/contentful-configuration",
29454
- step: "01-configuration",
29455
- menuOption: "Configuration > Project",
29456
- inputs: { ...debugFields(cfg), settings_file: describeSettingsFile() }
29457
- });
29458
- }).catch((err) => {
29459
- visit.error = scrubError(err, []);
29460
28845
  startDebugRun({
29461
28846
  flow: "settings/contentful-configuration",
29462
28847
  step: "01-configuration",
29463
28848
  menuOption: "Configuration > Project",
29464
- inputs: { settings_file: describeSettingsFile() }
28849
+ inputs: debugFields(cfg)
29465
28850
  });
29466
- setLoadError(visit.error);
29467
28851
  });
29468
28852
  }, []);
29469
- const endVisit = (current) => {
29470
- const onScreen = current ? snapshotOf(current) : void 0;
29471
- const change = visit.before && visit.persisted ? diffSnapshots(visit.before, visit.persisted) : { changed: false, changed_fields: [] };
29472
- const unsaved = visit.persisted && onScreen ? diffSnapshots(visit.persisted, onScreen) : { changed: false, changed_fields: [] };
29473
- void finishDebugRun({
29474
- outputs: {
29475
- ...debugFields(current),
29476
- ...change,
29477
- unsaved_edits: unsaved.changed_fields,
29478
- actions: visit.trail.entries(),
29479
- ...visit.error ? { error: visit.error } : {}
29480
- },
29481
- status: visit.error ? "error" : "success",
29482
- exitMethod: change.changed ? "saved" : "discarded"
29483
- });
29484
- };
29485
- useInput13((input, key) => {
29486
- if (!config && loadError && (key.escape || input === "q")) {
29487
- endVisit(null);
29488
- onDone();
29489
- }
29490
- });
29491
28853
  if (!config) {
29492
28854
  return /* @__PURE__ */ jsxs48(Box47, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29493
28855
  /* @__PURE__ */ jsx59(Text50, { bold: true, children: "Project" }),
29494
28856
  /* @__PURE__ */ jsx59(Text50, { children: " " }),
29495
- loadError ? /* @__PURE__ */ jsxs48(Fragment19, { children: [
29496
- /* @__PURE__ */ jsxs48(Text50, { color: PALETTE.error, children: [
29497
- "\u2717 Could not read the settings: ",
29498
- loadError
29499
- ] }),
29500
- /* @__PURE__ */ jsx59(Text50, { children: " " }),
29501
- /* @__PURE__ */ jsx59(ControlHints, { hints: [{ keys: "Esc/q", label: "back" }] })
29502
- ] }) : /* @__PURE__ */ jsx59(Text50, { color: PALETTE.accent, children: "Loading..." })
28857
+ /* @__PURE__ */ jsx59(Text50, { color: PALETTE.accent, children: "Loading..." })
29503
28858
  ] });
29504
28859
  }
29505
28860
  const save = () => {
29506
28861
  setSaving(true);
29507
28862
  setNotice(null);
29508
28863
  writeCredentials(config).then(() => {
29509
- visit.persisted = snapshotOf(config);
29510
- visit.trail.record("saved");
28864
+ setLastSaved(config);
29511
28865
  if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
29512
28866
  setNotice({ kind: "success", text: "Project settings saved" });
29513
28867
  }).catch((err) => {
29514
- visit.error = scrub(err);
29515
- visit.trail.record("save failed");
29516
28868
  setNotice({ kind: "error", text: err instanceof Error ? err.message : "Failed to save" });
29517
28869
  }).finally(() => setSaving(false));
29518
28870
  };
29519
28871
  const quit = () => {
29520
- endVisit(config);
28872
+ void finishDebugRun(
28873
+ lastSaved ? { outputs: debugFields(lastSaved), status: "success", exitMethod: "saved" } : { outputs: {}, status: "success", exitMethod: "discarded" }
28874
+ );
29521
28875
  onDone();
29522
28876
  };
29523
28877
  return /* @__PURE__ */ jsx59(
@@ -29530,7 +28884,6 @@ function ProjectScreen({ onDone }) {
29530
28884
  onChange: (key, value) => {
29531
28885
  setConfig({ ...config, [key]: value });
29532
28886
  setNotice(null);
29533
- visit.trail.record(`edited ${key}`);
29534
28887
  },
29535
28888
  onSave: save,
29536
28889
  onQuit: quit,
@@ -29554,7 +28907,7 @@ function ConfigurationScreen({ onDone }) {
29554
28907
  const [focus, setFocus] = useState33(0);
29555
28908
  const [open, setOpen] = useState33(null);
29556
28909
  const close = () => setOpen(null);
29557
- useInput14((input, key) => {
28910
+ useInput13((input, key) => {
29558
28911
  if (open) return;
29559
28912
  if (key.upArrow) {
29560
28913
  setFocus((i) => (i - 1 + SECTIONS.length) % SECTIONS.length);
@@ -29596,7 +28949,7 @@ function ConfigurationScreen({ onDone }) {
29596
28949
 
29597
28950
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
29598
28951
  import { useEffect as useEffect25, useState as useState34 } from "react";
29599
- import { Box as Box49, Text as Text52, useInput as useInput15 } from "ink";
28952
+ import { Box as Box49, Text as Text52, useInput as useInput14 } from "ink";
29600
28953
 
29601
28954
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/analytics-store.ts
29602
28955
  async function readAnalyticsSetting() {
@@ -29615,7 +28968,7 @@ async function writeAnalyticsSetting(setting) {
29615
28968
 
29616
28969
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
29617
28970
  init_debug_store();
29618
- import { Fragment as Fragment20, jsx as jsx61, jsxs as jsxs50 } from "react/jsx-runtime";
28971
+ import { Fragment as Fragment19, jsx as jsx61, jsxs as jsxs50 } from "react/jsx-runtime";
29619
28972
  function OptInAnalyticsScreen({ onDone }) {
29620
28973
  const [loading, setLoading] = useState34(true);
29621
28974
  const [enabled, setEnabled] = useState34(true);
@@ -29631,7 +28984,7 @@ function OptInAnalyticsScreen({ onDone }) {
29631
28984
  });
29632
28985
  });
29633
28986
  }, []);
29634
- useInput15((input, key) => {
28987
+ useInput14((input, key) => {
29635
28988
  if (loading) return;
29636
28989
  if (key.return || input === " ") {
29637
28990
  setEnabled((current) => {
@@ -29649,7 +29002,7 @@ function OptInAnalyticsScreen({ onDone }) {
29649
29002
  return /* @__PURE__ */ jsxs50(Box49, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29650
29003
  /* @__PURE__ */ jsx61(Text52, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
29651
29004
  /* @__PURE__ */ jsx61(Text52, { children: " " }),
29652
- loading ? /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs50(Fragment20, { children: [
29005
+ loading ? /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs50(Fragment19, { children: [
29653
29006
  /* @__PURE__ */ jsxs50(Text52, { children: [
29654
29007
  "Share anonymous usage data:",
29655
29008
  " ",
@@ -29674,7 +29027,7 @@ function OptInAnalyticsScreen({ onDone }) {
29674
29027
 
29675
29028
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
29676
29029
  import { useEffect as useEffect26, useState as useState35 } from "react";
29677
- import { Box as Box50, Text as Text53, useInput as useInput16 } from "ink";
29030
+ import { Box as Box50, Text as Text53, useInput as useInput15 } from "ink";
29678
29031
  init_debug_mode_store();
29679
29032
  init_debug_store();
29680
29033
  import { jsx as jsx62, jsxs as jsxs51 } from "react/jsx-runtime";
@@ -29693,7 +29046,7 @@ function DebugModeScreen({ onDone }) {
29693
29046
  });
29694
29047
  });
29695
29048
  }, []);
29696
- useInput16((input, key) => {
29049
+ useInput15((input, key) => {
29697
29050
  if (loading) return;
29698
29051
  if (key.return || input === " ") {
29699
29052
  setEnabled((current) => {
@@ -29730,7 +29083,7 @@ function DebugModeScreen({ onDone }) {
29730
29083
  }
29731
29084
 
29732
29085
  // packages/experience-design-system-cli/app.tsx
29733
- import { Fragment as Fragment21, jsx as jsx63 } from "react/jsx-runtime";
29086
+ import { Fragment as Fragment20, jsx as jsx63 } from "react/jsx-runtime";
29734
29087
  function App({ importOptions, inkClear }) {
29735
29088
  const [screen, setScreen] = useState36("start");
29736
29089
  const [importExitCode, setImportExitCode] = useState36();
@@ -29899,7 +29252,7 @@ function App({ importOptions, inkClear }) {
29899
29252
  }
29900
29253
  );
29901
29254
  }
29902
- if (importDefaults === void 0) return /* @__PURE__ */ jsx63(Fragment21, {});
29255
+ if (importDefaults === void 0) return /* @__PURE__ */ jsx63(Fragment20, {});
29903
29256
  if (projectPath === void 0) {
29904
29257
  return /* @__PURE__ */ jsx63(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
29905
29258
  }
@@ -29938,7 +29291,7 @@ function App({ importOptions, inkClear }) {
29938
29291
  }
29939
29292
  );
29940
29293
  }
29941
- return /* @__PURE__ */ jsx63(Fragment21, {});
29294
+ return /* @__PURE__ */ jsx63(Fragment20, {});
29942
29295
  }
29943
29296
  if (scopeRun && scopeFlow) {
29944
29297
  if (scopeFlow.status === "failed") {
@@ -29975,7 +29328,7 @@ function App({ importOptions, inkClear }) {
29975
29328
  }
29976
29329
  );
29977
29330
  }
29978
- return /* @__PURE__ */ jsx63(Fragment21, {});
29331
+ return /* @__PURE__ */ jsx63(Fragment20, {});
29979
29332
  }
29980
29333
  if (pendingLaunch?.cached) {
29981
29334
  return /* @__PURE__ */ jsx63(