@autoposting.ai/cli 0.2.31 → 0.3.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.
package/dist/cli.cjs CHANGED
@@ -9,9 +9,6 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
9
  var __esm = (fn, res) => function __init() {
10
10
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
11
  };
12
- var __commonJS = (cb, mod) => function __require() {
13
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
14
- };
15
12
  var __export = (target, all) => {
16
13
  for (var name in all)
17
14
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -33,54 +30,24 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
30
  mod
34
31
  ));
35
32
 
36
- // ../sdk/dist/index.js
37
- var require_dist = __commonJS({
38
- "../sdk/dist/index.js"(exports2, module2) {
33
+ // ../sdk/dist/index.mjs
34
+ function createError(status, body) {
35
+ const message = body.error ?? "An error occurred";
36
+ const code = body.code ?? "UNKNOWN";
37
+ if (status === 401) return new AuthenticationError(message, status, code);
38
+ if (status === 403) return new ScopeError(message, status, code);
39
+ if (status === 404) return new NotFoundError(message, status, code);
40
+ if (status === 400 || status === 422) return new ValidationError(message, status, code);
41
+ if (status === 429) return new RateLimitError(message, status, code);
42
+ if (status >= 500) return new ServerError(message, status, code);
43
+ return new AutopostingError(message, status, code);
44
+ }
45
+ var VERSION, AutopostingError, AuthenticationError, ScopeError, NotFoundError, ValidationError, RateLimitError, ServerError, Resource, AgentsResource, BillingResource, BrandsResource, CarouselsResource, ClipsResource, PostsResource, KbResource, IdeasResource, UsageResource, WebhooksResource, WorkspacesResource, Autoposting;
46
+ var init_dist = __esm({
47
+ "../sdk/dist/index.mjs"() {
39
48
  "use strict";
40
- var __defProp2 = Object.defineProperty;
41
- var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
42
- var __getOwnPropNames2 = Object.getOwnPropertyNames;
43
- var __hasOwnProp2 = Object.prototype.hasOwnProperty;
44
- var __export2 = (target, all) => {
45
- for (var name in all)
46
- __defProp2(target, name, { get: all[name], enumerable: true });
47
- };
48
- var __copyProps2 = (to, from, except, desc) => {
49
- if (from && typeof from === "object" || typeof from === "function") {
50
- for (let key of __getOwnPropNames2(from))
51
- if (!__hasOwnProp2.call(to, key) && key !== except)
52
- __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
53
- }
54
- return to;
55
- };
56
- var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
57
- var index_exports = {};
58
- __export2(index_exports, {
59
- AgentsResource: () => AgentsResource,
60
- AuthenticationError: () => AuthenticationError,
61
- Autoposting: () => Autoposting13,
62
- AutopostingError: () => AutopostingError,
63
- BillingResource: () => BillingResource,
64
- BrandsResource: () => BrandsResource,
65
- CarouselsResource: () => CarouselsResource,
66
- ClipsResource: () => ClipsResource,
67
- IdeasResource: () => IdeasResource,
68
- KbResource: () => KbResource,
69
- NotFoundError: () => NotFoundError,
70
- PostsResource: () => PostsResource,
71
- RateLimitError: () => RateLimitError,
72
- Resource: () => Resource,
73
- ScopeError: () => ScopeError,
74
- ServerError: () => ServerError,
75
- UsageResource: () => UsageResource,
76
- VERSION: () => VERSION3,
77
- ValidationError: () => ValidationError,
78
- WebhooksResource: () => WebhooksResource,
79
- WorkspacesResource: () => WorkspacesResource
80
- });
81
- module2.exports = __toCommonJS(index_exports);
82
- var VERSION3 = "0.1.0";
83
- var AutopostingError = class extends Error {
49
+ VERSION = "0.3.1";
50
+ AutopostingError = class extends Error {
84
51
  status;
85
52
  code;
86
53
  constructor(message, status, code) {
@@ -91,31 +58,20 @@ var require_dist = __commonJS({
91
58
  Object.setPrototypeOf(this, new.target.prototype);
92
59
  }
93
60
  };
94
- var AuthenticationError = class extends AutopostingError {
61
+ AuthenticationError = class extends AutopostingError {
95
62
  };
96
- var ScopeError = class extends AutopostingError {
63
+ ScopeError = class extends AutopostingError {
97
64
  };
98
- var NotFoundError = class extends AutopostingError {
65
+ NotFoundError = class extends AutopostingError {
99
66
  };
100
- var ValidationError = class extends AutopostingError {
67
+ ValidationError = class extends AutopostingError {
101
68
  };
102
- var RateLimitError = class extends AutopostingError {
69
+ RateLimitError = class extends AutopostingError {
103
70
  retryAfter;
104
71
  };
105
- var ServerError = class extends AutopostingError {
72
+ ServerError = class extends AutopostingError {
106
73
  };
107
- function createError(status, body) {
108
- const message = body.error ?? "An error occurred";
109
- const code = body.code ?? "UNKNOWN";
110
- if (status === 401) return new AuthenticationError(message, status, code);
111
- if (status === 403) return new ScopeError(message, status, code);
112
- if (status === 404) return new NotFoundError(message, status, code);
113
- if (status === 400 || status === 422) return new ValidationError(message, status, code);
114
- if (status === 429) return new RateLimitError(message, status, code);
115
- if (status >= 500) return new ServerError(message, status, code);
116
- return new AutopostingError(message, status, code);
117
- }
118
- var Resource = class {
74
+ Resource = class {
119
75
  constructor(client) {
120
76
  this.client = client;
121
77
  }
@@ -136,7 +92,8 @@ var require_dist = __commonJS({
136
92
  return this.client.request("DELETE", path2);
137
93
  }
138
94
  };
139
- var AgentsResource = class extends Resource {
95
+ AgentsResource = class extends Resource {
96
+ /** GET /agents — backend returns `{ items, total, limit, offset }`. */
140
97
  list() {
141
98
  return this.get("/agents");
142
99
  }
@@ -152,17 +109,19 @@ var require_dist = __commonJS({
152
109
  remove(id) {
153
110
  return this.delete(`/agents/${id}`);
154
111
  }
112
+ /** POST /agents/:id/run — queues a run; returns `{ runId, status }`, not a full AgentRun. */
155
113
  run(id) {
156
114
  return this.post(`/agents/${id}/run`);
157
115
  }
158
116
  toggle(id) {
159
117
  return this.post(`/agents/${id}/toggle`);
160
118
  }
119
+ /** GET /agents/:id/runs — backend returns `{ items, total, limit, offset }`. */
161
120
  runs(id) {
162
121
  return this.get(`/agents/${id}/runs`);
163
122
  }
164
123
  };
165
- var BillingResource = class extends Resource {
124
+ BillingResource = class extends Resource {
166
125
  status() {
167
126
  return this.get("/billing/status");
168
127
  }
@@ -170,7 +129,7 @@ var require_dist = __commonJS({
170
129
  return this.get("/billing/credits");
171
130
  }
172
131
  };
173
- var BrandsResource = class extends Resource {
132
+ BrandsResource = class extends Resource {
174
133
  list() {
175
134
  return this.get("/brands");
176
135
  }
@@ -190,7 +149,8 @@ var require_dist = __commonJS({
190
149
  return this.get(`/brands/${slug}/auth/status`);
191
150
  }
192
151
  };
193
- var CarouselsResource = class extends Resource {
152
+ CarouselsResource = class extends Resource {
153
+ /** GET /carousels — backend paginates: `{ items, total, limit, offset }`. */
194
154
  list() {
195
155
  return this.get("/carousels");
196
156
  }
@@ -203,37 +163,38 @@ var require_dist = __commonJS({
203
163
  generate(params) {
204
164
  return this.post("/carousels/generate", params);
205
165
  }
206
- /** POST /carousels/:id/draft — converts carousel to a post draft */
166
+ /** POST /carousels/:id/create-draft — converts carousel to a post draft */
207
167
  draft(id) {
208
- return this.post(`/carousels/${id}/draft`);
168
+ return this.post(`/carousels/${id}/create-draft`);
209
169
  }
210
170
  remove(id) {
211
171
  return this.client.request("DELETE", `/carousels/${id}`);
212
172
  }
213
173
  };
214
- var ClipsResource = class extends Resource {
174
+ ClipsResource = class extends Resource {
175
+ /** GET /clips — backend returns `{ clips, pagination }`, not a bare array. */
215
176
  list() {
216
177
  return this.client.request("GET", "/clips");
217
178
  }
218
179
  retrieve(id) {
219
180
  return this.client.request("GET", `/clips/${id}`);
220
181
  }
221
- async upload(filePath, options) {
222
- const fs3 = await import("fs");
223
- const path2 = await import("path");
224
- const data = fs3.readFileSync(filePath);
225
- const name = options?.name ?? path2.basename(filePath);
226
- const formData = new FormData();
227
- formData.append("file", new Blob([data]), name);
228
- formData.append("name", name);
229
- options?.onProgress?.(0);
230
- const clip = await this.client.request("POST", "/clips/upload", formData);
231
- options?.onProgress?.(100);
232
- return clip;
182
+ // ponytail: the backend has no single-request /clips/upload; uploading a file means the
183
+ // multipart init/presign/complete flow (upload-initiate → upload-presign → upload-complete).
184
+ // That's too much surface for v0.3.1 — fail honestly and point at importUrl. Upgrade path:
185
+ // implement the init/presign/complete dance here when direct upload is actually needed.
186
+ async upload(_filePath, _options) {
187
+ throw new AutopostingError(
188
+ "Direct clip file upload is not supported by the API yet \u2014 use `importUrl` with a public video URL instead.",
189
+ 0,
190
+ "NOT_IMPLEMENTED"
191
+ );
233
192
  }
193
+ /** POST /clips/import-url — backend returns `{ clipId }`, not a full Clip. */
234
194
  importUrl(params) {
235
- return this.client.request("POST", "/clips/import", params);
195
+ return this.client.request("POST", "/clips/import-url", params);
236
196
  }
197
+ /** POST /clips/:id/render — backend returns render job ids, not a Clip. */
237
198
  render(id) {
238
199
  return this.client.request("POST", `/clips/${id}/render`);
239
200
  }
@@ -241,49 +202,49 @@ var require_dist = __commonJS({
241
202
  return this.client.request("DELETE", `/clips/${id}`);
242
203
  }
243
204
  };
244
- var PostsResource = class extends Resource {
245
- list(params) {
246
- return this.client.request(
247
- "GET",
248
- "/v1/posts",
249
- void 0,
250
- params
251
- );
252
- }
253
- /** GET /v1/posts/:id */
205
+ PostsResource = class extends Resource {
206
+ /** GET /posts — backend returns a bare array (no pagination metadata). */
207
+ list(params = {}) {
208
+ const { brandSlug, status, limit, page } = params;
209
+ const query = {};
210
+ if (brandSlug) query.brandSlug = brandSlug;
211
+ if (status) query.status = status;
212
+ if (limit !== void 0) query.limit = limit;
213
+ if (page !== void 0 && page > 1) query.offset = (page - 1) * (limit ?? 20);
214
+ return this.client.request("GET", "/posts", void 0, query);
215
+ }
216
+ /** GET /posts/:id */
254
217
  getById(id) {
255
- return this.client.request("GET", `/v1/posts/${id}`);
218
+ return this.client.request("GET", `/posts/${id}`);
256
219
  }
257
220
  create(params) {
258
- return this.client.request("POST", "/v1/posts", params);
221
+ return this.client.request("POST", "/posts", params);
259
222
  }
260
223
  update(id, params) {
261
- return this.client.request("PUT", `/v1/posts/${id}`, params);
224
+ return this.client.request("PUT", `/posts/${id}`, params);
262
225
  }
263
- /** DELETE /v1/posts/:id */
226
+ /** DELETE /posts/:id */
264
227
  remove(id) {
265
- return this.client.request("DELETE", `/v1/posts/${id}`);
228
+ return this.client.request("DELETE", `/posts/${id}`);
266
229
  }
267
230
  publish(id) {
268
- return this.client.request("POST", `/v1/posts/${id}/publish`);
231
+ return this.client.request("POST", `/posts/${id}/publish`);
269
232
  }
270
233
  schedule(id, scheduledAt) {
271
- return this.client.request("PUT", `/v1/posts/${id}/schedule`, { scheduledAt });
234
+ return this.client.request("PUT", `/posts/${id}/schedule`, { scheduledAt });
272
235
  }
273
236
  retry(id) {
274
- return this.client.request("POST", `/v1/posts/${id}/retry`);
237
+ return this.client.request("POST", `/posts/${id}/retry`);
275
238
  }
276
239
  rewrite(id) {
277
- return this.client.request("POST", `/v1/posts/${id}/rewrite`);
240
+ return this.client.request("POST", `/posts/${id}/rewrite`);
278
241
  }
242
+ /** POST /posts/:id/score — backend returns `{ score }` only (no feedback). */
279
243
  score(id) {
280
- return this.client.request(
281
- "POST",
282
- `/v1/posts/${id}/score`
283
- );
244
+ return this.client.request("POST", `/posts/${id}/score`);
284
245
  }
285
246
  };
286
- var KbResource = class extends Resource {
247
+ KbResource = class extends Resource {
287
248
  list() {
288
249
  return this.get("/kbs");
289
250
  }
@@ -297,7 +258,10 @@ var require_dist = __commonJS({
297
258
  return this.delete(`/kbs/${id}`);
298
259
  }
299
260
  search(id, query) {
300
- return this.post(`/kbs/${id}/search`, { query });
261
+ return this.post(
262
+ `/kbs/${id}/search`,
263
+ { query }
264
+ );
301
265
  }
302
266
  ingestUrl(id, url) {
303
267
  return this.post(`/kbs/${id}/docs/ingest-url`, { url });
@@ -306,29 +270,37 @@ var require_dist = __commonJS({
306
270
  return this.get(`/kbs/${id}/docs`);
307
271
  }
308
272
  };
309
- var IdeasResource = class extends Resource {
273
+ IdeasResource = class extends Resource {
274
+ /** POST /ideas/generate-topic — returns an object whose `ideas` holds the generated ideas. */
310
275
  generate(params = {}) {
311
- return this.post("/ideas/generate", params);
276
+ return this.post("/ideas/generate-topic", params);
312
277
  }
278
+ /** GET /ideas — backend paginates: `{ items, total, limit, offset }`. */
313
279
  list() {
314
280
  return this.get("/ideas");
315
281
  }
316
- enrich(id) {
317
- return this.post(`/ideas/${id}/enrich`);
282
+ /**
283
+ * POST /ideas/enrich — enrich an idea (title/hook/angle) across 1..5 platforms.
284
+ * Async: returns a job id (202). NOTE: the backend enriches the idea *object*, not an
285
+ * id — there is no enrich-by-id route. Poll the result separately (not yet wrapped).
286
+ */
287
+ enrich(params) {
288
+ return this.post("/ideas/enrich", params);
318
289
  }
319
290
  remove(id) {
320
291
  return this.delete(`/ideas/${id}`);
321
292
  }
322
293
  };
323
- var UsageResource = class extends Resource {
294
+ UsageResource = class extends Resource {
324
295
  summary() {
325
296
  return this.get("/usage/summary");
326
297
  }
327
298
  };
328
- var WebhooksResource = class extends Resource {
299
+ WebhooksResource = class extends Resource {
329
300
  list() {
330
301
  return this.get("/webhooks");
331
302
  }
303
+ // NOTE: the backend has no GET /webhooks/:id route — this 404s until front-back adds it.
332
304
  retrieve(id) {
333
305
  return this.get(`/webhooks/${id}`);
334
306
  }
@@ -341,14 +313,19 @@ var require_dist = __commonJS({
341
313
  remove(id) {
342
314
  return this.client.request("DELETE", `/webhooks/${id}`);
343
315
  }
316
+ // POST /webhooks/:id/test — backend returns `{ delivered, httpStatus }`.
344
317
  test(id) {
345
318
  return this.post(`/webhooks/${id}/test`);
346
319
  }
347
320
  };
348
- var WorkspacesResource = class extends Resource {
321
+ WorkspacesResource = class extends Resource {
349
322
  constructor(client) {
350
323
  super(client);
351
324
  }
325
+ /**
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.
328
+ */
352
329
  list() {
353
330
  return this.get("/orgs");
354
331
  }
@@ -360,10 +337,10 @@ var require_dist = __commonJS({
360
337
  )
361
338
  );
362
339
  }
363
- return this.post("/orgs/set-active", { organizationId: id });
340
+ return this.client.request("PUT", "/orgs/active", { organizationId: id });
364
341
  }
365
342
  };
366
- var Autoposting13 = class {
343
+ Autoposting = class {
367
344
  /** @internal Not part of the public API — use SDK methods to make requests. */
368
345
  _apiKey;
369
346
  baseUrl;
@@ -390,7 +367,7 @@ var require_dist = __commonJS({
390
367
  );
391
368
  }
392
369
  this._apiKey = key;
393
- this.baseUrl = (config.baseUrl ?? "https://app.autoposting.ai").replace(/\/$/, "");
370
+ this.baseUrl = (config.baseUrl || process.env.AUTOPOSTING_BASE_URL || "https://app.autoposting.ai/api-proxy").replace(/\/$/, "");
394
371
  this.timeout = config.timeout ?? 3e4;
395
372
  this.extraHeaders = config.headers ?? {};
396
373
  this.authSource = config.authSource ?? "api-key";
@@ -419,46 +396,101 @@ var require_dist = __commonJS({
419
396
  }
420
397
  const isFormData = body instanceof FormData;
421
398
  const headers = {
399
+ ...this.extraHeaders,
422
400
  authorization: `Bearer ${this._apiKey}`,
423
- "user-agent": `autoposting-sdk/${VERSION3}`,
424
- "x-source": "sdk",
425
- ...this.extraHeaders
401
+ "user-agent": `autoposting-sdk/${VERSION}`,
402
+ "x-source": "sdk"
426
403
  };
427
404
  if (!isFormData) {
428
405
  headers["content-type"] = "application/json";
429
406
  }
430
407
  const controller = new AbortController();
431
408
  const timer = setTimeout(() => controller.abort(), this.timeout);
432
- let response;
433
409
  try {
434
- response = await fetch(url, {
435
- method,
436
- headers,
437
- body: isFormData ? body : body !== void 0 ? JSON.stringify(body) : void 0,
438
- signal: controller.signal
439
- });
440
- } finally {
441
- clearTimeout(timer);
442
- }
443
- if (!response.ok) {
444
- let errorBody = {};
410
+ let response;
445
411
  try {
446
- errorBody = await response.json();
447
- } catch {
412
+ response = await fetch(url, {
413
+ method,
414
+ headers,
415
+ body: isFormData ? body : body !== void 0 ? JSON.stringify(body) : void 0,
416
+ signal: controller.signal
417
+ });
418
+ } catch (err) {
419
+ if (err instanceof Error && err.name === "AbortError") {
420
+ throw new AutopostingError(
421
+ `Request to ${method} ${path2} timed out after ${this.timeout}ms.`,
422
+ 0,
423
+ "TIMEOUT"
424
+ );
425
+ }
426
+ throw new AutopostingError(
427
+ `Network request to ${method} ${path2} failed: ${err instanceof Error ? err.message : String(err)}`,
428
+ 0,
429
+ "NETWORK_ERROR"
430
+ );
448
431
  }
449
- const err = createError(response.status, errorBody);
450
- if (err instanceof RateLimitError) {
451
- const retryAfter = response.headers.get("Retry-After");
452
- if (retryAfter) {
453
- err.retryAfter = parseInt(retryAfter, 10);
432
+ if (!response.ok) {
433
+ const raw = await response.text();
434
+ let errorBody = {};
435
+ if (raw) {
436
+ try {
437
+ errorBody = JSON.parse(raw);
438
+ } catch {
439
+ }
440
+ }
441
+ if (!errorBody.error) {
442
+ const snippet = raw.replace(/\s+/g, " ").trim().slice(0, 120);
443
+ errorBody.error = snippet ? `HTTP ${response.status} ${response.statusText}: ${snippet}` : `HTTP ${response.status} ${response.statusText}`;
454
444
  }
445
+ const err = createError(response.status, errorBody);
446
+ if (err instanceof RateLimitError) {
447
+ const retryAfter = response.headers.get("Retry-After");
448
+ if (retryAfter) {
449
+ const seconds = Number(retryAfter);
450
+ if (Number.isFinite(seconds)) {
451
+ err.retryAfter = Math.max(0, Math.round(seconds));
452
+ } else {
453
+ const dateMs = Date.parse(retryAfter);
454
+ if (!Number.isNaN(dateMs)) {
455
+ err.retryAfter = Math.max(0, Math.round((dateMs - Date.now()) / 1e3));
456
+ }
457
+ }
458
+ }
459
+ }
460
+ throw err;
461
+ }
462
+ if (response.status === 204) {
463
+ return {};
464
+ }
465
+ const text = await response.text();
466
+ if (!text) return {};
467
+ let parsed;
468
+ try {
469
+ parsed = JSON.parse(text);
470
+ } catch {
471
+ throw new AutopostingError(
472
+ `Expected a JSON response from ${method} ${path2} but received non-JSON (HTTP ${response.status}). Verify the API base URL (AUTOPOSTING_BASE_URL / --base-url) points at the API, not the web app.`,
473
+ response.status,
474
+ "INVALID_RESPONSE"
475
+ );
476
+ }
477
+ if (typeof parsed === "object" && parsed !== null && parsed.success === true) {
478
+ const env = parsed;
479
+ return env.data !== void 0 ? env.data : {};
480
+ }
481
+ return parsed;
482
+ } catch (err) {
483
+ if (err instanceof Error && err.name === "AbortError") {
484
+ throw new AutopostingError(
485
+ `Request to ${method} ${path2} timed out after ${this.timeout}ms.`,
486
+ 0,
487
+ "TIMEOUT"
488
+ );
455
489
  }
456
490
  throw err;
491
+ } finally {
492
+ clearTimeout(timer);
457
493
  }
458
- if (response.status === 204) {
459
- return {};
460
- }
461
- return response.json();
462
494
  }
463
495
  };
464
496
  }
@@ -906,13 +938,26 @@ var init_tools = __esm({
906
938
  },
907
939
  {
908
940
  name: "enrich-idea",
909
- description: "Enrich an idea with additional AI-generated context.",
941
+ description: "Enrich an idea (title/hook/angle) into platform-ready drafts across 1..5 platforms. Async \u2014 returns a job ID.",
910
942
  inputSchema: {
911
943
  type: "object",
912
944
  properties: {
913
- id: { type: "string", description: "Idea ID to enrich" }
945
+ title: { type: "string", description: "Idea title" },
946
+ hook: { type: "string", description: "Idea hook" },
947
+ angle: { type: "string", description: "Idea angle" },
948
+ platforms: {
949
+ type: "array",
950
+ description: "Target platforms (1..5)",
951
+ items: {
952
+ type: "string",
953
+ enum: ["twitter", "linkedin", "instagram", "youtube", "threads"]
954
+ },
955
+ minItems: 1,
956
+ maxItems: 5
957
+ },
958
+ kbId: { type: "string", description: "Optional knowledge base ID for context" }
914
959
  },
915
- required: ["id"],
960
+ required: ["title", "hook", "angle", "platforms"],
916
961
  additionalProperties: false
917
962
  }
918
963
  },
@@ -1173,15 +1218,33 @@ var init_tools = __esm({
1173
1218
  function ok(data) {
1174
1219
  return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
1175
1220
  }
1221
+ function fail(error) {
1222
+ const message = error instanceof Error ? error.message : String(error);
1223
+ return { content: [{ type: "text", text: message }], isError: true };
1224
+ }
1176
1225
  function parsePlatforms2(raw) {
1177
1226
  if (typeof raw !== "string") return [];
1178
- return raw.split(",").map((p) => p.trim());
1227
+ const platforms = raw.split(",").map((p) => p.trim()).filter(Boolean);
1228
+ const invalid = platforms.filter((platform) => !PLATFORM_SET.has(platform));
1229
+ if (invalid.length > 0) {
1230
+ throw new Error(
1231
+ `Invalid platform(s): ${invalid.join(", ")}. Expected one of: ${PLATFORMS.join(", ")}.`
1232
+ );
1233
+ }
1234
+ return platforms;
1179
1235
  }
1180
1236
  function parseEvents(raw) {
1181
1237
  if (typeof raw !== "string") return [];
1182
1238
  return raw.split(",").map((e) => e.trim());
1183
1239
  }
1184
1240
  async function handleToolCall(name, args, client) {
1241
+ try {
1242
+ return await dispatchToolCall(name, args, client);
1243
+ } catch (error) {
1244
+ return fail(error);
1245
+ }
1246
+ }
1247
+ async function dispatchToolCall(name, args, client) {
1185
1248
  switch (name) {
1186
1249
  // Posts
1187
1250
  case "list-posts": {
@@ -1225,7 +1288,10 @@ async function handleToolCall(name, args, client) {
1225
1288
  return ok(result);
1226
1289
  }
1227
1290
  case "schedule-post": {
1228
- const result = await client.posts.schedule(args.id, args.scheduledAt);
1291
+ const result = await client.posts.schedule(
1292
+ args.id,
1293
+ args.scheduledAt
1294
+ );
1229
1295
  return ok(result);
1230
1296
  }
1231
1297
  case "retry-post": {
@@ -1337,11 +1403,17 @@ async function handleToolCall(name, args, client) {
1337
1403
  return ok({ deleted: true, id: args.id });
1338
1404
  }
1339
1405
  case "search-kb": {
1340
- const result = await client.kb.search(args.id, args.query);
1406
+ const result = await client.kb.search(
1407
+ args.id,
1408
+ args.query
1409
+ );
1341
1410
  return ok(result);
1342
1411
  }
1343
1412
  case "ingest-kb": {
1344
- const result = await client.kb.ingestUrl(args.id, args.url);
1413
+ const result = await client.kb.ingestUrl(
1414
+ args.id,
1415
+ args.url
1416
+ );
1345
1417
  return ok(result);
1346
1418
  }
1347
1419
  case "kb-docs": {
@@ -1362,7 +1434,17 @@ async function handleToolCall(name, args, client) {
1362
1434
  return ok(result);
1363
1435
  }
1364
1436
  case "enrich-idea": {
1365
- const result = await client.ideas.enrich(args.id);
1437
+ const result = await client.ideas.enrich({
1438
+ idea: {
1439
+ title: args.title,
1440
+ hook: args.hook,
1441
+ angle: args.angle
1442
+ },
1443
+ platforms: args.platforms.map((platform) => ({
1444
+ platform
1445
+ })),
1446
+ ...args.kbId ? { kbId: args.kbId } : {}
1447
+ });
1366
1448
  return ok(result);
1367
1449
  }
1368
1450
  case "delete-idea": {
@@ -1478,9 +1560,18 @@ async function handleToolCall(name, args, client) {
1478
1560
  };
1479
1561
  }
1480
1562
  }
1563
+ var PLATFORMS, PLATFORM_SET;
1481
1564
  var init_handler = __esm({
1482
1565
  "src/mcp/handler.ts"() {
1483
1566
  "use strict";
1567
+ PLATFORMS = [
1568
+ "x",
1569
+ "linkedin",
1570
+ "instagram",
1571
+ "threads",
1572
+ "youtube"
1573
+ ];
1574
+ PLATFORM_SET = new Set(PLATFORMS);
1484
1575
  }
1485
1576
  });
1486
1577
 
@@ -1490,9 +1581,9 @@ __export(server_exports, {
1490
1581
  startMcpServer: () => startMcpServer
1491
1582
  });
1492
1583
  async function startMcpServer() {
1493
- const client = new import_sdk12.Autoposting();
1584
+ const client = new Autoposting();
1494
1585
  const server = new import_server.Server(
1495
- { name: "autoposting-mcp", version: "0.1.0" },
1586
+ { name: "autoposting-mcp", version: VERSION },
1496
1587
  { capabilities: { tools: {} } }
1497
1588
  );
1498
1589
  server.setRequestHandler(import_types.ListToolsRequestSchema, async () => ({
@@ -1505,14 +1596,14 @@ async function startMcpServer() {
1505
1596
  const transport = new import_stdio.StdioServerTransport();
1506
1597
  await server.connect(transport);
1507
1598
  }
1508
- var import_server, import_stdio, import_types, import_sdk12;
1599
+ var import_server, import_stdio, import_types;
1509
1600
  var init_server = __esm({
1510
1601
  "src/mcp/server.ts"() {
1511
1602
  "use strict";
1512
1603
  import_server = require("@modelcontextprotocol/sdk/server/index.js");
1513
1604
  import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
1514
1605
  import_types = require("@modelcontextprotocol/sdk/types.js");
1515
- import_sdk12 = __toESM(require_dist());
1606
+ init_dist();
1516
1607
  init_tools();
1517
1608
  init_handler();
1518
1609
  }
@@ -1520,17 +1611,19 @@ var init_server = __esm({
1520
1611
 
1521
1612
  // src/cli.ts
1522
1613
  var import_commander19 = require("commander");
1614
+ init_dist();
1523
1615
 
1524
1616
  // src/commands/agents.ts
1525
1617
  var import_commander = require("commander");
1526
- var import_sdk = __toESM(require_dist());
1618
+ init_dist();
1527
1619
 
1528
1620
  // src/auth/credential-store.ts
1529
1621
  var import_node_fs = __toESM(require("fs"));
1530
1622
  var import_node_os = __toESM(require("os"));
1531
1623
  var import_node_path = __toESM(require("path"));
1532
1624
  function getCredentialsPath() {
1533
- const configBase = process.env.XDG_CONFIG_HOME ?? import_node_path.default.join(import_node_os.default.homedir(), ".config");
1625
+ const xdg = process.env.XDG_CONFIG_HOME;
1626
+ const configBase = xdg && import_node_path.default.isAbsolute(xdg) ? xdg : import_node_path.default.join(import_node_os.default.homedir(), ".config");
1534
1627
  return import_node_path.default.join(configBase, "autoposting", "credentials.json");
1535
1628
  }
1536
1629
  function readCredentials() {
@@ -1546,11 +1639,27 @@ function writeCredentials(creds) {
1546
1639
  const filePath = getCredentialsPath();
1547
1640
  const dir = import_node_path.default.dirname(filePath);
1548
1641
  import_node_fs.default.mkdirSync(dir, { recursive: true, mode: 448 });
1549
- import_node_fs.default.writeFileSync(filePath, JSON.stringify(creds, null, 2), { encoding: "utf8", mode: 384 });
1642
+ const tmpPath = `${filePath}.${process.pid}.tmp`;
1643
+ try {
1644
+ import_node_fs.default.writeFileSync(tmpPath, JSON.stringify(creds, null, 2), { encoding: "utf8", mode: 384 });
1645
+ import_node_fs.default.renameSync(tmpPath, filePath);
1646
+ } catch (err) {
1647
+ try {
1648
+ import_node_fs.default.unlinkSync(tmpPath);
1649
+ } catch {
1650
+ }
1651
+ throw err;
1652
+ }
1550
1653
  import_node_fs.default.chmodSync(filePath, 384);
1551
1654
  }
1552
1655
  function saveProfile(name, profile) {
1553
1656
  const existing = readCredentials();
1657
+ if (!existing && import_node_fs.default.existsSync(getCredentialsPath())) {
1658
+ try {
1659
+ import_node_fs.default.renameSync(getCredentialsPath(), `${getCredentialsPath()}.corrupt`);
1660
+ } catch {
1661
+ }
1662
+ }
1554
1663
  const creds = existing ?? { activeProfile: name, profiles: {} };
1555
1664
  creds.profiles[name] = profile;
1556
1665
  creds.activeProfile = name;
@@ -1615,7 +1724,9 @@ function red(text) {
1615
1724
  }
1616
1725
  function detectOutputMode(options) {
1617
1726
  if (options.quiet) return "quiet";
1618
- if (options.json || !process.stdout.isTTY) return "json";
1727
+ if (options.format === "json" || options.json) return "json";
1728
+ if (options.format === "table") return "tty";
1729
+ if (!process.stdout.isTTY) return "json";
1619
1730
  return "tty";
1620
1731
  }
1621
1732
  function formatOutput(data, mode) {
@@ -1748,12 +1859,18 @@ function matchesClass(error, className) {
1748
1859
  return false;
1749
1860
  }
1750
1861
  function exitCodeFromError(error) {
1862
+ const attached = error?.exitCode;
1863
+ if (typeof attached === "number" && Number.isInteger(attached) && attached >= 0) {
1864
+ return attached;
1865
+ }
1751
1866
  if (matchesClass(error, "AuthenticationError")) return EXIT_CODES.AUTH_ERROR;
1752
1867
  if (matchesClass(error, "ScopeError")) return EXIT_CODES.SCOPE_ERROR;
1753
1868
  if (matchesClass(error, "NotFoundError")) return EXIT_CODES.NOT_FOUND;
1754
1869
  if (matchesClass(error, "RateLimitError")) return EXIT_CODES.RATE_LIMITED;
1755
1870
  if (matchesClass(error, "ValidationError")) return EXIT_CODES.VALIDATION_ERROR;
1756
1871
  if (matchesClass(error, "NetworkError")) return EXIT_CODES.NETWORK_ERROR;
1872
+ const code = error?.code;
1873
+ if (code === "NETWORK_ERROR" || code === "TIMEOUT") return EXIT_CODES.NETWORK_ERROR;
1757
1874
  return EXIT_CODES.GENERAL_ERROR;
1758
1875
  }
1759
1876
 
@@ -1771,10 +1888,10 @@ function createAgentsCommand() {
1771
1888
  const spinner = printer.spinner("Fetching agents\u2026");
1772
1889
  try {
1773
1890
  const cred = resolveAuth({ apiKey: globals.apiKey });
1774
- const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1891
+ const client = new Autoposting({ apiKey: cred.apiKey });
1775
1892
  const list = await client.agents.list();
1776
1893
  spinner.stop();
1777
- const rows = list.map((a) => ({
1894
+ const rows = list.items.map((a) => ({
1778
1895
  id: a.id,
1779
1896
  name: a.name,
1780
1897
  type: a.type,
@@ -1795,7 +1912,7 @@ function createAgentsCommand() {
1795
1912
  const spinner = printer.spinner(`Fetching agent "${id}"\u2026`);
1796
1913
  try {
1797
1914
  const cred = resolveAuth({ apiKey: globals.apiKey });
1798
- const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1915
+ const client = new Autoposting({ apiKey: cred.apiKey });
1799
1916
  const agent = await client.agents.retrieve(id);
1800
1917
  spinner.stop();
1801
1918
  printer.log(agent);
@@ -1812,7 +1929,7 @@ function createAgentsCommand() {
1812
1929
  const spinner = printer.spinner("Creating agent\u2026");
1813
1930
  try {
1814
1931
  const cred = resolveAuth({ apiKey: globals.apiKey });
1815
- const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1932
+ const client = new Autoposting({ apiKey: cred.apiKey });
1816
1933
  const agent = await client.agents.create({
1817
1934
  name: opts.name,
1818
1935
  type: opts.type,
@@ -1839,7 +1956,7 @@ function createAgentsCommand() {
1839
1956
  const spinner = printer.spinner(`Updating agent "${id}"\u2026`);
1840
1957
  try {
1841
1958
  const cred = resolveAuth({ apiKey: globals.apiKey });
1842
- const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1959
+ const client = new Autoposting({ apiKey: cred.apiKey });
1843
1960
  const agent = await client.agents.update(id, {
1844
1961
  ...opts.name ? { name: opts.name } : {},
1845
1962
  ...opts.prompt ? { prompt: opts.prompt } : {},
@@ -1866,7 +1983,7 @@ function createAgentsCommand() {
1866
1983
  const spinner = printer.spinner(`Deleting agent "${id}"\u2026`);
1867
1984
  try {
1868
1985
  const cred = resolveAuth({ apiKey: globals.apiKey });
1869
- const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1986
+ const client = new Autoposting({ apiKey: cred.apiKey });
1870
1987
  await client.agents.remove(id);
1871
1988
  spinner.stop();
1872
1989
  printer.log(`Agent "${id}" deleted.`);
@@ -1882,10 +1999,10 @@ function createAgentsCommand() {
1882
1999
  const spinner = printer.spinner(`Running agent "${id}"\u2026`);
1883
2000
  try {
1884
2001
  const cred = resolveAuth({ apiKey: globals.apiKey });
1885
- const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1886
- const agentRun = await client.agents.run(id);
2002
+ const client = new Autoposting({ apiKey: cred.apiKey });
2003
+ const queued = await client.agents.run(id);
1887
2004
  spinner.stop();
1888
- printer.log(agentRun);
2005
+ printer.log({ runId: queued.runId, status: queued.status });
1889
2006
  } catch (err) {
1890
2007
  spinner.stop();
1891
2008
  printer.error(err);
@@ -1898,7 +2015,7 @@ function createAgentsCommand() {
1898
2015
  const spinner = printer.spinner(`Toggling agent "${id}"\u2026`);
1899
2016
  try {
1900
2017
  const cred = resolveAuth({ apiKey: globals.apiKey });
1901
- const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
2018
+ const client = new Autoposting({ apiKey: cred.apiKey });
1902
2019
  const agent = await client.agents.toggle(id);
1903
2020
  spinner.stop();
1904
2021
  printer.log(agent);
@@ -1914,10 +2031,10 @@ function createAgentsCommand() {
1914
2031
  const spinner = printer.spinner(`Fetching runs for agent "${id}"\u2026`);
1915
2032
  try {
1916
2033
  const cred = resolveAuth({ apiKey: globals.apiKey });
1917
- const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
2034
+ const client = new Autoposting({ apiKey: cred.apiKey });
1918
2035
  const list = await client.agents.runs(id);
1919
2036
  spinner.stop();
1920
- const rows = list.map((r) => ({
2037
+ const rows = list.items.map((r) => ({
1921
2038
  id: r.id,
1922
2039
  status: r.status,
1923
2040
  output: r.output ? r.output.length > 60 ? `${r.output.slice(0, 57)}\u2026` : r.output : "\u2014",
@@ -1938,8 +2055,32 @@ var import_commander2 = require("commander");
1938
2055
  var import_node_child_process = require("child_process");
1939
2056
 
1940
2057
  // src/auth/device-code-client.ts
2058
+ async function fetchWithTimeout(url, init = {}, timeoutMs = 3e4) {
2059
+ const controller = new AbortController();
2060
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
2061
+ try {
2062
+ return await fetch(url, { ...init, signal: controller.signal });
2063
+ } catch (err) {
2064
+ if (err instanceof Error && err.name === "AbortError") {
2065
+ throw new Error(`Request to ${url} timed out after ${timeoutMs}ms`);
2066
+ }
2067
+ throw err;
2068
+ } finally {
2069
+ clearTimeout(timer);
2070
+ }
2071
+ }
2072
+ async function parseJson(res) {
2073
+ const text = await res.text();
2074
+ try {
2075
+ return JSON.parse(text);
2076
+ } catch {
2077
+ throw new Error(
2078
+ `Expected a JSON response (HTTP ${res.status}) but received non-JSON. Verify the API base URL points at the API, not the web app.`
2079
+ );
2080
+ }
2081
+ }
1941
2082
  async function requestDeviceCode(baseUrl) {
1942
- const res = await fetch(`${baseUrl}/auth/cli/device-code`, {
2083
+ const res = await fetchWithTimeout(`${baseUrl}/auth/cli/device-code`, {
1943
2084
  method: "POST",
1944
2085
  headers: { "Content-Type": "application/json" }
1945
2086
  });
@@ -1947,22 +2088,20 @@ async function requestDeviceCode(baseUrl) {
1947
2088
  const text = await res.text().catch(() => res.statusText);
1948
2089
  throw new Error(`Device code request failed (${res.status}): ${text}`);
1949
2090
  }
1950
- const data = await res.json();
1951
- return data;
2091
+ return parseJson(res);
1952
2092
  }
1953
2093
  async function pollDeviceCode(baseUrl, deviceCode) {
1954
2094
  const url = `${baseUrl}/auth/cli/poll?device_code=${encodeURIComponent(deviceCode)}`;
1955
- const res = await fetch(url);
2095
+ const res = await fetchWithTimeout(url);
1956
2096
  if (!res.ok) {
1957
2097
  const text = await res.text().catch(() => res.statusText);
1958
2098
  throw new Error(`Poll request failed (${res.status}): ${text}`);
1959
2099
  }
1960
- const data = await res.json();
1961
- return data;
2100
+ return parseJson(res);
1962
2101
  }
1963
2102
 
1964
2103
  // src/commands/auth.ts
1965
- var DEFAULT_BASE_URL = "https://app.autoposting.ai";
2104
+ var DEFAULT_BASE_URL = "https://app.autoposting.ai/api-proxy";
1966
2105
  function resolveBaseUrl(globals) {
1967
2106
  return globals.baseUrl ?? process.env.AUTOPOSTING_BASE_URL ?? DEFAULT_BASE_URL;
1968
2107
  }
@@ -2116,7 +2255,7 @@ Enter code ${userCode} at ${verificationUri}
2116
2255
 
2117
2256
  // src/commands/billing.ts
2118
2257
  var import_commander3 = require("commander");
2119
- var import_sdk2 = __toESM(require_dist());
2258
+ init_dist();
2120
2259
  function resolveExitCode2(err) {
2121
2260
  const attached = err.exitCode;
2122
2261
  if (typeof attached === "number") return attached;
@@ -2130,20 +2269,22 @@ function createBillingCommand() {
2130
2269
  const spinner = printer.spinner("Fetching billing status\u2026");
2131
2270
  try {
2132
2271
  const cred = resolveAuth({ apiKey: globals.apiKey });
2133
- const client = new import_sdk2.Autoposting({ apiKey: cred.apiKey });
2272
+ const client = new Autoposting({ apiKey: cred.apiKey });
2134
2273
  const status = await client.billing.status();
2135
2274
  spinner.stop();
2136
2275
  printer.table(
2137
2276
  [
2138
2277
  {
2139
- plan: status.plan,
2140
- status: status.status,
2141
- "trial ends": status.trialEndsAt ?? "\u2014",
2142
- "renewal date": status.renewalDate ?? "\u2014",
2143
- "cancels at": status.cancelAt ?? "\u2014"
2278
+ plan: status.planName,
2279
+ status: status.status ?? "\u2014",
2280
+ cycle: status.billingCycle ?? "\u2014",
2281
+ accounts: `${status.accountsUsed}/${status.accountLimit === -1 ? "\u221E" : status.accountLimit}`,
2282
+ credits: status.creditBalance,
2283
+ renews: status.currentPeriodEnd ?? "\u2014",
2284
+ "trial ends": status.trialEnd ?? "\u2014"
2144
2285
  }
2145
2286
  ],
2146
- ["plan", "status", "trial ends", "renewal date", "cancels at"]
2287
+ ["plan", "status", "cycle", "accounts", "credits", "renews", "trial ends"]
2147
2288
  );
2148
2289
  } catch (err) {
2149
2290
  spinner.stop();
@@ -2157,25 +2298,26 @@ function createBillingCommand() {
2157
2298
  const spinner = printer.spinner("Fetching credit balance\u2026");
2158
2299
  try {
2159
2300
  const cred = resolveAuth({ apiKey: globals.apiKey });
2160
- const client = new import_sdk2.Autoposting({ apiKey: cred.apiKey });
2301
+ const client = new Autoposting({ apiKey: cred.apiKey });
2161
2302
  const credits = await client.billing.credits();
2162
2303
  spinner.stop();
2163
2304
  printer.table(
2164
2305
  [
2165
2306
  {
2166
- total: credits.total,
2167
- used: credits.used,
2168
- remaining: credits.remaining
2307
+ balance: credits.balanceFormatted,
2308
+ "spent (30d)": credits.totalSpent30d
2169
2309
  }
2170
2310
  ],
2171
- ["total", "used", "remaining"]
2311
+ ["balance", "spent (30d)"]
2172
2312
  );
2173
- if (credits.breakdown && Object.keys(credits.breakdown).length > 0) {
2174
- const breakdownRows = Object.entries(credits.breakdown).map(([key, val]) => ({
2175
- category: key,
2176
- credits: val
2313
+ if (credits.recentUsage.length > 0) {
2314
+ const usageRows = credits.recentUsage.map((e) => ({
2315
+ date: e.date,
2316
+ description: e.description,
2317
+ amount: e.amount,
2318
+ type: e.type
2177
2319
  }));
2178
- printer.table(breakdownRows, ["category", "credits"]);
2320
+ printer.table(usageRows, ["date", "description", "amount", "type"]);
2179
2321
  }
2180
2322
  } catch (err) {
2181
2323
  spinner.stop();
@@ -2188,7 +2330,7 @@ function createBillingCommand() {
2188
2330
 
2189
2331
  // src/commands/brands.ts
2190
2332
  var import_commander4 = require("commander");
2191
- var import_sdk3 = __toESM(require_dist());
2333
+ init_dist();
2192
2334
  function createBrandsCommand() {
2193
2335
  const brands = new import_commander4.Command("brands").description("Manage brands");
2194
2336
  brands.command("list").description("List all brands").action(async (_opts, cmd) => {
@@ -2197,7 +2339,7 @@ function createBrandsCommand() {
2197
2339
  const spinner = printer.spinner("Fetching brands\u2026");
2198
2340
  try {
2199
2341
  const cred = resolveAuth({ apiKey: globals.apiKey });
2200
- const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2342
+ const client = new Autoposting({ apiKey: cred.apiKey });
2201
2343
  const list = await client.brands.list();
2202
2344
  spinner.stop();
2203
2345
  const rows = list.map((b) => ({
@@ -2219,7 +2361,7 @@ function createBrandsCommand() {
2219
2361
  const spinner = printer.spinner(`Fetching brand "${slug}"\u2026`);
2220
2362
  try {
2221
2363
  const cred = resolveAuth({ apiKey: globals.apiKey });
2222
- const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2364
+ const client = new Autoposting({ apiKey: cred.apiKey });
2223
2365
  const brand = await client.brands.retrieve(slug);
2224
2366
  spinner.stop();
2225
2367
  printer.log(brand);
@@ -2235,7 +2377,7 @@ function createBrandsCommand() {
2235
2377
  const spinner = printer.spinner("Creating brand\u2026");
2236
2378
  try {
2237
2379
  const cred = resolveAuth({ apiKey: globals.apiKey });
2238
- const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2380
+ const client = new Autoposting({ apiKey: cred.apiKey });
2239
2381
  const brand = await client.brands.create({
2240
2382
  name: opts.name,
2241
2383
  ...opts.timezone ? { timezone: opts.timezone } : {}
@@ -2254,7 +2396,7 @@ function createBrandsCommand() {
2254
2396
  const spinner = printer.spinner(`Updating brand "${slug}"\u2026`);
2255
2397
  try {
2256
2398
  const cred = resolveAuth({ apiKey: globals.apiKey });
2257
- const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2399
+ const client = new Autoposting({ apiKey: cred.apiKey });
2258
2400
  const brand = await client.brands.update(slug, {
2259
2401
  ...opts.name ? { name: opts.name } : {},
2260
2402
  ...opts.timezone ? { timezone: opts.timezone } : {}
@@ -2277,7 +2419,7 @@ function createBrandsCommand() {
2277
2419
  const spinner = printer.spinner(`Deleting brand "${slug}"\u2026`);
2278
2420
  try {
2279
2421
  const cred = resolveAuth({ apiKey: globals.apiKey });
2280
- const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2422
+ const client = new Autoposting({ apiKey: cred.apiKey });
2281
2423
  await client.brands.remove(slug);
2282
2424
  spinner.stop();
2283
2425
  printer.log(`Brand "${slug}" deleted.`);
@@ -2293,7 +2435,7 @@ function createBrandsCommand() {
2293
2435
  const spinner = printer.spinner(`Fetching auth status for "${slug}"\u2026`);
2294
2436
  try {
2295
2437
  const cred = resolveAuth({ apiKey: globals.apiKey });
2296
- const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2438
+ const client = new Autoposting({ apiKey: cred.apiKey });
2297
2439
  const connections = await client.brands.authStatus(slug);
2298
2440
  spinner.stop();
2299
2441
  const rows = connections.map((c) => ({
@@ -2314,7 +2456,7 @@ function createBrandsCommand() {
2314
2456
 
2315
2457
  // src/commands/carousels.ts
2316
2458
  var import_commander5 = require("commander");
2317
- var import_sdk4 = __toESM(require_dist());
2459
+ init_dist();
2318
2460
  function resolveExitCode3(err) {
2319
2461
  const attached = err.exitCode;
2320
2462
  if (typeof attached === "number") return attached;
@@ -2328,10 +2470,10 @@ function createCarouselsCommand() {
2328
2470
  const spinner = printer.spinner("Fetching carousels\u2026");
2329
2471
  try {
2330
2472
  const cred = resolveAuth({ apiKey: globals.apiKey });
2331
- const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2473
+ const client = new Autoposting({ apiKey: cred.apiKey });
2332
2474
  const list = await client.carousels.list();
2333
2475
  spinner.stop();
2334
- const rows = list.map((c) => ({
2476
+ const rows = list.items.map((c) => ({
2335
2477
  id: c.id,
2336
2478
  title: c.title ?? "\u2014",
2337
2479
  slides: c.slides.length,
@@ -2351,7 +2493,7 @@ function createCarouselsCommand() {
2351
2493
  const spinner = printer.spinner(`Fetching carousel "${id}"\u2026`);
2352
2494
  try {
2353
2495
  const cred = resolveAuth({ apiKey: globals.apiKey });
2354
- const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2496
+ const client = new Autoposting({ apiKey: cred.apiKey });
2355
2497
  const carousel = await client.carousels.retrieve(id);
2356
2498
  spinner.stop();
2357
2499
  printer.log(carousel);
@@ -2367,7 +2509,7 @@ function createCarouselsCommand() {
2367
2509
  const spinner = printer.spinner("Creating carousel\u2026");
2368
2510
  try {
2369
2511
  const cred = resolveAuth({ apiKey: globals.apiKey });
2370
- const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2512
+ const client = new Autoposting({ apiKey: cred.apiKey });
2371
2513
  const carousel = await client.carousels.create(
2372
2514
  opts.title ? { title: opts.title } : void 0
2373
2515
  );
@@ -2385,7 +2527,7 @@ function createCarouselsCommand() {
2385
2527
  const spinner = printer.spinner("Generating carousel\u2026");
2386
2528
  try {
2387
2529
  const cred = resolveAuth({ apiKey: globals.apiKey });
2388
- const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2530
+ const client = new Autoposting({ apiKey: cred.apiKey });
2389
2531
  const carousel = await client.carousels.generate({
2390
2532
  topic: opts.topic,
2391
2533
  ...opts.brand ? { brandSlug: opts.brand } : {},
@@ -2405,7 +2547,7 @@ function createCarouselsCommand() {
2405
2547
  const spinner = printer.spinner(`Converting carousel "${id}" to draft\u2026`);
2406
2548
  try {
2407
2549
  const cred = resolveAuth({ apiKey: globals.apiKey });
2408
- const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2550
+ const client = new Autoposting({ apiKey: cred.apiKey });
2409
2551
  const result = await client.carousels.draft(id);
2410
2552
  spinner.stop();
2411
2553
  printer.log(result);
@@ -2425,7 +2567,7 @@ function createCarouselsCommand() {
2425
2567
  const spinner = printer.spinner(`Deleting carousel "${id}"\u2026`);
2426
2568
  try {
2427
2569
  const cred = resolveAuth({ apiKey: globals.apiKey });
2428
- const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2570
+ const client = new Autoposting({ apiKey: cred.apiKey });
2429
2571
  await client.carousels.remove(id);
2430
2572
  spinner.stop();
2431
2573
  printer.log(`Carousel "${id}" deleted.`);
@@ -2440,7 +2582,7 @@ function createCarouselsCommand() {
2440
2582
 
2441
2583
  // src/commands/clips.ts
2442
2584
  var import_commander6 = require("commander");
2443
- var import_sdk5 = __toESM(require_dist());
2585
+ init_dist();
2444
2586
  function resolveExitCode4(err) {
2445
2587
  const attached = err.exitCode;
2446
2588
  if (typeof attached === "number") return attached;
@@ -2454,10 +2596,10 @@ function createClipsCommand() {
2454
2596
  const spinner = printer.spinner("Fetching clips\u2026");
2455
2597
  try {
2456
2598
  const cred = resolveAuth({ apiKey: globals.apiKey });
2457
- const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2599
+ const client = new Autoposting({ apiKey: cred.apiKey });
2458
2600
  const list = await client.clips.list();
2459
2601
  spinner.stop();
2460
- const rows = list.map((c) => ({
2602
+ const rows = list.clips.map((c) => ({
2461
2603
  id: c.id,
2462
2604
  name: c.name,
2463
2605
  status: c.status,
@@ -2476,7 +2618,7 @@ function createClipsCommand() {
2476
2618
  const spinner = printer.spinner(`Fetching clip "${id}"\u2026`);
2477
2619
  try {
2478
2620
  const cred = resolveAuth({ apiKey: globals.apiKey });
2479
- const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2621
+ const client = new Autoposting({ apiKey: cred.apiKey });
2480
2622
  const clip = await client.clips.retrieve(id);
2481
2623
  spinner.stop();
2482
2624
  printer.log(clip);
@@ -2492,7 +2634,7 @@ function createClipsCommand() {
2492
2634
  const spinner = printer.spinner("Uploading clip\u2026");
2493
2635
  try {
2494
2636
  const cred = resolveAuth({ apiKey: globals.apiKey });
2495
- const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2637
+ const client = new Autoposting({ apiKey: cred.apiKey });
2496
2638
  const clip = await client.clips.upload(file, {
2497
2639
  name: opts.name,
2498
2640
  onProgress: (pct) => {
@@ -2513,13 +2655,13 @@ function createClipsCommand() {
2513
2655
  const spinner = printer.spinner("Importing clip\u2026");
2514
2656
  try {
2515
2657
  const cred = resolveAuth({ apiKey: globals.apiKey });
2516
- const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2517
- const clip = await client.clips.importUrl({
2658
+ const client = new Autoposting({ apiKey: cred.apiKey });
2659
+ const { clipId } = await client.clips.importUrl({
2518
2660
  url: opts.url,
2519
2661
  ...opts.name ? { name: opts.name } : {}
2520
2662
  });
2521
2663
  spinner.stop();
2522
- printer.log(clip);
2664
+ printer.log({ clipId });
2523
2665
  } catch (err) {
2524
2666
  spinner.stop();
2525
2667
  printer.error(err);
@@ -2532,10 +2674,10 @@ function createClipsCommand() {
2532
2674
  const spinner = printer.spinner(`Rendering clip "${id}"\u2026`);
2533
2675
  try {
2534
2676
  const cred = resolveAuth({ apiKey: globals.apiKey });
2535
- const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2536
- const clip = await client.clips.render(id);
2677
+ const client = new Autoposting({ apiKey: cred.apiKey });
2678
+ const { jobIds, activeJobIds, reusedJobIds } = await client.clips.render(id);
2537
2679
  spinner.stop();
2538
- printer.log(clip);
2680
+ printer.log({ jobIds, activeJobIds, reusedJobIds });
2539
2681
  } catch (err) {
2540
2682
  spinner.stop();
2541
2683
  printer.error(err);
@@ -2552,7 +2694,7 @@ function createClipsCommand() {
2552
2694
  const spinner = printer.spinner(`Deleting clip "${id}"\u2026`);
2553
2695
  try {
2554
2696
  const cred = resolveAuth({ apiKey: globals.apiKey });
2555
- const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2697
+ const client = new Autoposting({ apiKey: cred.apiKey });
2556
2698
  await client.clips.remove(id);
2557
2699
  spinner.stop();
2558
2700
  printer.log(`Clip "${id}" deleted.`);
@@ -2567,9 +2709,35 @@ function createClipsCommand() {
2567
2709
 
2568
2710
  // src/commands/posts.ts
2569
2711
  var import_commander7 = require("commander");
2570
- var import_sdk6 = __toESM(require_dist());
2712
+ init_dist();
2713
+ var VALID_PLATFORMS = ["x", "linkedin", "instagram", "threads", "youtube"];
2571
2714
  function parsePlatforms(raw) {
2572
- return raw.split(",").map((p) => p.trim());
2715
+ const parts = raw.split(",").map((p) => p.trim()).filter(Boolean);
2716
+ if (parts.length === 0) {
2717
+ throw new Error("No platforms provided. Pass a comma-separated list, e.g. --platforms x,linkedin");
2718
+ }
2719
+ const invalid = parts.filter((p) => !VALID_PLATFORMS.includes(p));
2720
+ if (invalid.length > 0) {
2721
+ throw new Error(
2722
+ `Unsupported platform(s): ${invalid.join(", ")}. Valid platforms: ${VALID_PLATFORMS.join(", ")}`
2723
+ );
2724
+ }
2725
+ return parts;
2726
+ }
2727
+ function parsePositiveInt(value, flag) {
2728
+ const n = Number(value);
2729
+ if (!Number.isInteger(n) || n < 1) {
2730
+ throw new Error(`${flag} must be a positive integer (received "${value}").`);
2731
+ }
2732
+ return n;
2733
+ }
2734
+ function validateScheduledAt(value) {
2735
+ if (Number.isNaN(Date.parse(value)) || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(value)) {
2736
+ throw new Error(
2737
+ `--at must be a valid ISO 8601 datetime, e.g. 2026-06-30T14:00:00Z (received "${value}").`
2738
+ );
2739
+ }
2740
+ return value;
2573
2741
  }
2574
2742
  function resolveExitCode5(err) {
2575
2743
  const attached = err.exitCode;
@@ -2584,15 +2752,15 @@ function createPostsCommand() {
2584
2752
  const spinner = printer.spinner("Fetching posts\u2026");
2585
2753
  try {
2586
2754
  const cred = resolveAuth({ apiKey: globals.apiKey });
2587
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2755
+ const client = new Autoposting({ apiKey: cred.apiKey });
2588
2756
  const result = await client.posts.list({
2589
2757
  brandSlug: opts.brand,
2590
2758
  status: opts.status,
2591
- limit: parseInt(opts.limit, 10),
2592
- page: parseInt(opts.page, 10)
2759
+ limit: parsePositiveInt(opts.limit, "--limit"),
2760
+ page: parsePositiveInt(opts.page, "--page")
2593
2761
  });
2594
2762
  spinner.stop();
2595
- const rows = result.data.map((p) => ({
2763
+ const rows = result.map((p) => ({
2596
2764
  id: p.id,
2597
2765
  brand: p.brandSlug,
2598
2766
  status: p.status,
@@ -2613,7 +2781,7 @@ function createPostsCommand() {
2613
2781
  const spinner = printer.spinner(`Fetching post "${id}"\u2026`);
2614
2782
  try {
2615
2783
  const cred = resolveAuth({ apiKey: globals.apiKey });
2616
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2784
+ const client = new Autoposting({ apiKey: cred.apiKey });
2617
2785
  const post = await client.posts.getById(id);
2618
2786
  spinner.stop();
2619
2787
  printer.log(post);
@@ -2623,19 +2791,23 @@ function createPostsCommand() {
2623
2791
  process.exit(resolveExitCode5(err));
2624
2792
  }
2625
2793
  });
2626
- posts.command("create").description("Create a new post").requiredOption("--brand <slug>", "Brand slug").requiredOption("--text <text>", "Post text content").requiredOption("--platforms <list>", "Comma-separated platforms (e.g. x,linkedin)").option("--at <iso>", "Schedule date/time (ISO 8601)").action(
2794
+ posts.command("create").description("Create a new post").requiredOption("--brand <slug>", "Brand slug").requiredOption("--text <text>", "Post text content").requiredOption("--platforms <list>", "Comma-separated platforms (e.g. x,linkedin)").option("--at <iso>", "Schedule date/time (ISO 8601)").option(
2795
+ "--thread <text...>",
2796
+ "Additional posts appended after --text to form a thread (X/Threads only, max 25)"
2797
+ ).action(
2627
2798
  async (opts, cmd) => {
2628
2799
  const globals = cmd.optsWithGlobals();
2629
2800
  const printer = createPrinter(globals);
2630
2801
  const spinner = printer.spinner("Creating post\u2026");
2631
2802
  try {
2632
2803
  const cred = resolveAuth({ apiKey: globals.apiKey });
2633
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2804
+ const client = new Autoposting({ apiKey: cred.apiKey });
2634
2805
  const post = await client.posts.create({
2635
2806
  brandSlug: opts.brand,
2636
2807
  text: opts.text,
2637
2808
  platforms: parsePlatforms(opts.platforms),
2638
- ...opts.at ? { scheduledAt: opts.at } : {}
2809
+ ...opts.at ? { scheduledAt: validateScheduledAt(opts.at) } : {},
2810
+ ...opts.thread && opts.thread.length > 0 ? { thread: opts.thread } : {}
2639
2811
  });
2640
2812
  spinner.stop();
2641
2813
  printer.log(post);
@@ -2653,11 +2825,11 @@ function createPostsCommand() {
2653
2825
  const spinner = printer.spinner(`Updating post "${id}"\u2026`);
2654
2826
  try {
2655
2827
  const cred = resolveAuth({ apiKey: globals.apiKey });
2656
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2828
+ const client = new Autoposting({ apiKey: cred.apiKey });
2657
2829
  const post = await client.posts.update(id, {
2658
2830
  ...opts.text ? { text: opts.text } : {},
2659
2831
  ...opts.platforms ? { platforms: parsePlatforms(opts.platforms) } : {},
2660
- ...opts.at ? { scheduledAt: opts.at } : {}
2832
+ ...opts.at ? { scheduledAt: validateScheduledAt(opts.at) } : {}
2661
2833
  });
2662
2834
  spinner.stop();
2663
2835
  printer.log(post);
@@ -2678,7 +2850,7 @@ function createPostsCommand() {
2678
2850
  const spinner = printer.spinner(`Deleting post "${id}"\u2026`);
2679
2851
  try {
2680
2852
  const cred = resolveAuth({ apiKey: globals.apiKey });
2681
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2853
+ const client = new Autoposting({ apiKey: cred.apiKey });
2682
2854
  await client.posts.remove(id);
2683
2855
  spinner.stop();
2684
2856
  printer.log(`Post "${id}" deleted.`);
@@ -2694,7 +2866,7 @@ function createPostsCommand() {
2694
2866
  const spinner = printer.spinner(`Publishing post "${id}"\u2026`);
2695
2867
  try {
2696
2868
  const cred = resolveAuth({ apiKey: globals.apiKey });
2697
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2869
+ const client = new Autoposting({ apiKey: cred.apiKey });
2698
2870
  const post = await client.posts.publish(id);
2699
2871
  spinner.stop();
2700
2872
  printer.log(post);
@@ -2710,8 +2882,8 @@ function createPostsCommand() {
2710
2882
  const spinner = printer.spinner(`Scheduling post "${id}"\u2026`);
2711
2883
  try {
2712
2884
  const cred = resolveAuth({ apiKey: globals.apiKey });
2713
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2714
- const post = await client.posts.schedule(id, opts.at);
2885
+ const client = new Autoposting({ apiKey: cred.apiKey });
2886
+ const post = await client.posts.schedule(id, validateScheduledAt(opts.at));
2715
2887
  spinner.stop();
2716
2888
  printer.log(post);
2717
2889
  } catch (err) {
@@ -2726,7 +2898,7 @@ function createPostsCommand() {
2726
2898
  const spinner = printer.spinner(`Retrying post "${id}"\u2026`);
2727
2899
  try {
2728
2900
  const cred = resolveAuth({ apiKey: globals.apiKey });
2729
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2901
+ const client = new Autoposting({ apiKey: cred.apiKey });
2730
2902
  const post = await client.posts.retry(id);
2731
2903
  spinner.stop();
2732
2904
  printer.log(post);
@@ -2742,7 +2914,7 @@ function createPostsCommand() {
2742
2914
  const spinner = printer.spinner(`Rewriting post "${id}"\u2026`);
2743
2915
  try {
2744
2916
  const cred = resolveAuth({ apiKey: globals.apiKey });
2745
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2917
+ const client = new Autoposting({ apiKey: cred.apiKey });
2746
2918
  const post = await client.posts.rewrite(id);
2747
2919
  spinner.stop();
2748
2920
  printer.log(post);
@@ -2758,7 +2930,7 @@ function createPostsCommand() {
2758
2930
  const spinner = printer.spinner(`Scoring post "${id}"\u2026`);
2759
2931
  try {
2760
2932
  const cred = resolveAuth({ apiKey: globals.apiKey });
2761
- const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2933
+ const client = new Autoposting({ apiKey: cred.apiKey });
2762
2934
  const result = await client.posts.score(id);
2763
2935
  spinner.stop();
2764
2936
  printer.log(result);
@@ -2773,7 +2945,7 @@ function createPostsCommand() {
2773
2945
 
2774
2946
  // src/commands/kb.ts
2775
2947
  var import_commander8 = require("commander");
2776
- var import_sdk7 = __toESM(require_dist());
2948
+ init_dist();
2777
2949
  function resolveExitCode6(err) {
2778
2950
  const attached = err.exitCode;
2779
2951
  if (typeof attached === "number") return attached;
@@ -2787,7 +2959,7 @@ function createKbCommand() {
2787
2959
  const spinner = printer.spinner("Fetching knowledge bases\u2026");
2788
2960
  try {
2789
2961
  const cred = resolveAuth({ apiKey: globals.apiKey });
2790
- const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2962
+ const client = new Autoposting({ apiKey: cred.apiKey });
2791
2963
  const list = await client.kb.list();
2792
2964
  spinner.stop();
2793
2965
  const rows = list.map((k) => ({
@@ -2809,7 +2981,7 @@ function createKbCommand() {
2809
2981
  const spinner = printer.spinner(`Fetching knowledge base "${id}"\u2026`);
2810
2982
  try {
2811
2983
  const cred = resolveAuth({ apiKey: globals.apiKey });
2812
- const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2984
+ const client = new Autoposting({ apiKey: cred.apiKey });
2813
2985
  const result = await client.kb.retrieve(id);
2814
2986
  spinner.stop();
2815
2987
  printer.log(result);
@@ -2825,7 +2997,7 @@ function createKbCommand() {
2825
2997
  const spinner = printer.spinner("Creating knowledge base\u2026");
2826
2998
  try {
2827
2999
  const cred = resolveAuth({ apiKey: globals.apiKey });
2828
- const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
3000
+ const client = new Autoposting({ apiKey: cred.apiKey });
2829
3001
  const result = await client.kb.create({ name: opts.name });
2830
3002
  spinner.stop();
2831
3003
  printer.log(result);
@@ -2845,7 +3017,7 @@ function createKbCommand() {
2845
3017
  const spinner = printer.spinner(`Deleting knowledge base "${id}"\u2026`);
2846
3018
  try {
2847
3019
  const cred = resolveAuth({ apiKey: globals.apiKey });
2848
- const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
3020
+ const client = new Autoposting({ apiKey: cred.apiKey });
2849
3021
  await client.kb.remove(id);
2850
3022
  spinner.stop();
2851
3023
  printer.log(`Knowledge base "${id}" deleted.`);
@@ -2861,15 +3033,16 @@ function createKbCommand() {
2861
3033
  const spinner = printer.spinner(`Searching knowledge base "${id}"\u2026`);
2862
3034
  try {
2863
3035
  const cred = resolveAuth({ apiKey: globals.apiKey });
2864
- const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2865
- const results = await client.kb.search(id, opts.query);
3036
+ const client = new Autoposting({ apiKey: cred.apiKey });
3037
+ const res = await client.kb.search(id, opts.query);
2866
3038
  spinner.stop();
2867
- const rows = results.map((r) => ({
2868
- docId: r.docId,
2869
- score: r.score.toFixed(3),
3039
+ const rows = res.results.map((r) => ({
3040
+ kind: r.kind,
3041
+ score: r.score != null ? r.score.toFixed(3) : "\u2014",
3042
+ uri: r.uri ?? "\u2014",
2870
3043
  content: r.content.length > 80 ? `${r.content.slice(0, 77)}\u2026` : r.content
2871
3044
  }));
2872
- printer.table(rows, ["docId", "score", "content"]);
3045
+ printer.table(rows, ["kind", "score", "uri", "content"]);
2873
3046
  } catch (err) {
2874
3047
  spinner.stop();
2875
3048
  printer.error(err);
@@ -2882,7 +3055,7 @@ function createKbCommand() {
2882
3055
  const spinner = printer.spinner(`Ingesting URL into knowledge base "${id}"\u2026`);
2883
3056
  try {
2884
3057
  const cred = resolveAuth({ apiKey: globals.apiKey });
2885
- const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
3058
+ const client = new Autoposting({ apiKey: cred.apiKey });
2886
3059
  const doc = await client.kb.ingestUrl(id, opts.url);
2887
3060
  spinner.stop();
2888
3061
  printer.log(doc);
@@ -2898,7 +3071,7 @@ function createKbCommand() {
2898
3071
  const spinner = printer.spinner(`Fetching documents for knowledge base "${id}"\u2026`);
2899
3072
  try {
2900
3073
  const cred = resolveAuth({ apiKey: globals.apiKey });
2901
- const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
3074
+ const client = new Autoposting({ apiKey: cred.apiKey });
2902
3075
  const docs = await client.kb.docs(id);
2903
3076
  spinner.stop();
2904
3077
  const rows = docs.map((d) => ({
@@ -2920,12 +3093,29 @@ function createKbCommand() {
2920
3093
 
2921
3094
  // src/commands/ideas.ts
2922
3095
  var import_commander9 = require("commander");
2923
- var import_sdk8 = __toESM(require_dist());
3096
+ init_dist();
2924
3097
  function resolveExitCode7(err) {
2925
3098
  const attached = err.exitCode;
2926
3099
  if (typeof attached === "number") return attached;
2927
3100
  return exitCodeFromError(err);
2928
3101
  }
3102
+ var VALID_IDEA_PLATFORMS = ["twitter", "linkedin", "instagram", "youtube", "threads"];
3103
+ function parseIdeaPlatforms(raw) {
3104
+ const parts = raw.split(",").map((p) => p.trim()).filter(Boolean);
3105
+ if (parts.length === 0) {
3106
+ throw new Error("No platforms provided. e.g. --platforms twitter,linkedin");
3107
+ }
3108
+ if (parts.length > 5) {
3109
+ throw new Error("At most 5 platforms allowed per enrichment request.");
3110
+ }
3111
+ const invalid = parts.filter((p) => !VALID_IDEA_PLATFORMS.includes(p));
3112
+ if (invalid.length > 0) {
3113
+ throw new Error(
3114
+ `Unsupported platform(s): ${invalid.join(", ")}. Valid: ${VALID_IDEA_PLATFORMS.join(", ")}`
3115
+ );
3116
+ }
3117
+ return parts.map((platform) => ({ platform }));
3118
+ }
2929
3119
  function createIdeasCommand() {
2930
3120
  const ideas = new import_commander9.Command("ideas").description("Manage content ideas");
2931
3121
  ideas.command("generate").description("Generate content ideas").option("--kb <id>", "Knowledge base ID to draw context from").option("--topic <text>", "Topic or theme for ideas").option("--count <n>", "Number of ideas to generate", "5").action(async (opts, cmd) => {
@@ -2934,20 +3124,20 @@ function createIdeasCommand() {
2934
3124
  const spinner = printer.spinner("Generating ideas\u2026");
2935
3125
  try {
2936
3126
  const cred = resolveAuth({ apiKey: globals.apiKey });
2937
- const client = new import_sdk8.Autoposting({ apiKey: cred.apiKey });
3127
+ const client = new Autoposting({ apiKey: cred.apiKey });
2938
3128
  const result = await client.ideas.generate({
2939
3129
  ...opts.kb ? { kbId: opts.kb } : {},
2940
3130
  ...opts.topic ? { topic: opts.topic } : {},
2941
3131
  count: parseInt(opts.count, 10)
2942
3132
  });
2943
3133
  spinner.stop();
2944
- const rows = result.map((i) => ({
2945
- id: i.id,
2946
- topic: i.topic ?? "\u2014",
2947
- enriched: i.enriched ? "yes" : "no",
2948
- text: i.text.length > 80 ? `${i.text.slice(0, 77)}\u2026` : i.text
3134
+ const rows = (result.ideas ?? []).map((i) => ({
3135
+ id: i.id ?? "\u2014",
3136
+ platform: i.targetPlatform,
3137
+ score: i.viralityScore,
3138
+ title: i.title.length > 80 ? `${i.title.slice(0, 77)}\u2026` : i.title
2949
3139
  }));
2950
- printer.table(rows, ["id", "topic", "enriched", "text"]);
3140
+ printer.table(rows, ["id", "platform", "score", "title"]);
2951
3141
  } catch (err) {
2952
3142
  spinner.stop();
2953
3143
  printer.error(err);
@@ -2960,39 +3150,46 @@ function createIdeasCommand() {
2960
3150
  const spinner = printer.spinner("Fetching ideas\u2026");
2961
3151
  try {
2962
3152
  const cred = resolveAuth({ apiKey: globals.apiKey });
2963
- const client = new import_sdk8.Autoposting({ apiKey: cred.apiKey });
3153
+ const client = new Autoposting({ apiKey: cred.apiKey });
2964
3154
  const list = await client.ideas.list();
2965
3155
  spinner.stop();
2966
- const rows = list.map((i) => ({
3156
+ const rows = list.items.map((i) => ({
2967
3157
  id: i.id,
2968
- topic: i.topic ?? "\u2014",
2969
- enriched: i.enriched ? "yes" : "no",
2970
- text: i.text.length > 80 ? `${i.text.slice(0, 77)}\u2026` : i.text,
2971
- createdAt: i.createdAt
3158
+ topic: i.topic || "\u2014",
3159
+ platform: i.targetPlatform,
3160
+ score: i.viralityScore,
3161
+ status: i.status,
3162
+ title: i.title.length > 60 ? `${i.title.slice(0, 57)}\u2026` : i.title
2972
3163
  }));
2973
- printer.table(rows, ["id", "topic", "enriched", "text", "createdAt"]);
3164
+ printer.table(rows, ["id", "topic", "platform", "score", "status", "title"]);
2974
3165
  } catch (err) {
2975
3166
  spinner.stop();
2976
3167
  printer.error(err);
2977
3168
  process.exit(resolveExitCode7(err));
2978
3169
  }
2979
3170
  });
2980
- ideas.command("enrich <id>").description("Enrich an idea with AI context").action(async (id, _opts, cmd) => {
2981
- const globals = cmd.optsWithGlobals();
2982
- const printer = createPrinter(globals);
2983
- const spinner = printer.spinner(`Enriching idea "${id}"\u2026`);
2984
- try {
2985
- const cred = resolveAuth({ apiKey: globals.apiKey });
2986
- const client = new import_sdk8.Autoposting({ apiKey: cred.apiKey });
2987
- const idea = await client.ideas.enrich(id);
2988
- spinner.stop();
2989
- printer.log(idea);
2990
- } catch (err) {
2991
- spinner.stop();
2992
- printer.error(err);
2993
- process.exit(resolveExitCode7(err));
3171
+ ideas.command("enrich").description("Enrich an idea into platform-ready drafts (async; returns a job ID)").requiredOption("--title <text>", "Idea title").requiredOption("--hook <text>", "Idea hook").requiredOption("--angle <text>", "Idea angle").requiredOption("--platforms <list>", `Comma-separated platforms (${VALID_IDEA_PLATFORMS.join(",")})`).option("--kb <id>", "Knowledge base ID for additional context").action(
3172
+ async (opts, cmd) => {
3173
+ const globals = cmd.optsWithGlobals();
3174
+ const printer = createPrinter(globals);
3175
+ const spinner = printer.spinner("Queuing enrichment\u2026");
3176
+ try {
3177
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3178
+ const client = new Autoposting({ apiKey: cred.apiKey });
3179
+ const { jobId } = await client.ideas.enrich({
3180
+ idea: { title: opts.title, hook: opts.hook, angle: opts.angle },
3181
+ platforms: parseIdeaPlatforms(opts.platforms),
3182
+ ...opts.kb ? { kbId: opts.kb } : {}
3183
+ });
3184
+ spinner.stop();
3185
+ printer.log(`Enrichment queued. Job ID: ${jobId}`);
3186
+ } catch (err) {
3187
+ spinner.stop();
3188
+ printer.error(err);
3189
+ process.exit(resolveExitCode7(err));
3190
+ }
2994
3191
  }
2995
- });
3192
+ );
2996
3193
  ideas.command("delete <id>").description("Delete an idea (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (id, opts, cmd) => {
2997
3194
  const globals = cmd.optsWithGlobals();
2998
3195
  const printer = createPrinter(globals);
@@ -3003,7 +3200,7 @@ function createIdeasCommand() {
3003
3200
  const spinner = printer.spinner(`Deleting idea "${id}"\u2026`);
3004
3201
  try {
3005
3202
  const cred = resolveAuth({ apiKey: globals.apiKey });
3006
- const client = new import_sdk8.Autoposting({ apiKey: cred.apiKey });
3203
+ const client = new Autoposting({ apiKey: cred.apiKey });
3007
3204
  await client.ideas.remove(id);
3008
3205
  spinner.stop();
3009
3206
  printer.log(`Idea "${id}" deleted.`);
@@ -3018,7 +3215,7 @@ function createIdeasCommand() {
3018
3215
 
3019
3216
  // src/commands/usage.ts
3020
3217
  var import_commander10 = require("commander");
3021
- var import_sdk9 = __toESM(require_dist());
3218
+ init_dist();
3022
3219
  function resolveExitCode8(err) {
3023
3220
  const attached = err.exitCode;
3024
3221
  if (typeof attached === "number") return attached;
@@ -3032,21 +3229,28 @@ function createUsageCommand() {
3032
3229
  const spinner = printer.spinner("Fetching usage summary\u2026");
3033
3230
  try {
3034
3231
  const cred = resolveAuth({ apiKey: globals.apiKey });
3035
- const client = new import_sdk9.Autoposting({ apiKey: cred.apiKey });
3232
+ const client = new Autoposting({ apiKey: cred.apiKey });
3036
3233
  const summary = await client.usage.summary();
3037
3234
  spinner.stop();
3038
- const rows = Object.entries(summary.platforms).map(([platform, stats]) => ({
3039
- platform,
3040
- posts: stats.posts,
3041
- published: stats.published,
3042
- failed: stats.failed
3235
+ printer.log(`Period: ${summary.range.from.slice(0, 10)} \u2192 ${summary.range.to.slice(0, 10)}`);
3236
+ printer.table(
3237
+ [
3238
+ {
3239
+ posts: summary.posts.total,
3240
+ published: summary.posts.published,
3241
+ agents: summary.agents.total,
3242
+ "active agents": summary.agents.active,
3243
+ "ai cost (usd)": summary.ai.totalCostUsd,
3244
+ "ai requests": summary.ai.requests
3245
+ }
3246
+ ],
3247
+ ["posts", "published", "agents", "active agents", "ai cost (usd)", "ai requests"]
3248
+ );
3249
+ const sourceRows = Object.entries(summary.posts.bySource).map(([source, count]) => ({
3250
+ source,
3251
+ posts: count
3043
3252
  }));
3044
- if (rows.length === 0) {
3045
- printer.log(`No usage data for period: ${summary.period}`);
3046
- } else {
3047
- printer.log(`Period: ${summary.period}`);
3048
- printer.table(rows, ["platform", "posts", "published", "failed"]);
3049
- }
3253
+ printer.table(sourceRows, ["source", "posts"]);
3050
3254
  } catch (err) {
3051
3255
  spinner.stop();
3052
3256
  printer.error(err);
@@ -3058,7 +3262,7 @@ function createUsageCommand() {
3058
3262
 
3059
3263
  // src/commands/webhooks.ts
3060
3264
  var import_commander11 = require("commander");
3061
- var import_sdk10 = __toESM(require_dist());
3265
+ init_dist();
3062
3266
  function resolveExitCode9(err) {
3063
3267
  const attached = err.exitCode;
3064
3268
  if (typeof attached === "number") return attached;
@@ -3072,7 +3276,7 @@ function createWebhooksCommand() {
3072
3276
  const spinner = printer.spinner("Fetching webhooks\u2026");
3073
3277
  try {
3074
3278
  const cred = resolveAuth({ apiKey: globals.apiKey });
3075
- const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3279
+ const client = new Autoposting({ apiKey: cred.apiKey });
3076
3280
  const list = await client.webhooks.list();
3077
3281
  spinner.stop();
3078
3282
  const rows = list.map((w) => ({
@@ -3095,7 +3299,7 @@ function createWebhooksCommand() {
3095
3299
  const spinner = printer.spinner(`Fetching webhook "${id}"\u2026`);
3096
3300
  try {
3097
3301
  const cred = resolveAuth({ apiKey: globals.apiKey });
3098
- const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3302
+ const client = new Autoposting({ apiKey: cred.apiKey });
3099
3303
  const webhook = await client.webhooks.retrieve(id);
3100
3304
  spinner.stop();
3101
3305
  printer.log(webhook);
@@ -3112,7 +3316,7 @@ function createWebhooksCommand() {
3112
3316
  const spinner = printer.spinner("Creating webhook\u2026");
3113
3317
  try {
3114
3318
  const cred = resolveAuth({ apiKey: globals.apiKey });
3115
- const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3319
+ const client = new Autoposting({ apiKey: cred.apiKey });
3116
3320
  const webhook = await client.webhooks.create({
3117
3321
  url: opts.url,
3118
3322
  events: opts.events.split(",").map((e) => e.trim()),
@@ -3134,7 +3338,7 @@ function createWebhooksCommand() {
3134
3338
  const spinner = printer.spinner(`Updating webhook "${id}"\u2026`);
3135
3339
  try {
3136
3340
  const cred = resolveAuth({ apiKey: globals.apiKey });
3137
- const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3341
+ const client = new Autoposting({ apiKey: cred.apiKey });
3138
3342
  const webhook = await client.webhooks.update(id, {
3139
3343
  ...opts.url ? { url: opts.url } : {},
3140
3344
  ...opts.events ? { events: opts.events.split(",").map((e) => e.trim()) } : {},
@@ -3159,7 +3363,7 @@ function createWebhooksCommand() {
3159
3363
  const spinner = printer.spinner(`Deleting webhook "${id}"\u2026`);
3160
3364
  try {
3161
3365
  const cred = resolveAuth({ apiKey: globals.apiKey });
3162
- const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3366
+ const client = new Autoposting({ apiKey: cred.apiKey });
3163
3367
  await client.webhooks.remove(id);
3164
3368
  spinner.stop();
3165
3369
  printer.log(`Webhook "${id}" deleted.`);
@@ -3175,10 +3379,12 @@ function createWebhooksCommand() {
3175
3379
  const spinner = printer.spinner(`Sending test event to webhook "${id}"\u2026`);
3176
3380
  try {
3177
3381
  const cred = resolveAuth({ apiKey: globals.apiKey });
3178
- const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3179
- await client.webhooks.test(id);
3382
+ const client = new Autoposting({ apiKey: cred.apiKey });
3383
+ const result = await client.webhooks.test(id);
3180
3384
  spinner.stop();
3181
- printer.log(`Test event sent to webhook "${id}".`);
3385
+ printer.log(
3386
+ `Test event sent to webhook "${id}" \u2014 delivered: ${result.delivered ? "yes" : "no"} (HTTP ${result.httpStatus}).`
3387
+ );
3182
3388
  } catch (err) {
3183
3389
  spinner.stop();
3184
3390
  printer.error(err);
@@ -3190,7 +3396,7 @@ function createWebhooksCommand() {
3190
3396
 
3191
3397
  // src/commands/workspaces.ts
3192
3398
  var import_commander12 = require("commander");
3193
- var import_sdk11 = __toESM(require_dist());
3399
+ init_dist();
3194
3400
  function resolveExitCode10(err) {
3195
3401
  const attached = err.exitCode;
3196
3402
  if (typeof attached === "number") return attached;
@@ -3204,14 +3410,14 @@ function createWorkspacesCommand() {
3204
3410
  const spinner = printer.spinner("Fetching workspaces\u2026");
3205
3411
  try {
3206
3412
  const cred = resolveAuth({ apiKey: globals.apiKey });
3207
- const client = new import_sdk11.Autoposting({ apiKey: cred.apiKey });
3208
- const list = await client.workspaces.list();
3413
+ const client = new Autoposting({ apiKey: cred.apiKey });
3414
+ const res = await client.workspaces.list();
3209
3415
  spinner.stop();
3210
- const rows = list.map((w) => ({
3416
+ const rows = res.organizations.map((w) => ({
3211
3417
  id: w.id,
3212
3418
  name: w.name,
3213
3419
  slug: w.slug,
3214
- active: w.isActive ? "yes" : "no",
3420
+ active: w.id === res.activeOrgId ? "yes" : "no",
3215
3421
  createdAt: w.createdAt
3216
3422
  }));
3217
3423
  printer.table(rows, ["id", "name", "slug", "active", "createdAt"]);
@@ -3228,7 +3434,7 @@ function createWorkspacesCommand() {
3228
3434
  try {
3229
3435
  const cred = resolveAuth({ apiKey: globals.apiKey });
3230
3436
  const authSource = cred.source === "flag" || cred.source === "env" || cred.source === "stored" ? "api-key" : "session";
3231
- const client = new import_sdk11.Autoposting({ apiKey: cred.apiKey, authSource });
3437
+ const client = new Autoposting({ apiKey: cred.apiKey, authSource });
3232
3438
  await client.workspaces.switchWorkspace(id);
3233
3439
  spinner.stop();
3234
3440
  printer.log(`Switched to workspace "${id}".`);
@@ -3243,9 +3449,9 @@ function createWorkspacesCommand() {
3243
3449
 
3244
3450
  // src/commands/doctor.ts
3245
3451
  var import_commander13 = require("commander");
3452
+ init_dist();
3246
3453
  var import_node_fs2 = __toESM(require("fs"));
3247
- var VERSION = "0.1.0";
3248
- var API_HEALTH_URL = "https://app.autoposting.ai/api/health";
3454
+ var API_HEALTH_URL = "https://app.autoposting.ai/api-proxy/health";
3249
3455
  async function runChecks() {
3250
3456
  const results = [];
3251
3457
  results.push({ name: "CLI Version", status: "pass", value: VERSION });
@@ -3258,7 +3464,7 @@ async function runChecks() {
3258
3464
  });
3259
3465
  try {
3260
3466
  resolveAuth();
3261
- results.push({ name: "Auth", status: "pass", value: "authenticated" });
3467
+ results.push({ name: "Auth", status: "pass", value: "credentials configured" });
3262
3468
  } catch {
3263
3469
  results.push({ name: "Auth", status: "fail", value: "not configured" });
3264
3470
  }
@@ -3273,7 +3479,11 @@ async function runChecks() {
3273
3479
  value: isSecure ? `${credPath} (0600)` : `${credPath} (mode ${mode.toString(8)} \u2014 expected 0600)`
3274
3480
  });
3275
3481
  } catch {
3276
- results.push({ name: "Credentials", status: "warn", value: "no credentials file found" });
3482
+ results.push({
3483
+ name: "Credentials",
3484
+ status: "warn",
3485
+ value: "no credentials file found"
3486
+ });
3277
3487
  }
3278
3488
  try {
3279
3489
  const controller = new AbortController();
@@ -3312,39 +3522,55 @@ function createDoctorCommand() {
3312
3522
 
3313
3523
  // src/commands/whoami.ts
3314
3524
  var import_commander14 = require("commander");
3525
+ init_dist();
3315
3526
  function createWhoamiCommand() {
3316
- return new import_commander14.Command("whoami").description("Show current authentication identity (alias for `auth whoami`)").action((_opts, cmd) => {
3527
+ return new import_commander14.Command("whoami").description("Show the current identity and validate the key against the server").action(async (_opts, cmd) => {
3528
+ const globals = cmd.optsWithGlobals();
3529
+ let cred;
3317
3530
  try {
3318
- const globals = cmd.optsWithGlobals();
3319
- const cred = resolveAuth({ apiKey: globals.apiKey });
3320
- const masked = `${cred.apiKey.slice(0, 8)}${"*".repeat(Math.max(0, cred.apiKey.length - 8))}`;
3321
- if (globals.json) {
3322
- const out = { source: cred.source, apiKey: masked };
3323
- if (cred.source === "stored") {
3324
- const creds = readCredentials();
3325
- const profileName = creds?.activeProfile ?? "unknown";
3326
- const profile = creds?.profiles[profileName];
3327
- out.profile = profileName;
3328
- if (profile?.workspace) out.workspace = profile.workspace;
3329
- if (profile?.email) out.email = profile.email;
3330
- }
3331
- console.log(JSON.stringify(out, null, 2));
3332
- return;
3333
- }
3334
- console.log(`Source: ${cred.source}`);
3335
- if (cred.source === "stored") {
3336
- const creds = readCredentials();
3337
- const profileName = creds?.activeProfile ?? "unknown";
3338
- const profile = creds?.profiles[profileName];
3339
- console.log(`Profile: ${profileName}`);
3340
- if (profile?.workspace) console.log(`Workspace: ${profile.workspace}`);
3341
- if (profile?.email) console.log(`Email: ${profile.email}`);
3342
- }
3343
- console.log(`API key: ${masked}`);
3531
+ cred = resolveAuth({ apiKey: globals.apiKey });
3344
3532
  } catch (err) {
3345
3533
  console.error(`Error: ${err.message}`);
3346
- process.exit(2);
3534
+ process.exitCode = exitCodeFromError(err);
3535
+ return;
3347
3536
  }
3537
+ const masked = `${cred.apiKey.slice(0, 8)}${"*".repeat(Math.max(0, cred.apiKey.length - 8))}`;
3538
+ let validity = "unverified";
3539
+ try {
3540
+ const client = new Autoposting({ apiKey: cred.apiKey });
3541
+ await client.usage.summary();
3542
+ validity = "valid";
3543
+ } catch (err) {
3544
+ const code = exitCodeFromError(err);
3545
+ validity = code === EXIT_CODES.AUTH_ERROR || code === EXIT_CODES.SCOPE_ERROR ? "rejected" : "unverified";
3546
+ }
3547
+ const exitCode = validity === "rejected" ? EXIT_CODES.AUTH_ERROR : 0;
3548
+ const creds = cred.source === "stored" ? readCredentials() : void 0;
3549
+ const profileName = creds?.activeProfile ?? "unknown";
3550
+ const email = creds?.profiles[profileName]?.email;
3551
+ if (globals.json) {
3552
+ const out = {
3553
+ source: cred.source,
3554
+ apiKey: masked,
3555
+ valid: validity === "valid",
3556
+ validity
3557
+ };
3558
+ if (cred.source === "stored") {
3559
+ out.profile = profileName;
3560
+ if (email) out.email = email;
3561
+ }
3562
+ console.log(JSON.stringify(out, null, 2));
3563
+ process.exitCode = exitCode;
3564
+ return;
3565
+ }
3566
+ console.log(`Source: ${cred.source}`);
3567
+ if (cred.source === "stored") {
3568
+ console.log(`Profile: ${profileName}`);
3569
+ if (email) console.log(`Email: ${email}`);
3570
+ }
3571
+ const tag = validity === "valid" ? "\u2713 valid" : validity === "rejected" ? "\u2717 rejected by server" : "\u26A0 unverified (could not reach server)";
3572
+ console.log(`API key: ${masked} ${tag}`);
3573
+ process.exitCode = exitCode;
3348
3574
  });
3349
3575
  }
3350
3576
 
@@ -3385,11 +3611,13 @@ function createOpenCommand() {
3385
3611
 
3386
3612
  // src/commands/update.ts
3387
3613
  var import_commander16 = require("commander");
3614
+ init_dist();
3388
3615
  var import_node_child_process2 = require("child_process");
3389
- var VERSION2 = "0.1.0";
3390
- var REGISTRY_URL = "https://registry.npmjs.org/autoposting-cli/latest";
3616
+ var REGISTRY_URL = "https://registry.npmjs.org/@autoposting.ai%2fcli/latest";
3391
3617
  function createUpdateCommand() {
3392
- return new import_commander16.Command("update").description("Check for a newer version of the CLI and optionally install it").option("--yes", "Install the latest version without prompting").action(async (opts) => {
3618
+ return new import_commander16.Command("update").description(
3619
+ "Check for a newer version of the CLI and optionally install it"
3620
+ ).option("--yes", "Install the latest version without prompting").action(async (opts) => {
3393
3621
  let latest;
3394
3622
  try {
3395
3623
  const controller = new AbortController();
@@ -3403,22 +3631,26 @@ function createUpdateCommand() {
3403
3631
  const data = await res.json();
3404
3632
  latest = data.version;
3405
3633
  } catch (err) {
3406
- console.error(`Error: could not reach npm registry \u2014 ${err.message}`);
3634
+ console.error(
3635
+ `Error: could not reach npm registry \u2014 ${err.message}`
3636
+ );
3407
3637
  process.exit(1);
3408
3638
  }
3409
- if (latest === VERSION2) {
3410
- console.log(`You are already on the latest version (${VERSION2}).`);
3639
+ if (latest === VERSION) {
3640
+ console.log(`You are already on the latest version (${VERSION}).`);
3411
3641
  return;
3412
3642
  }
3413
- console.log(`Current version: ${VERSION2}`);
3643
+ console.log(`Current version: ${VERSION}`);
3414
3644
  console.log(`Latest version: ${latest}`);
3415
3645
  if (!opts.yes) {
3416
3646
  console.log(`Run \`ap update --yes\` to install v${latest}.`);
3417
3647
  return;
3418
3648
  }
3419
- console.log(`Installing autoposting-cli@${latest}\u2026`);
3649
+ console.log(`Installing @autoposting.ai/cli@${latest}\u2026`);
3420
3650
  try {
3421
- (0, import_node_child_process2.execSync)(`npm install -g autoposting-cli@${latest}`, { stdio: "inherit" });
3651
+ (0, import_node_child_process2.execSync)(`npm install -g @autoposting.ai/cli@${latest}`, {
3652
+ stdio: "inherit"
3653
+ });
3422
3654
  console.log(`Updated to v${latest}.`);
3423
3655
  } catch (err) {
3424
3656
  console.error(`Error: install failed \u2014 ${err.message}`);
@@ -3509,7 +3741,7 @@ function createMcpCommand() {
3509
3741
  }
3510
3742
 
3511
3743
  // src/cli.ts
3512
- var program = new import_commander19.Command().name("autoposting").description("Autoposting CLI \u2014 manage social media from the terminal").version("0.1.0").option("--json", "Output as JSON").option("--quiet", "Suppress spinners and non-essential output").option("--format <type>", "Output format: table, json", "table").option("--api-key <key>", "API key (overrides env/stored credentials)").option("--no-color", "Disable color output").hook("preAction", (thisCommand) => {
3744
+ var program = new import_commander19.Command().name("autoposting").description("Autoposting CLI \u2014 manage social media from the terminal").version(VERSION).option("--json", "Output as JSON").option("--quiet", "Suppress spinners and non-essential output").option("--format <type>", "Output format: table, json", "table").option("--api-key <key>", "API key (overrides env/stored credentials)").option("--no-color", "Disable color output").hook("preAction", (thisCommand) => {
3513
3745
  const opts = thisCommand.opts();
3514
3746
  if (!opts.color) disableColor();
3515
3747
  });