@bagdock/cli 0.5.0 → 0.6.1

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 +209 -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,204 @@ 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 normalizeUrl(raw) {
2584
+ let url = raw.replace(/^['"]|['"]$/g, "").replace(/\/+$/, "");
2585
+ if (!/^https?:\/\//i.test(url)) {
2586
+ console.error(source_default.red(`Invalid URL (must start with http:// or https://): ${raw}`));
2587
+ process.exit(1);
2588
+ }
2589
+ return url;
2590
+ }
2591
+ function loadLocalEnv() {
2592
+ const envPath = join(process.cwd(), ".env.local");
2593
+ if (!existsSync(envPath)) {
2594
+ console.error(source_default.red("No .env.local found in"), source_default.bold(process.cwd()));
2595
+ console.error(source_default.dim("Create one with BAGDOCK_API_URL=https://your-ngrok-url"));
2596
+ process.exit(1);
2597
+ }
2598
+ const vars = {};
2599
+ const lines = readFileSync(envPath, "utf-8").split(`
2600
+ `);
2601
+ for (const line of lines) {
2602
+ const trimmed = line.trim();
2603
+ if (!trimmed || trimmed.startsWith("#"))
2604
+ continue;
2605
+ const eq = trimmed.indexOf("=");
2606
+ if (eq === -1)
2607
+ continue;
2608
+ vars[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim();
2609
+ }
2610
+ const apiUrl = vars["BAGDOCK_API_URL"];
2611
+ if (!apiUrl) {
2612
+ console.error(source_default.red("BAGDOCK_API_URL not found in .env.local"));
2613
+ console.error(source_default.dim("Add BAGDOCK_API_URL=https://your-ngrok-url to .env.local"));
2614
+ process.exit(1);
2615
+ }
2616
+ _apiBase = normalizeUrl(apiUrl);
2617
+ if (vars["BAGDOCK_DASHBOARD_URL"]) {
2618
+ _dashboardBase = normalizeUrl(vars["BAGDOCK_DASHBOARD_URL"]);
2619
+ }
2620
+ console.log(source_default.dim(`Using local env → ${_apiBase}`));
2621
+ }
2622
+ function setProfileOverride(name) {
2623
+ profileOverride = name;
2624
+ }
2625
+ function setEnvironmentOverride(env2) {
2626
+ envOverride = env2;
2627
+ }
2628
+ function getEnvironmentOverride() {
2629
+ return envOverride;
2630
+ }
2631
+ function ensureConfigDir() {
2632
+ if (!existsSync(CONFIG_DIR)) {
2633
+ mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
2634
+ }
2635
+ }
2636
+ function loadStore() {
2637
+ try {
2638
+ if (!existsSync(CREDENTIALS_FILE)) {
2639
+ return { activeProfile: "default", profiles: {} };
2640
+ }
2641
+ const raw = JSON.parse(readFileSync(CREDENTIALS_FILE, "utf-8"));
2642
+ if (raw.accessToken && !raw.profiles) {
2643
+ const migrated = {
2644
+ activeProfile: "default",
2645
+ profiles: { default: raw }
2646
+ };
2647
+ saveStore(migrated);
2648
+ return migrated;
2649
+ }
2650
+ return raw;
2651
+ } catch {
2652
+ return { activeProfile: "default", profiles: {} };
2653
+ }
2654
+ }
2655
+ function saveStore(store) {
2656
+ ensureConfigDir();
2657
+ writeFileSync(CREDENTIALS_FILE, JSON.stringify(store, null, 2), { mode: 384 });
2658
+ }
2659
+ function resolveProfile() {
2660
+ if (profileOverride)
2661
+ return profileOverride;
2662
+ if (process.env.BAGDOCK_PROFILE)
2663
+ return process.env.BAGDOCK_PROFILE;
2664
+ return loadStore().activeProfile;
2665
+ }
2666
+ function loadCredentials() {
2667
+ const store = loadStore();
2668
+ const name = resolveProfile();
2669
+ return store.profiles[name] ?? null;
2670
+ }
2671
+ function saveCredentials(creds, profileName) {
2672
+ const store = loadStore();
2673
+ const name = profileName ?? resolveProfile();
2674
+ store.profiles[name] = creds;
2675
+ if (!store.activeProfile || Object.keys(store.profiles).length === 1) {
2676
+ store.activeProfile = name;
2677
+ }
2678
+ saveStore(store);
2679
+ }
2680
+ function clearCredentials() {
2681
+ const store = loadStore();
2682
+ const name = resolveProfile();
2683
+ delete store.profiles[name];
2684
+ if (store.activeProfile === name) {
2685
+ const remaining = Object.keys(store.profiles);
2686
+ store.activeProfile = remaining[0] ?? "default";
2687
+ }
2688
+ saveStore(store);
2689
+ }
2690
+ function listProfiles() {
2691
+ const store = loadStore();
2692
+ return Object.entries(store.profiles).map(([name, creds]) => ({
2693
+ name,
2694
+ email: creds.email,
2695
+ operatorId: creds.operatorId,
2696
+ operatorSlug: creds.operatorSlug,
2697
+ environment: creds.environment,
2698
+ active: name === store.activeProfile
2699
+ }));
2700
+ }
2701
+ function switchProfile(name) {
2702
+ const store = loadStore();
2703
+ if (!store.profiles[name])
2704
+ return false;
2705
+ store.activeProfile = name;
2706
+ saveStore(store);
2707
+ return true;
2708
+ }
2709
+ function getActiveProfileName() {
2710
+ return resolveProfile();
2711
+ }
2712
+ function resolveLinkEnvironment() {
2713
+ try {
2714
+ const p = join(process.cwd(), ".bagdock", "link.json");
2715
+ if (!existsSync(p))
2716
+ return;
2717
+ const data = JSON.parse(readFileSync(p, "utf-8"));
2718
+ if (data.environment === "live" || data.environment === "test")
2719
+ return data.environment;
2720
+ return;
2721
+ } catch {
2722
+ return;
2723
+ }
2724
+ }
2725
+ function resolveEnvironment() {
2726
+ if (envOverride)
2727
+ return envOverride;
2728
+ const envVar = process.env.BAGDOCK_ENV;
2729
+ if (envVar === "test" || envVar === "live")
2730
+ return envVar;
2731
+ const creds = loadCredentials();
2732
+ return creds?.environment ?? "live";
2733
+ }
2734
+ function resolveOperatorSlug() {
2735
+ const envVar = process.env.BAGDOCK_OPERATOR;
2736
+ if (envVar)
2737
+ return envVar;
2738
+ const creds = loadCredentials();
2739
+ return creds?.operatorSlug;
2740
+ }
2741
+ function updateProfileContext(operatorId, operatorSlug, environment) {
2742
+ const creds = loadCredentials();
2743
+ if (!creds)
2744
+ return;
2745
+ saveCredentials({
2746
+ ...creds,
2747
+ operatorId,
2748
+ operatorSlug,
2749
+ environment
2750
+ });
2751
+ }
2752
+ function loadBagdockJson(dir) {
2753
+ const file = join(dir, "bagdock.json");
2754
+ if (!existsSync(file))
2755
+ return null;
2756
+ try {
2757
+ return JSON.parse(readFileSync(file, "utf-8"));
2758
+ } catch {
2759
+ return null;
2760
+ }
2761
+ }
2762
+ var CONFIG_DIR, CREDENTIALS_FILE, _apiBase, _dashboardBase, profileOverride, envOverride;
2763
+ var init_config = __esm(() => {
2764
+ init_source();
2765
+ CONFIG_DIR = join(homedir(), ".bagdock");
2766
+ CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
2767
+ _apiBase = process.env.BAGDOCK_API_URL ?? "https://api.bagdock.com";
2768
+ _dashboardBase = process.env.BAGDOCK_DASHBOARD_URL ?? "https://dashboard.bagdock.com";
2769
+ });
2770
+
2725
2771
  // src/output.ts
2726
2772
  function setOutputMode(opts) {
2727
2773
  quiet = !!opts.quiet;
@@ -3351,7 +3397,7 @@ async function login() {
3351
3397
  console.log(source_default.cyan(`
3352
3398
  Requesting device authorization...
3353
3399
  `));
3354
- const deviceRes = await fetch(`${API_BASE}/oauth2/device/authorize`, {
3400
+ const deviceRes = await fetch(`${getApiBase()}/oauth2/device/authorize`, {
3355
3401
  method: "POST",
3356
3402
  headers: { "Content-Type": "application/json" },
3357
3403
  body: JSON.stringify({ client_id: CLIENT_ID, scope: "developer:read developer:write" })
@@ -3373,7 +3419,7 @@ Requesting device authorization...
3373
3419
  const startedAt = Date.now();
3374
3420
  while (Date.now() - startedAt < MAX_POLL_DURATION_MS) {
3375
3421
  await sleep(pollInterval);
3376
- const tokenRes = await fetch(`${API_BASE}/oauth2/token`, {
3422
+ const tokenRes = await fetch(`${getApiBase()}/oauth2/token`, {
3377
3423
  method: "POST",
3378
3424
  headers: { "Content-Type": "application/json" },
3379
3425
  body: JSON.stringify({
@@ -3448,7 +3494,7 @@ async function whoami() {
3448
3494
  process.exit(1);
3449
3495
  }
3450
3496
  try {
3451
- const res = await fetch(`${API_BASE}/v1/auth/me`, {
3497
+ const res = await fetch(`${getApiBase()}/v1/auth/me`, {
3452
3498
  headers: { Authorization: `Bearer ${token}` }
3453
3499
  });
3454
3500
  if (!res.ok) {
@@ -3555,7 +3601,7 @@ Available profiles:
3555
3601
  }
3556
3602
  async function resolveOperatorAfterLogin(accessToken) {
3557
3603
  try {
3558
- const res = await fetch(`${API_BASE}/api/v1/me/operators`, {
3604
+ const res = await fetch(`${getApiBase()}/api/v1/me/operators`, {
3559
3605
  headers: { Authorization: `Bearer ${accessToken}` }
3560
3606
  });
3561
3607
  if (!res.ok)
@@ -3608,7 +3654,7 @@ async function apiFetch(path2, init2) {
3608
3654
  headers.set("X-Environment", env2);
3609
3655
  if (opSlug)
3610
3656
  headers.set("X-Operator-Slug", opSlug);
3611
- return fetch(`${API_BASE}${path2}`, { ...init2, headers });
3657
+ return fetch(`${getApiBase()}${path2}`, { ...init2, headers });
3612
3658
  }
3613
3659
  async function apiFetchJson(path2, method, body) {
3614
3660
  return apiFetch(path2, {
@@ -4062,7 +4108,7 @@ Deploying ${config.slug}@${config.version} → ${envLabel}
4062
4108
  compatibilityDate: config.compatibilityDate ?? "2024-09-23"
4063
4109
  }));
4064
4110
  try {
4065
- const res = await fetch(`${API_BASE}/api/v1/developer/apps/${config.slug}/deploy`, {
4111
+ const res = await fetch(`${getApiBase()}/api/v1/developer/apps/${config.slug}/deploy`, {
4066
4112
  method: "POST",
4067
4113
  headers: {
4068
4114
  Authorization: `Bearer ${token}`
@@ -4144,7 +4190,7 @@ async function submit() {
4144
4190
  Submitting ${source_default.bold(config.slug)} for marketplace review...
4145
4191
  `));
4146
4192
  try {
4147
- const res = await fetch(`${API_BASE}/api/v1/developer/apps/${config.slug}/submit`, {
4193
+ const res = await fetch(`${getApiBase()}/api/v1/developer/apps/${config.slug}/submit`, {
4148
4194
  method: "POST",
4149
4195
  headers: {
4150
4196
  Authorization: `Bearer ${token}`,
@@ -4503,7 +4549,7 @@ async function open2(slugArg) {
4503
4549
  return;
4504
4550
  }
4505
4551
  const envSegment = env2 === "test" ? "/test" : "";
4506
- const url = `${DASHBOARD_BASE}/${operatorSlug}${envSegment}/developer/apps/${slug}`;
4552
+ const url = `${getDashboardBase()}/${operatorSlug}${envSegment}/developer/apps/${slug}`;
4507
4553
  if (isJsonMode()) {
4508
4554
  outputSuccess({ url, slug, operator: operatorSlug, environment: env2 });
4509
4555
  return;
@@ -5238,9 +5284,11 @@ function toPascalCase(s) {
5238
5284
  init_output();
5239
5285
  init_config();
5240
5286
  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) => {
5287
+ 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
5288
  const opts = program2.opts();
5243
5289
  setOutputMode({ json: opts.json, quiet: opts.quiet });
5290
+ if (opts.ngrok)
5291
+ loadLocalEnv();
5244
5292
  if (opts.apiKey)
5245
5293
  setApiKeyOverride(opts.apiKey);
5246
5294
  if (opts.profile)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bagdock/cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
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
  }