universal-dev-standards 3.5.0-beta.12 → 3.5.0-beta.14
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 +42 -3
- package/src/commands/init.js +31 -8
- package/src/prompts/init.js +17 -2
- package/src/utils/github.js +48 -0
- package/standards-registry.json +4 -4
package/package.json
CHANGED
package/src/commands/check.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
compareFileHash,
|
|
14
14
|
hasFileHashes
|
|
15
15
|
} from '../utils/hasher.js';
|
|
16
|
-
import { downloadFromGitHub } from '../utils/github.js';
|
|
16
|
+
import { downloadFromGitHub, getMarketplaceSkillsInfo } from '../utils/github.js';
|
|
17
17
|
import {
|
|
18
18
|
parseReferences,
|
|
19
19
|
compareStandardsWithReferences
|
|
@@ -619,6 +619,11 @@ async function migrateToHashBasedTracking(projectPath, manifest) {
|
|
|
619
619
|
*/
|
|
620
620
|
function displaySkillsStatus(manifest, projectPath) {
|
|
621
621
|
console.log(chalk.cyan('Skills Status:'));
|
|
622
|
+
|
|
623
|
+
// Check which skills-compatible tools are configured
|
|
624
|
+
const hasClaudeCode = manifest.aiTools?.includes('claude-code');
|
|
625
|
+
const hasOpenCode = manifest.aiTools?.includes('opencode');
|
|
626
|
+
|
|
622
627
|
if (manifest.skills.installed) {
|
|
623
628
|
const location = manifest.skills.location || '';
|
|
624
629
|
// Check if skills are installed via Plugin Marketplace
|
|
@@ -629,8 +634,20 @@ function displaySkillsStatus(manifest, projectPath) {
|
|
|
629
634
|
|
|
630
635
|
if (isMarketplace) {
|
|
631
636
|
console.log(chalk.green(' ✓ Skills installed via Plugin Marketplace'));
|
|
637
|
+
|
|
638
|
+
// Try to get actual version from marketplace
|
|
639
|
+
const marketplaceInfo = getMarketplaceSkillsInfo();
|
|
640
|
+
if (marketplaceInfo && marketplaceInfo.version && marketplaceInfo.version !== 'unknown') {
|
|
641
|
+
console.log(chalk.gray(` Version: ${marketplaceInfo.version}`));
|
|
642
|
+
if (marketplaceInfo.lastUpdated) {
|
|
643
|
+
const updateDate = marketplaceInfo.lastUpdated.split('T')[0];
|
|
644
|
+
console.log(chalk.gray(` Last updated: ${updateDate}`));
|
|
645
|
+
}
|
|
646
|
+
} else {
|
|
647
|
+
console.log(chalk.gray(' Version: (run /plugin list to check)'));
|
|
648
|
+
}
|
|
649
|
+
|
|
632
650
|
console.log(chalk.gray(' Managed by Claude Code plugin system'));
|
|
633
|
-
console.log(chalk.gray(' To verify: /plugin list'));
|
|
634
651
|
console.log(chalk.gray(' Note: Marketplace skills are not file-based'));
|
|
635
652
|
} else {
|
|
636
653
|
const skillsDir = join(process.env.HOME || '', '.claude', 'skills');
|
|
@@ -638,9 +655,23 @@ function displaySkillsStatus(manifest, projectPath) {
|
|
|
638
655
|
const hasProjectSkills = existsSync(join(projectPath, '.claude', 'skills'));
|
|
639
656
|
|
|
640
657
|
if (hasGlobalSkills || hasProjectSkills) {
|
|
641
|
-
console.log(chalk.green(' ✓
|
|
658
|
+
console.log(chalk.green(' ✓ Skills installed'));
|
|
642
659
|
if (hasGlobalSkills) console.log(chalk.gray(' Global: ~/.claude/skills/'));
|
|
643
660
|
if (hasProjectSkills) console.log(chalk.gray(' Project: .claude/skills/'));
|
|
661
|
+
|
|
662
|
+
// Show compatible tools
|
|
663
|
+
const compatibleTools = [];
|
|
664
|
+
if (hasClaudeCode) compatibleTools.push('Claude Code');
|
|
665
|
+
if (hasOpenCode) compatibleTools.push('OpenCode');
|
|
666
|
+
if (compatibleTools.length > 0) {
|
|
667
|
+
console.log(chalk.gray(` Compatible: ${compatibleTools.join(', ')}`));
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// OpenCode auto-detection note (only if OpenCode is configured without Claude Code)
|
|
671
|
+
if (hasOpenCode && !hasClaudeCode) {
|
|
672
|
+
console.log(chalk.gray(' Note: OpenCode auto-detects .claude/skills/'));
|
|
673
|
+
}
|
|
674
|
+
|
|
644
675
|
// Migration suggestion
|
|
645
676
|
console.log(chalk.yellow(' ⚠ Consider migrating to Plugin Marketplace'));
|
|
646
677
|
console.log(chalk.gray(' Marketplace provides automatic updates and easier management.'));
|
|
@@ -655,6 +686,14 @@ function displaySkillsStatus(manifest, projectPath) {
|
|
|
655
686
|
console.log(chalk.gray(' Then reinitialize: uds init --yes'));
|
|
656
687
|
}
|
|
657
688
|
}
|
|
689
|
+
|
|
690
|
+
// Show compatible tools for marketplace installation too
|
|
691
|
+
if (isMarketplace && (hasClaudeCode || hasOpenCode)) {
|
|
692
|
+
const compatibleTools = [];
|
|
693
|
+
if (hasClaudeCode) compatibleTools.push('Claude Code');
|
|
694
|
+
if (hasOpenCode) compatibleTools.push('OpenCode');
|
|
695
|
+
console.log(chalk.gray(` Compatible: ${compatibleTools.join(', ')}`));
|
|
696
|
+
}
|
|
658
697
|
} else {
|
|
659
698
|
console.log(chalk.gray(' Skills not installed (using reference documents only)'));
|
|
660
699
|
}
|
package/src/commands/init.js
CHANGED
|
@@ -178,12 +178,17 @@ export async function initCommand(options) {
|
|
|
178
178
|
aiTools = handleAgentsMdSharing(aiTools);
|
|
179
179
|
|
|
180
180
|
const useClaudeCode = aiTools.includes('claude-code');
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
//
|
|
184
|
-
|
|
181
|
+
const useOpenCode = aiTools.includes('opencode');
|
|
182
|
+
const supportsSkills = useClaudeCode || useOpenCode;
|
|
183
|
+
// Skills-compatible tools: Claude Code and OpenCode (both auto-detect .claude/skills/)
|
|
184
|
+
const onlySkillsTools = aiTools.every(tool =>
|
|
185
|
+
tool === 'claude-code' || tool === 'opencode'
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// STEP 4: Skills handling (only if ALL selected tools support Skills)
|
|
189
|
+
// When other AI tools (Cursor, Cline, etc.) are also selected, they need full standards,
|
|
185
190
|
// so we skip the Skills prompt to avoid minimal installation affecting them
|
|
186
|
-
if (
|
|
191
|
+
if (supportsSkills && onlySkillsTools) {
|
|
187
192
|
const projectSkillsInfo = getProjectInstalledSkillsInfo(projectPath);
|
|
188
193
|
const userSkillsInfo = getInstalledSkillsInfo();
|
|
189
194
|
const repoInfo = getRepositoryInfo();
|
|
@@ -240,7 +245,7 @@ export async function initCommand(options) {
|
|
|
240
245
|
console.log(chalk.cyan('Skills Status:'));
|
|
241
246
|
console.log(chalk.gray(' No Skills installation detected'));
|
|
242
247
|
|
|
243
|
-
const location = await promptSkillsInstallLocation();
|
|
248
|
+
const location = await promptSkillsInstallLocation(aiTools);
|
|
244
249
|
if (location !== 'none') {
|
|
245
250
|
skillsConfig = {
|
|
246
251
|
installed: true,
|
|
@@ -356,8 +361,26 @@ export async function initCommand(options) {
|
|
|
356
361
|
test_levels: options.testLevels ? options.testLevels.split(',') : ['unit-testing', 'integration-testing']
|
|
357
362
|
};
|
|
358
363
|
|
|
359
|
-
//
|
|
360
|
-
const
|
|
364
|
+
// Determine AI tools from detection for skills compatibility check
|
|
365
|
+
const detectedAiTools = Object.keys(detected.aiTools).filter(k => detected.aiTools[k]);
|
|
366
|
+
// Map detected keys to standard tool names
|
|
367
|
+
const aiToolsNormalized = detectedAiTools.map(k => {
|
|
368
|
+
if (k === 'claudeCode') return 'claude-code';
|
|
369
|
+
if (k === 'geminiCli') return 'gemini-cli';
|
|
370
|
+
return k;
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
// Check if only skills-compatible tools are detected
|
|
374
|
+
const hasSkillsCompatibleTool = aiToolsNormalized.some(t => t === 'claude-code' || t === 'opencode');
|
|
375
|
+
const onlySkillsCompatibleTools = aiToolsNormalized.every(t => t === 'claude-code' || t === 'opencode');
|
|
376
|
+
|
|
377
|
+
// Handle Skills configuration based on CLI flag
|
|
378
|
+
// Default: marketplace only if all detected tools support skills
|
|
379
|
+
// If non-skills tools are detected, default to 'none' (full standards)
|
|
380
|
+
let skillsLocationFlag = options.skillsLocation;
|
|
381
|
+
if (!skillsLocationFlag) {
|
|
382
|
+
skillsLocationFlag = (hasSkillsCompatibleTool && onlySkillsCompatibleTools) ? 'marketplace' : 'none';
|
|
383
|
+
}
|
|
361
384
|
|
|
362
385
|
// Content mode from CLI flag (default: index for best balance)
|
|
363
386
|
const contentModeFlag = options.contentMode || 'index';
|
package/src/prompts/init.js
CHANGED
|
@@ -83,12 +83,27 @@ export async function promptAITools(detected = {}) {
|
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
85
|
* Prompt for Skills installation location
|
|
86
|
+
* @param {string[]} selectedTools - Selected AI tools (for displaying compatibility info)
|
|
86
87
|
* @returns {Promise<string>} 'user', 'project', or 'none'
|
|
87
88
|
*/
|
|
88
|
-
export async function promptSkillsInstallLocation() {
|
|
89
|
+
export async function promptSkillsInstallLocation(selectedTools = []) {
|
|
90
|
+
const hasClaudeCode = selectedTools.includes('claude-code');
|
|
91
|
+
const hasOpenCode = selectedTools.includes('opencode');
|
|
92
|
+
|
|
93
|
+
// Build compatible tools list
|
|
94
|
+
const compatibleTools = [];
|
|
95
|
+
if (hasClaudeCode) compatibleTools.push('Claude Code');
|
|
96
|
+
if (hasOpenCode) compatibleTools.push('OpenCode');
|
|
97
|
+
|
|
89
98
|
console.log();
|
|
90
99
|
console.log(chalk.cyan('Skills Installation:'));
|
|
91
|
-
|
|
100
|
+
if (compatibleTools.length > 1) {
|
|
101
|
+
console.log(chalk.gray(` Skills will work with: ${compatibleTools.join(' and ')}`));
|
|
102
|
+
} else if (compatibleTools.length === 1) {
|
|
103
|
+
console.log(chalk.gray(` Choose where to install ${compatibleTools[0]} Skills`));
|
|
104
|
+
} else {
|
|
105
|
+
console.log(chalk.gray(' Choose where to install Skills'));
|
|
106
|
+
}
|
|
92
107
|
console.log();
|
|
93
108
|
|
|
94
109
|
const { location } = await inquirer.prompt([
|
package/src/utils/github.js
CHANGED
|
@@ -453,6 +453,54 @@ export function installSkillToDir(skillName, targetBaseDir) {
|
|
|
453
453
|
};
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Get Plugin Marketplace installed skills info
|
|
458
|
+
* Reads from ~/.claude/plugins/installed_plugins.json
|
|
459
|
+
* @returns {Object|null} Marketplace skills info or null
|
|
460
|
+
*/
|
|
461
|
+
export function getMarketplaceSkillsInfo() {
|
|
462
|
+
const pluginsFile = join(homedir(), '.claude', 'plugins', 'installed_plugins.json');
|
|
463
|
+
|
|
464
|
+
if (!existsSync(pluginsFile)) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
try {
|
|
469
|
+
const data = JSON.parse(readFileSync(pluginsFile, 'utf-8'));
|
|
470
|
+
const plugins = data.plugins || {};
|
|
471
|
+
|
|
472
|
+
// Look for universal-dev-standards plugin (various marketplace keys)
|
|
473
|
+
const udsKeys = Object.keys(plugins).filter(key =>
|
|
474
|
+
key.includes('universal-dev-standards')
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
if (udsKeys.length === 0) {
|
|
478
|
+
return null;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Get the first matching plugin info
|
|
482
|
+
const pluginKey = udsKeys[0];
|
|
483
|
+
const pluginInfo = plugins[pluginKey];
|
|
484
|
+
|
|
485
|
+
if (!pluginInfo || pluginInfo.length === 0) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const info = pluginInfo[0];
|
|
490
|
+
return {
|
|
491
|
+
installed: true,
|
|
492
|
+
version: info.version || 'unknown',
|
|
493
|
+
installPath: info.installPath || null,
|
|
494
|
+
installedAt: info.installedAt || null,
|
|
495
|
+
lastUpdated: info.lastUpdated || null,
|
|
496
|
+
source: 'marketplace',
|
|
497
|
+
pluginKey
|
|
498
|
+
};
|
|
499
|
+
} catch {
|
|
500
|
+
return null;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
456
504
|
/**
|
|
457
505
|
* Download and install a single Skill to a specific target directory
|
|
458
506
|
* @param {string} skillName - Skill name
|
package/standards-registry.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"version": "3.5.0-beta.
|
|
4
|
-
"lastUpdated": "2026-01-
|
|
3
|
+
"version": "3.5.0-beta.14",
|
|
4
|
+
"lastUpdated": "2026-01-14",
|
|
5
5
|
"description": "Standards registry for universal-dev-standards with integrated skills and AI-optimized formats",
|
|
6
6
|
"formats": {
|
|
7
7
|
"ai": {
|
|
@@ -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.0-beta.
|
|
51
|
+
"version": "3.5.0-beta.14"
|
|
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.0-beta.
|
|
58
|
+
"version": "3.5.0-beta.14",
|
|
59
59
|
"note": "Skills are now included in the main repository under skills/"
|
|
60
60
|
}
|
|
61
61
|
},
|