forgestack-os-cli 0.3.4 → 0.3.6

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.
Files changed (46) hide show
  1. package/README.md +382 -150
  2. package/dist/commands/doctor.d.ts +12 -0
  3. package/dist/commands/doctor.js +214 -0
  4. package/dist/commands/doctor.js.map +1 -0
  5. package/dist/commands/organize.d.ts +2 -0
  6. package/dist/commands/organize.js +126 -0
  7. package/dist/commands/organize.js.map +1 -0
  8. package/dist/commands/run-tasks.d.ts +12 -0
  9. package/dist/commands/run-tasks.js +125 -0
  10. package/dist/commands/run-tasks.js.map +1 -0
  11. package/dist/index.js +30 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/utils/doctor/check-database.d.ts +8 -0
  14. package/dist/utils/doctor/check-database.js +271 -0
  15. package/dist/utils/doctor/check-database.js.map +1 -0
  16. package/dist/utils/doctor/check-docker.d.ts +8 -0
  17. package/dist/utils/doctor/check-docker.js +212 -0
  18. package/dist/utils/doctor/check-docker.js.map +1 -0
  19. package/dist/utils/doctor/check-env.d.ts +12 -0
  20. package/dist/utils/doctor/check-env.js +207 -0
  21. package/dist/utils/doctor/check-env.js.map +1 -0
  22. package/dist/utils/doctor/check-lint.d.ts +8 -0
  23. package/dist/utils/doctor/check-lint.js +225 -0
  24. package/dist/utils/doctor/check-lint.js.map +1 -0
  25. package/dist/utils/doctor/check-node.d.ts +20 -0
  26. package/dist/utils/doctor/check-node.js +172 -0
  27. package/dist/utils/doctor/check-node.js.map +1 -0
  28. package/dist/utils/doctor/check-ports.d.ts +15 -0
  29. package/dist/utils/doctor/check-ports.js +166 -0
  30. package/dist/utils/doctor/check-ports.js.map +1 -0
  31. package/dist/utils/doctor/check-prisma.d.ts +8 -0
  32. package/dist/utils/doctor/check-prisma.js +202 -0
  33. package/dist/utils/doctor/check-prisma.js.map +1 -0
  34. package/dist/utils/doctor/index.d.ts +14 -0
  35. package/dist/utils/doctor/index.js +15 -0
  36. package/dist/utils/doctor/index.js.map +1 -0
  37. package/dist/utils/doctor/types.d.ts +50 -0
  38. package/dist/utils/doctor/types.js +5 -0
  39. package/dist/utils/doctor/types.js.map +1 -0
  40. package/dist/utils/file-organizer.d.ts +17 -0
  41. package/dist/utils/file-organizer.js +170 -0
  42. package/dist/utils/file-organizer.js.map +1 -0
  43. package/dist/utils/task-runner.d.ts +14 -0
  44. package/dist/utils/task-runner.js +79 -0
  45. package/dist/utils/task-runner.js.map +1 -0
  46. package/package.json +11 -4
@@ -0,0 +1,214 @@
1
+ /**
2
+ * ForgeStack Doctor Command
3
+ *
4
+ * Validates the generated SaaS project environment and dev setup.
5
+ * Helps developers quickly detect missing dependencies, configuration issues,
6
+ * and common setup problems before running the app.
7
+ */
8
+ import chalk from 'chalk';
9
+ import path from 'path';
10
+ import { runNodeChecks, checkEnvVariables, checkDatabaseConnection, runPrismaChecks, runDockerChecks, checkAppPorts, runLintChecks, generateMissingEnvReport, } from '../utils/doctor/index.js';
11
+ import { logger } from '../utils/logger.js';
12
+ /**
13
+ * Status icons for console output
14
+ */
15
+ const STATUS_ICONS = {
16
+ pass: chalk.green('✅'),
17
+ warn: chalk.yellow('⚠️'),
18
+ fail: chalk.red('❌'),
19
+ skip: chalk.gray('⏭️'),
20
+ };
21
+ /**
22
+ * Format a check result for console output
23
+ */
24
+ function formatCheckResult(result) {
25
+ const icon = STATUS_ICONS[result.status];
26
+ let output = `${icon} ${result.name}: ${result.message}`;
27
+ if (result.details) {
28
+ output += chalk.gray(`\n └─ ${result.details}`);
29
+ }
30
+ if (result.fix && (result.status === 'fail' || result.status === 'warn')) {
31
+ output += chalk.cyan(`\n 💡 Fix: ${result.fix}`);
32
+ }
33
+ return output;
34
+ }
35
+ /**
36
+ * Create a summary from check results
37
+ */
38
+ function createSummary(checks) {
39
+ return {
40
+ total: checks.length,
41
+ passed: checks.filter(c => c.status === 'pass').length,
42
+ warnings: checks.filter(c => c.status === 'warn').length,
43
+ failed: checks.filter(c => c.status === 'fail').length,
44
+ skipped: checks.filter(c => c.status === 'skip').length,
45
+ };
46
+ }
47
+ /**
48
+ * Print the doctor report banner
49
+ */
50
+ function printBanner() {
51
+ console.log('');
52
+ console.log(chalk.bold.cyan('╔═══════════════════════════════════════════════════╗'));
53
+ console.log(chalk.bold.cyan('║ ║'));
54
+ console.log(chalk.bold.cyan('║ 🩺 ForgeStack Doctor Report ║'));
55
+ console.log(chalk.bold.cyan('║ ║'));
56
+ console.log(chalk.bold.cyan('╚═══════════════════════════════════════════════════╝'));
57
+ console.log('');
58
+ }
59
+ /**
60
+ * Print the summary section
61
+ */
62
+ function printSummary(summary) {
63
+ console.log('');
64
+ console.log(chalk.bold('─'.repeat(55)));
65
+ console.log(chalk.bold('\n📊 Summary:\n'));
66
+ const items = [
67
+ { label: 'Total Checks', value: summary.total, color: chalk.white },
68
+ { label: 'Passed', value: summary.passed, color: chalk.green },
69
+ { label: 'Warnings', value: summary.warnings, color: chalk.yellow },
70
+ { label: 'Failed', value: summary.failed, color: chalk.red },
71
+ { label: 'Skipped', value: summary.skipped, color: chalk.gray },
72
+ ];
73
+ for (const item of items) {
74
+ console.log(` ${item.color(`${item.label}:`)} ${item.value}`);
75
+ }
76
+ console.log('');
77
+ }
78
+ /**
79
+ * Print section header
80
+ */
81
+ function printSection(title) {
82
+ console.log(chalk.bold.blue(`\n📋 ${title}\n`));
83
+ }
84
+ /**
85
+ * Main doctor command implementation
86
+ */
87
+ export async function doctorCommand(options = {}) {
88
+ const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();
89
+ const allChecks = [];
90
+ // Print banner (unless JSON output)
91
+ if (!options.json) {
92
+ printBanner();
93
+ console.log(chalk.gray(`Working directory: ${cwd}\n`));
94
+ }
95
+ try {
96
+ // 1. Node & Package Manager Checks
97
+ if (!options.json) {
98
+ printSection('Node.js & Package Managers');
99
+ }
100
+ const nodeChecks = await runNodeChecks(cwd);
101
+ allChecks.push(...nodeChecks);
102
+ if (!options.json) {
103
+ nodeChecks.forEach(r => console.log(formatCheckResult(r)));
104
+ }
105
+ // 2. Environment Variable Checks
106
+ if (!options.json) {
107
+ printSection('Environment Variables');
108
+ }
109
+ const envChecks = await checkEnvVariables(cwd);
110
+ allChecks.push(...envChecks);
111
+ if (!options.json) {
112
+ envChecks.forEach(r => console.log(formatCheckResult(r)));
113
+ }
114
+ // Generate .env.missing report if requested
115
+ if (options.fix) {
116
+ const missingReportPath = await generateMissingEnvReport(cwd);
117
+ if (missingReportPath && !options.json) {
118
+ console.log(chalk.cyan(`\n 📝 Generated: ${missingReportPath}`));
119
+ }
120
+ }
121
+ // 3. Database Connectivity Checks
122
+ if (!options.json) {
123
+ printSection('Database Connectivity');
124
+ }
125
+ const dbChecks = await checkDatabaseConnection(cwd);
126
+ allChecks.push(...dbChecks);
127
+ if (!options.json) {
128
+ dbChecks.forEach(r => console.log(formatCheckResult(r)));
129
+ }
130
+ // 4. Prisma Checks
131
+ if (!options.json) {
132
+ printSection('Prisma ORM');
133
+ }
134
+ const prismaChecks = await runPrismaChecks(cwd);
135
+ allChecks.push(...prismaChecks);
136
+ if (!options.json) {
137
+ prismaChecks.forEach(r => console.log(formatCheckResult(r)));
138
+ }
139
+ // 5. Docker Checks
140
+ if (!options.json) {
141
+ printSection('Docker');
142
+ }
143
+ const dockerChecks = await runDockerChecks(cwd);
144
+ allChecks.push(...dockerChecks);
145
+ if (!options.json) {
146
+ dockerChecks.forEach(r => console.log(formatCheckResult(r)));
147
+ }
148
+ // 6. Port Availability Checks
149
+ if (!options.json) {
150
+ printSection('Port Availability');
151
+ }
152
+ const portChecks = await checkAppPorts();
153
+ allChecks.push(...portChecks);
154
+ if (!options.json) {
155
+ portChecks.forEach(r => console.log(formatCheckResult(r)));
156
+ }
157
+ // 7. Lint Checks (optional)
158
+ if (options.lint) {
159
+ if (!options.json) {
160
+ printSection('Code Quality (ESLint & TypeScript)');
161
+ }
162
+ const lintChecks = await runLintChecks(cwd);
163
+ allChecks.push(...lintChecks);
164
+ if (!options.json) {
165
+ lintChecks.forEach(r => console.log(formatCheckResult(r)));
166
+ }
167
+ }
168
+ // Create report
169
+ const summary = createSummary(allChecks);
170
+ const report = {
171
+ timestamp: new Date().toISOString(),
172
+ cwd,
173
+ checks: allChecks,
174
+ summary,
175
+ exitCode: summary.failed > 0 ? 1 : 0,
176
+ };
177
+ // Output
178
+ if (options.json) {
179
+ console.log(JSON.stringify(report, null, 2));
180
+ }
181
+ else {
182
+ printSummary(summary);
183
+ // Final status message
184
+ if (summary.failed > 0) {
185
+ logger.error(`Found ${summary.failed} critical issue(s) that need to be fixed.`);
186
+ }
187
+ else if (summary.warnings > 0) {
188
+ logger.warning(`Found ${summary.warnings} warning(s) to review.`);
189
+ }
190
+ else {
191
+ logger.success('All checks passed! Your environment is ready. 🚀');
192
+ }
193
+ console.log('');
194
+ }
195
+ // Exit with appropriate code
196
+ if (summary.failed > 0) {
197
+ process.exit(1);
198
+ }
199
+ }
200
+ catch (error) {
201
+ if (!options.json) {
202
+ logger.error('Doctor command failed unexpectedly');
203
+ console.error(error);
204
+ }
205
+ else {
206
+ console.log(JSON.stringify({
207
+ error: error instanceof Error ? error.message : String(error),
208
+ exitCode: 1,
209
+ }));
210
+ }
211
+ process.exit(1);
212
+ }
213
+ }
214
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAKH,aAAa,EACb,iBAAiB,EACjB,uBAAuB,EACvB,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,wBAAwB,GAC3B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;GAEG;AACH,MAAM,YAAY,GAAgC;IAC9C,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;IACtB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;IACxB,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAAmB;IAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,MAAM,GAAG,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC;IAEzD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,MAAqB;IACxC,OAAO;QACH,KAAK,EAAE,MAAM,CAAC,MAAM;QACpB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM;QACtD,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM;QACxD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM;QACtD,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM;KAC1D,CAAC;AACN,CAAC;AAED;;GAEG;AACH,SAAS,WAAW;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,OAAgC;IAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAE3C,MAAM,KAAK,GAAG;QACV,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;QACnE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;QAC9D,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE;QACnE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE;QAC5D,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;KAClE,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,KAAa;IAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAyB,EAAE;IAC3D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACpE,MAAM,SAAS,GAAkB,EAAE,CAAC;IAEpC,oCAAoC;IACpC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAChB,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,CAAC;QACD,mCAAmC;QACnC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,4BAA4B,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QAC5C,SAAS,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,uBAAuB,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC/C,SAAS,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC;QAED,4CAA4C;QAC5C,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,iBAAiB,GAAG,MAAM,wBAAwB,CAAC,GAAG,CAAC,CAAC;YAC9D,IAAI,iBAAiB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,iBAAiB,EAAE,CAAC,CAAC,CAAC;YACvE,CAAC;QACL,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,uBAAuB,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAC;QACpD,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;QAED,mBAAmB;QACnB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,YAAY,CAAC,CAAC;QAC/B,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;QAChD,SAAS,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,mBAAmB;QACnB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;QAChD,SAAS,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,YAAY,CAAC,mBAAmB,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,aAAa,EAAE,CAAC;QACzC,SAAS,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC;QAED,4BAA4B;QAC5B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAChB,YAAY,CAAC,oCAAoC,CAAC,CAAC;YACvD,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;YAC5C,SAAS,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAChB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/D,CAAC;QACL,CAAC;QAED,gBAAgB;QAChB,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,MAAM,GAAiB;YACzB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,GAAG;YACH,MAAM,EAAE,SAAS;YACjB,OAAO;YACP,QAAQ,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACvC,CAAC;QAEF,SAAS;QACT,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACJ,YAAY,CAAC,OAAO,CAAC,CAAC;YAEtB,uBAAuB;YACvB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,CAAC,KAAK,CAAC,SAAS,OAAO,CAAC,MAAM,2CAA2C,CAAC,CAAC;YACrF,CAAC;iBAAM,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;gBAC9B,MAAM,CAAC,OAAO,CAAC,SAAS,OAAO,CAAC,QAAQ,wBAAwB,CAAC,CAAC;YACtE,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,OAAO,CAAC,kDAAkD,CAAC,CAAC;YACvE,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;QAED,6BAA6B;QAC7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IAEL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACnD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBACvB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC7D,QAAQ,EAAE,CAAC;aACd,CAAC,CAAC,CAAC;QACR,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function organizeCommand(folderPath: string | undefined, options: Record<string, unknown>, _command?: Command): Promise<void>;
@@ -0,0 +1,126 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import chalk from 'chalk';
4
+ import inquirer from 'inquirer';
5
+ import { logger } from '../utils/logger.js';
6
+ import { organizeFilesByType, organizeFilesByDate, detectDuplicates } from '../utils/file-organizer.js';
7
+ export async function organizeCommand(folderPath, options, _command) {
8
+ try {
9
+ let targetPath = folderPath || '';
10
+ // If no folder path provided, use interactive prompt
11
+ if (!targetPath) {
12
+ const answers = await inquirer.prompt([
13
+ {
14
+ type: 'input',
15
+ name: 'path',
16
+ message: 'Enter the folder path to organize:',
17
+ default: process.cwd(),
18
+ validate: (input) => {
19
+ if (!input.trim())
20
+ return 'Path cannot be empty';
21
+ return true;
22
+ },
23
+ },
24
+ ]);
25
+ targetPath = answers.path;
26
+ }
27
+ // Resolve to absolute path
28
+ const absolutePath = path.resolve(targetPath);
29
+ // Validate folder exists
30
+ if (!(await fs.pathExists(absolutePath))) {
31
+ logger.error(`Folder does not exist: ${absolutePath}`);
32
+ process.exit(1);
33
+ }
34
+ const stats = await fs.stat(absolutePath);
35
+ if (!stats.isDirectory()) {
36
+ logger.error(`Path is not a directory: ${absolutePath}`);
37
+ process.exit(1);
38
+ }
39
+ // Get organization strategy
40
+ let strategy = options.strategy || '';
41
+ if (!['type', 'date'].includes(strategy)) {
42
+ const answers = await inquirer.prompt([
43
+ {
44
+ type: 'list',
45
+ name: 'strategy',
46
+ message: 'How would you like to organize files?',
47
+ choices: [
48
+ { name: 'By File Type (images, documents, etc.)', value: 'type' },
49
+ { name: 'By Date (YYYY-MM)', value: 'date' },
50
+ ],
51
+ },
52
+ ]);
53
+ strategy = answers.strategy;
54
+ }
55
+ // Check if user wants to handle duplicates
56
+ let handleDuplicates = !!options.duplicates;
57
+ if (!options.duplicates) {
58
+ const answers = await inquirer.prompt([
59
+ {
60
+ type: 'confirm',
61
+ name: 'duplicates',
62
+ message: 'Move duplicate files to a "Duplicates" folder?',
63
+ default: false,
64
+ },
65
+ ]);
66
+ handleDuplicates = answers.duplicates;
67
+ }
68
+ console.log('');
69
+ logger.title('📁 Organizing files...');
70
+ // Detect duplicates if needed
71
+ let duplicates = new Map();
72
+ if (handleDuplicates) {
73
+ logger.info('Detecting duplicate files...');
74
+ duplicates = await detectDuplicates(absolutePath);
75
+ if (duplicates.size === 0) {
76
+ console.log(chalk.gray('No duplicates found.'));
77
+ }
78
+ else {
79
+ console.log(chalk.gray(`Found ${duplicates.size} set(s) of duplicate files.`));
80
+ }
81
+ }
82
+ // Organize files
83
+ let result;
84
+ if (strategy === 'type') {
85
+ result = await organizeFilesByType(absolutePath, duplicates);
86
+ }
87
+ else {
88
+ result = await organizeFilesByDate(absolutePath, duplicates);
89
+ }
90
+ // Display results
91
+ console.log('');
92
+ logger.success('Organization complete!');
93
+ console.log('');
94
+ console.log(chalk.bold('Summary:'));
95
+ console.log(chalk.gray('─'.repeat(50)));
96
+ let totalFilesMoved = 0;
97
+ const categorizedEntries = Object.entries(result.categorized);
98
+ if (categorizedEntries.length === 0) {
99
+ console.log(chalk.gray('No files to organize.'));
100
+ }
101
+ else {
102
+ for (const [folder, count] of categorizedEntries) {
103
+ console.log(`${chalk.cyan('→')} ${folder}: ${chalk.bold(count)} files`);
104
+ totalFilesMoved += count;
105
+ }
106
+ }
107
+ if (result.duplicates > 0) {
108
+ console.log(`${chalk.cyan('→')} Duplicates: ${chalk.bold(result.duplicates)} files`);
109
+ totalFilesMoved += result.duplicates;
110
+ }
111
+ console.log(chalk.gray('─'.repeat(50)));
112
+ console.log(`${chalk.bold('Total files moved:')} ${chalk.green(totalFilesMoved)}`);
113
+ console.log('');
114
+ }
115
+ catch (error) {
116
+ logger.error('Failed to organize files');
117
+ if (error instanceof Error) {
118
+ console.error(chalk.red(error.message));
119
+ }
120
+ else {
121
+ console.error(error);
122
+ }
123
+ process.exit(1);
124
+ }
125
+ }
126
+ //# sourceMappingURL=organize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organize.js","sourceRoot":"","sources":["../../src/commands/organize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Command } from 'commander';
2
+ export interface Task {
3
+ name: string;
4
+ command: string;
5
+ cwd?: string;
6
+ }
7
+ export interface TasksConfig {
8
+ tasks: Task[];
9
+ parallel?: boolean;
10
+ stopOnError?: boolean;
11
+ }
12
+ export declare function runTasksCommand(configPath: string | undefined, options: Record<string, unknown>, _command?: Command): Promise<void>;
@@ -0,0 +1,125 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import chalk from 'chalk';
4
+ import inquirer from 'inquirer';
5
+ import { logger } from '../utils/logger.js';
6
+ import { executeTasksSequentially, executeTasksInParallel } from '../utils/task-runner.js';
7
+ export async function runTasksCommand(configPath, options, _command) {
8
+ try {
9
+ let tasksFilePath = configPath || '';
10
+ // If no config path provided, use interactive prompt
11
+ if (!tasksFilePath) {
12
+ const answers = await inquirer.prompt([
13
+ {
14
+ type: 'input',
15
+ name: 'path',
16
+ message: 'Enter the path to tasks.json config file:',
17
+ default: './tasks.json',
18
+ validate: (input) => {
19
+ if (!input.trim())
20
+ return 'Path cannot be empty';
21
+ return true;
22
+ },
23
+ },
24
+ ]);
25
+ tasksFilePath = answers.path;
26
+ }
27
+ // Resolve to absolute path
28
+ const absolutePath = path.resolve(tasksFilePath);
29
+ // Validate file exists
30
+ if (!(await fs.pathExists(absolutePath))) {
31
+ logger.error(`Config file not found: ${absolutePath}`);
32
+ process.exit(1);
33
+ }
34
+ // Validate it's a file
35
+ const stats = await fs.stat(absolutePath);
36
+ if (!stats.isFile()) {
37
+ logger.error(`Path is not a file: ${absolutePath}`);
38
+ process.exit(1);
39
+ }
40
+ // Parse config file
41
+ let config;
42
+ try {
43
+ const fileContent = await fs.readFile(absolutePath, 'utf-8');
44
+ config = JSON.parse(fileContent);
45
+ }
46
+ catch (error) {
47
+ logger.error(`Failed to parse config file: ${absolutePath}`);
48
+ if (error instanceof SyntaxError) {
49
+ console.error(chalk.red(`JSON Error: ${error.message}`));
50
+ }
51
+ process.exit(1);
52
+ }
53
+ // Validate config
54
+ if (!config.tasks || !Array.isArray(config.tasks) || config.tasks.length === 0) {
55
+ logger.error('Config file must contain a "tasks" array with at least one task');
56
+ process.exit(1);
57
+ }
58
+ // Validate each task
59
+ for (const task of config.tasks) {
60
+ if (!task.name || !task.command) {
61
+ logger.error('Each task must have a "name" and "command" field');
62
+ process.exit(1);
63
+ }
64
+ if (task.cwd && !(await fs.pathExists(task.cwd))) {
65
+ logger.warning(`Working directory does not exist for task "${task.name}": ${task.cwd}`);
66
+ }
67
+ }
68
+ // Determine execution mode (CLI options override config file)
69
+ const parallel = options.parallel === true || (config.parallel === true && options.parallel !== false);
70
+ const stopOnError = options.stopOnError !== false && (config.stopOnError !== false || options.stopOnError === true);
71
+ console.log('');
72
+ logger.title('🚀 Running Tasks');
73
+ console.log(chalk.gray(`Total tasks: ${config.tasks.length}`));
74
+ console.log(chalk.gray(`Mode: ${parallel ? 'Parallel' : 'Sequential'}`));
75
+ console.log(chalk.gray(`Stop on error: ${stopOnError ? 'Yes' : 'No'}`));
76
+ console.log('');
77
+ // Execute tasks
78
+ let results;
79
+ if (parallel) {
80
+ results = await executeTasksInParallel(config.tasks, stopOnError);
81
+ }
82
+ else {
83
+ results = await executeTasksSequentially(config.tasks, stopOnError);
84
+ }
85
+ // Display results
86
+ console.log('');
87
+ logger.title('📊 Task Results');
88
+ console.log(chalk.gray('─'.repeat(60)));
89
+ let successCount = 0;
90
+ let failureCount = 0;
91
+ for (const result of results) {
92
+ const statusIcon = result.success ? chalk.green('✔') : chalk.red('✖');
93
+ const statusText = result.success ? chalk.green('SUCCESS') : chalk.red('FAILED');
94
+ console.log(`${statusIcon} ${chalk.bold(result.name)}: ${statusText}`);
95
+ if (!result.success) {
96
+ failureCount++;
97
+ if (result.error) {
98
+ console.log(chalk.red(` Error: ${result.error}`));
99
+ }
100
+ }
101
+ else {
102
+ successCount++;
103
+ }
104
+ }
105
+ console.log(chalk.gray('─'.repeat(60)));
106
+ console.log('');
107
+ console.log(chalk.bold(`Results: ${chalk.green(`${successCount} succeeded`)} / ${chalk.red(`${failureCount} failed`)}`));
108
+ console.log('');
109
+ // Exit with appropriate code
110
+ if (failureCount > 0 && stopOnError) {
111
+ process.exit(1);
112
+ }
113
+ }
114
+ catch (error) {
115
+ logger.error('Failed to run tasks');
116
+ if (error instanceof Error) {
117
+ console.error(chalk.red(error.message));
118
+ }
119
+ else {
120
+ console.error(error);
121
+ }
122
+ process.exit(1);
123
+ }
124
+ }
125
+ //# sourceMappingURL=run-tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-tasks.js","sourceRoot":"","sources":["../../src/commands/run-tasks.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,6 +2,9 @@
2
2
  import { createRequire } from 'module';
3
3
  import { Command } from 'commander';
4
4
  import { createCommand } from './commands/create.js';
5
+ import { organizeCommand } from './commands/organize.js';
6
+ import { runTasksCommand } from './commands/run-tasks.js';
7
+ import { doctorCommand } from './commands/doctor.js';
5
8
  const pkgRequire = createRequire(import.meta.url);
6
9
  const { version: CLI_VERSION } = pkgRequire('../package.json');
7
10
  const program = new Command();
@@ -25,5 +28,32 @@ program
25
28
  .option('--multi-tenant', 'Enable multi-tenancy')
26
29
  .option('--skip-install', 'Skip dependency installation')
27
30
  .option('--skip-git', 'Skip Git initialization');
31
+ program
32
+ .command('organize [folder-path]')
33
+ .description('Organize files by type or date')
34
+ .action(organizeCommand)
35
+ .option('--strategy <type>', 'Organization strategy: type or date')
36
+ .option('--duplicates', 'Move duplicate files to a Duplicates folder');
37
+ program
38
+ .command('run-tasks [config-path]')
39
+ .description('Run batch tasks from a JSON config file')
40
+ .action(runTasksCommand)
41
+ .option('--parallel', 'Run tasks in parallel instead of sequentially')
42
+ .option('--stop-on-error', 'Stop execution if any task fails');
43
+ program
44
+ .command('doctor')
45
+ .description('Validate project environment and dev setup')
46
+ .action(async (options) => {
47
+ await doctorCommand({
48
+ lint: options.lint,
49
+ json: options.json,
50
+ fix: options.fix,
51
+ cwd: options.cwd,
52
+ });
53
+ })
54
+ .option('--lint', 'Run ESLint and TypeScript checks')
55
+ .option('--json', 'Output results as JSON for CI pipelines')
56
+ .option('--fix', 'Auto-generate missing .env report')
57
+ .option('--cwd <path>', 'Custom project directory to check');
28
58
  program.parse();
29
59
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAwB,CAAC;AAEtF,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,WAAW,CAAC,CAAC;AAE1B,OAAO;KACF,OAAO,CAAC,uBAAuB,CAAC;KAChC,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,aAAa,CAAC;KACrB,MAAM,CAAC,wBAAwB,EAAE,oBAAoB,CAAC;KACtD,MAAM,CAAC,uBAAuB,EAAE,mBAAmB,CAAC;KACpD,MAAM,CAAC,mBAAmB,EAAE,eAAe,CAAC;KAC5C,MAAM,CAAC,iBAAiB,EAAE,UAAU,CAAC;KACrC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC;KACpC,MAAM,CAAC,iBAAiB,EAAE,+BAA+B,CAAC;KAC1D,MAAM,CAAC,gBAAgB,EAAE,mCAAmC,CAAC;KAC7D,MAAM,CAAC,UAAU,EAAE,8BAA8B,CAAC;KAClD,MAAM,CAAC,aAAa,EAAE,2BAA2B,CAAC;KAClD,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;KAChD,MAAM,CAAC,gBAAgB,EAAE,8BAA8B,CAAC;KACxD,MAAM,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;AAErD,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAwB,CAAC;AAEtF,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,WAAW,CAAC,CAAC;AAE1B,OAAO;KACF,OAAO,CAAC,uBAAuB,CAAC;KAChC,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,aAAa,CAAC;KACrB,MAAM,CAAC,wBAAwB,EAAE,oBAAoB,CAAC;KACtD,MAAM,CAAC,uBAAuB,EAAE,mBAAmB,CAAC;KACpD,MAAM,CAAC,mBAAmB,EAAE,eAAe,CAAC;KAC5C,MAAM,CAAC,iBAAiB,EAAE,UAAU,CAAC;KACrC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC;KACpC,MAAM,CAAC,iBAAiB,EAAE,+BAA+B,CAAC;KAC1D,MAAM,CAAC,gBAAgB,EAAE,mCAAmC,CAAC;KAC7D,MAAM,CAAC,UAAU,EAAE,8BAA8B,CAAC;KAClD,MAAM,CAAC,aAAa,EAAE,2BAA2B,CAAC;KAClD,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;KAChD,MAAM,CAAC,gBAAgB,EAAE,8BAA8B,CAAC;KACxD,MAAM,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;AAErD,OAAO;KACF,OAAO,CAAC,wBAAwB,CAAC;KACjC,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,eAAe,CAAC;KACvB,MAAM,CAAC,mBAAmB,EAAE,qCAAqC,CAAC;KAClE,MAAM,CAAC,cAAc,EAAE,6CAA6C,CAAC,CAAC;AAE3E,OAAO;KACF,OAAO,CAAC,yBAAyB,CAAC;KAClC,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,eAAe,CAAC;KACvB,MAAM,CAAC,YAAY,EAAE,+CAA+C,CAAC;KACrE,MAAM,CAAC,iBAAiB,EAAE,kCAAkC,CAAC,CAAC;AAEnE,OAAO;KACF,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,KAAK,EAAE,OAAgC,EAAE,EAAE;IAC/C,MAAM,aAAa,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC,IAA2B;QACzC,IAAI,EAAE,OAAO,CAAC,IAA2B;QACzC,GAAG,EAAE,OAAO,CAAC,GAA0B;QACvC,GAAG,EAAE,OAAO,CAAC,GAAyB;KACzC,CAAC,CAAC;AACP,CAAC,CAAC;KACD,MAAM,CAAC,QAAQ,EAAE,kCAAkC,CAAC;KACpD,MAAM,CAAC,QAAQ,EAAE,yCAAyC,CAAC;KAC3D,MAAM,CAAC,OAAO,EAAE,mCAAmC,CAAC;KACpD,MAAM,CAAC,cAAc,EAAE,mCAAmC,CAAC,CAAC;AAEjE,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Database connectivity checks
3
+ */
4
+ import type { CheckResult } from './types.js';
5
+ /**
6
+ * Run database connectivity check
7
+ */
8
+ export declare function checkDatabaseConnection(cwd: string): Promise<CheckResult[]>;