@appuo/orbit 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Appuo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,372 @@
1
+ # 🌍 Orbit
2
+
3
+ **A fully CLI-based multi-cloud profile manager.**
4
+
5
+ [![npm](https://img.shields.io/npm/v/@appuo/orbit)](https://www.npmjs.com/package/@appuo/orbit)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
8
+
9
+ Orbit lets you manage multiple cloud provider accounts and switch between them instantly. No shell modifications. No global environment changes. No OS-specific hacks.
10
+
11
+ ---
12
+
13
+ ## Why Orbit?
14
+
15
+ If you deploy to **multiple Vercel accounts** (personal, company, client projects), switching between them is painful — you have to `vercel logout`, `vercel login`, verify email, wait...
16
+
17
+ Orbit fixes this:
18
+
19
+ ```bash
20
+ orbit use vercel company
21
+ vercel deploy # ← Deploys as company. Done.
22
+
23
+ orbit use vercel personal
24
+ vercel deploy # ← Deploys as personal. Instant.
25
+ ```
26
+
27
+ One command. Instant switch. Plain `vercel` commands just work.
28
+
29
+ ---
30
+
31
+ ## ✨ Features
32
+
33
+ - 🔄 **Instant Profile Switching** — `orbit use` swaps credentials natively, plain CLI commands work immediately
34
+ - 🔐 **Secure Token Storage** — Credentials stored in your OS keychain (Keychain / libsecret / Credential Vault)
35
+ - 🔑 **Integrated Login** — Orbit launches `vercel login` for you during setup, no manual token pasting
36
+ - 📧 **Email Display** — See which account each profile belongs to at a glance
37
+ - 🌐 **Multi-cloud Ready** — Extensible provider architecture (Vercel built-in, more coming)
38
+ - 🖥️ **Cross-platform** — macOS, Linux, and Windows
39
+ - ⚡ **Zero Config Pollution** — No `.bashrc`, `.zshrc`, or shell modifications
40
+
41
+ ---
42
+
43
+ ## 📦 Installation
44
+
45
+ ### Global Install (Recommended)
46
+
47
+ ```bash
48
+ npm install -g @appuo/orbit
49
+ ```
50
+
51
+ or with pnpm:
52
+
53
+ ```bash
54
+ pnpm add -g @appuo/orbit
55
+ ```
56
+
57
+ ### No Install (via npx)
58
+
59
+ ```bash
60
+ npx @appuo/orbit list
61
+ npx @appuo/orbit add vercel personal
62
+ ```
63
+
64
+ ### From Source
65
+
66
+ ```bash
67
+ git clone https://github.com/appuo/orbit.git
68
+ cd orbit
69
+ pnpm install
70
+ pnpm build
71
+ npm link
72
+ ```
73
+
74
+ ### Prerequisites
75
+
76
+ - **Node.js 18+**
77
+ - **Vercel CLI** installed globally (`npm i -g vercel`) for Vercel provider
78
+
79
+ ---
80
+
81
+ ## 🚀 Quick Start
82
+
83
+ ### 1. Add your first account
84
+
85
+ ```bash
86
+ orbit add vercel personal
87
+ ```
88
+
89
+ Orbit will detect if you're already logged into Vercel CLI:
90
+
91
+ ```
92
+ Found existing token (you@gmail.com) from vercel CLI. Use this? (Y/n) y
93
+ ✔ Profile "personal" added for vercel.
94
+ ```
95
+
96
+ If no token is found, Orbit will offer to log you in:
97
+
98
+ ```
99
+ No existing credentials found. Login with vercel CLI now? (Y/n) y
100
+ Visit vercel.com/device and enter XXXX-XXXX
101
+ Congratulations! You are now signed in.
102
+ ✔ New credentials found!
103
+ ✔ Profile "personal" added for vercel.
104
+ ```
105
+
106
+ ### 2. Add a second account
107
+
108
+ ```bash
109
+ orbit add vercel company
110
+ ```
111
+
112
+ Orbit shows whose token it found, so you can decide:
113
+
114
+ ```
115
+ Found existing token (you@gmail.com) from vercel CLI. Use this? (Y/n) n
116
+ Login to a different account with vercel CLI? (Y/n) y
117
+ Visit vercel.com/device and enter YYYY-YYYY
118
+ Congratulations! You are now signed in.
119
+ ✔ New credentials found!
120
+ ✔ Profile "company" added for vercel.
121
+ ```
122
+
123
+ ### 3. See all profiles
124
+
125
+ ```bash
126
+ orbit list
127
+ ```
128
+
129
+ ```
130
+ Provider Profile Email Status
131
+ vercel personal you@gmail.com ★ current
132
+ vercel company work@company.com —
133
+ ```
134
+
135
+ ### 4. Switch instantly
136
+
137
+ ```bash
138
+ orbit use vercel company
139
+ vercel deploy # ← Deploys as company
140
+ vercel whoami # ← Shows company account
141
+
142
+ orbit use vercel personal
143
+ vercel deploy # ← Deploys as personal
144
+ ```
145
+
146
+ No `vercel logout`. No `vercel login`. Just switch and go.
147
+
148
+ ---
149
+
150
+ ## 📖 Commands
151
+
152
+ | Command | Description |
153
+ |---------|-------------|
154
+ | `orbit add <provider> <profile>` | Add a new profile (with guided login) |
155
+ | `orbit list` | Show all profiles with email and status |
156
+ | `orbit use <provider> <profile>` | Switch active profile (swaps credentials) |
157
+ | `orbit exec <provider> <command...>` | Run command with the current profile |
158
+ | `orbit run <provider> <profile> <command...>` | Run command with a specific profile |
159
+ | `orbit current` | Show currently active profiles |
160
+ | `orbit remove <provider> <profile>` | Remove a profile and its credentials |
161
+
162
+ ### `orbit add <provider> <profile>`
163
+
164
+ Add a new cloud provider profile. Orbit guides you through the process:
165
+
166
+ 1. **Auto-discovery** — Checks for existing CLI credentials and shows the associated email
167
+ 2. **Integrated login** — Offers to run `vercel login` if no credentials found or if you want a different account
168
+ 3. **Manual token** — Falls back to secure token input if needed
169
+
170
+ ```bash
171
+ orbit add vercel staging
172
+ ```
173
+
174
+ ### `orbit use <provider> <profile>`
175
+
176
+ Switch the active profile. This **swaps the provider's auth credentials** so that native CLI commands work immediately.
177
+
178
+ ```bash
179
+ orbit use vercel company
180
+ # ✔ Now using profile "company" for vercel.
181
+
182
+ vercel deploy # ← Runs as company, no wrapper needed!
183
+ ```
184
+
185
+ ### `orbit exec <provider> <command...>`
186
+
187
+ Execute a command using the current active profile.
188
+
189
+ ```bash
190
+ orbit use vercel personal
191
+ orbit exec vercel deploy --prod
192
+ ```
193
+
194
+ ### `orbit run <provider> <profile> <command...>`
195
+
196
+ Run a command with a specific profile without changing the active selection.
197
+
198
+ ```bash
199
+ orbit run vercel company deploy --prod
200
+ ```
201
+
202
+ ### `orbit list`
203
+
204
+ Display all profiles with provider, name, email, and active status.
205
+
206
+ ```bash
207
+ orbit list
208
+ ```
209
+
210
+ ### `orbit current`
211
+
212
+ Show the currently active profile for each provider.
213
+
214
+ ```bash
215
+ orbit current
216
+ # ✔ vercel: personal
217
+ ```
218
+
219
+ ### `orbit remove <provider> <profile>`
220
+
221
+ Remove a profile, its stored token, and auth snapshot.
222
+
223
+ ```bash
224
+ orbit remove vercel staging
225
+ # ✔ Profile "staging" removed from vercel.
226
+ ```
227
+
228
+ ---
229
+
230
+ ## 🏗️ How It Works
231
+
232
+ ### Auth File Swap (the magic ✨)
233
+
234
+ When you run `orbit use vercel company`, Orbit:
235
+
236
+ 1. **Saves** the current profile's `auth.json` to `~/.orbit/auth/vercel/personal.json`
237
+ 2. **Restores** the target profile's `auth.json` from `~/.orbit/auth/vercel/company.json`
238
+ 3. **Updates** the config to mark `company` as current
239
+
240
+ This means `vercel` CLI reads its own native `auth.json` — no environment variable hacks, no token injection. The CLI thinks you just logged in normally.
241
+
242
+ ### Storage Architecture
243
+
244
+ ```
245
+ ~/.orbit/
246
+ ├── config.json # Profile names, current selections, metadata
247
+ └── auth/
248
+ └── vercel/
249
+ ├── personal.json # Auth snapshot for personal profile
250
+ └── company.json # Auth snapshot for company profile
251
+ ```
252
+
253
+ Tokens are additionally stored in your **OS keychain** via Keytar as a secure backup.
254
+
255
+ ---
256
+
257
+ ## 🖥️ Cross-Platform Support
258
+
259
+ | Feature | macOS | Linux | Windows |
260
+ |---------|-------|-------|---------|
261
+ | Keychain storage | ✅ Keychain | ✅ libsecret | ✅ Credential Vault |
262
+ | Auth file swap | ✅ | ✅ | ✅ |
263
+ | CLI execution | ✅ | ✅ | ✅ |
264
+ | Config storage | `~/.orbit/` | `~/.orbit/` | `%USERPROFILE%\.orbit\` |
265
+
266
+ Orbit uses `os.homedir()`, `path.join()`, and `execa` — no platform-specific hacks.
267
+
268
+ ---
269
+
270
+ ## 🔐 Security
271
+
272
+ ### Token Storage
273
+
274
+ All tokens are stored in your OS's native keychain:
275
+
276
+ | OS | Backend |
277
+ |----|---------|
278
+ | macOS | Keychain |
279
+ | Linux | libsecret (GNOME Keyring) |
280
+ | Windows | Credential Vault |
281
+
282
+ **Tokens are never:**
283
+ - Written to plain text config files
284
+ - Logged to stdout/stderr
285
+ - Stored in environment variables permanently
286
+
287
+ ### Config File
288
+
289
+ Only metadata is stored in `~/.orbit/config.json`:
290
+
291
+ ```json
292
+ {
293
+ "providers": {
294
+ "vercel": {
295
+ "profiles": ["personal", "company"],
296
+ "current": "personal",
297
+ "metadata": {
298
+ "personal": { "email": "you@gmail.com" },
299
+ "company": { "email": "work@company.com" }
300
+ }
301
+ }
302
+ }
303
+ }
304
+ ```
305
+
306
+ No secrets. No tokens. Just profile names, selections, and display metadata.
307
+
308
+ ---
309
+
310
+ ## 🛠️ Tech Stack
311
+
312
+ | Component | Technology |
313
+ |-----------|------------|
314
+ | Runtime | Node.js 18+ |
315
+ | Language | TypeScript (strict mode) |
316
+ | Module System | ESM only |
317
+ | CLI Framework | Commander.js |
318
+ | Styling | Chalk |
319
+ | Spinners | Ora |
320
+ | Process Execution | Execa |
321
+ | Secure Storage | Keytar |
322
+ | Validation | Zod |
323
+ | Bundler | tsup |
324
+
325
+ ---
326
+
327
+ ## 🛠️ Development
328
+
329
+ ```bash
330
+ # Clone and install
331
+ git clone https://github.com/appuo/orbit.git
332
+ cd orbit
333
+ pnpm install
334
+
335
+ # Build
336
+ pnpm build
337
+
338
+ # Type check
339
+ pnpm typecheck
340
+
341
+ # Watch mode
342
+ pnpm dev
343
+
344
+ # Link for local testing
345
+ npm link
346
+ orbit list
347
+ ```
348
+
349
+ ---
350
+
351
+ ## 🗺️ Roadmap
352
+
353
+ - [ ] **AWS Provider** — Support for AWS CLI with named profiles
354
+ - [ ] **GCP Provider** — Google Cloud SDK integration
355
+ - [ ] **Azure Provider** — Azure CLI support
356
+ - [ ] **Netlify Provider** — Netlify CLI support
357
+ - [ ] **Profile import/export** — Migrate profiles between machines
358
+ - [ ] **Token rotation** — Automatic token refresh support
359
+ - [ ] **Shell completions** — Auto-complete for bash, zsh, fish, PowerShell
360
+ - [ ] **Plugin system** — Community-driven provider plugins
361
+
362
+ ---
363
+
364
+ ## 🤝 Contributing
365
+
366
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
367
+
368
+ ---
369
+
370
+ ## 📄 License
371
+
372
+ MIT — see [LICENSE](LICENSE) for details.
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,719 @@
1
+ #!/usr/bin/env node
2
+ #!/usr/bin/env node
3
+
4
+ // src/index.ts
5
+ import { Command as Command8 } from "commander";
6
+
7
+ // src/providers/provider.interface.ts
8
+ var providers = /* @__PURE__ */ new Map();
9
+ var registerProvider = (provider) => {
10
+ providers.set(provider.name.toLowerCase(), provider);
11
+ };
12
+ var getProvider = (name) => {
13
+ const provider = providers.get(name.toLowerCase());
14
+ if (!provider) {
15
+ const available = Array.from(providers.keys()).join(", ");
16
+ throw new Error(
17
+ `Unknown provider "${name}". Available providers: ${available || "none"}`
18
+ );
19
+ }
20
+ return provider;
21
+ };
22
+
23
+ // src/providers/vercel.ts
24
+ import fs2 from "fs";
25
+ import path2 from "path";
26
+ import os2 from "os";
27
+
28
+ // src/utils/paths.ts
29
+ import os from "os";
30
+ import path from "path";
31
+ import fs from "fs";
32
+ var getConfigDir = () => {
33
+ return path.join(os.homedir(), ".orbit");
34
+ };
35
+ var getConfigPath = () => {
36
+ return path.join(getConfigDir(), "config.json");
37
+ };
38
+ var ensureConfigDir = () => {
39
+ const dir = getConfigDir();
40
+ if (!fs.existsSync(dir)) {
41
+ fs.mkdirSync(dir, { recursive: true });
42
+ }
43
+ };
44
+ var getAuthDir = (provider) => {
45
+ return path.join(getConfigDir(), "auth", provider);
46
+ };
47
+ var getAuthFilePath = (provider, profile) => {
48
+ return path.join(getAuthDir(provider), `${profile}.json`);
49
+ };
50
+ var ensureAuthDir = (provider) => {
51
+ const dir = getAuthDir(provider);
52
+ if (!fs.existsSync(dir)) {
53
+ fs.mkdirSync(dir, { recursive: true });
54
+ }
55
+ };
56
+
57
+ // src/providers/vercel.ts
58
+ var getVercelAuthPath = () => {
59
+ const platform = os2.platform();
60
+ const home = os2.homedir();
61
+ if (platform === "darwin") {
62
+ return path2.join(
63
+ home,
64
+ "Library",
65
+ "Application Support",
66
+ "com.vercel.cli",
67
+ "auth.json"
68
+ );
69
+ } else if (platform === "win32") {
70
+ const appData = process.env["APPDATA"] || path2.join(home, "AppData", "Roaming");
71
+ return path2.join(appData, "com.vercel.cli", "auth.json");
72
+ } else {
73
+ const xdgDataHome = process.env["XDG_DATA_HOME"] || path2.join(home, ".local", "share");
74
+ return path2.join(xdgDataHome, "com.vercel.cli", "auth.json");
75
+ }
76
+ };
77
+ var vercelProvider = {
78
+ name: "vercel",
79
+ getEnvVar() {
80
+ return "VERCEL_TOKEN";
81
+ },
82
+ getCliName() {
83
+ return "vercel";
84
+ },
85
+ validateToken(token) {
86
+ return token.length > 20;
87
+ },
88
+ async getStoredToken() {
89
+ try {
90
+ const configPath = getVercelAuthPath();
91
+ if (configPath && fs2.existsSync(configPath)) {
92
+ const content = fs2.readFileSync(configPath, "utf-8");
93
+ const config = JSON.parse(content);
94
+ if (config.token && typeof config.token === "string") {
95
+ return config.token;
96
+ }
97
+ }
98
+ } catch {
99
+ }
100
+ return null;
101
+ },
102
+ async getUserEmail(token) {
103
+ try {
104
+ const response = await fetch("https://api.vercel.com/v2/user", {
105
+ headers: {
106
+ Authorization: `Bearer ${token}`
107
+ }
108
+ });
109
+ if (!response.ok) return void 0;
110
+ const data = await response.json();
111
+ return data.user.email;
112
+ } catch {
113
+ return void 0;
114
+ }
115
+ },
116
+ async login() {
117
+ try {
118
+ const { execa: execa3 } = await import("execa");
119
+ await execa3("vercel", ["login"], { stdio: "inherit" });
120
+ return true;
121
+ } catch {
122
+ return false;
123
+ }
124
+ },
125
+ getAuthConfigPath() {
126
+ return getVercelAuthPath();
127
+ },
128
+ async captureAuth(profile) {
129
+ const authPath = getVercelAuthPath();
130
+ if (!authPath || !fs2.existsSync(authPath)) return;
131
+ ensureAuthDir("vercel");
132
+ const destPath = getAuthFilePath("vercel", profile);
133
+ fs2.copyFileSync(authPath, destPath);
134
+ },
135
+ async restoreAuth(profile) {
136
+ const sourcePath = getAuthFilePath("vercel", profile);
137
+ if (!fs2.existsSync(sourcePath)) return false;
138
+ const authPath = getVercelAuthPath();
139
+ if (!authPath) return false;
140
+ const authDir = path2.dirname(authPath);
141
+ if (!fs2.existsSync(authDir)) {
142
+ fs2.mkdirSync(authDir, { recursive: true });
143
+ }
144
+ fs2.copyFileSync(sourcePath, authPath);
145
+ return true;
146
+ }
147
+ };
148
+
149
+ // src/commands/add.ts
150
+ import { Command } from "commander";
151
+ import ora from "ora";
152
+ import chalk2 from "chalk";
153
+ import readline from "readline";
154
+
155
+ // src/storage/keychain.ts
156
+ import keytar from "keytar";
157
+ var SERVICE_NAME = "appuo-orbit";
158
+ var getKey = (provider, profile) => {
159
+ return `${provider}:${profile}`;
160
+ };
161
+ var storeToken = async (provider, profile, token) => {
162
+ await keytar.setPassword(SERVICE_NAME, getKey(provider, profile), token);
163
+ };
164
+ var getToken = async (provider, profile) => {
165
+ return keytar.getPassword(SERVICE_NAME, getKey(provider, profile));
166
+ };
167
+ var deleteToken = async (provider, profile) => {
168
+ return keytar.deletePassword(SERVICE_NAME, getKey(provider, profile));
169
+ };
170
+
171
+ // src/storage/configStore.ts
172
+ import fs3 from "fs";
173
+
174
+ // src/types/config.ts
175
+ import { z } from "zod";
176
+ var ProviderConfigSchema = z.object({
177
+ profiles: z.array(z.string()),
178
+ current: z.string().optional(),
179
+ metadata: z.record(z.string(), z.object({ email: z.string().optional() })).optional()
180
+ });
181
+ var OrbitConfigSchema = z.object({
182
+ providers: z.record(z.string(), ProviderConfigSchema)
183
+ });
184
+
185
+ // src/storage/configStore.ts
186
+ var defaultConfig = {
187
+ providers: {}
188
+ };
189
+ var loadConfig = () => {
190
+ const configPath = getConfigPath();
191
+ if (!fs3.existsSync(configPath)) {
192
+ ensureConfigDir();
193
+ fs3.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), "utf-8");
194
+ return { ...defaultConfig };
195
+ }
196
+ const raw = fs3.readFileSync(configPath, "utf-8");
197
+ const parsed = JSON.parse(raw);
198
+ return OrbitConfigSchema.parse(parsed);
199
+ };
200
+ var saveConfig = (config) => {
201
+ ensureConfigDir();
202
+ const configPath = getConfigPath();
203
+ fs3.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
204
+ };
205
+ var addProfile = (provider, profile, metadata) => {
206
+ const config = loadConfig();
207
+ if (!config.providers[provider]) {
208
+ config.providers[provider] = { profiles: [], current: void 0 };
209
+ }
210
+ const providerConfig = config.providers[provider];
211
+ if (providerConfig && !providerConfig.profiles.includes(profile)) {
212
+ providerConfig.profiles.push(profile);
213
+ }
214
+ if (metadata) {
215
+ if (!providerConfig.metadata) {
216
+ providerConfig.metadata = {};
217
+ }
218
+ providerConfig.metadata[profile] = metadata;
219
+ }
220
+ saveConfig(config);
221
+ };
222
+ var removeProfile = (provider, profile) => {
223
+ const config = loadConfig();
224
+ const providerConfig = config.providers[provider];
225
+ if (!providerConfig) return;
226
+ providerConfig.profiles = providerConfig.profiles.filter((p) => p !== profile);
227
+ if (providerConfig.current === profile) {
228
+ providerConfig.current = void 0;
229
+ }
230
+ if (providerConfig.profiles.length === 0) {
231
+ delete config.providers[provider];
232
+ }
233
+ saveConfig(config);
234
+ };
235
+ var setCurrentProfile = (provider, profile) => {
236
+ const config = loadConfig();
237
+ const providerConfig = config.providers[provider];
238
+ if (!providerConfig) {
239
+ throw new Error(`No profiles found for provider "${provider}".`);
240
+ }
241
+ if (!providerConfig.profiles.includes(profile)) {
242
+ throw new Error(`Profile "${profile}" does not exist for provider "${provider}".`);
243
+ }
244
+ providerConfig.current = profile;
245
+ saveConfig(config);
246
+ };
247
+ var getCurrentProfile = (provider) => {
248
+ const config = loadConfig();
249
+ return config.providers[provider]?.current;
250
+ };
251
+ var profileExists = (provider, profile) => {
252
+ const config = loadConfig();
253
+ return config.providers[provider]?.profiles.includes(profile) ?? false;
254
+ };
255
+
256
+ // src/utils/validator.ts
257
+ import { z as z2 } from "zod";
258
+ var nameSchema = z2.string().min(1, "Name cannot be empty").max(64, "Name is too long").regex(/^[a-zA-Z0-9_-]+$/, "Name must be alphanumeric (hyphens and underscores allowed)");
259
+ var validateProviderName = (name) => {
260
+ return nameSchema.parse(name);
261
+ };
262
+ var validateProfileName = (name) => {
263
+ return nameSchema.parse(name);
264
+ };
265
+
266
+ // src/utils/logger.ts
267
+ import chalk from "chalk";
268
+ var write = (stream, message) => {
269
+ stream.write(`${message}
270
+ `);
271
+ };
272
+ var logger = {
273
+ info: (message) => {
274
+ write(process.stdout, chalk.blue("\u2139") + ` ${message}`);
275
+ },
276
+ success: (message) => {
277
+ write(process.stdout, chalk.green("\u2714") + ` ${message}`);
278
+ },
279
+ warn: (message) => {
280
+ write(process.stderr, chalk.yellow("\u26A0") + ` ${message}`);
281
+ },
282
+ error: (message) => {
283
+ write(process.stderr, chalk.red("\u2716") + ` ${message}`);
284
+ },
285
+ plain: (message) => {
286
+ write(process.stdout, message);
287
+ },
288
+ newline: () => {
289
+ write(process.stdout, "");
290
+ }
291
+ };
292
+
293
+ // src/utils/errorHandler.ts
294
+ import { ZodError } from "zod";
295
+ var handleError = (error) => {
296
+ if (error instanceof ZodError) {
297
+ const messages = error.errors.map((e) => e.message).join(", ");
298
+ logger.error(`Validation error: ${messages}`);
299
+ process.exit(1);
300
+ }
301
+ if (error instanceof Error) {
302
+ logger.error(error.message);
303
+ if (process.env["ORBIT_DEBUG"] === "1") {
304
+ logger.plain(error.stack ?? "");
305
+ }
306
+ process.exit(1);
307
+ }
308
+ logger.error("An unexpected error occurred.");
309
+ process.exit(1);
310
+ };
311
+
312
+ // src/commands/add.ts
313
+ var promptHiddenInput = (prompt) => {
314
+ return new Promise((resolve, reject) => {
315
+ const rl = readline.createInterface({
316
+ input: process.stdin,
317
+ output: process.stdout
318
+ });
319
+ if (process.stdin.isTTY) {
320
+ process.stdout.write(prompt);
321
+ const stdin = process.stdin;
322
+ stdin.setRawMode(true);
323
+ stdin.resume();
324
+ let input = "";
325
+ const onData = (data) => {
326
+ const char = data.toString("utf-8");
327
+ if (char === "\n" || char === "\r" || char === "") {
328
+ stdin.setRawMode(false);
329
+ stdin.removeListener("data", onData);
330
+ stdin.pause();
331
+ rl.close();
332
+ process.stdout.write("\n");
333
+ resolve(input);
334
+ } else if (char === "") {
335
+ stdin.setRawMode(false);
336
+ stdin.removeListener("data", onData);
337
+ stdin.pause();
338
+ rl.close();
339
+ reject(new Error("User cancelled input."));
340
+ } else if (char === "\x7F" || char === "\b") {
341
+ input = input.slice(0, -1);
342
+ } else {
343
+ input += char;
344
+ }
345
+ };
346
+ stdin.on("data", onData);
347
+ } else {
348
+ rl.question(prompt, (answer) => {
349
+ rl.close();
350
+ resolve(answer);
351
+ });
352
+ }
353
+ });
354
+ };
355
+ var confirmInput = (prompt) => {
356
+ return new Promise((resolve) => {
357
+ const rl = readline.createInterface({
358
+ input: process.stdin,
359
+ output: process.stdout
360
+ });
361
+ rl.question(prompt, (answer) => {
362
+ rl.close();
363
+ const normalized = answer.trim().toLowerCase();
364
+ resolve(normalized === "y" || normalized === "yes" || normalized === "");
365
+ });
366
+ });
367
+ };
368
+ var addCommand = new Command("add").description("Add a new cloud provider profile").argument("<provider>", "Cloud provider name (e.g., vercel)").argument("<profile>", "Profile name (e.g., personal, company)").action(async (providerName, profileName) => {
369
+ try {
370
+ const validProvider = validateProviderName(providerName);
371
+ const validProfile = validateProfileName(profileName);
372
+ const provider = getProvider(validProvider);
373
+ if (profileExists(validProvider, validProfile)) {
374
+ logger.warn(`Profile "${validProfile}" already exists for ${provider.name}. It will be overwritten.`);
375
+ }
376
+ let token = "";
377
+ let storedTokenFound = false;
378
+ if (provider.getStoredToken) {
379
+ const spinner2 = ora(`Checking for existing ${provider.name} credentials...`).start();
380
+ try {
381
+ const storedToken = await provider.getStoredToken();
382
+ spinner2.stop();
383
+ if (storedToken) {
384
+ storedTokenFound = true;
385
+ let emailDisplay = "";
386
+ if (provider.getUserEmail) {
387
+ try {
388
+ const email = await provider.getUserEmail(storedToken);
389
+ if (email) emailDisplay = ` (${chalk2.cyan(email)})`;
390
+ } catch {
391
+ }
392
+ }
393
+ const useStored = await confirmInput(
394
+ `Found existing token${emailDisplay} from ${provider.name} CLI. Use this? (Y/n) `
395
+ );
396
+ if (useStored) {
397
+ token = storedToken;
398
+ }
399
+ }
400
+ } catch {
401
+ spinner2.stop();
402
+ }
403
+ }
404
+ if (!token && provider.login) {
405
+ const promptMsg = storedTokenFound ? `Login to a different account with ${provider.name} CLI? (Y/n) ` : `No existing credentials found. Login with ${provider.name} CLI now? (Y/n) `;
406
+ const shouldLogin = await confirmInput(promptMsg);
407
+ if (shouldLogin) {
408
+ const loginSuccess = await provider.login();
409
+ if (loginSuccess) {
410
+ if (provider.getStoredToken) {
411
+ const spinner2 = ora("Checking for new credentials...").start();
412
+ try {
413
+ const storedToken = await provider.getStoredToken();
414
+ spinner2.stop();
415
+ if (storedToken) {
416
+ token = storedToken;
417
+ logger.success("New credentials found!");
418
+ }
419
+ } catch {
420
+ spinner2.stop();
421
+ }
422
+ }
423
+ } else {
424
+ logger.warn("Login failed or was cancelled.");
425
+ }
426
+ }
427
+ }
428
+ if (!token) {
429
+ token = await promptHiddenInput(`\u{1F511} Enter token for ${provider.name}/${validProfile}: `);
430
+ }
431
+ if (!token.trim()) {
432
+ logger.error("Token cannot be empty.");
433
+ process.exit(1);
434
+ }
435
+ const spinner = ora("Validating token...").start();
436
+ if (!provider.validateToken(token.trim())) {
437
+ spinner.fail("Token validation failed.");
438
+ logger.error(`Invalid token format for ${provider.name}. Please check your token and try again.`);
439
+ process.exit(1);
440
+ }
441
+ spinner.text = "Storing token securely...";
442
+ await storeToken(validProvider, validProfile, token.trim());
443
+ if (provider.getUserEmail) {
444
+ spinner.text = "Fetching user info...";
445
+ try {
446
+ const email = await provider.getUserEmail(token.trim());
447
+ if (email) {
448
+ spinner.text = `Found user: ${email}. Updating configuration...`;
449
+ addProfile(validProvider, validProfile, { email });
450
+ } else {
451
+ addProfile(validProvider, validProfile);
452
+ }
453
+ } catch {
454
+ addProfile(validProvider, validProfile);
455
+ }
456
+ } else {
457
+ addProfile(validProvider, validProfile);
458
+ }
459
+ spinner.succeed(`Profile "${validProfile}" added for ${provider.name}.`);
460
+ if (provider.captureAuth) {
461
+ try {
462
+ await provider.captureAuth(validProfile);
463
+ } catch {
464
+ }
465
+ }
466
+ } catch (error) {
467
+ handleError(error);
468
+ }
469
+ });
470
+
471
+ // src/commands/list.ts
472
+ import { Command as Command2 } from "commander";
473
+ import chalk3 from "chalk";
474
+ var listCommand = new Command2("list").description("List all profiles across providers").action(() => {
475
+ try {
476
+ const config = loadConfig();
477
+ const providers2 = Object.keys(config.providers);
478
+ if (providers2.length === 0) {
479
+ logger.info('No profiles configured yet. Use "orbit add <provider> <profile>" to get started.');
480
+ return;
481
+ }
482
+ logger.newline();
483
+ logger.plain(
484
+ ` ${chalk3.bold.underline("Provider".padEnd(15))} ${chalk3.bold.underline("Profile".padEnd(20))} ${chalk3.bold.underline("Email".padEnd(30))} ${chalk3.bold.underline("Status")}`
485
+ );
486
+ logger.newline();
487
+ for (const providerName of providers2) {
488
+ const providerConfig = config.providers[providerName];
489
+ if (!providerConfig) continue;
490
+ for (const profile of providerConfig.profiles) {
491
+ const isCurrent = providerConfig.current === profile;
492
+ const email = providerConfig.metadata?.[profile]?.email ?? "-";
493
+ const status = isCurrent ? chalk3.green("\u2605 current") : chalk3.dim("\u2014");
494
+ const providerDisplay = isCurrent ? chalk3.cyan(providerName.padEnd(15)) : chalk3.white(providerName.padEnd(15));
495
+ const profileDisplay = isCurrent ? chalk3.cyan(profile.padEnd(20)) : chalk3.white(profile.padEnd(20));
496
+ const emailDisplay = isCurrent ? chalk3.cyan(email.padEnd(30)) : chalk3.gray(email.padEnd(30));
497
+ logger.plain(` ${providerDisplay} ${profileDisplay} ${emailDisplay} ${status}`);
498
+ }
499
+ }
500
+ logger.newline();
501
+ } catch (error) {
502
+ handleError(error);
503
+ }
504
+ });
505
+
506
+ // src/commands/remove.ts
507
+ import { Command as Command3 } from "commander";
508
+ import ora2 from "ora";
509
+ var removeCommand = new Command3("remove").description("Remove a cloud provider profile").argument("<provider>", "Cloud provider name").argument("<profile>", "Profile name to remove").action(async (providerName, profileName) => {
510
+ try {
511
+ const validProvider = validateProviderName(providerName);
512
+ const validProfile = validateProfileName(profileName);
513
+ getProvider(validProvider);
514
+ if (!profileExists(validProvider, validProfile)) {
515
+ logger.error(`Profile "${validProfile}" does not exist for provider "${validProvider}".`);
516
+ process.exit(1);
517
+ }
518
+ const spinner = ora2("Removing profile...").start();
519
+ spinner.text = "Deleting token from secure storage...";
520
+ await deleteToken(validProvider, validProfile);
521
+ spinner.text = "Updating configuration...";
522
+ removeProfile(validProvider, validProfile);
523
+ spinner.succeed(`Profile "${validProfile}" removed from ${validProvider}.`);
524
+ } catch (error) {
525
+ handleError(error);
526
+ }
527
+ });
528
+
529
+ // src/commands/use.ts
530
+ import { Command as Command4 } from "commander";
531
+ import ora3 from "ora";
532
+ var useCommand = new Command4("use").description("Set the current active profile for a provider").argument("<provider>", "Cloud provider name").argument("<profile>", "Profile name to activate").action(async (providerName, profileName) => {
533
+ try {
534
+ const validProvider = validateProviderName(providerName);
535
+ const validProfile = validateProfileName(profileName);
536
+ const provider = getProvider(validProvider);
537
+ if (!profileExists(validProvider, validProfile)) {
538
+ logger.error(`Profile "${validProfile}" does not exist for provider "${provider.name}".`);
539
+ process.exit(1);
540
+ }
541
+ const spinner = ora3("Switching profile...").start();
542
+ const currentProfile = getCurrentProfile(validProvider);
543
+ if (currentProfile && currentProfile !== validProfile && provider.captureAuth) {
544
+ try {
545
+ await provider.captureAuth(currentProfile);
546
+ } catch {
547
+ }
548
+ }
549
+ if (provider.restoreAuth) {
550
+ const restored = await provider.restoreAuth(validProfile);
551
+ if (restored) {
552
+ spinner.text = "Auth credentials restored...";
553
+ }
554
+ }
555
+ setCurrentProfile(validProvider, validProfile);
556
+ spinner.succeed(`Now using profile "${validProfile}" for ${provider.name}.`);
557
+ } catch (error) {
558
+ handleError(error);
559
+ }
560
+ });
561
+
562
+ // src/commands/run.ts
563
+ import { Command as Command5 } from "commander";
564
+ import { execa } from "execa";
565
+ var runCommand = new Command5("run").description("Run a command with a specific provider profile").argument("<provider>", "Cloud provider name").argument("<profile>", "Profile name to use").argument("<args...>", "Command arguments to pass to the provider CLI").passThroughOptions().allowUnknownOption().action(async (providerName, profileName, args) => {
566
+ try {
567
+ const validProvider = validateProviderName(providerName);
568
+ const validProfile = validateProfileName(profileName);
569
+ const provider = getProvider(validProvider);
570
+ if (!profileExists(validProvider, validProfile)) {
571
+ logger.error(`Profile "${validProfile}" does not exist for provider "${provider.name}".`);
572
+ process.exit(1);
573
+ }
574
+ logger.info(`Running as ${provider.name}/${validProfile}...`);
575
+ const currentProfile = getCurrentProfile(validProvider);
576
+ let swapped = false;
577
+ if (provider.restoreAuth) {
578
+ if (currentProfile && currentProfile !== validProfile && provider.captureAuth) {
579
+ try {
580
+ await provider.captureAuth(currentProfile);
581
+ } catch {
582
+ }
583
+ }
584
+ swapped = await provider.restoreAuth(validProfile);
585
+ }
586
+ try {
587
+ if (swapped) {
588
+ const cliName = provider.getCliName();
589
+ const result = await execa(cliName, args, {
590
+ stdio: "inherit",
591
+ reject: false
592
+ });
593
+ process.exitCode = result.exitCode ?? 0;
594
+ } else {
595
+ const token = await getToken(validProvider, validProfile);
596
+ if (!token) {
597
+ logger.error(`No token found for ${provider.name}/${validProfile}. Try adding it again with "orbit add".`);
598
+ process.exit(1);
599
+ }
600
+ const cliName = provider.getCliName();
601
+ const envVar = provider.getEnvVar();
602
+ const result = await execa(cliName, args, {
603
+ env: {
604
+ ...process.env,
605
+ [envVar]: token
606
+ },
607
+ stdio: "inherit",
608
+ reject: false
609
+ });
610
+ process.exitCode = result.exitCode ?? 0;
611
+ }
612
+ } finally {
613
+ if (swapped && currentProfile && currentProfile !== validProfile && provider.restoreAuth) {
614
+ try {
615
+ await provider.restoreAuth(currentProfile);
616
+ } catch {
617
+ }
618
+ }
619
+ }
620
+ process.exit(process.exitCode ?? 0);
621
+ } catch (error) {
622
+ handleError(error);
623
+ }
624
+ });
625
+
626
+ // src/commands/exec.ts
627
+ import { Command as Command6 } from "commander";
628
+ import { execa as execa2 } from "execa";
629
+ var execCommand = new Command6("exec").description("Execute a command using the current active profile").argument("<provider>", "Cloud provider name").argument("<args...>", "Command arguments to pass to the provider CLI").passThroughOptions().allowUnknownOption().action(async (providerName, args) => {
630
+ try {
631
+ const validProvider = validateProviderName(providerName);
632
+ const provider = getProvider(validProvider);
633
+ const currentProfile = getCurrentProfile(validProvider);
634
+ if (!currentProfile) {
635
+ logger.error(
636
+ `No active profile set for ${provider.name}. Use "orbit use ${validProvider} <profile>" first.`
637
+ );
638
+ process.exit(1);
639
+ }
640
+ if (provider.restoreAuth) {
641
+ await provider.restoreAuth(currentProfile);
642
+ }
643
+ const cliName = provider.getCliName();
644
+ logger.info(`Running as ${provider.name}/${currentProfile}...`);
645
+ if (provider.getAuthConfigPath?.()) {
646
+ const result2 = await execa2(cliName, args, {
647
+ stdio: "inherit",
648
+ reject: false
649
+ });
650
+ process.exit(result2.exitCode ?? 0);
651
+ }
652
+ const token = await getToken(validProvider, currentProfile);
653
+ if (!token) {
654
+ logger.error(
655
+ `No token found for ${provider.name}/${currentProfile}. Try adding it again with "orbit add".`
656
+ );
657
+ process.exit(1);
658
+ }
659
+ const envVar = provider.getEnvVar();
660
+ const result = await execa2(cliName, args, {
661
+ env: {
662
+ ...process.env,
663
+ [envVar]: token
664
+ },
665
+ stdio: "inherit",
666
+ reject: false
667
+ });
668
+ process.exit(result.exitCode ?? 0);
669
+ } catch (error) {
670
+ handleError(error);
671
+ }
672
+ });
673
+
674
+ // src/commands/current.ts
675
+ import { Command as Command7 } from "commander";
676
+ import chalk4 from "chalk";
677
+ var currentCommand = new Command7("current").description("Show current active profiles").action(() => {
678
+ try {
679
+ const config = loadConfig();
680
+ const providers2 = Object.keys(config.providers);
681
+ if (providers2.length === 0) {
682
+ logger.info("No profiles configured yet.");
683
+ return;
684
+ }
685
+ let hasActive = false;
686
+ for (const providerName of providers2) {
687
+ const providerConfig = config.providers[providerName];
688
+ if (providerConfig?.current) {
689
+ logger.success(
690
+ `${chalk4.bold(providerName)}: ${chalk4.cyan(providerConfig.current)}`
691
+ );
692
+ hasActive = true;
693
+ }
694
+ }
695
+ if (!hasActive) {
696
+ logger.info('No active profiles set. Use "orbit use <provider> <profile>" to set one.');
697
+ }
698
+ } catch (error) {
699
+ handleError(error);
700
+ }
701
+ });
702
+
703
+ // src/index.ts
704
+ registerProvider(vercelProvider);
705
+ var program = new Command8();
706
+ program.name("orbit").description("\u{1F30D} A fully CLI-based multi-cloud profile manager").version("1.0.0").enablePositionalOptions();
707
+ program.addCommand(addCommand);
708
+ program.addCommand(listCommand);
709
+ program.addCommand(removeCommand);
710
+ program.addCommand(useCommand);
711
+ program.addCommand(runCommand);
712
+ program.addCommand(execCommand);
713
+ program.addCommand(currentCommand);
714
+ try {
715
+ await program.parseAsync(process.argv);
716
+ } catch (error) {
717
+ handleError(error);
718
+ }
719
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/providers/provider.interface.ts","../src/providers/vercel.ts","../src/utils/paths.ts","../src/commands/add.ts","../src/storage/keychain.ts","../src/storage/configStore.ts","../src/types/config.ts","../src/utils/validator.ts","../src/utils/logger.ts","../src/utils/errorHandler.ts","../src/commands/list.ts","../src/commands/remove.ts","../src/commands/use.ts","../src/commands/run.ts","../src/commands/exec.ts","../src/commands/current.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { registerProvider } from './providers/provider.interface.js';\nimport { vercelProvider } from './providers/vercel.js';\nimport { addCommand } from './commands/add.js';\nimport { listCommand } from './commands/list.js';\nimport { removeCommand } from './commands/remove.js';\nimport { useCommand } from './commands/use.js';\nimport { runCommand } from './commands/run.js';\nimport { execCommand } from './commands/exec.js';\nimport { currentCommand } from './commands/current.js';\nimport { handleError } from './utils/errorHandler.js';\n\n// Register providers\nregisterProvider(vercelProvider);\n\nconst program = new Command();\n\nprogram\n .name('orbit')\n .description('🌍 A fully CLI-based multi-cloud profile manager')\n .version('1.0.0')\n .enablePositionalOptions();\n\nprogram.addCommand(addCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(removeCommand);\nprogram.addCommand(useCommand);\nprogram.addCommand(runCommand);\nprogram.addCommand(execCommand);\nprogram.addCommand(currentCommand);\n\ntry {\n await program.parseAsync(process.argv);\n} catch (error: unknown) {\n handleError(error);\n}\n","export interface Provider {\n name: string;\n getEnvVar(): string;\n getCliName(): string;\n validateToken(token: string): boolean;\n getStoredToken?(): Promise<string | null>;\n getUserEmail?(token: string): Promise<string | undefined>;\n login?(): Promise<boolean>;\n getAuthConfigPath?(): string | null;\n captureAuth?(profile: string): Promise<void>;\n restoreAuth?(profile: string): Promise<boolean>;\n}\n\nconst providers = new Map<string, Provider>();\n\nexport const registerProvider = (provider: Provider): void => {\n providers.set(provider.name.toLowerCase(), provider);\n};\n\nexport const getProvider = (name: string): Provider => {\n const provider = providers.get(name.toLowerCase());\n\n if (!provider) {\n const available = Array.from(providers.keys()).join(', ');\n throw new Error(\n `Unknown provider \"${name}\". Available providers: ${available || 'none'}`,\n );\n }\n\n return provider;\n};\n\nexport const getAllProviders = (): Provider[] => {\n return Array.from(providers.values());\n};\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport type { Provider } from './provider.interface.js';\nimport { getAuthFilePath, ensureAuthDir } from '../utils/paths.js';\n\nconst getVercelAuthPath = (): string | null => {\n const platform = os.platform();\n const home = os.homedir();\n\n if (platform === 'darwin') {\n return path.join(\n home,\n 'Library',\n 'Application Support',\n 'com.vercel.cli',\n 'auth.json',\n );\n } else if (platform === 'win32') {\n const appData = process.env['APPDATA'] || path.join(home, 'AppData', 'Roaming');\n return path.join(appData, 'com.vercel.cli', 'auth.json');\n } else {\n const xdgDataHome =\n process.env['XDG_DATA_HOME'] || path.join(home, '.local', 'share');\n return path.join(xdgDataHome, 'com.vercel.cli', 'auth.json');\n }\n};\n\nexport const vercelProvider: Provider = {\n name: 'vercel',\n\n getEnvVar(): string {\n return 'VERCEL_TOKEN';\n },\n\n getCliName(): string {\n return 'vercel';\n },\n\n validateToken(token: string): boolean {\n return token.length > 20;\n },\n\n async getStoredToken(): Promise<string | null> {\n try {\n const configPath = getVercelAuthPath();\n if (configPath && fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf-8');\n const config = JSON.parse(content) as { token?: string };\n if (config.token && typeof config.token === 'string') {\n return config.token;\n }\n }\n } catch {\n // Ignore errors\n }\n return null;\n },\n\n async getUserEmail(token: string): Promise<string | undefined> {\n try {\n const response = await fetch('https://api.vercel.com/v2/user', {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) return undefined;\n\n const data = (await response.json()) as { user: { email: string } };\n return data.user.email;\n } catch {\n return undefined;\n }\n },\n\n async login(): Promise<boolean> {\n try {\n const { execa } = await import('execa');\n await execa('vercel', ['login'], { stdio: 'inherit' });\n return true;\n } catch {\n return false;\n }\n },\n\n getAuthConfigPath(): string | null {\n return getVercelAuthPath();\n },\n\n async captureAuth(profile: string): Promise<void> {\n const authPath = getVercelAuthPath();\n if (!authPath || !fs.existsSync(authPath)) return;\n\n ensureAuthDir('vercel');\n const destPath = getAuthFilePath('vercel', profile);\n fs.copyFileSync(authPath, destPath);\n },\n\n async restoreAuth(profile: string): Promise<boolean> {\n const sourcePath = getAuthFilePath('vercel', profile);\n if (!fs.existsSync(sourcePath)) return false;\n\n const authPath = getVercelAuthPath();\n if (!authPath) return false;\n\n // Ensure the Vercel config directory exists\n const authDir = path.dirname(authPath);\n if (!fs.existsSync(authDir)) {\n fs.mkdirSync(authDir, { recursive: true });\n }\n\n fs.copyFileSync(sourcePath, authPath);\n return true;\n },\n};\n","import os from 'node:os';\nimport path from 'node:path';\nimport fs from 'node:fs';\n\nexport const getConfigDir = (): string => {\n return path.join(os.homedir(), '.orbit');\n};\n\nexport const getConfigPath = (): string => {\n return path.join(getConfigDir(), 'config.json');\n};\n\nexport const ensureConfigDir = (): void => {\n const dir = getConfigDir();\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n};\n\nexport const getAuthDir = (provider: string): string => {\n return path.join(getConfigDir(), 'auth', provider);\n};\n\nexport const getAuthFilePath = (provider: string, profile: string): string => {\n return path.join(getAuthDir(provider), `${profile}.json`);\n};\n\nexport const ensureAuthDir = (provider: string): void => {\n const dir = getAuthDir(provider);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n};\n","import { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport readline from 'node:readline';\nimport { getProvider } from '../providers/provider.interface.js';\nimport { storeToken } from '../storage/keychain.js';\nimport { addProfile, profileExists } from '../storage/configStore.js';\nimport { validateProviderName, validateProfileName } from '../utils/validator.js';\nimport { logger } from '../utils/logger.js';\nimport { handleError } from '../utils/errorHandler.js';\n\nconst promptHiddenInput = (prompt: string): Promise<string> => {\n return new Promise((resolve, reject) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n // Disable echo for hidden input\n if (process.stdin.isTTY) {\n process.stdout.write(prompt);\n const stdin = process.stdin;\n stdin.setRawMode(true);\n stdin.resume();\n\n let input = '';\n\n const onData = (data: Buffer): void => {\n const char = data.toString('utf-8');\n\n if (char === '\\n' || char === '\\r' || char === '\\u0004') {\n stdin.setRawMode(false);\n stdin.removeListener('data', onData);\n stdin.pause();\n rl.close();\n process.stdout.write('\\n');\n resolve(input);\n } else if (char === '\\u0003') {\n // Ctrl+C\n stdin.setRawMode(false);\n stdin.removeListener('data', onData);\n stdin.pause();\n rl.close();\n reject(new Error('User cancelled input.'));\n } else if (char === '\\u007F' || char === '\\b') {\n // Backspace\n input = input.slice(0, -1);\n } else {\n input += char;\n }\n };\n\n stdin.on('data', onData);\n } else {\n // Non-TTY fallback (piped input)\n rl.question(prompt, (answer) => {\n rl.close();\n resolve(answer);\n });\n }\n });\n};\n\nconst confirmInput = (prompt: string): Promise<boolean> => {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(prompt, (answer) => {\n rl.close();\n const normalized = answer.trim().toLowerCase();\n resolve(normalized === 'y' || normalized === 'yes' || normalized === '');\n });\n });\n};\n\nexport const addCommand = new Command('add')\n .description('Add a new cloud provider profile')\n .argument('<provider>', 'Cloud provider name (e.g., vercel)')\n .argument('<profile>', 'Profile name (e.g., personal, company)')\n .action(async (providerName: string, profileName: string) => {\n try {\n const validProvider = validateProviderName(providerName);\n const validProfile = validateProfileName(profileName);\n const provider = getProvider(validProvider);\n\n if (profileExists(validProvider, validProfile)) {\n logger.warn(`Profile \"${validProfile}\" already exists for ${provider.name}. It will be overwritten.`);\n }\n\n let token = '';\n let storedTokenFound = false;\n\n if (provider.getStoredToken) {\n const spinner = ora(`Checking for existing ${provider.name} credentials...`).start();\n try {\n const storedToken = await provider.getStoredToken();\n spinner.stop();\n\n if (storedToken) {\n storedTokenFound = true;\n let emailDisplay = '';\n if (provider.getUserEmail) {\n try {\n const email = await provider.getUserEmail(storedToken);\n if (email) emailDisplay = ` (${chalk.cyan(email)})`;\n } catch {\n // Ignore email fetch error\n }\n }\n\n const useStored = await confirmInput(\n `Found existing token${emailDisplay} from ${provider.name} CLI. Use this? (Y/n) `,\n );\n if (useStored) {\n token = storedToken;\n }\n }\n } catch {\n spinner.stop();\n // Ignore errors during auto-discovery\n }\n }\n\n if (!token && provider.login) {\n const promptMsg = storedTokenFound\n ? `Login to a different account with ${provider.name} CLI? (Y/n) `\n : `No existing credentials found. Login with ${provider.name} CLI now? (Y/n) `;\n\n const shouldLogin = await confirmInput(promptMsg);\n\n if (shouldLogin) {\n const loginSuccess = await provider.login();\n if (loginSuccess) {\n // Re-check for token\n if (provider.getStoredToken) {\n const spinner = ora('Checking for new credentials...').start();\n try {\n const storedToken = await provider.getStoredToken();\n spinner.stop();\n if (storedToken) {\n token = storedToken;\n logger.success('New credentials found!');\n }\n } catch {\n spinner.stop();\n }\n }\n } else {\n logger.warn('Login failed or was cancelled.');\n }\n }\n }\n\n if (!token) {\n token = await promptHiddenInput(`🔑 Enter token for ${provider.name}/${validProfile}: `);\n }\n\n if (!token.trim()) {\n logger.error('Token cannot be empty.');\n process.exit(1);\n }\n\n const spinner = ora('Validating token...').start();\n\n if (!provider.validateToken(token.trim())) {\n spinner.fail('Token validation failed.');\n logger.error(`Invalid token format for ${provider.name}. Please check your token and try again.`);\n process.exit(1);\n }\n\n spinner.text = 'Storing token securely...';\n await storeToken(validProvider, validProfile, token.trim());\n\n if (provider.getUserEmail) {\n spinner.text = 'Fetching user info...';\n try {\n const email = await provider.getUserEmail(token.trim());\n if (email) {\n spinner.text = `Found user: ${email}. Updating configuration...`;\n addProfile(validProvider, validProfile, { email });\n } else {\n addProfile(validProvider, validProfile);\n }\n } catch {\n addProfile(validProvider, validProfile);\n }\n } else {\n addProfile(validProvider, validProfile);\n }\n\n spinner.succeed(`Profile \"${validProfile}\" added for ${provider.name}.`);\n\n // Capture auth.json snapshot for this profile\n if (provider.captureAuth) {\n try {\n await provider.captureAuth(validProfile);\n } catch {\n // Non-critical: auth capture failure doesn't block profile creation\n }\n }\n } catch (error: unknown) {\n handleError(error);\n }\n });\n","import keytar from 'keytar';\n\nconst SERVICE_NAME = 'appuo-orbit';\n\nconst getKey = (provider: string, profile: string): string => {\n return `${provider}:${profile}`;\n};\n\nexport const storeToken = async (\n provider: string,\n profile: string,\n token: string,\n): Promise<void> => {\n await keytar.setPassword(SERVICE_NAME, getKey(provider, profile), token);\n};\n\nexport const getToken = async (\n provider: string,\n profile: string,\n): Promise<string | null> => {\n return keytar.getPassword(SERVICE_NAME, getKey(provider, profile));\n};\n\nexport const deleteToken = async (\n provider: string,\n profile: string,\n): Promise<boolean> => {\n return keytar.deletePassword(SERVICE_NAME, getKey(provider, profile));\n};\n","import fs from 'node:fs';\nimport { OrbitConfigSchema } from '../types/config.js';\nimport type { OrbitConfig } from '../types/config.js';\nimport { getConfigPath, ensureConfigDir } from '../utils/paths.js';\n\nconst defaultConfig: OrbitConfig = {\n providers: {},\n};\n\nexport const loadConfig = (): OrbitConfig => {\n const configPath = getConfigPath();\n\n if (!fs.existsSync(configPath)) {\n ensureConfigDir();\n fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf-8');\n return { ...defaultConfig };\n }\n\n const raw = fs.readFileSync(configPath, 'utf-8');\n const parsed: unknown = JSON.parse(raw);\n return OrbitConfigSchema.parse(parsed);\n};\n\nexport const saveConfig = (config: OrbitConfig): void => {\n ensureConfigDir();\n const configPath = getConfigPath();\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');\n};\n\nexport const addProfile = (\n provider: string,\n profile: string,\n metadata?: { email?: string },\n): void => {\n const config = loadConfig();\n\n if (!config.providers[provider]) {\n config.providers[provider] = { profiles: [], current: undefined };\n }\n\n const providerConfig = config.providers[provider];\n if (providerConfig && !providerConfig.profiles.includes(profile)) {\n providerConfig.profiles.push(profile);\n }\n\n if (metadata) {\n if (!providerConfig.metadata) {\n providerConfig.metadata = {};\n }\n providerConfig.metadata[profile] = metadata;\n }\n\n saveConfig(config);\n};\n\nexport const removeProfile = (provider: string, profile: string): void => {\n const config = loadConfig();\n const providerConfig = config.providers[provider];\n\n if (!providerConfig) return;\n\n providerConfig.profiles = providerConfig.profiles.filter((p) => p !== profile);\n\n if (providerConfig.current === profile) {\n providerConfig.current = undefined;\n }\n\n if (providerConfig.profiles.length === 0) {\n delete config.providers[provider];\n }\n\n saveConfig(config);\n};\n\nexport const setCurrentProfile = (provider: string, profile: string): void => {\n const config = loadConfig();\n const providerConfig = config.providers[provider];\n\n if (!providerConfig) {\n throw new Error(`No profiles found for provider \"${provider}\".`);\n }\n\n if (!providerConfig.profiles.includes(profile)) {\n throw new Error(`Profile \"${profile}\" does not exist for provider \"${provider}\".`);\n }\n\n providerConfig.current = profile;\n saveConfig(config);\n};\n\nexport const getCurrentProfile = (provider: string): string | undefined => {\n const config = loadConfig();\n return config.providers[provider]?.current;\n};\n\nexport const profileExists = (provider: string, profile: string): boolean => {\n const config = loadConfig();\n return config.providers[provider]?.profiles.includes(profile) ?? false;\n};\n","import { z } from 'zod';\n\nconst ProviderConfigSchema = z.object({\n profiles: z.array(z.string()),\n current: z.string().optional(),\n metadata: z.record(z.string(), z.object({ email: z.string().optional() })).optional(),\n});\n\nexport const OrbitConfigSchema = z.object({\n providers: z.record(z.string(), ProviderConfigSchema),\n});\n\nexport type ProviderConfig = z.infer<typeof ProviderConfigSchema>;\nexport type OrbitConfig = z.infer<typeof OrbitConfigSchema>;\n","import { z } from 'zod';\n\nconst nameSchema = z\n .string()\n .min(1, 'Name cannot be empty')\n .max(64, 'Name is too long')\n .regex(/^[a-zA-Z0-9_-]+$/, 'Name must be alphanumeric (hyphens and underscores allowed)');\n\nexport const validateProviderName = (name: string): string => {\n return nameSchema.parse(name);\n};\n\nexport const validateProfileName = (name: string): string => {\n return nameSchema.parse(name);\n};\n","import chalk from 'chalk';\n\nconst write = (stream: NodeJS.WriteStream, message: string): void => {\n stream.write(`${message}\\n`);\n};\n\nexport const logger = {\n info: (message: string): void => {\n write(process.stdout, chalk.blue('ℹ') + ` ${message}`);\n },\n\n success: (message: string): void => {\n write(process.stdout, chalk.green('✔') + ` ${message}`);\n },\n\n warn: (message: string): void => {\n write(process.stderr, chalk.yellow('⚠') + ` ${message}`);\n },\n\n error: (message: string): void => {\n write(process.stderr, chalk.red('✖') + ` ${message}`);\n },\n\n plain: (message: string): void => {\n write(process.stdout, message);\n },\n\n newline: (): void => {\n write(process.stdout, '');\n },\n};\n","import { logger } from './logger.js';\nimport { ZodError } from 'zod';\n\nexport const handleError = (error: unknown): never => {\n if (error instanceof ZodError) {\n const messages = error.errors.map((e) => e.message).join(', ');\n logger.error(`Validation error: ${messages}`);\n process.exit(1);\n }\n\n if (error instanceof Error) {\n logger.error(error.message);\n\n if (process.env['ORBIT_DEBUG'] === '1') {\n logger.plain(error.stack ?? '');\n }\n\n process.exit(1);\n }\n\n logger.error('An unexpected error occurred.');\n process.exit(1);\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadConfig } from '../storage/configStore.js';\nimport { logger } from '../utils/logger.js';\nimport { handleError } from '../utils/errorHandler.js';\n\nexport const listCommand = new Command('list')\n .description('List all profiles across providers')\n .action(() => {\n try {\n const config = loadConfig();\n const providers = Object.keys(config.providers);\n\n if (providers.length === 0) {\n logger.info('No profiles configured yet. Use \"orbit add <provider> <profile>\" to get started.');\n return;\n }\n\n logger.newline();\n logger.plain(\n ` ${chalk.bold.underline('Provider'.padEnd(15))} ${chalk.bold.underline('Profile'.padEnd(20))} ${chalk.bold.underline('Email'.padEnd(30))} ${chalk.bold.underline('Status')}`,\n );\n logger.newline();\n\n for (const providerName of providers) {\n const providerConfig = config.providers[providerName];\n if (!providerConfig) continue;\n\n for (const profile of providerConfig.profiles) {\n const isCurrent = providerConfig.current === profile;\n const email = providerConfig.metadata?.[profile]?.email ?? '-';\n const status = isCurrent ? chalk.green('★ current') : chalk.dim('—');\n\n const providerDisplay = isCurrent\n ? chalk.cyan(providerName.padEnd(15))\n : chalk.white(providerName.padEnd(15));\n const profileDisplay = isCurrent\n ? chalk.cyan(profile.padEnd(20))\n : chalk.white(profile.padEnd(20));\n const emailDisplay = isCurrent\n ? chalk.cyan(email.padEnd(30))\n : chalk.gray(email.padEnd(30));\n\n logger.plain(` ${providerDisplay} ${profileDisplay} ${emailDisplay} ${status}`);\n }\n }\n\n logger.newline();\n } catch (error: unknown) {\n handleError(error);\n }\n });\n","import { Command } from 'commander';\nimport ora from 'ora';\nimport { getProvider } from '../providers/provider.interface.js';\nimport { deleteToken } from '../storage/keychain.js';\nimport { removeProfile, profileExists } from '../storage/configStore.js';\nimport { validateProviderName, validateProfileName } from '../utils/validator.js';\nimport { logger } from '../utils/logger.js';\nimport { handleError } from '../utils/errorHandler.js';\n\nexport const removeCommand = new Command('remove')\n .description('Remove a cloud provider profile')\n .argument('<provider>', 'Cloud provider name')\n .argument('<profile>', 'Profile name to remove')\n .action(async (providerName: string, profileName: string) => {\n try {\n const validProvider = validateProviderName(providerName);\n const validProfile = validateProfileName(profileName);\n getProvider(validProvider); // Ensure provider is registered\n\n if (!profileExists(validProvider, validProfile)) {\n logger.error(`Profile \"${validProfile}\" does not exist for provider \"${validProvider}\".`);\n process.exit(1);\n }\n\n const spinner = ora('Removing profile...').start();\n\n spinner.text = 'Deleting token from secure storage...';\n await deleteToken(validProvider, validProfile);\n\n spinner.text = 'Updating configuration...';\n removeProfile(validProvider, validProfile);\n\n spinner.succeed(`Profile \"${validProfile}\" removed from ${validProvider}.`);\n } catch (error: unknown) {\n handleError(error);\n }\n });\n","import { Command } from 'commander';\nimport ora from 'ora';\nimport { getProvider } from '../providers/provider.interface.js';\nimport { setCurrentProfile, profileExists, getCurrentProfile } from '../storage/configStore.js';\nimport { validateProviderName, validateProfileName } from '../utils/validator.js';\nimport { logger } from '../utils/logger.js';\nimport { handleError } from '../utils/errorHandler.js';\n\nexport const useCommand = new Command('use')\n .description('Set the current active profile for a provider')\n .argument('<provider>', 'Cloud provider name')\n .argument('<profile>', 'Profile name to activate')\n .action(async (providerName: string, profileName: string) => {\n try {\n const validProvider = validateProviderName(providerName);\n const validProfile = validateProfileName(profileName);\n const provider = getProvider(validProvider);\n\n if (!profileExists(validProvider, validProfile)) {\n logger.error(`Profile \"${validProfile}\" does not exist for provider \"${provider.name}\".`);\n process.exit(1);\n }\n\n const spinner = ora('Switching profile...').start();\n\n // Save current profile's auth state before switching\n const currentProfile = getCurrentProfile(validProvider);\n if (currentProfile && currentProfile !== validProfile && provider.captureAuth) {\n try {\n await provider.captureAuth(currentProfile);\n } catch {\n // Non-critical\n }\n }\n\n // Restore target profile's auth state\n if (provider.restoreAuth) {\n const restored = await provider.restoreAuth(validProfile);\n if (restored) {\n spinner.text = 'Auth credentials restored...';\n }\n }\n\n setCurrentProfile(validProvider, validProfile);\n spinner.succeed(`Now using profile \"${validProfile}\" for ${provider.name}.`);\n } catch (error: unknown) {\n handleError(error);\n }\n });\n","import { Command } from 'commander';\nimport { execa } from 'execa';\nimport { getProvider } from '../providers/provider.interface.js';\nimport { getToken } from '../storage/keychain.js';\nimport { profileExists, getCurrentProfile } from '../storage/configStore.js';\nimport { validateProviderName, validateProfileName } from '../utils/validator.js';\nimport { logger } from '../utils/logger.js';\nimport { handleError } from '../utils/errorHandler.js';\n\nexport const runCommand = new Command('run')\n .description('Run a command with a specific provider profile')\n .argument('<provider>', 'Cloud provider name')\n .argument('<profile>', 'Profile name to use')\n .argument('<args...>', 'Command arguments to pass to the provider CLI')\n .passThroughOptions()\n .allowUnknownOption()\n .action(async (providerName: string, profileName: string, args: string[]) => {\n try {\n const validProvider = validateProviderName(providerName);\n const validProfile = validateProfileName(profileName);\n const provider = getProvider(validProvider);\n\n if (!profileExists(validProvider, validProfile)) {\n logger.error(`Profile \"${validProfile}\" does not exist for provider \"${provider.name}\".`);\n process.exit(1);\n }\n\n logger.info(`Running as ${provider.name}/${validProfile}...`);\n\n // Save current auth state and swap to target profile\n const currentProfile = getCurrentProfile(validProvider);\n let swapped = false;\n\n if (provider.restoreAuth) {\n // Save current auth state first\n if (currentProfile && currentProfile !== validProfile && provider.captureAuth) {\n try {\n await provider.captureAuth(currentProfile);\n } catch {\n // Non-critical\n }\n }\n\n // Restore target profile's auth\n swapped = await provider.restoreAuth(validProfile);\n }\n\n try {\n if (swapped) {\n // Auth swapped — run natively (no env injection needed)\n const cliName = provider.getCliName();\n const result = await execa(cliName, args, {\n stdio: 'inherit',\n reject: false,\n });\n process.exitCode = result.exitCode ?? 0;\n } else {\n // Fallback: inject VERCEL_TOKEN (for providers without auth swap)\n const token = await getToken(validProvider, validProfile);\n if (!token) {\n logger.error(`No token found for ${provider.name}/${validProfile}. Try adding it again with \"orbit add\".`);\n process.exit(1);\n }\n\n const cliName = provider.getCliName();\n const envVar = provider.getEnvVar();\n\n const result = await execa(cliName, args, {\n env: {\n ...process.env,\n [envVar]: token,\n },\n stdio: 'inherit',\n reject: false,\n });\n process.exitCode = result.exitCode ?? 0;\n }\n } finally {\n // Restore previous profile's auth\n if (swapped && currentProfile && currentProfile !== validProfile && provider.restoreAuth) {\n try {\n await provider.restoreAuth(currentProfile);\n } catch {\n // Non-critical\n }\n }\n }\n\n process.exit(process.exitCode ?? 0);\n } catch (error: unknown) {\n handleError(error);\n }\n });\n","import { Command } from 'commander';\nimport { execa } from 'execa';\nimport { getProvider } from '../providers/provider.interface.js';\nimport { getToken } from '../storage/keychain.js';\nimport { getCurrentProfile } from '../storage/configStore.js';\nimport { validateProviderName } from '../utils/validator.js';\nimport { logger } from '../utils/logger.js';\nimport { handleError } from '../utils/errorHandler.js';\n\nexport const execCommand = new Command('exec')\n .description('Execute a command using the current active profile')\n .argument('<provider>', 'Cloud provider name')\n .argument('<args...>', 'Command arguments to pass to the provider CLI')\n .passThroughOptions()\n .allowUnknownOption()\n .action(async (providerName: string, args: string[]) => {\n try {\n const validProvider = validateProviderName(providerName);\n const provider = getProvider(validProvider);\n\n const currentProfile = getCurrentProfile(validProvider);\n\n if (!currentProfile) {\n logger.error(\n `No active profile set for ${provider.name}. Use \"orbit use ${validProvider} <profile>\" first.`,\n );\n process.exit(1);\n }\n\n // Ensure current profile's auth is active\n if (provider.restoreAuth) {\n await provider.restoreAuth(currentProfile);\n }\n\n const cliName = provider.getCliName();\n\n logger.info(`Running as ${provider.name}/${currentProfile}...`);\n\n // Try native execution first (auth.json is already swapped)\n if (provider.getAuthConfigPath?.()) {\n const result = await execa(cliName, args, {\n stdio: 'inherit',\n reject: false,\n });\n process.exit(result.exitCode ?? 0);\n }\n\n // Fallback: inject env var\n const token = await getToken(validProvider, currentProfile);\n\n if (!token) {\n logger.error(\n `No token found for ${provider.name}/${currentProfile}. Try adding it again with \"orbit add\".`,\n );\n process.exit(1);\n }\n\n const envVar = provider.getEnvVar();\n\n const result = await execa(cliName, args, {\n env: {\n ...process.env,\n [envVar]: token,\n },\n stdio: 'inherit',\n reject: false,\n });\n\n process.exit(result.exitCode ?? 0);\n } catch (error: unknown) {\n handleError(error);\n }\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadConfig } from '../storage/configStore.js';\nimport { logger } from '../utils/logger.js';\nimport { handleError } from '../utils/errorHandler.js';\n\nexport const currentCommand = new Command('current')\n .description('Show current active profiles')\n .action(() => {\n try {\n const config = loadConfig();\n const providers = Object.keys(config.providers);\n\n if (providers.length === 0) {\n logger.info('No profiles configured yet.');\n return;\n }\n\n let hasActive = false;\n\n for (const providerName of providers) {\n const providerConfig = config.providers[providerName];\n if (providerConfig?.current) {\n logger.success(\n `${chalk.bold(providerName)}: ${chalk.cyan(providerConfig.current)}`,\n );\n hasActive = true;\n }\n }\n\n if (!hasActive) {\n logger.info('No active profiles set. Use \"orbit use <provider> <profile>\" to set one.');\n }\n } catch (error: unknown) {\n handleError(error);\n }\n });\n"],"mappings":"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","names":["Command","fs","path","os","os","path","fs","execa","chalk","fs","fs","z","spinner","chalk","Command","chalk","Command","providers","chalk","Command","ora","Command","ora","Command","ora","Command","ora","Command","Command","Command","execa","Command","result","execa","Command","chalk","Command","providers","chalk","Command"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@appuo/orbit",
3
+ "version": "1.0.0",
4
+ "description": "A fully CLI-based multi-cloud profile manager",
5
+ "type": "module",
6
+ "bin": {
7
+ "orbit": "dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsup src/index.ts --format esm --dts",
16
+ "dev": "tsup src/index.ts --format esm --dts --watch",
17
+ "typecheck": "tsc --noEmit",
18
+ "prepublishOnly": "pnpm build"
19
+ },
20
+ "keywords": [
21
+ "cli",
22
+ "cloud",
23
+ "profile",
24
+ "manager",
25
+ "vercel",
26
+ "multi-cloud",
27
+ "credentials",
28
+ "orbit"
29
+ ],
30
+ "author": "Appuo",
31
+ "license": "MIT",
32
+ "engines": {
33
+ "node": ">=18"
34
+ },
35
+ "dependencies": {
36
+ "chalk": "^5.6.2",
37
+ "commander": "^14.0.3",
38
+ "execa": "^9.6.1",
39
+ "keytar": "^7.9.0",
40
+ "ora": "^9.3.0",
41
+ "zod": "^4.3.6"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^25.2.3",
45
+ "tsup": "^8.5.1",
46
+ "typescript": "^5.9.3"
47
+ }
48
+ }