Build send_group_ai_record results from the canonical group-message sequence returned by the Core receipt correlator, using the same message ID mapping as normal inbound events.
Stop reporting the historical placeholder value of zero and surface receipt failures through the standard Action error path. Preserve the existing get_ai_record URL response and update the SDK result documentation without changing its public shape.
Add Action-level coverage for canonical ID generation and missing-receipt failures.
Refs #250
Wait for the canonical self group-message event after AI voice synthesis instead of interpreting undocumented response fields as a message sequence.
Correlate receipts by exact media UUID, buffer response races, and claim each semantic message identity only once across concurrent calls and duplicate multi-process pushes. Reject missing identifiers, invalid sequences, bounded-buffer overflow, and receipt timeouts with explicit diagnostics.
Keep fetchAiVoice focused on returning the media node and add regression coverage for race ordering, unrelated events, identical concurrent audio, duplicate pushes, malformed receipts, and timeout cleanup.
Fixes#250
Replace the lossy Qzone album-list endpoint with the QQ NT AlbumService protobuf request. Preserve creator nicknames and expose native pagination for get_qun_album_list.
Emit message_sent.private after successful friend messages sent through OneBot actions or the WebUI debug console when QQ does not provide an inbound self echo.
Keep a later QQ echo as the canonical stored event while suppressing duplicate downstream delivery across both race orders. Match echoes by conversation, sequence, message ID, and a bounded time window; leave group messages, temporary sessions, split file sends, unreliable receipts, and messages sent manually from the QQ client unchanged.
Add regression coverage for action-only reporting, both echo race orders, hash collisions, cached-but-unreported events, temporary sessions, and incomplete receipts.
Fixes#251
Replace the get_collection_list placeholder with authenticated, read-only collection retrieval through the existing bridge API.
Add strict binary envelope validation, bounded pagination, accurate category filtering, preserved 64-bit identifiers, and explicit ticket, transport, service, and malformed-response failures. Cap item counts, page traversal, response bytes, per-request waits, and the total operation time.
Expose the compatible response model through Core, OneBot, the SDK, and the generated MCP catalog. Cover protocol framing, cursor behavior, filtered hasMore semantics, cleanup failures, bridge ticket acquisition, and Action validation with regression tests.
Verified with the live test bot without changing native components or adding any collection write behavior.
Replace the get_online_clients placeholder with the latest QQ online-device snapshot and return stable OneBot fields for client ID, device name, and localized device category.
Fail explicitly when no snapshot has been observed or when callers request an unsupported fresh refresh, while preserving an observed empty snapshot as a successful result. Update SDK types and generated MCP schemas, and add action-level coverage for every state.
Store the latest online-device snapshot for each Bridge lifecycle and expose it through the bridge contract as an immutable, owned value.
Distinguish a snapshot that has not yet been observed from a valid empty snapshot, replace state atomically on each QQ update, clear it during disposal, and cover lifecycle, immutability, and cleanup behavior with focused tests.
Decode Event 0x210 subtype 349 into typed online-device snapshots, including QQ-compatible low-byte client type normalization and one-entry-per-device-category projection.
Keep replacement snapshots outside system-message deduplication, reject malformed device identities observably, and add wire-level regressions for complete, packed, repeated, and invalid payloads. Live verification covered mobile account switching without requiring native changes.
Decode the folder modifier metadata returned by group file listings and project it as last upload time, uploader ID, and uploader name for both folder listing actions.
Regenerate the MCP catalog and add protocol, bridge, OneBot projection, and action schema coverage for the new fields.
Closes#248
Accept explicit empty strings from both longNick and long_nick when callers need to clear the bot signature. Missing and non-string values remain rejected before reaching the bridge.
Preserve the QQ-compatible clear representation by omitting the empty profile value, and add action-level and wire-level regression coverage. Live verification confirmed successful clearing and readback on the test bot.
Fixes#247
Return the NapCat-compatible long_nick field from get_stranger_info for both freshly fetched and cached user profiles. Keep the field present as an empty string when profile data is unavailable so callers receive a stable response shape.
Document the response contract in the Action schema and generated MCP catalog, and cover fetched, cached, and empty fallback paths with regression tests. This change reuses the existing profile signature value and does not add QQ requests or alter protocol packets.
Closes#246
Replace the Unix socket servers with an in-memory Duplex transport so the mid-send close regression runs in restricted environments and on Windows.
Wait until the control write begins before closing the transport, assert the exact close error, and use an event-loop boundary to detect leaked promise rejections without timing sleeps.
This keeps the test on the public QqHookClient send path while removing unrelated OS socket setup and does not change production behavior.
Encode the opaque media-list cursor in the protobuf page-info field while leaving the reserved field empty. This restores subsequent-page requests without changing the OneBot action or response shape.
Add an independent wire oracle so future protocol definition drift cannot make the encoder regression test pass against itself.
Fixes#245
Consume complete well-formed value varints before retaining their low 32 bits, matching QQ push behavior without relaxing tag or length parsing.
Add generator and end-to-end group reaction regressions, including truncated and malformed varint coverage. Refs #242.
Keep per-widget configuration when persisted overview layouts are migrated against the current widget catalogue. Account shortcuts, notes, links, filters, and other configurable widgets now retain their saved values after a page reload.
Add a WebUI Vitest entry point and regression coverage for restoring an account widget with saved configuration.
Fixes#243.
Add a single appearance setting for SnowLuma's adaptive cursor and custom context menu, enabled by default for existing and new installations.
Turning the setting off immediately removes both interaction layers and restores the browser's native cursor and context menu. The preference remains synchronized through the existing server-backed appearance configuration.
Introduce a CSS-driven adaptive cursor that morphs for controls, text editing, dragging, resizing, busy states, and other native pointer semantics on desktop devices.
Add a themed context menu for editing, selections, links, images, and page navigation while preserving explicit native-menu escape paths. Store a default-on interaction preference through the normalized appearance model and cover its migration and opt-out behavior.
Replace native range inputs with an accessible Radix-backed control that preserves keyboard and assistive-technology semantics.
Reproduce the elastic handle, track stretch, tick visibility, and reduced-motion behavior while keeping SnowLuma theme tokens. Adopt the component for interface scale and background image controls.
Replace the feature-specific MP3 verification command with a workspace-wide native test entry point.
Keep native regression cases in package-owned test suites so future checks can expand without adding workflow steps.
Use the dedicated audio conversion path for record output so mono QQ voice records produce valid MP3 data.
Add release-target smoke coverage and preserve conversion and cleanup failures for diagnostics.
Fixes#239
Expose reverse_order in the SDK request types and regenerate the MCP action catalog for group and private message history.
Describe the anchored older-or-newer semantics and retain true as the backward-compatible default for existing clients.
Refs #229
Add reverse_order to group and private history actions, preserve latest-page behavior without an anchor, and keep local fallback results chronologically ordered.
Key self-sent private messages and reply targets by the conversation peer, reject cross-conversation anchors, and include request context when a server fetch falls back to local history.
Refs #229
Walk bounded QQ history windows in either direction while keeping all returned messages in chronological order.
Resolve short-capped forward ranges without skipping messages nearest the anchor, share the existing request throttle across group and private history, and surface incomplete fetches instead of returning silent partial results.
Refs #229
Replace the floating capsule treatment with a compact section-navigation rail that combines primary text, a restrained active tint, and a short underline for an unambiguous selected state.
Constrain the shared horizontal viewport so narrow screens scroll only inside the tab strip rather than widening the page. Existing keyboard navigation, focus handling, active-tab reveal, and reduced-motion behavior remain intact.
Introduce reusable one-pixel optical offsets for asymmetric forward and back glyphs without changing control boxes, spacing, or pointer hit areas.
Apply the correction consistently to navigation arrows, play controls, send actions, and the account sidebar so directional symbols appear centered across shared controls. No interaction or navigation behavior changes.
Add theme-neutral media keylines and layered card shadows so avatars, previews, pickers, and shared cards remain separated without relying on hard borders.
Keep the message composer radius hierarchy concentric across appearance settings and remove redundant nested canvas surfaces from forwarded-message editors. This changes visual presentation only; message composition behavior and emitted payloads remain unchanged.
Replace 145 scattered 10px and 11px declarations with semantic text roles across the dashboard, configuration, diagnostics, logs, and settings surfaces.
Promote instructions, errors, interactive labels, and empty states to at least 12px, raise security-sensitive and destructive warnings to 14px, and make general-purpose badges readable by default. Keep compact sizing only for dense technical metadata such as timestamps, identifiers, paths, versions, and counters.
Preserve the existing desktop density while improving Chinese text legibility and responsive behavior on narrow mobile layouts.
Remove runtime requests to external font services and make the default sans and monospace stacks rely entirely on locally available platform fonts.
Introduce explicit metadata and micro text tokens for dense technical content, disable synthetic font faces globally, and update the appearance selector so every bundled font choice accurately describes its local source.
Clear only the membership flag bit when normalizing group increase operation codes so unrelated high bits cannot collapse into the invitation value.
Add regression coverage for extended operation codes.
Derive group increase approval and invitation subtypes from the member-change operation code instead of actor identity.
Treat voluntary leave field 5 as structured metadata and attribute the operation to the departing member so valid notices are not discarded.
Add protocol and OneBot regression coverage for issue #237.
Keep terminal styling confined to interactive console output while storing plain structured log lines for subscribers and file persistence.
Sanitize downloads again at the WebUI boundary so cached legacy entries and fallback-formatted records cannot leak CSI, OSC, DCS, or C1 control sequences. Add regression coverage for colored output, hyperlinks, control strings, malformed sequences, and preserved multiline text.
Prevent the top-bar title and main route content from animating during the first authenticated render. This removes first-load flashing while preserving the existing transitions for subsequent navigation.
Add a shared, stable-size password visibility icon that switches with interruptible opacity, scale, and blur motion across login and password-change flows.
Apply the same motion language to password rule checks, remove the redundant outer pulse, skip initial-state animation, and switch immediately when reduced motion is enabled.
Replace broad transitions with property-specific animation for progress bars, filters, cards, and dashboard controls. This prevents unrelated layout properties from animating while preserving the existing visual feedback.
Standardize standalone press feedback at a 0.96 scale, keep disabled controls static, and honor both operating-system and in-app reduced-motion preferences.
Add a visible disclosure control for truncated host and runtime statistics while keeping the compact dashboard card layout unchanged.
Support hover, focus, mouse click, touch toggle, outside dismissal, and Escape, with direct accessible descriptions for assistive technology.
Keep the top bar as the page's single primary heading and rename the content section to Developer Tools at the secondary level.
This removes duplicate page titles for screen readers while preserving the existing debug layout and feature grouping.
Add edge fades and automatic active-tab reveal to shared horizontal tab lists, including revalidation when asynchronous labels or badges change width.
Give configuration tabs complete tab and panel semantics, keyboard navigation, focus treatment, and 40px desktop or 44px mobile targets without changing their visual hierarchy.
Increase shared dialog and sheet close targets to 40px on desktop and 44px on mobile while preserving the compact 16px icon.
Constrain dialogs to the viewport and scroll their body inside a fixed shell so long forms never move the close control off-screen.
Rebalance the mobile top bar so the page title can shrink independently while navigation and account actions keep stable touch targets.
Align status and description visibility with the actual desktop breakpoint, hide only decorative content on narrow screens, and retain kiosk access on common phone widths without horizontal overflow.
Add explicit title context for truncated labels and preserve the existing desktop density.
Give every theme option a reliable 44-pixel touch target on mobile while retaining the denser desktop presentation.
Adjust the active indicator to preserve visual balance at both sizes and add tactile press feedback that follows the application's reduced-motion settings.
Raise shared button and form-control defaults to provide clearer, more consistent interaction targets across the interface.
Guarantee 44-pixel touch targets and 16-pixel form text on narrow screens, preserve explicit desktop size overrides, and prevent mobile browser focus zoom.
Replace broad transitions with targeted press feedback, respect reduced-motion preferences, and allow callers to opt out without overriding their persistent transforms.
Parse RFC 2397 base64 data URLs through the shared binary source classifier so inline media cannot fall through to local file handling.
Reuse the same parsing path for buffered and disk-staged uploads, reject malformed or oversized inputs explicitly, and add regression coverage for both paths.
Refs #236
Treat an absent media-list return code as the protobuf zero default while preserving failures for explicit non-zero codes.
Add a regression test that exercises the encoded response path with media data and no status field.
Refs #234
Separate account login state from receive-path health in get_status. A logged-in account remains online while good becomes false only after the receive path has been confirmed stale.
Apply the same health value to OneBot lifecycle and heartbeat events so API polling and event consumers observe consistent status semantics.
Regenerate the MCP action catalog with the clarified contract and add regression coverage for the online-but-degraded response.
Refs #233.