genbox 1.0.129 → 1.0.130

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.
@@ -0,0 +1,635 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.completionCommand = void 0;
40
+ exports.isCompletionInstalledForCurrentShell = isCompletionInstalledForCurrentShell;
41
+ exports.getCompletionHint = getCompletionHint;
42
+ const commander_1 = require("commander");
43
+ const chalk_1 = __importDefault(require("chalk"));
44
+ const os = __importStar(require("os"));
45
+ const path = __importStar(require("path"));
46
+ const fs = __importStar(require("fs"));
47
+ // Get all command names for completion
48
+ const commands = [
49
+ 'init', 'create', 'list', 'ls', 'destroy', 'delete', 'connect', 'balance',
50
+ 'login', 'urls', 'push', 'status', 'forward', 'restore-db', 'help',
51
+ 'profiles', 'db', 'config', 'resolve', 'validate', 'rebuild', 'extend',
52
+ 'cleanup-ssh', 'restart', 'backup', 'backups', 'stop', 'start', 'resume',
53
+ 'template', 'run-prompt', 'run', 'completion'
54
+ ];
55
+ // Marker comment to identify our completion setup
56
+ const COMPLETION_MARKER = '# Genbox CLI completion';
57
+ function getShellConfig(shell) {
58
+ const home = os.homedir();
59
+ switch (shell) {
60
+ case 'bash':
61
+ // Check for .bashrc first, then .bash_profile (macOS default)
62
+ const bashrc = path.join(home, '.bashrc');
63
+ const bashProfile = path.join(home, '.bash_profile');
64
+ const configFile = fs.existsSync(bashrc) ? bashrc : bashProfile;
65
+ return {
66
+ configFile,
67
+ evalCommand: 'eval "$(gb completion bash)"',
68
+ reloadCommand: `source ${configFile}`,
69
+ };
70
+ case 'zsh':
71
+ return {
72
+ configFile: path.join(home, '.zshrc'),
73
+ evalCommand: 'eval "$(gb completion zsh)"',
74
+ reloadCommand: 'source ~/.zshrc',
75
+ };
76
+ case 'fish':
77
+ const fishCompletionsDir = path.join(home, '.config', 'fish', 'completions');
78
+ return {
79
+ configFile: path.join(fishCompletionsDir, 'gb.fish'),
80
+ evalCommand: '', // Fish doesn't use eval, we write directly to completions file
81
+ reloadCommand: '', // Fish auto-loads from completions directory
82
+ };
83
+ default:
84
+ return null;
85
+ }
86
+ }
87
+ function isCompletionInstalled(shell, config) {
88
+ if (shell === 'fish') {
89
+ // For fish, check if the completions file exists
90
+ return fs.existsSync(config.configFile);
91
+ }
92
+ // For bash/zsh, check if the config file contains our completion command
93
+ if (!fs.existsSync(config.configFile)) {
94
+ return false;
95
+ }
96
+ const content = fs.readFileSync(config.configFile, 'utf8');
97
+ return content.includes('gb completion') || content.includes(COMPLETION_MARKER);
98
+ }
99
+ function installCompletion(shell, config) {
100
+ try {
101
+ if (shell === 'fish') {
102
+ // For fish, create the completions directory if needed and write the file
103
+ const fishDir = path.dirname(config.configFile);
104
+ if (!fs.existsSync(fishDir)) {
105
+ fs.mkdirSync(fishDir, { recursive: true });
106
+ }
107
+ fs.writeFileSync(config.configFile, generateFishCompletion());
108
+ return {
109
+ success: true,
110
+ message: `Completions installed to ${config.configFile}`,
111
+ };
112
+ }
113
+ // For bash/zsh, append to config file
114
+ const completionBlock = `
115
+ ${COMPLETION_MARKER}
116
+ ${config.evalCommand}
117
+ `;
118
+ // Create config file if it doesn't exist
119
+ if (!fs.existsSync(config.configFile)) {
120
+ fs.writeFileSync(config.configFile, completionBlock);
121
+ }
122
+ else {
123
+ fs.appendFileSync(config.configFile, completionBlock);
124
+ }
125
+ return {
126
+ success: true,
127
+ message: `Completions added to ${config.configFile}`,
128
+ };
129
+ }
130
+ catch (error) {
131
+ return {
132
+ success: false,
133
+ message: error.message,
134
+ };
135
+ }
136
+ }
137
+ function generateBashCompletion() {
138
+ return `# Bash completion for genbox/gb
139
+ # Add to ~/.bashrc or ~/.bash_profile:
140
+ # eval "$(gb completion bash)"
141
+ # Or save to a file:
142
+ # gb completion bash > /etc/bash_completion.d/gb
143
+
144
+ _genbox_completions() {
145
+ local cur prev commands
146
+ COMPREPLY=()
147
+ cur="\${COMP_WORDS[COMP_CWORD]}"
148
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
149
+
150
+ # Main commands
151
+ commands="${commands.join(' ')}"
152
+
153
+ # Subcommands for grouped commands
154
+ local db_commands="sync restore snapshots"
155
+ local config_commands="show diff"
156
+ local template_commands="build list status delete"
157
+ local profiles_commands="list"
158
+ local backups_commands="list restore delete"
159
+
160
+ case "\${prev}" in
161
+ genbox|gb)
162
+ COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
163
+ return 0
164
+ ;;
165
+ db)
166
+ COMPREPLY=( $(compgen -W "\${db_commands}" -- "\${cur}") )
167
+ return 0
168
+ ;;
169
+ config)
170
+ COMPREPLY=( $(compgen -W "\${config_commands}" -- "\${cur}") )
171
+ return 0
172
+ ;;
173
+ template)
174
+ COMPREPLY=( $(compgen -W "\${template_commands}" -- "\${cur}") )
175
+ return 0
176
+ ;;
177
+ profiles)
178
+ COMPREPLY=( $(compgen -W "\${profiles_commands}" -- "\${cur}") )
179
+ return 0
180
+ ;;
181
+ backups)
182
+ COMPREPLY=( $(compgen -W "\${backups_commands}" -- "\${cur}") )
183
+ return 0
184
+ ;;
185
+ completion)
186
+ COMPREPLY=( $(compgen -W "bash zsh fish --install" -- "\${cur}") )
187
+ return 0
188
+ ;;
189
+ # Commands that take genbox names - could be enhanced with dynamic completion
190
+ create|destroy|delete|connect|status|urls|forward|push|restart|stop|start|resume|extend|rebuild|run|run-prompt)
191
+ # For now, no completion for genbox names (would need API call)
192
+ return 0
193
+ ;;
194
+ -s|--size)
195
+ COMPREPLY=( $(compgen -W "small medium large xl" -- "\${cur}") )
196
+ return 0
197
+ ;;
198
+ -p|--profile)
199
+ # Profile names would need to be read from config
200
+ return 0
201
+ ;;
202
+ --db)
203
+ COMPREPLY=( $(compgen -W "none fresh copy remote" -- "\${cur}") )
204
+ return 0
205
+ ;;
206
+ --db-source)
207
+ COMPREPLY=( $(compgen -W "staging production" -- "\${cur}") )
208
+ return 0
209
+ ;;
210
+ esac
211
+
212
+ # Option completion
213
+ if [[ "\${cur}" == -* ]]; then
214
+ local opts="--help -h"
215
+ case "\${COMP_WORDS[1]}" in
216
+ create)
217
+ opts="--help -h --profile -p --apps -a --add-apps --api --db --db-source --db-dump --db-copy-remote --size -s --branch -b --new-branch -n --from-branch -f --yes -y --dry-run --restore -r --inject-claude-auth"
218
+ ;;
219
+ list|ls)
220
+ opts="--help -h --all -a --terminated"
221
+ ;;
222
+ destroy|delete)
223
+ opts="--help -h --yes -y --all -a --save-changes"
224
+ ;;
225
+ status)
226
+ opts="--help -h --all -a --watch -w"
227
+ ;;
228
+ connect)
229
+ opts="--help -h --all -a"
230
+ ;;
231
+ forward)
232
+ opts="--help -h --ports -p --all -a"
233
+ ;;
234
+ extend)
235
+ opts="--help -h --hours --disable-auto-destroy --enable-auto-destroy --all -a"
236
+ ;;
237
+ rebuild)
238
+ opts="--help -h --yes -y --all -a"
239
+ ;;
240
+ stop)
241
+ opts="--help -h --yes -y --all -a"
242
+ ;;
243
+ start|resume)
244
+ opts="--help -h --all -a"
245
+ ;;
246
+ completion)
247
+ opts="--help -h --install"
248
+ ;;
249
+ esac
250
+ COMPREPLY=( $(compgen -W "\${opts}" -- "\${cur}") )
251
+ return 0
252
+ fi
253
+ }
254
+
255
+ complete -F _genbox_completions genbox
256
+ complete -F _genbox_completions gb
257
+ `;
258
+ }
259
+ function generateZshCompletion() {
260
+ return `#compdef genbox gb
261
+ # Zsh completion for genbox/gb
262
+ # Add to ~/.zshrc:
263
+ # eval "$(gb completion zsh)"
264
+ # Or save to a file in your fpath:
265
+ # gb completion zsh > ~/.zsh/completions/_gb
266
+
267
+ _genbox() {
268
+ local -a commands
269
+ commands=(
270
+ 'init:Initialize genbox.yaml configuration'
271
+ 'create:Create a new Genbox environment'
272
+ 'list:List genboxes'
273
+ 'ls:List genboxes (alias)'
274
+ 'destroy:Destroy a Genbox'
275
+ 'delete:Destroy a Genbox (alias)'
276
+ 'connect:SSH into a Genbox'
277
+ 'status:Check Genbox status'
278
+ 'urls:Show service URLs'
279
+ 'forward:Set up port forwarding'
280
+ 'push:Push local changes'
281
+ 'restore-db:Restore database to Genbox'
282
+ 'balance:Show credit balance'
283
+ 'login:Authenticate with Genbox'
284
+ 'help:Show detailed help'
285
+ 'profiles:Manage profiles'
286
+ 'db:Database operations'
287
+ 'config:Configuration commands'
288
+ 'template:Manage templates'
289
+ 'rebuild:Rebuild a Genbox'
290
+ 'extend:Extend Genbox lifetime'
291
+ 'restart:Restart services'
292
+ 'stop:Stop a Genbox'
293
+ 'start:Start a stopped Genbox'
294
+ 'resume:Start a stopped Genbox (alias)'
295
+ 'backup:Create a backup'
296
+ 'backups:Manage backups'
297
+ 'cleanup-ssh:Clean up SSH config'
298
+ 'run-prompt:Run Claude Code prompt'
299
+ 'run:Run Claude Code prompt (alias)'
300
+ 'completion:Generate shell completions'
301
+ )
302
+
303
+ local -a db_commands
304
+ db_commands=(
305
+ 'sync:Sync database from staging/production'
306
+ 'restore:Restore from snapshot'
307
+ 'snapshots:List snapshots'
308
+ )
309
+
310
+ local -a config_commands
311
+ config_commands=(
312
+ 'show:Show configuration'
313
+ 'diff:Compare profiles'
314
+ )
315
+
316
+ local -a template_commands
317
+ template_commands=(
318
+ 'build:Build a template'
319
+ 'list:List templates'
320
+ 'status:Check template status'
321
+ 'delete:Delete a template'
322
+ )
323
+
324
+ local -a sizes
325
+ sizes=('small' 'medium' 'large' 'xl')
326
+
327
+ local -a db_modes
328
+ db_modes=('none' 'fresh' 'copy' 'remote')
329
+
330
+ local -a db_sources
331
+ db_sources=('staging' 'production')
332
+
333
+ _arguments -C \\
334
+ '(-h --help)'{-h,--help}'[Show help]' \\
335
+ '(-v --version)'{-v,--version}'[Show version]' \\
336
+ '1: :->command' \\
337
+ '*:: :->args'
338
+
339
+ case $state in
340
+ command)
341
+ _describe -t commands 'genbox command' commands
342
+ ;;
343
+ args)
344
+ case $words[1] in
345
+ db)
346
+ _describe -t commands 'db command' db_commands
347
+ ;;
348
+ config)
349
+ _describe -t commands 'config command' config_commands
350
+ ;;
351
+ template)
352
+ _describe -t commands 'template command' template_commands
353
+ ;;
354
+ completion)
355
+ _arguments \\
356
+ '--install[Install completions to shell config]' \\
357
+ '1:shell:(bash zsh fish)'
358
+ ;;
359
+ create)
360
+ _arguments \\
361
+ '(-p --profile)'{-p,--profile}'[Use profile]:profile:' \\
362
+ '(-a --apps)'{-a,--apps}'[Apps to include]:apps:' \\
363
+ '--add-apps[Add apps to profile]:apps:' \\
364
+ '--api[API mode]:mode:(local staging production)' \\
365
+ '--db[Database mode]:mode:(none fresh copy remote)' \\
366
+ '--db-source[Database source]:source:(staging production)' \\
367
+ '--db-dump[Use existing dump]:file:_files' \\
368
+ '--db-copy-remote[Copy database on server]' \\
369
+ '(-s --size)'{-s,--size}'[Server size]:size:(small medium large xl)' \\
370
+ '(-b --branch)'{-b,--branch}'[Use existing branch]:branch:' \\
371
+ '(-n --new-branch)'{-n,--new-branch}'[Create new branch]:name:' \\
372
+ '(-f --from-branch)'{-f,--from-branch}'[Source branch]:branch:' \\
373
+ '(-y --yes)'{-y,--yes}'[Skip prompts]' \\
374
+ '--dry-run[Show what would be created]' \\
375
+ '(-r --restore)'{-r,--restore}'[Restore from backup]' \\
376
+ '--inject-claude-auth[Inject Claude credentials]' \\
377
+ '1:name:'
378
+ ;;
379
+ list|ls)
380
+ _arguments \\
381
+ '(-a --all)'{-a,--all}'[Show all genboxes]' \\
382
+ '--terminated[Include terminated]'
383
+ ;;
384
+ destroy|delete)
385
+ _arguments \\
386
+ '(-y --yes)'{-y,--yes}'[Skip confirmation]' \\
387
+ '(-a --all)'{-a,--all}'[Bulk delete mode]' \\
388
+ '--save-changes[Handle changes]:action:(save trash skip)' \\
389
+ '1:name:'
390
+ ;;
391
+ status)
392
+ _arguments \\
393
+ '(-a --all)'{-a,--all}'[Select from all]' \\
394
+ '(-w --watch)'{-w,--watch}'[Watch mode]' \\
395
+ '1:name:'
396
+ ;;
397
+ connect|urls|restart|stop)
398
+ _arguments \\
399
+ '(-a --all)'{-a,--all}'[Select from all]' \\
400
+ '1:name:'
401
+ ;;
402
+ start|resume)
403
+ _arguments \\
404
+ '(-a --all)'{-a,--all}'[Select from all]' \\
405
+ '1:name:'
406
+ ;;
407
+ forward)
408
+ _arguments \\
409
+ '(-a --all)'{-a,--all}'[Select from all]' \\
410
+ '(-p --ports)'{-p,--ports}'[Additional ports]:ports:' \\
411
+ '1:name:'
412
+ ;;
413
+ extend)
414
+ _arguments \\
415
+ '(-a --all)'{-a,--all}'[Select from all]' \\
416
+ '--hours[Hours to extend]:hours:' \\
417
+ '--disable-auto-destroy[Disable auto-destroy]' \\
418
+ '--enable-auto-destroy[Enable auto-destroy]' \\
419
+ '1:name:'
420
+ ;;
421
+ rebuild)
422
+ _arguments \\
423
+ '(-a --all)'{-a,--all}'[Select from all]' \\
424
+ '(-y --yes)'{-y,--yes}'[Skip confirmation]' \\
425
+ '1:name:'
426
+ ;;
427
+ help)
428
+ _values 'command' init create status connect forward restore-db urls push destroy
429
+ ;;
430
+ esac
431
+ ;;
432
+ esac
433
+ }
434
+
435
+ compdef _genbox genbox gb
436
+ `;
437
+ }
438
+ function generateFishCompletion() {
439
+ return `# Fish completion for genbox/gb
440
+ # Save to ~/.config/fish/completions/gb.fish:
441
+ # gb completion fish > ~/.config/fish/completions/gb.fish
442
+ # Or install automatically:
443
+ # gb completion fish --install
444
+
445
+ # Disable file completion by default
446
+ complete -c genbox -f
447
+ complete -c gb -f
448
+
449
+ # Main commands
450
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "init" -d "Initialize genbox.yaml configuration"
451
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "create" -d "Create a new Genbox environment"
452
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "list ls" -d "List genboxes"
453
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "destroy delete" -d "Destroy a Genbox"
454
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "connect" -d "SSH into a Genbox"
455
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "status" -d "Check Genbox status"
456
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "urls" -d "Show service URLs"
457
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "forward" -d "Set up port forwarding"
458
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "push" -d "Push local changes"
459
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "restore-db" -d "Restore database"
460
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "balance" -d "Show credit balance"
461
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "login" -d "Authenticate"
462
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "help" -d "Show detailed help"
463
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "profiles" -d "Manage profiles"
464
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "db" -d "Database operations"
465
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "config" -d "Configuration commands"
466
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "template" -d "Manage templates"
467
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "rebuild" -d "Rebuild a Genbox"
468
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "extend" -d "Extend Genbox lifetime"
469
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "restart" -d "Restart services"
470
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "stop" -d "Stop a Genbox"
471
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "start resume" -d "Start a stopped Genbox"
472
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "backup" -d "Create a backup"
473
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "backups" -d "Manage backups"
474
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "cleanup-ssh" -d "Clean up SSH config"
475
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "run-prompt run" -d "Run Claude Code prompt"
476
+ complete -c genbox -c gb -n "__fish_use_subcommand" -a "completion" -d "Generate shell completions"
477
+
478
+ # Subcommands for db
479
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from db" -a "sync" -d "Sync database"
480
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from db" -a "restore" -d "Restore from snapshot"
481
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from db" -a "snapshots" -d "List snapshots"
482
+
483
+ # Subcommands for config
484
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from config" -a "show" -d "Show configuration"
485
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from config" -a "diff" -d "Compare profiles"
486
+
487
+ # Subcommands for template
488
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from template" -a "build" -d "Build template"
489
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from template" -a "list" -d "List templates"
490
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from template" -a "status" -d "Check status"
491
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from template" -a "delete" -d "Delete template"
492
+
493
+ # Subcommands for completion
494
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from completion" -a "bash" -d "Bash completion"
495
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from completion" -a "zsh" -d "Zsh completion"
496
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from completion" -a "fish" -d "Fish completion"
497
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from completion" -l install -d "Install completions"
498
+
499
+ # Options for create
500
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -s p -l profile -d "Use profile"
501
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -s a -l apps -d "Apps to include"
502
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -l add-apps -d "Add apps to profile"
503
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -l api -d "API mode" -a "local staging production"
504
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -l db -d "Database mode" -a "none fresh copy remote"
505
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -l db-source -d "Database source" -a "staging production"
506
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -l db-dump -d "Use existing dump" -r
507
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -l db-copy-remote -d "Copy database on server"
508
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -s s -l size -d "Server size" -a "small medium large xl"
509
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -s b -l branch -d "Use existing branch"
510
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -s n -l new-branch -d "Create new branch"
511
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -s f -l from-branch -d "Source branch"
512
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -s y -l yes -d "Skip prompts"
513
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -l dry-run -d "Show what would be created"
514
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -s r -l restore -d "Restore from backup"
515
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from create" -l inject-claude-auth -d "Inject Claude credentials"
516
+
517
+ # Options for list
518
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from list ls" -s a -l all -d "Show all genboxes"
519
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from list ls" -l terminated -d "Include terminated"
520
+
521
+ # Options for destroy
522
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from destroy delete" -s y -l yes -d "Skip confirmation"
523
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from destroy delete" -s a -l all -d "Bulk delete mode"
524
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from destroy delete" -l save-changes -d "Handle changes" -a "save trash skip"
525
+
526
+ # Options for status
527
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from status" -s a -l all -d "Select from all"
528
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from status" -s w -l watch -d "Watch mode"
529
+
530
+ # Options for extend
531
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from extend" -s a -l all -d "Select from all"
532
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from extend" -l hours -d "Hours to extend"
533
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from extend" -l disable-auto-destroy -d "Disable auto-destroy"
534
+ complete -c genbox -c gb -n "__fish_seen_subcommand_from extend" -l enable-auto-destroy -d "Enable auto-destroy"
535
+
536
+ # Global options
537
+ complete -c genbox -c gb -s h -l help -d "Show help"
538
+ complete -c genbox -c gb -s v -l version -d "Show version"
539
+ `;
540
+ }
541
+ exports.completionCommand = new commander_1.Command('completion')
542
+ .description('Generate shell completion scripts')
543
+ .argument('<shell>', 'Shell type: bash, zsh, or fish')
544
+ .option('--install', 'Install completions to your shell config file')
545
+ .addHelpText('after', `
546
+ Examples:
547
+ ${chalk_1.default.dim('# Generate and manually add to config')}
548
+ ${chalk_1.default.cyan('eval "$(gb completion bash)"')} ${chalk_1.default.dim('# Add to ~/.bashrc')}
549
+ ${chalk_1.default.cyan('eval "$(gb completion zsh)"')} ${chalk_1.default.dim('# Add to ~/.zshrc')}
550
+
551
+ ${chalk_1.default.dim('# Auto-install to shell config')}
552
+ ${chalk_1.default.cyan('gb completion bash --install')}
553
+ ${chalk_1.default.cyan('gb completion zsh --install')}
554
+ ${chalk_1.default.cyan('gb completion fish --install')}
555
+ `)
556
+ .action((shell, options) => {
557
+ const shellLower = shell.toLowerCase();
558
+ // Validate shell
559
+ if (!['bash', 'zsh', 'fish'].includes(shellLower)) {
560
+ console.error(chalk_1.default.red(`Unknown shell: ${shell}`));
561
+ console.error(chalk_1.default.dim('Supported shells: bash, zsh, fish'));
562
+ process.exit(1);
563
+ }
564
+ // If --install flag, install completions
565
+ if (options.install) {
566
+ const config = getShellConfig(shellLower);
567
+ if (!config) {
568
+ console.error(chalk_1.default.red(`Cannot determine config file for ${shell}`));
569
+ process.exit(1);
570
+ }
571
+ // Check if already installed
572
+ if (isCompletionInstalled(shellLower, config)) {
573
+ console.log(chalk_1.default.yellow(`Completions already installed for ${shell}`));
574
+ console.log(chalk_1.default.dim(` Config: ${config.configFile}`));
575
+ return;
576
+ }
577
+ // Install
578
+ const result = installCompletion(shellLower, config);
579
+ if (result.success) {
580
+ console.log(chalk_1.default.green(`✓ ${result.message}`));
581
+ console.log('');
582
+ if (shellLower === 'fish') {
583
+ console.log(chalk_1.default.dim('Completions will be available in new Fish sessions.'));
584
+ }
585
+ else {
586
+ console.log(chalk_1.default.dim('To activate now, run:'));
587
+ console.log(chalk_1.default.cyan(` ${config.reloadCommand}`));
588
+ }
589
+ console.log('');
590
+ console.log(chalk_1.default.dim('Or restart your terminal.'));
591
+ }
592
+ else {
593
+ console.error(chalk_1.default.red(`Failed to install: ${result.message}`));
594
+ process.exit(1);
595
+ }
596
+ return;
597
+ }
598
+ // Otherwise, just output the completion script
599
+ switch (shellLower) {
600
+ case 'bash':
601
+ console.log(generateBashCompletion());
602
+ break;
603
+ case 'zsh':
604
+ console.log(generateZshCompletion());
605
+ break;
606
+ case 'fish':
607
+ console.log(generateFishCompletion());
608
+ break;
609
+ }
610
+ });
611
+ // Detect current shell name
612
+ function detectShell() {
613
+ const shell = process.env.SHELL || '';
614
+ if (shell.includes('bash'))
615
+ return 'bash';
616
+ if (shell.includes('fish'))
617
+ return 'fish';
618
+ if (shell.includes('zsh'))
619
+ return 'zsh';
620
+ return 'zsh'; // Default to zsh
621
+ }
622
+ // Export helper for login command to check if completions are installed
623
+ function isCompletionInstalledForCurrentShell() {
624
+ const shellName = detectShell();
625
+ const config = getShellConfig(shellName);
626
+ if (!config)
627
+ return false;
628
+ return isCompletionInstalled(shellName, config);
629
+ }
630
+ // Export helper for login command to show completion hint
631
+ function getCompletionHint() {
632
+ const shellName = detectShell();
633
+ return `${chalk_1.default.dim('Enable tab completion for a better experience:')}
634
+ ${chalk_1.default.cyan(`gb completion ${shellName} --install`)}`;
635
+ }
@@ -71,11 +71,20 @@ exports.listCommand = new commander_1.Command('list')
71
71
  // Show project info when listing all
72
72
  const projectSuffix = options.all && genbox.project ? ` [${genbox.project}]` : '';
73
73
  const nameWithProject = genbox.name + projectSuffix;
74
+ // Determine auto-destroy status first (needed for hour end coloring)
75
+ const now = new Date();
76
+ const minutesInactive = genbox.lastActivityAt
77
+ ? Math.floor((now.getTime() - new Date(genbox.lastActivityAt).getTime()) / (60 * 1000))
78
+ : 999; // Assume inactive if no activity data
79
+ // Check if auto-destroy will actually happen
80
+ const isProtectedPermanently = genbox.autoDestroyOnInactivity === false;
81
+ const isProtectedTemporarily = genbox.protectedUntil && new Date(genbox.protectedUntil).getTime() > now.getTime();
82
+ const isAutoDestroyPaused = minutesInactive < 5;
83
+ const willAutoDestroy = !isProtectedPermanently && !isProtectedTemporarily && !isAutoDestroyPaused;
74
84
  // Format end hour as relative time (destroy happens at 58 min mark, not 60)
75
85
  let endHourInfo = '';
76
86
  if (genbox.currentHourEnd && genbox.status === 'running') {
77
87
  const endTime = new Date(genbox.currentHourEnd);
78
- const now = new Date();
79
88
  // Subtract 2 minutes since auto-destroy happens at 58 min mark
80
89
  const destroyTime = endTime.getTime() - (2 * 60 * 1000);
81
90
  const diffMs = destroyTime - now.getTime();
@@ -86,17 +95,20 @@ exports.listCommand = new commander_1.Command('list')
86
95
  const timeStr = mins > 0
87
96
  ? `${mins}m:${secs.toString().padStart(2, '0')}s`
88
97
  : `${secs}s`;
89
- // Red color if less than 5 minutes
90
- if (mins < 5) {
98
+ // Red color only if less than 5 minutes AND auto-destroy will actually happen
99
+ if (mins < 5 && willAutoDestroy) {
91
100
  endHourInfo = chalk_1.default.red(` hour ends in ${timeStr}`);
92
101
  }
93
102
  else {
94
103
  endHourInfo = chalk_1.default.dim(` hour ends in ${timeStr}`);
95
104
  }
96
105
  }
97
- else {
106
+ else if (willAutoDestroy) {
98
107
  endHourInfo = chalk_1.default.red(' hour ending...');
99
108
  }
109
+ else {
110
+ endHourInfo = chalk_1.default.dim(' hour ending...');
111
+ }
100
112
  }
101
113
  // Show auto-destroy status (not applicable for stopped/terminated)
102
114
  let protectedInfo = '';
@@ -142,7 +154,6 @@ exports.listCommand = new commander_1.Command('list')
142
154
  }
143
155
  else if (genbox.protectedUntil) {
144
156
  const protectedUntil = new Date(genbox.protectedUntil);
145
- const now = new Date();
146
157
  const diffMs = protectedUntil.getTime() - now.getTime();
147
158
  const hoursRemaining = Math.ceil(diffMs / (1000 * 60 * 60));
148
159
  if (hoursRemaining > 0) {
@@ -154,10 +165,6 @@ exports.listCommand = new commander_1.Command('list')
154
165
  }
155
166
  else {
156
167
  // Check if auto-destroy is paused due to recent activity
157
- const now = new Date();
158
- const minutesInactive = genbox.lastActivityAt
159
- ? Math.floor((now.getTime() - new Date(genbox.lastActivityAt).getTime()) / (60 * 1000))
160
- : 999; // Assume inactive if no activity data
161
168
  if (minutesInactive < 5) {
162
169
  protectedInfo = chalk_1.default.green(' [auto-destroy paused]');
163
170
  }
@@ -9,6 +9,7 @@ const chalk_1 = __importDefault(require("chalk"));
9
9
  const inquirer_1 = __importDefault(require("inquirer"));
10
10
  const api_1 = require("../api");
11
11
  const config_store_1 = require("../config-store");
12
+ const completion_1 = require("./completion");
12
13
  exports.loginCommand = new commander_1.Command('login')
13
14
  .description('Login to Genbox')
14
15
  .action(async () => {
@@ -38,7 +39,12 @@ exports.loginCommand = new commander_1.Command('login')
38
39
  user: response.user,
39
40
  },
40
41
  });
41
- console.log(chalk_1.default.green('Successfully logged in!'));
42
+ console.log(chalk_1.default.green('Successfully logged in!'));
43
+ // Show completion hint if not already installed
44
+ if (!(0, completion_1.isCompletionInstalledForCurrentShell)()) {
45
+ console.log('');
46
+ console.log((0, completion_1.getCompletionHint)());
47
+ }
42
48
  }
43
49
  else {
44
50
  console.error(chalk_1.default.red('Login failed: No token received.'));
package/dist/index.js CHANGED
@@ -1,15 +1,12 @@
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");
6
- const program = new commander_1.Command();
7
- // eslint-disable-next-line @typescript-eslint/no-var-requires
8
- const { version } = require('../package.json');
9
- program
10
- .name('genbox')
11
- .description('Genbox CLI - AI-Powered Development Environments\n\nTIP: Use "gb" as a shorthand (e.g., gb list, gb create)')
12
- .version(version, '-v, --version', 'Output the current version');
13
10
  const create_1 = require("./commands/create");
14
11
  const list_1 = require("./commands/list");
15
12
  const destroy_1 = require("./commands/destroy");
@@ -39,6 +36,127 @@ const stop_1 = require("./commands/stop");
39
36
  const start_1 = require("./commands/start");
40
37
  const template_1 = require("./commands/template");
41
38
  const run_prompt_1 = require("./commands/run-prompt");
39
+ const completion_1 = require("./commands/completion");
40
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
41
+ const { version } = require('../package.json');
42
+ const commandCategories = {
43
+ 'CORE COMMANDS': [
44
+ { name: 'create', aliases: [], description: 'Create a new Genbox environment' },
45
+ { name: 'list', aliases: ['ls'], description: 'List genboxes' },
46
+ { name: 'destroy', aliases: ['delete'], description: 'Destroy a Genbox' },
47
+ { name: 'connect', aliases: [], description: 'SSH into a Genbox' },
48
+ { name: 'status', aliases: [], description: 'Check Genbox status and services' },
49
+ ],
50
+ 'LIFECYCLE': [
51
+ { name: 'start', aliases: ['resume'], description: 'Start a stopped Genbox' },
52
+ { name: 'stop', aliases: [], description: 'Stop a running Genbox' },
53
+ { name: 'restart', aliases: [], description: 'Restart services in a Genbox' },
54
+ { name: 'extend', aliases: [], description: 'Extend Genbox lifetime' },
55
+ { name: 'rebuild', aliases: [], description: 'Rebuild a Genbox with new config' },
56
+ ],
57
+ 'DEVELOPMENT': [
58
+ { name: 'urls', aliases: [], description: 'Show service URLs' },
59
+ { name: 'forward', aliases: [], description: 'Set up port forwarding' },
60
+ { name: 'push', aliases: [], description: 'Push local changes' },
61
+ { name: 'run-prompt', aliases: ['run'], description: 'Run Claude Code prompt remotely' },
62
+ ],
63
+ 'DATABASE': [
64
+ { name: 'db', aliases: [], description: 'Database operations (sync, restore, snapshots)' },
65
+ { name: 'restore-db', aliases: [], description: 'Restore local MongoDB to Genbox' },
66
+ ],
67
+ 'BACKUP & RESTORE': [
68
+ { name: 'backup', aliases: [], description: 'Create a backup' },
69
+ { name: 'backups', aliases: [], description: 'List and manage backups' },
70
+ { name: 'template', aliases: [], description: 'Manage project templates' },
71
+ ],
72
+ 'CONFIGURATION': [
73
+ { name: 'init', aliases: [], description: 'Initialize genbox.yaml' },
74
+ { name: 'config', aliases: [], description: 'Inspect configuration' },
75
+ { name: 'profiles', aliases: [], description: 'Manage profiles' },
76
+ { name: 'resolve', aliases: [], description: 'Compute final configuration' },
77
+ { name: 'validate', aliases: [], description: 'Validate configuration files' },
78
+ ],
79
+ 'ACCOUNT': [
80
+ { name: 'login', aliases: [], description: 'Authenticate with Genbox' },
81
+ { name: 'balance', aliases: [], description: 'Show credit balance' },
82
+ ],
83
+ 'HELP': [
84
+ { name: 'help', aliases: [], description: 'Show detailed help and examples' },
85
+ { name: 'completion', aliases: [], description: 'Generate shell completions' },
86
+ ],
87
+ };
88
+ function showCustomHelp() {
89
+ const output = [];
90
+ // Header
91
+ output.push('Genbox CLI - AI-Powered Development Environments');
92
+ output.push('');
93
+ output.push(chalk_1.default.green('TIP:') + ' Use ' + chalk_1.default.cyan('"gb"') + ' as a shorthand (e.g., gb list, gb create)');
94
+ output.push('');
95
+ // Usage
96
+ output.push(chalk_1.default.bold('USAGE'));
97
+ output.push(' genbox <command> [options]');
98
+ output.push('');
99
+ // Categorized commands
100
+ for (const [category, commands] of Object.entries(commandCategories)) {
101
+ output.push(chalk_1.default.bold(category));
102
+ for (const cmd of commands) {
103
+ const aliasStr = cmd.aliases.length > 0 ? chalk_1.default.dim(` (${cmd.aliases.join(', ')})`) : '';
104
+ const padding = Math.max(2, 22 - cmd.name.length - (cmd.aliases.length > 0 ? cmd.aliases[0].length + 4 : 0));
105
+ output.push(` ${chalk_1.default.cyan(cmd.name)}${aliasStr}${' '.repeat(padding)}${cmd.description}`);
106
+ }
107
+ output.push('');
108
+ }
109
+ // Global options
110
+ output.push(chalk_1.default.bold('OPTIONS'));
111
+ output.push(` ${chalk_1.default.cyan('-v, --version')} Show version number`);
112
+ output.push(` ${chalk_1.default.cyan('-h, --help')} Show help for command`);
113
+ output.push('');
114
+ // Examples
115
+ output.push(chalk_1.default.bold('EXAMPLES'));
116
+ output.push(chalk_1.default.dim(' # Create a new development environment'));
117
+ output.push(` ${chalk_1.default.cyan('$ gb create feature-auth')}`);
118
+ output.push('');
119
+ output.push(chalk_1.default.dim(' # Check status and wait for setup'));
120
+ output.push(` ${chalk_1.default.cyan('$ gb status -w')}`);
121
+ output.push('');
122
+ output.push(chalk_1.default.dim(' # Connect via SSH'));
123
+ output.push(` ${chalk_1.default.cyan('$ gb connect')}`);
124
+ output.push('');
125
+ output.push(chalk_1.default.dim(' # List all your genboxes'));
126
+ output.push(` ${chalk_1.default.cyan('$ gb list')}`);
127
+ output.push('');
128
+ // More help
129
+ output.push(chalk_1.default.bold('LEARN MORE'));
130
+ output.push(` Run ${chalk_1.default.cyan('gb help')} for detailed guides and workflow examples`);
131
+ output.push(` Run ${chalk_1.default.cyan('gb <command> --help')} for command-specific help`);
132
+ output.push(` Documentation: ${chalk_1.default.cyan('https://genbox.dev/docs')}`);
133
+ output.push('');
134
+ console.log(output.join('\n'));
135
+ }
136
+ const program = new commander_1.Command();
137
+ program
138
+ .name('genbox')
139
+ .description('Genbox CLI - AI-Powered Development Environments')
140
+ .version(version, '-v, --version', 'Show version number')
141
+ .helpOption('-h, --help', 'Show help for command')
142
+ .addHelpCommand(false); // Disable default help subcommand
143
+ // Custom help handler for root command
144
+ program.on('option:help', () => {
145
+ showCustomHelp();
146
+ process.exit(0);
147
+ });
148
+ // Handle --help as first arg (before parsing)
149
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
150
+ // Check if it's for root command (no subcommand before --help)
151
+ const args = process.argv.slice(2);
152
+ const helpIndex = args.findIndex(a => a === '--help' || a === '-h');
153
+ const hasSubcommandBeforeHelp = helpIndex > 0 && !args[0].startsWith('-');
154
+ if (!hasSubcommandBeforeHelp) {
155
+ showCustomHelp();
156
+ process.exit(0);
157
+ }
158
+ }
159
+ // Add all commands
42
160
  program
43
161
  .addCommand(init_1.initCommand)
44
162
  .addCommand(create_1.createCommand)
@@ -58,17 +176,18 @@ program
58
176
  .addCommand(config_1.configCommand)
59
177
  .addCommand(resolve_1.resolveCommand)
60
178
  .addCommand(validate_1.validateCommand)
61
- .addCommand(migrate_1.migrateCommand)
62
- .addCommand(migrate_1.deprecationsCommand)
63
- .addCommand(ssh_setup_1.sshSetupCommand)
179
+ .addCommand(migrate_1.migrateCommand, { hidden: true })
180
+ .addCommand(migrate_1.deprecationsCommand, { hidden: true })
181
+ .addCommand(ssh_setup_1.sshSetupCommand, { hidden: true })
64
182
  .addCommand(rebuild_1.rebuildCommand)
65
183
  .addCommand(extend_1.extendCommand)
66
- .addCommand(cleanup_ssh_1.cleanupSshCommand)
184
+ .addCommand(cleanup_ssh_1.cleanupSshCommand, { hidden: true })
67
185
  .addCommand(restart_1.restartCommand)
68
186
  .addCommand(backup_1.backupCommand)
69
187
  .addCommand(backups_1.backupsCommand)
70
188
  .addCommand(stop_1.stopCommand)
71
189
  .addCommand(start_1.startCommand)
72
190
  .addCommand(template_1.templateCommand)
73
- .addCommand(run_prompt_1.runPromptCommand);
191
+ .addCommand(run_prompt_1.runPromptCommand)
192
+ .addCommand(completion_1.completionCommand);
74
193
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genbox",
3
- "version": "1.0.129",
3
+ "version": "1.0.130",
4
4
  "description": "Genbox CLI - AI-Powered Development Environments",
5
5
  "main": "dist/index.js",
6
6
  "bin": {