Skip to content

Latest commit

 

History

History
51 lines (43 loc) · 15 KB

File metadata and controls

51 lines (43 loc) · 15 KB

Changelog

Unreleased

  • Bugfix: eca-chat-resume no longer silently no-ops when the picker is shown from a fresh welcome buffer. Filter out chats the server can't open (id is nil, which happens for legacy DB rows that pre-date the per-chat :id field) so they aren't offered, and surface a user-error when chat/open reports :found? false or no buffer was registered for the chat-id, instead of falling through the when-let*.

  • Add eca-chat-resume command to pick and resume a past chat via completing-read annotated with model, message count and relative update time. A Resume a previous session link in the welcome area triggers it, and e selects it in the transient menu. The originating empty welcome buffer is killed once the resumed chat is in place, so no stray tab is left behind.

  • Bugfix: avoid (wrong-number-of-arguments color-rgb-to-hsl 0) crash on chat startup in a no-window/TTY Emacs. face-background returns the literal sentinel "unspecified-bg" (not nil) on non-graphic frames, which was fed into color-lighten-name / color-darken-name from eca-chat--update-expandable-block-faces and eca-table-update-faces. New eca-safe-face-background helper in eca-util.el normalizes the "unspecified-bg" / "unspecified-fg" sentinels to nil so the when-let* guards short-circuit and the faces remain at their default appearance on TTY. #244

  • Add inline [+ Add MCP server] form and per-row remove button (with two-step inline confirmation) on the MCPs settings tab. Handles the new tool/serverRemoved notification so the UI updates live without a server restart.

  • eca-doctor now emits a ### Self-check section probing whether the loaded code carries the chat-RET expand fix: eca-chat-mode-map RET still points at eca-chat--key-pressed-return, eca-chat--key-pressed-return references the expandable clause before the markdown-link clause, the nearest expandable block label has RET bound in its text-property keymap, and the loaded eca-chat-expandable file's path (with a stale-.elc warning when the on-disk .el is newer). Each failing probe pushes a targeted hint pointing at commit dac33d8 and the appropriate remediation (pull master, restart Emacs, M-x byte-recompile-directory, or start a new chat so blocks get the new label keymap).

  • Bugfix: restore RET expanding/collapsing > blocks in the chat. The recent markdown-link-on-RET clause was intercepting the toggle when the label text was fontified as a link; the expandable check now runs before the link follow, and the label's text-property keymap also binds RET so it works in evil normal state without evil-collection wiring.

  • Add eca-doctor command that prints a markdown-formatted diagnostic report to *eca-doctor* for bug reports: a ## Versions section (same as eca-version) plus a ## Chat section sourced from the active session's auto-detected chat buffer. #242

  • Bugfix: stop the merged worktree fallback in eca-session from auto-adding an unrelated ancestor (typically $HOME) as a second workspace folder. The fallback previously declared two paths to be the "same repo" purely on git rev-parse --git-common-dir equality, which is also true for any subdirectory of a git-tracked HOME (yadm/chezmoi/git init ~); a buffer whose default-directory is ~ (e.g. the doom scratch buffer) would then trigger workspace/didChangeWorkspaceFolders and append ~ to the session created with C-u M-x eca on ~/.config/eca, showing both roots in the chat modeline. The match in eca--session-for-worktree now additionally requires that ROOT and the candidate folder are not in an ancestor/descendant relationship (real worktrees are always sibling directories, never nested), via the new eca--paths-nested-p helper. True sibling worktrees continue to merge as before. #238

  • Generate chatId client-side at chat-buffer creation. #231

  • Scope model/agent/variant selection to the active chat: eca-chat-select-model, eca-chat-select-variant and eca-chat--set-agent now write the local change to the chat buffer the user is interacting with (current buffer when invoked from inside a chat, falling back to the session's last chat) and include :chatId in the resulting chat/selectedModelChanged / chat/selectedAgentChanged notification. eca-chat-config-updated honors the new chatId field on config/updated: when present, per-chat fields (selectModel, selectAgent, selectVariant, selectTrust) apply only to that chat's buffer; when absent, the legacy session-wide path applies to every chat (still used for the initial config/updated after initialize). Fixes a long-standing leak where changing the model in one chat would silently overwrite another chat's display. #231

  • Add eca-process-wrapper-function, an optional function called with the resolved server command and the list of workspace folder paths just before make-process is invoked. It must return a (possibly transformed) command list, letting users run the eca server inside any command-prefix-style sandbox (firejail, bubblewrap, jai, docker, ...) directly from elisp — without a separate launcher script and with the workspace roots dynamically injected into the sandbox's directory whitelist. New "Sandboxing" section in the README documents the recommended pattern with jai and firejail examples.

  • Expand the eca-send-process-id docstring to explicitly cover sandbox tools that hide or remap the host PID (firejail, bubblewrap, jai, containers): in those setups the server's parent-process watchdog would otherwise see an invalid PID and shut down right after startup, so the variable must be set to nil. Cross-references eca-process-wrapper-function.

  • Bugfix: avoid void-function flymake-diagnostic-code errors in eca-editor--flymake-diagnostics (which surfaced as a 30s Timeout waiting for editor diagnostics response on editor/getDiagnostics whenever any flymake diagnostic was processed) by fboundp-guarding the flymake-diagnostic-code accessor; :code is simply omitted when the accessor isn't shipped with the running Emacs's flymake. The existing declare-function is preserved so the byte-compiler stays quiet on Emacsen that do expose it. #228

  • Hide the [-] (remove workspace) mode-line button when only a single workspace folder is active in the session, since removing the last workspace is disallowed anyway; the [+] (add workspace) button is still always shown. The button reappears automatically as soon as a second workspace is added.

  • Stop the CPU peg when watching a long uncollapsed write-tool argument body stream in (#234). The dominant cost was gfm-mode's markdown matchers (markdown-match-italic / markdown-match-bold / markdown-match-code) re-fontifying the whole growing body on every chunk, because toolCallPrepare updates go through eca-chat--update-expandable-content's delete-region + reinsert branch (which marks the entire body as needing fontification and lets jit-lock then run the matchers over it on the next redisplay). Introduce a buffer-local custom font-lock-fontify-region-function (eca-chat--fontify-region) that walks the requested region in eca-no-fontify text-property runs and only delegates the un-tagged sub-ranges to font-lock-default-fontify-region; tagged sub-ranges are skipped entirely, so jit-lock has nothing to do on them. The toolCallPrepare arm now tags the streaming body with eca-no-fontify at the source string, which travels naturally through (propertize content 'line-prefix ...) inside eca-chat--update-expandable-content and through the toggle-open path's eca-chat--insert, so every code path that lands the body in the buffer carries the tag. Cleanup is automatic: when toolCalled arrives it reinserts un-tagged final content via the same delete-region + reinsert path, after-change-functions clear fontified, and jit-lock then refontifies normally on the next redisplay (no manual font-lock-flush needed). Measured via a new tool-prep-stream-{skip,full} benchmark in benchmarks/eca-chat-bench.el (synchronous fontify per chunk to simulate jit-lock under --batch): at body 1000/5000/20000 chars, per-chunk cost drops from ~4.5ms / ~62ms / ~908ms to ~173µs / ~144µs / ~225µs respectively (26× / 432× / 4030×). The post-fix path is FLAT in body size (only the existing buffer churn remains), and the 20000-char run drops from 265 GCs to 0.

  • Make long chats fast again. Replaced linear (overlays-in (point-min) (point-max)) scans in singleton-overlay accessors and the expandable-block id lookup with O(1) buffer-local caches (a per-overlay slot for the chat singletons; a per-buffer hash table for expandable blocks). Region-scoped the per-turn font-lock-ensure and end-of-stream eca-chat--align-tables / eca-chat--beautify-tables to start at eca-chat--last-user-message-pos instead of point-min, so cost is bounded by the current turn rather than the full chat history. Measured on a synthetic 500-turn fixture (benchmarks/eca-chat-bench.el): per-streamed-chunk insert dropped from ~426µs to ~6µs (71×), expandable-id lookup from ~324µs to ~0.4µs (790×), and the end-of-stream finalize block from ~2.6s to ~9ms (274×).

  • Add benchmarks/eca-chat-bench.el, a chat-rendering benchmark harness runnable via M-x eca-chat-bench-run or eask emacs --batch -l benchmarks/eca-chat-bench.el -f eca-chat-bench-run. Builds synthetic chat buffers of varying size and times the streaming hot paths (insertion-point lookup, streamed chunk insert, expandable lookup/update, end-of-stream finalize); prints a markdown table with per-call µs / wall-ms / GC counts so future changes can be validated quantitatively.

  • Bugfix: avoid corrupted redisplay in emacs -nw by using single-cell BMP glyphs ( / ) for the chat mode-line trust indicator on terminal frames; emoji defaults are preserved on graphic frames. Configurable via eca-chat-trust-on-symbol-tty / eca-chat-trust-off-symbol-tty. #229

  • Expire the cached GitHub releases list used for eca server update detection. Previously eca-process--releases-cache was populated once per Emacs session and never invalidated, so long-running Emacs instances never noticed new eca server releases (and eca-install-server, despite its docstring, was bound by the same stale cache). New eca-server-releases-cache-ttl defcustom (default 3600 seconds; nil disables expiry; 0 always refetches) refreshes the cache on access once expired. New autoloaded interactive command eca-server-check-updates clears the cache and reports whether the installed server is up to date, has an available upgrade, or whether the GitHub check failed. eca-install-server now also clears the cache before fetching the latest version, matching its "Force download the latest eca server." docstring. #230

  • Render assistant-emitted ChatImageContent from chat/contentReceived inline in the chat buffer (e.g. images returned by the OpenAI image_generation tool). Decodes the base64 payload and displays it via an overlay carrying create-image data (overlay rather than display text-property so markdown-mode/gfm-mode font-lock cannot strip it on font-lock-ensure), falling back to a [Image: <mediaType>, <N> bytes] placeholder on TTY frames or when the image type is unavailable in the current Emacs build. Sizing is configurable via eca-chat-image-max-width (default fit-window — scales to the chat window body width, hard-capped by eca-chat-image-window-fit-cap, default 800px) and eca-chat-image-max-height (default nil); a fixed integer or nil (unconstrained) are also accepted for eca-chat-image-max-width. Per-chat zoom: eca-chat-image-zoom-in (C-c C-z + / C-c C-z =), eca-chat-image-zoom-out (C-c C-z -), and eca-chat-image-zoom-reset (C-c C-z 0) mutate the buffer-local eca-chat-image-scale (multiplier on the resolved width cap, default 1.0) by eca-chat-image-scale-step (default 1.2) and re-rasterize already-rendered images via image-flush so existing images snap to the new size without re-fetching. Save inline images to disk via eca-chat-save-image-at-point (C-c C-z s), also reachable via RET or mouse-2 directly on the image overlay (with a tooltip describing media type / byte count), with the destination customizable via eca-chat-save-image-directory (default workspace-root, resolving to <root>/.eca/images/; also accepts a literal path string or nil for default-directory) and eca-chat-save-image-filename-format (default eca-image-<YYYYMMDD-HHMMSS>.<ext>); saved bytes are pulled directly from the existing overlay via image-property :data, so display zoom does not affect the file and no server round-trip is needed.

  • Syntax-highlight the inline eca-complete ghost-text overlay using the buffer's major-mode, with optional foreground dimming for a "ghost" look similar to Cursor / Copilot. Configurable via eca-completion-syntax-highlight (default t) and eca-completion-overlay-dim-ratio (default 0.5, nil disables dimming). eca-completion-overlay-face now composes with APPEND priority on top of font-lock faces instead of overriding them. #227

  • Sync the mode-line trust indicator on chat resume by honoring the new selectTrust field on config/updated: the shield/flame icon now matches the server's persisted trust state for the resumed chat instead of always defaulting to off (eca #426).

  • Defer fontification during chat streaming: replace the per-chunk font-lock-ensure with a debounced idle-timer scheduler plus a single guaranteed font-lock-ensure at end-of-stream, configurable via eca-chat-fontify-debounce-interval (default 0.15s, nil disables intermediate fontify). Cuts font-lock CPU by ~99% on fast-streaming models and ~84% on slow-streaming ones.

  • Improve mode-line trust indicator: 🔥 (fire) when ON, 🛡 (shield) when OFF. Customizable via eca-chat-trust-on-symbol / eca-chat-trust-off-symbol.

  • Add eca-chat-remove-workspace-root command and [-] mode-line button to remove a workspace folder from a running session. Both 'add' and 'remove' is in the transient menu (W a / W r).

  • Add eca-chat-mode-line-format for customizable chat mode line layout. #184

  • Fix top-level (require 'tab-line) causing side effects when eca-chat-tab-line is nil. #195

  • Add support for chat/opened server notification, enabling the /fork command to open forked chats as new tabs.

  • Fix eca--uri-to-path returning wrong path on Windows (leading slash before drive letter). #200

  • Add eca-settings-tab-line option to disable tab-line-mode in settings buffers. #201

  • Replace helpful-heading face dependency with eca-settings-heading defface. #201

  • Fix settings tab re-registration reordering tabs. #201

  • Add support for chat/askQuestion server request, enabling tools to ask users questions with selectable options in the chat buffer. #338

0.6.0

  • Add eca-chat-save-to-file command. #95
  • Fix chat not being closed. #89
  • Fix: check existing eca sessions when opening chat. #88
  • Add rewrite feature.
  • Fix issue with view_ediff displaying empty buffers in ediff. #86
  • Fix user message contexts and file paths not being sent. #112

Started tracking since 03/11/25