@astryxdesign/cli 0.7.11 → 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 (68) hide show
  1. package/api/build/kit/rank.mjs +21 -4
  2. package/api/build/kit/words.d.mts +1 -0
  3. package/api/build/kit/words.mjs +1 -1
  4. package/api/icon/_adapter.d.mts +3 -2
  5. package/api/icon/_adapter.mjs +8 -2
  6. package/api/icon/_authoring.d.mts +1 -0
  7. package/api/icon/_authoring.mjs +586 -66
  8. package/api/icon/_default-look.d.mts +155 -0
  9. package/api/icon/_default-look.mjs +474 -0
  10. package/api/icon/_records.d.mts +1 -1
  11. package/api/icon/_records.mjs +1 -0
  12. package/api/icon/add/add.mjs +224 -38
  13. package/api/icon/icon.type.d.mts +22 -2
  14. package/api/icon/icon.type.mjs +6 -2
  15. package/api/icon/iconAdd.doc.mjs +2 -2
  16. package/api/icon/iconNewDefinition.doc.mjs +3 -2
  17. package/api/icon/iconNewSet.doc.mjs +4 -4
  18. package/api/icon/search/search.mjs +10 -9
  19. package/api/integration/add-helpers.d.mts +11 -1
  20. package/api/integration/add-helpers.mjs +5 -2
  21. package/api/integration/authoring-checks.d.mts +0 -2
  22. package/api/integration/authoring-checks.mjs +1 -6
  23. package/api/logger.mjs +2 -1
  24. package/api/swizzle/_adapter.d.mts +1 -0
  25. package/api/swizzle/_adapter.mjs +4 -1
  26. package/api/swizzle/_moduleGraph.d.mts +171 -0
  27. package/api/swizzle/_moduleGraph.mjs +795 -0
  28. package/api/swizzle/copy/copy.d.mts +2 -43
  29. package/api/swizzle/copy/copy.mjs +195 -314
  30. package/api/swizzle/swizzle.d.mts +0 -2
  31. package/api/swizzle/swizzle.doc.mjs +9 -4
  32. package/api/swizzle/swizzle.mjs +3 -7
  33. package/api/swizzle/swizzle.type.d.mts +2 -1
  34. package/api/swizzle/swizzle.type.mjs +3 -2
  35. package/assets/discover/official-packages.json +20 -0
  36. package/assets/docs/tree/icon-sets.doc.mjs +11 -5
  37. package/assets/templates/blocks/components/Table/TableRowIndexTable.doc.mjs +1 -1
  38. package/assets/templates/blocks/components/Table/TableRowIndexTable.tsx +2 -2
  39. package/assets/templates/pages/course-detail/page.tsx +699 -0
  40. package/assets/templates/pages/course-detail/template.doc.mjs +37 -0
  41. package/assets/templates/pages/file-explorer/page.tsx +103 -79
  42. package/assets/templates/pages/table-grouped/page.tsx +160 -232
  43. package/assets/templates/pages/table-grouped/template.doc.mjs +0 -2
  44. package/assets/templates/pages/theme-showcase/page.tsx +724 -792
  45. package/assets/templates/pages/theme-showcase/template.doc.mjs +4 -5
  46. package/authoring/doctypes/template/type.ts +1 -0
  47. package/clients/cli/commands/experimental/icon.mjs +31 -10
  48. package/clients/cli/commands/experimental-icon-add.doc.mjs +1 -1
  49. package/clients/cli/commands/experimental-icon-new-definition.doc.mjs +2 -1
  50. package/clients/cli/commands/experimental-icon-new-set.doc.mjs +2 -2
  51. package/clients/cli/commands/swizzle.doc.mjs +8 -3
  52. package/clients/cli/commands/swizzle.mjs +21 -9
  53. package/foundation/discovery/component-loader.d.mts +1 -1
  54. package/foundation/discovery/doc-types.mjs +9 -2
  55. package/foundation/discovery/icon-ranking.d.mts +27 -3
  56. package/foundation/discovery/icon-ranking.mjs +125 -8
  57. package/foundation/discovery/icon-set-checks.mjs +44 -35
  58. package/foundation/discovery/icon-set-discovery.d.mts +13 -0
  59. package/foundation/discovery/icon-set-discovery.mjs +25 -0
  60. package/foundation/discovery/icon-set-writer.d.mts +238 -16
  61. package/foundation/discovery/icon-set-writer.mjs +676 -79
  62. package/foundation/discovery/module-exports.d.mts +3 -2
  63. package/foundation/discovery/module-exports.mjs +167 -37
  64. package/foundation/fs/paths.d.mts +2 -1
  65. package/foundation/fs/paths.mjs +3 -4
  66. package/foundation/text/shell-arg.d.mts +14 -0
  67. package/foundation/text/shell-arg.mjs +17 -0
  68. package/package.json +6 -6
@@ -53,11 +53,12 @@ export function moduleExportSource(file: string, exportName: string, seen?: Set<
53
53
  export function moduleExportNames(file: string): string[] | null;
54
54
  /**
55
55
  * Every export of a module with where it is declared, in one pass: the same
56
- * answers as {@link moduleExportOrigin} for each name, read once per module.
56
+ * answers as the whole-tree {@link exportOrigin} for each name, read once per
57
+ * module.
57
58
  * Pass one `memo` to calls that read the same package, so a module behind
58
59
  * many barrels is read once; a memo keeps value and type reads apart, and
59
60
  * nothing is kept between memos. One difference follows ESM where
60
- * {@link moduleExportOrigin} does not: a name re-exported by name from a
61
+ * {@link exportOrigin} does not: a name re-exported by name from a
61
62
  * module that cannot be followed is absent, never filled from `export *`.
62
63
  * @param {string} file
63
64
  * @param {{types?: boolean, memo?: Map<string, Map<string, {file: string, name: string}>>}} [options]
@@ -161,17 +161,46 @@ const nodesByTree = new WeakMap();
161
161
  * @returns {readonly any[]}
162
162
  */
163
163
  function nodesOfType(node, type) {
164
+ return cachedNodes(node, `all\0${type}`, () =>
165
+ collectNodesOfType(node, type, []),
166
+ );
167
+ }
168
+
169
+ /**
170
+ * The module declarations of `type` at a program's top level, in source
171
+ * order: a library file is read without a walk of every function in it. A
172
+ * declaration nested in a namespace is not one of them. Only the readers of
173
+ * icon-set libraries use this: the parse-failure and re-export checks,
174
+ * {@link moduleExportOrigin} and the readers built on it, and
175
+ * {@link followedExportNames}. {@link bindingOrigin}, and so
176
+ * {@link aliasedOrigin}, {@link elementPropOrigins} and
177
+ * {@link moduleExportOrigins}, read with {@link nodesOfType}, as do the
178
+ * other readers.
179
+ * @param {any} program
180
+ * @param {string} type
181
+ * @returns {readonly any[]}
182
+ */
183
+ function moduleDeclarations(program, type) {
184
+ return cachedNodes(program, `top\0${type}`, () => topLevel(program, type));
185
+ }
186
+
187
+ /**
188
+ * @param {any} node
189
+ * @param {string} key
190
+ * @param {() => readonly any[]} find
191
+ * @returns {readonly any[]}
192
+ */
193
+ function cachedNodes(node, key, find) {
164
194
  if (node == null || typeof node !== 'object') return [];
165
195
  let byType = nodesByTree.get(node);
166
196
  if (!byType) {
167
197
  byType = new Map();
168
198
  nodesByTree.set(node, byType);
169
199
  }
170
- let found = byType.get(type);
171
- if (!found) {
172
- found = collectNodesOfType(node, type, []);
173
- byType.set(type, found);
174
- }
200
+ const cached = byType.get(key);
201
+ if (cached) return cached;
202
+ const found = find();
203
+ byType.set(key, found);
175
204
  return found;
176
205
  }
177
206
 
@@ -315,7 +344,7 @@ export function moduleParseFailure(file) {
315
344
  };
316
345
  }
317
346
  for (const type of ['ExportNamedDeclaration', 'ExportAllDeclaration']) {
318
- for (const node of nodesOfType(ast.program, type)) {
347
+ for (const node of moduleDeclarations(ast.program, type)) {
319
348
  const specifier = node.source?.value;
320
349
  if (typeof specifier !== 'string' || !specifier.startsWith('.')) {
321
350
  continue;
@@ -344,7 +373,7 @@ export function unfollowedReexports(file) {
344
373
  /** @type {Set<string>} */
345
374
  const missing = new Set();
346
375
  for (const type of ['ExportNamedDeclaration', 'ExportAllDeclaration']) {
347
- for (const node of nodesOfType(ast.program, type)) {
376
+ for (const node of moduleDeclarations(ast.program, type)) {
348
377
  const specifier = node.source?.value;
349
378
  if (typeof specifier !== 'string' || node.exportKind === 'type') continue;
350
379
  if (!resolveModuleOrPackage(specifier, file)) missing.add(specifier);
@@ -608,11 +637,12 @@ export function moduleExportNames(file) {
608
637
 
609
638
  /**
610
639
  * Every export of a module with where it is declared, in one pass: the same
611
- * answers as {@link moduleExportOrigin} for each name, read once per module.
640
+ * answers as the whole-tree {@link exportOrigin} for each name, read once per
641
+ * module.
612
642
  * Pass one `memo` to calls that read the same package, so a module behind
613
643
  * many barrels is read once; a memo keeps value and type reads apart, and
614
644
  * nothing is kept between memos. One difference follows ESM where
615
- * {@link moduleExportOrigin} does not: a name re-exported by name from a
645
+ * {@link exportOrigin} does not: a name re-exported by name from a
616
646
  * module that cannot be followed is absent, never filled from `export *`.
617
647
  * @param {string} file
618
648
  * @param {{types?: boolean, memo?: Map<string, Map<string, {file: string, name: string}>>}} [options]
@@ -677,7 +707,12 @@ function exportOriginsOf(file, read) {
677
707
  for (const node of declarations) {
678
708
  for (const name of declaredNames(node.declaration, types)) {
679
709
  named.add(name);
680
- if (!origins.has(name)) origins.set(name, {file, name});
710
+ if (!origins.has(name)) {
711
+ origins.set(
712
+ name,
713
+ declaredOrigin(ast, file, node.declaration, name, types),
714
+ );
715
+ }
681
716
  }
682
717
  }
683
718
  for (const [exportName, entries] of specifiers) {
@@ -697,7 +732,7 @@ function exportOriginsOf(file, read) {
697
732
  origin =
698
733
  result.origins.get(local) ??
699
734
  (result.low < Infinity
700
- ? moduleExportOrigin(target, local, new Set(), {types})
735
+ ? exportOrigin(target, local, new Set(), nodesOfType, types)
701
736
  : null);
702
737
  }
703
738
  } else {
@@ -1087,23 +1122,34 @@ export function staticExportObject(file, exportNames) {
1087
1122
  /**
1088
1123
  * A module's runtime named exports, indexed once per parsed tree: the
1089
1124
  * export declarations that declare something, and each export specifier by
1090
- * the name it exports, in source order.
1091
- * @type {WeakMap<object, {declarations: any[], specifiers: Map<string, Array<{node: any, specifier: any}>>}>}
1125
+ * the name it exports, in source order. Each reader of export declarations
1126
+ * has its own index, since the readers can find different declarations.
1127
+ * @type {WeakMap<object, Map<Function, {declarations: any[], specifiers: Map<string, Array<{node: any, specifier: any}>>}>>}
1092
1128
  */
1093
1129
  const namedExportIndexes = new WeakMap();
1094
1130
  /** The same index with type-only exports included. */
1095
1131
  const typedExportIndexes = new WeakMap();
1096
1132
 
1097
- /** @param {any} program @param {boolean} [types] include type-only exports */
1098
- function namedExportIndex(program, types = false) {
1133
+ /**
1134
+ * @param {any} program
1135
+ * @param {boolean} [types] include type-only exports
1136
+ * @param {(node: any, type: string) => readonly any[]} [read] how the
1137
+ * module's export declarations are read
1138
+ */
1139
+ function namedExportIndex(program, types = false, read = nodesOfType) {
1099
1140
  const indexes = types ? typedExportIndexes : namedExportIndexes;
1100
- const cached = indexes.get(program);
1141
+ let byReader = indexes.get(program);
1142
+ if (!byReader) {
1143
+ byReader = new Map();
1144
+ indexes.set(program, byReader);
1145
+ }
1146
+ const cached = byReader.get(read);
1101
1147
  if (cached) return cached;
1102
1148
  /** @type {any[]} */
1103
1149
  const declarations = [];
1104
1150
  /** @type {Map<string, Array<{node: any, specifier: any}>>} */
1105
1151
  const specifiers = new Map();
1106
- for (const node of nodesOfType(program, 'ExportNamedDeclaration')) {
1152
+ for (const node of read(program, 'ExportNamedDeclaration')) {
1107
1153
  if (node.exportKind === 'type' && !types) continue;
1108
1154
  if (node.declaration) declarations.push(node);
1109
1155
  for (const specifier of node.specifiers ?? []) {
@@ -1120,7 +1166,7 @@ function namedExportIndex(program, types = false) {
1120
1166
  }
1121
1167
  }
1122
1168
  const index = {declarations, specifiers};
1123
- indexes.set(program, index);
1169
+ byReader.set(read, index);
1124
1170
  return index;
1125
1171
  }
1126
1172
 
@@ -1142,6 +1188,21 @@ export function moduleExportOrigin(
1142
1188
  seen = new Set(),
1143
1189
  {types = false} = {},
1144
1190
  ) {
1191
+ return exportOrigin(file, exportName, seen, moduleDeclarations, types);
1192
+ }
1193
+
1194
+ /**
1195
+ * {@link moduleExportOrigin} with the reader of a module's export
1196
+ * declarations: {@link moduleDeclarations} for icon-set libraries, or
1197
+ * {@link nodesOfType} for every other caller.
1198
+ * @param {string} file
1199
+ * @param {string} exportName
1200
+ * @param {Set<string>} seen
1201
+ * @param {(node: any, type: string) => readonly any[]} read
1202
+ * @param {boolean} [types] also follow type-only exports and declarations
1203
+ * @returns {{file: string, name: string} | null}
1204
+ */
1205
+ function exportOrigin(file, exportName, seen, read, types = false) {
1145
1206
  const identity = `${file}\0${exportName}`;
1146
1207
  if (seen.has(identity)) return null;
1147
1208
  seen.add(identity);
@@ -1152,10 +1213,18 @@ export function moduleExportOrigin(
1152
1213
  } catch {
1153
1214
  return null;
1154
1215
  }
1155
- const {declarations, specifiers} = namedExportIndex(ast.program, types);
1216
+ const {declarations, specifiers} = namedExportIndex(ast.program, types, read);
1156
1217
  for (const node of declarations) {
1157
1218
  if (declarationExports(node.declaration, exportName, types)) {
1158
- return {file, name: exportName};
1219
+ return declaredOrigin(
1220
+ ast,
1221
+ file,
1222
+ node.declaration,
1223
+ exportName,
1224
+ types,
1225
+ seen,
1226
+ read,
1227
+ );
1159
1228
  }
1160
1229
  }
1161
1230
  for (const {node, specifier} of specifiers.get(exportName) ?? []) {
@@ -1163,28 +1232,28 @@ export function moduleExportOrigin(
1163
1232
  if (node.source) {
1164
1233
  const target = resolveModuleOrPackage(node.source.value, file);
1165
1234
  const origin = target
1166
- ? moduleExportOrigin(target, local, seen, {types})
1235
+ ? exportOrigin(target, local, seen, read, types)
1167
1236
  : null;
1168
1237
  if (origin) return origin;
1169
1238
  continue;
1170
1239
  }
1171
- return bindingOrigin(ast, file, local, seen, types);
1240
+ return bindingOrigin(ast, file, local, seen, types, read);
1172
1241
  }
1173
1242
  if (exportName === 'default') {
1174
- for (const node of nodesOfType(ast.program, 'ExportDefaultDeclaration')) {
1243
+ for (const node of read(ast.program, 'ExportDefaultDeclaration')) {
1175
1244
  const declaration = node.declaration;
1176
1245
  if (!types && !runtimeDefault(declaration)) continue;
1177
1246
  if (declaration.type === 'Identifier') {
1178
- return bindingOrigin(ast, file, declaration.name, seen, types);
1247
+ return bindingOrigin(ast, file, declaration.name, seen, types, read);
1179
1248
  }
1180
1249
  return {file, name: 'default'};
1181
1250
  }
1182
1251
  }
1183
- for (const node of nodesOfType(ast.program, 'ExportAllDeclaration')) {
1252
+ for (const node of read(ast.program, 'ExportAllDeclaration')) {
1184
1253
  if ((node.exportKind === 'type' && !types) || node.exported) continue;
1185
1254
  const target = resolveModuleOrPackage(node.source?.value, file);
1186
1255
  const origin = target
1187
- ? moduleExportOrigin(target, exportName, seen, {types})
1256
+ ? exportOrigin(target, exportName, seen, read, types)
1188
1257
  : null;
1189
1258
  if (origin) return origin;
1190
1259
  }
@@ -1240,7 +1309,10 @@ function originGapReason(file, exportName, seen = new Set()) {
1240
1309
  }
1241
1310
  /** @type {string | null} */
1242
1311
  let local = null;
1243
- for (const node of nodesOfType(ast.program, 'ExportNamedDeclaration')) {
1312
+ for (const node of moduleDeclarations(
1313
+ ast.program,
1314
+ 'ExportNamedDeclaration',
1315
+ )) {
1244
1316
  for (const specifier of node.specifiers ?? []) {
1245
1317
  const exported = specifier.exported?.name ?? specifier.exported?.value;
1246
1318
  if (exported !== exportName) continue;
@@ -1261,7 +1333,10 @@ function originGapReason(file, exportName, seen = new Set()) {
1261
1333
  }
1262
1334
  }
1263
1335
  if (exportName === 'default') {
1264
- for (const node of nodesOfType(ast.program, 'ExportDefaultDeclaration')) {
1336
+ for (const node of moduleDeclarations(
1337
+ ast.program,
1338
+ 'ExportDefaultDeclaration',
1339
+ )) {
1265
1340
  if (node.declaration?.type === 'Identifier') {
1266
1341
  local = node.declaration.name;
1267
1342
  }
@@ -1269,7 +1344,10 @@ function originGapReason(file, exportName, seen = new Set()) {
1269
1344
  }
1270
1345
  if (!local) {
1271
1346
  // Bound behind `export *`: the module it comes from says why.
1272
- for (const node of nodesOfType(ast.program, 'ExportAllDeclaration')) {
1347
+ for (const node of moduleDeclarations(
1348
+ ast.program,
1349
+ 'ExportAllDeclaration',
1350
+ )) {
1273
1351
  if (node.exportKind === 'type' || node.exported) continue;
1274
1352
  const target = resolveModuleOrPackage(node.source?.value, file);
1275
1353
  if (
@@ -1330,7 +1408,10 @@ export function followedExportNames(
1330
1408
  }
1331
1409
  /** @type {Set<string>} */
1332
1410
  const names = new Set();
1333
- for (const node of nodesOfType(ast.program, 'ExportNamedDeclaration')) {
1411
+ for (const node of moduleDeclarations(
1412
+ ast.program,
1413
+ 'ExportNamedDeclaration',
1414
+ )) {
1334
1415
  if (node.exportKind === 'type' && !types) continue;
1335
1416
  const declaration = node.declaration;
1336
1417
  if (declaration && (declaration.declare !== true || types)) {
@@ -1360,7 +1441,7 @@ export function followedExportNames(
1360
1441
  }
1361
1442
  }
1362
1443
  }
1363
- for (const node of nodesOfType(ast.program, 'ExportAllDeclaration')) {
1444
+ for (const node of moduleDeclarations(ast.program, 'ExportAllDeclaration')) {
1364
1445
  if ((node.exportKind === 'type' && !types) || node.exported) continue;
1365
1446
  const target = resolveModuleOrPackage(node.source?.value, file);
1366
1447
  if (target) {
@@ -1422,7 +1503,7 @@ export function exportValueKind(file, exportName) {
1422
1503
  return 'unknown';
1423
1504
  };
1424
1505
  if (origin.name === 'default') {
1425
- const [node] = nodesOfType(ast.program, 'ExportDefaultDeclaration');
1506
+ const [node] = moduleDeclarations(ast.program, 'ExportDefaultDeclaration');
1426
1507
  return node ? kindOf(node.declaration) : 'unknown';
1427
1508
  }
1428
1509
  for (const statement of ast.program.body) {
@@ -1479,7 +1560,7 @@ export function exportScalarType(file, exportName) {
1479
1560
  return null;
1480
1561
  };
1481
1562
  if (origin.name === 'default') {
1482
- const [node] = nodesOfType(ast.program, 'ExportDefaultDeclaration');
1563
+ const [node] = moduleDeclarations(ast.program, 'ExportDefaultDeclaration');
1483
1564
  return node ? typeOf(node.declaration) : null;
1484
1565
  }
1485
1566
  for (const statement of ast.program.body) {
@@ -1622,6 +1703,48 @@ export function elementPropOrigins(file, {sources, name, prop, unwrap}) {
1622
1703
  return origins;
1623
1704
  }
1624
1705
 
1706
+ /**
1707
+ * Where a declared export is defined. An `export const X = Y` whose value is
1708
+ * another binding is that binding, so an alias of an imported value has the
1709
+ * imported value's origin.
1710
+ * @param {any} ast
1711
+ * @param {string} file
1712
+ * @param {any} declaration
1713
+ * @param {string} name
1714
+ * @param {boolean} types
1715
+ * @param {Set<string>} [seen]
1716
+ * @param {(node: any, type: string) => readonly any[]} [read]
1717
+ * @returns {{file: string, name: string}}
1718
+ */
1719
+ function declaredOrigin(
1720
+ ast,
1721
+ file,
1722
+ declaration,
1723
+ name,
1724
+ types,
1725
+ seen = new Set(),
1726
+ read = nodesOfType,
1727
+ ) {
1728
+ if (
1729
+ declaration?.type === 'VariableDeclaration' &&
1730
+ declaration.kind === 'const'
1731
+ ) {
1732
+ for (const declarator of declaration.declarations) {
1733
+ if (
1734
+ declarator.id?.type === 'Identifier' &&
1735
+ declarator.id.name === name &&
1736
+ declarator.init?.type === 'Identifier'
1737
+ ) {
1738
+ const init = declarator.init.name;
1739
+ return (
1740
+ bindingOrigin(ast, file, init, seen, types, read) ?? {file, name}
1741
+ );
1742
+ }
1743
+ }
1744
+ }
1745
+ return {file, name};
1746
+ }
1747
+
1625
1748
  /**
1626
1749
  * Where a top-level binding of a parsed module comes from: an import from a
1627
1750
  * local module is followed to its origin; anything else is declared here.
@@ -1630,9 +1753,18 @@ export function elementPropOrigins(file, {sources, name, prop, unwrap}) {
1630
1753
  * @param {string} local
1631
1754
  * @param {Set<string>} seen
1632
1755
  * @param {boolean} [types] also follow `import type`
1756
+ * @param {(node: any, type: string) => readonly any[]} [read] how an
1757
+ * imported module's export declarations are read
1633
1758
  * @returns {{file: string, name: string} | null}
1634
1759
  */
1635
- function bindingOrigin(ast, file, local, seen, types = false) {
1760
+ function bindingOrigin(
1761
+ ast,
1762
+ file,
1763
+ local,
1764
+ seen,
1765
+ types = false,
1766
+ read = nodesOfType,
1767
+ ) {
1636
1768
  for (const node of ast.program.body) {
1637
1769
  if (
1638
1770
  node.type !== 'ImportDeclaration' ||
@@ -1646,9 +1778,7 @@ function bindingOrigin(ast, file, local, seen, types = false) {
1646
1778
  const imported =
1647
1779
  specifier.imported?.name ?? specifier.imported?.value ?? local;
1648
1780
  const target = resolveModuleOrPackage(node.source.value, file);
1649
- return target
1650
- ? moduleExportOrigin(target, imported, seen, {types})
1651
- : null;
1781
+ return target ? exportOrigin(target, imported, seen, read, types) : null;
1652
1782
  }
1653
1783
  }
1654
1784
  return {file, name: local};
@@ -166,7 +166,8 @@ export function discoverExternalPackages(startDir?: string): {
166
166
  }[];
167
167
  /**
168
168
  * List available component directories in packages/core/src.
169
- * Returns directory names that contain Astryx*.tsx files.
169
+ * Component directories are capitalized (`Button`, `Dialog`); lowercase
170
+ * directories hold shared infrastructure and are never listed.
170
171
  * @param {string} coreDir
171
172
  */
172
173
  export function listComponents(coreDir: string): string[];
@@ -854,7 +854,8 @@ export function discoverExternalPackages(startDir = process.cwd()) {
854
854
 
855
855
  /**
856
856
  * List available component directories in packages/core/src.
857
- * Returns directory names that contain Astryx*.tsx files.
857
+ * Component directories are capitalized (`Button`, `Dialog`); lowercase
858
+ * directories hold shared infrastructure and are never listed.
858
859
  * @param {string} coreDir
859
860
  */
860
861
  export function listComponents(coreDir) {
@@ -865,9 +866,7 @@ export function listComponents(coreDir) {
865
866
  return entries
866
867
  .filter(e => {
867
868
  if (!e.isDirectory()) return false;
868
- // Skip non-component dirs
869
- if (['hooks', 'theme', 'utils'].includes(e.name)) return false;
870
- return true;
869
+ return /^[A-Z]/.test(e.name);
871
870
  })
872
871
  .map(e => e.name)
873
872
  .sort();
@@ -0,0 +1,14 @@
1
+ // @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
2
+ // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
+
4
+ /**
5
+ * @file One command-line word for a printed command: a value as written when
6
+ * the shell reads it as one plain word, else single-quoted, so a printed
7
+ * command runs as printed and never substitutes anything.
8
+ */
9
+ /**
10
+ * A value as one shell word.
11
+ * @param {string} value
12
+ * @returns {string}
13
+ */
14
+ export function shellArg(value: string): string;
@@ -0,0 +1,17 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file One command-line word for a printed command: a value as written when
5
+ * the shell reads it as one plain word, else single-quoted, so a printed
6
+ * command runs as printed and never substitutes anything.
7
+ */
8
+
9
+ /**
10
+ * A value as one shell word.
11
+ * @param {string} value
12
+ * @returns {string}
13
+ */
14
+ export function shellArg(value) {
15
+ if (/^[A-Za-z0-9@/._-]+$/.test(value)) return value;
16
+ return `'${value.replace(/'/g, `'\\''`)}'`;
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/cli",
3
- "version": "0.7.11",
3
+ "version": "0.7.12-canary.ccb4a6d",
4
4
  "displayName": "CLI",
5
5
  "description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
6
6
  "author": "Meta Open Source",
@@ -124,7 +124,7 @@
124
124
  "zod": "^4.4.3"
125
125
  },
126
126
  "peerDependencies": {
127
- "@astryxdesign/core": "*"
127
+ "@astryxdesign/core": "0.7.12-canary.ccb4a6d"
128
128
  },
129
129
  "peerDependenciesMeta": {
130
130
  "@astryxdesign/core": {
@@ -132,10 +132,10 @@
132
132
  }
133
133
  },
134
134
  "devDependencies": {
135
- "@astryxdesign/charts": "*",
136
- "@astryxdesign/core": "*",
137
- "@astryxdesign/lab": "*",
138
- "@astryxdesign/theme-neutral": "*",
135
+ "@astryxdesign/charts": "0.7.12-canary.ccb4a6d",
136
+ "@astryxdesign/core": "0.7.12-canary.ccb4a6d",
137
+ "@astryxdesign/lab": "0.7.12-canary.ccb4a6d",
138
+ "@astryxdesign/theme-neutral": "0.7.12-canary.ccb4a6d",
139
139
  "@heroicons/react": "^2.2.0",
140
140
  "@stylexjs/stylex": "^0.19.0",
141
141
  "@types/babel__core": "^7.20.5",