Skip to content

AXIS v2.24.7

Choose a tag to compare

@github-actions github-actions released this 19 Oct 19:41
· 282 commits to main since this release
a2a4efb

[2.24.7] — 2026-10-19

Added

  • GitHub Release notes use the CHANGELOG version section (scripts/generate-changelog.py --extract) instead of the generic “Desktop build of AXIS (Tauri 2)” stub.
  • MCP connect / session chip sits on the command bar trailing edge (very top row, above Studio). Overlay indicator plots stack above price candles (setSeriesOrder); Layers lists Scripts above Panes.
  • Topbar Market after Venue. Binance (and OKX / Bybit / MEXC) can switch Spot, USDT-M, and COIN-M. BTCUSDT on Binance was always spot (api.binance.com / stream.binance.com); USDT-M uses fapi / fstream, COIN-M uses dapi / dstream. Engine series keys send PYNE/CCXT names (swap / future).

Fixed

  • CI is green again. The coverage gate ran the test files in parallel, so files sharing module state raced (clampPointsToPaintedRange) and every run since 2026-10-15 failed on a flaky assertion. The gate now runs serialized (--max-concurrency=1), and the engine-owned live plane (wire, series subscription, snapshot paint, close verification) got real unit coverage — the coverage floor (89%) was below it and is met again.
  • Pyodide compile mode no longer crashes on alert() / alertcondition(). The wheel hands the compiled __alerts back as an empty float array, and the runtime’s or [] on it raised ValueError: The truth value of an empty array is ambiguous — the whole compile run failed in the browser (Pyodide has no Numba, so this path is the norm there). The runtime now normalizes the packed event containers without truthiness checks.
  • A broken engine WebSocket no longer re-opens on every run. An abnormal close (1002 protocol error, 1006, 1011) after the socket opened now marks the shared /ws/run client dead for the cool-down, so the next runs go straight to REST instead of re-connecting to an endpoint that accepts the handshake and then drops every frame. Normal closes (1000 / 1001) keep the client reusable.
  • Interval switch no longer paints a stale cache tail plus the live candle. Switching 5m → 1m used to show yesterday’s last cached bar, a hole, then the current price because live started before venue pages closed cache→now. The load path now fills that tail before startLive.
  • Internal holes in the painted window are filled from the venue. A 1m cache that already reached “now” still left a ~2h blank (133 bars); load now fetches those ranges before live starts.
  • /ws/live subscribes a 500-bar tail instead of the full 5k window. A 5000-bar 1m full timed out; the chart stays on the REST/DSM window and the socket can go live.
  • Transient /ws/live errors no longer disconnect() the client. Snapshot timeout, empty snapshot, and subscribe/connect errors still fall back to venue+REST and debounce subscribe, but stopped stays false so the socket can stay up or reconnect. Only reset() / stopLive stop the client.
  • /ws/live snapshot wait is 120s, and a script miss no longer cools the series wire. History ensure of a painted 5m window often exceeds 30s; a Keltner (script) snapshot-timeout used to fail() the whole socket so the HUD stayed degraded · venue+REST.
  • Plot fills tail-align when the engine series is shorter than the chart. Adding Keltner (or any fill()) on a 5000-bar cache plus DSM/forming bars no longer leaves the band 2–3 candles left of the last bars.
  • Worker and engine API keys survive a new tab, PWA update, and browser restart. The secret vault was memory + sessionStorage only, and persist stripped apiKey from the app-state JSON — so the first hard reload after that migration (or the 2.24.6 update) looked like the app deleted the keys. They now also live in a dedicated localStorage bag (axis.secret-vault.v1), still out of workspace snapshots and the main persist payload. Exchange CEX keys stay session-only.
  • /ws/live no longer dies on Redesign2 auth timeout. Browser sockets cannot send Authorization, so the client now puts api_key on the upgrade URL (the engine already accepts that handshake) and does not block connect() on auth.ok. The auth frame is still sent. A close rejects any leftover auth waiter.

Desktop installers (Tauri 2). CLI tarball, worker bundle, and checksums attach from the Release workflow.