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,552 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Context Command
|
|
3
|
+
*
|
|
4
|
+
* CLI commands for managing .ai-context.yaml configuration files.
|
|
5
|
+
* Helps projects configure AI-friendly architecture settings.
|
|
6
|
+
*
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
import inquirer from 'inquirer';
|
|
12
|
+
import { existsSync, readFileSync, writeFileSync, readdirSync } from 'fs';
|
|
13
|
+
import { join, basename } from 'path';
|
|
14
|
+
import * as yaml from 'js-yaml';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* AI Context init command - generate .ai-context.yaml
|
|
18
|
+
*/
|
|
19
|
+
export async function aiContextInitCommand(options) {
|
|
20
|
+
const projectPath = process.cwd();
|
|
21
|
+
const configPath = join(projectPath, '.ai-context.yaml');
|
|
22
|
+
|
|
23
|
+
console.log();
|
|
24
|
+
console.log(chalk.bold('🤖 AI Context Configuration Generator'));
|
|
25
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
26
|
+
console.log();
|
|
27
|
+
|
|
28
|
+
// Check if already exists
|
|
29
|
+
if (existsSync(configPath) && !options.force) {
|
|
30
|
+
console.log(chalk.yellow('⚠️ .ai-context.yaml already exists.'));
|
|
31
|
+
console.log(chalk.gray(' Use --force to overwrite.'));
|
|
32
|
+
console.log();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Auto-detect project info
|
|
37
|
+
const projectInfo = detectProjectInfo(projectPath);
|
|
38
|
+
|
|
39
|
+
let config;
|
|
40
|
+
|
|
41
|
+
if (options.yes) {
|
|
42
|
+
// Non-interactive mode
|
|
43
|
+
config = generateConfig(projectInfo, projectPath);
|
|
44
|
+
} else {
|
|
45
|
+
// Interactive mode
|
|
46
|
+
const answers = await inquirer.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'input',
|
|
49
|
+
name: 'name',
|
|
50
|
+
message: 'Project name:',
|
|
51
|
+
default: projectInfo.name
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'list',
|
|
55
|
+
name: 'type',
|
|
56
|
+
message: 'Project type:',
|
|
57
|
+
choices: ['web-app', 'library', 'cli', 'api', 'monorepo', 'mobile', 'other'],
|
|
58
|
+
default: projectInfo.type
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'list',
|
|
62
|
+
name: 'language',
|
|
63
|
+
message: 'Primary language:',
|
|
64
|
+
choices: ['typescript', 'javascript', 'python', 'go', 'rust', 'java', 'other'],
|
|
65
|
+
default: projectInfo.language
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'list',
|
|
69
|
+
name: 'architecture',
|
|
70
|
+
message: 'Architecture type:',
|
|
71
|
+
choices: ['layered', 'microservices', 'modular', 'monolith', 'event-driven'],
|
|
72
|
+
default: 'layered'
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: 'confirm',
|
|
76
|
+
name: 'scanModules',
|
|
77
|
+
message: 'Scan for modules automatically?',
|
|
78
|
+
default: true
|
|
79
|
+
}
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
config = generateConfig({
|
|
83
|
+
...projectInfo,
|
|
84
|
+
...answers
|
|
85
|
+
}, projectPath, answers.scanModules);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Write configuration
|
|
89
|
+
const yamlContent = generateYamlWithComments(config);
|
|
90
|
+
writeFileSync(configPath, yamlContent);
|
|
91
|
+
|
|
92
|
+
console.log();
|
|
93
|
+
console.log(chalk.green('✅ Created .ai-context.yaml'));
|
|
94
|
+
console.log(chalk.gray(` ${configPath}`));
|
|
95
|
+
console.log();
|
|
96
|
+
|
|
97
|
+
// Show summary
|
|
98
|
+
console.log(chalk.bold('Configuration Summary:'));
|
|
99
|
+
console.log(` Project: ${chalk.cyan(config.project.name)}`);
|
|
100
|
+
console.log(` Type: ${chalk.cyan(config.project.type)}`);
|
|
101
|
+
console.log(` Language: ${chalk.cyan(config.project['primary-language'])}`);
|
|
102
|
+
console.log(` Modules: ${chalk.cyan(config.modules?.length || 0)} detected`);
|
|
103
|
+
console.log();
|
|
104
|
+
|
|
105
|
+
if (config.modules?.length > 0) {
|
|
106
|
+
console.log(chalk.bold('Detected Modules:'));
|
|
107
|
+
for (const mod of config.modules) {
|
|
108
|
+
console.log(` • ${chalk.cyan(mod.name)} - ${chalk.gray(mod.path)}`);
|
|
109
|
+
}
|
|
110
|
+
console.log();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
console.log(chalk.gray('Next steps:'));
|
|
114
|
+
console.log(chalk.gray(' 1. Review and customize .ai-context.yaml'));
|
|
115
|
+
console.log(chalk.gray(' 2. Add module descriptions'));
|
|
116
|
+
console.log(chalk.gray(' 3. Create QUICK-REF.md files for key modules'));
|
|
117
|
+
console.log();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* AI Context validate command - validate configuration
|
|
122
|
+
*/
|
|
123
|
+
export async function aiContextValidateCommand(options) {
|
|
124
|
+
const projectPath = process.cwd();
|
|
125
|
+
const configPath = join(projectPath, '.ai-context.yaml');
|
|
126
|
+
|
|
127
|
+
console.log();
|
|
128
|
+
console.log(chalk.bold('🔍 Validating .ai-context.yaml'));
|
|
129
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
130
|
+
console.log();
|
|
131
|
+
|
|
132
|
+
if (!existsSync(configPath)) {
|
|
133
|
+
console.log(chalk.red('❌ .ai-context.yaml not found.'));
|
|
134
|
+
console.log(chalk.gray(' Run `uds ai-context init` to create one.'));
|
|
135
|
+
console.log();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
141
|
+
const config = yaml.load(content);
|
|
142
|
+
|
|
143
|
+
const errors = [];
|
|
144
|
+
const warnings = [];
|
|
145
|
+
|
|
146
|
+
// Validate required fields
|
|
147
|
+
if (!config.version) warnings.push('Missing version field');
|
|
148
|
+
if (!config.project) errors.push('Missing project section');
|
|
149
|
+
if (!config.project?.name) errors.push('Missing project.name');
|
|
150
|
+
if (!config.project?.type) warnings.push('Missing project.type');
|
|
151
|
+
|
|
152
|
+
// Validate modules
|
|
153
|
+
if (config.modules && Array.isArray(config.modules)) {
|
|
154
|
+
for (let i = 0; i < config.modules.length; i++) {
|
|
155
|
+
const mod = config.modules[i];
|
|
156
|
+
if (!mod.name) errors.push(`Module ${i}: missing name`);
|
|
157
|
+
if (!mod.path) errors.push(`Module ${i}: missing path`);
|
|
158
|
+
|
|
159
|
+
// Check if path exists
|
|
160
|
+
if (mod.path) {
|
|
161
|
+
const fullPath = join(projectPath, mod.path);
|
|
162
|
+
if (!existsSync(fullPath)) {
|
|
163
|
+
warnings.push(`Module ${mod.name}: path does not exist (${mod.path})`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Validate documentation references
|
|
170
|
+
if (config.documentation) {
|
|
171
|
+
const docFields = ['quick-ref', 'detailed', 'examples'];
|
|
172
|
+
for (const field of docFields) {
|
|
173
|
+
if (config.documentation[field]) {
|
|
174
|
+
const docPath = join(projectPath, config.documentation[field]);
|
|
175
|
+
if (!existsSync(docPath)) {
|
|
176
|
+
warnings.push(`Documentation ${field}: path does not exist (${config.documentation[field]})`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Validate context-strategy
|
|
183
|
+
if (config['context-strategy']) {
|
|
184
|
+
const cs = config['context-strategy'];
|
|
185
|
+
if (cs['max-chunk-size'] && typeof cs['max-chunk-size'] !== 'number') {
|
|
186
|
+
errors.push('context-strategy.max-chunk-size must be a number');
|
|
187
|
+
}
|
|
188
|
+
const validPatterns = ['hierarchical', 'parallel', 'sequential'];
|
|
189
|
+
if (cs['analysis-pattern'] && !validPatterns.includes(cs['analysis-pattern'])) {
|
|
190
|
+
errors.push(`context-strategy.analysis-pattern must be one of: ${validPatterns.join(', ')}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Report results
|
|
195
|
+
if (errors.length === 0 && warnings.length === 0) {
|
|
196
|
+
console.log(chalk.green('✅ Configuration is valid!'));
|
|
197
|
+
} else {
|
|
198
|
+
if (errors.length > 0) {
|
|
199
|
+
console.log(chalk.red(`❌ ${errors.length} error(s):`));
|
|
200
|
+
for (const err of errors) {
|
|
201
|
+
console.log(chalk.red(` • ${err}`));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (warnings.length > 0) {
|
|
205
|
+
console.log(chalk.yellow(`⚠️ ${warnings.length} warning(s):`));
|
|
206
|
+
for (const warn of warnings) {
|
|
207
|
+
console.log(chalk.yellow(` • ${warn}`));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
console.log();
|
|
213
|
+
|
|
214
|
+
// Show configuration summary
|
|
215
|
+
if (options.verbose) {
|
|
216
|
+
console.log(chalk.bold('Configuration:'));
|
|
217
|
+
console.log(chalk.gray(yaml.dump(config)));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.log(chalk.red(`❌ Invalid YAML: ${error.message}`));
|
|
222
|
+
console.log();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* AI Context graph command - show dependency graph
|
|
228
|
+
*/
|
|
229
|
+
export async function aiContextGraphCommand(options) {
|
|
230
|
+
const projectPath = process.cwd();
|
|
231
|
+
const configPath = join(projectPath, '.ai-context.yaml');
|
|
232
|
+
|
|
233
|
+
console.log();
|
|
234
|
+
console.log(chalk.bold('📊 Module Dependency Graph'));
|
|
235
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
236
|
+
console.log();
|
|
237
|
+
|
|
238
|
+
if (!existsSync(configPath)) {
|
|
239
|
+
console.log(chalk.red('❌ .ai-context.yaml not found.'));
|
|
240
|
+
console.log(chalk.gray(' Run `uds ai-context init` to create one.'));
|
|
241
|
+
console.log();
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
247
|
+
const config = yaml.load(content);
|
|
248
|
+
|
|
249
|
+
if (!config.modules || config.modules.length === 0) {
|
|
250
|
+
console.log(chalk.yellow('⚠️ No modules defined in configuration.'));
|
|
251
|
+
console.log();
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Build dependency map
|
|
256
|
+
const modules = config.modules;
|
|
257
|
+
const moduleNames = new Set(modules.map(m => m.name));
|
|
258
|
+
|
|
259
|
+
// Text representation
|
|
260
|
+
console.log(chalk.bold('Modules:'));
|
|
261
|
+
for (const mod of modules) {
|
|
262
|
+
const priorityIcon = getPriorityIcon(mod.priority);
|
|
263
|
+
const deps = mod.dependencies || [];
|
|
264
|
+
const validDeps = deps.filter(d => moduleNames.has(d));
|
|
265
|
+
const invalidDeps = deps.filter(d => !moduleNames.has(d));
|
|
266
|
+
|
|
267
|
+
console.log(` ${priorityIcon} ${chalk.cyan(mod.name)}`);
|
|
268
|
+
console.log(` Path: ${chalk.gray(mod.path)}`);
|
|
269
|
+
if (mod.description) {
|
|
270
|
+
console.log(` Desc: ${chalk.gray(mod.description)}`);
|
|
271
|
+
}
|
|
272
|
+
if (validDeps.length > 0) {
|
|
273
|
+
console.log(` Deps: ${validDeps.map(d => chalk.blue(d)).join(', ')}`);
|
|
274
|
+
}
|
|
275
|
+
if (invalidDeps.length > 0) {
|
|
276
|
+
console.log(` ${chalk.yellow('Unknown deps:')} ${invalidDeps.join(', ')}`);
|
|
277
|
+
}
|
|
278
|
+
console.log();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Mermaid diagram
|
|
282
|
+
if (options.mermaid) {
|
|
283
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
284
|
+
console.log(chalk.bold('Mermaid Diagram:'));
|
|
285
|
+
console.log();
|
|
286
|
+
console.log('```mermaid');
|
|
287
|
+
console.log('graph TD');
|
|
288
|
+
for (const mod of modules) {
|
|
289
|
+
const deps = (mod.dependencies || []).filter(d => moduleNames.has(d));
|
|
290
|
+
if (deps.length === 0) {
|
|
291
|
+
console.log(` ${mod.name}[${mod.name}]`);
|
|
292
|
+
} else {
|
|
293
|
+
for (const dep of deps) {
|
|
294
|
+
console.log(` ${mod.name}[${mod.name}] --> ${dep}[${dep}]`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
console.log('```');
|
|
299
|
+
console.log();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
} catch (error) {
|
|
303
|
+
console.log(chalk.red(`❌ Error: ${error.message}`));
|
|
304
|
+
console.log();
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// ============================================================
|
|
309
|
+
// Helper Functions
|
|
310
|
+
// ============================================================
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Detect project information from common config files
|
|
314
|
+
*/
|
|
315
|
+
function detectProjectInfo(projectPath) {
|
|
316
|
+
const info = {
|
|
317
|
+
name: basename(projectPath),
|
|
318
|
+
type: 'web-app',
|
|
319
|
+
language: 'typescript'
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// Check package.json
|
|
323
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
324
|
+
if (existsSync(pkgPath)) {
|
|
325
|
+
try {
|
|
326
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
327
|
+
info.name = pkg.name || info.name;
|
|
328
|
+
|
|
329
|
+
// Detect type from scripts
|
|
330
|
+
if (pkg.bin) info.type = 'cli';
|
|
331
|
+
else if (pkg.main && !pkg.scripts?.start) info.type = 'library';
|
|
332
|
+
|
|
333
|
+
// Detect language
|
|
334
|
+
if (pkg.devDependencies?.typescript || pkg.dependencies?.typescript) {
|
|
335
|
+
info.language = 'typescript';
|
|
336
|
+
} else {
|
|
337
|
+
info.language = 'javascript';
|
|
338
|
+
}
|
|
339
|
+
} catch {
|
|
340
|
+
// Ignore parse errors
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Check pyproject.toml
|
|
345
|
+
const pyPath = join(projectPath, 'pyproject.toml');
|
|
346
|
+
if (existsSync(pyPath)) {
|
|
347
|
+
info.language = 'python';
|
|
348
|
+
try {
|
|
349
|
+
const content = readFileSync(pyPath, 'utf-8');
|
|
350
|
+
const nameMatch = content.match(/name\s*=\s*["']([^"']+)["']/);
|
|
351
|
+
if (nameMatch) info.name = nameMatch[1];
|
|
352
|
+
} catch {
|
|
353
|
+
// Ignore
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Check go.mod
|
|
358
|
+
const goPath = join(projectPath, 'go.mod');
|
|
359
|
+
if (existsSync(goPath)) {
|
|
360
|
+
info.language = 'go';
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Check Cargo.toml
|
|
364
|
+
const cargoPath = join(projectPath, 'Cargo.toml');
|
|
365
|
+
if (existsSync(cargoPath)) {
|
|
366
|
+
info.language = 'rust';
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return info;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Scan for modules in the project
|
|
374
|
+
*/
|
|
375
|
+
function scanForModules(projectPath, language) {
|
|
376
|
+
const modules = [];
|
|
377
|
+
const srcDirs = ['src', 'lib', 'app', 'packages'];
|
|
378
|
+
const ignoreDirs = ['node_modules', '__pycache__', '.git', 'dist', 'build', '.venv', 'vendor'];
|
|
379
|
+
|
|
380
|
+
for (const srcDir of srcDirs) {
|
|
381
|
+
const srcPath = join(projectPath, srcDir);
|
|
382
|
+
if (!existsSync(srcPath)) continue;
|
|
383
|
+
|
|
384
|
+
try {
|
|
385
|
+
const items = readdirSync(srcPath, { withFileTypes: true });
|
|
386
|
+
for (const item of items) {
|
|
387
|
+
if (!item.isDirectory()) continue;
|
|
388
|
+
if (ignoreDirs.includes(item.name)) continue;
|
|
389
|
+
if (item.name.startsWith('.')) continue;
|
|
390
|
+
|
|
391
|
+
const modPath = join(srcDir, item.name);
|
|
392
|
+
const fullPath = join(projectPath, modPath);
|
|
393
|
+
|
|
394
|
+
// Look for entry point
|
|
395
|
+
const entryFile = findEntryFile(fullPath, language);
|
|
396
|
+
|
|
397
|
+
modules.push({
|
|
398
|
+
name: item.name,
|
|
399
|
+
path: modPath + '/',
|
|
400
|
+
entry: entryFile || 'index.ts',
|
|
401
|
+
description: `${item.name} module`,
|
|
402
|
+
dependencies: [],
|
|
403
|
+
priority: 'medium'
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
} catch {
|
|
407
|
+
// Ignore scan errors
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return modules;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Find entry file for a module
|
|
416
|
+
*/
|
|
417
|
+
function findEntryFile(modulePath, language) {
|
|
418
|
+
const entryFiles = {
|
|
419
|
+
typescript: ['index.ts', 'index.tsx', 'main.ts'],
|
|
420
|
+
javascript: ['index.js', 'index.jsx', 'main.js'],
|
|
421
|
+
python: ['__init__.py', 'main.py'],
|
|
422
|
+
go: ['main.go'],
|
|
423
|
+
rust: ['lib.rs', 'main.rs']
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
const candidates = entryFiles[language] || entryFiles.typescript;
|
|
427
|
+
|
|
428
|
+
for (const file of candidates) {
|
|
429
|
+
if (existsSync(join(modulePath, file))) {
|
|
430
|
+
return file;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Generate configuration object
|
|
439
|
+
*/
|
|
440
|
+
function generateConfig(info, projectPath, scanModules = true) {
|
|
441
|
+
const config = {
|
|
442
|
+
version: '1.0.0',
|
|
443
|
+
project: {
|
|
444
|
+
name: info.name,
|
|
445
|
+
type: info.type,
|
|
446
|
+
'primary-language': info.language,
|
|
447
|
+
description: `${info.name} project`
|
|
448
|
+
},
|
|
449
|
+
modules: scanModules ? scanForModules(projectPath, info.language) : [],
|
|
450
|
+
'analysis-hints': {
|
|
451
|
+
'entry-points': detectEntryPoints(projectPath, info.language),
|
|
452
|
+
'ignore-patterns': getDefaultIgnorePatterns(info.language),
|
|
453
|
+
'architecture-type': info.architecture || 'layered'
|
|
454
|
+
},
|
|
455
|
+
documentation: {
|
|
456
|
+
'quick-ref': 'docs/QUICK-REF.md',
|
|
457
|
+
detailed: 'README.md',
|
|
458
|
+
examples: 'docs/examples/'
|
|
459
|
+
},
|
|
460
|
+
'context-strategy': {
|
|
461
|
+
'max-chunk-size': 50000,
|
|
462
|
+
overlap: 500,
|
|
463
|
+
'analysis-pattern': 'hierarchical',
|
|
464
|
+
'enable-rlm': true
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
return config;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Detect entry points
|
|
473
|
+
*/
|
|
474
|
+
function detectEntryPoints(projectPath, language) {
|
|
475
|
+
const entryPoints = [];
|
|
476
|
+
const candidates = {
|
|
477
|
+
typescript: ['src/index.ts', 'src/main.ts', 'index.ts'],
|
|
478
|
+
javascript: ['src/index.js', 'src/main.js', 'index.js'],
|
|
479
|
+
python: ['src/main.py', 'main.py', 'app.py'],
|
|
480
|
+
go: ['main.go', 'cmd/main.go'],
|
|
481
|
+
rust: ['src/main.rs', 'src/lib.rs']
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
const files = candidates[language] || candidates.typescript;
|
|
485
|
+
|
|
486
|
+
for (const file of files) {
|
|
487
|
+
if (existsSync(join(projectPath, file))) {
|
|
488
|
+
entryPoints.push(file);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return entryPoints.length > 0 ? entryPoints : files.slice(0, 2);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Get default ignore patterns for language
|
|
497
|
+
*/
|
|
498
|
+
function getDefaultIgnorePatterns(language) {
|
|
499
|
+
const common = ['.git', 'coverage', '*.log'];
|
|
500
|
+
|
|
501
|
+
const patterns = {
|
|
502
|
+
typescript: ['node_modules', 'dist', 'build', '*.test.ts', '*.spec.ts'],
|
|
503
|
+
javascript: ['node_modules', 'dist', 'build', '*.test.js', '*.spec.js'],
|
|
504
|
+
python: ['__pycache__', '.venv', 'venv', '*.pyc', '.pytest_cache'],
|
|
505
|
+
go: ['vendor'],
|
|
506
|
+
rust: ['target']
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
return [...common, ...(patterns[language] || patterns.typescript)];
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Generate YAML with helpful comments
|
|
514
|
+
*/
|
|
515
|
+
function generateYamlWithComments(config) {
|
|
516
|
+
const header = `# ============================================================
|
|
517
|
+
# .ai-context.yaml - AI Context Configuration
|
|
518
|
+
# ============================================================
|
|
519
|
+
# This file helps AI assistants understand your project structure
|
|
520
|
+
# and optimize their analysis and code generation.
|
|
521
|
+
#
|
|
522
|
+
# Reference: https://github.com/AsiaOstrich/universal-dev-standards
|
|
523
|
+
# Standard: core/ai-friendly-architecture.md
|
|
524
|
+
# ============================================================
|
|
525
|
+
|
|
526
|
+
`;
|
|
527
|
+
|
|
528
|
+
return header + yaml.dump(config, {
|
|
529
|
+
indent: 2,
|
|
530
|
+
lineWidth: 80,
|
|
531
|
+
quotingType: '"',
|
|
532
|
+
forceQuotes: false
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Get priority icon
|
|
538
|
+
*/
|
|
539
|
+
function getPriorityIcon(priority) {
|
|
540
|
+
const icons = {
|
|
541
|
+
high: chalk.red('●'),
|
|
542
|
+
medium: chalk.yellow('●'),
|
|
543
|
+
low: chalk.gray('●')
|
|
544
|
+
};
|
|
545
|
+
return icons[priority] || icons.medium;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export default {
|
|
549
|
+
aiContextInitCommand,
|
|
550
|
+
aiContextValidateCommand,
|
|
551
|
+
aiContextGraphCommand
|
|
552
|
+
};
|
package/src/commands/check.js
CHANGED
|
@@ -31,10 +31,10 @@ import {
|
|
|
31
31
|
compareStandardsWithReferences
|
|
32
32
|
} from '../utils/reference-sync.js';
|
|
33
33
|
import {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
extractMarkedContent
|
|
34
|
+
extractMarkedContent,
|
|
35
|
+
getToolFilePath
|
|
37
36
|
} from '../utils/integration-generator.js';
|
|
37
|
+
import { getToolFormat } from '../core/constants.js';
|
|
38
38
|
import { checkForUpdates } from '../utils/npm-registry.js';
|
|
39
39
|
import { t, getLanguage, setLanguage, isLanguageExplicitlySet } from '../i18n/messages.js';
|
|
40
40
|
|
package/src/commands/init.js
CHANGED
|
@@ -12,10 +12,12 @@ import {
|
|
|
12
12
|
import { detectAll } from '../utils/detector.js';
|
|
13
13
|
import {
|
|
14
14
|
copyStandard,
|
|
15
|
-
copyIntegration
|
|
16
|
-
writeManifest,
|
|
17
|
-
isInitialized
|
|
15
|
+
copyIntegration
|
|
18
16
|
} from '../utils/copier.js';
|
|
17
|
+
import {
|
|
18
|
+
writeManifest,
|
|
19
|
+
manifestExists as isInitialized
|
|
20
|
+
} from '../core/manifest.js';
|
|
19
21
|
import { t } from '../i18n/messages.js';
|
|
20
22
|
import {
|
|
21
23
|
downloadSkillToLocation,
|
|
@@ -558,6 +560,7 @@ export async function initCommand(options) {
|
|
|
558
560
|
|
|
559
561
|
// Helper to copy standard with format awareness
|
|
560
562
|
const copyStandardWithFormat = async (std, targetFormat) => {
|
|
563
|
+
// Use registry.getStandardSource to get relative path from standard object
|
|
561
564
|
const sourcePath = getStandardSource(std, targetFormat);
|
|
562
565
|
const result = await copyStandard(sourcePath, '.standards', projectPath);
|
|
563
566
|
return { ...result, sourcePath };
|