peak6-x-intelligence-plugin 0.1.0 → 0.1.2
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 +25 -10
- package/dist/manifest.js +102 -25
- package/dist/manifest.js.map +2 -2
- package/dist/ui/index.js +261 -22
- package/dist/ui/index.js.map +2 -2
- package/dist/worker.js +551 -28
- package/dist/worker.js.map +4 -4
- package/package.json +10 -16
package/dist/ui/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/ui/index.tsx
|
|
2
2
|
import { usePluginAction, usePluginData } from "@paperclipai/plugin-sdk/ui";
|
|
3
|
+
import { useState } from "react";
|
|
3
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
function DashboardWidget(_props) {
|
|
5
6
|
const { data, loading, error } = usePluginData("dashboard-summary");
|
|
@@ -45,7 +46,7 @@ function DashboardWidget(_props) {
|
|
|
45
46
|
] }),
|
|
46
47
|
summary.top_items.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
47
48
|
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.75rem", fontWeight: 600, marginBottom: "0.25rem" }, children: "Top Items" }),
|
|
48
|
-
summary.top_items.slice(0, 3).map((tweet) => /* @__PURE__ */ jsx(TweetCard, { tweet }, tweet.tweet_id))
|
|
49
|
+
summary.top_items.slice(0, 3).map((tweet) => /* @__PURE__ */ jsx(TweetCard, { tweet, compact: true }, tweet.tweet_id))
|
|
49
50
|
] })
|
|
50
51
|
] }) : /* @__PURE__ */ jsx("div", { style: { opacity: 0.5, fontSize: "0.85rem" }, children: "No corpus for today. Discovery runs daily at 6:00 AM UTC." }),
|
|
51
52
|
/* @__PURE__ */ jsx(
|
|
@@ -67,51 +68,289 @@ function DashboardWidget(_props) {
|
|
|
67
68
|
)
|
|
68
69
|
] });
|
|
69
70
|
}
|
|
71
|
+
function CorpusBrowserPage(_props) {
|
|
72
|
+
const todayStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
73
|
+
const [date, setDate] = useState(todayStr);
|
|
74
|
+
const [pillar, setPillar] = useState("");
|
|
75
|
+
const [minScore, setMinScore] = useState(0);
|
|
76
|
+
const [minEngagement, setMinEngagement] = useState(0);
|
|
77
|
+
const [authorityOnly, setAuthorityOnly] = useState(false);
|
|
78
|
+
const [page, setPage] = useState(1);
|
|
79
|
+
const params = {
|
|
80
|
+
date,
|
|
81
|
+
page,
|
|
82
|
+
page_size: 25
|
|
83
|
+
};
|
|
84
|
+
if (pillar) params.pillar = pillar;
|
|
85
|
+
if (minScore > 0) params.min_score = minScore;
|
|
86
|
+
if (minEngagement > 0) params.min_engagement = minEngagement;
|
|
87
|
+
if (authorityOnly) params.authority_only = true;
|
|
88
|
+
const { data, loading, error } = usePluginData("corpus-browser", params);
|
|
89
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "1.5rem", maxWidth: "960px", margin: "0 auto" }, children: [
|
|
90
|
+
/* @__PURE__ */ jsx("h2", { style: { margin: "0 0 1rem" }, children: "X Intelligence Corpus" }),
|
|
91
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.5rem", marginBottom: "1rem", alignItems: "center" }, children: [
|
|
92
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "0.25rem" }, children: (data?.available_dates ?? [todayStr]).slice(0, 7).map((d) => /* @__PURE__ */ jsx(
|
|
93
|
+
"button",
|
|
94
|
+
{
|
|
95
|
+
onClick: () => {
|
|
96
|
+
setDate(d);
|
|
97
|
+
setPage(1);
|
|
98
|
+
},
|
|
99
|
+
style: {
|
|
100
|
+
padding: "0.25rem 0.5rem",
|
|
101
|
+
fontSize: "0.75rem",
|
|
102
|
+
border: "1px solid currentColor",
|
|
103
|
+
borderRadius: "3px",
|
|
104
|
+
background: d === date ? "rgba(128,128,128,0.25)" : "transparent",
|
|
105
|
+
color: "inherit",
|
|
106
|
+
cursor: "pointer",
|
|
107
|
+
fontWeight: d === date ? 600 : 400
|
|
108
|
+
},
|
|
109
|
+
children: d === todayStr ? "Today" : d.slice(5)
|
|
110
|
+
},
|
|
111
|
+
d
|
|
112
|
+
)) }),
|
|
113
|
+
/* @__PURE__ */ jsxs(
|
|
114
|
+
"select",
|
|
115
|
+
{
|
|
116
|
+
value: pillar,
|
|
117
|
+
onChange: (e) => {
|
|
118
|
+
setPillar(e.target.value);
|
|
119
|
+
setPage(1);
|
|
120
|
+
},
|
|
121
|
+
style: {
|
|
122
|
+
padding: "0.25rem 0.5rem",
|
|
123
|
+
fontSize: "0.75rem",
|
|
124
|
+
border: "1px solid currentColor",
|
|
125
|
+
borderRadius: "3px",
|
|
126
|
+
background: "transparent",
|
|
127
|
+
color: "inherit"
|
|
128
|
+
},
|
|
129
|
+
children: [
|
|
130
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "All pillars" }),
|
|
131
|
+
(data?.available_pillars ?? []).map((p) => /* @__PURE__ */ jsx("option", { value: p, children: p }, p))
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
),
|
|
135
|
+
/* @__PURE__ */ jsxs("label", { style: { fontSize: "0.75rem", display: "flex", alignItems: "center", gap: "0.25rem" }, children: [
|
|
136
|
+
"Score ",
|
|
137
|
+
">",
|
|
138
|
+
"=",
|
|
139
|
+
/* @__PURE__ */ jsx(
|
|
140
|
+
"input",
|
|
141
|
+
{
|
|
142
|
+
type: "number",
|
|
143
|
+
min: 0,
|
|
144
|
+
max: 1,
|
|
145
|
+
step: 0.1,
|
|
146
|
+
value: minScore,
|
|
147
|
+
onChange: (e) => {
|
|
148
|
+
setMinScore(parseFloat(e.target.value) || 0);
|
|
149
|
+
setPage(1);
|
|
150
|
+
},
|
|
151
|
+
style: {
|
|
152
|
+
width: "3.5rem",
|
|
153
|
+
padding: "0.2rem 0.35rem",
|
|
154
|
+
fontSize: "0.75rem",
|
|
155
|
+
border: "1px solid currentColor",
|
|
156
|
+
borderRadius: "3px",
|
|
157
|
+
background: "transparent",
|
|
158
|
+
color: "inherit"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
] }),
|
|
163
|
+
/* @__PURE__ */ jsxs("label", { style: { fontSize: "0.75rem", display: "flex", alignItems: "center", gap: "0.25rem" }, children: [
|
|
164
|
+
"Engmt ",
|
|
165
|
+
">",
|
|
166
|
+
"=",
|
|
167
|
+
/* @__PURE__ */ jsx(
|
|
168
|
+
"input",
|
|
169
|
+
{
|
|
170
|
+
type: "number",
|
|
171
|
+
min: 0,
|
|
172
|
+
step: 10,
|
|
173
|
+
value: minEngagement,
|
|
174
|
+
onChange: (e) => {
|
|
175
|
+
setMinEngagement(parseInt(e.target.value) || 0);
|
|
176
|
+
setPage(1);
|
|
177
|
+
},
|
|
178
|
+
style: {
|
|
179
|
+
width: "3.5rem",
|
|
180
|
+
padding: "0.2rem 0.35rem",
|
|
181
|
+
fontSize: "0.75rem",
|
|
182
|
+
border: "1px solid currentColor",
|
|
183
|
+
borderRadius: "3px",
|
|
184
|
+
background: "transparent",
|
|
185
|
+
color: "inherit"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
)
|
|
189
|
+
] }),
|
|
190
|
+
/* @__PURE__ */ jsxs("label", { style: { fontSize: "0.75rem", display: "flex", alignItems: "center", gap: "0.25rem", cursor: "pointer" }, children: [
|
|
191
|
+
/* @__PURE__ */ jsx(
|
|
192
|
+
"input",
|
|
193
|
+
{
|
|
194
|
+
type: "checkbox",
|
|
195
|
+
checked: authorityOnly,
|
|
196
|
+
onChange: (e) => {
|
|
197
|
+
setAuthorityOnly(e.target.checked);
|
|
198
|
+
setPage(1);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
),
|
|
202
|
+
"Authority only"
|
|
203
|
+
] })
|
|
204
|
+
] }),
|
|
205
|
+
loading && /* @__PURE__ */ jsx("div", { style: { padding: "1rem", opacity: 0.5 }, children: "Loading corpus..." }),
|
|
206
|
+
error && /* @__PURE__ */ jsxs("div", { style: { padding: "1rem", color: "#ef4444" }, children: [
|
|
207
|
+
"Error: ",
|
|
208
|
+
error.message
|
|
209
|
+
] }),
|
|
210
|
+
data && !loading && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
211
|
+
/* @__PURE__ */ jsxs("div", { style: { fontSize: "0.8rem", opacity: 0.6, marginBottom: "0.75rem" }, children: [
|
|
212
|
+
data.pagination.totalCount,
|
|
213
|
+
" tweets",
|
|
214
|
+
data.pagination.totalPages > 1 && ` \u2014 page ${data.pagination.page} of ${data.pagination.totalPages}`
|
|
215
|
+
] }),
|
|
216
|
+
data.items.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: "2rem", textAlign: "center", opacity: 0.5 }, children: "No tweets match the current filters." }) : /* @__PURE__ */ jsx("div", { style: { display: "grid", gap: "0.5rem" }, children: data.items.map((tweet) => /* @__PURE__ */ jsx(TweetCard, { tweet }, tweet.tweet_id)) }),
|
|
217
|
+
data.pagination.totalPages > 1 && /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "center", gap: "0.5rem", marginTop: "1rem" }, children: [
|
|
218
|
+
/* @__PURE__ */ jsx(
|
|
219
|
+
"button",
|
|
220
|
+
{
|
|
221
|
+
onClick: () => setPage((p) => Math.max(1, p - 1)),
|
|
222
|
+
disabled: page <= 1,
|
|
223
|
+
style: {
|
|
224
|
+
padding: "0.3rem 0.75rem",
|
|
225
|
+
fontSize: "0.8rem",
|
|
226
|
+
border: "1px solid currentColor",
|
|
227
|
+
borderRadius: "3px",
|
|
228
|
+
background: "transparent",
|
|
229
|
+
color: "inherit",
|
|
230
|
+
cursor: page <= 1 ? "default" : "pointer",
|
|
231
|
+
opacity: page <= 1 ? 0.3 : 0.7
|
|
232
|
+
},
|
|
233
|
+
children: "Previous"
|
|
234
|
+
}
|
|
235
|
+
),
|
|
236
|
+
/* @__PURE__ */ jsxs("span", { style: { fontSize: "0.8rem", lineHeight: "1.8rem" }, children: [
|
|
237
|
+
page,
|
|
238
|
+
" / ",
|
|
239
|
+
data.pagination.totalPages
|
|
240
|
+
] }),
|
|
241
|
+
/* @__PURE__ */ jsx(
|
|
242
|
+
"button",
|
|
243
|
+
{
|
|
244
|
+
onClick: () => setPage((p) => Math.min(data.pagination.totalPages, p + 1)),
|
|
245
|
+
disabled: page >= data.pagination.totalPages,
|
|
246
|
+
style: {
|
|
247
|
+
padding: "0.3rem 0.75rem",
|
|
248
|
+
fontSize: "0.8rem",
|
|
249
|
+
border: "1px solid currentColor",
|
|
250
|
+
borderRadius: "3px",
|
|
251
|
+
background: "transparent",
|
|
252
|
+
color: "inherit",
|
|
253
|
+
cursor: page >= data.pagination.totalPages ? "default" : "pointer",
|
|
254
|
+
opacity: page >= data.pagination.totalPages ? 0.3 : 0.7
|
|
255
|
+
},
|
|
256
|
+
children: "Next"
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
] })
|
|
260
|
+
] })
|
|
261
|
+
] });
|
|
262
|
+
}
|
|
263
|
+
function SettingsPage() {
|
|
264
|
+
const { data, loading, error } = usePluginData("plugin-config");
|
|
265
|
+
if (loading) return /* @__PURE__ */ jsx("div", { children: "Loading settings..." });
|
|
266
|
+
if (error) return /* @__PURE__ */ jsxs("div", { children: [
|
|
267
|
+
"Error: ",
|
|
268
|
+
error.message
|
|
269
|
+
] });
|
|
270
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "1rem" }, children: [
|
|
271
|
+
/* @__PURE__ */ jsx("h2", { children: "X Intelligence Settings" }),
|
|
272
|
+
/* @__PURE__ */ jsx("p", { style: { opacity: 0.5 }, children: "Configure authority lists, scoring weights, and discovery topics via the plugin configuration panel." }),
|
|
273
|
+
/* @__PURE__ */ jsx("pre", { style: { background: "rgba(128,128,128,0.1)", padding: "1rem", borderRadius: "4px", overflow: "auto", fontSize: "0.8rem" }, children: JSON.stringify(data, null, 2) })
|
|
274
|
+
] });
|
|
275
|
+
}
|
|
70
276
|
function StatCard({ label, value }) {
|
|
71
277
|
return /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: "0.5rem", background: "rgba(128,128,128,0.1)", borderRadius: "4px" }, children: [
|
|
72
278
|
/* @__PURE__ */ jsx("div", { style: { fontSize: "1.1rem", fontWeight: 600 }, children: value }),
|
|
73
279
|
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.7rem", opacity: 0.5 }, children: label })
|
|
74
280
|
] });
|
|
75
281
|
}
|
|
76
|
-
function TweetCard({ tweet }) {
|
|
282
|
+
function TweetCard({ tweet, compact }) {
|
|
283
|
+
const totalEngagement = tweet.metrics.like_count + tweet.metrics.retweet_count + tweet.metrics.reply_count + tweet.metrics.quote_count;
|
|
284
|
+
const ratingCount = tweet.ratings?.length ?? 0;
|
|
77
285
|
return /* @__PURE__ */ jsxs(
|
|
78
286
|
"div",
|
|
79
287
|
{
|
|
80
288
|
style: {
|
|
81
|
-
padding: "0.4rem",
|
|
82
|
-
marginBottom: "0.25rem",
|
|
289
|
+
padding: compact ? "0.4rem" : "0.6rem",
|
|
290
|
+
marginBottom: compact ? "0.25rem" : 0,
|
|
83
291
|
background: "rgba(128,128,128,0.1)",
|
|
84
292
|
borderRadius: "4px",
|
|
85
|
-
fontSize: "0.8rem"
|
|
293
|
+
fontSize: compact ? "0.8rem" : "0.85rem"
|
|
86
294
|
},
|
|
87
295
|
children: [
|
|
88
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
|
|
296
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
|
|
89
297
|
/* @__PURE__ */ jsxs("span", { style: { fontWeight: 600 }, children: [
|
|
90
298
|
"@",
|
|
91
299
|
tweet.author_username,
|
|
92
|
-
tweet.is_authority && /* @__PURE__ */ jsx("span", { style: { color: "#2563eb", marginLeft: "0.25rem" }, title: "Authority handle", children: "*" })
|
|
300
|
+
tweet.is_authority && /* @__PURE__ */ jsx("span", { style: { color: "#2563eb", marginLeft: "0.25rem" }, title: "Authority handle", children: "*" }),
|
|
301
|
+
!compact && tweet.author_verified_type && /* @__PURE__ */ jsx("span", { style: { color: "#9333ea", marginLeft: "0.25rem", fontSize: "0.7rem" }, title: `Verified: ${tweet.author_verified_type}`, children: "V" })
|
|
93
302
|
] }),
|
|
94
|
-
/* @__PURE__ */ jsx("span", { style: { opacity: 0.5 }, children: tweet.score.toFixed(2) })
|
|
303
|
+
/* @__PURE__ */ jsx("span", { style: { opacity: 0.5, fontSize: "0.75rem" }, children: tweet.score.toFixed(2) })
|
|
95
304
|
] }),
|
|
96
|
-
/* @__PURE__ */ jsx("div", { style: { opacity: 0.7, marginTop: "0.15rem" }, children: tweet.text.length > 120 ? `${tweet.text.slice(0, 120)}...` : tweet.text })
|
|
305
|
+
/* @__PURE__ */ jsx("div", { style: { opacity: 0.7, marginTop: "0.15rem" }, children: compact ? tweet.text.length > 120 ? `${tweet.text.slice(0, 120)}...` : tweet.text : tweet.text.length > 280 ? `${tweet.text.slice(0, 280)}...` : tweet.text }),
|
|
306
|
+
!compact && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.75rem", marginTop: "0.4rem", fontSize: "0.7rem", opacity: 0.5 }, children: [
|
|
307
|
+
/* @__PURE__ */ jsxs("span", { title: "Relevance / Recency / Engagement", children: [
|
|
308
|
+
"Scores: ",
|
|
309
|
+
tweet.relevance_score.toFixed(2),
|
|
310
|
+
" / ",
|
|
311
|
+
tweet.recency_score.toFixed(2),
|
|
312
|
+
" / ",
|
|
313
|
+
tweet.engagement_score.toFixed(2)
|
|
314
|
+
] }),
|
|
315
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
316
|
+
tweet.metrics.like_count,
|
|
317
|
+
"L ",
|
|
318
|
+
tweet.metrics.retweet_count,
|
|
319
|
+
"RT ",
|
|
320
|
+
tweet.metrics.reply_count,
|
|
321
|
+
"Re ",
|
|
322
|
+
tweet.metrics.quote_count,
|
|
323
|
+
"Q (",
|
|
324
|
+
totalEngagement,
|
|
325
|
+
" total)"
|
|
326
|
+
] }),
|
|
327
|
+
tweet.author_followers_count > 0 && /* @__PURE__ */ jsxs("span", { children: [
|
|
328
|
+
tweet.author_followers_count.toLocaleString(),
|
|
329
|
+
" followers"
|
|
330
|
+
] }),
|
|
331
|
+
ratingCount > 0 && /* @__PURE__ */ jsxs("span", { children: [
|
|
332
|
+
ratingCount,
|
|
333
|
+
" rating",
|
|
334
|
+
ratingCount > 1 ? "s" : ""
|
|
335
|
+
] }),
|
|
336
|
+
/* @__PURE__ */ jsx("span", { children: tweet.source }),
|
|
337
|
+
/* @__PURE__ */ jsx(
|
|
338
|
+
"a",
|
|
339
|
+
{
|
|
340
|
+
href: `https://x.com/i/status/${tweet.tweet_id}`,
|
|
341
|
+
target: "_blank",
|
|
342
|
+
rel: "noopener noreferrer",
|
|
343
|
+
style: { color: "#2563eb", textDecoration: "none" },
|
|
344
|
+
children: "View on X"
|
|
345
|
+
}
|
|
346
|
+
)
|
|
347
|
+
] })
|
|
97
348
|
]
|
|
98
349
|
}
|
|
99
350
|
);
|
|
100
351
|
}
|
|
101
|
-
function SettingsPage() {
|
|
102
|
-
const { data, loading, error } = usePluginData("plugin-config");
|
|
103
|
-
if (loading) return /* @__PURE__ */ jsx("div", { children: "Loading settings..." });
|
|
104
|
-
if (error) return /* @__PURE__ */ jsxs("div", { children: [
|
|
105
|
-
"Error: ",
|
|
106
|
-
error.message
|
|
107
|
-
] });
|
|
108
|
-
return /* @__PURE__ */ jsxs("div", { style: { padding: "1rem" }, children: [
|
|
109
|
-
/* @__PURE__ */ jsx("h2", { children: "X Intelligence Settings" }),
|
|
110
|
-
/* @__PURE__ */ jsx("p", { style: { opacity: 0.5 }, children: "Configure authority lists, scoring weights, and discovery topics via the plugin configuration panel." }),
|
|
111
|
-
/* @__PURE__ */ jsx("pre", { style: { background: "rgba(128,128,128,0.1)", padding: "1rem", borderRadius: "4px", overflow: "auto", fontSize: "0.8rem" }, children: JSON.stringify(data, null, 2) })
|
|
112
|
-
] });
|
|
113
|
-
}
|
|
114
352
|
export {
|
|
353
|
+
CorpusBrowserPage,
|
|
115
354
|
DashboardWidget,
|
|
116
355
|
SettingsPage
|
|
117
356
|
};
|
package/dist/ui/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/ui/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import { usePluginAction, usePluginData, type PluginWidgetProps } from \"@paperclipai/plugin-sdk/ui\";\nimport type { CorpusSummary, ScoredTweet } from \"../types.js\";\n\ntype DashboardData = {\n today: CorpusSummary | null;\n lastRun: { date: string; corpusSize: number; generatedAt: string } | null;\n trackedHandles: number;\n};\n\nexport function DashboardWidget(_props: PluginWidgetProps) {\n const { data, loading, error } = usePluginData<DashboardData>(\"dashboard-summary\");\n const triggerDiscovery = usePluginAction(\"trigger-discovery\");\n\n if (loading) return <div style={{ padding: \"1rem\" }}>Loading X Intelligence...</div>;\n if (error) return <div style={{ padding: \"1rem\", color: \"#ef4444\" }}>Error: {error.message}</div>;\n\n const summary = data?.today;\n const lastRun = data?.lastRun;\n\n return (\n <div style={{ display: \"grid\", gap: \"0.75rem\", padding: \"0.5rem\" }}>\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}>\n <strong>X Intelligence</strong>\n <span style={{ fontSize: \"0.75rem\", opacity: 0.5 }}>\n {lastRun ? `Last run: ${lastRun.date}` : \"No runs yet\"}\n </span>\n </div>\n\n {summary ? (\n <>\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr 1fr\", gap: \"0.5rem\" }}>\n <StatCard label=\"Tweets\" value={summary.total_tweets} />\n <StatCard label=\"Handles\" value={data?.trackedHandles ?? 0} />\n <StatCard\n label=\"Cost\"\n value={`$${(\n summary.discovery_stats.xai_cost_estimate +\n summary.discovery_stats.x_api_cost_estimate\n ).toFixed(2)}`}\n />\n </div>\n\n <div style={{ fontSize: \"0.8rem\" }}>\n <div>\n Queries: {summary.discovery_stats.open_queries} open + {summary.discovery_stats.focused_queries} focused\n </div>\n <div>\n New handles: {summary.discovery_stats.new_handles_discovered} | Promoted: {summary.discovery_stats.handles_promoted}\n </div>\n </div>\n\n {summary.top_items.length > 0 && (\n <div>\n <div style={{ fontSize: \"0.75rem\", fontWeight: 600, marginBottom: \"0.25rem\" }}>Top Items</div>\n {summary.top_items.slice(0, 3).map((tweet) => (\n <TweetCard key={tweet.tweet_id} tweet={tweet} />\n ))}\n </div>\n )}\n </>\n ) : (\n <div style={{ opacity: 0.5, fontSize: \"0.85rem\" }}>\n No corpus for today. Discovery runs daily at 6:00 AM UTC.\n </div>\n )}\n\n <button\n onClick={() => void triggerDiscovery()}\n style={{\n padding: \"0.4rem 0.75rem\",\n fontSize: \"0.8rem\",\n border: \"1px solid currentColor\",\n borderRadius: \"4px\",\n background: \"transparent\",\n color: \"inherit\",\n opacity: 0.7,\n cursor: \"pointer\",\n }}\n >\n Trigger Discovery\n </button>\n </div>\n );\n}\n\nfunction StatCard({ label, value }: { label: string; value: string | number }) {\n return (\n <div style={{ textAlign: \"center\", padding: \"0.5rem\", background: \"rgba(128,128,128,0.1)\", borderRadius: \"4px\" }}>\n <div style={{ fontSize: \"1.1rem\", fontWeight: 600 }}>{value}</div>\n <div style={{ fontSize: \"0.7rem\", opacity: 0.5 }}>{label}</div>\n </div>\n );\n}\n\nfunction TweetCard({ tweet }: { tweet: ScoredTweet }) {\n return (\n <div\n style={{\n padding: \"0.4rem\",\n marginBottom: \"0.25rem\",\n background: \"rgba(128,128,128,0.1)\",\n borderRadius: \"4px\",\n fontSize: \"0.8rem\",\n }}\n >\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <span style={{ fontWeight: 600 }}>\n @{tweet.author_username}\n {tweet.is_authority && (\n <span style={{ color: \"#2563eb\", marginLeft: \"0.25rem\" }} title=\"Authority handle\">\n *\n </span>\n )}\n </span>\n <span style={{ opacity: 0.5 }}>{tweet.score.toFixed(2)}</span>\n </div>\n <div style={{ opacity: 0.7, marginTop: \"0.15rem\" }}>\n {tweet.text.length > 120 ? `${tweet.text.slice(0, 120)}...` : tweet.text}\n </div>\n </div>\n );\n}\n\nexport function SettingsPage() {\n const { data, loading, error } = usePluginData<Record<string, unknown>>(\"plugin-config\");\n\n if (loading) return <div>Loading settings...</div>;\n if (error) return <div>Error: {error.message}</div>;\n\n return (\n <div style={{ padding: \"1rem\" }}>\n <h2>X Intelligence Settings</h2>\n <p style={{ opacity: 0.5 }}>\n Configure authority lists, scoring weights, and discovery topics via the plugin configuration panel.\n </p>\n <pre style={{ background: \"rgba(128,128,128,0.1)\", padding: \"1rem\", borderRadius: \"4px\", overflow: \"auto\", fontSize: \"0.8rem\" }}>\n {JSON.stringify(data, null, 2)}\n </pre>\n </div>\n );\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,iBAAiB,
|
|
4
|
+
"sourcesContent": ["import { usePluginAction, usePluginData, type PluginWidgetProps, type PluginPageProps } from \"@paperclipai/plugin-sdk/ui\";\nimport { useState } from \"react\";\nimport type { CorpusSummary, ScoredTweet, CorpusBrowserData } from \"../types.js\";\n\ntype DashboardData = {\n today: CorpusSummary | null;\n lastRun: { date: string; corpusSize: number; generatedAt: string } | null;\n trackedHandles: number;\n};\n\nexport function DashboardWidget(_props: PluginWidgetProps) {\n const { data, loading, error } = usePluginData<DashboardData>(\"dashboard-summary\");\n const triggerDiscovery = usePluginAction(\"trigger-discovery\");\n\n if (loading) return <div style={{ padding: \"1rem\" }}>Loading X Intelligence...</div>;\n if (error) return <div style={{ padding: \"1rem\", color: \"#ef4444\" }}>Error: {error.message}</div>;\n\n const summary = data?.today;\n const lastRun = data?.lastRun;\n\n return (\n <div style={{ display: \"grid\", gap: \"0.75rem\", padding: \"0.5rem\" }}>\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}>\n <strong>X Intelligence</strong>\n <span style={{ fontSize: \"0.75rem\", opacity: 0.5 }}>\n {lastRun ? `Last run: ${lastRun.date}` : \"No runs yet\"}\n </span>\n </div>\n\n {summary ? (\n <>\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr 1fr\", gap: \"0.5rem\" }}>\n <StatCard label=\"Tweets\" value={summary.total_tweets} />\n <StatCard label=\"Handles\" value={data?.trackedHandles ?? 0} />\n <StatCard\n label=\"Cost\"\n value={`$${(\n summary.discovery_stats.xai_cost_estimate +\n summary.discovery_stats.x_api_cost_estimate\n ).toFixed(2)}`}\n />\n </div>\n\n <div style={{ fontSize: \"0.8rem\" }}>\n <div>\n Queries: {summary.discovery_stats.open_queries} open + {summary.discovery_stats.focused_queries} focused\n </div>\n <div>\n New handles: {summary.discovery_stats.new_handles_discovered} | Promoted: {summary.discovery_stats.handles_promoted}\n </div>\n </div>\n\n {summary.top_items.length > 0 && (\n <div>\n <div style={{ fontSize: \"0.75rem\", fontWeight: 600, marginBottom: \"0.25rem\" }}>Top Items</div>\n {summary.top_items.slice(0, 3).map((tweet) => (\n <TweetCard key={tweet.tweet_id} tweet={tweet} compact />\n ))}\n </div>\n )}\n </>\n ) : (\n <div style={{ opacity: 0.5, fontSize: \"0.85rem\" }}>\n No corpus for today. Discovery runs daily at 6:00 AM UTC.\n </div>\n )}\n\n <button\n onClick={() => void triggerDiscovery()}\n style={{\n padding: \"0.4rem 0.75rem\",\n fontSize: \"0.8rem\",\n border: \"1px solid currentColor\",\n borderRadius: \"4px\",\n background: \"transparent\",\n color: \"inherit\",\n opacity: 0.7,\n cursor: \"pointer\",\n }}\n >\n Trigger Discovery\n </button>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Corpus Browser Page\n// ---------------------------------------------------------------------------\n\nexport function CorpusBrowserPage(_props: PluginPageProps) {\n const todayStr = new Date().toISOString().split(\"T\")[0]!;\n const [date, setDate] = useState(todayStr);\n const [pillar, setPillar] = useState(\"\");\n const [minScore, setMinScore] = useState(0);\n const [minEngagement, setMinEngagement] = useState(0);\n const [authorityOnly, setAuthorityOnly] = useState(false);\n const [page, setPage] = useState(1);\n\n const params: Record<string, unknown> = {\n date,\n page,\n page_size: 25,\n };\n if (pillar) params.pillar = pillar;\n if (minScore > 0) params.min_score = minScore;\n if (minEngagement > 0) params.min_engagement = minEngagement;\n if (authorityOnly) params.authority_only = true;\n\n const { data, loading, error } = usePluginData<CorpusBrowserData>(\"corpus-browser\", params);\n\n return (\n <div style={{ padding: \"1.5rem\", maxWidth: \"960px\", margin: \"0 auto\" }}>\n <h2 style={{ margin: \"0 0 1rem\" }}>X Intelligence Corpus</h2>\n\n {/* Filter bar */}\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"0.5rem\", marginBottom: \"1rem\", alignItems: \"center\" }}>\n {/* Date buttons */}\n <div style={{ display: \"flex\", gap: \"0.25rem\" }}>\n {(data?.available_dates ?? [todayStr]).slice(0, 7).map((d) => (\n <button\n key={d}\n onClick={() => { setDate(d); setPage(1); }}\n style={{\n padding: \"0.25rem 0.5rem\",\n fontSize: \"0.75rem\",\n border: \"1px solid currentColor\",\n borderRadius: \"3px\",\n background: d === date ? \"rgba(128,128,128,0.25)\" : \"transparent\",\n color: \"inherit\",\n cursor: \"pointer\",\n fontWeight: d === date ? 600 : 400,\n }}\n >\n {d === todayStr ? \"Today\" : d.slice(5)}\n </button>\n ))}\n </div>\n\n {/* Pillar filter */}\n <select\n value={pillar}\n onChange={(e) => { setPillar(e.target.value); setPage(1); }}\n style={{\n padding: \"0.25rem 0.5rem\",\n fontSize: \"0.75rem\",\n border: \"1px solid currentColor\",\n borderRadius: \"3px\",\n background: \"transparent\",\n color: \"inherit\",\n }}\n >\n <option value=\"\">All pillars</option>\n {(data?.available_pillars ?? []).map((p) => (\n <option key={p} value={p}>{p}</option>\n ))}\n </select>\n\n {/* Score threshold */}\n <label style={{ fontSize: \"0.75rem\", display: \"flex\", alignItems: \"center\", gap: \"0.25rem\" }}>\n Score {\">\"}=\n <input\n type=\"number\"\n min={0}\n max={1}\n step={0.1}\n value={minScore}\n onChange={(e) => { setMinScore(parseFloat(e.target.value) || 0); setPage(1); }}\n style={{\n width: \"3.5rem\",\n padding: \"0.2rem 0.35rem\",\n fontSize: \"0.75rem\",\n border: \"1px solid currentColor\",\n borderRadius: \"3px\",\n background: \"transparent\",\n color: \"inherit\",\n }}\n />\n </label>\n\n {/* Engagement threshold */}\n <label style={{ fontSize: \"0.75rem\", display: \"flex\", alignItems: \"center\", gap: \"0.25rem\" }}>\n Engmt {\">\"}=\n <input\n type=\"number\"\n min={0}\n step={10}\n value={minEngagement}\n onChange={(e) => { setMinEngagement(parseInt(e.target.value) || 0); setPage(1); }}\n style={{\n width: \"3.5rem\",\n padding: \"0.2rem 0.35rem\",\n fontSize: \"0.75rem\",\n border: \"1px solid currentColor\",\n borderRadius: \"3px\",\n background: \"transparent\",\n color: \"inherit\",\n }}\n />\n </label>\n\n {/* Authority only toggle */}\n <label style={{ fontSize: \"0.75rem\", display: \"flex\", alignItems: \"center\", gap: \"0.25rem\", cursor: \"pointer\" }}>\n <input\n type=\"checkbox\"\n checked={authorityOnly}\n onChange={(e) => { setAuthorityOnly(e.target.checked); setPage(1); }}\n />\n Authority only\n </label>\n </div>\n\n {/* Loading / Error */}\n {loading && <div style={{ padding: \"1rem\", opacity: 0.5 }}>Loading corpus...</div>}\n {error && <div style={{ padding: \"1rem\", color: \"#ef4444\" }}>Error: {error.message}</div>}\n\n {/* Results */}\n {data && !loading && (\n <>\n <div style={{ fontSize: \"0.8rem\", opacity: 0.6, marginBottom: \"0.75rem\" }}>\n {data.pagination.totalCount} tweets\n {data.pagination.totalPages > 1 && ` \u2014 page ${data.pagination.page} of ${data.pagination.totalPages}`}\n </div>\n\n {data.items.length === 0 ? (\n <div style={{ padding: \"2rem\", textAlign: \"center\", opacity: 0.5 }}>\n No tweets match the current filters.\n </div>\n ) : (\n <div style={{ display: \"grid\", gap: \"0.5rem\" }}>\n {data.items.map((tweet) => (\n <TweetCard key={tweet.tweet_id} tweet={tweet} />\n ))}\n </div>\n )}\n\n {/* Pagination */}\n {data.pagination.totalPages > 1 && (\n <div style={{ display: \"flex\", justifyContent: \"center\", gap: \"0.5rem\", marginTop: \"1rem\" }}>\n <button\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n disabled={page <= 1}\n style={{\n padding: \"0.3rem 0.75rem\",\n fontSize: \"0.8rem\",\n border: \"1px solid currentColor\",\n borderRadius: \"3px\",\n background: \"transparent\",\n color: \"inherit\",\n cursor: page <= 1 ? \"default\" : \"pointer\",\n opacity: page <= 1 ? 0.3 : 0.7,\n }}\n >\n Previous\n </button>\n <span style={{ fontSize: \"0.8rem\", lineHeight: \"1.8rem\" }}>\n {page} / {data.pagination.totalPages}\n </span>\n <button\n onClick={() => setPage((p) => Math.min(data.pagination.totalPages, p + 1))}\n disabled={page >= data.pagination.totalPages}\n style={{\n padding: \"0.3rem 0.75rem\",\n fontSize: \"0.8rem\",\n border: \"1px solid currentColor\",\n borderRadius: \"3px\",\n background: \"transparent\",\n color: \"inherit\",\n cursor: page >= data.pagination.totalPages ? \"default\" : \"pointer\",\n opacity: page >= data.pagination.totalPages ? 0.3 : 0.7,\n }}\n >\n Next\n </button>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Settings page\n// ---------------------------------------------------------------------------\n\nexport function SettingsPage() {\n const { data, loading, error } = usePluginData<Record<string, unknown>>(\"plugin-config\");\n\n if (loading) return <div>Loading settings...</div>;\n if (error) return <div>Error: {error.message}</div>;\n\n return (\n <div style={{ padding: \"1rem\" }}>\n <h2>X Intelligence Settings</h2>\n <p style={{ opacity: 0.5 }}>\n Configure authority lists, scoring weights, and discovery topics via the plugin configuration panel.\n </p>\n <pre style={{ background: \"rgba(128,128,128,0.1)\", padding: \"1rem\", borderRadius: \"4px\", overflow: \"auto\", fontSize: \"0.8rem\" }}>\n {JSON.stringify(data, null, 2)}\n </pre>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Shared components\n// ---------------------------------------------------------------------------\n\nfunction StatCard({ label, value }: { label: string; value: string | number }) {\n return (\n <div style={{ textAlign: \"center\", padding: \"0.5rem\", background: \"rgba(128,128,128,0.1)\", borderRadius: \"4px\" }}>\n <div style={{ fontSize: \"1.1rem\", fontWeight: 600 }}>{value}</div>\n <div style={{ fontSize: \"0.7rem\", opacity: 0.5 }}>{label}</div>\n </div>\n );\n}\n\nfunction TweetCard({ tweet, compact }: { tweet: ScoredTweet; compact?: boolean }) {\n const totalEngagement = tweet.metrics.like_count + tweet.metrics.retweet_count + tweet.metrics.reply_count + tweet.metrics.quote_count;\n const ratingCount = tweet.ratings?.length ?? 0;\n\n return (\n <div\n style={{\n padding: compact ? \"0.4rem\" : \"0.6rem\",\n marginBottom: compact ? \"0.25rem\" : 0,\n background: \"rgba(128,128,128,0.1)\",\n borderRadius: \"4px\",\n fontSize: compact ? \"0.8rem\" : \"0.85rem\",\n }}\n >\n {/* Header */}\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}>\n <span style={{ fontWeight: 600 }}>\n @{tweet.author_username}\n {tweet.is_authority && (\n <span style={{ color: \"#2563eb\", marginLeft: \"0.25rem\" }} title=\"Authority handle\">*</span>\n )}\n {!compact && tweet.author_verified_type && (\n <span style={{ color: \"#9333ea\", marginLeft: \"0.25rem\", fontSize: \"0.7rem\" }} title={`Verified: ${tweet.author_verified_type}`}>V</span>\n )}\n </span>\n <span style={{ opacity: 0.5, fontSize: \"0.75rem\" }}>{tweet.score.toFixed(2)}</span>\n </div>\n\n {/* Text */}\n <div style={{ opacity: 0.7, marginTop: \"0.15rem\" }}>\n {compact\n ? (tweet.text.length > 120 ? `${tweet.text.slice(0, 120)}...` : tweet.text)\n : (tweet.text.length > 280 ? `${tweet.text.slice(0, 280)}...` : tweet.text)\n }\n </div>\n\n {/* Extended info (non-compact) */}\n {!compact && (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"0.75rem\", marginTop: \"0.4rem\", fontSize: \"0.7rem\", opacity: 0.5 }}>\n {/* Score breakdown */}\n <span title=\"Relevance / Recency / Engagement\">\n Scores: {tweet.relevance_score.toFixed(2)} / {tweet.recency_score.toFixed(2)} / {tweet.engagement_score.toFixed(2)}\n </span>\n\n {/* Engagement metrics */}\n <span>\n {tweet.metrics.like_count}L {tweet.metrics.retweet_count}RT {tweet.metrics.reply_count}Re {tweet.metrics.quote_count}Q\n ({totalEngagement} total)\n </span>\n\n {/* Followers */}\n {tweet.author_followers_count > 0 && (\n <span>{tweet.author_followers_count.toLocaleString()} followers</span>\n )}\n\n {/* Ratings */}\n {ratingCount > 0 && (\n <span>{ratingCount} rating{ratingCount > 1 ? \"s\" : \"\"}</span>\n )}\n\n {/* Source */}\n <span>{tweet.source}</span>\n\n {/* Link to original tweet */}\n <a\n href={`https://x.com/i/status/${tweet.tweet_id}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: \"#2563eb\", textDecoration: \"none\" }}\n >\n View on X\n </a>\n </div>\n )}\n </div>\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|