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
@@ -23,6 +23,8 @@ cd ~/code/project
23
23
  kward
24
24
  ```
25
25
 
26
+ To automatically resume the last active session for the current workspace on startup, enable `sessions.auto_resume` in your config — see [Configuration](configuration.md). When auto-resume is off (the default), Kward starts fresh each time and you can resume earlier work with `/sessions`.
27
+
26
28
  ## A normal session workflow
27
29
 
28
30
  Start a chat and give it a useful name:
@@ -31,6 +33,8 @@ Start a chat and give it a useful name:
31
33
  /rename oauth cleanup
32
34
  ```
33
35
 
36
+ `/rename` requires a name. Use `/name` without an argument to clear the current session name.
37
+
34
38
  Work normally:
35
39
 
36
40
  ```text
@@ -71,10 +75,12 @@ Inside the picker you can:
71
75
  | `r` | rename the highlighted session. |
72
76
  | `c` | clone the highlighted session. |
73
77
  | `f` | fork the highlighted session from an earlier prompt. |
74
- | `d d` | delete the highlighted session after confirmation. |
78
+ | `d` | start deleting the highlighted session. Press `d` again to confirm, or `Esc` to cancel. |
75
79
 
76
80
  Use names generously. A session named `oauth cleanup` or `release checklist` is much easier to find later than a timestamp.
77
81
 
82
+ Deleted sessions are moved to your OS trash or recycle bin when a supported platform tool is available (Finder on macOS, `gio trash` or `trash-put` on Linux, Recycle Bin on Windows). If no trash tool is found, the session file is permanently deleted. You can recover accidentally deleted sessions from your trash.
83
+
78
84
  ## Clone a session
79
85
 
80
86
  Clone when you want an exact copy of the current conversation and then continue in a separate branch.
@@ -185,6 +191,17 @@ After compaction, Kward may need to re-read files before editing them again. Tha
185
191
 
186
192
  Compaction is also context management. It trades detailed old conversation for a concise working summary so Kward can spend tokens on the next task.
187
193
 
194
+ ## Copy session text to the clipboard
195
+
196
+ Use `/copy` to copy conversation text without writing a file:
197
+
198
+ ```text
199
+ /copy last # copy the latest assistant response
200
+ /copy transcript # copy the full transcript as Markdown
201
+ ```
202
+
203
+ With no argument, `/copy` defaults to `last`. Copying uses the terminal clipboard (OSC 52) when supported.
204
+
188
205
  ## Export a session
189
206
 
190
207
  Export when you want notes outside Kward:
@@ -193,20 +210,35 @@ Export when you want notes outside Kward:
193
210
  /export notes.md
194
211
  ```
195
212
 
213
+ With no argument, `/export` writes a Markdown file beside the session file, derived from the session name with a `.md` extension.
214
+
196
215
  Exports are useful for handoff notes, review summaries, release records, or saving a human-readable transcript before deleting old sessions.
197
216
 
217
+ ## Check session status
218
+
219
+ Use `/status` to see the active session name, file path, and auto-compaction reserve at a glance:
220
+
221
+ ```text
222
+ /status
223
+ ```
224
+
225
+ This is useful when you want to confirm which session you are in or check whether auto-compaction is active.
226
+
198
227
  ## Which command should I use?
199
228
 
200
229
  | Need | Use |
201
230
  | --- | --- |
202
231
  | Continue earlier work | `/sessions` or `/resume` |
203
232
  | Give the current session a better name | `/rename <name>` |
233
+ | Clear the current session name | `/name` |
204
234
  | Keep the current state but try another future | `/clone` |
205
235
  | Start a separate session from before an earlier prompt | `/fork` |
206
236
  | Quickly retry an earlier prompt in this session | `/rewind` |
207
237
  | Inspect or navigate the full branch structure | `/tree` |
208
238
  | Reduce old context so a long session can continue | `/compact` |
239
+ | Copy the last response or full transcript to clipboard | `/copy [last\|transcript]` |
209
240
  | Save a readable transcript | `/export <path>` |
241
+ | Check the active session and compaction status | `/status` |
210
242
 
211
243
  ## Practical habits
212
244
 
@@ -218,3 +250,5 @@ Exports are useful for handoff notes, review summaries, release records, or savi
218
250
  - Compact when the conversation gets long, but keep the focus instruction specific.
219
251
 
220
252
  Sessions make Kward less like a single chat box and more like a workspace timeline. You can preserve context, branch it, compress it, and return to it when the work needs another pass.
253
+
254
+ RPC clients have their own session API with equivalent create, resume, list, clone, fork, rename, and compaction methods. See the [RPC documentation](rpc.md) for details.
data/doc/shell.md ADDED
@@ -0,0 +1,286 @@
1
+ # Embedded shell
2
+
3
+ Use `/shell` when you want to run a sequence of local commands without leaving Kward's interactive TUI.
4
+
5
+ `/shell` opens **ekwsh**, the embedded Kward shell. It is not a full terminal emulator. Kward keeps ownership of the composer, transcript, tab bar, and keybindings while each command runs through your normal shell one command at a time.
6
+
7
+ This makes it good for:
8
+
9
+ - checking Git state,
10
+ - running focused tests,
11
+ - inspecting files with command-line tools,
12
+ - using project aliases,
13
+ - keeping command output visible beside the current Kward session.
14
+
15
+ It is not intended for full-screen interactive programs such as `vim`, `less`, `top`, `ssh`, or REPLs.
16
+
17
+ ## Start shell mode
18
+
19
+ Inside interactive Kward:
20
+
21
+ ```text
22
+ /shell
23
+ ```
24
+
25
+ The composer prompt changes to show the shell's current directory:
26
+
27
+ ```text
28
+ Shell ~/code/project $
29
+ ```
30
+
31
+ Type commands as you would in a normal shell:
32
+
33
+ ```sh
34
+ git status --short
35
+ bundle exec ruby -Itest test/test_ekwsh.rb
36
+ cd lib/kward
37
+ pwd
38
+ ```
39
+
40
+ Leave shell mode with:
41
+
42
+ ```sh
43
+ exit
44
+ ```
45
+
46
+ or press Ctrl+D on an empty shell prompt.
47
+
48
+ ## How commands run
49
+
50
+ `ekwsh` runs each command through your configured shell using the shell's `-c` mode. It uses `$SHELL` when set, otherwise `/bin/sh`. The shell is intentionally not started as a login shell so Kward-managed environment values, such as configured PATH entries, are not overwritten by login startup files.
51
+
52
+ The current directory and exported environment are tracked by Kward between commands, so this works as expected:
53
+
54
+ ```sh
55
+ cd test
56
+ pwd
57
+ export FOO=bar
58
+ printf '%s\n' "$FOO"
59
+ unset FOO
60
+ ```
61
+
62
+ `cd` changes only the embedded shell's current directory. It does not change Kward's workspace root or the process directory used by the rest of Kward.
63
+
64
+ Shell output is shown in the transcript area, but it is not added to the AI conversation history.
65
+
66
+ ## Built-ins
67
+
68
+ `ekwsh` handles a small set of built-ins itself:
69
+
70
+ | Built-in | What it does |
71
+ | --- | --- |
72
+ | `cd [dir]` | Change the embedded shell directory. Supports `cd`, `cd -`, and normal relative paths. |
73
+ | `pwd` | Print the embedded shell directory. |
74
+ | `export KEY=value` | Set an environment variable for later commands. |
75
+ | `unset KEY` | Remove an environment variable from later commands. |
76
+ | `alias [name]` | List configured aliases, or show specific configured aliases. |
77
+ | `clear` | Clear Kward's visible transcript. |
78
+ | `exit` / `logout` | Leave shell mode. |
79
+
80
+ Built-ins take precedence over aliases and executables.
81
+
82
+ ## Tabs
83
+
84
+ Shell mode is tracked per Kward tab.
85
+
86
+ If you enter `/shell` in one tab, switch to another tab, and later switch back, that tab is still in shell mode. Its shell state and transcript snapshot are restored until you leave shell mode in that tab.
87
+
88
+ This means each tab can have its own:
89
+
90
+ - shell current directory,
91
+ - exported environment,
92
+ - visible shell transcript,
93
+ - command prompt state.
94
+
95
+ Kward's normal tab-switching shortcuts continue to work in shell mode.
96
+
97
+ ## Tab completion
98
+
99
+ Plain Tab completes shell input while in `ekwsh`.
100
+
101
+ Completion includes:
102
+
103
+ - built-in command names,
104
+ - configured aliases,
105
+ - executable names from `$PATH`,
106
+ - file paths from the shell's current directory.
107
+
108
+ Examples:
109
+
110
+ ```sh
111
+ pw<Tab> # pwd
112
+ ll<Tab> # configured alias, if present
113
+ cat lib/kw<Tab> # path completion
114
+ cd doc<Tab> # directory-only completion for cd
115
+ ```
116
+
117
+ Directory completions get a trailing slash. File and command completions get a trailing space when there is a single match.
118
+
119
+ Paths with spaces are shell-escaped:
120
+
121
+ ```sh
122
+ cat my<Tab>
123
+ # => cat my\ file.txt
124
+ ```
125
+
126
+ If there are multiple candidates, Kward applies any common prefix. When there is no longer common prefix, it prints a compact candidate list in the transcript.
127
+
128
+ ## Colors and ANSI output
129
+
130
+ `ekwsh` preserves safe ANSI SGR color/style sequences in command output, such as:
131
+
132
+ - colors,
133
+ - bold,
134
+ - dim,
135
+ - italic,
136
+ - underline,
137
+ - 256-color and truecolor SGR sequences.
138
+
139
+ It strips terminal-control sequences that could corrupt Kward's TUI, such as cursor movement, clear-screen controls, OSC title changes, and alternate-screen controls.
140
+
141
+ When rbenv is available, `ekwsh` also prepends the rbenv shims and bin directories to PATH and sets `RBENV_ROOT` when it was missing. This lets commands such as `ruby`, `bundle`, and `./exe/kward` use the same Ruby selected by rbenv without requiring `rbenv init` support in `ekwsh`.
142
+
143
+ By default, `ekwsh` sets conservative color-friendly environment values:
144
+
145
+ ```sh
146
+ CLICOLOR=1
147
+ COLORTERM=truecolor
148
+ TERM=xterm-256color # only when TERM is missing or dumb
149
+ ```
150
+
151
+ It does **not** force color by default. If a tool does not emit color because stdout is not a TTY, use a command-specific flag or configure forced color yourself:
152
+
153
+ ```sh
154
+ git diff --color=always
155
+ grep --color=always TODO lib/**/*.rb
156
+ ```
157
+
158
+ ## Global ekwsh config
159
+
160
+ You can configure environment variables and aliases in:
161
+
162
+ ```text
163
+ ~/.kward/ekwsh.yml
164
+ ```
165
+
166
+ If `KWARD_CONFIG_PATH` points to another config file, `ekwsh.yml` is read from that file's directory instead.
167
+
168
+ Example:
169
+
170
+ ```yaml
171
+ env:
172
+ FORCE_COLOR: "1"
173
+ CLICOLOR_FORCE: "1"
174
+ RAILS_ENV: "test"
175
+
176
+ aliases:
177
+ ll: "ls -la"
178
+ gs: "git status --short"
179
+ gd: "git diff --color=always"
180
+ be: "bundle exec"
181
+ t: "bundle exec ruby -Itest"
182
+ ```
183
+
184
+ ### Environment variables
185
+
186
+ `env` values are applied when shell mode starts, after Kward's conservative color defaults.
187
+
188
+ Keys must look like environment variable names:
189
+
190
+ ```text
191
+ A_Z, digits after the first character, and underscores
192
+ ```
193
+
194
+ Invalid keys are ignored. Values are converted to strings. Nil values are ignored.
195
+
196
+ Configured env is useful for local preferences such as:
197
+
198
+ ```yaml
199
+ env:
200
+ FORCE_COLOR: "1"
201
+ BUNDLE_WITHOUT: "production"
202
+ RAILS_ENV: "test"
203
+ ```
204
+
205
+ For one shell session, you can also use the built-in `export` command:
206
+
207
+ ```sh
208
+ export FORCE_COLOR=1
209
+ ```
210
+
211
+ ### Aliases
212
+
213
+ Aliases expand the first word of a command once.
214
+
215
+ With this config:
216
+
217
+ ```yaml
218
+ aliases:
219
+ ll: "ls -la"
220
+ t: "bundle exec ruby -Itest"
221
+ ```
222
+
223
+ these commands run as:
224
+
225
+ ```sh
226
+ ll lib
227
+ # runs: ls -la lib
228
+
229
+ t test/test_ekwsh.rb
230
+ # runs: bundle exec ruby -Itest test/test_ekwsh.rb
231
+ ```
232
+
233
+ Aliases are intentionally simple:
234
+
235
+ - only the first word is expanded,
236
+ - aliases do not recursively expand,
237
+ - built-ins win over alias names,
238
+ - aliases are not shell functions,
239
+ - aliases are global for now.
240
+
241
+ List configured aliases inside `ekwsh`:
242
+
243
+ ```sh
244
+ alias
245
+ ```
246
+
247
+ Show specific aliases:
248
+
249
+ ```sh
250
+ alias ll gs
251
+ ```
252
+
253
+ Aliases also appear in command-name Tab completion.
254
+
255
+ ## `/shell` versus `!command`
256
+
257
+ Kward has two ways to run local commands yourself:
258
+
259
+ ```text
260
+ !git status --short
261
+ ```
262
+
263
+ runs one command directly from the normal composer.
264
+
265
+ ```text
266
+ /shell
267
+ ```
268
+
269
+ starts an embedded command mode for several commands with persistent shell state, aliases, completion, and per-tab shell context.
270
+
271
+ Use `!command` for one-offs. Use `/shell` when you expect to run several commands in a row.
272
+
273
+ ## Limitations
274
+
275
+ `ekwsh` is deliberately not a full interactive terminal.
276
+
277
+ Current limitations:
278
+
279
+ - no job control,
280
+ - no persistent shell functions,
281
+ - no shell startup file sourcing,
282
+ - no full-screen terminal applications,
283
+ - no native readline from your login shell,
284
+ - command output is captured through pipes, not a PTY.
285
+
286
+ Some tools only emit color or progress UI when stdout is a real terminal. Prefer explicit command flags such as `--color=always` when needed.
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).