@eltonssouza/development-utility-kit 0.14.2 → 0.15.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/cli.js +13 -2
- package/bin/lib/identity.js +69 -7
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -432,6 +432,17 @@ function adoptProject(opts) {
|
|
|
432
432
|
templateContent = fs.readFileSync(srcClaudeMd, 'utf8');
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
+
// Rich auto-fill: project name (folder) + detect-stack (versions + database).
|
|
436
|
+
// Falls back gracefully if the richer detector module is unavailable.
|
|
437
|
+
let richStack = null;
|
|
438
|
+
const detectStackMod = tryRequire('./lib/detect-stack');
|
|
439
|
+
if (detectStackMod && typeof detectStackMod.detectStack === 'function') {
|
|
440
|
+
try {
|
|
441
|
+
richStack = detectStackMod.detectStack(subDir);
|
|
442
|
+
} catch { /* best-effort — placeholders remain */ }
|
|
443
|
+
}
|
|
444
|
+
const rich = { projectName: path.basename(path.resolve(subDir)), stack: richStack };
|
|
445
|
+
|
|
435
446
|
// Determine identity section
|
|
436
447
|
let identitySection;
|
|
437
448
|
if (initialIdentity) {
|
|
@@ -439,9 +450,9 @@ function adoptProject(opts) {
|
|
|
439
450
|
} else if (fs.existsSync(destClaudeMd)) {
|
|
440
451
|
const existingContent = fs.readFileSync(destClaudeMd, 'utf8');
|
|
441
452
|
const preserved = identity.readIdentitySection(existingContent);
|
|
442
|
-
identitySection = preserved !== null ? preserved : identity.generateIdentitySection(dr);
|
|
453
|
+
identitySection = preserved !== null ? preserved : identity.generateIdentitySection(dr, rich);
|
|
443
454
|
} else {
|
|
444
|
-
identitySection = identity.generateIdentitySection(dr);
|
|
455
|
+
identitySection = identity.generateIdentitySection(dr, rich);
|
|
445
456
|
}
|
|
446
457
|
|
|
447
458
|
const merged = identity.mergeClaudeMd('', templateContent, identitySection);
|
package/bin/lib/identity.js
CHANGED
|
@@ -11,25 +11,87 @@
|
|
|
11
11
|
|
|
12
12
|
const IDENTITY_HEADING = '## Project Identity';
|
|
13
13
|
|
|
14
|
+
const LANG_LABELS = {
|
|
15
|
+
java: 'Java', kotlin: 'Kotlin', typescript: 'TypeScript', javascript: 'JavaScript',
|
|
16
|
+
python: 'Python', go: 'Go', node: 'Node', rust: 'Rust', csharp: 'C#', ruby: 'Ruby',
|
|
17
|
+
};
|
|
18
|
+
const FRAMEWORK_LABELS = {
|
|
19
|
+
'spring-boot': 'Spring Boot', angular: 'Angular', react: 'React', vue: 'Vue',
|
|
20
|
+
svelte: 'Svelte', django: 'Django', fastapi: 'FastAPI', flask: 'Flask',
|
|
21
|
+
express: 'Express', nestjs: 'NestJS', gin: 'Gin', rails: 'Rails', aspire: 'Aspire',
|
|
22
|
+
'react-native': 'React Native', vite: 'Vite',
|
|
23
|
+
};
|
|
24
|
+
const DB_LABELS = {
|
|
25
|
+
postgres: 'PostgreSQL', postgresql: 'PostgreSQL', mysql: 'MySQL', mariadb: 'MariaDB',
|
|
26
|
+
mongodb: 'MongoDB', mongo: 'MongoDB', redis: 'Redis', sqlite: 'SQLite',
|
|
27
|
+
cassandra: 'Cassandra', elasticsearch: 'Elasticsearch',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Compose a clean "Java 21 + Spring Boot 3.2 + Angular 21" string from the rich
|
|
32
|
+
* detect-stack result. Returns null when nothing useful was detected.
|
|
33
|
+
* @param {object|null} stack detect-stack.js output
|
|
34
|
+
* @param {string[]} [hints] legacy stackHints (captures extra domains like n8n)
|
|
35
|
+
*/
|
|
36
|
+
function composeStackString(stack, hints) {
|
|
37
|
+
const parts = [];
|
|
38
|
+
if (stack && stack.language && stack.language !== 'unknown') {
|
|
39
|
+
const lang = LANG_LABELS[stack.language] || null;
|
|
40
|
+
const langVer = stack.java_version || stack.node_version
|
|
41
|
+
|| stack.python_version || stack.go_version || null;
|
|
42
|
+
if (lang) parts.push(langVer ? `${lang} ${langVer}` : lang);
|
|
43
|
+
const fw = stack.framework;
|
|
44
|
+
if (fw && fw !== 'unknown' && fw !== stack.language) {
|
|
45
|
+
const fwLabel = FRAMEWORK_LABELS[fw] || fw;
|
|
46
|
+
parts.push(stack.version ? `${fwLabel} ${stack.version}` : fwLabel);
|
|
47
|
+
}
|
|
48
|
+
if (stack.ui_lib && !parts.some((p) => p.toLowerCase().includes(String(stack.ui_lib).toLowerCase()))) {
|
|
49
|
+
parts.push(stack.ui_lib);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Fold in extra domains the rich detector misses (e.g. automation/n8n).
|
|
53
|
+
for (const h of hints || []) {
|
|
54
|
+
if (/n8n/i.test(h) && !parts.some((p) => /n8n/i.test(p))) parts.push('n8n');
|
|
55
|
+
}
|
|
56
|
+
return parts.length ? parts.join(' + ') : null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Map detected db keys to pretty labels, deduped. */
|
|
60
|
+
function composeDatabase(stack) {
|
|
61
|
+
if (!stack || !Array.isArray(stack.database) || stack.database.length === 0) return null;
|
|
62
|
+
const out = [];
|
|
63
|
+
for (const db of stack.database) {
|
|
64
|
+
const label = DB_LABELS[String(db).toLowerCase()] || db;
|
|
65
|
+
if (!out.includes(label)) out.push(label);
|
|
66
|
+
}
|
|
67
|
+
return out.length ? out.join(' + ') : null;
|
|
68
|
+
}
|
|
69
|
+
|
|
14
70
|
/**
|
|
15
71
|
* Build the Project Identity block pre-filled with detected values.
|
|
16
|
-
* @param {{ type: string, stackHints: string[] }} dr
|
|
72
|
+
* @param {{ type: string, stackHints: string[] }} dr legacy detector (type + breadth)
|
|
73
|
+
* @param {{ projectName?: string, stack?: object|null }} [rich] richer auto-fill:
|
|
74
|
+
* projectName (folder basename) + detect-stack.js result (versions + database).
|
|
17
75
|
* @returns {string}
|
|
18
76
|
*/
|
|
19
|
-
function generateIdentitySection(dr) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
77
|
+
function generateIdentitySection(dr, rich = {}) {
|
|
78
|
+
const stack = rich.stack || null;
|
|
79
|
+
const composed = composeStackString(stack, dr.stackHints);
|
|
80
|
+
const stackLine = composed
|
|
81
|
+
|| (dr.stackHints && dr.stackHints.length > 0 ? dr.stackHints.join(', ') : null)
|
|
82
|
+
|| '<ex: Java 25 + Spring Boot 4 + Angular 21>';
|
|
83
|
+
const nameLine = rich.projectName ? rich.projectName : '<project-name>';
|
|
84
|
+
const dbLine = composeDatabase(stack) || '<ex: PostgreSQL 17 + Redis 7>';
|
|
23
85
|
return `## Project Identity
|
|
24
86
|
|
|
25
87
|
> **Modifique apenas esta seção ao adotar o plugin em um novo projeto.**
|
|
26
88
|
> Todas as demais seções são base do plugin e não devem ser alteradas diretamente
|
|
27
89
|
> — use \`update-template\` para receber atualizações.
|
|
28
90
|
|
|
29
|
-
- **Project name**:
|
|
91
|
+
- **Project name**: \`${nameLine}\`
|
|
30
92
|
- **Project type**: \`${dr.type}\`
|
|
31
93
|
- **Primary stack**: \`${stackLine}\`
|
|
32
|
-
- **Database**:
|
|
94
|
+
- **Database**: \`${dbLine}\`
|
|
33
95
|
- **Domain**: \`<ex: e-commerce, fintech, healthcare>\`
|
|
34
96
|
- **Team size**: \`<ex: 3 backend, 2 frontend>\`
|
|
35
97
|
- **Additional rules**: _(deixe vazio se não houver)_`;
|