@orkestrel/scaffold 0.0.87 → 0.0.89

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.
@@ -473,7 +473,7 @@ Direct declaration populations are dense data arrays too. A sparse literal is re
473
473
 
474
474
  The precedence below assumes a readable node. A readable malformed keyword is ignored and widens according to the listed rule; a keyword access, enumeration, or recursive traversal that throws is not malformed schema vocabulary and is refused with `ContractError { code: 'structure', context: { shape: 'schema' } }`.
475
475
 
476
- `schemaToShape`'s precedence, top-down at each node (every keyword read is type-guarded; a malformed keyword is IGNORED, not thrown): (1) `enum` (≥ 1 string/number/boolean entry) → `literalShape`. (2) `oneOf` (≥ 1 record entry) → `oneOfShape` over the recursed variants, PROVIDED the record-entry count is at or under `INFER_BREADTH_LIMIT`; over the cap, building a subset union would be strictly narrower than the schema's full union, so the node widens to `rawShape` instead of sampling a subset. (3) `anyOf` identically → `unionShape`, with the same over-cap widen-to-`rawShape` rule rather than a subset union. (4) `type: 'string'/'number'/'integer'/'boolean'/'null'` → the matching primitive shape, with `minLength`/`maxLength`/`minimum`/`maximum` bounds kept only when well-formed and non-contradictory (a malformed or `min > max` pair drops to unbounded — widening, never narrowing). (5) `type: 'array'` → `arrayShape`, recursing into a record-valued `items` (else `rawShape`), with `minItems`/`maxItems` bounds. (6) `type: 'object'` (or no `type`/`enum`/`oneOf`/`anyOf` but a record `properties`) → `objectShape`: a property not listed in `required` is wrapped `optionalShape`; `additionalProperties: false` closes, a record value recurses into it (`objectShape` validates extras against that shape directly — no widening needed), and `true` / ABSENT / anything malformed leaves it open (`true`) — absent matches JSON Schema's own default, and `valueToSchema` / `samplesToSchema` always emit the keyword explicitly, so an absent value only arises from a hand-written schema. When `properties` has MORE keys than `INFER_BREADTH_LIMIT`, the schema's own `additionalProperties` is OVERRIDDEN and forced open (`true`) regardless of `false` or a record value — a key dropped past the sampling cap was never checked against a closed or record-valued rest shape, so forcing the object open is the only sound widening — mirroring the inferers' own `truncated ? true : !closed` rule. (7) Everything else — `{}`, an unrecognized `type`, exhausted depth (`INFER_DEPTH_LIMIT`), or a cyclic re-encounter — widens to `rawShape` (NOT `jsonShape`: `{}` is JSON Schema’s accept-anything schema, and `rawShape` is its exact inverse — its guard accepts every defined value and it re-emits `{}` verbatim, whereas `jsonShape`’s `isJSONValue` guard would reject the exotic originals (`Map`, `Set`, a class instance, a function, `NaN`) whose inferred schema is exactly `{}`). A `WeakMap` memo (keyed by schema-node identity + remaining depth), mirroring the inferers, guards a shared-reference schema DAG against exponential re-conversion. **Its key does not carry the active-ancestor set, and that is observable**: a node first reached through a CYCLIC path is cached with the shape it widened to at the back-edge, and a later ACYCLIC path is served that cached shape instead of descending further. Two schemas differing only in which sibling holds the cyclic node therefore convert to different shapes. Every such difference is a WIDENING — an accept-anything `rawShape` — so no value is wrongly rejected and the round-trip law is unaffected; what it costs is determinism ACROSS graphs, not within one, since the same input always converts the same way. This is stated as a limit rather than repaired because both repairs (dropping the ancestor set, or threading a cycle-affected flag through three public signatures) change the published surface.
476
+ `schemaToShape`'s precedence, top-down at each node (every keyword read is type-guarded; a malformed keyword is IGNORED, not thrown): (1) `enum` (≥ 1 string/number/boolean entry) → `literalShape`. (2) `oneOf` (≥ 1 record entry) → `oneOfShape` over the recursed variants, PROVIDED the record-entry count is at or under `INFER_BREADTH_LIMIT`; over the cap, building a subset union would be strictly narrower than the schema's full union, so the node widens to `rawShape` instead of sampling a subset. (3) `anyOf` identically → `unionShape`, with the same over-cap widen-to-`rawShape` rule rather than a subset union. (4) An array-valued `type` → `unionShape` over each distinct recognized name, converting `{ ...schema, type: member }` at the same depth so bounds, `items`, `properties`, and `description` apply to each member. A single distinct name returns its shape directly. An empty array or any unrecognized member widens the whole node to `rawShape`, even when `properties` is present; no member is dropped to narrow the union. The distinct-name count is checked against `INFER_BREADTH_LIMIT`; the recognized vocabulary fits below that cap, so repeated names do not exhaust it. This is runtime conversion support: the declared `JSONSchema.type` remains a single name because direct raw-schema validation supports only that vocabulary. (5) `type: 'string'/'number'/'integer'/'boolean'/'null'` → the matching primitive shape, with `minLength`/`maxLength`/`minimum`/`maximum` bounds kept only when well-formed and non-contradictory (a malformed or `min > max` pair drops to unbounded — widening, never narrowing). (6) `type: 'array'` → `arrayShape`, recursing into a record-valued `items` (else `rawShape`), with `minItems`/`maxItems` bounds. (7) `type: 'object'` (or no `type`/`enum`/`oneOf`/`anyOf` but a record `properties`) → `objectShape`: a property not listed in `required` is wrapped `optionalShape`; `additionalProperties: false` closes, a record value recurses into it (`objectShape` validates extras against that shape directly — no widening needed), and `true` / ABSENT / anything malformed leaves it open (`true`) — absent matches JSON Schema's own default, and `valueToSchema` / `samplesToSchema` always emit the keyword explicitly, so an absent value only arises from a hand-written schema. When `properties` has MORE keys than `INFER_BREADTH_LIMIT`, the schema's own `additionalProperties` is OVERRIDDEN and forced open (`true`) regardless of `false` or a record value — a key dropped past the sampling cap was never checked against a closed or record-valued rest shape, so forcing the object open is the only sound widening — mirroring the inferers' own `truncated ? true : !closed` rule. (8) Everything else — `{}`, an unrecognized `type`, exhausted depth (`INFER_DEPTH_LIMIT`), or a cyclic re-encounter — widens to `rawShape` (NOT `jsonShape`: `{}` is JSON Schema’s accept-anything schema, and `rawShape` is its exact inverse — its guard accepts every defined value and it re-emits `{}` verbatim, whereas `jsonShape`’s `isJSONValue` guard would reject the exotic originals (`Map`, `Set`, a class instance, a function, `NaN`) whose inferred schema is exactly `{}`). A `WeakMap` memo (keyed by schema-node identity + remaining depth), mirroring the inferers, guards a shared-reference schema DAG against exponential re-conversion. **Its key does not carry the active-ancestor set, and that is observable**: a node first reached through a CYCLIC path is cached with the shape it widened to at the back-edge, and a later ACYCLIC path is served that cached shape instead of descending further. Two schemas differing only in which sibling holds the cyclic node therefore convert to different shapes. Every such difference is a WIDENING — an accept-anything `rawShape` — so no value is wrongly rejected and the round-trip law is unaffected; what it costs is determinism ACROSS graphs, not within one, since the same input always converts the same way. This is stated as a limit rather than repaired because both repairs (dropping the ancestor set, or threading a cycle-affected flag through three public signatures) change the published surface.
477
477
 
478
478
  **Round-trip law:** for any READABLE value `v` — including `NaN`, `±Infinity`, a `Map`, a `Set`, a class instance, a function, a symbol, a bigint, and readable cyclic hosts — `compileGuard(schemaToShape(valueToSchema(v)))(v) === true`, with widening as the ONLY source of looseness, never narrowing. An unreadable host is refused before the law produces a schema. The law otherwise retains its three limits: JSON absence, `Date` serialization, and unstable reads between inference and validation. A widened node cannot be auto-generated: `createContract(schemaToShape(x)).generate()` throws when the conversion widened anywhere; its parser returns `undefined` for readable invalid input and propagates the shared coded refusal when a required read fails.
479
479
 
@@ -2067,6 +2067,12 @@ read or write that file.
2067
2067
 
2068
2068
  ## Generated workspace
2069
2069
 
2070
+ The generated factories name unnamed browser instances after merging the caller's override, using
2071
+ the merged project label and browser. An override setting the label to `widgets` produces
2072
+ `widgets (chromium)`, including for an instance added by the override. Explicit instance names stay
2073
+ unchanged. Vue and journey factories discard inherited instance names before applying their own
2074
+ labels. Vitest reports the same names when a wrapper runs alone and when the root registers it.
2075
+
2070
2076
  A workspace's file set is a function of its axes, its structural facts, and its extensions.
2071
2077
  Nothing is fixed except the manifest.
2072
2078
 
@@ -2084,7 +2090,8 @@ Nothing is fixed except the manifest.
2084
2090
  `dist/`, and `npm run check` would wait on `npm run build`. Every subpath is written before the
2085
2091
  bare specifier, because `vite.config.ts` derives its `alias` record from these entries in order and
2086
2092
  a bare specifier also matches its own subpaths. An `app` environment publishes nothing and maps no
2087
- such entry.
2093
+ such entry. Browser and Vue scoped configurations exclude Node globals. Browser setup helpers
2094
+ read CDP sessions as `unknown` and guard the members they use.
2088
2095
  - One template artifact, `configs/browsers.ts`, for a workspace selecting `browser` on either
2089
2096
  environment axis or in its setup runtime list.
2090
2097
  It resolves the Chromium the Playwright provider launches, and the root `vite.config.ts` calls it
@@ -2110,7 +2117,8 @@ Nothing is fixed except the manifest.
2110
2117
  journey per application of a journey workspace. Surfaces and extensions lists each face.
2111
2118
  - One template artifact, `tests/distribution.test.ts`, for a workspace publishing any `src`
2112
2119
  environment or sheet face. It is the packed-package proof, and it is claimed by presence rather
2113
- than birth, so a workspace that replaces it keeps its replacement. A published browser environment
2120
+ than birth, so a workspace that replaces it keeps its replacement. The suite stages its consumer
2121
+ during setup; listing the project creates no distribution staging directory. A published browser environment
2114
2122
  adds the
2115
2123
  real-browser stage to it: the stage bundles the installed package with the workspace's own
2116
2124
  `configs/browsers.ts` resolution, serves the bundle over a loopback server, and drives it in
@@ -2609,7 +2617,9 @@ The generated guide index lists each occupied Vue face with its source, tests, a
2609
2617
  - [`tests/src/core/cloners.test.ts`](../tests/src/core/cloners.test.ts) — ownership of a snapshot
2610
2618
  taken from a hostile value.
2611
2619
  - [`tests/src/core/templates.test.ts`](../tests/src/core/templates.test.ts) — the frozen template
2612
- definitions.
2620
+ definitions and generated configurations under live Vitest. The isolated `templates` project runs
2621
+ through `test:templates` in `prepublishOnly`; its compiler and Chromium processes run apart from
2622
+ the `src:core` project.
2613
2623
  - [`tests/src/core/constants.test.ts`](../tests/src/core/constants.test.ts) — the seeded rows named
2614
2624
  as a set, the floor form every shared table and this manifest carry, and the emitted TypeScript
2615
2625
  bound.
@@ -244,7 +244,7 @@
244
244
  "storage": "agents/skills/orkestrel-harden/SKILL.md",
245
245
  "destination": ".agents/skills/orkestrel-harden/SKILL.md",
246
246
  "executable": false,
247
- "digest": "fdb32a356c23d911f47a417b999397a188b508278cbf19d92b21e72979fea4c2"
247
+ "digest": "8d108a0545b9f70e7c27477af988b990d6a8f772649f04ef21bae99e08e4fa05"
248
248
  },
249
249
  {
250
250
  "storage": "agents/skills/orkestrel-harden/agents/openai.yaml",
@@ -280,7 +280,7 @@
280
280
  "storage": "agents/skills/orkestrel-harden/scripts/discovery.ts",
281
281
  "destination": ".agents/skills/orkestrel-harden/scripts/discovery.ts",
282
282
  "executable": false,
283
- "digest": "fad5a6093f42f02c9fc0ee955d7f94fede22f3c69f8d049c80dfb779cda89f39"
283
+ "digest": "3dd132bd7d8a40f43417d2dc604af1f383a623587a288e7f104fecfde0dca3b0"
284
284
  },
285
285
  {
286
286
  "storage": "agents/skills/orkestrel-journey/SKILL.md",
@@ -352,7 +352,7 @@
352
352
  "storage": "agents/skills/orkestrel-publish/SKILL.md",
353
353
  "destination": ".agents/skills/orkestrel-publish/SKILL.md",
354
354
  "executable": false,
355
- "digest": "f4bcc24e910bbd40de268ba6a9d4ba57b3e5f9ce69075dea395479a45ec0f9d4"
355
+ "digest": "9cb5cecb878001d08fa9cd250906628a3ad0f58eabde484ca8c1dc13510503e9"
356
356
  },
357
357
  {
358
358
  "storage": "agents/skills/orkestrel-publish/agents/openai.yaml",
@@ -370,13 +370,13 @@
370
370
  "storage": "agents/skills/orkestrel-publish/references/wave.md",
371
371
  "destination": ".agents/skills/orkestrel-publish/references/wave.md",
372
372
  "executable": false,
373
- "digest": "2d5479e0d3ed0529015f5f1f21345fb389f8119333b6c5530d2320be432fe1e1"
373
+ "digest": "68f5df5747f2b5cbd950413ce3e4a070ef5be229a79811711192763cd70d73fa"
374
374
  },
375
375
  {
376
376
  "storage": "agents/skills/orkestrel-publish/references/window.md",
377
377
  "destination": ".agents/skills/orkestrel-publish/references/window.md",
378
378
  "executable": false,
379
- "digest": "734840b4803d8914bb88634f76f8c03b37da13d411a640614e446fec3c0c6ac5"
379
+ "digest": "1debb388eba46e221f99a2518de5aa94ba04ffced781a855b4a305cafc7176c3"
380
380
  },
381
381
  {
382
382
  "storage": "agents/skills/orkestrel-publish/scripts/compare.ts",
@@ -400,7 +400,7 @@
400
400
  "storage": "agents/skills/orkestrel-publish/scripts/window.ts",
401
401
  "destination": ".agents/skills/orkestrel-publish/scripts/window.ts",
402
402
  "executable": false,
403
- "digest": "143e29576afbf97e29141e4c9f38faef306929fbdfe41442c490f0d3064d119e"
403
+ "digest": "46594a58df8c07926b737373ece0fcb65e3eadfc0786bf3891542ca98e291fcc"
404
404
  },
405
405
  {
406
406
  "storage": "agents/skills/orkestrel-scout/SKILL.md",
@@ -496,7 +496,7 @@
496
496
  "storage": "claude/agents/orkestrel.md",
497
497
  "destination": ".claude/agents/orkestrel.md",
498
498
  "executable": false,
499
- "digest": "02c8bfcfa26ee23e91cef48771e5a3038bdb8d4018f0510bef5cd17db82f5893"
499
+ "digest": "565dee392dced6c3e1e632295739eeb9465ca4828d26c18d02b57f106fdc5f38"
500
500
  },
501
501
  {
502
502
  "storage": "claude/agents/planner.md",
@@ -538,7 +538,7 @@
538
538
  "storage": "claude/rules/architecture.md",
539
539
  "destination": ".claude/rules/architecture.md",
540
540
  "executable": false,
541
- "digest": "6d8936e85dd3c01e915a91a5b7bb9aaafa9b09a899b0cf8ff6bb8f9e8ff8e629"
541
+ "digest": "5fb146c532f74910f5afa88070a7da03fd782c2f420f07d9581d2635d768807b"
542
542
  },
543
543
  {
544
544
  "storage": "claude/rules/browser.md",
@@ -586,7 +586,7 @@
586
586
  "storage": "claude/rules/tests.md",
587
587
  "destination": ".claude/rules/tests.md",
588
588
  "executable": false,
589
- "digest": "6913f316d2bae3bb19e579bf419c820cdba97ed70422ea5d11deb800bd07973e"
589
+ "digest": "5808e375cf559c6d51aa3a744bcea574613945629e66e304c3d2f338b2f7abc0"
590
590
  },
591
591
  {
592
592
  "storage": "claude/rules/typescript.md",
@@ -598,7 +598,7 @@
598
598
  "storage": "claude/rules/workspace.md",
599
599
  "destination": ".claude/rules/workspace.md",
600
600
  "executable": false,
601
- "digest": "3c9e269acd88935ee6c4f34dd07784f09f45bb6bfd1e27c6a183da3420da4fcc"
601
+ "digest": "f62b3c7321444d6fc30b587d9221915d0835ea3bb78204868e27beeb3ea5450b"
602
602
  },
603
603
  {
604
604
  "storage": "claude/rules/writing.md",
@@ -772,7 +772,7 @@
772
772
  "storage": "configs/policy.ts",
773
773
  "destination": "configs/policy.ts",
774
774
  "executable": false,
775
- "digest": "de238996682d2eb35a40941214dc5c1d6427c57159afc3055f243bf93a5e8f83"
775
+ "digest": "bf4ba1f29a04040f9bf953ad4641af08a2b0662e2dd6d6f8f3d7ae8282587158"
776
776
  },
777
777
  {
778
778
  "storage": "cursor/mcp.json",
@@ -862,7 +862,7 @@
862
862
  "storage": "guides/browser.md",
863
863
  "destination": "guides/browser.md",
864
864
  "executable": false,
865
- "digest": "2bd000da61376666df785bb4f51f3e7988ac821f29d9b3174abc8b716d503086"
865
+ "digest": "4dd8f7377b165d840dd3060f0af955458fff193612f833aadd04d37c34734afe"
866
866
  },
867
867
  {
868
868
  "storage": "guides/budget.md",
@@ -886,7 +886,7 @@
886
886
  "storage": "guides/contract.md",
887
887
  "destination": "guides/contract.md",
888
888
  "executable": false,
889
- "digest": "2aa2ebffe3cb466e0c6845a8bbd1cc81f16e526f952f938430e3cfcb700cdee5"
889
+ "digest": "5339c1ba3a1ffe9ffe5415d70bd4868a73f9ef2661c4ce97e22dc8a30054569c"
890
890
  },
891
891
  {
892
892
  "storage": "guides/csv.md",
@@ -1042,7 +1042,7 @@
1042
1042
  "storage": "guides/scaffold.md",
1043
1043
  "destination": "guides/scaffold.md",
1044
1044
  "executable": false,
1045
- "digest": "9d6ea9f86610e3237d6ddbe120aabdec137f022092fc5311ca18e87d4b4e6212"
1045
+ "digest": "02922fe230a3d85e58ad16aa9e3b2e93afd42e9d3d66b88f60bbd68b1b90e19e"
1046
1046
  },
1047
1047
  {
1048
1048
  "storage": "guides/sea.md",
@@ -1168,7 +1168,7 @@
1168
1168
  "storage": "tests/config.test.ts",
1169
1169
  "destination": "tests/config.test.ts",
1170
1170
  "executable": false,
1171
- "digest": "395ac8782ae05c678c13e460de654e32140125f159fcb882053340ab193bb5f3"
1171
+ "digest": "ac12462cfc786b77c23e8996c0a050f9719d870db08abe7f3a8994cbbf778e2d"
1172
1172
  },
1173
1173
  {
1174
1174
  "storage": "tests/policy.test.ts",
@@ -2144,5 +2144,5 @@
2144
2144
  ]
2145
2145
  }
2146
2146
  ],
2147
- "digest": "5c7e45000c69dd7340b13478851fcfaeaa972f3f25311e230def9b740dc82e15"
2147
+ "digest": "551ef9dbdc726896039afd3e7edc69321303f148e28cd711a6e4ba028dba2d46"
2148
2148
  }
@@ -183,7 +183,9 @@ describe('selected faces', () => {
183
183
  expect(project.test?.include).toContain(`tests/${axis}/${face}/**/*.test.ts`)
184
184
  expect(project.test?.browser).toMatchObject({
185
185
  enabled: true,
186
- instances: expect.arrayContaining([expect.objectContaining({ browser: 'chromium' })]),
186
+ instances: expect.arrayContaining([
187
+ expect.objectContaining({ browser: 'chromium', name: `${axis}:${face} (chromium)` }),
188
+ ]),
187
189
  })
188
190
  expect(project.optimizeDeps?.include).toEqual(
189
191
  expect.arrayContaining(['@orkestrel/test', '@orkestrel/test/browser']),
@@ -355,6 +357,14 @@ describe('selected faces', () => {
355
357
  width: selected.width,
356
358
  height: selected.height,
357
359
  })
360
+ expect(readConfigRecord(test.browser).instances).toEqual(
361
+ expect.arrayContaining([
362
+ expect.objectContaining({
363
+ browser: 'chromium',
364
+ name: `journey:${provide.variant} (chromium)`,
365
+ }),
366
+ ]),
367
+ )
358
368
  expect(typeof provide.capture).toBe('boolean')
359
369
  expect(readConfigRecord(project.optimizeDeps).include).toEqual(
360
370
  expect.arrayContaining(['@orkestrel/test', '@orkestrel/test/browser']),
@@ -398,6 +408,12 @@ describe('selected faces', () => {
398
408
  )
399
409
  const test = readConfigRecord(project.test)
400
410
  if (readConfigRecord(test.browser ?? {}).enabled !== true) continue
411
+ const label = typeof test.name === 'string' ? test.name : readConfigRecord(test.name).label
412
+ expect(readConfigRecord(test.browser).instances).toEqual(
413
+ expect.arrayContaining([
414
+ expect.objectContaining({ browser: 'chromium', name: `${label} (chromium)` }),
415
+ ]),
416
+ )
401
417
  const include = readConfigRecord(project.optimizeDeps).include
402
418
  expect(include).toEqual(
403
419
  expect.arrayContaining([
@@ -1889,6 +1905,12 @@ createSomething({
1889
1905
  code: 'function parseValue(): void {}\nexport { parseValue as coerceValue }',
1890
1906
  errors: [{ messageId: 'parser' }],
1891
1907
  },
1908
+ {
1909
+ name: 'rejects an unprefixed exported import alias [membership: parsers.ts functions whose name does not start with parse]',
1910
+ filename: 'app/edge/parsers.ts',
1911
+ code: 'export import coerceValue = Values.parseValue',
1912
+ errors: [{ messageId: 'parser' }],
1913
+ },
1892
1914
  ],
1893
1915
  })
1894
1916
 
@@ -1924,6 +1946,12 @@ createSomething({
1924
1946
  code: 'function createValue(): void {}\nexport { createValue as buildValue }',
1925
1947
  errors: [{ messageId: 'factory' }],
1926
1948
  },
1949
+ {
1950
+ name: 'rejects an unprefixed exported import alias [membership: factories.ts functions whose name does not start with create]',
1951
+ filename: 'app/edge/factories.ts',
1952
+ code: 'export import buildValue = Values.createValue',
1953
+ errors: [{ messageId: 'factory' }],
1954
+ },
1927
1955
  ],
1928
1956
  })
1929
1957
 
@@ -1954,6 +1982,16 @@ createSomething({
1954
1982
  filename: 'src/edge/plugins.ts',
1955
1983
  code: 'function createModalPlugin(): void {}\nexport { createModalPlugin as createDialogPlugin }',
1956
1984
  },
1985
+ {
1986
+ name: 'accepts an exported import alias in the plugin form',
1987
+ filename: 'src/edge/plugins.ts',
1988
+ code: 'export import createDialogPlugin = Factories.createModalPlugin',
1989
+ },
1990
+ {
1991
+ name: 'accepts an exported import alias outside plugins.ts',
1992
+ filename: 'src/edge/helpers.ts',
1993
+ code: 'export import registerModal = Factories.createModalPlugin',
1994
+ },
1957
1995
  ],
1958
1996
  invalid: [
1959
1997
  {
@@ -2034,6 +2072,18 @@ createSomething({
2034
2072
  code: 'export function createplugin(): void {}',
2035
2073
  errors: [{ messageId: 'plugin' }],
2036
2074
  },
2075
+ {
2076
+ name: 'rejects an underscore in the entity segment [membership: plugins.ts functions whose name is not create…Plugin or create…Plugins]',
2077
+ filename: 'src/edge/plugins.ts',
2078
+ code: 'export function createModal_Plugin(): void {}',
2079
+ errors: [{ messageId: 'plugin' }],
2080
+ },
2081
+ {
2082
+ name: 'rejects an exported import alias outside the plugin form [membership: plugins.ts functions whose name is not create…Plugin or create…Plugins]',
2083
+ filename: 'src/edge/plugins.ts',
2084
+ code: 'export import registerModal = Factories.createModalPlugin',
2085
+ errors: [{ messageId: 'plugin' }],
2086
+ },
2037
2087
  ],
2038
2088
  })
2039
2089