@dsai-io/tools 1.2.5 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -85,6 +85,10 @@ dsai config
85
85
 
86
86
  # Generate icon components from SVGs
87
87
  dsai icons build --format react
88
+
89
+ # Show full tool inventory (for humans and AI agents)
90
+ dsai info
91
+ dsai info --json # Structured JSON for agent consumption
88
92
  ```
89
93
 
90
94
  ## Configuration
@@ -4594,13 +4594,98 @@ var init_groups = __esm({
4594
4594
  ];
4595
4595
  }
4596
4596
  });
4597
+
4598
+ // src/tokens/style-dictionary/preprocessors/fix-references.ts
4599
+ function fixValue(value, mappings) {
4600
+ if (typeof value !== "string" || !value.startsWith("{")) {
4601
+ return value;
4602
+ }
4603
+ let result = value;
4604
+ for (const mapping of mappings) {
4605
+ result = result.split(mapping[0]).join(mapping[1]);
4606
+ }
4607
+ return result;
4608
+ }
4609
+ function processTokens(obj, mappings) {
4610
+ for (const key of Object.keys(obj)) {
4611
+ const value = obj[key];
4612
+ if (value && typeof value === "object") {
4613
+ const typedValue = value;
4614
+ if ("$value" in typedValue) {
4615
+ typedValue["$value"] = fixValue(typedValue["$value"], mappings);
4616
+ } else if ("value" in typedValue) {
4617
+ typedValue["value"] = fixValue(typedValue["value"], mappings);
4618
+ } else {
4619
+ processTokens(typedValue, mappings);
4620
+ }
4621
+ }
4622
+ }
4623
+ }
4624
+ function createFixReferencesPreprocessor(mappings) {
4625
+ return {
4626
+ name: "fix-references-custom",
4627
+ preprocessor: (dictionary) => {
4628
+ processTokens(dictionary, mappings);
4629
+ return dictionary;
4630
+ }
4631
+ };
4632
+ }
4633
+ var DEFAULT_PATH_MAPPINGS, fixReferences;
4634
+ var init_fix_references = __esm({
4635
+ "src/tokens/style-dictionary/preprocessors/fix-references.ts"() {
4636
+ DEFAULT_PATH_MAPPINGS = [
4637
+ ["{colors.brand.", "{color."],
4638
+ ["{colors.neutral.", "{neutral."],
4639
+ ["{borders.width.", "{border.width."]
4640
+ ];
4641
+ fixReferences = {
4642
+ name: "fix-references",
4643
+ preprocessor: (dictionary) => {
4644
+ processTokens(dictionary, DEFAULT_PATH_MAPPINGS);
4645
+ return dictionary;
4646
+ }
4647
+ };
4648
+ }
4649
+ });
4650
+
4651
+ // src/tokens/style-dictionary/preprocessors/index.ts
4652
+ var preprocessors_exports = {};
4653
+ __export(preprocessors_exports, {
4654
+ builtInPreprocessors: () => builtInPreprocessors,
4655
+ createFixReferencesPreprocessor: () => createFixReferencesPreprocessor,
4656
+ fixReferences: () => fixReferences,
4657
+ registerPreprocessors: () => registerPreprocessors
4658
+ });
4659
+ function registerPreprocessors(sd, customPreprocessors = []) {
4660
+ const allPreprocessors = [...builtInPreprocessors, ...customPreprocessors];
4661
+ for (const preprocessor of allPreprocessors) {
4662
+ sd.registerPreprocessor({
4663
+ name: preprocessor.name,
4664
+ preprocessor: preprocessor.preprocessor
4665
+ });
4666
+ }
4667
+ }
4668
+ var builtInPreprocessors;
4669
+ var init_preprocessors = __esm({
4670
+ "src/tokens/style-dictionary/preprocessors/index.ts"() {
4671
+ init_fix_references();
4672
+ init_fix_references();
4673
+ builtInPreprocessors = [fixReferences];
4674
+ }
4675
+ });
4597
4676
  function generateThemeBuildConfig(options) {
4598
4677
  const { themeDefinition, files, outputDir, config } = options;
4599
4678
  const isDefault = themeDefinition.isDefault;
4600
4679
  const platformsMap = /* @__PURE__ */ new Map();
4601
4680
  const enabledFormats = config.formats;
4602
4681
  for (const format of enabledFormats) {
4603
- const platformConfig = generatePlatformConfig(format, themeDefinition, outputDir, isDefault);
4682
+ const platformConfig = generatePlatformConfig(
4683
+ format,
4684
+ themeDefinition,
4685
+ outputDir,
4686
+ isDefault,
4687
+ config.prefix
4688
+ );
4604
4689
  if (platformConfig) {
4605
4690
  platformsMap.set(format, platformConfig);
4606
4691
  }
@@ -4609,6 +4694,7 @@ function generateThemeBuildConfig(options) {
4609
4694
  return {
4610
4695
  source: files,
4611
4696
  platforms,
4697
+ preprocessors: ["fix-references"],
4612
4698
  // Enable DTCG format support (tokens with $value, $type, etc.)
4613
4699
  usesDtcg: true,
4614
4700
  // Configure logging to not throw on broken references (they'll be logged but build continues)
@@ -4621,7 +4707,7 @@ function generateThemeBuildConfig(options) {
4621
4707
  }
4622
4708
  };
4623
4709
  }
4624
- function generatePlatformConfig(format, themeDefinition, outputDir, isDefault) {
4710
+ function generatePlatformConfig(format, themeDefinition, outputDir, isDefault, prefix) {
4625
4711
  const formatConfig = FORMAT_MAPPING.get(format);
4626
4712
  if (!formatConfig) {
4627
4713
  console.warn(`Unknown format: ${format}`);
@@ -4636,8 +4722,15 @@ function generatePlatformConfig(format, themeDefinition, outputDir, isDefault) {
4636
4722
  destination: outputFile,
4637
4723
  format: sdFormat
4638
4724
  };
4725
+ if (prefix && (format === "css" || format === "scss")) {
4726
+ fileConfig.options = {
4727
+ ...fileConfig.options,
4728
+ prefix
4729
+ };
4730
+ }
4639
4731
  if (format === "css" && !isDefault) {
4640
4732
  fileConfig.options = {
4733
+ ...fileConfig.options,
4641
4734
  selector: themeDefinition.selector
4642
4735
  };
4643
4736
  }
@@ -4750,6 +4843,8 @@ async function runStyleDictionaryBuild(sdConfig, options) {
4750
4843
  registerCustomTransforms(StyleDictionary);
4751
4844
  const { registerTransformGroups: registerTransformGroups2 } = await Promise.resolve().then(() => (init_groups(), groups_exports));
4752
4845
  registerTransformGroups2(StyleDictionary);
4846
+ const { registerPreprocessors: registerPreprocessors2 } = await Promise.resolve().then(() => (init_preprocessors(), preprocessors_exports));
4847
+ registerPreprocessors2(StyleDictionary);
4753
4848
  if (options.verbose) {
4754
4849
  console.warn(` \u{1F527} Style Dictionary platforms:`);
4755
4850
  for (const [platform, config] of Object.entries(sdConfig.platforms)) {
@@ -4943,7 +5038,7 @@ var init_theme_builder = __esm({
4943
5038
  ["ios", { default: "ios/macros", themed: "ios/macros" }]
4944
5039
  ]);
4945
5040
  TRANSFORM_GROUPS = /* @__PURE__ */ new Map([
4946
- ["css", "css"],
5041
+ ["css", "custom/css"],
4947
5042
  ["scss", "scss"],
4948
5043
  ["js", "js-custom"],
4949
5044
  // Use custom transform group for valid JS identifiers
@@ -5182,7 +5277,7 @@ function getPipelinePaths(customPaths) {
5182
5277
  ...customPaths
5183
5278
  };
5184
5279
  }
5185
- function createStepFromName(stepName, tokensPackageDir, figmaExportsDir, tokensDir, paths, sdConfigFile, strict, snapshotService, themesConfig, outputDir, formats = ["css", "scss", "json"], cssOutputDir, postprocessConfig) {
5280
+ function createStepFromName(stepName, tokensPackageDir, figmaExportsDir, tokensDir, paths, sdConfigFile, strict, snapshotService, themesConfig, outputDir, formats = ["css", "scss", "json"], cssOutputDir, postprocessConfig, prefix) {
5186
5281
  const displayName = STEP_DISPLAY_NAMES.get(stepName) ?? `Unknown: ${stepName}`;
5187
5282
  switch (stepName) {
5188
5283
  case "validate":
@@ -5387,6 +5482,7 @@ function createStepFromName(stepName, tokensPackageDir, figmaExportsDir, tokensD
5387
5482
  const result = await buildAllThemes({
5388
5483
  config: {
5389
5484
  formats,
5485
+ prefix,
5390
5486
  themes: {
5391
5487
  definitions: themeDefinitions
5392
5488
  }
@@ -5502,7 +5598,8 @@ function createBuildSteps(tokensDir, _toolsDir, options, pipeline) {
5502
5598
  options.outputDir,
5503
5599
  formats,
5504
5600
  options.cssOutputDir,
5505
- options.postprocessConfig
5601
+ options.postprocessConfig,
5602
+ options.prefix
5506
5603
  );
5507
5604
  if (stepName === "validate" && skipValidate) {
5508
5605
  step.skip = true;
@@ -6887,78 +6984,6 @@ var init_types2 = __esm({
6887
6984
  }
6888
6985
  });
6889
6986
 
6890
- // src/tokens/style-dictionary/preprocessors/fix-references.ts
6891
- function fixValue(value, mappings) {
6892
- if (typeof value !== "string" || !value.startsWith("{")) {
6893
- return value;
6894
- }
6895
- let result = value;
6896
- for (const mapping of mappings) {
6897
- result = result.split(mapping[0]).join(mapping[1]);
6898
- }
6899
- return result;
6900
- }
6901
- function processTokens(obj, mappings) {
6902
- for (const key of Object.keys(obj)) {
6903
- const value = obj[key];
6904
- if (value && typeof value === "object") {
6905
- const typedValue = value;
6906
- if ("$value" in typedValue) {
6907
- typedValue["$value"] = fixValue(typedValue["$value"], mappings);
6908
- } else if ("value" in typedValue) {
6909
- typedValue["value"] = fixValue(typedValue["value"], mappings);
6910
- } else {
6911
- processTokens(typedValue, mappings);
6912
- }
6913
- }
6914
- }
6915
- }
6916
- function createFixReferencesPreprocessor(mappings) {
6917
- return {
6918
- name: "fix-references-custom",
6919
- preprocessor: (dictionary) => {
6920
- processTokens(dictionary, mappings);
6921
- return dictionary;
6922
- }
6923
- };
6924
- }
6925
- var DEFAULT_PATH_MAPPINGS, fixReferences;
6926
- var init_fix_references = __esm({
6927
- "src/tokens/style-dictionary/preprocessors/fix-references.ts"() {
6928
- DEFAULT_PATH_MAPPINGS = [
6929
- ["{colors.brand.", "{color."],
6930
- ["{colors.neutral.", "{neutral."],
6931
- ["{borders.width.", "{border.width."]
6932
- ];
6933
- fixReferences = {
6934
- name: "fix-references",
6935
- preprocessor: (dictionary) => {
6936
- processTokens(dictionary, DEFAULT_PATH_MAPPINGS);
6937
- return dictionary;
6938
- }
6939
- };
6940
- }
6941
- });
6942
-
6943
- // src/tokens/style-dictionary/preprocessors/index.ts
6944
- function registerPreprocessors(sd, customPreprocessors = []) {
6945
- const allPreprocessors = [...builtInPreprocessors, ...customPreprocessors];
6946
- for (const preprocessor of allPreprocessors) {
6947
- sd.registerPreprocessor({
6948
- name: preprocessor.name,
6949
- preprocessor: preprocessor.preprocessor
6950
- });
6951
- }
6952
- }
6953
- var builtInPreprocessors;
6954
- var init_preprocessors = __esm({
6955
- "src/tokens/style-dictionary/preprocessors/index.ts"() {
6956
- init_fix_references();
6957
- init_fix_references();
6958
- builtInPreprocessors = [fixReferences];
6959
- }
6960
- });
6961
-
6962
6987
  // src/tokens/style-dictionary/config.ts
6963
6988
  function createStyleDictionaryConfig(dsaiConfig, options = {}) {
6964
6989
  const {
@@ -8340,7 +8365,7 @@ function transformImports(content, options) {
8340
8365
  const { aliases } = options;
8341
8366
  let result = content;
8342
8367
  result = result.replace(
8343
- /(from\s+['"])(?:\.\.\/)+types(?:\/([^'"]+))?(['"])/g,
8368
+ /(from\s+['"])\.\.\/\.\.\/types(?:\/([^'"]+))?(['"])/g,
8344
8369
  (_match, prefix, subpath, suffix) => {
8345
8370
  if (subpath) {
8346
8371
  return `${prefix}${aliases.importAlias}${aliases.components}/types/${subpath}${suffix}`;
@@ -8348,6 +8373,18 @@ function transformImports(content, options) {
8348
8373
  return `${prefix}${aliases.importAlias}${aliases.components}/types${suffix}`;
8349
8374
  }
8350
8375
  );
8376
+ result = result.replace(
8377
+ /(from\s+['"])\.\.\/\.\.\/hooks\/(\w+)(['"])/g,
8378
+ `$1${aliases.importAlias}${aliases.hooks}/$2$3`
8379
+ );
8380
+ result = result.replace(
8381
+ /(from\s+['"])\.\.\/\.\.\/utils\/(\w+(?:\/\w+)?)(['"])/g,
8382
+ `$1${aliases.importAlias}${aliases.utils}/$2$3`
8383
+ );
8384
+ result = result.replace(
8385
+ /(from\s+['"])\.\.\/\.\.\/utils(['"])/g,
8386
+ `$1${aliases.importAlias}${aliases.utils}$2`
8387
+ );
8351
8388
  result = result.replace(
8352
8389
  /(from\s+['"])\.\.\/(([A-Z]\w+)(\/[^'"]+)?)(['"])/g,
8353
8390
  (_match, prefix, _fullPath, dirName, subPath, suffix) => {
@@ -8358,18 +8395,6 @@ function transformImports(content, options) {
8358
8395
  return `${prefix}${aliases.importAlias}${aliases.ui}/${kebab}${suffix}`;
8359
8396
  }
8360
8397
  );
8361
- result = result.replace(
8362
- /(from\s+['"])(?:\.\.\/)+hooks\/(\w+)(['"])/g,
8363
- `$1${aliases.importAlias}${aliases.hooks}/$2$3`
8364
- );
8365
- result = result.replace(
8366
- /(from\s+['"])(?:\.\.\/)+utils\/(\w+(?:\/\w+)?)(['"])/g,
8367
- `$1${aliases.importAlias}${aliases.utils}/$2$3`
8368
- );
8369
- result = result.replace(
8370
- /(from\s+['"])(?:\.\.\/)+utils(['"])/g,
8371
- `$1${aliases.importAlias}${aliases.utils}$2`
8372
- );
8373
8398
  return result;
8374
8399
  }
8375
8400
  function normalizeExtensions(content, tsx) {
@@ -8425,16 +8450,17 @@ function writeRegistryItems(tree, options) {
8425
8450
  for (const item of tree.items) {
8426
8451
  const targetBaseDir = getTargetDir(item.type, aliases);
8427
8452
  for (const file of item.files) {
8428
- const fileName = path4.basename(file.path);
8429
8453
  let targetPath;
8430
8454
  if (file.target) {
8431
8455
  targetPath = path4.join(projectDir, file.target);
8432
8456
  } else if (item.type === "registry:ui" || item.type === "registry:component") {
8433
- targetPath = path4.join(projectDir, targetBaseDir, item.name, fileName);
8434
- } else if (item.type === "registry:type") {
8457
+ targetPath = path4.join(projectDir, targetBaseDir, item.name, path4.basename(file.path));
8458
+ } else if (item.type === "registry:hook") {
8459
+ targetPath = path4.join(projectDir, targetBaseDir, item.name, path4.basename(file.path));
8460
+ } else if (file.path.includes("/")) {
8435
8461
  targetPath = path4.join(projectDir, targetBaseDir, file.path);
8436
8462
  } else {
8437
- targetPath = path4.join(projectDir, targetBaseDir, fileName);
8463
+ targetPath = path4.join(projectDir, targetBaseDir, path4.basename(file.path));
8438
8464
  }
8439
8465
  if (fs3.existsSync(targetPath) && !shouldOverwrite) {
8440
8466
  if (log) log(` Skipped (exists): ${targetPath}`);
@@ -8736,9 +8762,9 @@ function formatCount(count, singular, plural) {
8736
8762
  }
8737
8763
 
8738
8764
  // src/cli/commands/add.ts
8739
- var VALID_TYPES = ["ui", "hook", "util", "lib", "type", "style"];
8765
+ var VALID_TYPES = ["ui", "hook", "util", "lib", "type"];
8740
8766
  function createAddCommand() {
8741
- const cmd = new commander.Command("add").description("Add DSAi items (components, hooks, utils) to your project").argument("[items...]", "Item names to add (e.g., button use-focus-trap cn)").option("--all", "Add all items of the specified type (default: ui)", false).option("--type <type>", "Filter by type: ui, hook, util, lib, type").option("--overwrite", "Overwrite existing files", false).option("--dry-run", "Preview changes without writing files", false).option("--registry <path>", "Path to local registry directory").option("--list", "List all available items", false).action(async (items, opts, cmdObj) => {
8767
+ const cmd = new commander.Command("add").description("Add DSAi items (components, hooks, utils) to your project").argument("[items...]", "Item names to add (e.g., button use-focus-trap cn)").option("--all", "Add all items of the specified type (default: ui)", false).option("--type <type>", "Filter by type: ui, hook, util, type").option("--overwrite", "Overwrite existing files", false).option("--dry-run", "Preview changes without writing files", false).option("--registry <path>", "Path to local registry directory").option("--list", "List all available items", false).action(async (items, opts, cmdObj) => {
8742
8768
  const parentOpts = cmdObj.parent?.opts() ?? {};
8743
8769
  const allOpts = {
8744
8770
  ...parentOpts,
@@ -8788,7 +8814,7 @@ ${colors.bold("Available items:")}
8788
8814
  if (!grouped[type]) grouped[type] = [];
8789
8815
  grouped[type].push(item);
8790
8816
  }
8791
- const displayOrder = ["ui", "hook", "util", "lib", "type", "style"];
8817
+ const displayOrder = ["ui", "hook", "util", "lib", "type"];
8792
8818
  for (const type of displayOrder) {
8793
8819
  const typeItems = grouped[type];
8794
8820
  if (!typeItems || typeItems.length === 0) continue;
@@ -9392,6 +9418,8 @@ async function runTokensBuild(options) {
9392
9418
  pipeline: config.tokens.pipeline,
9393
9419
  // Pass formats from config (default: css, scss, json)
9394
9420
  formats: config.tokens.formats,
9421
+ // Pass CSS custom property prefix from config
9422
+ prefix: config.tokens.prefix,
9395
9423
  // Pass output directory from config
9396
9424
  outputDir: config.tokens.outputDir ? path4.resolve(configDir, config.tokens.outputDir) : path4.resolve(configDir, "dist"),
9397
9425
  // Pass themes config for multi-theme builds
@@ -14087,7 +14115,7 @@ function analyzeImports(files, knownNpmDeps) {
14087
14115
  importPattern.lastIndex = 0;
14088
14116
  while ((m2 = importPattern.exec(file.content)) !== null) {
14089
14117
  const specifier = m2[1] ?? "";
14090
- const typesPattern = /\.\.\/(?:\.\.\/)?types(?:\/.*)?$/;
14118
+ const typesPattern = /^\.\.\/\.\.\/types(?:\/.*)?$/;
14091
14119
  if (typesPattern.test(specifier)) {
14092
14120
  registryDeps.add("dsai-types");
14093
14121
  continue;
@@ -14107,6 +14135,16 @@ function analyzeImports(files, knownNpmDeps) {
14107
14135
  if (regName) registryDeps.add(regName);
14108
14136
  continue;
14109
14137
  }
14138
+ const siblingUtilPattern = /^\.\.\/([a-z][\w-]*)(?:\/.*)?$/;
14139
+ const siblingUtilMatch = siblingUtilPattern.exec(specifier);
14140
+ if (siblingUtilMatch && siblingUtilMatch[1]) {
14141
+ const siblingDir = siblingUtilMatch[1];
14142
+ const regName = UTIL_SUBPATH_TO_REGISTRY[siblingDir];
14143
+ if (regName) {
14144
+ registryDeps.add(regName);
14145
+ continue;
14146
+ }
14147
+ }
14110
14148
  const compPattern = /^\.\.\/(\.\.\/)?(?:components\/)?([A-Z]\w+)(?:\/.*)?$/;
14111
14149
  const compMatch = compPattern.exec(specifier);
14112
14150
  if (compMatch && compMatch[2]) {
@@ -14250,6 +14288,8 @@ function buildTypesItem(reactSrcDir, log) {
14250
14288
  const files = sourceFiles.map((f) => {
14251
14289
  let content = f.content;
14252
14290
  content = content.replace(/export \{[^}]*\} from ['"]\.\.\/utils\/[^'"]+['"];?\n?/g, "");
14291
+ content = content.replace(/export\s+(?!type)\{[^}]*\}\s+from\s+['"]\.\/[^'"]+['"];?\n?/g, "");
14292
+ content = content.replace(/\/\*\*\s*\n\s*\*\s*@deprecated[^*]*\*\/\s*\n/g, "");
14253
14293
  return {
14254
14294
  path: `types/${f.path}`,
14255
14295
  type: "registry:type",
@@ -14392,9 +14432,135 @@ function createRegistryCommand() {
14392
14432
  }
14393
14433
 
14394
14434
  // src/version.ts
14395
- var version = "0.0.1";
14396
-
14397
- // src/cli/create-program.ts
14435
+ var version = "1.3.0";
14436
+
14437
+ // src/cli/commands/info.ts
14438
+ var registry = {
14439
+ package: "@dsai-io/tools",
14440
+ version,
14441
+ description: "Design System AI Toolkit \u2014 build, validate, and manage design tokens and icons.",
14442
+ documentation: "https://github.com/michelve/dsai",
14443
+ cli: {
14444
+ binary: "dsai",
14445
+ globalOptions: [
14446
+ { flag: "-c, --config <path>", description: "Path to config file" },
14447
+ { flag: "--cwd <dir>", description: "Working directory" },
14448
+ { flag: "--debug", description: "Enable debug mode" },
14449
+ { flag: "-q, --quiet", description: "Quiet mode \u2014 minimal output" },
14450
+ { flag: "--dry-run", description: "Dry run \u2014 don't write files" },
14451
+ { flag: "-v, --version", description: "Show version number" },
14452
+ { flag: "-h, --help", description: "Show help" }
14453
+ ],
14454
+ commands: [
14455
+ {
14456
+ name: "add [items...]",
14457
+ description: "Add DSAi items (components, hooks, utils) to your project",
14458
+ options: ["--all", "--type <type>", "--overwrite", "--dry-run", "--list"]
14459
+ },
14460
+ {
14461
+ name: "tokens build",
14462
+ description: "Build design tokens from source collections",
14463
+ options: ["--platforms <list>", "--watch", "--clean", "--theme <name>", "--list-themes"]
14464
+ },
14465
+ {
14466
+ name: "tokens validate",
14467
+ description: "Validate design token files",
14468
+ options: ["--fix", "--strict"]
14469
+ },
14470
+ {
14471
+ name: "tokens transform",
14472
+ description: "Transform Figma exports to Style Dictionary format",
14473
+ options: ["--dry-run", "--default-mode <mode>", "--ignore-modes <list>"]
14474
+ },
14475
+ {
14476
+ name: "tokens sync",
14477
+ description: "Sync tokens flat file",
14478
+ options: ["--format <format>"]
14479
+ },
14480
+ {
14481
+ name: "tokens postprocess",
14482
+ description: "Post-process CSS theme files",
14483
+ options: []
14484
+ },
14485
+ {
14486
+ name: "tokens snapshots list",
14487
+ description: "List all token collection snapshots",
14488
+ options: []
14489
+ },
14490
+ {
14491
+ name: "tokens snapshots info <id>",
14492
+ description: "Show snapshot details",
14493
+ options: []
14494
+ },
14495
+ {
14496
+ name: "tokens snapshots rollback <id>",
14497
+ description: "Rollback to a snapshot",
14498
+ options: ["--dry-run"]
14499
+ },
14500
+ {
14501
+ name: "icons build",
14502
+ description: "Generate icon components from SVG files",
14503
+ options: ["--format <format>", "--no-optimize", "--dry-run"]
14504
+ },
14505
+ {
14506
+ name: "init",
14507
+ description: "Initialize DSAi configuration with interactive prompts",
14508
+ options: ["--yes", "--template <template>", "--force"]
14509
+ },
14510
+ {
14511
+ name: "config",
14512
+ description: "Display resolved configuration",
14513
+ options: ["--json"]
14514
+ },
14515
+ {
14516
+ name: "registry build",
14517
+ description: "Build component registry JSON from source",
14518
+ options: ["--src <path>", "--out <path>", "--verbose"]
14519
+ },
14520
+ {
14521
+ name: "info",
14522
+ description: "Show tool inventory and capabilities",
14523
+ options: ["--json"]
14524
+ }
14525
+ ]
14526
+ }
14527
+ };
14528
+ function printInfo() {
14529
+ const log = (msg) => {
14530
+ console.log(msg);
14531
+ };
14532
+ log("");
14533
+ log(colors.bold(`${registry.package} v${registry.version}`));
14534
+ log(colors.muted(registry.description));
14535
+ log(colors.muted("\u2500".repeat(60)));
14536
+ log("");
14537
+ log(colors.bold("CLI Commands"));
14538
+ log("");
14539
+ for (const cmd of registry.cli.commands) {
14540
+ const opts = cmd.options.length > 0 ? colors.muted(` [${cmd.options.join(", ")}]`) : "";
14541
+ log(` ${colors.command(`dsai ${cmd.name}`)}${opts}`);
14542
+ log(` ${colors.muted(cmd.description)}`);
14543
+ }
14544
+ log("");
14545
+ log(colors.bold("Global Options"));
14546
+ log("");
14547
+ for (const opt of registry.cli.globalOptions) {
14548
+ log(` ${colors.cyan(opt.flag)} ${colors.muted(opt.description)}`);
14549
+ }
14550
+ log("");
14551
+ log(colors.bold("Documentation"));
14552
+ log(` ${colors.path(registry.documentation)}`);
14553
+ log("");
14554
+ }
14555
+ function createInfoCommand() {
14556
+ return new commander.Command("info").description("Show tool inventory and capabilities").option("--json", "Output as JSON for agent consumption", false).action((options) => {
14557
+ if (options.json) {
14558
+ console.log(JSON.stringify(registry, null, 2));
14559
+ } else {
14560
+ printInfo();
14561
+ }
14562
+ });
14563
+ }
14398
14564
  function createProgram() {
14399
14565
  const program2 = new commander.Command().name("dsai").description(
14400
14566
  `${colors.bold("DSAI Tools")} - Design System AI Toolkit
@@ -14461,6 +14627,7 @@ async function run(args = process.argv) {
14461
14627
  program.addCommand(createInitCommand());
14462
14628
  program.addCommand(createConfigCommand());
14463
14629
  program.addCommand(createRegistryCommand());
14630
+ program.addCommand(createInfoCommand());
14464
14631
  setupErrorHandling(program);
14465
14632
  await program.parseAsync(args);
14466
14633
  }