universal-dev-standards 4.0.0 → 4.2.0
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/bin/uds.js +75 -0
- package/bundled/core/ai-friendly-architecture.md +542 -0
- package/bundled/core/refactoring-standards.md +342 -120
- package/bundled/locales/zh-CN/README.md +210 -509
- package/bundled/locales/zh-CN/core/ai-friendly-architecture.md +306 -0
- package/bundled/locales/zh-CN/core/refactoring-standards.md +10 -9
- package/bundled/locales/zh-CN/docs/AI-AGENT-ROADMAP.md +82 -22
- package/bundled/locales/zh-CN/integrations/gemini-cli/GEMINI.md +35 -3
- package/bundled/locales/zh-CN/integrations/github-copilot/COPILOT-CHAT-REFERENCE.md +89 -3
- package/bundled/locales/zh-CN/integrations/github-copilot/skills-mapping.md +8 -4
- package/bundled/locales/zh-CN/skills/claude-code/commands/refactor.md +178 -0
- package/bundled/locales/zh-CN/skills/claude-code/refactoring-assistant/SKILL.md +243 -97
- package/bundled/locales/zh-TW/README.md +211 -490
- package/bundled/locales/zh-TW/core/ai-friendly-architecture.md +306 -0
- package/bundled/locales/zh-TW/core/refactoring-standards.md +347 -125
- package/bundled/locales/zh-TW/docs/AI-AGENT-ROADMAP.md +82 -22
- package/bundled/locales/zh-TW/integrations/gemini-cli/GEMINI.md +35 -3
- package/bundled/locales/zh-TW/integrations/github-copilot/COPILOT-CHAT-REFERENCE.md +89 -3
- package/bundled/locales/zh-TW/integrations/github-copilot/skills-mapping.md +8 -4
- package/bundled/locales/zh-TW/skills/claude-code/commands/refactor.md +178 -0
- package/bundled/locales/zh-TW/skills/claude-code/refactoring-assistant/SKILL.md +198 -52
- package/bundled/skills/claude-code/README.md +8 -0
- package/bundled/skills/claude-code/agents/README.md +305 -0
- package/bundled/skills/claude-code/agents/code-architect.md +259 -0
- package/bundled/skills/claude-code/agents/doc-writer.md +406 -0
- package/bundled/skills/claude-code/agents/reviewer.md +353 -0
- package/bundled/skills/claude-code/agents/spec-analyst.md +374 -0
- package/bundled/skills/claude-code/agents/test-specialist.md +364 -0
- package/bundled/skills/claude-code/commands/refactor.md +173 -0
- package/bundled/skills/claude-code/refactoring-assistant/SKILL.md +161 -63
- package/bundled/skills/claude-code/workflows/README.md +303 -0
- package/bundled/skills/claude-code/workflows/code-review.workflow.yaml +186 -0
- package/bundled/skills/claude-code/workflows/feature-dev.workflow.yaml +174 -0
- package/bundled/skills/claude-code/workflows/integrated-flow.workflow.yaml +238 -0
- package/bundled/skills/claude-code/workflows/large-codebase-analysis.workflow.yaml +226 -0
- package/package.json +11 -1
- package/src/commands/agent.js +417 -0
- package/src/commands/ai-context.js +552 -0
- package/src/commands/check.js +3 -3
- package/src/commands/init.js +6 -3
- package/src/commands/workflow.js +425 -0
- package/src/config/ai-agent-paths.js +217 -13
- package/src/core/constants.js +514 -0
- package/src/core/errors.js +398 -0
- package/src/core/manifest.js +473 -0
- package/src/core/paths.js +398 -0
- package/src/prompts/init.js +7 -5
- package/src/utils/agent-adapter.js +320 -0
- package/src/utils/agents-installer.js +393 -0
- package/src/utils/context-chunker.js +467 -0
- package/src/utils/copier.js +59 -99
- package/src/utils/hasher.js +2 -16
- package/src/utils/integration-generator.js +28 -52
- package/src/utils/workflows-installer.js +545 -0
- package/standards-registry.json +174 -24
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* UDS Manifest Schema v3.3.0
|
|
6
|
+
* Central configuration and state tracking for UDS installations
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Supported manifest schema versions
|
|
11
|
+
*/
|
|
12
|
+
export const SUPPORTED_SCHEMA_VERSIONS = ['3.0.0', '3.1.0', '3.2.0', '3.3.0'];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Current manifest schema version
|
|
16
|
+
*/
|
|
17
|
+
export const CURRENT_SCHEMA_VERSION = '3.3.0';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Default manifest values
|
|
21
|
+
*/
|
|
22
|
+
export const DEFAULT_MANIFEST = {
|
|
23
|
+
version: CURRENT_SCHEMA_VERSION,
|
|
24
|
+
upstream: {
|
|
25
|
+
repo: 'AsiaOstrich/universal-dev-standards',
|
|
26
|
+
version: null,
|
|
27
|
+
installed: new Date().toISOString()
|
|
28
|
+
},
|
|
29
|
+
level: 2,
|
|
30
|
+
format: 'ai',
|
|
31
|
+
standardsScope: 'minimal',
|
|
32
|
+
contentMode: 'index',
|
|
33
|
+
standards: [],
|
|
34
|
+
extensions: [],
|
|
35
|
+
integrations: [],
|
|
36
|
+
integrationConfigs: {},
|
|
37
|
+
options: {},
|
|
38
|
+
aiTools: [],
|
|
39
|
+
skills: {
|
|
40
|
+
installed: false,
|
|
41
|
+
location: 'marketplace',
|
|
42
|
+
names: [],
|
|
43
|
+
version: null,
|
|
44
|
+
installations: []
|
|
45
|
+
},
|
|
46
|
+
commands: {
|
|
47
|
+
installed: false,
|
|
48
|
+
names: [],
|
|
49
|
+
installations: []
|
|
50
|
+
},
|
|
51
|
+
methodology: null,
|
|
52
|
+
fileHashes: {},
|
|
53
|
+
skillHashes: {},
|
|
54
|
+
commandHashes: {},
|
|
55
|
+
integrationBlockHashes: {}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Validation schema for manifest
|
|
60
|
+
*/
|
|
61
|
+
const MANIFEST_SCHEMA = {
|
|
62
|
+
required: ['version', 'upstream', 'level', 'format', 'standardsScope', 'contentMode'],
|
|
63
|
+
properties: {
|
|
64
|
+
version: { type: 'string', pattern: '^\\d+\\.\\d+\\.\\d+$' },
|
|
65
|
+
level: { type: 'number', enum: [1, 2, 3] },
|
|
66
|
+
format: { type: 'string', enum: ['ai', 'human', 'both'] },
|
|
67
|
+
standardsScope: { type: 'string', enum: ['minimal', 'full'] },
|
|
68
|
+
contentMode: { type: 'string', enum: ['minimal', 'index', 'full'] }
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get manifest file path for a project
|
|
74
|
+
* @param {string} projectPath - Project root path
|
|
75
|
+
* @returns {string} Absolute path to manifest.json
|
|
76
|
+
*/
|
|
77
|
+
export function getManifestPath(projectPath) {
|
|
78
|
+
return join(projectPath, '.standards', 'manifest.json');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Check if manifest exists for a project
|
|
83
|
+
* @param {string} projectPath - Project root path
|
|
84
|
+
* @returns {boolean} True if manifest exists
|
|
85
|
+
*/
|
|
86
|
+
export function manifestExists(projectPath) {
|
|
87
|
+
return existsSync(getManifestPath(projectPath));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Read manifest from file system
|
|
92
|
+
* @param {string} projectPath - Project root path
|
|
93
|
+
* @returns {Object|null} Manifest data or null if not found/invalid
|
|
94
|
+
*/
|
|
95
|
+
export function readManifest(projectPath) {
|
|
96
|
+
const manifestPath = getManifestPath(projectPath);
|
|
97
|
+
|
|
98
|
+
if (!existsSync(manifestPath)) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const content = readFileSync(manifestPath, 'utf-8');
|
|
104
|
+
const manifest = JSON.parse(content);
|
|
105
|
+
|
|
106
|
+
// Validate basic structure
|
|
107
|
+
if (!validateManifest(manifest)) {
|
|
108
|
+
console.warn('Invalid manifest structure detected');
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return manifest;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.warn(`Failed to read manifest: ${error.message}`);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Write manifest to file system
|
|
121
|
+
* @param {Object} manifest - Manifest data
|
|
122
|
+
* @param {string} projectPath - Project root path
|
|
123
|
+
* @returns {string} Path to written manifest file
|
|
124
|
+
*/
|
|
125
|
+
export function writeManifest(manifest, projectPath) {
|
|
126
|
+
const manifestPath = getManifestPath(projectPath);
|
|
127
|
+
const manifestDir = dirname(manifestPath);
|
|
128
|
+
|
|
129
|
+
// Ensure .standards directory exists
|
|
130
|
+
if (!existsSync(manifestDir)) {
|
|
131
|
+
mkdirSync(manifestDir, { recursive: true });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Validate before writing
|
|
135
|
+
if (!validateManifest(manifest)) {
|
|
136
|
+
throw new Error('Invalid manifest structure');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
140
|
+
return manifestPath;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Validate manifest structure
|
|
145
|
+
* @param {Object} manifest - Manifest data to validate
|
|
146
|
+
* @returns {boolean} True if valid
|
|
147
|
+
*/
|
|
148
|
+
export function validateManifest(manifest) {
|
|
149
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check required fields
|
|
154
|
+
for (const field of MANIFEST_SCHEMA.required) {
|
|
155
|
+
if (!(field in manifest)) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Check property types and enums
|
|
161
|
+
for (const [key, schema] of Object.entries(MANIFEST_SCHEMA.properties)) {
|
|
162
|
+
const value = manifest[key];
|
|
163
|
+
|
|
164
|
+
if (schema.type === 'string') {
|
|
165
|
+
if (typeof value !== 'string') return false;
|
|
166
|
+
if (schema.pattern && !new RegExp(schema.pattern).test(value)) return false;
|
|
167
|
+
if (schema.enum && !schema.enum.includes(value)) return false;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (schema.type === 'number') {
|
|
171
|
+
if (typeof value !== 'number') return false;
|
|
172
|
+
if (schema.enum && !schema.enum.includes(value)) return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Validate nested objects
|
|
177
|
+
if (manifest.upstream && typeof manifest.upstream !== 'object') {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Create new manifest with default values
|
|
186
|
+
* @param {Object} overrides - Override specific fields
|
|
187
|
+
* @returns {Object} New manifest object
|
|
188
|
+
*/
|
|
189
|
+
export function createManifest(overrides = {}) {
|
|
190
|
+
return {
|
|
191
|
+
...DEFAULT_MANIFEST,
|
|
192
|
+
...overrides,
|
|
193
|
+
upstream: {
|
|
194
|
+
...DEFAULT_MANIFEST.upstream,
|
|
195
|
+
...(overrides.upstream || {})
|
|
196
|
+
},
|
|
197
|
+
options: {
|
|
198
|
+
...DEFAULT_MANIFEST.options,
|
|
199
|
+
...(overrides.options || {})
|
|
200
|
+
},
|
|
201
|
+
skills: {
|
|
202
|
+
...DEFAULT_MANIFEST.skills,
|
|
203
|
+
...(overrides.skills || {})
|
|
204
|
+
},
|
|
205
|
+
commands: {
|
|
206
|
+
...DEFAULT_MANIFEST.commands,
|
|
207
|
+
...(overrides.commands || {})
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Merge updates into existing manifest
|
|
214
|
+
* @param {Object} baseManifest - Base manifest
|
|
215
|
+
* @param {Object} updates - Updates to apply
|
|
216
|
+
* @returns {Object} Merged manifest
|
|
217
|
+
*/
|
|
218
|
+
export function mergeManifest(baseManifest, updates) {
|
|
219
|
+
if (!baseManifest) {
|
|
220
|
+
return createManifest(updates);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const merged = {
|
|
224
|
+
...baseManifest,
|
|
225
|
+
...updates,
|
|
226
|
+
upstream: {
|
|
227
|
+
...baseManifest.upstream,
|
|
228
|
+
...(updates.upstream || {})
|
|
229
|
+
},
|
|
230
|
+
options: {
|
|
231
|
+
...baseManifest.options,
|
|
232
|
+
...(updates.options || {})
|
|
233
|
+
},
|
|
234
|
+
skills: {
|
|
235
|
+
...baseManifest.skills,
|
|
236
|
+
...(updates.skills || {})
|
|
237
|
+
},
|
|
238
|
+
commands: {
|
|
239
|
+
...baseManifest.commands,
|
|
240
|
+
...(updates.commands || {})
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// Validate merged manifest
|
|
245
|
+
if (!validateManifest(merged)) {
|
|
246
|
+
throw new Error('Merged manifest is invalid');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return merged;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Migrate manifest to current schema version
|
|
254
|
+
* @param {Object} manifest - Manifest to migrate
|
|
255
|
+
* @returns {Object} Migrated manifest
|
|
256
|
+
*/
|
|
257
|
+
export function migrateManifest(manifest) {
|
|
258
|
+
if (!manifest) {
|
|
259
|
+
return createManifest();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const currentVersion = manifest.version || '1.0.0';
|
|
263
|
+
|
|
264
|
+
// Already at current version
|
|
265
|
+
if (currentVersion === CURRENT_SCHEMA_VERSION) {
|
|
266
|
+
return manifest;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
let migrated = { ...manifest };
|
|
270
|
+
|
|
271
|
+
// Migration logic for each version
|
|
272
|
+
if (currentVersion < '3.0.0') {
|
|
273
|
+
// Migrate from 2.x to 3.0.0
|
|
274
|
+
migrated = migrateToV300(migrated);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (currentVersion < '3.1.0') {
|
|
278
|
+
// Migrate to 3.1.0 - add fileHashes
|
|
279
|
+
migrated = migrateToV310(migrated);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (currentVersion < '3.2.0') {
|
|
283
|
+
// Migrate to 3.2.0 - add standardsScope, contentMode
|
|
284
|
+
migrated = migrateToV320(migrated);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (currentVersion < '3.3.0') {
|
|
288
|
+
// Migrate to 3.3.0 - add skillHashes, commandHashes, integrationBlockHashes
|
|
289
|
+
migrated = migrateToV330(migrated);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Update schema version
|
|
293
|
+
migrated.version = CURRENT_SCHEMA_VERSION;
|
|
294
|
+
|
|
295
|
+
return migrated;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Migration to version 3.0.0
|
|
300
|
+
* @param {Object} manifest - Pre-3.0.0 manifest
|
|
301
|
+
* @returns {Object} V3.0.0 compatible manifest
|
|
302
|
+
*/
|
|
303
|
+
function migrateToV300(manifest) {
|
|
304
|
+
return {
|
|
305
|
+
...DEFAULT_MANIFEST,
|
|
306
|
+
...manifest,
|
|
307
|
+
version: '3.0.0',
|
|
308
|
+
// Preserve existing fields where possible
|
|
309
|
+
upstream: {
|
|
310
|
+
...DEFAULT_MANIFEST.upstream,
|
|
311
|
+
...(manifest.upstream || {})
|
|
312
|
+
},
|
|
313
|
+
standards: manifest.standards || [],
|
|
314
|
+
extensions: manifest.extensions || [],
|
|
315
|
+
options: manifest.options || {},
|
|
316
|
+
aiTools: manifest.aiTools || []
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Migration to version 3.1.0
|
|
322
|
+
* @param {Object} manifest - V3.0.x manifest
|
|
323
|
+
* @returns {Object} V3.1.0 compatible manifest
|
|
324
|
+
*/
|
|
325
|
+
function migrateToV310(manifest) {
|
|
326
|
+
return {
|
|
327
|
+
...manifest,
|
|
328
|
+
version: '3.1.0',
|
|
329
|
+
fileHashes: manifest.fileHashes || {}
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Migration to version 3.2.0
|
|
335
|
+
* @param {Object} manifest - V3.1.x manifest
|
|
336
|
+
* @returns {Object} V3.2.0 compatible manifest
|
|
337
|
+
*/
|
|
338
|
+
function migrateToV320(manifest) {
|
|
339
|
+
return {
|
|
340
|
+
...manifest,
|
|
341
|
+
version: '3.2.0',
|
|
342
|
+
standardsScope: manifest.standardsScope || 'minimal',
|
|
343
|
+
contentMode: manifest.contentMode || 'index'
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Migration to version 3.3.0
|
|
349
|
+
* @param {Object} manifest - V3.2.x manifest
|
|
350
|
+
* @returns {Object} V3.3.0 compatible manifest
|
|
351
|
+
*/
|
|
352
|
+
function migrateToV330(manifest) {
|
|
353
|
+
return {
|
|
354
|
+
...manifest,
|
|
355
|
+
version: '3.3.0',
|
|
356
|
+
skillHashes: manifest.skillHashes || {},
|
|
357
|
+
commandHashes: manifest.commandHashes || {},
|
|
358
|
+
integrationBlockHashes: manifest.integrationBlockHashes || {}
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Update upstream information
|
|
364
|
+
* @param {Object} manifest - Manifest to update
|
|
365
|
+
* @param {Object} upstream - New upstream info
|
|
366
|
+
* @returns {Object} Updated manifest
|
|
367
|
+
*/
|
|
368
|
+
export function updateUpstream(manifest, upstream) {
|
|
369
|
+
return {
|
|
370
|
+
...manifest,
|
|
371
|
+
upstream: {
|
|
372
|
+
...manifest.upstream,
|
|
373
|
+
...upstream,
|
|
374
|
+
installed: new Date().toISOString()
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Add file hash to manifest
|
|
381
|
+
* @param {Object} manifest - Manifest to update
|
|
382
|
+
* @param {string} filePath - File path (relative to project root)
|
|
383
|
+
* @param {string} hash - SHA-256 hash with 'sha256:' prefix
|
|
384
|
+
* @param {number} size - File size in bytes
|
|
385
|
+
* @returns {Object} Updated manifest
|
|
386
|
+
*/
|
|
387
|
+
export function addFileHash(manifest, filePath, hash, size) {
|
|
388
|
+
return {
|
|
389
|
+
...manifest,
|
|
390
|
+
fileHashes: {
|
|
391
|
+
...manifest.fileHashes,
|
|
392
|
+
[filePath]: {
|
|
393
|
+
hash,
|
|
394
|
+
size,
|
|
395
|
+
installedAt: new Date().toISOString()
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Remove file hash from manifest
|
|
403
|
+
* @param {Object} manifest - Manifest to update
|
|
404
|
+
* @param {string} filePath - File path to remove
|
|
405
|
+
* @returns {Object} Updated manifest
|
|
406
|
+
*/
|
|
407
|
+
export function removeFileHash(manifest, filePath) {
|
|
408
|
+
const remainingHashes = Object.fromEntries(
|
|
409
|
+
Object.entries(manifest.fileHashes).filter(([key]) => key !== filePath)
|
|
410
|
+
);
|
|
411
|
+
return {
|
|
412
|
+
...manifest,
|
|
413
|
+
fileHashes: remainingHashes
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Check if manifest needs migration
|
|
419
|
+
* @param {Object} manifest - Manifest to check
|
|
420
|
+
* @returns {boolean} True if migration is needed
|
|
421
|
+
*/
|
|
422
|
+
export function needsMigration(manifest) {
|
|
423
|
+
if (!manifest) {
|
|
424
|
+
return true;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return manifest.version !== CURRENT_SCHEMA_VERSION;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Get all AI tools from manifest
|
|
432
|
+
* @param {Object} manifest - Manifest
|
|
433
|
+
* @returns {string[]} Array of AI tool names
|
|
434
|
+
*/
|
|
435
|
+
export function getAITools(manifest) {
|
|
436
|
+
return manifest.aiTools || [];
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Get all installed standards paths
|
|
441
|
+
* @param {Object} manifest - Manifest
|
|
442
|
+
* @returns {string[]} Array of standard file paths
|
|
443
|
+
*/
|
|
444
|
+
export function getStandards(manifest) {
|
|
445
|
+
return manifest.standards || [];
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Get adoption level
|
|
450
|
+
* @param {Object} manifest - Manifest
|
|
451
|
+
* @returns {number} Adoption level (1-3)
|
|
452
|
+
*/
|
|
453
|
+
export function getAdoptionLevel(manifest) {
|
|
454
|
+
return manifest.level || 2;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Check if skills are installed
|
|
459
|
+
* @param {Object} manifest - Manifest
|
|
460
|
+
* @returns {boolean} True if skills are installed
|
|
461
|
+
*/
|
|
462
|
+
export function areSkillsInstalled(manifest) {
|
|
463
|
+
return manifest.skills?.installed || false;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Check if commands are installed
|
|
468
|
+
* @param {Object} manifest - Manifest
|
|
469
|
+
* @returns {boolean} True if commands are installed
|
|
470
|
+
*/
|
|
471
|
+
export function areCommandsInstalled(manifest) {
|
|
472
|
+
return manifest.commands?.installed || false;
|
|
473
|
+
}
|