Elyra
Elyra The coding agent e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Elyra SQL Server MySQL-compatible SQL server in Rust Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra Sjá SEO & GEO workspace for macOS Elyra DataGrid Server-driven data grid for Laravel
Release notes
Changelog
Elyra

Changelog

All notable changes to Elyra Sjá are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

Planned

  • Shared team database — point every seat on a Studio (team) license at one database, so projects, history, trends and monitors are shared across the team instead of living per-machine. The database location becomes configurable, with a server-backed option for safe concurrent multi-user access.
  • Google Search Console / Bing integration (real ranking data).
  • Crawl cancellation from the UI.
  • Competitor comparison.

0.3.0 — 2026-07-24

The licensing release. License codes are now ed25519-signed and verified offline against a public key embedded in the app, so the binary contains no secret that could be turned into a keygen.

Upgrading: codes minted by the previous checksum scheme no longer validate. If you hold an older ELYRA-… code, get a replacement at elyracode.com/sja — the app will keep running on its trial grace period until you activate it.

Changed

  • Licenses are now ed25519-signed (issued and signed server-side by elyracode.com), replacing the offline FNV-1a checksum scheme. Codes look like SJA-<base64url(payload)>.<base64url(signature)> and carry plan, licensee and expiry claims; the app embeds only the public key, so the binary contains no secret and cannot be turned into a keygen. Expiry is enforced (exp == 0 means perpetual), issued-at is sanity-checked against the clock, and unknown payload versions fail closed. Codes are case-sensitive, so activation no longer upper-cases the input. Keys minted by the retired scheme stop validating.

Documentation

  • Licensing rewritten around the signed format: the token layout, every claim (v/id/plan/email/iat/exp, with exp = 0 meaning perpetual), how a code is accepted, and how to rotate the signing key.
  • Releasing documents publishing to elyracode.com with deploy_sja: the notarization gate, versioned filenames, the checksum sidecar, and the signed latest.json that drives the in-app updater.
  • Corrected the architecture map, which still described the retired checksum validator.

0.2.0 — 2026-07-24

A performance, security, and hardening release. No breaking changes to the user-facing workflow; the crawler is substantially faster and the AI file sandbox is now symlink-safe.

Performance

  • One shared, pooled HTTP client (src/http.rs) instead of building a new reqwest::Client (and rustls config) per request — a crawl previously paid a fresh TLS handshake for every page and every robots.txt / llms.txt probe.
  • Origin facts cached per crawl: robots.txt / llms.txt are probed once per origin instead of once per page (was 2 extra requests × every page).
  • Bounded-concurrency crawl (4 in flight, staggered starts) replaces the fully sequential loop with a fixed 250 ms sleep between pages.
  • HTML parsing moved to spawn_blocking so large DOMs no longer block the async runtime (and progress events).
  • Response bodies are capped (5 MB) and non-text content types are rejected, so a large or binary URL can't be pulled into memory and parsed as HTML.
  • list_reports no longer ships report payloads — history lists return metadata and fetch a full report on demand via get_report.
  • Database indexes on project_id (+ a partial index for unread alerts) and WAL journal mode, so monitor writes and UI reads don't block each other.
  • Release profile (lto = "thin", codegen-units = 1, strip).
  • Crawl reports slimmed over IPC: full per-page reports now live in a crawl_pages table and are fetched only when the user drills into a page, so loading a 100-page crawl no longer ships every check for every page.
  • History retention + vacuum at startup: keeps the 20 newest runs per URL and the 20 newest crawls per project past 90 days, caps alerts at 500, drops orphan page rows, and vacuums only when there is real space to reclaim.

Changed

  • Row mapping via sqlx::FromRow instead of hand-written try_get("col").unwrap_or_default() chains (~50 → 17 call sites, and the remainder are single-column RETURNING / JSON payload reads). Decoding now fails loudly on schema drift rather than silently defaulting.
    • Booleans keep an explicit conversion: SQLite stores them as INTEGER and the sqlx Any driver refuses to decode that into bool, so monitors/alerts map through private row structs with i64 flags.
    • Added an integration test that runs the migrations and exercises every list query, so a wrong column name or type fails in CI instead of at runtime.
  • main.rs split into focused modules (1460 → ~130 lines): app_paths, settings, licensing, projects, reports, trends, crawls, monitors, ai, export. Verified the registered command set is unchanged (33 commands).

Security

  • Sandbox escape via symlinks closed: the AI agent's file tools normalized paths lexically only, so a symlink inside the project could point at e.g. ~/.ssh. Paths are now canonicalized (resolving symlinks) and checked against the canonical project root.
  • PageSpeed API key moved to the Keychain, matching the AI key (it was stored in the settings JSON in SQLite).
  • Exported reports are written to an owner-only (0700) directory under Application Support instead of the shared /tmp, and pruned after a day — they can contain client data.
  • Release CI refuses to publish an unsigned update manifest if UPDATER_PRIVATE_KEY is missing (previously it emitted "signature": "").
  • Dropped the deprecated codesign --deep (single-binary app has no nested code).

Added

  • Offline test suite (16 tests) covering HTML parsing/word count, scoring and grading, recipe weighting, sitemap <loc> extraction, URL dedupe keys, robots.txt matching, crawl aggregation, license validation, and the file sandbox (including symlink escape).
  • CI workflow running cargo clippy --all-targets -D warnings + cargo test on every push and pull request.

Fixed

  • Word count no longer includes <script> / <style>, which inflated content depth and let JS-heavy pages pass the check on minified bundles.
  • robots.txt matching now supports * wildcards, $ anchors, and Allow: overrides (longest match wins), and honours Crawl-delay.
  • AI write-confirmation could hang forever: write_file awaited the UI's answer with no timeout, so a closed window left run_fix stuck and leaked the pending oneshot. Now times out after 3 minutes and cleans up.
  • Overlapping monitor ticks: the frontend timer started a new tick even if the previous one was still running (duplicate runs/alerts). Added a guard, and the interval is now cleared on destroy.
  • Crawl dedupe: post-redirect URLs weren't marked visited, so a page could be analyzed twice and skew duplicate-title detection. URL keys now also normalize directory indexes (/index.html).
  • Sitemap discovery is truncated early instead of collecting every <loc> (a sitemap can hold 50k entries) into memory.

0.1.1 — 2026-07-24

Fixed

  • App failed to launch after download: the SQLite path and migrations directory were baked in at compile time (CARGO_MANIFEST_DIR), pointing at the build machine. The database now lives in ~/Library/Application Support/Elyra Sja, and migrations are embedded in the binary and staged there at startup.

0.1.0 — 2026-07-24

First release. A standalone, local-first SEO/GEO optimization workspace built on the Elyra Framework (Rust + Svelte 5), for Apple Silicon macOS.

Added

  • Single-page analysis — fetch + parse a URL into 19 weighted, categorized checks across Meta, Structure, Social, GEO/AI, and Indexing, with an overall score (0–100) and grade.
  • Performance / Core Web Vitals — optional 6th category via Google PageSpeed Insights (LCP, CLS, TBT, FCP, performance score); opt-in in Settings.
  • Site crawl — sitemap + robots.txt discovery and internal-link BFS, with robots disallow respect, a politeness delay, broken-page detection, and duplicate title/description detection, rolled up into a site report.
  • Projects & history — projects (name, site URL, local code path) and a full analysis history stored in local SQLite.
  • Trends & comparison — score-over-time per URL with sparklines, and a run-to-run diff of fixed vs regressed checks.
  • AI fix agent — send an optimized fix prompt to your model (OpenAI / Anthropic) via elyra::ai; with a project's local path set, the agent edits the real files through sandboxed file tools, with an optional per-write confirmation dialog.
  • Fix-prompt builder — click any issue to append its context-aware, copy-paste-ready fix prompt to a prompt field.
  • Monitors & scheduling — recurring re-scans (hourly/6h/daily/weekly) that feed history and raise regression / error alerts with native notifications.
  • Client-ready PDF reports — branded, print-optimized reports for a single page and for a whole-site crawl.
  • Settings — AI provider/model + API key, PageSpeed, analysis defaults, agency branding, write-confirmation toggle, and license activation (⌘,).
  • Commercial licensing — a 3-day trial, then an offline-validated license code (issued at elyracode.com/sja). Secrets (API key, license) are stored in the macOS Keychain.
  • Auto-updater — ed25519-verified updates with a startup check and a "Check for Updates…" menu item.
  • Distribution.icns generation, DMG packaging, and a GitHub Actions release pipeline (build → sign → notarize → DMG → signed update manifest).
  • Theme — Tokyo Night palette with a Svelte-orange brand accent; dark/light/ auto.