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,271 @@
1
+ /**
2
+ * Database connectivity checks
3
+ */
4
+ import { execSync } from 'child_process';
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+ /**
8
+ * Parse a database connection string to determine type
9
+ */
10
+ function parseDatabaseUrl(url) {
11
+ if (!url)
12
+ return null;
13
+ if (url.startsWith('postgres://') || url.startsWith('postgresql://')) {
14
+ return { type: 'postgresql', connectionString: url };
15
+ }
16
+ if (url.startsWith('mongodb://') || url.startsWith('mongodb+srv://')) {
17
+ return { type: 'mongodb', connectionString: url };
18
+ }
19
+ if (url.startsWith('mysql://')) {
20
+ return { type: 'mysql', connectionString: url };
21
+ }
22
+ if (url.includes('.sqlite') || url.includes('.db') || url.startsWith('file:')) {
23
+ return { type: 'sqlite', connectionString: url };
24
+ }
25
+ return null;
26
+ }
27
+ /**
28
+ * Read DATABASE_URL from .env file
29
+ */
30
+ async function getDatabaseUrl(cwd) {
31
+ const envPath = path.join(cwd, '.env');
32
+ if (!await fs.pathExists(envPath)) {
33
+ return null;
34
+ }
35
+ const content = await fs.readFile(envPath, 'utf-8');
36
+ const lines = content.split('\n');
37
+ for (const line of lines) {
38
+ const match = line.match(/^DATABASE_URL\s*=\s*["']?([^"'\s]+)["']?/);
39
+ if (match) {
40
+ return match[1];
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * Check PostgreSQL connectivity
47
+ */
48
+ async function checkPostgresConnection(connectionString) {
49
+ try {
50
+ // Try using psql to check connection
51
+ execSync(`psql "${connectionString}" -c "SELECT 1" 2>&1`, {
52
+ encoding: 'utf-8',
53
+ stdio: ['pipe', 'pipe', 'pipe'],
54
+ timeout: 10000,
55
+ });
56
+ return {
57
+ name: 'PostgreSQL Connection',
58
+ status: 'pass',
59
+ message: 'Successfully connected to PostgreSQL',
60
+ };
61
+ }
62
+ catch (error) {
63
+ // Check if psql is installed
64
+ try {
65
+ execSync('psql --version', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
66
+ }
67
+ catch {
68
+ return {
69
+ name: 'PostgreSQL Connection',
70
+ status: 'warn',
71
+ message: 'Cannot verify connection (psql not installed)',
72
+ details: 'Install PostgreSQL client tools to enable connection verification',
73
+ fix: 'The connection will be verified when the app starts',
74
+ };
75
+ }
76
+ const errorMessage = error instanceof Error ? error.message : String(error);
77
+ if (errorMessage.includes('connection refused') || errorMessage.includes('ECONNREFUSED')) {
78
+ return {
79
+ name: 'PostgreSQL Connection',
80
+ status: 'fail',
81
+ message: 'PostgreSQL server is not running or unreachable',
82
+ fix: 'Start your PostgreSQL server or check the connection string',
83
+ };
84
+ }
85
+ if (errorMessage.includes('authentication failed') || errorMessage.includes('password')) {
86
+ return {
87
+ name: 'PostgreSQL Connection',
88
+ status: 'fail',
89
+ message: 'PostgreSQL authentication failed',
90
+ fix: 'Check your DATABASE_URL credentials in .env',
91
+ };
92
+ }
93
+ if (errorMessage.includes('does not exist')) {
94
+ return {
95
+ name: 'PostgreSQL Connection',
96
+ status: 'fail',
97
+ message: 'Database does not exist',
98
+ fix: 'Create the database or run migrations: npx prisma migrate dev',
99
+ };
100
+ }
101
+ return {
102
+ name: 'PostgreSQL Connection',
103
+ status: 'fail',
104
+ message: 'Failed to connect to PostgreSQL',
105
+ details: errorMessage.substring(0, 200),
106
+ fix: 'Check your DATABASE_URL in .env',
107
+ };
108
+ }
109
+ }
110
+ /**
111
+ * Check MongoDB connectivity
112
+ */
113
+ async function checkMongoConnection(connectionString) {
114
+ try {
115
+ // Try using mongosh or mongo to check connection
116
+ const mongoCmd = execSync('which mongosh 2>/dev/null || which mongo 2>/dev/null || echo mongosh', {
117
+ encoding: 'utf-8',
118
+ stdio: ['pipe', 'pipe', 'pipe'],
119
+ }).trim();
120
+ execSync(`${mongoCmd} "${connectionString}" --eval "db.runCommand({ping:1})" --quiet 2>&1`, {
121
+ encoding: 'utf-8',
122
+ stdio: ['pipe', 'pipe', 'pipe'],
123
+ timeout: 10000,
124
+ });
125
+ return {
126
+ name: 'MongoDB Connection',
127
+ status: 'pass',
128
+ message: 'Successfully connected to MongoDB',
129
+ };
130
+ }
131
+ catch (error) {
132
+ const errorMessage = error instanceof Error ? error.message : String(error);
133
+ // Check if mongo shell is not installed
134
+ if (errorMessage.includes('not found') || errorMessage.includes('not recognized')) {
135
+ return {
136
+ name: 'MongoDB Connection',
137
+ status: 'warn',
138
+ message: 'Cannot verify connection (mongosh not installed)',
139
+ details: 'Install MongoDB Shell to enable connection verification',
140
+ fix: 'The connection will be verified when the app starts',
141
+ };
142
+ }
143
+ return {
144
+ name: 'MongoDB Connection',
145
+ status: 'fail',
146
+ message: 'Failed to connect to MongoDB',
147
+ details: errorMessage.substring(0, 200),
148
+ fix: 'Check your DATABASE_URL in .env and ensure MongoDB is running',
149
+ };
150
+ }
151
+ }
152
+ /**
153
+ * Check MySQL connectivity
154
+ */
155
+ async function checkMysqlConnection(connectionString) {
156
+ try {
157
+ // Parse connection string
158
+ const url = new URL(connectionString);
159
+ const host = url.hostname;
160
+ const port = url.port || '3306';
161
+ const user = url.username;
162
+ const password = url.password;
163
+ const database = url.pathname.slice(1);
164
+ execSync(`mysql -h ${host} -P ${port} -u ${user} -p${password} ${database} -e "SELECT 1" 2>&1`, {
165
+ encoding: 'utf-8',
166
+ stdio: ['pipe', 'pipe', 'pipe'],
167
+ timeout: 10000,
168
+ });
169
+ return {
170
+ name: 'MySQL Connection',
171
+ status: 'pass',
172
+ message: 'Successfully connected to MySQL',
173
+ };
174
+ }
175
+ catch (error) {
176
+ const errorMessage = error instanceof Error ? error.message : String(error);
177
+ if (errorMessage.includes('not found') || errorMessage.includes('not recognized')) {
178
+ return {
179
+ name: 'MySQL Connection',
180
+ status: 'warn',
181
+ message: 'Cannot verify connection (mysql client not installed)',
182
+ fix: 'The connection will be verified when the app starts',
183
+ };
184
+ }
185
+ return {
186
+ name: 'MySQL Connection',
187
+ status: 'fail',
188
+ message: 'Failed to connect to MySQL',
189
+ details: errorMessage.substring(0, 200),
190
+ fix: 'Check your DATABASE_URL in .env and ensure MySQL is running',
191
+ };
192
+ }
193
+ }
194
+ /**
195
+ * Check SQLite file exists
196
+ */
197
+ async function checkSqliteConnection(connectionString) {
198
+ // Extract file path from connection string
199
+ let dbPath = connectionString.replace(/^file:/, '').replace(/\?.*$/, '');
200
+ // Handle relative paths
201
+ if (!path.isAbsolute(dbPath)) {
202
+ dbPath = path.join(process.cwd(), dbPath);
203
+ }
204
+ if (await fs.pathExists(dbPath)) {
205
+ return {
206
+ name: 'SQLite Database',
207
+ status: 'pass',
208
+ message: 'SQLite database file exists',
209
+ details: dbPath,
210
+ };
211
+ }
212
+ // Check if parent directory exists (database will be created on first run)
213
+ const dbDir = path.dirname(dbPath);
214
+ if (await fs.pathExists(dbDir)) {
215
+ return {
216
+ name: 'SQLite Database',
217
+ status: 'warn',
218
+ message: 'SQLite database file does not exist yet',
219
+ details: 'The file will be created when you run migrations',
220
+ fix: 'Run: npx prisma migrate dev',
221
+ };
222
+ }
223
+ return {
224
+ name: 'SQLite Database',
225
+ status: 'fail',
226
+ message: 'SQLite database directory does not exist',
227
+ fix: 'Create the directory or check the DATABASE_URL path',
228
+ };
229
+ }
230
+ /**
231
+ * Run database connectivity check
232
+ */
233
+ export async function checkDatabaseConnection(cwd) {
234
+ const results = [];
235
+ const databaseUrl = await getDatabaseUrl(cwd);
236
+ if (!databaseUrl) {
237
+ results.push({
238
+ name: 'Database Connection',
239
+ status: 'skip',
240
+ message: 'No DATABASE_URL configured',
241
+ details: 'Set DATABASE_URL in .env to enable database checks',
242
+ });
243
+ return results;
244
+ }
245
+ const dbConfig = parseDatabaseUrl(databaseUrl);
246
+ if (!dbConfig) {
247
+ results.push({
248
+ name: 'Database Connection',
249
+ status: 'warn',
250
+ message: 'Unknown database type in DATABASE_URL',
251
+ details: 'Supported: postgresql, mongodb, mysql, sqlite',
252
+ });
253
+ return results;
254
+ }
255
+ switch (dbConfig.type) {
256
+ case 'postgresql':
257
+ results.push(await checkPostgresConnection(databaseUrl));
258
+ break;
259
+ case 'mongodb':
260
+ results.push(await checkMongoConnection(databaseUrl));
261
+ break;
262
+ case 'mysql':
263
+ results.push(await checkMysqlConnection(databaseUrl));
264
+ break;
265
+ case 'sqlite':
266
+ results.push(await checkSqliteConnection(databaseUrl));
267
+ break;
268
+ }
269
+ return results;
270
+ }
271
+ //# sourceMappingURL=check-database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-database.js","sourceRoot":"","sources":["../../../src/utils/doctor/check-database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Docker installation and status checks
3
+ */
4
+ import type { CheckResult } from './types.js';
5
+ /**
6
+ * Run all Docker checks
7
+ */
8
+ export declare function runDockerChecks(cwd: string): Promise<CheckResult[]>;
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Docker installation and status checks
3
+ */
4
+ import { execSync } from 'child_process';
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+ /**
8
+ * Check if Docker files exist in the project
9
+ */
10
+ async function hasDockerConfig(cwd) {
11
+ const dockerFiles = [
12
+ 'Dockerfile',
13
+ 'docker-compose.yml',
14
+ 'docker-compose.yaml',
15
+ 'compose.yml',
16
+ 'compose.yaml',
17
+ ];
18
+ for (const file of dockerFiles) {
19
+ if (await fs.pathExists(path.join(cwd, file))) {
20
+ return true;
21
+ }
22
+ }
23
+ return false;
24
+ }
25
+ /**
26
+ * Check if Docker is installed
27
+ */
28
+ async function checkDockerInstalled() {
29
+ try {
30
+ const version = execSync('docker --version', {
31
+ encoding: 'utf-8',
32
+ stdio: ['pipe', 'pipe', 'pipe'],
33
+ }).trim();
34
+ // Extract version number
35
+ const match = version.match(/Docker version (\d+\.\d+\.\d+)/);
36
+ const versionNum = match ? match[1] : 'unknown';
37
+ return {
38
+ name: 'Docker',
39
+ status: 'pass',
40
+ message: `Docker installed: ${versionNum}`,
41
+ };
42
+ }
43
+ catch {
44
+ return {
45
+ name: 'Docker',
46
+ status: 'fail',
47
+ message: 'Docker is not installed',
48
+ fix: 'Install Docker from https://www.docker.com/get-started',
49
+ };
50
+ }
51
+ }
52
+ /**
53
+ * Check if Docker daemon is running
54
+ */
55
+ async function checkDockerRunning() {
56
+ try {
57
+ execSync('docker info', {
58
+ encoding: 'utf-8',
59
+ stdio: ['pipe', 'pipe', 'pipe'],
60
+ timeout: 10000,
61
+ });
62
+ return {
63
+ name: 'Docker Daemon',
64
+ status: 'pass',
65
+ message: 'Docker daemon is running',
66
+ };
67
+ }
68
+ catch (error) {
69
+ const errorMessage = error instanceof Error ? error.message : String(error);
70
+ if (errorMessage.includes('Cannot connect') || errorMessage.includes('permission denied')) {
71
+ return {
72
+ name: 'Docker Daemon',
73
+ status: 'fail',
74
+ message: 'Docker daemon is not running',
75
+ fix: 'Start Docker Desktop or run: sudo systemctl start docker',
76
+ };
77
+ }
78
+ return {
79
+ name: 'Docker Daemon',
80
+ status: 'fail',
81
+ message: 'Cannot connect to Docker daemon',
82
+ details: errorMessage.substring(0, 100),
83
+ fix: 'Ensure Docker is installed and running',
84
+ };
85
+ }
86
+ }
87
+ /**
88
+ * Check if Docker Compose is available
89
+ */
90
+ async function checkDockerCompose() {
91
+ // Try docker compose (V2)
92
+ try {
93
+ const version = execSync('docker compose version', {
94
+ encoding: 'utf-8',
95
+ stdio: ['pipe', 'pipe', 'pipe'],
96
+ }).trim();
97
+ const match = version.match(/v?(\d+\.\d+\.\d+)/);
98
+ const versionNum = match ? match[1] : 'unknown';
99
+ return {
100
+ name: 'Docker Compose',
101
+ status: 'pass',
102
+ message: `Docker Compose V2: ${versionNum}`,
103
+ };
104
+ }
105
+ catch {
106
+ // Try docker-compose (V1)
107
+ try {
108
+ const version = execSync('docker-compose --version', {
109
+ encoding: 'utf-8',
110
+ stdio: ['pipe', 'pipe', 'pipe'],
111
+ }).trim();
112
+ const match = version.match(/(\d+\.\d+\.\d+)/);
113
+ const versionNum = match ? match[1] : 'unknown';
114
+ return {
115
+ name: 'Docker Compose',
116
+ status: 'warn',
117
+ message: `Docker Compose V1: ${versionNum}`,
118
+ details: 'Consider upgrading to Docker Compose V2',
119
+ };
120
+ }
121
+ catch {
122
+ return {
123
+ name: 'Docker Compose',
124
+ status: 'fail',
125
+ message: 'Docker Compose is not installed',
126
+ fix: 'Install Docker Compose or update Docker Desktop',
127
+ };
128
+ }
129
+ }
130
+ }
131
+ /**
132
+ * Check if docker-compose.yml is valid
133
+ */
134
+ async function checkDockerComposeConfig(cwd) {
135
+ const composeFiles = [
136
+ 'docker-compose.yml',
137
+ 'docker-compose.yaml',
138
+ 'compose.yml',
139
+ 'compose.yaml',
140
+ ];
141
+ let composeFile = null;
142
+ for (const file of composeFiles) {
143
+ if (await fs.pathExists(path.join(cwd, file))) {
144
+ composeFile = file;
145
+ break;
146
+ }
147
+ }
148
+ if (!composeFile) {
149
+ return {
150
+ name: 'Docker Compose Config',
151
+ status: 'skip',
152
+ message: 'No docker-compose file found',
153
+ };
154
+ }
155
+ try {
156
+ execSync('docker compose config --quiet', {
157
+ cwd,
158
+ encoding: 'utf-8',
159
+ stdio: ['pipe', 'pipe', 'pipe'],
160
+ timeout: 10000,
161
+ });
162
+ return {
163
+ name: 'Docker Compose Config',
164
+ status: 'pass',
165
+ message: `${composeFile} is valid`,
166
+ };
167
+ }
168
+ catch (error) {
169
+ const errorMessage = error instanceof Error ? error.message : String(error);
170
+ return {
171
+ name: 'Docker Compose Config',
172
+ status: 'fail',
173
+ message: `Invalid ${composeFile}`,
174
+ details: errorMessage.substring(0, 200),
175
+ fix: 'Fix the syntax errors in your docker-compose file',
176
+ };
177
+ }
178
+ }
179
+ /**
180
+ * Run all Docker checks
181
+ */
182
+ export async function runDockerChecks(cwd) {
183
+ const results = [];
184
+ // Check if project uses Docker
185
+ const usesDocker = await hasDockerConfig(cwd);
186
+ if (!usesDocker) {
187
+ results.push({
188
+ name: 'Docker',
189
+ status: 'skip',
190
+ message: 'No Docker configuration found in project',
191
+ });
192
+ return results;
193
+ }
194
+ // Check Docker installation
195
+ const dockerInstalled = await checkDockerInstalled();
196
+ results.push(dockerInstalled);
197
+ if (dockerInstalled.status === 'fail') {
198
+ return results;
199
+ }
200
+ // Check Docker daemon
201
+ const dockerRunning = await checkDockerRunning();
202
+ results.push(dockerRunning);
203
+ if (dockerRunning.status === 'fail') {
204
+ return results;
205
+ }
206
+ // Check Docker Compose
207
+ results.push(await checkDockerCompose());
208
+ // Check compose config validity
209
+ results.push(await checkDockerComposeConfig(cwd));
210
+ return results;
211
+ }
212
+ //# sourceMappingURL=check-docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-docker.js","sourceRoot":"","sources":["../../../src/utils/doctor/check-docker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Environment variable validation checks
3
+ */
4
+ import type { CheckResult } from './types.js';
5
+ /**
6
+ * Check environment variables against .env.example
7
+ */
8
+ export declare function checkEnvVariables(cwd: string): Promise<CheckResult[]>;
9
+ /**
10
+ * Generate a .env.missing report file
11
+ */
12
+ export declare function generateMissingEnvReport(cwd: string): Promise<string | null>;