@astryxdesign/cli 0.7.2-canary.e26723d → 0.7.2-canary.e4bdd70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +9 -8
  2. package/api/docs/_adapter.d.mts +11 -0
  3. package/api/docs/_adapter.mjs +37 -0
  4. package/api/index.d.mts +2 -0
  5. package/api/index.mjs +2 -0
  6. package/api/integration/add-contribution.mjs +1 -1
  7. package/api/integration/add-contribution.test.mjs +4 -2
  8. package/api/integration/check/check.d.mts +96 -0
  9. package/api/integration/check/check.mjs +357 -0
  10. package/api/integration/check/check.test.mjs +489 -0
  11. package/api/integration/integration-check.type.d.mts +118 -0
  12. package/api/integration/integration-check.type.mjs +84 -0
  13. package/api/integration/integrationCheck.doc.d.mts +10 -0
  14. package/api/integration/integrationCheck.doc.mjs +73 -0
  15. package/api/integration/integrationComponentConflicts.doc.mjs +19 -4
  16. package/api/integration/validate-integration.mjs +8 -0
  17. package/api/integration/validate-integration.type.d.mts +8 -0
  18. package/api/integration/validate-integration.type.mjs +12 -1
  19. package/api/integration/validateIntegration.doc.mjs +17 -3
  20. package/api/search/search.d.mts +13 -6
  21. package/api/search/search.domain-priority.test.mjs +93 -18
  22. package/api/search/search.integration-check.test.mjs +24 -0
  23. package/api/search/search.mjs +33 -9
  24. package/api/theme/build/build.family.test.mjs +54 -6
  25. package/api/theme/build/build.mjs +110 -13
  26. package/api/theme/themeBuild.doc.mjs +4 -4
  27. package/assets/docs/styling-overview.doc.mjs +1 -1
  28. package/assets/docs/tree/add-a-component.doc.mjs +1 -1
  29. package/assets/docs/tree/add-a-theme.doc.mjs +1 -1
  30. package/assets/docs/tree/add-a-topic.doc.mjs +10 -7
  31. package/assets/docs/tree/agent-guidance.doc.mjs +2 -2
  32. package/assets/docs/tree/block-template.doc.mjs +8 -20
  33. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  34. package/assets/docs/tree/check-the-props.doc.mjs +51 -0
  35. package/assets/docs/tree/check-your-docs.doc.mjs +51 -5
  36. package/assets/docs/tree/checks.doc.mjs +21 -13
  37. package/assets/docs/tree/codemods.doc.mjs +4 -4
  38. package/assets/docs/tree/component-family.doc.mjs +3 -5
  39. package/assets/docs/tree/component-imports.doc.mjs +2 -2
  40. package/assets/docs/tree/components.doc.mjs +1 -1
  41. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +7 -18
  42. package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
  43. package/assets/docs/tree/describe-the-component.doc.mjs +1 -1
  44. package/assets/docs/tree/docs.doc.mjs +3 -3
  45. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  46. package/assets/docs/tree/document-the-theme.doc.mjs +1 -1
  47. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  48. package/assets/docs/tree/extend-or-replace.doc.mjs +6 -6
  49. package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
  50. package/assets/docs/tree/generate-a-palette.doc.mjs +5 -3
  51. package/assets/docs/tree/grade-template-with-agent.doc.mjs +1 -1
  52. package/assets/docs/tree/integrations.doc.mjs +8 -0
  53. package/assets/docs/tree/links.doc.mjs +5 -4
  54. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  55. package/assets/docs/tree/page-template.doc.mjs +4 -8
  56. package/assets/docs/tree/publishing.doc.mjs +1 -1
  57. package/assets/docs/tree/quick-start.doc.mjs +37 -21
  58. package/assets/docs/tree/replace-a-core-component.doc.mjs +4 -6
  59. package/assets/docs/tree/replace-a-core-template.doc.mjs +6 -8
  60. package/assets/docs/tree/sections-and-placement.doc.mjs +4 -6
  61. package/assets/docs/tree/see-it-in-an-app.doc.mjs +4 -2
  62. package/assets/docs/tree/short-and-findable.doc.mjs +6 -5
  63. package/assets/docs/tree/single-component.doc.mjs +12 -4
  64. package/assets/docs/tree/start-a-template.doc.mjs +3 -3
  65. package/assets/docs/tree/subcomponent.doc.mjs +6 -6
  66. package/assets/docs/tree/template-assets.doc.mjs +2 -2
  67. package/assets/docs/tree/template-doc-overview.doc.mjs +4 -15
  68. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  69. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  70. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  71. package/assets/docs/tree/template-styles.doc.mjs +2 -2
  72. package/assets/docs/tree/templates.doc.mjs +1 -1
  73. package/assets/docs/tree/test-in-an-app.doc.mjs +3 -3
  74. package/assets/docs/tree/test-template-in-app.doc.mjs +1 -1
  75. package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
  76. package/assets/docs/tree/troubleshooting.doc.mjs +4 -4
  77. package/assets/docs/tree/upgrading.doc.mjs +3 -3
  78. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +3 -1
  79. package/assets/docs/tree/verify-packed-template.doc.mjs +1 -1
  80. package/assets/docs/tree/versioning.doc.mjs +6 -6
  81. package/assets/docs/tree/write-the-template-file.doc.mjs +2 -2
  82. package/authoring/codemod/codemod.doc.mjs +7 -3
  83. package/authoring/config/config.doc.mjs +9 -6
  84. package/authoring/config/type.ts +4 -2
  85. package/authoring/discover/discover.doc.mjs +1 -1
  86. package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
  87. package/authoring/doctypes/command/command.doc.mjs +14 -12
  88. package/authoring/doctypes/component/component.doc.mjs +28 -25
  89. package/authoring/doctypes/component/type.ts +7 -5
  90. package/authoring/doctypes/enum/enum.doc.mjs +7 -4
  91. package/authoring/doctypes/function/function.doc.mjs +9 -8
  92. package/authoring/doctypes/hook/hook.doc.mjs +5 -4
  93. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
  94. package/authoring/doctypes/reference/reference.doc.mjs +11 -10
  95. package/authoring/doctypes/schema/schema.doc.mjs +9 -9
  96. package/authoring/doctypes/template/integration-template.doc.mjs +1 -1
  97. package/authoring/doctypes/template/template.doc.mjs +3 -3
  98. package/authoring/doctypes/theme/theme.doc.mjs +2 -2
  99. package/authoring/gap-report/gap-report.doc.mjs +2 -2
  100. package/authoring/identity/identity.doc.mjs +3 -3
  101. package/authoring/integration/integration.doc.mjs +4 -3
  102. package/clients/cli/commands/build-theme.path-safety.test.mjs +155 -21
  103. package/clients/cli/commands/doctor-integration-components.doc.mjs +8 -3
  104. package/clients/cli/commands/doctor-integration-validate.doc.mjs +11 -2
  105. package/clients/cli/commands/doctor-integration.test.mjs +447 -2
  106. package/clients/cli/commands/doctor.mjs +116 -0
  107. package/clients/cli/commands/integration-check.doc.mjs +85 -0
  108. package/clients/cli/commands/integration-check.test.mjs +267 -0
  109. package/clients/cli/commands/integration.doc.mjs +6 -2
  110. package/clients/cli/commands/integration.mjs +107 -1
  111. package/clients/cli/commands/text-json-parity.test.mjs +5 -0
  112. package/clients/cli/commands/theme-build.doc.mjs +2 -2
  113. package/clients/cli/index.mjs +1 -0
  114. package/foundation/discovery/authoring-self-docs.mjs +1 -1
  115. package/foundation/discovery/doc-types.mjs +2 -2
  116. package/foundation/discovery/integration-doc-files.d.mts +22 -0
  117. package/foundation/discovery/integration-doc-files.mjs +231 -0
  118. package/foundation/discovery/integration-doc-files.test.mjs +246 -0
  119. package/foundation/discovery/prop-drift.d.mts +61 -3
  120. package/foundation/discovery/prop-drift.mjs +559 -61
  121. package/foundation/discovery/prop-drift.test.mjs +1032 -10
  122. package/foundation/doc-compiler/doc-loads.test.mjs +2 -0
  123. package/foundation/response/response-types.doc.mjs +7 -2
  124. package/package.json +9 -9
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/codemods`: add codemods to an
4
+ * @file `astryx docs cli/integrations/building-blocks/codemods`: add codemods to an
5
5
  * integration package, and know which of them `astryx upgrade` runs in an app.
6
6
  */
7
7
 
@@ -82,7 +82,7 @@ export default {
82
82
  },
83
83
  {
84
84
  type: 'prose',
85
- text: "`type: 'code'` rewrites the app's source files that match `fileExtensions`. `type: 'config'` rewrites the app's `astryx.config` file instead, and runs before code codemods. `title` shows in the upgrade output, and `api.jscodeshift` is a jscodeshift instance for the file. Every field is in {@link generic:authoring}.",
85
+ text: "`type: 'code'` rewrites the app's source files that match `fileExtensions`. `type: 'config'` rewrites the app's `astryx.config` file instead, and runs before code codemods. `title` shows in the upgrade output, and `api.jscodeshift` is a jscodeshift instance for the file. Every field is in {@link schema:codemod}.",
86
86
  },
87
87
  ],
88
88
  },
@@ -124,14 +124,14 @@ npx astryx upgrade --from 0.6.3 --integration @acme/astryx-widgets --apply`,
124
124
  type: 'code',
125
125
  lang: 'text',
126
126
  code: `Integrations: @acme/astryx-widgets
127
- 1 codemod to run (dry run)
127
+ <n> codemods to run (dry run)
128
128
  Applying integration codemods...
129
129
  Rename AcmeCarousel delay to interval (v0.7.0, @acme/astryx-widgets)
130
130
  ! ~ src/Hero.tsx (would change)`,
131
131
  },
132
132
  {
133
133
  type: 'prose',
134
- text: "The count includes Core's codemods for the same versions, which run first and print above `Integrations:`. To run only yours, as when you test it, add `--codemod rename-delay`.",
134
+ text: "`<n>` counts Core's codemods for the same versions too: they run first and print above `Integrations:`. To run only yours, as when you test it, add `--codemod rename-delay`.",
135
135
  },
136
136
  {
137
137
  type: 'prose',
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/components/describe-the-component/component-family`:
4
+ * @file `astryx docs cli/integrations/building-blocks/components/describe-the-component/component-family`:
5
5
  * author one ComponentDoc for several public exports in a component family.
6
6
  */
7
7
 
@@ -38,10 +38,8 @@ export const docs = {
38
38
  ],
39
39
  },
40
40
  {
41
- type: 'reference',
42
- target: 'schema:component-doc',
43
- projection: {fields: ['components']},
44
- presentation: 'full',
41
+ type: 'prose',
42
+ text: 'Every field is in {@link schema:component-doc}.',
45
43
  },
46
44
  ],
47
45
  },
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/components/component-imports`: make an
4
+ * @file `astryx docs cli/integrations/building-blocks/components/component-imports`: make an
5
5
  * integration component's documented import resolve from the packed package.
6
6
  */
7
7
 
@@ -51,7 +51,7 @@ export const docs = {
51
51
  content: [
52
52
  {
53
53
  type: 'prose',
54
- text: '`integration verify` installs the packed package in a temporary app, resolves each documented import, and checks that the module exports the documented component name.',
54
+ text: '`integration verify` unpacks the packed package into a temporary app, resolves each documented import, and checks that the module exports the documented component name. Its `--json` output names each failure by code.',
55
55
  },
56
56
  {
57
57
  type: 'code',
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/components`: guides for adding and
4
+ * @file `astryx docs cli/integrations/building-blocks/components`: guides for adding and
5
5
  * documenting components in an integration package.
6
6
  */
7
7
 
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/debug-and-gap-reports`: receive a record
4
+ * @file `astryx docs cli/integrations/building-blocks/configuration/debug-and-gap-reports`: receive a record
5
5
  * of each CLI run with `debug`, and handle `astryx gap-report` with
6
6
  * `gapReport`, both named exports of the integration manifest.
7
7
  */
@@ -44,7 +44,7 @@ export default {
44
44
  },
45
45
  {
46
46
  type: 'prose',
47
- text: 'The event is a `DebugEvent` with `command`, `outcome`, `exitCode`, `durationMs`, `error`, and more, its values scrubbed (`redacted: true`). Every field is in {@link generic:authoring}.',
47
+ text: 'The event is a `DebugEvent` with `command`, `outcome`, `exitCode`, `durationMs`, `error`, and more, its values scrubbed (`redacted: true`). Every field is in {@link schema:debug-event}.',
48
48
  },
49
49
  {
50
50
  type: 'prose',
@@ -104,22 +104,11 @@ export const gapReport = {
104
104
  },
105
105
  {
106
106
  type: 'prose',
107
- text: 'Every handler in the app gets every report, so check `report.target.package` and skip reports about other packages. The receipt `status` is one of:',
108
- },
109
- {
110
- type: 'table',
111
- headers: ['`status`', 'Meaning'],
112
- rows: [
113
- [
114
- '`filed`',
115
- 'You created or queued the report. Return `url` or `message`.',
116
- ],
117
- [
118
- '`routed_only`',
119
- 'You point the caller to where to file it. `url` is required.',
120
- ],
121
- ['`skipped`', 'You chose not to act, for example on a duplicate.'],
122
- ],
107
+ text: 'Every handler in the app gets every report, so check `report.target.package` and skip reports about other packages.',
108
+ },
109
+ {
110
+ type: 'prose',
111
+ text: 'Every field is in {@link schema:gap-report-handler}.',
123
112
  },
124
113
  {
125
114
  type: 'prose',
@@ -45,7 +45,7 @@ export const oceanTheme = defineTheme({
45
45
  },
46
46
  {
47
47
  type: 'prose',
48
- text: 'Local imports must stay inside the theme folder. One that leaves it, such as `../../shared/colors`, fails with `invalid_theme`, and the theme disappears from `theme list`. `npx astryx theme template` writes a file that explains every `defineTheme` field. For the full token set, scope selectors, and component theming, read {@link generic:author-a-theme}.',
48
+ text: 'Local imports must stay inside the theme folder. One that leaves it, such as `../../shared/colors`, fails with `invalid_theme`, and every theme in the package disappears from `theme list`. `npx astryx theme template` writes a file that explains every `defineTheme` field. For the full token set and component theming, read {@link generic:author-a-theme}.',
49
49
  },
50
50
  ],
51
51
  },
@@ -55,13 +55,14 @@ export const oceanTheme = defineTheme({
55
55
  content: [
56
56
  {
57
57
  type: 'prose',
58
- text: 'To base a theme on an existing one, `extends` it: import the base theme and override only the tokens you change. The derived theme keeps a live link to the base and inherits its later changes — unlike `--from`, which forks a copy ({@link generic:add-a-theme}).',
58
+ text: 'To base a theme on an existing one, `extends` it: import the base theme and override only the tokens you change. Add the derived theme with `integration add theme ocean-contrast`, and import the base from its built package export, since local imports cannot leave the theme folder. The derived theme keeps a live link to the base and picks up its later changes when you rebuild it — unlike `--from`, which forks a copy ({@link generic:add-a-theme}).',
59
59
  },
60
60
  {
61
61
  type: 'code',
62
62
  lang: 'ts',
63
- code: `import {defineTheme} from '@astryxdesign/core/theme';
64
- import {oceanTheme} from './oceanTheme';
63
+ code: `// themes/ocean-contrast/oceanContrastTheme.ts
64
+ import {defineTheme} from '@astryxdesign/core/theme';
65
+ import {oceanTheme} from '@acme/astryx-widgets/themes/ocean';
65
66
 
66
67
  export const oceanContrastTheme = defineTheme({
67
68
  name: 'ocean-contrast',
@@ -79,7 +80,7 @@ export const oceanContrastTheme = defineTheme({
79
80
  content: [
80
81
  {
81
82
  type: 'prose',
82
- text: 'Each `[light, dark]` pair compiles to a `light-dark()` value, which switches only colors. Give it colors. For a value that is not a plain color — a gradient — put `light-dark()` on each color stop, not around the whole value: a browser without `light-dark()` drops the declaration, and the stop form is the one that degrades safely.',
83
+ text: 'Each `[light, dark]` pair compiles to a `light-dark()` value, which switches only colors. Give it colors. For a value that is not a plain color — a gradient — put `light-dark()` on each color stop, not around the whole value: `light-dark()` takes two colors, so wrapping whole gradients makes the value invalid where the token is used, and `theme build` does not warn.',
83
84
  },
84
85
  ],
85
86
  },
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/components/describe-the-component`:
4
+ * @file `astryx docs cli/integrations/building-blocks/components/describe-the-component`:
5
5
  * choose and maintain the ComponentDoc shape that matches a component's public
6
6
  * source.
7
7
  */
@@ -1,9 +1,9 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/docs`: the guides to writing docs for an
5
- * integration package, which join the same docs tree as the CLI's own
6
- * (spec:AST-046, spec:AST-047).
4
+ * @file `astryx docs cli/integrations/building-blocks/docs`: the guides to
5
+ * writing docs for an integration package, which join the same docs tree as
6
+ * the CLI's own (spec:AST-046, spec:AST-047).
7
7
  */
8
8
 
9
9
  /** @type {import('@astryxdesign/cli/authoring').NamespaceDoc} */
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/templates/document-the-template`:
4
+ * @file `astryx docs cli/integrations/building-blocks/templates/document-the-template`:
5
5
  * document page and block templates for discovery and correct reuse.
6
6
  */
7
7
 
@@ -50,7 +50,7 @@ export default {
50
50
  },
51
51
  {
52
52
  type: 'prose',
53
- text: 'Keep the section short: how to install the package, run `theme add`, apply the generated module ({@link generic:use-a-theme-in-an-app}), and customize with `extends`. When the theme uses a custom font, name the families and the optional exported font stylesheet that `theme add` imports ({@link generic:fonts-and-assets}). Extend `theme` rather than a topic another package replaces, or an app that lists that package first drops your section.',
53
+ text: 'Keep the section short: how to install the package, run `theme add`, apply the generated module ({@link generic:use-a-theme-in-an-app}), and customize with `extends`. When the theme uses a custom font, name the families and the optional exported font stylesheet that `theme add` imports ({@link generic:fonts-and-assets}). Extend `theme` rather than a topic another package replaces, or an app that loads that package after yours drops your section.',
54
54
  },
55
55
  ],
56
56
  },
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/templates/build-the-template/package-and-test/export-template-assets`:
4
+ * @file `astryx docs cli/integrations/building-blocks/templates/build-the-template/package-and-test/export-template-assets`:
5
5
  * expose and include everything a copied template imports, and declare the
6
6
  * packages it needs.
7
7
  */
@@ -1,9 +1,9 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/docs/extend-or-replace`: take over an
5
- * existing topic with `replaces`, merge sections into one with `extends`, and
6
- * check overlaps with Core topics.
4
+ * @file `astryx docs cli/integrations/building-blocks/docs/extend-or-replace`:
5
+ * take over an existing topic with `replaces`, merge sections into one with
6
+ * `extends`, and check overlaps with Core topics.
7
7
  */
8
8
 
9
9
  /** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
@@ -46,7 +46,7 @@ export const docs = {
46
46
  content: [
47
47
  {
48
48
  type: 'prose',
49
- text: 'Set `extends` to merge sections into an existing topic instead of owning it. A section with the same key replaces the base section, and a new section is added at the end.',
49
+ text: 'Set `extends` to merge sections into an existing topic instead of owning it. A section replaces the base section it matches, and a section that matches none is added at the end.',
50
50
  },
51
51
  {
52
52
  type: 'code',
@@ -63,7 +63,7 @@ export const docs = {
63
63
  type: 'list',
64
64
  style: 'unordered',
65
65
  items: [
66
- "A section's key is its `id`, or a key made from its title. Read the base topic's keys with `--index`.",
66
+ "Read the base topic's keys with `--index`, and give a section that replaces one that key as its `id`. A section without an `id` matches only a base section with exactly its title, or one whose `id` is the key its title makes, so `Integration Themes` is added beside a base `Integration themes` that has no `id`.",
67
67
  "The topic keeps the base's title and description, and readers open it by the base's name.",
68
68
  'Replace the `Overview` placeholder that `integration add` writes, or it is added to the base topic.',
69
69
  "Extend a topic to correct or add to it. A copy made with `replaces` stops getting the owner's fixes.",
@@ -87,7 +87,7 @@ export const docs = {
87
87
  {
88
88
  type: 'code',
89
89
  lang: 'text',
90
- code: 'severity: [info]\ntopic: acme-getting-started\nrelationship: replaces\ncoreTopic: getting-started\nmessage: Intentional override: "acme-getting-started" replaces the Core topic "getting-started".\n\nseverity: [fail]\ntopic: tokens\nrelationship: accidental\ncoreTopic: tokens\nmessage: Accidental conflict: "tokens" is already a Core topic. Rename it, declare replaces: \'tokens\' to take it over, or declare extends: \'tokens\' to merge sections.',
90
+ code: 'severity: [info]\ntopic: acme-getting-started\nrelationship: replaces\ncoreTopic: getting-started\nmessage: Intentional override: "acme-getting-started" replaces the Core topic "getting-started".\n\nseverity: [fail]\ntopic: color\nrelationship: accidental\ncoreTopic: color\nmessage: Accidental conflict: "color" is already a Core topic. Rename it, declare replaces: \'color\' to take it over, or declare extends: \'color\' to merge sections.',
91
91
  },
92
92
  {
93
93
  type: 'list',
@@ -61,7 +61,7 @@ export const oceanTheme = defineTheme({
61
61
  },
62
62
  {
63
63
  type: 'prose',
64
- text: 'The stylesheet can contain self-hosted `@font-face` rules or import a hosted stylesheet. A hosted `@import` is simple, but it delays loading compared with a preconnected `<link>`; choose that trade-off deliberately. If the app loads the same family outside the generated module, Doctor warns because it cannot prove the loader, but the warning does not fail the app.',
64
+ text: 'The stylesheet can contain self-hosted `@font-face` rules or import a hosted stylesheet. A hosted `@import` is simple, but it delays loading compared with a preconnected `<link>`; choose that trade-off deliberately. Doctor warns when it cannot prove the loader — a hosted `@import`, or no font stylesheet while the app loads the family itself — but the warning does not fail the app.',
65
65
  },
66
66
  {
67
67
  type: 'code',
@@ -83,7 +83,7 @@ export const oceanTheme = defineTheme({
83
83
  'Load every weight and style the theme uses. Do not let the browser synthesize bold or italic.',
84
84
  'Include self-hosted font files and their licenses in the packed package.',
85
85
  'Keep CSS and font assets side-effectful so a bundler does not remove the loader.',
86
- 'Run `integration verify`; it fails when an exported font stylesheet or one of its packed files cannot resolve.',
86
+ 'Run `integration verify`; it fails when an exported font stylesheet cannot resolve, but it does not check the font files the stylesheet names.',
87
87
  ],
88
88
  },
89
89
  ],
@@ -21,7 +21,7 @@ export const docs = {
21
21
  content: [
22
22
  {
23
23
  type: 'prose',
24
- text: 'A theme needs dozens of related colors — shades of each brand color for backgrounds, borders, text, and states, in both light and dark mode. A palette is that full set of shades. Rather than hand-pick every one, you name a few seed colors and generate the rest, so the shades stay consistent and keep enough contrast to read.',
24
+ text: 'A theme needs dozens of related colors — shades of each brand color for backgrounds, borders, text, and states, in both light and dark mode. A palette is that full set of shades. Rather than hand-pick every one, you name a few seed colors and generate the rest, so the shades stay consistent.',
25
25
  },
26
26
  {
27
27
  type: 'prose',
@@ -50,7 +50,9 @@ npx astryx theme palette generate themes/ocean/palette.config.json \\
50
50
  lang: 'text',
51
51
  code: `[ok] Wrote themes/ocean/tokens/ocean.palette.ts
52
52
 
53
- [ok] Wrote themes/ocean/tokens/ocean.palette.receipt.json`,
53
+ [ok] Wrote themes/ocean/tokens/ocean.palette.receipt.json
54
+
55
+ Review and edit the candidate before adopting it as theme-owned palette data.`,
54
56
  },
55
57
  {
56
58
  type: 'prose',
@@ -58,7 +60,7 @@ npx astryx theme palette generate themes/ocean/palette.config.json \\
58
60
  },
59
61
  {
60
62
  type: 'prose',
61
- text: 'Add `--preview <file>.html` to also get a web page showing every shade, so you can eyeball the palette in a browser. Write it outside `themes/` so it does not ship in your package. The full list of config fields and options is in {@link command:theme palette generate}.',
63
+ text: 'Add `--preview <file>.html` to also get a web page showing every shade, so you can eyeball the palette in a browser. Write it outside `themes/` so it does not ship in your package. Every option is in {@link command:theme palette generate}, and the config it reads is described in {@link function:generateTonalPalette}.',
62
64
  },
63
65
  ],
64
66
  },
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/building-blocks/templates/grade-template-with-agent`:
4
+ * @file `astryx docs cli/integrations/building-blocks/templates/write-good-templates/grade-template-with-agent`:
5
5
  * give an agent the canonical rubric and require a reproducible template grade.
6
6
  */
7
7
 
@@ -36,5 +36,13 @@ export const docs = {
36
36
  type: 'prose',
37
37
  text: 'An integration can also replace a built-in template or doc. To start, install `@astryxdesign/cli` and open {@link generic:quick-start}.',
38
38
  },
39
+ {
40
+ type: 'prose',
41
+ text: 'Every field of every file you write for an integration is in {@link generic:authoring}.',
42
+ },
43
+ {
44
+ type: 'prose',
45
+ text: "Every integration runs `astryx integration check --strict` in its own build: it is required, not optional, so a doc, prop, or link that stops matching the code fails your build instead of your users' apps. See {@link generic:checks}.",
46
+ },
39
47
  ],
40
48
  };
@@ -1,8 +1,9 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/docs/links`: link one doc to another by
5
- * identity, link the CLI's docs, and fix a link that names no doc.
4
+ * @file `astryx docs cli/integrations/building-blocks/docs/links`: link one doc
5
+ * to another by identity, link the CLI's docs, and fix a link that names no
6
+ * doc.
6
7
  */
7
8
 
8
9
  /** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
@@ -36,7 +37,7 @@ export const docs = {
36
37
  type: 'list',
37
38
  style: 'unordered',
38
39
  items: [
39
- 'The kind is `generic` for a topic or guide, `namespace` for a docs section, `command` or `function` for a CLI command or API function, `component` for a component, and `page` or `block` for a template.',
40
+ 'The kind is `generic` for a topic or guide, `namespace` for a docs section, `command` or `function` for a CLI command or API function, `schema` or `enum` for a schema or a fixed set of values, `component` for a component, and `page` or `block` for a template.',
40
41
  'Name a component by its export name and a template by its id. Its link reads as the command that opens it, such as `astryx component AcmeCarousel --package @acme/widgets`.',
41
42
  'Inside backticks or a code block, link syntax prints as written.',
42
43
  ],
@@ -89,7 +90,7 @@ export const docs = {
89
90
  style: 'unordered',
90
91
  items: [
91
92
  'The warning keeps exit code 0, so read the report before you ship; see {@link generic:check-your-docs}.',
92
- 'A stable CLI before 0.7.0 does not read links: it prints each one as written. See {@link generic:versioning}.',
93
+ 'Published 0.6.4 and later read links. An older CLI, such as published 0.6.3, prints each one as written; see {@link generic:versioning}.',
93
94
  ],
94
95
  },
95
96
  ],
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/templates/package-and-test`:
4
+ * @file `astryx docs cli/integrations/building-blocks/templates/build-the-template/package-and-test`:
5
5
  * expose a template from its package and prove the copied result in an app.
6
6
  */
7
7
 
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/templates/document-the-template/page-template`:
4
+ * @file `astryx docs cli/integrations/building-blocks/templates/document-the-template/page-template`:
5
5
  * the page-only fields that help people find a page.
6
6
  */
7
7
 
@@ -31,7 +31,7 @@ export const docs = {
31
31
  type: 'code',
32
32
  lang: 'javascript',
33
33
  label: 'templates/acme-dashboard.doc.mjs',
34
- code: `/** @type {import('@astryxdesign/cli/authoring').TemplateDoc} */
34
+ code: `/** @type {import('@astryxdesign/cli/authoring').IntegrationTemplateDoc} */
35
35
  export default {
36
36
  type: 'page',
37
37
  name: 'acme-dashboard',
@@ -49,12 +49,8 @@ export default {
49
49
  title: 'Help people find the page',
50
50
  content: [
51
51
  {
52
- type: 'reference',
53
- target: 'schema:template-doc',
54
- projection: {
55
- fields: ['category', 'scaffold'],
56
- },
57
- presentation: 'full',
52
+ type: 'prose',
53
+ text: 'Every field is in {@link schema:template-doc}.',
58
54
  },
59
55
  {
60
56
  type: 'list',
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/publishing`: publish an integration to
4
+ * @file `astryx docs cli/integrations/ship/publishing`: publish an integration to
5
5
  * npm, use release tags, and check the package before and after.
6
6
  */
7
7
 
@@ -34,20 +34,22 @@ export const docs = {
34
34
  },
35
35
  {
36
36
  type: 'prose',
37
- text: 'An integration starts as a normal npm package. Make a folder for it, create a package.json inside that folder, give the package a name, then install the Astryx CLI and Core for development.',
37
+ text: 'An integration starts as a normal npm package. Make a folder for it, create a package.json inside that folder, give the package a name, make it an ES module, then install the Astryx CLI, Core, and TypeScript for development.',
38
38
  },
39
39
  {
40
40
  type: 'code',
41
41
  lang: 'bash',
42
- code: "mkdir acme-widgets && cd acme-widgets\nnpm init -y\nnpm pkg set name=@acme/astryx-widgets\nnpm pkg set 'exports={}' --json\nnpm install -D @astryxdesign/cli @astryxdesign/core",
42
+ code: "mkdir acme-widgets && cd acme-widgets\nnpm init -y\nnpm pkg set name=@acme/astryx-widgets type=module\nnpm pkg set 'exports={}' --json\nnpm install -D @astryxdesign/cli @astryxdesign/core typescript@6",
43
43
  },
44
44
  {
45
45
  type: 'list',
46
46
  style: 'unordered',
47
47
  items: [
48
+ 'Set `"type": "module"`: the `.js` files the CLI generates, such as a built theme, are ES modules, and Node fails to load them in a package marked `"type": "commonjs"`, which `npm init -y` writes on npm 11.',
48
49
  'Start with `"exports": {}`: each component and template you add then writes the public import that `integration verify` resolves.',
49
50
  'Run the CLI as `npx astryx`, which runs the `@astryxdesign/cli` you installed as a devDependency.',
50
51
  'Component commands read Core, so they need `@astryxdesign/core` installed.',
52
+ "The checks compare your docs with your code through TypeScript's JavaScript compiler API, so they need `typescript` 5.0 through 6 installed. TypeScript 7 does not ship that API, and with it the checks skip those comparisons.",
51
53
  ],
52
54
  },
53
55
  {
@@ -86,6 +88,33 @@ export const docs = {
86
88
  type: 'prose',
87
89
  text: 'You now have an integration package with one exported component.',
88
90
  },
91
+ {
92
+ type: 'heading',
93
+ level: 3,
94
+ text: 'Check it in every build (required)',
95
+ },
96
+ {
97
+ type: 'prose',
98
+ text: 'Every integration runs `integration check --strict` in its own build, so a doc, prop, template, or link that stops matching the code fails your build instead of reaching the apps that install your package. Set it up now, as the `typecheck` script, and run it.',
99
+ },
100
+ {
101
+ type: 'code',
102
+ lang: 'bash',
103
+ code: 'npm pkg set scripts.typecheck="astryx integration check --strict"\nnpm run typecheck',
104
+ },
105
+ {
106
+ type: 'code',
107
+ lang: 'text',
108
+ code: '[ok] 0 errors, 0 warnings, 0 skipped. Every check passed.',
109
+ },
110
+ {
111
+ type: 'list',
112
+ style: 'unordered',
113
+ items: [
114
+ 'Run `typecheck` in CI and before every publish. When you add a `tsconfig.json`, put `tsc --noEmit && ` in front of the check so the same script checks your types.',
115
+ 'What each check covers, and what `--strict` adds: {@link generic:checks}.',
116
+ ],
117
+ },
89
118
  {
90
119
  type: 'heading',
91
120
  level: 3,
@@ -172,19 +201,19 @@ export const docs = {
172
201
  ],
173
202
  [
174
203
  '`peerDependencies`',
175
- '`@astryxdesign/cli`; add `@astryxdesign/core` when your code imports it',
204
+ '`@astryxdesign/core` when your code imports it; `@astryxdesign/cli`, optional, when you ship a feature that needs a newer CLI ({@link generic:versioning})',
176
205
  'The app supplies these packages for your integration.',
177
206
  ],
178
207
  [
179
208
  '`devDependencies`',
180
- '`@astryxdesign/cli` and `@astryxdesign/core`',
181
- 'Lets you run the CLI and build components while working on the integration.',
209
+ '`@astryxdesign/cli`, `@astryxdesign/core`, and `typescript`',
210
+ 'Lets you run the CLI, build components, and run the checks while working on the integration.',
182
211
  ],
183
212
  ],
184
213
  },
185
214
  {
186
215
  type: 'prose',
187
- text: 'Peer ranges and releases are covered in {@link generic:versioning}; `files` and publishing in {@link generic:publishing}.',
216
+ text: 'Peer ranges and releases are covered in {@link generic:versioning}; `files` and publishing in {@link generic:publishing}. Add `"typecheck": "tsc --noEmit && astryx integration check --strict"` to `scripts` so each run checks your types and that your docs, props, and links still match the code. It needs `typescript` and a `tsconfig.json`; see {@link generic:checks}.',
188
217
  },
189
218
  ],
190
219
  },
@@ -226,21 +255,8 @@ export const docs = {
226
255
  text: 'The file tells the CLI where this package keeps its integration items. Edit it only when you want a custom root or another optional setting. Paths are relative to package.json, and later adds keep a custom path you already set.',
227
256
  },
228
257
  {
229
- type: 'reference',
230
- target: 'schema:integration',
231
- projection: {
232
- fields: [
233
- 'providerId',
234
- 'components',
235
- 'templates',
236
- 'codemods',
237
- 'docs',
238
- 'themes',
239
- 'agentDocs',
240
- 'issuesUrl',
241
- ],
242
- },
243
- presentation: 'full',
258
+ type: 'prose',
259
+ text: 'Every field is in {@link schema:integration}.',
244
260
  },
245
261
  {
246
262
  type: 'heading',
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/components/replace-a-core-component`:
4
+ * @file `astryx docs cli/integrations/building-blocks/components/replace-a-core-component`:
5
5
  * intentionally make an integration component the default for a Core identity.
6
6
  */
7
7
 
@@ -65,10 +65,8 @@ export default {
65
65
  };`,
66
66
  },
67
67
  {
68
- type: 'reference',
69
- target: 'schema:component-doc',
70
- projection: {fields: ['replaces']},
71
- presentation: 'full',
68
+ type: 'prose',
69
+ text: 'Every field is in {@link schema:component-doc}.',
72
70
  },
73
71
  {
74
72
  type: 'prose',
@@ -87,7 +85,7 @@ export default {
87
85
  type: 'list',
88
86
  style: 'unordered',
89
87
  items: [
90
- 'Any `@astryxdesign/cli` range that starts at that release or later turns it on, including the `>=0.7.0` that earlier `integration add theme` and `integration add doc --parent` wrote.',
88
+ 'Any `@astryxdesign/cli` range that starts at that release or later turns it on, including the `>=0.7.0` that `integration add doc --parent` wrote in published 0.6.4 and 0.6.5, and `integration add theme` in published 0.6.5.',
91
89
  'Without such a range, the component keeps its own name, the Core component stays selected (a component named like its target stays ambiguous by that bare name, as before), and `doctor integration components` warns with the range to add. Apps that load such a package see no change.',
92
90
  '`replaces` names the Core `ComponentDoc` identity, not its display label, import path, or a standalone hook.',
93
91
  'Your component may keep a distinct name or use the same name as the target. A distinct name remains directly addressable on older CLIs that ignore `replaces`.',
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file `astryx docs cli/integrations/templates/document-the-template/replace-a-core-template`:
4
+ * @file `astryx docs cli/integrations/building-blocks/templates/document-the-template/replace-a-core-template`:
5
5
  * deliberately replace one Core template through template metadata.
6
6
  */
7
7
 
@@ -54,7 +54,7 @@ export const docs = {
54
54
  type: 'code',
55
55
  lang: 'javascript',
56
56
  label: 'templates/acme-app-shell.doc.mjs',
57
- code: `/** @type {import('@astryxdesign/cli/authoring').TemplateDoc} */
57
+ code: `/** @type {import('@astryxdesign/cli/authoring').IntegrationTemplateDoc} */
58
58
  export default {
59
59
  type: 'page',
60
60
  name: 'acme-app-shell',
@@ -67,10 +67,8 @@ export default {
67
67
  };`,
68
68
  },
69
69
  {
70
- type: 'reference',
71
- target: 'schema:template-doc',
72
- projection: {fields: ['replaces']},
73
- presentation: 'full',
70
+ type: 'prose',
71
+ text: 'Every field is in {@link schema:template-doc}.',
74
72
  },
75
73
  {
76
74
  type: 'prose',
@@ -84,7 +82,7 @@ export default {
84
82
  content: [
85
83
  {
86
84
  type: 'prose',
87
- text: 'Declare the CLI floor from the field above as an optional peer ({@link generic:versioning}).',
85
+ text: 'Declare the CLI floor that `integration verify` names as an optional peer ({@link generic:versioning}).',
88
86
  },
89
87
  {
90
88
  type: 'code',
@@ -103,7 +101,7 @@ export default {
103
101
  },
104
102
  {
105
103
  type: 'prose',
106
- text: '`integration verify` reports `replaces_needs_cli` when that peer is missing or too old. Without it, an older CLI drops that template and hides your doc topics.',
104
+ text: '`integration verify` reports `replaces_needs_cli` when that peer is missing or too old. Without it, published 0.6.3 and earlier drop that template and hide your doc topics.',
107
105
  },
108
106
  ],
109
107
  },