kward 0.71.0 → 0.73.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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +30 -0
  3. data/CHANGELOG.md +93 -0
  4. data/Gemfile.lock +2 -2
  5. data/README.md +4 -0
  6. data/doc/agent-tools.md +15 -6
  7. data/doc/authentication.md +22 -1
  8. data/doc/code-search.md +42 -2
  9. data/doc/configuration.md +106 -3
  10. data/doc/context-budgeting.md +136 -0
  11. data/doc/context-tools.md +16 -3
  12. data/doc/editor.md +415 -0
  13. data/doc/extensibility.md +16 -7
  14. data/doc/files.md +100 -0
  15. data/doc/getting-started.md +25 -18
  16. data/doc/git.md +123 -0
  17. data/doc/memory.md +24 -4
  18. data/doc/personas.md +34 -5
  19. data/doc/plugins.md +72 -1
  20. data/doc/releasing.md +37 -9
  21. data/doc/rpc.md +75 -5
  22. data/doc/session-management.md +35 -1
  23. data/doc/shell.md +332 -0
  24. data/doc/tabs.md +122 -0
  25. data/doc/troubleshooting.md +77 -1
  26. data/doc/usage.md +79 -7
  27. data/doc/web-search.md +12 -4
  28. data/doc/workspace-tools.md +51 -12
  29. data/examples/plugins/space_invaders.rb +377 -0
  30. data/lib/kward/agent.rb +1 -1
  31. data/lib/kward/ansi.rb +62 -23
  32. data/lib/kward/cli/commands.rb +33 -2
  33. data/lib/kward/cli/git.rb +150 -0
  34. data/lib/kward/cli/interactive_turn.rb +73 -9
  35. data/lib/kward/cli/plugins.rb +54 -4
  36. data/lib/kward/cli/prompt_interface.rb +32 -1
  37. data/lib/kward/cli/rendering.rb +4 -1
  38. data/lib/kward/cli/runtime_helpers.rb +268 -4
  39. data/lib/kward/cli/sessions.rb +2 -2
  40. data/lib/kward/cli/settings.rb +217 -9
  41. data/lib/kward/cli/slash_commands.rb +628 -2
  42. data/lib/kward/cli/tabs.rb +725 -0
  43. data/lib/kward/cli/tool_summaries.rb +6 -0
  44. data/lib/kward/cli.rb +150 -26
  45. data/lib/kward/clipboard.rb +2 -3
  46. data/lib/kward/compactor.rb +7 -19
  47. data/lib/kward/config_files.rb +145 -1
  48. data/lib/kward/context_budget_meter.rb +44 -0
  49. data/lib/kward/conversation.rb +12 -4
  50. data/lib/kward/editor_mode.rb +25 -0
  51. data/lib/kward/ekwsh.rb +559 -0
  52. data/lib/kward/image_attachments.rb +3 -1
  53. data/lib/kward/interactive_pty_runner.rb +151 -0
  54. data/lib/kward/local_command_runner.rb +155 -0
  55. data/lib/kward/local_pty_command_runner.rb +171 -0
  56. data/lib/kward/model/context_usage.rb +2 -2
  57. data/lib/kward/model/payloads.rb +2 -5
  58. data/lib/kward/plugin_registry.rb +61 -0
  59. data/lib/kward/project_files.rb +52 -0
  60. data/lib/kward/prompt_history.rb +84 -0
  61. data/lib/kward/prompt_interface/composer_controller.rb +69 -1
  62. data/lib/kward/prompt_interface/composer_renderer.rb +109 -13
  63. data/lib/kward/prompt_interface/composer_state.rb +96 -27
  64. data/lib/kward/prompt_interface/editor/auto_close_pairs.rb +123 -0
  65. data/lib/kward/prompt_interface/editor/auto_indent.rb +510 -0
  66. data/lib/kward/prompt_interface/editor/buffer.rb +109 -0
  67. data/lib/kward/prompt_interface/editor/controller.rb +1218 -0
  68. data/lib/kward/prompt_interface/editor/endwise.rb +321 -0
  69. data/lib/kward/prompt_interface/editor/file_marker.rb +40 -0
  70. data/lib/kward/prompt_interface/editor/indent_navigation.rb +61 -0
  71. data/lib/kward/prompt_interface/editor/kill_ring.rb +78 -0
  72. data/lib/kward/prompt_interface/editor/modes/emacs.rb +259 -0
  73. data/lib/kward/prompt_interface/editor/modes/modern.rb +354 -0
  74. data/lib/kward/prompt_interface/editor/modes/vibe.rb +1812 -0
  75. data/lib/kward/prompt_interface/editor/modes/vibe_insert_readline.rb +166 -0
  76. data/lib/kward/prompt_interface/editor/renderer.rb +244 -0
  77. data/lib/kward/prompt_interface/editor/search.rb +76 -0
  78. data/lib/kward/prompt_interface/editor/selections.rb +120 -0
  79. data/lib/kward/prompt_interface/editor/state.rb +1271 -0
  80. data/lib/kward/prompt_interface/editor/status_text.rb +23 -0
  81. data/lib/kward/prompt_interface/editor/syntax_highlighter.rb +422 -0
  82. data/lib/kward/prompt_interface/editor/undo_history.rb +46 -0
  83. data/lib/kward/prompt_interface/editor/vibe_state.rb +44 -0
  84. data/lib/kward/prompt_interface/file_overlay.rb +211 -0
  85. data/lib/kward/prompt_interface/git_prompt.rb +288 -0
  86. data/lib/kward/prompt_interface/interactive/controller.rb +186 -0
  87. data/lib/kward/prompt_interface/interactive/renderer.rb +71 -0
  88. data/lib/kward/prompt_interface/interactive/state.rb +62 -0
  89. data/lib/kward/prompt_interface/key_handler.rb +451 -57
  90. data/lib/kward/prompt_interface/overlay_renderer.rb +21 -2
  91. data/lib/kward/prompt_interface/project_browser.rb +524 -0
  92. data/lib/kward/prompt_interface/question_prompt.rb +99 -56
  93. data/lib/kward/prompt_interface/runtime_state.rb +43 -0
  94. data/lib/kward/prompt_interface/screen.rb +19 -3
  95. data/lib/kward/prompt_interface/selection_prompt.rb +10 -19
  96. data/lib/kward/prompt_interface/slash_overlay.rb +2 -0
  97. data/lib/kward/prompt_interface/stream_state.rb +7 -0
  98. data/lib/kward/prompt_interface/transcript_buffer.rb +6 -0
  99. data/lib/kward/prompt_interface.rb +366 -222
  100. data/lib/kward/prompts/commands.rb +9 -0
  101. data/lib/kward/prompts.rb +2 -0
  102. data/lib/kward/rpc/memory_methods.rb +83 -0
  103. data/lib/kward/rpc/server.rb +169 -83
  104. data/lib/kward/rpc/session_manager.rb +45 -121
  105. data/lib/kward/rpc/session_tree_rows.rb +9 -115
  106. data/lib/kward/rpc/tool_event_normalizer.rb +1 -1
  107. data/lib/kward/rpc/tool_metadata.rb +11 -0
  108. data/lib/kward/rpc/transcript_normalizer.rb +4 -39
  109. data/lib/kward/scratchpad_runner.rb +56 -0
  110. data/lib/kward/session_diff.rb +20 -3
  111. data/lib/kward/session_naming.rb +11 -0
  112. data/lib/kward/session_store.rb +44 -0
  113. data/lib/kward/session_tree_nodes.rb +136 -0
  114. data/lib/kward/session_tree_renderer.rb +9 -131
  115. data/lib/kward/tab_store.rb +47 -0
  116. data/lib/kward/terminal_keys.rb +84 -0
  117. data/lib/kward/terminal_sequences.rb +42 -0
  118. data/lib/kward/text_boundary.rb +25 -0
  119. data/lib/kward/tools/context_budget_stats.rb +54 -0
  120. data/lib/kward/tools/context_for_task.rb +204 -0
  121. data/lib/kward/tools/read_file.rb +8 -4
  122. data/lib/kward/tools/registry.rb +62 -16
  123. data/lib/kward/tools/tool_call.rb +10 -0
  124. data/lib/kward/version.rb +1 -1
  125. data/lib/kward/workers/git_guard.rb +93 -0
  126. data/lib/kward/workers/job.rb +99 -0
  127. data/lib/kward/workers/live_view.rb +49 -0
  128. data/lib/kward/workers/manager.rb +288 -0
  129. data/lib/kward/workers/queue_runner.rb +166 -0
  130. data/lib/kward/workers/queue_store.rb +112 -0
  131. data/lib/kward/workers/store.rb +72 -0
  132. data/lib/kward/workers/tool_policy.rb +23 -0
  133. data/lib/kward/workers/worker.rb +82 -0
  134. data/lib/kward/workers/write_lock.rb +38 -0
  135. data/lib/kward/workers.rb +10 -0
  136. data/lib/kward/workspace.rb +125 -87
  137. data/templates/default/fulldoc/html/css/kward.css +140 -36
  138. data/templates/default/fulldoc/html/images/kward_screen_1.png +0 -0
  139. data/templates/default/fulldoc/html/setup.rb +1 -0
  140. data/templates/default/kward_navigation.rb +12 -1
  141. data/templates/default/layout/html/layout.erb +23 -34
  142. data/templates/default/layout/html/setup.rb +6 -0
  143. metadata +67 -1
data/doc/tabs.md ADDED
@@ -0,0 +1,122 @@
1
+ # Tabs
2
+
3
+ Use tabs when you want more than one Kward conversation open in the same interactive terminal session.
4
+
5
+ Each tab has its own session-backed conversation, transcript, composer state, and running agent turn. That makes tabs useful for splitting work without losing your place: one tab can investigate a bug, another can draft docs, and a third can wait on a long-running answer.
6
+
7
+ ## Quick start
8
+
9
+ Open a new tab:
10
+
11
+ ```text
12
+ /tab new
13
+ ```
14
+
15
+ Switch to tab 1, 2, or another visible tab number:
16
+
17
+ ```text
18
+ /tab 1
19
+ /tab 2
20
+ ```
21
+
22
+ Rename the current tab:
23
+
24
+ ```text
25
+ /tab name Docs
26
+ ```
27
+
28
+ Close the current tab:
29
+
30
+ ```text
31
+ /tab close
32
+ ```
33
+
34
+ The tab bar appears at the bottom of the composer. The active tab is framed, and each tab label starts with its number.
35
+
36
+ ## Common workflow
37
+
38
+ A typical multi-tab flow looks like this:
39
+
40
+ 1. Start Kward interactively in your project.
41
+ 2. Use the main tab for the current implementation task.
42
+ 3. Run `/tab new` to open a clean conversation.
43
+ 4. Ask a separate question, such as:
44
+
45
+ ```text
46
+ Review the current API docs structure and suggest where a Tabs guide belongs.
47
+ ```
48
+
49
+ 5. Switch back with `/tab 1` while the other answer runs.
50
+ 6. Return to the second tab with `/tab 2` when it is ready.
51
+
52
+ Tabs keep the conversations separate, so context from one tab does not automatically spill into another.
53
+
54
+ ## Slash commands
55
+
56
+ | Command | Action |
57
+ | ------- | ------ |
58
+ | `/tab new` | Open a new tab with a fresh conversation |
59
+ | `/tab 1` through `/tab 9` | Switch to a numbered tab |
60
+ | `/tab close` | Close the current tab |
61
+ | `/tab name <label>` | Rename the current tab |
62
+ | `/tab rename <label>` | Same as `/tab name` |
63
+ | `/tab move left` | Move the current tab one slot left |
64
+ | `/tab move right` | Move the current tab one slot right |
65
+ | `/tab move <number>` | Move the current tab to a numbered position |
66
+
67
+ If you close the only remaining tab, Kward exits the interactive session. A running tab cannot be closed until it finishes or is cancelled.
68
+
69
+ ## Keyboard shortcuts
70
+
71
+ Kward supports two tab shortcut families. You can choose one in `/settings` or with `composer.tab_keybindings` in `config.json`.
72
+
73
+ `Ctrl+Tab` and `Ctrl+Shift+Tab` switch tabs when your terminal sends those keys:
74
+
75
+ | Key | Action |
76
+ | --- | ------ |
77
+ | `Ctrl+Tab` | Next tab |
78
+ | `Ctrl+Shift+Tab` | Previous tab |
79
+
80
+ When `composer.tab_keybindings` is `ctrl`:
81
+
82
+ | Key | Action |
83
+ | --- | ------ |
84
+ | `Ctrl+T` | New tab |
85
+ | `Ctrl+W` | Close tab |
86
+ | `Ctrl+1` through `Ctrl+9` | Switch to a numbered tab, if your terminal reports modified number keys |
87
+
88
+ When `composer.tab_keybindings` is `alt`:
89
+
90
+ | Key | Action |
91
+ | --- | ------ |
92
+ | `Alt+T` | New tab |
93
+ | `Alt+Right` | Next tab |
94
+ | `Alt+Left` | Previous tab |
95
+ | `Alt+1` through `Alt+9` | Switch to a numbered tab |
96
+
97
+ `auto` is the default. On macOS it prefers the Ctrl family; elsewhere it prefers the Alt family, because many terminals reserve or swallow Ctrl-based tab shortcuts.
98
+
99
+ ## Running work in another tab
100
+
101
+ A tab can keep running while you switch away. Kward marks tab labels by status:
102
+
103
+ - Yellow: running or queued.
104
+ - Green: waiting for your answer to an interactive question, or unread output is ready in a background tab.
105
+ - Red: failed or cancelled.
106
+
107
+ If you type into a busy tab, Kward queues normal prompts until the current turn finishes. Some running turns also support steering input, so short follow-up guidance may be delivered to the active run instead of waiting for the next turn.
108
+
109
+ Slash commands such as `/tab` still work while a tab is busy, so you can switch tabs, open a new tab, or move around without waiting.
110
+
111
+ ## Persistence
112
+
113
+ Tabs are backed by normal Kward sessions. Kward stores the open tab list, labels, and active tab per workspace, then restores them the next time you start interactive Kward in that workspace.
114
+
115
+ The tab layout is stored in Kward's config directory under `tabs/`. Session transcripts stay in the normal sessions directory. See [Sessions](session-management.md) for session naming, resuming, forking, exporting, and cleanup.
116
+
117
+ ## Notes and limitations
118
+
119
+ - Tabs are available in the interactive TUI.
120
+ - Each tab has its own conversation context; use explicit file mentions or summaries when you want to carry information between tabs.
121
+ - A running tab cannot be closed until it is idle.
122
+ - Terminal support for modified keys varies. If shortcuts do not arrive, use the `/tab` slash commands or switch `composer.tab_keybindings` between `ctrl` and `alt`.
@@ -1,6 +1,74 @@
1
1
  # Troubleshooting
2
2
 
3
- This page collects environment-specific issues that can affect Kward but are not caused by Kward itself.
3
+ This page covers common issues and how to diagnose them. When something is not working, start with `kward doctor` — it checks your config, directories, workspace, model, and auth status in one pass.
4
+
5
+ ## Run `kward doctor` first
6
+
7
+ `kward doctor` reports the state of your local setup without printing secrets:
8
+
9
+ ```bash
10
+ kward doctor
11
+ ```
12
+
13
+ It checks that your config file is readable and valid JSON, that the config and session directories are writable, that the workspace exists, which provider and model are active, and which credentials are configured. Use it as the first diagnostic step for any unexpected behavior.
14
+
15
+ `kward auth status` gives a focused view of credentials only, also without printing secrets:
16
+
17
+ ```bash
18
+ kward auth status
19
+ ```
20
+
21
+ ## Authentication errors and token expiration
22
+
23
+ OAuth tokens expire. Kward refreshes access tokens automatically when a refresh token is available, but if the refresh token is missing or expired, requests fail with a provider-specific error:
24
+
25
+ - OpenAI: `No OpenAI OAuth login found.`
26
+ - Anthropic: `No Anthropic OAuth login found.`
27
+ - Copilot: `No GitHub Copilot OAuth login found.`
28
+ - OpenRouter: `No OpenRouter API key found.`
29
+
30
+ Re-run login for the affected provider:
31
+
32
+ ```bash
33
+ kward login # OpenAI
34
+ kward login anthropic # Anthropic
35
+ kward login openrouter # OpenRouter
36
+ kward login github # Copilot
37
+ ```
38
+
39
+ Or use `/login` inside Kward. See [Authentication](authentication.md) for the full provider flow.
40
+
41
+ ## Provider usage limits and billing errors
42
+
43
+ Kward detects non-retryable quota and billing errors from providers, including messages such as `quota exceeded`, `insufficient_quota`, `out of credits`, and `monthly usage limit reached`. These are not retried — the request fails immediately.
44
+
45
+ If you see one of these errors:
46
+
47
+ - Check your provider dashboard for usage or billing limits.
48
+ - For OpenRouter, verify your account balance at [openrouter.ai](https://openrouter.ai).
49
+ - For OpenAI, check your organization's usage and billing settings.
50
+ - Switch to a different provider or model with `/model` if you have alternative credentials.
51
+
52
+ ## Rate limiting and transient server errors
53
+
54
+ Kward automatically retries transient failures: HTTP 429 (rate limit) and 5xx server errors. It makes up to 3 attempts total with short backoff delays. Network errors such as timeouts and connection resets are also retried.
55
+
56
+ If requests fail after retries, you will see a message like `request failed after 3 attempts`. Common causes:
57
+
58
+ - You are hitting the provider's rate limit. Wait a moment and retry, or reduce request frequency.
59
+ - The provider is experiencing an outage. Check the provider's status page.
60
+ - Your session context is very large, making each request slower and more likely to time out. Use `/compact` to reduce context.
61
+
62
+ ## Context overflow errors
63
+
64
+ When a conversation exceeds the model's context window, the provider returns an error such as `prompt is too long` or `exceeds the context window`. Kward detects these and does not retry them.
65
+
66
+ To resolve context overflow:
67
+
68
+ - Run `/compact` to summarize and reduce the conversation context.
69
+ - Start a new session with `/new` if the current one is no longer needed.
70
+ - Enable auto-compaction if it is off — see [Configuration](configuration.md).
71
+ - Switch to a model with a larger context window via `/model`.
4
72
 
5
73
  ## `gem install kward` succeeds, but `kward` is not found with rbenv
6
74
 
@@ -53,3 +121,11 @@ kward --help
53
121
  ```
54
122
 
55
123
  This stale `.rbenv-shim` file can be left behind by an interrupted `rbenv rehash` or gem installation. It is local rbenv state, not a Kward packaging issue.
124
+
125
+ ## Still stuck?
126
+
127
+ If none of the above resolves your issue:
128
+
129
+ 1. Run `kward doctor` and `kward auth status` to gather diagnostics.
130
+ 2. Check the [Authentication](authentication.md) and [Configuration](configuration.md) docs.
131
+ 3. Search or report issues at the [Kward issue tracker](https://github.com/kaiwood/kward/issues).
data/doc/usage.md CHANGED
@@ -12,7 +12,7 @@ cd ~/code/project
12
12
  kward
13
13
  ```
14
14
 
15
- When running from source, replace `kward` with `ruby lib/main.rb`.
15
+ When running from source, replace `kward` with `ruby lib/main.rb`. See [Getting started](getting-started.md) for install and sign-in.
16
16
 
17
17
  ## Common workflows
18
18
 
@@ -42,6 +42,14 @@ For larger reviews, use interactive mode so Kward can inspect related files:
42
42
  Review the current git diff. If something looks risky, inspect the relevant files before recommending changes.
43
43
  ```
44
44
 
45
+ To review and commit changes interactively, use `/git`:
46
+
47
+ ```text
48
+ /git
49
+ ```
50
+
51
+ It opens a staging overlay where you can stage or unstage files, preview diffs, and write a commit message without leaving Kward.
52
+
45
53
  ### Make a small code change
46
54
 
47
55
  ```text
@@ -64,6 +72,14 @@ Or run a shell command yourself from the composer by prefixing it with `!`:
64
72
  !git status --short
65
73
  ```
66
74
 
75
+ For several commands, enter the embedded Kward shell:
76
+
77
+ ```text
78
+ /shell
79
+ ```
80
+
81
+ `/shell` opens `ekwsh`, a Kward-native command mode. Kward keeps the tab bar, composer editing, and transcript rendering while each command runs through your configured shell. Built-ins such as `cd`, `pwd`, `export`, `unset`, `alias`, `clear`, `pty`, and `exit` maintain shell-mode state between commands. Plain Tab completes built-in command names, configured aliases, executables from `$PATH`, and file paths from the shell's current directory; `cd` completion suggests directories only. `ekwsh` preserves safe ANSI SGR color/style output while stripping terminal-control sequences that could corrupt the TUI, and sets conservative color-friendly environment defaults such as `CLICOLOR=1`, `COLORTERM=truecolor`, and `TERM=xterm-256color` when needed. Use `pty git log` or `/pty git log` when you intentionally want to hand the terminal to an interactive tool such as `less` or `vim`. You can set global shell env vars and aliases in `~/.kward/ekwsh.yml`; see [Configuration](configuration.md).
82
+
67
83
  ## Shell commands
68
84
 
69
85
  Useful shell commands:
@@ -72,10 +88,12 @@ Useful shell commands:
72
88
  kward # start interactive chat
73
89
  kward "Explain this project" # ask one question and exit
74
90
  kward help # show commands and examples
91
+ kward version # show the installed version
75
92
  kward doctor # check local setup
76
93
  kward login # sign in or save credentials
77
94
  kward auth status # show credential status without secrets
78
95
  kward sysprompt # inspect assembled instructions
96
+ kward stats tokens # export local token telemetry as CSV
79
97
  kward rpc # start the experimental RPC backend
80
98
  ```
81
99
 
@@ -88,15 +106,28 @@ kward --working-directory ~/code/project "Summarize this repository"
88
106
 
89
107
  ## Interactive slash commands
90
108
 
91
- Use slash commands for local actions that should not go to the model:
109
+ Slash commands run local actions in the current session. Most do not send a prompt to the model; exceptions like `/git` and `/workers` orchestrate local flows that may then trigger model work.
92
110
 
93
111
  | Command | Use it when you want to... |
94
112
  | --- | --- |
95
113
  | `/login` | sign in or save provider credentials. |
96
114
  | `/model` | choose the active model. |
97
115
  | `/reasoning` | choose reasoning effort. |
116
+ | `/git` | review uncommitted changes, stage files, and commit. |
117
+ | `/diff` | open the file changes recorded in the current session. |
118
+ | `/files` | browse project files in a nested tree and open them in the editor. |
119
+ | `/shell` | run workspace commands in the embedded Kward shell. |
120
+ | `/pty <command>` | hand the terminal to an interactive command such as `git log`/`less` or `vim`. |
121
+ | `/settings` | configure prompt overlays. |
98
122
  | `/status` | see session, model, and context status. |
99
- | `/new` | start a fresh session. |
123
+ | `/new` | start a fresh session in the current tab. |
124
+ | `/tab 2` | switch to tab 2. |
125
+ | `/tab move 1` | move the active tab to position 1. |
126
+ | `/tab move left` | move the active tab one position left. |
127
+ | `/tab move right` | move the active tab one position right. |
128
+ | `/tab close` | close the active tab. |
129
+ | `/tab new` | open a new tab. |
130
+ | `/tab name <label>` | rename the active tab label. |
100
131
  | `/sessions` | open the saved sessions picker or continue a previous session by path. |
101
132
  | `/resume` | alias for `/sessions`. |
102
133
  | `/name <name>` | name or clear the current session. |
@@ -107,13 +138,47 @@ Use slash commands for local actions that should not go to the model:
107
138
  | `/copy last` | copy the latest assistant answer. |
108
139
  | `/copy transcript` | copy the transcript as Markdown. |
109
140
  | `/export notes.md` | write the transcript to a Markdown file. |
110
- | `/compact [focus]` | summarize older context so a long chat can continue. |
141
+ | `/compact [instructions]` | summarize older context so a long chat can continue. |
111
142
  | `/memory ...` | manage opt-in memory. |
112
143
  | `/redraw` | fix terminal drawing after resize or glitches. |
144
+ | `/reload` | reload installed plugins. |
145
+ | `/workers` | open the experimental worker pipeline (`new`, `do <task>`, or `list`). |
146
+ | `/queue` | manage the experimental tab-backed worker queue (`add`, `list`, `open <id>`, `run`, `suspend <id>`, or `resume <id>`). |
113
147
  | `/exit` | leave Kward. |
114
148
 
115
149
  Prompt templates and plugins can add more slash commands.
116
150
 
151
+ ### Experimental tab-backed worker queue
152
+
153
+ Start Kward with `--experimental-workers` to try the tab-backed worker queue. The queue is an MVP for turning an existing tab/session into implementation work that can be reviewed later.
154
+
155
+ Typical flow:
156
+
157
+ ```text
158
+ /plan Add retry handling to webhook delivery
159
+ /queue add
160
+ /queue run
161
+ /queue open <id>
162
+ ```
163
+
164
+ `/queue add` stores the current tab session as a queued worker job. `/queue run` drains queued jobs one at a time. Each job continues its saved session as an implementation worker, starts only from a clean git workspace, commits any resulting changes, and then becomes `ready_for_review`. Use `/queue open <id>` to inspect the worker session, test the feature yourself, and continue the same session if a follow-up fix is needed.
165
+
166
+ Current MVP limitations:
167
+
168
+ - The queue is manual: run it with `/queue run` when you want it to work.
169
+ - Jobs run sequentially and stop when one becomes `blocked` or `failed`.
170
+ - A job will not start if the workspace is dirty; clean, commit, or stash your changes first.
171
+ - `/queue suspend <id>` and `/queue resume <id>` provide explicit stash-based parking primitives, but automatic foreground-tool-triggered yielding is not wired yet.
172
+ - The queue is experimental and stores metadata locally in Kward's config directory.
173
+
174
+ ## Prompt history
175
+
176
+ In interactive mode, Kward keeps prompt history per workspace under `~/.kward/history/`. Press Up/Down to recall previous prompts across restarts.
177
+
178
+ Press `Ctrl-R` to search history. Type a fuzzy query in the composer, use Up/Down to choose a result from the overlay, then press Enter to place it back in the composer for editing or resubmission. Press Esc or Ctrl-C to cancel the search and restore the draft.
179
+
180
+ `$path` editor-open commands are also saved after a file opens successfully, using the resolved workspace-relative path.
181
+
117
182
  ## Sessions
118
183
 
119
184
  Interactive chats are saved as workspace-scoped sessions under:
@@ -149,11 +214,18 @@ One-shot prompts are best for short tasks that do not need session history:
149
214
 
150
215
  ```bash
151
216
  kward "What does this repository do?"
217
+ cat error.log | kward
218
+ ```
219
+
220
+ When stdin and a prompt are both present, Kward runs in filter mode: stdin is the input, the prompt is the instruction, and stdout contains only the transformed result. You can also force this with `--filter` or `--mode filter`.
221
+
222
+ ```bash
152
223
  git diff | kward "Review this diff"
153
- cat error.log | kward "Explain the likely cause"
224
+ echo "Hello" | kward --filter "Translate to German"
225
+ kward --mode filter "Indent this JSON" < unindented.json
154
226
  ```
155
227
 
156
- Use `--` when your prompt starts with something that could be parsed as a command or option:
228
+ Use `--mode chat`, `--mode oneshot`, or `--mode filter` to override automatic mode detection. Use `--` when your prompt starts with something that could be parsed as a command or option:
157
229
 
158
230
  ```bash
159
231
  kward -- explain --working-directory
@@ -181,7 +253,7 @@ Important guardrails:
181
253
 
182
254
  ## Images
183
255
 
184
- If the active model supports images, Kward can attach image paths, Markdown image links, `file://` URLs, or image data URLs pasted into the composer.
256
+ If the active model supports images, Kward can attach image paths, Markdown image links, `file://` URLs, or image data URLs pasted into the composer. Supported formats are GIF, JPEG, PNG, and WebP, up to 20 MB per image.
185
257
 
186
258
  Use this for tasks such as:
187
259
 
data/doc/web-search.md CHANGED
@@ -36,16 +36,18 @@ Kward should search first, then fetch important pages before relying on them.
36
36
 
37
37
  ## Network behavior
38
38
 
39
- Web tools are advertised to the model by default. Queries and fetched URLs are sent over the network to the selected provider or target host.
39
+ Web tools are advertised to the model by default. Queries and fetched URLs are sent over the network to the selected provider or target host. See [Configuration](configuration.md) for the full `web_search` config reference including API key storage and the `provider` config setting.
40
40
 
41
41
  In automatic mode, provider fallback is:
42
42
 
43
43
  1. Exa API when `EXA_API_KEY` is configured, otherwise keyless Exa MCP.
44
- 2. Perplexity API when configured and model-provider fallback is allowed.
45
- 3. Gemini API with Google Search grounding when configured and model-provider fallback is allowed.
44
+ 2. Perplexity API when `PERPLEXITY_API_KEY` is configured and model-provider fallback is allowed.
45
+ 3. Gemini API with Google Search grounding when `GEMINI_API_KEY` is configured and model-provider fallback is allowed.
46
46
  4. DuckDuckGo HTML search, then bundled public SearXNG instances.
47
47
 
48
- You do not need an API key for basic web search, but keys can improve limits or provider choice.
48
+ You do not need an API key for basic web search, but keys can improve limits or provider choice. The default provider can also be set in config as `web_search.provider`; the tool argument overrides it for a single call.
49
+
50
+ Search output is capped at 8 KB total, with excerpts up to 300 characters and answer text up to 2,000 characters. HTTP requests use a 10-second timeout.
49
51
 
50
52
  ## Disable web tools
51
53
 
@@ -83,6 +85,10 @@ Arguments:
83
85
  - `max_bytes`: default 16384, capped at 131072.
84
86
  - `extract`: optional `auto`, `text`, or `markdown`.
85
87
 
88
+ In `auto` mode (default), Kward detects HTML content and extracts readable text by stripping scripts, styles, navigation, and forms, preserving headings, paragraphs, lists, code blocks, and blockquotes. Non-HTML content is returned as cleaned text. Use `markdown` to format extracted headings and code blocks as Markdown, or `text` for plain text without formatting.
89
+
90
+ Fetches follow up to 5 redirects and use a 10-second HTTP timeout.
91
+
86
92
  ### `fetch_raw`
87
93
 
88
94
  Reads a specific HTTP or HTTPS resource without readability extraction. Use it for JSON, YAML, XML, RSS, OpenAPI specs, and plain text.
@@ -92,3 +98,5 @@ Arguments:
92
98
  - `url`
93
99
  - `max_bytes`: default 16384, capped at 131072.
94
100
  - `accept`: optional HTTP `Accept` header.
101
+
102
+ Fetches follow up to 5 redirects and use a 10-second HTTP timeout.
@@ -12,14 +12,14 @@ Kward normally chooses these tools itself. You do not need to know their exact n
12
12
 
13
13
  ## Guardrails
14
14
 
15
- Workspace tools use the active workspace as their boundary. File paths are workspace-relative by default, and file tools are guarded so Kward does not edit arbitrary unread files.
15
+ Workspace tools use the active workspace as their boundary. File paths are workspace-relative by default, and file tools are guarded so Kward does not edit arbitrary unread files. Guardrails can be disabled with the `tools.workspace_guardrails` setting — see [Configuration](configuration.md). When disabled, file tools can access paths outside the workspace, but shell commands are unaffected since they already run as your OS user.
16
16
 
17
17
  Important behavior:
18
18
 
19
19
  - Existing files must be read in the current conversation before `write_file` or `edit_file` can change them.
20
- - Reads are bounded to avoid pulling very large files into context by accident.
20
+ - Reads are bounded to avoid pulling very large files into context by accident. Files larger than 256 KB cannot be read or edited. Read output is capped at 50 KB or 2,000 lines, whichever comes first.
21
21
  - Edits use exact text replacement, so accidental partial or fuzzy changes fail instead of guessing.
22
- - Shell commands run as your operating-system user from the workspace. They are powerful and should be treated like commands you run yourself.
22
+ - Shell commands run as your operating-system user from the workspace. They are powerful and should be treated like commands you run yourself. Command output is capped at 128 KB.
23
23
 
24
24
  ## Reading the workspace
25
25
 
@@ -33,25 +33,55 @@ Arguments:
33
33
 
34
34
  ### `read_file`
35
35
 
36
- Reads a workspace text file. Output is capped, and Kward can continue with line offsets when it needs more detail.
36
+ Reads a workspace text file. Output is capped, and Kward can continue with line offsets when it needs more detail. The tool also supports explicit context modes so Kward can start cheap and widen only when needed.
37
37
 
38
38
  Arguments:
39
39
 
40
40
  - `path`: workspace-relative file path.
41
41
  - `offset`: optional 1-indexed start line.
42
42
  - `limit`: optional maximum number of lines.
43
+ - `mode`: optional context mode:
44
+ - `preview`: read a short preview slice, defaulting to 120 lines when `limit` is omitted.
45
+ - `outline`: return only the source declaration outline.
46
+ - `range`: read the requested `offset`/`limit` slice.
47
+ - `full`: read from `offset` until Kward's read caps stop the response.
48
+ - `max_bytes`: optional per-call byte budget, capped by Kward's workspace read limit.
43
49
 
44
50
  A successful read marks the resolved file path as read for the conversation, allowing later edits to that file.
45
51
 
52
+ When called without `offset`, `limit`, or `mode` on a file that exceeds 2,000 lines or 50 KB, Kward returns a structure outline (classes, modules, methods) plus the first 120 lines instead of truncating blindly. This helps identify relevant entry points before requesting specific line ranges.
53
+
54
+ Binary files (detected by null bytes) return an error instead of content.
55
+
56
+ ### `context_budget_stats`
57
+
58
+ Returns approximate context-budget savings for the current active conversation since it was opened in this process. The report compares each raw tool result size with the model-facing result after compaction or duplicate replacement, includes per-tool totals, and estimates saved tokens using roughly four bytes per token.
59
+
60
+ Arguments: none.
61
+
62
+ These numbers are intentionally approximate runtime stats. They are useful for seeing whether Kward's budgeting is helping the current conversation, not for billing, and they are not reconstructed when a saved session is resumed.
63
+
64
+ ### `context_for_task`
65
+
66
+ Builds a compact, task-shaped context bundle from likely workspace files. It ranks files by task terms, includes source outlines, and adds short matching excerpts while respecting an approximate byte budget. This is intentionally lightweight: it does not maintain a persistent index or semantic graph.
67
+
68
+ Arguments:
69
+
70
+ - `task`: required task or question to gather context for.
71
+ - `paths`: optional files or directories to focus. Defaults to the workspace root.
72
+ - `budget`: optional approximate byte budget, default 4,000 and capped at 20,000.
73
+
74
+ Use this when Kward needs orientation for a bug, review, implementation, or explanation before deciding which exact file ranges to read.
75
+
46
76
  ### `summarize_file_structure`
47
77
 
48
- Returns a compact outline of classes, modules, methods, and functions in a source file. Kward uses it when a file may be too large to read fully at first.
78
+ Returns a compact outline of recognizable declarations in a source file, including line ranges and declaration kind where Kward can infer them. Kward uses it when a file may be too large to read fully at first.
49
79
 
50
80
  Arguments:
51
81
 
52
82
  - `path`: workspace-relative source file path.
53
83
 
54
- This tool saves tokens by letting Kward identify relevant entry points before requesting exact line ranges with `read_file`.
84
+ This tool saves tokens by letting Kward identify relevant entry points before requesting exact line ranges with `read_file`. The outline is capped at 80 entries and recognizes common Ruby, JavaScript/TypeScript, Go, Rust, Java, and C#-style declarations with lightweight pattern matching rather than a full parser. Binary files (detected by null bytes) return an error instead of content.
55
85
 
56
86
  ## Changing files
57
87
 
@@ -66,6 +96,8 @@ Arguments:
66
96
 
67
97
  Use full writes when replacing generated content or creating a new file. For small edits to existing files, Kward should usually prefer `edit_file`.
68
98
 
99
+ The result includes a unified diff of the changes, capped at 8 KB with a summary of additions and deletions when truncated.
100
+
69
101
  ### `edit_file`
70
102
 
71
103
  Applies one or more exact replacements to a file that has already been read.
@@ -77,7 +109,9 @@ Arguments:
77
109
  - `old_text`: unique exact text to replace.
78
110
  - `new_text`: replacement text.
79
111
 
80
- Each `old_text` must match exactly once, and replacements must not overlap. This keeps edits deterministic and avoids broad fuzzy rewriting.
112
+ Each `old_text` must match exactly once, and replacements must not overlap. This keeps edits deterministic and avoids broad fuzzy rewriting. Empty `old_text`, multiple matches, and no-op edits (where the result is identical) are all rejected with an error.
113
+
114
+ The result includes a unified diff of the changes, capped at 8 KB with a summary of additions and deletions when truncated.
81
115
 
82
116
  ## Running commands
83
117
 
@@ -90,16 +124,21 @@ Arguments:
90
124
  - `command`: command to run.
91
125
  - `timeout_seconds`: optional timeout, default 30 seconds.
92
126
 
93
- Kward uses shell commands for tests, linters, build checks, and simple repository inspection. Command output is bounded and may be compacted before it is sent back into model context, while the original output remains available in the session record.
127
+ Kward uses shell commands for tests, linters, build checks, and simple repository inspection. Command output is bounded at 128 KB and may be compacted before it is sent back into model context, while the original output remains available in the session record.
128
+
129
+ The output format is `Exit status: N` followed by `STDOUT:` and `STDERR:` sections. On timeout, Kward sends SIGTERM then SIGKILL after 0.2 seconds and returns a timeout error. Commands support cooperative cancellation when the session is cancelled.
94
130
 
95
131
  ## Token behavior
96
132
 
97
133
  Workspace tools are intentionally incremental:
98
134
 
99
135
  1. list directories to find likely files,
100
- 2. summarize large source files before reading everything,
101
- 3. read focused line ranges,
102
- 4. make exact edits,
103
- 5. run focused verification commands.
136
+ 2. use `read_file` with `mode: "outline"` or `summarize_file_structure` before reading everything,
137
+ 3. read focused line ranges with `mode: "range"`, `offset`, `limit`, and optional `max_bytes`,
138
+ 4. widen to `mode: "full"` only when focused context is insufficient,
139
+ 5. make exact edits,
140
+ 6. run focused verification commands.
104
141
 
105
142
  This keeps the model's context window focused on relevant evidence instead of flooding it with entire repositories or long command output.
143
+
144
+ For details on how tool outputs are compacted, deduplicated, and retrieved, see [Agent tools](agent-tools.md).