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.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -1
  3. data/Gemfile.lock +2 -2
  4. data/README.md +4 -0
  5. data/doc/agent-tools.md +15 -6
  6. data/doc/authentication.md +22 -1
  7. data/doc/code-search.md +42 -2
  8. data/doc/configuration.md +106 -3
  9. data/doc/context-budgeting.md +136 -0
  10. data/doc/context-tools.md +16 -3
  11. data/doc/editor.md +394 -0
  12. data/doc/extensibility.md +16 -7
  13. data/doc/files.md +100 -0
  14. data/doc/getting-started.md +25 -18
  15. data/doc/git.md +122 -0
  16. data/doc/memory.md +24 -4
  17. data/doc/personas.md +34 -5
  18. data/doc/plugins.md +72 -1
  19. data/doc/releasing.md +37 -9
  20. data/doc/rpc.md +74 -4
  21. data/doc/session-management.md +35 -1
  22. data/doc/shell.md +286 -0
  23. data/doc/tabs.md +122 -0
  24. data/doc/troubleshooting.md +77 -1
  25. data/doc/usage.md +53 -7
  26. data/doc/web-search.md +12 -4
  27. data/doc/workspace-tools.md +51 -12
  28. data/examples/plugins/space_invaders.rb +377 -0
  29. data/lib/kward/agent.rb +1 -1
  30. data/lib/kward/cli/commands.rb +33 -2
  31. data/lib/kward/cli/git.rb +150 -0
  32. data/lib/kward/cli/interactive_turn.rb +73 -9
  33. data/lib/kward/cli/plugins.rb +54 -4
  34. data/lib/kward/cli/prompt_interface.rb +32 -1
  35. data/lib/kward/cli/runtime_helpers.rb +133 -3
  36. data/lib/kward/cli/sessions.rb +2 -2
  37. data/lib/kward/cli/settings.rb +218 -9
  38. data/lib/kward/cli/slash_commands.rb +415 -2
  39. data/lib/kward/cli/tabs.rb +695 -0
  40. data/lib/kward/cli.rb +158 -26
  41. data/lib/kward/config_files.rb +123 -1
  42. data/lib/kward/context_budget_meter.rb +44 -0
  43. data/lib/kward/conversation.rb +12 -4
  44. data/lib/kward/editor_mode.rb +25 -0
  45. data/lib/kward/ekwsh.rb +362 -0
  46. data/lib/kward/plugin_registry.rb +61 -0
  47. data/lib/kward/project_files.rb +52 -0
  48. data/lib/kward/prompt_history.rb +82 -0
  49. data/lib/kward/prompt_interface/composer_controller.rb +69 -1
  50. data/lib/kward/prompt_interface/composer_renderer.rb +109 -13
  51. data/lib/kward/prompt_interface/composer_state.rb +96 -27
  52. data/lib/kward/prompt_interface/editor/auto_close_pairs.rb +123 -0
  53. data/lib/kward/prompt_interface/editor/auto_indent.rb +509 -0
  54. data/lib/kward/prompt_interface/editor/buffer.rb +109 -0
  55. data/lib/kward/prompt_interface/editor/controller.rb +1018 -0
  56. data/lib/kward/prompt_interface/editor/endwise.rb +321 -0
  57. data/lib/kward/prompt_interface/editor/file_marker.rb +40 -0
  58. data/lib/kward/prompt_interface/editor/indent_navigation.rb +61 -0
  59. data/lib/kward/prompt_interface/editor/kill_ring.rb +78 -0
  60. data/lib/kward/prompt_interface/editor/modes/emacs.rb +259 -0
  61. data/lib/kward/prompt_interface/editor/modes/modern.rb +353 -0
  62. data/lib/kward/prompt_interface/editor/modes/vibe.rb +1962 -0
  63. data/lib/kward/prompt_interface/editor/renderer.rb +243 -0
  64. data/lib/kward/prompt_interface/editor/search.rb +76 -0
  65. data/lib/kward/prompt_interface/editor/selections.rb +120 -0
  66. data/lib/kward/prompt_interface/editor/state.rb +1249 -0
  67. data/lib/kward/prompt_interface/editor/status_text.rb +23 -0
  68. data/lib/kward/prompt_interface/editor/syntax_highlighter.rb +420 -0
  69. data/lib/kward/prompt_interface/editor/undo_history.rb +46 -0
  70. data/lib/kward/prompt_interface/editor/vibe_state.rb +44 -0
  71. data/lib/kward/prompt_interface/file_overlay.rb +211 -0
  72. data/lib/kward/prompt_interface/git_prompt.rb +299 -0
  73. data/lib/kward/prompt_interface/interactive/controller.rb +186 -0
  74. data/lib/kward/prompt_interface/interactive/renderer.rb +71 -0
  75. data/lib/kward/prompt_interface/interactive/state.rb +62 -0
  76. data/lib/kward/prompt_interface/key_handler.rb +387 -35
  77. data/lib/kward/prompt_interface/overlay_renderer.rb +21 -2
  78. data/lib/kward/prompt_interface/project_browser.rb +524 -0
  79. data/lib/kward/prompt_interface/question_prompt.rb +98 -50
  80. data/lib/kward/prompt_interface/runtime_state.rb +43 -0
  81. data/lib/kward/prompt_interface/screen.rb +16 -0
  82. data/lib/kward/prompt_interface/selection_prompt.rb +7 -13
  83. data/lib/kward/prompt_interface/stream_state.rb +7 -0
  84. data/lib/kward/prompt_interface/transcript_buffer.rb +6 -0
  85. data/lib/kward/prompt_interface.rb +286 -8
  86. data/lib/kward/prompts/commands.rb +5 -0
  87. data/lib/kward/prompts.rb +2 -0
  88. data/lib/kward/rpc/server.rb +42 -3
  89. data/lib/kward/rpc/session_manager.rb +35 -47
  90. data/lib/kward/rpc/session_tree_rows.rb +9 -115
  91. data/lib/kward/rpc/tool_event_normalizer.rb +1 -1
  92. data/lib/kward/session_store.rb +44 -0
  93. data/lib/kward/session_tree_nodes.rb +136 -0
  94. data/lib/kward/session_tree_renderer.rb +9 -131
  95. data/lib/kward/tab_store.rb +47 -0
  96. data/lib/kward/text_boundary.rb +25 -0
  97. data/lib/kward/tools/context_budget_stats.rb +54 -0
  98. data/lib/kward/tools/context_for_task.rb +202 -0
  99. data/lib/kward/tools/read_file.rb +8 -4
  100. data/lib/kward/tools/registry.rb +62 -16
  101. data/lib/kward/tools/tool_call.rb +10 -0
  102. data/lib/kward/version.rb +1 -1
  103. data/lib/kward/workers/git_guard.rb +68 -0
  104. data/lib/kward/workers/live_view.rb +49 -0
  105. data/lib/kward/workers/manager.rb +288 -0
  106. data/lib/kward/workers/store.rb +72 -0
  107. data/lib/kward/workers/tool_policy.rb +23 -0
  108. data/lib/kward/workers/worker.rb +82 -0
  109. data/lib/kward/workers/write_lock.rb +38 -0
  110. data/lib/kward/workers.rb +7 -0
  111. data/lib/kward/workspace.rb +110 -24
  112. data/templates/default/fulldoc/html/css/kward.css +107 -36
  113. data/templates/default/kward_navigation.rb +12 -1
  114. data/templates/default/layout/html/layout.erb +4 -2
  115. data/templates/default/layout/html/setup.rb +6 -0
  116. metadata +53 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c53686afdfbf5de822759d70cb696e911cae8c5ffc7b5ce63e07306dc4ffaac
4
- data.tar.gz: '086c43642ad0149e3986277b7424b55f2dc50689a0e876c72e6bb9fd48e4272b'
3
+ metadata.gz: 32f9966cff49fb90d0c11f20277e77186fe439ede174a3d151a2a3dfdcddc726
4
+ data.tar.gz: ebcdfd83477ce0e90857019a67f8bfdf57f2f2e9cb4e7accdd89b790d6002b5c
5
5
  SHA512:
6
- metadata.gz: 97ebbbf26feedc4dd46d53d7af8b900670edf861cb40f6103eff5ea8579d605517cab49751ea5fe46c4023fa7ba8ced367d31290b34af463fd0cc8f1a9a1087e
7
- data.tar.gz: 424ac657d7efc70f2b87924914112c0910937deee7e4ec6521448ff4fe51967a58203de9693fb8989adea63fb23adef93668333c8bb5eb22963bff49e7420875
6
+ metadata.gz: 9c625a36cf64cb7348f1ff14a07bd27e6b311bcd2d5b219669885d105118977143f17d1321d0acfefddc81469c0a11311868b8e8905d2d5a68339065dddf0513
7
+ data.tar.gz: 7de5e8b2887d654d57bd2032fa86b4fad7b3c0859d74d323e4d9f44cd682b7f7b616a11858e5e20bb4f2cc5a829d3746f94576fb114a35504581a45a66adbb16
data/CHANGELOG.md CHANGED
@@ -2,7 +2,47 @@
2
2
 
3
3
  All notable changes to Kward will be documented in this file.
4
4
 
5
- ## [Unreleased]
5
+ ## [0.72.0] - 2026-06-28
6
+
7
+ ### Added
8
+
9
+ - Added a built-in editor that can be opened from the TUI with `$` or directly from the CLI with `kward edit <filename>`, with modern, Emacs-style, and Vibe editing modes.
10
+ - Added richer editor workflows including syntax highlighting, undo/redo, auto-indent, soft wrap, mouse support, multi-cursor editing, relative line numbers, and an expanded Vim-like Vibe mode with visual selections, text objects, registers, marks, macros, substitution, and Ruby navigation.
11
+ - Added `/shell`, an embedded Kward shell (`ekwsh`) for running workspace commands without leaving the TUI, including command/path completion, safe color output, optional global `ekwsh.yml` configuration, and rbenv shim autodetection.
12
+ - Added `/files`, a searchable project file browser that can open files in the editor and remembers cursor and folder expansion state per workspace.
13
+ - Added persistent TUI tabs for session-backed conversations, plus tab commands, shortcuts, status colors, and restoration across restarts.
14
+ - Added `/git` workflows for reviewing changes, viewing diffs, staging or unstaging files, and writing commit messages from inside the TUI.
15
+ - Added TUI composer improvements including `@` file mentions, persistent workspace prompt history with Ctrl+R search, and Tab/Shift+Tab reasoning-effort cycling.
16
+ - Added CLI execution modes via `--mode auto|chat|oneshot|filter` and `--filter` for transforming piped input.
17
+ - Added context-budgeting tools and workflows, including `read_file` modes, richer source outlines, `context_for_task`, `context_budget_stats`, and restored compacted tool-output inspection.
18
+ - Added interactive plugin commands backed by a Kward-driven canvas render loop.
19
+ - Added experimental agent-worker support behind the existing experimental workflow.
20
+ - Added new and expanded guides for editor usage, tabs, project files, Git workflows, agent tools, context budgeting, workspace tools, web search, code search, plugins, RPC, authentication, memory, sessions, troubleshooting, and releasing.
21
+
22
+ ### Changed
23
+
24
+ - Changed the built-in editor to use the modern editing mode by default, with smarter indentation and improved keyboard handling across terminal encodings.
25
+ - Improved TUI interaction polish across pickers, tabs, editor rendering, Git workflows, composer refresh behavior, mouse handling, and modal input isolation.
26
+ - Improved embedded shell environment handling so Kward-managed environment values are preserved while workspace shell conveniences still work.
27
+ - Improved RPC and session internals around steering events, session cleanup, worker metadata, session-tree traversal, and config updates.
28
+ - Improved tool-output context budgeting so agents start with focused context, preserve inspectable originals, and report active-conversation savings more accurately.
29
+ - Expanded documentation and generated-doc navigation to better reflect current workflows and configuration options.
30
+
31
+ ### Fixed
32
+
33
+ - Fixed embedded-shell completion, environment preservation, and rbenv handling issues.
34
+ - Fixed editor and TUI input edge cases involving shifted keys, CSI-u encodings, Command/Ctrl shortcuts, selection preservation, mouse scrolling, tab switching, modal questions, and commit-message editing.
35
+ - Fixed many built-in editor behaviors around selection rendering, cursor movement, soft wrap, indentation, deletion/change operations, undo/search behavior, macro recording, registers, text objects, visual mode, and viewport positioning.
36
+ - Fixed Git overlay staging and commit-message behavior.
37
+ - Fixed session, tab, and worker state issues including tab restoration, session cleanup, worker handoff, foreground write locks, and plugin/test isolation.
38
+ - Fixed RPC steering, tool-output restoration, context-budget statistics, and session-manager lifecycle behavior.
39
+ - Fixed documentation rendering, navigation, tables, quote styling, and generated guide layout issues.
40
+ - Fixed persona time-of-day handling to use the current local time.
41
+
42
+ ### Removed
43
+
44
+ - Removed the placeholder message from `/status` output.
45
+ - Removed unused RPC session helpers and temporarily hid worker labels behind the experimental worker flow.
6
46
 
7
47
  ## [0.71.0] - 2026-06-21
8
48
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kward (0.71.0)
4
+ kward (0.72.0)
5
5
  base64
6
6
  nokogiri
7
7
  tiktoken_ruby
@@ -146,7 +146,7 @@ CHECKSUMS
146
146
  html-proofer (5.2.1) sha256=fdd958a7cbf9c3255fb96fe7cfc4e611f64e2706e469488a3326309ad007d2fd
147
147
  io-event (1.16.2) sha256=9f9cb0a96ea5c3850a672606c65f27bc96d7621399ef6196acbfe2be0cd1279c
148
148
  json (2.19.9) sha256=9b9025b7cdddafa38d316eca0b2358488e42d417045c1b90d216a9fefe46b79a
149
- kward (0.71.0)
149
+ kward (0.72.0)
150
150
  logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
151
151
  metrics (0.15.0) sha256=61ded5bac95118e995b1bc9ed4a5f19bc9814928a312a85b200abbdac9039072
152
152
  minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1
data/README.md CHANGED
@@ -78,6 +78,9 @@ Start here:
78
78
  Feature guides:
79
79
 
80
80
  - [Sessions](doc/session-management.md): resume, clone, fork, rewind, compact, and navigate saved work.
81
+ - [Integrated Editor](doc/editor.md): open files from the composer, edit in-place, and choose editor keybindings.
82
+ - [Git](doc/git.md): review changes, use the diff viewer, stage files, and commit from the interactive TUI.
83
+ - [Shell](doc/shell.md): use `/shell`, the embedded Kward shell with aliases, completion, and per-tab state.
81
84
  - [Memory](doc/memory.md): opt-in core, soft, and session memory.
82
85
  - [Personas](doc/personas.md): configure Kward's tone and role by default, workspace, model, reasoning effort, time, and weekday.
83
86
 
@@ -89,6 +92,7 @@ Advanced:
89
92
  - [Releasing](doc/releasing.md): release checklist for RubyGems publishing.
90
93
  - [Agent tools](doc/agent-tools.md): overview of model-callable tools, token-saving behavior, and tool categories.
91
94
  - [Workspace tools](doc/workspace-tools.md): local file, edit, and shell command tools.
95
+ - [Context budgeting](doc/context-budgeting.md): focused context gathering, budgeted reads, output compaction, and token-saving history.
92
96
  - [Web search](doc/web-search.md): live search providers and network behavior for the web search agent tool.
93
97
  - [Code search](doc/code-search.md): package lookup, GitHub repository cache, and external source reading for the code search agent tool.
94
98
  - [Context tools](doc/context-tools.md): skills, compacted output retrieval, and structured clarification questions.
data/doc/agent-tools.md CHANGED
@@ -6,8 +6,9 @@ Tools are part of Kward's safety and context-management boundary:
6
6
 
7
7
  - schemas describe what the model is allowed to call,
8
8
  - Ruby tool objects validate and execute those calls,
9
- - workspace tools stay inside the active workspace by default,
9
+ - workspace tools stay inside the active workspace by default (see [Configuration](configuration.md) for the guardrail setting),
10
10
  - file-changing tools require the file to be read first,
11
+ - mutation tools (`edit_file`, `write_file`, `run_shell_command`) are gated by a write lock when agent workers are active, so only one worker can change the workspace at a time,
11
12
  - large outputs are bounded or compacted before they enter model context,
12
13
  - full tool outputs are kept in the session record for later inspection.
13
14
 
@@ -15,22 +16,26 @@ Tools are part of Kward's safety and context-management boundary:
15
16
 
16
17
  | Category | Tools | Guide |
17
18
  | --- | --- | --- |
18
- | Workspace tools | `list_directory`, `read_file`, `summarize_file_structure`, `write_file`, `edit_file`, `run_shell_command` | [Workspace tools](workspace-tools.md) |
19
+ | Workspace tools | `list_directory`, `read_file`, `context_for_task`, `context_budget_stats`, `summarize_file_structure`, `write_file`, `edit_file`, `run_shell_command` | [Workspace tools](workspace-tools.md) |
19
20
  | Web tools | `web_search`, `fetch_content`, `fetch_raw` | [Web search](web-search.md) |
20
21
  | Code search | `code_search` | [Code search](code-search.md) |
21
22
  | Context and interaction tools | `read_skill`, `retrieve_tool_output`, `ask_user_question` | [Context tools](context-tools.md) |
22
23
 
23
24
  ## How tools save tokens
24
25
 
25
- Kward tries to keep tool context useful without flooding the model:
26
+ Kward tries to keep tool context useful without flooding the model. The built-in prompt tells Kward to start with focused context tools and escalate from outlines/previews to exact ranges before full-file reads:
26
27
 
27
- - `read_file` reads bounded line ranges and supports continuation with `offset` and `limit`.
28
+ - `read_file` reads bounded line ranges, supports continuation with `offset` and `limit`, and accepts explicit `preview`, `outline`, `range`, and `full` modes with optional per-call byte budgets.
29
+ - `context_for_task` builds a task-shaped bundle from ranked files, outlines, and matching excerpts within a caller-supplied byte budget.
30
+ - `context_budget_stats` reports approximate active-conversation bytes and estimated tokens saved by compaction and duplicate output replacement.
28
31
  - `summarize_file_structure` returns a compact outline for large source files before reading all code.
29
32
  - Search, fetch, and shell outputs are capped or compacted before model ingestion.
30
33
  - Repeated identical tool output is replaced with a short reference instead of being sent again.
31
- - Compacted outputs are stored as artifacts that can be reopened with `retrieve_tool_output`.
34
+ - Compacted outputs are stored as artifacts that can be reopened with `retrieve_tool_output`, including after resuming a saved session that contains the original tool execution record.
32
35
 
33
- This lets the assistant reason from focused evidence while preserving access to original outputs when needed.
36
+ When a tool output exceeds 12 KB, Kward compacts it before sending it to the model. The compactor preserves the first 40 and last 40 lines, keeps lines matching error, test, or search-result patterns with 2 lines of surrounding context, and replaces omitted sections with `[... omitted lines ...]` markers. Shell command output is section-aware: STDOUT and STDERR sections are compacted separately. Compacted outputs include a header with the original and compacted byte counts and the artifact ID for retrieval. Error outputs under 8 KB are left intact so failure details stay visible.
37
+
38
+ This lets the assistant reason from focused evidence while preserving access to original outputs when needed. For a fuller overview of Kward's context budgeting and token-saving work, see [Context budgeting](context-budgeting.md).
34
39
 
35
40
  ## How tools are exposed
36
41
 
@@ -40,4 +45,8 @@ This lets the assistant reason from focused evidence while preserving access to
40
45
  - `read_skill` is advertised only when skills are available,
41
46
  - `ask_user_question` is advertised only when the frontend can display structured questions.
42
47
 
48
+ When agent workers are active, the registry can scope each worker to a subset of tools via an allowed-tool-names filter, so workers only see the tools they need.
49
+
50
+ When `write_file` or `edit_file` changes an `AGENTS.md` file in the workspace root, Kward automatically rebuilds the system message so the model picks up the new instructions without a restart.
51
+
43
52
  Unknown tool calls are recorded as tool results instead of crashing the session, so the model can recover and choose an advertised tool on the next turn.
@@ -12,6 +12,8 @@ Or inside interactive Kward:
12
12
  /login
13
13
  ```
14
14
 
15
+ `/login` opens a provider picker; `kward login` accepts the provider as an argument.
16
+
15
17
  Use the provider you already have access to. You can change the active model later with `/model`.
16
18
 
17
19
  ## Choose a provider
@@ -56,6 +58,14 @@ If Kward asks for an OAuth client ID, add it to `~/.kward/config.json`:
56
58
  }
57
59
  ```
58
60
 
61
+ Kward ships with a built-in client ID, so this is only needed if login fails or you want to use your own.
62
+
63
+ For a single shell session without OAuth, you can set an access token directly:
64
+
65
+ ```bash
66
+ OPENAI_ACCESS_TOKEN=... kward
67
+ ```
68
+
59
69
  ## Anthropic Claude Pro/Max
60
70
 
61
71
  ```bash
@@ -151,10 +161,21 @@ The model picker is the normal way to switch between configured providers and mo
151
161
 
152
162
  For one-off shell runs, `KWARD_PROVIDER` and provider-specific model environment variables remain available. See [Configuration](configuration.md) for the full list.
153
163
 
164
+ ## Custom auth file locations
165
+
166
+ Each auth file has an environment variable override, useful for isolated or multi-account setups. When unset, they default to the paths shown above under `~/.kward/`.
167
+
168
+ - `KWARD_AUTH_PATH` — OpenAI OAuth credentials (`auth.json`)
169
+ - `KWARD_ANTHROPIC_AUTH_PATH` — Anthropic OAuth credentials (`anthropic_auth.json`)
170
+ - `KWARD_GITHUB_AUTH_PATH` — GitHub OAuth credentials (`github_auth.json`)
171
+
172
+ When `KWARD_CONFIG_PATH` points at a custom config file, the OpenRouter API key is stored in that file instead of `~/.kward/config.json`.
173
+
154
174
  ## Security notes
155
175
 
156
176
  - Auth files are written with file mode `0600` when possible.
157
177
  - Do not commit `~/.kward/config.json` or auth files.
158
178
  - Prefer environment variables for temporary credentials.
159
179
  - `kward auth status` shows credential status without printing secrets.
160
- - `kward auth logout` removes saved credentials.
180
+ - `kward auth logout` removes **all** saved credentials at once: every OAuth file (OpenAI, Anthropic, GitHub) and the stored OpenRouter API key. There is no per-provider logout; to remove a single provider, delete its auth file by hand.
181
+ - `kward doctor` reports which credentials are currently configured alongside other local checks.
data/doc/code-search.md CHANGED
@@ -31,6 +31,18 @@ The `code_search` tool can:
31
31
 
32
32
  Kward should use this when the best answer depends on how another project actually implemented something.
33
33
 
34
+ ## Supported ecosystems
35
+
36
+ `package_search` and `github_search` accept an `ecosystem` parameter to narrow results:
37
+
38
+ - `rubygems` — RubyGems
39
+ - `npm` — npm registry
40
+ - `pypi` — Python Package Index
41
+ - `crates` — crates.io (Rust)
42
+ - `go` — Go module documentation
43
+
44
+ When omitted, `package_search` requires a `package` name and infers the registry from the ecosystem. `github_search` uses the ecosystem as an optional hint alongside the search query.
45
+
34
46
  ## Cache location
35
47
 
36
48
  Repositories are cached outside your workspace:
@@ -63,7 +75,7 @@ or:
63
75
  GH_TOKEN=...
64
76
  ```
65
77
 
66
- Tokens are used for GitHub API requests and are not included in tool output.
78
+ Tokens are used for GitHub API requests and are not included in tool output. See [Configuration](configuration.md) for the full environment variable reference.
67
79
 
68
80
  ## Tool actions
69
81
 
@@ -80,4 +92,32 @@ The tool uses an `action` parameter:
80
92
  | `refresh_cache` | fetch updates for a cached repository. |
81
93
  | `clear_cache` | remove a cached repository. |
82
94
 
83
- Search and read results are bounded so Kward does not load large external repositories into context by accident. Oversized and binary files are skipped.
95
+ ### Action arguments
96
+
97
+ | Action | Required arguments | Optional arguments |
98
+ | --- | --- | --- |
99
+ | `package_search` | `ecosystem`, `package` | — |
100
+ | `github_search` | `query` | `ecosystem`, `max_results` |
101
+ | `repo_clone` | `repo` | — |
102
+ | `repo_search` | `repo`, `query` | `max_results`, `context_lines` |
103
+ | `repo_read` | `repo`, `path` | `start_line`, `line_count` |
104
+ | `list_cache` | — | — |
105
+ | `refresh_cache` | `repo` | — |
106
+ | `clear_cache` | `repo` | — |
107
+
108
+ - `repo` is a GitHub URL or `owner/name`.
109
+ - `query` is a plain-text search string (not regex). Matching is case-sensitive substring.
110
+ - `start_line` is 1-indexed.
111
+ - `context_lines` controls how many lines before and after a match are included in search snippets.
112
+
113
+ ## Limits
114
+
115
+ Search and read results are bounded so Kward does not load large external repositories into context by accident:
116
+
117
+ - Search results: default 10 per query, max 50.
118
+ - Context lines in search snippets: default 2, max 5.
119
+ - Lines returned by `repo_read`: default 200, max 400.
120
+ - File size limit: 512 KB. Files larger than this are skipped during search and rejected on read.
121
+ - Scanned files in `repo_search`: max 5,000 files per scan. Files in `.git` directories, symlinks, files outside the repo root, and oversized files are skipped. Binary files fail gracefully via encoding detection and are skipped.
122
+ - Output truncation: 16 KB total per tool result.
123
+ - HTTP timeout: 10 seconds for all network requests.
data/doc/configuration.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Kward reads user configuration from `~/.kward/config.json` by default. Most users do not need to edit this file by hand at first: use `/login`, `/model`, `/reasoning`, and `/settings` from inside Kward when possible.
4
4
 
5
- On first start, if the file does not exist, Kward creates a starter config with an active Kward persona, explicit disabled memory settings, and the default composer busy-help setting so you can inspect and edit them. Provider-specific model defaults are added only when you choose a provider/model. If `KWARD_CONFIG_PATH` is set, Kward uses that file instead and treats that file's directory as the config directory for prompts, skills, memory, logs, and caches.
5
+ On first start, if the file does not exist, Kward creates a starter config with an active Kward persona, explicit disabled memory settings, and the default composer busy-help setting so you can inspect and edit them. Provider-specific model defaults are added only when you choose a provider/model. See [Personas](personas.md) for configuring persona selection by workspace, model, or reasoning effort. If `KWARD_CONFIG_PATH` is set, Kward uses that file instead and treats that file's directory as the config directory for prompts, skills, memory, logs, and caches.
6
6
 
7
7
  Small examples:
8
8
 
@@ -34,9 +34,31 @@ By default, Kward stores user data under `~/.kward`:
34
34
  ~/.kward/memory/
35
35
  ~/.kward/logs/
36
36
  ~/.kward/cache/
37
+ ~/.kward/plugins/
37
38
  ```
38
39
 
39
- When `KWARD_CONFIG_PATH=/path/to/config.json` is set, most config-related files live beside that file instead. User plugins are the exception: they are loaded only from `~/.kward/plugins`.
40
+ When `KWARD_CONFIG_PATH=/path/to/config.json` is set, most config-related files live beside that file instead. User plugins are the exception: they are loaded only from `~/.kward/plugins`. See [Plugins](plugins.md) for writing and loading user plugins.
41
+
42
+ ## Embedded shell config
43
+
44
+ The embedded Kward shell (`/shell`, internally `ekwsh`) reads optional global settings from `~/.kward/ekwsh.yml` or, when `KWARD_CONFIG_PATH` is set, from `ekwsh.yml` beside that config file.
45
+
46
+ Example:
47
+
48
+ ```yaml
49
+ env:
50
+ FORCE_COLOR: "1"
51
+ CLICOLOR_FORCE: "1"
52
+
53
+ aliases:
54
+ ll: "ls -la"
55
+ gs: "git status --short"
56
+ gd: "git diff --color=always"
57
+ ```
58
+
59
+ `env` values are applied when shell mode starts, after Kward's conservative color defaults. Keys must look like environment variable names (`A_Z`, digits after the first character, and underscores); invalid keys are ignored. Values are converted to strings.
60
+
61
+ `aliases` expand the first word of a command once. For example, `ll lib` runs `ls -la lib`. Built-in `ekwsh` commands such as `cd`, `pwd`, `export`, `unset`, `alias`, `clear`, and `exit` take precedence over aliases. Run `alias` inside `ekwsh` to list configured aliases. Aliases are also included in command-name Tab completion.
40
62
 
41
63
  ## Provider and model settings
42
64
 
@@ -48,6 +70,8 @@ Set `provider` to choose the active backend:
48
70
  }
49
71
  ```
50
72
 
73
+ When `provider` is unset, Kward infers the backend from available credentials, defaulting to OpenAI/Codex when OAuth credentials are present. Set `provider` or `KWARD_PROVIDER` to select another backend explicitly.
74
+
51
75
  Supported values are:
52
76
 
53
77
  - `codex` for the OpenAI/ChatGPT Codex backend.
@@ -73,7 +97,7 @@ Model settings:
73
97
  }
74
98
  ```
75
99
 
76
- `model` is a generic setting for the active provider. Provider-specific values such as `openai_model`, `anthropic_model`, `openrouter_model`, and `copilot_model` take precedence for their provider. `reasoning_effort` and `thinking_level` are generic reasoning settings. `openai_reasoning_effort`, `anthropic_reasoning_effort`, `openrouter_reasoning_effort`, and `copilot_reasoning_effort` are provider-specific forms.
100
+ `model` is a generic setting for the active provider. Provider-specific values such as `openai_model`, `anthropic_model`, `openrouter_model`, and `copilot_model` take precedence for their provider. `reasoning_effort` and `thinking_level` are generic reasoning settings. `thinking_level` is an alias for `reasoning_effort` honored by all providers. For each provider, Kward resolves reasoning in this order: the provider-specific key (for example `openai_reasoning_effort`), then the generic `reasoning_effort`, then `thinking_level`, then the default `medium`. `openai_reasoning_effort`, `anthropic_reasoning_effort`, `openrouter_reasoning_effort`, and `copilot_reasoning_effort` are provider-specific forms.
77
101
 
78
102
  Defaults:
79
103
 
@@ -162,6 +186,85 @@ The busy composer shows a short Ctrl+C cancellation hint by default. To hide it:
162
186
 
163
187
  This only hides the hint text; Ctrl+C still stops the current running response.
164
188
 
189
+ In the normal composer prompt, `Tab` cycles forward through the current model's reasoning efforts and `Shift+Tab` cycles backward. The shortcuts wrap around and update the persisted reasoning setting; file and slash-command completion overlays keep their existing `Tab` completion behavior.
190
+
191
+ `tab_keybindings` controls how the composer handles tab navigation shortcuts:
192
+
193
+ ```json
194
+ {
195
+ "composer": {
196
+ "tab_keybindings": "auto"
197
+ }
198
+ }
199
+ ```
200
+
201
+ `auto` (default) detects terminal support, `ctrl` uses `Ctrl+Tab`/`Shift+Tab` to cycle suggestions and indent, `alt` uses `Alt+Tab` for terminals where `Ctrl+Tab` is swallowed.
202
+
203
+ ## Editor settings
204
+
205
+ The built-in TUI file editor supports three keybinding modes. Modern is the default:
206
+
207
+ ```json
208
+ {
209
+ "editor": {
210
+ "mode": "modern"
211
+ }
212
+ }
213
+ ```
214
+
215
+ `mode` can be `modern`, `emacs`, or `vibe`. The old `default` value is still accepted as an alias for `modern`. You can change this from `/settings` > Interface > Editor mode; newly opened editor buffers pick up the setting immediately.
216
+
217
+ The editor automatically highlights Ruby, Crystal, Elixir, Julia, JavaScript, TypeScript, JSON, Markdown, YAML, Shell, Makefile, HTML, CSS, SCSS, Python, Go, Rust, Java, C#, C, C++, Swift, Kotlin, Lua, and SQL files when terminal color is enabled. Unknown file types and color-disabled terminals render plain text.
218
+
219
+ Auto-indent is enabled by default. Pressing Enter copies the current line indentation, detects the file's indentation unit when possible, and applies lightweight syntax-based indentation for recognized file types. For Ruby, Crystal, Elixir, Julia, Lua, Makefiles, and shell scripts, Enter after a block opener inserts the matching closing keyword, and Ctrl+Enter can force that behavior from the middle of the line in terminals that report modified Enter keys. When auto-indent is enabled, typing obvious closing tokens such as `}`, Ruby/Lua `end`, and shell `fi`/`done`/`esac` re-indents the current line, and Backspace in leading indentation removes one detected indentation unit. To disable it:
220
+
221
+ ```json
222
+ {
223
+ "editor": {
224
+ "auto_indent": false,
225
+ "auto_close_pairs": false
226
+ }
227
+ }
228
+ ```
229
+
230
+ `auto_indent` and `auto_close_pairs` both default to `true`. Set `auto_close_pairs` to `false` to disable automatic insertion of matching `()`, `[]`, `{}`, quotes, and backticks.
231
+
232
+ Line numbers are absolute by default. Set `line_numbers` to `relative` to show distances from the cursor line in editable buffers while keeping the current cursor line absolute:
233
+
234
+ ```json
235
+ {
236
+ "editor": {
237
+ "line_numbers": "relative"
238
+ }
239
+ }
240
+ ```
241
+
242
+ Soft-wrap is enabled by default so long lines wrap within the editor width instead of scrolling. To disable it:
243
+
244
+ ```json
245
+ {
246
+ "editor": {
247
+ "soft_wrap": false
248
+ }
249
+ }
250
+ ```
251
+
252
+ Editable editor buffers request a vertical bar cursor by default. Terminals that do not support cursor-shape escape sequences ignore this. To keep the terminal's normal cursor shape while editing:
253
+
254
+ ```json
255
+ {
256
+ "editor": {
257
+ "bar_cursor": false
258
+ }
259
+ }
260
+ ```
261
+
262
+ Modern mode uses composer-style keys: `Ctrl+S` saves, `Ctrl+Q` quits, `Ctrl+F` searches, Shift+Arrow selects text, `Ctrl+C` copies, `Ctrl+X` cuts, `Ctrl+V` pastes the editor kill buffer, `Ctrl+A`/`Ctrl+E` move to the start/end of the line, `Ctrl+B` moves left, `Ctrl+K` kills to end of line, `Ctrl+U` kills to start of line, and `Alt+B`/`Alt+F` move by word.
263
+
264
+ Emacs mode uses Emacs-style non-modal keys: `Ctrl+X Ctrl+S` saves, `Ctrl+X Ctrl+C` quits, `Ctrl+S` searches forward, `Ctrl+R` searches backward, `Ctrl+Space` sets the mark, `Ctrl+W` kills the region or previous word, `Alt+W` copies the region, `Ctrl+K` kills to end of line, `Ctrl+Y` yanks, and `Alt+Y` cycles the per-buffer kill ring after a yank.
265
+
266
+ Vibe mode opens files in normal mode and supports a compact classic-vibe subset: normal/insert/command modes, character and line visual modes with `v`/`V`, `h/j/k/l`, word and line movement, counts, simple `d`/`y` operator motions, `dd`, `yy`, `p`, `/` search, `u` undo, and `:w`, `:q`, `:q!`, `:wq`, `:x`, and `:number` commands. Yanks also copy to the terminal clipboard when OSC 52 is supported.
267
+
165
268
  ## Session settings
166
269
 
167
270
  Interactive CLI and RPC clients start fresh by default. To automatically resume the last active session for the current workspace:
@@ -0,0 +1,136 @@
1
+ # Context budgeting and token savings
2
+
3
+ Kward tries to keep the model's context focused. Instead of reading whole files and pasting every byte of command output back into the conversation, it gathers evidence in small steps, compacts noisy output, and keeps the original data available when needed.
4
+
5
+ This page summarizes the token-saving work in Kward: what existed before, what the newer focused-context tools add, and how those pieces fit together during normal agent work.
6
+
7
+ ## Why this matters
8
+
9
+ Coding agents spend a lot of tokens just finding the right code. A single broad file read, failed test run, or web fetch can add thousands of tokens to the next model call. That makes sessions slower, more expensive, and more likely to lose the useful details in noise.
10
+
11
+ Kward's goal is not to build a heavyweight semantic index. It is to stay lightweight and local while giving the agent a disciplined path:
12
+
13
+ ```text
14
+ find likely files -> inspect outlines/previews -> read exact ranges -> read full files only when needed
15
+ ```
16
+
17
+ ## The current workflow
18
+
19
+ When Kward needs code context, it should usually start with one of these tools:
20
+
21
+ - `context_for_task` for a compact task-shaped bundle.
22
+ - `summarize_file_structure` for a source outline of one file.
23
+ - `read_file` with `mode: "outline"` or `mode: "preview"`.
24
+
25
+ Then it can escalate only as needed:
26
+
27
+ - `read_file` with `mode: "range"`, `offset`, and `limit` for exact sections.
28
+ - `read_file` with `mode: "full"` only when focused context is not enough.
29
+
30
+ The built-in system prompt tells Kward to follow that escalation path, so these tools are part of normal agent behavior rather than hidden manual features.
31
+
32
+ ## Focused task context
33
+
34
+ `context_for_task` is the highest-level context-budgeting tool. Give it a task and, optionally, focused paths and a byte budget. It returns a compact text bundle with:
35
+
36
+ - ranked candidate files (by term-matching score),
37
+ - source outlines for each file,
38
+ - matching excerpts around task terms (2 lines of context),
39
+ - a header with the task, budget, and search terms used.
40
+
41
+ Tool arguments:
42
+
43
+ ```json
44
+ {
45
+ "task": "debug token validation failure",
46
+ "paths": ["lib"],
47
+ "budget": 4000
48
+ }
49
+ ```
50
+
51
+ - `task` is required.
52
+ - `paths` is optional; defaults to the workspace root. Each entry is a file or directory.
53
+ - `budget` is optional; defaults to 4,000 bytes, max 20,000.
54
+
55
+ Limits: at most 8 ranked files are returned, with up to 8 matching excerpts per file. Up to 64 files are scanned. Skipped directories include `.git`, `node_modules`, `vendor`, `tmp`, `log`, `coverage`, `dist`, `build`, `.bundle`, `.yardoc`, and `_yardoc`. Only files with known extensions (`.rb`, `.js`, `.ts`, `.py`, `.go`, `.rs`, `.java`, `.cs`, `.md`, `.yml`, `.json`, etc.) plus `Gemfile` are considered.
56
+
57
+ This is useful when Kward needs orientation before choosing exact files or line ranges. It is intentionally lightweight: no daemon, no database, no persistent graph, and no semantic/vector index.
58
+
59
+ ## Budgeted file reads
60
+
61
+ `read_file` supports explicit context modes:
62
+
63
+ | Mode | Use it when |
64
+ | --- | --- |
65
+ | `outline` | You need a source declaration outline (classes, modules, methods, functions) with line numbers before reading code. Capped at 80 entries. |
66
+ | `preview` | You want a short first look. Defaults to 120 lines when no `limit` is given. Respects `offset` and `limit` if provided. |
67
+ | `range` | You know the relevant line range. Uses `offset` and `limit` to read a specific section. |
68
+ | `full` | You need the full file content up to Kward's read caps. Functionally identical to `range` but signals full-read intent. |
69
+
70
+ `range` and `full` behave the same: both read a bounded slice using `offset`, `limit`, and `max_bytes`. The difference is semantic — use `full` when you want everything up to the cap, use `range` when you are targeting a section.
71
+
72
+ `read_file` also accepts `max_bytes`, which lets Kward request a smaller per-call byte budget. This can only reduce the output below the workspace default (50 KB); it cannot increase it.
73
+
74
+ Large source files still get special handling when read without a mode: Kward returns an outline plus the first 120 lines instead of blindly flooding context. See [Workspace tools](workspace-tools.md) for the full `read_file` argument reference and read limits.
75
+
76
+ ## Source outlines
77
+
78
+ `summarize_file_structure` and `read_file` with `mode: "outline"` return compact source outlines. These include recognizable declarations, declaration kind, indentation, and approximate line ranges.
79
+
80
+ The outline recognizer is deliberately simple. It uses lightweight patterns for common Ruby, JavaScript/TypeScript, Go, Rust, Java, and C#-style declarations. It is not a compiler or LSP replacement, but it is fast and dependency-free. See [Workspace tools](workspace-tools.md) for argument details.
81
+
82
+ ## Output compaction
83
+
84
+ Kward also saves tokens after tools run.
85
+
86
+ When a tool output is large enough, Kward compacts it before sending it back into model context. The original output is kept in the session record and can be reopened with `retrieve_tool_output`, including after resuming a saved session that contains the original tool execution record.
87
+
88
+ The compactor preserves:
89
+
90
+ - the first 40 lines,
91
+ - the last 40 lines,
92
+ - error, failure, test, search-result, URL, and heading context,
93
+ - separate STDOUT/STDERR sections for shell commands.
94
+
95
+ This is especially useful for commands like test runs, linters, package installs, and large fetches. The model sees the useful parts first, but the full output is not lost. See [Agent tools](agent-tools.md) for the full compaction strategy and artifact retrieval details.
96
+
97
+ ## Duplicate output reuse
98
+
99
+ If the same tool output appears again, Kward does not repeat it in model context. Instead, it inserts a short reference to the already-stored artifact.
100
+
101
+ That helps when commands or searches are retried and return the same large result.
102
+
103
+ ## Session compaction
104
+
105
+ Kward also supports conversation/session compaction. This is separate from tool-output compaction: instead of trimming one tool result, it summarizes older conversation state so a long session can continue with less context pressure.
106
+
107
+ Session compaction keeps the working conversation manageable while preserving the session history on disk. Run `/compact` manually, or enable auto-compaction in config — see [Session management](session-management.md) and [Configuration](configuration.md).
108
+
109
+ ## Measuring savings
110
+
111
+ Use `context_budget_stats` to see approximate savings for the current active conversation since it was opened in this process. These runtime stats are not reconstructed when a saved session is resumed.
112
+
113
+ It reports:
114
+
115
+ - tool calls counted,
116
+ - original bytes,
117
+ - model-facing returned bytes,
118
+ - saved bytes,
119
+ - estimated tokens saved,
120
+ - per-tool breakdown with `calls`, `savedBytes`, `returnedBytes`, and `originalBytes` for each tool.
121
+
122
+ The token estimate is intentionally rough, using about four bytes per token. It is meant to show whether context budgeting is helping, not to match provider billing exactly. See [Workspace tools](workspace-tools.md) for the tool reference.
123
+
124
+ ## Practical example
125
+
126
+ A good debugging flow looks like this:
127
+
128
+ ```text
129
+ User: Debug why auth token validation fails.
130
+ Kward: context_for_task(task: "debug auth token validation", paths: ["lib", "test"], budget: 5000)
131
+ Kward: read_file(path: "lib/auth.rb", mode: "range", offset: 40, limit: 80)
132
+ Kward: run_shell_command(command: "ruby -Itest test/test_auth.rb")
133
+ Kward: retrieve_tool_output(...) only if the compacted test output omitted something important.
134
+ ```
135
+
136
+ That gives the model enough evidence to work without reading the whole repository or stuffing every command byte into the next request.
data/doc/context-tools.md CHANGED
@@ -11,6 +11,8 @@ Arguments:
11
11
  - `name`: skill name.
12
12
  - `path`: optional path inside the skill, default `SKILL.md`.
13
13
 
14
+ Skill file paths must be relative and stay inside the skill folder. Absolute paths and path traversal are rejected. Files larger than 100 KB are also rejected.
15
+
14
16
  Skills are reusable instruction bundles stored in the Kward config directory. Kward advertises available skills by name and description, then reads the full skill only when it becomes relevant. That saves tokens because every skill does not need to be injected into every request.
15
17
 
16
18
  Typical uses:
@@ -32,13 +34,17 @@ Arguments:
32
34
  - `limit`: optional maximum lines to return, default 120.
33
35
  - `query`: optional case-insensitive text search within the original output.
34
36
 
35
- Kward may compact large shell, search, fetch, or file outputs before sending them back to the model. The compacted result includes enough summary to continue, plus an artifact id when the original output is worth preserving. If later work needs details, Kward can retrieve a focused slice of the original output instead of asking the tool to repeat the whole operation.
37
+ Kward may compact large shell, search, fetch, or file outputs before sending them back to the model. The compacted result includes enough summary to continue, plus an artifact id when the original output is worth preserving. If later work needs details, Kward can retrieve a focused slice of the original output instead of asking the tool to repeat the whole operation, including after resuming a saved session that contains the original tool execution record.
36
38
 
37
39
  This saves tokens in two ways:
38
40
 
39
41
  - repeated large outputs are not resent to the model,
40
42
  - follow-up reads can target only matching lines or a bounded line range.
41
43
 
44
+ When a `query` is provided, matching lines are returned with 1-indexed line numbers prefixed. The result includes a header with the artifact id, query, and line range. When there are more results than the limit, a continuation notice with the next `offset` is included.
45
+
46
+ For details on how tool outputs are compacted and when artifacts are created, see [Agent tools](agent-tools.md).
47
+
42
48
  ## `ask_user_question`
43
49
 
44
50
  `ask_user_question` asks one to four structured clarification questions through an interactive frontend.
@@ -49,9 +55,16 @@ Arguments:
49
55
  - each question has:
50
56
  - `header`: short label shown in the overlay,
51
57
  - `question`: the question text,
52
- - `options`: two to four selectable answers with labels and descriptions.
58
+ - `options`: two to four selectable answers with `label` and `description`.
59
+
60
+ Constraints:
61
+
62
+ - `multiSelect` is unsupported; questions are single-select.
63
+ - `preview` on options is unsupported.
64
+ - Each option requires both `label` and `description`.
65
+ - In terminal use, the picker also accepts custom typed answers beyond the provided options, so the user is not limited to the listed choices.
53
66
 
54
- This tool is advertised only when the active frontend supports structured questions. In terminal use, it lets Kward ask concise multiple-choice questions instead of guessing requirements. In RPC clients, the same question flow is bridged through UI events.
67
+ This tool is advertised only when the active frontend supports structured questions. In terminal use, it lets Kward ask concise multiple-choice questions instead of guessing requirements. In RPC clients, the same question flow is bridged through UI events — see the [RPC question bridge](rpc.md) for notification and response details.
55
68
 
56
69
  Good uses:
57
70