birdclaw 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +55 -5
  3. package/bin/birdclaw.mjs +50 -11
  4. package/package.json +9 -7
  5. package/public/birdclaw-mark.png +0 -0
  6. package/scripts/browser-perf.mjs +400 -0
  7. package/scripts/build-docs-site.mjs +940 -0
  8. package/scripts/docs-site-assets.mjs +311 -0
  9. package/scripts/run-vitest.mjs +21 -0
  10. package/scripts/sanitize-node-options.mjs +23 -0
  11. package/scripts/start-test-server.mjs +42 -0
  12. package/src/cli.ts +422 -14
  13. package/src/components/AccountSwitcher.tsx +186 -0
  14. package/src/components/AppNav.tsx +29 -9
  15. package/src/components/AvatarChip.tsx +9 -3
  16. package/src/components/BrandMark.tsx +67 -0
  17. package/src/components/ConversationThread.tsx +11 -10
  18. package/src/components/DmWorkspace.tsx +39 -14
  19. package/src/components/FeedState.tsx +147 -0
  20. package/src/components/InboxCard.tsx +14 -2
  21. package/src/components/LinkPreviewCard.tsx +40 -18
  22. package/src/components/MarkdownViewer.tsx +452 -0
  23. package/src/components/SavedTimelineView.tsx +64 -56
  24. package/src/components/SyncNowButton.tsx +137 -0
  25. package/src/components/ThemeSlider.tsx +49 -93
  26. package/src/components/TimelineCard.tsx +364 -136
  27. package/src/components/TimelineRouteFrame.tsx +170 -0
  28. package/src/components/TweetMediaGrid.tsx +170 -24
  29. package/src/components/TweetRichText.tsx +28 -13
  30. package/src/components/account-selection.ts +64 -0
  31. package/src/components/useTimelineRouteData.ts +153 -0
  32. package/src/lib/account-sync-job.ts +654 -0
  33. package/src/lib/actions-transport.ts +216 -146
  34. package/src/lib/api-client.ts +304 -0
  35. package/src/lib/archive-finder.ts +72 -53
  36. package/src/lib/archive-import.ts +1377 -1298
  37. package/src/lib/authored-live.ts +261 -204
  38. package/src/lib/avatar-cache.ts +159 -44
  39. package/src/lib/backup.ts +1532 -951
  40. package/src/lib/bird-actions.ts +139 -57
  41. package/src/lib/bird-command.ts +101 -28
  42. package/src/lib/bird.ts +549 -194
  43. package/src/lib/blocklist.ts +40 -23
  44. package/src/lib/blocks-write.ts +129 -80
  45. package/src/lib/blocks.ts +165 -97
  46. package/src/lib/bookmark-sync-job.ts +250 -160
  47. package/src/lib/conversation-surface.ts +205 -0
  48. package/src/lib/db.ts +35 -3
  49. package/src/lib/dms-live.ts +720 -66
  50. package/src/lib/effect-runtime.ts +45 -0
  51. package/src/lib/follow-graph.ts +224 -180
  52. package/src/lib/http-effect.ts +222 -0
  53. package/src/lib/inbox.ts +74 -43
  54. package/src/lib/link-index.ts +88 -76
  55. package/src/lib/link-insights.ts +24 -0
  56. package/src/lib/link-preview-metadata.ts +472 -52
  57. package/src/lib/media-fetch.ts +286 -213
  58. package/src/lib/mention-threads-live.ts +352 -288
  59. package/src/lib/mentions-live.ts +390 -342
  60. package/src/lib/moderation-target.ts +102 -65
  61. package/src/lib/moderation-write.ts +77 -18
  62. package/src/lib/mutes-write.ts +129 -80
  63. package/src/lib/mutes.ts +8 -1
  64. package/src/lib/openai.ts +84 -53
  65. package/src/lib/period-digest.ts +953 -0
  66. package/src/lib/profile-affiliation-hydration.ts +93 -54
  67. package/src/lib/profile-hydration.ts +124 -72
  68. package/src/lib/profile-replies.ts +60 -43
  69. package/src/lib/profile-resolver.ts +402 -294
  70. package/src/lib/queries.ts +1024 -189
  71. package/src/lib/research.ts +165 -120
  72. package/src/lib/sqlite.ts +1 -0
  73. package/src/lib/timeline-collections-live.ts +204 -167
  74. package/src/lib/timeline-live.ts +60 -39
  75. package/src/lib/tweet-lookup.ts +30 -19
  76. package/src/lib/types.ts +38 -1
  77. package/src/lib/ui.ts +41 -10
  78. package/src/lib/url-expansion.ts +226 -55
  79. package/src/lib/url-safety.ts +220 -0
  80. package/src/lib/web-sync.ts +511 -0
  81. package/src/lib/whois.ts +166 -147
  82. package/src/lib/x-web.ts +102 -71
  83. package/src/lib/xurl.ts +681 -411
  84. package/src/routeTree.gen.ts +63 -0
  85. package/src/routes/__root.tsx +25 -5
  86. package/src/routes/api/action.tsx +127 -78
  87. package/src/routes/api/avatar.tsx +39 -30
  88. package/src/routes/api/blocks.tsx +26 -23
  89. package/src/routes/api/conversation.tsx +25 -14
  90. package/src/routes/api/inbox.tsx +27 -21
  91. package/src/routes/api/link-insights.tsx +31 -25
  92. package/src/routes/api/link-preview.tsx +25 -21
  93. package/src/routes/api/period-digest.tsx +123 -0
  94. package/src/routes/api/profile-hydrate.tsx +31 -28
  95. package/src/routes/api/query.tsx +79 -55
  96. package/src/routes/api/status.tsx +18 -10
  97. package/src/routes/api/sync.tsx +105 -0
  98. package/src/routes/dms.tsx +195 -55
  99. package/src/routes/inbox.tsx +32 -19
  100. package/src/routes/index.tsx +21 -127
  101. package/src/routes/links.tsx +50 -5
  102. package/src/routes/mentions.tsx +21 -127
  103. package/src/routes/today.tsx +441 -0
  104. package/src/styles.css +74 -11
  105. package/vite.config.ts +8 -0
package/src/lib/db.ts CHANGED
@@ -131,6 +131,7 @@ export interface DmConversationsTable {
131
131
  account_id: string;
132
132
  participant_profile_id: string;
133
133
  title: string;
134
+ inbox_kind: "accepted" | "request";
134
135
  last_message_at: string;
135
136
  unread_count: number;
136
137
  needs_reply: number;
@@ -429,6 +430,7 @@ const BASE_SCHEMA_SQL = `
429
430
  account_id text not null,
430
431
  participant_profile_id text not null,
431
432
  title text not null,
433
+ inbox_kind text not null default 'accepted',
432
434
  last_message_at text not null,
433
435
  unread_count integer not null default 0,
434
436
  needs_reply integer not null default 0
@@ -574,11 +576,13 @@ const BASE_SCHEMA_SQL = `
574
576
 
575
577
  const INDEX_SQL = `
576
578
  create index if not exists idx_tweets_kind_created on tweets(kind, created_at desc);
579
+ create index if not exists idx_tweets_created on tweets(created_at desc);
577
580
  create index if not exists idx_tweets_account_created on tweets(account_id, created_at desc);
578
581
  create index if not exists idx_tweets_quoted on tweets(quoted_tweet_id);
579
582
  create index if not exists idx_tweet_collections_kind_account on tweet_collections(kind, account_id, collected_at desc, tweet_id);
580
583
  create index if not exists idx_tweet_collections_tweet on tweet_collections(tweet_id);
581
584
  create index if not exists idx_tweet_account_edges_kind_account on tweet_account_edges(kind, account_id, last_seen_at desc, tweet_id);
585
+ create index if not exists idx_tweet_account_edges_kind_tweet on tweet_account_edges(kind, tweet_id, account_id);
582
586
  create index if not exists idx_tweet_account_edges_tweet on tweet_account_edges(tweet_id);
583
587
  create index if not exists idx_dm_conversations_account on dm_conversations(account_id, last_message_at desc);
584
588
  create index if not exists idx_dm_messages_conversation on dm_messages(conversation_id, created_at asc);
@@ -676,6 +680,15 @@ function ensureAccountExternalUserIdColumn(db: Database) {
676
680
  }
677
681
  }
678
682
 
683
+ function ensureDmConversationInboxColumns(db: Database) {
684
+ const columnNames = getColumnNames(db, "dm_conversations");
685
+ if (!columnNames.has("inbox_kind")) {
686
+ db.exec(
687
+ "alter table dm_conversations add column inbox_kind text not null default 'accepted'",
688
+ );
689
+ }
690
+ }
691
+
679
692
  function ensureTweetCollectionsTable(db: Database) {
680
693
  db.exec(`
681
694
  create table if not exists tweet_collections (
@@ -939,6 +952,7 @@ function initDatabase(options: InitDatabaseOptions = {}) {
939
952
  nativeDb = new NativeSqliteDatabase(dbPath);
940
953
  nativeDb.exec(BASE_SCHEMA_SQL);
941
954
  ensureAccountExternalUserIdColumn(nativeDb);
955
+ ensureDmConversationInboxColumns(nativeDb);
942
956
  ensureTweetMetadataColumns(nativeDb);
943
957
  ensureProfileAvatarColumns(nativeDb);
944
958
  ensureTweetCollectionsTable(nativeDb);
@@ -979,11 +993,29 @@ export function getDb() {
979
993
  return kyselyDb as Kysely<BirdclawDatabase>;
980
994
  }
981
995
 
982
- export function resetDatabaseForTests() {
983
- kyselyDb?.destroy();
996
+ export async function closeDatabase() {
997
+ const db = kyselyDb;
998
+ const native = nativeDb;
984
999
  kyselyDb = undefined;
1000
+ nativeDb = undefined;
1001
+ demoSeedAttempted = false;
1002
+
1003
+ if (db) {
1004
+ await db.destroy();
1005
+ } else {
1006
+ native?.close();
1007
+ }
1008
+ }
985
1009
 
986
- nativeDb?.close();
1010
+ export function resetDatabaseForTests() {
1011
+ const db = kyselyDb;
1012
+ const native = nativeDb;
1013
+ kyselyDb = undefined;
987
1014
  nativeDb = undefined;
988
1015
  demoSeedAttempted = false;
1016
+ if (db) {
1017
+ void db.destroy();
1018
+ } else {
1019
+ native?.close();
1020
+ }
989
1021
  }