Module: Clacky::UIInterface
Overview
UIInterface defines the standard interface between Agent/CLI and UI implementations.
All UI controllers (UIController, JsonUIController) must implement these methods.
Defined Under Namespace
Classes: LegacyProgressHandleAdapter
Instance Method Summary
collapse
-
#append_output(content) ⇒ Object
-
#clear_input ⇒ Object
-
#log(message, level: :info) ⇒ Object
-
#phase_end(phase_id, summary: nil) ⇒ Object
-
#phase_start(kind:, label: nil) ⇒ Object
Phase grouping (optional, web UI uses this to fold subagent runs) === Begin a logical phase.
-
#request_confirmation(message, default: true) ⇒ Object
Blocking interaction ===.
-
#request_feedback_with_countdown(seconds: 10) ⇒ Object
Auto-approve countdown for request_user_feedback.
-
#set_idle_status ⇒ Object
-
#set_input_tips(message, type: :info) ⇒ Object
-
#set_working_status ⇒ Object
-
#show_assistant_message(content, files:) ⇒ Object
Output display ===.
-
#show_complete(iterations:, cost:, duration: nil, cache_stats: nil, awaiting_user_feedback: false, cost_source: nil) ⇒ Object
-
#show_diff(old_content, new_content, max_lines: 50) ⇒ Object
-
#show_error(message, code: nil, top_up_url: nil, raw_message: nil) ⇒ Object
-
#show_feedback_request(question, context, options) ⇒ Object
-
#show_file_edit_preview(path) ⇒ Object
-
#show_file_error(error_message) ⇒ Object
-
#show_file_write_preview(path, is_new_file:) ⇒ Object
-
#show_goal_status(goal) ⇒ Object
Broadcast the current standing-goal (/goal) state.
-
#show_info(message, prefix_newline: true) ⇒ Object
Status messages ===.
-
#show_progress(message = nil, prefix_newline: true, progress_type: "thinking", phase: "active", metadata: {}) ⇒ Object
Progress === Unified progress indicator with type-based display customization.
-
#show_shell_preview(command) ⇒ Object
-
#show_subagent_end ⇒ Object
-
#show_subagent_start(skill: nil, iterations: nil, cost_usd: nil) ⇒ Object
-
#show_success(message) ⇒ Object
-
#show_token_usage(token_data) ⇒ Object
-
#show_tool_args(formatted_args) ⇒ Object
-
#show_tool_call(name, args) ⇒ Object
-
#show_tool_error(error) ⇒ Object
-
#show_tool_result(result) ⇒ Object
-
#show_tool_stdout(lines) ⇒ Object
-
#show_warning(message) ⇒ Object
-
#start_progress(message: nil, style: :primary, quiet_on_fast_finish: false) ⇒ #update, ...
Progress (v2: owned handles) ===.
-
#stop(clear_screen: false) ⇒ Object
Path redaction (for encrypted brand skill tmpdirs) === === Lifecycle ===.
-
#stream_thinking_progress(input_tokens:, output_tokens:) ⇒ Object
Update the live "thinking" progress with streamed token counts.
-
#update_permission_mode(mode) ⇒ Object
Notify the UI that the agent changed its permission mode internally (e.g. /goal auto-switches to auto_approve).
-
#update_sessionbar(tasks: nil, cost: nil, cost_source: nil, status: nil, latency: nil) ⇒ Object
State updates ===.
-
#update_todos(todos) ⇒ Object
-
#with_phase(kind:, label: nil) ⇒ Object
Run block within a phase.
-
#with_progress(message: nil, style: :primary, quiet_on_fast_finish: false) {|handle| ... } ⇒ Object
Run the given block with a progress indicator active.
Instance Method Details
#append_output(content) ⇒ Object
37
|
# File 'lib/clacky/ui_interface.rb', line 37
def append_output(content); end
|
155
|
# File 'lib/clacky/ui_interface.rb', line 155
def clear_input; end
|
#log(message, level: :info) ⇒ Object
44
|
# File 'lib/clacky/ui_interface.rb', line 44
def log(message, level: :info); end
|
#phase_end(phase_id, summary: nil) ⇒ Object
170
|
# File 'lib/clacky/ui_interface.rb', line 170
def phase_end(phase_id, summary: nil); end
|
#phase_start(kind:, label: nil) ⇒ Object
Phase grouping (optional, web UI uses this to fold subagent runs) ===
Begin a logical phase. Events emitted between phase_start and phase_end
carry the phase_id so the UI can group them visually.
Returns the phase_id (caller is responsible for passing it to phase_end).
166
167
168
|
# File 'lib/clacky/ui_interface.rb', line 166
def phase_start(kind:, label: nil)
SecureRandom.uuid
end
|
#request_confirmation(message, default: true) ⇒ Object
143
|
# File 'lib/clacky/ui_interface.rb', line 143
def request_confirmation(message, default: true); end
|
#request_feedback_with_countdown(seconds: 10) ⇒ Object
Auto-approve countdown for request_user_feedback. Shows a live countdown
and lets the user press a key to take over and answer. Returns :timeout
when no one intervenes (agent should auto-decide and continue), or a
feedback string / "" when the user steps in. Non-interactive UIs (web,
json, channel) have no human watching a TTY, so they default to :timeout.
150
151
152
|
# File 'lib/clacky/ui_interface.rb', line 150
def request_feedback_with_countdown(seconds: 10)
:timeout
end
|
#set_idle_status ⇒ Object
140
|
# File 'lib/clacky/ui_interface.rb', line 140
def set_idle_status; end
|
156
|
# File 'lib/clacky/ui_interface.rb', line 156
def set_input_tips(message, type: :info); end
|
#set_working_status ⇒ Object
139
|
# File 'lib/clacky/ui_interface.rb', line 139
def set_working_status; end
|
#show_assistant_message(content, files:) ⇒ Object
12
|
# File 'lib/clacky/ui_interface.rb', line 12
def show_assistant_message(content, files:); end
|
#show_complete(iterations:, cost:, duration: nil, cache_stats: nil, awaiting_user_feedback: false, cost_source: nil) ⇒ Object
36
|
# File 'lib/clacky/ui_interface.rb', line 36
def show_complete(iterations:, cost:, duration: nil, cache_stats: nil, awaiting_user_feedback: false, cost_source: nil); end
|
#show_diff(old_content, new_content, max_lines: 50) ⇒ Object
25
|
# File 'lib/clacky/ui_interface.rb', line 25
def show_diff(old_content, new_content, max_lines: 50); end
|
#show_error(message, code: nil, top_up_url: nil, raw_message: nil) ⇒ Object
42
|
# File 'lib/clacky/ui_interface.rb', line 42
def show_error(message, code: nil, top_up_url: nil, raw_message: nil); end
|
#show_feedback_request(question, context, options) ⇒ Object
13
|
# File 'lib/clacky/ui_interface.rb', line 13
def show_feedback_request(question, context, options); end
|
#show_file_edit_preview(path) ⇒ Object
22
|
# File 'lib/clacky/ui_interface.rb', line 22
def show_file_edit_preview(path); end
|
#show_file_error(error_message) ⇒ Object
23
|
# File 'lib/clacky/ui_interface.rb', line 23
def show_file_error(error_message); end
|
#show_file_write_preview(path, is_new_file:) ⇒ Object
21
|
# File 'lib/clacky/ui_interface.rb', line 21
def show_file_write_preview(path, is_new_file:); end
|
#show_goal_status(goal) ⇒ Object
Broadcast the current standing-goal (/goal) state. goal is the
GoalState hash or nil. UIs that render goal progress override this.
30
|
# File 'lib/clacky/ui_interface.rb', line 30
def show_goal_status(goal); end
|
#show_info(message, prefix_newline: true) ⇒ Object
40
|
# File 'lib/clacky/ui_interface.rb', line 40
def show_info(message, prefix_newline: true); end
|
#show_progress(message = nil, prefix_newline: true, progress_type: "thinking", phase: "active", metadata: {}) ⇒ Object
Progress ===
Unified progress indicator with type-based display customization.
progress_type: "thinking" | "retrying" | "idle_compress" | custom
phase: "active" | "done"
metadata: extensible hash (e.g., 3, total: 10 for retries)
51
|
# File 'lib/clacky/ui_interface.rb', line 51
def show_progress(message = nil, prefix_newline: true, progress_type: "thinking", phase: "active", metadata: {}); end
|
#show_shell_preview(command) ⇒ Object
24
|
# File 'lib/clacky/ui_interface.rb', line 24
def show_shell_preview(command); end
|
#show_subagent_end ⇒ Object
15
|
# File 'lib/clacky/ui_interface.rb', line 15
def show_subagent_end; end
|
#show_subagent_start(skill: nil, iterations: nil, cost_usd: nil) ⇒ Object
14
|
# File 'lib/clacky/ui_interface.rb', line 14
def show_subagent_start(skill: nil, iterations: nil, cost_usd: nil); end
|
#show_success(message) ⇒ Object
43
|
# File 'lib/clacky/ui_interface.rb', line 43
def show_success(message); end
|
#show_token_usage(token_data) ⇒ Object
26
|
# File 'lib/clacky/ui_interface.rb', line 26
def show_token_usage(token_data); end
|
20
|
# File 'lib/clacky/ui_interface.rb', line 20
def show_tool_args(formatted_args); end
|
16
|
# File 'lib/clacky/ui_interface.rb', line 16
def show_tool_call(name, args); end
|
19
|
# File 'lib/clacky/ui_interface.rb', line 19
def show_tool_error(error); end
|
17
|
# File 'lib/clacky/ui_interface.rb', line 17
def show_tool_result(result); end
|
18
|
# File 'lib/clacky/ui_interface.rb', line 18
def show_tool_stdout(lines); end
|
#show_warning(message) ⇒ Object
41
|
# File 'lib/clacky/ui_interface.rb', line 41
def show_warning(message); end
|
#start_progress(message: nil, style: :primary, quiet_on_fast_finish: false) ⇒ #update, ...
Progress (v2: owned handles) ===
Start a new progress indicator and return an owned handle. The caller
is responsible for finishing it — use with_progress (below) whenever
possible to get ensure-based auto-close.
Default implementation degrades gracefully to the old show_progress API
so UI implementations that haven't migrated still behave correctly.
86
87
88
89
90
91
|
# File 'lib/clacky/ui_interface.rb', line 86
def start_progress(message: nil, style: :primary, quiet_on_fast_finish: false)
_ = quiet_on_fast_finish progress_type = style == :primary ? "thinking" : "idle_compress"
show_progress(message, progress_type: progress_type, phase: "active")
LegacyProgressHandleAdapter.new(self, progress_type: progress_type)
end
|
#stop(clear_screen: false) ⇒ Object
Path redaction (for encrypted brand skill tmpdirs) ===
Lifecycle ===
160
|
# File 'lib/clacky/ui_interface.rb', line 160
def stop(clear_screen: false); end
|
#stream_thinking_progress(input_tokens:, output_tokens:) ⇒ Object
Update the live "thinking" progress with streamed token counts.
This is purely decorative: it must NEVER start a new progress
indicator. If no thinking progress is currently active (e.g. during
idle compression, where only a quiet "Compressing..." progress is
live), the call is a no-op. UI2 overrides this; other UIs delegate
to show_progress.
59
60
61
62
63
64
65
|
# File 'lib/clacky/ui_interface.rb', line 59
def stream_thinking_progress(input_tokens:, output_tokens:)
show_progress(
progress_type: "thinking",
phase: "active",
metadata: { input_tokens: input_tokens, output_tokens: output_tokens }
)
end
|
#update_permission_mode(mode) ⇒ Object
Notify the UI that the agent changed its permission mode internally
(e.g. /goal auto-switches to auto_approve). UIs that render the mode
in a status bar override this.
35
|
# File 'lib/clacky/ui_interface.rb', line 35
def update_permission_mode(mode); end
|
#update_sessionbar(tasks: nil, cost: nil, cost_source: nil, status: nil, latency: nil) ⇒ Object
137
|
# File 'lib/clacky/ui_interface.rb', line 137
def update_sessionbar(tasks: nil, cost: nil, cost_source: nil, status: nil, latency: nil); end
|
#update_todos(todos) ⇒ Object
138
|
# File 'lib/clacky/ui_interface.rb', line 138
def update_todos(todos); end
|
#with_phase(kind:, label: nil) ⇒ Object
Run block within a phase. Always closes via ensure.
173
174
175
176
177
178
179
180
|
# File 'lib/clacky/ui_interface.rb', line 173
def with_phase(kind:, label: nil)
pid = phase_start(kind: kind, label: label)
begin
yield pid
ensure
phase_end(pid)
end
end
|
#with_progress(message: nil, style: :primary, quiet_on_fast_finish: false) {|handle| ... } ⇒ Object
Run the given block with a progress indicator active. The handle is
always finished in an ensure block — exceptions (including
AgentInterrupted) cannot leave the ticker or entry orphaned.
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/clacky/ui_interface.rb', line 98
def with_progress(message: nil, style: :primary, quiet_on_fast_finish: false)
handle = start_progress(
message: message,
style: style,
quiet_on_fast_finish: quiet_on_fast_finish
)
begin
yield handle
ensure
handle.finish
end
end
|