genbox 1.0.189 → 1.0.190

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.
@@ -11,6 +11,72 @@ const api_1 = require("../api");
11
11
  const config_store_1 = require("../config-store");
12
12
  const completion_1 = require("./completion");
13
13
  const logo_1 = require("../utils/logo");
14
+ /**
15
+ * Prompt user to claim a username if they don't have one yet
16
+ */
17
+ async function promptForUsername() {
18
+ try {
19
+ // Check if user already has a username
20
+ const usernameInfo = await (0, api_1.fetchApi)('/users/me/username');
21
+ if (usernameInfo.hasUsername) {
22
+ console.log(chalk_1.default.dim(` Username: ${usernameInfo.username}`));
23
+ return;
24
+ }
25
+ console.log('');
26
+ console.log(chalk_1.default.bold('Choose your username'));
27
+ console.log(chalk_1.default.dim('This will be used for your genbox URLs:'));
28
+ console.log(chalk_1.default.dim(' https://{genbox}.app.{username}.genbox.dev'));
29
+ console.log('');
30
+ // Show suggestion
31
+ if (usernameInfo.suggestion && usernameInfo.suggestionAvailable) {
32
+ console.log(chalk_1.default.dim(`Suggested: ${chalk_1.default.cyan(usernameInfo.suggestion)}`));
33
+ }
34
+ const { username } = await inquirer_1.default.prompt([
35
+ {
36
+ type: 'input',
37
+ name: 'username',
38
+ message: 'Username:',
39
+ default: usernameInfo.suggestionAvailable ? usernameInfo.suggestion : undefined,
40
+ validate: async (input) => {
41
+ if (!input || input.trim().length < 3) {
42
+ return 'Username must be at least 3 characters';
43
+ }
44
+ if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/.test(input.toLowerCase())) {
45
+ return 'Username must be lowercase, alphanumeric with hyphens (no start/end hyphen)';
46
+ }
47
+ // Check availability
48
+ try {
49
+ const check = await (0, api_1.fetchApi)(`/usernames/${input}/check`);
50
+ if (!check.available) {
51
+ return check.reason || 'Username is not available';
52
+ }
53
+ }
54
+ catch {
55
+ // If check fails, let server validate
56
+ }
57
+ return true;
58
+ },
59
+ },
60
+ ]);
61
+ // Save username
62
+ const result = await (0, api_1.fetchApi)('/users/me/username', {
63
+ method: 'POST',
64
+ body: JSON.stringify({ username: username.toLowerCase() }),
65
+ });
66
+ if (result.success) {
67
+ console.log(chalk_1.default.green(`✓ Username '${result.username}' claimed!`));
68
+ }
69
+ else {
70
+ console.log(chalk_1.default.yellow(`Could not set username: ${result.error}`));
71
+ }
72
+ }
73
+ catch (error) {
74
+ // Non-fatal - user can set username later
75
+ if (error.name !== 'ExitPromptError' && !error.message?.includes('force closed')) {
76
+ console.log(chalk_1.default.dim(' (You can set your username later with: gb username set <name>)'));
77
+ }
78
+ }
79
+ }
14
80
  exports.loginCommand = new commander_1.Command('login')
15
81
  .description('Login to Genbox')
16
82
  .action(async () => {
@@ -94,6 +160,8 @@ exports.loginCommand = new commander_1.Command('login')
94
160
  // Show logo on successful login
95
161
  (0, logo_1.printLogo)(chalk_1.default.green);
96
162
  console.log(chalk_1.default.green('✓ Successfully logged in!'));
163
+ // Prompt for username if not set
164
+ await promptForUsername();
97
165
  // Show completion hint if not already installed
98
166
  if (!(0, completion_1.isCompletionInstalledForCurrentShell)()) {
99
167
  console.log('');
@@ -0,0 +1,120 @@
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.usernameCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const inquirer_1 = __importDefault(require("inquirer"));
10
+ const api_1 = require("../api");
11
+ exports.usernameCommand = new commander_1.Command('username')
12
+ .description('Manage your username')
13
+ .action(async () => {
14
+ // Default action: show current username
15
+ try {
16
+ const info = await (0, api_1.fetchApi)('/users/me/username');
17
+ console.log(chalk_1.default.bold('\nUsername'));
18
+ if (info.hasUsername) {
19
+ console.log(` Current: ${chalk_1.default.cyan(info.username)}`);
20
+ console.log(chalk_1.default.dim(`\n Your genbox URLs: https://{genbox}.app.${info.username}.genbox.dev`));
21
+ }
22
+ else {
23
+ console.log(chalk_1.default.yellow(' No username set yet'));
24
+ console.log(chalk_1.default.dim('\n Set your username with: gb username set <name>'));
25
+ if (info.suggestion && info.suggestionAvailable) {
26
+ console.log(chalk_1.default.dim(` Suggested: ${info.suggestion}`));
27
+ }
28
+ }
29
+ }
30
+ catch (error) {
31
+ if (error instanceof api_1.AuthenticationError) {
32
+ (0, api_1.handleApiError)(error);
33
+ return;
34
+ }
35
+ console.error(chalk_1.default.red('Error:'), error.message);
36
+ }
37
+ });
38
+ // Sub-command: set username
39
+ exports.usernameCommand
40
+ .command('set <name>')
41
+ .description('Set or change your username')
42
+ .action(async (name) => {
43
+ try {
44
+ // Validate format
45
+ const normalized = name.toLowerCase().trim();
46
+ if (normalized.length < 3) {
47
+ console.error(chalk_1.default.red('Username must be at least 3 characters'));
48
+ return;
49
+ }
50
+ if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/.test(normalized)) {
51
+ console.error(chalk_1.default.red('Username must be lowercase, alphanumeric with hyphens (no start/end hyphen)'));
52
+ return;
53
+ }
54
+ // Check availability first
55
+ const check = await (0, api_1.fetchApi)(`/usernames/${normalized}/check`);
56
+ if (!check.available) {
57
+ console.error(chalk_1.default.red(`Username '${normalized}' is not available: ${check.reason}`));
58
+ return;
59
+ }
60
+ // Confirm change if user already has a username
61
+ const info = await (0, api_1.fetchApi)('/users/me/username');
62
+ if (info.hasUsername && info.username !== normalized) {
63
+ const { confirm } = await inquirer_1.default.prompt([
64
+ {
65
+ type: 'confirm',
66
+ name: 'confirm',
67
+ message: `Change username from '${info.username}' to '${normalized}'?`,
68
+ default: false,
69
+ },
70
+ ]);
71
+ if (!confirm) {
72
+ console.log(chalk_1.default.dim('Cancelled.'));
73
+ return;
74
+ }
75
+ }
76
+ // Set username
77
+ const result = await (0, api_1.fetchApi)('/users/me/username', {
78
+ method: 'POST',
79
+ body: JSON.stringify({ username: normalized }),
80
+ });
81
+ if (result.success) {
82
+ console.log(chalk_1.default.green(`✓ Username set to '${result.username}'`));
83
+ console.log(chalk_1.default.dim(`\n Your genbox URLs: https://{genbox}.app.${result.username}.genbox.dev`));
84
+ }
85
+ else {
86
+ console.error(chalk_1.default.red(`Failed: ${result.error}`));
87
+ }
88
+ }
89
+ catch (error) {
90
+ if (error.name === 'ExitPromptError' || error.message?.includes('force closed')) {
91
+ console.log(chalk_1.default.dim('Cancelled.'));
92
+ return;
93
+ }
94
+ if (error instanceof api_1.AuthenticationError) {
95
+ (0, api_1.handleApiError)(error);
96
+ return;
97
+ }
98
+ console.error(chalk_1.default.red('Error:'), error.message);
99
+ }
100
+ });
101
+ // Sub-command: check username availability
102
+ exports.usernameCommand
103
+ .command('check <name>')
104
+ .description('Check if a username is available')
105
+ .action(async (name) => {
106
+ try {
107
+ const normalized = name.toLowerCase().trim();
108
+ const result = await (0, api_1.fetchApi)(`/usernames/${normalized}/check`);
109
+ if (result.available) {
110
+ console.log(chalk_1.default.green(`✓ Username '${normalized}' is available`));
111
+ }
112
+ else {
113
+ console.log(chalk_1.default.red(`✗ Username '${normalized}' is not available`));
114
+ console.log(chalk_1.default.dim(` Reason: ${result.reason}`));
115
+ }
116
+ }
117
+ catch (error) {
118
+ console.error(chalk_1.default.red('Error:'), error.message);
119
+ }
120
+ });
package/dist/index.js CHANGED
@@ -81,6 +81,7 @@ const ps_1 = require("./commands/ps");
81
81
  const logs_1 = require("./commands/logs");
82
82
  const setup_1 = require("./commands/setup");
83
83
  const new_1 = require("./commands/new");
84
+ const username_1 = require("./commands/username");
84
85
  const config_store_1 = require("./config-store");
85
86
  const logo_1 = require("./utils/logo");
86
87
  const fs = __importStar(require("fs"));
@@ -184,6 +185,7 @@ const commandCategories = {
184
185
  { name: 'logout', aliases: [], description: 'Log out from Genbox' },
185
186
  { name: 'balance', aliases: [], description: 'Show credit balance' },
186
187
  { name: 'setup', aliases: [], description: 'Configure preferences (AI, GitHub, defaults)' },
188
+ { name: 'username', aliases: [], description: 'Manage your username' },
187
189
  ],
188
190
  'HELP': [
189
191
  { name: 'help', aliases: [], description: 'Show detailed help and examples' },
@@ -311,5 +313,6 @@ program
311
313
  .addCommand(logs_1.logsCommand)
312
314
  .addCommand(setup_1.setupCommand)
313
315
  .addCommand(new_1.newCommand)
316
+ .addCommand(username_1.usernameCommand)
314
317
  .addCommand(completion_1.completeCommand, { hidden: true }); // Internal command for shell completions
315
318
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genbox",
3
- "version": "1.0.189",
3
+ "version": "1.0.190",
4
4
  "description": "Genbox CLI - AI-Powered Development Environments",
5
5
  "main": "dist/index.js",
6
6
  "bin": {