berget 2.2.7 → 2.2.8

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 (130) hide show
  1. package/.github/workflows/publish.yml +6 -6
  2. package/.github/workflows/test.yml +1 -1
  3. package/.prettierrc +5 -3
  4. package/dist/index.js +24 -25
  5. package/dist/package.json +5 -3
  6. package/dist/src/agents/app.js +8 -8
  7. package/dist/src/agents/backend.js +3 -3
  8. package/dist/src/agents/devops.js +8 -8
  9. package/dist/src/agents/frontend.js +3 -3
  10. package/dist/src/agents/fullstack.js +3 -3
  11. package/dist/src/agents/index.js +18 -18
  12. package/dist/src/agents/quality.js +8 -8
  13. package/dist/src/agents/security.js +8 -8
  14. package/dist/src/client.js +115 -127
  15. package/dist/src/commands/api-keys.js +195 -202
  16. package/dist/src/commands/auth.js +16 -25
  17. package/dist/src/commands/autocomplete.js +8 -8
  18. package/dist/src/commands/billing.js +10 -19
  19. package/dist/src/commands/chat.js +139 -170
  20. package/dist/src/commands/clusters.js +21 -30
  21. package/dist/src/commands/code/__tests__/auth-sync.test.js +189 -186
  22. package/dist/src/commands/code/__tests__/fake-api-key-service.js +3 -13
  23. package/dist/src/commands/code/__tests__/fake-auth-service.js +21 -29
  24. package/dist/src/commands/code/__tests__/fake-command-runner.js +22 -33
  25. package/dist/src/commands/code/__tests__/fake-file-store.js +19 -41
  26. package/dist/src/commands/code/__tests__/fake-prompter.js +81 -97
  27. package/dist/src/commands/code/__tests__/setup-flow.test.js +295 -295
  28. package/dist/src/commands/code/adapters/clack-prompter.js +15 -32
  29. package/dist/src/commands/code/adapters/fs-file-store.js +25 -44
  30. package/dist/src/commands/code/adapters/spawn-command-runner.js +27 -41
  31. package/dist/src/commands/code/auth-sync.js +215 -228
  32. package/dist/src/commands/code/errors.js +15 -12
  33. package/dist/src/commands/code/setup.js +390 -425
  34. package/dist/src/commands/code.js +279 -294
  35. package/dist/src/commands/index.js +5 -5
  36. package/dist/src/commands/models.js +16 -25
  37. package/dist/src/commands/users.js +9 -18
  38. package/dist/src/constants/command-structure.js +138 -138
  39. package/dist/src/services/api-key-service.js +132 -152
  40. package/dist/src/services/auth-service.js +81 -95
  41. package/dist/src/services/browser-auth.js +121 -131
  42. package/dist/src/services/chat-service.js +369 -386
  43. package/dist/src/services/cluster-service.js +47 -62
  44. package/dist/src/services/collaborator-service.js +9 -21
  45. package/dist/src/services/flux-service.js +13 -25
  46. package/dist/src/services/helm-service.js +9 -21
  47. package/dist/src/services/kubectl-service.js +15 -29
  48. package/dist/src/utils/config-checker.js +7 -7
  49. package/dist/src/utils/config-loader.js +109 -109
  50. package/dist/src/utils/default-api-key.js +129 -139
  51. package/dist/src/utils/env-manager.js +55 -66
  52. package/dist/src/utils/error-handler.js +62 -62
  53. package/dist/src/utils/logger.js +74 -67
  54. package/dist/src/utils/markdown-renderer.js +28 -28
  55. package/dist/src/utils/opencode-validator.js +67 -69
  56. package/dist/src/utils/token-manager.js +67 -65
  57. package/dist/tests/commands/chat.test.js +30 -39
  58. package/dist/tests/commands/code.test.js +186 -195
  59. package/dist/tests/utils/config-loader.test.js +107 -107
  60. package/dist/tests/utils/env-manager.test.js +81 -90
  61. package/dist/tests/utils/opencode-validator.test.js +42 -41
  62. package/dist/vitest.config.js +1 -1
  63. package/eslint.config.mjs +50 -30
  64. package/index.ts +30 -31
  65. package/package.json +5 -3
  66. package/src/agents/app.ts +9 -9
  67. package/src/agents/backend.ts +4 -4
  68. package/src/agents/devops.ts +9 -9
  69. package/src/agents/frontend.ts +4 -4
  70. package/src/agents/fullstack.ts +4 -4
  71. package/src/agents/index.ts +27 -25
  72. package/src/agents/quality.ts +9 -9
  73. package/src/agents/security.ts +9 -9
  74. package/src/agents/types.ts +10 -10
  75. package/src/client.ts +85 -77
  76. package/src/commands/api-keys.ts +190 -185
  77. package/src/commands/auth.ts +15 -14
  78. package/src/commands/autocomplete.ts +10 -10
  79. package/src/commands/billing.ts +13 -12
  80. package/src/commands/chat.ts +145 -142
  81. package/src/commands/clusters.ts +20 -19
  82. package/src/commands/code/__tests__/auth-sync.test.ts +176 -175
  83. package/src/commands/code/__tests__/fake-api-key-service.ts +2 -2
  84. package/src/commands/code/__tests__/fake-auth-service.ts +18 -18
  85. package/src/commands/code/__tests__/fake-command-runner.ts +28 -22
  86. package/src/commands/code/__tests__/fake-file-store.ts +15 -15
  87. package/src/commands/code/__tests__/fake-prompter.ts +86 -85
  88. package/src/commands/code/__tests__/setup-flow.test.ts +253 -251
  89. package/src/commands/code/adapters/clack-prompter.ts +32 -30
  90. package/src/commands/code/adapters/fs-file-store.ts +18 -17
  91. package/src/commands/code/adapters/spawn-command-runner.ts +20 -15
  92. package/src/commands/code/auth-sync.ts +210 -210
  93. package/src/commands/code/errors.ts +11 -11
  94. package/src/commands/code/ports/auth-services.ts +7 -7
  95. package/src/commands/code/ports/command-runner.ts +2 -2
  96. package/src/commands/code/ports/file-store.ts +3 -3
  97. package/src/commands/code/ports/prompter.ts +13 -13
  98. package/src/commands/code/setup.ts +408 -406
  99. package/src/commands/code.ts +288 -287
  100. package/src/commands/index.ts +11 -10
  101. package/src/commands/models.ts +19 -18
  102. package/src/commands/users.ts +11 -10
  103. package/src/constants/command-structure.ts +159 -159
  104. package/src/services/api-key-service.ts +85 -85
  105. package/src/services/auth-service.ts +55 -54
  106. package/src/services/browser-auth.ts +62 -62
  107. package/src/services/chat-service.ts +169 -170
  108. package/src/services/cluster-service.ts +28 -28
  109. package/src/services/collaborator-service.ts +6 -6
  110. package/src/services/flux-service.ts +17 -17
  111. package/src/services/helm-service.ts +11 -11
  112. package/src/services/kubectl-service.ts +12 -12
  113. package/src/types/api.d.ts +1933 -1933
  114. package/src/types/json.d.ts +1 -1
  115. package/src/utils/config-checker.ts +6 -6
  116. package/src/utils/config-loader.ts +130 -129
  117. package/src/utils/default-api-key.ts +81 -80
  118. package/src/utils/env-manager.ts +37 -37
  119. package/src/utils/error-handler.ts +64 -64
  120. package/src/utils/logger.ts +72 -66
  121. package/src/utils/markdown-renderer.ts +28 -28
  122. package/src/utils/opencode-validator.ts +72 -71
  123. package/src/utils/token-manager.ts +69 -68
  124. package/tests/commands/chat.test.ts +32 -31
  125. package/tests/commands/code.test.ts +182 -181
  126. package/tests/utils/config-loader.test.ts +111 -110
  127. package/tests/utils/env-manager.test.ts +83 -79
  128. package/tests/utils/opencode-validator.test.ts +43 -42
  129. package/tsconfig.json +2 -1
  130. package/vitest.config.ts +2 -2
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -15,61 +6,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
6
  exports.registerApiKeyCommands = void 0;
16
7
  const chalk_1 = __importDefault(require("chalk"));
17
8
  const api_key_service_1 = require("../services/api-key-service");
18
- const error_handler_1 = require("../utils/error-handler");
19
9
  const default_api_key_1 = require("../utils/default-api-key");
20
- // Helper functions for better date formatting
21
- function formatDate(dateString) {
22
- const date = new Date(dateString);
23
- const now = new Date();
24
- const diffTime = Math.abs(now.getTime() - date.getTime());
25
- const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
26
- if (diffDays === 0)
27
- return chalk_1.default.green("Today");
28
- if (diffDays === 1)
29
- return chalk_1.default.yellow("Yesterday");
30
- if (diffDays < 7)
31
- return chalk_1.default.yellow(`${diffDays} days ago`);
32
- if (diffDays < 30)
33
- return chalk_1.default.blue(`${Math.floor(diffDays / 7)} weeks ago`);
34
- if (diffDays < 365)
35
- return chalk_1.default.magenta(`${Math.floor(diffDays / 30)} months ago`);
36
- return chalk_1.default.gray(`${Math.floor(diffDays / 365)} years ago`);
37
- }
38
- function formatLastUsed(dateString) {
39
- const date = new Date(dateString);
40
- const now = new Date();
41
- const diffTime = Math.abs(now.getTime() - date.getTime());
42
- const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
43
- if (diffDays === 0)
44
- return chalk_1.default.green("Today");
45
- if (diffDays === 1)
46
- return chalk_1.default.yellow("Yesterday");
47
- if (diffDays < 7)
48
- return chalk_1.default.yellow(`${diffDays} days ago`);
49
- if (diffDays < 30)
50
- return chalk_1.default.blue(`${Math.floor(diffDays / 7)} weeks ago`);
51
- if (diffDays < 365)
52
- return chalk_1.default.magenta(`${Math.floor(diffDays / 30)} months ago`);
53
- return chalk_1.default.gray(`${Math.floor(diffDays / 365)} years ago`);
54
- }
10
+ const error_handler_1 = require("../utils/error-handler");
55
11
  /**
56
12
  * Register API key commands
57
13
  */
58
14
  function registerApiKeyCommands(program) {
59
- const apiKey = program.command(api_key_service_1.ApiKeyService.COMMAND_GROUP).description("Manage API keys");
15
+ const apiKey = program.command(api_key_service_1.ApiKeyService.COMMAND_GROUP).description('Manage API keys');
60
16
  apiKey
61
17
  .command(api_key_service_1.ApiKeyService.COMMANDS.LIST)
62
- .description("List all API keys")
63
- .action(() => __awaiter(this, void 0, void 0, function* () {
18
+ .description('List all API keys')
19
+ .action(async () => {
64
20
  try {
65
21
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
66
- const keys = yield apiKeyService.list();
22
+ const keys = await apiKeyService.list();
67
23
  if (keys.length === 0) {
68
- console.log(chalk_1.default.yellow("No API keys found. Create one with `berget api-key create --name <name>`"));
24
+ console.log(chalk_1.default.yellow('No API keys found. Create one with `berget api-key create --name <name>`'));
69
25
  return;
70
26
  }
71
- console.log(chalk_1.default.bold("🔑 Your API keys:"));
72
- console.log("");
27
+ console.log(chalk_1.default.bold('🔑 Your API keys:'));
28
+ console.log('');
73
29
  // Create a more readable table with better spacing and colors
74
30
  const idWidth = 10;
75
31
  const nameWidth = 30;
@@ -77,222 +33,224 @@ function registerApiKeyCommands(program) {
77
33
  const statusWidth = 12;
78
34
  const createdWidth = 12;
79
35
  const usedWidth = 15;
80
- console.log(chalk_1.default.dim("ID".padEnd(idWidth)) +
81
- chalk_1.default.dim("NAME".padEnd(nameWidth)) +
82
- chalk_1.default.dim("PREFIX".padEnd(prefixWidth)) +
83
- chalk_1.default.dim("STATUS".padEnd(statusWidth)) +
84
- chalk_1.default.dim("CREATED".padEnd(createdWidth)) +
85
- chalk_1.default.dim("LAST USED"));
86
- console.log(chalk_1.default.dim("".repeat(idWidth + nameWidth + prefixWidth + statusWidth + createdWidth + usedWidth + 5)));
36
+ console.log(chalk_1.default.dim('ID'.padEnd(idWidth)) +
37
+ chalk_1.default.dim('NAME'.padEnd(nameWidth)) +
38
+ chalk_1.default.dim('PREFIX'.padEnd(prefixWidth)) +
39
+ chalk_1.default.dim('STATUS'.padEnd(statusWidth)) +
40
+ chalk_1.default.dim('CREATED'.padEnd(createdWidth)) +
41
+ chalk_1.default.dim('LAST USED'));
42
+ console.log(chalk_1.default.dim(''.repeat(idWidth + nameWidth + prefixWidth + statusWidth + createdWidth + usedWidth + 5)));
87
43
  keys.forEach((key) => {
88
- const lastUsed = key.lastUsed ? formatLastUsed(key.lastUsed) : chalk_1.default.yellow("Never used");
89
- const status = key.active ? chalk_1.default.green("● Active") : chalk_1.default.red("● Inactive");
44
+ const lastUsed = key.lastUsed ? formatLastUsed(key.lastUsed) : chalk_1.default.yellow('Never used');
45
+ const status = key.active ? chalk_1.default.green('● Active') : chalk_1.default.red('● Inactive');
90
46
  // Show only first 8 characters of ID for easier reading
91
- const shortId = chalk_1.default.cyan(String(key.id).substring(0, 8));
47
+ const shortId = chalk_1.default.cyan(String(key.id).slice(0, 8));
92
48
  // Format the prefix with better truncation
93
- const prefixStr = key.prefix.length > prefixWidth
94
- ? key.prefix.substring(0, prefixWidth - 3) + "..."
49
+ const prefixString = key.prefix.length > prefixWidth
50
+ ? key.prefix.slice(0, Math.max(0, prefixWidth - 3)) + '...'
95
51
  : chalk_1.default.gray(key.prefix);
96
52
  // Truncate name if too long
97
- const nameStr = key.name.length > nameWidth ? key.name.substring(0, nameWidth - 3) + "..." : key.name;
53
+ const nameString = key.name.length > nameWidth
54
+ ? key.name.slice(0, Math.max(0, nameWidth - 3)) + '...'
55
+ : key.name;
98
56
  // Format created date
99
57
  const createdDate = formatDate(key.created);
100
58
  console.log(shortId.padEnd(idWidth) +
101
- nameStr.padEnd(nameWidth) +
102
- prefixStr.padEnd(prefixWidth) +
59
+ nameString.padEnd(nameWidth) +
60
+ prefixString.padEnd(prefixWidth) +
103
61
  status.padEnd(statusWidth) +
104
62
  createdDate.padEnd(createdWidth) +
105
63
  lastUsed);
106
64
  });
107
- console.log("");
108
- console.log(chalk_1.default.dim("Use `berget api-key create --name <name>` to create a new API key"));
109
- console.log(chalk_1.default.dim("Use `berget api-key delete <id>` to delete an API key"));
110
- console.log(chalk_1.default.dim("Use `berget api-key rotate <id>` to rotate an API key"));
65
+ console.log('');
66
+ console.log(chalk_1.default.dim('Use `berget api-key create --name <name>` to create a new API key'));
67
+ console.log(chalk_1.default.dim('Use `berget api-key delete <id>` to delete an API key'));
68
+ console.log(chalk_1.default.dim('Use `berget api-key rotate <id>` to rotate an API key'));
111
69
  }
112
70
  catch (error) {
113
- (0, error_handler_1.handleError)("Failed to list API keys", error);
71
+ (0, error_handler_1.handleError)('Failed to list API keys', error);
114
72
  }
115
- }));
73
+ });
116
74
  apiKey
117
75
  .command(api_key_service_1.ApiKeyService.COMMANDS.CREATE)
118
- .description("Create a new API key")
119
- .option("--name <name>", "Name of the API key")
120
- .option("--description <description>", "Description of the API key")
121
- .action((options) => __awaiter(this, void 0, void 0, function* () {
76
+ .description('Create a new API key')
77
+ .option('--name <name>', 'Name of the API key')
78
+ .option('--description <description>', 'Description of the API key')
79
+ .action(async (options) => {
122
80
  try {
123
81
  if (!options.name) {
124
- console.error(chalk_1.default.red("Error: --name is required"));
125
- console.log("");
126
- console.log("Usage: berget api-key create --name <name> [--description <description>]");
82
+ console.error(chalk_1.default.red('Error: --name is required'));
83
+ console.log('');
84
+ console.log('Usage: berget api-key create --name <name> [--description <description>]');
127
85
  return;
128
86
  }
129
- console.log(chalk_1.default.blue("Creating API key..."));
87
+ console.log(chalk_1.default.blue('Creating API key...'));
130
88
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
131
- const result = yield apiKeyService.create({
132
- name: options.name,
89
+ const result = await apiKeyService.create({
133
90
  description: options.description,
91
+ name: options.name,
134
92
  });
135
- console.log("");
136
- console.log(chalk_1.default.green("✓ API key created"));
137
- console.log("");
138
- console.log(chalk_1.default.bold("API key details:"));
139
- console.log("");
140
- console.log(`${chalk_1.default.dim("ID:")} ${result.id}`);
141
- console.log(`${chalk_1.default.dim("Name:")} ${result.name}`);
93
+ console.log('');
94
+ console.log(chalk_1.default.green('✓ API key created'));
95
+ console.log('');
96
+ console.log(chalk_1.default.bold('API key details:'));
97
+ console.log('');
98
+ console.log(`${chalk_1.default.dim('ID:')} ${result.id}`);
99
+ console.log(`${chalk_1.default.dim('Name:')} ${result.name}`);
142
100
  if (result.description) {
143
- console.log(`${chalk_1.default.dim("Description:")} ${result.description}`);
101
+ console.log(`${chalk_1.default.dim('Description:')} ${result.description}`);
144
102
  }
145
- console.log(`${chalk_1.default.dim("Created:")} ${new Date(result.created).toLocaleString()}`);
146
- console.log("");
147
- console.log(chalk_1.default.bold("API key:"));
103
+ console.log(`${chalk_1.default.dim('Created:')} ${new Date(result.created).toLocaleString()}`);
104
+ console.log('');
105
+ console.log(chalk_1.default.bold('API key:'));
148
106
  console.log(chalk_1.default.cyan(result.key));
149
- console.log("");
150
- console.log(chalk_1.default.yellow("⚠️ IMPORTANT: Save this API key in a secure location."));
151
- console.log(chalk_1.default.yellow(" It will not be displayed again."));
152
- console.log("");
153
- console.log(chalk_1.default.dim("Use this key in your applications to authenticate with the Berget API."));
107
+ console.log('');
108
+ console.log(chalk_1.default.yellow('⚠️ IMPORTANT: Save this API key in a secure location.'));
109
+ console.log(chalk_1.default.yellow(' It will not be displayed again.'));
110
+ console.log('');
111
+ console.log(chalk_1.default.dim('Use this key in your applications to authenticate with the Berget API.'));
154
112
  }
155
113
  catch (error) {
156
- (0, error_handler_1.handleError)("Failed to create API key", error);
114
+ (0, error_handler_1.handleError)('Failed to create API key', error);
157
115
  }
158
- }));
116
+ });
159
117
  apiKey
160
118
  .command(api_key_service_1.ApiKeyService.COMMANDS.DELETE)
161
- .description("Delete an API key")
162
- .argument("<identifier>", "ID (first 8 chars), full ID, or name of the API key to delete")
163
- .action((identifier) => __awaiter(this, void 0, void 0, function* () {
119
+ .description('Delete an API key')
120
+ .argument('<identifier>', 'ID (first 8 chars), full ID, or name of the API key to delete')
121
+ .action(async (identifier) => {
164
122
  try {
165
123
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
166
124
  // First, get all API keys to find the matching one
167
- const keys = yield apiKeyService.list();
125
+ const keys = await apiKeyService.list();
168
126
  // Try to find the key by:
169
127
  // 1. Full ID match
170
128
  // 2. Short ID (first 8 chars) match
171
129
  // 3. Exact name match
172
130
  // 4. Partial name match
173
131
  // Check for exact matches first (full ID or exact name)
174
- let exactMatches = keys.filter(key => String(key.id) === identifier || key.name === identifier);
132
+ let exactMatches = keys.filter((key) => String(key.id) === identifier || key.name === identifier);
175
133
  // If no exact matches, check for short ID matches
176
134
  if (exactMatches.length === 0) {
177
- exactMatches = keys.filter(key => String(key.id).substring(0, 8) === identifier);
135
+ exactMatches = keys.filter((key) => String(key.id).slice(0, 8) === identifier);
178
136
  }
179
137
  // If still no matches, check for partial name matches
180
138
  if (exactMatches.length === 0) {
181
- exactMatches = keys.filter(key => key.name.toLowerCase().includes(identifier.toLowerCase()));
139
+ exactMatches = keys.filter((key) => key.name.toLowerCase().includes(identifier.toLowerCase()));
182
140
  }
183
141
  // Handle multiple matches
184
142
  if (exactMatches.length > 1) {
185
143
  console.error(chalk_1.default.red(`Error: Multiple API keys found matching "${identifier}"`));
186
- console.log("");
187
- console.log("Please be more specific. Matching keys:");
188
- exactMatches.forEach(key => {
189
- const shortId = String(key.id).substring(0, 8);
144
+ console.log('');
145
+ console.log('Please be more specific. Matching keys:');
146
+ for (const key of exactMatches) {
147
+ const shortId = String(key.id).slice(0, 8);
190
148
  console.log(` ${shortId.padEnd(8)} ${key.name}`);
191
- });
192
- console.log("");
193
- console.log("Use the first 8 characters of the ID to specify which key to delete.");
149
+ }
150
+ console.log('');
151
+ console.log('Use the first 8 characters of the ID to specify which key to delete.');
194
152
  return;
195
153
  }
196
154
  // Handle no matches
197
155
  if (exactMatches.length === 0) {
198
156
  console.error(chalk_1.default.red(`Error: No API key found matching "${identifier}"`));
199
- console.log("");
200
- console.log("Available API keys:");
201
- keys.forEach(key => {
202
- const shortId = String(key.id).substring(0, 8);
157
+ console.log('');
158
+ console.log('Available API keys:');
159
+ for (const key of keys) {
160
+ const shortId = String(key.id).slice(0, 8);
203
161
  console.log(` ${shortId.padEnd(8)} ${key.name}`);
204
- });
205
- console.log("");
206
- console.log("Use the first 8 characters of the ID, full ID, or name to delete.");
162
+ }
163
+ console.log('');
164
+ console.log('Use the first 8 characters of the ID, full ID, or name to delete.');
207
165
  return;
208
166
  }
209
167
  const matchingKey = exactMatches[0];
210
168
  const keyId = String(matchingKey.id);
211
- const shortId = keyId.substring(0, 8);
169
+ const shortId = keyId.slice(0, 8);
212
170
  console.log(chalk_1.default.blue(`Deleting API key ${shortId} (${matchingKey.name})...`));
213
- yield apiKeyService.delete(keyId);
171
+ await apiKeyService.delete(keyId);
214
172
  console.log(chalk_1.default.green(`✓ API key ${shortId} (${matchingKey.name}) has been deleted`));
215
- console.log("");
216
- console.log(chalk_1.default.dim("Applications using this key will no longer be able to authenticate."));
217
- console.log(chalk_1.default.dim("Use `berget api-key list` to see your remaining API keys."));
173
+ console.log('');
174
+ console.log(chalk_1.default.dim('Applications using this key will no longer be able to authenticate.'));
175
+ console.log(chalk_1.default.dim('Use `berget api-key list` to see your remaining API keys.'));
218
176
  }
219
177
  catch (error) {
220
- (0, error_handler_1.handleError)("Failed to delete API key", error);
178
+ (0, error_handler_1.handleError)('Failed to delete API key', error);
221
179
  }
222
- }));
180
+ });
223
181
  apiKey
224
182
  .command(api_key_service_1.ApiKeyService.COMMANDS.ROTATE)
225
- .description("Rotate an API key (creates a new one and invalidates the old one)")
226
- .argument("<id>", "ID of the API key to rotate")
227
- .action((id) => __awaiter(this, void 0, void 0, function* () {
183
+ .description('Rotate an API key (creates a new one and invalidates the old one)')
184
+ .argument('<id>', 'ID of the API key to rotate')
185
+ .action(async (id) => {
228
186
  try {
229
187
  console.log(chalk_1.default.blue(`Rotating API key ${id}...`));
230
- console.log(chalk_1.default.dim("This will invalidate the old key and generate a new one."));
188
+ console.log(chalk_1.default.dim('This will invalidate the old key and generate a new one.'));
231
189
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
232
- const result = yield apiKeyService.rotate(id);
233
- console.log("");
234
- console.log(chalk_1.default.green("✓ API key rotated"));
235
- console.log("");
236
- console.log(chalk_1.default.bold("New API key details:"));
237
- console.log("");
238
- console.log(`${chalk_1.default.dim("ID:")} ${result.id}`);
239
- console.log(`${chalk_1.default.dim("Name:")} ${result.name}`);
190
+ const result = await apiKeyService.rotate(id);
191
+ console.log('');
192
+ console.log(chalk_1.default.green('✓ API key rotated'));
193
+ console.log('');
194
+ console.log(chalk_1.default.bold('New API key details:'));
195
+ console.log('');
196
+ console.log(`${chalk_1.default.dim('ID:')} ${result.id}`);
197
+ console.log(`${chalk_1.default.dim('Name:')} ${result.name}`);
240
198
  if (result.description) {
241
- console.log(`${chalk_1.default.dim("Description:")} ${result.description}`);
199
+ console.log(`${chalk_1.default.dim('Description:')} ${result.description}`);
242
200
  }
243
- console.log(`${chalk_1.default.dim("Created:")} ${new Date(result.created).toLocaleString()}`);
244
- console.log("");
245
- console.log(chalk_1.default.bold("New API key:"));
201
+ console.log(`${chalk_1.default.dim('Created:')} ${new Date(result.created).toLocaleString()}`);
202
+ console.log('');
203
+ console.log(chalk_1.default.bold('New API key:'));
246
204
  console.log(chalk_1.default.cyan(result.key));
247
- console.log("");
248
- console.log(chalk_1.default.yellow("⚠️ IMPORTANT: Update your applications with this new API key."));
249
- console.log(chalk_1.default.yellow(" The old key has been invalidated and will no longer work."));
250
- console.log(chalk_1.default.yellow(" This new key will not be displayed again."));
205
+ console.log('');
206
+ console.log(chalk_1.default.yellow('⚠️ IMPORTANT: Update your applications with this new API key.'));
207
+ console.log(chalk_1.default.yellow(' The old key has been invalidated and will no longer work.'));
208
+ console.log(chalk_1.default.yellow(' This new key will not be displayed again.'));
251
209
  }
252
210
  catch (error) {
253
- (0, error_handler_1.handleError)("Failed to rotate API key", error);
211
+ (0, error_handler_1.handleError)('Failed to rotate API key', error);
254
212
  }
255
- }));
213
+ });
256
214
  apiKey
257
215
  .command(api_key_service_1.ApiKeyService.COMMANDS.DESCRIBE)
258
- .description("Show usage statistics for an API key")
259
- .argument("<id>", "ID of the API key")
260
- .option("--start <date>", "Start date (YYYY-MM-DD)")
261
- .option("--end <date>", "End date (YYYY-MM-DD)")
262
- .action((id, _options) => __awaiter(this, void 0, void 0, function* () {
216
+ .description('Show usage statistics for an API key')
217
+ .argument('<id>', 'ID of the API key')
218
+ .option('--start <date>', 'Start date (YYYY-MM-DD)')
219
+ .option('--end <date>', 'End date (YYYY-MM-DD)')
220
+ .action(async (id, _options) => {
263
221
  try {
264
222
  console.log(chalk_1.default.blue(`Fetching usage statistics for API key ${id}...`));
265
223
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
266
- const usage = yield apiKeyService.describe(id);
267
- console.log("");
224
+ const usage = await apiKeyService.describe(id);
225
+ console.log('');
268
226
  console.log(chalk_1.default.bold(`Usage statistics for API key: ${usage.name} (${id})`));
269
- console.log("");
227
+ console.log('');
270
228
  // Period information
271
229
  console.log(chalk_1.default.dim(`Period: ${usage.period.start} to ${usage.period.end}`));
272
- console.log("");
230
+ console.log('');
273
231
  // Request statistics
274
- console.log(chalk_1.default.bold("Request statistics:"));
232
+ console.log(chalk_1.default.bold('Request statistics:'));
275
233
  console.log(`Total requests: ${chalk_1.default.cyan(usage.requests.total.toLocaleString())}`);
276
234
  // Daily breakdown if available
277
235
  if (usage.requests.daily && usage.requests.daily.length > 0) {
278
- console.log("");
279
- console.log(chalk_1.default.bold("Daily breakdown:"));
280
- console.log(chalk_1.default.dim("".repeat(30)));
281
- console.log(chalk_1.default.dim("DATE".padEnd(12) + "REQUESTS"));
236
+ console.log('');
237
+ console.log(chalk_1.default.bold('Daily breakdown:'));
238
+ console.log(chalk_1.default.dim(''.repeat(30)));
239
+ console.log(chalk_1.default.dim('DATE'.padEnd(12) + 'REQUESTS'));
282
240
  usage.requests.daily.forEach((day) => {
283
241
  console.log(`${day.date.padEnd(12)}${day.count.toLocaleString()}`);
284
242
  });
285
243
  }
286
244
  // Model usage if available
287
245
  if (usage.models && usage.models.length > 0) {
288
- console.log("");
289
- console.log(chalk_1.default.bold("Model usage:"));
290
- console.log(chalk_1.default.dim("".repeat(70)));
291
- console.log(chalk_1.default.dim("MODEL".padEnd(20)) +
292
- chalk_1.default.dim("REQUESTS".padEnd(10)) +
293
- chalk_1.default.dim("INPUT".padEnd(12)) +
294
- chalk_1.default.dim("OUTPUT".padEnd(12)) +
295
- chalk_1.default.dim("TOTAL TOKENS"));
246
+ console.log('');
247
+ console.log(chalk_1.default.bold('Model usage:'));
248
+ console.log(chalk_1.default.dim(''.repeat(70)));
249
+ console.log(chalk_1.default.dim('MODEL'.padEnd(20)) +
250
+ chalk_1.default.dim('REQUESTS'.padEnd(10)) +
251
+ chalk_1.default.dim('INPUT'.padEnd(12)) +
252
+ chalk_1.default.dim('OUTPUT'.padEnd(12)) +
253
+ chalk_1.default.dim('TOTAL TOKENS'));
296
254
  usage.models.forEach((model) => {
297
255
  console.log(model.name.padEnd(20) +
298
256
  model.requests.toString().padEnd(10) +
@@ -301,22 +259,22 @@ function registerApiKeyCommands(program) {
301
259
  model.tokens.total.toLocaleString());
302
260
  });
303
261
  }
304
- console.log("");
305
- console.log(chalk_1.default.dim("Use these statistics to understand your API usage and optimize your costs."));
262
+ console.log('');
263
+ console.log(chalk_1.default.dim('Use these statistics to understand your API usage and optimize your costs.'));
306
264
  }
307
265
  catch (error) {
308
- (0, error_handler_1.handleError)("Failed to get API key usage", error);
266
+ (0, error_handler_1.handleError)('Failed to get API key usage', error);
309
267
  }
310
- }));
268
+ });
311
269
  apiKey
312
270
  .command(api_key_service_1.ApiKeyService.COMMANDS.SET_DEFAULT)
313
- .description("Set an API key as the default for chat commands")
314
- .argument("<id>", "ID of the API key to set as default")
315
- .action((id) => __awaiter(this, void 0, void 0, function* () {
271
+ .description('Set an API key as the default for chat commands')
272
+ .argument('<id>', 'ID of the API key to set as default')
273
+ .action(async (id) => {
316
274
  try {
317
275
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
318
- const keys = yield apiKeyService.list();
319
- const selectedKey = keys.find(key => key.id.toString() === id);
276
+ const keys = await apiKeyService.list();
277
+ const selectedKey = keys.find((key) => key.id.toString() === id);
320
278
  if (!selectedKey) {
321
279
  console.error(chalk_1.default.red(`Error: API key with ID ${id} not found`));
322
280
  return;
@@ -324,43 +282,78 @@ function registerApiKeyCommands(program) {
324
282
  // Save the default API key
325
283
  const defaultApiKeyManager = default_api_key_1.DefaultApiKeyManager.getInstance();
326
284
  // We need to rotate the key to get the actual key value
327
- const rotatedKey = yield apiKeyService.rotate(id);
285
+ const rotatedKey = await apiKeyService.rotate(id);
328
286
  defaultApiKeyManager.setDefaultApiKey(id, selectedKey.name, selectedKey.prefix, rotatedKey.key);
329
287
  console.log(chalk_1.default.green(`✓ API key "${selectedKey.name}" set as default for chat commands`));
330
- console.log("");
331
- console.log(chalk_1.default.dim("This API key will be used by default when running chat commands"));
332
- console.log(chalk_1.default.dim("You can override it with --api-key or --api-key-id options"));
288
+ console.log('');
289
+ console.log(chalk_1.default.dim('This API key will be used by default when running chat commands'));
290
+ console.log(chalk_1.default.dim('You can override it with --api-key or --api-key-id options'));
333
291
  }
334
292
  catch (error) {
335
- (0, error_handler_1.handleError)("Failed to set default API key", error);
293
+ (0, error_handler_1.handleError)('Failed to set default API key', error);
336
294
  }
337
- }));
295
+ });
338
296
  apiKey
339
297
  .command(api_key_service_1.ApiKeyService.COMMANDS.GET_DEFAULT)
340
- .description("Show the current default API key")
298
+ .description('Show the current default API key')
341
299
  .action(() => {
342
300
  try {
343
301
  const defaultApiKeyManager = default_api_key_1.DefaultApiKeyManager.getInstance();
344
302
  const defaultApiKeyData = defaultApiKeyManager.getDefaultApiKeyData();
345
303
  if (!defaultApiKeyData) {
346
- console.log(chalk_1.default.yellow("No default API key set"));
347
- console.log("");
348
- console.log("To set a default API key, run:");
349
- console.log(chalk_1.default.cyan(" berget api-keys set-default <id>"));
304
+ console.log(chalk_1.default.yellow('No default API key set'));
305
+ console.log('');
306
+ console.log('To set a default API key, run:');
307
+ console.log(chalk_1.default.cyan(' berget api-keys set-default <id>'));
350
308
  return;
351
309
  }
352
- console.log(chalk_1.default.bold("Default API key:"));
353
- console.log("");
354
- console.log(`${chalk_1.default.dim("ID:")} ${defaultApiKeyData.id}`);
355
- console.log(`${chalk_1.default.dim("Name:")} ${defaultApiKeyData.name}`);
356
- console.log(`${chalk_1.default.dim("Prefix:")} ${defaultApiKeyData.prefix}`);
357
- console.log("");
358
- console.log(chalk_1.default.dim("This API key will be used by default when running chat commands"));
359
- console.log(chalk_1.default.dim("You can override it with --api-key or --api-key-id options"));
310
+ console.log(chalk_1.default.bold('Default API key:'));
311
+ console.log('');
312
+ console.log(`${chalk_1.default.dim('ID:')} ${defaultApiKeyData.id}`);
313
+ console.log(`${chalk_1.default.dim('Name:')} ${defaultApiKeyData.name}`);
314
+ console.log(`${chalk_1.default.dim('Prefix:')} ${defaultApiKeyData.prefix}`);
315
+ console.log('');
316
+ console.log(chalk_1.default.dim('This API key will be used by default when running chat commands'));
317
+ console.log(chalk_1.default.dim('You can override it with --api-key or --api-key-id options'));
360
318
  }
361
319
  catch (error) {
362
- (0, error_handler_1.handleError)("Failed to get default API key", error);
320
+ (0, error_handler_1.handleError)('Failed to get default API key', error);
363
321
  }
364
322
  });
365
323
  }
366
324
  exports.registerApiKeyCommands = registerApiKeyCommands;
325
+ // Helper functions for better date formatting
326
+ function formatDate(dateString) {
327
+ const date = new Date(dateString);
328
+ const now = new Date();
329
+ const diffTime = Math.abs(now.getTime() - date.getTime());
330
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
331
+ if (diffDays === 0)
332
+ return chalk_1.default.green('Today');
333
+ if (diffDays === 1)
334
+ return chalk_1.default.yellow('Yesterday');
335
+ if (diffDays < 7)
336
+ return chalk_1.default.yellow(`${diffDays} days ago`);
337
+ if (diffDays < 30)
338
+ return chalk_1.default.blue(`${Math.floor(diffDays / 7)} weeks ago`);
339
+ if (diffDays < 365)
340
+ return chalk_1.default.magenta(`${Math.floor(diffDays / 30)} months ago`);
341
+ return chalk_1.default.gray(`${Math.floor(diffDays / 365)} years ago`);
342
+ }
343
+ function formatLastUsed(dateString) {
344
+ const date = new Date(dateString);
345
+ const now = new Date();
346
+ const diffTime = Math.abs(now.getTime() - date.getTime());
347
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
348
+ if (diffDays === 0)
349
+ return chalk_1.default.green('Today');
350
+ if (diffDays === 1)
351
+ return chalk_1.default.yellow('Yesterday');
352
+ if (diffDays < 7)
353
+ return chalk_1.default.yellow(`${diffDays} days ago`);
354
+ if (diffDays < 30)
355
+ return chalk_1.default.blue(`${Math.floor(diffDays / 7)} weeks ago`);
356
+ if (diffDays < 365)
357
+ return chalk_1.default.magenta(`${Math.floor(diffDays / 30)} months ago`);
358
+ return chalk_1.default.gray(`${Math.floor(diffDays / 365)} years ago`);
359
+ }