Skip to content

Releases: nocoo/xray

v1.9.4

24 Mar 08:49

Choose a tag to compare

[1.9.4] - 2026-03-24

Changed

  • Add superset run config and tweet export script
  • Update retrospective #24 with correct root cause and fix
  • Add retrospective #24 — ReadableStream lock in vinext auth

Fixed

  • Exclude all api routes from proxy to prevent body consumption
  • Clone request in auth route handler to avoid ReadableStream lock

v1.9.2

24 Mar 00:45

Choose a tag to compare

[1.9.2] - 2026-03-24

Added

  • Add automated release script

Fixed

  • Remove non-null assertions in release script
  • Resolve all 21 eslint errors for zero-tolerance L2 lint

v1.9.1

14 Mar 22:40

Choose a tag to compare

Refactored

  • Remove dead code — deleted unused auth-context.ts, useMutation hook, createE2EDb(), and 4 dead chart/palette exports
  • Extract shared utilities — consolidated duplicate functions into single shared implementations:
    • formatCount (4 copies → 1 in utils.ts)
    • formatTimeAgo (4 copies → 1 in utils.ts, with compact/long/coarse style variants)
    • estimateTweetHeight (2 copies → 1 in utils.ts)
    • pMap (2 copies → 1 in utils.ts)
    • sseMessage (2 copies → 1 in api-helpers.ts)
    • maskSecret (2 copies → 1 in crypto.ts, with prefix/tail mode parameter)
    • formatDate (2 copies → 1 in utils.ts)

Fixed

  • AI key masking security — restored conservative tail-only masking for API keys in AI settings (only last 4 chars visible), preventing the prefix exposure introduced by the maskSecret consolidation

Tests

  • 35 new tests covering all extracted shared utilities (formatCount, formatTimeAgo × 3 styles, formatDate, estimateTweetHeight, pMap, maskSecret × 2 modes)

Docs

  • Removed stale useMutation references from README, CHANGELOG, and architecture docs

v1.9.0

09 Mar 00:01

Choose a tag to compare

What's New

Added

  • Remove button on post cards — each post card now has a trash icon button (right-aligned, red hover) that deletes the post via DELETE /api/watchlists/[id]/posts?postId=N and removes it from the UI instantly
  • 90-day retention option — watchlist settings now support 90-day post retention in addition to the existing 1/3/7/15/30-day options
  • Rich translation progress — translation pipeline rewritten with sliding-window concurrency and live SSE previews; new start and translating events provide real-time feedback before each translation completes

Fixed

  • "Translating 0/0" flash — eliminated the brief zero-count display that appeared at the start of batch translation
  • getDb() test conflict — resolved module-level database initialization conflict that caused test failures when importing from @/db

Tests

  • 8 new parseSSEBuffer unit tests covering chunked streaming and edge cases
  • 5 new DELETE endpoint API tests (success, 404, 400, cross-watchlist rejection)
  • 3 new deleteById DB repository tests
  • 90-day retention acceptance test
  • 7 new route tests for settings and posts endpoints

v1.8.0

06 Mar 02:07

Choose a tag to compare

Documentation

  • Architecture doc rewritten — reflects current vinext + ScopedDB stack with updated module structure
  • Overview doc updated — web dashboard as primary purpose, refreshed feature descriptions
  • Run & scripts doc rewritten — web app workflow as primary, scripts as secondary
  • Config doc rewritten — environment variables as primary configuration method
  • Deployment doc updated — vinext build/start commands, TWEAPI_API_KEY env var, fixed version reference
  • API doc updated — added 8 missing webhook API endpoints (lists, messages, conversation, credits, usage, analytics, bookmarks, likes)
  • README refreshed — added missing features (lists, AI settings, webhooks, usage), test scripts, and docs reference
  • Project structure tree updated — all pages, services, and directories reflected
  • Removed obsolete migration plan (07-xray-web.md)
  • Fixed playwright port, eslint version, and pre-push status in testing doc
  • Added TWEAPI_API_KEY to .env.example and README env vars section
  • Fixed Docker volume mount path and added required env vars to deployment doc

v1.7.0

06 Mar 00:23

Choose a tag to compare

[1.7.0] - 2026-03-06

Added

  • vinext 0.0.21 upgrade — 12 versions of fixes from vinext 0.0.9, improving RSC compatibility, font handling, and route handler stability

Changed

  • ESLint 9 → 10 — major ESLint upgrade with typescript-eslint bumped to 8.56.1
  • AI SDK upgradedai and @ai-sdk/openai bumped to latest patch versions
  • lucide-react 0.575.0 → 0.577.0 — icon library patch upgrade
  • Semver ranges tightenedtypescript narrowed from ^5.0.0 to ^5.9.3, vite from ^7.0.0 to ^7.3.1 to match installed versions
  • Unused dependencies removed@auth/drizzle-adapter, zod, and @vitejs/plugin-rsc dropped from package.json

Fixed

  • TweAPI key leak — removed hardcoded API key from source; now reads exclusively from TWEAPI_API_KEY env var

Documentation

  • README updated with new preview image and refreshed feature list
  • TweAPI acknowledgement added to README

Housekeeping

  • Removed one-time migration script (migrate-profiles.ts)
  • Cleaned up .bfg-report/ artifacts and added pattern to .gitignore

v1.6.1

05 Mar 01:56

Choose a tag to compare

What's New

Fixed

  • Masonry column breakpoints — evenly spaced 3/4/5-col breakpoints at 512px intervals (1024/1536/2048) for balanced coverage across screen sizes; raised tall-screen bonus threshold to 5+ base cols so that the 4-column range is no longer skipped

v1.6.0

05 Mar 00:40

Choose a tag to compare

What's New

Added

  • Unified TweetCard action bar — every tweet card now displays a consistent bottom bar with Open (external link), Translate (inline 信达雅), and zhe.to Save buttons; replaces per-page ad-hoc actions
  • Generic /api/translate endpoint — standalone translation route for any tweet by ID, decoupled from the watchlist pipeline
  • Linkify tweet text — URLs in tweet text (t.co and other https links) are now clickable with external link styling
  • Photo hover zoom overlay — magnifying glass icon appears on hover over photo grid items
  • Quoted tweet author clickable — quoted tweet author name and avatar now link to the user's X profile with external link icon
  • Masonry layout for bookmarks & likes — bookmarks and likes pages now use the shared MasonryGrid component for responsive column layout
  • Batch edit mode for groups — group detail page supports multi-select members with batch delete
  • followers.js export format — twitter export parser now supports followers.js in addition to following.js
  • User-paced batch resolution — import dialog uses cooldown timer between batches and deduplicates by twitterId to avoid redundant API calls

Changed

  • (dashboard) route group — all authenticated pages moved into src/app/(dashboard)/ with a shared layout.tsx and useBreadcrumbs hook, replacing per-page <AppShell> wrappers
  • WatchlistPostCard simplified — delegates rendering and action bar entirely to TweetCard, reducing the component to a thin wrapper
  • Tweet type badges relocated — Reply, Quote, and Retweet badges moved from inline to the card's top-right corner
  • Author row streamlined — external link icon removed from the tweet card author row (now available in the action bar)
  • Watchlist header compressed — 5-zone header consolidated into a single toolbar row

Fixed

  • Route group import paths — 15 TypeScript errors across 10 files from the (dashboard) migration; all shared/types relative imports updated for the extra nesting level, and @/app/watchlist/ alias corrected to @/app/(dashboard)/watchlist/
  • Watchlist member CRUD reactivity — member add/edit/delete now uses local state updates instead of triggering a full page reload
  • Twitter export parser — handles unquoted JS keys, trailing commas, and numeric IDs (resolves to real usernames before import)
  • Import dedup — pre-filters export IDs against existing group members to skip already-imported users
  • Batch resolve stability — reduced batch size to 10, added AbortController for instant cancel, removed drop zone opacity flash

v1.4.0

04 Mar 06:09

Choose a tag to compare

Added

  • Activity assessment columns — Groups detail table now displays Likes, Last Tweet (relative time), and Activity badge (🟢 Active / 🟡 Low / 🔴 Inactive / — Unknown) computed from tweet recency and frequency
  • Enhanced Tweets column — shows tweet count with average tweets/day calculated from account age
  • Last tweet trackinglast_tweet_at column added to twitter_profiles table; populated during profile refresh by fetching the user's most recent tweet via fetchUserTweets
  • Add Members page — dedicated /groups/[id]/add page with 3-tab import flow: From Account (fetch following list), Manual (paste usernames), and Import File (drag-and-drop following.js)

Changed

  • Groups detail table enriched — profile avatars link to X profiles; @username and display name are clickable; Added column right-aligned; User header left-aligned
  • Streaming profile refresh — refresh button now resolves members one-by-one with live progress instead of batch-then-render
  • Inline add form removed — replaced by dedicated Add Members page accessible via header button

v1.3.0

04 Mar 04:31

Choose a tag to compare

What's New

Added

  • Groups feature — full CRUD for user-defined groups (groups + group_members tables), with /groups list page and /groups/[id] detail page featuring sortable table, search filter, and Twitter export import (drag-and-drop following.js)
  • Twitter profile cache — shared twitter_profiles table with ProfilesRepo for global caching of Twitter user data; auto-upserts on every getUserInfo and batch resolve call
  • Profile refreshPOST /api/profiles/refresh for manual profile snapshot updates; per-member refresh buttons on both Watchlist cards and Groups table rows with spinning indicator
  • Batch user resolutionPOST /api/explore/users/batch for bulk username lookup (up to 500); powers import dialogs and profile refresh flows
  • Profile linkinglink-profiles API for both watchlists and groups; automatically resolves twitter_id FK from cached profiles
  • Import from Twitter export — drag-and-drop or file picker for following.js data export files on both Following and Groups pages; parseTwitterExportFile() extracted to shared lib
  • Zhe.to integration — settings page at /integrations/zheto with API key management, and save-to-zheto button in watchlist post-card action bar
  • Quote count metricquote_count added to tweet card stats row
  • 71 new unit tests — 48 for GroupsRepo/GroupMembersRepo, 23 for ProfilesRepo

Changed

  • Sidebar restructured — Watchlists and Groups promoted to top-level collapsible sections (matching NavGroupSection style); Following page replaced by Groups; Integrations added as new nav group
  • MemberCard enriched — displays profile avatar, display name, verified badge, follower count, bio snippet, and tags from cached twitter_profiles data
  • Batch resolve limit raised from 100 to 500 usernames per request

Fixed

  • TweAPI domain — migration script corrected from tweapi.com to api.tweapi.io with proper camelCase field name mapping
  • Batch import errors — error messages now expose actual server response instead of generic failure text
  • Sidebar section styling — icons removed from Watchlists/Groups section headers; padding aligned with NavGroupSection