sphereai-cli 1.0.0

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 (70) hide show
  1. package/README.md +529 -0
  2. package/dist/commands/auth.d.ts +3 -0
  3. package/dist/commands/auth.d.ts.map +1 -0
  4. package/dist/commands/auth.js +194 -0
  5. package/dist/commands/auth.js.map +1 -0
  6. package/dist/commands/execute.d.ts +3 -0
  7. package/dist/commands/execute.d.ts.map +1 -0
  8. package/dist/commands/execute.js +165 -0
  9. package/dist/commands/execute.js.map +1 -0
  10. package/dist/commands/files.d.ts +3 -0
  11. package/dist/commands/files.d.ts.map +1 -0
  12. package/dist/commands/files.js +235 -0
  13. package/dist/commands/files.js.map +1 -0
  14. package/dist/commands/models.d.ts +3 -0
  15. package/dist/commands/models.d.ts.map +1 -0
  16. package/dist/commands/models.js +70 -0
  17. package/dist/commands/models.js.map +1 -0
  18. package/dist/commands/prompts.d.ts +3 -0
  19. package/dist/commands/prompts.d.ts.map +1 -0
  20. package/dist/commands/prompts.js +72 -0
  21. package/dist/commands/prompts.js.map +1 -0
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +103 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/services/api-client.d.ts +16 -0
  27. package/dist/services/api-client.d.ts.map +1 -0
  28. package/dist/services/api-client.js +125 -0
  29. package/dist/services/api-client.js.map +1 -0
  30. package/dist/services/auth-service.d.ts +28 -0
  31. package/dist/services/auth-service.d.ts.map +1 -0
  32. package/dist/services/auth-service.js +171 -0
  33. package/dist/services/auth-service.js.map +1 -0
  34. package/dist/services/cli-api-client.d.ts +20 -0
  35. package/dist/services/cli-api-client.d.ts.map +1 -0
  36. package/dist/services/cli-api-client.js +83 -0
  37. package/dist/services/cli-api-client.js.map +1 -0
  38. package/dist/services/config-service.d.ts +43 -0
  39. package/dist/services/config-service.d.ts.map +1 -0
  40. package/dist/services/config-service.js +97 -0
  41. package/dist/services/config-service.js.map +1 -0
  42. package/dist/services/file-tracking-service.d.ts +62 -0
  43. package/dist/services/file-tracking-service.d.ts.map +1 -0
  44. package/dist/services/file-tracking-service.js +207 -0
  45. package/dist/services/file-tracking-service.js.map +1 -0
  46. package/dist/types/api-types.d.ts +67 -0
  47. package/dist/types/api-types.d.ts.map +1 -0
  48. package/dist/types/api-types.js +10 -0
  49. package/dist/types/api-types.js.map +1 -0
  50. package/dist/utils/errors.d.ts +35 -0
  51. package/dist/utils/errors.d.ts.map +1 -0
  52. package/dist/utils/errors.js +82 -0
  53. package/dist/utils/errors.js.map +1 -0
  54. package/dist/utils/file-walker.d.ts +31 -0
  55. package/dist/utils/file-walker.d.ts.map +1 -0
  56. package/dist/utils/file-walker.js +118 -0
  57. package/dist/utils/file-walker.js.map +1 -0
  58. package/dist/utils/formatters.d.ts +35 -0
  59. package/dist/utils/formatters.d.ts.map +1 -0
  60. package/dist/utils/formatters.js +101 -0
  61. package/dist/utils/formatters.js.map +1 -0
  62. package/dist/utils/ignore-parser.d.ts +21 -0
  63. package/dist/utils/ignore-parser.d.ts.map +1 -0
  64. package/dist/utils/ignore-parser.js +170 -0
  65. package/dist/utils/ignore-parser.js.map +1 -0
  66. package/dist/utils/sphereignore.d.ts +34 -0
  67. package/dist/utils/sphereignore.d.ts.map +1 -0
  68. package/dist/utils/sphereignore.js +148 -0
  69. package/dist/utils/sphereignore.js.map +1 -0
  70. package/package.json +48 -0
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerModelsCommands(program: Command): void;
3
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/commands/models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoE7D"}
@@ -0,0 +1,70 @@
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.registerModelsCommands = registerModelsCommands;
7
+ const ora_1 = __importDefault(require("ora"));
8
+ const api_client_1 = require("../services/api-client");
9
+ const config_service_1 = require("../services/config-service");
10
+ const formatters_1 = require("../utils/formatters");
11
+ const errors_1 = require("../utils/errors");
12
+ function registerModelsCommands(program) {
13
+ const models = program
14
+ .command('models')
15
+ .description('AI Models management commands');
16
+ // List models command
17
+ models
18
+ .command('list')
19
+ .alias('ls')
20
+ .description('List available AI models')
21
+ .option('-p, --page <number>', 'Page number', parseInt, 1)
22
+ .option('-s, --size <number>', 'Page size', parseInt, 20)
23
+ .option('-a, --active-only', 'Show only active models', false)
24
+ .option('-o, --output <format>', 'Output format (json|table)', 'table')
25
+ .action(async (options) => {
26
+ try {
27
+ const token = config_service_1.configService.getToken();
28
+ (0, errors_1.requireAuth)(token);
29
+ const spinner = (0, ora_1.default)('Fetching AI models...').start();
30
+ const queryParams = {
31
+ _page: options.page,
32
+ _size: options.size,
33
+ _order: 'name'
34
+ };
35
+ // Filter active only
36
+ if (options.activeOnly) {
37
+ queryParams.active = true;
38
+ }
39
+ const modelsData = await api_client_1.apiClient.listModels(queryParams);
40
+ spinner.stop();
41
+ const format = options.output;
42
+ console.log((0, formatters_1.formatModelsList)(modelsData, format));
43
+ (0, formatters_1.info)(`Showing page ${options.page} (${modelsData.length} results)`);
44
+ }
45
+ catch (err) {
46
+ (0, errors_1.handleError)(err);
47
+ }
48
+ });
49
+ // Get model command
50
+ models
51
+ .command('get')
52
+ .description('Get AI model details by ID')
53
+ .argument('<model-id>', 'AI Model ID', parseInt)
54
+ .option('-o, --output <format>', 'Output format (json|table)', 'table')
55
+ .action(async (modelId, options) => {
56
+ try {
57
+ const token = config_service_1.configService.getToken();
58
+ (0, errors_1.requireAuth)(token);
59
+ const spinner = (0, ora_1.default)('Fetching model details...').start();
60
+ const model = await api_client_1.apiClient.getModel(modelId);
61
+ spinner.stop();
62
+ const format = options.output;
63
+ console.log((0, formatters_1.formatModel)(model, format));
64
+ }
65
+ catch (err) {
66
+ (0, errors_1.handleError)(err);
67
+ }
68
+ });
69
+ }
70
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/commands/models.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerPromptsCommands(program: Command): void;
3
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/commands/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqE9D"}
@@ -0,0 +1,72 @@
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.registerPromptsCommands = registerPromptsCommands;
7
+ const ora_1 = __importDefault(require("ora"));
8
+ const api_client_1 = require("../services/api-client");
9
+ const config_service_1 = require("../services/config-service");
10
+ const formatters_1 = require("../utils/formatters");
11
+ const errors_1 = require("../utils/errors");
12
+ function registerPromptsCommands(program) {
13
+ const prompts = program
14
+ .command('prompts')
15
+ .description('Manage prompts');
16
+ // List prompts command
17
+ prompts
18
+ .command('list')
19
+ .description('List all prompts')
20
+ .option('-o, --output <format>', 'Output format (json|table)', 'table')
21
+ .action(async (options) => {
22
+ try {
23
+ const token = config_service_1.configService.getToken();
24
+ if (!token) {
25
+ (0, formatters_1.error)('Not authenticated. Please login using "sphereai auth login"');
26
+ process.exit(1);
27
+ }
28
+ const spinner = (0, ora_1.default)('Fetching prompts...').start();
29
+ const response = await api_client_1.apiClient.getPrompts();
30
+ spinner.stop();
31
+ if (response.data.length === 0) {
32
+ (0, formatters_1.info)('No prompts found');
33
+ return;
34
+ }
35
+ const format = options.output;
36
+ console.log((0, formatters_1.formatPrompts)(response.data, format));
37
+ console.log('');
38
+ (0, formatters_1.info)(`${response.total} total prompts`);
39
+ }
40
+ catch (err) {
41
+ (0, errors_1.handleError)(err);
42
+ }
43
+ });
44
+ // Get prompt by ID command
45
+ prompts
46
+ .command('get <id>')
47
+ .description('Get prompt details by ID')
48
+ .option('-o, --output <format>', 'Output format (json|table)', 'table')
49
+ .action(async (id, options) => {
50
+ try {
51
+ const token = config_service_1.configService.getToken();
52
+ if (!token) {
53
+ (0, formatters_1.error)('Not authenticated. Please login using "sphereai auth login"');
54
+ process.exit(1);
55
+ }
56
+ const promptId = parseInt(id, 10);
57
+ if (isNaN(promptId)) {
58
+ (0, formatters_1.error)('Invalid prompt ID. Please provide a valid number.');
59
+ process.exit(1);
60
+ }
61
+ const spinner = (0, ora_1.default)(`Fetching prompt ${promptId}...`).start();
62
+ const prompt = await api_client_1.apiClient.getPromptById(promptId);
63
+ spinner.stop();
64
+ const format = options.output;
65
+ console.log((0, formatters_1.formatPromptDetails)(prompt, format));
66
+ }
67
+ catch (err) {
68
+ (0, errors_1.handleError)(err);
69
+ }
70
+ });
71
+ }
72
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/commands/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const dotenv_1 = __importDefault(require("dotenv"));
8
+ // Load environment variables from .env file
9
+ dotenv_1.default.config();
10
+ const commander_1 = require("commander");
11
+ const auth_1 = require("./commands/auth");
12
+ const prompts_1 = require("./commands/prompts");
13
+ const files_1 = require("./commands/files");
14
+ const config_service_1 = require("./services/config-service");
15
+ const api_client_1 = require("./services/api-client");
16
+ // Create the main CLI program
17
+ const program = new commander_1.Command();
18
+ program
19
+ .name('sphereai')
20
+ .description('CLI tool for interacting with the SphereAI API')
21
+ .version('1.0.0')
22
+ .option('--token <token>', 'Override stored authentication token')
23
+ .hook('preAction', (thisCommand) => {
24
+ // Handle global options before any command runs
25
+ const opts = thisCommand.opts();
26
+ // Override API URL if provided
27
+ if (opts.apiUrl) {
28
+ config_service_1.configService.setApiUrl(opts.apiUrl);
29
+ }
30
+ // Override token if provided
31
+ if (opts.token) {
32
+ api_client_1.apiClient.setAuthToken(opts.token);
33
+ }
34
+ else {
35
+ // Use stored token
36
+ const storedToken = config_service_1.configService.getToken();
37
+ if (storedToken) {
38
+ api_client_1.apiClient.setAuthToken(storedToken);
39
+ }
40
+ }
41
+ });
42
+ // Register command groups
43
+ (0, auth_1.registerAuthCommands)(program);
44
+ (0, prompts_1.registerPromptsCommands)(program);
45
+ (0, files_1.registerFilesCommands)(program);
46
+ // Add help examples
47
+ program.addHelpText('after', `
48
+
49
+ Examples:
50
+ # Authenticate using UserChannelKey
51
+ $ sphereai auth login YOUR_USER_CHANNEL_KEY
52
+
53
+ # Authenticate using OAuth2 (legacy)
54
+ $ sphereai auth login-oauth
55
+
56
+ # Set token manually
57
+ $ sphereai auth set-token eyJhbGc...
58
+
59
+ # Check current user
60
+ $ sphereai auth whoami
61
+
62
+ # List all prompts
63
+ $ sphereai prompts list
64
+
65
+ # List prompts with pagination
66
+ $ sphereai prompts list --page 2 --size 20
67
+
68
+ # List prompts in JSON format
69
+ $ sphereai prompts list --output json
70
+
71
+ # Add all files from current directory
72
+ $ sphereai files add .
73
+
74
+ # Add a specific file
75
+ $ sphereai files add src/index.ts
76
+
77
+ # List tracked files
78
+ $ sphereai files list
79
+
80
+ # Show status of tracked files
81
+ $ sphereai files status
82
+
83
+ # Clear all tracked files
84
+ $ sphereai files clear --force
85
+
86
+ Configuration:
87
+ Config file location: ~/.config/sphereai-cli/config.json
88
+ View config: sphereai auth config
89
+
90
+ Environment Variables:
91
+ SPHEREAI_API_URL - Main API URL for resources (required)
92
+ SPHEREAI_CLI_API_URL - CLI API URL for key-based auth (required for login)
93
+ SPHEREAI_TOKEN - Override stored token
94
+ SPHEREAI_AUTH_URL - OAuth2 URL (for legacy login-oauth)
95
+ SPHEREAI_OAUTH_CALLBACK_PORT - OAuth2 callback port (default: 3001)
96
+ `);
97
+ // Parse command line arguments
98
+ program.parse(process.argv);
99
+ // Show help if no command provided
100
+ if (!process.argv.slice(2).length) {
101
+ program.outputHelp();
102
+ }
103
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA,oDAA4B;AAE5B,4CAA4C;AAC5C,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,yCAAoC;AACpC,0CAAuD;AACvD,gDAA6D;AAC7D,4CAAyD;AACzD,8DAA0D;AAC1D,sDAAkD;AAGlD,8BAA8B;AAC9B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,iBAAiB,EAAE,sCAAsC,CAAC;KACjE,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;IACjC,gDAAgD;IAChD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IAEhC,+BAA+B;IAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,8BAAa,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,6BAA6B;IAC7B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,sBAAS,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,mBAAmB;QACnB,MAAM,WAAW,GAAG,8BAAa,CAAC,QAAQ,EAAE,CAAC;QAC7C,IAAI,WAAW,EAAE,CAAC;YAChB,sBAAS,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,0BAA0B;AAC1B,IAAA,2BAAoB,EAAC,OAAO,CAAC,CAAC;AAC9B,IAAA,iCAAuB,EAAC,OAAO,CAAC,CAAC;AACjC,IAAA,6BAAqB,EAAC,OAAO,CAAC,CAAC;AAE/B,oBAAoB;AACpB,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiD5B,CAAC,CAAC;AAEH,+BAA+B;AAC/B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,mCAAmC;AACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { AxiosRequestConfig } from 'axios';
2
+ import { User, PromptResponse, PaginatedResponse } from '../types/api-types';
3
+ export declare class ApiClient {
4
+ private client;
5
+ constructor(baseURL?: string, token?: string);
6
+ private handleError;
7
+ setAuthToken(token: string): void;
8
+ clearAuthToken(): void;
9
+ getCurrentUser(): User;
10
+ request<T>(config: AxiosRequestConfig): Promise<T>;
11
+ getPrompts(): Promise<PaginatedResponse<PromptResponse>>;
12
+ getPromptById(id: number): Promise<PromptResponse>;
13
+ }
14
+ export declare const apiClient: ApiClient;
15
+ export default ApiClient;
16
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/services/api-client.ts"],"names":[],"mappings":"AAAA,OAAc,EAA6B,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAE7E,OAAO,EACL,IAAI,EAGJ,cAAc,EACd,iBAAiB,EAElB,MAAM,oBAAoB,CAAC;AAE5B,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAgB;gBAElB,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IA6B5C,OAAO,CAAC,WAAW;IAkCnB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIjC,cAAc,IAAI,IAAI;IAItB,cAAc,IAAI,IAAI;IAsChB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAMlD,UAAU,IAAI,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAOxD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAIzD;AAGD,eAAO,MAAM,SAAS,WAAkB,CAAC;AAGzC,eAAe,SAAS,CAAC"}
@@ -0,0 +1,125 @@
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.apiClient = exports.ApiClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const config_service_1 = require("./config-service");
9
+ class ApiClient {
10
+ constructor(baseURL, token) {
11
+ const apiUrl = baseURL || config_service_1.configService.getApiUrl();
12
+ const authToken = token || config_service_1.configService.getToken();
13
+ console.log("API URL: " + apiUrl);
14
+ console.log("Auth Token: " + authToken);
15
+ this.client = axios_1.default.create({
16
+ baseURL: apiUrl,
17
+ timeout: 30000,
18
+ headers: {
19
+ 'Content-Type': 'application/json'
20
+ }
21
+ });
22
+ // Add auth token if available
23
+ if (authToken) {
24
+ this.setAuthToken(authToken);
25
+ }
26
+ // Response interceptor for error handling
27
+ this.client.interceptors.response.use((response) => response, (error) => {
28
+ return Promise.reject(this.handleError(error));
29
+ });
30
+ }
31
+ handleError(error) {
32
+ console.log("here");
33
+ console.log(error);
34
+ if (error.response) {
35
+ const { status, data } = error.response;
36
+ // Handle specific status codes
37
+ switch (status) {
38
+ case 401:
39
+ return new Error('Authentication failed. Please login again using "sphereai login"');
40
+ case 403:
41
+ return new Error('Access denied. You do not have permission to perform this action.');
42
+ case 404:
43
+ return new Error(data?.detail || 'Resource not found');
44
+ case 400:
45
+ if (data?.errors) {
46
+ const errorMessages = Object.entries(data.errors)
47
+ .map(([field, messages]) => `${field}: ${messages.join(', ')}`)
48
+ .join('\n');
49
+ return new Error(`Validation failed:\n${errorMessages}`);
50
+ }
51
+ return new Error(data?.detail || 'Bad request');
52
+ case 500:
53
+ return new Error('Internal server error. Please try again later.');
54
+ default:
55
+ return new Error(data?.detail || `Request failed with status ${status}`);
56
+ }
57
+ }
58
+ else if (error.request) {
59
+ return new Error('No response from server. Please check your internet connection.');
60
+ }
61
+ else {
62
+ return new Error(error.message || 'An unexpected error occurred');
63
+ }
64
+ }
65
+ setAuthToken(token) {
66
+ this.client.defaults.headers.common['Authorization'] = `Bearer ${token}`;
67
+ }
68
+ clearAuthToken() {
69
+ delete this.client.defaults.headers.common['Authorization'];
70
+ }
71
+ getCurrentUser() {
72
+ // Extract user information from JWT token
73
+ const token = config_service_1.configService.getToken();
74
+ if (!token) {
75
+ throw new Error('No authentication token found. Please login using "sphereai login"');
76
+ }
77
+ try {
78
+ // Decode JWT token (format: header.payload.signature)
79
+ const parts = token.split('.');
80
+ if (parts.length !== 3) {
81
+ throw new Error('Invalid token format');
82
+ }
83
+ // Decode the payload (base64url encoded)
84
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString('utf8'));
85
+ // Extract user information from token claims
86
+ const user = {
87
+ id: parseInt(payload.sub, 10),
88
+ customerId: parseInt(payload.customer_id, 10),
89
+ customerName: payload.customer_name,
90
+ name: payload.unique_name,
91
+ email: payload.email,
92
+ role: payload.role,
93
+ active: true, // Assume active if token is valid
94
+ createdAt: new Date(payload.iat * 1000).toISOString(),
95
+ updatedAt: null,
96
+ deletedAt: null
97
+ };
98
+ return user;
99
+ }
100
+ catch (error) {
101
+ throw new Error('Failed to decode user information from token. Please login again.');
102
+ }
103
+ }
104
+ // Generic request method for custom calls
105
+ async request(config) {
106
+ const response = await this.client.request(config);
107
+ return response.data;
108
+ }
109
+ // Prompts API
110
+ async getPrompts() {
111
+ const response = await this.client.get('/api/v1/Prompts');
112
+ console.log(response);
113
+ return response.data;
114
+ }
115
+ async getPromptById(id) {
116
+ const response = await this.client.get(`/api/v1/Prompts/${id}`);
117
+ return response.data;
118
+ }
119
+ }
120
+ exports.ApiClient = ApiClient;
121
+ // Export singleton instance with default configuration
122
+ exports.apiClient = new ApiClient();
123
+ // Export class for custom instances
124
+ exports.default = ApiClient;
125
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/services/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { AuthResponse } from '../types/api-types';
2
+ export declare class AuthService {
3
+ private server;
4
+ private app;
5
+ /**
6
+ * Start OAuth2 flow
7
+ * Opens browser to OAuth2 authorization URL and starts local callback server
8
+ */
9
+ startOAuth2Flow(authorizationUrl: string): Promise<string>;
10
+ /**
11
+ * Exchange authorization code for JWT token
12
+ * Note: For Implicit Flow, the token is already provided directly
13
+ * For Authorization Code Flow, this would need to exchange the code
14
+ */
15
+ exchangeCodeForToken(codeOrToken: string): Promise<string>;
16
+ /**
17
+ * Authenticate using UserChannelKey (from swagger.cli.json)
18
+ * This is the key-based authentication method specified in the API
19
+ * Uses the CLI API endpoint (SPHEREAI_CLI_API_URL)
20
+ */
21
+ authenticateWithKey(key: string): Promise<AuthResponse>;
22
+ /**
23
+ * Stop the OAuth callback server
24
+ */
25
+ private stopServer;
26
+ }
27
+ export declare const authService: AuthService;
28
+ //# sourceMappingURL=auth-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../../src/services/auth-service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,GAAG,CAAwB;IAEnC;;;OAGG;IACG,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA2HhE;;;;OAIG;IACG,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAehE;;;;OAIG;IACG,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAK7D;;OAEG;IACH,OAAO,CAAC,UAAU;CAOnB;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -0,0 +1,171 @@
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.authService = exports.AuthService = void 0;
7
+ const express_1 = __importDefault(require("express"));
8
+ const open_1 = __importDefault(require("open"));
9
+ const config_service_1 = require("./config-service");
10
+ const cli_api_client_1 = require("./cli-api-client");
11
+ class AuthService {
12
+ constructor() {
13
+ this.server = null;
14
+ this.app = null;
15
+ }
16
+ /**
17
+ * Start OAuth2 flow
18
+ * Opens browser to OAuth2 authorization URL and starts local callback server
19
+ */
20
+ async startOAuth2Flow(authorizationUrl) {
21
+ const port = config_service_1.configService.getOAuthCallbackPort();
22
+ const callbackUrl = `http://localhost:${port}/callback`;
23
+ return new Promise((resolve, reject) => {
24
+ // Create express app for OAuth callback
25
+ this.app = (0, express_1.default)();
26
+ // Callback route
27
+ this.app.get('/callback', async (req, res) => {
28
+ try {
29
+ const { code, token, error, error_description, redirect_uri } = req.query;
30
+ if (error) {
31
+ const errorMsg = error_description || error;
32
+ res.status(400).send(`
33
+ <html>
34
+ <head><title>Authentication Failed</title></head>
35
+ <body>
36
+ <h1>Authentication Failed</h1>
37
+ <p>${errorMsg}</p>
38
+ <p>You can close this window and return to the CLI.</p>
39
+ </body>
40
+ </html>
41
+ `);
42
+ this.stopServer();
43
+ reject(new Error(`OAuth2 error: ${errorMsg}`));
44
+ return;
45
+ }
46
+ // Check for token (Implicit Flow) or code (Authorization Code Flow)
47
+ let authValue = token || code;
48
+ // If token is not directly available, check if it's nested in redirect_uri parameter
49
+ if (!authValue && redirect_uri && typeof redirect_uri === 'string') {
50
+ try {
51
+ const url = new URL(redirect_uri);
52
+ const nestedToken = url.searchParams.get('token');
53
+ if (nestedToken) {
54
+ authValue = nestedToken;
55
+ }
56
+ }
57
+ catch (e) {
58
+ // If parsing fails, continue with normal flow
59
+ }
60
+ }
61
+ if (!authValue || typeof authValue !== 'string') {
62
+ res.status(400).send(`
63
+ <html>
64
+ <head><title>Authentication Failed</title></head>
65
+ <body>
66
+ <h1>Authentication Failed</h1>
67
+ <p>No authorization token or code received</p>
68
+ <p>You can close this window and return to the CLI.</p>
69
+ </body>
70
+ </html>
71
+ `);
72
+ this.stopServer();
73
+ reject(new Error('No authorization token or code received'));
74
+ return;
75
+ }
76
+ // Success page
77
+ res.send(`
78
+ <html>
79
+ <head><title>Authentication Successful</title></head>
80
+ <body>
81
+ <h1>Authentication Successful!</h1>
82
+ <p>You have been successfully authenticated.</p>
83
+ <p>You can close this window and return to the CLI.</p>
84
+ <script>setTimeout(() => window.close(), 3000);</script>
85
+ </body>
86
+ </html>
87
+ `);
88
+ // Stop server and resolve with token or code
89
+ this.stopServer();
90
+ resolve(authValue);
91
+ }
92
+ catch (err) {
93
+ res.status(500).send('Internal server error');
94
+ this.stopServer();
95
+ reject(err);
96
+ }
97
+ });
98
+ // Health check route
99
+ this.app.get('/health', (_req, res) => {
100
+ res.send('OK');
101
+ });
102
+ // Start server
103
+ this.server = this.app.listen(port, () => {
104
+ console.log(`OAuth callback server listening on port ${port}`);
105
+ // Build authorization URL with callback
106
+ const fullAuthUrl = `${authorizationUrl}?redirect_uri=${encodeURIComponent(callbackUrl)}&response_type=code`;
107
+ // Open browser to authorization URL
108
+ (0, open_1.default)(fullAuthUrl).catch((err) => {
109
+ console.error('Failed to open browser:', err.message);
110
+ console.log(`Please manually open this URL in your browser:\n${fullAuthUrl}`);
111
+ });
112
+ });
113
+ // Handle server errors
114
+ this.server.on('error', (err) => {
115
+ if (err.code === 'EADDRINUSE') {
116
+ reject(new Error(`Port ${port} is already in use. Please close any other instances or change the port.`));
117
+ }
118
+ else {
119
+ reject(err);
120
+ }
121
+ });
122
+ // Timeout after 5 minutes
123
+ setTimeout(() => {
124
+ if (this.server) {
125
+ this.stopServer();
126
+ reject(new Error('Authentication timeout. Please try again.'));
127
+ }
128
+ }, 5 * 60 * 1000);
129
+ });
130
+ }
131
+ /**
132
+ * Exchange authorization code for JWT token
133
+ * Note: For Implicit Flow, the token is already provided directly
134
+ * For Authorization Code Flow, this would need to exchange the code
135
+ */
136
+ async exchangeCodeForToken(codeOrToken) {
137
+ // If using Implicit Flow (token returned directly), just return it
138
+ // If using Authorization Code Flow, you would exchange the code here:
139
+ //
140
+ // const response = await apiClient.request({
141
+ // method: 'POST',
142
+ // url: '/api/v1/Auth/token',
143
+ // data: { code: codeOrToken, grant_type: 'authorization_code' }
144
+ // });
145
+ // return response.token;
146
+ // For Implicit Flow, return the token directly
147
+ return codeOrToken;
148
+ }
149
+ /**
150
+ * Authenticate using UserChannelKey (from swagger.cli.json)
151
+ * This is the key-based authentication method specified in the API
152
+ * Uses the CLI API endpoint (SPHEREAI_CLI_API_URL)
153
+ */
154
+ async authenticateWithKey(key) {
155
+ const response = await cli_api_client_1.cliApiClient.authenticate(key);
156
+ return response;
157
+ }
158
+ /**
159
+ * Stop the OAuth callback server
160
+ */
161
+ stopServer() {
162
+ if (this.server) {
163
+ this.server.close();
164
+ this.server = null;
165
+ this.app = null;
166
+ }
167
+ }
168
+ }
169
+ exports.AuthService = AuthService;
170
+ exports.authService = new AuthService();
171
+ //# sourceMappingURL=auth-service.js.map