x-relay-mcp 1.0.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/.claude/skills/x-relay/SKILL.md +130 -0
- package/README.md +21 -0
- package/dist/cli-DZkaLoUg.d.ts +232 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1958 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +123 -0
- package/dist/index.js +1977 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-shim.d.ts +11 -0
- package/dist/mcp-shim.js +1956 -0
- package/dist/mcp-shim.js.map +1 -0
- package/package.json +116 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# x-relay
|
|
2
|
+
|
|
3
|
+
A **deep-research tool for X/Twitter** for AI agents — a CLI (`xrelay`), an MCP server, and this skill.
|
|
4
|
+
Cast a wide net with live search, rank candidates cheaply on engagement/recency metadata, and read full
|
|
5
|
+
threads only for the finalists. Cookies are **auto-extracted from your local browser** (Arc/Chrome/Brave/Edge
|
|
6
|
+
on macOS) — no manual setup. No paid X API.
|
|
7
|
+
|
|
8
|
+
The tool is **atomic** (search / user / user-posts / thread / bookmarks). YOU compose the strategy. This skill
|
|
9
|
+
gives the **recommended funnel** first, then a per-command reference with cost so you can deviate intelligently.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Recommended workflow (the funnel)
|
|
14
|
+
|
|
15
|
+
Use this for "find the best X material / what's being said on <topic>" research tasks.
|
|
16
|
+
|
|
17
|
+
**Golden rule — protect your context window:** threads and timelines are large. NEVER bulk-read them during
|
|
18
|
+
exploration. Rank on cheap search metadata first; read a full thread only for the handful that survive.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
GATE 1 — cast a wide net (CHEAP: search)
|
|
22
|
+
Run several query variants (synonyms / intent angles / operators), dedupe by id.
|
|
23
|
+
xrelay search "prompt engineering" --limit 40 --product Top
|
|
24
|
+
xrelay search "writing prompts for llms" --product Latest --min-faves 50
|
|
25
|
+
xrelay search "context engineering" --since 2026-01-01 --filter -replies
|
|
26
|
+
Each tweet already carries: author (+verified, followers), likes, retweets, replies, quotes,
|
|
27
|
+
bookmarks, views, date, lang, url. Rank on THESE alone.
|
|
28
|
+
Signals: authority (verified / known author / followers), validation (likes + views + bookmarks),
|
|
29
|
+
recency (date — matters for fast topics), specificity (the text), reach (retweets/quotes).
|
|
30
|
+
Keep the ~10–15 most promising. NO thread reads yet.
|
|
31
|
+
|
|
32
|
+
GATE 2 — enrich the authors (1 CALL each: user)
|
|
33
|
+
xrelay user <handle> # bio, follower count, verified, how active
|
|
34
|
+
Confirm an author is who you think. Drop weak sources. Optionally peek a source's recent posts:
|
|
35
|
+
xrelay user-posts <handle> --limit 20
|
|
36
|
+
|
|
37
|
+
GATE 3 — full read (EXPENSIVE: thread — only the few that survive)
|
|
38
|
+
xrelay thread <id|url> # the tweet + its replies/conversation
|
|
39
|
+
|
|
40
|
+
Cross-source: your own saved material is a parallel input (a LOCAL cache —
|
|
41
|
+
offline, instant, no rate limits) —
|
|
42
|
+
xrelay bookmarks -q "<topic>" # fuse what you've already saved with live results
|
|
43
|
+
xrelay my-posts -q "<topic>" # and what you've written
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`--product Top` ranks by X's own engagement model (best for "the best on <topic>"); `--product Latest`
|
|
47
|
+
gives recency (best for "what's being said right now" and incremental sweeps).
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Commands (atomic reference)
|
|
52
|
+
|
|
53
|
+
All commands print a JSON envelope to stdout — `{ ok, command, data }` on success,
|
|
54
|
+
`{ ok:false, command, error:{code,message,hint} }` on failure. Exit codes: 0 ok, 1 command error,
|
|
55
|
+
2 unknown command.
|
|
56
|
+
|
|
57
|
+
### `search` — COST: cheap, broad. The net.
|
|
58
|
+
```
|
|
59
|
+
xrelay search "<query>" [--limit N] [--product Top|Latest|Media|People]
|
|
60
|
+
[--from <h>] [--to <h>] [--since YYYY-MM-DD] [--until YYYY-MM-DD]
|
|
61
|
+
[--lang xx] [--min-faves N] [--min-retweets N] [--filter media|links|replies|-replies ...]
|
|
62
|
+
```
|
|
63
|
+
- X **advanced operators also work inside the query string** — the flags are just a typed shortcut that
|
|
64
|
+
get folded into it. `--filter -replies` excludes replies; `--filter media` keeps only media tweets.
|
|
65
|
+
- Returns `{ query, product, tweets: [{ id, url, text, author:{handle,name,verified,followers},
|
|
66
|
+
metrics:{likes,retweets,replies,quotes,bookmarks,views}, createdAt, lang, media[], ... }], nextCursor }`.
|
|
67
|
+
|
|
68
|
+
### `user` — COST: 1 call. Vet a source.
|
|
69
|
+
```
|
|
70
|
+
xrelay user <handle|url>
|
|
71
|
+
```
|
|
72
|
+
- Returns `{ id, handle, name, bio, verified, followers, following, tweets, createdAt, location, avatar, url }`.
|
|
73
|
+
|
|
74
|
+
### `user-posts` — COST: medium. A source's timeline.
|
|
75
|
+
```
|
|
76
|
+
xrelay user-posts <handle|url> [--replies] [--limit N]
|
|
77
|
+
```
|
|
78
|
+
- `--replies` includes the user's replies (default: just their posts). Returns `{ tweets[], nextCursor }`.
|
|
79
|
+
|
|
80
|
+
### `thread` — COST: expensive. The full read.
|
|
81
|
+
```
|
|
82
|
+
xrelay thread <id|url>
|
|
83
|
+
```
|
|
84
|
+
- Returns `{ root: <tweet>, replies: [<tweet>...], nextCursor }`. Use on finalists only.
|
|
85
|
+
|
|
86
|
+
### `bookmarks` / `my-posts` — COST: cheap. Your local cache (offline, instant).
|
|
87
|
+
```
|
|
88
|
+
xrelay bookmarks [-q "<query>"] [--limit N] [--sort relevance|newest|likes|views|bookmarks]
|
|
89
|
+
[--sync] [--repair] [--live]
|
|
90
|
+
xrelay my-posts [-q "<query>"] [--limit N] [--sort ...] [--handle <you>] [--sync] [--live]
|
|
91
|
+
```
|
|
92
|
+
- Search YOUR saved posts / own posts in a local cache — no rate limits, instant, semantic-free keyword +
|
|
93
|
+
metadata ranking. Returns `{ source, cached, total, syncedAt, tweets[] }`.
|
|
94
|
+
- `--sync` refreshes the cache first (incremental — only new since last sync). `--live` bypasses the cache and
|
|
95
|
+
hits X. If the cache is empty, the result carries a `hint` telling you to `sync` first.
|
|
96
|
+
|
|
97
|
+
### `sync` — COST: medium. Refresh the local cache (incremental).
|
|
98
|
+
```
|
|
99
|
+
xrelay sync bookmarks|posts|all [--handle <you>] [--repair] [--max N]
|
|
100
|
+
```
|
|
101
|
+
- Pulls ONLY tweets newer than the last sync (snowflake-id watermark + newest-first early-break) — never a
|
|
102
|
+
full refetch. `--repair` refetches everything and patches records; `--max N` caps a run (good for a first
|
|
103
|
+
sync). `posts` needs your `--handle` once (it's remembered). Returns `{ source, added, total, watermark }`.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Composition notes
|
|
108
|
+
|
|
109
|
+
- **Dedupe by `id`** across multiple `search` calls — that's your job, not the tool's.
|
|
110
|
+
- **Rank, don't read.** The whole point is to avoid reading threads you don't need. Engagement + recency +
|
|
111
|
+
authority on the search results is usually enough to pick the 2–3 worth a `thread` read.
|
|
112
|
+
- **Operators are powerful**: `from:` (one author), `min_faves:` (quality floor), `since:`/`until:` (a window),
|
|
113
|
+
`filter:media`/`-filter:replies` (shape). Combine them to make the net precise instead of huge.
|
|
114
|
+
|
|
115
|
+
## Error codes
|
|
116
|
+
|
|
117
|
+
- `INVALID_INPUT` — empty query / missing handle or id. No network call.
|
|
118
|
+
- `AUTH_FAILED` — session cookies expired/invalid. Re-log into x.com in your browser (or set XRELAY_COOKIES).
|
|
119
|
+
- `RATE_LIMITED` — X throttled the token; back off and retry later.
|
|
120
|
+
- `FEATURE_DRIFT` — X rotated its private API; the tool's query-ids/features need a refresh.
|
|
121
|
+
- `NOT_FOUND` — the tweet/user is unavailable, or a transient API hiccup.
|
|
122
|
+
- `UNKNOWN_COMMAND` — unrecognized command.
|
|
123
|
+
|
|
124
|
+
## Setup
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
npm i -g x-relay-mcp
|
|
128
|
+
```
|
|
129
|
+
Cookies are read automatically from your logged-in browser (macOS Keychain). The first run may show a one-time
|
|
130
|
+
Keychain "Always Allow" prompt. Assumes a residential IP (run locally); datacenter IPs are blocked by X.
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# x-relay
|
|
2
|
+
|
|
3
|
+
A **deep-research tool for X/Twitter** for AI agents — a TypeScript **CLI** (`xrelay`), an **MCP server**
|
|
4
|
+
(`x-relay-mcp`), and a **Claude Code skill**. Cast a wide net with live search, rank candidates cheaply on
|
|
5
|
+
engagement metadata, and read full threads only for the finalists — plus a **local, incrementally-synced cache**
|
|
6
|
+
of your own bookmarks and posts. **No paid X API**: a from-scratch engine on X's private GraphQL surface using
|
|
7
|
+
your login cookies.
|
|
8
|
+
|
|
9
|
+
> **Status:** scaffolding. Design and grounded engine research are in [`PLAN.md`](./PLAN.md) and
|
|
10
|
+
> [`docs/ENGINE-RESEARCH.md`](./docs/ENGINE-RESEARCH.md). Built in the spirit of its sibling
|
|
11
|
+
> [`youtube-relay-mcp`](../youtube-context): atomic capabilities, the agent composes the strategy, a generated
|
|
12
|
+
> `SKILL.md` teaches the funnel.
|
|
13
|
+
|
|
14
|
+
## Why a CLI + skill (not just an MCP server)
|
|
15
|
+
|
|
16
|
+
The task is a search/fetch/rank pipeline. An agent shells out to `xrelay`, taught by the bundled `SKILL.md`.
|
|
17
|
+
The MCP shim is provided for parity and non-CLI hosts.
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
MIT © Tamas Gabor
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
type Ok<T> = {
|
|
2
|
+
ok: true;
|
|
3
|
+
command: string;
|
|
4
|
+
data: T;
|
|
5
|
+
};
|
|
6
|
+
type Err = {
|
|
7
|
+
ok: false;
|
|
8
|
+
command: string;
|
|
9
|
+
error: {
|
|
10
|
+
code: string;
|
|
11
|
+
message: string;
|
|
12
|
+
hint?: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
type Envelope<T> = Ok<T> | Err;
|
|
16
|
+
/** A tweet's author, as it appears embedded in a tweet result. */
|
|
17
|
+
type Author = {
|
|
18
|
+
id: string;
|
|
19
|
+
handle: string;
|
|
20
|
+
name: string;
|
|
21
|
+
verified: boolean;
|
|
22
|
+
followers?: number;
|
|
23
|
+
avatar?: string;
|
|
24
|
+
};
|
|
25
|
+
/** Engagement counters — all optional because X omits some in some contexts. */
|
|
26
|
+
type Metrics = {
|
|
27
|
+
likes?: number;
|
|
28
|
+
retweets?: number;
|
|
29
|
+
replies?: number;
|
|
30
|
+
quotes?: number;
|
|
31
|
+
bookmarks?: number;
|
|
32
|
+
views?: number;
|
|
33
|
+
};
|
|
34
|
+
type MediaKind = 'photo' | 'video' | 'gif';
|
|
35
|
+
/** A single tweet, normalized. The unit returned by search / timelines. */
|
|
36
|
+
type Tweet = {
|
|
37
|
+
id: string;
|
|
38
|
+
url: string;
|
|
39
|
+
text: string;
|
|
40
|
+
lang?: string;
|
|
41
|
+
createdAt?: string;
|
|
42
|
+
author: Author;
|
|
43
|
+
metrics: Metrics;
|
|
44
|
+
hashtags?: string[];
|
|
45
|
+
mentions?: string[];
|
|
46
|
+
urls?: string[];
|
|
47
|
+
media?: MediaKind[];
|
|
48
|
+
isReply?: boolean;
|
|
49
|
+
isRetweet?: boolean;
|
|
50
|
+
isQuote?: boolean;
|
|
51
|
+
conversationId?: string;
|
|
52
|
+
/** Present when this tweet quotes another. */
|
|
53
|
+
quoted?: Tweet;
|
|
54
|
+
};
|
|
55
|
+
/** A full user profile (the `user` command). */
|
|
56
|
+
type UserProfile = {
|
|
57
|
+
id: string;
|
|
58
|
+
handle: string;
|
|
59
|
+
name: string;
|
|
60
|
+
bio?: string;
|
|
61
|
+
verified: boolean;
|
|
62
|
+
followers: number;
|
|
63
|
+
following: number;
|
|
64
|
+
tweets: number;
|
|
65
|
+
createdAt?: string;
|
|
66
|
+
location?: string;
|
|
67
|
+
avatar?: string;
|
|
68
|
+
url: string;
|
|
69
|
+
};
|
|
70
|
+
/** A paginated set of tweets (search / timeline output). */
|
|
71
|
+
type TweetPage = {
|
|
72
|
+
tweets: Tweet[];
|
|
73
|
+
nextCursor?: string;
|
|
74
|
+
};
|
|
75
|
+
/** A search result, carrying back the query context. */
|
|
76
|
+
type SearchResult = TweetPage & {
|
|
77
|
+
query: string;
|
|
78
|
+
product: SearchProduct$1;
|
|
79
|
+
};
|
|
80
|
+
/** A tweet plus its reply thread (the `thread` command). */
|
|
81
|
+
type ThreadResult = {
|
|
82
|
+
root: Tweet;
|
|
83
|
+
replies: Tweet[];
|
|
84
|
+
nextCursor?: string;
|
|
85
|
+
};
|
|
86
|
+
type SearchProduct$1 = 'Top' | 'Latest' | 'Media' | 'People';
|
|
87
|
+
|
|
88
|
+
/** The two load-bearing cookies, plus any others the jar carries. */
|
|
89
|
+
type Cookies = {
|
|
90
|
+
authToken: string;
|
|
91
|
+
ct0: string;
|
|
92
|
+
extra?: Record<string, string>;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Parse a browser cookie string (`auth_token=abc; ct0=def; ...`) or a JSON object
|
|
96
|
+
* string (`{"auth_token":"abc","ct0":"def"}`). Throws naming what's missing.
|
|
97
|
+
*/
|
|
98
|
+
declare function parseCookies(input: string): Cookies;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Operation name → { queryId, operationName }. Values are the twscrape mid-2026
|
|
102
|
+
* snapshot from ENGINE-RESEARCH.md §2.
|
|
103
|
+
*
|
|
104
|
+
* IMPORTANT: query-ids ROTATE. They live here in config, never hardcoded in logic.
|
|
105
|
+
* A `(336) features cannot be null` (or a 404 on the URL) means the hashes drifted —
|
|
106
|
+
* refresh this config from the web bundle.
|
|
107
|
+
*/
|
|
108
|
+
declare const OPS: {
|
|
109
|
+
readonly SearchTimeline: {
|
|
110
|
+
readonly queryId: "Yw6L66Pw54NHKuq4Dp7b4Q";
|
|
111
|
+
readonly operationName: "SearchTimeline";
|
|
112
|
+
};
|
|
113
|
+
readonly UserByScreenName: {
|
|
114
|
+
readonly queryId: "IGgvgiOx4QZndDHuD3x9TQ";
|
|
115
|
+
readonly operationName: "UserByScreenName";
|
|
116
|
+
};
|
|
117
|
+
readonly UserByRestId: {
|
|
118
|
+
readonly queryId: "VQfQ9wwYdk6j_u2O4vt64Q";
|
|
119
|
+
readonly operationName: "UserByRestId";
|
|
120
|
+
};
|
|
121
|
+
readonly UserTweets: {
|
|
122
|
+
readonly queryId: "36rb3Xj3iJ64Q-9wKDjCcQ";
|
|
123
|
+
readonly operationName: "UserTweets";
|
|
124
|
+
};
|
|
125
|
+
readonly UserTweetsAndReplies: {
|
|
126
|
+
readonly queryId: "D5eKzDa5ZoJuC1TCeAXbWA";
|
|
127
|
+
readonly operationName: "UserTweetsAndReplies";
|
|
128
|
+
};
|
|
129
|
+
readonly UserMedia: {
|
|
130
|
+
readonly queryId: "9EovraBTXJYGSEQXZqlLmQ";
|
|
131
|
+
readonly operationName: "UserMedia";
|
|
132
|
+
};
|
|
133
|
+
readonly Bookmarks: {
|
|
134
|
+
readonly queryId: "XD0ViOeSOW4YoeNTGjVaYw";
|
|
135
|
+
readonly operationName: "Bookmarks";
|
|
136
|
+
};
|
|
137
|
+
readonly TweetDetail: {
|
|
138
|
+
readonly queryId: "oCon7R-cgWRFy6EfZjaKfg";
|
|
139
|
+
readonly operationName: "TweetDetail";
|
|
140
|
+
};
|
|
141
|
+
readonly Followers: {
|
|
142
|
+
readonly queryId: "_orfRBQae57vylFPH0Huhg";
|
|
143
|
+
readonly operationName: "Followers";
|
|
144
|
+
};
|
|
145
|
+
readonly Following: {
|
|
146
|
+
readonly queryId: "F42cDX8PDFxkbjjq6JrM2w";
|
|
147
|
+
readonly operationName: "Following";
|
|
148
|
+
};
|
|
149
|
+
readonly ListLatestTweetsTimeline: {
|
|
150
|
+
readonly queryId: "7UuJsFvnWuZo0HmxrzU42Q";
|
|
151
|
+
readonly operationName: "ListLatestTweetsTimeline";
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
type OpName = keyof typeof OPS;
|
|
155
|
+
type Vars = Record<string, unknown>;
|
|
156
|
+
type Feats = Record<string, boolean>;
|
|
157
|
+
interface BuiltRequest {
|
|
158
|
+
variables: Vars;
|
|
159
|
+
features: Feats;
|
|
160
|
+
fieldToggles?: Vars;
|
|
161
|
+
}
|
|
162
|
+
type SearchProduct = 'Top' | 'Latest' | 'Media' | 'People';
|
|
163
|
+
|
|
164
|
+
/** Yields the x-client-transaction-id for a request (method + path bound). */
|
|
165
|
+
type TransactionProvider = (method: string, path: string) => Promise<string>;
|
|
166
|
+
type ClientResult = {
|
|
167
|
+
ok: true;
|
|
168
|
+
value: unknown;
|
|
169
|
+
} | {
|
|
170
|
+
ok: false;
|
|
171
|
+
error: {
|
|
172
|
+
code: string;
|
|
173
|
+
message: string;
|
|
174
|
+
status?: number;
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/** A failure surfaced from the network/transport layer. Commands map it to an envelope. */
|
|
179
|
+
declare class EngineError extends Error {
|
|
180
|
+
readonly code: string;
|
|
181
|
+
readonly status?: number;
|
|
182
|
+
constructor(code: string, message: string, status?: number);
|
|
183
|
+
}
|
|
184
|
+
/** The transport surface the engine needs — satisfied by createClient, fakeable in tests. */
|
|
185
|
+
interface EngineClient {
|
|
186
|
+
get(op: OpName, request: BuiltRequest): Promise<ClientResult>;
|
|
187
|
+
}
|
|
188
|
+
interface SearchOpts {
|
|
189
|
+
product?: SearchProduct;
|
|
190
|
+
limit?: number;
|
|
191
|
+
}
|
|
192
|
+
interface UserTweetsOpts {
|
|
193
|
+
replies?: boolean;
|
|
194
|
+
limit?: number;
|
|
195
|
+
/** Stop paginating once a tweet with id <= this is seen (incremental sync watermark). */
|
|
196
|
+
stopAtId?: string;
|
|
197
|
+
}
|
|
198
|
+
interface PageOpts {
|
|
199
|
+
limit?: number;
|
|
200
|
+
/** Stop paginating once a tweet with id <= this is seen (incremental sync watermark). */
|
|
201
|
+
stopAtId?: string;
|
|
202
|
+
}
|
|
203
|
+
interface Engine {
|
|
204
|
+
search(query: string, opts?: SearchOpts): Promise<SearchResult>;
|
|
205
|
+
user(handle: string): Promise<UserProfile | null>;
|
|
206
|
+
userTweets(handle: string, opts?: UserTweetsOpts): Promise<TweetPage>;
|
|
207
|
+
bookmarks(opts?: PageOpts): Promise<TweetPage>;
|
|
208
|
+
thread(id: string): Promise<ThreadResult>;
|
|
209
|
+
}
|
|
210
|
+
interface EngineDeps {
|
|
211
|
+
/** Cookies for auth. Omit to auto-extract from the local browser (getCookies). */
|
|
212
|
+
cookies?: Cookies;
|
|
213
|
+
fetchImpl?: typeof fetch;
|
|
214
|
+
/** Injectable transport (tests). Defaults to a real client over the X API. */
|
|
215
|
+
client?: EngineClient;
|
|
216
|
+
/** Injectable transaction provider (tests). Defaults to the xctid generator. */
|
|
217
|
+
transaction?: TransactionProvider;
|
|
218
|
+
}
|
|
219
|
+
declare function createEngine(deps: EngineDeps): Engine;
|
|
220
|
+
|
|
221
|
+
interface ParsedArgs {
|
|
222
|
+
command?: string;
|
|
223
|
+
positionals: string[];
|
|
224
|
+
flags: Record<string, string[]>;
|
|
225
|
+
bools: Set<string>;
|
|
226
|
+
}
|
|
227
|
+
declare function parseArgs(argv: string[]): ParsedArgs;
|
|
228
|
+
/** Dispatch parsed args against an engine. Returns an envelope (does not print). */
|
|
229
|
+
declare function dispatch(parsed: ParsedArgs, engine: Engine): Promise<Envelope<unknown>>;
|
|
230
|
+
declare function run(argv: string[], engine?: Engine): Promise<number>;
|
|
231
|
+
|
|
232
|
+
export { type Author as A, type Cookies as C, type Err as E, type MediaKind as M, type Ok as O, type PageOpts as P, type SearchProduct as S, type Tweet as T, type UserProfile as U, type Engine as a, type Envelope as b, type TweetPage as c, type SearchResult as d, type ThreadResult as e, type EngineDeps as f, EngineError as g, type Metrics as h, type SearchOpts as i, type SearchProduct$1 as j, type UserTweetsOpts as k, createEngine as l, dispatch as m, parseCookies as n, type ParsedArgs as o, parseArgs as p, run as r };
|
package/dist/cli.d.ts
ADDED