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.
Track receive health for every process attached to an account while treating unarmed monitoring as compatible rather than degraded.
Report the account as healthy while any attached process remains healthy, and mark it degraded only after every attached process has been confirmed stale. Keep health ownership synchronized with process attach, migration, and detach transitions.
Fail fast when process ownership and health state diverge instead of silently presenting a healthy status. Add multi-process regression coverage for partial degradation, full degradation, and recovery.
Refs #233.
Arm receive monitoring only after an existing QQ heartbeat has been observed, preserving compatibility with sessions that do not expose the signal.
Require 90 seconds of receive silence plus a 15-second confirmation window before reporting degradation. Any later inbound frame refreshes or restores health, including non-routable frames that still prove the receive path is alive.
Bind watchdog state to the active account epoch so direct login switches and packet-driven account migration cannot inherit stale deadlines from a previous account.
Forward health transitions to the bridge layer without reconnecting, reinjecting, or otherwise changing session recovery behavior. Add regression coverage for arming, recovery, sleep-resume confirmation, account migration, and invalid-UIN frames.
Refs #233.
Replace route-local restore writes with the core transaction and map preflight, rollback, and post-commit cleanup failures to precise HTTP responses. Treat only ENOENT as a missing export file and return transaction, restored, skipped, migrated, and restart facts.
Update the settings panel to describe the full sensitive configuration group, avoid restart guidance for empty plans, and reload settings after both successful and failed imports so the UI reflects committed disk state. Add HTTP regression coverage for export and restore error semantics.
Move restore execution into a dedicated module with explicit preflight, snapshot, stage, commit, rollback, and cleanup phases. Keep live files untouched until staging completes, roll back partial commits, and retain the transaction directory when rollback or cleanup cannot finish.
Report the transaction ID, active phase, failed files, commit state, rollback result, and recovery path without logging configuration contents. Cover every filesystem boundary with a focused fault matrix, including unreadable current files and cleanup failures.
Route selected backup entries through owner-owned config parsers before any filesystem write. Reject unsupported paths, mismatched encodings, malformed base64, lossy normalization, invalid effective overlays, and decoded payloads larger than 32 MiB.
Treat WebUI state, private keys, and every OneBot config as a single sensitive group. Skip unselected sensitive entries without inspecting their contents, preserve recognized migrations, and assign restrictive modes to credential files.
Handle member joins and ordinary removals using their direct operator identity while preserving the special nested form used when the bot is removed.
Reject malformed values with bounded diagnostic context and add regression coverage for #228 and related member-decrease events.
Regenerate the MCP catalog from the OneBot action definitions. Document the new parameters, defaults, validation invariants, and merged notice readback.
Route regular and new-member announcements through their correct web endpoints. Validate option conflicts, preserve existing defaults, merge returned notice collections, and surface transport and upload failures.
Present Windows x64, Linux x64, and Linux arm64 as fully supported release targets in a concise download matrix.
Add quick-start and unattended-consent guidance, link commits and version comparisons, and filter merge and release housekeeping from the change list.
Refresh the adjacent packaging documentation so it matches current platform support.
Allow unattended deployments to accept the EULA and Privacy Notice through SNOWLUMA_ACCEPT_EULA and SNOWLUMA_ACCEPT_PRIVACY.
Require both values, reject invalid configuration, keep environment consent non-persistent, and log whether acceptance is complete or partial.
Document the deployment contract and add regression coverage for parsing, persistence isolation, and stored-consent compatibility.
Replace the compatibility no-op with a real batched read action for current groups and observed incoming private conversations.
Exclude stale groups, group temporary sessions, and sent-message echoes from private targets, then expose the functional action through the generated MCP catalog.
Add action and message-store regressions for target selection and delegation.
Carry the stable sender identity through decoded private-message events and persist the UID/UIN pair at the receive boundary.
This keeps later conversation operations independent of stale message rows or fallible profile lookups, with regression coverage for decoding and identity indexing.
Replace message-header sequence forwarding with a server-guided read flow for group and private conversations.
Batch read reports conservatively, validate per-conversation results and cursor advancement, and fail with actionable errors when the server does not apply an update.
Add regression coverage for mixed batches, pagination, already-current sessions, malformed responses, and private sequence-domain mismatches.
Define the server response envelopes for group and private read reports, including per-conversation result codes and current/latest cursors.
This lets callers distinguish transport success from an actual read-state update.
Validate the public OneBot data.data field before converting JSON segments to the internal message element shape. Invalid payloads still return retcode 1400, but now identify the correct public field without reaching the QQ bridge.
Add Action-level regression coverage for issue #220.
Surface whether a OneBot configuration was persisted, applied live, or left degraded. Keep failed adapters and apply errors visible in the config and overview pages instead of reporting a false success.
Serialize desired network plans, isolate per-adapter apply failures, restore prior bindings when possible, and report saved versus applied state. Quiesce Action and event ingress, await in-flight dispatches and transport closes, retain failed generations for retry, and propagate shutdown failures.
Replace the open message bag with a validated discriminated union and preflight complete messages before uploads or sends. Return BAD_REQUEST for invalid or unsendable segments instead of dropping fields, sending partial content, or silently changing private messages.
Persist user saves as authoritative per-account snapshots while retaining legacy overlay compatibility. Validate deterministic topology errors before writing and replace configuration files atomically.
Compile canonical names, aliases, stream kinds, documentation, and raw reservations into one immutable registry. Reject duplicate, undeclared, mismatched, or late handler registration before requests can be dispatched.
Wait for asynchronous transports to flush bad-request frames before processStreamRequest returns. This prevents malformed Stream API requests from losing their terminal error response.
Cap long-message gunzip output at 32 MiB and fail before an oversized QQ response can exhaust process memory. Include the resource id, compressed size, and configured limit in observable errors.
Apply the configured payload limit while per-message deflate is producing output, including fragmented frames. Abort oversized expansion before it can allocate unbounded memory.
Reject malformed nested payloads, cap compressed card expansion, and enforce per-message decode budgets. Preserve unknown-wire metadata in diagnostics so unsupported QQ elements remain observable without exhausting memory.
Reject malformed varints, out-of-bounds fields, and invalid groups before they escape their parent frame. Aggregate unknown-field metadata and decode signed int32 values while preserving SnowLuma's existing outbound encoding bytes.
send_private_msg / send_msg can now reply to a group temp-session message
by passing the source group_id. Inbound temp messages surface their
source group on sender.group_id; a reply is only made into a temp session
the bot has an inbound record of. Group temp replies route through
RoutingHead.grpTmp (field 3).