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 Félagi Agents as teammates on one board 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

Changelog

All notable changes to this project are documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

0.9.13 - 2026-08-14

Changed

  • ⌘P is one search dialog with tabs. Files, Symbols, Actions and Text — Files by default. Tab cycles, ⇧Tab goes back, or click. Finding a file, a symbol, a command and a line of text used to be four overlays behind four shortcuts, which meant deciding what you wanted before you started typing.

  • Move a class, and everything that points at it. Refactor: Move Class… takes the active file's fully-qualified name, asks for a new one, and shows what it would do before doing it: where the file goes, and every other file whose use or fully-qualified reference changes. PSR-4 decides the destination, so App\Domain\Order lands in app/Domain/Order.php — and a namespace with no PSR-4 mapping is refused rather than written somewhere Composer will never autoload.

    Matching is whole-name: moving App\Models\Order leaves App\Models\OrderItem alone, and Legacy\App\Models\Order is a different class. Aliased imports keep their alias, and a leading \ is preserved. Renaming the class in the same move updates its declaration and self-references too, without touching a method that happens to share the name.

  • Rename asks the language server, and shows you what it will do. F2 replaced whole-word matches in the active buffer and wrote them straight in — so it renamed inside strings and comments, missed every other file, and gave you no way to check before it happened.

    It now asks the language server, which knows which occurrences are the symbol and sees the whole workspace, then lists every site as it reads now and as it will read. Nothing is written until you confirm. Open buffers are changed through the document, so the rename is undoable; the rest are written to disk.

    Where there is no language server, or it declines the rename, the old textual behaviour is still there as the fallback.

0.9.12 - 2026-08-13

Added

  • Test failures you can click. Running the suite reported an exit code and left you to find the failure by eye. Where the runner can write JUnit XML — php artisan test, Pest, PHPUnit, Vitest — the TDD panel (⌘⇧T) now lists each failure with its first assertion line, and clicking one opens the file at the failing line. The toolbar shows 12 passed · 2 failed · 1 skipped, since "the suite failed" and "two of ninety tests failed" are different news.

    Runners that can't produce a report are run exactly as before, with the plain output. Nothing is passed a flag it doesn't take.

  • Pint and PHPStan. The two tools a modern Laravel project's CI enforces, which the editor previously knew nothing about. Both are picked up from vendor/bin, so a project that doesn't use them is unaffected.

    Pint becomes the formatter for PHP where the project ships it, taking precedence over the language server — a Laravel project's formatting is whatever Pint says it is, and letting Intelephense format to its own taste only produces a diff for Pint to undo. pint.json is respected.

    PHPStan runs on save over the saved file, and its findings show up as warnings next to the language server's, each carrying the rule identifier (variable.undefined) as its code. It needs a phpstan.neon, since that is what sets the level and paths. When PHPStan itself fails — a broken config, a missing path — the error is reported rather than swallowed, because a run that never looked at your code must not read as a clean one.

Fixed

  • Step debugging now works when PHP runs in a container. The Xdebug launch config sent an empty pathMappings, so the adapter had no way to turn the /var/www/html/... paths Xdebug reports into files on disk — breakpoints simply never bound, with no error to explain why. Debugging worked for a native php artisan serve and not at all under Laravel Sail, which is how a large share of Laravel projects run.

    e now reads the project's docker-compose.yml and maps the bind mount of the project root, so a stock Sail setup needs no configuration. Named volumes and unrelated mounts are ignored, and E_PHP_PATH_MAPPINGS takes a JSON object for setups that can't be inferred. A project without a compose file gets no mapping, exactly as before.

0.9.11 - 2026-08-13

Added

  • Pull requests can carry measurement instead of description. The session review knew what changed and the runtime capture knew what a request costs; nothing joined them. Measure routes, in the ship gate next to Run tests, works out which routes the changeset actually reaches, replays each one with the change and again with your working tree stashed, and puts the result in the pull-request body:

    Route Status Time Queries N+1 Verdict
    GET /orders 200 340 → 95 ms 42 → 4 removed improved
    GET /reports 200 → 500 90 → 5 ms 4 → 0 no broke
    PATCH /orders/{order} not replayed: would write

    An N+1 you introduced, a route that started failing, and a regression are called out as plainly as a win.

    Attribution is conservative on purpose. A route is claimed only when a controller it dispatches to changed, or when a routes file changed and the diff mentions that route — editing routes/web.php does not make every route in the app suspect. Every claim carries the reason it was made, and changed files that trace to no route are counted under the table rather than dropped: measured 3 routes means something different when forty files went untraced.

    What it will not pretend to know. Write routes and routes needing URL parameters are listed but never replayed — firing a PATCH at your app would change data, and guessing a parameter would measure a 404 and call it evidence. Without Clockwork the query and N+1 columns read not visible rather than zero, because "we could not see" and "there were none" are different claims. Where the changeset carries a migration, the section says so outright: stashing restores code but not your database, so the baseline ran old code against the new schema.

    Your uncommitted work is stashed and restored around the baseline. If the restore fails e says so and tells you the work is in git stash; a clean tree is no longer mistaken for lost work. Each pass also waits out PHP's opcache, which serves the previous bytecode for a couple of seconds after a file changes — without that the baseline silently measures the code that was just stashed away, and a change that removed a 25-query N+1 reports as 4 → 4 queries, regressed.

0.9.10 - 2026-08-12

Changed

  • Large files no longer freeze while you type. Every keystroke re-parsed the whole document with tree-sitter and re-diffed it against HEAD, synchronously on the UI thread. Files over 64 KB now do that work on a worker thread, debounced, keeping the previous colours on screen until the new ones land — a brief lag instead of a stall. Below 64 KB nothing changes; it stays inline so colours never trail the caret.

    The threshold is where it is because the work cannot be made cheap enough to keep inline: of the 112 ms a 188 KB Rust file costs, the tree-sitter parse alone is 45 ms and the highlight query most of the rest. cargo test -p e-core --test highlight_cost -- --ignored reproduces the measurements.

Fixed

  • Typing could abort the editor and lose unsaved work. A selection whose offsets outlived the text they were measured against — after a reload from disk, an agent edit or an undo-tree jump — reached the rope's CRDT engine as a malformed delta and tripped an assertion. So did two selections in one edit call that overlapped each other. Both fire inside a callback that cannot unwind, so the process aborted rather than panicking, taking unsaved changes with it. This was not theoretical; it is in ~/.config/e/crash.log, reached from ordinary keystrokes.

    Edit regions are now clamped to the buffer, and a region overlapping one already applied is dropped. Both paths are reproduced and pinned by tests in the vendored fork, including a 2000-case sweep of degenerate selections.

  • Syntax highlighting cost grew with the square of the file. Merging the overlay spans (inline SQL in PHP, Tailwind classes in Blade/HTML/Vue) over the base grammar's rescanned the overlay list from the front for every base span, making it O(base × overlay) — so a PHP file four times the size cost eight times as much. The merge now seeks to the first overlay that can apply. Measured per keystroke: 312 KB of PHP 2368 ms → 778 ms, 118 KB of Blade 330 ms → 81 ms, 78 KB of PHP 288 ms → 190 ms.

  • Workspace Replace All could rewrite your dependencies. The walker behind ⌘⇧F skipped only dot-entries, target and node_modules, so a Laravel vendor/, storage/ or public/build/ was fair game — Replace All would edit Composer packages and build output. Search and replace now honour .gitignore, the global gitignore and .git/info/exclude. A vendor/ you actually track (like this repo's vendored Floem) stays searchable.

  • Search and Replace All disagreed about what matched. Search matched case-insensitively and reported only the first hit per line; replace matched case-sensitively and rewrote every occurrence. So the list you were shown and the edit you got were different sets, and the "replaced in N files" count quietly undercounted. Both now run through one walker and one matcher, and the results list shows every occurrence. A new Aa toggle in the search picker governs both at once.

  • Replace All now shows what it will do before it does it — how many matches, in how many files, which files, under which case setting — and writes nothing until you confirm. It previously wrote straight to disk with no preview and no undo.

  • Workspace search hit positions are derived from the original text rather than a lowercased copy, so the caret lands correctly on lines whose byte length changes under case folding.

  • The search query is matched literally, so $user->name() finds that text instead of being interpreted as a pattern.

  • ~/.config/e no longer fills up with dead sockets. Every editor process created an agent-<pid>.sock for the agent workspace sync and only ever removed its own on startup, so one file accumulated per launch, forever (186 of them on the machine this was found on). Stale sockets are now swept at startup. Liveness is decided by whether anything answers on the socket rather than by whether the pid is still around, since pids get recycled; sockets younger than 30 seconds are left alone so a starting editor can't be caught mid-bind.

Security

  • The agent sync socket was reachable by any local process. It was named agent-<pid>.sock in a world-listable ~/.config/e, with no authentication — so anything running on the machine could find it by globbing and call run (arbitrary shell) or tinker (arbitrary PHP). The socket name now carries 96 bits of randomness, the directory is 0700 and the socket 0600, and the path reaches agents only through $E_EDITOR_SOCK. Knowing that the editor is running is no longer enough to drive it.

    run and tinker still execute without a per-call prompt: the autonomous test-fix-rerun loop is built on them, and the fix was authenticating the channel rather than interrupting a designed workflow. The limits of that are now written down in agent-sync.md, which previously claimed "nothing is exposed".

  • Database passwords are no longer kept in a world-readable file. Passwords, SSH passwords and SSH key passphrases were serialised in plaintext into ~/.config/e/databases.json, which was created with the process umask — 0644 in practice, so any account on the machine could read them. They now go to the OS credential store (macOS Keychain; Secret Service on Linux), keyed by a stable per-connection id so renaming a connection doesn't orphan its entry. databases.json keeps only the non-secret fields and is written 0600; an existing file is tightened as soon as e reads it, not just when it next writes. Where no credential store is reachable, secrets stay in the (0600) file and e says so. Connections saved by earlier versions keep working and migrate on the next save.

    Building on Linux now needs libdbus-1-dev — see docs/installation.md.

0.9.9 - 2026-08-01

Added

  • The official Laravel language server. In a Laravel project, e now runs laravel/lsp alongside Intelephense and merges their answers — Intelephense for general PHP, laravel/lsp for framework awareness: routes, views, translations, config, environment variables, assets/Mix, middleware, Inertia, Livewire, auth/policies, container bindings and validation rules, with completions, hovers, diagnostics (an unknown route or missing view is now a squiggle) and quick fixes. Blade files get a language server for the first time.

    Install it once with composer global require laravel/lsp. If it isn't installed nothing breaks — you keep e's built-in Laravel intelligence. The new laravel_lsp setting (on by default, restart to apply) switches between the two.

  • Multiple language servers per language. The LSP client can now run several servers for one file and combine them: document sync goes to all of them, completions and code actions are merged, hover and go-to-definition take the first answer, and formatting/rename stay with the primary server.

Fixed

  • Diagnostics could be silently dropped. The bridge from the LSP reader threads kept only the last message per frame, so diagnostics published close together could go missing until the next edit. They now travel through a drained queue. (This would have become systematic with two servers publishing for the same file.)

0.9.8 - 2026-07-28

Added

Session review (⌘⌥V) grew from “read the diff” into the whole path from an agent's changes to a shipped pull request.

  • Automated review flags. e inspects the diff itself and flags what agents tend to leave behind — debug statements (dd(, console.log(), hardcoded secrets, interpolated raw SQL, destructive migration steps, .env value changes, deleted authorization checks, eval/shell_exec/unsafe {, skipped or focused tests, weakened safety checks (rejectUnauthorized: false, chmod 777), removed tests and large one-sided deletions, plus TODOs and blocking sleep(s. Findings appear as a coloured dot per file and a list above the diff, each with Ask to send it straight to the agent. Matching is call-aware, so add( isn't mistaken for dd(.
  • Ship gate. A verdict bar — Ready (all reviewed, tests green, no flags), Notes (loose ends) or Needs attention (failing tests or danger flags) — with the reasons spelled out, and Run tests to fill in the missing piece.
  • Commit & PR. Ship the reviewed changeset without leaving the editor: it creates a branch derived from what changed, commits in logical groups in dependency order (chore(deps)feat(db)chore(config)feat(routes)feat(auth)feattestdocsci) with Conventional Commits subjects, pushes, and opens a pull request via gh whose description carries the summary, the grouped file list and the review evidence (files reviewed, test result, flag counts).
  • New sync-socket method review_summary — the agent can hand back its own write-up of the session, which becomes the pull-request description.

0.9.7 - 2026-07-28

Added

  • Agent session review (⌘⌥V, or Review: Session Changes). After an agent changes a pile of files, review the whole changeset locally instead of pushing and reviewing on GitHub:

    • Risk-ranked file list — migrations, .env, config, routes, auth and dependency manifests surface first; lockfiles, tests and docs sink to the bottom. Each file shows a reason badge, A/M/D/R, and +N −M.
    • Sign-off flow with a progress counter (12/50 reviewed) and Reviewed → to tick a file and jump to the next one that needs attention.
    • Per-file actionsOpen (jumps to the first changed line), Ask why (asks the agent to explain that file's change), and Revert (deletes the file if the session created it, otherwise restores it from HEAD).
    • Summarize asks the agent to describe the whole changeset and flag anything risky.

    The session boundary is a git checkpoint taken when the agent starts. With no session recorded it reviews everything uncommitted, so it works just as well when the agent ran in an external terminal.

0.9.6 - 2026-07-24

Added

  • Selectable terminal & agent output. Drag across output in the agent panel or the integrated terminal to select it, and copy with ⌘C. A plain click still focuses the panel for typing — click again to resume after selecting. (Powered by the vendored Floem fork's selectable rich_text.)
  • Click-to-open file paths. A path, path:line or path:line:col reference in agent/terminal output is now clickable and opens that file at the line in the editor.
  • Send selection to the agent (⌘⌥S, or Agent: Send Selection to Agent in the command palette). Types a one-line reference to your current file and selected lines into the agent — without submitting — so you can add your question and let it read the exact spot.
  • “Editor integration” setting (Settings → Agents, on by default) gates the click-to-open and send-selection features.

0.9.5 - 2026-07-24

Added

  • “Verify the fix” loop in the Runtime panel. Click the ✓ on a captured request to take a baseline measurement (it checkpoints your working tree, replays the request, and records time / query count / N+1). Apply a fix (edit code or ask the agent), hit Measure again, and get a before/after verdict — Improved / No change / Regressed / Broke — then Keep the change or Discard it (which reverts to the checkpoint). Backed by the pure, unit-tested e-verify metrics + e_core::git checkpoint/restore.
  • Selectable markdown. The .md reading preview is now selectable — drag across headings, bold, inline code and links and copy (⌘C) with the formatting intact. This is powered by our vendored Floem fork (below), which adds text selection to rich text.

Changed

  • The agent panel (⌘L) uses the terminal by default for every agent, including Elyra. The native RPC-rendered chat panel from 0.9.0 wasn't interactive enough on the current text/input views, so every agent now runs in the terminal panel out of the box. The native panel is still available as an experimental, opt-in toggle — Settings → Agents → “Native Elyra chat” (off by default).
  • The agent panel opens wider⌘L now starts at 600px (still resizable from 300–900px).
  • Vendored the Floem UI toolkit into vendor/floem. e now builds against its own copy of Floem instead of a pinned git revision, so we can extend the editor/text/input views ourselves (starting with selectable rich text) rather than being limited by upstream. See vendor/floem/FORK.md.

0.9.4 - 2026-07-23

Fixed

  • “Check for updates” no longer reports “up to date” when the check actually failed. A failed request (e.g. GitHub's unauthenticated rate limit, 60/hr) was silently treated as “no update”; it now shows a distinct Couldn't check for updates notice with a Retry. The silent startup check is also throttled to once every 6 hours so frequent restarts don't exhaust the rate limit (a manual check always runs).

0.9.3 - 2026-07-23

Added

  • Recent projects on the welcome screen. The empty-state screen now lists your recently-opened projects (most-recent-first) — click one to open it — so a fresh launch from the Dock has somewhere to go, Zed-style.

Changed

  • The agent transcript is now selectable. You can drag-select and copy (⌘C) any text in an assistant reply. Block structure (heading sizes, code boxes with a Copy button, list bullets) is preserved; inline emphasis within a paragraph is rendered as plain text, since floem's selectable text is single-style. User messages and reasoning are selectable too.

0.9.2 - 2026-07-23

Fixed

  • Native agent panel did nothing when launched from Finder/Dock. The agent is now started through your login shell ($SHELL -lc), so the full PATH (nvm/npm, Grove's node, etc.) is available — a bundled .app inherits only a minimal PATH, so elyra (and the node its shebang needs) couldn't be found by a direct spawn, and prompts silently went nowhere. Your message is now also shown immediately, and a clear error appears in the panel if the agent can't be started.

0.9.1 - 2026-07-19

Fixed

  • Unsaved “untitled” tabs are no longer lost on quit. Scratch buffers with content are now saved in the workspace session (and backed up periodically while you type) and recreated as untitled tabs the next time you open the project — no more losing notes because you closed the window without saving.
  • macOS: the app now fully quits when you close the window — the process and its Dock icon no longer linger (floem defaults to don't exit on close on macOS; e is single-window, so it exits).

0.9.0 - 2026-07-19

Added

  • Native agent chat panel (⌘L). Elyra now runs headless over its structured RPC protocol (elyra --mode rpc) and the conversation is rendered with native views instead of the agent's terminal UI inside a PTY — removing the per-frame ANSI re-parse that made the panel feel laggy. It brings:
    • Streaming replies rendered as formatted markdown — headings, lists, inline code, fenced code blocks and links, with comfortable line-height.
    • Tool-call cards showing the tool, a one-line argument summary, status (running / done / error) and a compact result preview.
    • A multi-line composer that word-wraps and auto-grows with your text (up to ~7 lines, then scrolls); Enter sends, Shift+Enter inserts a newline. It is focused automatically when the panel opens.
    • A real Stop button (abort), steering while the agent is running, and New Chat.
    • Copy buttons on fenced code blocks and under each assistant message.
    • Other agents (Claude Code, Codex) keep the terminal panel. Toggle the native panel with the native_agent setting (default on).
  • e-agent crate — a small, fully-tested RPC client (a lenient JSONL protocol decoder plus a reducer that folds the event stream into a renderable conversation) that powers the native panel.
  • Crash logging. Unhandled panics are appended to ~/.config/e/crash.log (message, location and backtrace) so GUI-only crashes can be diagnosed.

0.8.3 - 2026-07-08

Fixed

  • macOS: “cannot open files in the ‘folder’ format”. The app bundle now declares that it accepts folders, so opening a folder via Open With → e (or dropping one on the icon) no longer errors. Opening folders from the CLI (e <folder>) and with ⌘O already worked.

0.8.2 - 2026-07-07

Added

  • EditorConfig support. .editorconfig is honoured per file: indent size / tab width, and trim_trailing_whitespace / insert_final_newline on save (overriding the global On-Save settings). Full glob matching (*, **, ?, {…}) with root-stop and nearest-wins resolution.
  • Compare files. Compare Active File With… (command palette) shows a line diff between the current file and any file you pick.
  • Code actions / refactor. ⌘. requests LSP code actions (quick fixes, extract variable/method, …) at the cursor or selection and applies the chosen one — where the language server supports it.

0.8.1 - 2026-07-06

Added

  • Column editing. ⌥⌘↑ / ⌥⌘↓ add a caret one line above / below at the same column, growing a vertical multi-cursor — the keyboard form of column selection. Also available from the command palette.

0.8.0 - 2026-07-04

A major expansion of the database tools — the full “PhpStorm-parity and beyond” PRD, phases 1–5. The Database panel (⌘3) is now a complete daily driver.

SQL console (phase 1)

  • Real editor with SQL syntax highlighting, schema-aware completion (tables/columns/keywords), and a draggable resize handle.
  • Multi-statement runs: ⌘↵ runs the selection or the statement under the cursor, ⌘⇧↵ (or Run) runs everything; each statement gets its own result tab (pinnable).
  • Query history persisted per project (searchable; click to reload).
  • Named parameters: :param placeholders prompt for values (remembered).
  • Cancellable runs; duration + row counts shown per run.

Safe editing (phase 2)

  • Transactional editing: cell edits and row deletes stage as pending (amber cells, red rows) with a Submit (one transaction, via a confirmation dialog) / Revert bar.
  • Environment labels (local / staging / production) with colour, on each connection and the active result.
  • Destructive-statement and non-local write confirmation dialogs.
  • Pagination with total count + jump-to-page; value viewer with JSON pretty-printing; explicit NULL handling.

Data in/out (phase 3)

  • Export results as CSV / JSON / SQL inserts; copy as TSV / Markdown.
  • CSV import into a table (header mapping, one transaction).
  • Views in the object tree; search the tree.

Power tools (phase 4)

  • EXPLAIN findings banner + EXPLAIN a query straight from the Runtime panel; agent-suggested index migrations.
  • Generate/Copy DDL; related rows via reverse foreign keys; seed rows through an Eloquent factory.

Beyond parity (phase 5)

  • Database snapshots (SQLite copy / mysqldump / pg_dump), local only.
  • Session undo-log of writes (with generated reverse statements).
  • Schema relationships (ERD) view; search a value across all tables; row counts in the tree; generate a migration scaffold from Structure.

0.7.7 - 2026-07-04

Added

  • SQL console is now a real editor. The database panel's query box is a syntax-highlighted SQL editor (multi-line, monospace) instead of a plain text input, and it's resizable — drag the handle below it for more room.
  • Schema-aware completion in the console. As you type SQL, table and column names (from the connected database) and keywords are suggested; ⌘↵ runs the console. Reuses the inline-SQL engine.

0.7.6 - 2026-07-03

Added

  • Cell value viewer. Single-click a cell in the data grid to dock a read-only inspector at the bottom of the panel showing the full value — JSON objects and arrays are pretty-printed. Double-click still edits. (PhpStorm-style.)

Fixed

  • Laravel settings tab overflowed the dialog. The content pane sized itself to its widest row, pushing toggles and the App URL field off the right edge with a horizontal scrollbar; the pane is now pinned to the dialog width.

0.7.5 - 2026-07-03

Fixed

  • Keyboard navigation in the completion popup didn't work. Up/Down to move the selection and Enter/Tab to accept were silently ignored, so completions (Flux UI, Livewire, Laravel, LSP, …) could only be taken with the mouse. The handler was registered through the editor builder's .pre_command(), which only attaches to a plain TextDocument; because the editor uses a custom document wrapper for inlay hints and ghost text, the registration was dropped on the floor. It's now registered directly on the backing document, so the arrow keys and Enter/Tab drive the popup again — fingers stay on the keyboard.

0.7.4 - 2026-07-03

Added

  • Click to accept a completion. Completion suggestions can now be inserted with the mouse — click a row to select and apply it (previously only Enter/Tab worked). Combined with the 0.7.3 crash fix, accepting a suggestion (including Flux UI / Livewire / framework completions) now works reliably.

0.7.3 - 2026-07-03

Fixed

  • Crash when editing (pressing Enter, etc.). Recording an edit into the undo tree held a mutable borrow while bumping the revision counter, whose effect synchronously re-read the same undo tree — a double borrow that aborted the app (“e quit unexpectedly”). The borrow is now released before the update.

0.7.2 - 2026-07-03

Fixed

  • Command palette showed stale results. The results list keyed its rows on position alone, so as you typed, floem reused the view at each slot and left the previous labels in place (e.g. typing “che” listed unrelated commands and hid “Check for Updates”). Rows are now keyed on the command identity, so the list rebuilds correctly as the filter narrows.

Added

  • Delete rows & foreign-key hopping. The cell edit dialog now has a Delete row action (honouring the read-only guard and requiring a primary key) and a Follow FK → action that jumps to the referenced table filtered to the linked value. Backed by new tested e-db primitives insert_row, delete_row (with an empty-predicate guard so it can never wipe a table), fk_target and rows_where.
  • Column filters. Filter to value in the cell dialog restricts the data view to rows matching that cell (WHERE col = value / IS NULL), composing with sort and pagination. An active filter shows as a chip in the toolbar — click it to clear.
  • Insert rows. A + Row button on the data toolbar opens a dialog with one field per column (each with a NULL toggle). Blank, non-NULL columns are omitted so database defaults / auto-increment apply. Honours the read-only guard.

0.7.1 - 2026-07-03

Added

  • EXPLAIN + agent index suggestions. With the cursor in a SQL string, Explain SQL Under Cursor (⌥⌘⏎) runs the engine's EXPLAIN, shows the plan in the result panel, and flags full table scans / missing indexes. Suggest Index for SQL Under Cursor then hands the query + findings to the AI agent, which proposes a Laravel migration adding the index — EXPLAIN → diagnosis → ready-made migration in one flow (MySQL, PostgreSQL, SQLite).

  • Index view. The Structure tab now lists a table's indexes (name, unique vs plain, and the columns each covers) below its columns — for MySQL, PostgreSQL and SQLite. Useful for spotting missing indexes behind slow queries.

  • Database write protection. Connections that look like production (SSH tunnels, non-local hosts, or names containing prod/production/live) default to read-only, and cell edits to a read-only connection are blocked with a warning — guarding against accidental writes to a real server over an SSH tunnel. A lock badge (🔒/🔓) on each connection shows and toggles the state.

  • Inline SQL intelligence. Raw SQL inside PHP (DB::select("…"), ->whereRaw('…'), migrations' DB::statement("…"), …) is no longer a dead string:

    • Syntax highlighting via the tree-sitter SQL grammar (detected from the PHP parse tree; double- and single-quoted; plain strings untouched).
    • Schema-aware completion — typing inside the SQL string suggests table names after FROM/JOIN/UPDATE/INTO and column names elsewhere, from the live database schema cache.
    • Run the query under the cursor with ⌘⏎ (or “Database: Run SQL Under Cursor”): executes it against a connected database and shows the results in the DB result panel.

    Highlighting + schema validation + one-key execution in the same editor — without a separate database tool.

Fixed

  • Command palette (⌘⇧P) now actually filters as you type. The real cause wasn't just a stale query (0.7.0) — its query/selection lived on AppState (a different reactive scope), so the text_input and the results list didn't stay in sync and the list stayed on the unfiltered set. The palette now uses view-local signals like the file finder, so typing filters live.

0.7.0 - 2026-07-03

Fixed

  • Command palette (⌘⇧P) felt unresponsive. It didn't clear the previous query on open, so new keystrokes appended to a stale search (e.g. che became <old>che) and matched nothing. It now starts fresh every time — typing filters immediately.

Changed

  • Reopen the last project. Launching e with no path (double-click, Dock, bare e) now reopens the project you last had open instead of the current directory.

Added

  • Inline AI completion (“ghost text”). After a short idle in a code file, e asks a local Ollama code model (fill-in-the-middle) for a one-line continuation and shows it as grey text at the cursor; Tab accepts it, typing or Esc dismisses it. Entirely local and opt-in — enable it in Settings → Editor (ai_completion), with the model set via E_COMPLETION_MODEL (default qwen2.5-coder). Requests are debounced and never block the editor; nothing runs unless it's enabled and Ollama is reachable.

0.6.9 - 2026-07-03

Added

  • Linux releases. Each release now publishes Linux binaries (e-x86_64-unknown-linux-gnu.tar.gz and e-aarch64-unknown-linux-gnu.tar.gz) alongside the macOS builds, so the in-app auto-updater works on Linux too. A Linux build+test job was added to CI to catch platform breakage early. See installation for the system libraries needed.

0.6.8 - 2026-07-03

Fixed

  • Silent write failures are now surfaced. A failed disk write during a Livewire property rename or an applied agent edit (full/read-only disk) used to report success anyway — risking a class and its view drifting out of sync. Writes now notify on failure and only report success when the change landed; agent edits reply ok: false instead of claiming success.
  • Database lock hardening. A poisoned connection mutex in e-db (a thread panicking while holding the lock) no longer crashes the whole editor — the guard is recovered and the query returns normally or errors cleanly.

Changed

  • Modal overlay panels are registered as one (open-signal, view) list, so the "is anything open?" guard is derived automatically. Adding a panel is a single line and can no longer desync the two lists — the bug class behind the 0.6.5/0.6.6 unclickable-window regressions.

Internal

  • Split the state.rs god-module: cohesive feature clusters now live in their own files (runtime.rs, db_state.rs, terminal_state.rs, laravel_state.rs, completion_state.rs, navigation.rs, tdd_state.rs), each extending AppState from its own module. Pure moves, no behaviour change; state.rs is down ~2,245 lines (6,599 → 4,354, −34%), leaving mostly irreducible core state (the constructor, buffers, LSP, save/format, diagnostics, cursor, tabs). A new AppState::spawn_bg helper centralises the background-work + UI-marshal boilerplate.

  • A CI “Parser corpus” job runs the heuristic parsers (routes/views, Eloquent relationship + event graphs, Livewire/Inertia props) over real Laravel projects (laravel, pingcrm, livewire, laravel-permission), asserting “no panic, sane counts” — catching wild-PHP edge cases the happy-path unit tests miss.

  • macOS: "e cannot open files of this type". Opening a file via Finder ("Open With → e", double-click, or the Dock) no longer fails — the app bundle now declares e as a text editor for all file types, so .sql, .env, .log and anything else are accepted. Files already opened fine by dragging onto the window, via ⌘O, or e <file> from the CLI; this removes the OS rejection for the Finder path. (Rebuild the app / install the next release; macOS may take a moment to refresh its file associations.)

0.6.7 - 2026-07-03

Added

  • e-dap crate — a synchronous Debug Adapter Protocol client (sibling to e-lsp, same architecture: protocol client in its own crate, background reader thread, id-correlated blocking requests). Reuses the identical Content-Length stdio framing but dispatches on DAP's request/response/ event shape, correlates responses by request_seq, delivers adapter events to a handler, and answers reverse requests. Typed helpers cover the full step-debugging flow: initialize, launch/attach, setBreakpoints, configurationDone, step controls, threads/stackTrace/scopes/ variables, and evaluate. This is the editor half of native debugging; paired with Grove's grove debug on, PHP/Xdebug works, and JS (js-debug) / Rust (codelldb) come nearly free since the client is adapter-agnostic.
  • Debug panel + step-debugging in the UI. A new Debug overlay shows session status, execution controls (start/continue, step over/into/out, stop), the live call stack (click a frame to jump to source), current-frame variables, and all breakpoints. Breakpoints show as a red dot in the editor margin, and the line execution is paused on is highlighted; stopping auto-jumps to it. Keybindings: F5 start/continue, F9 toggle breakpoint on the caret line, F10 step over, F11 step into, ⇧F11 step out; all also in the command palette (“Debug: …”). The adapter (vscode-php-debug) is launched over Grove's bundled Node automatically (discovered from Grove's node-builds.json, falling back to node on PATH); the adapter path is auto-detected from installed VS Code/Cursor extensions or E_PHP_DEBUG_ADAPTER. Pair with grove debug on and step-debugging PHP works end to end.
  • Multi-language debugging. e-dap now speaks DAP over TCP as well as stdio, so beyond PHP (Xdebug) the debugger also drives JavaScript/TypeScript via vscode-js-debug and Rust/C/C++ via codelldb (both DAP servers). The adapter is chosen from the active file's language and auto-discovered from installed VS Code/Cursor extensions (overridable via E_JS_DEBUG_ADAPTER, E_CODELLDB, E_DEBUG_PROGRAM).
  • Alt-click in the editor toggles a breakpoint on the clicked line (Floem's built-in gutter isn't clickable), and breakpoints set before a file is opened now appear when it opens.
  • Settings: Enable Xdebug (Settings → Laravel, xdebug in config.json) — toggling it runs grove debug on/off so you can start step-debugging without the terminal. On startup the toggle is synced from Grove's real state (grove debug status). Degrades gracefully when Grove isn't installed.

Fixed

  • Debugging is fully opt-in and never affects the editor when Grove/Xdebug or a DAP adapter aren't installed: the adapter is now launched entirely off the UI thread, so a missing or slow adapter (including the TCP connect for JS/Rust) can't freeze the editor, and missing tools report a clear status instead.

0.6.6 - 2026-07-02

Fixed

  • The file explorer and editor were unclickable: an overlay group wrapper introduced in 0.6.5 covered the whole window and swallowed every click. It now only covers the window when one of its panels is open.
  • ⌘P now finds hidden files (.env, .gitignore, …); they were excluded from the file index.

0.6.5 - 2026-07-02

Added

  • Query-builder completion: column names inside where(), orderBy(), select(), pluck(), value(), groupBy(), … and relationship names inside with(), load(), whereHas(), resolved from the model/table and the live schema. Unknown columns are flagged inline (Column emial not found in table users) — something PhpStorm can't do without the database.
  • Related files (⌘⌥E): jump between the model, migration(s), factory, seeder, controller, policy, request, resource, and test for the same resource.
  • Validation intelligence: completion for rule names in validate([…]) / FormRequest rules(), plus a command to generate rules from a table's live schema (nullability, string lengths, types).
  • Gates & policies: completion and go-to-definition for abilities in can(), authorize(), @can, and Gate::allows() → the policy method.
  • Generate model from table: builds an Eloquent model from the live schema — fillable, casts, and relationships inferred from the actual foreign keys.
  • Event dispatch graph (⌘⌥G): events → listeners (from $listen, Event::listen, and auto-discovered handle() types), with F12 on a dispatched event jumping to a listener.

Changed

  • The file explorer now shows hidden files (.env, .gitignore, .github, …). Only .git, node_modules, and target are hidden.

0.6.4 - 2026-07-02

Added

  • Inertia awareness. Inertia::render('Users/Index') now resolves like view(): go-to-definition and completion reach the page component under resources/js/Pages, and the architecture map goes route → controller → page component instead of stopping at the controller.
  • Props contract (⌘⌥C): reconciles a page component with the controller that renders it — infers TypeScript types from the render call (User::paginate()User[], fields from the live schema), flags props sent but unused and props used but never sent, and generates TypeScript interfaces expanded from the real database schema. Also reconciles useForm fields against the matching FormRequest's validation rules.
  • Ziggy route intelligence on the JS side: route('name') in JS/TS/Vue/Svelte gets completion, hover, and go-to-definition from the same Laravel route table the PHP side uses.
  • Shared props: HandleInertiaRequests::share() is parsed so $page.props.auth.user and friends complete everywhere.
  • Inertia-aware request replay: the replay renders an Inertia response as an explorable props tree (with the component name, click to open) instead of raw HTML.
  • Livewire refactoring: wire:model completes from the component class's public properties, ⌘⌥J switches between the view and class, F12 on a property jumps to its declaration, and renaming a property (F2) updates both the class and every wire: reference in the view.
  • Runtime insight (⌘⌥I): a continuous Telescope-style panel that captures every request against the dev app via Clockwork — queries with N+1 warnings, cache hits/misses, mails, and events — with "Explain with agent" one click away. No Telescope or Debugbar needed.

0.6.3 - 2026-07-02

Added

  • Eloquent relationship graph (⌘⌥R): parses hasMany/belongsTo/ belongsToMany/morph* from your models and cross-checks them against the live database's foreign keys — flagging relations that exist in code but have no backing FK. Together with the schema diff it shows code, migrations, and the actual database in one picture.
  • Security lens on the architecture map (⌘⌥M): each route shows its middleware and a 🔒 / ⚠ badge; state-changing routes with no authentication are flagged, and one click asks the agent to suggest protection.
  • Generate a Pest test from a request replay: the 🧪 button writes a feature test with the path, status, and assertions derived from the actual response, ready for the ⌘⇧T "fix to green" loop.

0.6.2 - 2026-07-02

Changed

  • Redesigned the settings dialog (⌘,) into a two-pane layout: a category sidebar plus a search box that filters settings across every category, with hairline row dividers, per-row "restart" badges, and an "Open config.json" footer link. Close with Esc or the ✕.
  • The command palette (⌘⇧P) now uses fuzzy, ranked matching instead of a plain substring filter — typing up surfaces "Check for Updates" and "Move Line Up" first, and the selection resets to the best match as you type.

0.6.1 - 2026-07-02

Added

  • Semantic search (⌘⌥K): a "describe what you're looking for" mode that ranks project locations by meaning. Runs locally — uses a local Ollama embedding model when available, with a lexical fallback otherwise.
  • Visual undo tree (⌘⌥U): a branching history that preserves edits a linear undo would discard, with click-to-jump time travel persisted across sessions.

Changed

  • Release builds are now signed with a Developer ID and notarized by Apple, so the DMG opens without Gatekeeper warnings. CI signs automatically when the signing secrets are configured (see docs/installation.md).
  • Added the missing ⌘3 (Toggle database) shortcut to the welcome screen.

0.6.0 - 2026-07-02

Added

  • Schema diff (command palette): compares migrations against the live database and flags columns present in one but not the other.
  • Eloquent completion from the live database schema: typing $model-> suggests the real table columns (inferred model → table), merged with the language server.
  • Live laravel.log panel (⌘⌥L): tails the log with coloured levels, clickable stack frames, and a "Fix with AI" action.
  • Request-replay from the architecture map (⌘⌥M): a ▶ button on GET routes hits the running app (Grove https://<folder>.test by default, configurable via the App URL setting) and shows the response plus the SQL queries it ran (via Clockwork) with N+1 detection and "Explain with agent".
  • Autonomous TDD panel (⌘⇧T): run the test suite with pass/fail status, and a "Fix to green" loop where failures are sent to the agent, its proposed edits are reviewed, and tests re-run automatically until green (with an iteration cap and Stop).
  • Agent propose_edit: agents propose a new file version and you review it hunk-by-hunk (accept/reject each change) before applying — no blind writes.
  • Agent timeline (⌘⌥A): an audit log of everything the agent does over the socket, and a 🤖 marker in the status bar showing where the agent is looking.

0.5.1 - 2026-07-01

Changed

  • The welcome screen shows a minimalist, transparent app glyph instead of the boxed icon.
  • The Settings dialog (⌘,) has consistent row spacing and a darker backdrop.
  • The macOS "About e" menu-bar panel now shows the app icon, version, tagline and links (matching the ⌘⇧P About box's content).

0.5.0 - 2026-07-01

Added

  • Agent co-op over the sync socket: lsp_definition/lsp_references/lsp_hover/ lsp_symbols (reuse the running language server), db_schema (read the connected database's schema without exposing credentials), db_query (agent-proposed queries run only after you approve them in a consent dialog), run and tinker (execute commands/PHP and capture the output — the basis for autonomous TDD).
  • "Explain with agent" on failed database queries, and a "Fix with AI agent" action on problems, both prompt the agent panel directly.
  • Laravel Tinker scratchpad (⌘⌥T): run PHP against the app and see the output; "Tinker: Run Selection" evaluates the current selection.
  • Laravel architecture map (⌘⌥M): an interactive route → controller → view flow with clickable cards that jump to the code.

Changed

  • The app icon now appears in the About dialog and the welcome screen, and the bundle icon was refreshed.

0.4.9 - 2026-06-29

Added

  • AI Agent Workspace Sync: the editor exposes a local socket ($E_EDITOR_SOCK) so a CLI agent can read editor context (current file, cursor, selection, diagnostics) and drive the editor (open a file at a line, focus a panel, notify). See agent-sync.md.

0.4.8 - 2026-06-29

Added

  • Terminal scrollback (5000 lines): scroll up with the mouse wheel to review earlier output; the view stays anchored while output streams and snaps back to the bottom when you type.
  • Terminal background colours (SGR 40–47/100–107 and 256/true-colour) — git diff, coloured errors and search tools keep their highlighting.

Changed

  • SSH passwords are no longer written to disk: the askpass helper reads the secret from an environment variable that only lives in memory.
  • External-change file polling runs off the UI thread, so the editor never stalls on slow or network filesystems.
  • External reloads honour the file's detected encoding (UTF-16/Windows-1252).

Fixed

  • Language servers now shut down gracefully (shutdown + exit) and their stderr is logged instead of discarded, making LSP issues diagnosable.

0.4.7 - 2026-06-29

Added

  • The terminal panel (⌘T) is now drag-resizable in height — drag the handle along its top edge.

Fixed

  • The agent panel (⌘L) could not find CLI agents installed via nvm (command not found) when the app was launched from Finder; agents now run through an interactive login shell so .zshrc/.bashrc PATH is available.

0.4.6 - 2026-06-29

Added

  • Source Control: a ✨ button suggests a Conventional Commits message (type, scope and changed files) generated from your staged changes.

Changed

  • Project links now point to elyracode.com (About dialog, README docs link and Cargo metadata).

0.4.5 - 2026-06-28

Added

  • Tailwind CSS highlighting inside class="…" attributes (Blade, HTML, Vue): utility classes, variant prefixes (sm:, dark:, hover:) and arbitrary values (w-[680px]) are coloured distinctly.

0.4.4 - 2026-06-28

Changed

  • Blade syntax highlighting now colours Blade directives, {{ }}/{!! !!} expressions, {{-- comments --}} and the embedded PHP inside @php blocks and echoes — in addition to HTML, attributes and Tailwind classes.

0.4.3 - 2026-06-28

Changed

  • The ⌘P file finder now uses ranked fuzzy matching (file-name and short-path matches rank highest, e.g. wbp finds welcome.blade.php) and builds its index in the background, so it opens instantly even on very large folders.

0.4.2 - 2026-06-28

Added

  • Emmet abbreviation expansion (Tab) in HTML, Blade, Vue, Svelte and PHP: tags, classes, ids, attributes, text, nesting, grouping, multiplication and $ numbering.

Fixed

  • ⌘W / Esc now close the database results overlay (and the cell-edit popup).

0.4.1 - 2026-06-28

Added

  • Database: inline cell editing (double-click a cell in a table with a primary key), saved queries (per project), ClickHouse support (HTTP interface), and SSH tunnels for remote databases.

Changed

  • New application icon.

0.4.0 - 2026-06-28

Added

  • Database panel (⌘3): browse and query MySQL/MariaDB, PostgreSQL and SQLite databases. Connect from the project's .env or manually (with a Test button), browse tables with sortable columns, paging, a Data/Structure view and CSV export, and run SQL in a results grid (⌘↵ to run, horizontal scroll and arrow keys to pan). Right by default; configurable left.
  • Laravel features on par with the official VS Code extension: completion, hover and go-to-definition for route(), view(), config(), env(), __()/trans() and <x-...> Blade components, sourced from your project via php artisan. Auto-enabled in Laravel projects; toggle under Settings → Laravel features.

0.3.3 - 2026-06-28

Added

  • Line-ending conversion: click LF/CRLF in the status bar to convert the buffer.
  • Non-UTF-8 files now open (BOM detection + Windows-1252 fallback); the detected encoding is shown in the status bar and preserved on save.

Changed

  • Large files (>1MB) skip tree-sitter highlighting, git markers, blame, inlay hints and bracket matching to stay responsive.

0.3.2 - 2026-06-28

Added

  • Multi-root workspaces: "Add Folder to Workspace" adds more root folders; the explorer, file finder and search span them all.
  • Drag & drop files from Finder into the window to open them (folders open in a new window).
  • Select all occurrences of the word/selection (⌘⇧L).

0.3.1 - 2026-06-28

Added

  • Task runner (⌘⇧B): detects npm/yarn/pnpm/bun, Composer, Cargo, Go, Laravel artisan, Pest/PHPUnit and Makefile tasks and runs the chosen one in a named terminal. "Run Tests" runs the project's test command.
  • Customizable keybindings: every action is a named command, rebindable in the keybindings section of config.json.
  • Graphical settings page (⌘,): toggles and steppers for the common options, applied live and persisted to config.json. The raw JSON is still available via "Open Settings (config.json)".

0.3.0 - 2026-06-27

Added

  • Inlay hints: inline type and parameter-name hints from the language server, shown as dimmed phantom text. Configurable via inlay_hints.
  • Sticky scroll: the enclosing scope lines stay pinned at the top of the editor as you scroll (indentation-based). Configurable via sticky_scroll.
  • Workspace replace: the search panel (⌘⇧F) now has a Replace row and "Replace All".
  • Source Control: branch switcher (click the branch name), recent-commit history, and stash (Stash / Pop).
  • Editor tabs: drag to reorder, and right-click to pin (with Close Others).
  • User-defined snippets in the snippets section of config.json.

0.2.6 - 2026-06-27

Fixed

  • After an in-place auto-update, the bundle Info.plist version is rewritten so the macOS About panel shows the correct version (previously stale).
  • Dev/bundle scripts now stamp the real version from Cargo.toml into Info.plist.

0.2.5 - 2026-06-27

Fixed

  • Clicking a command/file in the ⌘P, ⌘⇧P, ⌘T and ⌘E palettes now runs the selection instead of just closing the palette (the close-on-blur fired before the click registered).
  • The update notice's "What's new" changelog now wraps properly and strips markdown noise, instead of overflowing horizontally.

0.2.4 - 2026-06-27

Added

  • macOS DMG installer (scripts/bundle-dmg.sh, also built per release) — drag e.app into Applications. Supports universal (arm64 + x86_64) builds and optional Developer ID signing/notarization.
  • "Install 'e' Command in PATH" command (⌘⇧P) — symlinks e into /usr/local/bin so you can launch the editor from any directory with e ..

0.2.3 - 2026-06-27

Added

  • Framework-aware completion: Flux UI components (<flux:…>), Livewire wire: directives, Tailwind utility classes (inside class="…"), and Vue/Svelte directives.
  • File-type icons in the explorer, per language/extension, with open/closed folder icons.

Fixed

  • Accepting a completion now places the caret at the end of the inserted text instead of in the middle (affected framework and LSP completions alike).

0.2.2 - 2026-06-27

Added

  • Configurable panel layout: sidebar_side and agent_side in settings move the explorer/Git sidebar and agent panel to the left or right (default: sidebar left, agent right).

Fixed

  • The quick-open palettes (⌘P, ⌘⇧P, ⌘T, ⌘E) no longer stretch to the full window height — they size to their contents.
  • Typing in a palette now reliably reaches its input: the editor no longer steals keyboard focus while a palette or dialog is open (it re-focuses on close).

0.2.1 - 2026-06-27

Added

  • Built-in completion that works with or without a language server: language keywords, identifiers already in the file, and — for PHP/Blade — Laravel facades and Blade directives. Merged with LSP and snippet suggestions.
  • New file (⌘N) creates an untitled buffer; Save As… (⌘⇧S) writes it to disk and reopens it with full language, LSP, and git support.
  • Complete user documentation in docs/ (installation, editing, navigation, languages, Laravel, source control, terminal, agents, configuration, updating, and troubleshooting).

Changed

  • The editor now takes keyboard focus automatically when a buffer becomes active (new file, opening a file, switching tabs), so you can type immediately without clicking into it first.

0.2.0 - 2026-06-27

Added

  • Git blame for the current line shown in the status bar.
  • Merge-conflict resolution bar: accept current, incoming, or both sides when the caret is inside a conflict block.
  • Open dialogs: ⌘O opens a native folder picker to open another project in a new window; an "Open File…" command opens any file in the current window.
  • Source Control panel (⌘2): branch display, staged / unstaged / untracked file groups with stage, unstage, discard and stage-all; commit, push and pull.
  • Editor zoom (⌘= / ⌘- / ⌘0) and a soft word-wrap toggle (⌥Z).
  • Navigation history: go back (⌃-) and forward (⌃⇧-) across jumps.
  • Richer status bar: git branch, line ending (LF/CRLF), indentation and encoding.
  • Recent-files quick switcher (⌘E): a most-recently-used list of files opened this session, newest first, with arrow-key navigation.
  • Built-in auto-updater: checks GitHub for newer releases on startup, shows the changelog in a notice, and installs the update in place on confirmation. Manual check available via the command palette ("Check for Updates").
  • Release workflow that publishes per-platform binary assets for each tag.
  • Find & Replace: replace and replace-all in the active file, with case-sensitive, whole-word and regex toggles (⌥⌘F).
  • Editing essentials: toggle line comment (⌘/), go to line (⌃G), move line up/down (⌥↑/↓), duplicate line (⇧⌥↓), delete line (⌘⇧K), and indent/outdent (⌘] / ⌘[).
  • Auto-closing brackets and quotes (with type-over and pair-aware backspace) and auto-indent on newline. Configurable via auto_close.
  • Unsaved-changes confirmation when closing a tab.
  • External file-change detection: clean buffers reload automatically; buffers with unsaved edits show a reload/keep prompt.

0.1.0 - 2026-06-27

Added

  • Tree-sitter syntax highlighting for Rust, Python, JavaScript, TypeScript, Go, C/C++, JSON, PHP, HTML, CSS, Blade, Vue and Svelte.
  • Language Server Protocol client with diagnostics, completion, hover, go-to-definition, find references, document & workspace symbols, formatting, rename, code actions and signature help; per-language servers auto-selected.
  • Laravel-aware completion for route(), view(), config() and env().
  • Fuzzy file finder (⌘P) and command palette (⌘⇧P).
  • Workspace search (⌘⇧F) and find-in-file (⌘F).
  • Integrated PTY terminal with ANSI colour, multiple tabs, rename and split.
  • AI agent panel (⌘L) running configurable CLI agents (Elyra, Claude Code, Codex), with an agent selector and global settings.
  • Split editor, resizable panels (drag), multi-cursor (⌘D).
  • Git change gutter and inline diff vs HEAD.
  • Inline diagnostics, bracket matching, snippets, breadcrumbs.
  • Markdown preview (⌘⇧M).
  • Light/dark themes (F8), auto-save, format & trim on save.
  • Session persistence per workspace and a workspace-wide problems panel.