@publishq/cli 0.0.5 → 0.0.7

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 CHANGED
@@ -19,7 +19,7 @@ Output is JSON by default: easy to pipe into `jq` and easy for an AI agent to pa
19
19
  ## Install
20
20
 
21
21
  ```bash
22
- npm install -g @publishq/cli
22
+ npm install -g @publishq/cli@latest
23
23
  ```
24
24
 
25
25
  You get two commands: `publishq` and the shorter `pq`. They do the same thing.
@@ -27,7 +27,7 @@ You get two commands: `publishq` and the shorter `pq`. They do the same thing.
27
27
  ## Quick start
28
28
 
29
29
  ```bash
30
- # 1. Save your API key (create one under Settings → API Keys in the web app)
30
+ # 1. Save your API key (create one under API Keys in the web app)
31
31
  pq auth set --key "pq_live_..."
32
32
 
33
33
  # 2. See your connected accounts
@@ -51,6 +51,8 @@ pq posts create --content "Hello TikTok" --accounts-json '[{"accountId":"<id>","
51
51
  pq posts update <post-id> [--content "New text"] [--scheduled-at <iso>] \
52
52
  [--media-id <id>] [--thumbnail-timestamp <ms>]
53
53
  pq posts update <post-id> --media-ids-json '[]' # remove all media
54
+ pq posts update <post-id> --accounts-json '[{"accountId":"<id>","platformSpecificSettings":{"thumbnailMediaId":"<image-media-id>"}}]'
55
+ pq posts update <post-id> --accounts-json '[{"accountId":"<id>","platformSpecificSettings":{"thumbnailMediaId":null}}]' # remove one setting
54
56
  pq posts delete <post-id>
55
57
  pq posts remove-account <post-id> <account-id>
56
58
  ```
@@ -83,7 +85,7 @@ pq media get <media-id>
83
85
  pq media upload --file ./photo.jpg [--filename custom.jpg]
84
86
  ```
85
87
 
86
- Upload returns a media object whose `id` you can pass to `pq posts create --media-id <id>`.
88
+ Upload returns a media object whose `id` you can pass to `pq posts create --media-id <id>`. Files up to 4 GB are accepted (500 MB on the Free plan).
87
89
 
88
90
  ## Scopes
89
91
 
@@ -101,8 +103,8 @@ API keys carry scopes that control access. A call missing the required scope ret
101
103
 
102
104
  ## Related
103
105
 
104
- - [`@publishq/sdk`](https://www.npmjs.com/package/@publishq/sdk) — the TypeScript SDK this CLI is built on.
105
- - [`@publishq/mcp`](https://www.npmjs.com/package/@publishq/mcp) — Model Context Protocol server for Claude Desktop and other AI agents.
106
+ - [`@publishq/sdk`](https://www.npmjs.com/package/@publishq/sdk): the TypeScript SDK this CLI is built on.
107
+ - [`@publishq/mcp`](https://www.npmjs.com/package/@publishq/mcp): Model Context Protocol server for Claude Desktop and other AI agents.
106
108
 
107
109
  ## License
108
110
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { readFileSync as readFileSync2 } from "fs";
4
+ import { openAsBlob, statSync } from "fs";
5
5
  import { basename } from "path";
6
6
  import yargs from "yargs";
7
7
  import { hideBin } from "yargs/helpers";
@@ -33,7 +33,7 @@ function getClient() {
33
33
  const apiKey = getApiKey();
34
34
  if (!apiKey) {
35
35
  console.error(
36
- 'No API key found. Generate one at https://publishq.com/app/settings, then run `publishq auth set --key "pq_live_..."` or set PUBLISHQ_API_KEY.'
36
+ 'No API key found. Generate one at https://publishq.com/app/api-keys, then run `publishq auth set --key "pq_live_..."` or set PUBLISHQ_API_KEY.'
37
37
  );
38
38
  process.exit(1);
39
39
  }
@@ -70,6 +70,7 @@ function describeError(error) {
70
70
  }
71
71
 
72
72
  // src/index.ts
73
+ var OPEN_AS_BLOB_MAX_BYTES = 2 ** 32;
73
74
  function parseJsonOption(option, value) {
74
75
  try {
75
76
  return JSON.parse(value);
@@ -115,18 +116,26 @@ yargs(hideBin(process.argv)).scriptName("publishq").usage("$0 <command> [options
115
116
  "Create, list, update, and delete posts",
116
117
  (y) => y.command(
117
118
  ["list", "$0"],
118
- "List posts (paginate with --page and --limit)",
119
+ "List the posts you created through PublishQ (paginate with --page and --limit; imported posts need --include-imported or --only-imported)",
119
120
  (yy) => yy.option("page", {
120
121
  type: "number",
121
122
  describe: "Page number (starts at 1)"
122
123
  }).option("limit", {
123
124
  type: "number",
124
125
  describe: "Page size (max 100)"
126
+ }).option("include-imported", {
127
+ type: "boolean",
128
+ describe: "Also include posts imported from a connected platform (excluded by default)"
129
+ }).option("only-imported", {
130
+ type: "boolean",
131
+ describe: "Return only posts imported from a connected platform"
125
132
  }),
126
133
  (argv) => {
127
134
  const query = {
128
135
  ...argv.page !== void 0 ? { page: argv.page } : {},
129
- ...argv.limit !== void 0 ? { limit: argv.limit } : {}
136
+ ...argv.limit !== void 0 ? { limit: argv.limit } : {},
137
+ ...argv.includeImported !== void 0 ? { includeImported: argv.includeImported } : {},
138
+ ...argv.onlyImported !== void 0 ? { onlyImported: argv.onlyImported } : {}
130
139
  };
131
140
  output(
132
141
  getClient().posts.list(
@@ -203,18 +212,26 @@ yargs(hideBin(process.argv)).scriptName("publishq").usage("$0 <command> [options
203
212
  }).conflicts("media-id", "media-ids-json").option("thumbnail-timestamp", {
204
213
  type: "number",
205
214
  describe: "New video thumbnail timestamp in milliseconds"
215
+ }).option("accounts-json", {
216
+ type: "string",
217
+ describe: "JSON array of account objects to update or add, with accountId and optional postOverrides/platformSpecificSettings. Only the fields you send change; send a field as null to remove it."
206
218
  }),
207
219
  (argv) => {
208
220
  const mediaIds = argv["media-ids-json"] !== void 0 ? parseJsonOption(
209
221
  "--media-ids-json",
210
222
  argv["media-ids-json"]
211
223
  ) : argv["media-id"];
224
+ const accounts = argv["accounts-json"] !== void 0 ? parseJsonOption(
225
+ "--accounts-json",
226
+ argv["accounts-json"]
227
+ ) : void 0;
212
228
  output(
213
229
  getClient().posts.update(argv.id, {
214
230
  ...argv.content !== void 0 ? { content: argv.content } : {},
215
231
  ...argv["scheduled-at"] !== void 0 ? { scheduledAt: argv["scheduled-at"] } : {},
216
232
  ...mediaIds !== void 0 ? { mediaIds } : {},
217
- ...argv["thumbnail-timestamp"] !== void 0 ? { thumbnailTimestamp: argv["thumbnail-timestamp"] } : {}
233
+ ...argv["thumbnail-timestamp"] !== void 0 ? { thumbnailTimestamp: argv["thumbnail-timestamp"] } : {},
234
+ ...accounts !== void 0 ? { accounts } : {}
218
235
  }),
219
236
  argv.pretty
220
237
  );
@@ -361,11 +378,21 @@ yargs(hideBin(process.argv)).scriptName("publishq").usage("$0 <command> [options
361
378
  type: "string",
362
379
  describe: "Override the uploaded file name"
363
380
  }),
364
- (argv) => {
365
- const buffer = readFileSync2(argv.file);
381
+ async (argv) => {
382
+ if (statSync(argv.file).size >= OPEN_AS_BLOB_MAX_BYTES) {
383
+ console.error(
384
+ JSON.stringify({
385
+ error: `${argv.file} is too big to upload: files must be smaller than 4 GB.`
386
+ })
387
+ );
388
+ process.exit(1);
389
+ }
366
390
  const name = argv.filename ?? basename(argv.file);
367
- const file = new File([buffer], name);
368
- output(getClient().media.upload({ file }), argv.pretty);
391
+ const file = new File([await openAsBlob(argv.file)], name);
392
+ return output(
393
+ getClient().media.upload({ file }),
394
+ argv.pretty
395
+ );
369
396
  }
370
397
  ).demandCommand(1, "Specify a media subcommand."),
371
398
  () => {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@publishq/cli",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "private": false,
5
- "description": "Official command-line interface for the PublishQ API — schedule and publish across your social platforms.",
5
+ "description": "Official command-line interface for the PublishQ API. Schedule and publish across your social platforms.",
6
6
  "license": "Apache-2.0",
7
7
  "author": "PublishQ",
8
8
  "homepage": "https://publishq.com",
@@ -27,8 +27,8 @@
27
27
  "LICENSE"
28
28
  ],
29
29
  "dependencies": {
30
- "yargs": "^17.7.2",
31
- "@publishq/sdk": "^0.0.1"
30
+ "@publishq/sdk": "^0.0.3",
31
+ "yargs": "^17.7.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^20",