spora 0.6.3 → 0.7.1
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 +7 -5
- package/dist/autonomy-DAV7X6QS.js +19 -0
- package/dist/{chunk-53YLFYJF.js → chunk-3RYCUGXE.js} +6 -2
- package/dist/chunk-3RYCUGXE.js.map +1 -0
- package/dist/{chunk-LKCYTFWN.js → chunk-AOQ3WLZV.js} +86 -106
- package/dist/chunk-AOQ3WLZV.js.map +1 -0
- package/dist/chunk-E5NR6HT4.js +29 -0
- package/dist/chunk-E5NR6HT4.js.map +1 -0
- package/dist/{chunk-EBO4F5NU.js → chunk-JBYZ7K56.js} +2 -2
- package/dist/chunk-KWWAIS3C.js +180 -0
- package/dist/chunk-KWWAIS3C.js.map +1 -0
- package/dist/{chunk-UINSD4FT.js → chunk-LXQNVVIY.js} +6 -6
- package/dist/{chunk-UINSD4FT.js.map → chunk-LXQNVVIY.js.map} +1 -1
- package/dist/{chunk-AIEXQCQS.js → chunk-M6YOQVSI.js} +2 -2
- package/dist/{chunk-B6RPMDML.js → chunk-NO3NQN67.js} +16 -6
- package/dist/chunk-NO3NQN67.js.map +1 -0
- package/dist/{chunk-QOKQ5OTU.js → chunk-NPV3OV2K.js} +3 -14
- package/dist/chunk-NPV3OV2K.js.map +1 -0
- package/dist/{chunk-4POAJONO.js → chunk-OACD3HGE.js} +7 -7
- package/dist/{chunk-UM57WU5I.js → chunk-P6KZIJYL.js} +2 -2
- package/dist/{chunk-AHXZIGQE.js → chunk-T7L2L7ZL.js} +2 -2
- package/dist/{chunk-ZJZKH7N7.js → chunk-VZBHRUZS.js} +2 -2
- package/dist/chunk-VZBHRUZS.js.map +1 -0
- package/dist/chunk-WIK74GGJ.js +295 -0
- package/dist/chunk-WIK74GGJ.js.map +1 -0
- package/dist/{chunk-YLJVFCT4.js → chunk-WN35MRMF.js} +2 -2
- package/dist/cli.js +168 -137
- package/dist/cli.js.map +1 -1
- package/dist/client-57BQKVYF.js +337 -0
- package/dist/client-57BQKVYF.js.map +1 -0
- package/dist/{colony-STNSQDYA.js → colony-JPZC3R34.js} +7 -7
- package/dist/{config-TFAFYSIW.js → config-FL4VJVKZ.js} +3 -3
- package/dist/{crypto-FHSQ72NU.js → crypto-NOXNL4GP.js} +3 -3
- package/dist/{goals-5TAPXNR2.js → goals-RBKLMILE.js} +3 -3
- package/dist/{heartbeat-5PWQERHL.js → heartbeat-TNEPE3ZP.js} +83 -92
- package/dist/heartbeat-TNEPE3ZP.js.map +1 -0
- package/dist/{identity-O4FLSZKZ.js → identity-VDUW4I2K.js} +3 -3
- package/dist/{init-E54LQDKA.js → init-ISSXETHY.js} +59 -46
- package/dist/init-ISSXETHY.js.map +1 -0
- package/dist/llm-T33QTPVW.js +22 -0
- package/dist/mcp-server.js +28 -28
- package/dist/mcp-server.js.map +1 -1
- package/dist/{memory-O3AJIKBX.js → memory-OIAH33G2.js} +3 -3
- package/dist/{memory-7FBE26K3.js → memory-PNW7SX7A.js} +3 -3
- package/dist/{paths-5GFUUHCZ.js → paths-BYR6MEPR.js} +2 -2
- package/dist/prompt-builder-5NYONN2W.js +23 -0
- package/dist/queue-G5PTE6R6.js +14 -0
- package/dist/{strategy-S45TX766.js → strategy-Z4JSFHSP.js} +3 -3
- package/dist/{web-chat-P6PZ3TP6.js → web-chat-3HM35XM4.js} +30 -85
- package/dist/web-chat-3HM35XM4.js.map +1 -0
- package/dist/x-client-GY6XSPK6.js +12 -0
- package/package.json +1 -1
- package/dist/account-creator-ZD643X3Z.js +0 -498
- package/dist/account-creator-ZD643X3Z.js.map +0 -1
- package/dist/chunk-53YLFYJF.js.map +0 -1
- package/dist/chunk-55XPDJ6P.js +0 -124
- package/dist/chunk-55XPDJ6P.js.map +0 -1
- package/dist/chunk-B6RPMDML.js.map +0 -1
- package/dist/chunk-H2N5G6R7.js +0 -249
- package/dist/chunk-H2N5G6R7.js.map +0 -1
- package/dist/chunk-LKCYTFWN.js.map +0 -1
- package/dist/chunk-QOKQ5OTU.js.map +0 -1
- package/dist/chunk-ZJZKH7N7.js.map +0 -1
- package/dist/chunk-ZMTC7BYD.js +0 -32
- package/dist/chunk-ZMTC7BYD.js.map +0 -1
- package/dist/client-GCHDQ6W2.js +0 -350
- package/dist/client-GCHDQ6W2.js.map +0 -1
- package/dist/client-I7Q4HC4F.js +0 -401
- package/dist/client-I7Q4HC4F.js.map +0 -1
- package/dist/decision-engine-SO33N7CT.js +0 -19
- package/dist/heartbeat-5PWQERHL.js.map +0 -1
- package/dist/init-E54LQDKA.js.map +0 -1
- package/dist/llm-3LSNADSR.js +0 -16
- package/dist/prompt-builder-3LQFX6QK.js +0 -23
- package/dist/queue-CXMLAQ6X.js +0 -14
- package/dist/web-chat-P6PZ3TP6.js.map +0 -1
- package/dist/x-client-7LMNSOTE.js +0 -12
- /package/dist/{config-TFAFYSIW.js.map → autonomy-DAV7X6QS.js.map} +0 -0
- /package/dist/{chunk-EBO4F5NU.js.map → chunk-JBYZ7K56.js.map} +0 -0
- /package/dist/{chunk-AIEXQCQS.js.map → chunk-M6YOQVSI.js.map} +0 -0
- /package/dist/{chunk-4POAJONO.js.map → chunk-OACD3HGE.js.map} +0 -0
- /package/dist/{chunk-UM57WU5I.js.map → chunk-P6KZIJYL.js.map} +0 -0
- /package/dist/{chunk-AHXZIGQE.js.map → chunk-T7L2L7ZL.js.map} +0 -0
- /package/dist/{chunk-YLJVFCT4.js.map → chunk-WN35MRMF.js.map} +0 -0
- /package/dist/{colony-STNSQDYA.js.map → colony-JPZC3R34.js.map} +0 -0
- /package/dist/{crypto-FHSQ72NU.js.map → config-FL4VJVKZ.js.map} +0 -0
- /package/dist/{decision-engine-SO33N7CT.js.map → crypto-NOXNL4GP.js.map} +0 -0
- /package/dist/{goals-5TAPXNR2.js.map → goals-RBKLMILE.js.map} +0 -0
- /package/dist/{identity-O4FLSZKZ.js.map → identity-VDUW4I2K.js.map} +0 -0
- /package/dist/{llm-3LSNADSR.js.map → llm-T33QTPVW.js.map} +0 -0
- /package/dist/{memory-7FBE26K3.js.map → memory-OIAH33G2.js.map} +0 -0
- /package/dist/{memory-O3AJIKBX.js.map → memory-PNW7SX7A.js.map} +0 -0
- /package/dist/{paths-5GFUUHCZ.js.map → paths-BYR6MEPR.js.map} +0 -0
- /package/dist/{prompt-builder-3LQFX6QK.js.map → prompt-builder-5NYONN2W.js.map} +0 -0
- /package/dist/{queue-CXMLAQ6X.js.map → queue-G5PTE6R6.js.map} +0 -0
- /package/dist/{strategy-S45TX766.js.map → strategy-Z4JSFHSP.js.map} +0 -0
- /package/dist/{x-client-7LMNSOTE.js.map → x-client-GY6XSPK6.js.map} +0 -0
package/dist/client-GCHDQ6W2.js
DELETED
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
rateLimiter
|
|
3
|
-
} from "./chunk-UINSD4FT.js";
|
|
4
|
-
import "./chunk-B6RPMDML.js";
|
|
5
|
-
import {
|
|
6
|
-
identityExists,
|
|
7
|
-
loadIdentity
|
|
8
|
-
} from "./chunk-AIEXQCQS.js";
|
|
9
|
-
import {
|
|
10
|
-
loadCredentials
|
|
11
|
-
} from "./chunk-ZJZKH7N7.js";
|
|
12
|
-
import {
|
|
13
|
-
logger
|
|
14
|
-
} from "./chunk-QOKQ5OTU.js";
|
|
15
|
-
import {
|
|
16
|
-
logInteraction
|
|
17
|
-
} from "./chunk-EBO4F5NU.js";
|
|
18
|
-
import "./chunk-53YLFYJF.js";
|
|
19
|
-
|
|
20
|
-
// src/x-client/api/client.ts
|
|
21
|
-
import { TwitterApi } from "twitter-api-v2";
|
|
22
|
-
function extractTwitterError(error) {
|
|
23
|
-
if (!error || typeof error !== "object") return String(error);
|
|
24
|
-
const e = error;
|
|
25
|
-
if (e.code && e.data) {
|
|
26
|
-
const status = e.code;
|
|
27
|
-
const data = e.data;
|
|
28
|
-
const errors = data.errors ?? data.detail ?? data.title ?? data.reason;
|
|
29
|
-
return `HTTP ${status}: ${JSON.stringify(errors ?? data)}`;
|
|
30
|
-
}
|
|
31
|
-
if (e.message) return e.message;
|
|
32
|
-
return String(error);
|
|
33
|
-
}
|
|
34
|
-
var XApiClient = class {
|
|
35
|
-
client;
|
|
36
|
-
userId = null;
|
|
37
|
-
creds;
|
|
38
|
-
constructor() {
|
|
39
|
-
this.creds = loadCredentials();
|
|
40
|
-
if (this.creds.method !== "api") {
|
|
41
|
-
throw new Error("API client requires API credentials. Current method: browser");
|
|
42
|
-
}
|
|
43
|
-
this.client = new TwitterApi({
|
|
44
|
-
appKey: this.creds.apiKey,
|
|
45
|
-
appSecret: this.creds.apiSecret,
|
|
46
|
-
accessToken: this.creds.accessToken,
|
|
47
|
-
accessSecret: this.creds.accessTokenSecret
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
async getUserId() {
|
|
51
|
-
if (this.userId) return this.userId;
|
|
52
|
-
const accessToken = this.creds.accessToken;
|
|
53
|
-
if (accessToken) {
|
|
54
|
-
const dashIdx = accessToken.indexOf("-");
|
|
55
|
-
if (dashIdx > 0) {
|
|
56
|
-
const candidate = accessToken.substring(0, dashIdx);
|
|
57
|
-
if (/^\d+$/.test(candidate)) {
|
|
58
|
-
logger.info(`User ID extracted from access token: ${candidate}`);
|
|
59
|
-
this.userId = candidate;
|
|
60
|
-
return this.userId;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
try {
|
|
65
|
-
const me = await this.client.v2.me();
|
|
66
|
-
if (me.data) {
|
|
67
|
-
logger.info(`User ID from /me endpoint: ${me.data.id} (@${me.data.username})`);
|
|
68
|
-
this.userId = me.data.id;
|
|
69
|
-
return this.userId;
|
|
70
|
-
}
|
|
71
|
-
} catch (err) {
|
|
72
|
-
logger.warn(`/me endpoint failed: ${extractTwitterError(err)}`);
|
|
73
|
-
}
|
|
74
|
-
const handle = this.getHandle();
|
|
75
|
-
logger.info(`Trying userByUsername lookup for: ${handle}`);
|
|
76
|
-
const result = await this.client.v2.userByUsername(handle);
|
|
77
|
-
if (!result.data) {
|
|
78
|
-
const errInfo = result.errors;
|
|
79
|
-
throw new Error(
|
|
80
|
-
`Could not find user @${handle}. API returned: ${JSON.stringify(errInfo ?? "no data")}`
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
this.userId = result.data.id;
|
|
84
|
-
return this.userId;
|
|
85
|
-
}
|
|
86
|
-
getHandle() {
|
|
87
|
-
let handle;
|
|
88
|
-
if (identityExists()) {
|
|
89
|
-
handle = loadIdentity().handle;
|
|
90
|
-
} else {
|
|
91
|
-
handle = this.creds.username;
|
|
92
|
-
}
|
|
93
|
-
if (!handle) throw new Error("No handle found. Create a Spore identity first.");
|
|
94
|
-
return handle.replace(/^@/, "");
|
|
95
|
-
}
|
|
96
|
-
async postTweet(content) {
|
|
97
|
-
if (!rateLimiter.canPost()) {
|
|
98
|
-
return { success: false, error: "Monthly post limit reached" };
|
|
99
|
-
}
|
|
100
|
-
try {
|
|
101
|
-
const result = await this.client.v2.tweet(content);
|
|
102
|
-
rateLimiter.consume();
|
|
103
|
-
logInteraction({
|
|
104
|
-
id: `int-${Date.now()}`,
|
|
105
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
106
|
-
type: "post",
|
|
107
|
-
tweetId: result.data.id,
|
|
108
|
-
content,
|
|
109
|
-
creditsUsed: 1,
|
|
110
|
-
success: true
|
|
111
|
-
});
|
|
112
|
-
return { success: true, tweetId: result.data.id };
|
|
113
|
-
} catch (error) {
|
|
114
|
-
const detail = extractTwitterError(error);
|
|
115
|
-
logger.error(`Failed to post tweet: ${detail}`);
|
|
116
|
-
return { success: false, error: detail };
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
async replyToTweet(tweetId, content) {
|
|
120
|
-
if (!rateLimiter.canPost()) {
|
|
121
|
-
return { success: false, error: "Monthly post limit reached" };
|
|
122
|
-
}
|
|
123
|
-
try {
|
|
124
|
-
const result = await this.client.v2.reply(content, tweetId);
|
|
125
|
-
rateLimiter.consume();
|
|
126
|
-
logInteraction({
|
|
127
|
-
id: `int-${Date.now()}`,
|
|
128
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
129
|
-
type: "reply",
|
|
130
|
-
tweetId: result.data.id,
|
|
131
|
-
inReplyTo: tweetId,
|
|
132
|
-
content,
|
|
133
|
-
creditsUsed: 1,
|
|
134
|
-
success: true
|
|
135
|
-
});
|
|
136
|
-
return { success: true, tweetId: result.data.id };
|
|
137
|
-
} catch (error) {
|
|
138
|
-
const detail = extractTwitterError(error);
|
|
139
|
-
logger.error(`Failed to reply: ${detail}`);
|
|
140
|
-
return { success: false, error: detail };
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
async deleteTweet(tweetId) {
|
|
144
|
-
try {
|
|
145
|
-
await this.client.v2.deleteTweet(tweetId);
|
|
146
|
-
return { success: true, tweetId };
|
|
147
|
-
} catch (error) {
|
|
148
|
-
return { success: false, error: error.message };
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
async likeTweet(tweetId) {
|
|
152
|
-
try {
|
|
153
|
-
rateLimiter.requireBasicTier("Like");
|
|
154
|
-
const userId = await this.getUserId();
|
|
155
|
-
await this.client.v2.like(userId, tweetId);
|
|
156
|
-
logInteraction({
|
|
157
|
-
id: `int-${Date.now()}`,
|
|
158
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
159
|
-
type: "like",
|
|
160
|
-
tweetId,
|
|
161
|
-
creditsUsed: 0,
|
|
162
|
-
success: true
|
|
163
|
-
});
|
|
164
|
-
return { success: true, tweetId };
|
|
165
|
-
} catch (error) {
|
|
166
|
-
return { success: false, error: error.message };
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
async unlikeTweet(tweetId) {
|
|
170
|
-
try {
|
|
171
|
-
rateLimiter.requireBasicTier("Unlike");
|
|
172
|
-
const userId = await this.getUserId();
|
|
173
|
-
await this.client.v2.unlike(userId, tweetId);
|
|
174
|
-
return { success: true, tweetId };
|
|
175
|
-
} catch (error) {
|
|
176
|
-
return { success: false, error: error.message };
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
async retweet(tweetId) {
|
|
180
|
-
try {
|
|
181
|
-
rateLimiter.requireBasicTier("Retweet");
|
|
182
|
-
const userId = await this.getUserId();
|
|
183
|
-
await this.client.v2.retweet(userId, tweetId);
|
|
184
|
-
logInteraction({
|
|
185
|
-
id: `int-${Date.now()}`,
|
|
186
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
187
|
-
type: "retweet",
|
|
188
|
-
tweetId,
|
|
189
|
-
creditsUsed: 0,
|
|
190
|
-
success: true
|
|
191
|
-
});
|
|
192
|
-
return { success: true, tweetId };
|
|
193
|
-
} catch (error) {
|
|
194
|
-
return { success: false, error: error.message };
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
async unretweet(tweetId) {
|
|
198
|
-
try {
|
|
199
|
-
rateLimiter.requireBasicTier("Unretweet");
|
|
200
|
-
const userId = await this.getUserId();
|
|
201
|
-
await this.client.v2.unretweet(userId, tweetId);
|
|
202
|
-
return { success: true, tweetId };
|
|
203
|
-
} catch (error) {
|
|
204
|
-
return { success: false, error: error.message };
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
async followUser(userId) {
|
|
208
|
-
try {
|
|
209
|
-
rateLimiter.requireBasicTier("Follow");
|
|
210
|
-
const myId = await this.getUserId();
|
|
211
|
-
await this.client.v2.follow(myId, userId);
|
|
212
|
-
logInteraction({
|
|
213
|
-
id: `int-${Date.now()}`,
|
|
214
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
215
|
-
type: "follow",
|
|
216
|
-
targetUserId: userId,
|
|
217
|
-
creditsUsed: 0,
|
|
218
|
-
success: true
|
|
219
|
-
});
|
|
220
|
-
return { success: true };
|
|
221
|
-
} catch (error) {
|
|
222
|
-
return { success: false, error: error.message };
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
async unfollowUser(userId) {
|
|
226
|
-
try {
|
|
227
|
-
rateLimiter.requireBasicTier("Unfollow");
|
|
228
|
-
const myId = await this.getUserId();
|
|
229
|
-
await this.client.v2.unfollow(myId, userId);
|
|
230
|
-
return { success: true };
|
|
231
|
-
} catch (error) {
|
|
232
|
-
return { success: false, error: error.message };
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
async getTimeline(options) {
|
|
236
|
-
try {
|
|
237
|
-
rateLimiter.requireBasicTier("Read timeline");
|
|
238
|
-
const userId = await this.getUserId();
|
|
239
|
-
const result = await this.client.v2.homeTimeline({
|
|
240
|
-
max_results: options?.count ?? 20,
|
|
241
|
-
"tweet.fields": ["created_at", "public_metrics", "in_reply_to_user_id"],
|
|
242
|
-
expansions: ["author_id"],
|
|
243
|
-
"user.fields": ["username"],
|
|
244
|
-
...options?.sinceId ? { since_id: options.sinceId } : {}
|
|
245
|
-
});
|
|
246
|
-
if (!result.data?.data) return [];
|
|
247
|
-
const userMap = /* @__PURE__ */ new Map();
|
|
248
|
-
for (const user of result.includes?.users ?? []) {
|
|
249
|
-
userMap.set(user.id, user.username);
|
|
250
|
-
}
|
|
251
|
-
return result.data.data.map((tweet) => ({
|
|
252
|
-
id: tweet.id,
|
|
253
|
-
text: tweet.text,
|
|
254
|
-
authorId: tweet.author_id ?? "unknown",
|
|
255
|
-
authorHandle: userMap.get(tweet.author_id ?? "") ?? "unknown",
|
|
256
|
-
createdAt: tweet.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
257
|
-
likeCount: tweet.public_metrics?.like_count,
|
|
258
|
-
retweetCount: tweet.public_metrics?.retweet_count,
|
|
259
|
-
replyCount: tweet.public_metrics?.reply_count
|
|
260
|
-
}));
|
|
261
|
-
} catch (error) {
|
|
262
|
-
const detail = extractTwitterError(error);
|
|
263
|
-
logger.error(`Failed to read timeline: ${detail}`);
|
|
264
|
-
return [];
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
async getMentions(options) {
|
|
268
|
-
try {
|
|
269
|
-
rateLimiter.requireBasicTier("Read mentions");
|
|
270
|
-
const userId = await this.getUserId();
|
|
271
|
-
const result = await this.client.v2.userMentionTimeline(userId, {
|
|
272
|
-
max_results: options?.count ?? 20,
|
|
273
|
-
"tweet.fields": ["created_at", "public_metrics"],
|
|
274
|
-
expansions: ["author_id"],
|
|
275
|
-
"user.fields": ["username"],
|
|
276
|
-
...options?.sinceId ? { since_id: options.sinceId } : {}
|
|
277
|
-
});
|
|
278
|
-
if (!result.data?.data) return [];
|
|
279
|
-
const userMap = /* @__PURE__ */ new Map();
|
|
280
|
-
for (const user of result.includes?.users ?? []) {
|
|
281
|
-
userMap.set(user.id, user.username);
|
|
282
|
-
}
|
|
283
|
-
return result.data.data.map((tweet) => ({
|
|
284
|
-
id: tweet.id,
|
|
285
|
-
text: tweet.text,
|
|
286
|
-
authorId: tweet.author_id ?? "unknown",
|
|
287
|
-
authorHandle: userMap.get(tweet.author_id ?? "") ?? "unknown",
|
|
288
|
-
createdAt: tweet.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
289
|
-
likeCount: tweet.public_metrics?.like_count,
|
|
290
|
-
retweetCount: tweet.public_metrics?.retweet_count,
|
|
291
|
-
replyCount: tweet.public_metrics?.reply_count
|
|
292
|
-
}));
|
|
293
|
-
} catch (error) {
|
|
294
|
-
const detail = extractTwitterError(error);
|
|
295
|
-
logger.error(`Failed to read mentions: ${detail}`);
|
|
296
|
-
return [];
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
async searchTweets(query, options) {
|
|
300
|
-
try {
|
|
301
|
-
rateLimiter.requireBasicTier("Search tweets");
|
|
302
|
-
const result = await this.client.v2.search(query, {
|
|
303
|
-
max_results: options?.count ?? 20,
|
|
304
|
-
"tweet.fields": ["created_at", "public_metrics"],
|
|
305
|
-
expansions: ["author_id"],
|
|
306
|
-
"user.fields": ["username"]
|
|
307
|
-
});
|
|
308
|
-
if (!result.data?.data) return [];
|
|
309
|
-
const userMap = /* @__PURE__ */ new Map();
|
|
310
|
-
for (const user of result.includes?.users ?? []) {
|
|
311
|
-
userMap.set(user.id, user.username);
|
|
312
|
-
}
|
|
313
|
-
return result.data.data.map((tweet) => ({
|
|
314
|
-
id: tweet.id,
|
|
315
|
-
text: tweet.text,
|
|
316
|
-
authorId: tweet.author_id ?? "unknown",
|
|
317
|
-
authorHandle: userMap.get(tweet.author_id ?? "") ?? "unknown",
|
|
318
|
-
createdAt: tweet.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
319
|
-
likeCount: tweet.public_metrics?.like_count,
|
|
320
|
-
retweetCount: tweet.public_metrics?.retweet_count,
|
|
321
|
-
replyCount: tweet.public_metrics?.reply_count
|
|
322
|
-
}));
|
|
323
|
-
} catch (error) {
|
|
324
|
-
const detail = extractTwitterError(error);
|
|
325
|
-
logger.error(`Failed to search tweets: ${detail}`);
|
|
326
|
-
return [];
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
async getProfile(handle) {
|
|
330
|
-
const result = await this.client.v2.userByUsername(handle, {
|
|
331
|
-
"user.fields": ["description", "public_metrics", "verified", "profile_image_url"]
|
|
332
|
-
});
|
|
333
|
-
if (!result.data) throw new Error(`User not found: @${handle}`);
|
|
334
|
-
return {
|
|
335
|
-
id: result.data.id,
|
|
336
|
-
handle: result.data.username,
|
|
337
|
-
name: result.data.name,
|
|
338
|
-
bio: result.data.description ?? "",
|
|
339
|
-
followersCount: result.data.public_metrics?.followers_count ?? 0,
|
|
340
|
-
followingCount: result.data.public_metrics?.following_count ?? 0,
|
|
341
|
-
tweetCount: result.data.public_metrics?.tweet_count ?? 0,
|
|
342
|
-
verified: result.data.verified ?? false,
|
|
343
|
-
profileImageUrl: result.data.profile_image_url
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
export {
|
|
348
|
-
XApiClient
|
|
349
|
-
};
|
|
350
|
-
//# sourceMappingURL=client-GCHDQ6W2.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/x-client/api/client.ts"],"sourcesContent":["import { TwitterApi } from \"twitter-api-v2\";\nimport { loadCredentials } from \"../../utils/crypto.js\";\nimport { loadIdentity, identityExists } from \"../../identity/index.js\";\nimport { logInteraction } from \"../../memory/index.js\";\nimport { rateLimiter } from \"../rate-limiter.js\";\nimport { logger } from \"../../utils/logger.js\";\nimport type {\n XClientInterface,\n Tweet,\n UserProfile,\n PostResult,\n TimelineOptions,\n SearchOptions,\n} from \"../types.js\";\n\n/**\n * Extract useful error details from twitter-api-v2 errors.\n * Their ApiResponseError has .code, .data, .errors properties that JSON.stringify misses.\n */\nfunction extractTwitterError(error: unknown): string {\n if (!error || typeof error !== \"object\") return String(error);\n const e = error as Record<string, unknown>;\n\n // twitter-api-v2 ApiResponseError shape\n if (e.code && e.data) {\n const status = e.code;\n const data = e.data as Record<string, unknown>;\n const errors = (data.errors ?? data.detail ?? data.title ?? data.reason) as unknown;\n return `HTTP ${status}: ${JSON.stringify(errors ?? data)}`;\n }\n\n // Fallback for standard errors\n if (e.message) return e.message as string;\n return String(error);\n}\n\nexport class XApiClient implements XClientInterface {\n private client: TwitterApi;\n private userId: string | null = null;\n private creds: ReturnType<typeof loadCredentials>;\n\n constructor() {\n this.creds = loadCredentials();\n if (this.creds.method !== \"api\") {\n throw new Error(\"API client requires API credentials. Current method: browser\");\n }\n\n // Use twitter-api-v2 with OAuth 1.0a User Context (proper auth for all endpoints)\n this.client = new TwitterApi({\n appKey: this.creds.apiKey!,\n appSecret: this.creds.apiSecret!,\n accessToken: this.creds.accessToken!,\n accessSecret: this.creds.accessTokenSecret!,\n });\n }\n\n private async getUserId(): Promise<string> {\n if (this.userId) return this.userId;\n\n // Strategy 1: Extract user ID from OAuth access token (format: {userId}-{rest})\n const accessToken = this.creds.accessToken;\n if (accessToken) {\n const dashIdx = accessToken.indexOf(\"-\");\n if (dashIdx > 0) {\n const candidate = accessToken.substring(0, dashIdx);\n if (/^\\d+$/.test(candidate)) {\n logger.info(`User ID extracted from access token: ${candidate}`);\n this.userId = candidate;\n return this.userId;\n }\n }\n }\n\n // Strategy 2: Use /2/users/me endpoint\n try {\n const me = await this.client.v2.me();\n if (me.data) {\n logger.info(`User ID from /me endpoint: ${me.data.id} (@${me.data.username})`);\n this.userId = me.data.id;\n return this.userId;\n }\n } catch (err) {\n logger.warn(`/me endpoint failed: ${extractTwitterError(err)}`);\n }\n\n // Strategy 3: Fall back to username lookup\n const handle = this.getHandle();\n logger.info(`Trying userByUsername lookup for: ${handle}`);\n const result = await this.client.v2.userByUsername(handle);\n if (!result.data) {\n // Log the full response for debugging\n const errInfo = (result as Record<string, unknown>).errors;\n throw new Error(\n `Could not find user @${handle}. API returned: ${JSON.stringify(errInfo ?? \"no data\")}`\n );\n }\n this.userId = result.data.id;\n return this.userId;\n }\n\n private getHandle(): string {\n let handle: string | undefined;\n if (identityExists()) {\n handle = loadIdentity().handle;\n } else {\n handle = this.creds.username;\n }\n if (!handle) throw new Error(\"No handle found. Create a Spore identity first.\");\n // Strip @ prefix — twitter-api-v2 userByUsername expects bare handle\n return handle.replace(/^@/, \"\");\n }\n\n async postTweet(content: string): Promise<PostResult> {\n if (!rateLimiter.canPost()) {\n return { success: false, error: \"Monthly post limit reached\" };\n }\n\n try {\n const result = await this.client.v2.tweet(content);\n\n rateLimiter.consume();\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"post\",\n tweetId: result.data.id,\n content,\n creditsUsed: 1,\n success: true,\n });\n\n return { success: true, tweetId: result.data.id };\n } catch (error) {\n const detail = extractTwitterError(error);\n logger.error(`Failed to post tweet: ${detail}`);\n return { success: false, error: detail };\n }\n }\n\n async replyToTweet(tweetId: string, content: string): Promise<PostResult> {\n if (!rateLimiter.canPost()) {\n return { success: false, error: \"Monthly post limit reached\" };\n }\n\n try {\n const result = await this.client.v2.reply(content, tweetId);\n\n rateLimiter.consume();\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"reply\",\n tweetId: result.data.id,\n inReplyTo: tweetId,\n content,\n creditsUsed: 1,\n success: true,\n });\n\n return { success: true, tweetId: result.data.id };\n } catch (error) {\n const detail = extractTwitterError(error);\n logger.error(`Failed to reply: ${detail}`);\n return { success: false, error: detail };\n }\n }\n\n async deleteTweet(tweetId: string): Promise<PostResult> {\n try {\n await this.client.v2.deleteTweet(tweetId);\n return { success: true, tweetId };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n }\n\n async likeTweet(tweetId: string): Promise<PostResult> {\n try {\n rateLimiter.requireBasicTier(\"Like\");\n const userId = await this.getUserId();\n await this.client.v2.like(userId, tweetId);\n\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"like\",\n tweetId,\n creditsUsed: 0,\n success: true,\n });\n\n return { success: true, tweetId };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n }\n\n async unlikeTweet(tweetId: string): Promise<PostResult> {\n try {\n rateLimiter.requireBasicTier(\"Unlike\");\n const userId = await this.getUserId();\n await this.client.v2.unlike(userId, tweetId);\n return { success: true, tweetId };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n }\n\n async retweet(tweetId: string): Promise<PostResult> {\n try {\n rateLimiter.requireBasicTier(\"Retweet\");\n const userId = await this.getUserId();\n await this.client.v2.retweet(userId, tweetId);\n\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"retweet\",\n tweetId,\n creditsUsed: 0,\n success: true,\n });\n\n return { success: true, tweetId };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n }\n\n async unretweet(tweetId: string): Promise<PostResult> {\n try {\n rateLimiter.requireBasicTier(\"Unretweet\");\n const userId = await this.getUserId();\n await this.client.v2.unretweet(userId, tweetId);\n return { success: true, tweetId };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n }\n\n async followUser(userId: string): Promise<PostResult> {\n try {\n rateLimiter.requireBasicTier(\"Follow\");\n const myId = await this.getUserId();\n await this.client.v2.follow(myId, userId);\n\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"follow\",\n targetUserId: userId,\n creditsUsed: 0,\n success: true,\n });\n\n return { success: true };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n }\n\n async unfollowUser(userId: string): Promise<PostResult> {\n try {\n rateLimiter.requireBasicTier(\"Unfollow\");\n const myId = await this.getUserId();\n await this.client.v2.unfollow(myId, userId);\n return { success: true };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n }\n\n async getTimeline(options?: TimelineOptions): Promise<Tweet[]> {\n try {\n rateLimiter.requireBasicTier(\"Read timeline\");\n const userId = await this.getUserId();\n const result = await this.client.v2.homeTimeline({\n max_results: options?.count ?? 20,\n \"tweet.fields\": [\"created_at\", \"public_metrics\", \"in_reply_to_user_id\"],\n expansions: [\"author_id\"],\n \"user.fields\": [\"username\"],\n ...(options?.sinceId ? { since_id: options.sinceId } : {}),\n });\n\n if (!result.data?.data) return [];\n\n const userMap = new Map<string, string>();\n for (const user of result.includes?.users ?? []) {\n userMap.set(user.id, user.username);\n }\n\n return result.data.data.map((tweet) => ({\n id: tweet.id,\n text: tweet.text,\n authorId: tweet.author_id ?? \"unknown\",\n authorHandle: userMap.get(tweet.author_id ?? \"\") ?? \"unknown\",\n createdAt: tweet.created_at ?? new Date().toISOString(),\n likeCount: tweet.public_metrics?.like_count,\n retweetCount: tweet.public_metrics?.retweet_count,\n replyCount: tweet.public_metrics?.reply_count,\n }));\n } catch (error) {\n const detail = extractTwitterError(error);\n logger.error(`Failed to read timeline: ${detail}`);\n return [];\n }\n }\n\n async getMentions(options?: TimelineOptions): Promise<Tweet[]> {\n try {\n rateLimiter.requireBasicTier(\"Read mentions\");\n const userId = await this.getUserId();\n const result = await this.client.v2.userMentionTimeline(userId, {\n max_results: options?.count ?? 20,\n \"tweet.fields\": [\"created_at\", \"public_metrics\"],\n expansions: [\"author_id\"],\n \"user.fields\": [\"username\"],\n ...(options?.sinceId ? { since_id: options.sinceId } : {}),\n });\n\n if (!result.data?.data) return [];\n\n const userMap = new Map<string, string>();\n for (const user of result.includes?.users ?? []) {\n userMap.set(user.id, user.username);\n }\n\n return result.data.data.map((tweet) => ({\n id: tweet.id,\n text: tweet.text,\n authorId: tweet.author_id ?? \"unknown\",\n authorHandle: userMap.get(tweet.author_id ?? \"\") ?? \"unknown\",\n createdAt: tweet.created_at ?? new Date().toISOString(),\n likeCount: tweet.public_metrics?.like_count,\n retweetCount: tweet.public_metrics?.retweet_count,\n replyCount: tweet.public_metrics?.reply_count,\n }));\n } catch (error) {\n const detail = extractTwitterError(error);\n logger.error(`Failed to read mentions: ${detail}`);\n return [];\n }\n }\n\n async searchTweets(query: string, options?: SearchOptions): Promise<Tweet[]> {\n try {\n rateLimiter.requireBasicTier(\"Search tweets\");\n const result = await this.client.v2.search(query, {\n max_results: options?.count ?? 20,\n \"tweet.fields\": [\"created_at\", \"public_metrics\"],\n expansions: [\"author_id\"],\n \"user.fields\": [\"username\"],\n });\n\n if (!result.data?.data) return [];\n\n const userMap = new Map<string, string>();\n for (const user of result.includes?.users ?? []) {\n userMap.set(user.id, user.username);\n }\n\n return result.data.data.map((tweet) => ({\n id: tweet.id,\n text: tweet.text,\n authorId: tweet.author_id ?? \"unknown\",\n authorHandle: userMap.get(tweet.author_id ?? \"\") ?? \"unknown\",\n createdAt: tweet.created_at ?? new Date().toISOString(),\n likeCount: tweet.public_metrics?.like_count,\n retweetCount: tweet.public_metrics?.retweet_count,\n replyCount: tweet.public_metrics?.reply_count,\n }));\n } catch (error) {\n const detail = extractTwitterError(error);\n logger.error(`Failed to search tweets: ${detail}`);\n return [];\n }\n }\n\n async getProfile(handle: string): Promise<UserProfile> {\n const result = await this.client.v2.userByUsername(handle, {\n \"user.fields\": [\"description\", \"public_metrics\", \"verified\", \"profile_image_url\"],\n });\n\n if (!result.data) throw new Error(`User not found: @${handle}`);\n\n return {\n id: result.data.id,\n handle: result.data.username,\n name: result.data.name,\n bio: result.data.description ?? \"\",\n followersCount: result.data.public_metrics?.followers_count ?? 0,\n followingCount: result.data.public_metrics?.following_count ?? 0,\n tweetCount: result.data.public_metrics?.tweet_count ?? 0,\n verified: result.data.verified ?? false,\n profileImageUrl: result.data.profile_image_url,\n };\n }\n}\n"],"mappings":"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","names":[]}
|