mdsmith 1.2.0 → 1.2.1

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/index.js CHANGED
@@ -8,82 +8,20 @@
8
8
  // npx mdsmith --analyze # project analyze
9
9
 
10
10
 
11
- const TECH_MAP = {
12
- // Frameworks
13
- express: "Express",
14
- fastify: "Fastify",
15
- koa: "Koa",
16
- hapi: "Hapi",
17
- "@nestjs/core": "NestJS",
18
-
19
- // ORMs
20
- prisma: "Prisma",
21
- "@prisma/client": "Prisma",
22
- sequelize: "Sequelize",
23
- mongoose: "Mongoose",
24
- typeorm: "TypeORM",
25
- drizzle: "Drizzle ORM",
26
-
27
- // Databases
28
- pg: "PostgreSQL",
29
- mysql: "MySQL",
30
- mysql2: "MySQL",
31
- sqlite3: "SQLite",
32
- mongodb: "MongoDB",
33
-
34
- // Auth
35
- jsonwebtoken: "JWT",
36
- passport: "Passport",
37
-
38
- // AI
39
- openai: "OpenAI",
40
- langchain: "LangChain",
41
-
42
- // Infra / Tools
43
- docker: "Docker",
44
- "swagger-ui-express": "Swagger",
45
- puppeteer: "Puppeteer",
46
- nodemailer: "Nodemailer"
47
- }
48
-
49
-
50
- const i18n = {
51
- en: {
52
- projectInfo: "Project Info",
53
- dependencies: "Dependencies",
54
- projectStructure: "Project Structure",
55
- availableScripts: "Available Scripts",
56
- version: "Version",
57
- packageManager: "Package Manager",
58
- type: "Type",
59
- generatedBy: "Generated by"
60
- },
61
- pt: {
62
- projectInfo: "Informações do Projeto",
63
- dependencies: "Dependências",
64
- projectStructure: "Estrutura do Projeto",
65
- availableScripts: "Scripts Disponíveis",
66
- version: "Versão",
67
- packageManager: "Gerenciador de Pacotes",
68
- type: "Tipo",
69
- generatedBy: "Gerado por"
70
- },
71
- es: {
72
- projectInfo: "Información del Proyecto",
73
- dependencies: "Dependencias",
74
- projectStructure: "Estructura del Proyecto",
75
- availableScripts: "Scripts Disponibles",
76
- version: "Versión",
77
- packageManager: "Administrador de Paquetes",
78
- type: "Tipo",
79
- generatedBy: "Generado por"
80
- }
81
- }
82
11
 
83
12
  const fs = require("fs");
84
13
 
85
14
  const path = require("path");
86
15
 
16
+ const core = require("../src/generators")
17
+ const detectors = require("../src/detectors")
18
+ const scanner = require("../src/scanner")
19
+ const readme = require("../src/readme")
20
+ const configModule = require("../src/config")
21
+ const analysisModule = require("../src/analysis")
22
+ const formatters = require("../src/formatters")
23
+
24
+
87
25
  const prompts = require('prompts');
88
26
 
89
27
  const projectRoot = process.cwd();
@@ -96,742 +34,21 @@ Please run mdsmith from the project root.
96
34
  process.exit(1)
97
35
  }
98
36
 
99
- const packageJson = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf-8"));
100
-
101
- const args = process.argv.slice(2)
102
-
103
- const defaultConfig = {
104
- ignore: ["node_modules", ".git", ".vscode"],
105
- depth: Infinity,
106
- emojis: true
107
- }
108
-
109
- function healthChecks(packageJson, projectRoot, analysis) {
110
- const checks = []
111
-
112
- if (!analysis.testing) {
113
- checks.push({
114
- type: "warning",
115
- message: "No test runner configured."
116
- })
117
- }
118
-
119
- if (!analysis.linting) {
120
- checks.push({
121
- type: "info",
122
- message: "No ESLint detected."
123
- })
124
- }
125
-
126
- if (!analysis.formatting) {
127
- checks.push({
128
- type: "info",
129
- message: "No Prettier detected."
130
- })
131
- }
132
-
133
- if (!packageJson.engines?.node) {
134
- checks.push({
135
- type: "critical",
136
- message: "Node version not defined in package.json engines."
137
- })
138
- }
139
-
140
- if (!fs.existsSync(path.join(projectRoot, "Dockerfile"))) {
141
- checks.push({
142
- type: "info",
143
- message: "No Dockerfile found."
144
- })
145
- }
146
-
147
- return checks
148
- }
149
-
150
-
151
- function formatDependencies(deps) {
152
- if (!deps || Object.keys(deps).length === 0) {
153
- return "No dependencies found.\n";
154
- }
155
-
156
- return Object.entries(deps)
157
- .map(([name, version]) => `- ${name} ${version}`)
158
- .join("\n");
159
- }
160
-
161
- function scanDir(dirPath, padding, config) {
162
- const entries = fs.readdirSync(dirPath, { withFileTypes: true })
163
- .sort((a, b) => {
164
- if (a.isDirectory() && !b.isDirectory()) return -1
165
- if (!a.isDirectory() && b.isDirectory()) return 1
166
- return a.name.localeCompare(b.name)
167
- })
168
-
169
- let treeContent = ""
170
-
171
-
172
- for (const entry of entries) {
173
-
174
- const fullPath = path.join(dirPath, entry.name);
175
-
176
- if (entry.isDirectory()) {
177
- if (config.ignore.includes(entry.name)){
178
- continue
179
- } else {
180
- treeContent += `${" ".repeat(padding*2)} 📂 ${entry.name}\n`
181
- if (config.depth === null || padding < config.depth){
182
- padding ++
183
- treeContent += scanDir(fullPath, padding, config)
184
- padding --
185
- } else {
186
- treeContent += `${" ".repeat((padding + 1) * 2)} ··· \n`
187
- }
188
- }
189
- } else {
190
- if (config.ignore.includes(entry.name)){
191
- continue
192
- } else{
193
- treeContent += `${" ".repeat(padding*2)} 📄 ${entry.name}\n`
194
- }
195
- }
196
- }
197
-
198
- return treeContent
199
- }
200
-
201
- async function buscarNome(nome) {
202
- if (!nome) {
203
- const confirm = await prompts({
204
- type: 'confirm',
205
- name: 'value',
206
- message: 'Project name not found in package.json. Provide one?',
207
- initial: true
208
- });
209
-
210
- if (!confirm.value) {
211
- console.log("\nProject name will be set as Unnamed Project.\n");
212
- return "Unnamed Project";
213
- }
214
-
215
- const response = await prompts({
216
- type: 'text',
217
- name: 'value',
218
- message: 'Enter the project name:'
219
- });
220
-
221
- console.log(`\nProject name set to "${response.value}".\n`);
222
- return response.value || "Unnamed Project";
223
- }
224
-
225
- return nome;
226
- }
227
-
228
- async function buscarDescricao(descricao) {
229
- if (!descricao) {
230
- const confirm = await prompts({
231
- type: 'confirm',
232
- name: 'value',
233
- message: 'Project description not found. Provide one?',
234
- initial: true
235
- });
236
-
237
- if (!confirm.value) {
238
- console.log("\nDescription placeholder added.\n");
239
- return "*Project description goes here*";
240
- }
241
-
242
- const response = await prompts({
243
- type: 'text',
244
- name: 'value',
245
- message: 'Enter the project description:'
246
- });
247
-
248
- console.log("\nDescription saved.\n");
249
- return response.value || "*Project description goes here*";
250
- }
251
-
252
- return descricao;
253
- }
254
-
255
- function detectarTipoProjeto(packageJson) {
256
- const deps = {
257
- ...packageJson.dependencies,
258
- ...packageJson.devDependencies
259
- }
260
-
261
- if (deps.react) return "Frontend React"
262
- if (deps.next) return "Next.js Application"
263
- if (deps.express) return "API REST (Express)"
264
- if (deps.typescript) return "Projeto TypeScript"
265
-
266
- return "Node.js Project"
267
- }
268
-
269
- function formatScripts(scripts) {
270
- if (!scripts || Object.keys(scripts).length === 0) {
271
- return "No scripts available.\n";
272
- }
273
-
274
- return Object.entries(scripts)
275
- .map(([name, script]) => `- ${name} -> ${script}`)
276
- .join("\n");
277
- }
278
-
279
- function detectarEnvVars(projectRoot) {
280
- const envPath = path.join(projectRoot, ".env")
281
-
282
- if (!fs.existsSync(envPath)) return []
283
-
284
- const content = fs.readFileSync(envPath, "utf-8")
285
-
286
- const vars = content
287
- .split("\n")
288
- .map(line => line.trim())
289
- .filter(line =>
290
- line &&
291
- !line.startsWith("#") &&
292
- line.includes("=")
293
- )
294
- .map(line => line.split("=")[0].trim())
295
-
296
- return vars
297
- }
298
-
299
- function gerarEnvSection(vars) {
300
- if (!vars.length) return ""
301
-
302
- let section = "## 🔑 Environment Variables\n\n"
303
- section += "Create a `.env` file in the project root with the following variables:\n\n"
304
-
305
- vars.forEach(v => {
306
- section += `- ${v}\n`
307
- })
308
-
309
- return section + "\n"
310
- }
311
-
312
- function detectarPorta(scanData) {
313
- const filesToScan = [...scanData.jsFiles, ...scanData.tsFiles]
314
-
315
- for (const filePath of filesToScan) {
316
- try {
317
- const content = fs.readFileSync(filePath, "utf-8")
318
-
319
- // 🔎 procurar qualquer .listen(...)
320
- const listenRegex = /\.listen\s*\(\s*([^)]+)\)/
321
- const listenMatch = content.match(listenRegex)
322
-
323
- if (!listenMatch) continue
324
-
325
- const rawArgument = listenMatch[1].split(",")[0].trim()
326
-
327
- // =============================
328
- // ✅ 1️⃣ Número direto
329
- // =============================
330
- if (/^\d+$/.test(rawArgument)) {
331
- return rawArgument
332
- }
333
-
334
- // =============================
335
- // ✅ 2️⃣ Fallback inline
336
- // ex: process.env.PORT || 3000
337
- // =============================
338
- const inlineFallback = rawArgument.match(/\|\|\s*(\d+)/)
339
- if (inlineFallback) {
340
- return inlineFallback[1]
341
- }
342
-
343
- // =============================
344
- // ✅ 3️⃣ Variável
345
- // ex: app.listen(port)
346
- // =============================
347
- const variableName = rawArgument.replace(/[^a-zA-Z0-9_]/g, "")
348
-
349
- if (!variableName) continue
350
-
351
- const variableRegex = new RegExp(
352
- `(const|let|var)\\s+${variableName}\\s*=\\s*([^;]+)`
353
- )
354
-
355
- const variableMatch = content.match(variableRegex)
356
-
357
- if (variableMatch) {
358
- const variableValue = variableMatch[2]
359
-
360
- // fallback dentro da variável
361
- const fallbackMatch = variableValue.match(/\|\|\s*(\d+)/)
362
- if (fallbackMatch) {
363
- return fallbackMatch[1]
364
- }
365
-
366
- // número direto dentro da variável
367
- const numberMatch = variableValue.match(/\d+/)
368
- if (numberMatch) {
369
- return numberMatch[0]
370
- }
371
- }
372
-
373
- // =============================
374
- // ✅ 4️⃣ process.env.PORT puro
375
- // =============================
376
- if (rawArgument.includes("process.env.PORT")) {
377
- return "process.env.PORT"
378
- }
379
-
380
- } catch (err) {
381
- // evita quebrar o CLI se algum arquivo falhar
382
- continue
383
- }
384
- }
385
-
386
- return null
387
- }
388
-
389
- function scanProjectFiles(projectRoot) {
390
- const result = {
391
- allFiles: [],
392
- jsFiles: [],
393
- tsFiles: [],
394
- envFiles: [],
395
- hasDockerfile: false,
396
- hasPrisma: false,
397
- hasSrcFolder: false,
398
- }
399
-
400
- function walk(dir) {
401
- const files = fs.readdirSync(dir)
402
-
403
- for (const file of files) {
404
- const fullPath = path.join(dir, file)
405
-
406
- // ignorar node_modules e .git
407
- if (
408
- fullPath.includes("node_modules") ||
409
- fullPath.includes(".git")
410
- ) continue
411
-
412
- const stat = fs.statSync(fullPath)
413
-
414
- if (stat.isDirectory()) {
415
- if (file === "src") {
416
- result.hasSrcFolder = true
417
- }
418
- walk(fullPath)
419
- } else {
420
- result.allFiles.push(fullPath)
421
-
422
- if (file.endsWith(".js")) result.jsFiles.push(fullPath)
423
- if (file.endsWith(".ts")) result.tsFiles.push(fullPath)
424
- if (file.startsWith(".env")) result.envFiles.push(fullPath)
425
-
426
- if (file === "Dockerfile") result.hasDockerfile = true
427
- if (fullPath.includes("prisma")) result.hasPrisma = true
428
- }
429
- }
430
- }
431
-
432
- walk(projectRoot)
433
-
434
- return result
435
- }
436
-
437
- function gerarGettingStarted(packageManager = "npm", scripts = {}, hasPrisma) {
438
- const lines = []
439
-
440
- lines.push(
441
- packageManager === "npm"
442
- ? "npm install"
443
- : `${packageManager} install`
444
- )
445
-
446
- if (hasPrisma) {
447
- lines.push("npx prisma migrate dev")
448
- }
449
-
450
- if (scripts.dev) {
451
- lines.push(getRunCommand("dev", packageManager))
452
- } else if (scripts.start) {
453
- lines.push(getRunCommand("start", packageManager))
454
- }
455
-
456
- return `
457
- ## 🚀 Getting Started
458
-
459
- \`\`\`bash
460
- ${lines.join("\n")}
461
- \`\`\`
462
-
463
- `
464
- }
465
-
466
-
467
- function getRunCommand(script, packageManager) {
468
- if (packageManager === "yarn") return `yarn ${script}`
469
- if (packageManager === "pnpm") return `pnpm ${script}`
470
- return `npm run ${script}`
471
- }
472
-
473
-
474
-
475
- async function generateReadme(packageJson, tree, config){
476
-
477
- const deps = {
478
- ...packageJson.dependencies,
479
- ...packageJson.devDependencies
480
- }
481
-
482
- const techStack = detectarTechStack(deps)
483
- const techSection = gerarTechStackSection(techStack)
484
-
485
-
37
+ let packageJson
486
38
 
487
-
488
- const envVars = detectarEnvVars(projectRoot)
489
- const envSection = gerarEnvSection(envVars)
490
-
491
- const nomeProjeto = await buscarNome(packageJson.name);
492
- const descricaoProjeto = await buscarDescricao(packageJson.description);
493
- const idioma = await escolherLingua()
494
- const t = i18n[idioma] || i18n.en
495
-
496
- const packageManager = detectarPackageManager(projectRoot)
497
-
498
- const scanData = scanProjectFiles(projectRoot)
499
- const port = detectarPorta(scanData)
500
-
501
- const commands = analisarScripts(packageJson.scripts, packageManager)
502
-
503
- const hasPrisma = detectarPrisma(projectRoot, packageJson)
504
- const dbSection = hasPrisma ? gerarDatabaseSection(packageManager) : ""
505
-
506
- const gettingStartedCommands = gerarGettingStarted(
507
- packageManager,
508
- packageJson.scripts,
509
- hasPrisma
39
+ try {
40
+ packageJson = JSON.parse(
41
+ fs.readFileSync(path.join(projectRoot, "package.json"), "utf-8")
510
42
  )
511
-
512
-
513
-
514
- const content = `
515
- # ${nomeProjeto}
516
-
517
- ${descricaoProjeto}
518
-
519
- ## ${config.emojis ? "🔖" : ""} ${t.projectInfo}
520
- - **${t.version}:** ${packageJson.version || "Not specified"}
521
- - **${t.packageManager}:** ${packageManager}
522
- - **${t.type}:** ${detectarTipoProjeto(packageJson)}
523
-
524
- ${techSection}
525
-
526
- ## ${config.emojis ? "📁" : ""} ${t.projectStructure}
527
- \`\`\`
528
- ${tree}
529
- \`\`\`
530
-
531
- ${gettingStartedCommands}
532
-
533
- ${envSection}
534
- ${dbSection}
535
-
536
- ${port ? `
537
- ## 🌐 Server
538
-
539
- After starting, the server will run at:
540
-
541
- http://localhost:${port}
542
-
543
- ` : ""}
544
-
545
-
546
- ---
547
-
548
- ${t.generatedBy} **mdSmith**
549
- `
550
-
551
- return content
552
-
553
- }
554
-
555
- function detectarPrisma(projectRoot, packageJson) {
556
- const deps = {
557
- ...packageJson.dependencies,
558
- ...packageJson.devDependencies
559
- }
560
-
561
- const hasPrismaDep = deps.prisma || deps["@prisma/client"]
562
- const hasPrismaFolder = fs.existsSync(path.join(projectRoot, "prisma"))
563
-
564
- return hasPrismaDep && hasPrismaFolder
565
- }
566
-
567
- function gerarDatabaseSection(packageManager) {
568
- let section = "## 🗄 Database Setup\n\n"
569
- section += "Run Prisma migrations:\n\n"
570
- section += "```bash\n"
571
-
572
- if (packageManager === "npm") {
573
- section += "npx prisma migrate dev\n"
574
- section += "npx prisma generate\n"
575
- } else {
576
- section += `${packageManager} prisma migrate dev\n`
577
- section += `${packageManager} prisma generate\n`
578
- }
579
-
580
- section += "```\n\n"
581
-
582
- return section
583
- }
584
-
585
-
586
-
587
- async function escolherLingua() {
588
- const response = await prompts({
589
- type: 'select',
590
- name: 'lang',
591
- message: 'Choose README language',
592
- choices: [
593
- { title: 'English', value: 'en' },
594
- { title: 'Português', value: 'pt' },
595
- { title: 'Español', value: 'es' }
596
- ],
597
- initial: 0
598
- });
599
-
600
- return response.lang || 'en';
601
- }
602
-
603
- function loadConfig(projectRoot) {
604
- const configPath = path.join(projectRoot, "mdsmith.config.json")
605
-
606
- if (!fs.existsSync(configPath)) {
607
- return defaultConfig
608
- }
609
-
610
- try {
611
- const fileContent = fs.readFileSync(configPath, "utf-8")
612
- const userConfig = JSON.parse(fileContent)
613
-
614
- return {
615
- ...defaultConfig,
616
- ...userConfig,
617
- ignore: [
618
- ...defaultConfig.ignore,
619
- ...(userConfig.ignore || [])
620
- ]
621
- }
622
-
623
-
624
- } catch (error) {
625
- console.log("Failed to read mdsmith.config.json. Using default configuration.")
626
- return defaultConfig
627
- }
628
- }
629
-
630
- function analisarProjeto(packageJson, projectRoot) {
631
- const deps = {
632
- ...packageJson.dependencies,
633
- ...packageJson.devDependencies
634
- }
635
-
636
- const analysis = {
637
- frontend: deps.react ? "React" :
638
- deps.next ? "Next.js" :
639
- null,
640
-
641
- backend: deps.express ? "Express" :
642
- deps.fastify ? "Fastify" :
643
- null,
644
-
645
- language: deps.typescript ? "TypeScript" : "JavaScript",
646
-
647
- bundler: deps.vite ? "Vite" :
648
- deps.webpack ? "Webpack" :
649
- null,
650
-
651
- styling: deps.tailwindcss ? "TailwindCSS" :
652
- deps.sass ? "Sass" :
653
- null,
654
-
655
- database: deps.mongoose ? "MongoDB" :
656
- deps.prisma ? "Prisma" :
657
- deps.pg ? "PostgreSQL" :
658
- null,
659
-
660
- testing: deps.jest ? "Jest" :
661
- deps.vitest ? "Vitest" :
662
- null,
663
-
664
- linting: deps.eslint ? "ESLint" : null,
665
-
666
- formatting: deps.prettier ? "Prettier" : null,
667
-
668
- node: detectarNodeVersion(projectRoot, packageJson)
669
- }
670
-
671
- if (analysis.frontend && analysis.backend) {
672
- analysis.architecture = "Fullstack"
673
- } else if (analysis.frontend) {
674
- analysis.architecture = "Frontend"
675
- } else if (analysis.backend) {
676
- analysis.architecture = "Backend"
677
- }
678
-
679
- return analysis
680
- }
681
-
682
- function detectarPackageManager(projectRoot) {
683
- if (fs.existsSync(path.join(projectRoot, "pnpm-lock.yaml"))) {
684
- return "pnpm"
685
- }
686
-
687
- if (fs.existsSync(path.join(projectRoot, "yarn.lock"))) {
688
- return "yarn"
689
- }
690
-
691
- if (fs.existsSync(path.join(projectRoot, "package-lock.json"))) {
692
- return "npm"
693
- }
694
-
695
- return "npm"
696
- }
697
-
698
- function analisarScripts(scripts = {}, packageManager) {
699
- const commands = {
700
- install: packageManager === "npm"
701
- ? "npm install"
702
- : `${packageManager} install`
703
- }
704
-
705
- if (scripts.dev) {
706
- commands.dev = `${packageManager} run dev`
707
- }
708
-
709
- if (scripts.build) {
710
- commands.build = `${packageManager} run build`
711
- }
712
-
713
- if (scripts.start) {
714
- commands.start = packageManager === "npm"
715
- ? "npm start"
716
- : `${packageManager} start`
717
- }
718
-
719
- if (scripts.preview) {
720
- commands.preview = `${packageManager} run preview`
721
- }
722
-
723
- return commands
724
- }
725
-
726
- function diagnosticarExecucao(commands) {
727
- const warnings = []
728
-
729
- if (!commands.dev && !commands.start) {
730
- warnings.push("No development or start script found.")
731
- }
732
-
733
- if (commands.build && !commands.start) {
734
- warnings.push("Build script found but no start script for production.")
735
- }
736
-
737
- return warnings
738
- }
739
-
740
- function detectarNodeVersion(projectRoot, packageJson) {
741
- if (packageJson.engines && packageJson.engines.node) {
742
- return packageJson.engines.node
743
- }
744
-
745
- const nvmrcPath = path.join(projectRoot, ".nvmrc")
746
- if (fs.existsSync(nvmrcPath)) {
747
- return fs.readFileSync(nvmrcPath, "utf-8").trim()
748
- }
749
-
750
- const nodeVersionPath = path.join(projectRoot, ".node-version")
751
- if (fs.existsSync(nodeVersionPath)) {
752
- return fs.readFileSync(nodeVersionPath, "utf-8").trim()
753
- }
754
-
755
- return process.version
756
- }
757
-
758
- function detectarTechStack(deps = {}) {
759
- const stack = new Set()
760
-
761
- for (const dep in deps) {
762
- if (TECH_MAP[dep]) {
763
- stack.add(TECH_MAP[dep])
764
- }
765
- }
766
-
767
- return Array.from(stack).sort()
768
- }
769
-
770
- function gerarTechStackSection(stack) {
771
- if (!stack.length) return ""
772
-
773
- let section = "## 🛠 Tech Stack\n\n"
774
-
775
- stack.forEach(tech => {
776
- section += `- ${tech}\n`
777
- })
778
-
779
- return section + "\n"
43
+ } catch {
44
+ console.log("Invalid package.json file.")
45
+ process.exit(1)
780
46
  }
781
47
 
782
-
783
- function formatarAnalise(analysis) {
784
- console.log(`
785
- Project Analysis
786
- ────────────────────────
787
- `)
788
-
789
- const entries = Object.entries(analysis)
790
-
791
- for (const [key, value] of entries) {
792
- if (value) {
793
- const label = key.charAt(0).toUpperCase() + key.slice(1)
794
- console.log(`✓ ${label}: ${value}`)
795
- }
796
- }
797
-
798
- console.log("")
799
- }
800
-
801
- function formatarExecucao(commands, warnings) {
802
- console.log(`Project Execution Strategy
803
- ────────────────────────`)
804
-
805
- console.log(`Install:`)
806
- console.log(` ${commands.install}\n`)
807
-
808
- if (commands.dev) {
809
- console.log(`Development:`)
810
- console.log(` ${commands.dev}\n`)
811
- }
812
-
813
- if (commands.build && commands.start) {
814
- console.log(`Production:`)
815
- console.log(` ${commands.build}`)
816
- console.log(` ${commands.start}\n`)
817
- }
818
-
819
- if (commands.preview) {
820
- console.log(`Preview:`)
821
- console.log(` ${commands.preview}\n`)
822
- }
823
-
824
- if (warnings.length > 0) {
825
- console.log(`Warnings:`)
826
- warnings.forEach(w => console.log(` ⚠ ${w}`))
827
- console.log()
828
- }
829
- }
830
-
831
-
48
+ const args = process.argv.slice(2)
832
49
 
833
50
  async function main() {
834
- const config = loadConfig(projectRoot)
51
+ const config = configModule.loadConfig(projectRoot)
835
52
 
836
53
  if(args.length == 0){
837
54
  console.log(`
@@ -853,7 +70,7 @@ Run "mdsmith --help" to view available commands.
853
70
 
854
71
  fs.writeFileSync(
855
72
  configPath,
856
- JSON.stringify(defaultConfig, null, 2)
73
+ JSON.stringify(configModule.defaultConfig, null, 2)
857
74
  )
858
75
 
859
76
  console.log("Configuration file created.")
@@ -877,20 +94,20 @@ mdSmith — Available Commands
877
94
  Project Structure
878
95
  ────────────────────────
879
96
  `);
880
- console.log(scanDir(projectRoot, 0, config))
97
+ console.log(scanner.scanDir(projectRoot, 0, config))
881
98
  process.exit(0)
882
99
  } else if (args.includes("--analyze")){
883
- const analysis = analisarProjeto(packageJson, projectRoot)
884
- const packageManager = detectarPackageManager(projectRoot)
100
+ const analysis = analysisModule.analisarProjeto(packageJson, projectRoot)
101
+ const packageManager = detectors.detectarPackageManager(projectRoot)
885
102
 
886
- formatarAnalise(analysis)
103
+ formatters.formatarAnalise(analysis)
887
104
 
888
- const commands = analisarScripts(packageJson.scripts, packageManager)
889
- const warnings = diagnosticarExecucao(commands)
105
+ const commands = analysisModule.analisarScripts(packageJson.scripts, packageManager)
106
+ const warnings = analysisModule.diagnosticarExecucao(commands)
890
107
 
891
- formatarExecucao(commands, warnings)
108
+ formatters.formatarExecucao(commands, warnings)
892
109
 
893
- const issues = healthChecks(packageJson, projectRoot, analysis)
110
+ const issues = analysisModule.healthChecks(packageJson, projectRoot, analysis)
894
111
 
895
112
  if (issues.length > 0) {
896
113
  console.log("Health Checks")
@@ -912,12 +129,12 @@ Project Structure
912
129
  Dependencies
913
130
  ────────────────────────
914
131
  `)
915
- const deps = formatDependencies(packageJson.dependencies)
132
+ const deps = core.formatDependencies(packageJson.dependencies)
916
133
  console.log(`${deps}\n`)
917
134
  console.log()
918
135
  process.exit(0)
919
136
  } else if (args.includes("--readme")){
920
- const content = await generateReadme(packageJson, scanDir(projectRoot, 0, config), config)
137
+ const content = await readme.generateReadme(packageJson, scanner.scanDir(projectRoot, 0, config), config)
921
138
 
922
139
  console.log(`
923
140
  README Preview