@astryxdesign/cli 0.7.11-canary.ed0adf3 → 0.7.12-canary.ccb4a6d

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 (79) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/api/build/kit/rank.mjs +21 -4
  3. package/api/build/kit/words.d.mts +1 -0
  4. package/api/build/kit/words.mjs +1 -1
  5. package/api/icon/_adapter.d.mts +3 -2
  6. package/api/icon/_adapter.mjs +8 -2
  7. package/api/icon/_authoring.d.mts +1 -0
  8. package/api/icon/_authoring.mjs +586 -66
  9. package/api/icon/_default-look.d.mts +155 -0
  10. package/api/icon/_default-look.mjs +474 -0
  11. package/api/icon/_records.d.mts +1 -1
  12. package/api/icon/_records.mjs +1 -0
  13. package/api/icon/add/add.mjs +224 -38
  14. package/api/icon/icon.type.d.mts +22 -2
  15. package/api/icon/icon.type.mjs +6 -2
  16. package/api/icon/iconAdd.doc.mjs +2 -2
  17. package/api/icon/iconNewDefinition.doc.mjs +3 -2
  18. package/api/icon/iconNewSet.doc.mjs +4 -4
  19. package/api/icon/search/search.mjs +10 -9
  20. package/api/integration/add-helpers.d.mts +11 -1
  21. package/api/integration/add-helpers.mjs +5 -2
  22. package/api/integration/authoring-checks.d.mts +0 -2
  23. package/api/integration/authoring-checks.mjs +1 -6
  24. package/api/logger.mjs +2 -1
  25. package/api/swizzle/_adapter.d.mts +1 -0
  26. package/api/swizzle/_adapter.mjs +4 -1
  27. package/api/swizzle/_moduleGraph.d.mts +171 -0
  28. package/api/swizzle/_moduleGraph.mjs +795 -0
  29. package/api/swizzle/copy/copy.d.mts +2 -43
  30. package/api/swizzle/copy/copy.mjs +195 -314
  31. package/api/swizzle/swizzle.d.mts +0 -2
  32. package/api/swizzle/swizzle.doc.mjs +9 -4
  33. package/api/swizzle/swizzle.mjs +3 -7
  34. package/api/swizzle/swizzle.type.d.mts +2 -1
  35. package/api/swizzle/swizzle.type.mjs +3 -2
  36. package/assets/discover/official-packages.json +20 -0
  37. package/assets/docs/tree/icon-sets.doc.mjs +11 -5
  38. package/assets/templates/blocks/components/Table/TableLeadingMarkSelection.doc.mjs +15 -0
  39. package/assets/templates/blocks/components/Table/TableLeadingMarkSelection.tsx +134 -0
  40. package/assets/templates/blocks/components/Table/TableRowIndexTable.doc.mjs +1 -1
  41. package/assets/templates/blocks/components/Table/TableRowIndexTable.tsx +2 -2
  42. package/assets/templates/pages/course-detail/page.tsx +699 -0
  43. package/assets/templates/pages/course-detail/template.doc.mjs +37 -0
  44. package/assets/templates/pages/file-explorer/page.tsx +103 -79
  45. package/assets/templates/pages/table-grouped/page.tsx +160 -232
  46. package/assets/templates/pages/table-grouped/template.doc.mjs +0 -2
  47. package/assets/templates/pages/theme-showcase/page.tsx +724 -792
  48. package/assets/templates/pages/theme-showcase/template.doc.mjs +4 -5
  49. package/authoring/doctypes/_schema.d.mts +1 -1
  50. package/authoring/doctypes/template/type.ts +1 -0
  51. package/clients/cli/commands/build.mjs +34 -5
  52. package/clients/cli/commands/experimental/icon.mjs +31 -10
  53. package/clients/cli/commands/experimental-icon-add.doc.mjs +1 -1
  54. package/clients/cli/commands/experimental-icon-new-definition.doc.mjs +2 -1
  55. package/clients/cli/commands/experimental-icon-new-set.doc.mjs +2 -2
  56. package/clients/cli/commands/swizzle.doc.mjs +8 -3
  57. package/clients/cli/commands/swizzle.mjs +21 -9
  58. package/clients/cli/index.mjs +36 -7
  59. package/foundation/discovery/component-loader.d.mts +1 -1
  60. package/foundation/discovery/doc-types.mjs +9 -2
  61. package/foundation/discovery/icon-ranking.d.mts +27 -3
  62. package/foundation/discovery/icon-ranking.mjs +125 -8
  63. package/foundation/discovery/icon-set-checks.mjs +44 -35
  64. package/foundation/discovery/icon-set-discovery.d.mts +13 -0
  65. package/foundation/discovery/icon-set-discovery.mjs +25 -0
  66. package/foundation/discovery/icon-set-writer.d.mts +238 -16
  67. package/foundation/discovery/icon-set-writer.mjs +676 -79
  68. package/foundation/discovery/module-exports.d.mts +62 -3
  69. package/foundation/discovery/module-exports.mjs +384 -58
  70. package/foundation/env/package-manager.d.mts +12 -4
  71. package/foundation/env/package-manager.mjs +15 -6
  72. package/foundation/env/semver.mjs +41 -9
  73. package/foundation/fs/paths.d.mts +2 -1
  74. package/foundation/fs/paths.mjs +3 -4
  75. package/foundation/release/notices.d.mts +16 -0
  76. package/foundation/release/notices.mjs +27 -6
  77. package/foundation/text/shell-arg.d.mts +14 -0
  78. package/foundation/text/shell-arg.mjs +17 -0
  79. package/package.json +6 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,56 @@
1
1
  # @xds/cli
2
2
 
3
+ # 0.7.11
4
+
5
+ #### New Features
6
+
7
+ - `astryx build` ranks Core blocks of component families its picker was not fitted with somewhat better: the block picker's doc-side word weights are refitted from paraphrases of each block's own source. (#10355)
8
+
9
+ #### Fixes
10
+
11
+ - `astryx build` names its two alternative page templates in the same order it chooses the start from, so the three templates it shows for a whole page are its best three. The start, the number of alternatives, the blocks and the JSON shape are unchanged. (#10357)
12
+ - `astryx build --type doc` and `--type theme` now point to `astryx search <query> --type doc` or `--type theme`: a build kit has no docs or themes, so build says so once on stderr and names the search that finds them. Stdout, JSON output and exit codes are unchanged. (#10401)
13
+ - `astryx doctor` no longer warns that no theme is wired in an app that imports its themes itself. Without a generated theme module or a package.json `astryx.theme`, the `themes` check now passes when the source of the app imports a theme's built module or stylesheet (the imports `theme add` writes) or passes a theme to `Theme`, followed through module-scope variables, `defineTheme({extends})`, re-exports and installed packages to its package, and names the file. Only a theme whose package is installed, or a local theme, counts. A theme passed to `Theme` that doctor cannot trace (a prop, a function result, a variable declared inside a component) is reported as not confirmed (info), not as missing. (#10353)
14
+ - The CLI's semver range check reads `^0` as any 0.x.y and `^0.0` as any 0.0.y, and reads a hyphen range (`1.0.0 - 2.0.0`) as inclusive bounds, with a partial upper bound (`1.0.0 - 2`) covering its whole series as npm does. Before, `^0` and `^0.0` were locked to a single patch version and a hyphen range could never match, so `astryx doctor` and the peer-version checks reported a false mismatch for projects that declare those ranges. (#10184)
15
+ - The reminder to run `astryx init` in a project that has not run it no longer prints before every command. It now prints after a command that succeeds, at most once a day per project, recorded in the per-user state as the daily hints are. It does not print with `--json`, after a command that fails, or when `CI` is set. `astryx doctor` still reports the missing setup in its agent-docs check every time. No JSON shape or exit code changes. (#10343)
16
+ - In a folder inside an Astryx project whose own `package.json` declares no Astryx package, such as a tool folder that installs its own `@astryxdesign/core`, the setup reminder's `init` command now names the project's release, as run from the project's folder: the project's own CLI when it installs one, otherwise the package runner pinned to the project's Core, such as `npx @astryxdesign/cli@0.7.3 init`. It used to pin the release of the CLI that answered the run, whatever the project records. No JSON shape or exit code changes. (#10343)
17
+ - `astryx experimental render`: a page outside a project now renders. Outside a project (no Core or CLI the folder reads, and no package.json that declares one), the page takes the `@astryxdesign/*` packages its folder lacks, and the integrations a host approves, from the copy the CLI itself runs with, instead of failing with ERR_RENDER_MISSING_DEPENDENCY. React and StyleX come from that copy too, so the page loads one copy of each, even in a React app that installs its own. When that copy's Core cannot be downloaded, a page that needs it fails with ERR_VERSIONS_UNAVAILABLE, as other commands that read Core do. Inside a project, the page uses only the project's own packages. (#10362)
18
+ - A link to a topic that an integration replaces under the same name opens the replacement. In an app whose integration replaced `theme` or `getting-started`, `doctor` reported Core's links to them as naming no doc. (#10342)
19
+ - `swizzle` no longer copies a component's browser test harnesses (`*.spec.ts`, `*.spec.tsx`, such as Item's `ItemMarkerColumns.a11y.chromium.spec.ts`) when the installed Core source holds them: `@astryxdesign/core` 0.7.5 and earlier, or Core's repository source. They import Playwright and an unpublished test package, so a project that swizzled such a component failed to type-check or build. Core 0.7.6 and later ship no harnesses, so swizzling from them is unchanged. (#10230)
20
+ - `astryx theme build` no longer depends on the order it loads the core component docs. A parent doc that lists a sub-component by name only, such as `Avatar.doc.mjs` listing `AvatarStatusDot`, erased the values the sub-component's own doc declares when it loaded after that doc; when `Avatar.doc.mjs` loaded last, `avatar-status-dot` `variant:success` counted as a custom value. The build now merges every doc's entry for a component. (#10288)
21
+ - `astryx integration verify` no longer reports `theme_module_stale` for a theme whose built module differs only in the command its comment says built it, such as a theme built with `yarn astryx` and verified where `pnpm exec astryx` runs. Any other difference still fails. (#10344)
22
+
23
+ #### Performance
24
+
25
+ - A compact or full hook list, and the suggestions for an unknown hook name, list each of Core's folders once. Before, they listed a folder again for each hook they looked up. (#10324)
26
+ - A search, build or component read lists each folder once. A process that runs several reads, such as a docs site's search or an agent harness, reuses a folder's listing once the folder has stayed unchanged for two seconds. A later read lists the folder again after an entry is added, removed or renamed. (#10274)
27
+ - Within one operation, component discovery reads each component doc once, and the component matcher looks for each component's doc once, not once for each name they resolve. Resolving 30 names that only the matcher finds, such as names in another case, makes 14,794 file-system calls instead of 305,108. Results are unchanged. (#10277)
28
+
29
+ #### Documentation
30
+
31
+ - The Authoring guides (Quick Start, Field reference, Building Blocks, Ship, Help, and Make your integration work globally) now carry the keyword "authoring", so `astryx search authoring` lists them right after the Authoring overview instead of after API function pages. (#10354)
32
+ - `astryx build --help` lists every value `--type` accepts (component, hook, doc, template, theme), matching the invalid-type error and what build actually runs, and says that `doc` and `theme` give an empty kit, since the kit has no doc or theme group. A test keeps the help text, the choices, the API doc and the error message on build and search naming the same set, and checks what each value returns. (#10361)
33
+ - Getting Started has an Upgrade section: upgrade every Astryx package your app lists in one command, to the same release, then run `astryx upgrade`. If your package manager holds new releases back, exempt the whole `@astryxdesign/*` scope, not only some of its packages. (#10241)
34
+ - The custom theme guide names the files of a local theme, including the same-stem descriptor `theme add` reads. (#10347)
35
+ - The CLI's bundled colour token docs say the status icon colours (`--color-icon-<status>`) paint status marks on the page or a card, such as a StatusDot. (#10204)
36
+ - New block, "Table — Selection in the Leading Mark": row selection with no checkbox column. Each row shows its avatar, and the checkbox takes the avatar's slot while a mouse is over it, on keyboard focus, and on every row once anything is selected. On touch screens the checkbox always shows. It uses the existing `useTableSelectionState` and renders the checkboxes in the name column, so no new Table API is involved. (#10395)
37
+
38
+ #### Other Changes
39
+
40
+ - Internal: the export reader can report type-only exports and map a module's whole public surface in one pass. No change to any command's output. (#10365)
41
+
42
+ #### Contributors
43
+
44
+ Thanks to everyone who contributed to this release:
45
+
46
+ - @cixzhang
47
+ - @josephfarina
48
+ - @thecodebasedot
49
+ - @utsavo-afk
50
+ - @vjeux
51
+
52
+ ---
53
+
3
54
  # 0.7.10
4
55
 
5
56
  #### New Features
@@ -41,7 +41,9 @@
41
41
  * `settings`) is that family's default. A variant displaces it only with two
42
42
  * matched terms of its own ("a small comparison note" does not make a
43
43
  * dashboard the comparison dashboard), and a base too weak to start on its
44
- * own displaces no variant ("a funnel for a dashboard" is the funnel).
44
+ * own displaces no variant ("a funnel for a dashboard" is the funnel) —
45
+ * unless the idea names its family in the head, which is start evidence on
46
+ * its own ("saml login" stays the login page).
45
47
  */
46
48
 
47
49
  import {
@@ -219,7 +221,8 @@ export function rankPages(query, pages) {
219
221
  }
220
222
  }
221
223
  const familyNamed = namedFamilies.has(family);
222
- if (headFamilies.has(family)) score += HEAD_FAMILY;
224
+ const headNamed = headFamilies.has(family);
225
+ if (headNamed) score += HEAD_FAMILY;
223
226
  else if (familyNamed) score += BODY_FAMILY;
224
227
  const base = normalized(page.name) === normalized(family);
225
228
  if (familyNamed && base) score += FAMILY_BASE;
@@ -228,6 +231,7 @@ export function rankPages(query, pages) {
228
231
  score,
229
232
  hits,
230
233
  familyNamed,
234
+ headNamed,
231
235
  containerMatched,
232
236
  family,
233
237
  base,
@@ -246,7 +250,14 @@ export function rankPages(query, pages) {
246
250
  /**
247
251
  * Put a named family's base template ahead of the variant that outranks it,
248
252
  * unless the variant matched START_TERMS terms the base did not, or the base
249
- * scores too little to start on its own.
253
+ * cannot start on its own: too little score, or too few matched terms. The
254
+ * head names the exception: a family word in the idea's head is start
255
+ * evidence on its own — the same evidence pickStart accepts in place of a
256
+ * second term — so a head-named one-term base can still take the lead ("saml
257
+ * login" is the login page, not the SSO flow). A base whose family the idea
258
+ * names only elsewhere still needs a second term: score alone drifts upward
259
+ * as the catalog grows (idf rises with page count) and would eventually let a
260
+ * one-term base displace its variant, while hits do not drift.
250
261
  * @param {RankedPage[]} ranked
251
262
  * @returns {RankedPage[]}
252
263
  */
@@ -254,7 +265,13 @@ function baseFirst(ranked) {
254
265
  const top = ranked[0];
255
266
  if (!top || top.base || !top.familyNamed) return ranked;
256
267
  const base = ranked.find(r => r.base && r.family === top.family);
257
- if (!base || base.score < START_SCORE) return ranked;
268
+ if (
269
+ !base ||
270
+ base.score < START_SCORE ||
271
+ (base.hits < START_TERMS && !base.headNamed)
272
+ ) {
273
+ return ranked;
274
+ }
258
275
  const own = [...top.matched].filter(t => !base.matched.has(t)).length;
259
276
  return own >= START_TERMS
260
277
  ? ranked
@@ -64,6 +64,7 @@ export type RankedPage = {
64
64
  score: number;
65
65
  hits: number;
66
66
  familyNamed: boolean;
67
+ headNamed: boolean;
67
68
  containerMatched: boolean;
68
69
  family: string;
69
70
  base: boolean;
@@ -163,7 +163,7 @@ export const SYNONYMS_OF = (() => {
163
163
  /**
164
164
  * @typedef {import('../_adapter.mjs').PageTemplate} PageTemplate
165
165
  * @typedef {import('../_adapter.mjs').ComponentWords} ComponentWords
166
- * @typedef {{name: string, score: number, hits: number, familyNamed: boolean, containerMatched: boolean, family: string, base: boolean, matched: Set<string>}} RankedPage
166
+ * @typedef {{name: string, score: number, hits: number, familyNamed: boolean, headNamed: boolean, containerMatched: boolean, family: string, base: boolean, matched: Set<string>}} RankedPage
167
167
  * @typedef {'page' | 'part' | 'edit'} IdeaKind
168
168
  */
169
169
 
@@ -50,6 +50,7 @@ export { astryxIconDefinitions } from "../../foundation/discovery/icon-definitio
50
50
  export { iconSetKey } from "../../foundation/discovery/icon-set-discovery.mjs";
51
51
  export { setConfigString } from "../../foundation/config/config-writer.mjs";
52
52
  export { exportValueKind } from "../../foundation/discovery/module-exports.mjs";
53
- export { iconRecord, importLine, leadingReading, matchIcon, rankIcons, scoreIcon } from "../../foundation/discovery/icon-ranking.mjs";
54
- export { assertIconExport, checkNewDefinition, definitionFile, findLocalIconSet, writeDefinitionFile, iconIdOf, closestNames, libraryIcons, mappableDefinitions, resolveIconSource, generatedModulePath, generatedNamesOf, generatedOrigins, iconModulePackage, sameIconModule, iconExportName, iconNaming, modulePrefix, setModuleNote, variantExportName, writeGeneratedIcons, writeIconSetData, definitionNameOf, iconIdIn, iconsWithWord, localSourceNote, THEME_MAP_NAME } from "../../foundation/discovery/icon-set-writer.mjs";
53
+ export { iconRecord, importLine, leadingReading, matchIcon, answeringMatches, rankIcons, scoreIcon } from "../../foundation/discovery/icon-ranking.mjs";
54
+ export { assertIconExport, checkNewDefinition, definitionNameFromInput, definitionFile, findLocalIconSet, writeDefinitionFile, iconIdOf, closestNames, libraryIcons, mappableDefinitions, resolveIconSource, generatedModulePath, generatedNamesOf, generatedOrigins, iconModulePackage, sameIconModule, iconExportName, iconNaming, modulePrefix, moduleNaming, iconNamingWithoutLook, splitLook, setModuleNote, variantExportName, writeGeneratedIcons, writeIconSetData, definitionNameOf, iconIdIn, iconsWithWord, localSourceNote, THEME_MAP_NAME } from "../../foundation/discovery/icon-set-writer.mjs";
55
55
  export { addIconDefinition, addIconSet } from "./_authoring.mjs";
56
+ export { checkVariantLook, drawnLooks } from "./_default-look.mjs";
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * @position api/icon — adapter for api/icon/{search,detail,list,use,map,add,
8
8
  * new-set,new-definition}; it also carries the icon ranking, the icon-set
9
- * writer, the set and definition authoring writes, and the config writer
10
- * the leaves use
9
+ * writer, the set and definition authoring writes, the default-look
10
+ * rule, and the config writer the leaves use
11
11
  */
12
12
 
13
13
  import * as fs from 'node:fs';
@@ -28,6 +28,7 @@ export {
28
28
  importLine,
29
29
  leadingReading,
30
30
  matchIcon,
31
+ answeringMatches,
31
32
  rankIcons,
32
33
  scoreIcon,
33
34
  } from '../../foundation/discovery/icon-ranking.mjs';
@@ -37,6 +38,7 @@ export {setConfigString} from '../../foundation/config/config-writer.mjs';
37
38
  export {
38
39
  assertIconExport,
39
40
  checkNewDefinition,
41
+ definitionNameFromInput,
40
42
  definitionFile,
41
43
  findLocalIconSet,
42
44
  writeDefinitionFile,
@@ -53,6 +55,9 @@ export {
53
55
  iconExportName,
54
56
  iconNaming,
55
57
  modulePrefix,
58
+ moduleNaming,
59
+ iconNamingWithoutLook,
60
+ splitLook,
56
61
  setModuleNote,
57
62
  variantExportName,
58
63
  writeGeneratedIcons,
@@ -65,6 +70,7 @@ export {
65
70
  } from '../../foundation/discovery/icon-set-writer.mjs';
66
71
  export {exportValueKind} from '../../foundation/discovery/module-exports.mjs';
67
72
  export {addIconDefinition, addIconSet} from './_authoring.mjs';
73
+ export {checkVariantLook, drawnLooks} from './_default-look.mjs';
68
74
 
69
75
  /**
70
76
  * Refuse a command that writes to a project or package when `cwd` is outside
@@ -44,3 +44,4 @@ export function addIconDefinition(name: string, options: {
44
44
  type: "integration.add";
45
45
  data: import("./icon.type.mjs").IconNewData;
46
46
  }>;
47
+ export type Looks = import("./_default-look.mjs").Looks;