@posteverywhere/cli 0.1.0
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 +27 -0
- package/SKILL.md +51 -0
- package/dist/index.js +173 -0
- package/package.json +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @posteverywhere/cli
|
|
2
|
+
|
|
3
|
+
The PostEverywhere CLI for AI agents — schedule and publish to Instagram, TikTok, YouTube, LinkedIn, Facebook, X, Threads, Pinterest, Bluesky, Telegram and Discord from the command line. Every command outputs structured JSON for agents (Claude, Cursor, OpenClaw, …) to parse.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
export POSTEVERYWHERE_API_KEY=pe_live_... # Settings → Developers in the dashboard
|
|
9
|
+
|
|
10
|
+
npx @posteverywhere/cli whoami # verify the key
|
|
11
|
+
npx @posteverywhere/cli accounts # list connected accounts (+ ids)
|
|
12
|
+
npx @posteverywhere/cli post -c "Hello 🚀" -a 123,456 # publish now
|
|
13
|
+
npx @posteverywhere/cli post -c "Later" -a 123 -s 2026-07-01T09:00:00Z # schedule (UTC)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Run `npx @posteverywhere/cli help` for the full command list.
|
|
17
|
+
|
|
18
|
+
## For AI agents
|
|
19
|
+
|
|
20
|
+
This package ships a `SKILL.md` describing the commands for agent auto-discovery. Point your agent at it, or connect via MCP instead:
|
|
21
|
+
|
|
22
|
+
- **Hosted MCP (no install):** `https://mcp.posteverywhere.ai` — see [docs](https://developers.posteverywhere.ai/integrations/mcp)
|
|
23
|
+
- **Local MCP:** `npx -y @posteverywhere/mcp`
|
|
24
|
+
|
|
25
|
+
## Auth & safety
|
|
26
|
+
|
|
27
|
+
Your API key authenticates into **your PostEverywhere account** and acts only through it — the CLI never touches your social-platform credentials directly. Keep a human in the loop before publishing.
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: posteverywhere
|
|
3
|
+
description: Schedule and publish social media posts to Instagram, TikTok, YouTube, LinkedIn, Facebook, X, Threads, Pinterest, Bluesky, Telegram and Discord. Use when the user asks to post, schedule, draft, or analyze social media content, or to list their connected social accounts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PostEverywhere
|
|
7
|
+
|
|
8
|
+
Manage a user's social media through the PostEverywhere CLI. Every command prints JSON.
|
|
9
|
+
|
|
10
|
+
## Setup (once)
|
|
11
|
+
The user must set their API key (from posteverywhere.ai → Settings → Developers):
|
|
12
|
+
```bash
|
|
13
|
+
export POSTEVERYWHERE_API_KEY=pe_live_...
|
|
14
|
+
```
|
|
15
|
+
Run commands with `npx @posteverywhere/cli <command>` (or `posteverywhere <command>` if installed).
|
|
16
|
+
|
|
17
|
+
## Always start here
|
|
18
|
+
1. `posteverywhere whoami` — confirms the key works and shows the plan/quota.
|
|
19
|
+
2. `posteverywhere accounts` — lists connected accounts. **You need the numeric account `id`s to post.** If empty, tell the user to connect accounts in the dashboard first.
|
|
20
|
+
|
|
21
|
+
## Core workflow
|
|
22
|
+
**Publish now** to accounts 123 and 456:
|
|
23
|
+
```bash
|
|
24
|
+
posteverywhere post -c "Launch day! 🚀" -a 123,456
|
|
25
|
+
```
|
|
26
|
+
**Schedule** (ISO-8601 UTC; include -s):
|
|
27
|
+
```bash
|
|
28
|
+
posteverywhere post -c "Weekly tips thread" -a 123 -s 2026-07-01T09:00:00Z
|
|
29
|
+
```
|
|
30
|
+
**With an image** — import it first, then attach the returned `media_id`:
|
|
31
|
+
```bash
|
|
32
|
+
posteverywhere upload https://example.com/photo.jpg # → { "media_id": "..." }
|
|
33
|
+
posteverywhere post -c "New drop" -a 123 -m <media_id>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Checking results
|
|
37
|
+
- `posteverywhere posts --status published --limit 10` — recent posts
|
|
38
|
+
- `posteverywhere results <postId>` — per-platform success/failure for one post
|
|
39
|
+
- `posteverywhere retry <postId>` — retry any failed platforms
|
|
40
|
+
- `posteverywhere account:health <id>` — why an account can't post (e.g. needs reconnect)
|
|
41
|
+
|
|
42
|
+
## Other
|
|
43
|
+
- `posteverywhere caption -t "summer sale" --platform instagram --tone playful` — AI captions
|
|
44
|
+
- `posteverywhere analytics --period month` — performance summary
|
|
45
|
+
- `posteverywhere campaigns` — list campaigns
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
- **Always `accounts` before `post`** — never guess account ids.
|
|
49
|
+
- **Always confirm content + target accounts with the user before publishing.** Keep a human in the loop.
|
|
50
|
+
- Times are UTC ISO-8601. Omit `-s` to publish immediately.
|
|
51
|
+
- On error the CLI prints `{"error": "..."}` to stderr and exits non-zero — read it and relay the cause (often: account needs reconnect, out of quota, or media not ready).
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* PostEverywhere CLI for AI agents (task #245, "skill" distribution).
|
|
5
|
+
*
|
|
6
|
+
* Thin wrapper over the public v1 REST API. Every command prints structured
|
|
7
|
+
* JSON to stdout so agents (Claude, Cursor, OpenClaw, etc.) can parse results.
|
|
8
|
+
* Auth: set POSTEVERYWHERE_API_KEY=pe_live_... (Settings → Developers).
|
|
9
|
+
*
|
|
10
|
+
* Same surface as the MCP server, for agents that run shell commands rather
|
|
11
|
+
* than speak MCP. See SKILL.md for the agent-facing command reference.
|
|
12
|
+
*/
|
|
13
|
+
const BASE = (process.env.POSTEVERYWHERE_API_URL || 'https://app.posteverywhere.ai').replace(/\/$/, '');
|
|
14
|
+
const KEY = process.env.POSTEVERYWHERE_API_KEY || '';
|
|
15
|
+
function out(data) {
|
|
16
|
+
process.stdout.write(JSON.stringify(data, null, 2) + '\n');
|
|
17
|
+
}
|
|
18
|
+
function fail(message, code = 1) {
|
|
19
|
+
process.stderr.write(JSON.stringify({ error: message }) + '\n');
|
|
20
|
+
process.exit(code);
|
|
21
|
+
}
|
|
22
|
+
// Parse "cmd positional --flag value -f value --bool" into { _: [...], flags }.
|
|
23
|
+
function parseArgs(argv) {
|
|
24
|
+
const positional = [];
|
|
25
|
+
const flags = {};
|
|
26
|
+
for (let i = 0; i < argv.length; i++) {
|
|
27
|
+
const a = argv[i];
|
|
28
|
+
if (a.startsWith('--') || a.startsWith('-')) {
|
|
29
|
+
const key = a.replace(/^-+/, '');
|
|
30
|
+
const next = argv[i + 1];
|
|
31
|
+
if (next !== undefined && !next.startsWith('-')) {
|
|
32
|
+
flags[key] = next;
|
|
33
|
+
i++;
|
|
34
|
+
}
|
|
35
|
+
else
|
|
36
|
+
flags[key] = true;
|
|
37
|
+
}
|
|
38
|
+
else
|
|
39
|
+
positional.push(a);
|
|
40
|
+
}
|
|
41
|
+
return { positional, flags };
|
|
42
|
+
}
|
|
43
|
+
async function api(method, path, body) {
|
|
44
|
+
if (!KEY || !KEY.startsWith('pe_live_')) {
|
|
45
|
+
fail('Missing or invalid POSTEVERYWHERE_API_KEY (must start with pe_live_). Create one at ' + BASE + ' → Settings → Developers.');
|
|
46
|
+
}
|
|
47
|
+
let resp;
|
|
48
|
+
try {
|
|
49
|
+
resp = await fetch(`${BASE}/api/v1${path}`, {
|
|
50
|
+
method,
|
|
51
|
+
headers: { Authorization: `Bearer ${KEY}`, ...(body ? { 'Content-Type': 'application/json' } : {}) },
|
|
52
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
fail(`Network error: ${e instanceof Error ? e.message : String(e)}`);
|
|
57
|
+
}
|
|
58
|
+
const json = await resp.json().catch(() => ({ error: { message: `HTTP ${resp.status}` } }));
|
|
59
|
+
if (json.error)
|
|
60
|
+
fail(typeof json.error === 'string' ? json.error : json.error.message || 'API error');
|
|
61
|
+
return json.data;
|
|
62
|
+
}
|
|
63
|
+
const csv = (v) => (typeof v === 'string' ? v.split(',').map((s) => s.trim()).filter(Boolean) : []);
|
|
64
|
+
const num = (v) => csv(v).map(Number).filter((n) => !Number.isNaN(n));
|
|
65
|
+
const HELP = `PostEverywhere CLI — manage social media from the command line / AI agents.
|
|
66
|
+
|
|
67
|
+
Auth: export POSTEVERYWHERE_API_KEY=pe_live_... (Settings → Developers)
|
|
68
|
+
|
|
69
|
+
Commands:
|
|
70
|
+
whoami Show the authed account, quota, and scopes
|
|
71
|
+
accounts List connected social accounts (+ their ids/health)
|
|
72
|
+
account:health <id> Detailed health for one account
|
|
73
|
+
post -c <text> -a <ids> [-s <iso>] [-m <media_ids>]
|
|
74
|
+
Create/schedule a post (-a = comma account ids; omit -s = publish now)
|
|
75
|
+
posts [--status x] [--platform y] [--limit n]
|
|
76
|
+
List posts
|
|
77
|
+
results <postId> Per-platform publish results for a post
|
|
78
|
+
retry <postId> Retry failed destinations of a post
|
|
79
|
+
upload <imageUrl> Import an image by URL (one-call), returns media_id
|
|
80
|
+
caption -t <topic> [--platform x] [--tone y]
|
|
81
|
+
Generate AI captions
|
|
82
|
+
analytics [--period week|month|all]
|
|
83
|
+
Account analytics summary
|
|
84
|
+
campaigns List campaigns
|
|
85
|
+
|
|
86
|
+
All output is JSON on stdout. Errors are JSON on stderr with a non-zero exit.
|
|
87
|
+
Docs: https://developers.posteverywhere.ai/integrations/mcp`;
|
|
88
|
+
async function main() {
|
|
89
|
+
const [, , cmd, ...rest] = process.argv;
|
|
90
|
+
const { positional, flags } = parseArgs(rest);
|
|
91
|
+
const f = (k, alias) => (flags[k] ?? (alias ? flags[alias] : undefined));
|
|
92
|
+
switch (cmd) {
|
|
93
|
+
case undefined:
|
|
94
|
+
case 'help':
|
|
95
|
+
case '--help':
|
|
96
|
+
case '-h':
|
|
97
|
+
process.stdout.write(HELP + '\n');
|
|
98
|
+
return;
|
|
99
|
+
case 'whoami':
|
|
100
|
+
return out(await api('GET', '/me'));
|
|
101
|
+
case 'accounts':
|
|
102
|
+
return out(await api('GET', '/accounts'));
|
|
103
|
+
case 'account:health': {
|
|
104
|
+
const id = positional[0];
|
|
105
|
+
if (!id)
|
|
106
|
+
fail('Usage: posteverywhere account:health <accountId>');
|
|
107
|
+
return out(await api('GET', `/accounts/${id}/health`));
|
|
108
|
+
}
|
|
109
|
+
case 'post': {
|
|
110
|
+
const content = f('content', 'c');
|
|
111
|
+
const accounts = num(f('accounts', 'a'));
|
|
112
|
+
if (typeof content !== 'string' || !content)
|
|
113
|
+
fail('Usage: post -c "text" -a 123,456 [-s 2026-07-01T09:00:00Z] [-m mediaId1,mediaId2]');
|
|
114
|
+
if (!accounts.length)
|
|
115
|
+
fail('At least one account id is required (-a 123,456). Run `posteverywhere accounts` to list ids.');
|
|
116
|
+
const body = { content, account_ids: accounts };
|
|
117
|
+
const sched = f('schedule', 's');
|
|
118
|
+
if (typeof sched === 'string') {
|
|
119
|
+
body.scheduled_for = sched;
|
|
120
|
+
body.timezone = f('timezone') || 'UTC';
|
|
121
|
+
}
|
|
122
|
+
const media = csv(f('media', 'm'));
|
|
123
|
+
if (media.length)
|
|
124
|
+
body.media_ids = media;
|
|
125
|
+
return out(await api('POST', '/posts', body));
|
|
126
|
+
}
|
|
127
|
+
case 'posts': {
|
|
128
|
+
const q = new URLSearchParams();
|
|
129
|
+
if (typeof f('status') === 'string')
|
|
130
|
+
q.set('status', f('status'));
|
|
131
|
+
if (typeof f('platform') === 'string')
|
|
132
|
+
q.set('platform', f('platform'));
|
|
133
|
+
q.set('limit', String(f('limit') || 20));
|
|
134
|
+
return out(await api('GET', `/posts?${q.toString()}`));
|
|
135
|
+
}
|
|
136
|
+
case 'results': {
|
|
137
|
+
if (!positional[0])
|
|
138
|
+
fail('Usage: posteverywhere results <postId>');
|
|
139
|
+
return out(await api('GET', `/posts/${positional[0]}/results`));
|
|
140
|
+
}
|
|
141
|
+
case 'retry': {
|
|
142
|
+
if (!positional[0])
|
|
143
|
+
fail('Usage: posteverywhere retry <postId>');
|
|
144
|
+
return out(await api('POST', `/posts/${positional[0]}/retry`));
|
|
145
|
+
}
|
|
146
|
+
case 'upload': {
|
|
147
|
+
const url = positional[0] || f('url');
|
|
148
|
+
if (typeof url !== 'string')
|
|
149
|
+
fail('Usage: posteverywhere upload <imageUrl>');
|
|
150
|
+
return out(await api('POST', '/media/upload-from-url', { url }));
|
|
151
|
+
}
|
|
152
|
+
case 'caption': {
|
|
153
|
+
const topic = f('topic', 't');
|
|
154
|
+
if (typeof topic !== 'string')
|
|
155
|
+
fail('Usage: posteverywhere caption -t "topic" [--platform x] [--tone y]');
|
|
156
|
+
const body = { topic };
|
|
157
|
+
if (typeof f('platform') === 'string')
|
|
158
|
+
body.platform = f('platform');
|
|
159
|
+
if (typeof f('tone') === 'string')
|
|
160
|
+
body.tone = f('tone');
|
|
161
|
+
return out(await api('POST', '/ai/generate-caption', body));
|
|
162
|
+
}
|
|
163
|
+
case 'analytics': {
|
|
164
|
+
const period = f('period') || 'month';
|
|
165
|
+
return out(await api('GET', `/analytics/summary?period=${encodeURIComponent(period)}`));
|
|
166
|
+
}
|
|
167
|
+
case 'campaigns':
|
|
168
|
+
return out(await api('GET', '/campaigns'));
|
|
169
|
+
default:
|
|
170
|
+
fail(`Unknown command: ${cmd}. Run \`posteverywhere help\` for the command list.`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
main().catch((e) => fail(e instanceof Error ? e.message : String(e)));
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@posteverywhere/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "PostEverywhere CLI for AI agents — schedule and publish to Instagram, TikTok, YouTube, LinkedIn, Facebook, X, Threads, Pinterest, Bluesky, Telegram & Discord from the command line. Structured JSON output for Claude, Cursor, and other agents.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"posteverywhere": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": ["dist", "SKILL.md", "README.md"],
|
|
10
|
+
"engines": { "node": ">=18.0.0" },
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"dev": "tsc --watch",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": ["social media", "cli", "ai agent", "claude", "mcp", "scheduling", "automation"],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"devDependencies": { "typescript": "^5.6.0", "@types/node": "^20.0.0" }
|
|
19
|
+
}
|