@bagdock/cli 0.5.0 → 0.6.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 (2) hide show
  1. package/dist/bagdock.js +201 -161
  2. package/package.json +2 -2
package/dist/bagdock.js CHANGED
@@ -2081,158 +2081,6 @@ var require_commander = __commonJS((exports) => {
2081
2081
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2082
2082
  });
2083
2083
 
2084
- // src/config.ts
2085
- import { homedir } from "os";
2086
- import { join } from "path";
2087
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2088
- function setProfileOverride(name) {
2089
- profileOverride = name;
2090
- }
2091
- function setEnvironmentOverride(env) {
2092
- envOverride = env;
2093
- }
2094
- function getEnvironmentOverride() {
2095
- return envOverride;
2096
- }
2097
- function ensureConfigDir() {
2098
- if (!existsSync(CONFIG_DIR)) {
2099
- mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
2100
- }
2101
- }
2102
- function loadStore() {
2103
- try {
2104
- if (!existsSync(CREDENTIALS_FILE)) {
2105
- return { activeProfile: "default", profiles: {} };
2106
- }
2107
- const raw = JSON.parse(readFileSync(CREDENTIALS_FILE, "utf-8"));
2108
- if (raw.accessToken && !raw.profiles) {
2109
- const migrated = {
2110
- activeProfile: "default",
2111
- profiles: { default: raw }
2112
- };
2113
- saveStore(migrated);
2114
- return migrated;
2115
- }
2116
- return raw;
2117
- } catch {
2118
- return { activeProfile: "default", profiles: {} };
2119
- }
2120
- }
2121
- function saveStore(store) {
2122
- ensureConfigDir();
2123
- writeFileSync(CREDENTIALS_FILE, JSON.stringify(store, null, 2), { mode: 384 });
2124
- }
2125
- function resolveProfile() {
2126
- if (profileOverride)
2127
- return profileOverride;
2128
- if (process.env.BAGDOCK_PROFILE)
2129
- return process.env.BAGDOCK_PROFILE;
2130
- return loadStore().activeProfile;
2131
- }
2132
- function loadCredentials() {
2133
- const store = loadStore();
2134
- const name = resolveProfile();
2135
- return store.profiles[name] ?? null;
2136
- }
2137
- function saveCredentials(creds, profileName) {
2138
- const store = loadStore();
2139
- const name = profileName ?? resolveProfile();
2140
- store.profiles[name] = creds;
2141
- if (!store.activeProfile || Object.keys(store.profiles).length === 1) {
2142
- store.activeProfile = name;
2143
- }
2144
- saveStore(store);
2145
- }
2146
- function clearCredentials() {
2147
- const store = loadStore();
2148
- const name = resolveProfile();
2149
- delete store.profiles[name];
2150
- if (store.activeProfile === name) {
2151
- const remaining = Object.keys(store.profiles);
2152
- store.activeProfile = remaining[0] ?? "default";
2153
- }
2154
- saveStore(store);
2155
- }
2156
- function listProfiles() {
2157
- const store = loadStore();
2158
- return Object.entries(store.profiles).map(([name, creds]) => ({
2159
- name,
2160
- email: creds.email,
2161
- operatorId: creds.operatorId,
2162
- operatorSlug: creds.operatorSlug,
2163
- environment: creds.environment,
2164
- active: name === store.activeProfile
2165
- }));
2166
- }
2167
- function switchProfile(name) {
2168
- const store = loadStore();
2169
- if (!store.profiles[name])
2170
- return false;
2171
- store.activeProfile = name;
2172
- saveStore(store);
2173
- return true;
2174
- }
2175
- function getActiveProfileName() {
2176
- return resolveProfile();
2177
- }
2178
- function resolveLinkEnvironment() {
2179
- try {
2180
- const p = join(process.cwd(), ".bagdock", "link.json");
2181
- if (!existsSync(p))
2182
- return;
2183
- const data = JSON.parse(readFileSync(p, "utf-8"));
2184
- if (data.environment === "live" || data.environment === "test")
2185
- return data.environment;
2186
- return;
2187
- } catch {
2188
- return;
2189
- }
2190
- }
2191
- function resolveEnvironment() {
2192
- if (envOverride)
2193
- return envOverride;
2194
- const envVar = process.env.BAGDOCK_ENV;
2195
- if (envVar === "test" || envVar === "live")
2196
- return envVar;
2197
- const creds = loadCredentials();
2198
- return creds?.environment ?? "live";
2199
- }
2200
- function resolveOperatorSlug() {
2201
- const envVar = process.env.BAGDOCK_OPERATOR;
2202
- if (envVar)
2203
- return envVar;
2204
- const creds = loadCredentials();
2205
- return creds?.operatorSlug;
2206
- }
2207
- function updateProfileContext(operatorId, operatorSlug, environment) {
2208
- const creds = loadCredentials();
2209
- if (!creds)
2210
- return;
2211
- saveCredentials({
2212
- ...creds,
2213
- operatorId,
2214
- operatorSlug,
2215
- environment
2216
- });
2217
- }
2218
- function loadBagdockJson(dir) {
2219
- const file = join(dir, "bagdock.json");
2220
- if (!existsSync(file))
2221
- return null;
2222
- try {
2223
- return JSON.parse(readFileSync(file, "utf-8"));
2224
- } catch {
2225
- return null;
2226
- }
2227
- }
2228
- var CONFIG_DIR, CREDENTIALS_FILE, API_BASE, DASHBOARD_BASE, profileOverride, envOverride;
2229
- var init_config = __esm(() => {
2230
- CONFIG_DIR = join(homedir(), ".bagdock");
2231
- CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
2232
- API_BASE = process.env.BAGDOCK_API_URL ?? "https://api.bagdock.com";
2233
- DASHBOARD_BASE = process.env.BAGDOCK_DASHBOARD_URL ?? "https://dashboard.bagdock.com";
2234
- });
2235
-
2236
2084
  // node_modules/chalk/source/vendor/ansi-styles/index.js
2237
2085
  function assembleStyles() {
2238
2086
  const codes = new Map;
@@ -2722,6 +2570,196 @@ var init_source = __esm(() => {
2722
2570
  source_default = chalk;
2723
2571
  });
2724
2572
 
2573
+ // src/config.ts
2574
+ import { homedir } from "os";
2575
+ import { join } from "path";
2576
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2577
+ function getApiBase() {
2578
+ return _apiBase;
2579
+ }
2580
+ function getDashboardBase() {
2581
+ return _dashboardBase;
2582
+ }
2583
+ function loadLocalEnv() {
2584
+ const envPath = join(process.cwd(), ".env.local");
2585
+ if (!existsSync(envPath)) {
2586
+ console.error(source_default.red("No .env.local found in"), source_default.bold(process.cwd()));
2587
+ console.error(source_default.dim("Create one with BAGDOCK_API_URL=https://your-ngrok-url"));
2588
+ process.exit(1);
2589
+ }
2590
+ const vars = {};
2591
+ const lines = readFileSync(envPath, "utf-8").split(`
2592
+ `);
2593
+ for (const line of lines) {
2594
+ const trimmed = line.trim();
2595
+ if (!trimmed || trimmed.startsWith("#"))
2596
+ continue;
2597
+ const eq = trimmed.indexOf("=");
2598
+ if (eq === -1)
2599
+ continue;
2600
+ vars[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim();
2601
+ }
2602
+ const apiUrl = vars["BAGDOCK_API_URL"];
2603
+ if (!apiUrl) {
2604
+ console.error(source_default.red("BAGDOCK_API_URL not found in .env.local"));
2605
+ console.error(source_default.dim("Add BAGDOCK_API_URL=https://your-ngrok-url to .env.local"));
2606
+ process.exit(1);
2607
+ }
2608
+ _apiBase = apiUrl;
2609
+ if (vars["BAGDOCK_DASHBOARD_URL"]) {
2610
+ _dashboardBase = vars["BAGDOCK_DASHBOARD_URL"];
2611
+ }
2612
+ console.log(source_default.dim(`Using local env → ${_apiBase}`));
2613
+ }
2614
+ function setProfileOverride(name) {
2615
+ profileOverride = name;
2616
+ }
2617
+ function setEnvironmentOverride(env2) {
2618
+ envOverride = env2;
2619
+ }
2620
+ function getEnvironmentOverride() {
2621
+ return envOverride;
2622
+ }
2623
+ function ensureConfigDir() {
2624
+ if (!existsSync(CONFIG_DIR)) {
2625
+ mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
2626
+ }
2627
+ }
2628
+ function loadStore() {
2629
+ try {
2630
+ if (!existsSync(CREDENTIALS_FILE)) {
2631
+ return { activeProfile: "default", profiles: {} };
2632
+ }
2633
+ const raw = JSON.parse(readFileSync(CREDENTIALS_FILE, "utf-8"));
2634
+ if (raw.accessToken && !raw.profiles) {
2635
+ const migrated = {
2636
+ activeProfile: "default",
2637
+ profiles: { default: raw }
2638
+ };
2639
+ saveStore(migrated);
2640
+ return migrated;
2641
+ }
2642
+ return raw;
2643
+ } catch {
2644
+ return { activeProfile: "default", profiles: {} };
2645
+ }
2646
+ }
2647
+ function saveStore(store) {
2648
+ ensureConfigDir();
2649
+ writeFileSync(CREDENTIALS_FILE, JSON.stringify(store, null, 2), { mode: 384 });
2650
+ }
2651
+ function resolveProfile() {
2652
+ if (profileOverride)
2653
+ return profileOverride;
2654
+ if (process.env.BAGDOCK_PROFILE)
2655
+ return process.env.BAGDOCK_PROFILE;
2656
+ return loadStore().activeProfile;
2657
+ }
2658
+ function loadCredentials() {
2659
+ const store = loadStore();
2660
+ const name = resolveProfile();
2661
+ return store.profiles[name] ?? null;
2662
+ }
2663
+ function saveCredentials(creds, profileName) {
2664
+ const store = loadStore();
2665
+ const name = profileName ?? resolveProfile();
2666
+ store.profiles[name] = creds;
2667
+ if (!store.activeProfile || Object.keys(store.profiles).length === 1) {
2668
+ store.activeProfile = name;
2669
+ }
2670
+ saveStore(store);
2671
+ }
2672
+ function clearCredentials() {
2673
+ const store = loadStore();
2674
+ const name = resolveProfile();
2675
+ delete store.profiles[name];
2676
+ if (store.activeProfile === name) {
2677
+ const remaining = Object.keys(store.profiles);
2678
+ store.activeProfile = remaining[0] ?? "default";
2679
+ }
2680
+ saveStore(store);
2681
+ }
2682
+ function listProfiles() {
2683
+ const store = loadStore();
2684
+ return Object.entries(store.profiles).map(([name, creds]) => ({
2685
+ name,
2686
+ email: creds.email,
2687
+ operatorId: creds.operatorId,
2688
+ operatorSlug: creds.operatorSlug,
2689
+ environment: creds.environment,
2690
+ active: name === store.activeProfile
2691
+ }));
2692
+ }
2693
+ function switchProfile(name) {
2694
+ const store = loadStore();
2695
+ if (!store.profiles[name])
2696
+ return false;
2697
+ store.activeProfile = name;
2698
+ saveStore(store);
2699
+ return true;
2700
+ }
2701
+ function getActiveProfileName() {
2702
+ return resolveProfile();
2703
+ }
2704
+ function resolveLinkEnvironment() {
2705
+ try {
2706
+ const p = join(process.cwd(), ".bagdock", "link.json");
2707
+ if (!existsSync(p))
2708
+ return;
2709
+ const data = JSON.parse(readFileSync(p, "utf-8"));
2710
+ if (data.environment === "live" || data.environment === "test")
2711
+ return data.environment;
2712
+ return;
2713
+ } catch {
2714
+ return;
2715
+ }
2716
+ }
2717
+ function resolveEnvironment() {
2718
+ if (envOverride)
2719
+ return envOverride;
2720
+ const envVar = process.env.BAGDOCK_ENV;
2721
+ if (envVar === "test" || envVar === "live")
2722
+ return envVar;
2723
+ const creds = loadCredentials();
2724
+ return creds?.environment ?? "live";
2725
+ }
2726
+ function resolveOperatorSlug() {
2727
+ const envVar = process.env.BAGDOCK_OPERATOR;
2728
+ if (envVar)
2729
+ return envVar;
2730
+ const creds = loadCredentials();
2731
+ return creds?.operatorSlug;
2732
+ }
2733
+ function updateProfileContext(operatorId, operatorSlug, environment) {
2734
+ const creds = loadCredentials();
2735
+ if (!creds)
2736
+ return;
2737
+ saveCredentials({
2738
+ ...creds,
2739
+ operatorId,
2740
+ operatorSlug,
2741
+ environment
2742
+ });
2743
+ }
2744
+ function loadBagdockJson(dir) {
2745
+ const file = join(dir, "bagdock.json");
2746
+ if (!existsSync(file))
2747
+ return null;
2748
+ try {
2749
+ return JSON.parse(readFileSync(file, "utf-8"));
2750
+ } catch {
2751
+ return null;
2752
+ }
2753
+ }
2754
+ var CONFIG_DIR, CREDENTIALS_FILE, _apiBase, _dashboardBase, profileOverride, envOverride;
2755
+ var init_config = __esm(() => {
2756
+ init_source();
2757
+ CONFIG_DIR = join(homedir(), ".bagdock");
2758
+ CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
2759
+ _apiBase = process.env.BAGDOCK_API_URL ?? "https://api.bagdock.com";
2760
+ _dashboardBase = process.env.BAGDOCK_DASHBOARD_URL ?? "https://dashboard.bagdock.com";
2761
+ });
2762
+
2725
2763
  // src/output.ts
2726
2764
  function setOutputMode(opts) {
2727
2765
  quiet = !!opts.quiet;
@@ -3351,7 +3389,7 @@ async function login() {
3351
3389
  console.log(source_default.cyan(`
3352
3390
  Requesting device authorization...
3353
3391
  `));
3354
- const deviceRes = await fetch(`${API_BASE}/oauth2/device/authorize`, {
3392
+ const deviceRes = await fetch(`${getApiBase()}/oauth2/device/authorize`, {
3355
3393
  method: "POST",
3356
3394
  headers: { "Content-Type": "application/json" },
3357
3395
  body: JSON.stringify({ client_id: CLIENT_ID, scope: "developer:read developer:write" })
@@ -3373,7 +3411,7 @@ Requesting device authorization...
3373
3411
  const startedAt = Date.now();
3374
3412
  while (Date.now() - startedAt < MAX_POLL_DURATION_MS) {
3375
3413
  await sleep(pollInterval);
3376
- const tokenRes = await fetch(`${API_BASE}/oauth2/token`, {
3414
+ const tokenRes = await fetch(`${getApiBase()}/oauth2/token`, {
3377
3415
  method: "POST",
3378
3416
  headers: { "Content-Type": "application/json" },
3379
3417
  body: JSON.stringify({
@@ -3448,7 +3486,7 @@ async function whoami() {
3448
3486
  process.exit(1);
3449
3487
  }
3450
3488
  try {
3451
- const res = await fetch(`${API_BASE}/v1/auth/me`, {
3489
+ const res = await fetch(`${getApiBase()}/v1/auth/me`, {
3452
3490
  headers: { Authorization: `Bearer ${token}` }
3453
3491
  });
3454
3492
  if (!res.ok) {
@@ -3555,7 +3593,7 @@ Available profiles:
3555
3593
  }
3556
3594
  async function resolveOperatorAfterLogin(accessToken) {
3557
3595
  try {
3558
- const res = await fetch(`${API_BASE}/api/v1/me/operators`, {
3596
+ const res = await fetch(`${getApiBase()}/api/v1/me/operators`, {
3559
3597
  headers: { Authorization: `Bearer ${accessToken}` }
3560
3598
  });
3561
3599
  if (!res.ok)
@@ -3608,7 +3646,7 @@ async function apiFetch(path2, init2) {
3608
3646
  headers.set("X-Environment", env2);
3609
3647
  if (opSlug)
3610
3648
  headers.set("X-Operator-Slug", opSlug);
3611
- return fetch(`${API_BASE}${path2}`, { ...init2, headers });
3649
+ return fetch(`${getApiBase()}${path2}`, { ...init2, headers });
3612
3650
  }
3613
3651
  async function apiFetchJson(path2, method, body) {
3614
3652
  return apiFetch(path2, {
@@ -4062,7 +4100,7 @@ Deploying ${config.slug}@${config.version} → ${envLabel}
4062
4100
  compatibilityDate: config.compatibilityDate ?? "2024-09-23"
4063
4101
  }));
4064
4102
  try {
4065
- const res = await fetch(`${API_BASE}/api/v1/developer/apps/${config.slug}/deploy`, {
4103
+ const res = await fetch(`${getApiBase()}/api/v1/developer/apps/${config.slug}/deploy`, {
4066
4104
  method: "POST",
4067
4105
  headers: {
4068
4106
  Authorization: `Bearer ${token}`
@@ -4144,7 +4182,7 @@ async function submit() {
4144
4182
  Submitting ${source_default.bold(config.slug)} for marketplace review...
4145
4183
  `));
4146
4184
  try {
4147
- const res = await fetch(`${API_BASE}/api/v1/developer/apps/${config.slug}/submit`, {
4185
+ const res = await fetch(`${getApiBase()}/api/v1/developer/apps/${config.slug}/submit`, {
4148
4186
  method: "POST",
4149
4187
  headers: {
4150
4188
  Authorization: `Bearer ${token}`,
@@ -4503,7 +4541,7 @@ async function open2(slugArg) {
4503
4541
  return;
4504
4542
  }
4505
4543
  const envSegment = env2 === "test" ? "/test" : "";
4506
- const url = `${DASHBOARD_BASE}/${operatorSlug}${envSegment}/developer/apps/${slug}`;
4544
+ const url = `${getDashboardBase()}/${operatorSlug}${envSegment}/developer/apps/${slug}`;
4507
4545
  if (isJsonMode()) {
4508
4546
  outputSuccess({ url, slug, operator: operatorSlug, environment: env2 });
4509
4547
  return;
@@ -5238,8 +5276,10 @@ function toPascalCase(s) {
5238
5276
  init_output();
5239
5277
  init_config();
5240
5278
  var program2 = new Command;
5241
- program2.name("bagdock").description("Bagdock developer CLI — built for humans, AI agents, and CI/CD pipelines").version("0.5.0").option("--json", "Force JSON output (auto-enabled in non-TTY)").option("-q, --quiet", "Suppress status messages (implies --json)").option("--api-key <key>", "API key to use for this invocation").option("-p, --profile <name>", "Profile to use (overrides BAGDOCK_PROFILE)").option("--env <environment>", "Override environment for this invocation (live, test)").hook("preAction", (_thisCommand, actionCommand) => {
5279
+ program2.name("bagdock").description("Bagdock developer CLI — built for humans, AI agents, and CI/CD pipelines").version("0.6.0").option("--json", "Force JSON output (auto-enabled in non-TTY)").option("-q, --quiet", "Suppress status messages (implies --json)").option("--api-key <key>", "API key to use for this invocation").option("-p, --profile <name>", "Profile to use (overrides BAGDOCK_PROFILE)").option("--env <environment>", "Override environment for this invocation (live, test)").option("--ngrok", "Use API URLs from .env.local (for ngrok tunnels)").hook("preAction", (_thisCommand, actionCommand) => {
5242
5280
  const opts = program2.opts();
5281
+ if (opts.ngrok)
5282
+ loadLocalEnv();
5243
5283
  setOutputMode({ json: opts.json, quiet: opts.quiet });
5244
5284
  if (opts.apiKey)
5245
5285
  setApiKeyOverride(opts.apiKey);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bagdock/cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Bagdock developer CLI — build, test, and deploy apps and edges on the Bagdock platform",
5
5
  "keywords": [
6
6
  "bagdock",
@@ -53,7 +53,7 @@
53
53
  "open": "^10.1.0"
54
54
  },
55
55
  "devDependencies": {
56
- "@types/bun": "latest",
56
+ "@types/bun": "^1.3.10",
57
57
  "typescript": "^5.3.3",
58
58
  "vitest": "^3.2.4"
59
59
  }