genbox 1.0.98 → 1.0.99
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/dist/commands/cleanup-ssh.js +91 -0
- package/dist/commands/destroy.js +4 -0
- package/dist/index.js +27 -1
- package/dist/ssh-config.js +21 -0
- package/package.json +1 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.cleanupSshCommand = void 0;
|
|
7
|
+
exports.cleanupOrphanedSshConfigs = cleanupOrphanedSshConfigs;
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const ora_1 = __importDefault(require("ora"));
|
|
11
|
+
const api_1 = require("../api");
|
|
12
|
+
const ssh_config_1 = require("../ssh-config");
|
|
13
|
+
/**
|
|
14
|
+
* Clean up orphaned SSH config entries for genboxes that no longer exist
|
|
15
|
+
* Returns the list of removed entries
|
|
16
|
+
*/
|
|
17
|
+
async function cleanupOrphanedSshConfigs(options = {}) {
|
|
18
|
+
const { silent = false } = options;
|
|
19
|
+
// Get all SSH config entries for genboxes
|
|
20
|
+
const sshEntries = (0, ssh_config_1.getAllSshConfigEntries)();
|
|
21
|
+
if (sshEntries.length === 0) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
// Fetch all user's genboxes from API
|
|
25
|
+
let existingGenboxes = [];
|
|
26
|
+
try {
|
|
27
|
+
existingGenboxes = await (0, api_1.fetchApi)('/genboxes');
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
// If not authenticated, we can't check - skip silently in auto mode
|
|
31
|
+
if (error instanceof api_1.AuthenticationError) {
|
|
32
|
+
if (!silent) {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
// Get names of existing genboxes (both running and terminated but recent)
|
|
40
|
+
const existingNames = new Set(existingGenboxes.map(g => g.name));
|
|
41
|
+
// Find orphaned entries (SSH configs for genboxes that don't exist anymore)
|
|
42
|
+
const orphaned = sshEntries.filter(name => !existingNames.has(name));
|
|
43
|
+
if (orphaned.length === 0) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
// Remove orphaned entries
|
|
47
|
+
const removed = [];
|
|
48
|
+
for (const name of orphaned) {
|
|
49
|
+
if ((0, ssh_config_1.removeSshConfigEntry)(name)) {
|
|
50
|
+
removed.push(name);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return removed;
|
|
54
|
+
}
|
|
55
|
+
exports.cleanupSshCommand = new commander_1.Command('cleanup-ssh')
|
|
56
|
+
.description('Remove SSH config entries for genboxes that no longer exist')
|
|
57
|
+
.option('-q, --quiet', 'Only output if entries were removed')
|
|
58
|
+
.action(async (options) => {
|
|
59
|
+
try {
|
|
60
|
+
const spinner = (0, ora_1.default)('Checking for orphaned SSH configs...').start();
|
|
61
|
+
const sshEntries = (0, ssh_config_1.getAllSshConfigEntries)();
|
|
62
|
+
if (sshEntries.length === 0) {
|
|
63
|
+
spinner.info(chalk_1.default.dim('No genbox SSH config entries found'));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
spinner.text = `Found ${sshEntries.length} SSH config entries, checking against API...`;
|
|
67
|
+
const removed = await cleanupOrphanedSshConfigs();
|
|
68
|
+
if (removed.length === 0) {
|
|
69
|
+
spinner.succeed(chalk_1.default.dim('No orphaned SSH configs found'));
|
|
70
|
+
if (!options.quiet) {
|
|
71
|
+
console.log(chalk_1.default.dim(` ${sshEntries.length} SSH config entries are all valid`));
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
spinner.succeed(chalk_1.default.green(`Cleaned up ${removed.length} orphaned SSH config${removed.length === 1 ? '' : 's'}`));
|
|
76
|
+
if (!options.quiet) {
|
|
77
|
+
console.log('');
|
|
78
|
+
console.log(chalk_1.default.dim('Removed entries for:'));
|
|
79
|
+
for (const name of removed) {
|
|
80
|
+
console.log(chalk_1.default.dim(` - ${name}`));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (error instanceof api_1.AuthenticationError) {
|
|
86
|
+
(0, api_1.handleApiError)(error);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
console.error(chalk_1.default.red(`Error: ${error.message}`));
|
|
90
|
+
}
|
|
91
|
+
});
|
package/dist/commands/destroy.js
CHANGED
|
@@ -234,6 +234,10 @@ async function triggerSaveWork(genbox) {
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
|
+
// Display Claude history backup status
|
|
238
|
+
if (result.claudeHistoryBackedUp) {
|
|
239
|
+
console.log(` ${chalk_1.default.green('✓')} Claude history backed up to database`);
|
|
240
|
+
}
|
|
237
241
|
return result;
|
|
238
242
|
}
|
|
239
243
|
catch (error) {
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
3
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
7
|
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
5
9
|
const init_1 = require("./commands/init");
|
|
10
|
+
const cleanup_ssh_1 = require("./commands/cleanup-ssh");
|
|
11
|
+
/**
|
|
12
|
+
* Auto-cleanup orphaned SSH configs on startup (non-blocking, silent)
|
|
13
|
+
* This runs in the background without affecting CLI startup time
|
|
14
|
+
*/
|
|
15
|
+
function autoCleanupSshConfigs() {
|
|
16
|
+
// Run cleanup in background - don't await, don't block startup
|
|
17
|
+
(0, cleanup_ssh_1.cleanupOrphanedSshConfigs)({ silent: true })
|
|
18
|
+
.then(removed => {
|
|
19
|
+
// Optionally log if GENBOX_DEBUG is set
|
|
20
|
+
if (process.env.GENBOX_DEBUG && removed.length > 0) {
|
|
21
|
+
console.error(chalk_1.default.dim(`[Auto-cleanup] Removed ${removed.length} orphaned SSH config(s): ${removed.join(', ')}`));
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
.catch(() => {
|
|
25
|
+
// Silently ignore errors - this is a background cleanup
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// Run auto-cleanup on startup (non-blocking)
|
|
29
|
+
autoCleanupSshConfigs();
|
|
6
30
|
const program = new commander_1.Command();
|
|
7
31
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
8
32
|
const { version } = require('../package.json');
|
|
@@ -31,6 +55,7 @@ const migrate_1 = require("./commands/migrate");
|
|
|
31
55
|
const ssh_setup_1 = require("./commands/ssh-setup");
|
|
32
56
|
const rebuild_1 = require("./commands/rebuild");
|
|
33
57
|
const extend_1 = require("./commands/extend");
|
|
58
|
+
const cleanup_ssh_2 = require("./commands/cleanup-ssh");
|
|
34
59
|
program
|
|
35
60
|
.addCommand(init_1.initCommand)
|
|
36
61
|
.addCommand(create_1.createCommand)
|
|
@@ -54,5 +79,6 @@ program
|
|
|
54
79
|
.addCommand(migrate_1.deprecationsCommand)
|
|
55
80
|
.addCommand(ssh_setup_1.sshSetupCommand)
|
|
56
81
|
.addCommand(rebuild_1.rebuildCommand)
|
|
57
|
-
.addCommand(extend_1.extendCommand)
|
|
82
|
+
.addCommand(extend_1.extendCommand)
|
|
83
|
+
.addCommand(cleanup_ssh_2.cleanupSshCommand);
|
|
58
84
|
program.parse(process.argv);
|
package/dist/ssh-config.js
CHANGED
|
@@ -38,6 +38,7 @@ exports.removeSshConfigEntry = removeSshConfigEntry;
|
|
|
38
38
|
exports.updateSshConfigEntry = updateSshConfigEntry;
|
|
39
39
|
exports.hasSshConfigEntry = hasSshConfigEntry;
|
|
40
40
|
exports.getSshAlias = getSshAlias;
|
|
41
|
+
exports.getAllSshConfigEntries = getAllSshConfigEntries;
|
|
41
42
|
const fs = __importStar(require("fs"));
|
|
42
43
|
const path = __importStar(require("path"));
|
|
43
44
|
const os = __importStar(require("os"));
|
|
@@ -214,3 +215,23 @@ function hasSshConfigEntry(name) {
|
|
|
214
215
|
function getSshAlias(name) {
|
|
215
216
|
return `genbox-${name}`;
|
|
216
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Get all Genbox SSH config entries from ~/.ssh/config
|
|
220
|
+
* Returns array of genbox names that have SSH config entries
|
|
221
|
+
*/
|
|
222
|
+
function getAllSshConfigEntries() {
|
|
223
|
+
try {
|
|
224
|
+
const config = readSshConfig();
|
|
225
|
+
const entries = [];
|
|
226
|
+
// Find all genbox markers
|
|
227
|
+
const regex = new RegExp(`${GENBOX_MARKER_START} (.+)`, 'g');
|
|
228
|
+
let match;
|
|
229
|
+
while ((match = regex.exec(config)) !== null) {
|
|
230
|
+
entries.push(match[1]);
|
|
231
|
+
}
|
|
232
|
+
return entries;
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
}
|