universal-dev-standards 3.5.1-beta.7 → 3.5.1-beta.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-dev-standards",
3
- "version": "3.5.1-beta.7",
3
+ "version": "3.5.1-beta.9",
4
4
  "description": "CLI tool for adopting Universal Development Standards",
5
5
  "keywords": [
6
6
  "documentation",
@@ -17,7 +17,9 @@ import {
17
17
  import { downloadFromGitHub, getMarketplaceSkillsInfo } from '../utils/github.js';
18
18
  import {
19
19
  getInstalledSkillsInfoForAgent,
20
- getInstalledCommandsForAgent
20
+ getInstalledCommandsForAgent,
21
+ installSkillsToMultipleAgents,
22
+ installCommandsToMultipleAgents
21
23
  } from '../utils/skills-installer.js';
22
24
  import {
23
25
  getAgentConfig,
@@ -245,7 +247,7 @@ export async function checkCommand(options = {}) {
245
247
  checkIntegrationFiles(manifest, projectPath, msg);
246
248
 
247
249
  // Skills status
248
- displaySkillsStatus(manifest, projectPath, msg);
250
+ const { missingSkills, missingCommands } = displaySkillsStatus(manifest, projectPath, msg);
249
251
 
250
252
  // Coverage report
251
253
  displayCoverageReport(manifest, msg, common);
@@ -258,6 +260,12 @@ export async function checkCommand(options = {}) {
258
260
  } else {
259
261
  console.log(chalk.yellow(msg.issuesDetected));
260
262
  }
263
+
264
+ // Offer to install missing Skills/Commands if not in noInteractive mode
265
+ if ((missingSkills.length > 0 || missingCommands.length > 0) && !options.noInteractive) {
266
+ await promptSkillsCommandsInstallation(manifest, projectPath, missingSkills, missingCommands, msg);
267
+ }
268
+
261
269
  console.log();
262
270
  }
263
271
 
@@ -648,18 +656,21 @@ async function migrateToHashBasedTracking(projectPath, manifest) {
648
656
  }
649
657
 
650
658
  /**
651
- * Display skills status
659
+ * Display skills status and return missing Skills/Commands info
660
+ * @returns {{missingSkills: Array, missingCommands: Array}}
652
661
  */
653
662
  function displaySkillsStatus(manifest, projectPath, msg) {
654
663
  console.log(chalk.cyan(msg.skillsStatus));
655
664
 
656
665
  const aiTools = manifest.aiTools || [];
666
+ const missingSkills = [];
667
+ const missingCommands = [];
657
668
 
658
669
  // If no AI tools configured, show basic info
659
670
  if (aiTools.length === 0) {
660
671
  console.log(chalk.gray(` ${msg.noAiToolsConfigured || 'No AI tools configured'}`));
661
672
  console.log();
662
- return;
673
+ return { missingSkills, missingCommands };
663
674
  }
664
675
 
665
676
  // Check for Marketplace installation (Claude Code specific)
@@ -701,7 +712,10 @@ function displaySkillsStatus(manifest, projectPath, msg) {
701
712
  const projectSkillsInfo = getInstalledSkillsInfoForAgent(tool, 'project', projectPath);
702
713
  const userSkillsInfo = getInstalledSkillsInfoForAgent(tool, 'user', projectPath);
703
714
 
704
- if (projectSkillsInfo?.installed || userSkillsInfo?.installed) {
715
+ // Check if using marketplace for Claude Code
716
+ const usingMarketplace = isMarketplace && tool === 'claude-code';
717
+
718
+ if (projectSkillsInfo?.installed || userSkillsInfo?.installed || usingMarketplace) {
705
719
  console.log(chalk.green(` ✓ Skills ${msg.installed || 'installed'}:`));
706
720
  if (userSkillsInfo?.installed) {
707
721
  console.log(chalk.gray(` - ${msg.skillsGlobal || 'User level'}: ${userSkillsInfo.path}`));
@@ -724,6 +738,12 @@ function displaySkillsStatus(manifest, projectPath, msg) {
724
738
  console.log(chalk.gray(` ${msg.canUseFallback || 'Can use fallback'}: ${config.fallbackSkillsPath}`));
725
739
  }
726
740
  }
741
+ // Track missing Skills
742
+ missingSkills.push({
743
+ agent: tool,
744
+ displayName,
745
+ paths: config.skills
746
+ });
727
747
  }
728
748
 
729
749
  // Check Commands installation for this agent
@@ -737,6 +757,12 @@ function displaySkillsStatus(manifest, projectPath, msg) {
737
757
  }
738
758
  } else {
739
759
  console.log(chalk.gray(` ○ Commands: ${msg.notInstalled || 'Not installed'}`));
760
+ // Track missing Commands
761
+ missingCommands.push({
762
+ agent: tool,
763
+ displayName,
764
+ path: config.commands.project
765
+ });
740
766
  }
741
767
  }
742
768
  }
@@ -758,6 +784,173 @@ function displaySkillsStatus(manifest, projectPath, msg) {
758
784
  }
759
785
 
760
786
  console.log();
787
+
788
+ return { missingSkills, missingCommands };
789
+ }
790
+
791
+ /**
792
+ * Prompt user to install missing Skills/Commands discovered during check
793
+ * @param {Object} manifest - The manifest object
794
+ * @param {string} projectPath - Project path
795
+ * @param {Array} missingSkills - Array of {agent, displayName, paths}
796
+ * @param {Array} missingCommands - Array of {agent, displayName, path}
797
+ * @param {Object} msg - i18n messages
798
+ * @returns {Promise<boolean>} - Whether anything was installed
799
+ */
800
+ async function promptSkillsCommandsInstallation(manifest, projectPath, missingSkills, missingCommands, msg) {
801
+ const repoInfo = getRepositoryInfo();
802
+ let installedAnything = false;
803
+
804
+ // Handle missing Skills with checkbox selection
805
+ if (missingSkills.length > 0) {
806
+ console.log();
807
+ console.log(chalk.cyan('━'.repeat(50)));
808
+ console.log(chalk.cyan.bold(msg.offerSkillsInstallation || 'Skills Installation'));
809
+ console.log(chalk.cyan('━'.repeat(50)));
810
+ console.log();
811
+
812
+ // Build checkbox choices
813
+ const skillChoices = missingSkills.map(skill => ({
814
+ name: skill.displayName,
815
+ value: skill.agent,
816
+ checked: true // Default checked for opt-out behavior
817
+ }));
818
+
819
+ // Add skip option
820
+ skillChoices.push(new inquirer.Separator());
821
+ skillChoices.push({
822
+ name: chalk.gray(msg.skipInstallation || 'Skip'),
823
+ value: '__skip__'
824
+ });
825
+
826
+ const { selectedSkillAgents } = await inquirer.prompt([{
827
+ type: 'checkbox',
828
+ name: 'selectedSkillAgents',
829
+ message: msg.selectSkillsToInstall || 'Select AI tools to install Skills for:',
830
+ choices: skillChoices,
831
+ validate: (answer) => {
832
+ if (answer.includes('__skip__') && answer.length > 1) {
833
+ return t().commands.update.skipValidationError || 'Cannot select Skip with other options';
834
+ }
835
+ return true;
836
+ }
837
+ }]);
838
+
839
+ const filteredSkillAgents = selectedSkillAgents.filter(a => a !== '__skip__');
840
+
841
+ if (filteredSkillAgents.length > 0) {
842
+ // Prompt for installation level
843
+ const { skillsLevel } = await inquirer.prompt([{
844
+ type: 'list',
845
+ name: 'skillsLevel',
846
+ message: t().commands.update.skillsLevelQuestion || 'Where should Skills be installed?',
847
+ choices: [
848
+ { name: `${t().commands.update.projectLevel || 'Project level'} (.claude/skills/, etc.)`, value: 'project' },
849
+ { name: `${t().commands.update.userLevel || 'User level'} (~/.claude/skills/, etc.)`, value: 'user' }
850
+ ],
851
+ default: 'project'
852
+ }]);
853
+
854
+ // Install Skills
855
+ const spinner = ora(t().commands.update.installingNewSkills || 'Installing Skills...').start();
856
+ const skillResult = await installSkillsToMultipleAgents(
857
+ filteredSkillAgents.map(agent => ({ agent, level: skillsLevel })),
858
+ null,
859
+ projectPath
860
+ );
861
+
862
+ // Update manifest
863
+ if (!manifest.skills) manifest.skills = {};
864
+ manifest.skills.installed = true;
865
+ manifest.skills.version = repoInfo.skills.version;
866
+ manifest.skills.installations = [
867
+ ...(manifest.skills.installations || []),
868
+ ...filteredSkillAgents.map(agent => ({ agent, level: skillsLevel }))
869
+ ];
870
+
871
+ if (skillResult.totalErrors === 0) {
872
+ spinner.succeed((msg.skillsInstalledSuccess || 'Installed Skills for {count} AI tools')
873
+ .replace('{count}', filteredSkillAgents.length));
874
+ } else {
875
+ spinner.warn((t().commands.update.newSkillsInstalledWithErrors || 'Installed Skills with {errors} errors')
876
+ .replace('{errors}', skillResult.totalErrors));
877
+ }
878
+
879
+ installedAnything = true;
880
+ }
881
+ }
882
+
883
+ // Handle missing Commands with checkbox selection
884
+ if (missingCommands.length > 0) {
885
+ console.log();
886
+ console.log(chalk.cyan('━'.repeat(50)));
887
+ console.log(chalk.cyan.bold(msg.offerCommandsInstallation || 'Commands Installation'));
888
+ console.log(chalk.cyan('━'.repeat(50)));
889
+ console.log();
890
+
891
+ // Build checkbox choices
892
+ const commandChoices = missingCommands.map(cmd => ({
893
+ name: `${cmd.displayName} ${chalk.gray(`(${cmd.path})`)}`,
894
+ value: cmd.agent,
895
+ checked: true // Default checked for opt-out behavior
896
+ }));
897
+
898
+ // Add skip option
899
+ commandChoices.push(new inquirer.Separator());
900
+ commandChoices.push({
901
+ name: chalk.gray(msg.skipInstallation || 'Skip'),
902
+ value: '__skip__'
903
+ });
904
+
905
+ const { selectedCommandAgents } = await inquirer.prompt([{
906
+ type: 'checkbox',
907
+ name: 'selectedCommandAgents',
908
+ message: msg.selectCommandsToInstall || 'Select AI tools to install Commands for:',
909
+ choices: commandChoices,
910
+ validate: (answer) => {
911
+ if (answer.includes('__skip__') && answer.length > 1) {
912
+ return t().commands.update.skipValidationError || 'Cannot select Skip with other options';
913
+ }
914
+ return true;
915
+ }
916
+ }]);
917
+
918
+ const filteredCommandAgents = selectedCommandAgents.filter(a => a !== '__skip__');
919
+
920
+ if (filteredCommandAgents.length > 0) {
921
+ const spinner = ora(t().commands.update.installingNewCommands || 'Installing commands...').start();
922
+ const cmdResult = await installCommandsToMultipleAgents(
923
+ filteredCommandAgents,
924
+ null,
925
+ projectPath
926
+ );
927
+
928
+ // Update manifest
929
+ if (!manifest.commands) manifest.commands = {};
930
+ manifest.commands.installed = true;
931
+ manifest.commands.installations = [
932
+ ...(manifest.commands.installations || []),
933
+ ...filteredCommandAgents
934
+ ];
935
+
936
+ if (cmdResult.totalErrors === 0) {
937
+ spinner.succeed((msg.commandsInstalledSuccess || 'Installed commands for {count} AI tools')
938
+ .replace('{count}', filteredCommandAgents.length));
939
+ } else {
940
+ spinner.warn((t().commands.update.newCommandsInstalledWithErrors || 'Installed commands with {errors} errors')
941
+ .replace('{errors}', cmdResult.totalErrors));
942
+ }
943
+
944
+ installedAnything = true;
945
+ }
946
+ }
947
+
948
+ // Save manifest if anything was installed
949
+ if (installedAnything) {
950
+ writeManifest(manifest, projectPath);
951
+ }
952
+
953
+ return installedAnything;
761
954
  }
762
955
 
763
956
  /**
@@ -1005,7 +1005,7 @@ async function promptNewFeatureInstallation(missingSkills, missingCommands) {
1005
1005
 
1006
1006
  const result = { installSkills: [], installCommands: [] };
1007
1007
 
1008
- // Handle missing Skills
1008
+ // Handle missing Skills with checkbox selection
1009
1009
  if (missingSkills.length > 0) {
1010
1010
  console.log(chalk.yellow(msg.skillsNotInstalledFor || 'Skills not yet installed for these AI tools:'));
1011
1011
  for (const skill of missingSkills) {
@@ -1013,14 +1013,38 @@ async function promptNewFeatureInstallation(missingSkills, missingCommands) {
1013
1013
  }
1014
1014
  console.log();
1015
1015
 
1016
- const { shouldInstallSkills } = await inquirer.prompt([{
1017
- type: 'confirm',
1018
- name: 'shouldInstallSkills',
1019
- message: msg.installSkillsNow || 'Would you like to install Skills for these AI tools?',
1020
- default: true
1016
+ // Build checkbox choices
1017
+ const skillChoices = missingSkills.map(skill => ({
1018
+ name: skill.displayName,
1019
+ value: skill.agent,
1020
+ checked: true // Default checked for opt-out behavior
1021
+ }));
1022
+
1023
+ // Add skip option
1024
+ skillChoices.push(new inquirer.Separator());
1025
+ skillChoices.push({
1026
+ name: chalk.gray(msg.skipSkillsInstallation || 'Skip Skills installation'),
1027
+ value: '__skip__'
1028
+ });
1029
+
1030
+ const { selectedSkillAgents } = await inquirer.prompt([{
1031
+ type: 'checkbox',
1032
+ name: 'selectedSkillAgents',
1033
+ message: msg.selectSkillsToInstall || 'Select AI tools to install Skills for:',
1034
+ choices: skillChoices,
1035
+ validate: (answer) => {
1036
+ // If skip is selected, ensure it's the only selection
1037
+ if (answer.includes('__skip__') && answer.length > 1) {
1038
+ return msg.skipValidationError || 'Cannot select Skip with other options';
1039
+ }
1040
+ return true;
1041
+ }
1021
1042
  }]);
1022
1043
 
1023
- if (shouldInstallSkills) {
1044
+ // Filter out skip and handle selection
1045
+ const filteredSkillAgents = selectedSkillAgents.filter(a => a !== '__skip__');
1046
+
1047
+ if (filteredSkillAgents.length > 0) {
1024
1048
  // Prompt for installation level
1025
1049
  const { skillsLevel } = await inquirer.prompt([{
1026
1050
  type: 'list',
@@ -1033,15 +1057,15 @@ async function promptNewFeatureInstallation(missingSkills, missingCommands) {
1033
1057
  default: 'project'
1034
1058
  }]);
1035
1059
 
1036
- result.installSkills = missingSkills.map(s => ({
1037
- agent: s.agent,
1060
+ result.installSkills = filteredSkillAgents.map(agent => ({
1061
+ agent,
1038
1062
  level: skillsLevel
1039
1063
  }));
1040
1064
  }
1041
1065
  console.log();
1042
1066
  }
1043
1067
 
1044
- // Handle missing Commands
1068
+ // Handle missing Commands with checkbox selection
1045
1069
  if (missingCommands.length > 0) {
1046
1070
  console.log(chalk.yellow(msg.commandsNotInstalledFor || 'Slash commands not yet installed for these AI tools:'));
1047
1071
  for (const cmd of missingCommands) {
@@ -1049,16 +1073,35 @@ async function promptNewFeatureInstallation(missingSkills, missingCommands) {
1049
1073
  }
1050
1074
  console.log();
1051
1075
 
1052
- const { shouldInstallCommands } = await inquirer.prompt([{
1053
- type: 'confirm',
1054
- name: 'shouldInstallCommands',
1055
- message: msg.installCommandsNow || 'Would you like to install slash commands for these AI tools?',
1056
- default: true
1076
+ // Build checkbox choices
1077
+ const commandChoices = missingCommands.map(cmd => ({
1078
+ name: `${cmd.displayName} ${chalk.gray(`(${cmd.path})`)}`,
1079
+ value: cmd.agent,
1080
+ checked: true // Default checked for opt-out behavior
1081
+ }));
1082
+
1083
+ // Add skip option
1084
+ commandChoices.push(new inquirer.Separator());
1085
+ commandChoices.push({
1086
+ name: chalk.gray(msg.skipCommandsInstallation || 'Skip Commands installation'),
1087
+ value: '__skip__'
1088
+ });
1089
+
1090
+ const { selectedCommandAgents } = await inquirer.prompt([{
1091
+ type: 'checkbox',
1092
+ name: 'selectedCommandAgents',
1093
+ message: msg.selectCommandsToInstall || 'Select AI tools to install Commands for:',
1094
+ choices: commandChoices,
1095
+ validate: (answer) => {
1096
+ if (answer.includes('__skip__') && answer.length > 1) {
1097
+ return msg.skipValidationError || 'Cannot select Skip with other options';
1098
+ }
1099
+ return true;
1100
+ }
1057
1101
  }]);
1058
1102
 
1059
- if (shouldInstallCommands) {
1060
- result.installCommands = missingCommands.map(c => c.agent);
1061
- }
1103
+ // Filter out skip
1104
+ result.installCommands = selectedCommandAgents.filter(a => a !== '__skip__');
1062
1105
  }
1063
1106
 
1064
1107
  return result;
@@ -594,7 +594,15 @@ export const messages = {
594
594
  runNpmUpdate: 'Run: npm update -g universal-dev-standards',
595
595
  // Final status
596
596
  projectCompliant: '✓ Project is compliant with standards',
597
- issuesDetected: '⚠ Some issues detected. Review above for details.'
597
+ issuesDetected: '⚠ Some issues detected. Review above for details.',
598
+ // Installation prompts
599
+ offerSkillsInstallation: 'Skills Installation',
600
+ offerCommandsInstallation: 'Commands Installation',
601
+ selectSkillsToInstall: 'Select AI tools to install Skills for:',
602
+ selectCommandsToInstall: 'Select AI tools to install Commands for:',
603
+ skipInstallation: 'Skip',
604
+ skillsInstalledSuccess: 'Installed Skills for {count} AI tools',
605
+ commandsInstalledSuccess: 'Installed commands for {count} AI tools'
598
606
  },
599
607
 
600
608
  // init command (commands/init.js)
@@ -752,6 +760,11 @@ export const messages = {
752
760
  commandsNotInstalledFor: 'Slash commands not yet installed for these AI tools:',
753
761
  installSkillsNow: 'Would you like to install Skills for these AI tools?',
754
762
  installCommandsNow: 'Would you like to install slash commands for these AI tools?',
763
+ selectSkillsToInstall: 'Select AI tools to install Skills for:',
764
+ selectCommandsToInstall: 'Select AI tools to install Commands for:',
765
+ skipSkillsInstallation: 'Skip Skills installation',
766
+ skipCommandsInstallation: 'Skip Commands installation',
767
+ skipValidationError: 'Cannot select Skip with other options',
755
768
  skillsLevelQuestion: 'Where should Skills be installed?',
756
769
  projectLevel: 'Project level',
757
770
  userLevel: 'User level',
@@ -1419,7 +1432,15 @@ export const messages = {
1419
1432
  runNpmUpdate: '執行:npm update -g universal-dev-standards',
1420
1433
  // Final status
1421
1434
  projectCompliant: '✓ 專案符合標準',
1422
- issuesDetected: '⚠ 偵測到一些問題。請檢視上方詳情。'
1435
+ issuesDetected: '⚠ 偵測到一些問題。請檢視上方詳情。',
1436
+ // Installation prompts
1437
+ offerSkillsInstallation: 'Skills 安裝',
1438
+ offerCommandsInstallation: '斜線命令安裝',
1439
+ selectSkillsToInstall: '選擇要安裝 Skills 的 AI 工具:',
1440
+ selectCommandsToInstall: '選擇要安裝斜線命令的 AI 工具:',
1441
+ skipInstallation: '跳過',
1442
+ skillsInstalledSuccess: '已為 {count} 個 AI 工具安裝 Skills',
1443
+ commandsInstalledSuccess: '已為 {count} 個 AI 工具安裝斜線命令'
1423
1444
  },
1424
1445
 
1425
1446
  // init command (commands/init.js)
@@ -1577,6 +1598,11 @@ export const messages = {
1577
1598
  commandsNotInstalledFor: '以下 AI 工具尚未安裝斜線命令:',
1578
1599
  installSkillsNow: '是否要為這些 AI 工具安裝 Skills?',
1579
1600
  installCommandsNow: '是否要為這些 AI 工具安裝斜線命令?',
1601
+ selectSkillsToInstall: '選擇要安裝 Skills 的 AI 工具:',
1602
+ selectCommandsToInstall: '選擇要安裝斜線命令的 AI 工具:',
1603
+ skipSkillsInstallation: '跳過 Skills 安裝',
1604
+ skipCommandsInstallation: '跳過斜線命令安裝',
1605
+ skipValidationError: '選擇「跳過」時不能同時選擇其他選項',
1580
1606
  skillsLevelQuestion: 'Skills 要安裝到哪裡?',
1581
1607
  projectLevel: '專案層級',
1582
1608
  userLevel: '使用者層級',
@@ -2147,7 +2173,15 @@ export const messages = {
2147
2173
  runNpmUpdate: '执行:npm update -g universal-dev-standards',
2148
2174
  // Final status
2149
2175
  projectCompliant: '✓ 项目符合标准',
2150
- issuesDetected: '⚠ 检测到一些问题。详情请查看上文。'
2176
+ issuesDetected: '⚠ 检测到一些问题。详情请查看上文。',
2177
+ // Installation prompts
2178
+ offerSkillsInstallation: 'Skills 安装',
2179
+ offerCommandsInstallation: '斜线命令安装',
2180
+ selectSkillsToInstall: '选择要安装 Skills 的 AI 工具:',
2181
+ selectCommandsToInstall: '选择要安装斜线命令的 AI 工具:',
2182
+ skipInstallation: '跳过',
2183
+ skillsInstalledSuccess: '已为 {count} 个 AI 工具安装 Skills',
2184
+ commandsInstalledSuccess: '已为 {count} 个 AI 工具安装斜线命令'
2151
2185
  },
2152
2186
 
2153
2187
  // update command
@@ -2234,6 +2268,11 @@ export const messages = {
2234
2268
  commandsNotInstalledFor: '以下 AI 工具尚未安装斜线命令:',
2235
2269
  installSkillsNow: '是否要为这些 AI 工具安装 Skills?',
2236
2270
  installCommandsNow: '是否要为这些 AI 工具安装斜线命令?',
2271
+ selectSkillsToInstall: '选择要安装 Skills 的 AI 工具:',
2272
+ selectCommandsToInstall: '选择要安装斜线命令的 AI 工具:',
2273
+ skipSkillsInstallation: '跳过 Skills 安装',
2274
+ skipCommandsInstallation: '跳过斜线命令安装',
2275
+ skipValidationError: '选择「跳过」时不能同时选择其他选项',
2237
2276
  skillsLevelQuestion: 'Skills 要安装到哪里?',
2238
2277
  projectLevel: '项目级别',
2239
2278
  userLevel: '用户级别',
@@ -473,16 +473,37 @@ export function getInstalledSkillsInfoForAgent(agent, level, projectPath = null)
473
473
 
474
474
  const manifestPath = join(targetDir, '.manifest.json');
475
475
 
476
+ // Check if manifest exists
476
477
  if (!existsSync(manifestPath)) {
477
- // Skills exist but no manifest
478
- return {
479
- installed: true,
480
- version: null,
481
- source: 'unknown',
482
- agent,
483
- level,
484
- path: targetDir
485
- };
478
+ // No manifest - check if there are actual skill files (SKILL.md in subdirectories)
479
+ try {
480
+ const entries = readdirSync(targetDir, { withFileTypes: true });
481
+ const skillDirs = entries.filter(e => e.isDirectory() && !e.name.startsWith('.'));
482
+
483
+ // Check if any subdirectory contains a SKILL.md file
484
+ const hasSkillFiles = skillDirs.some(dir => {
485
+ const skillFile = join(targetDir, dir.name, 'SKILL.md');
486
+ return existsSync(skillFile);
487
+ });
488
+
489
+ if (!hasSkillFiles) {
490
+ // Empty directory or no valid skills - not installed
491
+ return null;
492
+ }
493
+
494
+ // Has skill files but no manifest
495
+ return {
496
+ installed: true,
497
+ version: null,
498
+ source: 'unknown',
499
+ agent,
500
+ level,
501
+ path: targetDir
502
+ };
503
+ } catch {
504
+ // Error reading directory - assume not installed
505
+ return null;
506
+ }
486
507
  }
487
508
 
488
509
  try {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "version": "3.5.1-beta.7",
3
+ "version": "3.5.1-beta.9",
4
4
  "lastUpdated": "2026-01-15",
5
5
  "description": "Standards registry for universal-dev-standards with integrated skills and AI-optimized formats",
6
6
  "formats": {
@@ -48,14 +48,14 @@
48
48
  "standards": {
49
49
  "name": "universal-dev-standards",
50
50
  "url": "https://github.com/AsiaOstrich/universal-dev-standards",
51
- "version": "3.5.1-beta.7"
51
+ "version": "3.5.1-beta.9"
52
52
  },
53
53
  "skills": {
54
54
  "name": "universal-dev-standards",
55
55
  "url": "https://github.com/AsiaOstrich/universal-dev-standards",
56
56
  "localPath": "skills/claude-code",
57
57
  "rawUrl": "https://raw.githubusercontent.com/AsiaOstrich/universal-dev-standards/main/skills/claude-code",
58
- "version": "3.5.1-beta.7",
58
+ "version": "3.5.1-beta.9",
59
59
  "note": "Skills are now included in the main repository under skills/"
60
60
  }
61
61
  },