Class: RailsConsoleAi::Channel::Console

Inherits:
Base
  • Object
show all
Defined in:
lib/rails_console_ai/channel/console.rb

Constant Summary collapse

MAX_DISPLAY_LINES =

— Omitted output tracking (shared with Executor) —

20
MAX_DISPLAY_CHARS =
4000

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#cancelled?, #supports_danger?, #system_instructions

Constructor Details

#initializeConsole

Returns a new instance of Console.



9
10
11
# File 'lib/rails_console_ai/channel/console.rb', line 9

def initialize
  @real_stdout = $stdout
end

Instance Attribute Details

#real_stdoutObject (readonly)

Returns the value of attribute real_stdout.



7
8
9
# File 'lib/rails_console_ai/channel/console.rb', line 7

def real_stdout
  @real_stdout
end

Instance Method Details

#confirm(text) ⇒ Object



103
104
105
106
# File 'lib/rails_console_ai/channel/console.rb', line 103

def confirm(text)
  $stdout.print colorize(text, :yellow)
  $stdin.gets.to_s.strip.downcase
end

#console_capture_stringObject

Provide access to the console capture for session logging



174
175
176
# File 'lib/rails_console_ai/channel/console.rb', line 174

def console_capture_string
  @interactive_console_capture&.string
end

#display(text) ⇒ Object



13
14
15
# File 'lib/rails_console_ai/channel/console.rb', line 13

def display(text)
  $stdout.puts colorize(text, :cyan)
end

#display_code(code) ⇒ Object



37
38
39
40
41
42
# File 'lib/rails_console_ai/channel/console.rb', line 37

def display_code(code)
  $stdout.puts
  $stdout.puts colorize("# Generated code:", :yellow)
  $stdout.puts highlight_code(code)
  $stdout.puts
end

#display_error(text) ⇒ Object



33
34
35
# File 'lib/rails_console_ai/channel/console.rb', line 33

def display_error(text)
  $stderr.puts colorize(text, :red)
end

#display_result(result) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rails_console_ai/channel/console.rb', line 71

def display_result(result)
  full = "=> #{result.inspect}"
  lines = full.lines
  total_lines = lines.length
  total_chars = full.length

  if total_lines <= MAX_DISPLAY_LINES && total_chars <= MAX_DISPLAY_CHARS
    $stdout.puts colorize(full, :green)
  else
    truncated = lines.first(MAX_DISPLAY_LINES).join
    truncated = truncated[0, MAX_DISPLAY_CHARS] if truncated.length > MAX_DISPLAY_CHARS
    $stdout.puts colorize(truncated, :green)

    omitted_lines = [total_lines - MAX_DISPLAY_LINES, 0].max
    omitted_chars = [total_chars - truncated.length, 0].max
    parts = []
    parts << "#{omitted_lines} lines" if omitted_lines > 0
    parts << "#{omitted_chars} chars" if omitted_chars > 0

    @omitted_counter += 1
    @omitted_outputs[@omitted_counter] = full
    $stdout.puts colorize("  (omitting #{parts.join(', ')})  /expand #{@omitted_counter} to see all", :yellow)
  end
end

#display_result_output(output) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/rails_console_ai/channel/console.rb', line 44

def display_result_output(output)
  text = output.to_s
  return if text.strip.empty?

  lines = text.lines
  total_lines = lines.length
  total_chars = text.length

  if total_lines <= MAX_DISPLAY_LINES && total_chars <= MAX_DISPLAY_CHARS
    $stdout.print text
  else
    truncated = lines.first(MAX_DISPLAY_LINES).join
    truncated = truncated[0, MAX_DISPLAY_CHARS] if truncated.length > MAX_DISPLAY_CHARS
    $stdout.print truncated

    omitted_lines = [total_lines - MAX_DISPLAY_LINES, 0].max
    omitted_chars = [total_chars - truncated.length, 0].max
    parts = []
    parts << "#{omitted_lines} lines" if omitted_lines > 0
    parts << "#{omitted_chars} chars" if omitted_chars > 0

    @omitted_counter += 1
    @omitted_outputs[@omitted_counter] = text
    $stdout.puts colorize("  (output truncated, omitting #{parts.join(', ')})  /expand #{@omitted_counter} to see all", :yellow)
  end
end

#display_status(text) ⇒ Object



21
22
23
# File 'lib/rails_console_ai/channel/console.rb', line 21

def display_status(text)
  $stdout.puts "\e[2m#{text}\e[0m"
end

#display_thinking(text) ⇒ Object



17
18
19
# File 'lib/rails_console_ai/channel/console.rb', line 17

def display_thinking(text)
  $stdout.puts "\e[2m#{text}\e[0m"
end

#display_tool_call(text) ⇒ Object



25
26
27
# File 'lib/rails_console_ai/channel/console.rb', line 25

def display_tool_call(text)
  $stdout.puts "\e[33m  -> #{text}\e[0m"
end

#display_warning(text) ⇒ Object



29
30
31
# File 'lib/rails_console_ai/channel/console.rb', line 29

def display_warning(text)
  $stdout.puts colorize(text, :yellow)
end

#edit_code(code) ⇒ Object



120
121
122
# File 'lib/rails_console_ai/channel/console.rb', line 120

def edit_code(code)
  open_in_editor(code)
end

#expand_output(id) ⇒ Object



138
139
140
# File 'lib/rails_console_ai/channel/console.rb', line 138

def expand_output(id)
  @omitted_outputs[id]
end

#init_omitted_trackingObject



133
134
135
136
# File 'lib/rails_console_ai/channel/console.rb', line 133

def init_omitted_tracking
  @omitted_outputs = {}
  @omitted_counter = 0
end

#interactive_loop(engine) ⇒ Object

— Interactive loop —



144
145
146
147
148
149
# File 'lib/rails_console_ai/channel/console.rb', line 144

def interactive_loop(engine)
  @engine = engine
  engine.init_interactive
  init_interactive_state
  run_interactive_loop
end

#modeObject



112
113
114
# File 'lib/rails_console_ai/channel/console.rb', line 112

def mode
  'console'
end

#prompt(text) ⇒ Object



96
97
98
99
100
101
# File 'lib/rails_console_ai/channel/console.rb', line 96

def prompt(text)
  $stdout.print colorize(text, :cyan)
  answer = $stdin.gets
  return '(no answer provided)' if answer.nil?
  answer.strip.empty? ? '(no answer provided)' : answer.strip
end

#resume_interactive(engine, session) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/rails_console_ai/channel/console.rb', line 151

def resume_interactive(engine, session)
  @engine = engine
  engine.init_interactive
  init_interactive_state

  # Restore state from the previous session
  engine.restore_session(session)

  # Seed the capture buffer with previous output so it's preserved on save
  @interactive_console_capture.write(session.console_output.to_s)

  # Replay to the user via the real stdout (bypass TeeIO to avoid double-capture)
  if session.console_output && !session.console_output.strip.empty?
    @real_stdout.puts "\e[2m--- Replaying previous session output ---\e[0m"
    @real_stdout.puts session.console_output
    @real_stdout.puts "\e[2m--- End of previous output ---\e[0m"
    @real_stdout.puts
  end

  run_interactive_loop
end

#supports_editing?Boolean

Returns:

  • (Boolean)


116
117
118
# File 'lib/rails_console_ai/channel/console.rb', line 116

def supports_editing?
  true
end

#user_identityObject



108
109
110
# File 'lib/rails_console_ai/channel/console.rb', line 108

def user_identity
  RailsConsoleAi.current_user
end

#wrap_llm_call(&block) ⇒ Object



124
125
126
# File 'lib/rails_console_ai/channel/console.rb', line 124

def wrap_llm_call(&block)
  with_escape_monitoring(&block)
end

#write_to_capture(text) ⇒ Object



178
179
180
# File 'lib/rails_console_ai/channel/console.rb', line 178

def write_to_capture(text)
  @interactive_console_capture&.write(text)
end