kward 0.67.0 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/Gemfile.lock +2 -2
- data/README.md +5 -5
- data/doc/authentication.md +24 -1
- data/doc/configuration.md +9 -2
- data/doc/extensibility.md +1 -1
- data/doc/getting-started.md +4 -6
- data/doc/plugins.md +0 -2
- data/doc/releasing.md +7 -8
- data/doc/rpc.md +6 -6
- data/doc/usage.md +5 -2
- data/doc/web-search.md +2 -2
- data/kward.gemspec +4 -0
- data/lib/kward/agent.rb +29 -2
- data/lib/kward/ansi.rb +3 -0
- data/lib/kward/auth/anthropic_oauth.rb +291 -0
- data/lib/kward/auth/file.rb +2 -0
- data/lib/kward/auth/github_oauth.rb +3 -0
- data/lib/kward/auth/openai_oauth.rb +4 -0
- data/lib/kward/auth/openrouter_api_key.rb +2 -0
- data/lib/kward/cancellation.rb +3 -0
- data/lib/kward/cli/auth_commands.rb +82 -0
- data/lib/kward/cli/commands.rb +222 -0
- data/lib/kward/cli/compaction.rb +25 -0
- data/lib/kward/cli/doctor.rb +121 -0
- data/lib/kward/cli/interactive_turn.rb +225 -0
- data/lib/kward/cli/memory_commands.rb +133 -0
- data/lib/kward/cli/plugins.rb +112 -0
- data/lib/kward/cli/prompt_interface.rb +132 -0
- data/lib/kward/cli/rendering.rb +389 -0
- data/lib/kward/cli/runtime_helpers.rb +159 -0
- data/lib/kward/cli/sessions.rb +376 -0
- data/lib/kward/cli/settings.rb +663 -0
- data/lib/kward/cli/slash_commands.rb +112 -0
- data/lib/kward/cli/stats.rb +64 -0
- data/lib/kward/cli/tool_summaries.rb +153 -0
- data/lib/kward/cli.rb +38 -2790
- data/lib/kward/cli_transcript_formatter.rb +4 -7
- data/lib/kward/clipboard.rb +1 -0
- data/lib/kward/compaction/file_operation_tracker.rb +3 -0
- data/lib/kward/compactor.rb +29 -7
- data/lib/kward/config_files.rb +33 -24
- data/lib/kward/conversation.rb +70 -5
- data/lib/kward/events.rb +2 -0
- data/lib/kward/export_path.rb +2 -0
- data/lib/kward/image_attachments.rb +2 -0
- data/lib/kward/markdown_transcript.rb +2 -0
- data/lib/kward/memory/manager.rb +13 -0
- data/lib/kward/message_access.rb +23 -2
- data/lib/kward/message_text.rb +45 -0
- data/lib/kward/model/chat_invocation.rb +2 -0
- data/lib/kward/model/client.rb +295 -77
- data/lib/kward/model/context_overflow.rb +2 -0
- data/lib/kward/model/context_usage.rb +3 -0
- data/lib/kward/model/model_info.rb +143 -4
- data/lib/kward/model/payloads.rb +166 -13
- data/lib/kward/model/retry_message.rb +2 -0
- data/lib/kward/model/stream_parser.rb +129 -0
- data/lib/kward/pan/server.rb +3 -1
- data/lib/kward/plugin_registry.rb +12 -0
- data/lib/kward/private_file.rb +2 -0
- data/lib/kward/prompt_interface/banner.rb +3 -0
- data/lib/kward/prompt_interface/composer_controller.rb +262 -0
- data/lib/kward/prompt_interface/composer_renderer.rb +172 -0
- data/lib/kward/prompt_interface/composer_state.rb +221 -0
- data/lib/kward/prompt_interface/key_handler.rb +365 -0
- data/lib/kward/prompt_interface/layout.rb +31 -0
- data/lib/kward/prompt_interface/overlay_renderer.rb +111 -0
- data/lib/kward/prompt_interface/prompt_renderer.rb +91 -0
- data/lib/kward/prompt_interface/question_prompt.rb +328 -0
- data/lib/kward/prompt_interface/runtime_state.rb +59 -0
- data/lib/kward/prompt_interface/screen.rb +186 -0
- data/lib/kward/prompt_interface/selection_prompt.rb +242 -0
- data/lib/kward/prompt_interface/slash_overlay.rb +102 -0
- data/lib/kward/prompt_interface/stream_state.rb +65 -0
- data/lib/kward/prompt_interface/transcript_buffer.rb +85 -0
- data/lib/kward/prompt_interface/transcript_renderer.rb +142 -0
- data/lib/kward/prompt_interface.rb +69 -1832
- data/lib/kward/prompts/commands.rb +2 -0
- data/lib/kward/prompts/templates.rb +3 -0
- data/lib/kward/prompts.rb +2 -0
- data/lib/kward/question_contract.rb +66 -0
- data/lib/kward/resources/avatar_kward_logo.rb +2 -0
- data/lib/kward/resources/pixel_logo.rb +2 -0
- data/lib/kward/rpc/attachment_normalizer.rb +60 -0
- data/lib/kward/rpc/auth_manager.rb +65 -11
- data/lib/kward/rpc/config_manager.rb +11 -0
- data/lib/kward/rpc/prompt_bridge.rb +5 -26
- data/lib/kward/rpc/redactor.rb +3 -0
- data/lib/kward/rpc/runtime_payloads.rb +4 -1
- data/lib/kward/rpc/server.rb +37 -10
- data/lib/kward/rpc/session_manager.rb +123 -347
- data/lib/kward/rpc/session_metrics.rb +68 -0
- data/lib/kward/rpc/session_tree.rb +48 -0
- data/lib/kward/rpc/session_tree_rows.rb +208 -0
- data/lib/kward/rpc/tool_event_normalizer.rb +3 -0
- data/lib/kward/rpc/tool_metadata.rb +3 -0
- data/lib/kward/rpc/transcript_normalizer.rb +3 -0
- data/lib/kward/rpc/transport.rb +3 -0
- data/lib/kward/session_diff.rb +2 -0
- data/lib/kward/session_store.rb +125 -31
- data/lib/kward/session_trash.rb +1 -0
- data/lib/kward/session_tree_renderer.rb +8 -41
- data/lib/kward/session_tree_tool_display.rb +56 -0
- data/lib/kward/skills/registry.rb +3 -0
- data/lib/kward/starter_pack_installer.rb +1 -0
- data/lib/kward/steering.rb +2 -0
- data/lib/kward/telemetry/logger.rb +3 -0
- data/lib/kward/telemetry/stats.rb +3 -0
- data/lib/kward/tools/ask_user_question.rb +20 -32
- data/lib/kward/tools/base.rb +8 -0
- data/lib/kward/tools/code_search.rb +5 -0
- data/lib/kward/tools/edit_file.rb +5 -0
- data/lib/kward/tools/list_directory.rb +5 -0
- data/lib/kward/tools/read_file.rb +5 -0
- data/lib/kward/tools/read_skill.rb +5 -0
- data/lib/kward/tools/registry.rb +33 -2
- data/lib/kward/tools/run_shell_command.rb +5 -0
- data/lib/kward/tools/search/code.rb +7 -0
- data/lib/kward/tools/search/web.rb +17 -14
- data/lib/kward/tools/tool_call.rb +25 -5
- data/lib/kward/tools/web_search.rb +7 -1
- data/lib/kward/tools/write_file.rb +5 -0
- data/lib/kward/transcript_export.rb +2 -0
- data/lib/kward/version.rb +2 -1
- data/lib/kward/workspace.rb +45 -5
- metadata +43 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Namespace for the Kward CLI agent runtime.
|
|
2
|
+
module Kward
|
|
3
|
+
# Terminal transcript rendering helpers.
|
|
4
|
+
class PromptInterface
|
|
5
|
+
# Renderer for transcript entries in the terminal prompt interface.
|
|
6
|
+
module TranscriptRenderer
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def write_stream_block_locked(label, delta, finish: false)
|
|
10
|
+
with_synchronized_output_locked do
|
|
11
|
+
prepare_transcript_output_locked unless @restoring_transcript
|
|
12
|
+
if label && @stream_state.block != label
|
|
13
|
+
ensure_transcript_block_separator_locked
|
|
14
|
+
write_transcript_text_locked("#{colored("#{transcript_label(label)}>", label_color(label), :bold)}\n")
|
|
15
|
+
@stream_state.start_block(label)
|
|
16
|
+
end
|
|
17
|
+
write_transcript_text_locked(delta) unless delta.empty?
|
|
18
|
+
write_transcript_text_locked("\n") if finish && @stream_state.block
|
|
19
|
+
@stream_state.finish_block if finish
|
|
20
|
+
restore_composer_cursor_locked unless @restoring_transcript
|
|
21
|
+
end
|
|
22
|
+
@output_io.flush unless @restoring_transcript
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def write_transcript_text_locked(text)
|
|
26
|
+
append_transcript_buffer(text.to_s)
|
|
27
|
+
remember_transcript_viewport_locked unless text.to_s.empty?
|
|
28
|
+
write_visual_transcript_text_locked(text)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def write_visual_transcript_text_locked(text)
|
|
32
|
+
width, height = screen_size
|
|
33
|
+
output_text = terminal_newlines(text.to_s)
|
|
34
|
+
advance_pending_stream_wrap_locked(output_text, width: width, height: height)
|
|
35
|
+
@output_io.print(output_text)
|
|
36
|
+
update_stream_position(output_text, width: width)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def append_transcript_buffer(text)
|
|
40
|
+
@transcript_buffer.append(text.to_s)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def invalidate_transcript_display_rows_cache
|
|
44
|
+
@transcript_buffer.invalidate_display_rows_cache
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def ensure_transcript_block_separator_locked
|
|
48
|
+
return if @transcript_buffer.empty? || @transcript_buffer.end_with?("\n\n")
|
|
49
|
+
|
|
50
|
+
write_transcript_text_locked(@transcript_buffer.end_with?("\n") ? "\n" : "\n\n")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def terminal_newlines(text)
|
|
54
|
+
text.gsub(/\r\n|\r|\n/, "\r\n")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def redraw_transcript_locked(width: screen_width, height: screen_height)
|
|
58
|
+
return unless transcript_renderable?
|
|
59
|
+
|
|
60
|
+
rows = transcript_viewport_rows(transcript_redraw_row_count(height), width)
|
|
61
|
+
clear_screen_rows_locked(1, rows.length)
|
|
62
|
+
return if rows.empty?
|
|
63
|
+
|
|
64
|
+
move_to_screen(1, 1)
|
|
65
|
+
@output_io.print(terminal_newlines(rows.join("\n")))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def transcript_viewport_text(row_count, width)
|
|
69
|
+
transcript_viewport_rows(row_count, width).join("\n")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def transcript_viewport_rows(row_count, width)
|
|
73
|
+
return [] unless row_count.positive?
|
|
74
|
+
|
|
75
|
+
rows = transcript_display_rows(width).last(row_count)
|
|
76
|
+
rows = ([""] * (row_count - rows.length)) + rows if rows.length < row_count
|
|
77
|
+
rows
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def remember_transcript_viewport_locked(height = screen_height)
|
|
81
|
+
@transcript_viewport_rows = transcript_bottom_row(height)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def transcript_renderable?
|
|
85
|
+
@visual_banner_count.positive? || !@transcript_buffer.empty?
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def transcript_display_rows(width)
|
|
89
|
+
@transcript_buffer.display_rows(width, visual_banner_count: @visual_banner_count, banner_rows: method(:banner_rows))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def transcript_text_display_rows(width)
|
|
93
|
+
@transcript_buffer.text_display_rows(width)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def reset_stream_position_from_transcript_locked(width = screen_width)
|
|
97
|
+
@stream_state.reset_position_from_rows(transcript_display_rows(width), width)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def move_to_transcript_cursor_locked(width: screen_width, height: screen_height)
|
|
101
|
+
if @stream_state.pending_wrap?
|
|
102
|
+
move_to_screen(transcript_bottom_row(height), width)
|
|
103
|
+
else
|
|
104
|
+
move_to_screen(transcript_bottom_row(height), [@stream_state.col + 1, width].min)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def advance_pending_stream_wrap_locked(output_text, width: screen_width, height: screen_height)
|
|
109
|
+
return unless @stream_state.pending_wrap?
|
|
110
|
+
return if output_text.empty? || output_text.start_with?("\r", "\n")
|
|
111
|
+
|
|
112
|
+
move_to_screen(transcript_bottom_row(height), width)
|
|
113
|
+
@output_io.print("\r\n")
|
|
114
|
+
@stream_state.clear_pending_wrap
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def update_stream_position(text, width: screen_width)
|
|
118
|
+
@stream_state.update_position(text, width: width)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def transcript_label(label)
|
|
122
|
+
label == "Assistant" ? @assistant_label : label
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def label_color(label)
|
|
126
|
+
case label
|
|
127
|
+
when "Reasoning"
|
|
128
|
+
:yellow
|
|
129
|
+
when "Assistant", "Kward"
|
|
130
|
+
:green
|
|
131
|
+
when "Tool"
|
|
132
|
+
:magenta
|
|
133
|
+
when "Tool output"
|
|
134
|
+
:cyan
|
|
135
|
+
else
|
|
136
|
+
:blue
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|