Class: RubynCode::CLI::MentionExpander

Inherits:
Object
  • Object
show all
Defined in:
lib/rubyn_code/cli/mention_expander.rb

Overview

Expands ‘@path/to/file` mentions in user input into inline file content, mirroring Claude Code / Codex `@`-mentions. The original text is kept and the referenced files are appended as labeled, fenced blocks so the agent sees both the request and the files it points at.

Conservative by design: only existing, readable, reasonably-sized regular files inside the project are expanded. Unresolved mentions (and things that merely look like mentions, e.g. email addresses) are left untouched.

Constant Summary collapse

MENTION =

A mention is an “@” that doesn’t follow a word char or another “@” (so emails like foo@bar.com don’t match), followed by a path-ish run.

/(?<![\w@])@([^\s@]+)/
TRAILING_PUNCT =
/[).,;:!?'"]+\z/
MAX_FILE_BYTES =
64 * 1024
MAX_FILES =
10

Instance Method Summary collapse

Constructor Details

#initialize(project_root:) ⇒ MentionExpander

Returns a new instance of MentionExpander.

Parameters:

  • project_root (String)


22
23
24
# File 'lib/rubyn_code/cli/mention_expander.rb', line 22

def initialize(project_root:)
  @project_root = project_root
end

Instance Method Details

#expand(input) ⇒ Array(String, Array<String>)

Returns expanded text + resolved rel paths.

Parameters:

  • input (String)

    raw user input

Returns:

  • (Array(String, Array<String>))

    expanded text + resolved rel paths



28
29
30
31
32
33
34
35
36
# File 'lib/rubyn_code/cli/mention_expander.rb', line 28

def expand(input)
  return [input, []] unless input.is_a?(String) && input.include?('@')

  resolved = scan(input)
  return [input, []] if resolved.empty?

  blocks = resolved.map { |rel, abs| file_block(rel, abs) }
  ["#{input}\n\n#{blocks.join("\n\n")}", resolved.map(&:first)]
end