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