All notable changes to eca-cli. Format inspired by Keep a Changelog. No formal versioning yet — entries are grouped by roadmap phase and refactor phase.
@-file context injection and the background-jobs panel shipped; /rollback + /fork remain (see docs/roadmap.md Phase 11).
@-file context injection (#4): typing@at start-of-input or after a space opens a fuzzy file picker (chat/queryFiles); the selection is inserted inline as@<path>and sent as thecontextsarray on the nextchat/prompt. Inline@<token>styled bold in the user-message renderer./jobsbackground-jobs panel (#3): newsrc/eca_cli/jobs.clj—:jobsstate slice,jobs/updatedpush handler,[N jobs]status-bar slot, on-demandjobs/readOutputpopup, and ad→confirm→jobs/killflow. Push-only refresh, no polling.
/mcppanel + status-bar slot +tool/serverUpdatedhandler (#2): newsrc/eca_cli/mcp.clj— MCP state slice, event-driven init (onetool/serverUpdatedper configured server at startup), aggregate-health status-bar slot (MCPs: 3/4 ⚠), per-server status rows with tool count, and a[connect]affordance dispatchingmcp/connectServeronrequires-authrows.
Aligns eca-cli's vocabulary with upstream ECA (#7, closes #6). No behaviour change; transparent data migration. bb test 86 tests / bb itest 25 tests green.
- ns
eca-cli.sessions→eca-cli.chats; command/sessions→/chats; persistence fileeca-cli-sessions.edn→eca-cli-chats.ednwith a one-time legacy-fallback read so no resume history is lost; pickeropen-session-picker→open-chat-picker,:kind :session→:chat. - Deliberately unchanged: run-scoped approval state (
:session-trusted-tools), server payload keys (:sessionTokens/:sessionCost), and tmux's ownsessionterm — these already match upstream.
Finishes the structural debt from the Phase A audit. 85/85 tests green at every commit.
README.md,LICENSE(Apache 2.0),CHANGELOG.mdat project root.src/eca_cli/view/blocks.clj— extracted per-item block renderers fromview.clj(assistant text, user message, tool-call expanded/collapsed, thinking, hook, system) plus ANSI styling constants.chat/handle-config-updated,chat/handle-chat-opened,chat/handle-chat-cleared— extracted fromstate.clj'shandle-eca-notification.- 4 shutdown-lifecycle deftests in
test/eca_cli/lifecycle_test.cljcovering protocol-level sequence order, cmd-quit composition, exception resilience, and Ctrl+C //quitequivalence. - 7 block-navigation deftests in
test/eca_cli/chat_test.clj. - 6 new Alt-prefixed keybindings:
Alt+↑/Alt+↓(jump top-level blocks, skip sub-items),Alt+g/Alt+G(focus first / last block),Alt+c/Alt+o(collapse / expand all). Documented in README with terminal-compatibility note. - New test files:
test/eca_cli/lifecycle_test.clj,test/eca_cli/chat_test.clj,test/eca_cli/view/blocks_test.clj.
state.clj: 272 → 252 LOC.handle-eca-notificationnow delegates each chat-domain case in one line.view.clj: 265 → 149 LOC. Composer + chat-area + overlay renderers retained; block renderers moved out.chat.clj: 462 → 561 LOC. Absorbed three new notification handlers and six new key dispatch arms.
Split monolithic state.clj (1121 LOC) into feature-scoped namespaces aligned with the ECA editor-plugin convention. No behavioural changes; 73/73 tests green at every commit.
chat.clj— content handlers, tool-call lifecycle,send-chat-prompt!, focus helpers, key dispatch for:ready/:chatting/:approvingmodes,chat/contentReceivednotification handler.picker.clj— picker overlay state + key dispatch for:pickingmode (model / agent / session selection);printable-char?helper.login.clj— provider login cmd builders,providers/updatednotification handler, key dispatch for:loginmode.view/rebuild-lines— leaf utility called from every feature ns.- Pre-refactor test hardening: 7 deftests covering the approval flow (
y/n/Y), Enter-to-send prompt,:window-sizeresize, and Ctrl+C shutdown. docs/refactor/00-assessment.md— eca-cli-vs-ECA-editor-plugin checklist audit.docs/refactor/01-phase-a-plan.md— refactor plan with outcome section recording final LOC vs targets, mid-flight plan revisions, and final dep graph.docs/refactor/02-phase-b-plan.md— Phase B plan with audit-grounded detail.docs/refactor/03-feature-gaps-roadmap-proposal.md— maps user-visible feature gaps onto roadmap phases.
state.cljreduced from 1121 → 272 LOC; now a clean dispatcher (runtime events → global keys → per-mode delegation).commands.cljreplaced 4-line stub with a full slash-command registry,dispatch-command,open-command-picker, andcmd-*handlers (~114 LOC).sessions.cljextended (29 → 56 LOC) to absorb chat-list/open/delete cmd builders.view.cljgainedrebuild-lines.docs/roadmap.mdrenumbered: Tool-Call Diff Display promoted to Phase 6, MCP Integration to Phase 7, Markdown Rendering demoted to Phase 8 — ECA-required items now precede UX polish.
- Collapsible tool blocks in chat with status icons and expandable arguments / output.
- Thinking blocks: live "thinking…" indicator that becomes a collapsed "Thought" block once reasoning completes.
- Hook execution blocks: surface ECA hook lifecycle (running / ok / failed) with optional output panes.
- Sub-agent nesting: when a tool call spawns a sub-agent, that sub-agent's content renders nested under the spawn block.
- Focus model:
Tab/Shift+Tabcycle through focusable items;↑/↓arrows navigate within focus;Entertoggles:expanded?;Escclears focus.
- Sub-agent task prompts render as assistant text rather than user input.
- Status icons use ANSI-coloured 1-wide chars to avoid JLine layout artifacts on focus swap.
- Slash-command registry (
/model,/agent,/new,/sessions,/clear,/help,/quit,/login). - Interactive command picker triggered by typing
/in an empty input. commands.cljnamespace as the extensibility seam — adding a new command means adding one entry.
- Session persistence (
~/.cache/eca/eca-cli-sessions.edn) keyed by workspace path. /new— start a fresh chat (deletes the current chat-id from sessions)./sessions— browse and resume previous chats via picker.chat/openedandchat/listprotocol handling for replay and switching.- Workspace isolation: each workspace path keeps its own most-recent chat-id.
- ECA binary upgrade:
bb upgrade-ecadownloads and installs the pinned ECA binary.
alt-screen true— fullscreen mode; native mouse selection via Shift+drag.- DECSET 1000 mouse reporting — mouse-wheel scroll (3 lines per tick).
- Input history:
↑/↓in:readymode recalls previously sent messages. PgUp/PgDn— full-page scroll through chat history.
- Model and agent lists populated from ECA's
config/updatednotification. - Ctrl+L and
/modelopen a model picker; selection sendschat/selectedModelChanged. /agentpicker; selection sendschat/selectedAgentChanged.- Status bar shows current
model • agentat all times.
- Effective-opts model override bug — explicit
--modelflag now wins over config defaults.
- End-to-end provider login flow tested against real credentials.
- Login cancellation, re-trigger, and timeout handling.
- Connection lifecycle (
initialize/initialized/ shutdown) with visible status. - Streaming chat with the LLM.
- Tool-call approval flow (
y/n/Yfor approve / reject / approve-and-trust). - Reader-error detection — ECA EOF surfaces as a system message rather than a silent hang.
- Echo suppression — ECA echoes user messages back; eca-cli consumes the echo via
:echo-pendingflag rather than rendering it twice. - Charm.clj integration — the Elm-loop runtime driving the TUI.
- Initial test suite: protocol, view, state.
- JSON-RPC transport layer over stdin/stdout.
- TUI core (
core.clj,state.clj,view.clj). - ECA process spawn and reader thread.
- TUI mockups for all major UI states.
CLAUDE.mdwith architecture and dev commands.