@autoposting.ai/cli 0.2.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 ADDED
@@ -0,0 +1,3535 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
12
+ var __commonJS = (cb, mod) => function __require() {
13
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
14
+ };
15
+ var __export = (target, all) => {
16
+ for (var name in all)
17
+ __defProp(target, name, { get: all[name], enumerable: true });
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
+ }
25
+ return to;
26
+ };
27
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
28
+ // If the importer is in node compatibility mode or this is not an ESM
29
+ // file that has been converted to a CommonJS file using a Babel-
30
+ // compatible transform (i.e. "__esModule" has not been set), then set
31
+ // "default" to the CommonJS "module.exports" for node compatibility.
32
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
33
+ mod
34
+ ));
35
+
36
+ // ../sdk/dist/index.js
37
+ var require_dist = __commonJS({
38
+ "../sdk/dist/index.js"(exports2, module2) {
39
+ "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 {
84
+ status;
85
+ code;
86
+ constructor(message, status, code) {
87
+ super(message);
88
+ this.name = this.constructor.name;
89
+ this.status = status;
90
+ this.code = code;
91
+ Object.setPrototypeOf(this, new.target.prototype);
92
+ }
93
+ };
94
+ var AuthenticationError = class extends AutopostingError {
95
+ };
96
+ var ScopeError = class extends AutopostingError {
97
+ };
98
+ var NotFoundError = class extends AutopostingError {
99
+ };
100
+ var ValidationError = class extends AutopostingError {
101
+ };
102
+ var RateLimitError = class extends AutopostingError {
103
+ retryAfter;
104
+ };
105
+ var ServerError = class extends AutopostingError {
106
+ };
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 {
119
+ constructor(client) {
120
+ this.client = client;
121
+ }
122
+ client;
123
+ get(path2, query) {
124
+ return this.client.request("GET", path2, void 0, query);
125
+ }
126
+ post(path2, body) {
127
+ return this.client.request("POST", path2, body);
128
+ }
129
+ put(path2, body) {
130
+ return this.client.request("PUT", path2, body);
131
+ }
132
+ patch(path2, body) {
133
+ return this.client.request("PATCH", path2, body);
134
+ }
135
+ delete(path2) {
136
+ return this.client.request("DELETE", path2);
137
+ }
138
+ };
139
+ var AgentsResource = class extends Resource {
140
+ list() {
141
+ return this.get("/agents");
142
+ }
143
+ retrieve(id) {
144
+ return this.get(`/agents/${id}`);
145
+ }
146
+ create(params) {
147
+ return this.post("/agents", params);
148
+ }
149
+ update(id, params) {
150
+ return this.patch(`/agents/${id}`, params);
151
+ }
152
+ remove(id) {
153
+ return this.delete(`/agents/${id}`);
154
+ }
155
+ run(id) {
156
+ return this.post(`/agents/${id}/run`);
157
+ }
158
+ toggle(id) {
159
+ return this.post(`/agents/${id}/toggle`);
160
+ }
161
+ runs(id) {
162
+ return this.get(`/agents/${id}/runs`);
163
+ }
164
+ };
165
+ var BillingResource = class extends Resource {
166
+ status() {
167
+ return this.get("/billing/status");
168
+ }
169
+ credits() {
170
+ return this.get("/billing/credits");
171
+ }
172
+ };
173
+ var BrandsResource = class extends Resource {
174
+ list() {
175
+ return this.get("/brands");
176
+ }
177
+ retrieve(slug) {
178
+ return this.get(`/brands/${slug}`);
179
+ }
180
+ create(params) {
181
+ return this.post("/brands", params);
182
+ }
183
+ update(slug, params) {
184
+ return this.patch(`/brands/${slug}`, params);
185
+ }
186
+ remove(slug) {
187
+ return this.delete(`/brands/${slug}`);
188
+ }
189
+ authStatus(slug) {
190
+ return this.get(`/brands/${slug}/auth/status`);
191
+ }
192
+ };
193
+ var CarouselsResource = class extends Resource {
194
+ list() {
195
+ return this.get("/carousels");
196
+ }
197
+ retrieve(id) {
198
+ return this.get(`/carousels/${id}`);
199
+ }
200
+ create(params) {
201
+ return this.post("/carousels", params);
202
+ }
203
+ generate(params) {
204
+ return this.post("/carousels/generate", params);
205
+ }
206
+ /** POST /carousels/:id/draft — converts carousel to a post draft */
207
+ draft(id) {
208
+ return this.post(`/carousels/${id}/draft`);
209
+ }
210
+ remove(id) {
211
+ return this.client.request("DELETE", `/carousels/${id}`);
212
+ }
213
+ };
214
+ var ClipsResource = class extends Resource {
215
+ list() {
216
+ return this.client.request("GET", "/clips");
217
+ }
218
+ retrieve(id) {
219
+ return this.client.request("GET", `/clips/${id}`);
220
+ }
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;
233
+ }
234
+ importUrl(params) {
235
+ return this.client.request("POST", "/clips/import", params);
236
+ }
237
+ render(id) {
238
+ return this.client.request("POST", `/clips/${id}/render`);
239
+ }
240
+ remove(id) {
241
+ return this.client.request("DELETE", `/clips/${id}`);
242
+ }
243
+ };
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 */
254
+ getById(id) {
255
+ return this.client.request("GET", `/v1/posts/${id}`);
256
+ }
257
+ create(params) {
258
+ return this.client.request("POST", "/v1/posts", params);
259
+ }
260
+ update(id, params) {
261
+ return this.client.request("PUT", `/v1/posts/${id}`, params);
262
+ }
263
+ /** DELETE /v1/posts/:id */
264
+ remove(id) {
265
+ return this.client.request("DELETE", `/v1/posts/${id}`);
266
+ }
267
+ publish(id) {
268
+ return this.client.request("POST", `/v1/posts/${id}/publish`);
269
+ }
270
+ schedule(id, scheduledAt) {
271
+ return this.client.request("PUT", `/v1/posts/${id}/schedule`, { scheduledAt });
272
+ }
273
+ retry(id) {
274
+ return this.client.request("POST", `/v1/posts/${id}/retry`);
275
+ }
276
+ rewrite(id) {
277
+ return this.client.request("POST", `/v1/posts/${id}/rewrite`);
278
+ }
279
+ score(id) {
280
+ return this.client.request(
281
+ "POST",
282
+ `/v1/posts/${id}/score`
283
+ );
284
+ }
285
+ };
286
+ var KbResource = class extends Resource {
287
+ list() {
288
+ return this.get("/kbs");
289
+ }
290
+ retrieve(id) {
291
+ return this.get(`/kbs/${id}`);
292
+ }
293
+ create(params) {
294
+ return this.post("/kbs", params);
295
+ }
296
+ remove(id) {
297
+ return this.delete(`/kbs/${id}`);
298
+ }
299
+ search(id, query) {
300
+ return this.post(`/kbs/${id}/search`, { query });
301
+ }
302
+ ingestUrl(id, url) {
303
+ return this.post(`/kbs/${id}/docs/ingest-url`, { url });
304
+ }
305
+ docs(id) {
306
+ return this.get(`/kbs/${id}/docs`);
307
+ }
308
+ };
309
+ var IdeasResource = class extends Resource {
310
+ generate(params = {}) {
311
+ return this.post("/ideas/generate", params);
312
+ }
313
+ list() {
314
+ return this.get("/ideas");
315
+ }
316
+ enrich(id) {
317
+ return this.post(`/ideas/${id}/enrich`);
318
+ }
319
+ remove(id) {
320
+ return this.delete(`/ideas/${id}`);
321
+ }
322
+ };
323
+ var UsageResource = class extends Resource {
324
+ summary() {
325
+ return this.get("/usage/summary");
326
+ }
327
+ };
328
+ var WebhooksResource = class extends Resource {
329
+ list() {
330
+ return this.get("/webhooks");
331
+ }
332
+ retrieve(id) {
333
+ return this.get(`/webhooks/${id}`);
334
+ }
335
+ create(params) {
336
+ return this.post("/webhooks", params);
337
+ }
338
+ update(id, params) {
339
+ return this.patch(`/webhooks/${id}`, params);
340
+ }
341
+ remove(id) {
342
+ return this.client.request("DELETE", `/webhooks/${id}`);
343
+ }
344
+ test(id) {
345
+ return this.post(`/webhooks/${id}/test`);
346
+ }
347
+ };
348
+ var WorkspacesResource = class extends Resource {
349
+ constructor(client) {
350
+ super(client);
351
+ }
352
+ list() {
353
+ return this.get("/orgs");
354
+ }
355
+ switchWorkspace(id) {
356
+ if (this.client.authSource === "api-key") {
357
+ return Promise.reject(
358
+ new Error(
359
+ "API keys are bound to a single workspace. Use session auth to switch."
360
+ )
361
+ );
362
+ }
363
+ return this.post("/orgs/set-active", { organizationId: id });
364
+ }
365
+ };
366
+ var Autoposting13 = class {
367
+ /** @internal Not part of the public API — use SDK methods to make requests. */
368
+ _apiKey;
369
+ baseUrl;
370
+ timeout;
371
+ extraHeaders;
372
+ /** Indicates how the client was authenticated; used by WorkspacesResource. */
373
+ authSource;
374
+ agents;
375
+ billing;
376
+ brands;
377
+ carousels;
378
+ clips;
379
+ posts;
380
+ kb;
381
+ ideas;
382
+ usage;
383
+ webhooks;
384
+ workspaces;
385
+ constructor(config = {}) {
386
+ const key = config.apiKey ?? process.env.AUTOPOSTING_API_KEY;
387
+ if (!key) {
388
+ throw new Error(
389
+ "API key is required. Pass apiKey in config or set AUTOPOSTING_API_KEY env var."
390
+ );
391
+ }
392
+ this._apiKey = key;
393
+ this.baseUrl = (config.baseUrl ?? "https://api.autoposting.ai").replace(/\/$/, "");
394
+ this.timeout = config.timeout ?? 3e4;
395
+ this.extraHeaders = config.headers ?? {};
396
+ this.authSource = config.authSource ?? "api-key";
397
+ this.agents = new AgentsResource(this);
398
+ this.billing = new BillingResource(this);
399
+ this.brands = new BrandsResource(this);
400
+ this.carousels = new CarouselsResource(this);
401
+ this.clips = new ClipsResource(this);
402
+ this.posts = new PostsResource(this);
403
+ this.kb = new KbResource(this);
404
+ this.ideas = new IdeasResource(this);
405
+ this.usage = new UsageResource(this);
406
+ this.webhooks = new WebhooksResource(this);
407
+ this.workspaces = new WorkspacesResource(this);
408
+ }
409
+ async request(method, path2, body, query) {
410
+ let url = `${this.baseUrl}${path2}`;
411
+ if (query && Object.keys(query).length > 0) {
412
+ const params = new URLSearchParams();
413
+ for (const [k, v] of Object.entries(query)) {
414
+ if (v !== void 0 && v !== null) {
415
+ params.set(k, String(v));
416
+ }
417
+ }
418
+ url = `${url}?${params.toString()}`;
419
+ }
420
+ const isFormData = body instanceof FormData;
421
+ const headers = {
422
+ authorization: `Bearer ${this._apiKey}`,
423
+ "user-agent": `autoposting-sdk/${VERSION3}`,
424
+ "x-source": "sdk",
425
+ ...this.extraHeaders
426
+ };
427
+ if (!isFormData) {
428
+ headers["content-type"] = "application/json";
429
+ }
430
+ const controller = new AbortController();
431
+ const timer = setTimeout(() => controller.abort(), this.timeout);
432
+ let response;
433
+ 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 = {};
445
+ try {
446
+ errorBody = await response.json();
447
+ } catch {
448
+ }
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);
454
+ }
455
+ }
456
+ throw err;
457
+ }
458
+ if (response.status === 204) {
459
+ return {};
460
+ }
461
+ return response.json();
462
+ }
463
+ };
464
+ }
465
+ });
466
+
467
+ // src/mcp/tools.ts
468
+ var ALL_TOOLS;
469
+ var init_tools = __esm({
470
+ "src/mcp/tools.ts"() {
471
+ "use strict";
472
+ ALL_TOOLS = [
473
+ // Posts
474
+ {
475
+ name: "list-posts",
476
+ description: "List posts with optional filters by brand, status, limit, and page.",
477
+ inputSchema: {
478
+ type: "object",
479
+ properties: {
480
+ brandSlug: { type: "string", description: "Filter by brand slug" },
481
+ status: {
482
+ type: "string",
483
+ enum: ["draft", "scheduled", "published", "failed"],
484
+ description: "Filter by post status"
485
+ },
486
+ limit: { type: "number", description: "Max results per page (default 20)" },
487
+ page: { type: "number", description: "Page number (default 1)" }
488
+ },
489
+ additionalProperties: false
490
+ }
491
+ },
492
+ {
493
+ name: "get-post",
494
+ description: "Get a post by its ID.",
495
+ inputSchema: {
496
+ type: "object",
497
+ properties: {
498
+ id: { type: "string", description: "Post ID" }
499
+ },
500
+ required: ["id"],
501
+ additionalProperties: false
502
+ }
503
+ },
504
+ {
505
+ name: "create-post",
506
+ description: "Create a new post draft for a brand on one or more platforms.",
507
+ inputSchema: {
508
+ type: "object",
509
+ properties: {
510
+ brandSlug: { type: "string", description: "Brand slug to post under" },
511
+ text: { type: "string", description: "Post text content" },
512
+ platforms: {
513
+ type: "string",
514
+ description: "Comma-separated platform list (e.g. x,linkedin)"
515
+ },
516
+ scheduledAt: {
517
+ type: "string",
518
+ description: "ISO 8601 datetime to schedule the post"
519
+ }
520
+ },
521
+ required: ["brandSlug", "text", "platforms"],
522
+ additionalProperties: false
523
+ }
524
+ },
525
+ {
526
+ name: "update-post",
527
+ description: "Update the text, platforms, or scheduled time of an existing post.",
528
+ inputSchema: {
529
+ type: "object",
530
+ properties: {
531
+ id: { type: "string", description: "Post ID" },
532
+ text: { type: "string", description: "New post text" },
533
+ platforms: { type: "string", description: "Comma-separated new platform list" },
534
+ scheduledAt: { type: "string", description: "New ISO 8601 scheduled datetime" }
535
+ },
536
+ required: ["id"],
537
+ additionalProperties: false
538
+ }
539
+ },
540
+ {
541
+ name: "delete-post",
542
+ description: "Permanently delete a post by ID.",
543
+ inputSchema: {
544
+ type: "object",
545
+ properties: {
546
+ id: { type: "string", description: "Post ID to delete" }
547
+ },
548
+ required: ["id"],
549
+ additionalProperties: false
550
+ }
551
+ },
552
+ {
553
+ name: "publish-post",
554
+ description: "Immediately publish a post to all its platforms.",
555
+ inputSchema: {
556
+ type: "object",
557
+ properties: {
558
+ id: { type: "string", description: "Post ID to publish" }
559
+ },
560
+ required: ["id"],
561
+ additionalProperties: false
562
+ }
563
+ },
564
+ {
565
+ name: "schedule-post",
566
+ description: "Schedule a post to be published at a specific date and time.",
567
+ inputSchema: {
568
+ type: "object",
569
+ properties: {
570
+ id: { type: "string", description: "Post ID to schedule" },
571
+ scheduledAt: { type: "string", description: "ISO 8601 datetime for publishing" }
572
+ },
573
+ required: ["id", "scheduledAt"],
574
+ additionalProperties: false
575
+ }
576
+ },
577
+ {
578
+ name: "retry-post",
579
+ description: "Retry publishing a failed post.",
580
+ inputSchema: {
581
+ type: "object",
582
+ properties: {
583
+ id: { type: "string", description: "Post ID to retry" }
584
+ },
585
+ required: ["id"],
586
+ additionalProperties: false
587
+ }
588
+ },
589
+ {
590
+ name: "rewrite-post",
591
+ description: "AI-rewrite the text of a post.",
592
+ inputSchema: {
593
+ type: "object",
594
+ properties: {
595
+ id: { type: "string", description: "Post ID to rewrite" }
596
+ },
597
+ required: ["id"],
598
+ additionalProperties: false
599
+ }
600
+ },
601
+ {
602
+ name: "score-post",
603
+ description: "Score a post with AI feedback and return a numeric score with explanation.",
604
+ inputSchema: {
605
+ type: "object",
606
+ properties: {
607
+ id: { type: "string", description: "Post ID to score" }
608
+ },
609
+ required: ["id"],
610
+ additionalProperties: false
611
+ }
612
+ },
613
+ // Brands
614
+ {
615
+ name: "list-brands",
616
+ description: "List all brands in the workspace.",
617
+ inputSchema: {
618
+ type: "object",
619
+ properties: {},
620
+ additionalProperties: false
621
+ }
622
+ },
623
+ {
624
+ name: "get-brand",
625
+ description: "Get a brand by its slug.",
626
+ inputSchema: {
627
+ type: "object",
628
+ properties: {
629
+ brandSlug: { type: "string", description: "Brand slug" }
630
+ },
631
+ required: ["brandSlug"],
632
+ additionalProperties: false
633
+ }
634
+ },
635
+ {
636
+ name: "create-brand",
637
+ description: "Create a new brand in the workspace.",
638
+ inputSchema: {
639
+ type: "object",
640
+ properties: {
641
+ name: { type: "string", description: "Brand display name" },
642
+ timezone: { type: "string", description: "IANA timezone (e.g. America/New_York)" }
643
+ },
644
+ required: ["name"],
645
+ additionalProperties: false
646
+ }
647
+ },
648
+ {
649
+ name: "update-brand",
650
+ description: "Update a brand name or timezone.",
651
+ inputSchema: {
652
+ type: "object",
653
+ properties: {
654
+ brandSlug: { type: "string", description: "Brand slug to update" },
655
+ name: { type: "string", description: "New display name" },
656
+ timezone: { type: "string", description: "New IANA timezone" }
657
+ },
658
+ required: ["brandSlug"],
659
+ additionalProperties: false
660
+ }
661
+ },
662
+ {
663
+ name: "delete-brand",
664
+ description: "Permanently delete a brand by slug.",
665
+ inputSchema: {
666
+ type: "object",
667
+ properties: {
668
+ brandSlug: { type: "string", description: "Brand slug to delete" }
669
+ },
670
+ required: ["brandSlug"],
671
+ additionalProperties: false
672
+ }
673
+ },
674
+ {
675
+ name: "brand-auth-status",
676
+ description: "Show the platform connection status for a brand.",
677
+ inputSchema: {
678
+ type: "object",
679
+ properties: {
680
+ brandSlug: { type: "string", description: "Brand slug" }
681
+ },
682
+ required: ["brandSlug"],
683
+ additionalProperties: false
684
+ }
685
+ },
686
+ // Agents
687
+ {
688
+ name: "list-agents",
689
+ description: "List all agents in the workspace.",
690
+ inputSchema: {
691
+ type: "object",
692
+ properties: {},
693
+ additionalProperties: false
694
+ }
695
+ },
696
+ {
697
+ name: "get-agent",
698
+ description: "Get an agent by its ID.",
699
+ inputSchema: {
700
+ type: "object",
701
+ properties: {
702
+ id: { type: "string", description: "Agent ID" }
703
+ },
704
+ required: ["id"],
705
+ additionalProperties: false
706
+ }
707
+ },
708
+ {
709
+ name: "create-agent",
710
+ description: "Create a new publish or research agent.",
711
+ inputSchema: {
712
+ type: "object",
713
+ properties: {
714
+ name: { type: "string", description: "Agent name" },
715
+ type: {
716
+ type: "string",
717
+ enum: ["publish", "research"],
718
+ description: "Agent type"
719
+ },
720
+ brandSlug: { type: "string", description: "Brand slug to associate with" },
721
+ prompt: { type: "string", description: "Agent instructions or prompt" },
722
+ frequency: {
723
+ type: "string",
724
+ enum: ["manual", "daily", "weekly"],
725
+ description: "Run frequency"
726
+ },
727
+ time: { type: "string", description: "Time of day to run (HH:MM)" },
728
+ weekday: { type: "string", description: "Day of week (required for weekly frequency)" },
729
+ kbId: { type: "string", description: "Knowledge base ID to attach" }
730
+ },
731
+ required: ["name", "type", "prompt", "frequency"],
732
+ additionalProperties: false
733
+ }
734
+ },
735
+ {
736
+ name: "update-agent",
737
+ description: "Update an agent name, prompt, frequency, or schedule.",
738
+ inputSchema: {
739
+ type: "object",
740
+ properties: {
741
+ id: { type: "string", description: "Agent ID" },
742
+ name: { type: "string", description: "New agent name" },
743
+ prompt: { type: "string", description: "New prompt" },
744
+ frequency: { type: "string", description: "New frequency: manual, daily, or weekly" },
745
+ time: { type: "string", description: "New time of day (HH:MM)" },
746
+ weekday: { type: "string", description: "New day of week" }
747
+ },
748
+ required: ["id"],
749
+ additionalProperties: false
750
+ }
751
+ },
752
+ {
753
+ name: "delete-agent",
754
+ description: "Permanently delete an agent by ID.",
755
+ inputSchema: {
756
+ type: "object",
757
+ properties: {
758
+ id: { type: "string", description: "Agent ID to delete" }
759
+ },
760
+ required: ["id"],
761
+ additionalProperties: false
762
+ }
763
+ },
764
+ {
765
+ name: "run-agent",
766
+ description: "Trigger an immediate run of an agent.",
767
+ inputSchema: {
768
+ type: "object",
769
+ properties: {
770
+ id: { type: "string", description: "Agent ID to run" }
771
+ },
772
+ required: ["id"],
773
+ additionalProperties: false
774
+ }
775
+ },
776
+ {
777
+ name: "toggle-agent",
778
+ description: "Enable or disable an agent.",
779
+ inputSchema: {
780
+ type: "object",
781
+ properties: {
782
+ id: { type: "string", description: "Agent ID to toggle" }
783
+ },
784
+ required: ["id"],
785
+ additionalProperties: false
786
+ }
787
+ },
788
+ {
789
+ name: "agent-runs",
790
+ description: "List the run history for an agent.",
791
+ inputSchema: {
792
+ type: "object",
793
+ properties: {
794
+ id: { type: "string", description: "Agent ID" }
795
+ },
796
+ required: ["id"],
797
+ additionalProperties: false
798
+ }
799
+ },
800
+ // Knowledge Bases
801
+ {
802
+ name: "list-kbs",
803
+ description: "List all knowledge bases in the workspace.",
804
+ inputSchema: {
805
+ type: "object",
806
+ properties: {},
807
+ additionalProperties: false
808
+ }
809
+ },
810
+ {
811
+ name: "get-kb",
812
+ description: "Get a knowledge base by its ID.",
813
+ inputSchema: {
814
+ type: "object",
815
+ properties: {
816
+ id: { type: "string", description: "Knowledge base ID" }
817
+ },
818
+ required: ["id"],
819
+ additionalProperties: false
820
+ }
821
+ },
822
+ {
823
+ name: "create-kb",
824
+ description: "Create a new knowledge base.",
825
+ inputSchema: {
826
+ type: "object",
827
+ properties: {
828
+ name: { type: "string", description: "Knowledge base name" }
829
+ },
830
+ required: ["name"],
831
+ additionalProperties: false
832
+ }
833
+ },
834
+ {
835
+ name: "delete-kb",
836
+ description: "Permanently delete a knowledge base by ID.",
837
+ inputSchema: {
838
+ type: "object",
839
+ properties: {
840
+ id: { type: "string", description: "Knowledge base ID to delete" }
841
+ },
842
+ required: ["id"],
843
+ additionalProperties: false
844
+ }
845
+ },
846
+ {
847
+ name: "search-kb",
848
+ description: "Search a knowledge base with a text query.",
849
+ inputSchema: {
850
+ type: "object",
851
+ properties: {
852
+ id: { type: "string", description: "Knowledge base ID to search" },
853
+ query: { type: "string", description: "Search query text" }
854
+ },
855
+ required: ["id", "query"],
856
+ additionalProperties: false
857
+ }
858
+ },
859
+ {
860
+ name: "ingest-kb",
861
+ description: "Ingest a URL into a knowledge base.",
862
+ inputSchema: {
863
+ type: "object",
864
+ properties: {
865
+ id: { type: "string", description: "Knowledge base ID to ingest into" },
866
+ url: { type: "string", description: "URL to ingest" }
867
+ },
868
+ required: ["id", "url"],
869
+ additionalProperties: false
870
+ }
871
+ },
872
+ {
873
+ name: "kb-docs",
874
+ description: "List documents stored in a knowledge base.",
875
+ inputSchema: {
876
+ type: "object",
877
+ properties: {
878
+ id: { type: "string", description: "Knowledge base ID" }
879
+ },
880
+ required: ["id"],
881
+ additionalProperties: false
882
+ }
883
+ },
884
+ // Ideas
885
+ {
886
+ name: "generate-ideas",
887
+ description: "AI-generate content ideas, optionally seeded from a knowledge base or topic.",
888
+ inputSchema: {
889
+ type: "object",
890
+ properties: {
891
+ kbId: { type: "string", description: "Knowledge base ID to draw context from" },
892
+ topic: { type: "string", description: "Topic or theme for idea generation" },
893
+ count: { type: "number", description: "Number of ideas to generate (default 5)" }
894
+ },
895
+ additionalProperties: false
896
+ }
897
+ },
898
+ {
899
+ name: "list-ideas",
900
+ description: "List all saved content ideas.",
901
+ inputSchema: {
902
+ type: "object",
903
+ properties: {},
904
+ additionalProperties: false
905
+ }
906
+ },
907
+ {
908
+ name: "enrich-idea",
909
+ description: "Enrich an idea with additional AI-generated context.",
910
+ inputSchema: {
911
+ type: "object",
912
+ properties: {
913
+ id: { type: "string", description: "Idea ID to enrich" }
914
+ },
915
+ required: ["id"],
916
+ additionalProperties: false
917
+ }
918
+ },
919
+ {
920
+ name: "delete-idea",
921
+ description: "Permanently delete an idea by ID.",
922
+ inputSchema: {
923
+ type: "object",
924
+ properties: {
925
+ id: { type: "string", description: "Idea ID to delete" }
926
+ },
927
+ required: ["id"],
928
+ additionalProperties: false
929
+ }
930
+ },
931
+ // Clips
932
+ {
933
+ name: "list-clips",
934
+ description: "List all video clips in the workspace.",
935
+ inputSchema: {
936
+ type: "object",
937
+ properties: {},
938
+ additionalProperties: false
939
+ }
940
+ },
941
+ {
942
+ name: "get-clip",
943
+ description: "Get a video clip by its ID.",
944
+ inputSchema: {
945
+ type: "object",
946
+ properties: {
947
+ id: { type: "string", description: "Clip ID" }
948
+ },
949
+ required: ["id"],
950
+ additionalProperties: false
951
+ }
952
+ },
953
+ {
954
+ name: "import-clip",
955
+ description: "Import a video clip from a remote URL.",
956
+ inputSchema: {
957
+ type: "object",
958
+ properties: {
959
+ url: { type: "string", description: "URL of the video to import" },
960
+ name: { type: "string", description: "Optional name for the imported clip" }
961
+ },
962
+ required: ["url"],
963
+ additionalProperties: false
964
+ }
965
+ },
966
+ {
967
+ name: "render-clip",
968
+ description: "Trigger rendering for a video clip.",
969
+ inputSchema: {
970
+ type: "object",
971
+ properties: {
972
+ id: { type: "string", description: "Clip ID to render" }
973
+ },
974
+ required: ["id"],
975
+ additionalProperties: false
976
+ }
977
+ },
978
+ {
979
+ name: "delete-clip",
980
+ description: "Permanently delete a video clip by ID.",
981
+ inputSchema: {
982
+ type: "object",
983
+ properties: {
984
+ id: { type: "string", description: "Clip ID to delete" }
985
+ },
986
+ required: ["id"],
987
+ additionalProperties: false
988
+ }
989
+ },
990
+ // Carousels
991
+ {
992
+ name: "list-carousels",
993
+ description: "List all carousels in the workspace.",
994
+ inputSchema: {
995
+ type: "object",
996
+ properties: {},
997
+ additionalProperties: false
998
+ }
999
+ },
1000
+ {
1001
+ name: "get-carousel",
1002
+ description: "Get a carousel by its ID.",
1003
+ inputSchema: {
1004
+ type: "object",
1005
+ properties: {
1006
+ id: { type: "string", description: "Carousel ID" }
1007
+ },
1008
+ required: ["id"],
1009
+ additionalProperties: false
1010
+ }
1011
+ },
1012
+ {
1013
+ name: "create-carousel",
1014
+ description: "Create a new empty carousel.",
1015
+ inputSchema: {
1016
+ type: "object",
1017
+ properties: {
1018
+ title: { type: "string", description: "Optional carousel title" }
1019
+ },
1020
+ additionalProperties: false
1021
+ }
1022
+ },
1023
+ {
1024
+ name: "generate-carousel",
1025
+ description: "AI-generate a carousel from a topic.",
1026
+ inputSchema: {
1027
+ type: "object",
1028
+ properties: {
1029
+ topic: { type: "string", description: "Topic to generate slides for" },
1030
+ brandSlug: { type: "string", description: "Brand slug for brand voice" },
1031
+ slideCount: { type: "number", description: "Number of slides to generate" }
1032
+ },
1033
+ required: ["topic"],
1034
+ additionalProperties: false
1035
+ }
1036
+ },
1037
+ {
1038
+ name: "draft-carousel",
1039
+ description: "Convert a carousel into a post draft.",
1040
+ inputSchema: {
1041
+ type: "object",
1042
+ properties: {
1043
+ id: { type: "string", description: "Carousel ID to convert" }
1044
+ },
1045
+ required: ["id"],
1046
+ additionalProperties: false
1047
+ }
1048
+ },
1049
+ {
1050
+ name: "delete-carousel",
1051
+ description: "Permanently delete a carousel by ID.",
1052
+ inputSchema: {
1053
+ type: "object",
1054
+ properties: {
1055
+ id: { type: "string", description: "Carousel ID to delete" }
1056
+ },
1057
+ required: ["id"],
1058
+ additionalProperties: false
1059
+ }
1060
+ },
1061
+ // Webhooks
1062
+ {
1063
+ name: "list-webhooks",
1064
+ description: "List all webhooks in the workspace.",
1065
+ inputSchema: {
1066
+ type: "object",
1067
+ properties: {},
1068
+ additionalProperties: false
1069
+ }
1070
+ },
1071
+ {
1072
+ name: "get-webhook",
1073
+ description: "Get a webhook by its ID.",
1074
+ inputSchema: {
1075
+ type: "object",
1076
+ properties: {
1077
+ id: { type: "string", description: "Webhook ID" }
1078
+ },
1079
+ required: ["id"],
1080
+ additionalProperties: false
1081
+ }
1082
+ },
1083
+ {
1084
+ name: "create-webhook",
1085
+ description: "Create a new webhook endpoint for receiving events.",
1086
+ inputSchema: {
1087
+ type: "object",
1088
+ properties: {
1089
+ url: { type: "string", description: "HTTPS endpoint URL to receive events" },
1090
+ events: {
1091
+ type: "string",
1092
+ description: "Comma-separated event types (e.g. post.published,post.failed)"
1093
+ },
1094
+ secret: { type: "string", description: "Optional HMAC signing secret" }
1095
+ },
1096
+ required: ["url", "events"],
1097
+ additionalProperties: false
1098
+ }
1099
+ },
1100
+ {
1101
+ name: "update-webhook",
1102
+ description: "Update the URL, events, or active state of a webhook.",
1103
+ inputSchema: {
1104
+ type: "object",
1105
+ properties: {
1106
+ id: { type: "string", description: "Webhook ID" },
1107
+ url: { type: "string", description: "New endpoint URL" },
1108
+ events: { type: "string", description: "New comma-separated event types" },
1109
+ active: { type: "boolean", description: "Whether the webhook is active" }
1110
+ },
1111
+ required: ["id"],
1112
+ additionalProperties: false
1113
+ }
1114
+ },
1115
+ {
1116
+ name: "delete-webhook",
1117
+ description: "Permanently delete a webhook by ID.",
1118
+ inputSchema: {
1119
+ type: "object",
1120
+ properties: {
1121
+ id: { type: "string", description: "Webhook ID to delete" }
1122
+ },
1123
+ required: ["id"],
1124
+ additionalProperties: false
1125
+ }
1126
+ },
1127
+ {
1128
+ name: "test-webhook",
1129
+ description: "Send a test event to a webhook endpoint.",
1130
+ inputSchema: {
1131
+ type: "object",
1132
+ properties: {
1133
+ id: { type: "string", description: "Webhook ID to send the test event to" }
1134
+ },
1135
+ required: ["id"],
1136
+ additionalProperties: false
1137
+ }
1138
+ },
1139
+ // Billing
1140
+ {
1141
+ name: "billing-status",
1142
+ description: "Get the current billing plan and subscription status.",
1143
+ inputSchema: {
1144
+ type: "object",
1145
+ properties: {},
1146
+ additionalProperties: false
1147
+ }
1148
+ },
1149
+ {
1150
+ name: "billing-credits",
1151
+ description: "Get the current AI credit balance and usage breakdown.",
1152
+ inputSchema: {
1153
+ type: "object",
1154
+ properties: {},
1155
+ additionalProperties: false
1156
+ }
1157
+ },
1158
+ // Usage
1159
+ {
1160
+ name: "usage-summary",
1161
+ description: "Get a summary of post and publishing usage for the current period.",
1162
+ inputSchema: {
1163
+ type: "object",
1164
+ properties: {},
1165
+ additionalProperties: false
1166
+ }
1167
+ }
1168
+ ];
1169
+ }
1170
+ });
1171
+
1172
+ // src/mcp/handler.ts
1173
+ function ok(data) {
1174
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
1175
+ }
1176
+ function parsePlatforms2(raw) {
1177
+ if (typeof raw !== "string") return [];
1178
+ return raw.split(",").map((p) => p.trim());
1179
+ }
1180
+ function parseEvents(raw) {
1181
+ if (typeof raw !== "string") return [];
1182
+ return raw.split(",").map((e) => e.trim());
1183
+ }
1184
+ async function handleToolCall(name, args, client) {
1185
+ switch (name) {
1186
+ // Posts
1187
+ case "list-posts": {
1188
+ const result = await client.posts.list({
1189
+ brandSlug: args.brandSlug,
1190
+ status: args.status,
1191
+ limit: args.limit,
1192
+ page: args.page
1193
+ });
1194
+ return ok(result);
1195
+ }
1196
+ case "get-post": {
1197
+ const result = await client.posts.getById(args.id);
1198
+ return ok(result);
1199
+ }
1200
+ case "create-post": {
1201
+ const result = await client.posts.create({
1202
+ brandSlug: args.brandSlug,
1203
+ text: args.text,
1204
+ platforms: parsePlatforms2(args.platforms),
1205
+ ...args.scheduledAt ? { scheduledAt: args.scheduledAt } : {}
1206
+ });
1207
+ return ok(result);
1208
+ }
1209
+ case "update-post": {
1210
+ const result = await client.posts.update(args.id, {
1211
+ ...args.text ? { text: args.text } : {},
1212
+ ...args.platforms ? {
1213
+ platforms: parsePlatforms2(args.platforms)
1214
+ } : {},
1215
+ ...args.scheduledAt ? { scheduledAt: args.scheduledAt } : {}
1216
+ });
1217
+ return ok(result);
1218
+ }
1219
+ case "delete-post": {
1220
+ await client.posts.remove(args.id);
1221
+ return ok({ deleted: true, id: args.id });
1222
+ }
1223
+ case "publish-post": {
1224
+ const result = await client.posts.publish(args.id);
1225
+ return ok(result);
1226
+ }
1227
+ case "schedule-post": {
1228
+ const result = await client.posts.schedule(args.id, args.scheduledAt);
1229
+ return ok(result);
1230
+ }
1231
+ case "retry-post": {
1232
+ const result = await client.posts.retry(args.id);
1233
+ return ok(result);
1234
+ }
1235
+ case "rewrite-post": {
1236
+ const result = await client.posts.rewrite(args.id);
1237
+ return ok(result);
1238
+ }
1239
+ case "score-post": {
1240
+ const result = await client.posts.score(args.id);
1241
+ return ok(result);
1242
+ }
1243
+ // Brands
1244
+ case "list-brands": {
1245
+ const result = await client.brands.list();
1246
+ return ok(result);
1247
+ }
1248
+ case "get-brand": {
1249
+ const result = await client.brands.retrieve(args.brandSlug);
1250
+ return ok(result);
1251
+ }
1252
+ case "create-brand": {
1253
+ const result = await client.brands.create({
1254
+ name: args.name,
1255
+ ...args.timezone ? { timezone: args.timezone } : {}
1256
+ });
1257
+ return ok(result);
1258
+ }
1259
+ case "update-brand": {
1260
+ const result = await client.brands.update(args.brandSlug, {
1261
+ ...args.name ? { name: args.name } : {},
1262
+ ...args.timezone ? { timezone: args.timezone } : {}
1263
+ });
1264
+ return ok(result);
1265
+ }
1266
+ case "delete-brand": {
1267
+ await client.brands.remove(args.brandSlug);
1268
+ return ok({ deleted: true, brandSlug: args.brandSlug });
1269
+ }
1270
+ case "brand-auth-status": {
1271
+ const result = await client.brands.authStatus(args.brandSlug);
1272
+ return ok(result);
1273
+ }
1274
+ // Agents
1275
+ case "list-agents": {
1276
+ const result = await client.agents.list();
1277
+ return ok(result);
1278
+ }
1279
+ case "get-agent": {
1280
+ const result = await client.agents.retrieve(args.id);
1281
+ return ok(result);
1282
+ }
1283
+ case "create-agent": {
1284
+ const result = await client.agents.create({
1285
+ name: args.name,
1286
+ type: args.type,
1287
+ prompt: args.prompt,
1288
+ frequency: args.frequency,
1289
+ ...args.brandSlug ? { brandSlug: args.brandSlug } : {},
1290
+ ...args.time ? { time: args.time } : {},
1291
+ ...args.weekday ? { weekday: args.weekday } : {},
1292
+ ...args.kbId ? { kbId: args.kbId } : {}
1293
+ });
1294
+ return ok(result);
1295
+ }
1296
+ case "update-agent": {
1297
+ const result = await client.agents.update(args.id, {
1298
+ ...args.name ? { name: args.name } : {},
1299
+ ...args.prompt ? { prompt: args.prompt } : {},
1300
+ ...args.frequency ? { frequency: args.frequency } : {},
1301
+ ...args.time ? { time: args.time } : {},
1302
+ ...args.weekday ? { weekday: args.weekday } : {}
1303
+ });
1304
+ return ok(result);
1305
+ }
1306
+ case "delete-agent": {
1307
+ await client.agents.remove(args.id);
1308
+ return ok({ deleted: true, id: args.id });
1309
+ }
1310
+ case "run-agent": {
1311
+ const result = await client.agents.run(args.id);
1312
+ return ok(result);
1313
+ }
1314
+ case "toggle-agent": {
1315
+ const result = await client.agents.toggle(args.id);
1316
+ return ok(result);
1317
+ }
1318
+ case "agent-runs": {
1319
+ const result = await client.agents.runs(args.id);
1320
+ return ok(result);
1321
+ }
1322
+ // Knowledge Bases
1323
+ case "list-kbs": {
1324
+ const result = await client.kb.list();
1325
+ return ok(result);
1326
+ }
1327
+ case "get-kb": {
1328
+ const result = await client.kb.retrieve(args.id);
1329
+ return ok(result);
1330
+ }
1331
+ case "create-kb": {
1332
+ const result = await client.kb.create({ name: args.name });
1333
+ return ok(result);
1334
+ }
1335
+ case "delete-kb": {
1336
+ await client.kb.remove(args.id);
1337
+ return ok({ deleted: true, id: args.id });
1338
+ }
1339
+ case "search-kb": {
1340
+ const result = await client.kb.search(args.id, args.query);
1341
+ return ok(result);
1342
+ }
1343
+ case "ingest-kb": {
1344
+ const result = await client.kb.ingestUrl(args.id, args.url);
1345
+ return ok(result);
1346
+ }
1347
+ case "kb-docs": {
1348
+ const result = await client.kb.docs(args.id);
1349
+ return ok(result);
1350
+ }
1351
+ // Ideas
1352
+ case "generate-ideas": {
1353
+ const result = await client.ideas.generate({
1354
+ ...args.kbId ? { kbId: args.kbId } : {},
1355
+ ...args.topic ? { topic: args.topic } : {},
1356
+ ...args.count ? { count: args.count } : {}
1357
+ });
1358
+ return ok(result);
1359
+ }
1360
+ case "list-ideas": {
1361
+ const result = await client.ideas.list();
1362
+ return ok(result);
1363
+ }
1364
+ case "enrich-idea": {
1365
+ const result = await client.ideas.enrich(args.id);
1366
+ return ok(result);
1367
+ }
1368
+ case "delete-idea": {
1369
+ await client.ideas.remove(args.id);
1370
+ return ok({ deleted: true, id: args.id });
1371
+ }
1372
+ // Clips
1373
+ case "list-clips": {
1374
+ const result = await client.clips.list();
1375
+ return ok(result);
1376
+ }
1377
+ case "get-clip": {
1378
+ const result = await client.clips.retrieve(args.id);
1379
+ return ok(result);
1380
+ }
1381
+ case "import-clip": {
1382
+ const result = await client.clips.importUrl({
1383
+ url: args.url,
1384
+ ...args.name ? { name: args.name } : {}
1385
+ });
1386
+ return ok(result);
1387
+ }
1388
+ case "render-clip": {
1389
+ const result = await client.clips.render(args.id);
1390
+ return ok(result);
1391
+ }
1392
+ case "delete-clip": {
1393
+ await client.clips.remove(args.id);
1394
+ return ok({ deleted: true, id: args.id });
1395
+ }
1396
+ // Carousels
1397
+ case "list-carousels": {
1398
+ const result = await client.carousels.list();
1399
+ return ok(result);
1400
+ }
1401
+ case "get-carousel": {
1402
+ const result = await client.carousels.retrieve(args.id);
1403
+ return ok(result);
1404
+ }
1405
+ case "create-carousel": {
1406
+ const result = await client.carousels.create(
1407
+ args.title ? { title: args.title } : void 0
1408
+ );
1409
+ return ok(result);
1410
+ }
1411
+ case "generate-carousel": {
1412
+ const result = await client.carousels.generate({
1413
+ topic: args.topic,
1414
+ ...args.brandSlug ? { brandSlug: args.brandSlug } : {},
1415
+ ...args.slideCount ? { slideCount: args.slideCount } : {}
1416
+ });
1417
+ return ok(result);
1418
+ }
1419
+ case "draft-carousel": {
1420
+ const result = await client.carousels.draft(args.id);
1421
+ return ok(result);
1422
+ }
1423
+ case "delete-carousel": {
1424
+ await client.carousels.remove(args.id);
1425
+ return ok({ deleted: true, id: args.id });
1426
+ }
1427
+ // Webhooks
1428
+ case "list-webhooks": {
1429
+ const result = await client.webhooks.list();
1430
+ return ok(result);
1431
+ }
1432
+ case "get-webhook": {
1433
+ const result = await client.webhooks.retrieve(args.id);
1434
+ return ok(result);
1435
+ }
1436
+ case "create-webhook": {
1437
+ const result = await client.webhooks.create({
1438
+ url: args.url,
1439
+ events: parseEvents(args.events),
1440
+ ...args.secret ? { secret: args.secret } : {}
1441
+ });
1442
+ return ok(result);
1443
+ }
1444
+ case "update-webhook": {
1445
+ const result = await client.webhooks.update(args.id, {
1446
+ ...args.url ? { url: args.url } : {},
1447
+ ...args.events ? { events: parseEvents(args.events) } : {},
1448
+ ...args.active !== void 0 ? { active: args.active } : {}
1449
+ });
1450
+ return ok(result);
1451
+ }
1452
+ case "delete-webhook": {
1453
+ await client.webhooks.remove(args.id);
1454
+ return ok({ deleted: true, id: args.id });
1455
+ }
1456
+ case "test-webhook": {
1457
+ await client.webhooks.test(args.id);
1458
+ return ok({ sent: true, id: args.id });
1459
+ }
1460
+ // Billing
1461
+ case "billing-status": {
1462
+ const result = await client.billing.status();
1463
+ return ok(result);
1464
+ }
1465
+ case "billing-credits": {
1466
+ const result = await client.billing.credits();
1467
+ return ok(result);
1468
+ }
1469
+ // Usage
1470
+ case "usage-summary": {
1471
+ const result = await client.usage.summary();
1472
+ return ok(result);
1473
+ }
1474
+ default:
1475
+ return {
1476
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
1477
+ isError: true
1478
+ };
1479
+ }
1480
+ }
1481
+ var init_handler = __esm({
1482
+ "src/mcp/handler.ts"() {
1483
+ "use strict";
1484
+ }
1485
+ });
1486
+
1487
+ // src/mcp/server.ts
1488
+ var server_exports = {};
1489
+ __export(server_exports, {
1490
+ startMcpServer: () => startMcpServer
1491
+ });
1492
+ async function startMcpServer() {
1493
+ const client = new import_sdk12.Autoposting();
1494
+ const server = new import_server.Server(
1495
+ { name: "autoposting-mcp", version: "0.1.0" },
1496
+ { capabilities: { tools: {} } }
1497
+ );
1498
+ server.setRequestHandler(import_types.ListToolsRequestSchema, async () => ({
1499
+ tools: ALL_TOOLS
1500
+ }));
1501
+ server.setRequestHandler(import_types.CallToolRequestSchema, async (request) => {
1502
+ const { name, arguments: args } = request.params;
1503
+ return handleToolCall(name, args ?? {}, client);
1504
+ });
1505
+ const transport = new import_stdio.StdioServerTransport();
1506
+ await server.connect(transport);
1507
+ }
1508
+ var import_server, import_stdio, import_types, import_sdk12;
1509
+ var init_server = __esm({
1510
+ "src/mcp/server.ts"() {
1511
+ "use strict";
1512
+ import_server = require("@modelcontextprotocol/sdk/server/index.js");
1513
+ import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
1514
+ import_types = require("@modelcontextprotocol/sdk/types.js");
1515
+ import_sdk12 = __toESM(require_dist());
1516
+ init_tools();
1517
+ init_handler();
1518
+ }
1519
+ });
1520
+
1521
+ // src/cli.ts
1522
+ var import_commander19 = require("commander");
1523
+
1524
+ // src/commands/agents.ts
1525
+ var import_commander = require("commander");
1526
+ var import_sdk = __toESM(require_dist());
1527
+
1528
+ // src/auth/credential-store.ts
1529
+ var import_node_fs = __toESM(require("fs"));
1530
+ var import_node_os = __toESM(require("os"));
1531
+ var import_node_path = __toESM(require("path"));
1532
+ function getCredentialsPath() {
1533
+ const configBase = process.env.XDG_CONFIG_HOME ?? import_node_path.default.join(import_node_os.default.homedir(), ".config");
1534
+ return import_node_path.default.join(configBase, "autoposting", "credentials.json");
1535
+ }
1536
+ function readCredentials() {
1537
+ const filePath = getCredentialsPath();
1538
+ try {
1539
+ const raw = import_node_fs.default.readFileSync(filePath, "utf8");
1540
+ return JSON.parse(raw);
1541
+ } catch {
1542
+ return null;
1543
+ }
1544
+ }
1545
+ function writeCredentials(creds) {
1546
+ const filePath = getCredentialsPath();
1547
+ const dir = import_node_path.default.dirname(filePath);
1548
+ 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 });
1550
+ import_node_fs.default.chmodSync(filePath, 384);
1551
+ }
1552
+ function saveProfile(name, profile) {
1553
+ const existing = readCredentials();
1554
+ const creds = existing ?? { activeProfile: name, profiles: {} };
1555
+ creds.profiles[name] = profile;
1556
+ creds.activeProfile = name;
1557
+ writeCredentials(creds);
1558
+ }
1559
+ function deleteProfile(name) {
1560
+ const creds = readCredentials();
1561
+ if (!creds) return;
1562
+ delete creds.profiles[name];
1563
+ if (creds.activeProfile === name) {
1564
+ const remaining = Object.keys(creds.profiles);
1565
+ creds.activeProfile = remaining[0] ?? "";
1566
+ }
1567
+ writeCredentials(creds);
1568
+ }
1569
+ function deleteAllProfiles() {
1570
+ writeCredentials({ activeProfile: "", profiles: {} });
1571
+ }
1572
+ function getActiveProfile() {
1573
+ const creds = readCredentials();
1574
+ if (!creds || !creds.activeProfile) return null;
1575
+ return creds.profiles[creds.activeProfile] ?? null;
1576
+ }
1577
+ function setActiveProfile(name) {
1578
+ const creds = readCredentials();
1579
+ if (!creds) throw new Error(`Profile "${name}" does not exist (no credentials file)`);
1580
+ if (!creds.profiles[name]) throw new Error(`Profile "${name}" does not exist`);
1581
+ creds.activeProfile = name;
1582
+ writeCredentials(creds);
1583
+ }
1584
+
1585
+ // src/auth/auth-manager.ts
1586
+ function resolveAuth(options) {
1587
+ if (options?.apiKey) {
1588
+ return { apiKey: options.apiKey, source: "flag" };
1589
+ }
1590
+ const envKey = process.env.AUTOPOSTING_API_KEY;
1591
+ if (envKey) {
1592
+ return { apiKey: envKey, source: "env" };
1593
+ }
1594
+ const profile = getActiveProfile();
1595
+ if (profile?.apiKey) {
1596
+ return { apiKey: profile.apiKey, source: "stored" };
1597
+ }
1598
+ const err = new Error(
1599
+ "No API key found. Run `ap auth login --api-key <key>` or set AUTOPOSTING_API_KEY."
1600
+ );
1601
+ err.exitCode = 2;
1602
+ throw err;
1603
+ }
1604
+
1605
+ // src/output/formatter.ts
1606
+ var RED = "\x1B[31m";
1607
+ var RESET = "\x1B[0m";
1608
+ var colorEnabled = true;
1609
+ function disableColor() {
1610
+ colorEnabled = false;
1611
+ }
1612
+ function red(text) {
1613
+ if (!colorEnabled || !process.stdout.isTTY) return text;
1614
+ return `${RED}${text}${RESET}`;
1615
+ }
1616
+ function detectOutputMode(options) {
1617
+ if (options.quiet) return "quiet";
1618
+ if (options.json || !process.stdout.isTTY) return "json";
1619
+ return "tty";
1620
+ }
1621
+ function formatOutput(data, mode) {
1622
+ if (mode === "quiet") return "";
1623
+ if (mode === "json") return JSON.stringify(data, null, 2);
1624
+ if (typeof data === "string") return data;
1625
+ return JSON.stringify(data, null, 2);
1626
+ }
1627
+ function formatTable(rows, columns) {
1628
+ if (rows.length === 0) return "";
1629
+ const cols = columns ?? Object.keys(rows[0]);
1630
+ const widths = cols.map((col) => col.length);
1631
+ for (const row of rows) {
1632
+ for (let i = 0; i < cols.length; i++) {
1633
+ const val = String(row[cols[i]] ?? "");
1634
+ if (val.length > widths[i]) widths[i] = val.length;
1635
+ }
1636
+ }
1637
+ const pad = (s, w) => s.padEnd(w, " ");
1638
+ const separator = widths.map((w) => "-".repeat(w)).join(" ");
1639
+ const header = cols.map((c, i) => pad(c.toUpperCase(), widths[i])).join(" ");
1640
+ const dataRows = rows.map(
1641
+ (row) => cols.map((c, i) => pad(String(row[c] ?? ""), widths[i])).join(" ")
1642
+ );
1643
+ return [header, separator, ...dataRows].join("\n");
1644
+ }
1645
+ function formatError(error, mode) {
1646
+ const message = error instanceof Error ? error.message : error;
1647
+ if (mode === "tty") return red(`Error: ${message}`);
1648
+ return JSON.stringify({ error: message }, null, 2);
1649
+ }
1650
+
1651
+ // src/output/spinner.ts
1652
+ var NO_OP_SPINNER = {
1653
+ start: () => {
1654
+ },
1655
+ stop: () => {
1656
+ },
1657
+ fail: () => {
1658
+ }
1659
+ };
1660
+ var OraSpinner = class {
1661
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1662
+ instance = null;
1663
+ start(message) {
1664
+ import("ora").then(({ default: ora }) => {
1665
+ this.instance = ora(message).start();
1666
+ }).catch(() => {
1667
+ process.stdout.write(`${message}
1668
+ `);
1669
+ });
1670
+ }
1671
+ stop(message) {
1672
+ if (this.instance) {
1673
+ this.instance.succeed(message);
1674
+ this.instance = null;
1675
+ } else if (message) {
1676
+ process.stdout.write(`${message}
1677
+ `);
1678
+ }
1679
+ }
1680
+ fail(message) {
1681
+ if (this.instance) {
1682
+ this.instance.fail(message);
1683
+ this.instance = null;
1684
+ } else {
1685
+ process.stderr.write(`${message}
1686
+ `);
1687
+ }
1688
+ }
1689
+ };
1690
+ function createSpinner(mode) {
1691
+ if (mode === "tty") return new OraSpinner();
1692
+ return NO_OP_SPINNER;
1693
+ }
1694
+
1695
+ // src/output/printer.ts
1696
+ var Printer = class {
1697
+ constructor(mode) {
1698
+ this.mode = mode;
1699
+ }
1700
+ mode;
1701
+ log(data) {
1702
+ const out = formatOutput(data, this.mode);
1703
+ if (out !== "") console.log(out);
1704
+ }
1705
+ table(rows, columns) {
1706
+ if (this.mode === "quiet") return;
1707
+ if (this.mode === "json") {
1708
+ console.log(formatOutput(rows, "json"));
1709
+ return;
1710
+ }
1711
+ const out = formatTable(rows, columns);
1712
+ if (out !== "") console.log(out);
1713
+ }
1714
+ error(err) {
1715
+ const out = formatError(err, this.mode);
1716
+ console.error(out);
1717
+ }
1718
+ spinner(message) {
1719
+ const s = createSpinner(this.mode);
1720
+ s.start(message);
1721
+ return s;
1722
+ }
1723
+ };
1724
+ function createPrinter(options) {
1725
+ const mode = detectOutputMode(options);
1726
+ return new Printer(mode);
1727
+ }
1728
+
1729
+ // src/output/exit-codes.ts
1730
+ var EXIT_CODES = {
1731
+ SUCCESS: 0,
1732
+ GENERAL_ERROR: 1,
1733
+ AUTH_ERROR: 2,
1734
+ SCOPE_ERROR: 3,
1735
+ NOT_FOUND: 4,
1736
+ RATE_LIMITED: 5,
1737
+ VALIDATION_ERROR: 6,
1738
+ NETWORK_ERROR: 7
1739
+ };
1740
+ function matchesClass(error, className) {
1741
+ if (error == null || typeof error !== "object") return false;
1742
+ let proto = Object.getPrototypeOf(error);
1743
+ while (proto !== null) {
1744
+ const ctor = proto.constructor;
1745
+ if (ctor?.name === className) return true;
1746
+ proto = Object.getPrototypeOf(proto);
1747
+ }
1748
+ return false;
1749
+ }
1750
+ function exitCodeFromError(error) {
1751
+ if (matchesClass(error, "AuthenticationError")) return EXIT_CODES.AUTH_ERROR;
1752
+ if (matchesClass(error, "ScopeError")) return EXIT_CODES.SCOPE_ERROR;
1753
+ if (matchesClass(error, "NotFoundError")) return EXIT_CODES.NOT_FOUND;
1754
+ if (matchesClass(error, "RateLimitError")) return EXIT_CODES.RATE_LIMITED;
1755
+ if (matchesClass(error, "ValidationError")) return EXIT_CODES.VALIDATION_ERROR;
1756
+ if (matchesClass(error, "NetworkError")) return EXIT_CODES.NETWORK_ERROR;
1757
+ return EXIT_CODES.GENERAL_ERROR;
1758
+ }
1759
+
1760
+ // src/commands/agents.ts
1761
+ function resolveExitCode(err) {
1762
+ const attached = err.exitCode;
1763
+ if (typeof attached === "number") return attached;
1764
+ return exitCodeFromError(err);
1765
+ }
1766
+ function createAgentsCommand() {
1767
+ const agents = new import_commander.Command("agents").description("Manage agents");
1768
+ agents.command("list").description("List all agents").action(async (_opts, cmd) => {
1769
+ const globals = cmd.optsWithGlobals();
1770
+ const printer = createPrinter(globals);
1771
+ const spinner = printer.spinner("Fetching agents\u2026");
1772
+ try {
1773
+ const cred = resolveAuth({ apiKey: globals.apiKey });
1774
+ const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1775
+ const list = await client.agents.list();
1776
+ spinner.stop();
1777
+ const rows = list.map((a) => ({
1778
+ id: a.id,
1779
+ name: a.name,
1780
+ type: a.type,
1781
+ brand: a.brandSlug ?? "\u2014",
1782
+ frequency: a.frequency,
1783
+ enabled: a.enabled ? "yes" : "no"
1784
+ }));
1785
+ printer.table(rows, ["id", "name", "type", "brand", "frequency", "enabled"]);
1786
+ } catch (err) {
1787
+ spinner.stop();
1788
+ printer.error(err);
1789
+ process.exit(resolveExitCode(err));
1790
+ }
1791
+ });
1792
+ agents.command("get <id>").description("Get an agent by ID").action(async (id, _opts, cmd) => {
1793
+ const globals = cmd.optsWithGlobals();
1794
+ const printer = createPrinter(globals);
1795
+ const spinner = printer.spinner(`Fetching agent "${id}"\u2026`);
1796
+ try {
1797
+ const cred = resolveAuth({ apiKey: globals.apiKey });
1798
+ const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1799
+ const agent = await client.agents.retrieve(id);
1800
+ spinner.stop();
1801
+ printer.log(agent);
1802
+ } catch (err) {
1803
+ spinner.stop();
1804
+ printer.error(err);
1805
+ process.exit(resolveExitCode(err));
1806
+ }
1807
+ });
1808
+ agents.command("create").description("Create a new agent").requiredOption("--name <name>", "Agent name").requiredOption("--type <type>", "Agent type: publish or research").option("--brand <slug>", "Brand slug to associate with").requiredOption("--prompt <text>", "Agent prompt / instructions").requiredOption("--frequency <freq>", "Run frequency: manual, daily, or weekly").option("--time <HH:MM>", "Time of day to run (required for daily/weekly)").option("--weekday <day>", "Day of week to run (required for weekly)").option("--kb <id>", "Knowledge base ID to attach").action(
1809
+ async (opts, cmd) => {
1810
+ const globals = cmd.optsWithGlobals();
1811
+ const printer = createPrinter(globals);
1812
+ const spinner = printer.spinner("Creating agent\u2026");
1813
+ try {
1814
+ const cred = resolveAuth({ apiKey: globals.apiKey });
1815
+ const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1816
+ const agent = await client.agents.create({
1817
+ name: opts.name,
1818
+ type: opts.type,
1819
+ prompt: opts.prompt,
1820
+ frequency: opts.frequency,
1821
+ ...opts.brand ? { brandSlug: opts.brand } : {},
1822
+ ...opts.time ? { time: opts.time } : {},
1823
+ ...opts.weekday ? { weekday: opts.weekday } : {},
1824
+ ...opts.kb ? { kbId: opts.kb } : {}
1825
+ });
1826
+ spinner.stop();
1827
+ printer.log(agent);
1828
+ } catch (err) {
1829
+ spinner.stop();
1830
+ printer.error(err);
1831
+ process.exit(resolveExitCode(err));
1832
+ }
1833
+ }
1834
+ );
1835
+ agents.command("update <id>").description("Update an agent").option("--name <name>", "New agent name").option("--prompt <text>", "New prompt / instructions").option("--frequency <freq>", "New frequency: manual, daily, or weekly").option("--time <HH:MM>", "New time of day").option("--weekday <day>", "New day of week").action(
1836
+ async (id, opts, cmd) => {
1837
+ const globals = cmd.optsWithGlobals();
1838
+ const printer = createPrinter(globals);
1839
+ const spinner = printer.spinner(`Updating agent "${id}"\u2026`);
1840
+ try {
1841
+ const cred = resolveAuth({ apiKey: globals.apiKey });
1842
+ const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1843
+ const agent = await client.agents.update(id, {
1844
+ ...opts.name ? { name: opts.name } : {},
1845
+ ...opts.prompt ? { prompt: opts.prompt } : {},
1846
+ ...opts.frequency ? { frequency: opts.frequency } : {},
1847
+ ...opts.time ? { time: opts.time } : {},
1848
+ ...opts.weekday ? { weekday: opts.weekday } : {}
1849
+ });
1850
+ spinner.stop();
1851
+ printer.log(agent);
1852
+ } catch (err) {
1853
+ spinner.stop();
1854
+ printer.error(err);
1855
+ process.exit(resolveExitCode(err));
1856
+ }
1857
+ }
1858
+ );
1859
+ agents.command("delete <id>").description("Delete an agent (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (id, opts, cmd) => {
1860
+ const globals = cmd.optsWithGlobals();
1861
+ const printer = createPrinter(globals);
1862
+ if (!opts.force) {
1863
+ printer.error("--force is required to delete an agent. Pass --force to confirm.");
1864
+ process.exit(1);
1865
+ }
1866
+ const spinner = printer.spinner(`Deleting agent "${id}"\u2026`);
1867
+ try {
1868
+ const cred = resolveAuth({ apiKey: globals.apiKey });
1869
+ const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1870
+ await client.agents.remove(id);
1871
+ spinner.stop();
1872
+ printer.log(`Agent "${id}" deleted.`);
1873
+ } catch (err) {
1874
+ spinner.stop();
1875
+ printer.error(err);
1876
+ process.exit(resolveExitCode(err));
1877
+ }
1878
+ });
1879
+ agents.command("run <id>").description("Trigger an agent run immediately").action(async (id, _opts, cmd) => {
1880
+ const globals = cmd.optsWithGlobals();
1881
+ const printer = createPrinter(globals);
1882
+ const spinner = printer.spinner(`Running agent "${id}"\u2026`);
1883
+ try {
1884
+ const cred = resolveAuth({ apiKey: globals.apiKey });
1885
+ const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1886
+ const agentRun = await client.agents.run(id);
1887
+ spinner.stop();
1888
+ printer.log(agentRun);
1889
+ } catch (err) {
1890
+ spinner.stop();
1891
+ printer.error(err);
1892
+ process.exit(resolveExitCode(err));
1893
+ }
1894
+ });
1895
+ agents.command("toggle <id>").description("Enable or disable an agent").action(async (id, _opts, cmd) => {
1896
+ const globals = cmd.optsWithGlobals();
1897
+ const printer = createPrinter(globals);
1898
+ const spinner = printer.spinner(`Toggling agent "${id}"\u2026`);
1899
+ try {
1900
+ const cred = resolveAuth({ apiKey: globals.apiKey });
1901
+ const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1902
+ const agent = await client.agents.toggle(id);
1903
+ spinner.stop();
1904
+ printer.log(agent);
1905
+ } catch (err) {
1906
+ spinner.stop();
1907
+ printer.error(err);
1908
+ process.exit(resolveExitCode(err));
1909
+ }
1910
+ });
1911
+ agents.command("runs <id>").description("List run history for an agent").action(async (id, _opts, cmd) => {
1912
+ const globals = cmd.optsWithGlobals();
1913
+ const printer = createPrinter(globals);
1914
+ const spinner = printer.spinner(`Fetching runs for agent "${id}"\u2026`);
1915
+ try {
1916
+ const cred = resolveAuth({ apiKey: globals.apiKey });
1917
+ const client = new import_sdk.Autoposting({ apiKey: cred.apiKey });
1918
+ const list = await client.agents.runs(id);
1919
+ spinner.stop();
1920
+ const rows = list.map((r) => ({
1921
+ id: r.id,
1922
+ status: r.status,
1923
+ output: r.output ? r.output.length > 60 ? `${r.output.slice(0, 57)}\u2026` : r.output : "\u2014",
1924
+ createdAt: r.createdAt
1925
+ }));
1926
+ printer.table(rows, ["id", "status", "output", "createdAt"]);
1927
+ } catch (err) {
1928
+ spinner.stop();
1929
+ printer.error(err);
1930
+ process.exit(resolveExitCode(err));
1931
+ }
1932
+ });
1933
+ return agents;
1934
+ }
1935
+
1936
+ // src/commands/auth.ts
1937
+ var import_commander2 = require("commander");
1938
+ var import_node_child_process = require("child_process");
1939
+
1940
+ // src/auth/device-code-client.ts
1941
+ async function requestDeviceCode(baseUrl) {
1942
+ const res = await fetch(`${baseUrl}/auth/cli/device-code`, {
1943
+ method: "POST",
1944
+ headers: { "Content-Type": "application/json" }
1945
+ });
1946
+ if (!res.ok) {
1947
+ const text = await res.text().catch(() => res.statusText);
1948
+ throw new Error(`Device code request failed (${res.status}): ${text}`);
1949
+ }
1950
+ const data = await res.json();
1951
+ return data;
1952
+ }
1953
+ async function pollDeviceCode(baseUrl, deviceCode) {
1954
+ const url = `${baseUrl}/auth/cli/poll?device_code=${encodeURIComponent(deviceCode)}`;
1955
+ const res = await fetch(url);
1956
+ if (!res.ok) {
1957
+ const text = await res.text().catch(() => res.statusText);
1958
+ throw new Error(`Poll request failed (${res.status}): ${text}`);
1959
+ }
1960
+ const data = await res.json();
1961
+ return data;
1962
+ }
1963
+
1964
+ // src/commands/auth.ts
1965
+ var DEFAULT_BASE_URL = "https://api.autoposting.ai";
1966
+ function resolveBaseUrl(globals) {
1967
+ return globals.baseUrl ?? process.env.AUTOPOSTING_BASE_URL ?? DEFAULT_BASE_URL;
1968
+ }
1969
+ function tryOpenUrl(url) {
1970
+ try {
1971
+ const platform = process.platform;
1972
+ if (platform === "darwin") (0, import_node_child_process.execSync)(`open "${url}"`, { stdio: "ignore" });
1973
+ else if (platform === "win32") (0, import_node_child_process.execSync)(`start "" "${url}"`, { stdio: "ignore" });
1974
+ else (0, import_node_child_process.execSync)(`xdg-open "${url}"`, { stdio: "ignore" });
1975
+ } catch {
1976
+ }
1977
+ }
1978
+ function createAuthCommand() {
1979
+ const auth = new import_commander2.Command("auth").description("Manage authentication and profiles");
1980
+ auth.command("login").description("Log in via browser device code flow, or store an API key directly with --api-key").option("--api-key <key>", "API key to store directly (skips device code flow)").option("--profile <name>", "Profile name to save under", "default").option("--base-url <url>", "API base URL (overrides AUTOPOSTING_BASE_URL)").action(async (localOpts, cmd) => {
1981
+ const opts = cmd.optsWithGlobals();
1982
+ if (opts.apiKey) {
1983
+ saveProfile(opts.profile, {
1984
+ apiKey: opts.apiKey,
1985
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
1986
+ });
1987
+ console.log(`Logged in. Profile "${opts.profile}" saved.`);
1988
+ return;
1989
+ }
1990
+ const baseUrl = resolveBaseUrl(opts);
1991
+ let deviceCodeResp;
1992
+ try {
1993
+ deviceCodeResp = await requestDeviceCode(baseUrl);
1994
+ } catch (err) {
1995
+ console.error(`Error: ${err.message}`);
1996
+ process.exit(2);
1997
+ }
1998
+ const { deviceCode, userCode, verificationUri } = deviceCodeResp;
1999
+ let pollInterval = deviceCodeResp.interval;
2000
+ console.log(`
2001
+ Enter code ${userCode} at ${verificationUri}
2002
+ `);
2003
+ tryOpenUrl(verificationUri);
2004
+ const frames = ["|", "/", "-", "\\"];
2005
+ let frameIdx = 0;
2006
+ const spinnerInterval = setInterval(() => {
2007
+ process.stdout.write(`\rWaiting for authorization... ${frames[frameIdx++ % frames.length]}`);
2008
+ }, 100);
2009
+ const clearSpinner = () => {
2010
+ clearInterval(spinnerInterval);
2011
+ process.stdout.write("\r\x1B[K");
2012
+ };
2013
+ while (true) {
2014
+ await new Promise((resolve) => setTimeout(resolve, pollInterval * 1e3));
2015
+ let result;
2016
+ try {
2017
+ result = await pollDeviceCode(baseUrl, deviceCode);
2018
+ } catch (err) {
2019
+ clearSpinner();
2020
+ console.error(`Error: ${err.message}`);
2021
+ process.exit(2);
2022
+ }
2023
+ switch (result.status) {
2024
+ case "complete": {
2025
+ clearSpinner();
2026
+ const token = result.sessionToken;
2027
+ saveProfile(opts.profile, {
2028
+ apiKey: token,
2029
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
2030
+ });
2031
+ console.log(`Logged in. Profile "${opts.profile}" saved.`);
2032
+ return;
2033
+ }
2034
+ case "expired_token":
2035
+ clearSpinner();
2036
+ console.error("Error: Authorization expired. Run `ap auth login` again.");
2037
+ process.exit(2);
2038
+ break;
2039
+ case "access_denied":
2040
+ clearSpinner();
2041
+ console.error("Error: Access denied.");
2042
+ process.exit(2);
2043
+ break;
2044
+ case "slow_down":
2045
+ pollInterval = result.interval ?? pollInterval * 2;
2046
+ break;
2047
+ case "authorization_pending":
2048
+ default:
2049
+ break;
2050
+ }
2051
+ }
2052
+ });
2053
+ auth.command("logout").description("Remove the active profile (or all profiles with --all)").option("--all", "Remove all stored profiles").action((opts) => {
2054
+ if (opts.all) {
2055
+ deleteAllProfiles();
2056
+ console.log("All profiles removed.");
2057
+ return;
2058
+ }
2059
+ const creds = readCredentials();
2060
+ const active = creds?.activeProfile;
2061
+ if (!active) {
2062
+ console.log("No active profile to log out from.");
2063
+ return;
2064
+ }
2065
+ deleteProfile(active);
2066
+ console.log(`Profile "${active}" removed.`);
2067
+ });
2068
+ auth.command("switch <profile>").description("Switch the active profile").action((profile) => {
2069
+ try {
2070
+ setActiveProfile(profile);
2071
+ console.log(`Switched to profile "${profile}".`);
2072
+ } catch (err) {
2073
+ console.error(`Error: ${err.message}`);
2074
+ process.exit(2);
2075
+ }
2076
+ });
2077
+ auth.command("whoami").description("Show current authentication method and identity").action((_opts, cmd) => {
2078
+ try {
2079
+ const globals = cmd.optsWithGlobals();
2080
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2081
+ console.log(`Source: ${cred.source}`);
2082
+ if (cred.source === "stored") {
2083
+ const creds = readCredentials();
2084
+ const profileName = creds?.activeProfile ?? "unknown";
2085
+ const profile = creds?.profiles[profileName];
2086
+ console.log(`Profile: ${profileName}`);
2087
+ if (profile?.workspace) console.log(`Workspace: ${profile.workspace}`);
2088
+ if (profile?.email) console.log(`Email: ${profile.email}`);
2089
+ }
2090
+ const masked = `${cred.apiKey.slice(0, 8)}${"*".repeat(Math.max(0, cred.apiKey.length - 8))}`;
2091
+ console.log(`API key: ${masked}`);
2092
+ } catch (err) {
2093
+ console.error(`Error: ${err.message}`);
2094
+ process.exit(2);
2095
+ }
2096
+ });
2097
+ auth.command("status").description("Alias for whoami \u2014 show current authentication status").action((_opts, cmd) => {
2098
+ try {
2099
+ const globals = cmd.optsWithGlobals();
2100
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2101
+ console.log(`Source: ${cred.source}`);
2102
+ if (cred.source === "stored") {
2103
+ const creds = readCredentials();
2104
+ const profileName = creds?.activeProfile ?? "unknown";
2105
+ console.log(`Profile: ${profileName}`);
2106
+ }
2107
+ const masked = `${cred.apiKey.slice(0, 8)}${"*".repeat(Math.max(0, cred.apiKey.length - 8))}`;
2108
+ console.log(`API key: ${masked}`);
2109
+ } catch (err) {
2110
+ console.error(`Error: ${err.message}`);
2111
+ process.exit(2);
2112
+ }
2113
+ });
2114
+ return auth;
2115
+ }
2116
+
2117
+ // src/commands/billing.ts
2118
+ var import_commander3 = require("commander");
2119
+ var import_sdk2 = __toESM(require_dist());
2120
+ function resolveExitCode2(err) {
2121
+ const attached = err.exitCode;
2122
+ if (typeof attached === "number") return attached;
2123
+ return exitCodeFromError(err);
2124
+ }
2125
+ function createBillingCommand() {
2126
+ const billing = new import_commander3.Command("billing").description("View billing information");
2127
+ billing.command("status").description("Show current plan and subscription status").action(async (_opts, cmd) => {
2128
+ const globals = cmd.optsWithGlobals();
2129
+ const printer = createPrinter(globals);
2130
+ const spinner = printer.spinner("Fetching billing status\u2026");
2131
+ try {
2132
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2133
+ const client = new import_sdk2.Autoposting({ apiKey: cred.apiKey });
2134
+ const status = await client.billing.status();
2135
+ spinner.stop();
2136
+ printer.table(
2137
+ [
2138
+ {
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"
2144
+ }
2145
+ ],
2146
+ ["plan", "status", "trial ends", "renewal date", "cancels at"]
2147
+ );
2148
+ } catch (err) {
2149
+ spinner.stop();
2150
+ printer.error(err);
2151
+ process.exit(resolveExitCode2(err));
2152
+ }
2153
+ });
2154
+ billing.command("credits").description("Show credit balance and usage breakdown").action(async (_opts, cmd) => {
2155
+ const globals = cmd.optsWithGlobals();
2156
+ const printer = createPrinter(globals);
2157
+ const spinner = printer.spinner("Fetching credit balance\u2026");
2158
+ try {
2159
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2160
+ const client = new import_sdk2.Autoposting({ apiKey: cred.apiKey });
2161
+ const credits = await client.billing.credits();
2162
+ spinner.stop();
2163
+ printer.table(
2164
+ [
2165
+ {
2166
+ total: credits.total,
2167
+ used: credits.used,
2168
+ remaining: credits.remaining
2169
+ }
2170
+ ],
2171
+ ["total", "used", "remaining"]
2172
+ );
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
2177
+ }));
2178
+ printer.table(breakdownRows, ["category", "credits"]);
2179
+ }
2180
+ } catch (err) {
2181
+ spinner.stop();
2182
+ printer.error(err);
2183
+ process.exit(resolveExitCode2(err));
2184
+ }
2185
+ });
2186
+ return billing;
2187
+ }
2188
+
2189
+ // src/commands/brands.ts
2190
+ var import_commander4 = require("commander");
2191
+ var import_sdk3 = __toESM(require_dist());
2192
+ function createBrandsCommand() {
2193
+ const brands = new import_commander4.Command("brands").description("Manage brands");
2194
+ brands.command("list").description("List all brands").action(async (_opts, cmd) => {
2195
+ const globals = cmd.optsWithGlobals();
2196
+ const printer = createPrinter(globals);
2197
+ const spinner = printer.spinner("Fetching brands\u2026");
2198
+ try {
2199
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2200
+ const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2201
+ const list = await client.brands.list();
2202
+ spinner.stop();
2203
+ const rows = list.map((b) => ({
2204
+ slug: b.slug,
2205
+ name: b.name,
2206
+ platforms: b.platforms.filter((p) => p.connected).map((p) => p.platform).join(", ") || "\u2014",
2207
+ timezone: b.timezone
2208
+ }));
2209
+ printer.table(rows, ["slug", "name", "platforms", "timezone"]);
2210
+ } catch (err) {
2211
+ spinner.stop();
2212
+ printer.error(err);
2213
+ process.exit(exitCodeFromError(err));
2214
+ }
2215
+ });
2216
+ brands.command("get <slug>").description("Get a brand by slug").action(async (slug, _opts, cmd) => {
2217
+ const globals = cmd.optsWithGlobals();
2218
+ const printer = createPrinter(globals);
2219
+ const spinner = printer.spinner(`Fetching brand "${slug}"\u2026`);
2220
+ try {
2221
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2222
+ const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2223
+ const brand = await client.brands.retrieve(slug);
2224
+ spinner.stop();
2225
+ printer.log(brand);
2226
+ } catch (err) {
2227
+ spinner.stop();
2228
+ printer.error(err);
2229
+ process.exit(exitCodeFromError(err));
2230
+ }
2231
+ });
2232
+ brands.command("create").description("Create a new brand").requiredOption("--name <name>", "Brand display name").option("--timezone <tz>", "IANA timezone (e.g. America/New_York)").action(async (opts, cmd) => {
2233
+ const globals = cmd.optsWithGlobals();
2234
+ const printer = createPrinter(globals);
2235
+ const spinner = printer.spinner("Creating brand\u2026");
2236
+ try {
2237
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2238
+ const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2239
+ const brand = await client.brands.create({
2240
+ name: opts.name,
2241
+ ...opts.timezone ? { timezone: opts.timezone } : {}
2242
+ });
2243
+ spinner.stop();
2244
+ printer.log(brand);
2245
+ } catch (err) {
2246
+ spinner.stop();
2247
+ printer.error(err);
2248
+ process.exit(exitCodeFromError(err));
2249
+ }
2250
+ });
2251
+ brands.command("update <slug>").description("Update a brand").option("--name <name>", "New display name").option("--timezone <tz>", "New IANA timezone").action(async (slug, opts, cmd) => {
2252
+ const globals = cmd.optsWithGlobals();
2253
+ const printer = createPrinter(globals);
2254
+ const spinner = printer.spinner(`Updating brand "${slug}"\u2026`);
2255
+ try {
2256
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2257
+ const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2258
+ const brand = await client.brands.update(slug, {
2259
+ ...opts.name ? { name: opts.name } : {},
2260
+ ...opts.timezone ? { timezone: opts.timezone } : {}
2261
+ });
2262
+ spinner.stop();
2263
+ printer.log(brand);
2264
+ } catch (err) {
2265
+ spinner.stop();
2266
+ printer.error(err);
2267
+ process.exit(exitCodeFromError(err));
2268
+ }
2269
+ });
2270
+ brands.command("delete <slug>").description("Delete a brand (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (slug, opts, cmd) => {
2271
+ const globals = cmd.optsWithGlobals();
2272
+ const printer = createPrinter(globals);
2273
+ if (!opts.force) {
2274
+ printer.error("--force is required to delete a brand. Pass --force to confirm.");
2275
+ process.exit(1);
2276
+ }
2277
+ const spinner = printer.spinner(`Deleting brand "${slug}"\u2026`);
2278
+ try {
2279
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2280
+ const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2281
+ await client.brands.remove(slug);
2282
+ spinner.stop();
2283
+ printer.log(`Brand "${slug}" deleted.`);
2284
+ } catch (err) {
2285
+ spinner.stop();
2286
+ printer.error(err);
2287
+ process.exit(exitCodeFromError(err));
2288
+ }
2289
+ });
2290
+ brands.command("auth-status <slug>").description("Show platform connection status for a brand").action(async (slug, _opts, cmd) => {
2291
+ const globals = cmd.optsWithGlobals();
2292
+ const printer = createPrinter(globals);
2293
+ const spinner = printer.spinner(`Fetching auth status for "${slug}"\u2026`);
2294
+ try {
2295
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2296
+ const client = new import_sdk3.Autoposting({ apiKey: cred.apiKey });
2297
+ const connections = await client.brands.authStatus(slug);
2298
+ spinner.stop();
2299
+ const rows = connections.map((c) => ({
2300
+ platform: c.platform,
2301
+ connected: c.connected ? "yes" : "no",
2302
+ username: c.username ?? "\u2014",
2303
+ "token status": c.tokenExpired === true ? "expired" : c.connected ? "ok" : "\u2014"
2304
+ }));
2305
+ printer.table(rows, ["platform", "connected", "username", "token status"]);
2306
+ } catch (err) {
2307
+ spinner.stop();
2308
+ printer.error(err);
2309
+ process.exit(exitCodeFromError(err));
2310
+ }
2311
+ });
2312
+ return brands;
2313
+ }
2314
+
2315
+ // src/commands/carousels.ts
2316
+ var import_commander5 = require("commander");
2317
+ var import_sdk4 = __toESM(require_dist());
2318
+ function resolveExitCode3(err) {
2319
+ const attached = err.exitCode;
2320
+ if (typeof attached === "number") return attached;
2321
+ return exitCodeFromError(err);
2322
+ }
2323
+ function createCarouselsCommand() {
2324
+ const carousels = new import_commander5.Command("carousels").description("Manage carousels");
2325
+ carousels.command("list").description("List all carousels").action(async (_opts, cmd) => {
2326
+ const globals = cmd.optsWithGlobals();
2327
+ const printer = createPrinter(globals);
2328
+ const spinner = printer.spinner("Fetching carousels\u2026");
2329
+ try {
2330
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2331
+ const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2332
+ const list = await client.carousels.list();
2333
+ spinner.stop();
2334
+ const rows = list.map((c) => ({
2335
+ id: c.id,
2336
+ title: c.title ?? "\u2014",
2337
+ slides: c.slides.length,
2338
+ status: c.status,
2339
+ createdAt: c.createdAt
2340
+ }));
2341
+ printer.table(rows, ["id", "title", "slides", "status", "createdAt"]);
2342
+ } catch (err) {
2343
+ spinner.stop();
2344
+ printer.error(err);
2345
+ process.exit(resolveExitCode3(err));
2346
+ }
2347
+ });
2348
+ carousels.command("get <id>").description("Get a carousel by ID").action(async (id, _opts, cmd) => {
2349
+ const globals = cmd.optsWithGlobals();
2350
+ const printer = createPrinter(globals);
2351
+ const spinner = printer.spinner(`Fetching carousel "${id}"\u2026`);
2352
+ try {
2353
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2354
+ const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2355
+ const carousel = await client.carousels.retrieve(id);
2356
+ spinner.stop();
2357
+ printer.log(carousel);
2358
+ } catch (err) {
2359
+ spinner.stop();
2360
+ printer.error(err);
2361
+ process.exit(resolveExitCode3(err));
2362
+ }
2363
+ });
2364
+ carousels.command("create").description("Create a new carousel").option("--title <title>", "Carousel title").action(async (opts, cmd) => {
2365
+ const globals = cmd.optsWithGlobals();
2366
+ const printer = createPrinter(globals);
2367
+ const spinner = printer.spinner("Creating carousel\u2026");
2368
+ try {
2369
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2370
+ const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2371
+ const carousel = await client.carousels.create(
2372
+ opts.title ? { title: opts.title } : void 0
2373
+ );
2374
+ spinner.stop();
2375
+ printer.log(carousel);
2376
+ } catch (err) {
2377
+ spinner.stop();
2378
+ printer.error(err);
2379
+ process.exit(resolveExitCode3(err));
2380
+ }
2381
+ });
2382
+ carousels.command("generate").description("AI-generate a carousel from a topic").requiredOption("--topic <topic>", "Topic to generate slides for").option("--brand <slug>", "Brand slug for brand voice").option("--slides <n>", "Number of slides to generate").action(async (opts, cmd) => {
2383
+ const globals = cmd.optsWithGlobals();
2384
+ const printer = createPrinter(globals);
2385
+ const spinner = printer.spinner("Generating carousel\u2026");
2386
+ try {
2387
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2388
+ const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2389
+ const carousel = await client.carousels.generate({
2390
+ topic: opts.topic,
2391
+ ...opts.brand ? { brandSlug: opts.brand } : {},
2392
+ ...opts.slides ? { slideCount: parseInt(opts.slides, 10) } : {}
2393
+ });
2394
+ spinner.stop();
2395
+ printer.log(carousel);
2396
+ } catch (err) {
2397
+ spinner.stop();
2398
+ printer.error(err);
2399
+ process.exit(resolveExitCode3(err));
2400
+ }
2401
+ });
2402
+ carousels.command("draft <id>").description("Convert a carousel to a post draft").action(async (id, _opts, cmd) => {
2403
+ const globals = cmd.optsWithGlobals();
2404
+ const printer = createPrinter(globals);
2405
+ const spinner = printer.spinner(`Converting carousel "${id}" to draft\u2026`);
2406
+ try {
2407
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2408
+ const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2409
+ const result = await client.carousels.draft(id);
2410
+ spinner.stop();
2411
+ printer.log(result);
2412
+ } catch (err) {
2413
+ spinner.stop();
2414
+ printer.error(err);
2415
+ process.exit(resolveExitCode3(err));
2416
+ }
2417
+ });
2418
+ carousels.command("delete <id>").description("Delete a carousel (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (id, opts, cmd) => {
2419
+ const globals = cmd.optsWithGlobals();
2420
+ const printer = createPrinter(globals);
2421
+ if (!opts.force) {
2422
+ printer.error("--force is required to delete a carousel. Pass --force to confirm.");
2423
+ process.exit(1);
2424
+ }
2425
+ const spinner = printer.spinner(`Deleting carousel "${id}"\u2026`);
2426
+ try {
2427
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2428
+ const client = new import_sdk4.Autoposting({ apiKey: cred.apiKey });
2429
+ await client.carousels.remove(id);
2430
+ spinner.stop();
2431
+ printer.log(`Carousel "${id}" deleted.`);
2432
+ } catch (err) {
2433
+ spinner.stop();
2434
+ printer.error(err);
2435
+ process.exit(resolveExitCode3(err));
2436
+ }
2437
+ });
2438
+ return carousels;
2439
+ }
2440
+
2441
+ // src/commands/clips.ts
2442
+ var import_commander6 = require("commander");
2443
+ var import_sdk5 = __toESM(require_dist());
2444
+ function resolveExitCode4(err) {
2445
+ const attached = err.exitCode;
2446
+ if (typeof attached === "number") return attached;
2447
+ return exitCodeFromError(err);
2448
+ }
2449
+ function createClipsCommand() {
2450
+ const clips = new import_commander6.Command("clips").description("Manage video clips");
2451
+ clips.command("list").description("List all clips").action(async (_opts, cmd) => {
2452
+ const globals = cmd.optsWithGlobals();
2453
+ const printer = createPrinter(globals);
2454
+ const spinner = printer.spinner("Fetching clips\u2026");
2455
+ try {
2456
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2457
+ const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2458
+ const list = await client.clips.list();
2459
+ spinner.stop();
2460
+ const rows = list.map((c) => ({
2461
+ id: c.id,
2462
+ name: c.name,
2463
+ status: c.status,
2464
+ duration: c.duration !== void 0 ? `${c.duration}s` : "\u2014"
2465
+ }));
2466
+ printer.table(rows, ["id", "name", "status", "duration"]);
2467
+ } catch (err) {
2468
+ spinner.stop();
2469
+ printer.error(err);
2470
+ process.exit(resolveExitCode4(err));
2471
+ }
2472
+ });
2473
+ clips.command("get <id>").description("Get a clip by ID").action(async (id, _opts, cmd) => {
2474
+ const globals = cmd.optsWithGlobals();
2475
+ const printer = createPrinter(globals);
2476
+ const spinner = printer.spinner(`Fetching clip "${id}"\u2026`);
2477
+ try {
2478
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2479
+ const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2480
+ const clip = await client.clips.retrieve(id);
2481
+ spinner.stop();
2482
+ printer.log(clip);
2483
+ } catch (err) {
2484
+ spinner.stop();
2485
+ printer.error(err);
2486
+ process.exit(resolveExitCode4(err));
2487
+ }
2488
+ });
2489
+ clips.command("upload <file>").description("Upload a video file as a clip").option("--name <name>", "Override the clip name (defaults to filename)").action(async (file, opts, cmd) => {
2490
+ const globals = cmd.optsWithGlobals();
2491
+ const printer = createPrinter(globals);
2492
+ const spinner = printer.spinner("Uploading clip\u2026");
2493
+ try {
2494
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2495
+ const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2496
+ const clip = await client.clips.upload(file, {
2497
+ name: opts.name,
2498
+ onProgress: (pct) => {
2499
+ if (pct > 0 && pct < 100) spinner.stop();
2500
+ }
2501
+ });
2502
+ spinner.stop();
2503
+ printer.log(clip);
2504
+ } catch (err) {
2505
+ spinner.stop();
2506
+ printer.error(err);
2507
+ process.exit(resolveExitCode4(err));
2508
+ }
2509
+ });
2510
+ clips.command("import").description("Import a clip from a URL").requiredOption("--url <url>", "URL of the video to import").option("--name <name>", "Name for the imported clip").action(async (opts, cmd) => {
2511
+ const globals = cmd.optsWithGlobals();
2512
+ const printer = createPrinter(globals);
2513
+ const spinner = printer.spinner("Importing clip\u2026");
2514
+ try {
2515
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2516
+ const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2517
+ const clip = await client.clips.importUrl({
2518
+ url: opts.url,
2519
+ ...opts.name ? { name: opts.name } : {}
2520
+ });
2521
+ spinner.stop();
2522
+ printer.log(clip);
2523
+ } catch (err) {
2524
+ spinner.stop();
2525
+ printer.error(err);
2526
+ process.exit(resolveExitCode4(err));
2527
+ }
2528
+ });
2529
+ clips.command("render <id>").description("Trigger rendering for a clip").action(async (id, _opts, cmd) => {
2530
+ const globals = cmd.optsWithGlobals();
2531
+ const printer = createPrinter(globals);
2532
+ const spinner = printer.spinner(`Rendering clip "${id}"\u2026`);
2533
+ try {
2534
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2535
+ const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2536
+ const clip = await client.clips.render(id);
2537
+ spinner.stop();
2538
+ printer.log(clip);
2539
+ } catch (err) {
2540
+ spinner.stop();
2541
+ printer.error(err);
2542
+ process.exit(resolveExitCode4(err));
2543
+ }
2544
+ });
2545
+ clips.command("delete <id>").description("Delete a clip (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (id, opts, cmd) => {
2546
+ const globals = cmd.optsWithGlobals();
2547
+ const printer = createPrinter(globals);
2548
+ if (!opts.force) {
2549
+ printer.error("--force is required to delete a clip. Pass --force to confirm.");
2550
+ process.exit(1);
2551
+ }
2552
+ const spinner = printer.spinner(`Deleting clip "${id}"\u2026`);
2553
+ try {
2554
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2555
+ const client = new import_sdk5.Autoposting({ apiKey: cred.apiKey });
2556
+ await client.clips.remove(id);
2557
+ spinner.stop();
2558
+ printer.log(`Clip "${id}" deleted.`);
2559
+ } catch (err) {
2560
+ spinner.stop();
2561
+ printer.error(err);
2562
+ process.exit(resolveExitCode4(err));
2563
+ }
2564
+ });
2565
+ return clips;
2566
+ }
2567
+
2568
+ // src/commands/posts.ts
2569
+ var import_commander7 = require("commander");
2570
+ var import_sdk6 = __toESM(require_dist());
2571
+ function parsePlatforms(raw) {
2572
+ return raw.split(",").map((p) => p.trim());
2573
+ }
2574
+ function resolveExitCode5(err) {
2575
+ const attached = err.exitCode;
2576
+ if (typeof attached === "number") return attached;
2577
+ return exitCodeFromError(err);
2578
+ }
2579
+ function createPostsCommand() {
2580
+ const posts = new import_commander7.Command("posts").description("Manage posts");
2581
+ posts.command("list").description("List posts").option("--brand <slug>", "Filter by brand slug").option("--status <status>", "Filter by status (draft|scheduled|published|failed)").option("--limit <n>", "Max results per page", "20").option("--page <n>", "Page number", "1").action(async (opts, cmd) => {
2582
+ const globals = cmd.optsWithGlobals();
2583
+ const printer = createPrinter(globals);
2584
+ const spinner = printer.spinner("Fetching posts\u2026");
2585
+ try {
2586
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2587
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2588
+ const result = await client.posts.list({
2589
+ brandSlug: opts.brand,
2590
+ status: opts.status,
2591
+ limit: parseInt(opts.limit, 10),
2592
+ page: parseInt(opts.page, 10)
2593
+ });
2594
+ spinner.stop();
2595
+ const rows = result.data.map((p) => ({
2596
+ id: p.id,
2597
+ brand: p.brandSlug,
2598
+ status: p.status,
2599
+ platforms: p.platforms.join(", "),
2600
+ text: p.text.length > 60 ? `${p.text.slice(0, 57)}\u2026` : p.text,
2601
+ scheduledAt: p.scheduledAt ?? "\u2014"
2602
+ }));
2603
+ printer.table(rows, ["id", "brand", "status", "platforms", "text", "scheduledAt"]);
2604
+ } catch (err) {
2605
+ spinner.stop();
2606
+ printer.error(err);
2607
+ process.exit(resolveExitCode5(err));
2608
+ }
2609
+ });
2610
+ posts.command("get <id>").description("Get a post by ID").action(async (id, _opts, cmd) => {
2611
+ const globals = cmd.optsWithGlobals();
2612
+ const printer = createPrinter(globals);
2613
+ const spinner = printer.spinner(`Fetching post "${id}"\u2026`);
2614
+ try {
2615
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2616
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2617
+ const post = await client.posts.getById(id);
2618
+ spinner.stop();
2619
+ printer.log(post);
2620
+ } catch (err) {
2621
+ spinner.stop();
2622
+ printer.error(err);
2623
+ process.exit(resolveExitCode5(err));
2624
+ }
2625
+ });
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(
2627
+ async (opts, cmd) => {
2628
+ const globals = cmd.optsWithGlobals();
2629
+ const printer = createPrinter(globals);
2630
+ const spinner = printer.spinner("Creating post\u2026");
2631
+ try {
2632
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2633
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2634
+ const post = await client.posts.create({
2635
+ brandSlug: opts.brand,
2636
+ text: opts.text,
2637
+ platforms: parsePlatforms(opts.platforms),
2638
+ ...opts.at ? { scheduledAt: opts.at } : {}
2639
+ });
2640
+ spinner.stop();
2641
+ printer.log(post);
2642
+ } catch (err) {
2643
+ spinner.stop();
2644
+ printer.error(err);
2645
+ process.exit(resolveExitCode5(err));
2646
+ }
2647
+ }
2648
+ );
2649
+ posts.command("update <id>").description("Update a post").option("--text <text>", "New post text").option("--platforms <list>", "New comma-separated platforms").option("--at <iso>", "New scheduled date/time (ISO 8601)").action(
2650
+ async (id, opts, cmd) => {
2651
+ const globals = cmd.optsWithGlobals();
2652
+ const printer = createPrinter(globals);
2653
+ const spinner = printer.spinner(`Updating post "${id}"\u2026`);
2654
+ try {
2655
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2656
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2657
+ const post = await client.posts.update(id, {
2658
+ ...opts.text ? { text: opts.text } : {},
2659
+ ...opts.platforms ? { platforms: parsePlatforms(opts.platforms) } : {},
2660
+ ...opts.at ? { scheduledAt: opts.at } : {}
2661
+ });
2662
+ spinner.stop();
2663
+ printer.log(post);
2664
+ } catch (err) {
2665
+ spinner.stop();
2666
+ printer.error(err);
2667
+ process.exit(resolveExitCode5(err));
2668
+ }
2669
+ }
2670
+ );
2671
+ posts.command("delete <id>").description("Delete a post (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (id, opts, cmd) => {
2672
+ const globals = cmd.optsWithGlobals();
2673
+ const printer = createPrinter(globals);
2674
+ if (!opts.force) {
2675
+ printer.error("--force is required to delete a post. Pass --force to confirm.");
2676
+ process.exit(1);
2677
+ }
2678
+ const spinner = printer.spinner(`Deleting post "${id}"\u2026`);
2679
+ try {
2680
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2681
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2682
+ await client.posts.remove(id);
2683
+ spinner.stop();
2684
+ printer.log(`Post "${id}" deleted.`);
2685
+ } catch (err) {
2686
+ spinner.stop();
2687
+ printer.error(err);
2688
+ process.exit(resolveExitCode5(err));
2689
+ }
2690
+ });
2691
+ posts.command("publish <id>").description("Publish a post immediately").action(async (id, _opts, cmd) => {
2692
+ const globals = cmd.optsWithGlobals();
2693
+ const printer = createPrinter(globals);
2694
+ const spinner = printer.spinner(`Publishing post "${id}"\u2026`);
2695
+ try {
2696
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2697
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2698
+ const post = await client.posts.publish(id);
2699
+ spinner.stop();
2700
+ printer.log(post);
2701
+ } catch (err) {
2702
+ spinner.stop();
2703
+ printer.error(err);
2704
+ process.exit(resolveExitCode5(err));
2705
+ }
2706
+ });
2707
+ posts.command("schedule <id>").description("Schedule a post for a specific time").requiredOption("--at <iso>", "ISO 8601 datetime to schedule the post").action(async (id, opts, cmd) => {
2708
+ const globals = cmd.optsWithGlobals();
2709
+ const printer = createPrinter(globals);
2710
+ const spinner = printer.spinner(`Scheduling post "${id}"\u2026`);
2711
+ try {
2712
+ 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);
2715
+ spinner.stop();
2716
+ printer.log(post);
2717
+ } catch (err) {
2718
+ spinner.stop();
2719
+ printer.error(err);
2720
+ process.exit(resolveExitCode5(err));
2721
+ }
2722
+ });
2723
+ posts.command("retry <id>").description("Retry a failed post").action(async (id, _opts, cmd) => {
2724
+ const globals = cmd.optsWithGlobals();
2725
+ const printer = createPrinter(globals);
2726
+ const spinner = printer.spinner(`Retrying post "${id}"\u2026`);
2727
+ try {
2728
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2729
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2730
+ const post = await client.posts.retry(id);
2731
+ spinner.stop();
2732
+ printer.log(post);
2733
+ } catch (err) {
2734
+ spinner.stop();
2735
+ printer.error(err);
2736
+ process.exit(resolveExitCode5(err));
2737
+ }
2738
+ });
2739
+ posts.command("rewrite <id>").description("AI-rewrite a post").action(async (id, _opts, cmd) => {
2740
+ const globals = cmd.optsWithGlobals();
2741
+ const printer = createPrinter(globals);
2742
+ const spinner = printer.spinner(`Rewriting post "${id}"\u2026`);
2743
+ try {
2744
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2745
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2746
+ const post = await client.posts.rewrite(id);
2747
+ spinner.stop();
2748
+ printer.log(post);
2749
+ } catch (err) {
2750
+ spinner.stop();
2751
+ printer.error(err);
2752
+ process.exit(resolveExitCode5(err));
2753
+ }
2754
+ });
2755
+ posts.command("score <id>").description("Score a post with AI feedback").action(async (id, _opts, cmd) => {
2756
+ const globals = cmd.optsWithGlobals();
2757
+ const printer = createPrinter(globals);
2758
+ const spinner = printer.spinner(`Scoring post "${id}"\u2026`);
2759
+ try {
2760
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2761
+ const client = new import_sdk6.Autoposting({ apiKey: cred.apiKey });
2762
+ const result = await client.posts.score(id);
2763
+ spinner.stop();
2764
+ printer.log(result);
2765
+ } catch (err) {
2766
+ spinner.stop();
2767
+ printer.error(err);
2768
+ process.exit(resolveExitCode5(err));
2769
+ }
2770
+ });
2771
+ return posts;
2772
+ }
2773
+
2774
+ // src/commands/kb.ts
2775
+ var import_commander8 = require("commander");
2776
+ var import_sdk7 = __toESM(require_dist());
2777
+ function resolveExitCode6(err) {
2778
+ const attached = err.exitCode;
2779
+ if (typeof attached === "number") return attached;
2780
+ return exitCodeFromError(err);
2781
+ }
2782
+ function createKbCommand() {
2783
+ const kb = new import_commander8.Command("kb").description("Manage knowledge bases");
2784
+ kb.command("list").description("List all knowledge bases").action(async (_opts, cmd) => {
2785
+ const globals = cmd.optsWithGlobals();
2786
+ const printer = createPrinter(globals);
2787
+ const spinner = printer.spinner("Fetching knowledge bases\u2026");
2788
+ try {
2789
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2790
+ const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2791
+ const list = await client.kb.list();
2792
+ spinner.stop();
2793
+ const rows = list.map((k) => ({
2794
+ id: k.id,
2795
+ name: k.name,
2796
+ docs: k.docCount ?? 0,
2797
+ createdAt: k.createdAt
2798
+ }));
2799
+ printer.table(rows, ["id", "name", "docs", "createdAt"]);
2800
+ } catch (err) {
2801
+ spinner.stop();
2802
+ printer.error(err);
2803
+ process.exit(resolveExitCode6(err));
2804
+ }
2805
+ });
2806
+ kb.command("get <id>").description("Get a knowledge base by ID").action(async (id, _opts, cmd) => {
2807
+ const globals = cmd.optsWithGlobals();
2808
+ const printer = createPrinter(globals);
2809
+ const spinner = printer.spinner(`Fetching knowledge base "${id}"\u2026`);
2810
+ try {
2811
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2812
+ const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2813
+ const result = await client.kb.retrieve(id);
2814
+ spinner.stop();
2815
+ printer.log(result);
2816
+ } catch (err) {
2817
+ spinner.stop();
2818
+ printer.error(err);
2819
+ process.exit(resolveExitCode6(err));
2820
+ }
2821
+ });
2822
+ kb.command("create").description("Create a new knowledge base").requiredOption("--name <name>", "Knowledge base name").action(async (opts, cmd) => {
2823
+ const globals = cmd.optsWithGlobals();
2824
+ const printer = createPrinter(globals);
2825
+ const spinner = printer.spinner("Creating knowledge base\u2026");
2826
+ try {
2827
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2828
+ const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2829
+ const result = await client.kb.create({ name: opts.name });
2830
+ spinner.stop();
2831
+ printer.log(result);
2832
+ } catch (err) {
2833
+ spinner.stop();
2834
+ printer.error(err);
2835
+ process.exit(resolveExitCode6(err));
2836
+ }
2837
+ });
2838
+ kb.command("delete <id>").description("Delete a knowledge base (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (id, opts, cmd) => {
2839
+ const globals = cmd.optsWithGlobals();
2840
+ const printer = createPrinter(globals);
2841
+ if (!opts.force) {
2842
+ printer.error("--force is required to delete a knowledge base. Pass --force to confirm.");
2843
+ process.exit(1);
2844
+ }
2845
+ const spinner = printer.spinner(`Deleting knowledge base "${id}"\u2026`);
2846
+ try {
2847
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2848
+ const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2849
+ await client.kb.remove(id);
2850
+ spinner.stop();
2851
+ printer.log(`Knowledge base "${id}" deleted.`);
2852
+ } catch (err) {
2853
+ spinner.stop();
2854
+ printer.error(err);
2855
+ process.exit(resolveExitCode6(err));
2856
+ }
2857
+ });
2858
+ kb.command("search <id>").description("Search a knowledge base").requiredOption("--query <text>", "Search query").action(async (id, opts, cmd) => {
2859
+ const globals = cmd.optsWithGlobals();
2860
+ const printer = createPrinter(globals);
2861
+ const spinner = printer.spinner(`Searching knowledge base "${id}"\u2026`);
2862
+ try {
2863
+ 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);
2866
+ spinner.stop();
2867
+ const rows = results.map((r) => ({
2868
+ docId: r.docId,
2869
+ score: r.score.toFixed(3),
2870
+ content: r.content.length > 80 ? `${r.content.slice(0, 77)}\u2026` : r.content
2871
+ }));
2872
+ printer.table(rows, ["docId", "score", "content"]);
2873
+ } catch (err) {
2874
+ spinner.stop();
2875
+ printer.error(err);
2876
+ process.exit(resolveExitCode6(err));
2877
+ }
2878
+ });
2879
+ kb.command("ingest <id>").description("Ingest a URL into a knowledge base").requiredOption("--url <url>", "URL to ingest").action(async (id, opts, cmd) => {
2880
+ const globals = cmd.optsWithGlobals();
2881
+ const printer = createPrinter(globals);
2882
+ const spinner = printer.spinner(`Ingesting URL into knowledge base "${id}"\u2026`);
2883
+ try {
2884
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2885
+ const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2886
+ const doc = await client.kb.ingestUrl(id, opts.url);
2887
+ spinner.stop();
2888
+ printer.log(doc);
2889
+ } catch (err) {
2890
+ spinner.stop();
2891
+ printer.error(err);
2892
+ process.exit(resolveExitCode6(err));
2893
+ }
2894
+ });
2895
+ kb.command("docs <id>").description("List documents in a knowledge base").action(async (id, _opts, cmd) => {
2896
+ const globals = cmd.optsWithGlobals();
2897
+ const printer = createPrinter(globals);
2898
+ const spinner = printer.spinner(`Fetching documents for knowledge base "${id}"\u2026`);
2899
+ try {
2900
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2901
+ const client = new import_sdk7.Autoposting({ apiKey: cred.apiKey });
2902
+ const docs = await client.kb.docs(id);
2903
+ spinner.stop();
2904
+ const rows = docs.map((d) => ({
2905
+ id: d.id,
2906
+ name: d.name,
2907
+ type: d.type,
2908
+ status: d.status,
2909
+ createdAt: d.createdAt
2910
+ }));
2911
+ printer.table(rows, ["id", "name", "type", "status", "createdAt"]);
2912
+ } catch (err) {
2913
+ spinner.stop();
2914
+ printer.error(err);
2915
+ process.exit(resolveExitCode6(err));
2916
+ }
2917
+ });
2918
+ return kb;
2919
+ }
2920
+
2921
+ // src/commands/ideas.ts
2922
+ var import_commander9 = require("commander");
2923
+ var import_sdk8 = __toESM(require_dist());
2924
+ function resolveExitCode7(err) {
2925
+ const attached = err.exitCode;
2926
+ if (typeof attached === "number") return attached;
2927
+ return exitCodeFromError(err);
2928
+ }
2929
+ function createIdeasCommand() {
2930
+ const ideas = new import_commander9.Command("ideas").description("Manage content ideas");
2931
+ 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) => {
2932
+ const globals = cmd.optsWithGlobals();
2933
+ const printer = createPrinter(globals);
2934
+ const spinner = printer.spinner("Generating ideas\u2026");
2935
+ try {
2936
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2937
+ const client = new import_sdk8.Autoposting({ apiKey: cred.apiKey });
2938
+ const result = await client.ideas.generate({
2939
+ ...opts.kb ? { kbId: opts.kb } : {},
2940
+ ...opts.topic ? { topic: opts.topic } : {},
2941
+ count: parseInt(opts.count, 10)
2942
+ });
2943
+ 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
2949
+ }));
2950
+ printer.table(rows, ["id", "topic", "enriched", "text"]);
2951
+ } catch (err) {
2952
+ spinner.stop();
2953
+ printer.error(err);
2954
+ process.exit(resolveExitCode7(err));
2955
+ }
2956
+ });
2957
+ ideas.command("list").description("List all ideas").action(async (_opts, cmd) => {
2958
+ const globals = cmd.optsWithGlobals();
2959
+ const printer = createPrinter(globals);
2960
+ const spinner = printer.spinner("Fetching ideas\u2026");
2961
+ try {
2962
+ const cred = resolveAuth({ apiKey: globals.apiKey });
2963
+ const client = new import_sdk8.Autoposting({ apiKey: cred.apiKey });
2964
+ const list = await client.ideas.list();
2965
+ spinner.stop();
2966
+ const rows = list.map((i) => ({
2967
+ 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
2972
+ }));
2973
+ printer.table(rows, ["id", "topic", "enriched", "text", "createdAt"]);
2974
+ } catch (err) {
2975
+ spinner.stop();
2976
+ printer.error(err);
2977
+ process.exit(resolveExitCode7(err));
2978
+ }
2979
+ });
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));
2994
+ }
2995
+ });
2996
+ ideas.command("delete <id>").description("Delete an idea (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (id, opts, cmd) => {
2997
+ const globals = cmd.optsWithGlobals();
2998
+ const printer = createPrinter(globals);
2999
+ if (!opts.force) {
3000
+ printer.error("--force is required to delete an idea. Pass --force to confirm.");
3001
+ process.exit(1);
3002
+ }
3003
+ const spinner = printer.spinner(`Deleting idea "${id}"\u2026`);
3004
+ try {
3005
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3006
+ const client = new import_sdk8.Autoposting({ apiKey: cred.apiKey });
3007
+ await client.ideas.remove(id);
3008
+ spinner.stop();
3009
+ printer.log(`Idea "${id}" deleted.`);
3010
+ } catch (err) {
3011
+ spinner.stop();
3012
+ printer.error(err);
3013
+ process.exit(resolveExitCode7(err));
3014
+ }
3015
+ });
3016
+ return ideas;
3017
+ }
3018
+
3019
+ // src/commands/usage.ts
3020
+ var import_commander10 = require("commander");
3021
+ var import_sdk9 = __toESM(require_dist());
3022
+ function resolveExitCode8(err) {
3023
+ const attached = err.exitCode;
3024
+ if (typeof attached === "number") return attached;
3025
+ return exitCodeFromError(err);
3026
+ }
3027
+ function createUsageCommand() {
3028
+ const usage = new import_commander10.Command("usage").description("View usage statistics");
3029
+ usage.command("summary").description("Show usage summary for the current period").action(async (_opts, cmd) => {
3030
+ const globals = cmd.optsWithGlobals();
3031
+ const printer = createPrinter(globals);
3032
+ const spinner = printer.spinner("Fetching usage summary\u2026");
3033
+ try {
3034
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3035
+ const client = new import_sdk9.Autoposting({ apiKey: cred.apiKey });
3036
+ const summary = await client.usage.summary();
3037
+ 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
3043
+ }));
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
+ }
3050
+ } catch (err) {
3051
+ spinner.stop();
3052
+ printer.error(err);
3053
+ process.exit(resolveExitCode8(err));
3054
+ }
3055
+ });
3056
+ return usage;
3057
+ }
3058
+
3059
+ // src/commands/webhooks.ts
3060
+ var import_commander11 = require("commander");
3061
+ var import_sdk10 = __toESM(require_dist());
3062
+ function resolveExitCode9(err) {
3063
+ const attached = err.exitCode;
3064
+ if (typeof attached === "number") return attached;
3065
+ return exitCodeFromError(err);
3066
+ }
3067
+ function createWebhooksCommand() {
3068
+ const webhooks = new import_commander11.Command("webhooks").description("Manage webhooks");
3069
+ webhooks.command("list").description("List all webhooks").action(async (_opts, cmd) => {
3070
+ const globals = cmd.optsWithGlobals();
3071
+ const printer = createPrinter(globals);
3072
+ const spinner = printer.spinner("Fetching webhooks\u2026");
3073
+ try {
3074
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3075
+ const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3076
+ const list = await client.webhooks.list();
3077
+ spinner.stop();
3078
+ const rows = list.map((w) => ({
3079
+ id: w.id,
3080
+ url: w.url,
3081
+ events: w.events.join(", "),
3082
+ active: w.active ? "yes" : "no",
3083
+ createdAt: w.createdAt
3084
+ }));
3085
+ printer.table(rows, ["id", "url", "events", "active", "createdAt"]);
3086
+ } catch (err) {
3087
+ spinner.stop();
3088
+ printer.error(err);
3089
+ process.exit(resolveExitCode9(err));
3090
+ }
3091
+ });
3092
+ webhooks.command("get <id>").description("Get a webhook by ID").action(async (id, _opts, cmd) => {
3093
+ const globals = cmd.optsWithGlobals();
3094
+ const printer = createPrinter(globals);
3095
+ const spinner = printer.spinner(`Fetching webhook "${id}"\u2026`);
3096
+ try {
3097
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3098
+ const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3099
+ const webhook = await client.webhooks.retrieve(id);
3100
+ spinner.stop();
3101
+ printer.log(webhook);
3102
+ } catch (err) {
3103
+ spinner.stop();
3104
+ printer.error(err);
3105
+ process.exit(resolveExitCode9(err));
3106
+ }
3107
+ });
3108
+ webhooks.command("create").description("Create a new webhook").requiredOption("--url <url>", "Endpoint URL to receive events").requiredOption("--events <list>", "Comma-separated event types (e.g. post.published,post.failed)").option("--secret <secret>", "Signing secret for HMAC verification").action(
3109
+ async (opts, cmd) => {
3110
+ const globals = cmd.optsWithGlobals();
3111
+ const printer = createPrinter(globals);
3112
+ const spinner = printer.spinner("Creating webhook\u2026");
3113
+ try {
3114
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3115
+ const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3116
+ const webhook = await client.webhooks.create({
3117
+ url: opts.url,
3118
+ events: opts.events.split(",").map((e) => e.trim()),
3119
+ ...opts.secret ? { secret: opts.secret } : {}
3120
+ });
3121
+ spinner.stop();
3122
+ printer.log(webhook);
3123
+ } catch (err) {
3124
+ spinner.stop();
3125
+ printer.error(err);
3126
+ process.exit(resolveExitCode9(err));
3127
+ }
3128
+ }
3129
+ );
3130
+ webhooks.command("update <id>").description("Update a webhook").option("--url <url>", "New endpoint URL").option("--events <list>", "New comma-separated event types").option("--active", "Set webhook as active").option("--no-active", "Set webhook as inactive").action(
3131
+ async (id, opts, cmd) => {
3132
+ const globals = cmd.optsWithGlobals();
3133
+ const printer = createPrinter(globals);
3134
+ const spinner = printer.spinner(`Updating webhook "${id}"\u2026`);
3135
+ try {
3136
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3137
+ const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3138
+ const webhook = await client.webhooks.update(id, {
3139
+ ...opts.url ? { url: opts.url } : {},
3140
+ ...opts.events ? { events: opts.events.split(",").map((e) => e.trim()) } : {},
3141
+ ...opts.active !== void 0 ? { active: opts.active } : {}
3142
+ });
3143
+ spinner.stop();
3144
+ printer.log(webhook);
3145
+ } catch (err) {
3146
+ spinner.stop();
3147
+ printer.error(err);
3148
+ process.exit(resolveExitCode9(err));
3149
+ }
3150
+ }
3151
+ );
3152
+ webhooks.command("delete <id>").description("Delete a webhook (requires --force)").option("--force", "Confirm deletion without interactive prompt").action(async (id, opts, cmd) => {
3153
+ const globals = cmd.optsWithGlobals();
3154
+ const printer = createPrinter(globals);
3155
+ if (!opts.force) {
3156
+ printer.error("--force is required to delete a webhook. Pass --force to confirm.");
3157
+ process.exit(1);
3158
+ }
3159
+ const spinner = printer.spinner(`Deleting webhook "${id}"\u2026`);
3160
+ try {
3161
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3162
+ const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3163
+ await client.webhooks.remove(id);
3164
+ spinner.stop();
3165
+ printer.log(`Webhook "${id}" deleted.`);
3166
+ } catch (err) {
3167
+ spinner.stop();
3168
+ printer.error(err);
3169
+ process.exit(resolveExitCode9(err));
3170
+ }
3171
+ });
3172
+ webhooks.command("test <id>").description("Send a test event to a webhook").action(async (id, _opts, cmd) => {
3173
+ const globals = cmd.optsWithGlobals();
3174
+ const printer = createPrinter(globals);
3175
+ const spinner = printer.spinner(`Sending test event to webhook "${id}"\u2026`);
3176
+ try {
3177
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3178
+ const client = new import_sdk10.Autoposting({ apiKey: cred.apiKey });
3179
+ await client.webhooks.test(id);
3180
+ spinner.stop();
3181
+ printer.log(`Test event sent to webhook "${id}".`);
3182
+ } catch (err) {
3183
+ spinner.stop();
3184
+ printer.error(err);
3185
+ process.exit(resolveExitCode9(err));
3186
+ }
3187
+ });
3188
+ return webhooks;
3189
+ }
3190
+
3191
+ // src/commands/workspaces.ts
3192
+ var import_commander12 = require("commander");
3193
+ var import_sdk11 = __toESM(require_dist());
3194
+ function resolveExitCode10(err) {
3195
+ const attached = err.exitCode;
3196
+ if (typeof attached === "number") return attached;
3197
+ return exitCodeFromError(err);
3198
+ }
3199
+ function createWorkspacesCommand() {
3200
+ const workspaces = new import_commander12.Command("workspaces").description("Manage workspaces");
3201
+ workspaces.command("list").description("List all workspaces").action(async (_opts, cmd) => {
3202
+ const globals = cmd.optsWithGlobals();
3203
+ const printer = createPrinter(globals);
3204
+ const spinner = printer.spinner("Fetching workspaces\u2026");
3205
+ try {
3206
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3207
+ const client = new import_sdk11.Autoposting({ apiKey: cred.apiKey });
3208
+ const list = await client.workspaces.list();
3209
+ spinner.stop();
3210
+ const rows = list.map((w) => ({
3211
+ id: w.id,
3212
+ name: w.name,
3213
+ slug: w.slug,
3214
+ active: w.isActive ? "yes" : "no",
3215
+ createdAt: w.createdAt
3216
+ }));
3217
+ printer.table(rows, ["id", "name", "slug", "active", "createdAt"]);
3218
+ } catch (err) {
3219
+ spinner.stop();
3220
+ printer.error(err);
3221
+ process.exit(resolveExitCode10(err));
3222
+ }
3223
+ });
3224
+ workspaces.command("switch <id>").description("Switch the active workspace (session auth only)").action(async (id, _opts, cmd) => {
3225
+ const globals = cmd.optsWithGlobals();
3226
+ const printer = createPrinter(globals);
3227
+ const spinner = printer.spinner(`Switching to workspace "${id}"\u2026`);
3228
+ try {
3229
+ const cred = resolveAuth({ apiKey: globals.apiKey });
3230
+ 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 });
3232
+ await client.workspaces.switchWorkspace(id);
3233
+ spinner.stop();
3234
+ printer.log(`Switched to workspace "${id}".`);
3235
+ } catch (err) {
3236
+ spinner.stop();
3237
+ printer.error(err);
3238
+ process.exit(resolveExitCode10(err));
3239
+ }
3240
+ });
3241
+ return workspaces;
3242
+ }
3243
+
3244
+ // src/commands/doctor.ts
3245
+ var import_commander13 = require("commander");
3246
+ var import_node_fs2 = __toESM(require("fs"));
3247
+ var VERSION = "0.1.0";
3248
+ var API_HEALTH_URL = "https://app.autoposting.ai/api/health";
3249
+ async function runChecks() {
3250
+ const results = [];
3251
+ results.push({ name: "CLI Version", status: "pass", value: VERSION });
3252
+ const nodeVersion = process.version;
3253
+ const nodeMajor = parseInt(nodeVersion.slice(1), 10);
3254
+ results.push({
3255
+ name: "Node.js",
3256
+ status: nodeMajor >= 20 ? "pass" : "fail",
3257
+ value: nodeVersion
3258
+ });
3259
+ try {
3260
+ resolveAuth();
3261
+ results.push({ name: "Auth", status: "pass", value: "authenticated" });
3262
+ } catch {
3263
+ results.push({ name: "Auth", status: "fail", value: "not configured" });
3264
+ }
3265
+ const credPath = getCredentialsPath();
3266
+ try {
3267
+ const stat = import_node_fs2.default.statSync(credPath);
3268
+ const mode = stat.mode & 511;
3269
+ const isSecure = mode === 384;
3270
+ results.push({
3271
+ name: "Credentials",
3272
+ status: isSecure ? "pass" : "warn",
3273
+ value: isSecure ? `${credPath} (0600)` : `${credPath} (mode ${mode.toString(8)} \u2014 expected 0600)`
3274
+ });
3275
+ } catch {
3276
+ results.push({ name: "Credentials", status: "warn", value: "no credentials file found" });
3277
+ }
3278
+ try {
3279
+ const controller = new AbortController();
3280
+ const timeout = setTimeout(() => controller.abort(), 5e3);
3281
+ const res = await fetch(API_HEALTH_URL, { signal: controller.signal });
3282
+ clearTimeout(timeout);
3283
+ results.push({
3284
+ name: "API",
3285
+ status: res.ok ? "pass" : "fail",
3286
+ value: `HTTP ${res.status}`
3287
+ });
3288
+ } catch (err) {
3289
+ const msg = err instanceof Error ? err.message : String(err);
3290
+ results.push({ name: "API", status: "fail", value: `unreachable: ${msg}` });
3291
+ }
3292
+ return results;
3293
+ }
3294
+ function createDoctorCommand() {
3295
+ const cmd = new import_commander13.Command("doctor").description("Run diagnostic checks on your CLI setup").option("--json", "Output results as JSON").action(async (_opts, cmd2) => {
3296
+ const globals = cmd2.optsWithGlobals();
3297
+ const results = await runChecks();
3298
+ if (globals.json) {
3299
+ console.log(JSON.stringify(results, null, 2));
3300
+ } else {
3301
+ for (const r of results) {
3302
+ const icon = r.status === "pass" ? "\u2713" : r.status === "warn" ? "!" : "\u2717";
3303
+ const label = r.status === "pass" ? "pass" : r.status === "warn" ? "warn" : "FAIL";
3304
+ console.log(` ${icon} ${r.name.padEnd(16)} [${label}] ${r.value}`);
3305
+ }
3306
+ }
3307
+ const anyFail = results.some((r) => r.status === "fail");
3308
+ if (anyFail) process.exit(1);
3309
+ });
3310
+ return cmd;
3311
+ }
3312
+
3313
+ // src/commands/whoami.ts
3314
+ var import_commander14 = require("commander");
3315
+ function createWhoamiCommand() {
3316
+ return new import_commander14.Command("whoami").description("Show current authentication identity (alias for `auth whoami`)").action((_opts, cmd) => {
3317
+ 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}`);
3344
+ } catch (err) {
3345
+ console.error(`Error: ${err.message}`);
3346
+ process.exit(2);
3347
+ }
3348
+ });
3349
+ }
3350
+
3351
+ // src/commands/open.ts
3352
+ var import_commander15 = require("commander");
3353
+ var import_open = __toESM(require("open"));
3354
+ var URLS = {
3355
+ "": "https://app.autoposting.ai",
3356
+ posts: "https://app.autoposting.ai/posts",
3357
+ brands: "https://app.autoposting.ai/brands",
3358
+ agents: "https://app.autoposting.ai/agents",
3359
+ settings: "https://app.autoposting.ai/settings",
3360
+ billing: "https://app.autoposting.ai/settings/billing"
3361
+ };
3362
+ var VALID_SECTIONS = Object.keys(URLS).filter((k) => k !== "");
3363
+ function createOpenCommand() {
3364
+ return new import_commander15.Command("open").description(`Open the Autoposting dashboard in your browser. Sections: ${VALID_SECTIONS.join(", ")}`).argument("[section]", `Dashboard section to open (${VALID_SECTIONS.join("|")})`, "").option("--no-browser", "Print URL only, do not open browser").action(async (section, opts) => {
3365
+ const key = section ?? "";
3366
+ if (!(key in URLS)) {
3367
+ console.error(`Error: unknown section "${key}". Valid sections: ${VALID_SECTIONS.join(", ")}`);
3368
+ process.exit(1);
3369
+ }
3370
+ const url = URLS[key];
3371
+ if (!opts.browser) {
3372
+ console.log(url);
3373
+ return;
3374
+ }
3375
+ console.log(`Opening ${url}`);
3376
+ try {
3377
+ await (0, import_open.default)(url);
3378
+ } catch (err) {
3379
+ console.error(`Error: failed to open browser \u2014 ${err.message}`);
3380
+ console.log(`Visit manually: ${url}`);
3381
+ process.exit(1);
3382
+ }
3383
+ });
3384
+ }
3385
+
3386
+ // src/commands/update.ts
3387
+ var import_commander16 = require("commander");
3388
+ 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";
3391
+ 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) => {
3393
+ let latest;
3394
+ try {
3395
+ const controller = new AbortController();
3396
+ const timeout = setTimeout(() => controller.abort(), 8e3);
3397
+ const res = await fetch(REGISTRY_URL, { signal: controller.signal });
3398
+ clearTimeout(timeout);
3399
+ if (!res.ok) {
3400
+ console.error(`Error: registry returned HTTP ${res.status}`);
3401
+ process.exit(1);
3402
+ }
3403
+ const data = await res.json();
3404
+ latest = data.version;
3405
+ } catch (err) {
3406
+ console.error(`Error: could not reach npm registry \u2014 ${err.message}`);
3407
+ process.exit(1);
3408
+ }
3409
+ if (latest === VERSION2) {
3410
+ console.log(`You are already on the latest version (${VERSION2}).`);
3411
+ return;
3412
+ }
3413
+ console.log(`Current version: ${VERSION2}`);
3414
+ console.log(`Latest version: ${latest}`);
3415
+ if (!opts.yes) {
3416
+ console.log(`Run \`ap update --yes\` to install v${latest}.`);
3417
+ return;
3418
+ }
3419
+ console.log(`Installing autoposting-cli@${latest}\u2026`);
3420
+ try {
3421
+ (0, import_node_child_process2.execSync)(`npm install -g autoposting-cli@${latest}`, { stdio: "inherit" });
3422
+ console.log(`Updated to v${latest}.`);
3423
+ } catch (err) {
3424
+ console.error(`Error: install failed \u2014 ${err.message}`);
3425
+ process.exit(1);
3426
+ }
3427
+ });
3428
+ }
3429
+
3430
+ // src/commands/completion.ts
3431
+ var import_commander17 = require("commander");
3432
+ var ALL_COMMANDS = [
3433
+ "posts",
3434
+ "brands",
3435
+ "agents",
3436
+ "kb",
3437
+ "ideas",
3438
+ "clips",
3439
+ "carousels",
3440
+ "webhooks",
3441
+ "billing",
3442
+ "usage",
3443
+ "workspaces",
3444
+ "auth",
3445
+ "doctor",
3446
+ "whoami",
3447
+ "open",
3448
+ "update",
3449
+ "completion"
3450
+ ];
3451
+ var SHELLS = ["bash", "zsh", "fish", "pwsh"];
3452
+ var TEMPLATES = {
3453
+ bash: (cmds) => `# bash completion for ap / autoposting
3454
+ # Add to ~/.bashrc or ~/.bash_profile:
3455
+ # source <(ap completion bash)
3456
+ _ap_completions() {
3457
+ local cur="\${COMP_WORDS[COMP_CWORD]}"
3458
+ local commands="${cmds.join(" ")}"
3459
+ COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
3460
+ }
3461
+ complete -F _ap_completions ap
3462
+ complete -F _ap_completions autoposting
3463
+ `,
3464
+ zsh: (cmds) => `# zsh completion for ap / autoposting
3465
+ # Add to ~/.zshrc:
3466
+ # source <(ap completion zsh)
3467
+ # Or append directly:
3468
+ # ap completion zsh >> ~/.zshrc
3469
+ _ap() {
3470
+ compadd ${cmds.join(" ")}
3471
+ }
3472
+ compdef _ap ap autoposting
3473
+ `,
3474
+ fish: (cmds) => `# fish completion for ap / autoposting
3475
+ # Save to ~/.config/fish/completions/ap.fish or run:
3476
+ # ap completion fish | source
3477
+ ${cmds.map((c) => `complete -c ap -f -a '${c}'`).join("\n")}
3478
+ ${cmds.map((c) => `complete -c autoposting -f -a '${c}'`).join("\n")}
3479
+ `,
3480
+ pwsh: (cmds) => `# PowerShell completion for ap / autoposting
3481
+ # Add to your $PROFILE:
3482
+ # ap completion pwsh | Invoke-Expression
3483
+ Register-ArgumentCompleter -Native -CommandName @('ap', 'autoposting') -ScriptBlock {
3484
+ param($wordToComplete, $commandAst, $cursorPosition)
3485
+ $commands = @(${cmds.map((c) => `'${c}'`).join(", ")})
3486
+ $commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
3487
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
3488
+ }
3489
+ }
3490
+ `
3491
+ };
3492
+ function createCompletionCommand() {
3493
+ return new import_commander17.Command("completion").description(`Generate shell completion script. Shells: ${SHELLS.join(", ")}`).argument("<shell>", `Shell type (${SHELLS.join("|")})`).action((shell) => {
3494
+ if (!SHELLS.includes(shell)) {
3495
+ console.error(`Error: unsupported shell "${shell}". Supported: ${SHELLS.join(", ")}`);
3496
+ process.exit(1);
3497
+ }
3498
+ process.stdout.write(TEMPLATES[shell](ALL_COMMANDS));
3499
+ });
3500
+ }
3501
+
3502
+ // src/commands/mcp.ts
3503
+ var import_commander18 = require("commander");
3504
+ function createMcpCommand() {
3505
+ return new import_commander18.Command("mcp").description("Start MCP stdio server for AI agent integration").action(async () => {
3506
+ const { startMcpServer: startMcpServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
3507
+ await startMcpServer2();
3508
+ });
3509
+ }
3510
+
3511
+ // 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) => {
3513
+ const opts = thisCommand.opts();
3514
+ if (!opts.color) disableColor();
3515
+ });
3516
+ program.addCommand(createAuthCommand());
3517
+ program.addCommand(createBillingCommand());
3518
+ program.addCommand(createBrandsCommand());
3519
+ program.addCommand(createCarouselsCommand());
3520
+ program.addCommand(createClipsCommand());
3521
+ program.addCommand(createPostsCommand());
3522
+ program.addCommand(createAgentsCommand());
3523
+ program.addCommand(createKbCommand());
3524
+ program.addCommand(createIdeasCommand());
3525
+ program.addCommand(createUsageCommand());
3526
+ program.addCommand(createWebhooksCommand());
3527
+ program.addCommand(createWorkspacesCommand());
3528
+ program.addCommand(createDoctorCommand());
3529
+ program.addCommand(createWhoamiCommand());
3530
+ program.addCommand(createOpenCommand());
3531
+ program.addCommand(createUpdateCommand());
3532
+ program.addCommand(createCompletionCommand());
3533
+ program.addCommand(createMcpCommand());
3534
+ program.parse();
3535
+ //# sourceMappingURL=cli.cjs.map