Changelog
Release notes for AXIS.
This page
Manuals
All notable changes to AXIS (hoox-sh/axis) are documented in this file.
This changelog is recursive: it lists the full git history of the
repository, grouped by month and conventional-commit type. Agents and
humans must keep it updated on every release (see AGENTS.md § Changelog & releases).
Format roughly follows Keep a Changelog with commit SHAs for traceability.
Generated/updated: 2026-09-12 · 401 commits · describe-tag: v2.6.5
[Unreleased]
Added
- Convert to Pine v6 in the editor overflow menu and command palette. Rewrites any older version (missing
//@versioncounts as v1) toward v6: colors /n/ timeframe names,ta.*/math.*/request.*,study(→indicator(, typedinput.*(),iff/offset. Not a semantic v6 migrator. - Alerts panel: create form covers percent-change, drawing-touch, and indicator plot conditions (not only price / on-chain). Delivery is browser notifications, a compact HTTPS webhook, and an optional L2 webhook (
channel: "l2"payload). Live stream ticks evaluate the book. - Pine
alert()/alertcondition(): interpret runs export enginealertsinto the book (pine_alert). Arm any/alert()/alertcondition()(optional title) on a strategy or indicator; last-bar watermark avoids backtest spam. Strategyalert_messagefills are included. Pyodide interpret exports the same payload. - Compile-path Pine alerts: in-browser compile records
alert()/alertcondition()in the object-mode bar loop (PYNE's compiler used to emit empty statements for Numba). Remote Flask/pyne-worker compile still cannot collect Python alert events, so AXIS sends interpret when the script calls those builtins.
Fixed
- Fold marker labels were inverted (expanded blocks announced “Unfold”). They now read Fold block / Unfold block.
Changed
- Workstation chrome polish: two-bar command + module switch, 4/8px grid, 1px hairline, periwinkle
#8B9CFFon#07080C/#0C0E14, Live as a 6px pulse, HUD capsules, 32px watchlist rows, 32×32 drawing rail, 26px status strip, tablet overlay drawers, mobile Chart/List/Editor/More. Same product — density and grouping only. - Cloudflare® rename: Worker script
pynescript-axis→worker-axis(https://worker.axis.hoox.sh). Pages projectpynescript-axis→axis(https://axis.hoox.sh; previews*.axis.pages.dev). Health JSONserviceisworker-axis. Legacypynescript-axis.pages.devandpynescript-axis.*.workers.devhosts still match in CORS / client heuristics. - Live stream on by default: Settings → General → Enable live stream (
live.preferAfterLoad, default on). Saving starts or stops the venue WebSocket; boot starts live when history is already loaded. Persist no longer writes a false default when the flag was missing. - Server/Pyodide execution default is Auto (try compiler, fall back to interpreter). Strict Compiler is not the default: Flask/Numba is not prewarmed, first compile JITs, and some Pine stays object-mode. HUD and first-run now follow the engine schema instead of showing Interpreter when mode was never saved.
- Editor fold gutter: 14px Lucide chevrons replace the 10px
▾/▸glyphs (down = expanded, right = folded), with a clickable⋯placeholder on folded blocks. Tab close/add and header Run/Library/Profiler use the same icon set and size. - Editor color tools: one working color (picker overlay + any-form input + transparency) instead of a disconnected converter that stayed on
#939fff. Chip captions use#RRGGBB tNsocolor.new(...)is not truncated; formats list copies the draft; Replace / Replace all / Jump; checkerboard swatches show Pine transparency.
[2.6.6] — 2026-09-12
Fixed
axis secret put ADMIN_TOKENvs Cloudflare® 10053 (@hoox-sh/axis-cli0.3.2): empty[vars] ADMIN_TOKEN = ""is still a binding, so Wrangler refuses the secret.axis secret putnow comments the plaintext var, deploys once to drop it, retries on 10053, then sets the secret.axis keys createprompts for the token (CLI cannot read Worker secrets) and doctor warns on a leftover[vars]stub.
[2.6.5] — 2026-09-12
Added
- AXIS CLI cloud-storage bootstrap (
@hoox-sh/axis-cli0.3.1):axis setup --prod/axis setup kvcreate and bindAPI_KEYSKV;axis keys create/validatemint and checkpn_…keys;axis deployapplies the remote D1 schema first;axis health --scriptsandaxis doctor --remoteprobe/api/scriptsandfeatures.keys. Typical prod path is nowsetup --prod→secret put ADMIN_TOKEN→deploy all→keys create.
Changed
- CLI
run()now times out Wrangler (wrangler whoamiin doctor) with SIGTERM then SIGKILL soaxis doctor --jsoncannot hang.
[2.6.4] — 2026-09-12
Added
- Script version history on every storage engine: local (IndexedDB/
localStoragesnapshots, FIFO 50) and cloud Worker (script_versions+GET /api/scripts/:id/versions) now implement the samelistVersions/readAtRevisioncontract as git. The library history panel is no longer git-only. - Worker URL + API key in Settings: Script storage credentials for the cloud Worker (
endpoint+pn_…key, generate demo key, test connection) live in Settings → General / Studio Settings as well as Script Library. Switching to Cloud no longer requires hunting the library panel first. - Workers inventory skeleton: while backends are probing, the Workers page shows pulse placeholder cards (and an inspector skeleton) instead of an empty grid.
Fixed
- Cloud script storage used the Pine engine URL:
resolveCloudConfigno longer falls back tostore.endpoint(:5002//api/run). Worker base defaults to wrangler:8787on localhost or the production workers.dev host. - Storage engine switch deleted the source library: copy between engines never calls
removeon the source. Dialog primary action is Copy scripts; Switch without copying leaves both libraries as-is. - Minimap height restored: short files no longer stretch the overview canvas to the full editor column — 2px per line, compressed only when the document exceeds the host.
- Update reload asks first: Update now / Hard reload (and
hardReloaditself) open a confirm prompt with current → new version before the app reloads. - Studio always opens Settings: the topbar / palette Studio button lands on Settings every time (no longer restores the last rail page). Settings is the first Workspace rail item. The Studio click handler no longer falls through
??into Runtime then Workers because those callbacks returnvoid. - Workers is a full-viewport studio page: same overlay as Settings/Runtime/Wire/Plugins (not a half-width right sheet). Escape closes it.
Changed
- Storage-change dialog copy: “Copy scripts” / “Switch without copying” instead of migrate-and-delete / start fresh.
[2.6.3] — 2026-09-12
Fixed
- Docker image build failed on
sync:versions:bun run buildstamps Dockerfile/compose/bake VERSION fallbacks, but the image context did not copy those files →ENOENT /app/Dockerfileduring GHCR bake. Missing stamp files are skipped, and the three files are copied into the build stage.
[2.6.2] — 2026-09-12
Added
-
Editor minimap (interactive): a scaled canvas overview docked to the editor right edge — one row per line, accent viewport box, cursor line. Click/drag scrolls the editor; auto-hides in narrow containers. Toggle in the editor overflow menu (View → Minimap, persisted
editorMinimapEnabled, default on). -
Foldable code sections: indent-based folding for Pine (StreamLanguage has no syntax tree) with a void-styled fold gutter plus standard fold keybindings.
-
Indent grid: faint
·dots for leading whitespace plus one vertical guide per completed 4-space indent level, width-preserving and viewport-scoped. -
Per-tab version/type badges + Save: each editor tab shows
vN(from//@version=,–fallback) andSTR/IND/LIB(from the declaration call,–fallback) plus a Save button that persists that tab via the existing library/draft path. -
Workers stays a right-side non-modal sheet: the Workers overlay remains a right-aligned sheet with a left scrim that click-throughs to the chart/editor (modality unchanged: no focus trap, no Escape-steal) — not a full-width page like Runtime/Wire/Settings/Plugins.
-
Language Feature Bar above the editor status strip: a chip row (Hover · Sig · Complete · Lint · Marks · Chips · Remote) where each chip is colored only while the feature is actually firing (open card / list / hint, running check, rendered marks) — dimmed while switched off — so the bar shows which features the current script uses and which could be disabled. Click toggles the master switch, long-press (~550ms) or right-click opens a popover with the group's full settings. The row itself is a persisted “Language Feature Bar” option (Settings → Editor intelligence → View, default on;
editorFeatureBarEnabledin the store). -
Standalone CLI binaries (bun compile):
bun run build:binaries(packages/cli/scripts/build-binaries.ts) cross-compiles the CLI into single-file executables for 7 targets — linux x64/arm64 (glibc + musl), macOS x64/arm64, Windows x64 — with a native--version/--helpsmoke test. Own package metadata is now embedded at bundle/compile time (src/own-package.tsstatic JSON import) and preflight recognizes a newbinaryinstall context ($bunfs→ "standalone binary (bun compile)"), so version display, engine checks, and drift detection work without a package.json on disk. Binaries ship asaxis-cli-<version>-bun-<target>release assets and are covered bySHA256SUMS(bare asset filenames — a flat download verifies with onesha256sum -c). -
VERSIONsingle source of truth: the repo-rootVERSIONfile now owns the release number —bun run sync:versions(runs withbun run build) stampspackage.json,src-tauri/tauri.conf.json,src-tauri/Cargo.toml,src-tauri/Cargo.lock,public/version.json(served at/version.json), and the generatedsrc/version.ts(APP_VERSION, also shown in About) +worker/src/version.ts(WORKER_VERSION, surfaced on/+/health).bun run check:versionsasserts the whole set; the Makefile readsVERSIONdirectly. -
Update manager + notification: the app polls the deployed
/version.json(5 min interval + focus/visibility/online, cache-busted) and a waiting service worker routes through the same state — a new deploy shows anaxis-update-banner(Update now / Hard reload / Later), announces via screen-reader live region + status line, and fires a Browser Notification when permission was already granted (never prompts). Hard reload unregisters workers, deletesaxis-*caches, and navigates cache-busted. Covered bytests/update-manager.test.ts+tests/version.test.ts. -
Window-close confirmation:
src/pwa/close-guard.tsinstalls onebeforeunloadlistener per page and prompts only while a registered predicate reports unsaved work — the tabbed editor registers dirty-tab state (both chart and popout shells). Master switch + custom message APIs included; covered bytests/close-guard.test.ts.
Fixed
- Pyodide engine crashed on bars containing null (
eval_codetraceback + empty drawings): the browser bridge interpolated rawJSON.stringify(bars)into Python source, so JSONnull/true/falsebecame PythonNameErrors before Pine ever ran — surfacing only as a truncated_pyodide/_base.pytraceback withdrawings: [].src/engines/catalog.ts,src/engines/index.js, andworker/src/pyodide_runtime.tsnow pass JSON strings viaglobals+json.loads, returndrawings: []on bridge failures, and surface the full Python traceback (newcallPyodideRunScript/formatPyodideBridgeError, covered bytests/pyodide-bridge.test.ts).pyodide/pynescript_runtime.pyre-synced with the deployedpublic/pyodidecopy (drawing-registry reset + compile-path GC). - Pyodide bridge errors kept their head, not the exception tail:
formatPyodideBridgeErrorcut long tracebacks withfull.slice(0, 6000), dropping the finalNameError: …line that users need; it now trims the middle (keeps theeval_codehead + the exception tail) insrc/engines/catalog.ts, the legacysrc/engines/index.js, andworker/src/pyodide_runtime.ts— which previously surfaced onlyerr.message(Pyodide's…-truncated form). Covered by a newtests/pyodide-bridge.test.tscase. - Language Feature Bar nits: clicking a chip whose settings menu is open now dismisses the popover instead of flipping the group's master switch (long-press opens the menu; the natural dismissal — a short press on the same chip — accidentally toggled the feature off). Number settings (Hover delay, Max options, …) now draft raw keystrokes and clamp/commit on blur or Enter, so values below a field's
mincan be typed instead of snapping mid-entry. Clicking a different chip while a popover is open switches the popover without toggling. - Test DOM stub Symbol-safety:
tests/setup.tsdatasetproxy now passes through non-string keys (e.g.Symbol.toPrimitive) instead of throwing onconsole.log/inspect, and the traceback-trim budgets are named constants kept in sync acrosssrc/engines/catalog.ts,src/engines/index.js, andworker/src/pyodide_runtime.ts. - Docker builds were broken by the git-hooks
preparescript: rootpackage.jsongained"prepare": "git config core.hooksPath .githooks"(commitd5f0cf89), which runs on everybun install— including inside the imagedepsstage, where git is not installed → exit 127 on every bake since then (v2.6.1 GHCR images never published). The Dockerfile now installs with--ignore-scripts(no dep needs lifecycle scripts; native binaries ship as platform optionalDeps) — verified with a localbuildtarget bake (dist/.version= 2.6.1). Stale version fallbacks (2.3.0/2.3.1) refreshed to2.6.1acrossDockerfile,docker-bake.hcl, anddocker-compose.yml. - Service worker no longer cache-first
/version.jsonprobes: cache-busted/version.json?t=*polls were classified as same-origin static and stuffed unique entries into the 96-entry runtime cache, evicting hashed chunks and/pyodide/*. Those probes now bypass the SW. Cache names bumpedv6→v7so poisoned runtime caches are dropped on activate. - Close-guard disabled before update hard/soft reload: the unsaved-work
beforeunloadprompt blocked Update now / Hard reload; the update path now disables the guard immediately before navigating. - Drawings e2e counts user-drawing SVG only: the chart overlay SVG count no longer includes chrome/grid paths, so the trend-line persistence assertion is not a false pass.
openStudiono longer toggle-closes a slow overlay: opening Studio while the sheet is still animating in no longer treats a second click as a close.- CLI binary install URL documents app tag vs CLI version: GitHub Release tags use the app
VERSION(v2.6.2); standalone binaries are named with the CLI package version (axis-cli-0.3.0-bun-linux-x64). The CLI README curl snippet now uses both current values so the documented URL is not a 404. - Docker build stamps
VITE_APP_VERSIONfrom theVERSIONfile: compose/bake ARG fallbacks are no longer the Vite stamp, sodocker compose up --buildwithoutVERSION=matches/version.json.DockerfileARG VERSION=, compose${VERSION:-}, and bakevariable "VERSION"defaults joinsync:versions/check:versions. - Feature bar long-press/contextmenu no longer race-dismiss; dialog focus: the chip popover no longer closes on the same pointer that opened it, and the settings dialog receives focus.
- Minimap pointercancel + full-height hit target:
pointercancelends a drag the same waypointerupdoes, and the hit area spans the editor height so clicks near the gutter register. - Workers non-modal sheet restored: Workers is a right-aligned sheet again (not full-width), with a left scrim that click-throughs to the chart/editor.
IndentWidget.eqso guides don't rebuild on every scroll: indent-grid widgets compare equal across viewport updates, so CodeMirror does not reconstruct guides on each scroll.
Changed
- Coverage push toward 80/85%: ~260 new unit tests across gateway, signed-fetch, pine-logs, watchlist tickers/live, symbol catalog, bars-cache, streams catalog, workers probe, git-oauth, dataset sinks/expand, data-source-manager, credentials, and drawing coords (
createCoordContextwith stub scales — coords 36% → ~100%) — scoped core gate up 82.8% → ~90% (passes the 80% and 85% floors), app lines 80.1% → 82.6%. Fixed 5 wrong expectations in the generated data-coverage tests (walk-loopexpandedsemantics, same-bucket merge conflicts, sink-merge unions) and 2 cross-suite leaks (probe teardown deleting the sharedwindowstub, a real-timer device-flow poll). Overall lcov sits at ~79.3% — the remainder is browser/chart/worker-runtime code (drawing layer, pane manager, pyne-lsp, durable session) that needs E2E rather than unit tests. - Drawings e2e + chart DOM harness: new
e2e/charts.tsharness (stubbed network, mock-bar boot, toolbar tool selection, chart clicks, SVG shape counting) ande2e/drawings.spec.ts— draws a trend line via the real toolbar, asserts the SVG overlay renders, reloads to prove storage persistence, and switches tools. Covers the browser-bound drawing layer that unit tests cannot reach (no layout engine/canvas in bun). - GitHub Release now carries CLI + worker artifacts: a new
release-assetsjob in.github/workflows/release.ymlattaches, for everyv*tag, the offline-install CLI tarball (axis-cli-<cli-version>.tgzvianpm pack— verified with an offlinenpm i -g+axis --versionsmoke), a deployable worker source snapshot (axis-worker-<tag-version>.tar.gz—LICENSE+worker/minusnode_modules/.wrangler/.dev.vars, sanity-checked forwrangler.toml.example+src/index.ts), andSHA256SUMS-<tag-version>.txt. The job waits for the desktop workflow to create the Release (creates it itself if desktop never does) and uploads with--clobber; existing tags can be backfilled viagh workflow run release.yml --ref main -f tag=vX.Y.Z. - CLI binary smoke test runs on host-native targets:
packages/cli/scripts/build-binaries.tsno longer assumes a linux-x64 host — it smoke-tests whichever wanted target matches the running platform/arch (e.g.bun-darwin-arm64) and skips cleanly when none does, sobun run build:binariescross-compiling on macOS/ARM64 dev machines no longer fails on the smoke step. Classic CI (ubuntu-x64) smoke is unchanged. - Pyodide runtime surfaces drawing-GC failures instead of silently no-opping:
pyodide/pynescript_runtime.py(synced topublic/pyodide) now warns once on stderr whenDrawingRegistryexport/limits or the compile-pathgc_exported_drawingscall fails (e.g. a pyne wheel API change/move) rather than swallowing the error whilemetastill advertises the caps.max_*_countdeclaration parsing now strips//and/* */comments so a cap mentioned in a comment isn't captured, and the redundant"mode"entry is dropped fromcompile_meta.
[2.6.1] — 2026-09-08
Fixed
- Desktop bundles carried the wrong version: the v2.6.0 GitHub Release shipped desktop assets named
2.4.1becausesrc-tauri/tauri.conf.json,src-tauri/Cargo.toml, andsrc-tauri/Cargo.lockwere never bumped past v2.4.1 —tauri-actionderives bundle versions from the Tauri config, not the git tag. All four version stamps are now2.6.1, and a newbun run check:versionsguard (scripts/check-versions.mjs, enforced in CI + the desktop workflow) fails on any drift.
Changed
- Script Logs moved into the editor: the topbar
Script Logsbutton and the shell-levelScriptLogsPanel(src/ui/ScriptLogsPanel.tsx, deleted) are gone — logs now live as an editor-localScriptLogsPane(src/editor/ScriptLogsPane.tsx) above the editor statusbar, toggled by aLogsbutton besideSymbols(axis-editor-logs-toggle+axis-editor-logs-badge) and via the palette (axis-editor-show-logsevent). Statusbar clusters now wrap as units (flex-wrap, actionsflex-shrink-0) so buttons stay clickable in narrow docks instead of squeezing under each other. Guards: Playwright smokeScript Logs lives in the editor bottom bar, not the topbar. - Default timeframe is now 15m: the chart-slot fallback (
src/chart/layout.ts) and workspace-snapshot build/parse fallbacks (src/storage/workspace-snapshot.ts) changed from1dto15m, matching the store default — new chart slots and restored snapshots without an interval start on the 15-minute TF. - Studio opens on Settings:
lastStudioPageinitial insrc/app.tsxchangedruntime→settings— the first Studio open (topbar button / palette) lands on Settings (subsequent opens still remember the last page). - Workers page is non-modal:
AppPage(src/ui/studio/AppPage.tsx) gains amodalprop;StudioHostrenders Workers non-modally — transparent click-through scrim (new.ax-page-backdrop--nonmodalsheet instudio.css), no focus trap, no Escape-steal — so the chart and editor stay interactive while Workers is open. Modality follows the active rail page; other pages are unchanged. - Workers top status grid removed: the aggregate Healthy / Health / Active backend summary deleted from
src/ui/workers/WorkersPage.tsx— status now exists only per worker (inventory cards + detail pane + footer probe line). Guards: Playwright smokeWorkers page is non-modal(scrim pointer-events, no top status, Escape does not close).
Added
-
Versioned git hooks (
.githooks/): pre-commit runs Biome (check) on staged files only (fast); pre-push runsbun run typecheck(tsc) +bun run lint(errors fail, warnings pass). Auto-configured via the rootpreparescript (git config core.hooksPath .githooks) on everybun install; bypass with--no-verify. -
CLI installation self-check (
@hoox-sh/axis-cli0.3.0): everyaxiscommand self-verifies on start (packages/cli/src/utils/preflight.ts) — engine compliance (Node ≥ 20 / Bun ≥ 1.2), install context (npm install / npx cache / repo checkout), and version drift when a globally installed CLI is older than the repo checkout it operates on (warnsnpm i -g @hoox-sh/axis-cli). Warnings-only on stderr: skipped for--version/--help, silenced by--quiet/--json, never blocks or fails a command.axis doctorgains the optional CLI installation row (cli-installin--json). Tests:packages/cli/tests/preflight.test.ts(context detection, engines, drift, doctor row).
Changed
- Docs are CLI-first: all
bun run axis:*invocations acrossREADME.md,AGENTS.md,docs/**(cloudflare, local-dev, index, topologies, vps-demo),worker/README.md, andpackages/cli/README.mdreplaced with the primaryaxis <command>form;bun run axis:*is now documented as a repo-only alias (alias tables flipped indocs/devops/cli.mdxanddocs/enduser/getting-started/installation.mdx). New Installation self-check section in the CLI docs.
[2.6.0] — 2026-09-08
Added
- Keypress feedback for consumed shortcuts:
dispatchShortcutnow emits anaxis-shortcut-firedCustomEvent (id / chord / description —src/ui/shortcuts/runtime.ts) and a transient bottom-center chip (src/ui/shortcuts/Feedback.tsx,data-testid="axis-shortcut-feedback",aria-live="polite", pointer-events none, ~1.2 s auto-hide, platform-correct chord glyphs viaformatChord) confirms every consumed binding — main shortcut keys no longer feel dead even when the side effect is subtle.
Changed
- Docs synced to v2.5.0:
docs/index.mdx+docs/enduser/getting-started/installation.mdxversion stamps;docs/ui/ui-shell.mdxgains Keyboard shortcuts (dispatch hub, scopes, recorder, Shortcuts modal) and Mobile shell (phones / tablets) sections;docs/ui/index.mdxsubsystem table mentions shortcuts + mobile shell;docs/ui/results-and-strategy.mdxanddocs/enduser/guides/strategy-and-results.mdxdocument the v2.4.3 results overhaul (Events Stream/Open⇄Close position-cycle views, single-column strategy tab, saved-run stats snapshots, sharedwalkStrategyEventswalker).
Fixed
- Keyboard shortcuts were dead:
ShortcutHubwas never mounted (the component had zero importers, so the capture-phase keydown dispatcher insrc/ui/shortcuts/Hub.tsxand the wholesrc/ui/shortcuts/actions.tsregistration side effect never loaded) —Ctrl/Cmd+K/Ctrl/Cmd+Shift+P(command palette),Shift+?(shortcuts help),Ctrl/Cmd+,(settings),Ctrl/Cmd+\(toggle editor),Esc, and everychart.*binding (zoom / pan / tool letters / grid layouts) silently no-oped. The product shell (src/app.tsx) now mounts<ShortcutHub />(plus<ShortcutFeedback />). Only the parallelMod-S/Mod-Ghandler insrc/editor/tabbed-editor.tsxsurvived, which is why save worked while the palette was unreachable by keyboard. Guard tests:tests/shortcut-feedback.test.tsand the Playwright smokeMod-K opens and closes the command palette (shortcut hub guard)ine2e/smoke.spec.ts.
[2.5.0] — 2026-09-07
Added
- Mobile-first responsive shell (phones ≤767px, tablets 768–1023px; desktop ≥1024px unchanged):
- Viewport signal (
src/ui/responsive.ts): reactivephone | tablet | desktopmode +pointer: coarsedetection — all JS layout branching keys off this instead of CSS-only hacks, because panel geometry is persisted px state. - App-style phone shell: compact header (brand · venue picker · symbol picker via SymbolModal · interval select) + bottom tab bar (Chart · Panels · Editor · Studio · More) replace the desktop Topbar/StatusBar; Panels list and More drawer (Run, Live, Studio pages, Settings, theme, About) open as nav overlays.
- Panel sheets (
FloatableShellmobile mode): docked/floating panels render as full-viewport sheets under the header / above the tab bar — one active sheet at a time (src/ui/panels/mobile-sheet.ts); drag-to-undock, resize handles, and hover-slide are disabled on phones. Sheets dismiss via swipe-down on the title bar (grabber affordance + live translate feedback) or the close button. Desktop geometry is bypassed, never overwritten, so phone↔desktop switches preserve the user's layout. Phones boot chart-first (open panels don't steal the viewport). - Chart force-single on phones: 2H/2V/4 layouts collapse to the active slot with a slot-switcher chip row; other slots stay preserved in
store.chartLayout. - Tablet: desktop shell kept, topbar becomes horizontally scrollable.
- Dialogs → bottom sheets on phones (
sc-dialog), safe-area insets (viewport-fit=cover,env(safe-area-inset-*)),100dvhapp root,interactive-widget=resizes-contentfor soft-keyboard handling, ≥44px touch targets in mobile chrome (pointer: coarse). - Studio tables wrap cells on phones instead of forcing horizontal overflow.
- Viewport signal (
- PYNE runtime 0.5.0: vendored
pynescript-0.5.0-py3-none-any.whl(built from the sister pyne repo viascripts/sync-pyne-wheel.sh); stale 0.4.x wheels dropped; hard-coded wheel paths insrc/engines/catalog.ts/src/engines/index.jsupdated (hoox_pyne-0.4.2/pynescript-0.4.0→pynescript-0.5.0). Pine language builtins unchanged.
Changed
- Zero Biome lint errors (368 → 0) across 641 checked files:
- Tooling: Biome 2.5 (
biome.json, lint-only — Prettier keeps formatting),lint/lint:fixscripts, Prettier 3.9 pinned (.prettierrcsingle-quote/width-100,.prettierignore), projectopencode.jsonenabling LSP + formatter. - Real fixes: regex
exec-loops →matchAll()(pine-colors, preevaluate, pyne-lsp, script-inputs, library-publish, …),type="button"on ~18 buttons, keyboard handlers (Enter/Escape) +tabIndex/ARIA value semantics on interactive widgets,role="region"divs →<section>, global-shadowing renames (escape→escapeHtml,valueOf→readFieldValue), duplicate object keys removed,const enum→enum(isolatedModules safety). - Justified suppressions (each with reason): intentional control-char sanitization regexes (injection safety), CSS
env(safe-area-inset)fallbacks, backdrop click-away surfaces, custom-widget rows with nested buttons, sticky-regex tokenizer. - Verified regression-free:
tsc --noEmitclean; test suite identical to pre-change baseline (pre-existingserver.test.tshook timeout +window.matchMediacross-file pollution unaffected).
- Tooling: Biome 2.5 (
[2.4.3] — 2026-09-07
Added
- Results panel — events views & richer reports (spec:
.opencode/specs/2026-09-07-results-views-design.md):- Events tab view switcher:
Stream(classic chronological list, now enriched with entry fill count / running position qty+avg,from_entry, remaining qty after closes, and per-fill P&L on close/exit rows) and Open ⇄ Close — a two-column grid with one row per position: entries on the left (fill list, pyramiding averages into the position, total qty @ avg price), exits on the right (each close fill with P&L, partial-close remainder, Open/Closed badge). Re-opens after a full close form new cycles (id #2);close_allflattens every open cycle; rows click-jump to the fill on the chart. - Strategy tab — single column: fill options → stats cards (12: trades, win rate, W/L, PF, net profit, Return % (compounded per-trade), max DD, avg trade/win/loss, gross profit/loss) → equity chart → closed-trades table below it, with new Bars (bars held) and Fills (pyramided entry count) columns.
- Saved runs tab — rich stats:
buildResultMetanow persists a JSON-safe strategy stats snapshot (StrategyStatsSnapshot) computed from the run's events (profitFactor: null= ∞); saved rows render a stats grid (trades, W/L, win %, PF, net P&L, return %, max DD, avg trade); legacy saved rows fall back gracefully. - Pyramiding parity: entry fills into a live position now average into the trade P&L (
entry = Σ(p·q)/Σq) matching the pyne broker(px − avg) × close_qty; per-position cycles and the enriched stream are computed by a single shared walker (walkStrategyEventsinsrc/results/strategy.ts, re-exported viasrc/results/positions.ts).
- Events tab view switcher:
[2.4.2] — 2026-09-07
Added
- Global keyboard shortcuts: app-level chord dispatch hub (
src/ui/shortcuts/) with capture-phase handling, dialog-skip guard, per-user persisted overrides on the app store, and a live shortcut registry — wired to the command palette, editor, and chart canvas.- Recorder: Settings → Keyboard → record chord, plus a Shortcuts modal listing default bindings with live rendering.
- Editor line ops (
src/editor/cm-line-ops.ts):Prec.highkeymap extensions (duplicate line, toggle comment, indent/unindent, delete line) for the Pine editor; palette extensions render recorded chords. - CLI npm release pipeline (
.github/workflows/release.yml): full publish flow for@hoox-sh/axis-clivia org secretNPM_TOKEN_HOOXSH—- tag/version guard:
cli-v*tags must equalcli-v<packages/cli version>(hard fail on mismatch); rootv*tags publish the CLI when its version is missing from the registry and skip cleanly otherwise;workflow_dispatchgains aforcere-attempt input. - post-publish registry verification (
npm viewwith propagation retries). - Node-only smoke test: fetches the published tarball, installs it into a clean directory with
--ignore-scripts, and assertsaxis --version/axis --helpon Node (no Bun, no repo). - step summary now reports tag kind, registry verify, and smoke results.
- tag/version guard:
@hoox-sh/axis-cli0.2.2 — first CLI-only release via the new pipeline:cli-v0.2.2tag →Release (npm)workflow (provenance publish, registry verification, Node-only smoke test of the published tarball). Code identical to 0.2.1; release exercises the full publish path end-to-end.
Fixed
- UI review findings (
/.opencode/review/) — 23 of the 25 consolidated findings (editor-audit + pass1/2/3) fixed across the editor, drawing chrome, panels, and themes:- Escape friction cluster (
AXIS-ED-ESC-OVERLAY,AXIS-P1-ESC-CANCEL-DRAFT,AXIS-UI-DRAW-MEASURE-ESC,AXIS-UI-KB-ESC-RECORD): new CodeMirror Escape command dismisses suggest / hover / signature overlays in order; drawing drafts (measure, …) now always cancel on Escape (capture-phase handler immune to other preventDefault consumers); the Keyboard shortcut recorder records Escape as a chord withstopImmediatePropagation+ adata-axis-recording-chordguard so the Studio page no longer closes mid-recording; conflict flags are scope-aware (app.escapevschart.cancel-draftlayer by design, no false conflict). - Drawing flyout clipping (
AXIS-P1-DRAW-MENU-CLIP,AXIS-UI-DRAW-MENU-CLIP): Line / Fib / Shapes / Annot / Measure flyouts and the settings popover clamp to the nearest clipping ancestor — tall menus (13-item Shapes) scroll instead of spilling past the viewport, and flip upward when there is no room below. - Callout / text prompts (
AXIS-UI-DRAW-CALLOUT,AXIS-UI-DRAW-TEXT-FOCUS): all blockingwindow.promptcalls (callout, note, anchored text, text tool, double-click re-edit) replaced with a non-blocking in-app dialog (src/chart/drawings/tools/text-prompt.ts) that autofocuses the input, commits on Enter, cancels on Escape — also fixes Tauri webviews wherewindow.promptis unsupported. - Bar replay dismiss (
AXIS-P1-REPLAY-DBL-CLOSE,AXIS-UI-REPLAY-DBLCLICK): topbar toggle trusts both the subscribed UI state and the module session (a missed emission can no longer turn an exit click into a start), and Escape exits replay. - Results staleness (
AXIS-ED-RESULTS-STALE): the store tracks the newest run (newestRunId); the script selector shows a "new run" marker when focus lags the footer. - Status / System Logs clash (
AXIS-UI-STATUS-LOGS-CLASH): the System Logs expanded body is clamped to the viewport (reserving topbar + workspace + status strip), so an oversized persisted height can no longer push the Status strip off-screen. - Diagnostic cascade (
AXIS-ED-DIAG-CASCADE): the pre-eval balance scanner no longer carries an unterminated string across lines (one bad quote suppressed every later structural diagnostic), and remote parse errors only shadow local errors on the same line — semantic errors after a parse failure now surface. - A11y live region (
AXIS-ED-A11Y-LIVE): diagnostics changes announce politely via the shared SR live region; the Problems count is arole="status"live element. - Long-line clip (
AXIS-ED-LINE-CLIP):overflow-wrap: anywhereon editor content so wrap mode breaks long tokens instead of clipping. - Contextual autocomplete (
AXIS-ED-AC-CONTEXT): completions rank by prefix quality, cursor position (statement start boosts keywords, value position boosts series / user locals) and in-buffer local bindings. input.inthover (AXIS-ED-HOVER-INPUTINT): exact catalog member beats the last-segment type fact, so hovers show signature + params instead of namespace docs.- Contrast (
AXIS-ED-LIGHT-CONTRAST,AXIS-UI-THEME-GRAPHITE-CONTRAST): theme bridge enforces contrast floors for--color-text-dim/--color-text-faint(WCAG-ish 4:1 / 3.2:1) with correct mix direction per base; static light-theme faint token darkened (#8b8e9c → #666a78). - Focus + labels (
AXIS-ED-FOCUS,AXIS-ED-ICON-LABELS): visible focus rings on editor tool / status / tabbar buttons and the CM surface; editor tab strip uses propertablist/tabsemantics with a real (non-nested) close button; aria-labels on icon-only git bar, topbar panel toggles, and Problems copy button. - Eraser on locked drawings (
AXIS-UI-DRAW-ERASER-LOCK): locked erase / delete attempts now show a transient toast + assertive SR notice instead of a silent no-op.
- Escape friction cluster (
- Architecture apply guard:
applyArchitectureonly preloads Pyodide when a real DOM append target exists. The unit-test document stub now exposesquerySelector, which previously flipped the browser-detection gate and madeprefetchPyodideAssetsthrow ondocument.head.appendChildunderapplyArchitecturetests (commits Offline Lab,clears the stream slot).
[2.4.1] — 2026-09-06
Fixed
- Worker typecheck: clean
tsc --noEmitunder the strictworker/tsconfig.json(noUncheckedIndexedAccess,exactOptionalPropertyTypes).auth.extractBearer: regex capture non-null assertion — match guarantees the capture.scripts.rowToMeta/listD1: buildScriptMetawith optionaldescription/pathonly when set (no implicitundefined).scripts.handleScriptsdraft put: includenameonly when defined;parts[0]non-null after the_draft/ empty-path guards.
No runtime behavior change; only type compliance so worker tsc matches the pre-push gate.
[2.4.0] — 2026-09-06
Added
- DSM-first data plane: AXIS now loads datasets first — the chart paints instantly from the DatasetStore (repaired), then a background DSM job auto-completes the series (validate → classify gaps → sliced walk-back backfill) with progressive repaints as slices land. Venue REST remains the fallback/seed path; the Reload button forces a venue refetch (
preferDataset: false). - DatasetStore (
src/data/dataset-store.ts): single source of truth for OHLCV datasets with pluggable persistence sinks —session(memory only),local(IndexedDB, default),git/worker(storage-plugin documents, debounced + retried, never blocking the chart). All consumers (chart loads, DSM jobs, live ticks, compare, CSV upload) read/write through it. - Dataset validation & repair (
src/data/dataset-validate.ts):repairBarsdrops corrupt rows, dedupes, sorts, and snaps individually off-phase bars to the series' dominant open-time phase (≥3 bars, ≥60% agreement — consistent venue offsets are preserved).classifyGapssplits gaps into fillable vs legitimate (weekend closures for session venues, declared maintenance windows) so the DSM stops chasing phantom gaps.validateDatasetcomposes both into a report. - Dataset merge with conflict detection (
src/data/merge-datasets.ts): overlapping timestamps whose OHLCV disagree beyond a relative tolerance are conflicts, auto-resolved by policy (newest-winsdefault,keep-current,prefer-incoming); non-overlapping bars always union. - Settings → Data → Dataset persistence main switch:
Session | Local | Git | Worker(default Local), persisted asstore.datasetPersistenceand synced to the DatasetStore on boot/change. - Sliced-backfill progress chip in the topbar Data group: live
loaded / expectedbar count while a DSM job completes the current dataset in the background.
Fixed
- DatasetStore reads are memory-first and never wipe the mirror on a sink miss; switching persistence copies in-memory series into the new sink.
- Git/Worker sinks return pending bars from
get(no empty merge during DSM walk-back), serialize per-key flushes so a retry cannot clobber a newer put, and write-through to IndexedDB as a durable front.onSinkErrorlands in system logs. - Progressive paint no longer goes through
loadBars(that re-fitted the viewport every slice).paintDatasetis generation-guarded so a slower prior load cannot paint over a newer symbol. - DSM jobs repair +
validateDataset/ fillable gaps (not rawvalidateBarCoverage);ensureDatasetCompleteuses the source calendar class. In-flight jobs for the same key are reused; the progress chip counts bars in the target window.
Changed
- Topbar order: the Venue picker moved to the front of the Market group (Venue → Symbol → Interval → Type → Compare) since it determines valid symbols/intervals; the Data group keeps plugin config, upload, datasets, Load, and Reload.
- DSM job engine reads and writes now route through the DatasetStore (session-mode safe, progressive repaints fire on every merged slice);
expand-cache(cache→now + live ticks) and the Data Manager source do the same, with a repair pass on Data Manager resolves and CSV uploads. - Reload shows the same loading spinner /
loadSeqas Load.
Tests
tests/dataset-validate.test.ts— repair (corrupt rows, phase-aware snap, dedupe, sort), gap classification (24/7 vs session venues, maintenance windows), dataset reports.tests/merge-datasets.test.ts— conflict detection tolerance, merge policies, union/sort behavior.tests/dataset-store.test.ts— sink routing (session vs local), conflict-resolved merges, replace/remove, change subscription, persistence-mode switch.tests/dataset-sinks.test.ts— remotegetreturns pending bars before flush.tests/integration/load-symbol.test.ts— DSM-first cache paint without hitting the venue.
[2.3.1] — 2026-09-05
Fixed
- Doctor: missing gitignored
worker/wrangler.tomlis a warning untilaxis setup, not a hard fail. - Live badge: show Reconnecting… / Offline while the websocket is down; one reconnect warning per disconnect burst.
- Static PWA server:
GET /healthisok(not SPA HTML); OPTIONS 204; favicon served. - Versions: product identity is 2.3.1 everywhere (About, Tauri, docs).
- Desk / PYNE path: sibling repo is
../pyne(fallback../pynescript).
Added
- Modest Install app chip on
beforeinstallprompt(no nag). - Quick Start defines SRC / STR / ENG / STO in plain language.
Changed
- Default editor width is 30% of the viewport (was 50%) on first load and layout reset.
- Default chart interval is
15m(was1d). - Timeframes: topbar / settings / DSM / watchlist interval list now includes
3m,30m,2h,6h,8h,12h,3d, and1Malongside the previous set. - Topbar Inputs: removed the Inputs button and its Studio/Settings visibility toggle. Script inputs still open from the Scripts list, command palette, and the existing inputs modal.
[2.3.0] — 2026-09-05
Fixed
- CI unit tests: plugin bootstrap now re-registers after
registry.clear()(catalog flags reset together). Store/runner tests resetresultsFocusIdsosetLastRunis not skipped. Data-manager selection is cleared in stream catalog tests. CI pins Bun1.3.14(latestwas racing global store/registry).bun test --max-concurrency=1for deterministic unit runs. Worker origin URL helpers live insrc/data/worker-origin.tssostore→ HTTP client → market-worker → on-chain proxy no longer hits a TDZ on import.
Changed
- Repo description & tags: GitHub / package / PWA / desktop copy no longer frames AXIS as “for Pine Script™”. Tagline covers CEX OHLCV, drawings, on-chain overlays, and Pine Script™ via PYNE; extra GitHub topics and package keywords.
Added
- Per-tool drawing settings: style bar grows context chips (extend L/R, show price, lock, custom color) plus a gear popover for fib levels, text/font size, risk/reward, arrow caps, and stats toggles. Last-used extras persist per kind in
drawingPrefs.byKind. Paint honors extend flags, custom fib ratios (including reverse), highlighter width, long/short RR, and double-click text re-edit.
Tests
- Tool settings catalog —
tests/tool-settings.test.ts: every drawing kind has controls; ray/highlighter/long defaults; fib + RR helpers; normalize keepsmeta.fibLevels. - Store
byKindmerge —setDrawingPrefsdeep-merges per tool without wiping siblings.
[2.2.0] — 2026-09-04
Added
- Results → Raw JSON tree: collapsible VOID-colored viewer (keys / strings / numbers / bools) with key filter, Expand / Collapse, and Tree | Source. Large
plots/seriesarrays page in (32 at a time) so a full run does not mount thousands of nodes. Click a primitive to copy it. Footer Copy / JSON still export the full payload.
Changed
- Studio fullscreen canvas: Runtime, Wire, Settings, Workers, and Plugins (plus nested tabs) now use the full overlay width instead of a reading-column cap. Wide layouts are two columns — Runtime (engine | endpoint), Settings General / Data / Topbar / Editor / Theme token grids, Workers inventory | inspector, Plugins catalog cards, Results strategy table. Legacy
sc-settings-*chrome on Editor intelligence, exchange keys, and stacked plugin fields is replaced with studioax-*primitives. - Theme color field: Settings → Theme uses one
StudioColorInputper token (swatch picker + text). Accepts hex,rgb()/rgba(), CSS names, and Pinecolor.*enums; the picker rewrites in the same form. - Editor color chips: clicking an inline script color chip opens a native picker and replaces the source in the original form (
#hex,color.red,color.rgb,color.new), keeping transparency. - Studio scroll: nested panes, tables, code blocks, and library lists no longer scroll on their own. Only the modal canvas (
.ax-page-canvas) scrolls. - Studio primitives: status pills stay compact (no longer stretch full-width inside cards); Idle/Skipped/Degraded get the same pill chrome as Healthy/Down; cards, stats, inline buttons, and feature rows tightened. Same language applied across Runtime, Wire, Settings (all tabs), Plugins (catalog / install / library), Workers, and Results: capability badges are
ax-cap, catalog rows are entity lists, chips-as-tags stay small, and compactsc-*chrome hosted in the overlay is scaled up to studio density. - Results overlay: true fullscreen studio shell (
.ax-page-backdrop+.ax-page, no dialog padding/blur). Header holds auto-open / script picker / saved-runs chip; Copy / JSON / CSV sit in the sticky footer. Canvas is the only scroller. Stacks above other studio pages (z-index: 1050) so a finished strategy is not trapped under Wire or Workers. Events, Strategy, Optimise, Plots, Metrics, Raw, and Saved use the sameax-*primitives as the rest of studio.
Fixed
- Strategy Saved-runs loop: live silent re-runs (every-tick / bar-close) were calling
setLastRunwithoutpersistence: 'skip', so localsaveResultwrote a new IndexedDB row about once a second. Durable save is now user-initiated Run only; deferred / skipped / superseded payloads never persist. Fire-and-forget saves are serialized so FIFO trim cannot race. - E2E smoke vs Studio overlay: topbar Architecture / Runtime / Settings / Plugins hooks are
hidden(Playwright no longer treatssr-only1×1 clips as clickable, which hung behind the fullscreen button). Smoke, critical, and library journeys open those pages through the visible Studio button + rail (axis-studio-rail-*). - Editor false typo on
syminfo.mintick: pre-eval “unknown built-in member” only knewsyminfo.prefix/syminfo.tickerfrompyne-builtins.json(the two callables). Host variables (mintick,tickerid,timezone,currency, …) are now allowlisted with the other Pine constants, matching pyne’s implementedsyminfo.*surface. - Market proxy (Worker): MEXC public REST is served through
/api/market/mexc/{klines,ticker/24hr,exchangeInfo}becauseapi.mexc.comdoes not sendAccess-Control-Allow-Origin.fetchMexcJsontries the Worker first and the direct host only as last-ditch fallback (offline lab,skipWorkerProxytests, or Worker 5xx / network). Worker 4xx (allowlist / not found) is thrown immediately so the browser does not pay a CORS-blocked extra hop. SharedresolveMarketWorkerBaselives insrc/data/market-worker.ts(re-exported frombinance-http.ts/mexc-http.ts). Call sites:watchlist-tickers.ts,sources/catalog.ts(mexcRest.fetchHistorical),symbol-catalog.ts(exchangeInfo). Interval allowlist is AXIS TFs plus venue1M(1h→60m,1w→1W; no1s/3m/2h/6h/8h/12h/3d).ticker/24hrallowlists optionalsymbol=(single object, cached per symbol); there is nosymbols=batch — omit the query for the full book. Watchlist uses per-symbol requests when the list is small (≤8), else the full book. No signed MEXC path yet.
Tests
- Run-result persist —
tests/run-results-persist.test.ts:persistence: 'skip'and ephemeral meta do not write Saved runs; interactive Run writes once; three silentliveTickre-runs do not append. - Studio / Results e2e —
e2e/studio.tsopens rail pages without clicking hidden topbar hooks; critical Results close usesaxis-results-closebecause the fullscreen overlay covers the topbar toggle. - Pre-eval
syminfo.*host vars —tests/preevaluate.test.ts:syminfo.mintick/tickerid/timezone/currencyare known;syminfo.minitckstill suggestsmintick. - MEXC client fetch order —
tests/mexc-http.test.ts: Worker first,skipWorkerProxygoes direct, abort does not try the next host, Worker 400 does not callapi.mexc.com, Worker 5xx still falls through. Watchlist small-listsymbol=vs full-book path. - MEXC Worker ticker
symbol=+1M—worker/tests/market-proxy.test.ts: optionalsymbol=forwarded and cached separately from the full book;symbols=rejected; native1Mklines accepted. - Color rewrite helpers —
tests/pine-colors.test.ts:formatPickedChipColorkeeps kind/transparency;rewriteColorKeepingFormatpreserves hex / rgb / rgba / named. - JSON tree helpers —
tests/studio-json.test.ts: kind / preview / stats, expand-all skips huge arrays, filter does not walk 200-point plot series.
[2.1.1] — 2026-08-29
Fixed
- CORS product-host list: retired the legacy
*.pynescript.aibranch fromPRODUCT_ORIGIN_RE(workerpickOrigin) — production URL ispynescript.online, not.ai. The fallback default inenv.ALLOWED_ORIGIN(and the inline fallback when none is configured) now also points athttps://pynescript.online. Legacy.airequests fall through to the allowlist fallback instead of being echoed.isOAuthProxyBase(git-oauth client proxy allowlist) drops the.aicheck for symmetry. Docs (README,docs/devops/cors-and-origins.mdx,docs/worker/bindings.mdx,docs/architecture/evaluation.mdx,docs/llm.txt) updated.
Tests
- CORS regression:
worker/tests/cors-origin.test.tsadds adoes NOT echo the retired pynescript.ai product hostcase that confirmshttps://pynescript.aiandhttps://app.pynescript.airequests fall back to the configuredALLOWED_ORIGINfirst entry (i.e. they're no longer auto-allowed as product hosts).
[2.1.0] — 2026-08-29
Added
- Local storage: persisted run results:
localStoragePluginnow implements the optionalsaveResult/loadResult/listResults/removeResultmethods so completed strategy/indicator runs can survive reloads. IndexedDB schema bumped from v1 → v2 — additive migration only, with a newresultsobject store keyed by compound[scriptId, runId]and abyScriptindex onmeta.scriptIdfor cheap per-script listing. FIFO trim keeps at mostMAX_RESULTS_PER_SCRIPT = 50runs per script (oldest bymeta.startedAtevicted; the just-saved run is always preserved). ALOCAL_STORAGE_VERSION = 2constant is exported for downstream schema detection, and the plugin now advertisescapabilities.results = trueso UI can render saved-runs affordances. localStorage JSON + in-memoryMapfallbacks mirror the same semantics for SSR/tests (pynescript.axis.results.v1key +_getMemResultsForTestshelper). Plugin contract extended insrc/plugins/types.tswith aresults?: booleancapability flag. - Storage change confirmation dialog: new
StorageChangePrompt(src/ui/StorageChangePrompt.tsx) is mounted once at the app root and hosts the existingStorageChangeDialogwhenever the user switches storage engines. A newpromptStorageChange(oldId, newId)helper insrc/storage/service.tsis the single entry point — short-circuits silently when the engine is unchanged or unset (first-time set), and otherwise opens the dialog so the user can pick Migrate scripts or Start fresh before the active plugin flips. The migration itself still runs through the existing dialog (it callsgetStorage(fromId)/getStorage(toId)directly so the active plugin stays pinned to the source until commit). All four storage-change call sites now route through it —ScriptLibraryPaneldropdown,SettingsDialoggeneral tab Save,PluginsPagecatalog activate,PluginManagermodal activate — so there is exactly one shared dialog state, not four duplicated ones. - Per-panel icon in FloatableShell header:
FloatableShellnow renders the panel-specific glyph next to the hamburger menu (testidaxis-panel-header-icon-{panelId}), matching the Topbar panel toggle. Single source of truth isPANEL_ICON: Record<PanelId, IconName>insrc/ui/icon-map.ts; TypeScript exhaustiveness guarantees everyPanelIdhas an entry. Missing mappings fall back to the hamburger-only chrome without breaking the panel.
Fixed
- Status bar chip 1px hover wobble:
ConnectionHudchips (ChipShell,TickPulse,LiveBadge) no longer shift pixels on hover/active. Locked border-width toborder-[1px](Tailwind v4borderno longer relies on theme indirection), addedtransition-noneto prevent any color flicker, and pre-applied thering-1outline onLiveBadgeso only the ring color animates betweenring-transparentandring-accent(no box-shadow structure delta)..sc-btn-ghostgained an explicitbox-sizing: border-box(defensive — Tailwind v4 preflight already sets it on*). - Duplicate "Open in new tab" in editor dock menu: the editor panel's dock menu showed both the generic DOCK_MENU "New tab" entry and an editor-specific "Open in new tab" entry passed via
menuExtra. ThemenuExtrais nowundefined(per theFloatableShellJSX usage inEditorPane), so the dock menu shows the generic "New tab" entry exactly once. The editor's own "Open in new tab" affordance lives only in the right-sideEditorOverflowMenu(testidaxis-editor-btn-new-tab-overflow), where it pops the editor out into a full browser tab instead of a docked window.
Tests
- Storage result round-trip + FIFO + fallback —
tests/storage-local-results.test.tscovers the new IndexedDB v2resultsobject store: add / load / list / remove, FIFO trim atMAX_RESULTS_PER_SCRIPT = 50, thebyScriptindex, SSR fallback (pynescript.axis.results.v1+_getMemResultsForTests), and additive schema migration from v1. - Service façade + plugin opt-in —
tests/storage-service-results.test.tsexercisessaveRunResult/loadRunResult/listRunResults/removeRunResult/supportsRunResultsthrough the active plugin, including the local-only fallback when the active engine (git / cloud) doesn't implement the optional result methods. - Storage change prompt —
tests/storage-change-prompt.test.tsasserts the dialog is mounted exactly once at the app root, opens on engine change, and short-circuits silently when the engine is unchanged. - Editor menu dedupe —
tests/editor-menu.test.tslocks the regression:EditorPaneno longer passes amenuExtrawith a "New tab" entry, the dock menu still contains exactly one "New tab", andEditorOverflowMenustill owns the overflow "Open in new tab". - Panel header icon routing —
tests/panel-icon.test.tsverifiesPANEL_ICONcovers everyPanelId, each value is a validIconName, andFloatableShellreadsPANEL_ICON[props.id]and emits theaxis-panel-header-icon-{panelId}testid.
[2.0.31] — 2026-08-28
Changed
- About modal: removed ethos manifesto list and author section; added AXIS + PYNE version badges and brief no-walled-garden philosophy.
- Studio consistency:
ThemePanel(Settings → Theme) now uses the studioax-*primitives (StudioSection,StudioField,StudioInput,StudioToggle,StudioChip,StudioButton,StudioHint) instead of legacysc-settings-*classes, matching Runtime / Wire / Workers / Plugins. Studio--ax-*tokens promoted to:rootso shared panels render correctly outside the modal. - Theme color input: each token uses a single color input (mono text field + non-interactive preview swatch) instead of a paired swatch picker and text box; number tokens use one number input.
- Studio modal radius: added a scoped
--radius-surfacetoken (8px inside.ax-page, defaulting to 3px elsewhere). Studio modal surfaces —.ax-card,.ax-btn, rail nav items, color preview, equity tooltip, HPO chart wrap, results auto-open toggle, and the Results error box — now use the higher radius. Chart/panel<input>/<select>and small chips/badges keep their existing 2–3px radius for hierarchy.
Added
- Results fullscreen studio modal: replaced the docked Results panel (
FloatableShell) with a focused fullscreen studio overlay (ResultsModal) opened viastore.resultsPanel.open. Six restyled subpages — Events, Strategy, Optimise, Plots, Metrics, Raw — share one studio canvas (ax-page/ax-*) withStudioStat,StudioTabs, andax-list/ax-cardprimitives.StrategyReportandHpoPanelrebuilt on studio classes (stat cards, equity card, ax-field controls, ax-list search space). Results auto-open only forstrategy()scripts (indicators no longer auto-open). - Results auto-open setting: new persisted
resultsAutoOpenflag (defaulttrue) gates the strategy-only auto-open in the runner. A visible toggle sits at the top of the Results modal header ("Auto-open on strategies"); the same control is exposed in Settings → General ("Auto-open results on strategies"). Persisted via localStorage and hydrated on boot. - Strategy equity graph: replaced the flat SVG line with a rich
EquityChart— gradient area fill, zero baseline, gridlines with money-axis labels, underwater drawdown shading, and a hover crosshair + tooltip showing time, equity, and drawdown. - Results subpage polish: Events list now shows colored type badges and long/short direction pills; Plots shows a sparkline card per series (positive/negative color); Optimise shows an in-sample / out-of-sample trial score chart with legend; Metrics shows a status pill plus derived stats (profit factor, max DD, plot points, script type).
- Results full-width + 2-column subpages: the Results modal canvas now uses the full studio width (
ax-page-canvas--wide, no reading-column cap). Optimise uses a two-column split — search configuration + search space on the left, live study chart + trials table on the right. Strategy uses a two-column split — stats + equity curve on the left, closed-trades table on the right (stacks to one column under 64rem). - Topbar settings: new 'Topbar' tab in Settings with toggles for each topbar group (brand, market, data, compute, layout, panels, system) and individual panel buttons (watchlist, editor, library, scripts, inputs, layers, DSM, on-chain, alerts, values, results, script logs, system logs, status). Settings are persisted via localStorage.
- HPO (Optimise) polish: the search config (trials, sampler, objective, validation, holdout/walk-forward sizes, min trades, and per-param bounds) now persists across reloads; the trial chart pins its x-axis to the trial index (IS/OOS lines no longer desync when trials error), marks the best trial, and shows the score scale; the results header gained a status chip, best IS/OOS scores, and a Clear button; categorical params show their choices and the search-space list has an empty state.
- HPO tier gating: added a persisted
tier(free/pro/self-hosted) — the free tier disables walk-forward validation (shown as "(Pro)") with an upgrade hint, while Pro / Self-hosted show a tier badge and unlock it. The engine-runs cap was raised from 400 → 1000 so walk-forward fits within the trial ceiling.
Fixed
- Workers probe non-blocking: initial backend probe deferred past first paint (double
requestAnimationFrame) and a non-blocking "Probing backends…" hint shows while the first snapshot loads — the Workers panel is ready and interactive immediately, regardless of slow/failed probes. - Indicator engine correctness: styled Pine plots (
histogram/area/columns/stepline/baseline/line/cross/circles) were silently dropped becausesplitSeriesByKindonly acceptedplot/hlinekinds — they now route to line plots (missing-kind and unknown-kind both default to line). Enginestatus: 'success'is no longer downgraded to error by a stray non-fatalerror/messagestring. Series↔time-axis alignment is now derived from the exact bars the engine evaluated (passed throughgetOhlcvTimesForApply), fixing misaligned/blank newest bars on live ticks and HPO holdout slices. Explicitoverlay=trueis no longer auto-demoted to a sub-pane by the oscillator-scale heuristic. ThegetOhlcvTimesForApplycache is reused for the commonstore.barscase (the bypass path only applies to a genuinely different axis) and invalidates on astore.barsreference change. - Results panel dock cleanup: removed the dead
resultspanel from the dock registry (PanelId,PANEL_META,PANEL_IDS,DOCK_STACK_ORDER) so the bottom dock no longer reserves ~220px of empty space — Results is now a fullscreen modal driven solely byresultsPanel.open. - Input override no-op on chart: changing a script input (e.g. RSI length 14→56) now repaints the whole series.
PaneManager.syncOverlayLines/syncOverlayOhlc/syncBgcolorBandsgained aforceFullowner option;runAndApplyInnerpassesforceFull: opts.liveTick !== trueso interactive runs / input recomputes bypass the tip-only smart-apply (which only patched the last bar when length + last time were unchanged). Live ticks keep the fast path vialiveTick: truein the multiplex re-run loop. - Wire page: removed separate scrolling sections; now uses single-scroll ax-page-canvas pattern matching Runtime, Settings, Workers, and Plugins.
- Settings polish: consolidated duplicate
sc-settings-*CSS into single definitions, addedsc-settings-section--plainandsc-settings-content--compactvariants to replace!importantoverrides, addedcolor-mixfallback,focus-visibleon color swatches, andprefers-reduced-motionguard; replaced!mt-0 !border-t-0 !pt-0with semantic variant and fixed ThemePanel compact gap override. - Workers probe: fixed
requestAnimationFrameleak — now cancels on unmount and removes deadhasLoadedsignal; probe defers to next frame without blocking studio paint. - Vendor: removed obsolete
pynescript-0.4.0/0.4.1wheels (replaced byhoox_pyne-0.4.2).
[2.0.30] — 2026-08-26
Fixed
- plot display= in compile mode:
plot(..., display=display.data_window)was not carried inplot_metabecause the compiler didn't fold Pinedisplay.*constants. Both axes now resolvedisplay.data_window/display.pane/etc. to bitfield integers and pass them through toplot_meta. - Pyne wheel — vendor
pynescript-0.4.2(was 0.4.1). Compiler display folding + server compile-path backfill.
[2.0.29] — 2026-08-26
Changed
- Engine default mode — both Pro and Pyodide engines now default to
auto(try compile, fall back to interpret) instead ofinterpret.
Fixed
- hline linestyle in compile mode: server-side compile path did not include
linestyle/color/priceinplot_metabecauseplot_attrsis empty for hline/fill. Backfill from__drawingsnow fills missing visual attrs. - Pyne wheel — vendor
pynescript-0.4.1(was 0.4.0). Server compile-path backfill fix.
[2.0.28] — 2026-08-26
Fixed
- hline linestyle in interpret mode: the interpret path (Pyodide default) did not synthesize
plot_metafrom__drawings, so LWC price lines forhline()always rendered solid regardless oflinestyle=. Both interpret and compile paths now synthesizeplot_metawith kind/linestyle/color/price for hline, fill, and plotshape drawing types.
[2.0.27] — 2026-08-26
Changed
- Pyodide PYNE wheel — vendor
pynescript-0.4.0(was 0.3.7). Engine catalog, legacy JS engine, SW cache test, and editor builtins synced from pyne 0.4.0.
Fixed
- hline linestyle:
hline(linestyle=hline.style_dashed)rendered solid — the drawing path only checkedr.style(neverr.linestyle), and the compile-mode overlay path lackedplot_metaentirely so the LWC price-line never received the style. Both paths now covered:pyne-drawings.tsfalls back tor.linestyle, and both Pyodide runtimes synthesizeplot_metafrom__drawings(hline/fill/plotshape kinds with linestyle, color, price). - multi-chart: same indicator on every grid cell showed identical values — the runner evaluates Pine against
store.bars(active plane), but focusing another slot never swapped in that slot's cached history, so every Run/add computed from whichever chart was loaded last.setActiveChartSlotnow restores the focused slot's own bars (+ gen bump), stops stale bar replay, restarts live for the slot's market, and silently re-runs applied scripts so each chart shows its own values. - multi-chart: switching to a 2×2 grid could overwrite the active chart with a sibling's symbol — ChartHost "prefetched" inactive slots via
loadSymbolData, which always writes the active plane (last-mounted sibling won). Removed; empty cells load on focus instead. - tables: render Pine
table.celltext_valign(top/middle/bottom) andtext_sizetokens/numeric points in the table HUD — parsed previously but rendered fixed 10px/middle; defaults unchanged when absent. - bgcolor: carry band titles into
syncBgcolorBandsand apply them as series titles on create/update, matching the offlinebuildPlotVisualspath.
[2.0.26] — 2026-08-24
Added
- Pages security headers —
public/_headersships the nginx/server.ts hardening baseline to Cloudflare® Pages deploys (CSP with self scripts +wasm-unsafe-evalfor Pyodide, https/wss connect, plus nosniff / referrer / frame-deny), so axis.hoox.sh gets enforced headers instead of only Page Shield's Report-Only placeholder. - Native MEXC CEX —
mexc-rest/mexc-wsas a built-in venue (public spot klines, no CCXT). Venue picker lists MEXC with Binance/OKX/Bybit; signed REST usesX-MEXC-APIKEY. MEXC was removed from the pinned CCXT shortlist.
Fixed
hline()levels vanished oncebgcolor()rendered —priceLineHostpicked the first non-overlay series, which after the bgcolor fix could be abgcolor_*histogram living on its own hidden 0–1 price scale; hlines attached there mapped far off-viewport. Host selection now skips bgcolor underlays (TradingView® paints backgrounds behind panes — they never host price lines).bgcolor()/barcolor()drew nothing — response normalization coerced every series sample throughNumber(), turning engine color arrays (rgba(8, 153, 129, 0.298)per bar) into all-null, so the histogram bands were filtered out before reaching the chart. CSS color samples now pass through normalization untouched (coerceSeriesSample); value plots still coerce as before.- Workers status chips stayed “Unknown” —
StudioStatusclosed over the firstprops.status(unknownwhile probes ran). The CSS class updated (green/red dot) but the word did not. Label is now read from props on each render.
Changed
-
Topbar Studio — one Studio button replaces Wire, Runtime, and Settings. Those pages stay in the studio rail (and ⌘K). The button reopens the last studio page.
-
Wire recipe grid — the hatch is a behind-layer at lower opacity. The right-edge fade no longer masks preset names.
-
PYNE Pro API origin is
https://pynescript.online— Hetzner VPS (nginx → gunicorn:5002).axis.hoox.shis the Cloudflare® Pages PWA, not same-origin with the API. Default Backend URL, Workers Manager probe, datafeed gateway, and Settings/Runtime presets follow the new origin; savedaxis.hoox.sh/ old VPS IP endpoints remap on load.
[2.0.25] — 2026-08-23
Fixed
- Script Settings inputs no longer lose to editor defaults — re-running an applied script from the editor keeps per-instance
inputValues/ strategy properties. Empty{}bags no longer wipe saved settings. Overrides persist only when they differ from the script default and are keyed by title, id, and LHS var name so the engine actually applies them.
Changed
- npm publish uses org secret
NPM_TOKEN_HOOXSH—release.ymlno longer looks for a repoNPM_TOKEN. Root Bun tests ignorepackages/**soaxis-clisuites run only afterpackages/clideps are installed. Authenticated skip detection treats an already-published version as success.
[2.0.24] — 2026-08-23
Added
- Production-grade
@hoox-sh/axis-cli0.2.0 — first npm publish of the AXIS CLI. Node-compatibledist/+npm i -g @hoox-sh/axis-cli, AGPLLICENSEin the tarball, provenance on tag publish, CI coverage forpackages/cli.
Fixed
-
plot(..., display=)was ignored at apply time — editor already knewdisplay.data_window/none/pane/price_scale/status_line/all, but every series still painted on the pane and in the Data Window. AXIS now readsplot_meta.display(token or Pine bitfield):nonehides everywhere,data_windowkeeps Data Window and skips the chart,price_scale/status_linegate last-value labels. PYNE packsdisplay=on plot/hline/shape/fill/bgcolor. -
E2E smoke vs studio pages — Plugins is opened from the Runtime rail (topbar hook is sr-only). Wire Apply waits for an exact
Wire · Offline Labtitle so a driftedOffline Lab +Nplan is not applied as Live Crypto. -
axis setup --remote-d1skipped local D1 —setup d1treated--remoteas exclusive of local even whenlocal: truewas passed, so bootstrap never applied the schema locally.--remotealone stays remote-only;--local --remoteand--remote-d1apply both. -
Worker
/healthprobe accepted any HTTP 2xx —probeHealthOR'd the JSONstatus === "healthy"check withres.ok, so a 200 HTML page counted as healthy. Requires a JSONstatusofhealthyorok. -
Failed
axis deploy workerran wrangler deploy twice — on inherit/quiet failure the CLI re-invoked deploy to capture stderr. Capture once, parse the workers.dev URL, never redeploy on error. -
--jsonmixed human banners into stdout —--jsonnow implies--quietso doctor/health/deploy emit parseable JSON only. -
Docker GHCR version tags could skip on
v*—docker.ymlpath-filteredpush, and GitHub applies that filter to tag pushes. Tag/main image builds no longer use a path filter (PRs still do). -
Unknown
axiscommands dumped a generic wrapper error — Commander help/version/unknown-command now exit with Commander's own code instead ofhandleError.
Changed
- npm release workflow — pin Bun 1.3.14,
id-token: write+npm publish --provenance, pack dry-run (LICENSE/dist/bin required), org secretNPM_TOKEN_HOOXSH. CI unit job now typechecks and testspackages/cli. Dead@clack/promptsdependency removed.
[2.0.23] — 2026-08-23
Changed
- Drawings / plot parity plan —
docs/architecture/drawings-parity.mdxlists P0–P3 work: user-tool move/handles, Pine pane routing, PYNE export gaps (tables, fill meta, plotshape Y, OHLC).
Fixed
-
Pre-eval treated
chart.fg_coloras a typo —pyne-builtins.jsononly listschart.point.*callables, sochart.bg_color/chart.fg_color(and thecolor_background/color_foregroundaliases, plus viewportleft_visible_bar_time/right_visible_bar_time/is_standard) were flagged “not a built-in member”. Allowlisted with the other Pine host constants. -
1-point drawings did not body-move —
shiftDrawingonly special-casedtext/priceLabel. Note, flag, crossline, anchored text, and arrow marks now shiftp1(andpoints[]when present). Third-anchorp3handles hit-test and resize. -
Linefill GC was a no-op —
garbageCollectScriptDrawingsignoredskip.linefillon the early-return. Overflowing linefill-only batches now trim oldest. Polyline/linefill copyforce_overlay; polylinefill_colormaps to fill. -
overlay=falsebgcolor/fill always hit the price pane — bgcolor bands takepaneId; fills use the script-pane drawing layer when the indicator is not overlay. Emptydrawings: []clears script SVG even on silent live re-runs. -
plotshape on oscillator panes —
setShapeMarkerstakes a pane id; overlay=false scripts attach LWC markers to the first overlay series onind_*instead of price candles. Trade markers stay on price. -
Drawing tool settings — Fill slider covers channel, triangle, gann boxes, ranges, highlighter; highlighter stroke no longer multiplies width ×6; horizontal ray places on one click; XABCD / head-and-shoulders commit on the 5th point.
-
Hide drawings hid only user tools — the eye toggle now also clears Pine script SVG and
fill()bands (every pane layer).label.style_text_outlinepaints outlined text;yloc.abovebar/belowbarsit 8px off the wick. First Add Indicator re-owns plotshape / fills / script drawings from__editor__to the script id. Histogram overlays honorplot_meta.histbasewhen the engine sends it.
[2.0.22] — 2026-08-23
Added
-
Topbar Venue picker — Data group is now Venue (native CEX / pinned CCXT / CCXT… / local) instead of a raw source-plugin list. Picking Bitget (CCXT) writes
ccxt-rest+ccxt-wsand bothexchangebags together;store.provider.idisccxt:bitget. Exchange ID stays on the topbar only for CCXT…. Stream remains hidden while paired. -
CCXT symbol browse uses that exchange's markets — with Source = CCXT (Gateway), the symbol modal loads
GET /markets?exchange=and keeps unifiedBTC/USDTtickers (slash is no longer stripped). Stream is hidden on the topbar while it still matches the source pairing (Wire / HUD Fix if it drifts). -
CCXT session API keys — Settings → Data can store a key + secret (+ passphrase / uid) per CCXT exchange id (
ccxt:bybit, …) in the RAM vault (neverpluginsConfig/ localStorage). Save POSTsPOST /datafeed/session; Load/Live then pass onlycred=on OHLCV/watch. Public candles still work without a key. Topbar shows an API key chip next to the CCXT exchange picker. Gatewayauto|pyne|sidecarmoved to Settings (advanced). Sidecar accepts/ohlcvand/datafeed/ohlcv. PYNEPOST /datafeed/sessionacceptsapiKey/secret/passwordin the JSON body. -
npm release pipeline for the AXIS CLI —
@hoox-sh/axis-cli(packages/cli) is now publishable: dropped"private", and a new.github/workflows/release.ymltypechecks, tests, builds and publishes the package to npm onv*tags using anNPM_TOKENrepository secret. A registry-version guard skips cleanly when the version is already published (safe tag re-runs); run summary reports local vs registry versions. -
"What's in this repo" section in README — table mapping every part of the repo to its role and paths: app/PWA, datafeed pipeline, calc engines + Workers Manager, vendored Pyodide runtime, on-chain plane, Cloudflare® Worker (API/WS/D1/KV/R2), allowlisted
/api/onchainproxy, Tauri desktop shell, npm-published CLI, tests/ops. -
Plugin config
advancedfields + Settings section — schema fields can now be markedadvanced(API base URL, Bars, Synthesize on failure, …). They are hidden from the Topbar config row and rendered in Settings → "Source & stream plugins" with full descriptions, using the shared form classes. -
Full unified ccxt exchange dropdown — the Exchange ID select is fed by the gateway's complete ccxt exchange list (
/health→ newccxt_exchanges, mirrorsccxt.exchanges; ~103 venues) instead of only the native adapters. PYNE side:backend/api/datafeed.pyhealth payload extended accordingly.
Changed
-
Studio full-page overlay — Runtime, Wire, and Settings are no longer right-edge drawers. They share one full-viewport page (
src/ui/studio/,ax-*classes) with a left rail, 16px type root, and large fields. Compactsc-dialogstays for Symbol / Script Settings / About / ⌘K. -
Runtime uncoupled from Workers and Plugins — Topbar Runtime is the active engine / endpoint / exec mode / health. Workers (backend inventory) and Plugins (contract catalog) are sibling pages from the rail, ⌘K, or Runtime cards — not tabs inside Runtime. Engine/endpoint/mode moved out of Settings → General; storage stays a Wire slot.
-
Workers studio restyle — Backend inventory is a full
ax-*studio page (WorkersPage): large health cards + inspector (probe features, numbered install steps, Use as calculation backend). No inner Overview/Detail/Install/Configure tabs and nosc-btnchrome. Engine writes go throughsaveEngineConfig. Open Plugins is a sibling cross-link, not a nested catalog. -
Plugins studio restyle — Contract catalog is a full
ax-*studio page (PluginsPage), sibling of Runtime. Catalog / Install / Script Library stay asStudioTabs(e2e tab name Catalog). Kind chips, large rows with Use + capability badges, URL install + example cards, Script Library embed, active src/eng/stm/stor footer + Done. Open Workers and Open Wire are sibling cross-links. Close stays on the AppPage shell (axis-plugins-close);axis-managerstays on the dialog only. -
Data tab no longer duplicates bar count or Binance API host — how many bars to load lives only under General → Historical bars. Native CEX host URLs stay as fetch defaults (Binance already has host + Worker fallback). Gecko proxy/network, CCXT gateway, and synthesize-on-failure remain.
-
Docker release images tagged by version, not sha —
docker-bake.hclrelease targets now pushpwa-v<VERSION>/pwa-nginx-v<VERSION>(e.g.ghcr.io/hoox-sh/axis:pwa-v2.0.21) instead ofpwa-sha-<sha>. The git SHA remains on the image as theorg.opencontainers.image.revisionlabel and build arg; workflow docs updated to match.
Fixed
-
Plugin config row — first-save, apply, and exchange dropdown — shared source/stream fields now (1) resolve a stored value from any target bag before falling back to a schema default (stream
exchangeis no longer hidden by a source default of''), (2) persist text/number keystrokes but only reload history on blur/Enter (selects/checkboxes still apply immediately), (3) treat the exchange control as a<select>only when the gateway list is actually populated, with a placeholderSelect exchange…option and a free-text fallback when the fetch fails or returns empty, (4) cache the ccxt list per gateway mode, and (5) wire stacked-formlabel forto the controlid. GeckobaseUrl/network, Coinbase granularity, and Mock Walk start price are Settings-only (advanced). Topbar Load no longer bails out while a previous fetch is in flight. -
Pre-eval scanners close paired typographic quotes —
“…”/‘…’now close on the matching right quote (not only the same code point), so a pasted title string no longer marks the rest of the file as an unclosed string and block Run. SharedisQuoteCloseinpine-scan-util.ts. -
array<string>survived asarrayafter Add types — the declaration rewriter captured the collection token but dropped<string>when inserting a missing type1 qualifier. Generic args are preserved (simple array<string> vals = …). -
Type methods and
export enummissed as user bindings — indentedmethod profit(this) =>inside atypebody andexport enum Namenow register as declared names (same asexport type). -
const(and line-leading keywords) colored inconsistently — green vs violet — a float ending in a trailing dot (2.,0.) was split into number + lone., leaving the tokenizer'safterDotstate set at end-of-line. The state leaked across comments/blank lines, so the next code line's first word (const,series, …) rendered as a member property (green) instead of a keyword (violet accent). Number scanning now consumes trailing-dot floats andafterDotresets at every line start. -
Pre-eval typo checker round 3 — validated against the real 2222-line grid strategy — found via local reproduction on
grid.pine: generic typed declarations (var series array<string> TP1 = …) were not parsed by the assignment regex, so TP1/SL1/TRL1-class vars were never registered as declared; library import coordinates (import cryptolinx/String/1 as strx) leaked into both the declaration collector and ident scanner (String/Hooxflags); and dotted method calls (.init(),.show(),.abs()) were treated as bare-call typos. All three fixed; checker now reports 0 typos on grid.pine, grid.2.pine. -
Pre-eval typo checker round 2 — declaration coverage + copy-paste resilience — remaining false positives addressed:
strategy(linktoseries=…)whitelisted (pyne accepts arbitrary declaration kwargs); typographic/curly quotes (“”‘’) now treated as string delimiters in every scanner so pasted text no longer leaks as identifiers;enummembers + enum/type names,typefields, andfor [i, v] in …loop vars are collected as declared bindings; dotted-path roots (Mode.SINGLE) skipped by the ident scanner. -
Pre-eval typo checker flooded false positives (~260 per script) — pyne's LSP metadata only lists functions/namespaces, so the pre-eval linter treated core built-in series variables (
close,high,low,open,volume,ohlc4,hl2…), type qualifiers (simple/series/const) andtext.align_*/text.wrap_*constants as unknown identifiers and suggested nonsense ("Unknownclose— did you meanCROSS?"). Added a curatedPINE_BUILTIN_VARSsupplement (OHLCV + derived, time/bar state, calendar parts) plus the missingtext.*members to the known-path index; qualifiers also join the bare-call skip set. Regression tests cover the reported failure pattern (now zero typos). -
Config row crash on first save —
setFieldwrotepluginsConfigthrough a deep Solid store path whose parent bag did not exist yet; solid-js/store does not auto-create intermediate nodes, so the first-ever config change threwTypeError: can't access property "exchange"and never persisted. Bag creation is now guarded (writePluginField), covered by regression tests and a browser e2e run. -
Gateway select had no choices — the ccxt
gatewayschema fields lackedoptions, so the dropdown rendered only its current value.auto | pyne | sidecarare now declared on bothccxt-restandccxt-ws. -
Config row deduplication — the Topbar renders one shared row for the union of active source/stream config fields (was: duplicated per picker); changes write through to all declaring plugins so ccxt-rest and ccxt-ws stay in sync.
-
Gateway loopback on remote pages (hardened VPS) —
gatewayBaseresolvedpyne/autotohttp://127.0.0.1:5002/datafeedeven when the page was served from a remote host, so browsers onaxis.hoox.shfired doomed cross-origin requests at the visitor's machine (CORS NetworkError). Remote pages now resolve to same-origin/datafeedon product hosts (nginx) or the product API origin cross-origin (Pages previews); loopback behavior is unchanged for local dev. Explicit endpoint overrides still win. -
ccxt-ws
require()actually removed — v2.0.21 added the staticgatewayWsimport but left the shadowing CommonJSrequire('../data/gateway')call in place, so the browser bundle still threw on stream start. Therequireis now gone.
Changed
-
Plugin config moved to Settings → Data — the "Source & stream plugins" section (with the advanced fields) now lives in the Data tab above Exchange API keys, with a note that CCXT Gateway venues serve public market data and need no keys. Native-source keys (Binance/OKX/Bybit/Coinbase/Kraken) remain session-only in the browser vault and sign requests client-side.
-
Config row styled like the Source picker — inline plugin config fields now render through
TopbarField(integrated uppercase label, sharedaxis-tb-fieldchrome, focus-within ring), matching Symbol/Source/Interval exactly; the Settings variant keeps the dialog's stacked form classes. -
Stream config pass-through —
multiplex.startLivenow passesstore.pluginsConfig[stream:<id>]intostream.start({ config }), matching the source path, so ccxt-ws receives the configured exchange id. -
ccxt plugins: clear error for unconfigured exchange —
ccxt-rest/ccxt-wsno longer fire requests with an emptyexchange=param; they surface "exchange id not configured" instead.
[2.0.21] — 2026-08-21
Fixed
-
ccxt-ws stream:
require()in browser ESM — replaced CommonJSrequire('../data/gateway')with a static import. Therequirecall threwReferenceErrorin the Vite browser bundle when activating theccxt-wsstream (Bun tests masked it since Bun honorsrequirein ESM). -
ccxt-rest backfill window inversion —
endTimewas forwarded as CCXTsince, which pages forward from that timestamp, breaking the Data Source Manager walk-back contract (bars must end at/beforeendTime). Now derivessince = endTime − limit·timeframeso each page covers[endTime − limit·tf, endTime]and gap-fill converges.
[2.0.20] — 2026-08-21
Added
-
Datafeed gateway transport (
src/data/gateway.ts) — resolves gateway URL (auto/pyne/sidecar/direct), probes sidecar health with 30s TTL cache, and providesgatewayFetch/gatewayWshelpers for plugins that route through the PYNE datafeed gateway or local sidecar. -
ccxt-rest source plugin — long-tail exchange OHLCV via the PYNE datafeed gateway or sidecar. Routes
ccxt:<exchange>venues throughGET /datafeed/ohlcv. Credentials stay server-side; browser never holds API keys. -
ccxt-ws stream plugin — real-time klines via the datafeed gateway WebSocket. Routes through
WS /datafeed/watchwith exchange+symbol+timeframe params. -
Gateway-aware active resolution — when provider gateway is not
directand the venue is accxt:<exchange>long-tail id, active source resolves toccxt-restand stream toccxt-ws. Native venues (binance, okx, etc.) are never swapped.
[2.0.19] — 2026-08-20
Fixed
-
Hex color lint false positive — pre-eval
scanIdentRefsno longer treats hex color tails (e.g.d3eein#22d3ee) as unknown identifiers. Scans backward past hex digits to detect the#prefix and skips the entire literal. -
Pre-existing TypeScript errors — resolved 23 type errors across 7 files: null barIndex guard, CSS
TextAlignnarrowing,PineTablecamelCase property reads viaRecord<string, unknown>,linefillmissing fromDrawingLimits/ drawing caps/counts/skip,cancelledstatus narrowed type assertions,ParamValueimport + explicit typing, legacypanelWindows/dockLayoutaccess onAppState.
Changed
- CI typecheck gate — added
bunx tsc --noEmitas a first step in the CI workflow (runs before unit + security tests). Addedtypecheckscript topackage.json.
[2.0.18] — 2026-08-20
Added
- Provider session — chart aggregators inherit a locked venue identity (
store.provider: source + stream + market + auth mode). Source changes re-pair the live stream; HUD shows venue and a Fix chip when stream mismatches. Data Source Manager follows the chart source unless "different source" is checked. kraken-rest— public Kraken OHLC source, paired withkraken-ws.- Exchange API keys — Settings → Data stores key/secret/passphrase in a session vault (RAM only). Saving a key for the active venue sets
provider.authMode = authenticated. Secrets never go to localStorage,pluginsConfig, or error-share dumps. - Signed Binance klines — with a vault key, history uses HMAC REST then the Worker
GET /api/market/binance/signed/klines(request-scopedX-Exchange-Key/X-Exchange-Secret, not a Worker vault). Public allowlisted proxy is unchanged. - Venue HMAC signers — thin Binance / OKX / Bybit / Coinbase / Kraken signers in
src/data/venues/(no CCXT). - Test key — Settings → Data Test key button verifies saved credentials with a signed 1-bar kline fetch. Shows success, 401/403 rejection, or CORS/network warnings.
- ADR-016 — provider-locked market data architecture decision record.
- SessionDO multi-venue — Worker Durable Object relay now supports all 5 venues (Binance, OKX, Bybit, Coinbase, Kraken) via
venuequery param. Each venue's WS URL and subscribe message handled correctly. Browser → DO control messages acceptvenuefor resubscribe. - Shared venue WS builders —
src/streams/ws-venues.tsprovidesbuildVenueWs()for both browser-side StreamPlugins and the Worker DO. Single source of truth for URL patterns and subscribe messages. @hoox-sh/axis-datafeed— optional Bun sidecar (packages/datafeed/) using CCXT Pro for users who want local WS without running Flask. Mirrors the PYNE datafeed gateway contract:GET /datafeed/ohlcv,GET /datafeed/markets,WS /datafeed/watch,POST /datafeed/session. Run withbun run dev:datafeed.
Fixed
- Mixed-provider quotes — watchlist no longer falls back to Binance tickers for Kraken (or unknown venues).
- Coinbase live bars — stream uses Advanced Trade venue candles folded into the chart interval, not ticker buckets.
- Binance synthetic fallback —
fallbackdefaults off, so a network error cannot look like real prices.
[2.0.17] — 2026-08-19
Visible pre-eval squiggles, Problems that drop on edit, and idle lint for named args and declared vars.
Added
- Named-arg typos — idle lint flags unknown function/method parameters (
plot(..., coltor=color.green)→color=) from curated signatures, builtin docs, and user-function parameter lists. - User-var typos — assignment /
var/ tuple-unpack / function-parameter names are added to the typo map (declaration is source of truth), solength = 14thenlenghtsuggestslength.
Fixed
- Lint underlines — pre-eval / error marks use a high-precedence squiggle (SVG + wavy underline + inset line), not CodeMirror
baseTheme, so they stay visible against Tailwind. Empty decoration sets rebuild when underlines are on. The tab-switch effect no longer loops and cancel the idle lint timer, which left the buffer with Problems but no squiggles. - Stale Problems — pre-eval rows drop as soon as the buffer diverges from the last linted source. Idle lint no longer stamps the live buffer onto old diagnostics, and rescheduling the same buffer does not wipe a completed lint (fixing a typo no longer leaves the old error in the list).
[2.0.16] — 2026-08-19
Restore editor hover, lint underlines, and chips after a dead Settings bag and clipped hover cards.
Fixed
- Editor intel dead bag — an all-off persisted Settings bag (checkbox mount / store-proxy spread) no longer disables hover, lint underlines, completions, and chips. Hydrate recovers defaults; user patches write
rev. - Hover cards clipped — Pine hover tooltips set
clip: falseso overflow-hidden editor chrome no longer hides cards on the first lines. - Hover hide-on-apply — decoration / selection transactions no longer dismiss hover cards; only document edits do.
- Editor hover catalog — bare
close/newno longer stealstrategy.close/array.new. Hover facts win; completions still walk modules. display.pane— real Pine v5+ member is allowlisted (no more typo →display.none). Inventedmath.isnan/math.isfinitecompletions removed.- Editor intel timeouts — Hover / Completion timeout settings now reach
/lsp/*(were hardcoded). - Intel number fields — clamp on blur / spinner, not every keystroke, so
1500is typeable. - Diagnostic hover — respects Show errors / warnings / typos / info flags.
- Pre-eval flags apply live — toggling lint generation immediately re-runs or clears marks.
- Hide + tables —
table.*HUDs follow visibility; drawings / fills /barcolorare owner-scoped so hide with a sibling no longer leaves the hidden script’s artifacts. - Hide exclusive pane — empty oscillator strip is destroyed; show recreates it.
*brprimitives —destroyPanedetaches line-break primitives; attach failure is not cached; segments are cached and culled to the visible range.- Last-bar drawings — script paint no longer grows
rightOffsetup to 500 bars for wall-clocktimenow(one-barbar_index+1still maps). - PYNE Agent seed — same-origin plugin install no longer writes a hardcoded Worker URL; chat stays off until the operator sets the endpoint.
- Unstamped last-run marks — engine underlines drop unless
meta.axisSource(orscript) still matches the buffer.
Improved
- Hover facts —
hl2/ohlc4/hlcc4use midpoint / OHLC / HLCC wording (onlyhlc3is typical price). plotshape/plotchar— curated params includeformat,precision,force_overlay;seriesisint/bool.- Docs —
areabris only on the broken-segment row; debugging mermaid includes pre-eval → Problems.
[2.0.15] — 2026-08-19
Editor intelligence settings, Supertrend linebr gaps, live script hide/run, and PYNE Agent chat markdown.
Added
- Editor intelligence settings — Settings → Editor (and command Open Editor Settings) exposes every lint / pre-eval / hover-card / signature-hint / autocomplete / underline / gutter / inline-chip option, plus idle / tab-switch / remote timeouts. Defaults match the previous hardcoded behavior; Reset defaults restores them.
- Strategy chart trade size — entry/exit markers print
Long N/Short N(and exit id + qty) so the filled amount is visible on the chart, not only the order id. - Hide plot names on last-value labels — Settings and chart [T] clear
RSI/Overboughttitles beside the last value; the numeric label stays. Independent of [N].
Improved
- Pre-eval timings — idle lint stays 1s after the last keystroke (configurable 200–3000 ms). Tab switch uses a separate 200 ms beat (was a hardcoded 120 ms). Remote
/lsp/diagnosticswait is 2s (configurable) and only starts after idle; local marks still publish immediately. Stale “2s idle” editor comment removed. - PYNE Agent chat markdown — replies render headings, lists, and bold instead of raw
###/1. **Foo**. Plugin default API endpoint is empty (set in plugin config); no hardcoded Worker URL. - Editor hover + param checklist — mouseover covers keywords, types/qualifiers, series (
close/bar_index), namespaces (ta.), user inputs/functions, and hex colors. Call hints list type + default; current param is emphasized (no strikethrough on used). Hover cards use a void-theme header, parameter definition list, and inset example. - Pre-eval / Problems / debug chips — idle lint is 1s;
study()and baresecurity()warn; duplicateindicator()/strategy()warn; Problems label pre-eval vs run; debug chips have higher contrast and truncate long logs. - Live scripts auto-run — starting a stream immediately re-runs every visible script on the chart (no extra Run). Hide pauses execution and clears that script’s plots (series, markers, drawings, fills,
barcolorwhen it is the last visible script); show re-runs it.library()sources stay out of the live / reapply loop. - Editor type highlighting —
int/float/string/ … and declared UDTs / enums (type Point,export enum Easing,m.Easing) use the type token in bold.series/simpleare bold only as type qualifiers;m.SuperTrend(stays a library member. - Strategy Properties wiring — Apply persists only changed
strategy()kwargs (so leverage is not overwritten by default margin %). Leverage ↔ margin UI no longer writes the auto-filled sibling into the bag. Editor Properties apply on isolate/HPO runs. Execution flags are documented as not implemented in PYNE.
Fixed
-
plot.style_linebr/steplinebr/areabronna— Lightweight Charts Line/Area series drop whitespace points and connect the remaining samples, so Supertrend-stylebull ? st : naplots drew a diagonal through inactive stretches.*brstyles now hide the LWC connector and stroke each finite run (isolated samples stay a tick).plot.style_linestill spansna. -
Hide mid-run — an in-flight live apply no longer paints after Hide; empty-bar
startLiveno longer logsNo bars loaded. -
Last-value names — compare / on-chain titles survive [T]; volume stays number-only unless a title was set. Default
exactOnCandleputsLong Non the side arrow, not the in-bar circle. -
Isolate / HPO strategy bag — explicit
strategyProps: {}means no rewrite; isolate no longer merges leftover editor broker settings onto a baked study. -
Last-bar /
varipdrawings —line.new/box.new/ polylines / linefills that extend one bar past the series (bar_index + 1) are no longer snapped to the last candle (that flattened them into a vertical tick). Labels still clamptimenowonto the last bar. Historicalvaripplots already render as a normal 1-sample-per-bar series (AXIS does not sendrealtime_last_bar; enabling it would reset last-barvaripcells under pyne’s current re-init). -
Remote LSP cooldown — aborting an in-flight
/lsp/*request (typing, hover leave, pre-eval cancel) no longer starts the 30s failure cooldown, so idle parse diagnostics still reach pyne. -
Editor Problems / underlines — a clean pre-eval no longer wipes last-run runtime errors. Pre-eval and last-run marks are unioned while the buffer still matches the run source.
-
plotshape/plotchar/plotarrowstyle=— completions offershape.*instead of invalidplot.style_*. -
Pre-eval block comments —
"/*"andhttps://inside strings are no longer treated as comments (which could block Run). -
Inline debug line parse — log values like
RSI: 55no longer become a chip on line 55; structuredlinewins. -
color=completions —color.new/color.rgb/color.from_gradientstay in the list (including aftercolor=color.).
See also
[2.0.14] — 2026-08-17
Strategy hyperparameter search in Results, isolated trial runs, and /optimize proxy wiring.
Added
- Hyperparameter Optimisation — built-in component plugin (
hyperparameter-optimisation) and Results → Optimise tab. Searchesstrategy()input.*values over N trials. Evaluation SoT is pynePOST /optimize(TPE / random / grid + holdout / walk-forward); Pyodide falls back to an isolated client loop. Apply winner merges into Script Inputs (unsearched fields stay). Strategies only. runScript({ isolate, bars, signal })— headless engine eval so HPO trials do not touchlastRun, the chart, or the engine HUD. Live multiplex defers while a study is running.- Vite / Docker nginx proxy
/optimizenext to/runso same-origin VPS andbun run devhit Flask.
See also
[2.0.13] — 2026-08-17
Call-parameter intelligence, richer Pine highlighting, script input enums, and Pine table lifecycle.
Added
- Call parameter intelligence — hover on
plot/input.int/ta.sma(and other curated calls) shows parameter docs + an example. After,inside a call, completions offer remaining named args (title=,minval=) in a Parameters section and already-used ones under Already used. A signature hint below the cursor lists every parameter and marks used / current / unused.
Improved
- Pine editor highlighting — series builtins (
close,bar_index,time, OHLC) use a cyan token distinct from user variables;import … asaliases and library export members (m.Easing) use a violet family; types get a warm token. New chrome vars--color-cyan,--color-editor-builtin,--color-editor-lib,--color-editor-lib-member,--color-editor-type.
Fixed
- Script Inputs enum values —
input.enum(m.Easing.linear)no longer shows the import/Python path as a text field. Members are inferred fromenumdeclarations (local + imported library source), values normalize toType.member, and the modal seeds from that script’srunResults(not another indicator’slastRun). - Script display name — applied scripts / pane badges always use the Pine
indicator()/strategy()/library()title (not engine"plot"or a stale file name). - Pine tables after delete — table HUD only shows tables from still-applied scripts’
runResults(orphans /__editor__leftovers no longer stick). First-run migrates run cache to the real script id; last-script delete clears script drawings. - Pine table layout — grid size expands from cell extents when engine understates rows/columns; frame/border and cell align improved.
[2.0.12] — 2026-08-17
Editor color chips + type declarations, chart label/marker lifecycle, topbar icon map, debug UX.
Added
- Editor inline color chips — square swatches (line-height × line-height) before Pine color literals (
#hex,color.red,color.rgb(...),color.new(...)). Click selects the range. - Add type declarations (editor overflow → Source) — after a successful first run, inserts missing Pine type1 (
series/simple/const) and type2 (int/float/bool/string/color/ …) on untyped assignments. ICON_MAP(src/ui/icon-map.ts+Iconsinicons.tsx) — one Lucide glyph per product intent; topbar panel buttons each use a unique icon.
Improved
- Panel hamburger menu — consistent 12px label / 14px icons; New window → New tab.
- System Logs — clear control uses trash icon instead of ×.
- Topbar panels — reordered List → Editor → Library → Scripts → Inputs → Layers → DSM → On-Chain → Alerts → Values → Results → Script Logs → System Logs → Status.
- Inline debug / Chart pins — overflow Debug items include full how-to on hover; toggle shows status-bar tips.
Fixed
- Duplicate last-value labels on indicator panes (editor owner + real script id stacked series).
- Strategy long/short labels stayed after remove — trade markers are owner-scoped and cleared on detach.
- Chart chrome — removed top-right fullscreen / chart-only icon buttons (F11 / Shift+F / Esc still work).
- Inline debug enable gate — chips only when explicitly on; pin gutter class clears when empty.
[2.0.11] — 2026-08-17
Chart script lifecycle, per-script indicator panes, pyne-worker engine, panel drag UX.
Fixed
- Panel title bar — a plain click no longer undocks the panel to float; undock/move starts only after the pointer is dragged past a small threshold (hamburger still: click = menu, hold/drag = move).
- Non-overlay indicators — each
overlay=falsescript gets its own sub-pane (ind_<id>) instead of stacking into a single sharedindicatorpane. Removing one script only clears that owner’s series and no longer destroys siblings’ full history (was left with 1–2 bars). - Chart scripts lifecycle — add/remove/reopen stays correct: owner-scoped detach (no leftover series/empty panes), ChartHost no longer wipes re-applied scripts after history paint, centralized
reapplyChartScriptsrestores visible scripts (with saved inputs/strategy props) after symbol load / cache paint; applied scripts are sanitized on hydrate and re-run on reopen.
Added
- Engine
pyne-worker— built-in edge evaluator plugin (defaulthttps://pyne-worker.cryptolinx.workers.dev), API key field, Workers Manager / Settings presets. Distinct from AXIS data-plane Worker and Flaskserver.
[2.0.10] — 2026-08-16
Market data resilience, Script Settings input layout, and local-first editor LSP.
Improved
- Script Settings → Inputs formatting — Pine
group,inline,tooltip(\\n), andactive/active=<ident>layout in the modal (TV Settings-style sections, same-line clusters,?help, grayed inactive fields).input.text_areauses a multi-line control. - Editor LSP hover + autocomplete — local builtins/doc annotations show immediately (no wait on a dead Backend URL); remote Pro API is short-timeout + 30s cooldown after failure. ⌘/Ctrl-Space triggers completion; tooltip z-index raised so hover/suggest stay above chart chrome.
Fixed
- Browser market data / plugins (CORS “status null”) — when the page cannot reach venue hosts or remote plugin modules (geo, firewall, port 9443, extensions), AXIS no longer hard-depends on a single cross-origin path:
- Binance REST tries
api.binance.com→data-api.binance.vision, then the Worker allowlisted proxyGET /api/market/binance/{klines,ticker/24hr,exchangeInfo}. - Binance WS rotates
stream.binance.com:9443→:443→ default 443 →data-stream.binance.vision. - PYNE Agent plugin ships same-origin at
/plugins/axis-pine-agent.js(legacy remote URL migrates on restore); agent API endpoint still defaults to the pyne-agent Worker. - Service worker navigation never rejects
respondWith(offline shell HTML); cache version v5.
- Binance REST tries
Added
- Worker market proxy —
worker/src/market.tspublic allowlist for Binance klines / 24hr ticker / exchangeInfo (short isolate cache; not an open reverse proxy).
[2.0.9] — 2026-08-15
Editor symbol catalog, richer Pine highlighting, CORS for Pages previews, and CI greens.
Added
- Editor symbol & emoji manager — status-bar Symbols catalog of TV-editor-safe arrows, box drawing, blocks, marks, spaces, and chart emoji (IBM Plex Mono vs wide). Insert raw, quoted, or
plotchar(…).
Improved
- Pine highlighting — stateful multiline strings +
/* */blocks,\\n/ hex-color atoms, namespaces (ta.,label.new), types, control vs definition keywords, function names before(. - Format — leaves continuation lines of an unclosed string or block comment untouched.
Fixed
- CORS — Cloudflare® Pages previews (
*.pynescript-axis.pages.dev) can callhttps://axis.hoox.sh. Pyne always allowlists those product Origins and treatsGET /healthas a free CORS path (AXIS Settings probe). WorkerpickOriginalready echoed the same hosts. - CI — library publish stays on the local cache when leftover/invalid git credentials fail remote (was
GitHub: Bad credentialsin the full unit suite). Smoke waits onaxis-status-messageand opens Plugins via Runtimes. Vite build on macOS/Windows resolves SolidTopbar.tsx/Watchlist.tsxinstead of same-stem legacy JS. Docker push uses thereleasebake group (no:localdocker.io tags) and bake-action v6 env overrides.
Changed
- Pyodide PYNE wheel — vendor
pynescript-0.3.7(Runtime.run(libraries=)forimport ns/Name/ver, ring-series skip, runtime hot path). Engine catalog, legacy JS engine, SW cache test, and editor builtins synced from pyne 0.3.7.
[2.0.8] — 2026-08-15
Architecture modal, library publish emulator, drawings/plot parity, and the post-2.0.7 hardening stack.
Changed
- Pyodide PYNE wheel — vendor
pynescript-0.3.6(UDTarray.binary_search*sort_field, drawing export/delete/fold). Engine catalog, legacy JS engine, SW cache test, and editor builtin metadata synced from pyne 0.3.6.
Added
- Library publish emulator —
library()scripts publish to git{basePath}/published/{ns}/{Name}/{1,2,3…}/lib.pyne(plus local cache). Library panel Publish library, or auto-publish on a successful Run. Consumersimport ns/Name/ver; AXIS resolves the folder and sends sources to the engine (register_library_source). - Architecture modal — topbar Wire (and command palette Open Architecture) opens a compose-recipe dialog: pick Offline Lab / Live Crypto / CSV Desk / On-Chain / Team Cloud, then swap or switch off any source · stream · engine · storage · dataset slot. Plan name records drift (
Live Crypto +1 −1); Apply commitssetActivePlugin+ optional on-chain panel. - Pine
labelstyles / yloc — normalize passes throughstyle,yloc,size/text_size,textcolor, andcolor; SVG paint supportslabel.style_label_up|down|left|right|center(and bare tokens), bubble tips, icon markers (xcross, triangles, …), andyloc.abovebar/yloc.belowbarwhen OHLC bars are available (defaultyloc.price+ bubble for unknown styles). - About AXIS modal — click the topbar HOOX/AXIS brand (or command palette About AXIS / Help → About) for product, author, and HOOX ethos from hoox.sh/manifesto, with links to AXIS / PYNE / docs.
- Script settings → Properties — when a
strategy()is loaded, a Properties tab exposes broker parameters (initial capital, order size / pyramiding, commission, leverage / margin, process orders on close, calc flags). Overrides persist per script and are merged intostrategy()on run without rewriting the editor buffer. linefill.newpaint — normalize + SVG quad fill between two lines (pairs with pyneexport_for_apilinefill serialization).barcolor()— per-bar candle body/wick tint fromkind: barcolorseries (LWC color fields).- plotshape multi-script — shape markers are owner-scoped by script id so one run does not wipe another script’s shapes.
- Non-overlay drawings —
overlay=falsescripts paint geometry on the indicator pane Y-scale;force_overlaystill routes to price. - Compile
line.set_*— pyne folds set events onto handles before export (final geometry for AXIS).
Improved
- Editor default width — factory / layout-reset docked editor width is 50vw (was fixed 460px); existing persisted widths unchanged.
- Editor gutters on demand — line-number column stays content-width (digits only; overrides CM 20px min); diagnostic + inline-debug gutters hide until they have markers (profiler-style).
- Modal focus trap — shared
installFocusTrapcycles Tab inside Settings / About and restores prior focus on close. - Chart a11y region — ChartHost exposes
role="region"with symbol/interval/bar-count label; load success/error uses polite/assertive SR announcer. - Session DO stream sanitize — symbol
^[A-Z0-9]{1,20}$+ Binance interval allowlist before upstream WS URL is built. - Prod plugin remote allowlist — production builds default-deny remote plugin hosts (same-origin
/plugins/*+data:+ allowlisted PYNE Agent host); override withVITE_ALLOW_REMOTE_PLUGINS/VITE_PLUGIN_REMOTE_ALLOW. - Plot fill apply — skip SVG rebuild when fill fingerprint matches; pan/zoom paint uses visible-range cull + pixel-budget stride on dense bands.
- Runner OHLCV times cache — live re-apply reuses the times axis when
chartDataGen+ length + last time are unchanged (open-bar ticks). - Webhook URL policy — https-only, no credentials, reject loopback/private IP literals; 8s AbortController timeout.
- Presentation Escape — detect AXIS modals via
[role=dialog][aria-modal=true](not only native<dialog open>). - CSP baseline — nginx + Bun static server send Content-Security-Policy (self scripts, wasm-unsafe-eval, https/wss connect, frame-ancestors self).
- First-paint bundle — chart PWA critical path no longer statically imports CodeMirror/editor or
@tauri-apps/*:index.tsxdynamic-imports App vs EditorApp;EditorPaneis Solidlazy+Showwhen docked editor is open; Tauri shell install is dynamic-imported after a lightweightisTauriShellcheck. - Multi-chart slot bars reactive —
chart-registrystores per-slotbars/chartDataGenin a Solid store so inactive ChartHost slots re-paint when those paths change. - PWA SW update UX — stop blind
SKIP_WAITINGwithout a reload path; post skip-waiting only when activating a waiting update, and soft-reload once oncontrollerchange(refreshing guard) so mixed old/new modules never stick. Still skips DEV and Tauri. - Heavy live re-runs — at ≥10k bars,
every-tickindicator re-runs are treated asbar-closeso full OHLCV is not re-encoded for the engine on every open-bar tick (effectiveLiveRerunMode). - Offline history fallback — when venue/source fetch fails,
loadSymbolDatapaints warmbars-cacheseries and reportsOffline · N cached bars(telemetrydegraded). - SW runtime cache cap —
axis-runtime-v4soft-caps at 96 entries (FIFO trim after put); version bump clears prior unboundedv3runtime caches. - Watchlist quote batching — multi-symbol WS ticks coalesce to one Solid price-map write per animation frame.
- Live tick rAF coalesce — multiplex keeps only the newest bar until the next animation frame so trade-ticker floods (Coinbase) do not thrash store + LWC every message.
- Pane resize coalescing —
PaneManagerResizeObserver callbacks flush once per rAF (was synchronousapplyOptionsper pane entry). - Smart series apply fingerprint — overlay tip no-op when length + last time and last value match (skips redundant LWC
updateon silent re-runs). - Overlay tip-only re-apply — silent live
syncOverlayLinesupdates the last point without a fulltoLwcLineDatamap when prior meta length + lastTime match (falls back to full setData on length/time change). - StatusBar / Results strategy reports — no longer rebuild trade pairing on every live
store.barspath update; depend onlastRun/chartDataGen/ fill-mode prefs. loadBarsbatching — multi-field store writes run inside Solidbatch()for a single reactive flush.- Vite critical path —
modulePreloaddrops CodeMirror / pyne-builtins from first paint; gzip enabled on Docker nginx;X-Frame-Options: DENY. - OHLCV bulk paint hardening —
mapBarsToPriceData/ volume mapper drop non-finite rows so one NaN bar cannot blank LWC series. - Plot styles — distinct series kinds for
plot.style_columns(vs histogram),plot.style_cross(discrete markers, no connector), andplot.style_stepline_diamond(stepline + vertex markers). plotshape diamond/cross map to square marks with optional+/✕glyphs. LWC still lacks column-width and native diamond/cross point markers — documented in charting docs. line.style_arrow_*— script lines paint SVG arrow heads forarrow_left/arrow_right/arrow_both(were solid stroke only).
Fixed
- Editor Problems panel close — auto-open only when diagnostic count increases; no longer re-forces open on every pre-eval/store tick while problems remain (statusbar toggle can stay closed).
- Worker
/api/runauth fail-closed — whenEXTERNAL_BACKENDis non-empty orPYODIDE_IN_WORKER=enabledandALLOW_OPEN_KEYSis not"1",POST /api/runrequiresrequireApiKey(also still forced byAPI_KEYS/REQUIRE_RUN_AUTH); local demos keep open keys without burning unauthenticated compute on a real backend. - Script-only drawing layer leak —
clearScriptPaneLayers()on ChartHost unmount (RO + time-scale subs were retained after multi-chart dispose). - Companion panel postMessage — origin-bound target + receiver check (no more
*). - Legacy results event CSS class — allowlist kind tokens before interpolating into
class(attribute breakout). - ResizeHandle multi-touch — ignore non-primary pointer ids mid-drag.
- bars-cache IDB integrity —
pagehide/beforeunloadflush pending debounced puts.
Tests
- CI workflow —
.github/workflows/ci.ymlrunsbun run test,test:security, and Playwright@smoke(Chromium) on PR / main. - Optional firehose bench —
tests/bench/(AXIS_BENCH=1/bun run test:bench): 500kappendBarticks on ~50k history with soft wall budget; skipped by default. - Drawings / plot-visuals — unit coverage for
force_overlaynormalize,linefilledge cases,barcolorSeriesToMap/coerceBarColor, and GC withlinefillpresent. - plot-visuals — columns / cross / stepline_diamond kind mapping, histogram-family helpers, diamond/cross shape + glyph defaults.
- chart-type / heavy-data — non-finite OHLC filter on price + volume mappers.
- store-append-scale — always-on
appendBarsame-time + cap invariants. - multiplex-heavy-rerun / sw-strategy / load-symbol — heavy re-run mode, runtime cache FIFO cap, offline bars-cache fallback.
- register-sw — pure update helpers (
shouldSoftReloadOnControllerChange, skip-waiting) + controllerchange single-reload mocks. - security / runner / fills — remote plugin prod allowlist, webhook URL policy, OHLCV times cache, plot fill signature.
[2.0.7] — 2026-08-12
Pine drawings diagnostics and plotarrow direction; pairs with pyne 0.3.5 last-bar line export.
Fixed
line.new/ drawings apply — prefer DrawingLayer fallback when applying Pine drawings; warn when the engine returns drawings that normalize to zero or when no layer is mounted (load bars first).plotarrow— negative series samples render as down arrows (were always up).
[2.0.6] — 2026-08-12
Test suite isolation and store hydrate defaults hardening.
Fixed
- Tests — isolate store/state defaults across suites; strategy-extra uses event prices (not bar fills); engine
isReadymock returns JSON health; hydrate never restores plane telemetry from disk. - Store seed — createStore no longer aliases nested
DEFAULTSobjects (telemetry/panels/live), so path updates cannot poison factory defaults.
[2.0.5] — 2026-08-12
Panel manager defaults / reset / chart overlay; classic Status + System Logs chrome; editor open-in-new-tab.
Added
- Panel manager — per-panel default position (dock + size + float coords in
PANEL_META); panel menu Reset to default. - Chart overlay — per-panel toggle and bulk Chart overlay: all on/off (
setAllPanelsChartOverlay); edge-docked panels float over the chart without shrinking it. - Editor — Open in new tab in overflow panel options (and left dock menu).
Changed
- Status bar — restored classic fixed footer look (no panel title chrome).
- System Logs — restored classic collapsible strip (expand/collapse body); topbar shows/hides the strip. Label System Logs (not bare “Logs”).
[2.0.4] — 2026-08-11
Script Logs / System Logs naming and Status / System Logs topbar toggles.
Changed
- Script Logs / System Logs — Script
log.*pane titled Script Logs (editor tool + panel); app telemetry titled System Logs. - Status & System Logs — topbar toggles for Script Logs, System Logs, Status.
[2.0.3] — 2026-08-11
Runtimes hub, editor save-before-run / idle lint, Workers Manager reliability, and hardened VPS probe routing.
Fixed
- Workers Manager endless probing — open-effect no longer tracks
store.endpoint(backend changes re-fired probes); every probe gets a hard timeout merged with the modal abort; Pyodide probe uses HEAD instead of downloading fullpyodide.js;probeAllWorkersusesallSettled. - Workers Manager / hardened VPS — pyne Pro probes use same-origin
https://axis.hoox.sh/health(nginx → loopback :5002) instead of client127.0.0.1:5002, which UFW correctly blocks on the public VPS.
Changed
- Runtimes hub — single dialog for Status (Workers Manager) and Plugins (catalog / install / library); topbar Runtimes entry; cross-links between sections; models remain separate.
- Save before Run — clicking Run (editor header, topbar split, Mod-Enter, command palette) auto-saves the active script to the library when the tab is dirty or not yet bound (
libraryId). Save failure blocks the run. - Idle lint — editor underlines (e.g.
plt()→ unknown) reappear after 2s without typing, not only after Save/Run. Mid-keystroke marks stay cleared; bare call typos likeplt()flagged locally. - Workers Manager UX — distinct icon per catalog worker; Usage / When to use copy on Detail + Install; docs updated.
- Editor line numbers — gutter width follows digit count only (no fixed min-width / heavy padding).
[2.0.2] — 2026-08-11
Editor chrome polish and docked panel hover slide.
Added
- Panel hover slide — docked panels can collapse to a peek strip and slide open/closed on pointer enter/leave. Toggle Slide on hover in the panel hamburger menu (left/right/bottom only). Store APIs:
setPanelHoverSlide,togglePanelHoverSlide,isPanelHoverSlide. Preference persists onpanelChrome[id].hoverSlide.
Changed
- Editor chrome polish — header tools always show icon + label (no hover slide-in); Format removed from the editor header and tab strip (still available via overflow Format document and
Shift+Alt+F/Mod+Shift+F). - Library from editor — primary Library tool opens the script library panel; overflow menu also has Open library.
Fixed
- Tab close / switch — closing a tab left of the active one no longer jumps focus; CM buffer is snapshotted before add/close/switch;
setDocno-ops on identical content.
[2.0.1] — 2026-08-11
Security and performance release from the multi-agent harden-perf audit
(4 specialist scanners + synthesis). Report: docs/devops/harden-perf-audit-2026-08-11.md.
Security
- Fail-closed Worker auth when D1 is bound without
API_KEYSKV (API_KEYS_REQUIRED). - CORS: product hosts + project-scoped
*.pynescript-axis.pages.devonly (no open*.pages.dev). /api/run: auth whenAPI_KEYSorREQUIRE_RUN_AUTH; per-IP/key rate limit (30/min); script/bars size caps; upstream proxy timeout.- Git OAuth: env
GITHUB_OAUTH_CLIENT_ID/GITLAB_OAUTH_CLIENT_IDwins over bodyclientId; tighter start/poll rate limits. - Watchlist: build rows with
textContent(no unescaped symbolinnerHTML).
Performance & reliability
- bars-cache: memory-first
getCachedBars, IDB hydrate,getCachedBarCount/ range without full clone when warm. - DSM gap-fill progress uses
getCachedBarCountinstead of full series loads. - engine-ws: 45s dead cool-down — keep dead client so live re-runs do not thrash reconnects.
Commits
0a668e00— fix(security,perf): gate /api/run, OAuth clientId, WS cool-down156221b9— fix(security,perf): fail-closed Worker auth, CORS, bars-cache
Full history (recursive)
2026-09 (82 commits)
Features
1dc6c089(2026-09-12) — feat(cli): cloud-storage setup, keys, and D1 schema deployc111371a(2026-09-12) — feat(storage): copy-on-switch, Worker settings, version historya9f7bb6e(2026-09-12) — feat(release): VERSION single source of truth with update manager and close guard319403fb(2026-09-10) — feat(editor): minimap, folding, indent grid, tab badges, workers full width8e9e8d6b(2026-09-10) — feat(editor): Language Feature Bar with live activity chips4d565427(2026-09-08) — feat(cli): standalone binaries via bun compile; fix Docker prepare-hook break1fef94c3(2026-09-08) — feat(ui): default TF 15m, studio opens on Settings, non-modal Workers, no top status77d8600e(2026-09-08) — feat(cli): installation self-check on start + doctor cli-install row716a26eb(2026-09-07) — feat(ui): mobile-first responsive shell (phone sheets, tab bar, force-single chart)74418b05(2026-09-07) — feat(results): events views (Open⇄Close), single-column strategy tab, rich saved statse00b6c97(2026-09-06) — feat(shortcuts): shortcuts modal + Settings → Keyboard recorder6efa590a(2026-09-06) — feat(shortcuts): palette extensions with live shortcut rendering47706d85(2026-09-06) — feat(shortcuts): wire chart keymap through the dispatch hubacc5ce93(2026-09-06) — feat(shortcuts): editor keymap extensions with Prec.high line opse07ecb8c(2026-09-06) — feat(shortcuts): wire app-level bindings through the dispatch hub2795ac72(2026-09-06) — feat(shortcuts): capture-phase dispatch hub with dialog-skip guard50467b3d(2026-09-06) — feat(shortcuts): persisted overrides slice on the app store902741d1(2026-09-06) — feat(shortcuts): chord parser, registry, and default bindingsda5e96d7(2026-09-06) — feat(data): route all dataset paths through the DatasetStoref597806b(2026-09-06) — feat(ui): dataset persistence switch + sliced-backfill progress chip257342d1(2026-09-06) — feat(data): DSM-first load pipeline with progressive painta5caf0ab(2026-09-06) — feat(data): DatasetStore with pluggable persistence sinksd105e161(2026-09-06) — feat(data): dataset merge with conflict detection & policies19c92dd1(2026-09-06) — feat(data): dataset validation & repair with gap classificationa63c3b69(2026-09-06) — feat(ui): move Venue picker to front of Market groupbe830abe(2026-09-05) — feat(chart): per-tool drawing settings (v2.3.0)
Fixes
99eb5f20(2026-09-12) — fix(ui): Studio Settings home, Workers fullscreen, minimap height9e963eab(2026-09-12) — fix(docker): skip missing VERSION stamp files in image buildff4674a1(2026-09-12) — fix: harden PWA, editor, e2e, and Docker; release 2.6.23a5de985(2026-09-12) — fix(pwa): retry transient fetch failures in SW cache-firstcb089b18(2026-09-12) — fix(e2e): retry twice on CI runnersb3915c90(2026-09-12) — fix(e2e): wait for boot in openStudio, upload failure artifacts8f8c91cd(2026-09-12) — fix(docker): copy version-stamped files into build context60aa2c4e(2026-09-12) — fix(ci, docker): copy VERSION into build stage, harden studio helperbd8d1c0c(2026-09-11) — fix(pyodide, editor, cli): bridge traceback tail, feature-bar popover, host-native smoke364776c5(2026-09-09) — fix(pyodide): pass bars via globals + json.loads, surface full tracebacke4888c72(2026-09-08) — fix(ci): SHA256SUMS used CI paths for binaries — sha256sum -c unusable7d16a7bb(2026-09-08) — fix(ci): CLI tgz mv target — packages/cli/.. is packages/, not the root144ef3d3(2026-09-08) — fix(ci): GITHUB_ENV var casing — release-assets referenced empty varscdb188b9(2026-09-08) — fix(ci): worker bundle sanity check — wrangler.toml is gitignoredcb6f00f5(2026-09-08) — fix(ci): check-versions fails on Windows runners — CRLF line endingsd4082f4c(2026-09-08) — fix(shortcuts): mount ShortcutHub + keypress feedbackc06a14cf(2026-09-07) — fix(test): make CI test suite green (server hook timeout, matchMedia stubs)81f24c76(2026-09-07) — fix(lint): resolve all Biome lint errors (368→0); add Biome + Prettier tooling7d9f2dec(2026-09-07) — fix(ui): resolve 23 UI-review findings across editor, drawings, panels, themes464a9497(2026-09-06) — fix(architecture): only preload Pyodide when the DOM can host asset links8d5daf5c(2026-09-06) — fix(worker): clean up tsc errors under noUncheckedIndexedAccess & exactOptionalPropertyTypes7ee49cc4(2026-09-06) — fix(data): DatasetStore memory-first, DSM paint/gaps, v2.4.0520869dc(2026-09-05) — fix: setup review — doctor, live HUD, static health, 2.3.116499ac7(2026-09-04) — fix(results): skip live-tick persist and unstick studio e2e
Refactors
ac0d8a90(2026-09-08) — refactor(editor): move Script Logs into the editor bottom bar
Documentation
477084bf(2026-09-08) — docs(changelog): note bare-filename SHA256SUMS for binaries055d73d5(2026-09-08) — docs: CLI-first command surface (axis command primary, bun run axis:* as repo alias)9b75c459(2026-09-08) — docs(readme): real badge row, stack cross-links, unified stack footerefa7e87c(2026-09-08) — docs(readme): add official Codecov coverage badgee38a72f9(2026-09-07) — docs: sync docs to v2.5.0 — shortcuts, mobile shell, results viewseecca17d(2026-09-06) — docs(changelog): regenerate full history for v2.4.0e9df22fe(2026-09-06) — docs(changelog): DSM-first dataset store, validation, persistence switchd10a9ea4(2026-09-05) — docs(screenshots): wire stills into README and matching guidesadcb846d(2026-09-05) — docs(screenshots): close editor except on editor-focused stills3211bfe0(2026-09-05) — docs(screenshots): recapture at 1920x1080 and 2560x14409b820a77(2026-09-05) — docs(screenshots): capture PWA, Studio, and CLI stills plus GIFs
CI
60a0c8d6(2026-09-08) — ci(release): attach CLI tarball + worker source bundle to GitHub Releasesd5f0cf89(2026-09-08) — ci(hooks): versioned .githooks — pre-commit biome (staged), pre-push tsc + lintcdb68ff9(2026-09-08) — ci: split Codecov uploads per flag, bump action to v7, target 75%9fe171a6(2026-09-08) — ci: upload unit + CLI coverage to Codecov637cfa87(2026-09-06) — ci(cli): full npm release pipeline with tag guard, registry verify, Node smoke
Tests
079f1569(2026-09-12) — test(e2e): drawings overlay spec with chart DOM harness3e6778ea(2026-09-12) — test(coverage): lift scoped core gate 82.8% to 89.9%6527e3de(2026-09-10) — test(editor): cover folding, indent grid, minimap class2c9643b3(2026-09-05) — test(pwa): stub beforeinstallprompt without DOM Eventc0d88523(2026-09-05) — test(load-symbol): isolate live stream and leftover scripts
Chores
b327a28a(2026-09-10) — chore: stop tracking .grok/ and AGENTS.md (local-only)28420c09(2026-09-08) — chore(release): v2.6.1 — sync desktop version stamps + check:versions guard67723020(2026-09-08) — chore(release): v2.6.0 — shortcut hub fix, keypress feedbacka78a7fca(2026-09-07) — chore(release): v2.5.0 — mobile shell, pyne 0.5.0, zero lint errors8d6a7c70(2026-09-07) — chore(engines): vendor pynescript wheel 0.5.0 from pyne9ae3e3da(2026-09-07) — chore(release): v2.4.3 — results events views, single-column strategy, saved statsaaf4d9ac(2026-09-07) — chore(release): v2.4.2 — UI review fixes, keyboard shortcuts, line opsfa49a6c1(2026-09-06) — chore(cli): release @hoox-sh/axis-cli 0.2.236ba501c(2026-09-06) — chore(release): v2.4.1 — worker tsc compliancee84b8325(2026-09-04) — chore(release): prepare v2.2.0
2026-08 (237 commits)
Security
d2b50220(2026-08-13) — a11y,security: focus trap, chart region, SessionDO stream sanitize4321c4b9(2026-08-13) — security,perf: plugin allowlist, webhook policy, CSP, fill/runner hot paths72869743(2026-08-13) — perf,security,ci: multi-agent optim stack (registry, overlay tip, auth, SW, bundle, CI)ebfc9955(2026-08-07) — harden chart, data, and run paths for performance and crash resilience
Features
783a1003(2026-08-30) — feat(ui): fullscreen studio overlay, Results JSON tree, and market proxy hardening9081a559(2026-08-29) — feat(worker): MEXC public REST through /api/market/mexc/* proxyfb193c25(2026-08-29) — feat(panel): per-panel icon in FloatableShell header9196e4cb(2026-08-29) — feat(ui): storage-change migration dialog008fb22a(2026-08-29) — feat(storage): persist strategy/indicator run results via StoragePlugineb86c103(2026-08-28) — feat(results): fullscreen results studio, HPO polish, and tier gating28a1f202(2026-08-27) — feat(settings): add topbar tab to SettingsPage (studio view)339f6a05(2026-08-27) — feat(settings): add topbar visibility settings tab67b1558d(2026-08-24) — feat(security): enforce CSP baseline on Cloudflare® Pages deploys3fb40122(2026-08-24) — feat(data): native MEXC spot venue + PYNE Pro origin pynescript.online09e047cd(2026-08-24) — feat(ui): single Studio button replaces Wire/Runtime/Settingscd0148ca(2026-08-23) — feat(cli): ship production-grade @hoox-sh/axis-cli 0.2.00d45a6f2(2026-08-23) — feat(ui): full-page studio overlay for Runtime, Wire, and Settings6900c093(2026-08-22) — feat(ui): slide-over drawers for Settings, Runtimes, and Wirec685a2d4(2026-08-22) — feat(ui): Venue picker pairs native CEX and CCXT in one controlfe0ed9c7(2026-08-22) — feat(ui): CCXT symbol catalog and hide paired stream95144094(2026-08-22) — feat(data): CCXT session keys and plugin-config/editor fixes339175f0(2026-08-21) — feat(ui): advanced config fields in Settings + full ccxt exchange list203b4492(2026-08-21) — feat(ui): topbar plugin config row for source/stream configSchema6b4d5543(2026-08-21) — feat(plugins): gateway-aware active source/stream resolution1631975f(2026-08-21) — feat(stream): ccxt-ws gateway stream pluginc1887afd(2026-08-21) — feat(source): ccxt-rest gateway source plugina47baf04(2026-08-21) — feat(data): gateway transport layer for CCXT datafeed3c72d089(2026-08-20) — feat(release): AXIS v2.0.18 multi-venue DO, credential vault, CCXT sidecarc42992e8(2026-08-19) — feat(release): AXIS v2.0.17 editor lint underlines and typos720237a1(2026-08-19) — feat(release): AXIS v2.0.16 editor intel recoveryfd23d4a8(2026-08-19) — feat(release): AXIS v2.0.15 editor intelligence and linebrcbe6369f(2026-08-19) — feat(editor): richer hover, param checklist, and pre-evala2178fc9(2026-08-18) — feat: live script execution, chart labels, and strategy properties35557be3(2026-08-17) — feat(release): AXIS v2.0.14 strategy hyperparameter optimisation9ec62e96(2026-08-17) — feat(release): AXIS v2.0.13 params, highlighting, input enums, tablesdb3b42c1(2026-08-17) — feat(release): AXIS v2.0.12 editor UX, chart lifecycle, icon mapf96319e3(2026-08-17) — feat(release): AXIS v2.0.11 chart scripts lifecycle and pyne-worker engine7f85d664(2026-08-16) — feat(release): AXIS v2.0.10 market proxy, inputs layout, local-first LSP2cae2b72(2026-08-15) — feat(editor): symbol catalog and richer Pine highlighting9411a16b(2026-08-15) — feat(pyodide): vendor pynescript 0.3.7 wheelfe6dfb18(2026-08-15) — feat(library): git versioned publish emulator for import ns/Name/ver4d1e8647(2026-08-13) — feat(ui): architecture modal to wire plugin slots from recipes814cb21f(2026-08-13) — feat(editor): 50vw default width; content-sized gutters80f25012(2026-08-13) — feat(pyodide): vendor pynescript 0.3.6 wheel904ec110(2026-08-12) — feat(drawings): paint line.style_arrow_left/right/both heads669ee31d(2026-08-12) — feat(drawings,plot): label styles/yloc, plot columns/cross/diamond8b80166b(2026-08-12) — feat(drawings): non-overlay pane Y + force_overlay routing46229069(2026-08-12) — feat(drawings,plot): linefill paint, barcolor, multi-script shapes4b379391(2026-08-12) — feat(ui): strategy Properties tab in Script settings4bf973e4(2026-08-12) — feat(ui): About AXIS modal on logo clicke96114b0(2026-08-12) — feat(editor): handle PYNE Agent insert/open script eventse29aa644(2026-08-12) — feat(ui,panels): panel defaults, chart overlay, classic logs chromea00ad891(2026-08-11) — feat(ui): dockable Status and System Logs; Script Logs naming7f44667e(2026-08-11) — feat(runtimes,editor): hub, idle lint, save-before-run, tight line gutters0c4a812d(2026-08-11) — feat(editor,panels): hover-slide docks and editor chrome polish7abea423(2026-08-10) — feat(chart): price-scale decimals with auto from symbol/bars235079b7(2026-08-10) — feat(editor): autoformat, color tools, and chrome redesign9ce5e0f3(2026-08-10) — feat: plot style chart parity, preeval constants, and storage versionsdee91540(2026-08-10) — feat(ui): fullscreen modes, price-pane scale controls, brand density8aa9dddc(2026-08-10) — feat(ui): symbol modal and richer Scripts panel cards60502d08(2026-08-10) — feat(cli): add AXIS CLI for install, setup, deploy, and doctorda9dd6fd(2026-08-10) — feat: Workers Manager modal and Tauri desktop shellcf938db1(2026-08-09) — feat(examples): add Pine v6 script library starter packa21dc811(2026-08-08) — feat(plugins): install PYNE Agent component and enable component URL loadfae48240(2026-08-08) — feat(onchain): refresh jobs, CSV export, and popular protocol presets61c9993c(2026-08-08) — feat(onchain): alerts UI, data view, commands, and ADR-0158ad97cb8(2026-08-07) — feat(onchain): alerts, layers, HUD health, and DSM walk-back polishf91a10f7(2026-08-07) — feat(onchain): data plane with DefiLlama TVL, DEX OHLCV, and eventsf62611a0(2026-08-07) — feat(editor): typo marks, wrap toggle, resizable Problems259204e5(2026-08-07) — feat(editor): pre-eval marks wrong code and disables Run6a945396(2026-08-07) — feat(drawings): merge parallel agent tool packs with full tests9427a565(2026-08-07) — feat(drawings): Gann, fib extras, patterns, and forecast tools963f5f87(2026-08-07) — feat(drawings): seed types and catalog for next parity packsaaa2cca5(2026-08-07) — feat(drawings): pitchfork, brush, callout, and more parity tools1abe0795(2026-08-07) — feat(drawings): registry-based tools toward charting platform parity807262a4(2026-08-07) — feat(data): dataset manager load window, venue live, expand to now0e4ae885(2026-08-06) — feat(data): raise historical bars cap to 100k58ff7be5(2026-08-06) — feat(data): cached datasets browser and Data Manager chart sourcec1d45d00(2026-08-06) — feat(ui): high-end theme presets, Scripts panel, Run accent only while busy4a6c5e49(2026-08-06) — feat(data): background Data Source Manager for multi-page OHLCV backfillb7887c92(2026-08-06) — feat(editor): slide-in tool labels on hover4d533975(2026-08-06) — feat(strategy): close fills, slippage next-open, marker prefs; fix script settings focus4705cb96(2026-08-06) — feat: symbol-scoped drawings, chart refresh, labels, editor docs43b0de57(2026-08-04) — feat(docker): full Buildx bake + Compose stack for AXIS PWAb51879b0(2026-08-04) — feat(ui): move chart Theme Manager to its own Settings tab5f6863f0(2026-08-03) — feat: chart Theme Manager (Pine chart.bg_color/fg_color) and UI hardening26a8358d(2026-08-03) — feat: GitHub/GitLab OAuth connect, multi-script results focus, hoox-sh org902f3d4f(2026-08-03) — feat: multi-agent PWA hardening for rock-solid reliabilityb844a76f(2026-08-02) — feat(ui): library panel, editor run/tab, live-after-load defaulted812a67(2026-08-02) — feat(chart): render Pine fill(plot1, plot2, color=…) as SVG bands7b481574(2026-08-02) — feat(library): default git scripts to .pyne under pyne-library52e2aa8c(2026-08-02) — feat(library): drag-drop .pine files into script library0b0df8e7(2026-08-01) — feat(editor,topbar): parallel polish — ruler, diagnostics, git, pins, problems10dd5074(2026-08-01) — feat(editor): show cursor line:col in stats stripc44f4cd9(2026-08-01) — feat(chart): script action icons on pane name badgesee31517a(2026-08-01) — feat: TV-class power features from parallel agentsa6cd8e1b(2026-08-01) — feat(editor): inline debug, wrap, stats; layers left slide-in9309f9a2(2026-08-01) — feat(layers): list and select user drawings in Layers panelf45bf320(2026-08-01) — feat(drawings): vline, extend, arrow, ellipse + toolbar polish40430f6b(2026-08-01) — feat(chart): multi-chart layouts, indicator align, editor full heightbacedac8(2026-08-01) — feat(ui): chart reflow with docks, reload/reset, float editor fixes0f9c4433(2026-08-01) — feat(ui): stack multiple docked panels one below the otherf982e0d8(2026-08-01) — feat(chart): multi-pane sync, scale controls, drawing GC, history depth
Fixes
defaccea(2026-08-29) — fix(data): try MEXC Worker proxy first, direct host as fallback167921f2(2026-08-29) — fix(worker): update CORS product hosts to pynescript.online (retire .ai)8426f3d9(2026-08-29) — fix(editor): remove duplicate 'Open in new tab' entry6178bced(2026-08-29) — fix(ui): status bar chips wobble on hovere0b8d4a8(2026-08-27) — fix(chart): repaint full series on input override recompute5fe39320(2026-08-27) — fix(ui): fine-tune settings polish and worker probead473102(2026-08-27) — fix(ui): polish settings pages and fix worker health probe blockingbb702efb(2026-08-27) — fix(wire): remove separate scrolling sections from wire pagef38a0239(2026-08-26) — fix(compile): display= folding into plot_attrs for data_window-only plotscb9c1773(2026-08-26) — fix(compile): hline linestyle via plot_meta backfill + default auto mode5bc18f5d(2026-08-26) — fix(hline): synthesize plot_meta in interpret path for hline linestyled417025f(2026-08-26) — fix(multi-chart): restore slot history on focus so each cell computes independently5025302f(2026-08-26) — fix(hline): carry linestyle through both drawing and overlay pathsb07befb9(2026-08-25) — fix(chart): render table cell valign/text-size; carry bgcolor band titles86b86bd7(2026-08-24) — fix(chart): never host hlines on bgcolor underlays53cef490(2026-08-24) — fix(chart): finish PlotSample widening in runner types2db34902(2026-08-24) — fix(chart): preserve engine color series so bgcolor/barcolor render68b13118(2026-08-23) — fix(settings): keep user inputs on applied scriptsea13ba50(2026-08-23) — fix(ui): seed Wire plan on mount and expose source for e2e70d0b378(2026-08-23) — fix(chart): honor Pine plot display.* flagsbed28c62(2026-08-23) — fix(chart): hide Pine drawings, label pad, histbase, re-owna05e42d8(2026-08-23) — fix(chart): plotshape pane routing and drawing tool settings098bfee4(2026-08-23) — fix(chart): drawing move, linefill GC, overlay pane routing55e26ddd(2026-08-22) — fix(editor): stop afterDot state leak from trailing-dot floatsd98048a8(2026-08-22) — fix(editor): pre-eval typo round 3 — generics, import paths, dotted calls47beaa62(2026-08-22) — fix(editor): pre-eval typo round 2 — decl forms, curly quotes, linktoseries5f0c3f36(2026-08-22) — fix(editor): stop pre-eval typo flood on built-in vars, qualifiers, text.*2f8ff1d2(2026-08-22) — fix(ui): plugin config first-save crash + gateway select optionsa6323558(2026-08-21) — fix(ui): single shared plugin config row + exchange dropdown7e74a266(2026-08-21) — fix(gateway): remote-page loopback resolution + drop shadowed require67361dc6(2026-08-21) — fix(datafeed): ccxt-ws browser ESM require + ccxt-rest walk-back windowaefa3baf(2026-08-20) — fix(editor): skip hex color tails in pre-eval identifier scannerd408f110(2026-08-20) — fix: resolve all 23 pre-existing TypeScript errors + CI typecheck gate804c5662(2026-08-20) — fix(test): reset store provider state in credentials beforeEachb160498e(2026-08-19) — fix: review follow-up for hover, hide, linebr, and agent seed35efaed7(2026-08-19) — fix(plugins): render PYNE Agent markdown and drop default endpoint7ccd745d(2026-08-19) — fix(chart): break plot.style_linebr on nadbcf1f0a(2026-08-18) — fix: review follow-up for live hide, labels, and strategy propsfa57f639(2026-08-17) — fix(editor): LSP pre-eval marks and last-bar drawingsf0235ac1(2026-08-15) — fix(ci): desktop Watchlist case clash and GHCR-only docker push42cb454f(2026-08-15) — fix(ci): green unit, smoke, desktop build, and docker bake4d34d82a(2026-08-13) — fix(editor): allow Problems panel to stay closedeb61d218(2026-08-12) — fix(drawings,plot): line.new last-bar export path + plotarrow direction299ec83c(2026-08-12) — fix(test,store): green suite — isolate defaults, health mock, bar fills41099e71(2026-08-11) — fix(plugins): clearer errors when cross-origin plugin import lacks CORS3bc43323(2026-08-11) — fix(panels): harden hover-slide reflow for non-DOM test windows0a668e00(2026-08-11) — fix(security,perf): gate /api/run, OAuth clientId, WS cool-down156221b9(2026-08-11) — fix(security,perf): fail-closed Worker auth, CORS, bars-cache9bfc801b(2026-08-10) — fix(editor,run): defer syntax lint; enum completions; protect interactive Run24f9cf68(2026-08-08) — fix(run): Re-run replace, add-instance menu, clear stuck Running77d2727e(2026-08-08) — fix(onchain): health probe always targets Worker baseb24fbd19(2026-08-08) — fix(onchain): honor empty health endpoint overridef8e3ae47(2026-08-08) — fix(onchain): always use AXIS Worker proxy; allow product CORS origins794ecadb(2026-08-08) — fix(onchain): do not proxy DefiLlama via axis.hoox.sh SPA host6d672e34(2026-08-07) — fix(editor): recognize strategy qty constants; copy problems3557ac99(2026-08-07) — fix(drawings): keep trendline draft when tool re-syncs mid-placeb81991da(2026-08-06) — fix(deploy): same-origin Pro API on https://axis.hoox.sh3e1f3a76(2026-08-06) — fix(git): harden storage integrity and OAuth device flow6f870e52(2026-08-06) — fix(data): backfill from now with gap validate; theme chrome; editor toolsebddd006(2026-08-06) — fix(data): multi-page walk-back without startTime+endTime trapfdb4c6b1(2026-08-06) — fix(ui): repair DrawingToolbar JSX after badge layout comment1fd8b64f(2026-08-06) — fix(ui): keep script badges above drawing toolbar chrome9140e31d(2026-08-04) — fix(strategy): correct PnL for Long/Short reverse entries260a59c4(2026-08-04) — fix(strategy): stop zeroing net PnL from placeholder prices/profit0867b1ce(2026-08-04) — fix(ui): make log copy buttons work on HTTP (clipboard fallback)10313f67(2026-08-04) — fix(strategy): qty-aware PnL, equity curve, and Strategy results tab4b32864d(2026-08-04) — fix(pyodide): align vendored wheel dist-info with pynescript filename7f516350(2026-08-04) — fix(ui): stop overlapping PRICE, indicator, and symbol badges73fd9d3d(2026-08-03) — fix: strategy events, plot colors, and price-scale labels16a381d1(2026-08-03) — fix(ui): icon-only editor tools; new tab in panel hamburgera4cc7b27(2026-08-02) — fix(chart): collapse stacked same-text Pine status labels146bb090(2026-08-02) — fix(results): drop no-fill closes; recover Source inputs; clamp future labels134414dc(2026-08-02) — fix(library): strip TradingView® Expand (N lines) chrome on import3d89f4ac(2026-08-02) — fix(library): open every dropped .pine as its own editor tababcf5eb2(2026-08-02) — fix(library): block browser file-open on pine drag-drop85e037be(2026-08-01) — fix(dock): side-by-side panels on left/right (indicators left of editor)33305aec(2026-08-01) — fix(chart): plot indicators on stable sub-pane id4fd29aea(2026-08-01) — fix(chart): stop oscillator scripts vanishing on the price pane8a11fdc5(2026-08-01) — fix(editor): restore full height so lines are editable3a77976d(2026-08-01) — fix(replay): start with full history, not a single candlef89b9cc6(2026-08-01) — fix(editor): sync full Pine builtins corpus from pyne
Performance
de00cbf3(2026-08-13) — perf(pwa): heavy live re-run throttle, offline bars fallback, SW v4 capa9375440(2026-08-13) — perf: coalesce live ticks, resize, and strategy UI; harden paint/securitycb901eb4(2026-08-10) — perf: full-app hardening — live ticks, overlays, load abort, boot splita9f57958(2026-08-10) — perf(chart): heavy history paint, conflation, and O(1) live ticks
Refactors
afb85816(2026-08-26) — refactor(about): remove ethos/author, add versions and philosophy6041c2d6(2026-08-22) — refactor(ui): move plugin config section into Settings → Data tabf19fe9a2(2026-08-08) — refactor: rename remaining pine-* modules to pyne-*18eedc78(2026-08-08) — refactor: rename pine-language/lsp/builtins editor stack to pyne-*096a799f(2026-08-08) — refactor: rename pine-editor CSS, DOM, and PyneEditor componentb52526af(2026-08-08) — refactor: rename pine-editor.js to pyne-editor.jsf0a1446b(2026-08-02) — refactor: rename chart palette TV→VOID; document Pine naming parity
Documentation
0a705de9(2026-08-27) — docs(changelog): add topbar settings and wire page fix entries35dacd21(2026-08-24) — docs: studio shell, MEXC venue, and PYNE Pro origin across guidesdce471b0(2026-08-21) — docs(devops): list /datafeed/ among nginx-proxied Pro API paths27b5ca13(2026-08-21) — docs(changelog): datafeed gateway phase 4 additions36900319(2026-08-15) — docs(cors): document Pages preview origins for axis.hoox.shd3172dbb(2026-08-11) — docs: AXIS 2.0.1 docs, CLI-first ops, Pine Script™ v6 examples78c22e85(2026-08-11) — docs(release): recursive changelog, AGENTS release workflow, v2.0.1f7c30e04(2026-08-09) — docs: prefix internal links with /axis/docs3d6fe1ab(2026-08-08) — docs(ui): clarify on-chain uses public APIs unless Worker endpointf21dcc47(2026-08-08) — docs: update llm.txt for PyneEditor rename95e181c3(2026-08-08) — docs: document on-chain data plane in README, hubs, and workerdf7b77ab(2026-08-07) — docs: add PYNE Agent (pyne-agent-worker) plugin guides5d1dc0f0(2026-08-07) — docs: add PYNE Agent (pyne-agent-worker) plugin guidesdc62332f(2026-08-03) — docs: regenerate llm.txt and llms.txt agent corpora5dc92693(2026-08-01) — docs: align UI and end-user guides with last 15 commits
CI
0c963fc6(2026-08-23) — ci(cli): do not fail release when access public is forbidden88ca0133(2026-08-23) — ci(cli): treat already-published 0.2.0 as success and set publicc35de1fe(2026-08-23) — ci(cli): auth registry checks and always set package publice07c59df(2026-08-23) — ci(cli): force @hoox-sh/axis-cli public after npm publishdd3ebf85(2026-08-23) — ci(cli): publish with NPM_TOKEN_HOOXSH and isolate CLI tests75c4543c(2026-08-22) — ci: versioned docker tags and npm publish for axis-cli3ddc4193(2026-08-10) — ci(docker): fix image build, enhance make targets, add GHCR workflow5b4bbef4(2026-08-10) — ci: build Tauri desktop app on every main push
Tests
5d5844ae(2026-08-23) — test(e2e): open Plugins via studio rail; exact Offline Lab apply
Chores
862631e6(2026-08-29) — chore(release): prepare v2.1.140668dbc(2026-08-29) — chore(release): prepare v2.1.0f34c76cf(2026-08-26) — chore(release): bump to v2.0.27 — PYNE wheel 0.4.0, hline linestyle, multi-chart fixd323c8fd(2026-08-24) — chore(release): v2.0.26a01be631(2026-08-23) — chore(release): AXIS v2.0.2322966e62(2026-08-23) — chore(release): AXIS v2.0.223e7236ef(2026-08-21) — chore(release): v2.0.20b4b3227b(2026-08-15) — chore(release): AXIS v2.0.8236d042f(2026-08-12) — chore(release): AXIS v2.0.75f6d7a9a(2026-08-12) — chore(release): AXIS v2.0.612cffe27(2026-08-11) — chore: ignore local multi-agent sync notice files33e11930(2026-08-06) — chore(worker): gitignore wrangler.toml and ship example9cb4dad0(2026-08-06) — chore: vendor latest pyne 0.3.0 wheel (parity Aug 6)9fba8aaf(2026-08-03) — chore: rename SuperChart branding to AXIS including CF project id0cbda10b(2026-08-01) — chore(pyodide): vendor pynescript 0.3.0 wheel with drawing GC
Style
21676494(2026-08-22) — style(ui): render inline plugin config fields via TopbarField
Merges
938835cb(2026-08-08) — Merge pull request #1 from hoox-sh/feat/onchain-data-plane
Other
e6491985(2026-08-08) — merge: resolve main conflicts for on-chain docs
2026-07 (79 commits)
Security
8c4a635c(2026-07-24) — Harden + bugs + polish (16 changes)
Features
593bb8aa(2026-07-31) — feat(inputs): OHLC source enums and cross-indicator plot sources501761db(2026-07-30) — feat(ui): make all panels border-resizable down to 1px852d2fa2(2026-07-30) — feat(ui): Scriptlogs rename; editor FloatableShell + tools745e3426(2026-07-30) — feat(ui): Pine Logs panel and Editor Profiler modea2ed35e6(2026-07-30) — feat(chart): multi-type price series and fix settings save raced0e52bb2(2026-07-29) — feat: live watchlist WS quotes and TV-style drawing chrome9487673c(2026-07-29) — feat(ui): softer inputs and collapsible panel dock menu4e9a6100(2026-07-29) — feat(ui): density scale slider and floatable dockable panels4e3f029d(2026-07-29) — feat(ui): data window, layers, script inputs; plot visuals + strategy60c7e2f9(2026-07-29) — feat(settings): presets for VPS UI + local pyne compile52cd2668(2026-07-29) — feat(editor): prefer pyne Pro API LSP for completion and hover08fdbf24(2026-07-29) — feat(editor): Pine completion and hover from LSP builtin metadataebb4db8d(2026-07-29) — feat(hud): ENG/RUN/MODE/PATH chips with sticky hover infoba480687(2026-07-29) — feat(settings): expose PYNE execution mode (interpret/compile/auto)7dc63117(2026-07-27) — feat(axis): connection HUD, WSS engine path, chart stability7cf3d357(2026-07-27) — feat(axis): quality stack at 95% coverage, e2e, and ops polish55a5a0c2(2026-07-26) — feat(axis): self-host Pyodide and preload on idlee264c91e(2026-07-26) — feat(axis): source-aware watchlist with interval and refresh settings5de17948(2026-07-26) — feat(axis): plugin capability badges and storage status chromeb56e4f61(2026-07-26) — feat(axis): git script storage and Pine table HUD3e00e1e1(2026-07-26) — feat(axis): script library, storage plugins, and drawing polish6322cd7b(2026-07-26) — feat(axis): render Pine drawings and drag user drawingsc9d2a0e8(2026-07-26) — feat(axis): interactive chart drawing tools31b7eed8(2026-07-26) — feat(axis): jump-to-trade from Results and status-bar P&L9c0e3b06(2026-07-26) — feat(axis): strategy trade markers, equity pane, and event normalizationbd0a106b(2026-07-26) — feat(axis): ship AXIS charting PWA, evaluator corpus fixes, and /run/batchc2f27a02(2026-07-25) — feat: SuperChart rewrite + Pine evaluator runtime fidelityacee8d1c(2026-07-24) — feat: slide-in editor pane with push-layout and drag resize2a6a2163(2026-07-23) — feat: Pyodide engine rewrite, watchlist sidebar, URL hash sync, demo scripts40db7f47(2026-07-23) — feat(pwa): wire multi-tab editor (CodeMirror 6 with tab persistence)68da3cce(2026-07-23) — feat(pwa): plugin manager, script library, theme switcher, symbol autocomplete, plugin examplesfe90be7b(2026-07-23) — feat(pwa): settings dialog, multi-pane, volume, time presets, strategy tester9be7d819(2026-07-23) — feat(frontend): modular PWA + Cloudflare® Worker backend28b57862(2026-07-20) — feat(v6): multiline strings, export const runtime, strategy state, library import
Fixes
d5e487f2(2026-07-31) — fix(profiler): compute gutter % from Σ line cost, not wall ms4d5ad0a0(2026-07-31) — fix(profiler): send profiler over WS and auto-run on enable34cb26a3(2026-07-31) — fix(editor): render LSP hover markdown and round tooltip corners0abecff8(2026-07-31) — fix(profiler): pass profiler flag to API and map profile/logs33308a88(2026-07-29) — fix(ui): stop pine drawing flicker; indigo loader accent3c6dbbae(2026-07-29) — fix(engine): REST fallback after WS timeout must not reuse dead AbortSignal7b4b951e(2026-07-29) — fix(settings): clearer endpoint probe errors for NetworkError156e8c7f(2026-07-29) — fix(hud): keep ENG plane in sync with selected engine8ffa6c5c(2026-07-29) — fix(ui): pyodide load hint, clarify MODE vs ENG chips, clip tick pulse9dfeab37(2026-07-29) — fix(pyodide): install local wheels with deps=falsef4dd5d0b(2026-07-29) — fix(settings): always show execution mode for server/pyodide57814bd1(2026-07-29) — fix(settings): show execution mode for pyodide engine too7d0021d2(2026-07-29) — fix(engine): tolerate bare NaN in REST /run responsesb97649fd(2026-07-29) — fix(engine): send execution mode in REST /run body22178b3a(2026-07-27) — fix(api): accept null optional symbol on WS live re-runs431b3da2(2026-07-26) — fix(axis): serve pyodide wheels from public/ and stop SPA HTML fallback2d10a39a(2026-07-26) — fix(axis): open Indicators panel from topbar togglef75867d8(2026-07-26) — fix(axis): return multi-plot series from /run and harden trade pairing49ddff4e(2026-07-26) — fix(axis): multi-plot series with colors and bar-mode crossovercf36ed70(2026-07-26) — fix(axis): serve example plugins from /plugins in production754b433c(2026-07-26) — fix(axis): split plugin-badge utils for bun tests; drop wrangler d.ts1ef06799(2026-07-26) — fix(axis): resolve marker time from bar_time and kind from parity events4252dc9e(2026-07-26) — fix(evaluator): Console UDT multi-dispatch, bare na, and bar-loop lock95479073(2026-07-24) — fix(chart): fix chart and volume pane CSS layout6642164d(2026-07-24) — Fix chart overlap: absolute-position the loading skeleton086277c3(2026-07-24) — Fix data window positioning: use fixed coords + getBoundingClientRectaaff9631(2026-07-24) — Fix 4 layout/UX issues: loading skeleton, auto-run demos, watchlist, data window4bc3132f(2026-07-24) — fix: stdev always returns None due to AdvancedIndicators dispatch + PineSeries initial Nonee0854e83(2026-07-24) — fix: dict/NoneType errors in Pyodide engine (input.int, color.new, arith)40568a06(2026-07-24) — fix: builtin dispatch only passes kwargs if handler accepts them7f2d7928(2026-07-24) — fix: SMA constant values and RSI None crash in Pyodide enginec35b12d6(2026-07-23) — fix: merge kwargs into positional args for builtins in Pyodide runtime
Documentation
6bd9c848(2026-07-29) — docs: inline TSDoc and module headers across the codebasea3ee4a19(2026-07-29) — docs(cors): allow any localhost/127 port on Worker; skip 0.0.0.02b09f248(2026-07-28) — docs(license): AGPL-3.0-only (not or-later)8fe2058f(2026-07-28) — docs: cross-link HOOX / pyne / axis with hoox.sh websites
Tests
1e314369(2026-07-29) — test(engine): assert REST /run body includes execution mode
Chores
42bf3ba9(2026-07-29) — chore(pyodide): vendor latest pyne wheel and sync bridgee6040569(2026-07-28) — chore: bootstrap standalone axis repo from pyne frontend/8dff3a71(2026-07-28) — chore(license): relicense to AGPL-3.0-or-later under jango_blockchained202a0499(2026-07-23) — chore: switch frontend + worker to Bun + TypeScript 6
Style
1ee7f8ea(2026-07-26) — style(axis): larger drawing toolbar icons432dcf51(2026-07-26) — style(axis): swap Hell Flieder for void indigo from landing pack
Other
514b90d1(2026-07-24) — Add copy buttons with SVG icons to status bar + results panels
2026-01 (1 commits)
Features
bb224279(2026-01-13) — feat: Google Server Setup and Closed Source Transition
2025-10 (2 commits)
Features
38a00b82(2025-10-24) — feat(script): Add overlay series for line chart and improve data handling
Other
5613175b(2025-10-20) — Add technical analysis built-ins and corresponding tests
How to update
- Edit [Unreleased] (or the new version section) by hand for the story.
- Regenerate the recursive history block:
python3 scripts/generate-changelog.py
- Commit changelog with the release; then tag, push, publish, sync
(see
AGENTS.md§ Changelog & releases).