@autoposting.ai/cli 0.3.1 → 0.3.2

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/dist/cli.cjs CHANGED
@@ -42,11 +42,11 @@ function createError(status, body) {
42
42
  if (status >= 500) return new ServerError(message, status, code);
43
43
  return new AutopostingError(message, status, code);
44
44
  }
45
- var VERSION, AutopostingError, AuthenticationError, ScopeError, NotFoundError, ValidationError, RateLimitError, ServerError, Resource, AgentsResource, BillingResource, BrandsResource, CarouselsResource, ClipsResource, PostsResource, KbResource, IdeasResource, UsageResource, WebhooksResource, WorkspacesResource, Autoposting;
45
+ var VERSION, AutopostingError, AuthenticationError, ScopeError, NotFoundError, ValidationError, RateLimitError, ServerError, Resource, AgentsResource, BillingResource, BrandsResource, CarouselsResource, ClipsResource, PostsResource, KbResource, IdeasResource, UsageResource, WebhooksResource, WorkspacesResource, IDEMPOTENT_METHODS, RETRYABLE_STATUS, sleep, Autoposting;
46
46
  var init_dist = __esm({
47
47
  "../sdk/dist/index.mjs"() {
48
48
  "use strict";
49
- VERSION = "0.3.1";
49
+ VERSION = "0.3.2";
50
50
  AutopostingError = class extends Error {
51
51
  status;
52
52
  code;
@@ -324,9 +324,17 @@ var init_dist = __esm({
324
324
  }
325
325
  /**
326
326
  * GET /orgs — backend returns `{ organizations, activeOrgId }`, not a bare array.
327
- * NOTE: this route is session-only (better-auth session); an API key receives 401.
327
+ * This route is session-only (better-auth session); an API key receives a bare 401,
328
+ * so guard up front with accurate guidance instead of an opaque "Unauthorized".
328
329
  */
329
330
  list() {
331
+ if (this.client.authSource === "api-key") {
332
+ return Promise.reject(
333
+ new Error(
334
+ "Listing workspaces requires session auth. An API key is scoped to a single workspace and cannot list organizations \u2014 manage workspaces from the web dashboard."
335
+ )
336
+ );
337
+ }
330
338
  return this.get("/orgs");
331
339
  }
332
340
  switchWorkspace(id) {
@@ -340,6 +348,9 @@ var init_dist = __esm({
340
348
  return this.client.request("PUT", "/orgs/active", { organizationId: id });
341
349
  }
342
350
  };
351
+ IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "PUT", "DELETE"]);
352
+ RETRYABLE_STATUS = /* @__PURE__ */ new Set([500, 502, 503, 504]);
353
+ sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
343
354
  Autoposting = class {
344
355
  /** @internal Not part of the public API — use SDK methods to make requests. */
345
356
  _apiKey;
@@ -348,6 +359,8 @@ var init_dist = __esm({
348
359
  extraHeaders;
349
360
  /** Indicates how the client was authenticated; used by WorkspacesResource. */
350
361
  authSource;
362
+ maxRetries;
363
+ retryBaseMs;
351
364
  agents;
352
365
  billing;
353
366
  brands;
@@ -371,6 +384,8 @@ var init_dist = __esm({
371
384
  this.timeout = config.timeout ?? 3e4;
372
385
  this.extraHeaders = config.headers ?? {};
373
386
  this.authSource = config.authSource ?? "api-key";
387
+ this.maxRetries = Math.max(0, config.maxRetries ?? 2);
388
+ this.retryBaseMs = Math.max(0, config.retryBaseMs ?? 300);
374
389
  this.agents = new AgentsResource(this);
375
390
  this.billing = new BillingResource(this);
376
391
  this.brands = new BrandsResource(this);
@@ -383,7 +398,42 @@ var init_dist = __esm({
383
398
  this.webhooks = new WebhooksResource(this);
384
399
  this.workspaces = new WorkspacesResource(this);
385
400
  }
401
+ /**
402
+ * GET /auth/profile — resolve the server-side identity behind the current credential.
403
+ * Validates the key (401 on reject) and returns who/what it's scoped to.
404
+ */
405
+ getProfile() {
406
+ return this.request("GET", "/auth/profile");
407
+ }
408
+ /**
409
+ * Public entry point. Retries idempotent requests (GET/PUT/DELETE) on transient
410
+ * failures — network errors, timeouts, and 5xx — with exponential backoff + jitter.
411
+ * Non-idempotent methods (POST/PATCH) are never retried, to avoid duplicate side effects.
412
+ */
386
413
  async request(method, path2, body, query) {
414
+ let lastErr;
415
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
416
+ if (attempt > 0) {
417
+ const backoff = this.retryBaseMs * 2 ** (attempt - 1);
418
+ await sleep(backoff + Math.floor(Math.random() * this.retryBaseMs));
419
+ }
420
+ try {
421
+ return await this._send(method, path2, body, query);
422
+ } catch (err) {
423
+ lastErr = err;
424
+ if (attempt < this.maxRetries && this.isRetryable(method, err)) continue;
425
+ throw err;
426
+ }
427
+ }
428
+ throw lastErr;
429
+ }
430
+ isRetryable(method, err) {
431
+ if (!IDEMPOTENT_METHODS.has(method)) return false;
432
+ if (!(err instanceof AutopostingError)) return false;
433
+ if (err.code === "NETWORK_ERROR" || err.code === "TIMEOUT") return true;
434
+ return RETRYABLE_STATUS.has(err.status);
435
+ }
436
+ async _send(method, path2, body, query) {
387
437
  let url = `${this.baseUrl}${path2}`;
388
438
  if (query && Object.keys(query).length > 0) {
389
439
  const params = new URLSearchParams();
@@ -1792,7 +1842,7 @@ var OraSpinner = class {
1792
1842
  if (this.instance) {
1793
1843
  this.instance.fail(message);
1794
1844
  this.instance = null;
1795
- } else {
1845
+ } else if (message) {
1796
1846
  process.stderr.write(`${message}
1797
1847
  `);
1798
1848
  }
@@ -1809,6 +1859,10 @@ var Printer = class {
1809
1859
  this.mode = mode;
1810
1860
  }
1811
1861
  mode;
1862
+ /** True only for human-readable output, where extra hint lines are safe to print. */
1863
+ isTty() {
1864
+ return this.mode === "tty";
1865
+ }
1812
1866
  log(data) {
1813
1867
  const out = formatOutput(data, this.mode);
1814
1868
  if (out !== "") console.log(out);
@@ -1901,7 +1955,7 @@ function createAgentsCommand() {
1901
1955
  }));
1902
1956
  printer.table(rows, ["id", "name", "type", "brand", "frequency", "enabled"]);
1903
1957
  } catch (err) {
1904
- spinner.stop();
1958
+ spinner.fail();
1905
1959
  printer.error(err);
1906
1960
  process.exit(resolveExitCode(err));
1907
1961
  }
@@ -1917,7 +1971,7 @@ function createAgentsCommand() {
1917
1971
  spinner.stop();
1918
1972
  printer.log(agent);
1919
1973
  } catch (err) {
1920
- spinner.stop();
1974
+ spinner.fail();
1921
1975
  printer.error(err);
1922
1976
  process.exit(resolveExitCode(err));
1923
1977
  }
@@ -1943,7 +1997,7 @@ function createAgentsCommand() {
1943
1997
  spinner.stop();
1944
1998
  printer.log(agent);
1945
1999
  } catch (err) {
1946
- spinner.stop();
2000
+ spinner.fail();
1947
2001
  printer.error(err);
1948
2002
  process.exit(resolveExitCode(err));
1949
2003
  }
@@ -1967,7 +2021,7 @@ function createAgentsCommand() {
1967
2021
  spinner.stop();
1968
2022
  printer.log(agent);
1969
2023
  } catch (err) {
1970
- spinner.stop();
2024
+ spinner.fail();
1971
2025
  printer.error(err);
1972
2026
  process.exit(resolveExitCode(err));
1973
2027
  }
@@ -1988,7 +2042,7 @@ function createAgentsCommand() {
1988
2042
  spinner.stop();
1989
2043
  printer.log(`Agent "${id}" deleted.`);
1990
2044
  } catch (err) {
1991
- spinner.stop();
2045
+ spinner.fail();
1992
2046
  printer.error(err);
1993
2047
  process.exit(resolveExitCode(err));
1994
2048
  }
@@ -2004,7 +2058,7 @@ function createAgentsCommand() {
2004
2058
  spinner.stop();
2005
2059
  printer.log({ runId: queued.runId, status: queued.status });
2006
2060
  } catch (err) {
2007
- spinner.stop();
2061
+ spinner.fail();
2008
2062
  printer.error(err);
2009
2063
  process.exit(resolveExitCode(err));
2010
2064
  }
@@ -2020,7 +2074,7 @@ function createAgentsCommand() {
2020
2074
  spinner.stop();
2021
2075
  printer.log(agent);
2022
2076
  } catch (err) {
2023
- spinner.stop();
2077
+ spinner.fail();
2024
2078
  printer.error(err);
2025
2079
  process.exit(resolveExitCode(err));
2026
2080
  }
@@ -2042,7 +2096,7 @@ function createAgentsCommand() {
2042
2096
  }));
2043
2097
  printer.table(rows, ["id", "status", "output", "createdAt"]);
2044
2098
  } catch (err) {
2045
- spinner.stop();
2099
+ spinner.fail();
2046
2100
  printer.error(err);
2047
2101
  process.exit(resolveExitCode(err));
2048
2102
  }
@@ -2287,7 +2341,7 @@ function createBillingCommand() {
2287
2341
  ["plan", "status", "cycle", "accounts", "credits", "renews", "trial ends"]
2288
2342
  );
2289
2343
  } catch (err) {
2290
- spinner.stop();
2344
+ spinner.fail();
2291
2345
  printer.error(err);
2292
2346
  process.exit(resolveExitCode2(err));
2293
2347
  }
@@ -2320,7 +2374,7 @@ function createBillingCommand() {
2320
2374
  printer.table(usageRows, ["date", "description", "amount", "type"]);
2321
2375
  }
2322
2376
  } catch (err) {
2323
- spinner.stop();
2377
+ spinner.fail();
2324
2378
  printer.error(err);
2325
2379
  process.exit(resolveExitCode2(err));
2326
2380
  }
@@ -2331,6 +2385,24 @@ function createBillingCommand() {
2331
2385
  // src/commands/brands.ts
2332
2386
  var import_commander4 = require("commander");
2333
2387
  init_dist();
2388
+ function tokenStatus(c, now = Date.now()) {
2389
+ if (!c.connected) return "\u2014";
2390
+ if (c.refreshError) return "expired";
2391
+ if (c.expiresAt) {
2392
+ const expMs = Date.parse(c.expiresAt);
2393
+ if (Number.isNaN(expMs) || expMs <= now) return "expired";
2394
+ }
2395
+ return "ok";
2396
+ }
2397
+ function buildAuthStatusRow(c, now = Date.now()) {
2398
+ return {
2399
+ platform: c.platform,
2400
+ connected: c.connected ? "yes" : "no",
2401
+ username: c.platformUsername ?? "\u2014",
2402
+ "token status": tokenStatus(c, now),
2403
+ expires: c.expiresAt ?? "\u2014"
2404
+ };
2405
+ }
2334
2406
  function createBrandsCommand() {
2335
2407
  const brands = new import_commander4.Command("brands").description("Manage brands");
2336
2408
  brands.command("list").description("List all brands").action(async (_opts, cmd) => {
@@ -2350,7 +2422,7 @@ function createBrandsCommand() {
2350
2422
  }));
2351
2423
  printer.table(rows, ["slug", "name", "platforms", "timezone"]);
2352
2424
  } catch (err) {
2353
- spinner.stop();
2425
+ spinner.fail();
2354
2426
  printer.error(err);
2355
2427
  process.exit(exitCodeFromError(err));
2356
2428
  }
@@ -2366,7 +2438,7 @@ function createBrandsCommand() {
2366
2438
  spinner.stop();
2367
2439
  printer.log(brand);
2368
2440
  } catch (err) {
2369
- spinner.stop();
2441
+ spinner.fail();
2370
2442
  printer.error(err);
2371
2443
  process.exit(exitCodeFromError(err));
2372
2444
  }
@@ -2385,7 +2457,7 @@ function createBrandsCommand() {
2385
2457
  spinner.stop();
2386
2458
  printer.log(brand);
2387
2459
  } catch (err) {
2388
- spinner.stop();
2460
+ spinner.fail();
2389
2461
  printer.error(err);
2390
2462
  process.exit(exitCodeFromError(err));
2391
2463
  }
@@ -2404,7 +2476,7 @@ function createBrandsCommand() {
2404
2476
  spinner.stop();
2405
2477
  printer.log(brand);
2406
2478
  } catch (err) {
2407
- spinner.stop();
2479
+ spinner.fail();
2408
2480
  printer.error(err);
2409
2481
  process.exit(exitCodeFromError(err));
2410
2482
  }
@@ -2424,7 +2496,7 @@ function createBrandsCommand() {
2424
2496
  spinner.stop();
2425
2497
  printer.log(`Brand "${slug}" deleted.`);
2426
2498
  } catch (err) {
2427
- spinner.stop();
2499
+ spinner.fail();
2428
2500
  printer.error(err);
2429
2501
  process.exit(exitCodeFromError(err));
2430
2502
  }
@@ -2438,15 +2510,10 @@ function createBrandsCommand() {
2438
2510
  const client = new Autoposting({ apiKey: cred.apiKey });
2439
2511
  const connections = await client.brands.authStatus(slug);
2440
2512
  spinner.stop();
2441
- const rows = connections.map((c) => ({
2442
- platform: c.platform,
2443
- connected: c.connected ? "yes" : "no",
2444
- username: c.username ?? "\u2014",
2445
- "token status": c.tokenExpired === true ? "expired" : c.connected ? "ok" : "\u2014"
2446
- }));
2447
- printer.table(rows, ["platform", "connected", "username", "token status"]);
2513
+ const rows = connections.map((c) => buildAuthStatusRow(c));
2514
+ printer.table(rows, ["platform", "connected", "username", "token status", "expires"]);
2448
2515
  } catch (err) {
2449
- spinner.stop();
2516
+ spinner.fail();
2450
2517
  printer.error(err);
2451
2518
  process.exit(exitCodeFromError(err));
2452
2519
  }
@@ -2482,7 +2549,7 @@ function createCarouselsCommand() {
2482
2549
  }));
2483
2550
  printer.table(rows, ["id", "title", "slides", "status", "createdAt"]);
2484
2551
  } catch (err) {
2485
- spinner.stop();
2552
+ spinner.fail();
2486
2553
  printer.error(err);
2487
2554
  process.exit(resolveExitCode3(err));
2488
2555
  }
@@ -2498,7 +2565,7 @@ function createCarouselsCommand() {
2498
2565
  spinner.stop();
2499
2566
  printer.log(carousel);
2500
2567
  } catch (err) {
2501
- spinner.stop();
2568
+ spinner.fail();
2502
2569
  printer.error(err);
2503
2570
  process.exit(resolveExitCode3(err));
2504
2571
  }
@@ -2516,7 +2583,7 @@ function createCarouselsCommand() {
2516
2583
  spinner.stop();
2517
2584
  printer.log(carousel);
2518
2585
  } catch (err) {
2519
- spinner.stop();
2586
+ spinner.fail();
2520
2587
  printer.error(err);
2521
2588
  process.exit(resolveExitCode3(err));
2522
2589
  }
@@ -2536,7 +2603,7 @@ function createCarouselsCommand() {
2536
2603
  spinner.stop();
2537
2604
  printer.log(carousel);
2538
2605
  } catch (err) {
2539
- spinner.stop();
2606
+ spinner.fail();
2540
2607
  printer.error(err);
2541
2608
  process.exit(resolveExitCode3(err));
2542
2609
  }
@@ -2552,7 +2619,7 @@ function createCarouselsCommand() {
2552
2619
  spinner.stop();
2553
2620
  printer.log(result);
2554
2621
  } catch (err) {
2555
- spinner.stop();
2622
+ spinner.fail();
2556
2623
  printer.error(err);
2557
2624
  process.exit(resolveExitCode3(err));
2558
2625
  }
@@ -2572,7 +2639,7 @@ function createCarouselsCommand() {
2572
2639
  spinner.stop();
2573
2640
  printer.log(`Carousel "${id}" deleted.`);
2574
2641
  } catch (err) {
2575
- spinner.stop();
2642
+ spinner.fail();
2576
2643
  printer.error(err);
2577
2644
  process.exit(resolveExitCode3(err));
2578
2645
  }
@@ -2607,7 +2674,7 @@ function createClipsCommand() {
2607
2674
  }));
2608
2675
  printer.table(rows, ["id", "name", "status", "duration"]);
2609
2676
  } catch (err) {
2610
- spinner.stop();
2677
+ spinner.fail();
2611
2678
  printer.error(err);
2612
2679
  process.exit(resolveExitCode4(err));
2613
2680
  }
@@ -2623,7 +2690,7 @@ function createClipsCommand() {
2623
2690
  spinner.stop();
2624
2691
  printer.log(clip);
2625
2692
  } catch (err) {
2626
- spinner.stop();
2693
+ spinner.fail();
2627
2694
  printer.error(err);
2628
2695
  process.exit(resolveExitCode4(err));
2629
2696
  }
@@ -2644,7 +2711,7 @@ function createClipsCommand() {
2644
2711
  spinner.stop();
2645
2712
  printer.log(clip);
2646
2713
  } catch (err) {
2647
- spinner.stop();
2714
+ spinner.fail();
2648
2715
  printer.error(err);
2649
2716
  process.exit(resolveExitCode4(err));
2650
2717
  }
@@ -2663,7 +2730,7 @@ function createClipsCommand() {
2663
2730
  spinner.stop();
2664
2731
  printer.log({ clipId });
2665
2732
  } catch (err) {
2666
- spinner.stop();
2733
+ spinner.fail();
2667
2734
  printer.error(err);
2668
2735
  process.exit(resolveExitCode4(err));
2669
2736
  }
@@ -2679,7 +2746,7 @@ function createClipsCommand() {
2679
2746
  spinner.stop();
2680
2747
  printer.log({ jobIds, activeJobIds, reusedJobIds });
2681
2748
  } catch (err) {
2682
- spinner.stop();
2749
+ spinner.fail();
2683
2750
  printer.error(err);
2684
2751
  process.exit(resolveExitCode4(err));
2685
2752
  }
@@ -2699,7 +2766,7 @@ function createClipsCommand() {
2699
2766
  spinner.stop();
2700
2767
  printer.log(`Clip "${id}" deleted.`);
2701
2768
  } catch (err) {
2702
- spinner.stop();
2769
+ spinner.fail();
2703
2770
  printer.error(err);
2704
2771
  process.exit(resolveExitCode4(err));
2705
2772
  }
@@ -2732,11 +2799,17 @@ function parsePositiveInt(value, flag) {
2732
2799
  return n;
2733
2800
  }
2734
2801
  function validateScheduledAt(value) {
2735
- if (Number.isNaN(Date.parse(value)) || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(value)) {
2802
+ const ms = Date.parse(value);
2803
+ if (Number.isNaN(ms) || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(value)) {
2736
2804
  throw new Error(
2737
2805
  `--at must be a valid ISO 8601 datetime, e.g. 2026-06-30T14:00:00Z (received "${value}").`
2738
2806
  );
2739
2807
  }
2808
+ if (ms <= Date.now()) {
2809
+ throw new Error(
2810
+ `--at must be in the future (received "${value}", which is in the past). A past schedule time publishes immediately.`
2811
+ );
2812
+ }
2740
2813
  return value;
2741
2814
  }
2742
2815
  function resolveExitCode5(err) {
@@ -2770,7 +2843,7 @@ function createPostsCommand() {
2770
2843
  }));
2771
2844
  printer.table(rows, ["id", "brand", "status", "platforms", "text", "scheduledAt"]);
2772
2845
  } catch (err) {
2773
- spinner.stop();
2846
+ spinner.fail();
2774
2847
  printer.error(err);
2775
2848
  process.exit(resolveExitCode5(err));
2776
2849
  }
@@ -2786,7 +2859,7 @@ function createPostsCommand() {
2786
2859
  spinner.stop();
2787
2860
  printer.log(post);
2788
2861
  } catch (err) {
2789
- spinner.stop();
2862
+ spinner.fail();
2790
2863
  printer.error(err);
2791
2864
  process.exit(resolveExitCode5(err));
2792
2865
  }
@@ -2812,7 +2885,7 @@ function createPostsCommand() {
2812
2885
  spinner.stop();
2813
2886
  printer.log(post);
2814
2887
  } catch (err) {
2815
- spinner.stop();
2888
+ spinner.fail();
2816
2889
  printer.error(err);
2817
2890
  process.exit(resolveExitCode5(err));
2818
2891
  }
@@ -2834,7 +2907,7 @@ function createPostsCommand() {
2834
2907
  spinner.stop();
2835
2908
  printer.log(post);
2836
2909
  } catch (err) {
2837
- spinner.stop();
2910
+ spinner.fail();
2838
2911
  printer.error(err);
2839
2912
  process.exit(resolveExitCode5(err));
2840
2913
  }
@@ -2855,8 +2928,11 @@ function createPostsCommand() {
2855
2928
  spinner.stop();
2856
2929
  printer.log(`Post "${id}" deleted.`);
2857
2930
  } catch (err) {
2858
- spinner.stop();
2931
+ spinner.fail();
2859
2932
  printer.error(err);
2933
+ if (!(err instanceof NotFoundError) && printer.isTty()) {
2934
+ printer.error(`The post may not have been deleted \u2014 verify with: ap posts get "${id}"`);
2935
+ }
2860
2936
  process.exit(resolveExitCode5(err));
2861
2937
  }
2862
2938
  });
@@ -2871,7 +2947,7 @@ function createPostsCommand() {
2871
2947
  spinner.stop();
2872
2948
  printer.log(post);
2873
2949
  } catch (err) {
2874
- spinner.stop();
2950
+ spinner.fail();
2875
2951
  printer.error(err);
2876
2952
  process.exit(resolveExitCode5(err));
2877
2953
  }
@@ -2887,7 +2963,7 @@ function createPostsCommand() {
2887
2963
  spinner.stop();
2888
2964
  printer.log(post);
2889
2965
  } catch (err) {
2890
- spinner.stop();
2966
+ spinner.fail();
2891
2967
  printer.error(err);
2892
2968
  process.exit(resolveExitCode5(err));
2893
2969
  }
@@ -2903,7 +2979,7 @@ function createPostsCommand() {
2903
2979
  spinner.stop();
2904
2980
  printer.log(post);
2905
2981
  } catch (err) {
2906
- spinner.stop();
2982
+ spinner.fail();
2907
2983
  printer.error(err);
2908
2984
  process.exit(resolveExitCode5(err));
2909
2985
  }
@@ -2919,7 +2995,7 @@ function createPostsCommand() {
2919
2995
  spinner.stop();
2920
2996
  printer.log(post);
2921
2997
  } catch (err) {
2922
- spinner.stop();
2998
+ spinner.fail();
2923
2999
  printer.error(err);
2924
3000
  process.exit(resolveExitCode5(err));
2925
3001
  }
@@ -2935,7 +3011,7 @@ function createPostsCommand() {
2935
3011
  spinner.stop();
2936
3012
  printer.log(result);
2937
3013
  } catch (err) {
2938
- spinner.stop();
3014
+ spinner.fail();
2939
3015
  printer.error(err);
2940
3016
  process.exit(resolveExitCode5(err));
2941
3017
  }
@@ -2970,7 +3046,7 @@ function createKbCommand() {
2970
3046
  }));
2971
3047
  printer.table(rows, ["id", "name", "docs", "createdAt"]);
2972
3048
  } catch (err) {
2973
- spinner.stop();
3049
+ spinner.fail();
2974
3050
  printer.error(err);
2975
3051
  process.exit(resolveExitCode6(err));
2976
3052
  }
@@ -2986,7 +3062,7 @@ function createKbCommand() {
2986
3062
  spinner.stop();
2987
3063
  printer.log(result);
2988
3064
  } catch (err) {
2989
- spinner.stop();
3065
+ spinner.fail();
2990
3066
  printer.error(err);
2991
3067
  process.exit(resolveExitCode6(err));
2992
3068
  }
@@ -3002,7 +3078,7 @@ function createKbCommand() {
3002
3078
  spinner.stop();
3003
3079
  printer.log(result);
3004
3080
  } catch (err) {
3005
- spinner.stop();
3081
+ spinner.fail();
3006
3082
  printer.error(err);
3007
3083
  process.exit(resolveExitCode6(err));
3008
3084
  }
@@ -3022,7 +3098,7 @@ function createKbCommand() {
3022
3098
  spinner.stop();
3023
3099
  printer.log(`Knowledge base "${id}" deleted.`);
3024
3100
  } catch (err) {
3025
- spinner.stop();
3101
+ spinner.fail();
3026
3102
  printer.error(err);
3027
3103
  process.exit(resolveExitCode6(err));
3028
3104
  }
@@ -3044,7 +3120,7 @@ function createKbCommand() {
3044
3120
  }));
3045
3121
  printer.table(rows, ["kind", "score", "uri", "content"]);
3046
3122
  } catch (err) {
3047
- spinner.stop();
3123
+ spinner.fail();
3048
3124
  printer.error(err);
3049
3125
  process.exit(resolveExitCode6(err));
3050
3126
  }
@@ -3060,7 +3136,7 @@ function createKbCommand() {
3060
3136
  spinner.stop();
3061
3137
  printer.log(doc);
3062
3138
  } catch (err) {
3063
- spinner.stop();
3139
+ spinner.fail();
3064
3140
  printer.error(err);
3065
3141
  process.exit(resolveExitCode6(err));
3066
3142
  }
@@ -3083,7 +3159,7 @@ function createKbCommand() {
3083
3159
  }));
3084
3160
  printer.table(rows, ["id", "name", "type", "status", "createdAt"]);
3085
3161
  } catch (err) {
3086
- spinner.stop();
3162
+ spinner.fail();
3087
3163
  printer.error(err);
3088
3164
  process.exit(resolveExitCode6(err));
3089
3165
  }
@@ -3139,7 +3215,7 @@ function createIdeasCommand() {
3139
3215
  }));
3140
3216
  printer.table(rows, ["id", "platform", "score", "title"]);
3141
3217
  } catch (err) {
3142
- spinner.stop();
3218
+ spinner.fail();
3143
3219
  printer.error(err);
3144
3220
  process.exit(resolveExitCode7(err));
3145
3221
  }
@@ -3163,7 +3239,7 @@ function createIdeasCommand() {
3163
3239
  }));
3164
3240
  printer.table(rows, ["id", "topic", "platform", "score", "status", "title"]);
3165
3241
  } catch (err) {
3166
- spinner.stop();
3242
+ spinner.fail();
3167
3243
  printer.error(err);
3168
3244
  process.exit(resolveExitCode7(err));
3169
3245
  }
@@ -3184,7 +3260,7 @@ function createIdeasCommand() {
3184
3260
  spinner.stop();
3185
3261
  printer.log(`Enrichment queued. Job ID: ${jobId}`);
3186
3262
  } catch (err) {
3187
- spinner.stop();
3263
+ spinner.fail();
3188
3264
  printer.error(err);
3189
3265
  process.exit(resolveExitCode7(err));
3190
3266
  }
@@ -3205,7 +3281,7 @@ function createIdeasCommand() {
3205
3281
  spinner.stop();
3206
3282
  printer.log(`Idea "${id}" deleted.`);
3207
3283
  } catch (err) {
3208
- spinner.stop();
3284
+ spinner.fail();
3209
3285
  printer.error(err);
3210
3286
  process.exit(resolveExitCode7(err));
3211
3287
  }
@@ -3252,7 +3328,7 @@ function createUsageCommand() {
3252
3328
  }));
3253
3329
  printer.table(sourceRows, ["source", "posts"]);
3254
3330
  } catch (err) {
3255
- spinner.stop();
3331
+ spinner.fail();
3256
3332
  printer.error(err);
3257
3333
  process.exit(resolveExitCode8(err));
3258
3334
  }
@@ -3288,7 +3364,7 @@ function createWebhooksCommand() {
3288
3364
  }));
3289
3365
  printer.table(rows, ["id", "url", "events", "active", "createdAt"]);
3290
3366
  } catch (err) {
3291
- spinner.stop();
3367
+ spinner.fail();
3292
3368
  printer.error(err);
3293
3369
  process.exit(resolveExitCode9(err));
3294
3370
  }
@@ -3304,7 +3380,7 @@ function createWebhooksCommand() {
3304
3380
  spinner.stop();
3305
3381
  printer.log(webhook);
3306
3382
  } catch (err) {
3307
- spinner.stop();
3383
+ spinner.fail();
3308
3384
  printer.error(err);
3309
3385
  process.exit(resolveExitCode9(err));
3310
3386
  }
@@ -3325,7 +3401,7 @@ function createWebhooksCommand() {
3325
3401
  spinner.stop();
3326
3402
  printer.log(webhook);
3327
3403
  } catch (err) {
3328
- spinner.stop();
3404
+ spinner.fail();
3329
3405
  printer.error(err);
3330
3406
  process.exit(resolveExitCode9(err));
3331
3407
  }
@@ -3347,7 +3423,7 @@ function createWebhooksCommand() {
3347
3423
  spinner.stop();
3348
3424
  printer.log(webhook);
3349
3425
  } catch (err) {
3350
- spinner.stop();
3426
+ spinner.fail();
3351
3427
  printer.error(err);
3352
3428
  process.exit(resolveExitCode9(err));
3353
3429
  }
@@ -3368,7 +3444,7 @@ function createWebhooksCommand() {
3368
3444
  spinner.stop();
3369
3445
  printer.log(`Webhook "${id}" deleted.`);
3370
3446
  } catch (err) {
3371
- spinner.stop();
3447
+ spinner.fail();
3372
3448
  printer.error(err);
3373
3449
  process.exit(resolveExitCode9(err));
3374
3450
  }
@@ -3386,7 +3462,7 @@ function createWebhooksCommand() {
3386
3462
  `Test event sent to webhook "${id}" \u2014 delivered: ${result.delivered ? "yes" : "no"} (HTTP ${result.httpStatus}).`
3387
3463
  );
3388
3464
  } catch (err) {
3389
- spinner.stop();
3465
+ spinner.fail();
3390
3466
  printer.error(err);
3391
3467
  process.exit(resolveExitCode9(err));
3392
3468
  }
@@ -3422,7 +3498,7 @@ function createWorkspacesCommand() {
3422
3498
  }));
3423
3499
  printer.table(rows, ["id", "name", "slug", "active", "createdAt"]);
3424
3500
  } catch (err) {
3425
- spinner.stop();
3501
+ spinner.fail();
3426
3502
  printer.error(err);
3427
3503
  process.exit(resolveExitCode10(err));
3428
3504
  }
@@ -3433,13 +3509,12 @@ function createWorkspacesCommand() {
3433
3509
  const spinner = printer.spinner(`Switching to workspace "${id}"\u2026`);
3434
3510
  try {
3435
3511
  const cred = resolveAuth({ apiKey: globals.apiKey });
3436
- const authSource = cred.source === "flag" || cred.source === "env" || cred.source === "stored" ? "api-key" : "session";
3437
- const client = new Autoposting({ apiKey: cred.apiKey, authSource });
3512
+ const client = new Autoposting({ apiKey: cred.apiKey });
3438
3513
  await client.workspaces.switchWorkspace(id);
3439
3514
  spinner.stop();
3440
3515
  printer.log(`Switched to workspace "${id}".`);
3441
3516
  } catch (err) {
3442
- spinner.stop();
3517
+ spinner.fail();
3443
3518
  printer.error(err);
3444
3519
  process.exit(resolveExitCode10(err));
3445
3520
  }
@@ -3536,9 +3611,10 @@ function createWhoamiCommand() {
3536
3611
  }
3537
3612
  const masked = `${cred.apiKey.slice(0, 8)}${"*".repeat(Math.max(0, cred.apiKey.length - 8))}`;
3538
3613
  let validity = "unverified";
3614
+ let identity;
3539
3615
  try {
3540
- const client = new Autoposting({ apiKey: cred.apiKey });
3541
- await client.usage.summary();
3616
+ const client = new Autoposting({ apiKey: cred.apiKey, maxRetries: 0 });
3617
+ identity = await client.getProfile();
3542
3618
  validity = "valid";
3543
3619
  } catch (err) {
3544
3620
  const code = exitCodeFromError(err);
@@ -3555,6 +3631,11 @@ function createWhoamiCommand() {
3555
3631
  valid: validity === "valid",
3556
3632
  validity
3557
3633
  };
3634
+ if (identity?.orgId) {
3635
+ out.orgId = identity.orgId;
3636
+ out.authType = identity.authType;
3637
+ if (identity.email) out.email = identity.email;
3638
+ }
3558
3639
  if (cred.source === "stored") {
3559
3640
  out.profile = profileName;
3560
3641
  if (email) out.email = email;
@@ -3568,6 +3649,10 @@ function createWhoamiCommand() {
3568
3649
  console.log(`Profile: ${profileName}`);
3569
3650
  if (email) console.log(`Email: ${email}`);
3570
3651
  }
3652
+ if (identity?.orgId) {
3653
+ console.log(`Org: ${identity.orgId}`);
3654
+ console.log(`Auth: ${identity.authType}`);
3655
+ }
3571
3656
  const tag = validity === "valid" ? "\u2713 valid" : validity === "rejected" ? "\u2717 rejected by server" : "\u26A0 unverified (could not reach server)";
3572
3657
  console.log(`API key: ${masked} ${tag}`);
3573
3658
  process.exitCode = exitCode;