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

Instance Method Details

#append_output(content) ⇒ Object



37
# File 'lib/clacky/ui_interface.rb', line 37

def append_output(content); end

#clear_inputObject

Input control (CLI layer) ===



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

Blocking interaction ===



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_statusObject



140
# File 'lib/clacky/ui_interface.rb', line 140

def set_idle_status; end

#set_input_tips(message, type: :info) ⇒ Object



156
# File 'lib/clacky/ui_interface.rb', line 156

def set_input_tips(message, type: :info); end

#set_working_statusObject



139
# File 'lib/clacky/ui_interface.rb', line 139

def set_working_status; end

#show_assistant_message(content, files:) ⇒ Object

Output display ===

Parameters:

  • content (String)

    text portion of the assistant reply (file:// links stripped)

  • files (Array<Hash>)

    extracted file refs: [{ name:, path:, inline: }]



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

Status messages ===



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_endObject



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

#show_tool_args(formatted_args) ⇒ Object



20
# File 'lib/clacky/ui_interface.rb', line 20

def show_tool_args(formatted_args); end

#show_tool_call(name, args) ⇒ Object



16
# File 'lib/clacky/ui_interface.rb', line 16

def show_tool_call(name, args); end

#show_tool_error(error) ⇒ Object



19
# File 'lib/clacky/ui_interface.rb', line 19

def show_tool_error(error); end

#show_tool_result(result) ⇒ Object



17
# File 'lib/clacky/ui_interface.rb', line 17

def show_tool_result(result); end

#show_tool_stdout(lines) ⇒ Object



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.

Parameters:

  • message (String, nil) (defaults to: nil)

    Initial progress message (nil picks a random thinking verb).

  • style (Symbol) (defaults to: :primary)

    :primary (foreground, yellow, bumps sessionbar) or :quiet (background, gray, no sessionbar change).

  • quiet_on_fast_finish (Boolean) (defaults to: false)

    When true, a finish under FAST_FINISH_THRESHOLD_SECONDS removes the progress line entirely (preferred for per-tool wrappers so fast tools don't leave a permanent "Executing foo… (0s)" log line). The default implementation ignores this flag — it only affects the native UI2::UIController + ProgressHandle path.

Returns:

  • (#update, #finish, #cancel)

    a ProgressHandle-like object.



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 # default impl doesn't honor fast-collapse
  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

State updates ===



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.

Yield Parameters:

  • handle

    the progress handle



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