replicas-cli 0.1.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 (66) hide show
  1. package/README.md +93 -0
  2. package/dist/commands/connect.d.ts +4 -0
  3. package/dist/commands/connect.d.ts.map +1 -0
  4. package/dist/commands/connect.js +145 -0
  5. package/dist/commands/connect.js.map +1 -0
  6. package/dist/commands/login.d.ts +2 -0
  7. package/dist/commands/login.d.ts.map +1 -0
  8. package/dist/commands/login.js +149 -0
  9. package/dist/commands/login.js.map +1 -0
  10. package/dist/commands/logout.d.ts +2 -0
  11. package/dist/commands/logout.d.ts.map +1 -0
  12. package/dist/commands/logout.js +17 -0
  13. package/dist/commands/logout.js.map +1 -0
  14. package/dist/commands/org.d.ts +3 -0
  15. package/dist/commands/org.d.ts.map +1 -0
  16. package/dist/commands/org.js +83 -0
  17. package/dist/commands/org.js.map +1 -0
  18. package/dist/commands/whoami.d.ts +2 -0
  19. package/dist/commands/whoami.d.ts.map +1 -0
  20. package/dist/commands/whoami.js +31 -0
  21. package/dist/commands/whoami.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 +109 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/lib/api.d.ts +7 -0
  27. package/dist/lib/api.d.ts.map +1 -0
  28. package/dist/lib/api.js +52 -0
  29. package/dist/lib/api.js.map +1 -0
  30. package/dist/lib/auth.d.ts +4 -0
  31. package/dist/lib/auth.d.ts.map +1 -0
  32. package/dist/lib/auth.js +61 -0
  33. package/dist/lib/auth.js.map +1 -0
  34. package/dist/lib/config.d.ts +10 -0
  35. package/dist/lib/config.d.ts.map +1 -0
  36. package/dist/lib/config.js +70 -0
  37. package/dist/lib/config.js.map +1 -0
  38. package/dist/lib/git.d.ts +4 -0
  39. package/dist/lib/git.d.ts.map +1 -0
  40. package/dist/lib/git.js +39 -0
  41. package/dist/lib/git.js.map +1 -0
  42. package/dist/lib/organization.d.ts +5 -0
  43. package/dist/lib/organization.d.ts.map +1 -0
  44. package/dist/lib/organization.js +29 -0
  45. package/dist/lib/organization.js.map +1 -0
  46. package/dist/lib/ports.d.ts +3 -0
  47. package/dist/lib/ports.d.ts.map +1 -0
  48. package/dist/lib/ports.js +44 -0
  49. package/dist/lib/ports.js.map +1 -0
  50. package/dist/lib/replicas-config.d.ts +8 -0
  51. package/dist/lib/replicas-config.d.ts.map +1 -0
  52. package/dist/lib/replicas-config.js +58 -0
  53. package/dist/lib/replicas-config.js.map +1 -0
  54. package/dist/lib/ssh.d.ts +5 -0
  55. package/dist/lib/ssh.d.ts.map +1 -0
  56. package/dist/lib/ssh.js +82 -0
  57. package/dist/lib/ssh.js.map +1 -0
  58. package/dist/lib/supabase.d.ts +5 -0
  59. package/dist/lib/supabase.d.ts.map +1 -0
  60. package/dist/lib/supabase.js +15 -0
  61. package/dist/lib/supabase.js.map +1 -0
  62. package/dist/types/index.d.ts +44 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/index.js +3 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/package.json +50 -0
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # Replicas CLI
2
+
3
+ Official CLI for [Replicas](https://replicas.dev) - manage cloud development workspaces with automatic SSH tunneling and port forwarding.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g replicas-cli
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Login to your Replicas account
15
+ replicas login
16
+
17
+ # Connect to a workspace
18
+ replicas connect my-workspace
19
+
20
+ # Connect and copy files from replicas.json
21
+ replicas connect my-workspace --copy
22
+ ```
23
+
24
+ ## Commands
25
+
26
+ ### `replicas login`
27
+ Authenticate with your Replicas account via browser-based OAuth.
28
+
29
+ ### `replicas logout`
30
+ Clear stored credentials.
31
+
32
+ ### `replicas whoami`
33
+ Display current authenticated user.
34
+
35
+ ### `replicas org`
36
+ Display current organization.
37
+
38
+ ### `replicas org switch`
39
+ Switch between organizations.
40
+
41
+ ### `replicas connect <workspace-name> [--copy]`
42
+ Connect to a workspace via SSH with automatic port forwarding.
43
+
44
+ **Options:**
45
+ - `-c, --copy` - Copy files listed in `replicas.json` to the workspace
46
+
47
+ ## Configuration
48
+
49
+ Create a `replicas.json` file in your repository root to configure file copying and port forwarding:
50
+
51
+ ```json
52
+ {
53
+ "copy": [
54
+ "web/.env",
55
+ "api/secrets.json"
56
+ ],
57
+ "ports": [3000, 8080, 5432]
58
+ }
59
+ ```
60
+
61
+ When you run `replicas connect --copy`, it will:
62
+ 1. Copy the specified files to the workspace
63
+ 2. Set up port forwarding for the specified ports (automatically finding available local ports if needed)
64
+
65
+ ## Features
66
+
67
+ - **Secure Authentication**: OAuth-based login with token refresh
68
+ - **Quick SSH Access**: Connect to workspaces with a single command
69
+ - **File Syncing**: Copy environment files and secrets to workspaces
70
+ - **Smart Port Forwarding**: Automatic port conflict resolution
71
+ - **SSH Key Caching**: Reuse SSH keys across sessions
72
+ - **Multi-Organization**: Switch between different organizations
73
+
74
+ ## How it Works
75
+
76
+ 1. **SSH Key Management**: The CLI securely caches SSH keys in `~/.replicas/keys/`
77
+ 2. **Port Detection**: Automatically detects ports in use and finds alternatives
78
+ 3. **File Copying**: Uses `scp` to copy files to `/home/ubuntu/workspaces/<repo-name>/`
79
+ 4. **Port Forwarding**: Maps workspace ports to local ports (e.g., workspace:3000 → localhost:3001)
80
+
81
+ ## Requirements
82
+
83
+ - Node.js 18+
84
+ - SSH client (openssh)
85
+ - `lsof` (for port detection, pre-installed on macOS/Linux)
86
+
87
+ ## Support
88
+
89
+ For issues or questions, visit [https://replicas.dev](https://replicas.dev)
90
+
91
+ ## License
92
+
93
+ MIT
@@ -0,0 +1,4 @@
1
+ export declare function connectCommand(workspaceName: string, options: {
2
+ copy?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAqBA,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8JtG"}
@@ -0,0 +1,145 @@
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.connectCommand = connectCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const prompts_1 = __importDefault(require("prompts"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const config_1 = require("../lib/config");
12
+ const api_1 = require("../lib/api");
13
+ const ssh_1 = require("../lib/ssh");
14
+ const git_1 = require("../lib/git");
15
+ const replicas_config_1 = require("../lib/replicas-config");
16
+ const ports_1 = require("../lib/ports");
17
+ async function connectCommand(workspaceName, options) {
18
+ if (!(0, config_1.isAuthenticated)()) {
19
+ console.log(chalk_1.default.red('Not logged in. Please run "replicas login" first.'));
20
+ process.exit(1);
21
+ }
22
+ const orgId = (0, config_1.getOrganizationId)();
23
+ if (!orgId) {
24
+ console.log(chalk_1.default.red('No organization selected. Please run "replicas org switch" first.'));
25
+ process.exit(1);
26
+ }
27
+ try {
28
+ // Step 1: Query workspaces by name
29
+ console.log(chalk_1.default.blue(`\nSearching for workspace: ${workspaceName}...`));
30
+ const response = await (0, api_1.orgAuthenticatedFetch)(`/api/workspaces?name=${encodeURIComponent(workspaceName)}`);
31
+ if (response.workspaces.length === 0) {
32
+ console.log(chalk_1.default.red(`No workspaces found with name matching "${workspaceName}".`));
33
+ process.exit(1);
34
+ }
35
+ // Step 2: If multiple workspaces, prompt user to select one
36
+ let selectedWorkspace;
37
+ if (response.workspaces.length === 1) {
38
+ selectedWorkspace = response.workspaces[0];
39
+ }
40
+ else {
41
+ console.log(chalk_1.default.yellow(`\nFound ${response.workspaces.length} workspaces matching "${workspaceName}":`));
42
+ const selectResponse = await (0, prompts_1.default)({
43
+ type: 'select',
44
+ name: 'workspaceId',
45
+ message: 'Select a workspace:',
46
+ choices: response.workspaces.map(ws => ({
47
+ title: `${ws.name} (${ws.status || 'unknown'})`,
48
+ value: ws.id,
49
+ description: `IP: ${ws.ipv4_address || 'N/A'} | Instance: ${ws.instance_type || 'N/A'}`,
50
+ })),
51
+ });
52
+ if (!selectResponse.workspaceId) {
53
+ console.log(chalk_1.default.yellow('\nCancelled.'));
54
+ return;
55
+ }
56
+ selectedWorkspace = response.workspaces.find(ws => ws.id === selectResponse.workspaceId);
57
+ }
58
+ console.log(chalk_1.default.green(`\n✓ Selected workspace: ${selectedWorkspace.name}`));
59
+ console.log(chalk_1.default.gray(` IP: ${selectedWorkspace.ipv4_address}`));
60
+ console.log(chalk_1.default.gray(` Status: ${selectedWorkspace.status || 'unknown'}`));
61
+ if (!selectedWorkspace.ipv4_address) {
62
+ console.log(chalk_1.default.red('\nWorkspace does not have an IP address. It may not be running yet.'));
63
+ process.exit(1);
64
+ }
65
+ // Step 3: Get SSH key
66
+ console.log(chalk_1.default.blue('\nRetrieving SSH key...'));
67
+ const privateKey = await (0, ssh_1.getSSHKey)(selectedWorkspace.ssh_key_id);
68
+ // Write key to a temporary file for SSH
69
+ const keyPath = path_1.default.join(config_1.CONFIG_DIR, 'keys', `${selectedWorkspace.ssh_key_id}.pem`);
70
+ fs_1.default.writeFileSync(keyPath, privateKey, { mode: 0o600 });
71
+ console.log(chalk_1.default.green('✓ SSH key ready'));
72
+ // Step 4: Handle --copy flag
73
+ if (options.copy) {
74
+ if (!(0, git_1.isInsideGitRepo)()) {
75
+ console.log(chalk_1.default.yellow('\nWarning: Not inside a git repository. Skipping file copy.'));
76
+ }
77
+ else {
78
+ const repoName = (0, git_1.getGitRepoName)();
79
+ const replicasConfig = (0, replicas_config_1.readReplicasConfig)();
80
+ if (!replicasConfig || !replicasConfig.copy || replicasConfig.copy.length === 0) {
81
+ console.log(chalk_1.default.yellow('\nNo files to copy (replicas.json not found or empty).'));
82
+ }
83
+ else {
84
+ console.log(chalk_1.default.blue(`\nCopying files to workspace (repo: ${repoName})...`));
85
+ const { valid, invalid } = (0, replicas_config_1.validateCopyFiles)(replicasConfig.copy);
86
+ if (invalid.length > 0) {
87
+ console.log(chalk_1.default.yellow(`\nWarning: ${invalid.length} file(s) not found locally:`));
88
+ invalid.forEach(file => console.log(chalk_1.default.gray(` - ${file}`)));
89
+ }
90
+ for (const file of valid) {
91
+ const localPath = (0, replicas_config_1.getAbsoluteCopyPath)(file);
92
+ const remotePath = `/home/ubuntu/workspaces/${repoName}/${file}`;
93
+ console.log(chalk_1.default.gray(` Copying ${file}...`));
94
+ try {
95
+ // Create remote directory first
96
+ await (0, ssh_1.scpCopyFile)(keyPath, localPath, remotePath, selectedWorkspace.ipv4_address);
97
+ console.log(chalk_1.default.green(` ✓ ${file}`));
98
+ }
99
+ catch (error) {
100
+ console.log(chalk_1.default.red(` ✗ Failed to copy ${file}: ${error instanceof Error ? error.message : 'Unknown error'}`));
101
+ }
102
+ }
103
+ console.log(chalk_1.default.green(`\n✓ File copy complete (${valid.length} files)`));
104
+ }
105
+ }
106
+ }
107
+ // Step 5: Handle port forwarding
108
+ const portMappings = new Map();
109
+ if ((0, git_1.isInsideGitRepo)()) {
110
+ const replicasConfig = (0, replicas_config_1.readReplicasConfig)();
111
+ if (replicasConfig && replicasConfig.ports && replicasConfig.ports.length > 0) {
112
+ console.log(chalk_1.default.blue('\nSetting up port forwarding...'));
113
+ const mappings = await (0, ports_1.mapPortsToLocal)(replicasConfig.ports);
114
+ for (const [remotePort, localPort] of mappings) {
115
+ portMappings.set(remotePort, localPort);
116
+ console.log(chalk_1.default.gray(` Forwarding localhost:${localPort} -> workspace:${remotePort}`));
117
+ }
118
+ console.log(chalk_1.default.green('✓ Port forwarding configured'));
119
+ }
120
+ }
121
+ // Step 6: Connect via SSH
122
+ console.log(chalk_1.default.blue(`\nConnecting to ${selectedWorkspace.name}...`));
123
+ // Build display command
124
+ let sshCommand = `ssh -i ${keyPath}`;
125
+ for (const [remotePort, localPort] of portMappings) {
126
+ sshCommand += ` -L ${localPort}:localhost:${remotePort}`;
127
+ }
128
+ sshCommand += ` ubuntu@${selectedWorkspace.ipv4_address}`;
129
+ console.log(chalk_1.default.gray(`SSH command: ${sshCommand}`));
130
+ if (portMappings.size > 0) {
131
+ console.log(chalk_1.default.cyan('\nPort forwarding active:'));
132
+ for (const [remotePort, localPort] of portMappings) {
133
+ console.log(chalk_1.default.cyan(` • localhost:${localPort} → workspace:${remotePort}`));
134
+ }
135
+ }
136
+ console.log(chalk_1.default.gray('\nPress Ctrl+D to disconnect.\n'));
137
+ await (0, ssh_1.connectSSH)(keyPath, selectedWorkspace.ipv4_address, portMappings);
138
+ console.log(chalk_1.default.green('\n✓ Disconnected from workspace.\n'));
139
+ }
140
+ catch (error) {
141
+ console.error(chalk_1.default.red(`\nError: ${error instanceof Error ? error.message : 'Unknown error'}`));
142
+ process.exit(1);
143
+ }
144
+ }
145
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function loginCommand(): Promise<void>;
2
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAgBA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAoJlD"}
@@ -0,0 +1,149 @@
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.loginCommand = loginCommand;
7
+ const http_1 = __importDefault(require("http"));
8
+ const url_1 = require("url");
9
+ const open_1 = __importDefault(require("open"));
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const config_1 = require("../lib/config");
12
+ const auth_1 = require("../lib/auth");
13
+ const organization_1 = require("../lib/organization");
14
+ const WEB_APP_URL = process.env.REPLICAS_WEB_URL || 'https://replicas.dev';
15
+ function generateState() {
16
+ return Math.random().toString(36).substring(2, 15) +
17
+ Math.random().toString(36).substring(2, 15);
18
+ }
19
+ async function loginCommand() {
20
+ const state = generateState();
21
+ return new Promise((resolve, reject) => {
22
+ let authTimeout;
23
+ const server = http_1.default.createServer(async (req, res) => {
24
+ const url = new url_1.URL(req.url || '', `http://${req.headers.host}`);
25
+ if (url.pathname === '/callback') {
26
+ const returnedState = url.searchParams.get('state');
27
+ const accessToken = url.searchParams.get('access_token');
28
+ const refreshToken = url.searchParams.get('refresh_token');
29
+ const expiresAt = url.searchParams.get('expires_at');
30
+ const error = url.searchParams.get('error');
31
+ if (error) {
32
+ const errorUrl = `${WEB_APP_URL}/cli-login/error?message=${encodeURIComponent(error)}`;
33
+ res.writeHead(302, {
34
+ 'Location': errorUrl,
35
+ 'Connection': 'close'
36
+ });
37
+ res.end();
38
+ clearTimeout(authTimeout);
39
+ setImmediate(() => {
40
+ server.closeAllConnections?.();
41
+ server.close();
42
+ reject(new Error(`Authentication failed: ${error}`));
43
+ });
44
+ return;
45
+ }
46
+ if (returnedState !== state) {
47
+ const errorUrl = `${WEB_APP_URL}/cli-login/error?message=${encodeURIComponent('Invalid state parameter. This might be a CSRF attack.')}`;
48
+ res.writeHead(302, {
49
+ 'Location': errorUrl,
50
+ 'Connection': 'close'
51
+ });
52
+ res.end();
53
+ clearTimeout(authTimeout);
54
+ setImmediate(() => {
55
+ server.closeAllConnections?.();
56
+ server.close();
57
+ reject(new Error('Invalid state parameter'));
58
+ });
59
+ return;
60
+ }
61
+ if (!accessToken || !refreshToken || !expiresAt) {
62
+ const errorUrl = `${WEB_APP_URL}/cli-login/error?message=${encodeURIComponent('Missing required authentication tokens.')}`;
63
+ res.writeHead(302, {
64
+ 'Location': errorUrl,
65
+ 'Connection': 'close'
66
+ });
67
+ res.end();
68
+ clearTimeout(authTimeout);
69
+ setImmediate(() => {
70
+ server.closeAllConnections?.();
71
+ server.close();
72
+ reject(new Error('Missing authentication tokens'));
73
+ });
74
+ return;
75
+ }
76
+ const config = {
77
+ access_token: accessToken,
78
+ refresh_token: refreshToken,
79
+ expires_at: parseInt(expiresAt, 10),
80
+ };
81
+ try {
82
+ (0, config_1.writeConfig)(config);
83
+ const user = await (0, auth_1.getCurrentUser)();
84
+ try {
85
+ const orgId = await (0, organization_1.ensureOrganization)();
86
+ console.log(chalk_1.default.gray(` Organization: ${orgId}`));
87
+ }
88
+ catch (orgError) {
89
+ console.log(chalk_1.default.yellow(' Warning: Could not fetch organizations'));
90
+ console.log(chalk_1.default.gray(' You can set your organization later with: replicas org switch'));
91
+ }
92
+ const successUrl = `${WEB_APP_URL}/cli-login/success?email=${encodeURIComponent(user.email)}`;
93
+ res.writeHead(302, {
94
+ 'Location': successUrl,
95
+ 'Connection': 'close'
96
+ });
97
+ res.end();
98
+ console.log(chalk_1.default.green('\n✓ Successfully logged in!'));
99
+ console.log(chalk_1.default.gray(` Email: ${user.email}\n`));
100
+ clearTimeout(authTimeout);
101
+ setImmediate(() => {
102
+ server.closeAllConnections?.();
103
+ server.close();
104
+ resolve();
105
+ });
106
+ }
107
+ catch (error) {
108
+ const errorUrl = `${WEB_APP_URL}/cli-login/error?message=${encodeURIComponent('Failed to verify authentication.')}`;
109
+ res.writeHead(302, {
110
+ 'Location': errorUrl,
111
+ 'Connection': 'close'
112
+ });
113
+ res.end();
114
+ clearTimeout(authTimeout);
115
+ setImmediate(() => {
116
+ server.closeAllConnections?.();
117
+ server.close();
118
+ reject(error);
119
+ });
120
+ }
121
+ }
122
+ else {
123
+ res.writeHead(404);
124
+ res.end('Not found');
125
+ }
126
+ });
127
+ server.listen(0, 'localhost', () => {
128
+ const address = server.address();
129
+ if (!address || typeof address === 'string') {
130
+ reject(new Error('Failed to start server'));
131
+ return;
132
+ }
133
+ const port = address.port;
134
+ const loginUrl = `${WEB_APP_URL}/cli-login?port=${port}&state=${state}`;
135
+ console.log(chalk_1.default.blue('\nOpening browser for authentication...'));
136
+ console.log(chalk_1.default.gray(`If the browser doesn't open automatically, visit:\n${loginUrl}\n`));
137
+ (0, open_1.default)(loginUrl).catch((error) => {
138
+ console.log(chalk_1.default.yellow('Failed to open browser automatically.'));
139
+ console.log(chalk_1.default.gray(`Please open this URL manually:\n${loginUrl}\n`));
140
+ });
141
+ });
142
+ authTimeout = setTimeout(() => {
143
+ server.closeAllConnections?.();
144
+ server.close();
145
+ reject(new Error('Authentication timeout. Please try again.'));
146
+ }, 5 * 60 * 1000);
147
+ });
148
+ }
149
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function logoutCommand(): void;
2
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAGA,wBAAgB,aAAa,IAAI,IAAI,CAQpC"}
@@ -0,0 +1,17 @@
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.logoutCommand = logoutCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const config_1 = require("../lib/config");
9
+ function logoutCommand() {
10
+ if (!(0, config_1.isAuthenticated)()) {
11
+ console.log(chalk_1.default.yellow('You are not logged in.'));
12
+ return;
13
+ }
14
+ (0, config_1.deleteConfig)();
15
+ console.log(chalk_1.default.green('✓ Successfully logged out!'));
16
+ }
17
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":";;;;;AAGA,sCAQC;AAXD,kDAA0B;AAC1B,0CAA8D;AAE9D,SAAgB,aAAa;IAC3B,IAAI,CAAC,IAAA,wBAAe,GAAE,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAA,qBAAY,GAAE,CAAC;IACf,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function orgCommand(): Promise<void>;
2
+ export declare function orgSwitchCommand(): Promise<void>;
3
+ //# sourceMappingURL=org.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org.d.ts","sourceRoot":"","sources":["../../src/commands/org.ts"],"names":[],"mappings":"AAMA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA+BhD;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgDtD"}
@@ -0,0 +1,83 @@
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.orgCommand = orgCommand;
7
+ exports.orgSwitchCommand = orgSwitchCommand;
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const prompts_1 = __importDefault(require("prompts"));
10
+ const organization_1 = require("../lib/organization");
11
+ const config_1 = require("../lib/config");
12
+ const config_2 = require("../lib/config");
13
+ async function orgCommand() {
14
+ if (!(0, config_2.isAuthenticated)()) {
15
+ console.log(chalk_1.default.red('Not logged in. Please run "replicas login" first.'));
16
+ process.exit(1);
17
+ }
18
+ try {
19
+ const currentOrgId = (0, config_1.getOrganizationId)();
20
+ const organizations = await (0, organization_1.fetchOrganizations)();
21
+ if (!currentOrgId) {
22
+ console.log(chalk_1.default.yellow('No organization selected.'));
23
+ console.log(chalk_1.default.gray('Run "replicas org switch" to select an organization.\n'));
24
+ return;
25
+ }
26
+ const currentOrg = organizations.find(org => org.id === currentOrgId);
27
+ if (!currentOrg) {
28
+ console.log(chalk_1.default.yellow(`Current organization ID (${currentOrgId}) not found.`));
29
+ console.log(chalk_1.default.gray('Run "replicas org switch" to select a new organization.\n'));
30
+ return;
31
+ }
32
+ console.log(chalk_1.default.green('\nCurrent organization:'));
33
+ console.log(chalk_1.default.gray(` Name: ${currentOrg.name}`));
34
+ console.log(chalk_1.default.gray(` ID: ${currentOrg.id}\n`));
35
+ }
36
+ catch (error) {
37
+ console.error(chalk_1.default.red(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`));
38
+ process.exit(1);
39
+ }
40
+ }
41
+ async function orgSwitchCommand() {
42
+ if (!(0, config_2.isAuthenticated)()) {
43
+ console.log(chalk_1.default.red('Not logged in. Please run "replicas login" first.'));
44
+ process.exit(1);
45
+ }
46
+ try {
47
+ const organizations = await (0, organization_1.fetchOrganizations)();
48
+ if (organizations.length === 0) {
49
+ console.log(chalk_1.default.yellow('You are not a member of any organization.'));
50
+ console.log(chalk_1.default.gray('Please contact support.\n'));
51
+ return;
52
+ }
53
+ if (organizations.length === 1) {
54
+ await (0, organization_1.setActiveOrganization)(organizations[0].id);
55
+ console.log(chalk_1.default.green(`\n✓ Organization set to: ${organizations[0].name}\n`));
56
+ return;
57
+ }
58
+ const currentOrgId = (0, config_1.getOrganizationId)();
59
+ const response = await (0, prompts_1.default)({
60
+ type: 'select',
61
+ name: 'organizationId',
62
+ message: 'Select an organization:',
63
+ choices: organizations.map(org => ({
64
+ title: `${org.name}${org.id === currentOrgId ? ' (current)' : ''}`,
65
+ value: org.id,
66
+ description: org.id,
67
+ })),
68
+ initial: organizations.findIndex(org => org.id === currentOrgId),
69
+ });
70
+ if (!response.organizationId) {
71
+ console.log(chalk_1.default.yellow('\nCancelled.'));
72
+ return;
73
+ }
74
+ await (0, organization_1.setActiveOrganization)(response.organizationId);
75
+ const selectedOrg = organizations.find(org => org.id === response.organizationId);
76
+ console.log(chalk_1.default.green(`\n✓ Switched to organization: ${selectedOrg?.name}\n`));
77
+ }
78
+ catch (error) {
79
+ console.error(chalk_1.default.red(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`));
80
+ process.exit(1);
81
+ }
82
+ }
83
+ //# sourceMappingURL=org.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org.js","sourceRoot":"","sources":["../../src/commands/org.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function whoamiCommand(): Promise<void>;
2
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAoBnD"}
@@ -0,0 +1,31 @@
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.whoamiCommand = whoamiCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const auth_1 = require("../lib/auth");
9
+ const config_1 = require("../lib/config");
10
+ async function whoamiCommand() {
11
+ if (!(0, config_1.isAuthenticated)()) {
12
+ console.log(chalk_1.default.yellow('You are not logged in.'));
13
+ console.log(chalk_1.default.gray('Run "replicas login" to authenticate.'));
14
+ return;
15
+ }
16
+ try {
17
+ const user = await (0, auth_1.getCurrentUser)();
18
+ console.log(chalk_1.default.blue('\nCurrent User:'));
19
+ console.log(chalk_1.default.gray(` ID: ${user.id}`));
20
+ console.log(chalk_1.default.gray(` Email: ${user.email}\n`));
21
+ }
22
+ catch (error) {
23
+ console.error(chalk_1.default.red('Failed to get user information.'));
24
+ if (error instanceof Error) {
25
+ console.error(chalk_1.default.gray(error.message));
26
+ }
27
+ console.log(chalk_1.default.gray('\nTry running "replicas login" again.'));
28
+ process.exit(1);
29
+ }
30
+ }
31
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":";;;;;AAIA,sCAoBC;AAxBD,kDAA0B;AAC1B,sCAA6C;AAC7C,0CAAgD;AAEzC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC,IAAA,wBAAe,GAAE,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAc,GAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAC5D,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,eAAe,CAAC"}