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,170 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import crypto from 'crypto';
4
+ // File type categories
5
+ const FILE_CATEGORIES = {
6
+ Images: ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp', '.ico', '.tiff'],
7
+ Documents: ['.pdf', '.doc', '.docx', '.txt', '.xls', '.xlsx', '.ppt', '.pptx', '.odt'],
8
+ Archives: ['.zip', '.rar', '.7z', '.tar', '.gz', '.bz2', '.iso'],
9
+ Videos: ['.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm', '.m4v'],
10
+ Audio: ['.mp3', '.wav', '.flac', '.aac', '.ogg', '.wma', '.m4a'],
11
+ Code: ['.js', '.ts', '.py', '.java', '.cpp', '.c', '.go', '.rs', '.rb', '.php', '.html', '.css', '.json', '.xml', '.yaml', '.yml'],
12
+ Data: ['.csv', '.sql', '.db', '.sqlite', '.json', '.yaml'],
13
+ Executables: ['.exe', '.msi', '.app', '.bin', '.sh', '.bat'],
14
+ Others: [],
15
+ };
16
+ /**
17
+ * Calculate MD5 hash of a file
18
+ */
19
+ async function getFileHash(filePath) {
20
+ try {
21
+ const content = await fs.readFile(filePath);
22
+ return crypto.createHash('md5').update(content).digest('hex');
23
+ }
24
+ catch {
25
+ // Return empty string for unreadable files
26
+ return '';
27
+ }
28
+ }
29
+ /**
30
+ * Detect duplicate files by hash
31
+ */
32
+ export async function detectDuplicates(folderPath) {
33
+ const fileHashes = new Map();
34
+ const duplicates = new Map();
35
+ // System folders to skip
36
+ const skipFolders = new Set(['.git', '.env', 'node_modules', '.next', 'dist', 'build', '.DS_Store', '.vscode']);
37
+ async function scanDirectory(dir) {
38
+ try {
39
+ const files = await fs.readdir(dir);
40
+ for (const file of files) {
41
+ if (skipFolders.has(file) || file.startsWith('.')) {
42
+ continue;
43
+ }
44
+ const filePath = path.join(dir, file);
45
+ try {
46
+ const stats = await fs.stat(filePath);
47
+ if (stats.isDirectory()) {
48
+ await scanDirectory(filePath);
49
+ }
50
+ else if (stats.isFile() && stats.size > 0) {
51
+ try {
52
+ const hash = await getFileHash(filePath);
53
+ if (hash) {
54
+ if (!fileHashes.has(hash)) {
55
+ fileHashes.set(hash, []);
56
+ }
57
+ fileHashes.get(hash).push(filePath);
58
+ }
59
+ }
60
+ catch {
61
+ // Skip files that can't be hashed
62
+ }
63
+ }
64
+ }
65
+ catch {
66
+ // Skip files/folders that can't be accessed
67
+ }
68
+ }
69
+ }
70
+ catch {
71
+ // Skip directories that can't be read
72
+ }
73
+ }
74
+ await scanDirectory(folderPath);
75
+ // Identify actual duplicates
76
+ for (const [hash, files] of fileHashes) {
77
+ if (files.length > 1) {
78
+ duplicates.set(hash, files);
79
+ }
80
+ }
81
+ return duplicates;
82
+ }
83
+ /**
84
+ * Organize files by type into categorized folders
85
+ */
86
+ export async function organizeFilesByType(folderPath, duplicates = new Map()) {
87
+ const result = { categorized: {}, duplicates: 0 };
88
+ const duplicateSet = new Set();
89
+ // Build a set of duplicate files for quick lookup
90
+ for (const files of duplicates.values()) {
91
+ files.forEach(f => duplicateSet.add(f));
92
+ }
93
+ async function scanAndOrganize(dir) {
94
+ const files = await fs.readdir(dir);
95
+ for (const file of files) {
96
+ const filePath = path.join(dir, file);
97
+ const stats = await fs.stat(filePath);
98
+ if (stats.isDirectory()) {
99
+ // Skip special folders
100
+ if (file === 'Duplicates' || file.startsWith('.')) {
101
+ continue;
102
+ }
103
+ await scanAndOrganize(filePath);
104
+ }
105
+ else {
106
+ const ext = path.extname(file).toLowerCase();
107
+ // Find category
108
+ let category = 'Others';
109
+ for (const [cat, extensions] of Object.entries(FILE_CATEGORIES)) {
110
+ if (extensions.includes(ext)) {
111
+ category = cat;
112
+ break;
113
+ }
114
+ }
115
+ const destFolder = path.join(folderPath, duplicateSet.has(filePath) ? 'Duplicates' : category);
116
+ await fs.ensureDir(destFolder);
117
+ await fs.move(filePath, path.join(destFolder, file), { overwrite: true });
118
+ if (duplicateSet.has(filePath)) {
119
+ result.duplicates++;
120
+ }
121
+ else {
122
+ result.categorized[category] = (result.categorized[category] || 0) + 1;
123
+ }
124
+ }
125
+ }
126
+ }
127
+ await scanAndOrganize(folderPath);
128
+ return result;
129
+ }
130
+ /**
131
+ * Organize files by date (YYYY-MM format)
132
+ */
133
+ export async function organizeFilesByDate(folderPath, duplicates = new Map()) {
134
+ const result = { categorized: {}, duplicates: 0 };
135
+ const duplicateSet = new Set();
136
+ // Build a set of duplicate files
137
+ for (const files of duplicates.values()) {
138
+ files.forEach(f => duplicateSet.add(f));
139
+ }
140
+ async function scanAndOrganize(dir) {
141
+ const files = await fs.readdir(dir);
142
+ for (const file of files) {
143
+ const filePath = path.join(dir, file);
144
+ const stats = await fs.stat(filePath);
145
+ if (stats.isDirectory()) {
146
+ if (file.startsWith('.') || /^\d{4}-\d{2}$/.test(file)) {
147
+ continue;
148
+ }
149
+ await scanAndOrganize(filePath);
150
+ }
151
+ else {
152
+ // Get file modification date
153
+ const mtime = new Date(stats.mtime);
154
+ const dateFolder = mtime.toISOString().slice(0, 7); // YYYY-MM
155
+ const destFolder = path.join(folderPath, duplicateSet.has(filePath) ? 'Duplicates' : dateFolder);
156
+ await fs.ensureDir(destFolder);
157
+ await fs.move(filePath, path.join(destFolder, file), { overwrite: true });
158
+ if (duplicateSet.has(filePath)) {
159
+ result.duplicates++;
160
+ }
161
+ else {
162
+ result.categorized[dateFolder] = (result.categorized[dateFolder] || 0) + 1;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ await scanAndOrganize(folderPath);
168
+ return result;
169
+ }
170
+ //# sourceMappingURL=file-organizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-organizer.js","sourceRoot":"","sources":["../../src/utils/file-organizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Task } from '../commands/run-tasks.js';
2
+ export interface TaskResult {
3
+ name: string;
4
+ success: boolean;
5
+ error?: string;
6
+ }
7
+ /**
8
+ * Execute tasks sequentially (one after another)
9
+ */
10
+ export declare function executeTasksSequentially(tasks: Task[], stopOnError?: boolean): Promise<TaskResult[]>;
11
+ /**
12
+ * Execute tasks in parallel
13
+ */
14
+ export declare function executeTasksInParallel(tasks: Task[], stopOnError?: boolean): Promise<TaskResult[]>;
@@ -0,0 +1,79 @@
1
+ import { execSync } from 'child_process';
2
+ import chalk from 'chalk';
3
+ import os from 'os';
4
+ /**
5
+ * Execute a single task
6
+ */
7
+ async function executeTask(task) {
8
+ try {
9
+ console.log(`${chalk.cyan('→')} Running: ${chalk.bold(task.name)}`);
10
+ // Use shell: true for cross-platform command execution
11
+ const options = {
12
+ stdio: 'pipe',
13
+ encoding: 'utf-8',
14
+ shell: true,
15
+ };
16
+ if (task.cwd) {
17
+ options.cwd = task.cwd;
18
+ }
19
+ // Add shell option for cross-platform compatibility
20
+ if (os.platform() === 'win32') {
21
+ options.shell = 'cmd.exe';
22
+ }
23
+ try {
24
+ execSync(task.command, options);
25
+ }
26
+ catch (error) {
27
+ // execSync throws on non-zero exit code
28
+ // Extract stderr if available
29
+ if (error instanceof Error) {
30
+ throw error;
31
+ }
32
+ throw new Error(`Command failed: ${task.command}`);
33
+ }
34
+ console.log(`${chalk.green('✔')} ${task.name} completed`);
35
+ return { name: task.name, success: true };
36
+ }
37
+ catch (error) {
38
+ const errorMessage = error instanceof Error ? error.message.split('\n')[0] : String(error);
39
+ console.log(`${chalk.red('✖')} ${task.name} failed`);
40
+ return { name: task.name, success: false, error: errorMessage };
41
+ }
42
+ }
43
+ /**
44
+ * Execute tasks sequentially (one after another)
45
+ */
46
+ export async function executeTasksSequentially(tasks, stopOnError = true) {
47
+ const results = [];
48
+ for (const task of tasks) {
49
+ console.log('');
50
+ const result = await executeTask(task);
51
+ results.push(result);
52
+ if (!result.success && stopOnError) {
53
+ console.log('');
54
+ console.log(chalk.yellow('⚠ Stopping execution due to task failure'));
55
+ break;
56
+ }
57
+ }
58
+ return results;
59
+ }
60
+ /**
61
+ * Execute tasks in parallel
62
+ */
63
+ export async function executeTasksInParallel(tasks, stopOnError = true) {
64
+ console.log('');
65
+ const promises = tasks.map(task => executeTask(task)
66
+ .catch(error => ({
67
+ name: task.name,
68
+ success: false,
69
+ error: error instanceof Error ? error.message : String(error),
70
+ })));
71
+ const results = await Promise.all(promises);
72
+ // If stopOnError is true and any task failed, we should note this
73
+ if (stopOnError && results.some(r => !r.success)) {
74
+ console.log('');
75
+ console.log(chalk.yellow('⚠ Some tasks failed during parallel execution'));
76
+ }
77
+ return results;
78
+ }
79
+ //# sourceMappingURL=task-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-runner.js","sourceRoot":"","sources":["../../src/utils/task-runner.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "forgestack-os-cli",
3
- "version": "0.3.4",
4
- "description": "ForgeStack OS CLI - Generate production-ready full-stack SaaS applications",
3
+ "version": "0.3.6",
4
+ "description": "ForgeStack OS CLI - Generate production-ready full-stack SaaS applications with file organization and batch task execution utilities",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -32,7 +32,13 @@
32
32
  "cli",
33
33
  "generator",
34
34
  "saas",
35
- "full-stack"
35
+ "full-stack",
36
+ "organize-files",
37
+ "file-organization",
38
+ "task-runner",
39
+ "batch-execution",
40
+ "duplicate-detection",
41
+ "workflow"
36
42
  ],
37
43
  "author": {
38
44
  "name": "Sumit Chauhan",
@@ -48,11 +54,12 @@
48
54
  },
49
55
  "homepage": "https://github.com/halloffame12/forgestack-os#readme",
50
56
  "engines": {
51
- "node": ">=20"
57
+ "node": ">=18"
52
58
  },
53
59
  "dependencies": {
54
60
  "chalk": "^4.1.2",
55
61
  "commander": "^13.0.0",
62
+ "crypto": "^1.0.1",
56
63
  "ejs": "^3.1.10",
57
64
  "execa": "^5.1.1",
58
65
  "fs-extra": "^11.2.0",