Skip to content

feat(@-refs): inline @file context via chat/queryFiles#4

Open
ssjoleary wants to merge 3 commits into
mainfrom
phase-11a-at-refs
Open

feat(@-refs): inline @file context via chat/queryFiles#4
ssjoleary wants to merge 3 commits into
mainfrom
phase-11a-at-refs

Conversation

@ssjoleary
Copy link
Copy Markdown
Contributor

Summary

  • Typing @ in :ready (at start of input, or after a space) opens a fuzzy file picker that dispatches chat/queryFiles to the server.
  • Selected file is inserted inline as @<path> at the cursor and added to :pending-contexts, which is sent as the contexts array on the next chat/prompt and reset to [] after send.
  • User-message renderer styles @<token> tokens with ANSI bold while preserving the outer reverse-video wrap.

Tracks Phase 11a in docs/roadmap.md.

Decisions worth flagging

  • Single-select per @ invocation — matches eca-nvim + eca-emacs ecosystem (multiple files = multiple @ presses). Multi-file batch selection deliberately deferred.
  • Inline tag, not separate chip block — matches eca-emacs (eca-chat-context.el:449-458) and aligns with the eca server's own inline parser (eca/src/eca/features/context.clj:124-139). Belt-and-braces send: inline @path token AND explicit contexts array.
  • Trigger guard@ only opens the picker when preceded by space, start-of-line, or empty input. Mid-word @ (e.g. user@host) inserts a literal @.
  • Cursor-position-aware insertion — selection appends @<path> at the cursor (not end-of-string), via subs/set-value.
  • ANSI bold uses \\033[1m ... \\033[22m (not 0m reset) so the outer reverse-video wrap on user lines is preserved. wrap-text is already ANSI-aware so token boldness survives wrapping.
  • /-autocomplete suppression is already enforced by the existing :ready-only guard in autocomplete-slash?; new test pins this down explicitly.

Out of scope (deliberate)

  • Multi-file batch selection.
  • Separate Contexts chip block above message.
  • Non-file context types (@cursor, @repoMap, @mcpResource).
  • Line-range syntax @file.clj:L1-L10 — server supports but defer client surfacing.
  • Recent-files boost / client fuzzy ranking beyond what server returns.

Test plan

  • bb test — 96 tests, 431 assertions, 0 failures
  • New test/eca_cli/at_refs_test.clj (9 tests, 24 assertions): keystroke opens picker, mid-word no-op, after-space, selection appends tag + context, escape no side effects, pending-contexts flushed on send, slash suppressed while picker open, ANSI-bold render, async loaded results splice
  • clj-kondo: 0 warnings on changed files (4 pre-existing warnings in import blocks unchanged)

brepl smoke

@ keystroke intercept in :ready:

mode: :picking
picker kind: :at-file
cmd dispatched: true

User-message render with @-tokens (ANSI bold visible):

"[7m ❯ review [1m@src/foo.clj[22m and [1m@docs/x.md[22m [0m"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds inline @file context references to the chat flow, wiring file picker selection into prompt contexts and user-message rendering.

Changes:

  • Adds chat/queryFiles protocol support and @ picker state handling.
  • Sends selected file contexts with chat/prompt.
  • Styles inline @path tokens in rendered user messages and adds test coverage.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/eca_cli/state.clj Adds @ trigger handling and async file query command.
src/eca_cli/picker.clj Adds at-file picker state, filtering, and selection insertion.
src/eca_cli/chat.clj Includes pending contexts in prompt sends and clears them after submit.
src/eca_cli/protocol.clj Adds chat-query-files! request wrapper.
src/eca_cli/view.clj Adds picker label for file selection.
src/eca_cli/view/blocks.clj Styles rendered @path tokens with ANSI bold.
test/eca_cli/at_refs_test.clj Adds unit tests for @ picker, contexts, rendering, and protocol params.
bb.edn Adds the new test namespace to the test task.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/eca_cli/chat.clj Outdated
Comment on lines +426 to +428
(send-chat-prompt! (:server state) (:chat-id state) text
(cond-> (:opts state)
(seq contexts) (assoc :contexts contexts)))
Comment thread src/eca_cli/chat.clj
(let [new-state (-> state
(update :items conj {:type :user :text text})
(assoc :mode :chatting :pending-message text :echo-pending true)
(assoc :pending-contexts [])
Comment thread src/eca_cli/picker.clj Outdated
(nth filtered idx))]
(if path
[(-> state
(update :input #(-> % (insert-at-cursor (str "@" path)) ti/focus))
Comment thread src/eca_cli/state.clj
Comment on lines +257 to +259
(autocomplete-at? state msg)
[(picker/open-at-file-picker state)
(query-files-cmd (:server state) (:chat-id state) "")]
ssjoleary and others added 2 commits May 15, 2026 19:46
Addresses PR #4 review (4 issues):
- Filter :pending-contexts to inline @<path> tokens at send so deleted
  tokens drop their contexts.
- Preserve :pending-contexts across login-retry by capturing into :opts
  before clearing.
- Insert separator around @<path> when cursor is adjacent to non-whitespace,
  so `foo|bar` -> `foo @path bar` not `foo@pathbar`.
- Re-dispatch chat/queryFiles on filter typing so server-capped list
  doesn't trap files the user is searching for.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collapse two near-identical cond branches in update-state behind a
single named predicate at-file-filter-keystroke?. The duplicated
branches (printable-char and backspace) shared their entire body —
hand to picker, re-query server with current :query. Predicate names
the policy (what counts as filter typing); the single branch carries
the mechanism (dispatch + re-query).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants