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.
- package/CHANGELOG.md +63 -0
- package/README.md +55 -5
- package/bin/birdclaw.mjs +50 -11
- package/package.json +9 -7
- package/public/birdclaw-mark.png +0 -0
- package/scripts/browser-perf.mjs +400 -0
- package/scripts/build-docs-site.mjs +940 -0
- package/scripts/docs-site-assets.mjs +311 -0
- package/scripts/run-vitest.mjs +21 -0
- package/scripts/sanitize-node-options.mjs +23 -0
- package/scripts/start-test-server.mjs +42 -0
- package/src/cli.ts +422 -14
- package/src/components/AccountSwitcher.tsx +186 -0
- package/src/components/AppNav.tsx +29 -9
- package/src/components/AvatarChip.tsx +9 -3
- package/src/components/BrandMark.tsx +67 -0
- package/src/components/ConversationThread.tsx +11 -10
- package/src/components/DmWorkspace.tsx +39 -14
- package/src/components/FeedState.tsx +147 -0
- package/src/components/InboxCard.tsx +14 -2
- package/src/components/LinkPreviewCard.tsx +40 -18
- package/src/components/MarkdownViewer.tsx +452 -0
- package/src/components/SavedTimelineView.tsx +64 -56
- package/src/components/SyncNowButton.tsx +137 -0
- package/src/components/ThemeSlider.tsx +49 -93
- package/src/components/TimelineCard.tsx +364 -136
- package/src/components/TimelineRouteFrame.tsx +170 -0
- package/src/components/TweetMediaGrid.tsx +170 -24
- package/src/components/TweetRichText.tsx +28 -13
- package/src/components/account-selection.ts +64 -0
- package/src/components/useTimelineRouteData.ts +153 -0
- package/src/lib/account-sync-job.ts +654 -0
- package/src/lib/actions-transport.ts +216 -146
- package/src/lib/api-client.ts +304 -0
- package/src/lib/archive-finder.ts +72 -53
- package/src/lib/archive-import.ts +1377 -1298
- package/src/lib/authored-live.ts +261 -204
- package/src/lib/avatar-cache.ts +159 -44
- package/src/lib/backup.ts +1532 -951
- package/src/lib/bird-actions.ts +139 -57
- package/src/lib/bird-command.ts +101 -28
- package/src/lib/bird.ts +549 -194
- package/src/lib/blocklist.ts +40 -23
- package/src/lib/blocks-write.ts +129 -80
- package/src/lib/blocks.ts +165 -97
- package/src/lib/bookmark-sync-job.ts +250 -160
- package/src/lib/conversation-surface.ts +205 -0
- package/src/lib/db.ts +35 -3
- package/src/lib/dms-live.ts +720 -66
- package/src/lib/effect-runtime.ts +45 -0
- package/src/lib/follow-graph.ts +224 -180
- package/src/lib/http-effect.ts +222 -0
- package/src/lib/inbox.ts +74 -43
- package/src/lib/link-index.ts +88 -76
- package/src/lib/link-insights.ts +24 -0
- package/src/lib/link-preview-metadata.ts +472 -52
- package/src/lib/media-fetch.ts +286 -213
- package/src/lib/mention-threads-live.ts +352 -288
- package/src/lib/mentions-live.ts +390 -342
- package/src/lib/moderation-target.ts +102 -65
- package/src/lib/moderation-write.ts +77 -18
- package/src/lib/mutes-write.ts +129 -80
- package/src/lib/mutes.ts +8 -1
- package/src/lib/openai.ts +84 -53
- package/src/lib/period-digest.ts +953 -0
- package/src/lib/profile-affiliation-hydration.ts +93 -54
- package/src/lib/profile-hydration.ts +124 -72
- package/src/lib/profile-replies.ts +60 -43
- package/src/lib/profile-resolver.ts +402 -294
- package/src/lib/queries.ts +1024 -189
- package/src/lib/research.ts +165 -120
- package/src/lib/sqlite.ts +1 -0
- package/src/lib/timeline-collections-live.ts +204 -167
- package/src/lib/timeline-live.ts +60 -39
- package/src/lib/tweet-lookup.ts +30 -19
- package/src/lib/types.ts +38 -1
- package/src/lib/ui.ts +41 -10
- package/src/lib/url-expansion.ts +226 -55
- package/src/lib/url-safety.ts +220 -0
- package/src/lib/web-sync.ts +511 -0
- package/src/lib/whois.ts +166 -147
- package/src/lib/x-web.ts +102 -71
- package/src/lib/xurl.ts +681 -411
- package/src/routeTree.gen.ts +63 -0
- package/src/routes/__root.tsx +25 -5
- package/src/routes/api/action.tsx +127 -78
- package/src/routes/api/avatar.tsx +39 -30
- package/src/routes/api/blocks.tsx +26 -23
- package/src/routes/api/conversation.tsx +25 -14
- package/src/routes/api/inbox.tsx +27 -21
- package/src/routes/api/link-insights.tsx +31 -25
- package/src/routes/api/link-preview.tsx +25 -21
- package/src/routes/api/period-digest.tsx +123 -0
- package/src/routes/api/profile-hydrate.tsx +31 -28
- package/src/routes/api/query.tsx +79 -55
- package/src/routes/api/status.tsx +18 -10
- package/src/routes/api/sync.tsx +105 -0
- package/src/routes/dms.tsx +195 -55
- package/src/routes/inbox.tsx +32 -19
- package/src/routes/index.tsx +21 -127
- package/src/routes/links.tsx +50 -5
- package/src/routes/mentions.tsx +21 -127
- package/src/routes/today.tsx +441 -0
- package/src/styles.css +74 -11
- 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
|
|
983
|
-
kyselyDb
|
|
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
|
-
|
|
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
|
}
|