birdclaw 0.9.0 → 0.9.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/CHANGELOG.md +16 -0
- package/README.md +3 -1
- package/dist/cli/birdclaw.js +189 -17
- package/dist/client/assets/AvatarChip-BN3b4MhM.js +1 -0
- package/dist/client/assets/ProfilePreview-CHbT0U9a.js +1 -0
- package/dist/client/assets/SavedTimelineView-mGXE9EYJ.js +1 -0
- package/dist/client/assets/SmartTimestamp-DG8XJKUz.js +1 -0
- package/dist/client/assets/TimelineRouteFrame-BmMC7qLj.js +1 -0
- package/dist/client/assets/blocks-CawnB0mN.js +1 -0
- package/dist/client/assets/{bookmarks-Cprrli-V.js → bookmarks-DZIMTKEp.js} +1 -1
- package/dist/client/assets/chunk-C0phanGV.js +1 -0
- package/dist/client/assets/circle-check-C_Vq3ElD.js +1 -0
- package/dist/client/assets/{client-stream-contracts-D1QUdWfh.js → client-stream-contracts-DcKcyZhg.js} +1 -1
- package/dist/client/assets/createLucideIcon-JV8isFFR.js +1 -0
- package/dist/client/assets/data-sources-BJUT2qaO.js +1 -0
- package/dist/client/assets/discuss-DMPJVaRk.js +1 -0
- package/dist/client/assets/dms-BfPFG4Qr.js +1 -0
- package/dist/client/assets/inbox-DmeYJ7tt.js +1 -0
- package/dist/client/assets/index-Bqmo4MbK.js +31 -0
- package/dist/client/assets/likes-BxVL-j_C.js +1 -0
- package/dist/client/assets/links-BeA1Wt8F.js +1 -0
- package/dist/client/assets/mapbox-BTSMNSry.js +2 -0
- package/dist/client/assets/{mapbox-gl-WUhsQcSS.js → mapbox-gl-CPemBIlO.js} +1 -1
- package/dist/client/assets/{mentions-C3JYXV2K.js → mentions-DBrY-UPg.js} +1 -1
- package/dist/client/assets/network-map-MqbE164r.js +2 -0
- package/dist/client/assets/profile-analyze-DEA75Reh.js +1 -0
- package/dist/client/assets/{profile-hydration-client-BQyC5--e.js → profile-hydration-client-BNe0sUmK.js} +1 -1
- package/dist/client/assets/profiles._handle-K34ofz9U.js +1 -0
- package/dist/client/assets/query-client-DUP1ZzP7.js +17 -0
- package/dist/client/assets/rate-limits-B8Wmpt9r.js +1 -0
- package/dist/client/assets/react-dom-DHl6Ug7F.js +1 -0
- package/dist/client/assets/react-nBylq1U5.js +1 -0
- package/dist/client/assets/{repeat-2-CQ0lek01.js → repeat-2-xCwHM9hD.js} +1 -1
- package/dist/client/assets/{routes-CeIv5bkV.js → routes-Bl-Lw2hN.js} +1 -1
- package/dist/client/assets/schemas-CaALBBpc.js +64 -0
- package/dist/client/assets/search-Dq5kYsxA.js +1 -0
- package/dist/client/assets/{sparkles-Gx_BHkDX.js → sparkles-CQVlvHsZ.js} +1 -1
- package/dist/client/assets/{styles-DTMajAmk.css → styles-zihNNCGg.css} +2 -2
- package/dist/client/assets/today-DFvZ0Ys5.js +1 -0
- package/dist/client/assets/{triangle-alert-DJPCW6jQ.js → triangle-alert-CBL7s2pf.js} +1 -1
- package/dist/client/assets/useTimelineRouteData-Cpf-Jqsx.js +1 -0
- package/dist/client/assets/{users-DI3w8Mol.js → users-CHbKlqUr.js} +1 -1
- package/dist/server/assets/{_tanstack-start-manifest_v-CjYYXQ8Z.js → _tanstack-start-manifest_v-CVfs07C8.js} +35 -35
- package/dist/server/assets/{empty-plugin-adapters-D9UWiqvJ.js → empty-plugin-adapters-DzrEkdBF.js} +1 -1
- package/dist/server/assets/{router-DP7iZD-q.js → router-D8AUR_Gz.js} +114 -38
- package/dist/server/assets/start-FaDOTmto.js +4 -0
- package/dist/server/server.js +3413 -50
- package/package.json +1 -1
- package/dist/client/assets/AvatarChip-C8zELEVt.js +0 -1
- package/dist/client/assets/ProfilePreview-CsiLpFrb.js +0 -1
- package/dist/client/assets/SavedTimelineView-DE4CXK-h.js +0 -1
- package/dist/client/assets/SmartTimestamp-BypN4KPq.js +0 -1
- package/dist/client/assets/TimelineRouteFrame-D6djyMAT.js +0 -1
- package/dist/client/assets/blocks-h27nF3TL.js +0 -1
- package/dist/client/assets/circle-check-BCK_qvXt.js +0 -1
- package/dist/client/assets/createLucideIcon-CMLcIxOz.js +0 -1
- package/dist/client/assets/data-sources-Beb3JZkl.js +0 -1
- package/dist/client/assets/discuss-ciwVz7Fo.js +0 -1
- package/dist/client/assets/dms-BZ3GUPey.js +0 -1
- package/dist/client/assets/inbox-Dajdut79.js +0 -1
- package/dist/client/assets/index-a1ZAcWSa.js +0 -31
- package/dist/client/assets/likes-CxZZqiZC.js +0 -1
- package/dist/client/assets/links-CsWS9uKL.js +0 -1
- package/dist/client/assets/mapbox-dx7h2mOm.js +0 -2
- package/dist/client/assets/network-map-D4XA7TTO.js +0 -2
- package/dist/client/assets/profile-analyze-QAznTMjZ.js +0 -1
- package/dist/client/assets/profiles._handle-qntfbCE1.js +0 -1
- package/dist/client/assets/query-client-DZ5C7UNo.js +0 -17
- package/dist/client/assets/rate-limits-eHs_5dDB.js +0 -1
- package/dist/client/assets/react-BwGzW7mM.js +0 -1
- package/dist/client/assets/react-dom-DEMAB80t.js +0 -1
- package/dist/client/assets/rolldown-runtime-B-9mzPXz.js +0 -1
- package/dist/client/assets/schemas-CntsNLmN.js +0 -64
- package/dist/client/assets/search-C_LqodNa.js +0 -1
- package/dist/client/assets/today-DxppbQGF.js +0 -1
- package/dist/client/assets/useTimelineRouteData-CWvBmHLE.js +0 -1
- package/dist/server/assets/start-5Z2QO8AU.js +0 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.9.2 - 2026-07-04
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Split oversized backup JSONL outputs into deterministic 48 MiB part files and serialize and validate them sequentially, keeping large archives below hosted Git limits without Git LFS.
|
|
8
|
+
|
|
9
|
+
## 0.9.1 - 2026-07-02
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Route inbox scoring and Responses API requests through `BIRDCLAW_OPENAI_BASE_URL`, retain `OPENAI_BASE_URL` as a compatibility fallback, and add opt-in OpenAI transport diagnostics. (#89 - thanks @martintrojer)
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Correct the seeded local account handle, display name, user ID, and stale avatar from the authenticated Bird identity during explicit profile hydration. (#88 - thanks @martintrojer)
|
|
18
|
+
|
|
3
19
|
## 0.9.0 - 2026-07-02
|
|
4
20
|
|
|
5
21
|
### Added
|
package/README.md
CHANGED
|
@@ -233,7 +233,7 @@ birdclaw import archive ~/Downloads/twitter-archive-2025.zip --json
|
|
|
233
233
|
|
|
234
234
|
Don't have an archive yet? Request it from <https://x.com/settings/download_your_data>; X emails a download link when it is ready, which may take a few days. A fresh Birdclaw database needs the archive import to establish account identity before live sync. See [Archive Import → Get an archive](docs/archive.md#get-an-archive).
|
|
235
235
|
|
|
236
|
-
Optional profile hydration can improve bios, follower counts, and avatars, but it performs live X profile reads and can spend API credits on large archives:
|
|
236
|
+
Optional profile hydration through xurl can improve bios, follower counts, and avatars, but it performs live X profile reads and can spend API credits on large archives. In Bird-only mode, the command corrects the seeded local account identity from `bird whoami` without bulk-hydrating imported profiles:
|
|
237
237
|
|
|
238
238
|
```bash
|
|
239
239
|
birdclaw import hydrate-profiles --json
|
|
@@ -598,9 +598,11 @@ data/dms/conversations.jsonl
|
|
|
598
598
|
data/dms/YYYY.jsonl
|
|
599
599
|
data/moderation/blocks.jsonl
|
|
600
600
|
data/moderation/mutes.jsonl
|
|
601
|
+
data/<logical-shard>.part-NNNN.jsonl
|
|
601
602
|
```
|
|
602
603
|
|
|
603
604
|
Tweets are sharded by year for human browsing and yearly analysis. Collection-only tweets whose real creation date is unknown go into `data/tweets/unknown.jsonl` instead of pretending they belong to 1970. Timeline membership is stored in `data/timeline_edges`; likes and bookmarks are stored as account-scoped collection edges in `data/collections`. DMs are sharded by year with `conversation_id` in each row; this keeps Git fast while preserving conversation membership.
|
|
605
|
+
Any logical shard larger than 48 MiB is split into deterministic `.part-0001.jsonl` files. Import and validation accept both numbered parts and the earlier unsplit layout, so large private backups remain ordinary Git repositories without Git LFS.
|
|
604
606
|
|
|
605
607
|
Use `backup sync` when the target is a private Git repo. It pulls first, merge-imports the remote backup into local SQLite, exports the local union back into text shards, commits, and pushes.
|
|
606
608
|
|
package/dist/cli/birdclaw.js
CHANGED
|
@@ -187,6 +187,10 @@ var __test__ = {
|
|
|
187
187
|
};
|
|
188
188
|
|
|
189
189
|
// src/lib/backup-table-codecs.ts
|
|
190
|
+
var BACKUP_SHARD_PART_PATTERN = /\.part-\d{4,}\.jsonl$/u;
|
|
191
|
+
function logicalBackupShardPath(relativePath) {
|
|
192
|
+
return relativePath.replace(BACKUP_SHARD_PART_PATTERN, ".jsonl");
|
|
193
|
+
}
|
|
190
194
|
function fixedShard(relativePath, countKey) {
|
|
191
195
|
return {
|
|
192
196
|
shardPath: () => relativePath,
|
|
@@ -1205,7 +1209,8 @@ function adaptLegacyTweetState(schemaVersion, tweets, collections, timelineEdges
|
|
|
1205
1209
|
return { collections: nextCollections, timelineEdges: nextTimelineEdges };
|
|
1206
1210
|
}
|
|
1207
1211
|
function backupCodecForPath(relativePath, codecs = BACKUP_TABLE_CODECS) {
|
|
1208
|
-
const
|
|
1212
|
+
const logicalPath = logicalBackupShardPath(relativePath);
|
|
1213
|
+
const matches = codecs.filter((codec) => codec.matchesPath(logicalPath));
|
|
1209
1214
|
if (matches.length !== 1) {
|
|
1210
1215
|
throw new Error(
|
|
1211
1216
|
matches.length === 0 ? `No backup codec owns path: ${relativePath}` : `Multiple backup codecs own path: ${relativePath}`
|
|
@@ -1234,7 +1239,7 @@ function countBackupFiles(files, codecs = BACKUP_TABLE_CODECS) {
|
|
|
1234
1239
|
for (const file of files) {
|
|
1235
1240
|
if (!file.path.startsWith("data/")) continue;
|
|
1236
1241
|
const codec = backupCodecForPath(file.path, codecs);
|
|
1237
|
-
const key = codec.countKey(file.path);
|
|
1242
|
+
const key = codec.countKey(logicalBackupShardPath(file.path));
|
|
1238
1243
|
counts[key] = (counts[key] ?? 0) + file.rows;
|
|
1239
1244
|
}
|
|
1240
1245
|
return counts;
|
|
@@ -3716,8 +3721,9 @@ function runSubprocessEffect(options) {
|
|
|
3716
3721
|
}
|
|
3717
3722
|
|
|
3718
3723
|
// src/lib/backup.ts
|
|
3719
|
-
var BACKUP_SCHEMA_VERSION =
|
|
3724
|
+
var BACKUP_SCHEMA_VERSION = 4;
|
|
3720
3725
|
var MIN_SUPPORTED_BACKUP_SCHEMA_VERSION = 1;
|
|
3726
|
+
var DEFAULT_MAX_BACKUP_SHARD_BYTES = 48 * 1024 * 1024;
|
|
3721
3727
|
var MANIFEST_PATH = "manifest.json";
|
|
3722
3728
|
var DATA_DIR = "data";
|
|
3723
3729
|
var GITATTRIBUTES_PATH = ".gitattributes";
|
|
@@ -3815,6 +3821,50 @@ function getExportRowSets(db) {
|
|
|
3815
3821
|
function buildShards(db) {
|
|
3816
3822
|
return buildBackupShardsFromRowSets(getExportRowSets(db));
|
|
3817
3823
|
}
|
|
3824
|
+
function normalizeMaxBackupShardBytes(value) {
|
|
3825
|
+
const maxBytes = value ?? DEFAULT_MAX_BACKUP_SHARD_BYTES;
|
|
3826
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) {
|
|
3827
|
+
throw new Error("Backup shard byte limit must be a positive integer");
|
|
3828
|
+
}
|
|
3829
|
+
return maxBytes;
|
|
3830
|
+
}
|
|
3831
|
+
function partPath(relativePath, partNumber) {
|
|
3832
|
+
if (!relativePath.endsWith(".jsonl")) {
|
|
3833
|
+
throw new Error(`Backup shard path must end in .jsonl: ${relativePath}`);
|
|
3834
|
+
}
|
|
3835
|
+
return relativePath.replace(
|
|
3836
|
+
/\.jsonl$/u,
|
|
3837
|
+
`.part-${String(partNumber).padStart(4, "0")}.jsonl`
|
|
3838
|
+
);
|
|
3839
|
+
}
|
|
3840
|
+
function splitJsonlShard(relativePath, rows, maxBytes) {
|
|
3841
|
+
const parts = [];
|
|
3842
|
+
let currentRows = [];
|
|
3843
|
+
let currentBytes = 0;
|
|
3844
|
+
for (const [index, row] of rows.entries()) {
|
|
3845
|
+
const rowBytes = Buffer.byteLength(jsonlStringify(row)) + 1;
|
|
3846
|
+
if (rowBytes > maxBytes) {
|
|
3847
|
+
throw new Error(
|
|
3848
|
+
`Backup row exceeds shard byte limit: ${relativePath}:${index + 1} is ${rowBytes} bytes (limit ${maxBytes})`
|
|
3849
|
+
);
|
|
3850
|
+
}
|
|
3851
|
+
if (currentRows.length > 0 && currentBytes + rowBytes > maxBytes) {
|
|
3852
|
+
parts.push(currentRows);
|
|
3853
|
+
currentRows = [];
|
|
3854
|
+
currentBytes = 0;
|
|
3855
|
+
}
|
|
3856
|
+
currentRows.push(row);
|
|
3857
|
+
currentBytes += rowBytes;
|
|
3858
|
+
}
|
|
3859
|
+
if (currentRows.length > 0) parts.push(currentRows);
|
|
3860
|
+
if (parts.length <= 1) {
|
|
3861
|
+
return [{ relativePath, rows: parts[0] ?? [] }];
|
|
3862
|
+
}
|
|
3863
|
+
return parts.map((partRows, index) => ({
|
|
3864
|
+
relativePath: partPath(relativePath, index + 1),
|
|
3865
|
+
rows: partRows
|
|
3866
|
+
}));
|
|
3867
|
+
}
|
|
3818
3868
|
function writeJsonlFileEffect(repoPath, relativePath, rows) {
|
|
3819
3869
|
return Effect5.gen(function* () {
|
|
3820
3870
|
const fullPath = yield* trySync2(
|
|
@@ -3951,6 +4001,7 @@ data/follow_events.jsonl
|
|
|
3951
4001
|
\`\`\`
|
|
3952
4002
|
|
|
3953
4003
|
Tweets are sharded by creation year. Collection-only tweets whose creation date is unknown live in \`data/tweets/unknown.jsonl\`. Timeline edges keep account-scoped home/mention membership separate from canonical tweet content. DMs are sharded by year and keep \`conversation_id\` in each row.
|
|
4004
|
+
Logical shards larger than 48 MiB are split into deterministic \`.part-0001.jsonl\` files so ordinary Git hosting remains usable without Git LFS.
|
|
3954
4005
|
The links shard stores expanded short URLs and their source tweet/DM occurrences so linked-tweet search can be rebuilt without re-expanding every \`t.co\` URL.
|
|
3955
4006
|
|
|
3956
4007
|
Never commit live tokens, browser cookies, raw SQLite WAL/SHM sidecars, or temporary cache files here.
|
|
@@ -4202,7 +4253,8 @@ function exportBackupEffect({
|
|
|
4202
4253
|
commit = false,
|
|
4203
4254
|
push = false,
|
|
4204
4255
|
message = "archive: update birdclaw backup",
|
|
4205
|
-
validate = true
|
|
4256
|
+
validate = true,
|
|
4257
|
+
maxShardBytes
|
|
4206
4258
|
}) {
|
|
4207
4259
|
return Effect5.gen(function* () {
|
|
4208
4260
|
const resolvedRepoPath = yield* trySync2(() => path2.resolve(repoPath));
|
|
@@ -4216,19 +4268,27 @@ function exportBackupEffect({
|
|
|
4216
4268
|
}
|
|
4217
4269
|
yield* ensureBackupGitattributesEffect(resolvedRepoPath);
|
|
4218
4270
|
yield* ensureBackupReadmeEffect(resolvedRepoPath);
|
|
4271
|
+
const maxBytes = yield* trySync2(
|
|
4272
|
+
() => normalizeMaxBackupShardBytes(maxShardBytes)
|
|
4273
|
+
);
|
|
4219
4274
|
const shards = yield* trySync2(() => buildShards(database));
|
|
4220
4275
|
const shardEntries = yield* trySync2(
|
|
4221
4276
|
() => [...shards.entries()].sort(
|
|
4222
4277
|
([left], [right]) => left.localeCompare(right)
|
|
4223
4278
|
)
|
|
4224
4279
|
);
|
|
4280
|
+
const shardParts = yield* trySync2(
|
|
4281
|
+
() => shardEntries.flatMap(
|
|
4282
|
+
([relativePath, rows]) => splitJsonlShard(relativePath, rows, maxBytes)
|
|
4283
|
+
)
|
|
4284
|
+
);
|
|
4225
4285
|
const expectedPaths = yield* trySync2(
|
|
4226
|
-
() => new Set(
|
|
4286
|
+
() => new Set(shardParts.map(({ relativePath }) => relativePath))
|
|
4227
4287
|
);
|
|
4228
4288
|
const files = yield* Effect5.forEach(
|
|
4229
|
-
|
|
4230
|
-
(
|
|
4231
|
-
{ concurrency:
|
|
4289
|
+
shardParts,
|
|
4290
|
+
({ relativePath, rows }) => writeJsonlFileEffect(resolvedRepoPath, relativePath, rows),
|
|
4291
|
+
{ concurrency: 1 }
|
|
4232
4292
|
);
|
|
4233
4293
|
yield* removeStaleBackupFilesEffect(resolvedRepoPath, expectedPaths);
|
|
4234
4294
|
const counts = yield* trySync2(() => countBackupFiles(files));
|
|
@@ -4416,7 +4476,7 @@ function readBackupImportRowsEffect(resolvedRepoPath, manifest) {
|
|
|
4416
4476
|
});
|
|
4417
4477
|
}
|
|
4418
4478
|
function rowsForManifestPath(manifest, predicate) {
|
|
4419
|
-
return manifest.files.map((file) => file.path).filter(predicate).sort();
|
|
4479
|
+
return manifest.files.map((file) => file.path).filter((relativePath) => predicate(logicalBackupShardPath(relativePath))).sort();
|
|
4420
4480
|
}
|
|
4421
4481
|
function importBackupEffect({
|
|
4422
4482
|
repoPath,
|
|
@@ -4886,7 +4946,7 @@ function validateBackupEffect(repoPath) {
|
|
|
4886
4946
|
}
|
|
4887
4947
|
return { file, errors: fileErrors };
|
|
4888
4948
|
}),
|
|
4889
|
-
{ concurrency:
|
|
4949
|
+
{ concurrency: 1 }
|
|
4890
4950
|
);
|
|
4891
4951
|
const files = [];
|
|
4892
4952
|
for (const result of results) {
|
|
@@ -5043,6 +5103,18 @@ var DEFAULT_DELIMITER_HOLD = 8;
|
|
|
5043
5103
|
function toError3(error) {
|
|
5044
5104
|
return error instanceof Error ? error : new Error(String(error));
|
|
5045
5105
|
}
|
|
5106
|
+
var DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
|
|
5107
|
+
function resolveOpenAIBaseUrl(getEnv2) {
|
|
5108
|
+
const configured = getEnv2("BIRDCLAW_OPENAI_BASE_URL") || getEnv2("OPENAI_BASE_URL");
|
|
5109
|
+
const base = configured?.trim() || DEFAULT_OPENAI_BASE_URL;
|
|
5110
|
+
return base.replace(/\/+$/, "");
|
|
5111
|
+
}
|
|
5112
|
+
function debugLog(getEnv2, message) {
|
|
5113
|
+
if (!getEnv2("BIRDCLAW_DEBUG")) return;
|
|
5114
|
+
if (typeof process === "undefined") return;
|
|
5115
|
+
process.stderr.write(`[birdclaw:openai] ${message}
|
|
5116
|
+
`);
|
|
5117
|
+
}
|
|
5046
5118
|
function createOpenAIStreamState() {
|
|
5047
5119
|
return {
|
|
5048
5120
|
eventBuffer: "",
|
|
@@ -5181,8 +5253,11 @@ function requestOpenAIResponseEffect({
|
|
|
5181
5253
|
if (!apiKey) {
|
|
5182
5254
|
return yield* Effect6.fail(new Error("OPENAI_API_KEY is not set"));
|
|
5183
5255
|
}
|
|
5256
|
+
const baseUrl = resolveOpenAIBaseUrl(runtime.env);
|
|
5257
|
+
const url = `${baseUrl}/responses`;
|
|
5258
|
+
debugLog(runtime.env, `POST ${url}`);
|
|
5184
5259
|
const response = yield* tryPromise(
|
|
5185
|
-
() => runtime.fetch(
|
|
5260
|
+
() => runtime.fetch(url, {
|
|
5186
5261
|
method: "POST",
|
|
5187
5262
|
signal,
|
|
5188
5263
|
headers: {
|
|
@@ -5191,17 +5266,29 @@ function requestOpenAIResponseEffect({
|
|
|
5191
5266
|
},
|
|
5192
5267
|
body: JSON.stringify(body)
|
|
5193
5268
|
})
|
|
5194
|
-
).pipe(
|
|
5269
|
+
).pipe(
|
|
5270
|
+
Effect6.mapError(toError3),
|
|
5271
|
+
Effect6.tapError(
|
|
5272
|
+
(error) => Effect6.sync(
|
|
5273
|
+
() => debugLog(runtime.env, `network error for ${url}: ${error.message}`)
|
|
5274
|
+
)
|
|
5275
|
+
)
|
|
5276
|
+
);
|
|
5195
5277
|
if (!response.ok) {
|
|
5196
5278
|
const text = yield* tryPromise(() => response.text()).pipe(
|
|
5197
5279
|
Effect6.mapError(toError3)
|
|
5198
5280
|
);
|
|
5281
|
+
debugLog(
|
|
5282
|
+
runtime.env,
|
|
5283
|
+
`${url} -> ${String(response.status)} ${text.slice(0, 400)}`
|
|
5284
|
+
);
|
|
5199
5285
|
return yield* Effect6.fail(
|
|
5200
5286
|
new Error(
|
|
5201
5287
|
`OpenAI request failed: ${String(response.status)} ${text.slice(0, 400)}`
|
|
5202
5288
|
)
|
|
5203
5289
|
);
|
|
5204
5290
|
}
|
|
5291
|
+
debugLog(runtime.env, `${url} -> ${String(response.status)} OK`);
|
|
5205
5292
|
return response;
|
|
5206
5293
|
});
|
|
5207
5294
|
}
|
|
@@ -6809,9 +6896,11 @@ function parseBirdWhoami(stdout) {
|
|
|
6809
6896
|
}
|
|
6810
6897
|
return line.match(/^\D*(\d{2,})\D*$/)?.[1];
|
|
6811
6898
|
}).find((value) => Boolean(value));
|
|
6899
|
+
const name = stdout.match(/@[A-Za-z0-9_]{1,15}\s*\(([^)]+)\)/)?.[1]?.trim();
|
|
6812
6900
|
return {
|
|
6813
6901
|
username: usernameMatch[1],
|
|
6814
|
-
...id ? { id } : {}
|
|
6902
|
+
...id ? { id } : {},
|
|
6903
|
+
...name ? { name } : {}
|
|
6815
6904
|
};
|
|
6816
6905
|
}
|
|
6817
6906
|
function getAuthenticatedBirdAccountEffect() {
|
|
@@ -6823,6 +6912,9 @@ function getAuthenticatedBirdAccountEffect() {
|
|
|
6823
6912
|
});
|
|
6824
6913
|
});
|
|
6825
6914
|
}
|
|
6915
|
+
function getAuthenticatedBirdAccount() {
|
|
6916
|
+
return runEffectPromise(getAuthenticatedBirdAccountEffect());
|
|
6917
|
+
}
|
|
6826
6918
|
function listDirectMessagesViaBirdEffect({
|
|
6827
6919
|
maxResults,
|
|
6828
6920
|
inbox = "all",
|
|
@@ -19313,14 +19405,77 @@ function trySync7(try_) {
|
|
|
19313
19405
|
catch: toError11
|
|
19314
19406
|
});
|
|
19315
19407
|
}
|
|
19408
|
+
var SEEDED_ACCOUNT_HANDLE = "steipete";
|
|
19409
|
+
var SEEDED_ACCOUNT_EXTERNAL_USER_ID = "25401953";
|
|
19410
|
+
function hydrateAccountFromBirdEffect() {
|
|
19411
|
+
return Effect34.gen(function* () {
|
|
19412
|
+
const account = yield* tryPromise(() => getAuthenticatedBirdAccount()).pipe(
|
|
19413
|
+
Effect34.catchAll(() => Effect34.succeed(null))
|
|
19414
|
+
);
|
|
19415
|
+
if (!account?.username) return false;
|
|
19416
|
+
const handle = account.username.replace(/^@/, "");
|
|
19417
|
+
const name = account.name?.trim() || null;
|
|
19418
|
+
const externalUserId = account.id ?? null;
|
|
19419
|
+
const hydrated = yield* trySync7(() => {
|
|
19420
|
+
const db = getNativeDb();
|
|
19421
|
+
return db.transaction(() => {
|
|
19422
|
+
const current = db.prepare(
|
|
19423
|
+
`select handle, external_user_id, transport from accounts where id = 'acct_primary'`
|
|
19424
|
+
).get();
|
|
19425
|
+
if (!current) return false;
|
|
19426
|
+
const storedHandle = current?.handle?.replace(/^@/, "") ?? null;
|
|
19427
|
+
const handleMatches = storedHandle?.toLowerCase() === handle.toLowerCase();
|
|
19428
|
+
const identityMatches = externalUserId !== null && current.external_user_id !== null ? externalUserId === current.external_user_id : handleMatches;
|
|
19429
|
+
const isSeededPlaceholder = storedHandle?.toLowerCase() === SEEDED_ACCOUNT_HANDLE && current.external_user_id === SEEDED_ACCOUNT_EXTERNAL_USER_ID && current.transport === "xurl";
|
|
19430
|
+
if (!identityMatches && !isSeededPlaceholder) return false;
|
|
19431
|
+
const identityChanged = !identityMatches;
|
|
19432
|
+
if (identityChanged) {
|
|
19433
|
+
db.prepare(
|
|
19434
|
+
`update profiles
|
|
19435
|
+
set handle = ?,
|
|
19436
|
+
display_name = coalesce(?, display_name),
|
|
19437
|
+
avatar_url = null
|
|
19438
|
+
where id = 'profile_me'`
|
|
19439
|
+
).run(handle, name);
|
|
19440
|
+
db.prepare(
|
|
19441
|
+
`update accounts
|
|
19442
|
+
set handle = ?,
|
|
19443
|
+
name = coalesce(?, name),
|
|
19444
|
+
transport = 'bird',
|
|
19445
|
+
external_user_id = ?
|
|
19446
|
+
where id = 'acct_primary'`
|
|
19447
|
+
).run(`@${handle}`, name, externalUserId);
|
|
19448
|
+
} else {
|
|
19449
|
+
db.prepare(
|
|
19450
|
+
`update profiles
|
|
19451
|
+
set handle = ?,
|
|
19452
|
+
display_name = coalesce(?, display_name)
|
|
19453
|
+
where id = 'profile_me'`
|
|
19454
|
+
).run(handle, name);
|
|
19455
|
+
db.prepare(
|
|
19456
|
+
`update accounts
|
|
19457
|
+
set handle = ?,
|
|
19458
|
+
name = coalesce(?, name),
|
|
19459
|
+
transport = 'bird',
|
|
19460
|
+
external_user_id = coalesce(?, external_user_id)
|
|
19461
|
+
where id = 'acct_primary'`
|
|
19462
|
+
).run(`@${handle}`, name, externalUserId);
|
|
19463
|
+
}
|
|
19464
|
+
return true;
|
|
19465
|
+
})();
|
|
19466
|
+
});
|
|
19467
|
+
return hydrated;
|
|
19468
|
+
});
|
|
19469
|
+
}
|
|
19316
19470
|
function hydrateProfilesFromXEffect() {
|
|
19317
19471
|
return Effect34.gen(function* () {
|
|
19318
19472
|
const transport = yield* tryPromise(() => getTransportStatus());
|
|
19319
19473
|
if (transport.availableTransport !== "xurl") {
|
|
19474
|
+
const hydratedAccount2 = yield* hydrateAccountFromBirdEffect();
|
|
19320
19475
|
return {
|
|
19321
19476
|
ok: true,
|
|
19322
19477
|
hydratedProfiles: 0,
|
|
19323
|
-
hydratedAccount:
|
|
19478
|
+
hydratedAccount: hydratedAccount2,
|
|
19324
19479
|
reason: transport.statusText
|
|
19325
19480
|
};
|
|
19326
19481
|
}
|
|
@@ -22394,6 +22549,7 @@ import { Effect as Effect42 } from "effect";
|
|
|
22394
22549
|
|
|
22395
22550
|
// src/lib/openai.ts
|
|
22396
22551
|
import { Effect as Effect41 } from "effect";
|
|
22552
|
+
var getEnv = (name) => process.env[name];
|
|
22397
22553
|
function clampScore(value) {
|
|
22398
22554
|
return Math.max(0, Math.min(100, Math.round(value)));
|
|
22399
22555
|
}
|
|
@@ -22413,8 +22569,11 @@ function scoreInboxItemWithOpenAIEffect(input) {
|
|
|
22413
22569
|
return yield* Effect41.fail(new Error("OPENAI_API_KEY is not set"));
|
|
22414
22570
|
}
|
|
22415
22571
|
const model = process.env.BIRDCLAW_OPENAI_MODEL || "gpt-5.2";
|
|
22572
|
+
const baseUrl = resolveOpenAIBaseUrl(getEnv);
|
|
22573
|
+
const url = `${baseUrl}/chat/completions`;
|
|
22574
|
+
debugLog(getEnv, `POST ${url} (model=${model})`);
|
|
22416
22575
|
const response = yield* tryPromise(
|
|
22417
|
-
() => fetch(
|
|
22576
|
+
() => fetch(url, {
|
|
22418
22577
|
method: "POST",
|
|
22419
22578
|
headers: {
|
|
22420
22579
|
authorization: `Bearer ${apiKey}`,
|
|
@@ -22435,10 +22594,23 @@ function scoreInboxItemWithOpenAIEffect(input) {
|
|
|
22435
22594
|
]
|
|
22436
22595
|
})
|
|
22437
22596
|
})
|
|
22438
|
-
).pipe(
|
|
22597
|
+
).pipe(
|
|
22598
|
+
Effect41.mapError(toError15),
|
|
22599
|
+
Effect41.tapError(
|
|
22600
|
+
(error) => Effect41.sync(
|
|
22601
|
+
() => debugLog(getEnv, `network error for ${url}: ${error.message}`)
|
|
22602
|
+
)
|
|
22603
|
+
)
|
|
22604
|
+
);
|
|
22439
22605
|
if (!response.ok) {
|
|
22606
|
+
const text = yield* tryPromise(() => response.text()).pipe(
|
|
22607
|
+
Effect41.mapError(toError15)
|
|
22608
|
+
);
|
|
22609
|
+
debugLog(getEnv, `${url} -> ${response.status} ${text.slice(0, 400)}`);
|
|
22440
22610
|
return yield* Effect41.fail(
|
|
22441
|
-
new Error(
|
|
22611
|
+
new Error(
|
|
22612
|
+
`OpenAI request failed: ${response.status} ${text.slice(0, 400)}`
|
|
22613
|
+
)
|
|
22442
22614
|
);
|
|
22443
22615
|
}
|
|
22444
22616
|
const payload = yield* tryPromise(() => response.json()).pipe(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{M as n,Rn as r,y as i}from"./schemas-CaALBBpc.js";var a=e(t(),1);function o(e){return new Intl.NumberFormat(`en`,{notation:`compact`}).format(e)}var s=1e3,c=60*s,l=60*c,u=24*l,d=new Intl.DateTimeFormat(`en`,{hour:`numeric`,minute:`2-digit`}),f=new Intl.DateTimeFormat(`en`,{weekday:`long`}),p=new Intl.DateTimeFormat(`en`,{month:`short`,day:`numeric`}),m=new Intl.DateTimeFormat(`en`,{year:`numeric`,month:`short`,day:`numeric`}),h=new Intl.DateTimeFormat(`en`,{year:`numeric`,month:`long`,day:`numeric`,hour:`numeric`,minute:`2-digit`,second:`2-digit`,timeZoneName:`short`});function g(e){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}function _(e){return Date.UTC(e.getFullYear(),e.getMonth(),e.getDate())/u}function v(e,t){let n=d.format(e),r=_(t)-_(e);return r===1?`Yesterday at ${n}`:r>=2&&r<=6?`${f.format(e)} at ${n}`:`${(e.getFullYear()===t.getFullYear()?p:m).format(e)} at ${n}`}function y(e){let t=g(e);return t?new Intl.DateTimeFormat(`en`,{hour:`numeric`,minute:`2-digit`,month:`short`,day:`numeric`}).format(t):e}function b(e){let t=g(e);return t?h.format(t):e}function x(e,t=Date.now()){let n=g(e),r=new Date(t);if(!n||Number.isNaN(r.getTime()))return e;let i=r.getTime()-n.getTime();if(i>=-45*s&&i<45*s)return`just now`;if(i<0)return v(n,r);if(i<l)return`${Math.max(1,Math.floor(i/c))} min ago`;if(i<u){let e=Math.max(1,Math.floor(i/l));return`${e} ${e===1?`hour`:`hours`} ago`}return v(n,r)}function S(e){return e.split(` `).map(e=>e[0]??``).join(``).slice(0,2)}var C=r();function w({profileId:e,avatarUrl:t,name:r,hue:o,size:s=`default`}){let c=e&&t?T(e,t):null,[l,u]=(0,a.useState)(null),d=c&&l!==c;return(0,C.jsx)(`span`,{className:n(i,s===`large`&&`avatar-chip-large size-16 text-[18px]`,s===`small`&&`avatar-chip-small size-8 text-[12px]`),style:{backgroundColor:`hsl(${String(o)} 72% 50%)`},children:d?(0,C.jsx)(`img`,{alt:r,className:`size-full rounded-[inherit] object-cover`,loading:`lazy`,onError:()=>u(c),src:c}):S(r)})}function T(e,t){return`/api/avatar?${new URLSearchParams({profileId:e,v:t}).toString()}`}export{y as a,b as i,T as n,x as o,o as r,w as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{$t as n,M as r,Pn as i,Qt as a,Rn as o,Zt as s,en as c,in as l,nn as u,rn as d,tn as f}from"./schemas-CaALBBpc.js";import{n as p,r as m,t as h}from"./AvatarChip-BN3b4MhM.js";var g=e(t(),1),_=/https?:\/\/[^\s<>"'`]+/g,v=/[),.;:!?]+$/;function y(e){try{let t=new URL(e),n=t.hostname.replace(/^www\./,``),r=`${t.pathname}${t.search}${t.hash}`;return r===`/`?n:`${n}${r}`}catch{return e}}function b(e){try{let t=new URL(e);return`${t.protocol}//${t.hostname.replace(/^www\./,``)}${t.pathname}`}catch{return e.split(`?`)[0]??e}}function x(e,t){if(b(e.expandedUrl)===b(t.url))return!0;try{let t=new URL(e.expandedUrl),n=t.hostname.replace(/^www\./,``);return(n===`x.com`||n===`twitter.com`)&&t.pathname.startsWith(`/i/article/`)}catch{return!1}}function S(e){return e&&typeof e==`object`?e:{}}function ee(e){let t=S(e),n=Array.isArray(t.mentions)?t.mentions:[],r=Array.isArray(t.urls)?t.urls:[],i=Array.isArray(t.hashtags)?t.hashtags:[],a=S(t.article),o=String(a.title??``).trim(),s=String(a.url??``).trim();return{...n.length?{mentions:n.map(e=>{let t=S(e);return{username:String(t.username??``),id:typeof t.id==`string`?String(t.id):void 0,start:Number(t.start??0),end:Number(t.end??0)}})}:{},...r.length?{urls:r.map(e=>{let t=S(e),n=String(t.expandedUrl??t.expanded_url??t.url??``);return{url:String(t.url??``),expandedUrl:n,displayUrl:String(t.displayUrl??t.display_url??n??t.url??``),start:Number(t.start??0),end:Number(t.end??0),...typeof t.title==`string`?{title:t.title}:{},...typeof t.description==`string`||t.description===null?{description:t.description}:{},...typeof t.imageUrl==`string`?{imageUrl:t.imageUrl}:typeof t.image_url==`string`?{imageUrl:t.image_url}:{},...typeof t.siteName==`string`?{siteName:t.siteName}:typeof t.site_name==`string`?{siteName:t.site_name}:{}}})}:{},...i.length?{hashtags:i.map(e=>{let t=S(e);return{tag:String(t.tag??t.text??``),start:Number(t.start??0),end:Number(t.end??0)}})}:{},...o&&s?{article:{title:o,url:s,...typeof(a.previewText??a.preview_text)==`string`&&String(a.previewText??a.preview_text).trim()?{previewText:String(a.previewText??a.preview_text).trim()}:{},...typeof(a.coverImageUrl??a.cover_image_url)==`string`&&String(a.coverImageUrl??a.cover_image_url).trim()?{coverImageUrl:String(a.coverImageUrl??a.cover_image_url).trim()}:{}}}:{}}}function C(e){return ee(S(e).description)}function te(e,t,n,r){return e<r&&n<t}function w(e,t){if(t<=0)return 0;let n=0,r=0;for(let i of e){if(r>=t)break;n+=i.length,r+=1}return n}function T(e,t,n,r){let i=e.slice(n,r);return t.kind===`mention`?i.toLowerCase()===`@${t.username}`.toLowerCase():t.kind===`hashtag`?i.toLowerCase()===`#${t.tag}`.toLowerCase():i===t.url}function E(e,t){if(t.start>=0&&t.end>t.start&&t.end<=e.length&&T(e,t,t.start,t.end))return t;let n=w(e,t.start),r=w(e,t.end);return n>=0&&r>n&&r<=e.length&&T(e,t,n,r)?{...t,start:n,end:r}:t}function ne(e,t){let n=E(e,{...t,kind:`url`});return{start:n.start,end:n.end}}function D(e,t,n){let r=(t.urls??[]).map(e=>{let t=n?.(e.url),r=t?.expandedUrl||e.expandedUrl||e.url;return{...e,expandedUrl:r,displayUrl:t?.displayUrl||e.displayUrl||y(r),...t?.title?{title:t.title}:{},...t&&`description`in t?{description:t.description??null}:{},...t?.imageUrl?{imageUrl:t.imageUrl}:{},...t?.siteName?{siteName:t.siteName}:{}}}),i=[];for(let t of e.matchAll(_)){let e=t[0].replace(v,``),a=t.index??0,o=a+e.length;if(!e||r.some(e=>te(a,o,e.start,e.end)))continue;let s=n?.(e),c=s?.expandedUrl||e;i.push({url:e,expandedUrl:c,displayUrl:s?.displayUrl||y(c),start:a,end:o,...s?.title?{title:s.title}:{},...s&&`description`in s?{description:s.description??null}:{},...s?.imageUrl?{imageUrl:s.imageUrl}:{},...s?.siteName?{siteName:s.siteName}:{}})}return i.length===0?{...t,urls:r}:{...t,urls:[...r,...i].sort((e,t)=>e.start-t.start)}}function O(e){return[...e.mentions?.map(e=>({...e,kind:`mention`}))??[],...e.urls?.map(e=>({...e,kind:`url`}))??[],...e.hashtags?.map(e=>({...e,kind:`hashtag`}))??[]].sort((e,t)=>e.start-t.start)}function k(e,t){return O(t).map(t=>E(e,t)).sort((e,t)=>e.start-t.start)}function re(e,t,n){let r=k(e,t),i=0,a=``;for(let t of r){if(t.start<i||t.end<=t.start||t.end>e.length)continue;a+=e.slice(i,t.start);let r=e.slice(t.start,t.end);a+=n(t,r),i=t.end}return a+=e.slice(i),a}function ie(e,t){return re(e,t,(e,t)=>e.kind===`url`?e.expandedUrl:e.kind===`mention`?`@${e.username}`:e.kind===`hashtag`?`#${e.tag}`:t)}function A(e){if(!e)return null;try{let t=new URL(e);return t.protocol!==`http:`&&t.protocol!==`https:`?null:t.toString()}catch{return null}}var j=4,M=2500,N=`800px 0px`,P=[],F=new Set,I=new Set,L=0,R=!1,z=null,B=null;function V(e){I.delete(e)&&(--L,H())}function H(){for(;L<j&&P.length>0;){let e=P.shift();if(!e)return;let t=new Image;L+=1,I.add(t),t.decoding=`async`,t.onerror=()=>V(t),t.onload=()=>{if(typeof t.decode!=`function`){V(t);return}t.decode().catch(()=>void 0).finally(()=>V(t))},t.src=e}}function U(){z=null,B=null,H()}function W(){if(P.length===0||z!==null||B!==null)return;let e=window.requestIdleCallback?.bind(window);if(e){z=e(U,{timeout:M});return}B=window.setTimeout(U,0)}function G(){R=!1,W()}function K(){if(document.readyState===`complete`){W();return}R||(R=!0,window.addEventListener(`load`,G,{once:!0}))}function q(e,t){if(!e||!t||typeof window>`u`)return;let n=p(e,t);F.has(n)||(F.add(n),P.push(n),K())}function J(e,t,n){(0,g.useEffect)(()=>{if(!t||!n)return;let r=e.current;if(!r||typeof IntersectionObserver>`u`){q(t,n);return}let i=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(i.disconnect(),q(t,n))},{rootMargin:N});return i.observe(r),()=>i.disconnect()},[n,t,e])}var ae=10,oe=12,se=120,Y={top:0,left:0,maxWidth:0,maxHeight:0,side:`bottom`,measured:!1,ready:!1};function ce(e,t){return e.reduce((e,n)=>t===`bottom`?n.bottom>e.bottom||n.bottom===e.bottom&&n.width>e.width?n:e:n.top<e.top||n.top===e.top&&n.width>e.width?n:e)}function le(e,t,n){return n<t?t:Math.min(Math.max(e,t),n)}function ue({referenceRects:e,floatingWidth:t,floatingHeight:n,viewport:r,gap:i=ae,gutter:a=oe}){let o=Math.min(...e.map(e=>e.top)),s=Math.max(...e.map(e=>e.bottom)),c=Math.max(0,r.bottom-a-s-i),l=Math.max(0,o-r.top-a-i),u=c>=n||c>=l?`bottom`:`top`,d=u===`bottom`?c:l,f=Math.min(n,d),p=ce(e,u),m=Math.max(0,r.width-a*2),h=Math.min(t,m),g=r.left+a,_=r.right-a-h,v=le(p.left+p.width/2-h/2,g,_);return{top:u===`bottom`?s+i:o-i-f,left:v,maxWidth:m,maxHeight:d,side:u,measured:!0,ready:!0}}function de(){let e=window.visualViewport,t=e?.offsetLeft??0,n=e?.offsetTop??0,r=e?.width??window.innerWidth,i=e?.height??window.innerHeight;return{top:n,right:t+r,bottom:n+i,left:t,width:r,height:i}}function fe(e){let t=Array.from(e.getClientRects()).filter(e=>e.width>0||e.height>0);return t.length>0?t:[e.getBoundingClientRect()]}function pe(e,t){return e.some(e=>e.right>=t.left&&e.left<=t.right&&e.bottom>=t.top&&e.top<=t.bottom)}function me(e,t){return e.top===t.top&&e.left===t.left&&e.maxWidth===t.maxWidth&&e.maxHeight===t.maxHeight&&e.side===t.side&&e.measured===t.measured&&e.ready===t.ready}function X(e){return{position:`fixed`,top:e.top,left:e.left,maxWidth:e.measured?e.maxWidth:void 0,maxHeight:e.measured?e.maxHeight:void 0,visibility:e.ready?`visible`:`hidden`}}function Z(e,...t){return e instanceof Node&&t.some(t=>t?.contains(e))}function Q(e={}){let t=e.closeDelayMs??se,[n,r]=(0,g.useState)(!1),[i,a]=(0,g.useState)(Y),o=(0,g.useId)(),s=(0,g.useRef)(null),c=(0,g.useRef)(null),l=(0,g.useRef)(null),u=(0,g.useCallback)(()=>{l.current!==null&&(window.clearTimeout(l.current),l.current=null)},[]),d=(0,g.useCallback)(()=>{u(),n||a(Y),r(!0)},[u,n]),f=(0,g.useCallback)(()=>{u(),r(!1)},[u]),p=(0,g.useCallback)(()=>{u(),l.current=window.setTimeout(()=>{l.current=null;let e=s.current,t=c.current,n=Z(document.activeElement,e,t),i=!!e?.matches(`:hover`)||!!t?.matches(`:hover`);!n&&!i&&r(!1)},t)},[u,t]),m=(0,g.useCallback)(e=>{Z(e.relatedTarget,s.current,c.current)||p()},[p]),h=(0,g.useCallback)(e=>{e.key===`Escape`&&(f(),s.current?.querySelector(`a,button`)?.focus())},[f]),_=(0,g.useCallback)(()=>{let e=s.current,t=c.current;if(!e||!t)return;let n=de(),r=fe(e);if(!pe(r,n)){a(e=>e.ready?{...e,ready:!1}:e);return}let i=t.getBoundingClientRect(),o=t.querySelector(`[data-floating-preview-content]`),l=window.getComputedStyle(t),u=[l.paddingTop,l.paddingBottom,l.borderTopWidth,l.borderBottomWidth].reduce((e,t)=>e+(Number.parseFloat(t)||0),0),d=Math.max(i.height,(o?.getBoundingClientRect().height??0)+u),f=ue({referenceRects:r,floatingWidth:i.width,floatingHeight:d,viewport:n});i.width>f.maxWidth+.5&&(f.ready=!1),a(e=>me(e,f)?e:f)},[]);(0,g.useLayoutEffect)(()=>{if(!n)return;_();let e=0,t=()=>{_(),e=window.requestAnimationFrame(t)};e=window.requestAnimationFrame(t);let r=window.visualViewport;window.addEventListener(`resize`,_),window.addEventListener(`scroll`,_,!0),r?.addEventListener(`resize`,_),r?.addEventListener(`scroll`,_);let i=typeof ResizeObserver>`u`?null:new ResizeObserver(_);return s.current&&i?.observe(s.current),c.current&&i?.observe(c.current),()=>{window.cancelAnimationFrame(e),window.removeEventListener(`resize`,_),window.removeEventListener(`scroll`,_,!0),r?.removeEventListener(`resize`,_),r?.removeEventListener(`scroll`,_),i?.disconnect()}},[n,_]),(0,g.useEffect)(()=>()=>u(),[u]);let v={onPointerEnter:e=>d(),onPointerLeave:e=>p(),onFocus:e=>d(),onBlur:m,onKeyDown:h};return{open:n,referenceRef:s,floatingRef:c,floatingStyle:X(i),referenceProps:v,floatingProps:v,floatingId:o,closePreview:f}}var $=o();function he({profile:e}){let t=k(e.bio,C(e.entities)),n=0;return(0,$.jsxs)(`span`,{className:s,children:[t.map((t,r)=>{if(t.kind!==`url`||t.start<n||t.end<=t.start||t.end>e.bio.length)return null;let a=e.bio.slice(n,t.start);n=t.end;let o=A(t.expandedUrl);return(0,$.jsxs)(g.Fragment,{children:[a,o?(0,$.jsx)(`a`,{className:i,href:o,rel:`noreferrer`,target:`_blank`,children:t.expandedUrl}):e.bio.slice(t.start,t.end)]},`${t.url}-${String(r)}`)}),e.bio.slice(n)]})}function ge({profile:e,children:t,className:i=``}){let o=Q();return J(o.referenceRef,e.id,e.avatarUrl),(0,$.jsxs)(`span`,{ref:o.referenceRef,className:r(n,i),...o.referenceProps,children:[(0,$.jsx)(`a`,{"aria-controls":o.open?o.floatingId:void 0,"aria-expanded":o.open,className:l,href:`/profiles/${encodeURIComponent(e.handle)}`,children:t}),o.open?(0,$.jsx)(`span`,{"aria-label":`${e.displayName} profile preview`,id:o.floatingId,ref:o.floatingRef,className:a,role:`group`,style:o.floatingStyle,...o.floatingProps,children:(0,$.jsxs)(`span`,{className:`grid gap-2`,"data-floating-preview-content":!0,children:[(0,$.jsxs)(`span`,{className:f,children:[(0,$.jsx)(h,{avatarUrl:e.avatarUrl,hue:e.avatarHue,name:e.displayName,profileId:e.id}),(0,$.jsxs)(`span`,{className:`flex min-w-0 flex-col`,children:[(0,$.jsx)(`span`,{className:d,children:e.displayName}),(0,$.jsxs)(`span`,{className:c,children:[`@`,e.handle]})]})]}),e.bio?(0,$.jsx)(he,{profile:e}):null,(0,$.jsxs)(`span`,{className:u,children:[m(e.followersCount),` followers`]})]})}):null]})}export{k as a,ne as c,A as i,C as l,Q as n,D as o,J as r,x as s,ge as t,ie as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{Rn as n}from"./schemas-CaALBBpc.js";import{a as r,i,n as a,o,r as s,t as c}from"./useTimelineRouteData-Cpf-Jqsx.js";import{f as l}from"./index-Bqmo4MbK.js";var u=e(t(),1),d=n(),f={liked:`Likes`,bookmarked:`Bookmarks`};function p({filter:e,title:t,loadingLabel:n,searchPlaceholder:p}){let[m,h]=(0,u.useState)(``),{meta:g,items:_,loading:v,error:y,retry:b,refreshLocalView:x,replyToTweet:S,hasMore:C,loadingMore:w,loadMore:T}=c({resource:`home`,search:m,errorFallback:`${f[e]} unavailable`,likedOnly:e===`liked`,bookmarkedOnly:e===`bookmarked`}),E=(0,u.useMemo)(()=>g?`${String(_.length)} visible · ${g.transport.statusText}`:_.length>0?`${String(_.length)} visible`:n,[_.length,n,g]),D=e===`liked`?`likes`:`bookmarks`;return(0,d.jsx)(s,{header:(0,d.jsx)(a,{title:f[e],subtitles:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(i,{children:t}),(0,d.jsx)(i,{children:E})]}),action:(0,d.jsx)(l,{accounts:g?.accounts,kind:D,label:e===`liked`?`Sync likes`:`Sync bookmarks`,onSynced:x}),controls:(0,d.jsx)(r,{onChange:h,placeholder:p,value:m})}),loading:v,loadingLabel:n,loadingDetail:`Reading local ${f[e].toLowerCase()}`,error:y,errorTitle:`Could not load ${f[e].toLowerCase()}`,onRetry:b,empty:_.length===0,emptyLabel:`Nothing saved here yet`,emptyDetail:`Sync this collection or broaden the search.`,hasMore:C,loadingMore:w,onLoadMore:T,children:_.map(e=>(0,d.jsx)(o,{item:e,onReply:S,showReplyControls:!1},e.id))})}export{p as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{Rn as n}from"./schemas-CaALBBpc.js";import{a as r,i,o as a}from"./AvatarChip-BN3b4MhM.js";var o=e(t(),1),s=n(),c=3e4,l=new Set,u=Date.now(),d=null;function f(){u=Date.now();for(let e of l)e()}function p(e){return l.add(e),d===null&&(u=Date.now(),d=setInterval(f,c)),()=>{l.delete(e),l.size===0&&d!==null&&(clearInterval(d),d=null)}}function m(){return u}function h(){return null}function g({className:e,value:t}){let n=(0,o.useSyncExternalStore)(p,m,h),c=i(t);return(0,s.jsx)(`time`,{"aria-label":c,className:e,dateTime:t,title:c,children:n===null?r(t):a(t,n)})}export{g as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{Dn as n,M as r,Mn as i,On as a,Rn as o,kn as s}from"./schemas-CaALBBpc.js";import{a as c,i as l,n as u,o as d,r as f,t as p}from"./useTimelineRouteData-Cpf-Jqsx.js";import{f as m}from"./index-Bqmo4MbK.js";var h=e(t(),1),g=o(),_=[{value:`all`,label:`All`},{value:`unreplied`,label:`Unreplied`},{value:`replied`,label:`Replied`}];function v({title:e,resource:t,initialReplyFilter:o,searchPlaceholder:v,syncKind:y,syncLabel:b,loadingLabel:x,loadingDetail:S,errorTitle:C,errorFallback:w,emptyLabel:T,emptyDetail:E,subtitle:D}){let[O,k]=(0,h.useState)(o),[A,j]=(0,h.useState)(``),{meta:M,items:N,loading:P,error:F,replyError:I,retry:L,refreshLocalView:R,replyToTweet:z,hasMore:B,loadingMore:V,loadMore:H}=p({resource:t,replyFilter:O,search:A,errorFallback:w});return(0,g.jsx)(f,{header:(0,g.jsx)(u,{title:e,subtitles:(0,g.jsx)(l,{children:(0,h.useMemo)(()=>D(M),[M,D])}),action:(0,g.jsx)(m,{accounts:M?.accounts,allowAutoSync:!0,autoSyncBlocked:P,kind:y,label:b,onSynced:R,showAccountPicker:!0}),controls:(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(c,{onChange:j,placeholder:v,value:A}),(0,g.jsx)(`div`,{className:s,children:_.map(e=>{let t=O===e.value;return(0,g.jsx)(`button`,{type:`button`,"aria-pressed":t,className:r(n,t&&`text-[var(--ink)] font-bold`),onClick:()=>k(e.value),children:(0,g.jsxs)(`span`,{className:`relative inline-flex flex-col items-center justify-center py-1`,children:[e.label,t?(0,g.jsx)(`span`,{className:a}):null]})},e.value)})})]})}),notice:I?(0,g.jsx)(`p`,{className:r(i,`px-4 py-2 text-red-500`),children:I}):null,loading:P,loadingLabel:x,loadingDetail:S,error:F,errorTitle:C,onRetry:L,empty:N.length===0,emptyLabel:T,emptyDetail:E,hasMore:B,loadingMore:V,onLoadMore:H,children:N.map(e=>(0,g.jsx)(d,{item:e,onReply:z},e.id))})}export{v as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{An as n,C as r,Ft as i,Gt as a,Kt as ee,M as o,Mn as te,N as s,Rn as c,S as l,Tn as u,Ut as d,Wt as f,Xt as p,cn as m,dt as h,jn as ne,pn as re,ut as g}from"./schemas-CaALBBpc.js";import{A as _,a as v,b as y,n as b,r as ie,s as x,u as ae}from"./query-client-DUP1ZzP7.js";import{r as S,t as C}from"./AvatarChip-BN3b4MhM.js";import{Z as w,c as T,ct as E,d as D}from"./index-Bqmo4MbK.js";var O=e(t()),k=c();function A(){let e=T.useSearch(),t=T.useNavigate();return(0,k.jsx)(j,{searchState:e,onSearchChange:(e,n)=>void t({search:e,replace:n?.replace})})}function j({searchState:e,onSearchChange:t}={}){let c=y(),[T,A]=(0,O.useState)(()=>w({})),j=e??T,M=(e,n)=>t?t(e,n):A(e),N=j.account,P=j.q,[F,I]=(0,O.useState)(!1),[L,R]=(0,O.useState)(``),[z,B]=(0,O.useState)(``),V=E({queryKey:b.status,queryFn:({signal:e})=>v({signal:e})}),H=V.data??null,U=D(P,180),W=N.trim().length>0,G=!!H,K=E({queryKey:[...b.blocks,{accountId:N,search:U}],enabled:W,queryFn:async({signal:e})=>{let t=new URLSearchParams({account:N,limit:`12`});return U.trim()&&t.set(`search`,U.trim()),ie(`/api/blocks?${t.toString()}`,{signal:e},ae,`Blocklist request failed`)},placeholderData:_,staleTime:5*6e4}),q=K.data?.items??[],J=K.data?.matches??[],Y=E({queryKey:[...b.blockSync,N],enabled:W,retry:!1,queryFn:async()=>{let e=await x({kind:`syncBlocks`,accountId:N});if(e.ok===!1||e.transport?.ok===!1)throw Error(e.transport?.output??`Block sync failed`);return await c.invalidateQueries({queryKey:b.blocks}),e},staleTime:5*6e4}),X=Y.isFetching,Z=V.error??K.error??Y.error??null,Q=z||(Z instanceof Error?Z.message:Z?`Unable to load blocklist`:``);(0,O.useEffect)(()=>{H?.accounts.length&&(H.accounts.some(e=>e.id===N)||M({...j,account:H.accounts[0]?.id??`acct_primary`},{replace:!0}))},[N,H]),(0,O.useEffect)(()=>{let e=Y.data;!e||e.transport?.output?.includes(`disabled`)||R(e.transport?.output??`Synced ${String(e.syncedCount??0)} remote blocks`)},[Y.data]);let oe=(0,O.useMemo)(()=>H?X?`Syncing remote blocklist · ${H.transport.statusText}`:`${String(q.length)} blocked profiles · ${H.transport.statusText}`:q.length>0?`${String(q.length)} blocked profiles · loading transport...`:`Loading local blocklist...`,[X,q.length,H]);async function $(e,t){let n=t.trim();if(n){I(!0),B(``),R(``);try{let t=await x({kind:e,accountId:N,query:n});if(t.ok===!1||t.transport?.ok===!1){B(t.transport?.output??`Blocklist action failed`);return}R(`${e===`blockProfile`?`Blocked`:`Unblocked`} @${t.profile?.handle??n.replace(/^@/,``)} · ${t.transport?.output??`local`}`),await c.invalidateQueries({queryKey:b.blocks})}catch(e){B(e instanceof Error?e.message:`Blocklist action failed`)}finally{I(!1)}}}return(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(`header`,{className:d,children:[(0,k.jsx)(`div`,{className:f,children:(0,k.jsxs)(`div`,{className:`flex min-w-0 flex-col`,children:[(0,k.jsx)(`h1`,{className:ee,children:`Blocks`}),(0,k.jsx)(`h2`,{className:o(a,`text-[14px]`),children:`Maintain a clean blocklist locally.`}),(0,k.jsx)(`p`,{className:a,children:oe})]})}),(0,k.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 px-4 pb-3`,children:[(0,k.jsx)(`select`,{className:o(re,ne),disabled:!G,onChange:e=>M({...j,account:e.target.value}),value:N,children:H?.accounts.map(e=>(0,k.jsx)(`option`,{value:e.id,children:e.handle},e.id))}),(0,k.jsx)(`input`,{className:o(n,`flex-1 min-w-[200px]`),disabled:!W,onChange:e=>M({...j,q:e.target.value},{replace:!0}),placeholder:`Handle, name, bio, or Twitter URL`,value:P}),(0,k.jsx)(`button`,{className:p,disabled:!W||F||!P.trim(),onClick:()=>void $(`blockProfile`,P),type:`button`,children:F?`Working...`:`Block`})]})]}),L?(0,k.jsx)(`p`,{className:u,children:L}):null,Q?(0,k.jsx)(`p`,{className:h,children:Q}):null,J.length>0?(0,k.jsxs)(`section`,{className:`flex flex-col`,children:[(0,k.jsx)(`h2`,{className:`px-4 pt-3 pb-1 text-[13px] font-semibold uppercase tracking-wide text-[var(--ink-soft)]`,children:`Search matches`}),J.map(e=>(0,k.jsxs)(`article`,{className:r,children:[(0,k.jsx)(C,{avatarUrl:e.profile.avatarUrl,hue:e.profile.avatarHue,name:e.profile.displayName,profileId:e.profile.id}),(0,k.jsxs)(`div`,{className:l,children:[(0,k.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,k.jsxs)(`div`,{className:`flex min-w-0 flex-col`,children:[(0,k.jsx)(`strong`,{className:`truncate text-[15px] text-[var(--ink)]`,children:e.profile.displayName}),(0,k.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 text-[13px] text-[var(--ink-soft)]`,children:[(0,k.jsxs)(`span`,{children:[`@`,e.profile.handle]}),(0,k.jsx)(`span`,{className:i}),(0,k.jsxs)(`span`,{children:[S(e.profile.followersCount),` `,`followers`]})]})]}),(0,k.jsx)(`button`,{className:e.isBlocked?m:s,onClick:()=>void $(e.isBlocked?`unblockProfile`:`blockProfile`,e.profile.id),type:`button`,children:e.isBlocked?`Unblock`:`Block`})]}),(0,k.jsx)(`p`,{className:`text-[14px] leading-[1.4] text-[var(--ink)]`,children:e.profile.bio})]})]},e.profile.id))]}):null,(0,k.jsxs)(`section`,{className:`flex flex-col`,children:[q.length===0&&J.length===0?(0,k.jsx)(`div`,{className:g,children:`No blocks in this account.`}):null,q.map(e=>(0,k.jsxs)(`article`,{className:r,children:[(0,k.jsx)(C,{avatarUrl:e.profile.avatarUrl,hue:e.profile.avatarHue,name:e.profile.displayName,profileId:e.profile.id}),(0,k.jsxs)(`div`,{className:l,children:[(0,k.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,k.jsxs)(`div`,{className:`flex min-w-0 flex-col`,children:[(0,k.jsx)(`strong`,{className:`truncate text-[15px] text-[var(--ink)]`,children:e.profile.displayName}),(0,k.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 text-[13px] text-[var(--ink-soft)]`,children:[(0,k.jsxs)(`span`,{children:[`@`,e.profile.handle]}),(0,k.jsx)(`span`,{className:i}),(0,k.jsx)(`span`,{children:e.accountHandle}),(0,k.jsx)(`span`,{className:i}),(0,k.jsxs)(`span`,{children:[S(e.profile.followersCount),` `,`followers`]})]})]}),(0,k.jsx)(`button`,{className:m,onClick:()=>void $(`unblockProfile`,e.profile.id),type:`button`,children:`Unblock`})]}),e.profile.bio?(0,k.jsx)(`p`,{className:`text-[14px] leading-[1.4] text-[var(--ink)]`,children:e.profile.bio}):null,(0,k.jsxs)(`p`,{className:te,children:[`Blocked `,new Date(e.blockedAt).toLocaleString(),` ·`,` `,e.source]})]})]},e.accountId+e.profile.id))]})]})}export{j as BlocksRouteView,A as component};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Rn as e}from"./schemas-
|
|
1
|
+
import{Rn as e}from"./schemas-CaALBBpc.js";import{t}from"./SavedTimelineView-mGXE9EYJ.js";var n=e();function r(){return(0,n.jsx)(t,{eyebrow:`bookmarks`,filter:`bookmarked`,loadingLabel:`Loading bookmarks...`,searchPlaceholder:`Search bookmarks`,title:`Saved threads, receipts, and future rabbit holes.`})}export{r as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(e&&(t=e(e=0)),t),s=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));export{o as n,l as r,s as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./createLucideIcon-JV8isFFR.js";var t=e(`circle-check`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]);export{t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{Ln as n,M as r,Pn as i,Rn as a,_ as o,a as s,c,d as l,i as u,l as d,m as f,s as p,u as m}from"./schemas-CaALBBpc.js";import{t as h}from"./createLucideIcon-JV8isFFR.js";import{r as g,t as _}from"./AvatarChip-BN3b4MhM.js";import{i as v,n as y,r as ee,t as b,u as te}from"./ProfilePreview-CHbT0U9a.js";import{t as ne}from"./SmartTimestamp-DG8XJKUz.js";var x=h(`loader-circle`,[[`path`,{d:`M21 12a9 9 0 1 1-6.219-8.56`,key:`13zald`}]]),S=e(t(),1),C=a();function w(e){return e.trim().replace(/^\(/,``).replace(/\)$/,``).replace(/^tweet_/,``)}function T(e){return/^\d{12,25}$/.test(w(e))}function E(e){return Array.from(e.matchAll(/\b(?:tweet_)?[A-Za-z0-9_:-]{3,}\b/g)).map(e=>e[0]).filter(e=>e.startsWith(`tweet_`)||/^\d{12,25}$/.test(e))}function D(e,t){let n=[],r=t;for(;r<e.length;){let t=/^\s+\((?:\s*(?:tweet_[A-Za-z0-9_:-]+|\d{12,25})\s*,?)+\)/.exec(e.slice(r));if(!t)break;n.push(...E(t[0])),r+=t[0].length}return{references:n,cursor:r}}function O(e,t={}){let n=0;for(let t of[`. `,`? `,`! `,`; `,`: `]){let r=e.lastIndexOf(t);r>=0&&(n=Math.max(n,r+t.length))}let r=e.length;for(;n<r&&/\s/.test(e[n]??``);)n+=1;for(;r>n&&/\s/.test(e[r-1]??``);)--r;let i=n;for(let t of[`, with `,`, while `,`, and `]){let a=e.lastIndexOf(t,r);if(a>=n){i=a+2;break}}if(t.preferClause!==!1&&(i>n||r-n>140)){for(;i<r&&/\s/.test(e[i]??``);)i+=1;r>i&&(n=i)}return r>n?{start:n,end:r}:null}function re(e){return e.replace(/^[-*]\s+/,``)}function k(e,t){let n=/^((?:\s+source\b)+)(?=\s*(?:[.,;:!?)]|$))/i.exec(e.slice(t));return n?t+n[0].length:t}function ie(e){return e.url||`https://x.com/${e.author}/status/${e.id}`}function A(e){return`https://x.com/i/status/${w(e)}`}function j(e){try{let t=new URL(e);return`${t.protocol}//${t.hostname}${t.pathname}`}catch{return e.split(`?`)[0]??e}}function ae(e,t){try{let n=new URL(e),r=n.hostname.replace(/^www\./,``);return r!==`x.com`&&r!==`twitter.com`?!1:RegExp(`/status/${t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}/(?:photo|video)(?:/|$)`).test(n.pathname)}catch{return!1}}function M(e,t,n){if(n.length===0)return e;let r=/(https?:\/\/[^\s]+)\s*$/.exec(e);if(!r)return e;let i=r[1];if(!i)return e;let a=new Set(n.flatMap(e=>e.thumbnailUrl?[e.url,e.thumbnailUrl]:[e.url])),o=j(i),s=[...a].some(e=>j(e)===o),c=(t.entities?.urls??[]).some(e=>e.end>e.start?!1:[...a].some(t=>j(t)===j(e.expandedUrl))),l=(()=>{try{return new URL(i).hostname.replace(/^www\./,``)===`t.co`}catch{return!1}})();return!s&&!ae(i,t.id)&&!(l&&c)?e:e.slice(0,r.index).trimEnd()}function N({items:e}){let t=e.flatMap(e=>{let t=e.type===`image`?v(e.thumbnailUrl??e.url):v(e.thumbnailUrl);return t?[{item:e,url:t}]:[]}).slice(0,4);return t.length===0?null:(0,C.jsx)(`span`,{className:t.length===1?`mt-2 block overflow-hidden rounded-xl border border-[var(--line)] bg-[var(--bg-active)]`:`mt-2 grid grid-cols-2 gap-1.5 overflow-hidden rounded-xl`,children:t.map(({item:e,url:n},r)=>(0,C.jsx)(`img`,{alt:e.altText??`Tweet media ${String(r+1)}`,className:t.length===1?`block max-h-64 w-full object-contain`:`block aspect-square size-full rounded-lg border border-[var(--line)] object-cover`,decoding:`async`,src:n},`${n}-${String(r)}`))})}function P({children:e,href:t,onClick:n,describedBy:r}){return(0,C.jsx)(`a`,{"aria-describedby":r,className:`rounded-sm px-0.5 text-[var(--accent)] hover:bg-[var(--accent-soft)] hover:no-underline`,href:t,onClick:n,rel:`noreferrer`,target:`_blank`,children:e})}function F({tweet:e,children:t}){let n=y();ee(n.referenceRef,e.authorProfile.id,e.authorProfile.avatarUrl);let r=e.entities?.article,i=e.media??[],a=te(e.text,e.entities??{}),o=r?[r.title,r.previewText].filter((e,t,n)=>!!e&&n.indexOf(e)===t).join(`
|
|
2
2
|
|
|
3
3
|
`):M(a,e,i);return(0,C.jsxs)(`span`,{ref:n.referenceRef,className:`inline align-baseline`,...n.referenceProps,children:[(0,C.jsx)(P,{describedBy:n.open?n.floatingId:void 0,href:ie(e),onClick:e=>{n.closePreview(),e.currentTarget.blur()},children:t}),n.open?(0,C.jsx)(`span`,{id:n.floatingId,ref:n.floatingRef,className:`fixed z-40 w-[360px] overflow-y-auto rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] p-3 text-left text-[14px] leading-[1.4] text-[var(--ink)] shadow-[0_14px_40px_var(--shadow-strong)]`,role:`tooltip`,style:n.floatingStyle,...n.floatingProps,children:(0,C.jsxs)(`span`,{className:`block`,"data-floating-preview-content":!0,children:[(0,C.jsxs)(`span`,{className:`mb-2 flex items-center gap-2`,children:[(0,C.jsx)(_,{avatarUrl:e.authorProfile.avatarUrl,hue:e.authorProfile.avatarHue,name:e.name,profileId:e.authorProfile.id,size:`small`}),(0,C.jsxs)(`span`,{className:`min-w-0`,children:[(0,C.jsx)(`span`,{className:`block truncate font-bold`,children:e.name}),(0,C.jsxs)(`span`,{className:`block truncate text-[12px] text-[var(--ink-soft)]`,children:[`@`,e.author,` · `,(0,C.jsx)(ne,{value:e.createdAt})]})]})]}),(0,C.jsx)(`span`,{className:`whitespace-pre-wrap [overflow-wrap:anywhere]`,children:o}),(0,C.jsx)(N,{items:i}),(0,C.jsxs)(`span`,{className:`mt-2 flex gap-3 text-[12px] text-[var(--ink-soft)]`,children:[(0,C.jsx)(`span`,{children:e.source}),e.likeCount>0?(0,C.jsxs)(`span`,{children:[g(e.likeCount),` likes`]}):null,e.needsReply?(0,C.jsx)(`span`,{children:`reply open`}):null]})]})}):null]})}function oe(e,t){return e.slice(1).flatMap((e,n)=>[n===0?` `:`, `,(0,C.jsx)(P,{href:A(e),children:`source ${String(n+2)}`},`${t}-direct-source-${String(n+2)}`)])}function I(e,t){if(t<2)return null;let n=Array.from(e.matchAll(/,\s+and\s+|,\s+or\s+|;\s+|,\s+|\s+and\s+|\s+or\s+/g));if(n.length<t-1)return null;let r=n.slice(-(t-1)),i=[],a=0;for(let t of r){let n=t.index;if(n===void 0)return null;let r=e.slice(a,n);if(!r.trim())return null;i.push({text:r,separatorAfter:t[0]}),a=n+t[0].length}let o=e.slice(a);return o.trim()?(i.push({text:o,separatorAfter:``}),i.length===t?i:null):null}function se(e,t,n){let r=I(e,t.length);if(!r){let r=t[0];return r?[(0,C.jsx)(F,{tweet:r,children:e},n),...L(t,n)]:[]}return r.flatMap((e,r)=>{let i=t[r];return i?[(0,C.jsx)(F,{tweet:i,children:e.text},`${n}-part-${String(r)}`),e.separatorAfter]:[]})}function ce(e,t,n){let r=I(e,t.length);if(!r){let r=t[0];return r?[(0,C.jsx)(P,{href:A(r),children:e},n),...oe(t,n)]:[]}return r.flatMap((e,r)=>{let i=t[r];return i?[(0,C.jsx)(P,{href:A(i),children:e.text},`${n}-direct-part-${String(r)}`),e.separatorAfter]:[]})}function L(e,t){return e.slice(1).flatMap((e,n)=>[n===0?` `:`, `,(0,C.jsx)(F,{tweet:e,children:`source ${String(n+2)}`},`${t}-source-${String(n+2)}`)])}function R(e,t){return e.flatMap((n,r)=>[r===0?``:`, `,(0,C.jsx)(F,{tweet:n,children:e.length===1?`source`:`source ${String(r+1)}`},`${t}-fallback-${String(r+1)}`)])}function z(e,t,n){let r=t[0];if(!r)return!1;let i=e.at(-1);if(typeof i!=`string`)return!1;let a=/(["“][^"”]+["”])(\s*)$/.exec(i);if(a){let o=a[1],s=a[2]??``,c=i.slice(0,a.index);return e[e.length-1]=c,e.push((0,C.jsx)(F,{tweet:r,children:o},n),...L(t,n),/^\s*$/.test(s)?``:s),!0}let o=O(i,{preferClause:t.length===1});if(!o)return!1;let s=i.slice(0,o.start),c=i.slice(o.start,o.end),l=i.slice(o.end);return e[e.length-1]=s,e.push(...se(c,t,n),/^\s*$/.test(l)?``:l),!0}function B(e,t,n){if(!t[0])return!1;let r=e.at(-1);if(typeof r!=`string`)return!1;let i=O(r,{preferClause:t.length===1});if(!i)return!1;let a=r.slice(0,i.start),o=r.slice(i.start,i.end),s=r.slice(i.end);return e[e.length-1]=a,e.push(...ce(o,t,n),/^\s*$/.test(s)?``:s),!0}function V(e,t){let r=/(\[[^\]\n]+\]\s*\(https?:\/\/[^\s)]+\)|\*\*[^*]+\*\*|@[A-Za-z0-9_]{1,20}|\((?:\s*(?:tweet_[A-Za-z0-9_:-]+|\d{12,25})\s*,?)+\)|\btweet_[A-Za-z0-9_:-]+\b|\b\d{12,25}\b)/g,a=[],o=0,s;for(;s=r.exec(e);){let c=s[0],l=`${c}-${String(s.index)}`;if(s.index>o&&a.push(e.slice(o,s.index)),o=s.index+c.length,c.startsWith(`**`)&&c.endsWith(`**`)){a.push((0,C.jsx)(`strong`,{children:c.slice(2,-2)},l));continue}let u=/^\[([^\]\n]+)\]\s*\((https?:\/\/[^\s)]+)\)$/.exec(c);if(u){let e=v(u[2]);a.push(e?(0,C.jsx)(`a`,{className:i,href:e,rel:`noreferrer`,target:`_blank`,children:u[1]},l):u[1]);continue}if(c.startsWith(`@`)){let e=t.profilesByHandle.get(c.slice(1).toLowerCase());a.push(e?(0,C.jsx)(b,{profile:e,children:(0,C.jsx)(`span`,{className:n,children:c})},l):(0,C.jsx)(`a`,{className:n,href:`/profiles/${encodeURIComponent(c.slice(1))}`,children:c},l));continue}let d=c.startsWith(`(`)&&c.endsWith(`)`),f=E(c);if(d){let t=D(e,o),n=[...f,...t.references];t.references.length>0&&n.every(T)&&(f=n,o=t.cursor,r.lastIndex=o)}let p=f.map(e=>t.tweetsById.get(w(e))),m=f.length>0&&p.every(Boolean),h=p.filter(e=>!!e),g=h[0];if(d&&f.length>1&&!m){if(f.every(T)){let t=k(e,o);if(B(a,f,l)){o=t;continue}a.push(...f.flatMap((e,t)=>[t===0?``:`, `,(0,C.jsx)(P,{href:A(e),children:`source ${String(t+1)}`},`${l}-direct-${String(t)}`)])),o=t;continue}a.push(c);continue}if(g&&d&&m&&z(a,h,l)){o=k(e,o);continue}if(g&&d&&m){a.push(...R(h,l)),o=k(e,o);continue}if(g)a.push((0,C.jsx)(F,{tweet:g,children:d?`source`:c},l));else if(d&&f.length===1&&T(f[0]??``)){let t=k(e,o);if(B(a,f,l)){o=t;continue}a.push((0,C.jsx)(P,{href:A(f[0]),children:`source`},`${l}-direct`)),o=t;continue}else a.push(c)}return o<e.length&&a.push(e.slice(o)),a.map((e,t)=>(0,C.jsx)(S.Fragment,{children:e},typeof e==`string`?`${e}-${String(t)}`:t))}function H(e){return`conversations`in e&&`profile`in e}function U(e,t,n){let r=w(n.id);e.set(r,n),e.set(`tweet_${r}`,n),t.set(n.author.toLowerCase(),n.authorProfile)}function W(e){return{id:e.profileId,handle:e.author,displayName:e.name||e.author,bio:e.bio,followersCount:e.followersCount,avatarHue:210,avatarUrl:e.avatarUrl,createdAt:e.createdAt}}function le(e,t){return{id:e.id,url:e.url,source:`authored`,author:t.handle,name:t.displayName,authorProfile:t,createdAt:e.createdAt,text:e.text,entities:e.entities,likeCount:e.likeCount,liked:!1,bookmarked:!1,needsReply:!1,media:[]}}function G(e){let t=W(e);return{id:e.id,url:e.url,source:`mentions`,author:e.author,name:e.name||e.author,authorProfile:t,createdAt:e.createdAt,text:e.text,entities:e.entities,likeCount:e.likeCount,liked:!1,bookmarked:!1,needsReply:!1,media:[]}}function ue(e){let t=new Map,n=new Map;if(!e)return{tweetsById:t,profilesByHandle:n};if(H(e)){n.set(e.profile.handle.toLowerCase(),e.profile);for(let t of e.profiles??[])n.set(t.handle.toLowerCase(),t);for(let r of e.tweets)U(t,n,le(r,e.profile));for(let r of e.conversations)U(t,n,G(r));return{tweetsById:t,profilesByHandle:n}}for(let r of e.tweets)U(t,n,r);return{tweetsById:t,profilesByHandle:n}}function de({markdown:e,context:t,className:n}){let i=ue(t),a=e.replace(/\]\s*\r?\n\s*\((https?:\/\/[^\s)]+)\)/g,`]($1)`).split(/\r?\n/),o=[],s=[],c=()=>{s.length!==0&&(o.push((0,C.jsx)(`ul`,{className:`my-2.5 flex list-disc flex-col gap-1.5 pl-5 first:mt-0 marker:text-[var(--ink-soft)]`,children:s.map((e,t)=>(0,C.jsx)(`li`,{children:e},String(t)))},`list-${String(o.length)}`)),s=[])};for(let e of a){let t=e.trim();if(!t){c();continue}if(t.startsWith(`### `)){c(),o.push((0,C.jsx)(`h3`,{className:`mt-5 mb-1.5 text-[14px] font-bold uppercase tracking-wide text-[var(--ink-soft)] first:mt-0`,children:V(t.slice(4),i)},`h3-${String(o.length)}`));continue}if(t.startsWith(`## `)){c(),o.push((0,C.jsx)(`h2`,{className:`mt-6 mb-2 text-[18px] font-bold text-[var(--ink)] first:mt-0`,children:V(t.slice(3),i)},`h2-${String(o.length)}`));continue}if(t.startsWith(`# `)){c(),o.push((0,C.jsx)(`h1`,{className:`mt-0 mb-2.5 text-[20px] font-bold text-[var(--ink)]`,children:V(t.slice(2),i)},`h1-${String(o.length)}`));continue}if(/^[-*]\s+/.test(t)){s.push(V(re(t),i));continue}c(),o.push((0,C.jsx)(`p`,{className:`my-2.5 whitespace-pre-wrap first:mt-0 [overflow-wrap:anywhere]`,children:V(t,i)},`p-${String(o.length)}`))}return c(),(0,C.jsx)(`article`,{className:r(`max-w-none px-4 py-3 text-[15px] leading-[1.55] text-[var(--ink)]`,n),children:o})}async function fe(e,{label:t,statusMessages:n}){let r=n?.[e.status];if(r)return Error(r);let i=`${String(e.status)}${e.statusText?` ${e.statusText}`:``}`,a=``;try{if((e.headers.get(`content-type`)??``).includes(`application/json`)){let t=await e.json();if(t&&typeof t==`object`){let e=t;typeof e.message==`string`?a=e.message:typeof e.error==`string`&&(a=e.error)}}else a=(await e.text()).trim()}catch{a=``}return Error(a?`${t} (${i}): ${a}`:`${t} (${i})`)}function K(e){return e.reason instanceof Error?e.reason:new DOMException(`The operation was aborted`,`AbortError`)}async function pe(e,t){if(!t)return e.read();if(t.aborted)throw K(t);return new Promise((n,r)=>{let i=()=>{e.cancel(t.reason).catch(()=>void 0),r(K(t))};t.addEventListener(`abort`,i,{once:!0}),e.read().then(n,r).finally(()=>{t.removeEventListener(`abort`,i)})})}async function me({body:e,schema:t,onEvent:n,isTerminal:r=()=>!1,signal:i,prematureEofError:a=()=>Error(`Stream closed before a terminal event was received`)}){let o=e.getReader(),s=new TextDecoder,c=``,l=!1,u=async e=>{let i=e.trim();if(!i)return;let a=t.parse(JSON.parse(i));await n(a),r(a)&&(l=!0)};try{for(;;){let{done:e,value:t}=await pe(o,i);if(e)break;c+=s.decode(t,{stream:!0});let n=c.indexOf(`
|
|
4
4
|
`);for(;n>=0;)await u(c.slice(0,n)),c=c.slice(n+1),n=c.indexOf(`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";var n=e(t(),1),r=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),i=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),a=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),o=e=>{let t=a(e);return t.charAt(0).toUpperCase()+t.slice(1)},s={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},c=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},l=(0,n.createContext)({}),u=()=>(0,n.useContext)(l),d=(0,n.forwardRef)(({color:e,size:t,strokeWidth:i,absoluteStrokeWidth:a,className:o=``,children:l,iconNode:d,...f},p)=>{let{size:m=24,strokeWidth:h=2,absoluteStrokeWidth:g=!1,color:_=`currentColor`,className:v=``}=u()??{},y=a??g?Number(i??h)*24/Number(t??m):i??h;return(0,n.createElement)(`svg`,{ref:p,...s,width:t??m??s.width,height:t??m??s.height,stroke:e??_,strokeWidth:y,className:r(`lucide`,v,o),...!l&&!c(f)&&{"aria-hidden":`true`},...f},[...d.map(([e,t])=>(0,n.createElement)(e,t)),...Array.isArray(l)?l:[l]])}),f=(e,t)=>{let a=(0,n.forwardRef)(({className:a,...s},c)=>(0,n.createElement)(d,{ref:c,iconNode:t,className:r(`lucide-${i(o(e))}`,`lucide-${e}`,a),...s}));return a.displayName=o(e),a};export{f as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{Gt as n,Ht as r,Kt as i,M as a,Rn as o,Tn as s,Ut as c,Wt as l,cn as u,dt as d}from"./schemas-CaALBBpc.js";import{t as f}from"./createLucideIcon-JV8isFFR.js";import{t as p}from"./circle-check-C_Vq3ElD.js";import{t as m}from"./triangle-alert-CBL7s2pf.js";import{h,n as g,r as _}from"./query-client-DUP1ZzP7.js";import{ct as v,ft as y,vt as b}from"./index-Bqmo4MbK.js";var x=f(`circle-x`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m15 9-6 6`,key:`1uzhvr`}],[`path`,{d:`m9 9 6 6`,key:`z0biqf`}]]),S=f(`route`,[[`circle`,{cx:`6`,cy:`19`,r:`3`,key:`1kj8tv`}],[`path`,{d:`M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15`,key:`1d8sl`}],[`circle`,{cx:`18`,cy:`5`,r:`3`,key:`gq8acd`}]]),C=f(`square-terminal`,[[`path`,{d:`m7 11 2-2-2-2`,key:`1lz0vl`}],[`path`,{d:`M11 13h4`,key:`1p7l4v`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}]]),w=e(t()),T=o();async function E(){return _(`/api/data-sources`,void 0,h,`Data source status failed`)}function D(e){return e===`birdclaw`?b:e===`bird`?C:S}function O(e){return e===`ok`?`border-[color:color-mix(in_srgb,#22c55e_45%,var(--line))] bg-[color:color-mix(in_srgb,#22c55e_10%,var(--bg))] text-[color:color-mix(in_srgb,#22c55e_82%,var(--ink))]`:e===`warning`?`border-[color:color-mix(in_srgb,#f59e0b_50%,var(--line))] bg-[color:color-mix(in_srgb,#f59e0b_12%,var(--bg))] text-[color:color-mix(in_srgb,#f59e0b_82%,var(--ink))]`:`border-[color:color-mix(in_srgb,var(--alert)_55%,var(--line))] bg-[var(--alert-soft)] text-[var(--alert)]`}function k(e){return e===`ok`?p:e===`warning`?m:x}function A(e){return e===`birdclaw`?`local`:e}function j({source:e}){let t=D(e.source),n=k(e.status);return(0,T.jsxs)(`section`,{className:`min-w-0 border-b border-[var(--line)] px-4 py-4`,children:[(0,T.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,T.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[(0,T.jsx)(`div`,{className:`grid size-10 shrink-0 place-items-center rounded-md border border-[var(--line)] bg-[var(--bg-active)] text-[var(--ink)]`,children:(0,T.jsx)(t,{className:`size-5`,strokeWidth:1.9})}),(0,T.jsxs)(`div`,{className:`min-w-0`,children:[(0,T.jsx)(`h2`,{className:`truncate text-[16px] font-bold text-[var(--ink)]`,children:e.label}),(0,T.jsx)(`p`,{className:`truncate text-[13px] text-[var(--ink-soft)]`,children:e.installed===!1?`not installed`:e.detail})]})]}),(0,T.jsxs)(`span`,{className:a(`inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-0.5 text-[12px] font-bold`,O(e.status)),children:[(0,T.jsx)(n,{className:`size-3.5`,strokeWidth:2}),e.works?`works`:e.status]})]}),(0,T.jsx)(`div`,{className:`mt-4 flex flex-wrap gap-2`,children:e.accounts.length>0?e.accounts.map((e,t)=>(0,T.jsxs)(`span`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full border border-[var(--line)] bg-[var(--bg)] px-2.5 py-1 text-[12px] font-semibold text-[var(--ink-soft)]`,children:[e.app?(0,T.jsx)(`span`,{className:`text-[var(--ink-faint)]`,children:e.app}):null,(0,T.jsx)(`span`,{className:`truncate`,children:e.handle??(e.username?`@${e.username}`:e.id)}),e.isDefault?(0,T.jsx)(`span`,{className:`text-[var(--accent)]`,children:`default`}):null]},`${e.app??``}:${e.username??e.handle??e.id??String(t)}`)):(0,T.jsx)(`span`,{className:`text-[13px] text-[var(--ink-soft)]`,children:`no authenticated account detected`})})]})}function M({capability:e,sourcesByKind:t}){let n=[e.primary,...e.fallbacks];return(0,T.jsxs)(`div`,{className:`grid gap-3 border-b border-[var(--line)] px-4 py-4 min-[840px]:grid-cols-[220px_minmax(0,1fr)]`,children:[(0,T.jsxs)(`div`,{className:`min-w-0`,children:[(0,T.jsx)(`div`,{className:`font-bold text-[var(--ink)]`,children:e.label}),e.notes?(0,T.jsx)(`div`,{className:`mt-1 text-[12px] text-[var(--ink-soft)]`,children:e.notes}):null]}),(0,T.jsx)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:n.map((n,r)=>{let i=t.get(n);return(0,T.jsxs)(`div`,{className:a(`inline-flex items-center gap-2 rounded-full border px-3 py-1 text-[13px] font-semibold`,i?.works?`border-[color:color-mix(in_srgb,#22c55e_38%,var(--line))] text-[var(--ink)]`:`border-[var(--line)] text-[var(--ink-soft)]`),children:[(0,T.jsx)(`span`,{className:`text-[12px] text-[var(--ink-faint)]`,children:r===0?`primary`:`fallback ${String(r)}`}),(0,T.jsx)(`span`,{children:A(n)})]},`${e.key}:${n}:${String(r)}`)})})]})}function N(){let e=v({queryKey:g.dataSources,queryFn:E,staleTime:5*6e4}),t=e.data??null,o=e.isFetching,f=e.error,p=(0,w.useMemo)(()=>new Map((t?.sources??[]).map(e=>[e.source,e])),[t]);return(0,T.jsxs)(`section`,{className:`flex min-h-screen flex-col`,children:[(0,T.jsx)(`header`,{className:c,children:(0,T.jsxs)(`div`,{className:l,children:[(0,T.jsxs)(`div`,{children:[(0,T.jsx)(`h1`,{className:i,children:`Data Sources`}),(0,T.jsx)(`p`,{className:n,children:`Live auth, local archive, and automatic fallback order`})]}),(0,T.jsx)(`div`,{className:r,children:(0,T.jsxs)(`button`,{className:u,type:`button`,onClick:()=>void e.refetch(),disabled:o,children:[(0,T.jsx)(y,{className:a(`size-4`,o&&`animate-spin`)}),`Refresh`]})})]})}),f?(0,T.jsx)(`div`,{className:d,children:f instanceof Error?f.message:`Data sources unavailable`}):null,t?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`div`,{className:`grid border-t border-[var(--line)]`,children:t.sources.map(e=>(0,T.jsx)(j,{source:e},e.source))}),(0,T.jsxs)(`section`,{className:`min-h-0 flex-1`,children:[(0,T.jsxs)(`header`,{className:`border-b border-[var(--line)] px-4 py-3`,children:[(0,T.jsx)(`h2`,{className:`text-[16px] font-bold text-[var(--ink)]`,children:`Fallbacks`}),(0,T.jsx)(`p`,{className:`text-[13px] text-[var(--ink-soft)]`,children:`Calls try the next source when the current source cannot serve the request.`})]}),t.capabilities.map(e=>(0,T.jsx)(M,{capability:e,sourcesByKind:p},e.key))]})]}):o?(0,T.jsx)(`div`,{className:s,children:`Checking data sources...`}):null]})}export{N as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{An as n,Gt as r,Ht as i,Kt as a,M as o,Rn as s,Ut as c,Wt as l,Xt as u,an as d,cn as f,dt as p,on as m,pn as h,sn as g}from"./schemas-CaALBBpc.js";import{t as _}from"./circle-check-C_Vq3ElD.js";import{a as v,i as y,o as b,s as x,t as S}from"./client-stream-contracts-DcKcyZhg.js";import{t as C}from"./search-Dq5kYsxA.js";import{t as w}from"./sparkles-CQVlvHsZ.js";import{Q as T,bt as E,ft as D,l as O}from"./index-Bqmo4MbK.js";var k=e(t()),A=s(),j=[{value:`search`,label:`Live search`},{value:`all`,label:`All local`},{value:`home`,label:`Home`},{value:`mentions`,label:`Mentions`},{value:`authored`,label:`Authored`},{value:`likes`,label:`Likes`},{value:`bookmarks`,label:`Bookmarks`}],M=[{value:`auto`,label:`Auto`},{value:`bird`,label:`Bird`},{value:`xurl`,label:`xurl`},{value:`local`,label:`Local`}],N=2e4,P=200;function F(){return Error(`Discussion connection closed before completion. Retry to continue.`)}function I(e){return e instanceof Error?e.message:`Discussion failed`}function L(e,t){let n=new URL(`/api/search-discussion`,window.location.origin);return n.searchParams.set(`query`,e),n.searchParams.set(`source`,t.source),n.searchParams.set(`mode`,t.mode),n.searchParams.set(`includeDms`,String(t.includeDms)),n.searchParams.set(`limit`,String(N)),n.searchParams.set(`maxPages`,String(P)),t.question.trim()&&n.searchParams.set(`question`,t.question.trim()),t.refresh&&n.searchParams.set(`refresh`,`true`),n}function R({label:e,value:t,options:n,onChange:r}){return(0,A.jsxs)(`label`,{className:`relative min-w-0`,children:[(0,A.jsx)(`span`,{className:`pointer-events-none absolute left-3 top-1.5 z-10 text-[11px] font-semibold uppercase tracking-[0.08em] text-[var(--ink-soft)]`,children:e}),(0,A.jsx)(`select`,{"aria-label":e,className:o(h,`h-[54px] rounded-2xl bg-[var(--bg)] pb-1 pl-3 pr-9 pt-5 font-semibold text-[var(--ink)]`),value:t,onChange:e=>r(e.currentTarget.value),children:n.map(e=>(0,A.jsx)(`option`,{value:e.value,children:e.label},e.value))}),(0,A.jsx)(E,{"aria-hidden":`true`,className:`pointer-events-none absolute right-3 top-1/2 size-4 -translate-y-1/2 text-[var(--ink-soft)]`,strokeWidth:2})]})}function z(e){if(!e)return`Live keyword search with local memory.`;let t=e.counts;return[e.liveSearch?e.liveSearch.ok?`${e.liveSearch.source} ${String(e.liveSearch.count)} fetched`:`${e.liveSearch.source} failed`:`local`,`${String(t.search)} search`,`${String(t.home+t.mentions+t.authored)} timeline`,`${String(t.likes+t.bookmarks)} saved`,e.includeDms?`${String(t.dms)} DMs`:null].filter(Boolean).join(` · `)}function B(e,t,n,r,i){let[a,o]=(0,k.useState)(``),[s,c]=(0,k.useState)(null),[l,u]=(0,k.useState)(null),d=(0,k.useCallback)(()=>{o(``),c(null),u(null)},[]),{error:f,loading:p,run:m}=v({schema:y,request:(0,k.useCallback)((a,o)=>{let s=e.trim();return fetch(L(s,{source:t,mode:n,includeDms:r,question:i,refresh:o}),{signal:a})},[r,n,e,i,t]),onStart:d,onEvent:(0,k.useCallback)(e=>{if(e.type===`start`)c(e.context);else if(e.type===`delta`)o(t=>t+e.delta);else if(e.type===`done`)u(e.result),c(e.result.context),o(e.result.markdown);else if(e.type===`error`)throw Error(e.error)},[]),isTerminal:S,errorLabel:`Discussion request failed`,emptyBodyMessage:`Discussion request failed: empty response body`,prematureEofError:F,formatError:I});return{context:s,error:f,loading:p,markdown:a,result:l,run:(0,k.useCallback)((t=!1)=>{e.trim()&&m(t)},[e,m])}}function V(){let e=O.useSearch(),t=O.useNavigate();return(0,A.jsx)(H,{searchState:e,onSearchChange:(e,n)=>void t({search:e,replace:n?.replace})})}function H({searchState:e,onSearchChange:t}={}){let[s,h]=(0,k.useState)(()=>T({})),v=e??s,y=(e,n)=>t?t(e,n):h(e),{q:S,question:E,source:O,mode:N,includeDms:P}=v,[F,I]=(0,k.useState)(``),L=(0,k.useRef)(!1),{context:V,error:H,loading:U,markdown:W,result:G,run:K}=B(F,O,N,P,E),q=(0,k.useMemo)(()=>z(G?.context??V),[V,G]);function J(e){e.preventDefault();let t=S.trim();t&&(L.current=!0,I(t),t===F&&(L.current=!1,K(!1)))}return(0,k.useEffect)(()=>{!F||!L.current||(L.current=!1,K(!1))},[K,F]),(0,A.jsxs)(`div`,{className:`flex min-h-screen flex-col`,children:[(0,A.jsxs)(`header`,{className:c,children:[(0,A.jsxs)(`div`,{className:l,children:[(0,A.jsxs)(`div`,{className:`min-w-0`,children:[(0,A.jsx)(`h1`,{className:a,children:`Discuss`}),(0,A.jsx)(`p`,{className:r,children:q})]}),(0,A.jsx)(`div`,{className:i,children:(0,A.jsxs)(`button`,{type:`button`,className:f,onClick:()=>K(!0),disabled:U||!F,children:[(0,A.jsx)(D,{className:o(`size-4`,U&&`animate-spin`),"aria-hidden":`true`}),`Refresh`]})})]}),(0,A.jsxs)(`form`,{className:`grid gap-2 px-4 pb-3 md:grid-cols-[minmax(220px,1fr)_minmax(180px,0.8fr)_auto]`,onSubmit:J,children:[(0,A.jsxs)(`label`,{className:g,children:[(0,A.jsx)(C,{className:d,strokeWidth:2}),(0,A.jsx)(`input`,{className:m,placeholder:`Keywords`,value:S,onChange:e=>y({...v,q:e.currentTarget.value},{replace:!0})})]}),(0,A.jsx)(`input`,{className:n,placeholder:`Optional question`,value:E,onChange:e=>y({...v,question:e.currentTarget.value},{replace:!0})}),(0,A.jsxs)(`button`,{type:`submit`,className:u,disabled:U||!S.trim(),children:[(0,A.jsx)(w,{className:`size-4`,"aria-hidden":`true`}),`Discuss`]}),(0,A.jsxs)(`div`,{className:`grid gap-2 md:col-span-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]`,children:[(0,A.jsx)(R,{label:`Source`,options:j,value:O,onChange:e=>y({...v,source:e})}),(0,A.jsx)(R,{label:`Mode`,options:M,value:N,onChange:e=>y({...v,mode:e})}),(0,A.jsxs)(`label`,{className:`inline-flex h-[54px] items-center gap-2 rounded-2xl border border-[var(--line)] bg-[var(--bg)] px-3 text-[13px] font-medium text-[var(--ink-soft)]`,children:[(0,A.jsx)(`input`,{type:`checkbox`,checked:P,onChange:e=>y({...v,includeDms:e.currentTarget.checked})}),`DMs`]})]})]})]}),H?(0,A.jsx)(`div`,{className:p,children:H}):null,(0,A.jsx)(`div`,{className:`border-b border-[var(--line)] px-4 py-2 text-[13px] text-[var(--ink-soft)]`,children:(0,A.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[U?(0,A.jsx)(x,{className:`size-4 animate-spin`,"aria-hidden":`true`}):W?(0,A.jsx)(_,{className:`size-4`,"aria-hidden":`true`}):(0,A.jsx)(w,{className:`size-4`,"aria-hidden":`true`}),U?`Searching and streaming`:G?`${G.cached?`Cached`:`Ready`} · ${G.context.query}`:`Ready`]})}),W?(0,A.jsx)(b,{context:G?.context??V,markdown:W}):(0,A.jsx)(`div`,{className:`px-4 py-5 text-[14px] text-[var(--ink-soft)]`,children:U?`Waiting for the first tokens...`:`Search to begin.`})]})}export{H as DiscussRouteView,V as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{Dn as n,Gt as r,Kt as i,M as a,Mn as o,On as s,Rn as c,Ut as l,Wt as u,an as d,dn as f,fn as p,kn as ee,on as te,sn as ne}from"./schemas-CaALBBpc.js";import{t as re}from"./search-Dq5kYsxA.js";import{A as ie,a as ae,b as m,d as h,n as g,r as _,s as v}from"./query-client-DUP1ZzP7.js";import{$ as y,A as b,O as oe,ct as x,d as se,f as ce,k as le,ot as S,p as ue,st as C,u as w}from"./index-Bqmo4MbK.js";var T=e(t()),E=c(),de=[{value:`all`,label:`All`},{value:`unreplied`,label:`Unreplied`},{value:`replied`,label:`Replied`}],fe=[{value:`recent`,label:`Newest`},{value:`followers`,label:`Followers`}],pe=[{value:`all`,label:`All`},{value:`accepted`,label:`Accepted`},{value:`requests`,label:`Requests`}],D=`flex h-[46px] shrink-0 items-center gap-2 rounded-md border border-[var(--line)] bg-[var(--bg)] px-3 py-0 text-[14px] text-[var(--ink)] outline-none transition-colors duration-150 focus-within:border-[var(--accent)] focus-within:shadow-[0_0_0_1px_var(--accent)]`;function O(){let e=w.useSearch(),t=w.useNavigate();return(0,E.jsx)(k,{searchState:e,onSearchChange:(e,n)=>void t({search:e,replace:n?.replace})})}function k({searchState:e,onSearchChange:t}={}){let c=m(),[w,O]=(0,T.useState)(()=>y({})),k=e??w,A=(e,n)=>t?t(e,n):O(e),j=k.inbox,M=k.reply,N=k.minFollowers,P=k.minInfluence,F=k.sort,I=k.q,L=k.conversation||void 0,[R,z]=(0,T.useState)(``),B=x({queryKey:g.status,queryFn:({signal:e})=>ae({signal:e})}).data??null,V=S(B?.accounts),H=se(I,180),U=[...g.dms,{inboxFilter:j,replyFilter:M,minFollowers:N,minInfluenceScore:P,sort:F,search:H,selectedAccountId:V??null,selectedConversationId:L??null}],W=x({queryKey:U,queryFn:({signal:e})=>{let t=new URL(`/api/query`,window.location.origin);return t.searchParams.set(`resource`,`dms`),t.searchParams.set(`inbox`,j),t.searchParams.set(`replyFilter`,M),t.searchParams.set(`sort`,F),N.trim()&&t.searchParams.set(`minFollowers`,N.trim()),P.trim()&&t.searchParams.set(`minInfluenceScore`,P.trim()),V&&j!==`requests`&&t.searchParams.set(`account`,V),L&&t.searchParams.set(`conversationId`,L),H.trim()&&t.searchParams.set(`search`,H.trim()),_(t,{signal:e},h,`Direct messages unavailable`)},placeholderData:ie,staleTime:5*6e4}),G=W.data,K=G?.resource===`dms`?G:null,q=K?.items??[],me=K?.selectedConversation?.messages??[],J=K?.selectedConversation?.conversation.id;(0,T.useEffect)(()=>{if(!W.data)return;let e=J??q[0]?.id,t=L&&q.some(e=>e.id===L)?L:e;t&&t!==L&&A({...k,conversation:t},{replace:!0})},[W.data,q,J]);let Y=q.find(e=>e.id===L)??null,he=!!(!W.isError&&L&&J&&L!==J),X=(0,T.useMemo)(()=>B?`${String(B.stats.dms)} conversations cached locally`:`Loading direct messages...`,[B]),Z=C({mutationFn:({conversationId:e,text:t})=>v({kind:`replyDm`,conversationId:e,text:t}),onMutate:async({conversationId:e,text:t})=>{await c.cancelQueries({queryKey:U});let n=c.getQueryData(U);if(!n||n.resource!==`dms`||!Y)return{previous:n};let r=new Date().toISOString(),i=B?.accounts.find(e=>e.id===Y.accountId),a=(i?.handle??Y.accountHandle).replace(/^@/,``),o={id:`optimistic-${r}`,conversationId:e,text:t,createdAt:r,direction:`outbound`,isReplied:!0,mediaCount:0,sender:{id:`local-${Y.accountId}`,handle:a,displayName:i?.name??a,bio:``,followersCount:0,avatarHue:18,createdAt:r}};return c.setQueryData(U,{...n,items:n.items.map(n=>n.id===e?{...n,lastMessageAt:r,lastMessagePreview:t,needsReply:!1,unreadCount:0}:n),selectedConversation:n.selectedConversation?{...n.selectedConversation,messages:[...n.selectedConversation.messages,o]}:n.selectedConversation}),{previous:n}},onError:(e,t,n)=>{n?.previous&&c.setQueryData(U,n.previous)},onSettled:()=>Promise.all([c.invalidateQueries({queryKey:g.dms}),c.invalidateQueries({queryKey:g.status})])});async function ge(e){let t=R.trim();if(!(!t||!Y)){z(``);try{await Z.mutateAsync({conversationId:e,text:t}),A({...k,conversation:e})}catch{z(t)}}}function _e(){Promise.all([c.invalidateQueries({queryKey:g.dms}),c.invalidateQueries({queryKey:g.status})])}let ve=W.isPending,Q=W.error?W.error instanceof Error?W.error.message:`Messages unavailable`:null,$=Z.error?Z.error instanceof Error?Z.error.message:`Reply failed`:null;return(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`header`,{className:l,children:[(0,E.jsxs)(`div`,{className:u,children:[(0,E.jsxs)(`div`,{className:`flex min-w-0 flex-col`,children:[(0,E.jsx)(`h1`,{className:i,children:`Messages`}),(0,E.jsx)(`p`,{className:r,children:X})]}),(0,E.jsx)(ce,{accounts:B?.accounts,kind:`dms`,label:`Sync DMs`,onSynced:_e,syncOptions:{inbox:j,limit:j===`requests`?200:50,maxPages:j===`requests`?3:1}})]}),(0,E.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 px-4 pb-3`,children:[(0,E.jsx)(`div`,{className:p,"aria-label":`DM inbox`,children:pe.map(e=>(0,E.jsx)(`button`,{"aria-pressed":j===e.value,className:a(f,j===e.value&&`bg-[var(--bg-active)] text-[var(--ink)]`),onClick:()=>A({...k,inbox:e.value}),type:`button`,children:e.label},e.value))}),(0,E.jsxs)(`label`,{className:a(ne,`flex-1 min-w-[200px]`),children:[(0,E.jsx)(re,{className:d,strokeWidth:2}),(0,E.jsx)(`input`,{className:te,onChange:e=>A({...k,q:e.target.value},{replace:!0}),placeholder:`Search DMs`,value:I})]}),(0,E.jsxs)(`label`,{className:a(D,`w-[156px]`),children:[(0,E.jsx)(`span`,{className:`shrink-0 text-[12px] font-semibold text-[var(--ink-soft)]`,children:`Followers`}),(0,E.jsx)(`input`,{className:`min-w-0 flex-1 border-0 bg-transparent text-right text-[14px] text-[var(--ink)] outline-none placeholder:text-[var(--ink-soft)]`,inputMode:`numeric`,onChange:e=>A({...k,minFollowers:e.target.value},{replace:!0}),placeholder:`Any`,value:N})]}),(0,E.jsxs)(`label`,{className:a(D,`w-[132px]`),children:[(0,E.jsx)(`span`,{className:`shrink-0 text-[12px] font-semibold text-[var(--ink-soft)]`,children:`Score`}),(0,E.jsx)(`input`,{className:`min-w-0 flex-1 border-0 bg-transparent text-right text-[14px] text-[var(--ink)] outline-none placeholder:text-[var(--ink-soft)]`,inputMode:`numeric`,onChange:e=>A({...k,minInfluence:e.target.value},{replace:!0}),placeholder:`Any`,value:P})]}),(0,E.jsx)(`div`,{className:p,children:fe.map(e=>(0,E.jsx)(`button`,{className:a(f,e.value===F&&`bg-[var(--bg-active)] text-[var(--ink)]`),onClick:()=>A({...k,sort:e.value}),type:`button`,children:e.label},e.value))})]}),(0,E.jsx)(`div`,{className:ee,"aria-label":`DM reply filter`,children:de.map(e=>{let t=M===e.value;return(0,E.jsx)(`button`,{type:`button`,"aria-pressed":t,className:a(n,t&&`text-[var(--ink)] font-bold`),onClick:()=>A({...k,reply:e.value}),children:(0,E.jsxs)(`span`,{className:`relative inline-flex flex-col items-center justify-center py-1`,children:[e.value,t?(0,E.jsx)(`span`,{className:s}):null]})},e.value)})})]}),$?(0,E.jsx)(`p`,{className:a(o,`px-4 py-2 text-red-500`),children:$}):null,ve&&q.length===0||he?(0,E.jsx)(b,{detail:`Reading local conversations and reply state`,label:`Loading messages`}):Q?(0,E.jsx)(le,{action:(0,E.jsx)(`button`,{className:`rounded-full bg-[var(--accent)] px-4 py-1.5 text-[14px] font-bold text-white`,onClick:()=>void W.refetch(),type:`button`,children:`Retry`}),message:Q,title:`Could not load messages`}):q.length===0?(0,E.jsx)(oe,{detail:`Sync DMs or broaden the filters to find a conversation.`,label:`No conversations in this view`}):(0,E.jsx)(ue,{conversations:q,onReplyDraftChange:z,onReplySend:ge,onSelectConversation:e=>A({...k,conversation:e}),replyDraft:R,selectedConversation:Y,selectedMessages:me})]})}export{k as DmsRouteView,O as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./chunk-C0phanGV.js";import{t}from"./react-nBylq1U5.js";import{An as n,Dn as r,Gt as i,Kt as a,M as o,Mn as s,On as c,Rn as l,Ut as u,Wt as d,Xt as f,cn as p,ht as m,jn as h,kn as g,ut as _}from"./schemas-CaALBBpc.js";import{t as v}from"./sparkles-CQVlvHsZ.js";import{A as y,a as b,b as x,f as S,n as C,r as ee,s as w}from"./query-client-DUP1ZzP7.js";import{ct as T,et as E,h as D,m as O,ot as k,st as A}from"./index-Bqmo4MbK.js";var j=e(t()),M=l(),N=[{value:`mixed`,label:`Mixed`},{value:`mentions`,label:`Mentions`},{value:`dms`,label:`DMs`}];function P(){let e=O.useSearch(),t=O.useNavigate();return(0,M.jsx)(F,{searchState:e,onSearchChange:(e,n)=>void t({search:e,replace:n?.replace})})}function F({searchState:e,onSearchChange:t}={}){let l=x(),[O,P]=(0,j.useState)(()=>E({})),F=e??O,I=(e,n)=>t?t(e,n):P(e),{kind:L,minScore:R,hideLowSignal:z}=F,[B,V]=(0,j.useState)(null),[H,U]=(0,j.useState)(``),[W,G]=(0,j.useState)(!1),[K,q]=(0,j.useState)(null),J=T({queryKey:C.status,queryFn:({signal:e})=>b({signal:e})}).data??null,Y=k(J?.accounts),X=T({queryKey:[...C.inbox,{hideLowSignal:z,kind:L,minScore:R,selectedAccountId:Y??null}],queryFn:async({signal:e})=>{let t=new URL(`/api/inbox`,window.location.origin);return t.searchParams.set(`kind`,L),t.searchParams.set(`minScore`,R),Y&&t.searchParams.set(`account`,Y),z&&t.searchParams.set(`hideLowSignal`,`1`),ee(t,{signal:e},S,`Inbox request failed`)},placeholderData:y,staleTime:5*6e4}),Z=X.data?.items??[],Q=X.data?.stats??null,$=A({mutationFn:()=>w({kind:`scoreInbox`,scoreKind:L,account:Y,limit:8}),onSuccess:()=>l.invalidateQueries({queryKey:C.inbox})}),te=(0,j.useMemo)(()=>!J||!Q?`Ranking unreplied mentions and DMs...`:`${String(Q.total)} in queue · ${String(Q.openai)} OpenAI scored · ${J.transport.statusText}`,[J,Q]);async function ne(){await $.mutateAsync()}async function re(e){if(H.trim()){G(!0),q(null);try{await w(e.entityKind===`dm`?{kind:`replyDm`,conversationId:e.entityId,text:H}:{kind:`replyTweet`,accountId:e.accountId,tweetId:e.entityId,text:H}),U(``),V(null),await l.invalidateQueries({queryKey:C.inbox})}catch(e){q(e instanceof Error?e.message:`Reply failed`)}finally{G(!1)}}}return(0,M.jsxs)(M.Fragment,{children:[(0,M.jsxs)(`header`,{className:u,children:[(0,M.jsxs)(`div`,{className:d,children:[(0,M.jsxs)(`div`,{className:`flex min-w-0 flex-col`,children:[(0,M.jsx)(`h1`,{className:a,children:`Inbox`}),(0,M.jsx)(`p`,{className:i,children:te})]}),(0,M.jsxs)(`button`,{className:f,disabled:$.isPending,onClick:()=>void ne(),type:`button`,children:[(0,M.jsx)(v,{className:`size-4`,strokeWidth:2.2}),$.isPending?`Scoring...`:`Score with OpenAI`]})]}),(0,M.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 px-4 pb-3`,children:[(0,M.jsx)(`input`,{className:o(n,h),inputMode:`numeric`,onChange:e=>I({...F,minScore:e.target.value},{replace:!0}),placeholder:`Min AI score`,value:R}),(0,M.jsx)(`button`,{className:p,onClick:()=>I({...F,hideLowSignal:!z}),type:`button`,"aria-pressed":z,children:z?`Hide low-signal`:`Show all`})]}),(0,M.jsx)(`div`,{className:g,children:N.map(e=>{let t=L===e.value;return(0,M.jsx)(`button`,{type:`button`,"aria-pressed":t,className:o(r,t&&`text-[var(--ink)] font-bold`),onClick:()=>I({...F,kind:e.value}),children:(0,M.jsxs)(`span`,{className:`relative inline-flex flex-col items-center justify-center py-1`,children:[e.value,t?(0,M.jsx)(`span`,{className:c}):null]})},e.value)})})]}),K?(0,M.jsx)(`p`,{className:o(s,`px-4 py-2 text-red-500`),children:K}):null,(0,M.jsxs)(`section`,{className:m,children:[Z.length===0?(0,M.jsx)(`div`,{className:_,children:`Inbox clear.`}):null,Z.map(e=>(0,M.jsx)(D,{isReplying:B===e.id,item:e,onReplyChange:U,onReplySend:()=>void re(e),onReplyToggle:()=>{if(q(null),B===e.id){V(null),U(``);return}V(e.id),U(``)},replyDraft:B===e.id?H:``},e.id))]}),W?(0,M.jsx)(`p`,{className:o(s,`px-4 py-2`),children:`Sending reply...`}):null]})}export{F as InboxRouteView,P as component};
|