[Manager and settings]

Plugin Manager catalog, URL install, capability badges, and Settings dialog for engine, storage, and endpoints.

Manager and settings

Two orthogonal surfaces configure AXIS: the Plugin Manager (what exists and is active) and Settings (endpoint, engine, storage, interval defaults). Neither embeds language semantics.

Abstract

SurfaceOpens fromMutates
Plugin ManagerTopbar PluginsRegistry membership, active source via Use, library ops
SettingsTopbar gearendpoint, active engine/storage, chart interval, watchlist refresh

Active plugins live in store.activePlugins; per-plugin fields in store.pluginsConfig keyed by `${'{'}kind{'}'}:${'{'}id{'}'}`.

Conceptual model

Plugin Manager

Catalog

Lists sources, streams, engines, storages from the unified registry.

ActionEffect
UsesetActivePlugin(kind, id) for that row’s kind
Capability badgesoffline, needsAuth, needsNetwork, needsProxy from plugin.capabilities
Built-in flagBuilt-ins resist casual unregister

Status bar shows active engine id and storage backend after changes.

Install (URL)

Paste a module URL exporting a default plugin object (kind, id, name, contract methods). AXIS:

  1. Fetches and validates export
  2. Registers into the TypeScript registry
  3. 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 frontend/tests/security/.

Example plugins ship in public/plugins/:

  • example-coingecko-source.js
  • example-tiny-pine-engine.js
  • example-cf-do-stream.js

Script Library tab

See Script library. Manager hosts the panel so library and plugins share one modal.

Settings dialog

FieldBehavior
Backend URLShown when engine is server or has configSchema.endpoint
Test / ProbeGET health against endpoint; status message
EngineRegistry engine list; labels via engineOptionLabel
Storagelocal | cloud | git
Default intervalUpdates store; may reload bars for current symbol
Watchlist refreshClamp 5–120 seconds

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)

ControlStore field
Engine selectactivePlugins.engine, flat engine
Storage selectactivePlugins.storage
Endpointendpoint
Source/stream topbaractivePlugins.*, source, live.streamId
Theme toggletheme + data-theme on <html>

Internals

PathRole
frontend/src/ui/PluginManager.tsxManager modal
frontend/src/ui/SettingsDialog.tsxSettings
frontend/src/ui/plugin-badges.tsxCapability badges
frontend/src/plugins/registry.tsUnified registry
frontend/src/plugins/loader.tsURL load + restore
frontend/src/plugins/bootstrap.tsBuilt-ins

Invariants

  1. Settings never write script bodies—only layout/config.
  2. Catalog Use does not auto-Run; Load/Run remain explicit.
  3. Source change may re-default stream (defaultStreamForSource).
  4. API keys for cloud/git belong in pluginsConfig, not in git-committed defaults.

Worked examples

Point AXIS at local Worker

  1. Settings → Engine Server-Side → Endpoint http://127.0.0.1:8787
  2. Probe → OK
  3. Save → Run

Install example source

  1. Manager → Install → URL to .../plugins/example-coingecko-source.js (served origin)
  2. Catalog → Source appears → Use → Load

Failure modes

SymptomFix
Empty catalogBuilt-ins not registered—hard reload; check console
URL install failsCORS on plugin host; bad export; mixed content
Probe failsBackend down; wrong path; HTTPS mixed content
Settings not stickylocalStorage blocked / quota

See also