birdclaw 0.9.4 → 0.10.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 (126) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +22 -7
  3. package/dist/cli/birdclaw.js +6360 -4395
  4. package/dist/client/assets/{AvatarChip-C8zELEVt.js → AvatarChip-DsHj3LT7.js} +1 -1
  5. package/dist/client/assets/FeedState-DhMv4zXD.js +1 -0
  6. package/dist/client/assets/ProfileAnalysisStream-B8zyyye-.js +1 -0
  7. package/dist/client/assets/{ProfilePreview-CsiLpFrb.js → ProfilePreview-CaaMHV2N.js} +1 -1
  8. package/dist/client/assets/SavedTimelineView-4QYaZ4CU.js +1 -0
  9. package/dist/client/assets/{SmartTimestamp-BypN4KPq.js → SmartTimestamp-CXaNLqN7.js} +1 -1
  10. package/dist/client/assets/SyncNowButton-DDYT2jQT.js +1 -0
  11. package/dist/client/assets/TimelineRouteFrame-DJdUR7DX.js +1 -0
  12. package/dist/client/assets/TweetRichText-D-amgcEl.js +1 -0
  13. package/dist/client/assets/account-selection-h7m9xmzU.js +1 -0
  14. package/dist/client/assets/blocks-BpjvGwYq.js +2 -0
  15. package/dist/client/assets/blocks-C84MpzHq.js +1 -0
  16. package/dist/client/assets/{bookmarks-B2I0kAWY.js → bookmarks-Gy6MvAc9.js} +1 -1
  17. package/dist/client/assets/chevron-down-e-c5H12y.js +1 -0
  18. package/dist/client/assets/circle-DiJUdlek.js +1 -0
  19. package/dist/client/assets/{client-stream-contracts-D1QUdWfh.js → client-stream-contracts-CNz2FSrQ.js} +1 -1
  20. package/dist/client/assets/data-sources-CqxgDfE3.js +1 -0
  21. package/dist/client/assets/database-Dl3XWRaa.js +1 -0
  22. package/dist/client/assets/discuss-C0CUMn6v.js +1 -0
  23. package/dist/client/assets/discuss-DKC6H1fN.js +2 -0
  24. package/dist/client/assets/dms-DWA5tvJS.js +1 -0
  25. package/dist/client/assets/dms-Q1a1kZ_P.js +2 -0
  26. package/dist/client/assets/external-link-CfdTAkvn.js +1 -0
  27. package/dist/client/assets/gauge-DP2ku9zz.js +1 -0
  28. package/dist/client/assets/heart-D-ERjZPN.js +1 -0
  29. package/dist/client/assets/inbox-C9zFrQ76.js +1 -0
  30. package/dist/client/assets/inbox-DjlVjj3K.js +2 -0
  31. package/dist/client/assets/index-B8hO98gL.js +31 -0
  32. package/dist/client/assets/lazyRouteComponent-CLLbUvMd.js +1 -0
  33. package/dist/client/assets/likes-BXANVRCj.js +1 -0
  34. package/dist/client/assets/links-6tWeHun_.js +2 -0
  35. package/dist/client/assets/links-D3Ut-aUB.js +1 -0
  36. package/dist/client/assets/mapbox-DfIoNJn2.js +2 -0
  37. package/dist/client/assets/mapbox-gl-BdaHQI9U.js +3220 -0
  38. package/dist/client/assets/{mentions-B6BXntri.js → mentions-BKO40XiK.js} +1 -1
  39. package/dist/client/assets/message-circle-79LZr2oN.js +1 -0
  40. package/dist/client/assets/network-map-2EPsbMIT.js +2 -0
  41. package/dist/client/assets/network-map-CrXvY--k.css +1 -0
  42. package/dist/client/assets/network-map-DUpppygD.js +2 -0
  43. package/dist/client/assets/preload-helper-MpqUbZCn.js +1 -0
  44. package/dist/client/assets/profile-analyze-B5Rr41WP.js +2 -0
  45. package/dist/client/assets/profile-analyze-BqvM9hSa.js +1 -0
  46. package/dist/client/assets/{profile-hydration-client-BQyC5--e.js → profile-hydration-client-DoFW3yKH.js} +1 -1
  47. package/dist/client/assets/profiles._handle-DWyWAGG8.js +1 -0
  48. package/dist/client/assets/profiles._handle-DdZ9wAT-.js +2 -0
  49. package/dist/client/assets/query-client-CA-do_IS.js +17 -0
  50. package/dist/client/assets/rate-limits-DyRTb_U4.js +1 -0
  51. package/dist/client/assets/refresh-cw-IUfM9D_1.js +1 -0
  52. package/dist/client/assets/route-search-CmZT7pGD.js +1 -0
  53. package/dist/client/assets/{routes-6U4Cc79j.js → routes-ARIEjgq-.js} +1 -1
  54. package/dist/client/assets/{schemas-CntsNLmN.js → schemas-CMQMhQXI.js} +1 -1
  55. package/dist/client/assets/styles-CjeA43Ci.css +2 -0
  56. package/dist/client/assets/today-DNAg-wnA.js +2 -0
  57. package/dist/client/assets/today-Q3xFx4cl.js +1 -0
  58. package/dist/client/assets/useDebouncedValue-BJLRInUq.js +1 -0
  59. package/dist/client/assets/useQuery-CL_NXLnc.js +1 -0
  60. package/dist/client/assets/useTimelineRouteData-DYhYLZY4.js +1 -0
  61. package/dist/client/assets/user-search-DL5_6EZd.js +1 -0
  62. package/dist/server/assets/{AvatarChip-DWag3IzT.js → AvatarChip-B5ASnpQ4.js} +1 -1
  63. package/dist/server/assets/{FeedState-CwzcvP-p.js → FeedState-YrMZ10Gf.js} +1 -1
  64. package/dist/server/assets/{ProfileAnalysisStream-CLjrYzEx.js → ProfileAnalysisStream-1CHrSLNN.js} +2 -2
  65. package/dist/server/assets/{ProfilePreview-Bq-DSUM2.js → ProfilePreview-Dk2CdOOS.js} +2 -2
  66. package/dist/server/assets/{SavedTimelineView-Bk9nfnb-.js → SavedTimelineView-Ern3q7LW.js} +2 -2
  67. package/dist/server/assets/{SmartTimestamp-C06w_f9J.js → SmartTimestamp-sxGoy8Uj.js} +1 -1
  68. package/dist/server/assets/{SyncNowButton-CKuXKYcd.js → SyncNowButton-C3OQghU4.js} +6 -4
  69. package/dist/server/assets/{TimelineRouteFrame-Bg3e7X_N.js → TimelineRouteFrame-CYD-qMuy.js} +3 -3
  70. package/dist/server/assets/{TweetRichText-wzUAtbPS.js → TweetRichText-BEo_OCEM.js} +2 -2
  71. package/dist/server/assets/_tanstack-start-manifest_v-CHtuH75x.js +221 -0
  72. package/dist/server/assets/{blocks-CaP_u3mY.js → blocks-DWZAKPAX.js} +3 -3
  73. package/dist/server/assets/{blocks-DKy4yTF-.js → blocks-VXmcBqKD.js} +3 -3
  74. package/dist/server/assets/{bookmarks-CPFq3JVX.js → bookmarks-DVCjWQPu.js} +1 -1
  75. package/dist/server/assets/{client-stream-contracts-gtXEreFY.js → client-stream-contracts-DVzk8DzM.js} +4 -4
  76. package/dist/server/assets/{data-sources-DWwmQqcO.js → data-sources-UEYjgFHD.js} +1 -1
  77. package/dist/server/assets/{discuss-CVGB4_I0.js → discuss-4b2z14mT.js} +3 -3
  78. package/dist/server/assets/{discuss-BB8wFy4L.js → discuss-CJ_vThu8.js} +3 -3
  79. package/dist/server/assets/{dms-vbEumuuO.js → dms-Cr5heLhm.js} +4 -4
  80. package/dist/server/assets/{dms-7NzdyQZQ.js → dms-DbJk33XB.js} +6 -6
  81. package/dist/server/assets/{empty-plugin-adapters-D9UWiqvJ.js → empty-plugin-adapters-YdH6Vqte.js} +1 -1
  82. package/dist/server/assets/{inbox-CBeZctFd.js → inbox-BJzEE8Aa.js} +2 -2
  83. package/dist/server/assets/{inbox-UpHhXODd.js → inbox-D607zrwZ.js} +4 -4
  84. package/dist/server/assets/{likes-CDAjYyTm.js → likes-C3EpsPbF.js} +1 -1
  85. package/dist/server/assets/{links-DU-TIHtg.js → links-BU_FRxcz.js} +6 -6
  86. package/dist/server/assets/{links-sQ3q2jvO.js → links-Dz-6bmkg.js} +6 -6
  87. package/dist/server/assets/{mentions-DdndGSRw.js → mentions-BHd6N_OL.js} +1 -1
  88. package/dist/server/assets/{network-map-CcOz-T9O.js → network-map-S3bgKEDj.js} +2 -2
  89. package/dist/server/assets/{network-map-B9iOapuB.js → network-map-rmU1NSHD.js} +2 -2
  90. package/dist/server/assets/{profile-analyze-CUfXmXEH.js → profile-analyze-CyfbGAsL.js} +3 -3
  91. package/dist/server/assets/{profile-analyze-BmDeTif5.js → profile-analyze-Drz-nRl-.js} +1 -1
  92. package/dist/server/assets/{profiles._handle-BAqnghwo.js → profiles._handle-BBXArSJO.js} +5 -5
  93. package/dist/server/assets/{profiles._handle-8snagiR1.js → profiles._handle-CsU6xBVm.js} +4 -4
  94. package/dist/server/assets/{rate-limits-BY2-aQPT.js → rate-limits-3C3mBM3G.js} +1 -1
  95. package/dist/server/assets/{router-DVQ3M870.js → router-BMfpBcBM.js} +2734 -2127
  96. package/dist/server/assets/{routes-D9226vKz.js → routes-Cyokiwx1.js} +1 -1
  97. package/dist/server/assets/start-P4i55asu.js +4 -0
  98. package/dist/server/assets/{today-DKWphGrC.js → today-CRa6Y-Tg.js} +3 -3
  99. package/dist/server/assets/{today-BmvIMJzI.js → today-CScZDxQx.js} +3 -3
  100. package/dist/server/assets/{ui-rDHeS-cc.js → ui-CL21-Ku0.js} +1 -1
  101. package/dist/server/assets/{useTimelineRouteData-BmDbGvQ8.js → useTimelineRouteData-BWxx9yQl.js} +6 -6
  102. package/dist/server/server.js +3515 -51
  103. package/package.json +19 -19
  104. package/dist/client/assets/SavedTimelineView-BSnwnujP.js +0 -1
  105. package/dist/client/assets/TimelineRouteFrame-H3D4R0Xu.js +0 -1
  106. package/dist/client/assets/blocks-WsAOmHsv.js +0 -1
  107. package/dist/client/assets/data-sources-DI5W9oVq.js +0 -1
  108. package/dist/client/assets/discuss-t2QxXK0h.js +0 -1
  109. package/dist/client/assets/dms-DjyXURaJ.js +0 -1
  110. package/dist/client/assets/inbox-CkHVoykL.js +0 -1
  111. package/dist/client/assets/index-BR860w88.js +0 -31
  112. package/dist/client/assets/index-bpFrQ5yG.css +0 -1
  113. package/dist/client/assets/likes-CenHqxQG.js +0 -1
  114. package/dist/client/assets/links-lDqy93u8.js +0 -1
  115. package/dist/client/assets/mapbox-CVPXIYUZ.js +0 -2
  116. package/dist/client/assets/mapbox-gl-DRRiLKWb.js +0 -3215
  117. package/dist/client/assets/network-map-BCUtBk8G.js +0 -2
  118. package/dist/client/assets/profile-analyze-YExKd6Lx.js +0 -1
  119. package/dist/client/assets/profiles._handle-idhd3kYo.js +0 -1
  120. package/dist/client/assets/query-client-DZ5C7UNo.js +0 -17
  121. package/dist/client/assets/rate-limits-jGxIfvUD.js +0 -1
  122. package/dist/client/assets/styles-DT4Pxoi-.css +0 -2
  123. package/dist/client/assets/today-COmNSYaE.js +0 -1
  124. package/dist/client/assets/useTimelineRouteData-BpQzU16P.js +0 -1
  125. package/dist/server/assets/_tanstack-start-manifest_v-mm-2VYBo.js +0 -148
  126. package/dist/server/assets/start-5Z2QO8AU.js +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "birdclaw",
3
- "version": "0.9.4",
3
+ "version": "0.10.0",
4
4
  "description": "Local Twitter memory in SQLite for archives, DMs, likes, bookmarks, and moderation",
5
5
  "homepage": "https://github.com/steipete/birdclaw#readme",
6
6
  "license": "MIT",
@@ -35,7 +35,7 @@
35
35
  "test": "node ./scripts/run-vitest.mjs run",
36
36
  "coverage": "node ./scripts/run-vitest.mjs run --coverage",
37
37
  "e2e": "playwright test",
38
- "typecheck": "tsgo --noEmit",
38
+ "typecheck": "tsc --noEmit",
39
39
  "format": "oxfmt --write bin src scripts playwright vite.config.ts vitest.config.ts playwright.config.ts",
40
40
  "format:check": "oxfmt --check bin src scripts playwright vite.config.ts vitest.config.ts playwright.config.ts",
41
41
  "lint": "oxlint --import-plugin --node-plugin --vitest-plugin --deny-warnings -A require-mock-type-parameters -A no-control-regex bin src scripts playwright vite.config.ts vitest.config.ts playwright.config.ts",
@@ -47,12 +47,13 @@
47
47
  "docs:site": "node scripts/build-docs-site.mjs"
48
48
  },
49
49
  "dependencies": {
50
+ "@modelcontextprotocol/sdk": "^1.29.0",
50
51
  "@tanstack/react-query": "^5.101.2",
51
- "@tanstack/react-router": "1.170.16",
52
+ "@tanstack/react-router": "1.170.18",
52
53
  "commander": "^15.0.0",
53
- "effect": "^3.21.4",
54
- "lucide-react": "^1.22.0",
55
- "mapbox-gl": "^3.25.0",
54
+ "effect": "^3.22.0",
55
+ "lucide-react": "^1.24.0",
56
+ "mapbox-gl": "^3.26.0",
56
57
  "react": "^19.2.7",
57
58
  "react-dom": "^19.2.7",
58
59
  "react-map-gl": "^8.1.1",
@@ -62,31 +63,30 @@
62
63
  "devDependencies": {
63
64
  "@playwright/test": "^1.61.1",
64
65
  "@tailwindcss/typography": "^0.5.20",
65
- "@tailwindcss/vite": "^4.3.2",
66
- "@tanstack/react-start": "1.168.26",
66
+ "@tailwindcss/vite": "^4.3.3",
67
+ "@tanstack/react-start": "1.168.28",
67
68
  "@testing-library/dom": "^10.4.1",
68
69
  "@testing-library/jest-dom": "^6.9.1",
69
70
  "@testing-library/react": "^16.3.2",
70
71
  "@types/geojson": "^7946.0.16",
71
- "@types/node": "^26.1.0",
72
+ "@types/node": "^26.1.1",
72
73
  "@types/react": "^19.2.17",
73
74
  "@types/react-dom": "^19.2.3",
74
75
  "@types/supercluster": "^7.1.3",
75
- "@typescript/native-preview": "7.0.0-dev.20260701.1",
76
76
  "@vitejs/plugin-react": "^6.0.3",
77
- "@vitest/coverage-v8": "^4.1.9",
77
+ "@vitest/coverage-v8": "^4.1.10",
78
78
  "esbuild": "^0.28.1",
79
79
  "jsdom": "^29.1.1",
80
- "oxfmt": "^0.57.0",
81
- "oxlint": "^1.72.0",
82
- "tailwindcss": "^4.3.2",
83
- "tsx": "^4.22.4",
84
- "typescript": "^6.0.3",
85
- "vite": "^8.1.2",
86
- "vitest": "^4.1.9"
80
+ "oxfmt": "^0.59.0",
81
+ "oxlint": "^1.74.0",
82
+ "tailwindcss": "^4.3.3",
83
+ "tsx": "^4.23.1",
84
+ "typescript": "^7.0.2",
85
+ "vite": "^8.1.5",
86
+ "vitest": "^4.1.10"
87
87
  },
88
88
  "engines": {
89
- "node": ">=25.8.1 <27"
89
+ "node": ">=26.5.0 <27"
90
90
  },
91
91
  "packageManager": "pnpm@10.34.3"
92
92
  }
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-B-9mzPXz.js";import{t}from"./react-BwGzW7mM.js";import{Rn as n}from"./schemas-CntsNLmN.js";import{a as r,i,n as a,o,r as s,t as c}from"./useTimelineRouteData-BpQzU16P.js";import{f as l}from"./index-BR860w88.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};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-B-9mzPXz.js";import{t}from"./react-BwGzW7mM.js";import{Dn as n,M as r,Mn as i,On as a,Rn as o,kn as s}from"./schemas-CntsNLmN.js";import{a as c,i as l,n as u,o as d,r as f,t as p}from"./useTimelineRouteData-BpQzU16P.js";import{f as m}from"./index-BR860w88.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};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-B-9mzPXz.js";import{t}from"./react-BwGzW7mM.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-CntsNLmN.js";import{M as _,a as v,b as y,n as b,r as ie,s as x,u as ae}from"./query-client-DZ5C7UNo.js";import{r as S,t as C}from"./AvatarChip-C8zELEVt.js";import{Z as w,c as T,ct as E,d as D}from"./index-BR860w88.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 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-B-9mzPXz.js";import{t}from"./react-BwGzW7mM.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-CntsNLmN.js";import{t as f}from"./createLucideIcon-CMLcIxOz.js";import{t as p}from"./circle-check-BCK_qvXt.js";import{t as m}from"./triangle-alert-DJPCW6jQ.js";import{h,n as g,r as _}from"./query-client-DZ5C7UNo.js";import{_t as v,ct as y,ft as b}from"./index-BR860w88.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(`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`}]]),C=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`}]]),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`?v:e===`bird`?S:C}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=y({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)(b,{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};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-B-9mzPXz.js";import{t}from"./react-BwGzW7mM.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-CntsNLmN.js";import{t as _}from"./circle-check-BCK_qvXt.js";import{a as v,i as y,o as b,s as x,t as S}from"./client-stream-contracts-D1QUdWfh.js";import{t as C}from"./sparkles-Gx_BHkDX.js";import{t as w}from"./search-C_LqodNa.js";import{Q as T,ft as E,l as D,yt as O}from"./index-BR860w88.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)(O,{"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=D.useSearch(),t=D.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:D,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,D),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)(E,{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)(w,{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:D,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)(C,{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)(C,{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};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-B-9mzPXz.js";import{t}from"./react-BwGzW7mM.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-CntsNLmN.js";import{t as re}from"./search-C_LqodNa.js";import{M as ie,a as ae,b as m,d as h,n as g,r as _,s as v}from"./query-client-DZ5C7UNo.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-BR860w88.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};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-B-9mzPXz.js";import{t}from"./react-BwGzW7mM.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-CntsNLmN.js";import{t as v}from"./sparkles-Gx_BHkDX.js";import{M as y,a as b,b as x,f as S,n as C,r as ee,s as w}from"./query-client-DZ5C7UNo.js";import{ct as T,et as E,h as D,m as O,ot as k,st as A}from"./index-BR860w88.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};