Adds three seeded shape traits composable with all existing looks:
round/squat/slender builds via aspect-ratio stretch (svg renders with
preserveAspectRatio=none so eyes, claws, accessories, and rare-variant
geometry stay aligned), dainty/regular/mighty claw sizes scaled on the
paths inside the claw groups so wave/snip act animations still compose,
and a ~30% tail fan with lobes peeking out behind the lower body. Shape
rolls come after the original traits in the RNG sequence, so existing
seeds keep their palette and personality. The sprite svg gains
overflow: visible so scaled mighty claws are not clipped at the viewBox
edge; the host strip still owns the ledge clipping.
Session menu items (Open chat, Pin, Mark unread, Rename, Fork, Workboard,
Archive, Delete) and native link menu items (Sidebar, Browser, Copy) now
render right-aligned accelerator hints and activate on bare letter keys
while the menu is open. Disabled items and modified keystrokes are ignored;
buttons expose aria-keyshortcuts.
Closes#103086
The docs landing page and README still led with the retired cartoon
crawfish wordmark while the rest of the site uses the round mascot brand.
Swap in generated hero banners (dark/light), add the missing fourth
quick-start card (Connect a Channel), align the Mintlify backup palette
with the site coral tokens, and drop the old logo assets.
* fix(nvidia): refresh bundled featured models
* fix(nvidia): match featured model feed exactly
* fix(nvidia): remove transient feed detail
* fix(nvidia): correct super context window
* fix(nvidia): align auth choice expectation
* fix(nvidia): hide deprecated models from selection
Refresh the bundled featured catalog while retaining deprecated model metadata for exact-reference compatibility. Route NVIDIA onboarding and catalog picker surfaces through selectable-only provider builders.
* fix(nvidia): simplify featured model table
* fix(nvidia): restore shipped compatibility rows
Render pending approvals from shared typed views, add marked grapheme-safe display wraps for QQ Desktop, preserve the 300 UTF-16-unit cap, fence command and metadata safely, and report plugin expiry from the runtime clock.
Fixes#101979
* fix(agent-runner-memory): use truncateUtf16Safe for memory flush error truncation
Replace raw UTF-16 slices in buildMemoryFlushErrorPayload and
truncateMemoryFlushErrorMessage with truncateUtf16Safe to prevent
surrogate pair splitting in error messages shown to users.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
* test(auto-reply): cover UTF-16-safe memory errors
* test(auto-reply): tighten UTF-16 memory error coverage
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(heartbeat): remove static iteration cap in seekNextActivePhaseDueMs
* fix(heartbeat): floor seek step at 60s to bound active-hours seek iterations
The static MAX_SEEK_ITERATIONS cap (10,080 ≈ 7 days / 1 min) was removed
in the previous fix but replaced the risk with unbounded iteration for
sub-minute intervals. Floor the seek step at 60s via MIN_SEEK_STEP_MS
so the loop is always bounded by MAX_SEEK_HORIZON_MS / 60_000 = ~10,080
iterations regardless of the configured intervalMs. Active-hours windows
are minute-granular, so finer steps add no precision.
* fix(heartbeat): batch seek in whole-interval multiples to preserve phase alignment
Use the smallest intervalMs multiple >= 60s as the seek step so every
candidate checked is reachable from startMs by whole intervalMs steps.
This fixes the phase-alignment regression from the previous fix where
Math.max(intervalMs, 60_000) could return off-phase slots for non-divisor
sub-minute intervals like 45s.
Added a regression test for 45s interval to verify the returned candidate
is phase-aligned.
* fix(heartbeat): check every phase candidate, bound only by 1M-iter safety cap
Drop batched seeking (intervalMs-multiple steps) because any multiplier > 1
can skip phase slots inside narrow active windows. Instead check every
phase candidate, with a 1M-iteration safety cap that prevents event-loop
stalls from sub-ms intervals while covering the full 7-day horizon for
intervals >= 605ms.
Added regression test for 59s interval / 1min active window where batched
steps (118s) would skip from 08:59:44 past 09:00:43 to 09:01:42.
* fix(heartbeat): bound sub-second seek with batch-step + backward-walk
Replace the 1M-iteration per-candidate cap with a two-tier strategy:
- intervalMs >= 1s: per-candidate scan (naturally bounded by horizon)
- intervalMs < 1s: batch in whole-interval multiples >= 1s, with
backward walk on inactive->active transitions to find the earliest
phase-aligned active slot
Max iterations <= 604,800 in all cases (~10 ms for trivial predicates,
~0.6-6 s for production isWithinActiveHours with Intl.DateTimeFormat).
Added tests:
- Sub-second interval, startMs already active -> returns directly
- Sub-second interval, inactive->active transition -> backward walk
finds earliest phase-aligned slot
* fix(heartbeat): unify seek at >= 30s batch step, max 20,160 predicate calls
Use a single batched-seek path for all intervals: step in whole-interval
multiples >= 30 s with backward walk on inactive->active transitions.
For intervalMs >= 30 s (30 s, 59 s, 60 s+): multiplier = 1, effectively
per-candidate with no batch overhead.
For intervalMs < 30 s (1 s, 500 ms, 1 ms): batched at >= 30 s, backward
walk finds the first active phase-aligned slot in the window.
Max predicate calls <= 20,160 for any interval (30 s minimum step /
7-day horizon). Production isWithinActiveHours (Intl.DateTimeFormat)
cost: ~20–200 ms worst case vs 0.6–6 s for the per-candidate approach.
* fix(heartbeat): bound active-hours seek cost
* fix(heartbeat): resolve current main
* test(heartbeat): isolate active-window regression
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>