kward 0.71.0 → 0.72.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 +41 -1
- data/Gemfile.lock +2 -2
- data/README.md +4 -0
- data/doc/agent-tools.md +15 -6
- data/doc/authentication.md +22 -1
- data/doc/code-search.md +42 -2
- data/doc/configuration.md +106 -3
- data/doc/context-budgeting.md +136 -0
- data/doc/context-tools.md +16 -3
- data/doc/editor.md +394 -0
- data/doc/extensibility.md +16 -7
- data/doc/files.md +100 -0
- data/doc/getting-started.md +25 -18
- data/doc/git.md +122 -0
- data/doc/memory.md +24 -4
- data/doc/personas.md +34 -5
- data/doc/plugins.md +72 -1
- data/doc/releasing.md +37 -9
- data/doc/rpc.md +74 -4
- data/doc/session-management.md +35 -1
- data/doc/shell.md +286 -0
- data/doc/tabs.md +122 -0
- data/doc/troubleshooting.md +77 -1
- data/doc/usage.md +53 -7
- data/doc/web-search.md +12 -4
- data/doc/workspace-tools.md +51 -12
- data/examples/plugins/space_invaders.rb +377 -0
- data/lib/kward/agent.rb +1 -1
- data/lib/kward/cli/commands.rb +33 -2
- data/lib/kward/cli/git.rb +150 -0
- data/lib/kward/cli/interactive_turn.rb +73 -9
- data/lib/kward/cli/plugins.rb +54 -4
- data/lib/kward/cli/prompt_interface.rb +32 -1
- data/lib/kward/cli/runtime_helpers.rb +133 -3
- data/lib/kward/cli/sessions.rb +2 -2
- data/lib/kward/cli/settings.rb +218 -9
- data/lib/kward/cli/slash_commands.rb +415 -2
- data/lib/kward/cli/tabs.rb +695 -0
- data/lib/kward/cli.rb +158 -26
- data/lib/kward/config_files.rb +123 -1
- data/lib/kward/context_budget_meter.rb +44 -0
- data/lib/kward/conversation.rb +12 -4
- data/lib/kward/editor_mode.rb +25 -0
- data/lib/kward/ekwsh.rb +362 -0
- data/lib/kward/plugin_registry.rb +61 -0
- data/lib/kward/project_files.rb +52 -0
- data/lib/kward/prompt_history.rb +82 -0
- data/lib/kward/prompt_interface/composer_controller.rb +69 -1
- data/lib/kward/prompt_interface/composer_renderer.rb +109 -13
- data/lib/kward/prompt_interface/composer_state.rb +96 -27
- data/lib/kward/prompt_interface/editor/auto_close_pairs.rb +123 -0
- data/lib/kward/prompt_interface/editor/auto_indent.rb +509 -0
- data/lib/kward/prompt_interface/editor/buffer.rb +109 -0
- data/lib/kward/prompt_interface/editor/controller.rb +1018 -0
- data/lib/kward/prompt_interface/editor/endwise.rb +321 -0
- data/lib/kward/prompt_interface/editor/file_marker.rb +40 -0
- data/lib/kward/prompt_interface/editor/indent_navigation.rb +61 -0
- data/lib/kward/prompt_interface/editor/kill_ring.rb +78 -0
- data/lib/kward/prompt_interface/editor/modes/emacs.rb +259 -0
- data/lib/kward/prompt_interface/editor/modes/modern.rb +353 -0
- data/lib/kward/prompt_interface/editor/modes/vibe.rb +1962 -0
- data/lib/kward/prompt_interface/editor/renderer.rb +243 -0
- data/lib/kward/prompt_interface/editor/search.rb +76 -0
- data/lib/kward/prompt_interface/editor/selections.rb +120 -0
- data/lib/kward/prompt_interface/editor/state.rb +1249 -0
- data/lib/kward/prompt_interface/editor/status_text.rb +23 -0
- data/lib/kward/prompt_interface/editor/syntax_highlighter.rb +420 -0
- data/lib/kward/prompt_interface/editor/undo_history.rb +46 -0
- data/lib/kward/prompt_interface/editor/vibe_state.rb +44 -0
- data/lib/kward/prompt_interface/file_overlay.rb +211 -0
- data/lib/kward/prompt_interface/git_prompt.rb +299 -0
- data/lib/kward/prompt_interface/interactive/controller.rb +186 -0
- data/lib/kward/prompt_interface/interactive/renderer.rb +71 -0
- data/lib/kward/prompt_interface/interactive/state.rb +62 -0
- data/lib/kward/prompt_interface/key_handler.rb +387 -35
- data/lib/kward/prompt_interface/overlay_renderer.rb +21 -2
- data/lib/kward/prompt_interface/project_browser.rb +524 -0
- data/lib/kward/prompt_interface/question_prompt.rb +98 -50
- data/lib/kward/prompt_interface/runtime_state.rb +43 -0
- data/lib/kward/prompt_interface/screen.rb +16 -0
- data/lib/kward/prompt_interface/selection_prompt.rb +7 -13
- data/lib/kward/prompt_interface/stream_state.rb +7 -0
- data/lib/kward/prompt_interface/transcript_buffer.rb +6 -0
- data/lib/kward/prompt_interface.rb +286 -8
- data/lib/kward/prompts/commands.rb +5 -0
- data/lib/kward/prompts.rb +2 -0
- data/lib/kward/rpc/server.rb +42 -3
- data/lib/kward/rpc/session_manager.rb +35 -47
- data/lib/kward/rpc/session_tree_rows.rb +9 -115
- data/lib/kward/rpc/tool_event_normalizer.rb +1 -1
- data/lib/kward/session_store.rb +44 -0
- data/lib/kward/session_tree_nodes.rb +136 -0
- data/lib/kward/session_tree_renderer.rb +9 -131
- data/lib/kward/tab_store.rb +47 -0
- data/lib/kward/text_boundary.rb +25 -0
- data/lib/kward/tools/context_budget_stats.rb +54 -0
- data/lib/kward/tools/context_for_task.rb +202 -0
- data/lib/kward/tools/read_file.rb +8 -4
- data/lib/kward/tools/registry.rb +62 -16
- data/lib/kward/tools/tool_call.rb +10 -0
- data/lib/kward/version.rb +1 -1
- data/lib/kward/workers/git_guard.rb +68 -0
- data/lib/kward/workers/live_view.rb +49 -0
- data/lib/kward/workers/manager.rb +288 -0
- data/lib/kward/workers/store.rb +72 -0
- data/lib/kward/workers/tool_policy.rb +23 -0
- data/lib/kward/workers/worker.rb +82 -0
- data/lib/kward/workers/write_lock.rb +38 -0
- data/lib/kward/workers.rb +7 -0
- data/lib/kward/workspace.rb +110 -24
- data/templates/default/fulldoc/html/css/kward.css +107 -36
- data/templates/default/kward_navigation.rb +12 -1
- data/templates/default/layout/html/layout.erb +4 -2
- data/templates/default/layout/html/setup.rb +6 -0
- metadata +53 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Namespace for the Kward CLI agent runtime.
|
|
2
|
+
module Kward
|
|
3
|
+
# Interactive terminal UI used by the CLI frontend.
|
|
4
|
+
class PromptInterface
|
|
5
|
+
# Renderer for interactive mode canvas frames. Draws the canvas buffer into
|
|
6
|
+
# the composer region using the same boxed-row infrastructure as the editor.
|
|
7
|
+
module InteractiveRenderer
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def interactive_active_locked?
|
|
11
|
+
!@interactive_state.nil?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def interactive_layout(width, height = screen_height)
|
|
15
|
+
state = @interactive_state
|
|
16
|
+
controller = state[:controller]
|
|
17
|
+
rows = [interactive_top_border(width, state)]
|
|
18
|
+
content_width = [width - 4, 1].max
|
|
19
|
+
canvas_width = [content_width - 2, 1].max
|
|
20
|
+
|
|
21
|
+
controller.cells.each do |cell_row|
|
|
22
|
+
line = cell_row[0, canvas_width].map do |cell|
|
|
23
|
+
char = cell[:char]
|
|
24
|
+
colors = cell[:colors]
|
|
25
|
+
colors.empty? ? char : colored(char, *colors)
|
|
26
|
+
end.join
|
|
27
|
+
rows << box_content_row(visible_ljust(line, content_width), content_width)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
rows << footer_row(content_width, interactive_status_text(state))
|
|
31
|
+
rows.concat(interactive_bottom_rows(width))
|
|
32
|
+
cursor_row = 1
|
|
33
|
+
cursor_col = 2
|
|
34
|
+
[rows, cursor_row, cursor_col]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def interactive_top_border(width, state)
|
|
38
|
+
title = visible_truncate(state[:title].to_s, [width - 4, 1].max)
|
|
39
|
+
plain_title = ANSI.strip(title)
|
|
40
|
+
"#{colored("╭", :primary_green)} #{title} #{colored("─" * [width - plain_title.length - 4, 0].max, :primary_green)}#{colored("╮", :primary_green)}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def interactive_status_text(state)
|
|
44
|
+
fps = state[:controller].fps
|
|
45
|
+
"Interactive · #{fps.to_i}fps · Ctrl+C exits"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def interactive_bottom_rows(width)
|
|
49
|
+
@tabs.empty? ? [bottom_border(width)] : tab_border_rows(width)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def tick_interactive_locked
|
|
53
|
+
return false unless interactive_active_locked?
|
|
54
|
+
|
|
55
|
+
controller = @interactive_state[:controller]
|
|
56
|
+
return false if controller.exited?
|
|
57
|
+
|
|
58
|
+
now = monotonic_now
|
|
59
|
+
interval = 1.0 / controller.fps
|
|
60
|
+
elapsed = now - @last_interactive_tick
|
|
61
|
+
return false if elapsed < interval
|
|
62
|
+
|
|
63
|
+
steps = (elapsed / interval).floor
|
|
64
|
+
@last_interactive_tick += steps * interval
|
|
65
|
+
result = controller.invoke_tick
|
|
66
|
+
controller.exit if result == :exit
|
|
67
|
+
true
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Namespace for the Kward CLI agent runtime.
|
|
2
|
+
module Kward
|
|
3
|
+
# Interactive terminal UI used by the CLI frontend.
|
|
4
|
+
class PromptInterface
|
|
5
|
+
# State lifecycle for interactive mode. Manages entering and exiting the
|
|
6
|
+
# canvas-based render loop, including composer snapshot save/restore.
|
|
7
|
+
module InteractiveState
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def interactive_canvas_width
|
|
11
|
+
[screen_width - 6, 1].max
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def route_interactive_key(key)
|
|
15
|
+
return false unless interactive_active_locked?
|
|
16
|
+
|
|
17
|
+
interactive_key = interactive_csi_u_key(key)
|
|
18
|
+
unless interactive_key == false
|
|
19
|
+
return force_interactive_exit if interactive_key == :force_exit
|
|
20
|
+
|
|
21
|
+
@interactive_state[:controller].push_key(interactive_key)
|
|
22
|
+
return true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
name = key_name_for(key) if key.is_a?(String) && key.length >= 1
|
|
26
|
+
return force_interactive_exit if key == "\x03" || name == :escape
|
|
27
|
+
|
|
28
|
+
@interactive_state[:controller].push_key(name || key)
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def interactive_csi_u_key(key)
|
|
33
|
+
sequence = parse_csi_u_key(key)
|
|
34
|
+
return false unless sequence
|
|
35
|
+
|
|
36
|
+
code = sequence[:code]
|
|
37
|
+
modifier = sequence[:modifier]
|
|
38
|
+
queue_pending_keys(sequence[:remaining]) if sequence[:remaining] && !sequence[:remaining].empty?
|
|
39
|
+
|
|
40
|
+
return :force_exit if code == 27 || (code.to_i.chr.downcase == "c" && ctrl_modifier?(modifier))
|
|
41
|
+
return :return if code == 13
|
|
42
|
+
return :backspace if [8, 127].include?(code)
|
|
43
|
+
return :space if code == 32 && !ctrl_modifier?(modifier) && !alt_modifier?(modifier) && !super_modifier?(modifier)
|
|
44
|
+
|
|
45
|
+
text = csi_u_printable_text(sequence)
|
|
46
|
+
return text if text
|
|
47
|
+
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def force_interactive_exit
|
|
52
|
+
@interactive_state[:controller].force_exit
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def handle_interactive_key(key)
|
|
57
|
+
route_interactive_key(key)
|
|
58
|
+
nil
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|