typefully-cli 0.1.0__tar.gz
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.
- typefully_cli-0.1.0/.coverage +0 -0
- typefully_cli-0.1.0/.github/workflows/ci.yml +31 -0
- typefully_cli-0.1.0/.gitignore +13 -0
- typefully_cli-0.1.0/CHANGELOG.md +34 -0
- typefully_cli-0.1.0/CLAUDE.md +59 -0
- typefully_cli-0.1.0/CONTRIBUTING.md +80 -0
- typefully_cli-0.1.0/LICENSE +21 -0
- typefully_cli-0.1.0/PKG-INFO +263 -0
- typefully_cli-0.1.0/README.md +228 -0
- typefully_cli-0.1.0/TODOS.md +70 -0
- typefully_cli-0.1.0/docs/batch-format.md +103 -0
- typefully_cli-0.1.0/pyproject.toml +52 -0
- typefully_cli-0.1.0/src/typefully_cli/__init__.py +3 -0
- typefully_cli-0.1.0/src/typefully_cli/__main__.py +5 -0
- typefully_cli-0.1.0/src/typefully_cli/auth.py +57 -0
- typefully_cli-0.1.0/src/typefully_cli/batch.py +126 -0
- typefully_cli-0.1.0/src/typefully_cli/cli.py +876 -0
- typefully_cli-0.1.0/src/typefully_cli/client.py +267 -0
- typefully_cli-0.1.0/src/typefully_cli/config.py +104 -0
- typefully_cli-0.1.0/src/typefully_cli/console.py +56 -0
- typefully_cli-0.1.0/src/typefully_cli/exceptions.py +80 -0
- typefully_cli-0.1.0/src/typefully_cli/media.py +70 -0
- typefully_cli-0.1.0/src/typefully_cli/output.py +188 -0
- typefully_cli-0.1.0/tests/__init__.py +0 -0
- typefully_cli-0.1.0/tests/conftest.py +1 -0
- typefully_cli-0.1.0/tests/test_auth.py +45 -0
- typefully_cli-0.1.0/tests/test_batch.py +131 -0
- typefully_cli-0.1.0/tests/test_cli.py +573 -0
- typefully_cli-0.1.0/tests/test_client.py +182 -0
- typefully_cli-0.1.0/tests/test_media.py +35 -0
- typefully_cli-0.1.0/tests/test_output.py +150 -0
|
Binary file
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: pip install -e ".[dev]"
|
|
26
|
+
|
|
27
|
+
- name: Lint
|
|
28
|
+
run: ruff check src/ tests/
|
|
29
|
+
|
|
30
|
+
- name: Test
|
|
31
|
+
run: python -m pytest tests/ -v
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2026-03-26)
|
|
4
|
+
|
|
5
|
+
Initial release.
|
|
6
|
+
|
|
7
|
+
### Commands
|
|
8
|
+
- `config set`, `config show`, `config path` -- manage configuration
|
|
9
|
+
- `me` -- show authenticated user
|
|
10
|
+
- `accounts`, `account-detail` -- list and inspect connected social sets
|
|
11
|
+
- `draft`, `thread` -- create single posts and multi-post threads
|
|
12
|
+
- `get`, `update`, `delete` -- manage existing drafts
|
|
13
|
+
- `drafts` -- list drafts with filtering (status, tag, limit, offset, order)
|
|
14
|
+
- `recent` -- list published posts with date range pagination
|
|
15
|
+
- `tags`, `tag-create` -- list and create tags (auto-created via `--tag`)
|
|
16
|
+
- `upload` -- upload media files (S3 presigned URL + poll)
|
|
17
|
+
- `batch` -- batch create drafts/threads from text file with dry-run support
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
- Agent-first JSON output by default, `--text` for human-readable Rich output
|
|
21
|
+
- Structured error JSON on stderr with exit codes (0/1/2/3)
|
|
22
|
+
- Auth chain: `--api-key` flag > `TYPEFULLY_API_KEY` env var > config file > 1Password
|
|
23
|
+
- Account resolution by name, username, or numeric ID
|
|
24
|
+
- Partial failure handling for delete and batch (exit 3 with both streams)
|
|
25
|
+
- Cross-platform posting: X, LinkedIn, Threads, Bluesky, Mastodon
|
|
26
|
+
- Media filename sanitization (spaces/special chars replaced with `_`)
|
|
27
|
+
- Rate limiting on batch operations (0.3s between requests)
|
|
28
|
+
|
|
29
|
+
### QA fixes
|
|
30
|
+
- Rich markup escaping for all user/API content in `--text` mode
|
|
31
|
+
- Date validation for `--since` / `--until` (YYYY-MM-DD required)
|
|
32
|
+
- Local limit validation (1-50) for `drafts`, `tags`, `recent`
|
|
33
|
+
- Clean error payloads in partial-failure stdout (no raw upstream bodies)
|
|
34
|
+
- README accuracy: limit caps, date validation, tag/media lifecycle scope
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# typefully-cli
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Python CLI wrapping the Typefully API v2. Agent-first design: JSON output by default, structured errors on stderr, deterministic behavior. 17 Click commands for drafts, threads, batch, media, tags, accounts, config.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
src/typefully_cli/
|
|
11
|
+
cli.py -- 17 Click commands, shared options, error handler, payload builder
|
|
12
|
+
client.py -- httpx wrapper over Typefully API v2 (rate-limited, account resolution)
|
|
13
|
+
auth.py -- API key resolution chain: flag > env > config > 1Password
|
|
14
|
+
config.py -- TOML config at ~/.config/typefully/config.toml
|
|
15
|
+
console.py -- stderr output (status, warnings, errors) via Rich
|
|
16
|
+
output.py -- Rich --text formatting (all user content escaped via rich.markup.escape)
|
|
17
|
+
batch.py -- Batch file parser (--- separators, === threads, metadata headers)
|
|
18
|
+
media.py -- S3 presigned upload + poll workflow
|
|
19
|
+
exceptions.py -- TypefullyError hierarchy with structured JSON serialization
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Key patterns
|
|
23
|
+
|
|
24
|
+
- **Output contract:** Success -> `{"ok": true, "data": ...}` on stdout. Errors -> `{"ok": false, "error": {...}}` on stderr. Exit codes: 0 success, 1 input/auth, 2 API, 3 partial failure.
|
|
25
|
+
- **Rich markup safety:** All user/API text in output.py is wrapped with `_esc()` (rich.markup.escape) before printing. Never pass raw API content to `_console.print()`.
|
|
26
|
+
- **Input validation:** Dates via `_validate_date()`, limits via `_validate_limit()`, both raise `TypefullyError(code="invalid_input")` which exits 1.
|
|
27
|
+
- **Partial failure:** Delete and batch loops catch per-item errors. `_handle_multi_result()` handles the 3-branch contract (all succeed / partial / all fail).
|
|
28
|
+
- **Error sanitization:** `APIError.user_message` property strips raw upstream bodies from stdout payloads. Full details stay on stderr.
|
|
29
|
+
|
|
30
|
+
## Dev setup
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install -e ".[dev]"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Test and lint
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
python3 -m pytest tests/ -v
|
|
40
|
+
ruff check src/ tests/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Auth for live testing
|
|
44
|
+
|
|
45
|
+
Config at `~/.config/typefully/config.toml`. Test account: BungeeCEO.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
typefully config set api_key tf_...
|
|
49
|
+
typefully config set default_account BungeeCEO
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Conventions
|
|
53
|
+
|
|
54
|
+
- Python 3.9+ compatibility (no walrus operator, no `match` statements)
|
|
55
|
+
- Line length: 100 chars (ruff)
|
|
56
|
+
- All new CLI commands get the `@shared_options` decorator and `@error_handler`
|
|
57
|
+
- All new output.py functions must escape user content with `_esc()`
|
|
58
|
+
- Tests use Click's CliRunner with mock client/console/config
|
|
59
|
+
- No emojis in code or docs
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Dev setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone https://github.com/nicedevelopers/typefully-cli.git
|
|
7
|
+
cd typefully-cli
|
|
8
|
+
pip install -e ".[dev]"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Run tests
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
python3 -m pytest tests/ -v
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Lint
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
ruff check src/ tests/
|
|
21
|
+
ruff format --check src/ tests/
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Project structure
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
src/typefully_cli/
|
|
28
|
+
cli.py -- Click commands and shared options
|
|
29
|
+
client.py -- Typefully API v2 HTTP client
|
|
30
|
+
auth.py -- API key resolution chain
|
|
31
|
+
config.py -- TOML config management
|
|
32
|
+
console.py -- stderr output (Rich)
|
|
33
|
+
output.py -- --text mode formatting (Rich, all user content escaped)
|
|
34
|
+
batch.py -- Batch file parser
|
|
35
|
+
media.py -- Media upload workflow
|
|
36
|
+
exceptions.py -- Exception hierarchy
|
|
37
|
+
tests/
|
|
38
|
+
test_cli.py -- CLI command tests (CliRunner)
|
|
39
|
+
test_client.py -- Client and account resolution tests
|
|
40
|
+
test_batch.py -- Batch parser tests
|
|
41
|
+
test_media.py -- Filename sanitization tests
|
|
42
|
+
test_output.py -- Rich markup escaping tests
|
|
43
|
+
test_auth.py -- Auth chain and redaction tests
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Conventions
|
|
47
|
+
|
|
48
|
+
- Python 3.9+ (no walrus, no `match`)
|
|
49
|
+
- Line length: 100 chars
|
|
50
|
+
- All CLI commands use `@shared_options` and `@error_handler`
|
|
51
|
+
- All output.py functions escape user content with `_esc()`
|
|
52
|
+
- Tests mock the Typefully API (no live calls in CI)
|
|
53
|
+
- JSON output is the default; `--text` is opt-in
|
|
54
|
+
|
|
55
|
+
## PR process
|
|
56
|
+
|
|
57
|
+
1. Fork and create a branch
|
|
58
|
+
2. Make changes, add tests
|
|
59
|
+
3. `python3 -m pytest tests/ -v` -- all tests pass
|
|
60
|
+
4. `ruff check src/ tests/` -- no lint errors
|
|
61
|
+
5. Open a PR with a clear description
|
|
62
|
+
|
|
63
|
+
## Output contract
|
|
64
|
+
|
|
65
|
+
Any new command must follow the output contract:
|
|
66
|
+
|
|
67
|
+
- Success: `{"ok": true, "data": ...}` on stdout (exit 0)
|
|
68
|
+
- Error: `{"ok": false, "error": {"code": "...", "message": "...", "hint": "..."}}` on stderr (exit 1 or 2)
|
|
69
|
+
- Partial failure: success data on stdout + error envelope on stderr (exit 3)
|
|
70
|
+
|
|
71
|
+
## Auth for testing
|
|
72
|
+
|
|
73
|
+
Get an API key from [Typefully Settings > API](https://typefully.com/settings/api). Set it locally:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
typefully config set api_key tf_your_key
|
|
77
|
+
typefully config set default_account YourAccount
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Live API tests are not run in CI. For local validation, use a real account.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dheeraj Shah
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: typefully-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI for the Typefully API -- manage drafts, threads, and publishing from the terminal
|
|
5
|
+
Project-URL: Homepage, https://github.com/nicedevelopers/typefully-cli
|
|
6
|
+
Project-URL: Repository, https://github.com/nicedevelopers/typefully-cli
|
|
7
|
+
Project-URL: Issues, https://github.com/nicedevelopers/typefully-cli/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/nicedevelopers/typefully-cli/blob/main/CHANGELOG.md
|
|
9
|
+
Author: Dheeraj Shah
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cli,social-media,twitter,typefully,x
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Requires-Dist: click>=8.0
|
|
27
|
+
Requires-Dist: httpx>=0.24
|
|
28
|
+
Requires-Dist: rich>=13.0
|
|
29
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# typefully-cli
|
|
37
|
+
|
|
38
|
+
Manage [Typefully](https://typefully.com) drafts, threads, and publishing from your terminal. Built for AI agents. Works great for humans too.
|
|
39
|
+
|
|
40
|
+
[](https://github.com/dheeraj-shah/typefully-cli)
|
|
41
|
+
[](LICENSE)
|
|
42
|
+
|
|
43
|
+
## Why
|
|
44
|
+
|
|
45
|
+
- **Automate publishing** -- schedule and publish from CI/CD pipelines, cron jobs, or scripts
|
|
46
|
+
- **Batch create** -- turn a text file into 50 drafts with one command
|
|
47
|
+
- **Agent-native** -- JSON output, structured errors, deterministic exit codes. Designed for Claude Code, LLM agents, and automation
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pipx install typefully-cli # recommended
|
|
53
|
+
uv tool install typefully-cli # alternative
|
|
54
|
+
pip install typefully-cli # fallback
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# First-time setup (interactive)
|
|
61
|
+
typefully config init
|
|
62
|
+
|
|
63
|
+
# Or set your API key directly (get it from typefully.com/settings/api)
|
|
64
|
+
typefully config set api_key tf_your_key_here
|
|
65
|
+
|
|
66
|
+
# Check auth
|
|
67
|
+
typefully me
|
|
68
|
+
|
|
69
|
+
# Create a draft
|
|
70
|
+
typefully draft "Hello world" --schedule next
|
|
71
|
+
|
|
72
|
+
# Create a thread
|
|
73
|
+
typefully thread "First post" "Second post" --tag launch
|
|
74
|
+
|
|
75
|
+
# Batch create from file
|
|
76
|
+
typefully batch posts.txt --schedule next --tag campaign
|
|
77
|
+
|
|
78
|
+
# Upload media and attach it
|
|
79
|
+
typefully upload photo.jpg
|
|
80
|
+
typefully draft "Check this out" --media <media_id>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## For Humans
|
|
84
|
+
|
|
85
|
+
Add `--text` to any command for readable output instead of JSON.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
typefully drafts --text
|
|
89
|
+
typefully recent --text --since 2025-01-01
|
|
90
|
+
typefully get 12345 --text
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Other handy features:**
|
|
94
|
+
|
|
95
|
+
- `typefully open 12345` -- open a draft in your browser
|
|
96
|
+
- `typefully recent --format csv` -- export published posts to CSV
|
|
97
|
+
- `typefully config init` -- guided first-time setup
|
|
98
|
+
|
|
99
|
+
**Shell completions** -- add to your shell rc file:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Bash
|
|
103
|
+
eval "$(_TYPEFULLY_COMPLETE=bash_source typefully)"
|
|
104
|
+
|
|
105
|
+
# Zsh
|
|
106
|
+
eval "$(_TYPEFULLY_COMPLETE=zsh_source typefully)"
|
|
107
|
+
|
|
108
|
+
# Fish
|
|
109
|
+
_TYPEFULLY_COMPLETE=fish_source typefully | source
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## For Agents
|
|
113
|
+
|
|
114
|
+
Every command writes structured JSON. Success to stdout, errors to stderr. Parse with `jq`, pipe to other tools, or consume directly from an LLM agent.
|
|
115
|
+
|
|
116
|
+
### Output contract
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Success (stdout)
|
|
120
|
+
{"ok": true, "data": ...}
|
|
121
|
+
|
|
122
|
+
# Error (stderr)
|
|
123
|
+
{"ok": false, "error": {"code": "auth_failed", "message": "...", "hint": "..."}}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Exit codes
|
|
127
|
+
|
|
128
|
+
| Code | Meaning | When |
|
|
129
|
+
|------|---------|------|
|
|
130
|
+
| `0` | Success | Everything worked |
|
|
131
|
+
| `1` | Input/auth error | Bad credentials, missing account, invalid input |
|
|
132
|
+
| `2` | API error | Upstream Typefully API failure |
|
|
133
|
+
| `3` | Partial failure | Some items in a batch/delete succeeded, others failed |
|
|
134
|
+
|
|
135
|
+
### Error codes
|
|
136
|
+
|
|
137
|
+
| Code | Trigger |
|
|
138
|
+
|------|---------|
|
|
139
|
+
| `auth_failed` | No API key found in flag, env, config, or 1Password |
|
|
140
|
+
| `no_account` | No account specified or account not found |
|
|
141
|
+
| `api_error` | Non-2xx response from Typefully API |
|
|
142
|
+
| `invalid_input` | Bad date format, limit out of range, single-post thread |
|
|
143
|
+
| `batch_parse_error` | Malformed batch file |
|
|
144
|
+
| `media_upload_error` | Upload failed or unsupported format |
|
|
145
|
+
|
|
146
|
+
### Partial failure (batch/delete)
|
|
147
|
+
|
|
148
|
+
When some operations succeed and some fail (exit 3):
|
|
149
|
+
- **stdout**: success data with `deleted`/`created` array + `errors` array
|
|
150
|
+
- **stderr**: `partial_failure` error envelope
|
|
151
|
+
|
|
152
|
+
When all fail (exit 2): nothing on stdout, `all_failed` on stderr.
|
|
153
|
+
|
|
154
|
+
### Common patterns
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Suppress status messages, keep errors
|
|
158
|
+
typefully accounts --quiet 2>/dev/null
|
|
159
|
+
|
|
160
|
+
# Extract draft IDs
|
|
161
|
+
typefully drafts | jq '.data.results[].id'
|
|
162
|
+
|
|
163
|
+
# Get error hint on failure
|
|
164
|
+
typefully me 2>/tmp/err.json || jq '.error.hint' /tmp/err.json
|
|
165
|
+
|
|
166
|
+
# Batch create and log results
|
|
167
|
+
typefully batch posts.txt --output results.json
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Flags for agents
|
|
171
|
+
|
|
172
|
+
- `--quiet` -- suppress stderr status messages (errors still shown)
|
|
173
|
+
- `--api-key KEY` -- pass API key directly (skips config/env lookup)
|
|
174
|
+
- `--account NAME` -- target a specific account (accepts name, username, or numeric ID)
|
|
175
|
+
|
|
176
|
+
## Auth
|
|
177
|
+
|
|
178
|
+
Resolution order: `--api-key` flag > `TYPEFULLY_API_KEY` env var > config file > 1Password.
|
|
179
|
+
|
|
180
|
+
Get your API key from [Typefully Settings > API](https://typefully.com/settings/api).
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Interactive setup
|
|
184
|
+
typefully config init
|
|
185
|
+
|
|
186
|
+
# Or manually
|
|
187
|
+
typefully config set api_key tf_your_key_here
|
|
188
|
+
typefully config set default_account MyBrand
|
|
189
|
+
|
|
190
|
+
# Optional: 1Password fallback (requires op CLI)
|
|
191
|
+
typefully config set onepassword_item "Typefully API"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Commands
|
|
195
|
+
|
|
196
|
+
All account-scoped commands accept `--api-key`, `--account`, `--text`, `--quiet`.
|
|
197
|
+
|
|
198
|
+
| Command | Description |
|
|
199
|
+
|---------|-------------|
|
|
200
|
+
| `me` | Current user info |
|
|
201
|
+
| `accounts` | List connected accounts with IDs |
|
|
202
|
+
| `account-detail [NAME]` | Platform details for an account |
|
|
203
|
+
| `draft "text"` | Create a single-post draft |
|
|
204
|
+
| `thread "p1" "p2" ...` | Create a multi-post thread (min 2 posts) |
|
|
205
|
+
| `get ID` | View a draft |
|
|
206
|
+
| `open ID` | Open a draft in the browser |
|
|
207
|
+
| `update ID ["text"]` | Edit a draft (use `===` to separate thread posts) |
|
|
208
|
+
| `delete ID [ID ...]` | Delete one or more drafts |
|
|
209
|
+
| `drafts` | List drafts (`--status`, `--tag`, `--limit 1-50`, `--offset`, `--order`) |
|
|
210
|
+
| `recent` | Published posts (`-n 1-50`, `--since`, `--until`, `--format csv`) |
|
|
211
|
+
| `upload FILE` | Upload media, returns media ID |
|
|
212
|
+
| `tags` | List tags (`--limit 1-50`, `--offset`) |
|
|
213
|
+
| `tag-create "name"` | Create a tag (usually auto-created via `--tag`) |
|
|
214
|
+
| `batch FILE` | Batch create from text file (`--dry-run`, `--output`, `--schedule`, `--tag`) |
|
|
215
|
+
| `config set KEY VALUE` | Set config (api_key, default_account, onepassword_item) |
|
|
216
|
+
| `config init` | Interactive first-time setup |
|
|
217
|
+
| `config show` | Show config (secrets redacted) |
|
|
218
|
+
| `config path` | Print config file path |
|
|
219
|
+
|
|
220
|
+
**Draft options:** `--schedule ISO|next|now`, `--tag SLUG` (repeatable, auto-created), `--title`, `--media ID`, `--share`, `--reply-to URL`, `--scratchpad`, `--qrt URL`, `--threadify`, `--auto-retweet/--no-auto-retweet`, `--auto-plug/--no-auto-plug`, `--linkedin`, `--threads`, `--bluesky`, `--mastodon`
|
|
221
|
+
|
|
222
|
+
Run `typefully COMMAND --help` for full option details.
|
|
223
|
+
|
|
224
|
+
## Batch File Format
|
|
225
|
+
|
|
226
|
+
Drafts separated by `---`. Thread posts separated by `===`. Optional metadata headers per block.
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
tag: launch
|
|
230
|
+
schedule: next
|
|
231
|
+
First post of a thread
|
|
232
|
+
===
|
|
233
|
+
Second post
|
|
234
|
+
---
|
|
235
|
+
A standalone draft
|
|
236
|
+
---
|
|
237
|
+
tag: announcement
|
|
238
|
+
schedule: 2026-04-01T10:00:00Z
|
|
239
|
+
Another standalone draft
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Supported metadata: `tag`, `schedule`, `title`, `scratchpad`, `media` (comma-separated IDs). See [docs/batch-format.md](docs/batch-format.md) for the full spec.
|
|
243
|
+
|
|
244
|
+
## Configuration
|
|
245
|
+
|
|
246
|
+
Config file: `~/.config/typefully/config.toml`
|
|
247
|
+
|
|
248
|
+
```toml
|
|
249
|
+
[auth]
|
|
250
|
+
api_key = "tf_..."
|
|
251
|
+
# onepassword_item = "Typefully API"
|
|
252
|
+
|
|
253
|
+
[defaults]
|
|
254
|
+
account = "MyBrand"
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Contributing
|
|
258
|
+
|
|
259
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
260
|
+
|
|
261
|
+
## License
|
|
262
|
+
|
|
263
|
+
MIT
|