Roadmap
Milestones delivered so far, and what's next. Each shipped milestone is compiled, clippy-clean, and tested (SQLite for the DB layer; GUI/OS integrations are launch-smoked, with visual/side-effecting steps called out as unverified).
Delivered
-
M0 — tao + wry +
elyra://custom protocol + one#[command]end to end over MessagePack; container; assets from memory with a fallback page. -
M1 —
EventBus+channel()+ per-flush batching; async custom protocol (noblock_on). Both frontends include a latency probe. -
M2 — specta codegen (
rata codegen) → TS types + typedapi.*; the CLI (dev,codegen,build). -
M3 — providers (
register/boot), the middleware pipeline,Resultcommands, window options. -
M4 — multi-window + the
Windowshandle,rata newscaffolding,rata bundle(macOS.app+ ad-hoc signing). -
M5 —
elyra-db(SQLite/MySQL/Postgres via sqlxAny) +rata migrate(batched, reversible, status). -
M6 — system tray (
tray-icon, clicks → event bus) and the auto-updater (manifest + semver + ed25519 verification; HTTP fetch + staged download). -
M7 —
#[derive(Model)]Active Record: CRUD + typed query builder, per-driver placeholders, injection-safe column identifiers. -
M8 — model extras:
bool↔INTEGER mapping,#[model(column)], and#[model(timestamps)]. -
M9 — model relations (
has_many/has_one/belongs_to) andwhere_infor eager-load queries. -
M10 — eager loading: each relation gets a
load_<name>batch method (oneWHERE fk IN (..)query, grouped into aHashMap) to avoid N+1. -
UI components (v0.1.0) — a built-in About dialog (
App::about) and an auto-update toast (App::updater), both rendered by@elyra/runtime; the updater now applies + relaunches (Updater::apply_and_relaunch). -
Codegen serde support — types export through
specta-serde, sorename/rename_all, tagged / untagged enums,flatten, andskipare reflected in the generated TypeScript. -
System integration (
systemfeature) — native file dialogs,openExternal, clipboard, OS notifications, and standard paths, exposed through@elyra/runtime(dialog/shell/clipboard/notify/paths). -
Database CI — model CRUD runs against real MySQL and Postgres service containers in CI (
framework/tests/model_servers.rs), covering per-driver placeholders and key retrieval; skipped locally unless theELYRA_TEST_*_URLenv vars are set. -
Desktop platform APIs (v0.3.0) — the Electron-parity push: UI components (dialogs / toasts / ⌘K palette / context menu), window control + file drop + state persistence, global shortcuts, a native app menu, a settings store, autostart, sidecar processes, and single-instance + deep-linking.
-
AI SDK (v0.3.1 → v0.4.0) — a Laravel-inspired
elyra::ai: agents, tools, sub-agents, provider tools (web search / fetch), structured output, streaming, images, audio (TTS / STT), embeddings, an in-memory vector store for RAG, plus retries / provider failover / response caching, over Anthropic + OpenAI (aifeature). -
Shared facades (v0.5.0) —
Cache,Storage, andQueuewith the same ergonomics as the Askr/Laravel side, over local backends. -
Shared substrate contract — the
substrate-corecrate formalizes the backend-agnosticCache/Storage/Queuetraits; Elyra's facades implement them (verified intests/substrate.rs), ready for Askr to depend on the same crate. -
Hardening + Laravel parity (v0.5.7) — an IPC token + capability model and origin-scoped CORS, a default CSP, deny-by-default sidecar spawn and policy-gated
shell.open, bounded/depth-checked request bodies, an authenticated single-instance handshake, HTTPS + streaming in the updater, and OS-keychainSecrets. PlusLog,Config,TestApp, the schema builder with Rust migrations + seeders, Eloquent-style pagination/aggregates/joins/soft deletes/transactions, queue retries + DLQ, typed event channels in codegen, assetETag/Rangecaching, a cross-platform app menu,.deb/portable bundling, and CI across macOS/Linux/Windows. See the changelog. -
Security + structure (v0.5.8) — per-command abilities (
#[command(can = "…")]+App::allow_ability), soCapability::Commandsis no longer one grant over every registered command;Secretsreturns a value that zeroizes on drop;ForbiddenErrornames the gate that refused instead of always blaming the token;shell.rssplit into ashell/module with access control isolated inguard; pluselyra::preludeandrata make:middleware. -
Laravel depth (v0.6.0) — models:
belongs_to_many, casts, local + global scopes and factories; container: trait-object and lazy bindings; domain events withApp::broadcastto a typed frontend channel; durable queues; test fakes withApp::swap. -
Desktop depth (v0.7.0) — per-command middleware with aliases and groups; clock-time scheduling and cron, sleep- and DST-aware; validation for nested input, arrays and the database (44 rules); translations shared by Rust and Svelte.
-
Resources (v0.8.0) —
rata make:resource: the commands, validation, events and tests for a model,--viewfor the Svelte screens,--generatefor the model, migration, factory and seeder from a field list; a hash router and a registry behind them; translated validation messages and typed$t. -
Live queries (v0.9.0) —
#[command(live)]: reads recorded, writes reported, the affected subscriptions re-run (coalesced, unchanged results skipped) and pushed to the windows watching; typedlive.*stores on the frontend; live lists and detail views frommake:resource. -
AI agents (v0.10.0) — every app an MCP server: granted commands as tools with JSON Schemas from their types,
myapp --mcpinto the running app or headless, confirmation in the client, live commands as resources with subscriptions, an event and a channel for every call, rate limits, andrata mcp install. -
MCP resource templates (v0.11.0) — live commands with arguments as URIs an agent fills in and watches (
app://customers_show/{id}), with completion for enums and booleans. -
A Laravel backend (v0.12.0) — the desktop half of a Laravel app:
Http,Backendwith Laravel's answers mapped (a422per field), Sanctum sign-in with the token in the keychain, live queries over the API, andmake:resource --backend; CI against a real Laravel app.
Next / open
-
Desktop and web, with a Laravel backend — the web half is Laravel (on Askr). After RFC 0005 (v0.12.0: sign-in, the API, its errors): RFC 0006, Laravel's broadcasting in over the Pusher protocol (Askr, Reverb, Pusher), so a change on the web updates the open windows; then RFC 0007, working offline and syncing.
-
Codegen — optional
biginttransport for integers beyond 2^53 (MessagePack already carriesi64on the wire; this is a TS-typing opt-in). -
Models — composite (multi-column) primary keys. (Single non-
i64keys, relation auto-hydration into struct fields, and column-aware relation FKs have shipped.) -
AI SDK — additional providers (Gemini, Groq, …) and OpenAI provider tools via the Responses API; live provider integration tests in CI.
-
Live queries — finer invalidation than per table (rows, or the query's own
WHERE) if measurements ask for it; database change capture (SQLiteupdate_hook, PostgresLISTEN/NOTIFY) to also catch raw SQL and other processes. Both deliberately out of v1 (RFC 0002). -
MCP — prompts; completions an app computes for a template's variables (customer names, say), beyond the enums and booleans the schema gives.
-
Dogfood — port a real app to pressure-test the DX.
-
Installers — MSI (WiX) / NSIS on Windows and AppImage/Flatpak on Linux;
rata bundlecurrently produces a.deb, a portable.tar.gzand a portable Windows folder. -
Capabilities per window — the policy is app-global today; per-window scoping is the next step. (Per-command declarations have shipped: see
#[command(can = "…")]in security.)
Out of scope
Elyra is a framework, not a release pipeline. It deliberately does not handle
code signing, Apple ID / Developer ID, notarization, or building and shipping
binaries — those belong to each application's own release process. rata bundle
produces a local, ad-hoc-signed .app for development; producing a signed,
notarized, distributable build is the app's responsibility.
The updater is the same: it provides verified download + apply primitives, but generating keys, signing artifacts, and hosting the manifest are the app's job, not the framework's.
Known sharp edges
- Events use HTTP-style long-poll over the custom protocol (wry's async responder is one-shot). One connection is multiplexed across channels.
- macOS requires the webview on the main thread; the tokio runtime is kept separate and every request is spawned onto it.
- The
#[command]macro handles neither generics norOption<Ctx>— deliberate. rata devrelies on cross-schemefetch(http origin →elyra://); CORS is set, but platform behavior there is unverified.