social-cli
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesesocial-cli
social-cli
Agent-optimized social CLI. Bluesky + X. YAML in, YAML out, exit codes for automation.
针对Agent优化的社交平台CLI工具。支持Bluesky + X。YAML输入输出,通过退出码实现自动化。
Setup
安装配置
1. Install
1. 安装
bash
git clone https://github.com/letta-ai/social-cli.git
cd social-cli
pnpm install
pnpm buildLink the binary globally or invoke via / from the repo directory.
node dist/cli.jspnpm startbash
git clone https://github.com/letta-ai/social-cli.git
cd social-cli
pnpm install
pnpm build可将二进制文件全局链接,或在仓库目录下通过 / 调用。
node dist/cli.jspnpm start2. Credentials
2. 凭证配置
Create a in the working directory where you run :
.envsocial-clibash
undefined在运行的工作目录中创建一个文件:
social-cli.envbash
undefinedBluesky / ATProto
Bluesky / ATProto
ATPROTO_HANDLE=you.bsky.social
ATPROTO_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
ATPROTO_PDS=https://bsky.social # optional, defaults to bsky.social
ATPROTO_HANDLE=you.bsky.social
ATPROTO_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
ATPROTO_PDS=https://bsky.social # optional, defaults to bsky.social
X / Twitter (OAuth 1.0a)
X / Twitter (OAuth 1.0a)
X_API_KEY=...
X_API_SECRET=...
X_ACCESS_TOKEN=...
X_ACCESS_TOKEN_SECRET=...
X_BEARER_TOKEN=... # optional, for app-only endpoints
Only credentials for platforms you actually use are required.X_API_KEY=...
X_API_SECRET=...
X_ACCESS_TOKEN=...
X_ACCESS_TOKEN_SECRET=...
X_BEARER_TOKEN=... # optional, for app-only endpoints
仅需配置你实际使用的平台凭证即可。3. Verify
3. 验证
bash
social-cli whoami
social-cli rate-limitsbash
social-cli whoami
social-cli rate-limitsAgent loop (sync → check → dispatch)
Agent循环(同步→检查→调度)
The canonical automation workflow. Each phase reads/writes YAML files in the working directory.
bash
social-cli sync # pull notifications → inbox-{platform}.yaml
social-cli check || exit 0 # anything actionable? exit 1 = nothing to do标准自动化工作流。每个阶段都会读写工作目录中的YAML文件。
bash
social-cli sync # pull notifications → inbox-{platform}.yaml
social-cli check || exit 0 # anything actionable? exit 1 = nothing to doread inbox, decide, write outbox-{platform}.yaml
read inbox, decide, write outbox-{platform}.yaml
social-cli dispatch # execute outbox, archive results
- `sync`: deduplicates against `sent_ledger-{platform}.yaml` and caps inbox size.
- `check`: exits 0 if inbox has actionable items, 1 otherwise. Wrap with `|| exit 0` in cron loops.
- `dispatch`: executes the outbox atomically. Writes `dispatch_result-{platform}.yaml` and appends to `sent_ledger-{platform}.yaml` for replay protection.social-cli dispatch # execute outbox, archive results
- `sync`:基于`sent_ledger-{platform}.yaml`去重,并限制收件箱大小。
- `check`:如果收件箱中有可操作项则返回0,否则返回1。在定时任务循环中可搭配`|| exit 0`使用。
- `dispatch`:原子性执行发件箱中的操作。生成`dispatch_result-{platform}.yaml`文件,并将结果追加到`sent_ledger-{platform}.yaml`中以防止重复执行。Quick commands
快速命令
bash
undefinedbash
undefinedPost / reply / thread
发布/回复/线程
social-cli post "Hello world" -p bsky
social-cli reply "Thanks" --id "at://did:plc:.../app.bsky.feed.post/abc" -p bsky
social-cli thread "p1" "p2" "p3" -p bsky
social-cli post "Hello world" -p bsky
social-cli reply "Thanks" --id "at://did:plc:.../app.bsky.feed.post/abc" -p bsky
social-cli thread "p1" "p2" "p3" -p bsky
Engagement
互动操作
social-cli like "at://..." -p bsky
social-cli delete "at://..." -p bsky
social-cli follow "handle.bsky.social" -p bsky
social-cli like "at://..." -p bsky
social-cli delete "at://..." -p bsky
social-cli follow "handle.bsky.social" -p bsky
Reading
内容读取
social-cli search "query" -p bsky -n 10 # → stdout YAML
social-cli feed -p bsky -n 20 # → feed.yaml (or -o - for stdout)
social-cli feed --feed "at://did:.../app.bsky.feed.generator/name" -n 10 # custom feed
social-cli profile "handle.bsky.social" -p bsky
social-cli whoami
social-cli rate-limits
undefinedsocial-cli search "query" -p bsky -n 10 # → stdout YAML
social-cli feed -p bsky -n 20 # → feed.yaml (or -o - for stdout)
social-cli feed --feed "at://did:.../app.bsky.feed.generator/name" -n 10 # custom feed
social-cli profile "handle.bsky.social" -p bsky
social-cli whoami
social-cli rate-limits
undefinedAnnotations (Bluesky only)
标注功能(仅Bluesky支持)
Uses the lexicon (W3C Web Annotation model). Annotations work on any URL, not just ATProto posts. They appear in margin.at and Semble.
at.margin.notebash
undefined使用词汇表(W3C Web标注模型)。标注功能适用于任何URL,不仅限于ATProto帖子。标注内容会显示在margin.at和Semble中。
at.margin.notebash
undefinedAnnotate a web page
标注网页
social-cli annotate "Note about this article" --target https://example.com
social-cli annotate "Note about this article" --target https://example.com
Anchor to an exact passage
锚定到指定段落
social-cli annotate "Key insight" --target https://example.com
--quote "exact passage from the page" --motivation highlighting
--quote "exact passage from the page" --motivation highlighting
Motivations: `commenting`, `highlighting`, `questioning`, `describing`, `linking`.social-cli annotate "Key insight" --target https://example.com
--quote "exact passage from the page" --motivation highlighting
--quote "exact passage from the page" --motivation highlighting
标注动机:`commenting`(评论)、`highlighting`(高亮)、`questioning`(提问)、`describing`(描述)、`linking`(链接)。Inbox format (inbox-{platform}.yaml
)
inbox-{platform}.yaml收件箱格式(inbox-{platform}.yaml
)
inbox-{platform}.yamlyaml
notifications:
- id: "at://did:plc:xxx/app.bsky.feed.post/abc"
platform: bsky
type: mention # mention, reply, like, follow, repost, quote
author: someone.bsky.social
authorId: "did:plc:xxx"
postId: "at://..."
text: "Hey, what do you think?"
timestamp: "2026-03-25T12:00:00Z"
parentPostId: "at://..." # for replies
parentPostText: "..." # context
rootPostId: "at://..." # thread root
rootPostText: "..."yaml
notifications:
- id: "at://did:plc:xxx/app.bsky.feed.post/abc"
platform: bsky
type: mention # mention, reply, like, follow, repost, quote
author: someone.bsky.social
authorId: "did:plc:xxx"
postId: "at://..."
text: "Hey, what do you think?"
timestamp: "2026-03-25T12:00:00Z"
parentPostId: "at://..." # for replies
parentPostText: "..." # context
rootPostId: "at://..." # thread root
rootPostText: "..."Outbox format (outbox-{platform}.yaml
)
outbox-{platform}.yaml发件箱格式(outbox-{platform}.yaml
)
outbox-{platform}.yamlWrite decisions as a list. Each entry is a single action.
dispatchyaml
dispatch:
- reply:
platform: bsky
id: "at://did:plc:xxx/app.bsky.feed.post/abc"
text: "Thanks for the mention"
- post:
text: "Hello from my agent"
platforms: [bsky, x] # post to both
- thread:
platform: bsky
posts:
- "Thread post 1"
- "Thread post 2"
- like:
platform: bsky
id: "at://..."
- annotate:
platform: bsky
id: "https://example.com/article"
text: "Key observation"
motivation: commenting
quote: "exact text to anchor to"
- ignore:
id: "notif_003"
reason: "spam"将决策写入列表中。每个条目对应一个单独的操作。
dispatchyaml
dispatch:
- reply:
platform: bsky
id: "at://did:plc:xxx/app.bsky.feed.post/abc"
text: "Thanks for the mention"
- post:
text: "Hello from my agent"
platforms: [bsky, x] # post to both
- thread:
platform: bsky
posts:
- "Thread post 1"
- "Thread post 2"
- like:
platform: bsky
id: "at://..."
- annotate:
platform: bsky
id: "https://example.com/article"
text: "Key observation"
motivation: commenting
quote: "exact text to anchor to"
- ignore:
id: "notif_003"
reason: "spam"Dispatch results and exit codes
调度结果与退出码
dispatch_result-{platform}.yaml| Code | Meaning |
|---|---|
| 0 | All actions succeeded |
| 1 | Invalid outbox (schema error, missing creds) |
| 2 | Partial failure (some succeeded, some failed) |
Thread failures include a field with the index and remaining posts so you can retry just the tail.
resumeFrom每次调度后都会生成文件。退出码含义如下:
dispatch_result-{platform}.yaml| 代码 | 含义 |
|---|---|
| 0 | 所有操作执行成功 |
| 1 | 发件箱无效(schema错误、缺少凭证) |
| 2 | 部分失败(部分操作成功,部分失败) |
线程发布失败时,会包含字段,记录起始索引和剩余帖子,以便你仅重试未成功的部分。
resumeFromCharacter limits
字符限制
| Platform | Limit |
|---|---|
| Bluesky | 300 chars |
| X | 280 chars |
The CLI rejects over-limit posts before hitting the API.
| 平台 | 限制 |
|---|---|
| Bluesky | 300字符 |
| X | 280字符 |
CLI会在调用API前拒绝超出字符限制的帖子。
Platform differences
平台差异
| Feature | Bluesky | X |
|---|---|---|
Annotations ( | Yes | No |
| Search | Yes | Yes |
| Feed | Yes (custom feeds) | Yes (home/user) |
| Threads | Yes | Yes |
| Notifications | mention, reply, like, follow, repost, quote | mentions only |
| Quote post context | Yes | Yes |
| 功能 | Bluesky | X |
|---|---|---|
标注功能( | 支持 | 不支持 |
| 搜索 | 支持 | 支持 |
| 动态流 | 支持(自定义动态流) | 支持(主页/用户动态) |
| 线程发布 | 支持 | 支持 |
| 通知类型 | 提及、回复、点赞、关注、转发、引用 | 仅提及 |
| 引用帖子上下文 | 支持 | 支持 |
Resilience
容错能力
- Retries 3x with exponential backoff on 429s, 5xx, and network errors. Respects .
Retry-After - Bluesky session auto-refreshes on token expiry.
- Atomic file writes (tmp + rename) — no partial inbox/outbox corruption.
- Thread resume on partial failure via .
resumeFrom - prevents duplicate dispatch across runs.
sent_ledger-{platform}.yaml
- 遇到429、5xx错误及网络错误时,会进行3次指数退避重试,并遵循头部信息。
Retry-After - Bluesky会话会在令牌过期时自动刷新。
- 原子性文件写入(临时文件+重命名)——不会出现收件箱/发件箱部分损坏的情况。
- 线程发布失败时可通过字段恢复。
resumeFrom - 可防止跨运行重复调度。
sent_ledger-{platform}.yaml
Working directory layout
工作目录结构
Everything is scoped to your current working directory, so you can run multiple agents with isolated state:
./
├── .env
├── inbox-bsky.yaml # sync output
├── inbox-x.yaml
├── outbox-bsky.yaml # your decisions
├── outbox-x.yaml
├── dispatch_result-bsky.yaml # last dispatch outcome
├── dispatch_result-x.yaml
├── sent_ledger-bsky.yaml # replay protection
├── sent_ledger-x.yaml
└── feed.yaml # optional feed snapshots所有文件都限定在当前工作目录中,因此你可以运行多个Agent并保持各自状态独立:
./
├── .env
├── inbox-bsky.yaml # 同步输出
├── inbox-x.yaml
├── outbox-bsky.yaml # 你的决策
├── outbox-x.yaml
├── dispatch_result-bsky.yaml # 上次调度结果
├── dispatch_result-x.yaml
├── sent_ledger-bsky.yaml # 重放防护
├── sent_ledger-x.yaml
└── feed.yaml # 可选的动态流快照References
参考资料
- : full command map with all flags
references/commands.md - : complete outbox YAML schema
references/outbox-schema.md - : patterns for cron/systemd automation loops
references/agent-loop.md
- :包含所有参数的完整命令列表
references/commands.md - :完整的发件箱YAML schema
references/outbox-schema.md - :定时任务/systemd自动化循环的实现模式
references/agent-loop.md