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 +1 -1
- package/src/commands/check.js +198 -5
- package/src/commands/update.js +61 -18
- package/src/i18n/messages.js +42 -3
- package/src/utils/skills-installer.js +30 -9
- package/standards-registry.json +3 -3
package/package.json
CHANGED
package/src/commands/check.js
CHANGED
|
@@ -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
|
|
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
|
/**
|
package/src/commands/update.js
CHANGED
|
@@ -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
|
-
|
|
1017
|
-
|
|
1018
|
-
name:
|
|
1019
|
-
|
|
1020
|
-
|
|
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
|
-
|
|
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 =
|
|
1037
|
-
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
|
-
|
|
1053
|
-
|
|
1054
|
-
name:
|
|
1055
|
-
|
|
1056
|
-
|
|
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
|
-
|
|
1060
|
-
|
|
1061
|
-
}
|
|
1103
|
+
// Filter out skip
|
|
1104
|
+
result.installCommands = selectedCommandAgents.filter(a => a !== '__skip__');
|
|
1062
1105
|
}
|
|
1063
1106
|
|
|
1064
1107
|
return result;
|
package/src/i18n/messages.js
CHANGED
|
@@ -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
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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 {
|
package/standards-registry.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"version": "3.5.1-beta.
|
|
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.
|
|
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.
|
|
58
|
+
"version": "3.5.1-beta.9",
|
|
59
59
|
"note": "Skills are now included in the main repository under skills/"
|
|
60
60
|
}
|
|
61
61
|
},
|