Manager and settings
Runtime, Workers, Plugins, Wire, and Settings — how AXIS chrome is split.
This page
Five studio pages share one full-viewport overlay. Runtime is the active calculation context; Workers and Plugins are catalogs, not tabs inside it.
Abstract
| Surface | Opens from | Mutates |
|---|---|---|
| Runtime | Topbar Studio · studio rail · ⌘K “Open Runtime” | Active engine, endpoint, exec mode, probe of that backend |
| Workers | Studio rail · ⌘K “Open Workers” · Runtime card | Probe catalog; activate a backend (endpoint / engine) |
| Plugins | Studio rail · ⌘K “Open Plugins” · hidden topbar testid | Registry membership, Use, inline URL install |
| Wire | Topbar Studio → Wire rail · ⌘K “Open Architecture” | Compose slots; Apply writes activePlugins |
| Settings | Topbar Studio → Settings rail · ⌘K “Open Settings” | Appearance, chart, live, MCP bridge, session keys, editor intel, theme |
Active plugins live in store.activePlugins; per-plugin fields in store.pluginsConfig keyed by `${'{'}kind{'}'}:${'{'}id{'}'}`.
Conceptual model
Rendering…
Plugin Manager
Catalog
Lists sources, streams, engines, storages from the unified registry. Sources, streams, engines, and storage are single slots — one active row per kind, so each section carries a “Single slot · one active” badge and rows flip between Use and Active. Components are multi-slot: many register side by side and rows show a Registered chip instead of an activate button.
| Action | Effect |
|---|---|
| Use | setActivePlugin(kind, id) for that row’s kind |
| Capability badges | offline, needsAuth, needsNetwork, needsProxy from plugin.capabilities |
| Built-in flag | Built-ins resist casual unregister |
Status bar shows active engine id and storage backend after changes.
Install from URL (inline)
The install flow lives inline on the catalog page (no separate tab), next to the Installed URLs list. Paste a module URL exporting a default plugin object (kind, id, name, contract methods). AXIS:
- Fetches and validates export
- Registers into the TypeScript registry
- Persists install record so
restoreInstalledPlugins()reloads next visit
Security notes (operator-level): only https/http schemes suitable for module load; treat third-party URLs as code execution in your browser origin. See security tests under tests/security/.
Supported URL kinds: source, stream, engine, dataset, component. Example plugins ship in public/plugins/:
example-coingecko-source.jsexample-tiny-pyne-engine.jsexample-cf-do-stream.js
PYNE Agent (sister project — natural language → PYNE scripts) installs as a component from your deployed worker URL (or via Workers Manager → Install):
https://<pyne-agent-worker>/plugin/axis-pine-agent.js
See PYNE Agent and plugin reference. Works without the HOOX mesh.
Script library
The Plugins page no longer embeds the Script Library. Use the topbar Library panel — see Script library.
Runtime vs Workers vs Plugins
One overlay (AppPage in src/ui/studio/) with a left rail. Switching rail pages does not close the overlay.
- Runtime —
src/ui/runtime/RuntimePage.tsx— active engine, endpoint, exec mode. - Workers —
src/ui/workers/WorkersPage.tsx— backend inventory and probes. - Plugins —
src/ui/plugins/PluginsPage.tsx— catalog with inline install.
Workers
Opens from the studio rail, ⌘K Open Workers, or a Runtime related card.
| Sub-tab | Role |
|---|---|
| Overview | Health cards (distinct icon per worker) for pyne Pro API, AXIS Worker (prod + local wrangler), Pyodide, PWA service worker, optional PYNE Agent / pyne-worker |
| Detail | Usage (when to pick this worker), probe latency, feature flags, Use-as-backend / preload / install actions |
| Install | When to use + step-by-step setup with copyable commands (make run, wrangler, plugin URL, …) |
| Configure | Paste Backend URL, presets (:5002, :8787, workers.dev, axis.hoox.sh), activate Pyodide, install agent plugin |
Catalog items (usage)
| Worker | Icon intent | When to use |
|---|---|---|
| pyne Pro API | server | Primary Server calculation backend (Flask :5002). Best for compile/Numba and long history. |
| AXIS Worker | zap | Production edge data plane (on-chain proxy, scripts D1, optional /api/run). Default for On-Chain. |
| AXIS Worker (local) | activity | Local wrangler :8787 while developing the Worker. |
| Pyodide | cpu | In-browser offline calc — no Backend URL; first load ~20–30s. |
| Service Worker | wifi | PWA shell cache (auto in production; skipped in Vite dev). Not a calc engine. |
| PYNE Agent | download | Optional NL → Pine plugin; scripts still run via your engine. |
| pyne-worker | settings | Optional HOOX mesh edge evaluator; paste origin as Backend URL. |
Probes
- Run once when the modal opens; Refresh re-runs.
- Each worker has a hard wall-clock timeout (~5s) so a hung host cannot leave “Probing…” forever.
- Pyodide probe uses HEAD (not a full
pyodide.jsdownload). - HTTP probes hit
GET /health(JSON markers). Implementation:src/workers/*,src/ui/workers/WorkersPage.tsx. Operator CLI twin: AXIS CLI.
Hardened VPS note: production UFW typically allows only 22 + 443. Pro API binds 127.0.0.1:5002 — public :5002 probes correctly time out. On https://axis.hoox.sh, Workers Manager probes pyne Pro via same-origin https://axis.hoox.sh/health (nginx reverse-proxy), not loopback. See VPS demo.
Runtime (engine)
Engine, execution mode, Backend URL, Test, and Prefer WebSocket live on Runtime, not Settings. Storage is a Wire slot.
| Field | Behavior |
|---|---|
| Engine | Registry engine list; labels via engineOptionLabel |
| Execution mode | When the active engine exposes configSchema.mode (server): interpret | compile | auto. Stored in pluginsConfig.engine:<id>.mode and sent on each run (WS and REST). |
| Prefer WebSocket run | Server engine: prefer /ws/run over REST when available |
| Backend URL | Shown when engine is server or has configSchema.endpoint |
| Test / Probe | GET health against endpoint; status message |
Settings
Product chrome only. Engine/endpoint/mode are on Runtime. Chart type, interval, and scale live on the price-scale Chart type & scale panel (gear), not a new Settings tab. Discover app-wide Settings from the Studio rail or ⌘K Open Settings.
| Field | Behavior |
|---|---|
| Default interval | Updates store; may reload bars for current symbol |
| Watchlist refresh | Clamp 5–120 seconds |
| Chart theme | Preset picker (void / classic / mono / boutique dark & light) — see src/theme/presets.ts |
| History bars | One-shot Load depth (venue may clamp further) |
| Rolling window | Base chart/engine window (200–4500 bars). Live charts anchor at the TradingView®-style period boundary — week start for intraday, month start for daily, year start for weekly/monthly (UTC) — grow up to +20% (hard cap 5000), then reset to that boundary when it fits, otherwise to the base. This keeps bar_index and the first strategy event stable between resets instead of sliding the head on every candle. The engine depth grows in 100-bar chunks so live subscriptions do not resubscribe per tick. The anchor needs extra history: set History bars above the Rolling window. Because the cap must drop bars, a reset at the ceiling lands on the base window when the boundary is already the window head — bar_index shifts once per grow cycle, not per candle. |
| MCP | Connect this tab to MCP (default on). Requires a Worker API key under Settings → General → Worker (cloud + MCP). Status line shows open / idle / error. See MCP (agents). |
Deep multi-page history and gap repair live in the Data Source Manager, not Settings.
Live re-run cadence. Live → every-tick evaluates on every venue tick (about every 2 s on a 1m Binance stream); bar-close evaluates once per closed candle. The engine subscription is a full snapshot on subscribe and delta frames afterwards. The wire.script.paint debug line is the client painting the cached delta onto the chart window — windowBars is the chart window size, not a full re-evaluation.
Execution mode maps to PYNE Runtime.run(..., mode=…):
| Mode | Behavior |
|---|---|
interpret | Full AST interpreter |
compile | Numba/numpy compiled path (first run JITs; Flask is not prewarmed) |
auto | Default on Server / Pyodide: try compile, fall back to interpret on failure |
The Connection HUD engine chip shows the selected mode. Save persists via Solid store persist() into pynescript.axis.v1. Escape closes; Ctrl/Cmd+Enter saves.
Pyodide engines hide endpoint—calculation is same-origin assets, not Flask.
Interface surface (UI map)
| Control | Store field |
|---|---|
| Engine select | activePlugins.engine, flat engine |
| Storage select | activePlugins.storage |
| Endpoint | endpoint |
| Source/stream topbar | activePlugins.*, source, live.streamId |
| Theme toggle | theme + data-theme on <html> |
Internals
| Path | Role |
|---|---|
src/ui/studio/ | Full-page overlay kit (ax-*) |
src/ui/runtime/RuntimePage.tsx | Active engine / endpoint / mode |
src/ui/plugins/PluginsPage.tsx | Catalog + inline install |
src/ui/workers/WorkersPage.tsx | Backend inventory / probes |
src/ui/settings/SettingsPage.tsx | Product chrome |
src/ui/wire/WirePage.tsx | Compose recipes |
src/ui/plugin-badges.tsx | Capability badges |
src/plugins/registry.ts | Unified registry |
src/plugins/loader.ts | URL load + restore (incl. component) |
src/plugins/bootstrap.ts | Built-ins |
Invariants
- Settings never write script bodies—only layout/config.
- Catalog Use does not auto-Run; Add to chart / Run remain explicit.
- Source change may re-default stream (
defaultStreamForSource). - API keys for cloud/git belong in
pluginsConfig, not in git-committed defaults.
Worked examples
Point AXIS at local Worker
- Settings → Engine Server-Side → Endpoint
http://127.0.0.1:8787 - Probe → OK
- Save → Run
Install example source
- Manager → Install from URL →
.../plugins/example-coingecko-source.js(served origin) - Catalog → Source appears → Use → boot or watchlist paints bars; Add to chart / Run for scripts
Failure modes
| Symptom | Fix |
|---|---|
| Empty catalog | Built-ins not registered—hard reload; check console |
| URL install fails | CORS on plugin host; bad export; mixed content |
| Probe fails | Backend down; wrong path; HTTPS mixed content |
| Settings not sticky | localStorage blocked / quota |