projax 0.1.29

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 (38) hide show
  1. package/LINKING.md +86 -0
  2. package/README.md +141 -0
  3. package/dist/core/database.d.ts +66 -0
  4. package/dist/core/database.js +312 -0
  5. package/dist/core/detector.d.ts +9 -0
  6. package/dist/core/detector.js +149 -0
  7. package/dist/core/index.d.ts +11 -0
  8. package/dist/core/index.js +43 -0
  9. package/dist/core/scanner.d.ts +8 -0
  10. package/dist/core/scanner.js +114 -0
  11. package/dist/electron/main.d.ts +1 -0
  12. package/dist/electron/main.js +310 -0
  13. package/dist/electron/port-extractor.d.ts +9 -0
  14. package/dist/electron/port-extractor.js +351 -0
  15. package/dist/electron/port-scanner.d.ts +13 -0
  16. package/dist/electron/port-scanner.js +93 -0
  17. package/dist/electron/port-utils.d.ts +21 -0
  18. package/dist/electron/port-utils.js +200 -0
  19. package/dist/electron/preload.d.ts +49 -0
  20. package/dist/electron/preload.js +21 -0
  21. package/dist/electron/renderer/assets/index-BZ6USRnW.js +42 -0
  22. package/dist/electron/renderer/assets/index-DNtxfrZe.js +42 -0
  23. package/dist/electron/renderer/assets/index-khk3K-qG.css +1 -0
  24. package/dist/electron/renderer/index.html +15 -0
  25. package/dist/electron/script-runner.d.ts +40 -0
  26. package/dist/electron/script-runner.js +651 -0
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.js +971 -0
  29. package/dist/port-extractor.d.ts +9 -0
  30. package/dist/port-extractor.js +351 -0
  31. package/dist/port-scanner.d.ts +13 -0
  32. package/dist/port-scanner.js +93 -0
  33. package/dist/port-utils.d.ts +21 -0
  34. package/dist/port-utils.js +200 -0
  35. package/dist/script-runner.d.ts +40 -0
  36. package/dist/script-runner.js +651 -0
  37. package/package.json +40 -0
  38. package/rebuild-sqlite.js +82 -0
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FRAMEWORKS = void 0;
37
+ exports.detectTestFramework = detectTestFramework;
38
+ exports.isTestFile = isTestFile;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ exports.FRAMEWORKS = [
42
+ {
43
+ name: 'jest',
44
+ configFiles: ['jest.config.js', 'jest.config.ts', 'jest.config.json', 'jest.config.mjs', 'jest.config.cjs'],
45
+ testPatterns: [
46
+ /\.test\.(js|ts|jsx|tsx)$/i,
47
+ /\.spec\.(js|ts|jsx|tsx)$/i,
48
+ ],
49
+ testDirs: ['__tests__', '__test__'],
50
+ },
51
+ {
52
+ name: 'vitest',
53
+ configFiles: ['vitest.config.ts', 'vitest.config.js', 'vitest.config.mjs'],
54
+ testPatterns: [
55
+ /\.test\.(js|ts|jsx|tsx)$/i,
56
+ /\.spec\.(js|ts|jsx|tsx)$/i,
57
+ ],
58
+ testDirs: ['__tests__'],
59
+ },
60
+ {
61
+ name: 'mocha',
62
+ configFiles: ['.mocharc.js', '.mocharc.json', '.mocharc.yaml', '.mocharc.yml', 'mocha.opts'],
63
+ testPatterns: [
64
+ /\.test\.(js|ts|jsx|tsx)$/i,
65
+ /\.spec\.(js|ts|jsx|tsx)$/i,
66
+ ],
67
+ testDirs: ['test', 'tests'],
68
+ },
69
+ ];
70
+ function detectTestFramework(projectPath) {
71
+ const packageJsonPath = path.join(projectPath, 'package.json');
72
+ // Check package.json for test scripts and dependencies
73
+ if (fs.existsSync(packageJsonPath)) {
74
+ try {
75
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
76
+ // Check dependencies and devDependencies
77
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
78
+ if (deps.jest)
79
+ return 'jest';
80
+ if (deps.vitest)
81
+ return 'vitest';
82
+ if (deps.mocha)
83
+ return 'mocha';
84
+ // Check for jest config in package.json
85
+ if (packageJson.jest)
86
+ return 'jest';
87
+ // Check test scripts
88
+ if (packageJson.scripts) {
89
+ const testScript = packageJson.scripts.test || '';
90
+ if (testScript.includes('jest'))
91
+ return 'jest';
92
+ if (testScript.includes('vitest'))
93
+ return 'vitest';
94
+ if (testScript.includes('mocha'))
95
+ return 'mocha';
96
+ }
97
+ }
98
+ catch (error) {
99
+ // Invalid JSON, continue with file-based detection
100
+ }
101
+ }
102
+ // Check for config files
103
+ for (const framework of exports.FRAMEWORKS) {
104
+ for (const configFile of framework.configFiles) {
105
+ const configPath = path.join(projectPath, configFile);
106
+ if (fs.existsSync(configPath)) {
107
+ return framework.name;
108
+ }
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ function isTestFile(filePath, detectedFramework = null) {
114
+ const fileName = path.basename(filePath);
115
+ const dirName = path.dirname(filePath);
116
+ const parentDirName = path.basename(dirName);
117
+ // If framework is detected, use its specific patterns
118
+ if (detectedFramework) {
119
+ const framework = exports.FRAMEWORKS.find(f => f.name === detectedFramework);
120
+ if (framework) {
121
+ // Check test patterns
122
+ for (const pattern of framework.testPatterns) {
123
+ if (pattern.test(fileName)) {
124
+ return true;
125
+ }
126
+ }
127
+ // Check test directories
128
+ for (const testDir of framework.testDirs) {
129
+ if (parentDirName === testDir) {
130
+ return true;
131
+ }
132
+ }
133
+ }
134
+ }
135
+ // Fallback: check all common patterns
136
+ for (const framework of exports.FRAMEWORKS) {
137
+ for (const pattern of framework.testPatterns) {
138
+ if (pattern.test(fileName)) {
139
+ return true;
140
+ }
141
+ }
142
+ for (const testDir of framework.testDirs) {
143
+ if (parentDirName === testDir) {
144
+ return true;
145
+ }
146
+ }
147
+ }
148
+ return false;
149
+ }
@@ -0,0 +1,11 @@
1
+ export * from './database';
2
+ export * from './detector';
3
+ export * from './scanner';
4
+ export { getDatabaseManager } from './database';
5
+ import { Project, Test } from './database';
6
+ import { scanProject, scanAllProjects } from './scanner';
7
+ export declare function getAllProjects(): Project[];
8
+ export declare function addProject(name: string, projectPath: string): Project;
9
+ export declare function removeProject(id: number): void;
10
+ export declare function getTestsByProject(projectId: number): Test[];
11
+ export { scanProject, scanAllProjects };
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.scanAllProjects = exports.scanProject = exports.getDatabaseManager = void 0;
18
+ exports.getAllProjects = getAllProjects;
19
+ exports.addProject = addProject;
20
+ exports.removeProject = removeProject;
21
+ exports.getTestsByProject = getTestsByProject;
22
+ __exportStar(require("./database"), exports);
23
+ __exportStar(require("./detector"), exports);
24
+ __exportStar(require("./scanner"), exports);
25
+ var database_1 = require("./database");
26
+ Object.defineProperty(exports, "getDatabaseManager", { enumerable: true, get: function () { return database_1.getDatabaseManager; } });
27
+ // Convenience functions for common operations
28
+ const database_2 = require("./database");
29
+ const scanner_1 = require("./scanner");
30
+ Object.defineProperty(exports, "scanProject", { enumerable: true, get: function () { return scanner_1.scanProject; } });
31
+ Object.defineProperty(exports, "scanAllProjects", { enumerable: true, get: function () { return scanner_1.scanAllProjects; } });
32
+ function getAllProjects() {
33
+ return (0, database_2.getDatabaseManager)().getAllProjects();
34
+ }
35
+ function addProject(name, projectPath) {
36
+ return (0, database_2.getDatabaseManager)().addProject(name, projectPath);
37
+ }
38
+ function removeProject(id) {
39
+ (0, database_2.getDatabaseManager)().removeProject(id);
40
+ }
41
+ function getTestsByProject(projectId) {
42
+ return (0, database_2.getDatabaseManager)().getTestsByProject(projectId);
43
+ }
@@ -0,0 +1,8 @@
1
+ import { Project, Test } from './database';
2
+ export interface ScanResult {
3
+ project: Project;
4
+ testsFound: number;
5
+ tests: Test[];
6
+ }
7
+ export declare function scanProject(projectId: number): ScanResult;
8
+ export declare function scanAllProjects(): ScanResult[];
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scanProject = scanProject;
37
+ exports.scanAllProjects = scanAllProjects;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const detector_1 = require("./detector");
41
+ const database_1 = require("./database");
42
+ function scanProject(projectId) {
43
+ const db = (0, database_1.getDatabaseManager)();
44
+ const project = db.getProject(projectId);
45
+ if (!project) {
46
+ throw new Error(`Project with id ${projectId} not found`);
47
+ }
48
+ if (!fs.existsSync(project.path)) {
49
+ throw new Error(`Project path does not exist: ${project.path}`);
50
+ }
51
+ // Detect framework first
52
+ const framework = (0, detector_1.detectTestFramework)(project.path);
53
+ // Remove existing tests for this project
54
+ db.removeTestsByProject(projectId);
55
+ // Scan for test files
56
+ const tests = [];
57
+ const testFiles = findTestFiles(project.path, framework);
58
+ for (const testFile of testFiles) {
59
+ const relativePath = path.relative(project.path, testFile);
60
+ const test = db.addTest(projectId, relativePath, framework);
61
+ tests.push(test);
62
+ }
63
+ // Update last scanned timestamp
64
+ db.updateProjectLastScanned(projectId);
65
+ return {
66
+ project: db.getProject(projectId),
67
+ testsFound: tests.length,
68
+ tests,
69
+ };
70
+ }
71
+ function findTestFiles(dir, framework, results = []) {
72
+ if (!fs.existsSync(dir)) {
73
+ return results;
74
+ }
75
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
76
+ for (const entry of entries) {
77
+ const fullPath = path.join(dir, entry.name);
78
+ // Skip node_modules, .git, and other common ignore directories
79
+ if (entry.isDirectory()) {
80
+ if (entry.name === 'node_modules' ||
81
+ entry.name === '.git' ||
82
+ entry.name === 'dist' ||
83
+ entry.name === 'build' ||
84
+ entry.name === '.next' ||
85
+ entry.name === '.nuxt' ||
86
+ entry.name === 'coverage' ||
87
+ entry.name.startsWith('.')) {
88
+ continue;
89
+ }
90
+ findTestFiles(fullPath, framework, results);
91
+ }
92
+ else if (entry.isFile()) {
93
+ if ((0, detector_1.isTestFile)(fullPath, framework)) {
94
+ results.push(fullPath);
95
+ }
96
+ }
97
+ }
98
+ return results;
99
+ }
100
+ function scanAllProjects() {
101
+ const db = (0, database_1.getDatabaseManager)();
102
+ const projects = db.getAllProjects();
103
+ const results = [];
104
+ for (const project of projects) {
105
+ try {
106
+ const result = scanProject(project.id);
107
+ results.push(result);
108
+ }
109
+ catch (error) {
110
+ console.error(`Error scanning project ${project.name}:`, error);
111
+ }
112
+ }
113
+ return results;
114
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const electron_1 = require("electron");
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs"));
39
+ // Import from bundled core in CLI package, or fallback to @projax/core
40
+ let coreModule;
41
+ try {
42
+ // Try relative import first (when bundled in CLI: dist/electron/main.js -> dist/core)
43
+ coreModule = require('../core');
44
+ }
45
+ catch {
46
+ try {
47
+ // Try alternative path (local development: packages/electron/dist/main.js -> packages/cli/dist/core)
48
+ coreModule = require('../../cli/dist/core');
49
+ }
50
+ catch {
51
+ // Fallback to package import
52
+ coreModule = require('@projax/core');
53
+ }
54
+ }
55
+ const { getDatabaseManager, getAllProjects, addProject, removeProject, scanProject, scanAllProjects, getTestsByProject, } = coreModule;
56
+ let mainWindow = null;
57
+ // Prevent multiple instances
58
+ const gotTheLock = electron_1.app.requestSingleInstanceLock();
59
+ if (!gotTheLock) {
60
+ electron_1.app.quit();
61
+ }
62
+ else {
63
+ electron_1.app.on('second-instance', () => {
64
+ // Someone tried to run a second instance, focus our window instead
65
+ if (mainWindow) {
66
+ if (mainWindow.isMinimized())
67
+ mainWindow.restore();
68
+ mainWindow.focus();
69
+ }
70
+ });
71
+ function createWindow() {
72
+ // Don't create a new window if one already exists
73
+ if (mainWindow) {
74
+ mainWindow.focus();
75
+ return;
76
+ }
77
+ const isDev = process.env.NODE_ENV === 'development';
78
+ mainWindow = new electron_1.BrowserWindow({
79
+ width: 1200,
80
+ height: 800,
81
+ frame: false,
82
+ titleBarStyle: process.platform === 'darwin' ? 'hidden' : 'hidden',
83
+ webPreferences: {
84
+ preload: path.join(__dirname, 'preload.js'),
85
+ nodeIntegration: false,
86
+ contextIsolation: true,
87
+ },
88
+ });
89
+ // Load the app
90
+ if (isDev) {
91
+ mainWindow.loadURL('http://localhost:7898');
92
+ mainWindow.webContents.openDevTools();
93
+ }
94
+ else {
95
+ // Try bundled renderer path first (when bundled in CLI: dist/electron/renderer/index.html)
96
+ // Then try local dev path (packages/electron/dist/renderer/index.html)
97
+ const bundledRenderer = path.join(__dirname, 'renderer', 'index.html');
98
+ const localRenderer = path.join(__dirname, '..', 'renderer', 'index.html');
99
+ if (fs.existsSync(bundledRenderer)) {
100
+ mainWindow.loadFile(bundledRenderer);
101
+ }
102
+ else if (fs.existsSync(localRenderer)) {
103
+ mainWindow.loadFile(localRenderer);
104
+ }
105
+ else {
106
+ console.error('Error: Renderer index.html not found');
107
+ console.error('Bundled path:', bundledRenderer);
108
+ console.error('Local path:', localRenderer);
109
+ electron_1.app.quit();
110
+ }
111
+ }
112
+ mainWindow.on('closed', () => {
113
+ mainWindow = null;
114
+ });
115
+ }
116
+ electron_1.app.whenReady().then(() => {
117
+ createWindow();
118
+ electron_1.app.on('activate', () => {
119
+ // On macOS, re-create window when dock icon is clicked and no windows are open
120
+ if (electron_1.BrowserWindow.getAllWindows().length === 0) {
121
+ createWindow();
122
+ }
123
+ else if (mainWindow) {
124
+ mainWindow.focus();
125
+ }
126
+ });
127
+ });
128
+ }
129
+ electron_1.app.on('window-all-closed', () => {
130
+ if (process.platform !== 'darwin') {
131
+ electron_1.app.quit();
132
+ }
133
+ });
134
+ // IPC Handlers
135
+ electron_1.ipcMain.handle('get-projects', async () => {
136
+ try {
137
+ console.log('Getting projects from database...');
138
+ const projects = getAllProjects();
139
+ console.log(`Found ${projects.length} project(s)`);
140
+ return projects;
141
+ }
142
+ catch (error) {
143
+ console.error('Error getting projects:', error);
144
+ throw error;
145
+ }
146
+ });
147
+ electron_1.ipcMain.handle('add-project', async (_, projectPath) => {
148
+ if (!fs.existsSync(projectPath)) {
149
+ throw new Error('Path does not exist');
150
+ }
151
+ if (!fs.statSync(projectPath).isDirectory()) {
152
+ throw new Error('Path must be a directory');
153
+ }
154
+ const db = getDatabaseManager();
155
+ const existingProject = db.getProjectByPath(projectPath);
156
+ if (existingProject) {
157
+ throw new Error('Project already exists');
158
+ }
159
+ const projectName = path.basename(projectPath);
160
+ return db.addProject(projectName, projectPath);
161
+ });
162
+ electron_1.ipcMain.handle('remove-project', async (_, projectId) => {
163
+ removeProject(projectId);
164
+ });
165
+ electron_1.ipcMain.handle('scan-project', async (_, projectId) => {
166
+ return scanProject(projectId);
167
+ });
168
+ electron_1.ipcMain.handle('scan-all-projects', async () => {
169
+ return scanAllProjects();
170
+ });
171
+ electron_1.ipcMain.handle('get-tests', async (_, projectId) => {
172
+ try {
173
+ const db = getDatabaseManager();
174
+ return getTestsByProject(projectId);
175
+ }
176
+ catch (error) {
177
+ console.error('Error getting tests:', error);
178
+ throw error;
179
+ }
180
+ });
181
+ electron_1.ipcMain.handle('select-directory', async () => {
182
+ if (!mainWindow)
183
+ return null;
184
+ const result = await electron_1.dialog.showOpenDialog(mainWindow, {
185
+ properties: ['openDirectory'],
186
+ });
187
+ if (result.canceled || result.filePaths.length === 0) {
188
+ return null;
189
+ }
190
+ return result.filePaths[0];
191
+ });
192
+ // Window controls
193
+ electron_1.ipcMain.handle('minimize-window', () => {
194
+ if (mainWindow) {
195
+ mainWindow.minimize();
196
+ }
197
+ });
198
+ electron_1.ipcMain.handle('maximize-window', () => {
199
+ if (mainWindow) {
200
+ if (mainWindow.isMaximized()) {
201
+ mainWindow.unmaximize();
202
+ }
203
+ else {
204
+ mainWindow.maximize();
205
+ }
206
+ }
207
+ });
208
+ electron_1.ipcMain.handle('close-window', () => {
209
+ if (mainWindow) {
210
+ mainWindow.close();
211
+ }
212
+ });
213
+ // Rename project
214
+ electron_1.ipcMain.handle('rename-project', async (_, projectId, newName) => {
215
+ const db = getDatabaseManager();
216
+ return db.updateProjectName(projectId, newName);
217
+ });
218
+ // Get project scripts
219
+ electron_1.ipcMain.handle('get-project-scripts', async (_, projectPath) => {
220
+ // Try bundled path first (when bundled in CLI: dist/electron/main.js -> dist/script-runner.js)
221
+ // Then try local dev path (packages/electron/dist/main.js -> packages/cli/dist/script-runner.js)
222
+ const bundledScriptRunnerPath = path.join(__dirname, '..', 'script-runner.js');
223
+ const localScriptRunnerPath = path.join(__dirname, '..', '..', '..', 'cli', 'dist', 'script-runner.js');
224
+ let scriptRunnerPath;
225
+ if (fs.existsSync(bundledScriptRunnerPath)) {
226
+ scriptRunnerPath = bundledScriptRunnerPath;
227
+ }
228
+ else {
229
+ scriptRunnerPath = localScriptRunnerPath;
230
+ }
231
+ const { getProjectScripts } = await Promise.resolve(`${scriptRunnerPath}`).then(s => __importStar(require(s)));
232
+ const result = getProjectScripts(projectPath);
233
+ // Convert Map to array for IPC serialization
234
+ const scriptsArray = Array.from(result.scripts.entries()).map(([name, script]) => ({
235
+ name,
236
+ ...script,
237
+ }));
238
+ return {
239
+ type: result.type,
240
+ scripts: scriptsArray,
241
+ };
242
+ });
243
+ // Run script
244
+ electron_1.ipcMain.handle('run-script', async (_, projectPath, scriptName, args = [], background = false) => {
245
+ // Try bundled path first (when bundled in CLI: dist/electron/main.js -> dist/script-runner.js)
246
+ // Then try local dev path (packages/electron/dist/main.js -> packages/cli/dist/script-runner.js)
247
+ const bundledScriptRunnerPath = path.join(__dirname, '..', 'script-runner.js');
248
+ const localScriptRunnerPath = path.join(__dirname, '..', '..', '..', 'cli', 'dist', 'script-runner.js');
249
+ let scriptRunnerPath;
250
+ if (fs.existsSync(bundledScriptRunnerPath)) {
251
+ scriptRunnerPath = bundledScriptRunnerPath;
252
+ }
253
+ else {
254
+ scriptRunnerPath = localScriptRunnerPath;
255
+ }
256
+ const { runScriptInBackground } = await Promise.resolve(`${scriptRunnerPath}`).then(s => __importStar(require(s)));
257
+ const db = getDatabaseManager();
258
+ const project = db.getProjectByPath(projectPath);
259
+ if (!project) {
260
+ throw new Error('Project not found');
261
+ }
262
+ // Run in background (foreground scripts would need IPC streaming for output)
263
+ await runScriptInBackground(projectPath, project.name, scriptName, args, false);
264
+ return { success: true, background: true };
265
+ });
266
+ // Scan ports
267
+ electron_1.ipcMain.handle('scan-project-ports', async (_, projectId) => {
268
+ // Try bundled path first (when bundled in CLI: dist/electron/main.js -> dist/port-scanner.js)
269
+ // Then try local dev path (packages/electron/dist/main.js -> packages/cli/dist/port-scanner.js)
270
+ const bundledPortScannerPath = path.join(__dirname, '..', 'port-scanner.js');
271
+ const localPortScannerPath = path.join(__dirname, '..', '..', '..', 'cli', 'dist', 'port-scanner.js');
272
+ let portScannerPath;
273
+ if (fs.existsSync(bundledPortScannerPath)) {
274
+ portScannerPath = bundledPortScannerPath;
275
+ }
276
+ else {
277
+ portScannerPath = localPortScannerPath;
278
+ }
279
+ const { scanProjectPorts } = await Promise.resolve(`${portScannerPath}`).then(s => __importStar(require(s)));
280
+ await scanProjectPorts(projectId);
281
+ const db = getDatabaseManager();
282
+ return db.getProjectPorts(projectId);
283
+ });
284
+ electron_1.ipcMain.handle('scan-all-ports', async () => {
285
+ // Try bundled path first (when bundled in CLI: dist/electron/main.js -> dist/port-scanner.js)
286
+ // Then try local dev path (packages/electron/dist/main.js -> packages/cli/dist/port-scanner.js)
287
+ const bundledPortScannerPath = path.join(__dirname, '..', 'port-scanner.js');
288
+ const localPortScannerPath = path.join(__dirname, '..', '..', '..', 'cli', 'dist', 'port-scanner.js');
289
+ let portScannerPath;
290
+ if (fs.existsSync(bundledPortScannerPath)) {
291
+ portScannerPath = bundledPortScannerPath;
292
+ }
293
+ else {
294
+ portScannerPath = localPortScannerPath;
295
+ }
296
+ const { scanAllProjectPorts } = await Promise.resolve(`${portScannerPath}`).then(s => __importStar(require(s)));
297
+ await scanAllProjectPorts();
298
+ const db = getDatabaseManager();
299
+ const projects = getAllProjects();
300
+ const result = {};
301
+ for (const project of projects) {
302
+ result[project.id] = db.getProjectPorts(project.id);
303
+ }
304
+ return result;
305
+ });
306
+ // Get project ports
307
+ electron_1.ipcMain.handle('get-project-ports', async (_, projectId) => {
308
+ const db = getDatabaseManager();
309
+ return db.getProjectPorts(projectId);
310
+ });
@@ -0,0 +1,9 @@
1
+ export interface PortInfo {
2
+ port: number;
3
+ script: string | null;
4
+ source: string;
5
+ }
6
+ /**
7
+ * Extract ports from a project's configuration files
8
+ */
9
+ export declare function extractPortsFromProject(projectPath: string): Promise<PortInfo[]>;