langmart-gateway-type3 3.0.44 → 3.0.46

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 (65) hide show
  1. package/dist/admin-tools.d.ts +46 -0
  2. package/dist/admin-tools.d.ts.map +1 -0
  3. package/dist/admin-tools.js +933 -0
  4. package/dist/admin-tools.js.map +1 -0
  5. package/dist/agent-tools.d.ts +38 -0
  6. package/dist/agent-tools.d.ts.map +1 -0
  7. package/dist/agent-tools.js +813 -0
  8. package/dist/agent-tools.js.map +1 -0
  9. package/dist/billing-tools.d.ts +25 -0
  10. package/dist/billing-tools.d.ts.map +1 -0
  11. package/dist/billing-tools.js +283 -0
  12. package/dist/billing-tools.js.map +1 -0
  13. package/dist/cli.d.ts +2 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +792 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/collection-tools.d.ts +26 -0
  18. package/dist/collection-tools.d.ts.map +1 -0
  19. package/dist/collection-tools.js +347 -0
  20. package/dist/collection-tools.js.map +1 -0
  21. package/dist/lib/tool-schema-validator.d.ts +35 -0
  22. package/dist/lib/tool-schema-validator.d.ts.map +1 -0
  23. package/dist/lib/tool-schema-validator.js +146 -0
  24. package/dist/lib/tool-schema-validator.js.map +1 -0
  25. package/dist/marketplace-tools.d.ts +116 -0
  26. package/dist/marketplace-tools.d.ts.map +1 -0
  27. package/dist/marketplace-tools.js +3089 -0
  28. package/dist/marketplace-tools.js.map +1 -0
  29. package/dist/organization-tools.d.ts +37 -0
  30. package/dist/organization-tools.d.ts.map +1 -0
  31. package/dist/organization-tools.js +609 -0
  32. package/dist/organization-tools.js.map +1 -0
  33. package/dist/seller-tools.d.ts +28 -0
  34. package/dist/seller-tools.d.ts.map +1 -0
  35. package/dist/seller-tools.js +437 -0
  36. package/dist/seller-tools.js.map +1 -0
  37. package/dist/src/mcp-tools/gateway-tools.d.ts +107 -0
  38. package/dist/src/mcp-tools/gateway-tools.d.ts.map +1 -0
  39. package/dist/src/mcp-tools/gateway-tools.js +398 -0
  40. package/dist/src/mcp-tools/gateway-tools.js.map +1 -0
  41. package/dist/src/types/mcp-types.d.ts +76 -0
  42. package/dist/src/types/mcp-types.d.ts.map +1 -0
  43. package/dist/src/types/mcp-types.js +54 -0
  44. package/dist/src/types/mcp-types.js.map +1 -0
  45. package/dist/support-tools.d.ts +23 -0
  46. package/dist/support-tools.d.ts.map +1 -0
  47. package/dist/support-tools.js +292 -0
  48. package/dist/support-tools.js.map +1 -0
  49. package/dist/test-key-redaction-integration.d.ts +7 -0
  50. package/dist/test-key-redaction-integration.d.ts.map +1 -0
  51. package/dist/test-key-redaction-integration.js +80 -0
  52. package/dist/test-key-redaction-integration.js.map +1 -0
  53. package/dist/test-key-redaction.d.ts +6 -0
  54. package/dist/test-key-redaction.d.ts.map +1 -0
  55. package/dist/test-key-redaction.js +115 -0
  56. package/dist/test-key-redaction.js.map +1 -0
  57. package/dist/test-vault-migration.d.ts +2 -0
  58. package/dist/test-vault-migration.d.ts.map +1 -0
  59. package/dist/test-vault-migration.js +130 -0
  60. package/dist/test-vault-migration.js.map +1 -0
  61. package/dist/user-tools.d.ts +40 -0
  62. package/dist/user-tools.d.ts.map +1 -0
  63. package/dist/user-tools.js +685 -0
  64. package/dist/user-tools.js.map +1 -0
  65. package/package.json +2 -69
package/dist/cli.js ADDED
@@ -0,0 +1,792 @@
1
+ "use strict";
2
+ // File: gateway-type3/cli.ts
3
+ // CLI Client for Gateway Type 3 Management
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const local_vault_1 = require("./local-vault");
10
+ const MANAGEMENT_URL = process.env.MANAGEMENT_URL || 'http://localhost:8083';
11
+ const REGISTRY_URL = process.env.REGISTRY_API_URL || 'http://localhost:8081';
12
+ // Initialize vault to check for stored auth key
13
+ const vault = new local_vault_1.LocalVault({
14
+ vaultPath: process.env.VAULT_PATH,
15
+ masterPassword: process.env.VAULT_PASSWORD
16
+ });
17
+ // Auto-load API key from vault if not in environment
18
+ let API_KEY = process.env.GATEWAY_API_KEY || '';
19
+ if (!API_KEY && vault.hasAuthKey()) {
20
+ API_KEY = vault.getAuthKey() || '';
21
+ if (API_KEY) {
22
+ console.log('šŸ” Using stored authentication key from vault');
23
+ }
24
+ }
25
+ /**
26
+ * Helper function to resolve connection identifier to UUID
27
+ * Accepts either:
28
+ * - Sequence number (1, 2, 3...) - maps to connection sorted by created_at
29
+ * - UUID - returns as-is
30
+ */
31
+ async function resolveConnectionId(input) {
32
+ // If input is a UUID format, return as-is
33
+ if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(input)) {
34
+ return input;
35
+ }
36
+ // Otherwise treat as sequence number
37
+ const index = parseInt(input);
38
+ if (isNaN(index) || index < 1) {
39
+ throw new Error('Invalid connection identifier. Use sequence number (1, 2, 3...) or UUID');
40
+ }
41
+ // Fetch connections sorted by created_at
42
+ const response = await axios_1.default.get(`${REGISTRY_URL}/api/connections`, {
43
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
44
+ });
45
+ // Sort by created_at (oldest first)
46
+ const sorted = response.data.connections.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
47
+ if (index > sorted.length) {
48
+ throw new Error(`Connection #${index} not found. You have ${sorted.length} connection(s)`);
49
+ }
50
+ return sorted[index - 1].id;
51
+ }
52
+ const commands = [
53
+ {
54
+ name: 'status',
55
+ description: 'Get gateway running status',
56
+ handler: async (args) => {
57
+ try {
58
+ const response = await axios_1.default.get(`${MANAGEMENT_URL}/status`);
59
+ console.log('\nšŸ“Š Gateway Status:');
60
+ console.log('─'.repeat(60));
61
+ console.log(`Status: ${response.data.status}`);
62
+ console.log(`Version: ${response.data.version}`);
63
+ console.log(`Instance ID: ${response.data.instance_id}`);
64
+ console.log(`Uptime: ${response.data.uptime_human}`);
65
+ console.log(`Registry Connected: ${response.data.registry_connected ? 'āœ… Yes' : 'āŒ No'}`);
66
+ console.log(`Registry Auth: ${response.data.registry_authenticated ? 'āœ… Yes' : 'āŒ No'}`);
67
+ console.log('\nšŸ“ˆ Metrics:');
68
+ console.log(` Requests Handled: ${response.data.metrics.requests_handled}`);
69
+ console.log(` Requests Active: ${response.data.metrics.requests_active}`);
70
+ console.log(` Error Count: ${response.data.metrics.error_count}`);
71
+ console.log(` Avg Latency: ${response.data.metrics.avg_latency_ms.toFixed(2)}ms`);
72
+ console.log('\nšŸ” Local Vault Credentials:');
73
+ console.log(` Total Stored: ${response.data.credentials.connections_count}`);
74
+ if (response.data.credentials.connections_count > 0) {
75
+ console.log(` Use "npm run cli providers" for details`);
76
+ }
77
+ console.log('─'.repeat(60));
78
+ }
79
+ catch (error) {
80
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
81
+ process.exit(1);
82
+ }
83
+ }
84
+ },
85
+ {
86
+ name: 'shutdown',
87
+ description: 'Gracefully shutdown the gateway',
88
+ handler: async (args) => {
89
+ try {
90
+ const response = await axios_1.default.post(`${MANAGEMENT_URL}/shutdown`);
91
+ console.log('āœ…', response.data.message);
92
+ }
93
+ catch (error) {
94
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
95
+ process.exit(1);
96
+ }
97
+ }
98
+ },
99
+ {
100
+ name: 'vault',
101
+ description: 'List credentials in local vault',
102
+ handler: async (args) => {
103
+ try {
104
+ // Get vault providers (connection_ids with credentials)
105
+ const vaultResponse = await axios_1.default.get(`${MANAGEMENT_URL}/providers`);
106
+ if (vaultResponse.data.providers.length === 0) {
107
+ console.log('\nšŸ”Œ Local Vault Providers:');
108
+ console.log('─'.repeat(80));
109
+ console.log(' No credentials stored in local vault');
110
+ console.log(' Use "npm run cli add-provider <#> <api-key>" to add credentials');
111
+ console.log('─'.repeat(80));
112
+ return;
113
+ }
114
+ // Fetch connection details from registry if API key available
115
+ let connectionsMap = new Map();
116
+ if (API_KEY) {
117
+ try {
118
+ const connectionsResponse = await axios_1.default.get(`${REGISTRY_URL}/api/connections`, {
119
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
120
+ });
121
+ // Sort by created_at to match sequence numbering
122
+ const sorted = connectionsResponse.data.connections.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
123
+ sorted.forEach((conn, index) => {
124
+ connectionsMap.set(conn.id, { ...conn, sequence: index + 1 });
125
+ });
126
+ }
127
+ catch (e) {
128
+ // Registry not available, show limited info
129
+ }
130
+ }
131
+ console.log('\nšŸ”Œ Local Vault Providers:');
132
+ console.log('─'.repeat(80));
133
+ vaultResponse.data.providers.forEach((provider) => {
134
+ const connDetails = connectionsMap.get(provider.connection_id);
135
+ if (connDetails) {
136
+ console.log(`#${connDetails.sequence} - ${connDetails.access_key}`);
137
+ console.log(` Provider: ${connDetails.provider.name} (${connDetails.provider.key})`);
138
+ console.log(` Endpoint: ${connDetails.endpoint_url}`);
139
+ console.log(` Gateway Mode: self-hosted (local vault)`);
140
+ console.log(` Credential: āœ… Stored in vault`);
141
+ }
142
+ else {
143
+ console.log(` ${provider.connection_id}`);
144
+ console.log(` Credential: āœ… Stored in vault`);
145
+ console.log(` (Run "npm run cli connections" for full details)`);
146
+ }
147
+ console.log('');
148
+ });
149
+ console.log(`Total: ${vaultResponse.data.providers.length} credential(s) in local vault`);
150
+ console.log('─'.repeat(80));
151
+ }
152
+ catch (error) {
153
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
154
+ process.exit(1);
155
+ }
156
+ }
157
+ },
158
+ {
159
+ name: 'add-provider',
160
+ description: 'Add a provider credential (Usage: add-provider <#|connection_id> <api_key> [provider_name] [description])',
161
+ handler: async (args) => {
162
+ if (args.length < 2) {
163
+ console.error('āŒ Usage: add-provider <#|connection_id> <api_key> [provider_name] [description]');
164
+ console.error(' #: Connection sequence number from connections (e.g., 1, 2, 3)');
165
+ console.error(' connection_id: UUID of the connection');
166
+ process.exit(1);
167
+ }
168
+ const [connection_input, api_key, provider_name, description] = args;
169
+ try {
170
+ const connection_id = await resolveConnectionId(connection_input);
171
+ const response = await axios_1.default.post(`${MANAGEMENT_URL}/providers`, {
172
+ connection_id,
173
+ api_key,
174
+ provider_name,
175
+ description
176
+ });
177
+ console.log('āœ…', response.data.message);
178
+ }
179
+ catch (error) {
180
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
181
+ process.exit(1);
182
+ }
183
+ }
184
+ },
185
+ {
186
+ name: 'update-provider',
187
+ description: 'Update a provider credential API key (Usage: update-provider <#|connection_id> <new_api_key>)',
188
+ handler: async (args) => {
189
+ if (args.length < 2) {
190
+ console.error('āŒ Usage: update-provider <#|connection_id> <new_api_key>');
191
+ console.error(' #: Connection sequence number from connections (e.g., 1, 2, 3)');
192
+ process.exit(1);
193
+ }
194
+ const [connection_input, api_key] = args;
195
+ try {
196
+ const connection_id = await resolveConnectionId(connection_input);
197
+ // Remove old credential
198
+ await axios_1.default.delete(`${MANAGEMENT_URL}/providers/${connection_id}`);
199
+ // Add new credential
200
+ const response = await axios_1.default.post(`${MANAGEMENT_URL}/providers`, {
201
+ connection_id,
202
+ api_key
203
+ });
204
+ console.log('āœ…', response.data.message);
205
+ }
206
+ catch (error) {
207
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
208
+ process.exit(1);
209
+ }
210
+ }
211
+ },
212
+ {
213
+ name: 'remove-provider',
214
+ description: 'Remove a provider credential (Usage: remove-provider <#|connection_id>)',
215
+ handler: async (args) => {
216
+ if (args.length < 1) {
217
+ console.error('āŒ Usage: remove-provider <#|connection_id>');
218
+ console.error(' #: Connection sequence number from connections (e.g., 1, 2, 3)');
219
+ process.exit(1);
220
+ }
221
+ const [connection_input] = args;
222
+ try {
223
+ const connection_id = await resolveConnectionId(connection_input);
224
+ const response = await axios_1.default.delete(`${MANAGEMENT_URL}/providers/${connection_id}`);
225
+ console.log('āœ…', response.data.message);
226
+ }
227
+ catch (error) {
228
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
229
+ process.exit(1);
230
+ }
231
+ }
232
+ },
233
+ {
234
+ name: 'auth',
235
+ description: 'Authenticate with registry and save API key (Usage: auth <api_key>)',
236
+ handler: async (args) => {
237
+ if (args.length < 1) {
238
+ console.error('āŒ Usage: auth <api_key>');
239
+ process.exit(1);
240
+ }
241
+ const [api_key] = args;
242
+ try {
243
+ // Test the API key by making a request to the registry
244
+ console.log('šŸ”‘ Testing API key with registry...');
245
+ const testResponse = await axios_1.default.get(`${REGISTRY_URL}/api/connections`, {
246
+ headers: { 'Authorization': `Bearer ${api_key}` }
247
+ });
248
+ // If we got here, the key is valid
249
+ console.log('āœ… API key is valid');
250
+ // Save to vault for future use
251
+ await vault.setAuthKey(api_key);
252
+ console.log('āœ… API key saved to vault');
253
+ console.log('ā„¹ļø You can now run CLI commands without setting GATEWAY_API_KEY');
254
+ // Update gateway's auth key via management API
255
+ try {
256
+ const response = await axios_1.default.post(`${MANAGEMENT_URL}/auth`, { api_key });
257
+ console.log('āœ…', response.data.message);
258
+ if (response.data.note) {
259
+ console.log('ā„¹ļø ', response.data.note);
260
+ }
261
+ }
262
+ catch (mgmtError) {
263
+ console.log('āš ļø Gateway not running - key saved to vault only');
264
+ }
265
+ // Update the global API_KEY variable
266
+ API_KEY = api_key;
267
+ }
268
+ catch (error) {
269
+ console.error('āŒ Authentication failed:', error.response?.data?.error || error.message);
270
+ console.error(' API key is invalid or registry is not accessible');
271
+ process.exit(1);
272
+ }
273
+ }
274
+ },
275
+ {
276
+ name: 'reconnect',
277
+ description: 'Reconnect to registry',
278
+ handler: async (args) => {
279
+ try {
280
+ const response = await axios_1.default.post(`${MANAGEMENT_URL}/reconnect`);
281
+ console.log('āœ…', response.data.message);
282
+ }
283
+ catch (error) {
284
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
285
+ process.exit(1);
286
+ }
287
+ }
288
+ },
289
+ {
290
+ name: 'logout',
291
+ description: 'Clear stored authentication key from vault',
292
+ handler: async (args) => {
293
+ try {
294
+ if (!vault.hasAuthKey()) {
295
+ console.log('ā„¹ļø No authentication key stored in vault');
296
+ return;
297
+ }
298
+ await vault.removeAuthKey();
299
+ console.log('āœ… Authentication key removed from vault');
300
+ console.log('ā„¹ļø You will need to run "auth <api_key>" again to authenticate');
301
+ // Clear the global API_KEY variable
302
+ API_KEY = '';
303
+ }
304
+ catch (error) {
305
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
306
+ process.exit(1);
307
+ }
308
+ }
309
+ },
310
+ {
311
+ name: 'health',
312
+ description: 'Check gateway health',
313
+ handler: async (args) => {
314
+ try {
315
+ const response = await axios_1.default.get(`${MANAGEMENT_URL}/health`);
316
+ console.log('āœ… Gateway is healthy');
317
+ console.log(' Timestamp:', response.data.timestamp);
318
+ }
319
+ catch (error) {
320
+ console.error('āŒ Gateway is unhealthy');
321
+ console.error(' Error:', error.response?.data?.error || error.message);
322
+ process.exit(1);
323
+ }
324
+ }
325
+ },
326
+ {
327
+ name: 'models',
328
+ description: 'Discover available models from connections (Usage: models [#|connection_id])',
329
+ handler: async (args) => {
330
+ if (!API_KEY) {
331
+ console.error('āŒ GATEWAY_API_KEY environment variable is required');
332
+ process.exit(1);
333
+ }
334
+ try {
335
+ // Get all connections first
336
+ const connectionsResponse = await axios_1.default.get(`${REGISTRY_URL}/api/connections`, {
337
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
338
+ });
339
+ // Sort by created_at to match sequence numbering
340
+ const sorted = connectionsResponse.data.connections.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
341
+ // Determine which connections to query
342
+ let connectionsToQuery = sorted;
343
+ if (args.length > 0) {
344
+ // User specified a connection
345
+ const connection_id = await resolveConnectionId(args[0]);
346
+ connectionsToQuery = sorted.filter((c) => c.id === connection_id);
347
+ if (connectionsToQuery.length === 0) {
348
+ console.error('āŒ Connection not found');
349
+ process.exit(1);
350
+ }
351
+ }
352
+ console.log('\nšŸ¤– Discovering Models...');
353
+ console.log('─'.repeat(80));
354
+ // Query models for each connection
355
+ for (const conn of connectionsToQuery) {
356
+ const sequence = sorted.findIndex((c) => c.id === conn.id) + 1;
357
+ console.log(`\n#${sequence} - ${conn.access_key}`);
358
+ console.log(`Provider: ${conn.provider.name} (${conn.provider.key})`);
359
+ console.log(`Endpoint: ${conn.endpoint_url}`);
360
+ try {
361
+ // Make model discovery request through registry
362
+ const modelsResponse = await axios_1.default.post(`${REGISTRY_URL}/api/models/discover`, {
363
+ connection_id: conn.id
364
+ }, {
365
+ headers: {
366
+ 'Authorization': `Bearer ${API_KEY}`,
367
+ 'Content-Type': 'application/json'
368
+ },
369
+ timeout: 30000
370
+ });
371
+ if (modelsResponse.data.success && modelsResponse.data.models && modelsResponse.data.models.length > 0) {
372
+ console.log(`Models: ${modelsResponse.data.models.length} found (${modelsResponse.data.stored} stored)`);
373
+ console.log('');
374
+ // Show discovered models
375
+ modelsResponse.data.models.forEach((model, idx) => {
376
+ console.log(` ${idx + 1}. ${model.id}`);
377
+ if (model.name && model.name !== model.id) {
378
+ console.log(` Name: ${model.name}`);
379
+ }
380
+ if (model.context_window) {
381
+ console.log(` Context: ${model.context_window} tokens`);
382
+ }
383
+ if (model.pricing && (model.pricing.input > 0 || model.pricing.output > 0)) {
384
+ console.log(` Pricing: $${model.pricing.input}/1K input, $${model.pricing.output}/1K output`);
385
+ }
386
+ });
387
+ }
388
+ else {
389
+ console.log('Models: None found');
390
+ }
391
+ }
392
+ catch (error) {
393
+ if (error.code === 'ECONNABORTED') {
394
+ console.log('āš ļø Timeout - endpoint did not respond');
395
+ }
396
+ else if (error.response?.status === 404) {
397
+ console.log('āš ļø Model discovery not supported by this provider');
398
+ }
399
+ else {
400
+ console.log(`āš ļø Error: ${error.response?.data?.error || error.message}`);
401
+ }
402
+ }
403
+ }
404
+ console.log('\n' + '─'.repeat(80));
405
+ console.log(`šŸ’” Tip: Use "npm run cli models <#>" to query a specific connection`);
406
+ console.log('');
407
+ }
408
+ catch (error) {
409
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
410
+ process.exit(1);
411
+ }
412
+ }
413
+ },
414
+ {
415
+ name: 'providers',
416
+ description: 'List available providers from registry',
417
+ handler: async (args) => {
418
+ if (!API_KEY) {
419
+ console.error('āŒ GATEWAY_API_KEY environment variable is required');
420
+ process.exit(1);
421
+ }
422
+ try {
423
+ const response = await axios_1.default.get(`${REGISTRY_URL}/api/public/providers`, {
424
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
425
+ });
426
+ console.log('\n🌐 Available Providers from Registry:');
427
+ console.log('─'.repeat(80));
428
+ if (response.data.providers.length === 0) {
429
+ console.log(' No providers available');
430
+ }
431
+ else {
432
+ response.data.providers.forEach((provider, index) => {
433
+ console.log(`${index + 1}. ${provider.name}`);
434
+ console.log(` Provider Key: ${provider.key}`);
435
+ console.log(` Base URL: ${provider.base_url || 'N/A'}`);
436
+ console.log(` Your Access Pts: ${provider.user_connections}`);
437
+ console.log('');
438
+ });
439
+ }
440
+ console.log(`Total: ${response.data.total} providers`);
441
+ console.log('─'.repeat(80));
442
+ }
443
+ catch (error) {
444
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
445
+ process.exit(1);
446
+ }
447
+ }
448
+ },
449
+ {
450
+ name: 'connections',
451
+ description: 'List your access points from registry',
452
+ handler: async (args) => {
453
+ if (!API_KEY) {
454
+ console.error('āŒ GATEWAY_API_KEY environment variable is required');
455
+ process.exit(1);
456
+ }
457
+ try {
458
+ const response = await axios_1.default.get(`${REGISTRY_URL}/api/connections`, {
459
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
460
+ });
461
+ // Sort by created_at (oldest first) to maintain consistent numbering
462
+ const sorted = response.data.connections.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
463
+ console.log('\nšŸ”Œ Your Access Points:');
464
+ console.log('─'.repeat(80));
465
+ if (sorted.length === 0) {
466
+ console.log(' No access points configured');
467
+ }
468
+ else {
469
+ sorted.forEach((ap, index) => {
470
+ console.log(`#${index + 1} - ${ap.access_key}`);
471
+ console.log(` Provider: ${ap.provider.name} (${ap.provider.key})`);
472
+ console.log(` Endpoint: ${ap.endpoint_url}`);
473
+ console.log(` Type: ${ap.endpoint_type}`);
474
+ console.log(` Gateway Mode: ${ap.gateway_type === 2 ? 'managed' : 'self-hosted'}`);
475
+ console.log(` Rate Limits: ${ap.rate_limits.rpm} RPM / ${ap.rate_limits.tpm} TPM`);
476
+ console.log(` Status: ${ap.status}`);
477
+ console.log(` Created: ${new Date(ap.created_at).toLocaleString()}`);
478
+ console.log('');
479
+ });
480
+ console.log('šŸ’” Tip: Use the # number (e.g., "1") instead of UUID in commands');
481
+ }
482
+ console.log(`Total: ${sorted.length} access points`);
483
+ console.log('─'.repeat(80));
484
+ }
485
+ catch (error) {
486
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
487
+ process.exit(1);
488
+ }
489
+ }
490
+ },
491
+ {
492
+ name: 'add-connection',
493
+ description: 'Create new access point on registry (Usage: add-connection <provider_key> <endpoint_url> <gateway_mode> [endpoint_type] [api_key])',
494
+ handler: async (args) => {
495
+ if (!API_KEY) {
496
+ console.error('āŒ GATEWAY_API_KEY environment variable is required');
497
+ process.exit(1);
498
+ }
499
+ if (args.length < 3) {
500
+ console.error('āŒ Usage: add-connection <provider_key> <endpoint_url> <gateway_mode> [endpoint_type] [api_key]');
501
+ console.error(' provider_key: ollama, openai, anthropic, groq, etc.');
502
+ console.error(' endpoint_url: Provider API endpoint URL');
503
+ console.error(' gateway_mode: managed (registry-managed) or self-hosted (local vault)');
504
+ console.error(' endpoint_type: (optional, default: openai-v1) openai-v1, anthropic-messages, google-gemini, etc.');
505
+ console.error(' api_key: Required for managed, optional for self-hosted');
506
+ process.exit(1);
507
+ }
508
+ const [provider_key, endpoint_url, gateway_mode, endpoint_type = 'openai-v1', api_key] = args;
509
+ // Map gateway_mode to gateway_type number
510
+ let gateway_type;
511
+ if (gateway_mode === 'managed') {
512
+ gateway_type = 2;
513
+ }
514
+ else if (gateway_mode === 'self-hosted') {
515
+ gateway_type = 3;
516
+ }
517
+ else {
518
+ console.error('āŒ Invalid gateway_mode. Use "managed" or "self-hosted"');
519
+ process.exit(1);
520
+ }
521
+ try {
522
+ // First get provider_id from provider_key
523
+ const providersResponse = await axios_1.default.get(`${REGISTRY_URL}/api/public/providers`, {
524
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
525
+ });
526
+ const provider = providersResponse.data.providers.find((p) => p.key === provider_key);
527
+ if (!provider) {
528
+ console.error(`āŒ Provider key '${provider_key}' not found`);
529
+ console.error(' Available providers:');
530
+ providersResponse.data.providers.forEach((p) => {
531
+ console.error(` - ${p.key} (${p.name})`);
532
+ });
533
+ process.exit(1);
534
+ }
535
+ const response = await axios_1.default.post(`${REGISTRY_URL}/api/connections`, {
536
+ provider_id: provider.id,
537
+ endpoint_url,
538
+ endpoint_type,
539
+ gateway_type: gateway_type,
540
+ api_key
541
+ }, {
542
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
543
+ });
544
+ console.log('āœ…', response.data.message);
545
+ console.log('\nšŸ“‹ Access Point Details:');
546
+ console.log(' ID: ', response.data.connection.id);
547
+ console.log(' Access Key: ', response.data.connection.access_key);
548
+ console.log(' Provider: ', response.data.connection.provider.name);
549
+ console.log(' Gateway Mode: ', gateway_type === 2 ? 'managed' : 'self-hosted');
550
+ console.log(' Status: ', response.data.connection.status);
551
+ if (gateway_type === 3 && api_key) {
552
+ console.log('\nā„¹ļø Now adding credential to local vault...');
553
+ try {
554
+ const vaultResponse = await axios_1.default.post(`${MANAGEMENT_URL}/providers`, {
555
+ connection_id: response.data.connection.id,
556
+ api_key: api_key,
557
+ provider_name: response.data.connection.provider.name
558
+ });
559
+ console.log('āœ…', vaultResponse.data.message);
560
+ }
561
+ catch (vaultError) {
562
+ console.error('āš ļø Warning: Failed to add to local vault:', vaultError.response?.data?.error || vaultError.message);
563
+ console.error(' You can add it manually using: npm run cli add-provider');
564
+ }
565
+ }
566
+ }
567
+ catch (error) {
568
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
569
+ process.exit(1);
570
+ }
571
+ }
572
+ },
573
+ {
574
+ name: 'switch-to-managed',
575
+ description: 'Switch access point to managed mode (registry-managed) (Usage: switch-to-managed <#|connection_id> [api_key])',
576
+ handler: async (args) => {
577
+ if (!API_KEY) {
578
+ console.error('āŒ GATEWAY_API_KEY environment variable is required');
579
+ process.exit(1);
580
+ }
581
+ if (args.length < 1) {
582
+ console.error('āŒ Usage: switch-to-managed <#|connection_id> [api_key]');
583
+ console.error(' #: Connection sequence number from connections (e.g., 1, 2, 3)');
584
+ console.error(' api_key: (optional) The provider API key, will be retrieved from local vault if not provided');
585
+ process.exit(1);
586
+ }
587
+ const [connection_input, provided_api_key] = args;
588
+ let api_key = provided_api_key;
589
+ try {
590
+ const connection_id = await resolveConnectionId(connection_input);
591
+ // If API key not provided, backend will retrieve it from vault automatically
592
+ if (!api_key) {
593
+ console.log('ā„¹ļø API key will be retrieved from local vault by backend...');
594
+ }
595
+ const response = await axios_1.default.put(`${REGISTRY_URL}/api/connections/${connection_id}`, {
596
+ gateway_type: 2,
597
+ api_key: api_key || undefined
598
+ }, {
599
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
600
+ });
601
+ console.log('āœ…', response.data.message);
602
+ console.log(' Access point switched to managed mode (registry-managed)');
603
+ console.log(' Credential is now stored on registry');
604
+ console.log('\nā„¹ļø Removing credential from local vault...');
605
+ try {
606
+ await axios_1.default.delete(`${MANAGEMENT_URL}/providers/${connection_id}`);
607
+ console.log('āœ… Credential removed from local vault');
608
+ }
609
+ catch (vaultError) {
610
+ console.error('āš ļø Warning: Failed to remove from local vault:', vaultError.response?.data?.error || vaultError.message);
611
+ }
612
+ }
613
+ catch (error) {
614
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
615
+ process.exit(1);
616
+ }
617
+ }
618
+ },
619
+ {
620
+ name: 'switch-to-self-hosted',
621
+ description: 'Switch access point to self-hosted mode (local vault) (Usage: switch-to-self-hosted <#|connection_id> <api_key>)',
622
+ handler: async (args) => {
623
+ if (!API_KEY) {
624
+ console.error('āŒ GATEWAY_API_KEY environment variable is required');
625
+ process.exit(1);
626
+ }
627
+ if (args.length < 2) {
628
+ console.error('āŒ Usage: switch-to-self-hosted <#|connection_id> <api_key>');
629
+ console.error(' #: Connection sequence number from connections (e.g., 1, 2, 3)');
630
+ console.error(' api_key: The provider API key to store in local vault');
631
+ process.exit(1);
632
+ }
633
+ const [connection_input, api_key] = args;
634
+ try {
635
+ const connection_id = await resolveConnectionId(connection_input);
636
+ const response = await axios_1.default.put(`${REGISTRY_URL}/api/connections/${connection_id}`, {
637
+ gateway_type: 3,
638
+ api_key
639
+ }, {
640
+ headers: { 'Authorization': `Bearer ${API_KEY}` }
641
+ });
642
+ console.log('āœ…', response.data.message);
643
+ console.log(' Access point switched to self-hosted mode (local vault)');
644
+ console.log(' Credential removed from registry');
645
+ console.log('\nā„¹ļø Adding credential to local vault...');
646
+ try {
647
+ const vaultResponse = await axios_1.default.post(`${MANAGEMENT_URL}/providers`, {
648
+ connection_id: connection_id,
649
+ api_key: api_key
650
+ });
651
+ console.log('āœ…', vaultResponse.data.message);
652
+ }
653
+ catch (vaultError) {
654
+ console.error('āš ļø Warning: Failed to add to local vault:', vaultError.response?.data?.error || vaultError.message);
655
+ }
656
+ }
657
+ catch (error) {
658
+ console.error('āŒ Error:', error.response?.data?.error || error.message);
659
+ process.exit(1);
660
+ }
661
+ }
662
+ },
663
+ {
664
+ name: 'help',
665
+ description: 'Show this help message',
666
+ handler: async (args) => {
667
+ showHelp();
668
+ }
669
+ }
670
+ ];
671
+ function showHelp() {
672
+ console.log('\n');
673
+ console.log('═'.repeat(80));
674
+ console.log('šŸš€ Gateway Type 3 CLI - Self-Hosted Gateway Management');
675
+ console.log('═'.repeat(80));
676
+ console.log('\nšŸ’” TIP: Interactive UI Available!');
677
+ console.log('─'.repeat(80));
678
+ console.log(' For a better experience, try the interactive UI:');
679
+ console.log(' npm run ui');
680
+ console.log(' Features: Visual menus, real-time status, guided workflows');
681
+ console.log('\nšŸ“š QUICK START - First Time Setup:');
682
+ console.log('─'.repeat(80));
683
+ console.log(' 1. Authenticate (saves your API key securely):');
684
+ console.log(' npm run cli auth <your-api-key>');
685
+ console.log(' Example: npm run cli auth sk-test-inference-key');
686
+ console.log('');
687
+ console.log(' 2. View your access points (connections):');
688
+ console.log(' npm run cli connections');
689
+ console.log('');
690
+ console.log(' 3. Add provider credentials to local vault:');
691
+ console.log(' npm run cli add-provider <#> <api-key>');
692
+ console.log(' Example: npm run cli add-provider 1 ollama');
693
+ console.log('');
694
+ console.log(' šŸ’” After authentication, you can run ALL commands without setting API key!');
695
+ console.log('\nšŸ”‘ Authentication & Security:');
696
+ console.log('─'.repeat(80));
697
+ console.log(' auth <api-key> Authenticate with registry (saves key to vault)');
698
+ console.log(' logout Clear stored authentication key from vault');
699
+ console.log(' status Show gateway health and connection status');
700
+ console.log(' health Quick health check');
701
+ console.log(' models [#] Discover available models (all connections or specific #)');
702
+ console.log('\nšŸ”Œ Access Points (Connections) - View & Manage:');
703
+ console.log('─'.repeat(80));
704
+ console.log(' connections List all your access points with sequence numbers (#1, #2...)');
705
+ console.log(' providers List available providers from registry');
706
+ console.log(' add-connection Create new access point on registry');
707
+ console.log(' Usage: add-connection <provider> <url> <mode> [type] [key]');
708
+ console.log(' Example: add-connection ollama http://localhost:11434/v1 self-hosted');
709
+ console.log('\nšŸ—ļø Provider Credentials - Local Vault Management:');
710
+ console.log('─'.repeat(80));
711
+ console.log(' vault List credentials stored in local vault');
712
+ console.log(' add-provider Add credential to vault (use # from connections)');
713
+ console.log(' Usage: add-provider <#> <api-key> [name] [description]');
714
+ console.log(' Example: add-provider 1 ollama');
715
+ console.log(' update-provider Update credential in vault');
716
+ console.log(' Usage: update-provider <#> <new-api-key>');
717
+ console.log(' remove-provider Remove credential from vault');
718
+ console.log(' Usage: remove-provider <#>');
719
+ console.log('\nšŸ”„ Gateway Mode Switching:');
720
+ console.log('─'.repeat(80));
721
+ console.log(' switch-to-managed Switch to managed mode (registry stores credential)');
722
+ console.log(' Usage: switch-to-managed <#> [api-key]');
723
+ console.log(' switch-to-self-hosted Switch to self-hosted mode (local vault stores credential)');
724
+ console.log(' Usage: switch-to-self-hosted <#> <api-key>');
725
+ console.log('\nāš™ļø Gateway Control:');
726
+ console.log('─'.repeat(80));
727
+ console.log(' shutdown Gracefully shutdown the gateway server');
728
+ console.log(' reconnect Reconnect gateway to registry');
729
+ console.log('\nšŸ’” TIPS & TRICKS:');
730
+ console.log('─'.repeat(80));
731
+ console.log(' • Use sequence numbers (#1, #2, #3) instead of long UUIDs');
732
+ console.log(' • Run "connections" to see all your # numbers');
733
+ console.log(' • "Managed" mode: Registry stores credentials (easier, less private)');
734
+ console.log(' • "Self-hosted" mode: Local vault stores credentials (more secure, more control)');
735
+ console.log(' • Authenticate once with "auth" - key saved securely for all future commands');
736
+ console.log(' • Use "logout" to clear stored authentication when switching accounts');
737
+ console.log('\nšŸ“– COMMON WORKFLOWS:');
738
+ console.log('─'.repeat(80));
739
+ console.log(' First-time setup:');
740
+ console.log(' npm run cli auth sk-your-api-key');
741
+ console.log(' npm run cli connections');
742
+ console.log(' npm run cli add-provider 1 <provider-api-key>');
743
+ console.log('');
744
+ console.log(' Check gateway status:');
745
+ console.log(' npm run cli status');
746
+ console.log(' npm run cli vault');
747
+ console.log('');
748
+ console.log(' Discover available models:');
749
+ console.log(' npm run cli models # All connections');
750
+ console.log(' npm run cli models 4 # Specific connection #4');
751
+ console.log('');
752
+ console.log(' Manage credentials:');
753
+ console.log(' npm run cli connections # See all access points');
754
+ console.log(' npm run cli add-provider 2 <api-key> # Add credential for #2');
755
+ console.log(' npm run cli update-provider 2 <new-api-key> # Update credential for #2');
756
+ console.log(' npm run cli remove-provider 2 # Remove credential for #2');
757
+ console.log('');
758
+ console.log(' Switch modes:');
759
+ console.log(' npm run cli switch-to-managed 1 # Move to registry');
760
+ console.log(' npm run cli switch-to-self-hosted 1 <api-key> # Move to local vault');
761
+ console.log('\n🌐 Environment Variables (Optional):');
762
+ console.log('─'.repeat(80));
763
+ console.log(' GATEWAY_API_KEY Your registry API key (auto-loaded from vault after auth)');
764
+ console.log(' MANAGEMENT_URL Gateway management API (default: http://localhost:8083)');
765
+ console.log(' REGISTRY_API_URL Registry API URL (default: http://localhost:8081)');
766
+ console.log('\n');
767
+ console.log('═'.repeat(80));
768
+ console.log('šŸ“˜ For more help, visit: https://github.com/your-repo/docs');
769
+ console.log('═'.repeat(80));
770
+ console.log('');
771
+ }
772
+ async function main() {
773
+ const args = process.argv.slice(2);
774
+ if (args.length === 0) {
775
+ showHelp();
776
+ process.exit(0);
777
+ }
778
+ const commandName = args[0];
779
+ const commandArgs = args.slice(1);
780
+ const command = commands.find(cmd => cmd.name === commandName);
781
+ if (!command) {
782
+ console.error(`āŒ Unknown command: ${commandName}`);
783
+ console.error(' Run "npm run cli help" for available commands');
784
+ process.exit(1);
785
+ }
786
+ await command.handler(commandArgs);
787
+ }
788
+ main().catch((error) => {
789
+ console.error('āŒ Fatal error:', error.message);
790
+ process.exit(1);
791
+ });
792
+ //# sourceMappingURL=cli.js.map