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.
Files changed (77) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +3 -1
  3. package/dist/cli/birdclaw.js +189 -17
  4. package/dist/client/assets/AvatarChip-BN3b4MhM.js +1 -0
  5. package/dist/client/assets/ProfilePreview-CHbT0U9a.js +1 -0
  6. package/dist/client/assets/SavedTimelineView-mGXE9EYJ.js +1 -0
  7. package/dist/client/assets/SmartTimestamp-DG8XJKUz.js +1 -0
  8. package/dist/client/assets/TimelineRouteFrame-BmMC7qLj.js +1 -0
  9. package/dist/client/assets/blocks-CawnB0mN.js +1 -0
  10. package/dist/client/assets/{bookmarks-Cprrli-V.js → bookmarks-DZIMTKEp.js} +1 -1
  11. package/dist/client/assets/chunk-C0phanGV.js +1 -0
  12. package/dist/client/assets/circle-check-C_Vq3ElD.js +1 -0
  13. package/dist/client/assets/{client-stream-contracts-D1QUdWfh.js → client-stream-contracts-DcKcyZhg.js} +1 -1
  14. package/dist/client/assets/createLucideIcon-JV8isFFR.js +1 -0
  15. package/dist/client/assets/data-sources-BJUT2qaO.js +1 -0
  16. package/dist/client/assets/discuss-DMPJVaRk.js +1 -0
  17. package/dist/client/assets/dms-BfPFG4Qr.js +1 -0
  18. package/dist/client/assets/inbox-DmeYJ7tt.js +1 -0
  19. package/dist/client/assets/index-Bqmo4MbK.js +31 -0
  20. package/dist/client/assets/likes-BxVL-j_C.js +1 -0
  21. package/dist/client/assets/links-BeA1Wt8F.js +1 -0
  22. package/dist/client/assets/mapbox-BTSMNSry.js +2 -0
  23. package/dist/client/assets/{mapbox-gl-WUhsQcSS.js → mapbox-gl-CPemBIlO.js} +1 -1
  24. package/dist/client/assets/{mentions-C3JYXV2K.js → mentions-DBrY-UPg.js} +1 -1
  25. package/dist/client/assets/network-map-MqbE164r.js +2 -0
  26. package/dist/client/assets/profile-analyze-DEA75Reh.js +1 -0
  27. package/dist/client/assets/{profile-hydration-client-BQyC5--e.js → profile-hydration-client-BNe0sUmK.js} +1 -1
  28. package/dist/client/assets/profiles._handle-K34ofz9U.js +1 -0
  29. package/dist/client/assets/query-client-DUP1ZzP7.js +17 -0
  30. package/dist/client/assets/rate-limits-B8Wmpt9r.js +1 -0
  31. package/dist/client/assets/react-dom-DHl6Ug7F.js +1 -0
  32. package/dist/client/assets/react-nBylq1U5.js +1 -0
  33. package/dist/client/assets/{repeat-2-CQ0lek01.js → repeat-2-xCwHM9hD.js} +1 -1
  34. package/dist/client/assets/{routes-CeIv5bkV.js → routes-Bl-Lw2hN.js} +1 -1
  35. package/dist/client/assets/schemas-CaALBBpc.js +64 -0
  36. package/dist/client/assets/search-Dq5kYsxA.js +1 -0
  37. package/dist/client/assets/{sparkles-Gx_BHkDX.js → sparkles-CQVlvHsZ.js} +1 -1
  38. package/dist/client/assets/{styles-DTMajAmk.css → styles-zihNNCGg.css} +2 -2
  39. package/dist/client/assets/today-DFvZ0Ys5.js +1 -0
  40. package/dist/client/assets/{triangle-alert-DJPCW6jQ.js → triangle-alert-CBL7s2pf.js} +1 -1
  41. package/dist/client/assets/useTimelineRouteData-Cpf-Jqsx.js +1 -0
  42. package/dist/client/assets/{users-DI3w8Mol.js → users-CHbKlqUr.js} +1 -1
  43. package/dist/server/assets/{_tanstack-start-manifest_v-CjYYXQ8Z.js → _tanstack-start-manifest_v-CVfs07C8.js} +35 -35
  44. package/dist/server/assets/{empty-plugin-adapters-D9UWiqvJ.js → empty-plugin-adapters-DzrEkdBF.js} +1 -1
  45. package/dist/server/assets/{router-DP7iZD-q.js → router-D8AUR_Gz.js} +114 -38
  46. package/dist/server/assets/start-FaDOTmto.js +4 -0
  47. package/dist/server/server.js +3413 -50
  48. package/package.json +1 -1
  49. package/dist/client/assets/AvatarChip-C8zELEVt.js +0 -1
  50. package/dist/client/assets/ProfilePreview-CsiLpFrb.js +0 -1
  51. package/dist/client/assets/SavedTimelineView-DE4CXK-h.js +0 -1
  52. package/dist/client/assets/SmartTimestamp-BypN4KPq.js +0 -1
  53. package/dist/client/assets/TimelineRouteFrame-D6djyMAT.js +0 -1
  54. package/dist/client/assets/blocks-h27nF3TL.js +0 -1
  55. package/dist/client/assets/circle-check-BCK_qvXt.js +0 -1
  56. package/dist/client/assets/createLucideIcon-CMLcIxOz.js +0 -1
  57. package/dist/client/assets/data-sources-Beb3JZkl.js +0 -1
  58. package/dist/client/assets/discuss-ciwVz7Fo.js +0 -1
  59. package/dist/client/assets/dms-BZ3GUPey.js +0 -1
  60. package/dist/client/assets/inbox-Dajdut79.js +0 -1
  61. package/dist/client/assets/index-a1ZAcWSa.js +0 -31
  62. package/dist/client/assets/likes-CxZZqiZC.js +0 -1
  63. package/dist/client/assets/links-CsWS9uKL.js +0 -1
  64. package/dist/client/assets/mapbox-dx7h2mOm.js +0 -2
  65. package/dist/client/assets/network-map-D4XA7TTO.js +0 -2
  66. package/dist/client/assets/profile-analyze-QAznTMjZ.js +0 -1
  67. package/dist/client/assets/profiles._handle-qntfbCE1.js +0 -1
  68. package/dist/client/assets/query-client-DZ5C7UNo.js +0 -17
  69. package/dist/client/assets/rate-limits-eHs_5dDB.js +0 -1
  70. package/dist/client/assets/react-BwGzW7mM.js +0 -1
  71. package/dist/client/assets/react-dom-DEMAB80t.js +0 -1
  72. package/dist/client/assets/rolldown-runtime-B-9mzPXz.js +0 -1
  73. package/dist/client/assets/schemas-CntsNLmN.js +0 -64
  74. package/dist/client/assets/search-C_LqodNa.js +0 -1
  75. package/dist/client/assets/today-DxppbQGF.js +0 -1
  76. package/dist/client/assets/useTimelineRouteData-CWvBmHLE.js +0 -1
  77. 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
 
@@ -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 matches = codecs.filter((codec) => codec.matchesPath(relativePath));
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 = 3;
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(shardEntries.map(([relativePath]) => relativePath))
4286
+ () => new Set(shardParts.map(({ relativePath }) => relativePath))
4227
4287
  );
4228
4288
  const files = yield* Effect5.forEach(
4229
- shardEntries,
4230
- ([relativePath, rows]) => writeJsonlFileEffect(resolvedRepoPath, relativePath, rows),
4231
- { concurrency: "unbounded" }
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: "unbounded" }
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("https://api.openai.com/v1/responses", {
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(Effect6.mapError(toError3));
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: false,
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("https://api.openai.com/v1/chat/completions", {
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(Effect41.mapError(toError15));
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(`OpenAI request failed: ${response.status}`)
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-CntsNLmN.js";import{t}from"./SavedTimelineView-DE4CXK-h.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};
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"./rolldown-runtime-B-9mzPXz.js";import{t}from"./react-BwGzW7mM.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-CntsNLmN.js";import{t as h}from"./createLucideIcon-CMLcIxOz.js";import{r as g,t as _}from"./AvatarChip-C8zELEVt.js";import{i as v,n as y,r as ee,t as b,u as te}from"./ProfilePreview-CsiLpFrb.js";import{t as ne}from"./SmartTimestamp-BypN4KPq.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(`
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};