portkeeper 1.1.0 ā 1.1.2
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/README.md +10 -12
- package/dist/cli/commands/gui.d.ts.map +1 -1
- package/dist/cli/commands/gui.js +115 -142
- package/dist/cli/commands/gui.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/electron/main/index.js +3 -3
- package/package.json +3 -2
- package/scripts/debug-gui.sh +12 -0
- package/scripts/ensure-electron.js +53 -0
- package/scripts/fix-native-modules.sh +15 -0
- package/scripts/postinstall.js +43 -0
- package/scripts/test-gui.sh +16 -0
package/README.md
CHANGED
|
@@ -28,8 +28,12 @@ A comprehensive port management tool for developers that helps reserve, monitor,
|
|
|
28
28
|
|
|
29
29
|
### Via npm
|
|
30
30
|
```bash
|
|
31
|
+
# CLI only (lightweight)
|
|
31
32
|
npm install -g portkeeper
|
|
32
33
|
|
|
34
|
+
# CLI + GUI (includes Electron)
|
|
35
|
+
npm install -g portkeeper --include=optional
|
|
36
|
+
|
|
33
37
|
# Verify installation
|
|
34
38
|
portman --version
|
|
35
39
|
```
|
|
@@ -45,20 +49,17 @@ npm link
|
|
|
45
49
|
```
|
|
46
50
|
|
|
47
51
|
### GUI Application
|
|
48
|
-
The GUI
|
|
52
|
+
The GUI is included with Port Keeper:
|
|
49
53
|
|
|
50
54
|
```bash
|
|
51
|
-
#
|
|
52
|
-
portman gui --install
|
|
53
|
-
|
|
54
|
-
# Or install separately
|
|
55
|
-
portman gui install
|
|
56
|
-
|
|
57
|
-
# Then launch anytime with
|
|
55
|
+
# Launch the GUI (requires --include=optional during install)
|
|
58
56
|
portman gui
|
|
57
|
+
|
|
58
|
+
# If GUI not found, install with:
|
|
59
|
+
npm install -g portkeeper --include=optional
|
|
59
60
|
```
|
|
60
61
|
|
|
61
|
-
The GUI
|
|
62
|
+
Note: The GUI requires Electron (~100MB). Install with `--include=optional` to get GUI support.
|
|
62
63
|
|
|
63
64
|
## Quick Start
|
|
64
65
|
|
|
@@ -95,9 +96,6 @@ portman export team-ports.json
|
|
|
95
96
|
```bash
|
|
96
97
|
# Launch the GUI application
|
|
97
98
|
portman gui
|
|
98
|
-
|
|
99
|
-
# First time? Install with:
|
|
100
|
-
portman gui --install
|
|
101
99
|
```
|
|
102
100
|
|
|
103
101
|
In the GUI:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gui.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/gui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"gui.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/gui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoHpC,eAAO,MAAM,UAAU,SAwEnB,CAAC"}
|
package/dist/cli/commands/gui.js
CHANGED
|
@@ -1,180 +1,153 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { spawn } from 'child_process';
|
|
3
|
+
import { spawn, execSync } from 'child_process';
|
|
4
4
|
import { existsSync } from 'fs';
|
|
5
5
|
import { join, dirname } from 'path';
|
|
6
|
-
import { homedir } from 'os';
|
|
7
|
-
import { mkdir } from 'fs/promises';
|
|
8
|
-
import { createWriteStream } from 'fs';
|
|
9
|
-
import { get } from 'https';
|
|
10
|
-
import { promisify } from 'util';
|
|
11
|
-
import { exec as execCallback } from 'child_process';
|
|
12
|
-
import { chmod } from 'fs/promises';
|
|
13
6
|
import { fileURLToPath } from 'url';
|
|
7
|
+
import { homedir } from 'os';
|
|
14
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
9
|
const __dirname = dirname(__filename);
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
const findElectronExecutable = () => {
|
|
11
|
+
const possiblePaths = [
|
|
12
|
+
join(__dirname, '..', '..', '..', 'node_modules', 'electron', 'dist', 'Electron.app', 'Contents', 'MacOS', 'Electron'),
|
|
13
|
+
join(__dirname, '..', '..', '..', 'node_modules', 'electron', 'dist', 'electron.exe'),
|
|
14
|
+
join(__dirname, '..', '..', '..', 'node_modules', 'electron', 'dist', 'electron'),
|
|
15
|
+
join(__dirname, '..', '..', '..', '..', 'node_modules', 'electron', 'dist', 'Electron.app', 'Contents', 'MacOS', 'Electron'),
|
|
16
|
+
join(__dirname, '..', '..', '..', '..', 'node_modules', 'electron', 'dist', 'electron.exe'),
|
|
17
|
+
join(__dirname, '..', '..', '..', '..', 'node_modules', 'electron', 'dist', 'electron'),
|
|
18
|
+
join(homedir(), '.npm-global', 'lib', 'node_modules', 'electron', 'dist', 'Electron.app', 'Contents', 'MacOS', 'Electron'),
|
|
19
|
+
join(homedir(), '.npm-global', 'lib', 'node_modules', 'electron', 'dist', 'electron.exe'),
|
|
20
|
+
join(homedir(), '.npm-global', 'lib', 'node_modules', 'electron', 'dist', 'electron'),
|
|
21
|
+
];
|
|
22
|
+
for (const path of possiblePaths) {
|
|
23
|
+
if (existsSync(path)) {
|
|
24
|
+
return path;
|
|
25
|
+
}
|
|
28
26
|
}
|
|
27
|
+
return null;
|
|
29
28
|
};
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
return baseUrl + 'Port-Keeper-linux-x86_64.AppImage';
|
|
29
|
+
const findGuiEntry = () => {
|
|
30
|
+
const possiblePaths = [
|
|
31
|
+
join(__dirname, '..', '..', 'electron', 'main', 'index.js'),
|
|
32
|
+
join(__dirname, '..', '..', 'gui', 'main', 'index.js'),
|
|
33
|
+
join(__dirname, '..', '..', '..', 'dist', 'electron', 'main', 'index.js'),
|
|
34
|
+
join(__dirname, '..', '..', '..', 'dist', 'gui', 'main', 'index.js'),
|
|
35
|
+
];
|
|
36
|
+
for (const path of possiblePaths) {
|
|
37
|
+
if (existsSync(path)) {
|
|
38
|
+
return path;
|
|
39
|
+
}
|
|
44
40
|
}
|
|
41
|
+
return null;
|
|
45
42
|
};
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
const ensureElectronAndModules = () => {
|
|
44
|
+
try {
|
|
45
|
+
const hasElectron = findElectronExecutable() !== null;
|
|
46
|
+
if (!hasElectron) {
|
|
47
|
+
console.log(chalk.yellow('\nš¦ Electron is required for the GUI'));
|
|
48
|
+
console.log(chalk.gray('Installing Electron and preparing native modules...\n'));
|
|
49
|
+
try {
|
|
50
|
+
const globalModulesPath = join(__dirname, '..', '..', '..');
|
|
51
|
+
execSync('npm install electron@28.0.0 --no-save --prefix ' + globalModulesPath, { stdio: 'inherit' });
|
|
52
|
+
console.log(chalk.gray('\nRebuilding native modules for Electron...'));
|
|
53
|
+
execSync(`npm rebuild better-sqlite3 --runtime=electron --target=28.0.0 --dist-url=https://electronjs.org/headers --abi=119`, {
|
|
54
|
+
cwd: globalModulesPath,
|
|
55
|
+
stdio: 'inherit'
|
|
56
|
+
});
|
|
57
|
+
console.log(chalk.green('ā
Electron installed and modules prepared!\n'));
|
|
58
|
+
return true;
|
|
53
59
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return;
|
|
60
|
+
catch (installError) {
|
|
61
|
+
console.error(chalk.red('Failed to install Electron:'), installError instanceof Error ? installError.message : String(installError));
|
|
62
|
+
return false;
|
|
57
63
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
response.pipe(file);
|
|
66
|
-
file.on('finish', () => {
|
|
67
|
-
file.close();
|
|
68
|
-
console.log('\n');
|
|
69
|
-
resolve();
|
|
70
|
-
});
|
|
71
|
-
}).on('error', reject);
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
const installGui = async () => {
|
|
75
|
-
const guiDir = join(homedir(), '.portkeeper', 'gui');
|
|
76
|
-
await mkdir(guiDir, { recursive: true });
|
|
77
|
-
console.log(chalk.blue('š Installing Port Keeper GUI...\n'));
|
|
78
|
-
const downloadUrl = getDownloadUrl();
|
|
79
|
-
const platform = process.platform;
|
|
80
|
-
if (platform === 'darwin') {
|
|
81
|
-
const dmgPath = join(guiDir, 'Port-Keeper.dmg');
|
|
82
|
-
console.log(chalk.gray('Downloading macOS app...'));
|
|
83
|
-
await downloadFile(downloadUrl, dmgPath);
|
|
84
|
-
console.log(chalk.gray('Mounting DMG...'));
|
|
85
|
-
await exec(`hdiutil attach "${dmgPath}" -nobrowse -quiet`);
|
|
86
|
-
console.log(chalk.gray('Copying app...'));
|
|
87
|
-
await exec(`cp -R "/Volumes/Port Keeper/Port Keeper.app" "${guiDir}/"`);
|
|
88
|
-
console.log(chalk.gray('Unmounting DMG...'));
|
|
89
|
-
await exec('hdiutil detach "/Volumes/Port Keeper" -quiet');
|
|
90
|
-
console.log(chalk.gray('Cleaning up...'));
|
|
91
|
-
await exec(`rm "${dmgPath}"`);
|
|
92
|
-
}
|
|
93
|
-
else if (platform === 'win32') {
|
|
94
|
-
const exePath = join(guiDir, 'Port Keeper.exe');
|
|
95
|
-
console.log(chalk.gray('Downloading Windows app...'));
|
|
96
|
-
await downloadFile(downloadUrl, exePath);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
const appImagePath = join(guiDir, 'port-keeper.AppImage');
|
|
100
|
-
console.log(chalk.gray('Downloading Linux AppImage...'));
|
|
101
|
-
await downloadFile(downloadUrl, appImagePath);
|
|
102
|
-
await chmod(appImagePath, 0o755);
|
|
103
|
-
}
|
|
104
|
-
console.log(chalk.green('\nā
GUI installed successfully!\n'));
|
|
105
|
-
};
|
|
106
|
-
const launchGui = () => {
|
|
107
|
-
const guiPath = getGuiPath();
|
|
108
|
-
console.log(chalk.blue('š Launching Port Keeper GUI...\n'));
|
|
109
|
-
const child = spawn(guiPath, [], {
|
|
110
|
-
detached: true,
|
|
111
|
-
stdio: 'ignore'
|
|
112
|
-
});
|
|
113
|
-
child.unref();
|
|
114
|
-
console.log(chalk.green('ā
GUI launched!'));
|
|
115
|
-
console.log(chalk.gray('\nThe Port Keeper GUI is now running.'));
|
|
116
|
-
console.log(chalk.gray('You can close this terminal window.\n'));
|
|
117
|
-
};
|
|
118
|
-
const tryLaunchBundledGui = () => {
|
|
119
|
-
try {
|
|
120
|
-
const packageRoot = join(__dirname, '..', '..', '..');
|
|
121
|
-
const electronPath = join(packageRoot, 'node_modules', '.bin', 'electron');
|
|
122
|
-
const mainPath = join(packageRoot, 'dist', 'gui', 'main', 'index.js');
|
|
123
|
-
if (existsSync(electronPath) && existsSync(mainPath)) {
|
|
124
|
-
console.log(chalk.blue('š Launching Port Keeper GUI...\n'));
|
|
125
|
-
const child = spawn(electronPath, [mainPath], {
|
|
126
|
-
detached: true,
|
|
127
|
-
stdio: 'ignore',
|
|
128
|
-
env: { ...process.env, ELECTRON_IS_DEV: '0' }
|
|
64
|
+
}
|
|
65
|
+
console.log(chalk.gray('Checking native modules compatibility...'));
|
|
66
|
+
const testPath = join(__dirname, '..', '..', '..');
|
|
67
|
+
try {
|
|
68
|
+
execSync(`npm rebuild better-sqlite3 --runtime=electron --target=28.0.0 --dist-url=https://electronjs.org/headers --abi=119`, {
|
|
69
|
+
cwd: testPath,
|
|
70
|
+
stdio: 'pipe'
|
|
129
71
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
console.log(chalk.gray('You can close this terminal window.\n'));
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
catch (rebuildError) {
|
|
134
75
|
return true;
|
|
135
76
|
}
|
|
136
77
|
}
|
|
137
78
|
catch (error) {
|
|
79
|
+
console.error(chalk.red('Error preparing GUI:'), error instanceof Error ? error.message : String(error));
|
|
80
|
+
return false;
|
|
138
81
|
}
|
|
139
|
-
return false;
|
|
140
82
|
};
|
|
141
83
|
export const guiCommand = new Command('gui')
|
|
142
84
|
.description('Launch the Port Keeper GUI application')
|
|
143
|
-
.option('--
|
|
144
|
-
.option('--
|
|
145
|
-
.action(
|
|
85
|
+
.option('--dev', 'Run in development mode')
|
|
86
|
+
.option('--skip-rebuild', 'Skip native module rebuild check')
|
|
87
|
+
.action((options) => {
|
|
146
88
|
try {
|
|
147
|
-
|
|
89
|
+
const electronPath = findElectronExecutable();
|
|
90
|
+
const guiEntry = findGuiEntry();
|
|
91
|
+
if (!electronPath || !guiEntry) {
|
|
92
|
+
console.log(chalk.yellow('\nā ļø GUI components not found.\n'));
|
|
93
|
+
if (!electronPath) {
|
|
94
|
+
console.log(chalk.red('Electron is not installed.'));
|
|
95
|
+
}
|
|
96
|
+
if (!guiEntry) {
|
|
97
|
+
console.log(chalk.red('GUI files are missing.'));
|
|
98
|
+
}
|
|
99
|
+
console.log(chalk.cyan('\nTo use the GUI, you have two options:\n'));
|
|
100
|
+
console.log(chalk.white('Option 1: Install from source'));
|
|
101
|
+
console.log(chalk.gray(' git clone https://github.com/ahmadzein/portkeeper.git'));
|
|
102
|
+
console.log(chalk.gray(' cd portkeeper'));
|
|
103
|
+
console.log(chalk.gray(' npm install'));
|
|
104
|
+
console.log(chalk.gray(' npm run dev:gui\n'));
|
|
105
|
+
console.log(chalk.white('Option 2: Reinstall portkeeper with optional dependencies'));
|
|
106
|
+
console.log(chalk.gray(' npm uninstall -g portkeeper'));
|
|
107
|
+
console.log(chalk.gray(' npm install -g portkeeper --include=optional\n'));
|
|
108
|
+
console.log(chalk.yellow('Note: The GUI requires Electron which is a large dependency (~100MB).'));
|
|
109
|
+
console.log(chalk.yellow('It is marked as optional to keep the CLI lightweight.\n'));
|
|
148
110
|
return;
|
|
149
111
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
112
|
+
if (!options.skipRebuild) {
|
|
113
|
+
if (!ensureElectronAndModules()) {
|
|
114
|
+
console.log(chalk.red('\nā Failed to prepare the GUI environment'));
|
|
115
|
+
console.log(chalk.yellow('You can try:'));
|
|
116
|
+
console.log(chalk.gray(' 1. Running with --skip-rebuild flag'));
|
|
117
|
+
console.log(chalk.gray(' 2. Installing with: npm install -g portkeeper --include=optional'));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
154
120
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
console.log(chalk.white(' portman gui install # Just install\n'));
|
|
160
|
-
console.log(chalk.gray('The GUI will be downloaded and installed to:'));
|
|
161
|
-
console.log(chalk.gray(` ${join(homedir(), '.portkeeper', 'gui')}\n`));
|
|
162
|
-
return;
|
|
121
|
+
console.log(chalk.blue('š Launching Port Keeper GUI...\n'));
|
|
122
|
+
const env = { ...process.env };
|
|
123
|
+
if (options.dev) {
|
|
124
|
+
env.ELECTRON_IS_DEV = '1';
|
|
163
125
|
}
|
|
164
|
-
|
|
126
|
+
const child = spawn(electronPath, [guiEntry], {
|
|
127
|
+
detached: true,
|
|
128
|
+
stdio: 'ignore',
|
|
129
|
+
env
|
|
130
|
+
});
|
|
131
|
+
child.unref();
|
|
132
|
+
console.log(chalk.green('ā
GUI launched!'));
|
|
133
|
+
console.log(chalk.gray('\nThe Port Keeper GUI is now running.'));
|
|
134
|
+
console.log(chalk.gray('You can close this terminal window.\n'));
|
|
165
135
|
}
|
|
166
136
|
catch (error) {
|
|
167
|
-
console.error(chalk.red('\nā Error:'), error instanceof Error ? error.message : String(error));
|
|
168
|
-
console.error(chalk.gray('\
|
|
137
|
+
console.error(chalk.red('\nā Error launching GUI:'), error instanceof Error ? error.message : String(error));
|
|
138
|
+
console.error(chalk.gray('\nPlease try reinstalling with: npm install -g portkeeper --include=optional'));
|
|
169
139
|
}
|
|
170
140
|
});
|
|
171
141
|
guiCommand
|
|
172
142
|
.command('install')
|
|
173
|
-
.description('Install
|
|
143
|
+
.description('Install GUI dependencies (Electron)')
|
|
174
144
|
.action(async () => {
|
|
175
145
|
try {
|
|
176
|
-
|
|
177
|
-
console.log(chalk.
|
|
146
|
+
console.log(chalk.blue('š¦ Installing GUI dependencies...\n'));
|
|
147
|
+
console.log(chalk.yellow('This will install Electron (~100MB) as an optional dependency.\n'));
|
|
148
|
+
console.log(chalk.cyan('Please run:'));
|
|
149
|
+
console.log(chalk.white(' npm install -g portkeeper --include=optional\n'));
|
|
150
|
+
console.log(chalk.gray('This ensures Electron is properly installed for the GUI.'));
|
|
178
151
|
}
|
|
179
152
|
catch (error) {
|
|
180
153
|
console.error(chalk.red('\nā Installation failed:'), error instanceof Error ? error.message : String(error));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gui.js","sourceRoot":"","sources":["../../../src/cli/commands/gui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"gui.js","sourceRoot":"","sources":["../../../src/cli/commands/gui.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -15,8 +15,8 @@ import { aiCommand } from './commands/ai.js';
|
|
|
15
15
|
const program = new Command();
|
|
16
16
|
program
|
|
17
17
|
.name('portman')
|
|
18
|
-
.description('Port
|
|
19
|
-
.version('1.
|
|
18
|
+
.description('Port Keeper - Manage your local development ports')
|
|
19
|
+
.version('1.1.2');
|
|
20
20
|
program.addCommand(checkCommand);
|
|
21
21
|
program.addCommand(reserveCommand);
|
|
22
22
|
program.addCommand(listCommand);
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAE9B,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;IAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,IAAI,EAAE,CAAC;AACjB,CAAC"}
|
|
@@ -139,7 +139,7 @@ const optimizer = {
|
|
|
139
139
|
};
|
|
140
140
|
var electronApp_1 = dist.electronApp = electronApp;
|
|
141
141
|
dist.ipcHelper = ipcHelper;
|
|
142
|
-
|
|
142
|
+
dist.is = is;
|
|
143
143
|
var optimizer_1 = dist.optimizer = optimizer;
|
|
144
144
|
dist.platform = platform;
|
|
145
145
|
class PortDatabase {
|
|
@@ -772,7 +772,7 @@ function createWindow() {
|
|
|
772
772
|
});
|
|
773
773
|
mainWindow.on("ready-to-show", () => {
|
|
774
774
|
mainWindow?.show();
|
|
775
|
-
if (
|
|
775
|
+
if (process.env["ELECTRON_IS_DEV"] === "1" || process.env["DEBUG_ELECTRON"]) {
|
|
776
776
|
mainWindow?.webContents.openDevTools();
|
|
777
777
|
}
|
|
778
778
|
});
|
|
@@ -780,7 +780,7 @@ function createWindow() {
|
|
|
780
780
|
shell.openExternal(details.url);
|
|
781
781
|
return { action: "deny" };
|
|
782
782
|
});
|
|
783
|
-
if (
|
|
783
|
+
if (process.env["ELECTRON_IS_DEV"] === "1" && process.env["ELECTRON_RENDERER_URL"]) {
|
|
784
784
|
mainWindow.loadURL(process.env["ELECTRON_RENDERER_URL"]);
|
|
785
785
|
} else {
|
|
786
786
|
mainWindow.loadFile(join(__dirname, "../renderer/index.html"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "portkeeper",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "A comprehensive port management tool for developers with CLI and GUI interfaces",
|
|
5
5
|
"main": "dist/cli/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"README.md",
|
|
13
13
|
"LICENSE",
|
|
14
14
|
"resources/",
|
|
15
|
+
"scripts/",
|
|
15
16
|
"electron.vite.config.ts"
|
|
16
17
|
],
|
|
17
18
|
"scripts": {
|
|
@@ -23,7 +24,7 @@
|
|
|
23
24
|
"build": "npm run build:cli && npm run build:gui",
|
|
24
25
|
"build:npm": "npm run build:cli && npm run build:gui",
|
|
25
26
|
"prepublishOnly": "npm run build:npm",
|
|
26
|
-
"postinstall": "
|
|
27
|
+
"postinstall": "node scripts/postinstall.js",
|
|
27
28
|
"fix:electron": "npm rebuild better-sqlite3 --runtime=electron --target=28.0.0 --dist-url=https://electronjs.org/headers --abi=119",
|
|
28
29
|
"fix:node": "npm rebuild better-sqlite3",
|
|
29
30
|
"build:cli": "tsc -p tsconfig.cli.json",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
echo "Checking GUI build files..."
|
|
4
|
+
echo "Main file exists: $(test -f dist/electron/main/index.js && echo "YES" || echo "NO")"
|
|
5
|
+
echo "Preload file exists: $(test -f dist/electron/preload/index.js && echo "YES" || echo "NO")"
|
|
6
|
+
echo "Renderer exists: $(test -f dist/electron/renderer/index.html && echo "YES" || echo "NO")"
|
|
7
|
+
|
|
8
|
+
echo -e "\nPreload file path in main:"
|
|
9
|
+
grep -n "preload:" dist/electron/main/index.js | head -5
|
|
10
|
+
|
|
11
|
+
echo -e "\nStarting GUI with debug..."
|
|
12
|
+
DEBUG_ELECTRON=1 npm start
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
|
|
8
|
+
export function ensureElectron() {
|
|
9
|
+
// Check if Electron is installed
|
|
10
|
+
const electronPaths = [
|
|
11
|
+
'./node_modules/electron',
|
|
12
|
+
'../node_modules/electron',
|
|
13
|
+
'../../node_modules/electron',
|
|
14
|
+
'../../../node_modules/electron'
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const hasElectron = electronPaths.some(path => existsSync(path));
|
|
18
|
+
|
|
19
|
+
if (!hasElectron) {
|
|
20
|
+
console.log(chalk.yellow('\nš¦ Electron is not installed. Installing now...'));
|
|
21
|
+
console.log(chalk.gray('This is a one-time setup (~100MB download)\n'));
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// Install electron as an optional dependency
|
|
25
|
+
execSync('npm install electron@28.0.0 --no-save', {
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
cwd: process.cwd()
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Rebuild native modules for Electron
|
|
31
|
+
console.log(chalk.gray('\nRebuilding native modules for Electron...'));
|
|
32
|
+
execSync(
|
|
33
|
+
'npm rebuild better-sqlite3 --runtime=electron --target=28.0.0 --dist-url=https://electronjs.org/headers --abi=119',
|
|
34
|
+
{ stdio: 'inherit' }
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
console.log(chalk.green('\nā
Electron installed successfully!'));
|
|
38
|
+
return true;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error(chalk.red('\nā Failed to install Electron:'), error.message);
|
|
41
|
+
console.log(chalk.yellow('\nPlease install manually with:'));
|
|
42
|
+
console.log(chalk.white(' npm install -g electron@28.0.0'));
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Run if called directly
|
|
51
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
52
|
+
ensureElectron();
|
|
53
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Fix native modules for both Node.js and Electron
|
|
4
|
+
echo "š§ Fixing native modules..."
|
|
5
|
+
|
|
6
|
+
# Check if we're running CLI or GUI
|
|
7
|
+
if [ "$1" == "electron" ]; then
|
|
8
|
+
echo "š¦ Rebuilding for Electron..."
|
|
9
|
+
npm rebuild better-sqlite3 --runtime=electron --target=28.0.0 --dist-url=https://electronjs.org/headers --abi=119
|
|
10
|
+
echo "ā
Native modules fixed for Electron"
|
|
11
|
+
else
|
|
12
|
+
echo "š¦ Rebuilding for Node.js..."
|
|
13
|
+
npm rebuild better-sqlite3
|
|
14
|
+
echo "ā
Native modules fixed for Node.js"
|
|
15
|
+
fi
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
|
|
7
|
+
console.log(chalk.blue('š§ Setting up portkeeper...'));
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
// Always rebuild for Node.js first
|
|
11
|
+
console.log(chalk.gray('Rebuilding native modules for Node.js...'));
|
|
12
|
+
execSync('npm rebuild better-sqlite3', { stdio: 'inherit' });
|
|
13
|
+
console.log(chalk.green('ā
Native modules prepared for CLI'));
|
|
14
|
+
|
|
15
|
+
// Check if Electron is installed
|
|
16
|
+
const hasElectron = existsSync('./node_modules/electron');
|
|
17
|
+
|
|
18
|
+
if (hasElectron) {
|
|
19
|
+
console.log(chalk.gray('\nElectron detected. Preparing GUI support...'));
|
|
20
|
+
try {
|
|
21
|
+
// Create a separate build for Electron
|
|
22
|
+
execSync(
|
|
23
|
+
'npm rebuild better-sqlite3 --runtime=electron --target=28.0.0 --dist-url=https://electronjs.org/headers --abi=119',
|
|
24
|
+
{ stdio: 'inherit' }
|
|
25
|
+
);
|
|
26
|
+
console.log(chalk.green('ā
Native modules prepared for GUI'));
|
|
27
|
+
} catch (electronError) {
|
|
28
|
+
console.log(chalk.yellow('ā ļø Could not prepare Electron modules. GUI may require manual setup.'));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log(chalk.green('\n⨠Portkeeper installation complete!'));
|
|
33
|
+
console.log(chalk.gray('\nUsage:'));
|
|
34
|
+
console.log(chalk.white(' portman --help ') + chalk.gray('Show all available commands'));
|
|
35
|
+
console.log(chalk.white(' portman list ') + chalk.gray('List all managed ports'));
|
|
36
|
+
console.log(chalk.white(' portman gui ') + chalk.gray('Launch the GUI (requires Electron)'));
|
|
37
|
+
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error(chalk.red('ā Setup failed:'), error.message);
|
|
40
|
+
console.log(chalk.yellow('\nYou may need to manually rebuild native modules:'));
|
|
41
|
+
console.log(chalk.gray(' npm rebuild better-sqlite3'));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Ensure we're in the project root
|
|
4
|
+
cd "$(dirname "$0")/.."
|
|
5
|
+
|
|
6
|
+
# Build the GUI first
|
|
7
|
+
echo "Building GUI..."
|
|
8
|
+
npm run build:gui
|
|
9
|
+
|
|
10
|
+
# Fix sqlite3 for Electron
|
|
11
|
+
echo "Fixing native modules for Electron..."
|
|
12
|
+
npm run fix:electron
|
|
13
|
+
|
|
14
|
+
# Run the GUI
|
|
15
|
+
echo "Launching GUI..."
|
|
16
|
+
npm start
|