kiwimatecoder 0.1.0__py3-none-any.whl

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 (104) hide show
  1. kiwimatecoder/__init__.py +8 -0
  2. kiwimatecoder/__main__.py +12 -0
  3. kiwimatecoder/acp/__init__.py +13 -0
  4. kiwimatecoder/acp/protocol.py +115 -0
  5. kiwimatecoder/acp/server.py +823 -0
  6. kiwimatecoder/acp/stdio.py +32 -0
  7. kiwimatecoder/agent.py +1162 -0
  8. kiwimatecoder/ai.py +68 -0
  9. kiwimatecoder/audit.py +65 -0
  10. kiwimatecoder/browser.py +261 -0
  11. kiwimatecoder/catalog.py +445 -0
  12. kiwimatecoder/checkpoints.py +103 -0
  13. kiwimatecoder/client.py +820 -0
  14. kiwimatecoder/clipboard.py +99 -0
  15. kiwimatecoder/commands.py +6757 -0
  16. kiwimatecoder/config.py +5335 -0
  17. kiwimatecoder/diagnostics.py +295 -0
  18. kiwimatecoder/documents.py +299 -0
  19. kiwimatecoder/evals/__init__.py +39 -0
  20. kiwimatecoder/evals/cases.py +230 -0
  21. kiwimatecoder/evals/render.py +46 -0
  22. kiwimatecoder/evals/runner.py +319 -0
  23. kiwimatecoder/events.py +95 -0
  24. kiwimatecoder/forge.py +172 -0
  25. kiwimatecoder/git.py +164 -0
  26. kiwimatecoder/headless.py +255 -0
  27. kiwimatecoder/hooks.py +170 -0
  28. kiwimatecoder/hunks.py +260 -0
  29. kiwimatecoder/i18n.py +368 -0
  30. kiwimatecoder/images.py +195 -0
  31. kiwimatecoder/index/__init__.py +14 -0
  32. kiwimatecoder/index/builder.py +376 -0
  33. kiwimatecoder/index/embeddings.py +151 -0
  34. kiwimatecoder/index/search.py +247 -0
  35. kiwimatecoder/index/store.py +251 -0
  36. kiwimatecoder/instructions.py +83 -0
  37. kiwimatecoder/jobs.py +594 -0
  38. kiwimatecoder/lsp/__init__.py +56 -0
  39. kiwimatecoder/lsp/client.py +548 -0
  40. kiwimatecoder/lsp/manager.py +353 -0
  41. kiwimatecoder/lsp/protocol.py +79 -0
  42. kiwimatecoder/main.py +4258 -0
  43. kiwimatecoder/mcp/__init__.py +45 -0
  44. kiwimatecoder/mcp/client.py +385 -0
  45. kiwimatecoder/mcp/errors.py +7 -0
  46. kiwimatecoder/mcp/manager.py +253 -0
  47. kiwimatecoder/mcp/protocol.py +132 -0
  48. kiwimatecoder/media.py +904 -0
  49. kiwimatecoder/memory.py +141 -0
  50. kiwimatecoder/network.py +112 -0
  51. kiwimatecoder/notify.py +139 -0
  52. kiwimatecoder/permissions.py +171 -0
  53. kiwimatecoder/pickers.py +417 -0
  54. kiwimatecoder/plugins.py +245 -0
  55. kiwimatecoder/pricing.py +167 -0
  56. kiwimatecoder/prompts.py +213 -0
  57. kiwimatecoder/providers.py +342 -0
  58. kiwimatecoder/redaction.py +66 -0
  59. kiwimatecoder/remote.py +294 -0
  60. kiwimatecoder/repl.py +1388 -0
  61. kiwimatecoder/routing.py +65 -0
  62. kiwimatecoder/sandbox.py +169 -0
  63. kiwimatecoder/sdk.py +146 -0
  64. kiwimatecoder/session.py +574 -0
  65. kiwimatecoder/share.py +386 -0
  66. kiwimatecoder/shell.py +660 -0
  67. kiwimatecoder/skills.py +138 -0
  68. kiwimatecoder/sync.py +513 -0
  69. kiwimatecoder/team.py +249 -0
  70. kiwimatecoder/telemetry.py +392 -0
  71. kiwimatecoder/templates.py +108 -0
  72. kiwimatecoder/tools/__init__.py +190 -0
  73. kiwimatecoder/tools/ask.py +62 -0
  74. kiwimatecoder/tools/base.py +69 -0
  75. kiwimatecoder/tools/browser.py +261 -0
  76. kiwimatecoder/tools/edit_file.py +143 -0
  77. kiwimatecoder/tools/forge.py +207 -0
  78. kiwimatecoder/tools/git.py +158 -0
  79. kiwimatecoder/tools/image.py +300 -0
  80. kiwimatecoder/tools/io.py +346 -0
  81. kiwimatecoder/tools/list_dir.py +67 -0
  82. kiwimatecoder/tools/lsp.py +254 -0
  83. kiwimatecoder/tools/memory.py +115 -0
  84. kiwimatecoder/tools/paths.py +234 -0
  85. kiwimatecoder/tools/read_file.py +113 -0
  86. kiwimatecoder/tools/registry.py +91 -0
  87. kiwimatecoder/tools/run_bash.py +189 -0
  88. kiwimatecoder/tools/search.py +224 -0
  89. kiwimatecoder/tools/selection.py +108 -0
  90. kiwimatecoder/tools/shell.py +158 -0
  91. kiwimatecoder/tools/skill.py +46 -0
  92. kiwimatecoder/tools/task.py +61 -0
  93. kiwimatecoder/tools/todo.py +77 -0
  94. kiwimatecoder/tools/web.py +146 -0
  95. kiwimatecoder/tools/write_file.py +83 -0
  96. kiwimatecoder/ui.py +189 -0
  97. kiwimatecoder/updater.py +502 -0
  98. kiwimatecoder/web.py +499 -0
  99. kiwimatecoder-0.1.0.dist-info/METADATA +2016 -0
  100. kiwimatecoder-0.1.0.dist-info/RECORD +104 -0
  101. kiwimatecoder-0.1.0.dist-info/WHEEL +5 -0
  102. kiwimatecoder-0.1.0.dist-info/entry_points.txt +2 -0
  103. kiwimatecoder-0.1.0.dist-info/licenses/LICENSE +21 -0
  104. kiwimatecoder-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2016 @@
1
+ Metadata-Version: 2.4
2
+ Name: kiwimatecoder
3
+ Version: 0.1.0
4
+ Summary: AI-powered coding assistant CLI. Bring your own API key.
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 Kyle8933
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Requires-Python: >=3.10
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: typer>=0.12
31
+ Requires-Dist: rich>=13
32
+ Requires-Dist: httpx>=0.27
33
+ Requires-Dist: prompt_toolkit>=3.0.52
34
+ Provides-Extra: browser
35
+ Requires-Dist: playwright>=1.40; extra == "browser"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=8; extra == "dev"
38
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
39
+ Requires-Dist: click>=8.0; extra == "dev"
40
+ Dynamic: license-file
41
+
42
+ # kiwimatecoder
43
+
44
+ An agentic AI coding assistant for your terminal. Run one command and drop into an
45
+ interactive session that can read, edit, and run code in your project — across the
46
+ model provider of your choice. Bring your own API key.
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install -e .
52
+ ```
53
+
54
+ For a regular (non-editable) install:
55
+
56
+ ```bash
57
+ pip install .
58
+ ```
59
+
60
+ ### Installation options
61
+
62
+ **Install script** (no clone needed; installs from GitHub):
63
+
64
+ ```bash
65
+ curl -fsSL https://raw.githubusercontent.com/Kyle8933/kiwimatecoder/main/scripts/install.sh | sh
66
+ ```
67
+
68
+ The script checks for Python >= 3.10, prefers `pipx` when available (falling
69
+ back to `pip install --user`), verifies `kiwimatecoder --version`, and prints
70
+ PATH guidance when the console script is not yet visible. Append `-s <ref>` to
71
+ install a tag, branch, or commit, or set `KIWIMATECODER_REF`.
72
+
73
+ **Docker:**
74
+
75
+ ```bash
76
+ docker build -t kiwimatecoder .
77
+ docker run --rm -it -v "$PWD:/workspace" -e OPENROUTER_API_KEY kiwimatecoder
78
+ docker run --rm -v "$PWD:/workspace" -e OPENROUTER_API_KEY kiwimatecoder \
79
+ -p "Summarize this repository" --model anthropic/claude-sonnet-5
80
+ ```
81
+
82
+ The image is `python:3.12-slim`, installs the package, and runs as the
83
+ non-root `kiwimate` user with `/workspace` as the working directory. A fresh
84
+ container has no saved config, so no model is chosen: pass `--model` (see
85
+ [Choosing a model](#choosing-a-model)).
86
+
87
+ **Homebrew:** `packaging/homebrew/kiwimatecoder.rb` is a virtualenv formula
88
+ template pinned to a git tag. It is not published to a tap yet; fill in the
89
+ tag revision and generate the `resource` blocks as described in the file, then
90
+ install with `brew install --build-from-source ./packaging/homebrew/kiwimatecoder.rb`.
91
+
92
+ ## Quick start
93
+
94
+ Add an API key for at least one provider, then launch the interactive session:
95
+
96
+ ```bash
97
+ kiwimatecoder setup
98
+ kiwimatecoder
99
+ ```
100
+
101
+ `kiwimatecoder setup` walks you through choosing a provider, saving its API
102
+ key, and choosing the model to use with it. There are no default models: after
103
+ the key is saved, setup shows the provider's model list (plus **Type a model
104
+ id…** for anything unlisted), and your pick is remembered for that provider.
105
+ You can also pass the arguments directly:
106
+
107
+ ```bash
108
+ kiwimatecoder setup --provider openrouter
109
+ kiwimatecoder setup --provider openai --key sk-... --model gpt-5.6-sol # non-interactive
110
+ ```
111
+
112
+ Without a terminal (or if you cancel the picker) and no earlier choice, setup
113
+ prints `No model chosen yet` (a local server instead uses the first model it
114
+ lists); the REPL then asks for a model when it starts, or you can set one later
115
+ with `kiwimatecoder config model set <id>`. At launch the REPL also asks about
116
+ any fallback provider on the roster that has no model (failover skips those),
117
+ and `kiwimatecoder doctor` warns about them.
118
+
119
+ Running `kiwimatecoder` with no arguments opens the interactive REPL. It keeps
120
+ running until you exit. Type a request in plain language and KiwiMateCoder will
121
+ read files, search the codebase, propose edits, and run commands to carry it
122
+ out. For larger or ambiguous tasks, it starts with a short plan and gives you a
123
+ few concrete options so you can choose the scope and tradeoffs before it
124
+ proceeds.
125
+
126
+ ```
127
+ kiwi (openrouter:anthropic/claude-sonnet-5 · ask) › add a docstring to main.py
128
+ ```
129
+
130
+ - **Ctrl-C** cancels the current turn and returns you to the prompt; whatever
131
+ the model had already streamed is kept in the conversation so you can continue
132
+ from it.
133
+ - **Ctrl-D** exits the session.
134
+ - While the agent is working you can type ahead: press Enter to send a steering
135
+ message and the model picks it up on its next step, or type a slash command
136
+ (e.g. `/undo`) and it runs as soon as the turn finishes. Ctrl-C during the
137
+ turn cancels it.
138
+ - Your prompt history is saved; the up-arrow recalls commands from previous
139
+ sessions.
140
+ - Every session is auto-saved when you exit. Pick it back up with
141
+ `kiwimatecoder --continue` (same as `--resume last`), or from inside the REPL
142
+ with `/load last`.
143
+ - Type `/` to open the slash-command menu. It filters as you keep typing.
144
+ - Run `/model`, `/provider`, or `/mode` without an argument to open a
145
+ keyboard-driven selector. `/provider` is a checklist: check every provider you
146
+ want on the failover roster. The first checked provider is the primary; the
147
+ rest are tried in order if the primary fails. Experimental providers
148
+ (currently KiwiMate) appear in their own **Experimental** box at the top of
149
+ the list. After you confirm, you choose a model for every provider on the
150
+ roster that does not have one yet. `/provider <id>` replaces the roster with
151
+ that single provider (and asks for its model if none is chosen). Arrow keys
152
+ move, Enter selects, and Ctrl-C returns to the prompt without changing
153
+ anything.
154
+ - Opening `/model` checks the provider for models released since you last looked,
155
+ and drops any it has retired. `/model refresh` forces the check. The model you
156
+ pick is saved as that provider's model for the next session. Each provider
157
+ remembers its own model, so switching the primary with `/provider` uses the
158
+ model chosen for the new primary instead of carrying a vendor-specific id
159
+ across providers. `/config model reset` forgets the choice: pick another with
160
+ `/model` (local servers fall back to the first model they list).
161
+ - `/model search <term>` searches the provider's full catalog by name and opens
162
+ the selector on the matches — useful when a model is older than the newest few
163
+ that `/model` lists.
164
+ - Use `/mode plan` when you only want investigation and options, with no edits or
165
+ shell commands.
166
+
167
+ ## Permission modes
168
+
169
+ The agent can edit files and run shell commands. A permission mode controls how much
170
+ it can do without asking, and you can switch it at any time with `/mode`:
171
+
172
+ | Mode | Behavior |
173
+ |------|----------|
174
+ | `ask` (default) | Reads run freely; every file write/edit or shell command shows a preview/diff and waits for your approval. |
175
+ | `auto-accept` | Actions run without prompting. |
176
+ | `plan` | Read-only: the agent can inspect and explain, but cannot write or run anything. |
177
+
178
+ At an approval prompt, answer `a` (always) to approve that tool for the rest of
179
+ the session **and future sessions**. Persisted approvals survive restarts and
180
+ provider switches; manage them with `/config permissions` or
181
+ `config permissions list|remove|clear`. When a diff spans multiple hunks, answer
182
+ `h` to choose which hunks to apply (e.g. `1,3`, `1-2`, `all`, or `none`).
183
+
184
+ Every mutating action is checkpointed before it runs. Restore the last change
185
+ with `/undo`, rewind several steps with `/undo 3`, and list them with
186
+ `/checkpoints`.
187
+
188
+ Reads, writes, edits, listings and searches are sandboxed to the workspace root (via symlink-aware path resolution). `run_bash` commands execute with the workspace root as their cwd but are otherwise unrestricted (subject to approval/mode); use them for git, tests, builds, etc.
189
+
190
+ ### Command rules
191
+
192
+ Auto-approve trusted commands and hard-block dangerous ones with regex rules
193
+ (deny rules block even in `auto-accept` mode):
194
+
195
+ ```text
196
+ /config commands allow ^pytest\b
197
+ /config commands deny rm\s+-rf
198
+ /config commands list
199
+ ```
200
+
201
+ ### Dry run and trusted workspace
202
+
203
+ `/dry-run` previews every mutating tool call (diffs and shell commands) without
204
+ executing anything or prompting. `/config trust on` lets read-only tools read
205
+ paths outside the workspace root; writes stay sandboxed.
206
+
207
+ ## Slash commands
208
+
209
+ | Command | Description |
210
+ |---------|-------------|
211
+ | `/help` | Show available commands. |
212
+ | `/exit`, `/quit` | Leave the session. |
213
+ | `/clear` | Clear the conversation history. |
214
+ | `/model [name\|refresh\|list\|search <term>]` | Interactively choose a model (the list is refreshed from the provider), set one by name, refresh/show the list, or search the full catalog by name. The choice is remembered for that provider. |
215
+ | `/provider [id]` | Choose a failover roster (checklist; experimental providers sit in their own box at the top), or replace it with one provider by id. Asks for a model for each provider that has none. |
216
+ | `/mode [ask\|auto-accept\|plan]` | Interactively choose, or directly set, the permission mode. |
217
+ | `/dry-run [on\|off\|toggle]` | Preview mutating actions without running them. |
218
+ | `/undo [count]`, `/checkpoints` | Restore files changed by recent tools, or list checkpoints. |
219
+ | `/todos` | Show the agent's task list. |
220
+ | `/templates` | List custom prompt templates discovered in the workspace and user command directories. |
221
+ | `/compact [budget]` | Trim older history to fit a token budget. |
222
+ | `/save`, `/load`, `/sessions`, `/fork [name]`, `/export [path]` | Save, resume, branch, or export sessions as Markdown. |
223
+ | `/share [gist] [--include-tool-output]`, `/share import <path> [--name NAME]` | Share a redacted session bundle as a local file or a secret GitHub gist, or import one as a saved session. |
224
+ | `/sync [status\|push\|pull]` | Show or sync saved sessions across machines through a shared folder (opt-in). |
225
+ | `/tools` | List available tools. |
226
+ | `/files` | List files changed this session. |
227
+ | `/context [list\|add\|remove\|clear]` | Pin files to include as context on every turn. |
228
+ | `/image model [list\|refresh\|search <term>\|<id>]`, `/image [--size WxH] [--model id] <prompt>` | Generate an image with the configured media provider and attach it to your next message (opt-in; see [Image and video generation](#image-and-video-generation)). |
229
+ | `/video model [list\|refresh\|search <term>\|<id>]`, `/video [--duration s] [--size 720p] [--model id] [--image path] <prompt>`, `/video resume <job-id>` | Generate a short video (billed per second; takes minutes), or fetch a job that was still rendering. |
230
+ | `/media [list [count]\|provider [id]]` | Show whether image and video generation are ready, list recently generated files, or switch the media provider. |
231
+ | `/memory [list\|add\|add-user\|clear]` | Show or edit persistent project and user memory. |
232
+ | `/index [status\|build\|clear]` | Show, refresh, or delete the local codebase index used by semantic search. |
233
+ | `/jobs [list\|show <id>\|cancel <id>\|tick\|run <prompt>]` | List or manage detached background agent jobs; `tick` starts due scheduled runs. |
234
+ | `/config` | Show or change providers, keys, models, filters, permissions, command rules, sampling, styles, themes, output modes, accessibility, verify, and budgets. |
235
+ | `/mcp [list\|reload]` | List configured MCP servers, their status, and registered tools; `reload` reconnects every server. |
236
+ | `/cost` | Show token usage, context gauge, and estimated USD cost for this session (per-model pricing). |
237
+ | `/doctor` | Run environment, config, provider, and workspace diagnostics. |
238
+
239
+ Examples:
240
+
241
+ ```text
242
+ /context add README.md kiwimatecoder/*.py
243
+ /undo 2
244
+ /export review.md
245
+ /fork experiment
246
+ ```
247
+
248
+ Config examples:
249
+
250
+ ```text
251
+ /config
252
+ /config provider add local "Local Models" http://localhost:1234/v1 local-code LOCAL_API_KEY
253
+ /config provider edit local name="Local Models 2" model=local-fast
254
+ /config key set local <YOUR_KEY>
255
+ /config provider use local
256
+ /config model set anthropic/claude-sonnet-5 openrouter
257
+ /config model reset openrouter
258
+ /config models allow local-code local-fast
259
+ /config models deny noisy-model
260
+ /config models refresh
261
+ /config mode set plan
262
+ /config permissions list
263
+ /config permissions remove run_bash
264
+ /config commands allow ^pytest\b
265
+ /config commands deny rm\s+-rf
266
+ /config sampling set temperature=0.2 max_tokens=4096
267
+ /config sampling reset
268
+ /config style set concise
269
+ /config ui theme ocean
270
+ /config ui output compact
271
+ /config ui ascii on
272
+ /config prompt set "Prefer functional style; never use classes."
273
+ /config prompt clear
274
+ /config verify set "pytest -q"
275
+ /config budget tokens 500000
276
+ /config budget cost 5.00
277
+ /config trust on
278
+ /config remote host devbox
279
+ /config remote user kiwi
280
+ /config remote workspace /srv/app
281
+ /config remote enable on
282
+ /config browser enable on
283
+ /config browser headless off
284
+ /config browser timeout 20000
285
+ /config provider remove local
286
+ ```
287
+
288
+ Running bare `/config` opens an interactive menu. Picking an entry lets you
289
+ change that setting: toggles and fixed choices (theme, locale, log level, …) are
290
+ picked from a list, free-form values (a proxy URL, an image size, a regex) are
291
+ typed, and each list shows the current value. Sections with several independent
292
+ settings, such as **Media** or **UI**, return to their list after each change
293
+ until you pick **Done** (Ctrl-C also leaves; at a typed prompt, Ctrl-C or an
294
+ empty line cancels just that entry). **Keys** works the same way: choose a
295
+ provider, then set (type a new key, which is not shown as you type) or remove
296
+ it. Only **Show** and **help** just print. Every entry also works as a typed
297
+ command as shown above, and `/config key set` / `/config key list` always show
298
+ which file or environment variable the active key comes from.
299
+
300
+ ## Tools
301
+
302
+ The assistant has these capabilities, all scoped to the workspace:
303
+
304
+ - `read_file`, `list_dir`, `search` (grep + glob + semantic) — read-only,
305
+ always allowed; batches of read-only calls run in parallel.
306
+ - `view_image` — attach a workspace image (`.png`, `.jpg`, `.jpeg`, `.gif`,
307
+ `.webp`) so a vision-capable model can see it (see below).
308
+ - `generate_image`, `generate_video` — create an image or a short video through the
309
+ configured media provider and save it under `.kiwimatecoder/media/` (opt-in and
310
+ approval-gated because they cost money; see below).
311
+ - `write_file`, `edit_file` — create/modify files (approval-gated; each is
312
+ checkpointed first so `/undo` can restore it).
313
+ - `run_bash` — run shell commands (approval-gated, subject to command rules).
314
+ - `shell` — run a command in a persistent shell that remembers `cd` and exported
315
+ environment state between calls (approval-gated; see below).
316
+ - `shell_jobs` — start, list, read, or kill detached background commands
317
+ (approval-gated; see below).
318
+ - `update_todos` — keep the visible task list in sync with multi-step work.
319
+ - `task` — delegate a focused investigation to a subagent with its own context
320
+ (approval-gated; see below).
321
+ - `ask_user` — ask a clarifying question with optional choices (interactive
322
+ sessions only).
323
+ - `web_fetch`, `web_search` — read a page or search the web; read-only, and
324
+ local/private addresses are blocked by default (see below).
325
+ - `browser` — drive an optional headless Chromium page (screenshot, click,
326
+ type, evaluate) when Playwright is installed and browser automation is
327
+ enabled (approval-gated; see below).
328
+ - `remember`, `recall` — persist and read durable facts across sessions (see
329
+ below).
330
+ - `git`, `git_write` — inspect status/diff/log and stage, unstage, commit, or
331
+ create a branch (see below).
332
+ - `forge`, `forge_write` — list/view or create pull requests/merge requests
333
+ and issues through the `gh`/`glab` CLI (see below).
334
+ - `read_clipboard`, `write_clipboard` — read the system clipboard or copy text
335
+ to it (see below).
336
+ - `http_get`, `http_request` — exercise an HTTP API and inspect the response
337
+ (see below).
338
+ - `lsp_diagnostics`, `lsp_definition`, `lsp_references` — language-server
339
+ diagnostics and navigation, when enabled (see below).
340
+
341
+ ## Persistent shell
342
+
343
+ `run_bash` starts a fresh process per call, so `cd` and exported environment
344
+ variables never survive between commands. The `shell` tool instead drives one
345
+ long-lived shell per session (`/bin/sh` on POSIX, Git Bash on Windows; install
346
+ Git for Windows, or turn it off with `config shell persistent off`) so state
347
+ sticks:
348
+
349
+ ```text
350
+ shell: cd backend
351
+ shell: source .venv/bin/activate
352
+ shell: pytest -q # runs inside backend with the venv active
353
+ ```
354
+
355
+ - The shell starts in the session workspace root. Output (stdout + stderr
356
+ combined) is capped at 30 KB with a truncation note, and every call reports
357
+ the exit code.
358
+ - A command that exceeds the timeout (default 120 s) is killed and the shell is
359
+ restarted, so a hung command can never wedge the session.
360
+ - `shell_jobs` runs commands detached from the shell and captures their output
361
+ under `~/.kiwimatecoder/jobs/shell/`. `action: list` shows tracked jobs,
362
+ `action: output` reads one, and `action: kill` terminates it. At most
363
+ `shell.max_jobs` (default 8) run at once.
364
+ - Settings: `/config shell [show|persistent on|off|timeout <s>|max-jobs <n>]`
365
+ in the REPL, or `kiwimatecoder config shell ...` from the shell.
366
+ - Exiting the session terminates the persistent shell and every tracked
367
+ background job. `run_bash` is unchanged and still the right tool for
368
+ one-shot commands.
369
+
370
+ ## Command sandboxing
371
+
372
+ On macOS and Linux you can execute `run_bash` (and the persistent shell and its
373
+ background jobs) through an OS-level sandbox. It is **off by default**:
374
+
375
+ ```bash
376
+ kiwimatecoder config sandbox show
377
+ kiwimatecoder config sandbox enable on
378
+ kiwimatecoder config sandbox network off # block network access
379
+ kiwimatecoder config sandbox add-path ~/shared # extra writable directory
380
+ ```
381
+
382
+ The REPL equivalent is `/config sandbox [show|enable on|off|network on|off|
383
+ add-path <path>|remove-path <path>|clear-paths]`.
384
+
385
+ - **macOS** uses seatbelt via `sandbox-exec`: `process*` is allowed, reads are
386
+ broadly allowed, and writes are limited to the workspace, `/tmp`, and
387
+ `extra_writable`.
388
+ - **Linux** uses bubblewrap (`bwrap`): `/` is mounted read-only, the workspace
389
+ is read-write, `/tmp` is a private tmpfs, and `--unshare-net` is added when
390
+ the network toggle is off. Install the `bubblewrap` package to use it.
391
+ - Windows has no supported backend; enabling it there falls back to running
392
+ unsandboxed with a warning in the tool output.
393
+ - When the sandbox is enabled, the approval preview shows the wrapped command
394
+ and the network mode. If the backend is missing or fails to start, the tool
395
+ warns and runs the command unsandboxed rather than failing.
396
+ - Config lives in the `sandbox` section:
397
+ `{"enabled": false, "network": true, "extra_writable": []}`.
398
+
399
+ > **Limitations:** the sandbox is a damage-limiter for ordinary commands, not a
400
+ > security boundary against a hostile model or malicious code. Reads stay
401
+ > broad, the sandbox runs with your user's privileges (no user namespaces or
402
+ > credential isolation on macOS), and an unavailable backend silently degrades
403
+ > to an unsandboxed shell with only a warning. Read access to API keys stored
404
+ > on disk is not blocked, so use `--mode plan` or command rules when that
405
+ > matters.
406
+
407
+ ## Remote and devcontainer execution
408
+
409
+ Shell commands can run on another machine over SSH or inside a
410
+ devcontainer/Docker container. `run_bash`, the persistent `shell`, and
411
+ `shell_jobs` all execute remotely when it is configured; the approval preview
412
+ shows the wrapper and tool output includes a `[remote]` note. It is **off by
413
+ default**:
414
+
415
+ ```bash
416
+ kiwimatecoder config remote show
417
+ kiwimatecoder config remote host devbox # ssh [user@]host
418
+ kiwimatecoder config remote user kiwi # optional
419
+ kiwimatecoder config remote port 2222 # optional (default 22)
420
+ kiwimatecoder config remote identity ~/.ssh/id_ed25519 # optional
421
+ kiwimatecoder config remote workspace /srv/app # cd before running
422
+ kiwimatecoder config remote devcontainer auto # auto|off|container name
423
+ kiwimatecoder config remote enable on
424
+ ```
425
+
426
+ The REPL equivalent is `/config remote [show|enable on|off|host <h>|user <u>|
427
+ port <n>|identity <path>|workspace <path>|devcontainer <auto|off|name>]`.
428
+
429
+ When `devcontainer` is `auto` (the default), the first usable route wins:
430
+
431
+ 1. a `.devcontainer/devcontainer.json` in the workspace **and** the
432
+ `devcontainer` CLI: `devcontainer exec --workspace-folder <ws> sh -lc ...`;
433
+ 2. that detected container through `docker exec -w <workspaceFolder>
434
+ <name> ...`;
435
+ 3. SSH when `remote.host` is set: `ssh -o BatchMode=yes [-p <port>]
436
+ [-i <identity>] [user@]host -- sh -lc ...`, with
437
+ `cd <remote.workspace> && <command>` when a remote workspace is set;
438
+ 4. local execution with a warning in the tool output.
439
+
440
+ Set `devcontainer off` to skip detection, or name a container explicitly to
441
+ force `docker exec`. Remote wrapping happens first and a remote command is not
442
+ additionally wrapped in a local sandbox. If `ssh`, `docker`, or `devcontainer`
443
+ is missing, the command runs locally and the output carries the warning.
444
+
445
+ - Config lives in the `remote` section:
446
+ `{"enabled": false, "host": "", "user": "", "port": 22, "identity": "",
447
+ "workspace": "", "devcontainer": "auto"}`. `identity` must point at an
448
+ existing key file, and enabling remote execution requires a host (or an
449
+ explicit container name).
450
+ - The persistent shell starts through the same wrapper, so `cd` and exported
451
+ variables persist on the remote side. SSH uses agent/key auth only
452
+ (`BatchMode=yes`); there is no password prompt.
453
+
454
+ > **Limitations:** only commands run remotely. File tools (`read_file`,
455
+ > `write_file`, `edit_file`, `search`, ...) still read the **locally**
456
+ > accessible workspace, so point them at the remote tree with sshfs, a bind
457
+ > mount, or a synced checkout. A full SFTP-backed file layer is deliberately
458
+ > not shipped: a half-working remote filesystem would silently split reads and
459
+ > writes between two machines. Detached agent jobs (`/jobs`) also run locally
460
+ > against that same local view. SSH host keys and identity files are the
461
+ > user's responsibility; remote command approval and command rules work
462
+ > exactly as they do locally.
463
+
464
+ ## Web access
465
+
466
+ `web_search` searches the web with the DuckDuckGo HTML endpoint (no API key)
467
+ and returns titles, URLs, and snippets. `web_fetch` downloads a page,
468
+ follows redirects, converts HTML to readable text, and summarizes binary
469
+ responses instead of dumping them. Both are read-only tools, so they run
470
+ without approval and stay available in plan mode, and both descriptions tell
471
+ the model to cite the URLs it relies on.
472
+
473
+ - Response size is capped with a truncation note; defaults are 50,000
474
+ characters and a 20-second timeout.
475
+ - `localhost`, loopback/private/link-local IPs, and `*.local` hosts are
476
+ refused by default. Enable them with `/config web allow-local on` (or
477
+ `kiwimatecoder config web allow-local on`) when you are working against a
478
+ local dev server.
479
+ - Settings live under `/config web show|max-chars <n>|timeout <s>|allow-local <on|off>`
480
+ in the REPL, or `kiwimatecoder config web ...` from the shell.
481
+ - DuckDuckGo parses the public HTML page, so result extraction is best-effort
482
+ and may need updating if that page's markup changes; `web_fetch` is
483
+ unaffected.
484
+
485
+ ## Proxy, custom CA, and offline mode
486
+
487
+ Every outbound request — chat streaming, model catalogs, `web_fetch`/
488
+ `web_search`, and embeddings — honors the `network` settings in
489
+ `~/.kiwimatecoder/config.json`:
490
+
491
+ ```json
492
+ {
493
+ "network": {
494
+ "proxy": "http://proxy.corp:8080",
495
+ "ca_bundle": "/etc/ssl/certs/corp-ca.pem",
496
+ "offline": false
497
+ }
498
+ }
499
+ ```
500
+
501
+ Set them from the REPL with `/config network ...` or from the shell with
502
+ `kiwimatecoder config network ...`:
503
+
504
+ ```bash
505
+ kiwimatecoder config network show
506
+ kiwimatecoder config network proxy http://proxy.corp:8080 # or: clear
507
+ kiwimatecoder config network ca /etc/ssl/certs/corp-ca.pem # or: clear
508
+ kiwimatecoder config network offline on # or: off
509
+ ```
510
+
511
+ - `proxy` routes all requests through an HTTP(S) proxy (`proxy`/`verify` are
512
+ passed to the underlying `httpx` clients).
513
+ - `ca_bundle` points at a PEM file used instead of the system trust store for
514
+ TLS verification — for corporate MITM proxies or self-signed CAs. The file
515
+ must exist when set.
516
+ - `offline on` is air-gapped mode: cloud chat, model catalogs, web tools, and
517
+ embeddings are refused with an "offline mode is enabled" error before any
518
+ request is made. **Local providers keep working** — `ollama`, `lmstudio`,
519
+ `unsloth`, and custom providers on `localhost`/`*.local` are still reachable
520
+ for chat, catalog, and embedding calls. `web_fetch`/`web_search` always
521
+ refuse offline because they only reach the public internet.
522
+
523
+ ## Browser automation
524
+
525
+ The `browser` tool drives a headless Chromium page through Playwright when you
526
+ opt in. Playwright is not installed by default, and the tool stays hidden until
527
+ browser automation is enabled:
528
+
529
+ ```bash
530
+ pip install 'kiwimatecoder[browser]'
531
+ playwright install chromium
532
+ kiwimatecoder config browser enable on
533
+ ```
534
+
535
+ Without the extra, the tool returns a clear install hint instead of failing;
536
+ the base install keeps the same dependency set.
537
+
538
+ - The tool is approval-gated because a page can submit forms or trigger
539
+ downloads. In `ask` mode the preview shows `browser <action> <url|selector>`
540
+ (scripts are redacted and capped). It is not advertised while disabled, and
541
+ plan mode only advertises read-only tools.
542
+ - `open` accepts only `http(s)` URLs and refuses `localhost`, loopback/private
543
+ IPs, and `*.local` hosts unless `/config web allow-local on` is set. It
544
+ reports the final URL after redirects and the page title.
545
+ - `text` returns visible page text capped at ~30,000 characters with a
546
+ truncation note. `click`/`type` take a CSS selector, and `evaluate` runs
547
+ JavaScript and returns a capped JSON-ish result.
548
+ - `screenshot` saves a PNG to
549
+ `<workspace>/.kiwimatecoder/screenshots/<timestamp>.png` and attaches it to
550
+ the next request, so a vision-capable model sees it exactly like a
551
+ `view_image` attachment. The `vision` per-turn count and size limits apply.
552
+ - One page is shared by successive tool calls in a session; `close` (and
553
+ leaving the REPL) shuts Chromium down. `timeout_ms` can override the
554
+ configured action timeout per call.
555
+ - Settings live under `/config browser [show|enable on|off|headless on|off|timeout <ms>]`
556
+ in the REPL, or `kiwimatecoder config browser ...` from the shell (defaults:
557
+ off, headless on, 15,000 ms; timeout range 1s–120s). Changing a setting
558
+ closes the live page so the next call starts with the new values.
559
+
560
+ ```text
561
+ Open https://example.com/docs and summarize the visible text.
562
+ Screenshot the pricing page and tell me what stands out.
563
+ Fill the search box with "playwright" and click Search.
564
+ ```
565
+
566
+ ## Git and forge tools
567
+
568
+ The agent can inspect and change git state through dedicated tools instead of
569
+ dropping to `run_bash`:
570
+
571
+ - `git` (read-only) — `status`, `diff` (staged or not, optionally against a
572
+ ref), `log` (1–100 commits), `show <ref>`, and `branches`.
573
+ - `git_write` (approval-gated) — `stage`, `unstage`, `commit` (a non-empty
574
+ message is required), and `checkout_branch` (creates a new branch). The
575
+ approval prompt shows the exact `git ...` command line.
576
+ - `forge` (read-only) — `pr_list`, `pr_view`, `issue_list`, and `issue_view`
577
+ for the forge detected from the `origin` remote.
578
+ - `forge_write` (approval-gated) — `pr_create` and `issue_create`.
579
+
580
+ Forge integration goes through the official CLI (`gh` for GitHub, `glab` for
581
+ GitLab), so your existing CLI login is used and no token is read or stored by
582
+ KiwiMateCoder. The matching CLI must be installed and authenticated; on
583
+ GitLab, pull requests are handled as merge requests (`glab mr ...`).
584
+
585
+ Intentionally out of scope: `push`, `reset`, `clean`, and any forge
586
+ merge/close/delete command. Those stay manual, or go through `run_bash` where
587
+ the command rules and approval prompt apply.
588
+
589
+ ## Clipboard and HTTP tools
590
+
591
+ Clipboard access uses the platform's standard tool, discovered on `PATH` and
592
+ run without a shell: `pbpaste`/`pbcopy` on macOS, `wl-paste`/`wl-copy`
593
+ (preferred) or `xclip` on Linux, and PowerShell's `Get-Clipboard`/
594
+ `Set-Clipboard` on Windows. If none is installed the tool returns a clear
595
+ install hint instead of failing.
596
+
597
+ - `read_clipboard` is read-only, so it runs without approval.
598
+ - `write_clipboard` is approval-gated and the preview shows the redacted text
599
+ (clipped to ~200 characters).
600
+
601
+ `http_get` and `http_request` exercise HTTP APIs and print the status line,
602
+ selected response headers, and the body (JSON is pretty-printed, bodies are
603
+ truncated with a note). 4xx/5xx responses are returned for inspection rather
604
+ than raised, and ``httpx`` errors are converted to friendly messages.
605
+
606
+ - `http_get(url, headers?)` is read-only.
607
+ - `http_request(method, url, headers?, body?, json?, timeout?)` is
608
+ approval-gated because it can change remote state. Methods are GET, POST,
609
+ PUT, PATCH, and DELETE; `body` (raw text) and `json` are mutually exclusive.
610
+ - Both reuse the `web` settings: response size and timeout come from
611
+ `/config web max-chars` / `/config web timeout`, and local/private addresses
612
+ stay blocked unless `/config web allow-local on`.
613
+
614
+ ```text
615
+ Read what's on my clipboard and save it to notes.txt.
616
+ Copy the test command to my clipboard.
617
+ GET https://api.github.com/repos/psf/requests and summarize the JSON.
618
+ POST https://httpbin.org/post with json {"hello": "world"}.
619
+ ```
620
+
621
+ ## Images
622
+
623
+ Attach images to a message three ways, all sharing the same size and count
624
+ limits:
625
+
626
+ - Type `@path/to/image.png` in a prompt. Existing image files under the
627
+ workspace are attached and removed from the text (a lone `@image.png` sends
628
+ "Please analyze the attached image(s)."). Paths that are missing, outside the
629
+ workspace, or not images are left in the text untouched.
630
+ - Paste or drag an image into the terminal. Most terminals insert the file path
631
+ at the cursor; `@`-mention extraction then attaches it on send.
632
+ - Let the model call the `view_image` tool when it needs to look at a file.
633
+
634
+ Each image is validated (extension and magic bytes), base64-encoded, and sent
635
+ to the model as an image part on the next request. Both OpenAI-compatible and
636
+ native Anthropic providers are supported. Limits live under
637
+ `/config vision [show|max-bytes <n>|max-images <n>]` (defaults: 5 MB per image,
638
+ 4 images per turn); oversized or invalid images produce a clear message instead
639
+ of a failed request.
640
+
641
+ ### Image and video generation
642
+
643
+ Generate images and short videos with your provider's media API and keep them in
644
+ the workspace. Generation is **opt-in** and approval-gated because it costs
645
+ money:
646
+
647
+ ```text
648
+ /config media enable on
649
+ /config media provider openai
650
+ /image model list # pick an image model (or: /image model <id>)
651
+ /config media size 1024x1024
652
+ /image a red fox reading a book
653
+ ```
654
+
655
+ Media models are chosen **per provider**, and there is no default: ids and prices
656
+ change quickly, so you pick one yourself. `/image model` shows the current image
657
+ model for the media provider; `/image model list` lists that provider's image
658
+ models (a picker in an interactive session, a table otherwise), `/image model
659
+ refresh` re-fetches the list, `/image model search <term>` filters it, and
660
+ `/image model <id>` sets an id directly (a single word: anything else is treated
661
+ as a mistyped prompt). `/video model` takes the same arguments for video.
662
+ `/media provider` shows the providers with their models (a picker when
663
+ interactive); `/media provider <id>` switches the provider the media tools use
664
+ and, interactively, offers to choose any missing models. Each provider remembers
665
+ its own image and video model, so switching providers does not lose your choice.
666
+ Because `model` is a subcommand, a prompt that starts with the word
667
+ `model` needs `--` first (`/image -- model railway in the snow`).
668
+
669
+ `/image [--size WxH] [--model <id>] <prompt>` saves a PNG under
670
+ `.kiwimatecoder/media/` and queues it for the next request. Options come before
671
+ the prompt, which is taken verbatim (quotes included); use `--` if a prompt
672
+ starts with dashes. The same generation is available to the model as the
673
+ `generate_image` tool: it asks for approval first, with a preview showing the
674
+ provider, model, size, and prompt. Responses are accepted as
675
+ `data[0].b64_json` or `data[0].url` (URL downloads are capped at 20 MB and
676
+ honor offline mode and the local-address guard). OpenAI-compatible providers
677
+ are called at `/images/generations`; OpenRouter at `/images`.
678
+
679
+ Video uses the same switch and provider but its own model, which you choose
680
+ yourself (there is no default: ids and prices change quickly and a clip is billed
681
+ per second):
682
+
683
+ ```text
684
+ /media provider openrouter
685
+ /video model list # pick a video model (or: /video model <id>)
686
+ /config media duration 5 # seconds
687
+ /config media video-size 720p # or 1280x720; "default" clears it
688
+ /video a paper boat drifting down a rainy street
689
+ /video --duration 8 --size 1080p --image start.png the boat starts to sail
690
+ ```
691
+
692
+ `/video [--duration <s>] [--size <WxH|720p>] [--model <id>] [--image <path>]
693
+ <prompt>` submits an asynchronous job, shows live status while it renders
694
+ (usually a few minutes), and streams the finished file to
695
+ `.kiwimatecoder/media/` with a 500 MB cap. `--image` animates a workspace image
696
+ as the first frame (OpenRouter models). Press Ctrl+C to stop waiting: the job
697
+ keeps running (and billing) on the provider, and `/video resume <job-id>` fetches
698
+ it later without paying twice. Polling is bounded to 15 minutes and tolerates
699
+ brief network errors; the API key is only ever sent to the provider's own host,
700
+ never to a download CDN. The model can call the approval-gated `generate_video`
701
+ tool (its preview states the per-second billing); after a timeout it resumes with
702
+ `resume_job_id` rather than regenerating.
703
+
704
+ Two wire formats are spoken, chosen from the provider's host: OpenRouter
705
+ (`duration`, `resolution`/`size`, `frame_images`, `unsigned_urls`) and the OpenAI
706
+ Videos API (`seconds`, `size`, multipart form, `/videos/<id>/content`). The OpenAI
707
+ format is covered by mocked-transport tests only; please report anything a live
708
+ endpoint rejects.
709
+
710
+ `/media` shows whether image and video generation are ready (and what is missing:
711
+ disabled, offline, no API key, no model chosen) and lists the most recent files;
712
+ reference an image from the list with `@<path>` to attach it again. Provider auth,
713
+ API versioning (Azure-style `?api-version=`), proxy, and custom CA settings all
714
+ come from the normal config. Configure it from the shell with
715
+ `config media show|enable on|off|model <id|none> [--provider <id>]|provider <id>|size <WxH>|video-model
716
+ <id|none> [--provider <id>]|duration <seconds>|video-size <size>|output-dir <path>`
717
+ (inside the REPL, `/config media model <id|none> [provider]` and `/config media
718
+ video-model <id|none> [provider]` take the provider as an optional trailing word;
719
+ `none`, `clear`, `default` or `-` clears the model for that provider).
720
+
721
+ ## Notebooks, PDFs, and docx
722
+
723
+ `read_file` extracts structured documents to text automatically, so the model
724
+ can read them without extra tooling:
725
+
726
+ - **Jupyter notebooks** (`.ipynb`) render as `## Cell N (type)` sections with
727
+ cell sources plus text and stream outputs; image outputs are summarized as
728
+ `[image/png output, N bytes]`.
729
+ - **Word documents** (`.docx`) are unzipped and `word/document.xml` is stripped
730
+ to text with paragraph and line breaks preserved.
731
+ - **PDFs** (`.pdf`) use the `pdftotext` CLI (from Poppler) when installed for
732
+ reliable extraction. When it is missing, a conservative stdlib fallback
733
+ inflates FlateDecode streams and reads text from `BT`/`ET` blocks; if nothing
734
+ is parseable the result explains how to install `pdftotext` instead of
735
+ failing.
736
+
737
+ Document output is capped at ~200 KB with a truncation note, and `offset`/
738
+ `limit` are ignored for documents (they apply to plain text files only).
739
+ Malformed documents always return a clear message rather than raising.
740
+
741
+ ## Providers
742
+
743
+ KiwiMateCoder ships a built-in registry of providers. Switch live with `/provider`,
744
+ or set the persistent primary from the shell with `config provider use <id>`. An
745
+ API key can be saved interactively with `kiwimatecoder setup`, directly with
746
+ `config key set <provider> <key>`, or via the provider's environment variable.
747
+ You can also add OpenAI-compatible custom providers with `config provider add`.
748
+
749
+ | Provider id | Key env var | Notes |
750
+ |-------------|-------------|-------|
751
+ | `kiwimate` **(experimental)** | `KIWIMATE_API_KEY` | [kiwimate.net](https://kiwimate.net); keys start with `sk-km-`. Chat only — no tool use yet (see below). |
752
+ | `openai` | `OPENAI_API_KEY` | |
753
+ | `anthropic` | `ANTHROPIC_API_KEY` | Native Messages API. |
754
+ | `google` | `GEMINI_API_KEY` | |
755
+ | `xai` | `XAI_API_KEY` | |
756
+ | `mistral` | `MISTRAL_API_KEY` | |
757
+ | `deepseek` | `DEEPSEEK_API_KEY` | |
758
+ | `qwen` | `DASHSCOPE_API_KEY` | |
759
+ | `moonshot` | `MOONSHOT_API_KEY` | |
760
+ | `openrouter` | `OPENROUTER_API_KEY` | The provider used until you pick another. |
761
+ | `azure` | `AZURE_OPENAI_API_KEY` | Placeholder endpoint; the model is your deployment name. |
762
+ | `bedrock` | `AWS_BEARER_TOKEN_BEDROCK` | Placeholder endpoint. |
763
+ | `groq` | `GROQ_API_KEY` | |
764
+ | `together` | `TOGETHER_API_KEY` | |
765
+ | `fireworks` | `FIREWORKS_API_KEY` | |
766
+ | `cerebras` | `CEREBRAS_API_KEY` | |
767
+ | `deepinfra` | `DEEPINFRA_API_KEY` | |
768
+ | `ollama` | `OLLAMA_API_KEY` (optional) | Local. |
769
+ | `lmstudio` | `LMSTUDIO_API_KEY` (optional) | Local. |
770
+ | `unsloth` | `UNSLOTH_API_KEY` (required) | Local. |
771
+
772
+ ### Choosing a model
773
+
774
+ There are no default models. You choose the model to use with each provider
775
+ when you add it, and the choice is remembered per provider:
776
+
777
+ - `kiwimatecoder setup` asks you to pick one from the provider's list after it
778
+ saves the key (or pass `--model <id>` to skip the picker).
779
+ - `/provider` asks for a model for each provider you add to the roster.
780
+ - Custom providers take the model as the fourth argument of
781
+ `config provider add <id> <name> <base_url> <model>`; change it with
782
+ `config provider edit <id> --model <id>` or `/config provider edit <id> model=<id>`.
783
+ - `config model set <id> [--provider <id>]` or `/config model set <model>
784
+ [provider]` changes the model for the active (or named) provider, and
785
+ `config model reset [--provider <id>]` / `/config model reset [provider]`
786
+ forgets it. `config provider list` shows each provider's chosen model.
787
+
788
+ The interactive REPL asks for a model at launch when the primary has none. A
789
+ fallback provider without a chosen model is skipped (with a note) during
790
+ failover. Headless runs never prompt: `kiwimatecoder -p`, `ask`, and `jobs run`
791
+ exit `1` with `No model chosen for <provider>…` when neither `--model` nor a
792
+ chosen model is available (`eval run` reports the same message as invalid
793
+ input, exit `2`). Local servers are the one exception — with nothing chosen,
794
+ the session uses the first model the running server lists.
795
+
796
+ Groq, Together, Fireworks, Cerebras, and DeepInfra work out of the box once
797
+ their API key is set — they speak the standard OpenAI-compatible protocol.
798
+
799
+ ### KiwiMate (experimental)
800
+
801
+ `kiwimate` is KiwiMate's own OpenAI-compatible API from
802
+ [kiwimate.net](https://kiwimate.net). It is listed first in every provider
803
+ picker, in its own **Experimental** box, and marked `(experimental)` in
804
+ `config provider list`. Create a key at `kiwimate.net/developers/console` (it
805
+ starts with `sk-km-`), then run `kiwimatecoder setup --provider kiwimate` (or
806
+ set `KIWIMATE_API_KEY`, then `config provider use kiwimate` and `config model
807
+ set <id>`). Setup offers the endpoint's models, falling back to the suggested
808
+ `kiwimate-mini-1-0`, `kiwimate-small-1-0`, `kiwimate-medium-1-0`, and
809
+ `kiwimate-large-1-0`, and reminds you that the provider is experimental.
810
+
811
+ The endpoint is limited for now:
812
+
813
+ - **Chat only, no tool use yet.** KiwiMateCoder sends it no tool schemas, so
814
+ with KiwiMate as the provider the agent cannot read or edit files or run
815
+ commands. Tool calls and results already in the conversation are flattened
816
+ into plain text when you switch to it mid-session.
817
+ - **Replies are capped at about 1,024 tokens.** The REPL prints `The reply was
818
+ cut off at the provider's output limit.` when that happens.
819
+ - **System prompts are ignored by the endpoint**, so project instructions
820
+ (`AGENTS.md`), memory, output styles, and custom prompts do not reach the
821
+ model. Only the last 20 non-system messages of the conversation are
822
+ forwarded to it.
823
+
824
+ `azure` and `bedrock` ship **placeholder** endpoints because the endpoint is
825
+ account-specific (`https://<resource>.openai.azure.com/openai/v1` and
826
+ `https://bedrock-runtime.<region>.amazonaws.com/openai/v1`). Point them at your
827
+ own resource by adding a custom provider (built-in entries cannot be edited):
828
+
829
+ ```bash
830
+ kiwimatecoder config provider add my-azure "My Azure" \
831
+ https://my-resource.openai.azure.com/openai/v1 my-deployment \
832
+ --key-env AZURE_OPENAI_API_KEY --key-header api-key --key-prefix "" \
833
+ --api-version 2024-10-21
834
+ kiwimatecoder config key set my-azure <key>
835
+
836
+ kiwimatecoder config provider add bedrock-eu "Bedrock (eu-central-1)" \
837
+ https://bedrock-runtime.eu-central-1.amazonaws.com/openai/v1 \
838
+ openai.gpt-5.6-sol --key-env AWS_BEARER_TOKEN_BEDROCK
839
+ ```
840
+
841
+ Azure OpenAI authenticates with an `api-key` header (no `Bearer` prefix) and
842
+ versions its API with `?api-version=`; both are configurable per custom provider
843
+ (`--key-header`, `--key-prefix`, `--api-version`, or the slash equivalents).
844
+ AWS Bedrock's OpenAI-compatible endpoint accepts a bearer token only: SigV4/IAM
845
+ signing, Azure managed identity, Google Vertex AI (project-specific endpoint,
846
+ OAuth2-only auth), and interactive OAuth/device-code flows are not implemented
847
+ (deferred; see ROADMAP).
848
+
849
+ Each built-in provider still ships a short list of suggested model ids, used
850
+ only to fill the pickers when its live listing is unavailable — none of them is
851
+ used unless you choose it. The live catalog below is what `/model` actually
852
+ offers once the provider can be queried (see **Needs a key** below).
853
+
854
+ The `anthropic` provider talks to Anthropic's native Messages API, including
855
+ streaming tool calls and native model listing. Custom providers can opt into the
856
+ same path with `config provider edit <id> --compat anthropic` (or
857
+ `/config provider edit <id> compat=anthropic`); everything else speaks the
858
+ OpenAI-compatible chat+tools protocol.
859
+
860
+ ### Local providers (Ollama, LM Studio & Unsloth)
861
+
862
+ The `ollama`, `lmstudio`, and `unsloth` providers talk to model servers on your
863
+ own machine. Make sure the server is running ([Ollama](https://ollama.com) on
864
+ `http://localhost:11434`, [LM Studio](https://lmstudio.ai)'s local server on
865
+ `http://localhost:1234`, or [Unsloth](https://unsloth.ai)'s Studio API on
866
+ `http://localhost:8888`), then:
867
+
868
+ ```text
869
+ /provider ollama
870
+ ```
871
+
872
+ That's it for Ollama and LM Studio — no API key needed. You can choose a model
873
+ like any other provider (`kiwimatecoder setup` offers the server's models when
874
+ it is running, and `/model` lists them); until you do, the session uses the
875
+ first model the server lists. `kiwimatecoder setup` detects which local servers
876
+ are running and marks them in the picker. Tool calling depends on the model you
877
+ pick, so choose a tool-capable family (Llama 3.1+, Qwen 3, DeepSeek, ...).
878
+
879
+ `unsloth` works the same way but **requires a key**: Unsloth enforces auth even
880
+ on localhost. Create one in Unsloth under Settings → API (it starts with
881
+ `sk-unsloth-`), run `kiwimatecoder setup --provider unsloth` to save it, and
882
+ load a GGUF model in Unsloth before chatting. Tip: start Unsloth's server with
883
+ `--disable-tools` when an external agent drives it — otherwise Unsloth's own
884
+ server-side tools swallow the agent's tool calls.
885
+
886
+ A key only matters if your server enforces auth (e.g. LM Studio's server token,
887
+ or Ollama behind an authenticating proxy) — set `OLLAMA_API_KEY` /
888
+ `LMSTUDIO_API_KEY` or `config key set ollama <key>` in that case. Running on a
889
+ different port or another machine? Add it as a custom provider instead, with
890
+ the model to use as the fourth argument:
891
+ `/config provider add mybox "My Box" http://mybox.local:11434/v1 llama3.1:8b` —
892
+ any `localhost`/`*.local` provider is treated as keyless automatically.
893
+
894
+ ## Model catalogs
895
+
896
+ Model ids drift constantly, so the list `/model` offers is fetched from the
897
+ provider itself rather than being frozen into the release.
898
+
899
+ - **Newest first.** Opening `/model` (or running `/model refresh`) calls the
900
+ provider's `/models` endpoint and offers what it serves today, ordered by
901
+ release date, with your current model pinned first. Search
902
+ (`/model search <term>`) bypasses this newest-first cap and scans the whole
903
+ catalog by name.
904
+ - **Deprecated ids disappear.** Anything the provider no longer lists is dropped
905
+ from the catalog, and `/model refresh` prints what was removed. If your current
906
+ model is one of them, it says so.
907
+ - **Only usable models.** Embedding, image, audio, moderation, and non
908
+ tool-calling models are filtered out — the agent loop needs text chat plus tool
909
+ calls (chat-only providers such as KiwiMate keep models without tool support).
910
+ The newest 60 are offered; any other id still works if you type it.
911
+ - **Cached for a day.** Results are stored in `~/.kiwimatecoder/model_cache.json`
912
+ and reused for 24 hours, so the selector stays instant and tab completion never
913
+ touches the network. A failed fetch falls back to the cached list, then to the
914
+ built-in suggestions, and is not retried automatically for 30 minutes.
915
+ - **Needs a key.** A cloud provider is only queried once it has an API key
916
+ configured; keyless local servers (`ollama`, `lmstudio`, and any custom
917
+ provider on `localhost` or a `*.local` host) are queried without one —
918
+ `unsloth`, which enforces auth locally, is queried once its key is set.
919
+
920
+ From the shell, `kiwimatecoder config models show [--provider <id>]` and
921
+ `kiwimatecoder config models refresh [--provider <id>]` show or refresh the same
922
+ catalog.
923
+
924
+ The suggested model tuples in `kiwimatecoder/providers.py` are only the offline
925
+ fallback for the pickers (never a default), and custom providers can list
926
+ theirs via a `"models"` array in `~/.kiwimatecoder/config.json`. `/config models
927
+ allow|deny` reshapes what is offered on top of whichever catalog is in use, and
928
+ `/model <name>` or `config model set <name>` accepts any id, listed or not.
929
+
930
+ ## One-shot mode
931
+
932
+ For a quick question without entering the REPL:
933
+
934
+ ```bash
935
+ kiwimatecoder ask "how do I reverse a list in python?"
936
+ kiwimatecoder ask "review this file" --file app.py --provider openai --model gpt-5.6-sol
937
+ ```
938
+
939
+ `ask` uses the model chosen for the provider unless `--model` is passed, and
940
+ exits `1` with `No model chosen for <provider>…` when there is neither.
941
+
942
+ ## Headless mode
943
+
944
+ Run one agentic turn without entering the REPL — useful for scripts and CI:
945
+
946
+ ```bash
947
+ kiwimatecoder -p "Summarize the changes in the working tree."
948
+ echo "Explain src/app.py" | kiwimatecoder -p -
949
+ kiwimatecoder -p "Summarize the changes." --provider openai --model gpt-5.6-sol
950
+ ```
951
+
952
+ The prompt is the value of `-p/--print`; `-p -` reads it from stdin. The run
953
+ uses the model chosen for the provider (`kiwimatecoder setup` or `config model
954
+ set`); pass `--model` to override it, or when none is chosen — headless runs
955
+ never prompt for one. Flags:
956
+
957
+ | Flag | Meaning |
958
+ | --- | --- |
959
+ | `--output-format text\|json\|stream-json` | `text` streams assistant text to stdout (default); `json` prints one JSON object at the end; `stream-json` prints one compact JSON object per event, ending with a `result` line. |
960
+ | `--mode ask\|auto-accept\|plan` | Permission mode for this run (default: the configured mode). |
961
+ | `--yes` | Treat approvals as granted (auto-accept) — never prompts. |
962
+ | `--max-turns N` | Hard cap on tool-loop iterations (default 30). |
963
+ | `--provider`, `--model` | Provider/model overrides for this run. `--provider` makes that provider the primary, ahead of the configured roster; `--model` is required when no model is chosen for it. |
964
+ | `--workspace PATH` | Workspace root (default: current directory). |
965
+ | `--quiet` | Suppress tool/progress lines on stderr in text mode. |
966
+
967
+ Tool and progress lines go to **stderr**; only assistant text (text mode) or
968
+ JSON (json/stream-json modes) goes to **stdout**. Headless runs never prompt:
969
+ actions that would need approval are denied with a note on stderr unless
970
+ `--yes` or `--mode auto-accept` is used.
971
+
972
+ Exit codes: `0` success, `1` runtime failure (missing key or model — `No model
973
+ chosen for <provider>…` on stderr — provider error, turn cap without a final
974
+ answer), `2` invalid usage (bad format, mode, provider, or workspace).
975
+
976
+ CI example (a fresh runner has no saved config, so pass `--model`):
977
+
978
+ ```yaml
979
+ - name: Review the diff
980
+ run: |
981
+ kiwimatecoder -p "Review the staged diff and list risks." \
982
+ --model anthropic/claude-sonnet-5 \
983
+ --output-format json --max-turns 10 > review.json
984
+ cat review.json
985
+ ```
986
+
987
+ More recipes (ready-made GitHub Actions workflows, exit-code gating, and
988
+ pre-commit setup) live in [docs/ci.md](docs/ci.md).
989
+
990
+ ## Shell completions and man page
991
+
992
+ Typer ships shell completion for bash, zsh, fish, and PowerShell:
993
+
994
+ ```bash
995
+ kiwimatecoder --install-completion # detect and install for your shell
996
+ kiwimatecoder --show-completion bash # print the script to stdout instead
997
+ ```
998
+
999
+ A troff man page is committed at `docs/kiwimatecoder.1`; view it with `man
1000
+ ./docs/kiwimatecoder.1` (on Linux, `man -l docs/kiwimatecoder.1`). Regenerate it
1001
+ from the Typer command tree after changing the CLI:
1002
+
1003
+ ```bash
1004
+ python scripts/generate_man.py # rewrite the man page
1005
+ python scripts/generate_man.py --check # fail when the committed file is stale
1006
+ ```
1007
+
1008
+ Interactive sessions need a real terminal. When stdin is not a TTY (a pipe, a
1009
+ CI job, cron), the bare command — and `--resume`/`--continue` — exits with code
1010
+ `2` and a note pointing at headless mode instead of starting prompt_toolkit.
1011
+ Use `kiwimatecoder -p "..."` or `echo "..." | kiwimatecoder -p -`.
1012
+
1013
+ ## Python SDK
1014
+
1015
+ Embed the agent in a Python program with `kiwimatecoder.sdk`:
1016
+
1017
+ ```python
1018
+ from kiwimatecoder.sdk import run_agent_sync
1019
+
1020
+ result = run_agent_sync(
1021
+ "Summarize README.md in three bullets.",
1022
+ workspace=".",
1023
+ mode="plan",
1024
+ model="anthropic/claude-sonnet-5", # omit to use the provider's chosen model
1025
+ )
1026
+
1027
+ if result.success:
1028
+ print(result.text)
1029
+ print(result.usage, result.cost_usd) # tokens and estimated USD (or None)
1030
+ ```
1031
+
1032
+ Without `model=`, the run uses the model chosen for the provider. When there
1033
+ is none, `run_agent`/`run_agent_sync` raise
1034
+ `kiwimatecoder.config.ModelNotChosenError` (a `ValueError`) before contacting
1035
+ the provider.
1036
+
1037
+ `RunResult` carries `text`, `usage` (`prompt_tokens`/`completion_tokens`),
1038
+ `cost_usd`, `provider`, `model`, `mode`, `tools_used`, `messages`, `success`,
1039
+ and `error`. Pass `on_event` to observe the same events as stream-JSON
1040
+ (`text_delta`, `tool_start`, `tool_end`, `usage`, `done`), `confirm` to
1041
+ approve actions, and `console` to receive the agent's tool/progress output.
1042
+ Approvals are denied by default. From async code use `await run_agent(...)`;
1043
+ `run_agent_sync` raises a clear error if called inside a running loop.
1044
+
1045
+ ## Editor integration (ACP)
1046
+
1047
+ KiwiMateCoder can run as an [Agent Client Protocol](https://agentclientprotocol.com)
1048
+ (ACP) agent over stdio, so an ACP-capable editor can drive it:
1049
+
1050
+ ```bash
1051
+ kiwimatecoder acp [--workspace PATH]
1052
+ ```
1053
+
1054
+ A Zed-style agent configuration (`settings.json`) looks like:
1055
+
1056
+ ```json
1057
+ {
1058
+ "agent": {
1059
+ "command": "kiwimatecoder",
1060
+ "args": ["acp"]
1061
+ }
1062
+ }
1063
+ ```
1064
+
1065
+ The server speaks JSON-RPC 2.0 over newline-delimited JSON on stdin/stdout;
1066
+ the only thing ever written to stdout is protocol traffic. Implemented subset:
1067
+
1068
+ - `initialize` handshake with agent capabilities and version info.
1069
+ - `session/new` creates one conversation rooted at the client's `cwd`,
1070
+ using the **configured** permission mode (never an assumed auto-accept).
1071
+ - `session/prompt` runs one agent turn, streaming assistant text chunks and
1072
+ tool-call progress as `session/update` notifications; the response carries
1073
+ `end_turn`, `cancelled`, `refusal`, or `max_tokens`.
1074
+ - `session/cancel` cancels the running turn; partial assistant text is kept.
1075
+ - `session/request_permission` bridges every write/command approval to the
1076
+ editor when the session runs in `ask` mode. Approving with "always"
1077
+ persists the tool allowlist; a cancelled or unanswered request (default
1078
+ timeout 300s, `config acp timeout <s>`) is denied exactly like a normal
1079
+ denial.
1080
+
1081
+ This is a focused subset: terminal and MCP client capabilities advertised by
1082
+ the editor are not wired through (MCP servers still come from KiwiMateCoder
1083
+ config), `loadSession` is not supported, image prompt parts are ignored with a
1084
+ note to the model, and the file tools operate on the local filesystem. When
1085
+ the client advertises `fs.readTextFile`/`fs.writeTextFile`, the server exposes
1086
+ `read_text_file`/`write_text_file` helpers that delegate to
1087
+ `fs/read_text_file`/`fs/write_text_file`; otherwise those helpers use the
1088
+ local filesystem.
1089
+
1090
+ ## Background jobs
1091
+
1092
+ Run an agent task detached from your terminal, then check on it later:
1093
+
1094
+ ```bash
1095
+ kiwimatecoder jobs run "Add type hints to kiwimatecoder/jobs.py and run mypy."
1096
+ kiwimatecoder jobs run "Fix the failing test." --provider openai --model gpt-5.6-sol
1097
+ kiwimatecoder jobs list
1098
+ kiwimatecoder jobs show <id>
1099
+ kiwimatecoder jobs output <id>
1100
+ kiwimatecoder jobs cancel <id>
1101
+ kiwimatecoder jobs clear # finished jobs only; --all includes running
1102
+ ```
1103
+
1104
+ Each job is one headless run (`python -m kiwimatecoder -p ... --output-format
1105
+ json`) recorded as JSON under `~/.kiwimatecoder/jobs/<id>.json` with its combined
1106
+ output at `~/.kiwimatecoder/jobs/<id>.log`. Records survive restarts; `jobs list`
1107
+ refreshes running jobs from their process and parsed result, and corruption in
1108
+ one record never hides the others. A job uses the model chosen for its provider
1109
+ unless `--model` is passed; `jobs run` and `jobs schedule` check this before
1110
+ starting anything and exit `1` with `No model chosen for <provider>…` when
1111
+ there is neither.
1112
+
1113
+ > **Warning:** `jobs run` defaults to `--mode auto-accept`, so an unattended job
1114
+ > can edit files and run commands without asking. Pass `--mode ask` (approvals
1115
+ > are then denied, since nothing can prompt) or `--mode plan` (read-only) to
1116
+ > constrain a job, and only point jobs at workspaces you trust.
1117
+
1118
+ Inside a session, `/jobs [list|show <id>|cancel <id>|tick]` does the same, and
1119
+ `/jobs run <prompt>` starts a job in the session's workspace (still
1120
+ `auto-accept`). Jobs are marked `running`, `succeeded`, `failed`, or
1121
+ `cancelled`; `cancelled` covers an explicit `jobs cancel`.
1122
+
1123
+ ### Scheduling
1124
+
1125
+ Scheduling is pull-based — there is no daemon and no platform cron integration.
1126
+ `jobs schedule "<prompt>" --every <seconds>` starts a run immediately and stores
1127
+ the interval plus a `next_run_at` timestamp; every later invocation of
1128
+ `kiwimatecoder jobs tick` (or `/jobs tick`) starts any run that is due. A job
1129
+ that is still running is skipped, so runs never overlap. A due job that cannot
1130
+ start (its workspace is gone, its provider was removed, or no model is chosen)
1131
+ is left in place and reported as `Skipped <id>: <reason>`; `jobs tick` then
1132
+ exits `1`. Wire `jobs tick` to your own scheduler, for example:
1133
+
1134
+ ```cron
1135
+ */5 * * * * kiwimatecoder jobs tick
1136
+ ```
1137
+
1138
+ ## Update
1139
+
1140
+ Update the CLI from the same Python environment:
1141
+
1142
+ ```bash
1143
+ kiwimatecoder update
1144
+ ```
1145
+
1146
+ or with a flag:
1147
+
1148
+ ```bash
1149
+ kiwimatecoder --update
1150
+ ```
1151
+
1152
+ (The older `-update` form still works but is deprecated.) Check the installed
1153
+ version before/after with:
1154
+
1155
+ ```bash
1156
+ kiwimatecoder --version
1157
+ ```
1158
+
1159
+ When KiwiMateCoder is running from a Git checkout, the updater first fetches
1160
+ `origin` and compares the local `HEAD` to `origin/<branch>`:
1161
+
1162
+ - **Already up to date** — prints `Already on the latest version (commit <sha>).`
1163
+ and exits without pulling or reinstalling.
1164
+ - **Behind** — prints `Updating from <old-sha> (N commit(s) behind origin/<branch>)…`,
1165
+ runs `git pull --ff-only`, reinstalls the checkout with
1166
+ `pip install --upgrade -e <path>`, and reports `Updated <old-sha> → <new-sha>.`
1167
+
1168
+ KiwiMateCoder is not published to PyPI, so for packaged (non-Git) installs the
1169
+ fallback runs
1170
+ `pip install --upgrade --force-reinstall git+https://github.com/Kyle8933/kiwimatecoder.git`.
1171
+
1172
+ ### Updating and pinning versions
1173
+
1174
+ Pin a branch, tag, or commit with `--ref`:
1175
+
1176
+ ```bash
1177
+ kiwimatecoder update --ref v0.1.0 # tag
1178
+ kiwimatecoder update --ref main # branch
1179
+ kiwimatecoder update --ref 1a2b3c4 # commit
1180
+ ```
1181
+
1182
+ In a Git checkout the updater fetches `origin` and then puts the checkout on
1183
+ the ref: the current branch is fast-forwarded with `git pull --ff-only` (local
1184
+ commits are never merged unexpectedly), while every other ref is a plain
1185
+ `git checkout` followed by `pip install --upgrade -e <path>`. The command
1186
+ prints the old and new commit SHAs. For packaged installs it reinstalls
1187
+ `git+https://github.com/Kyle8933/kiwimatecoder.git@<ref>`.
1188
+
1189
+ To roll back, pin an older tag or commit the same way; `kiwimatecoder --version`
1190
+ shows the installed version. Generate a software bill of materials for the
1191
+ installed environment with:
1192
+
1193
+ ```bash
1194
+ python scripts/generate_sbom.py --output sbom.json
1195
+ ```
1196
+
1197
+ It is stdlib-only, emits CycloneDX-shaped JSON with the package and direct
1198
+ dependency versions, and is uploaded as a CI artifact by the `sbom` job.
1199
+
1200
+
1201
+ ## Project instructions
1202
+
1203
+ Drop an `AGENTS.md` (or `CLAUDE.md`, `.kiwimatecoder/AGENTS.md`,
1204
+ `.kiwimatecoder/instructions.md`) at the workspace root and its contents are
1205
+ loaded into the system prompt on every turn — build commands, style rules,
1206
+ testing conventions. Files are capped at 32KB each and 48KB total.
1207
+
1208
+ ## Memory
1209
+
1210
+ The agent can remember durable facts about you and your projects across
1211
+ sessions. Memory is plain Markdown, one `- fact` bullet per line, in two
1212
+ scopes:
1213
+
1214
+ - **Project** — `<workspace>/.kiwimatecoder/memory.md`; travels with the
1215
+ repository and applies only there.
1216
+ - **User** — `~/.kiwimatecoder/memory.md`; shared across every workspace.
1217
+
1218
+ The model writes with the approval-gated `remember` tool (`scope=project` or
1219
+ `scope=user`) and reads with the read-only `recall` tool. Active facts are
1220
+ loaded into the system prompt on every turn, capped at 16KB by default so a
1221
+ pathological file cannot crowd out the conversation.
1222
+
1223
+ Manage memory directly with `/memory`:
1224
+
1225
+ ```text
1226
+ /memory # show both files and their facts
1227
+ /memory add The build uses uv, not pip
1228
+ /memory add-user I prefer concise answers
1229
+ /memory clear project
1230
+ /memory clear user
1231
+ ```
1232
+
1233
+ Settings live under `kiwimatecoder config memory show|max-bytes <n>|enable on|off`.
1234
+ Never store secrets or API keys in memory — the prompt section says so
1235
+ explicitly, and the `remember` preview runs the same secret redaction as audit
1236
+ output.
1237
+
1238
+ ## Custom commands and prompt templates
1239
+
1240
+ Drop a Markdown file in `<workspace>/.kiwimatecoder/commands/` (or
1241
+ `~/.kiwimatecoder/commands/`) and its filename becomes a slash command. The
1242
+ body is the prompt sent as a normal user turn; `$ARGUMENTS` is replaced with
1243
+ whatever you type after the command, and the arguments are appended when the
1244
+ token is absent. Workspace templates win over user templates with the same
1245
+ name, and built-in commands always win over templates. `/templates` lists what
1246
+ was discovered; `/help` adds a Custom commands group.
1247
+
1248
+ ```text
1249
+ # .kiwimatecoder/commands/review.md
1250
+ # Review the current diff
1251
+ Review $ARGUMENTS for bugs, security issues, and missing tests.
1252
+
1253
+ /review src/app.py
1254
+ ```
1255
+
1256
+ ## Agent Skills
1257
+
1258
+ Skills are Markdown instruction bundles the model loads only when a task
1259
+ matches, so they cost no tokens on turns that do not use them. Each skill is a
1260
+ directory containing `SKILL.md`:
1261
+
1262
+ ```text
1263
+ <workspace>/.kiwimatecoder/skills/pdf/SKILL.md # project skill
1264
+ ~/.kiwimatecoder/skills/pdf/SKILL.md # personal skill
1265
+ ```
1266
+
1267
+ The system prompt lists each skill's name and first line only; the model calls
1268
+ the read-only `load_skill` tool to pull the full body (capped at 32KB).
1269
+ Workspace skills shadow user skills with the same name.
1270
+
1271
+ ## Plugins
1272
+
1273
+ Plugins are Python files with a `register(api)` entry point that can add tools,
1274
+ slash commands, and event subscribers without forking the CLI:
1275
+
1276
+ ```python
1277
+ from kiwimatecoder.tools.base import FunctionTool, ToolResult
1278
+
1279
+ def register(api):
1280
+ api.register_tool(FunctionTool(
1281
+ name="word_count",
1282
+ description="Count words in a file.",
1283
+ parameters={
1284
+ "type": "object",
1285
+ "properties": {"path": {"type": "string"}},
1286
+ "required": ["path"],
1287
+ },
1288
+ func=lambda args, session: ToolResult(content="..."),
1289
+ ))
1290
+ api.register_command("hello", lambda arg, session, console: "continue")
1291
+ api.subscribe("post_tool", lambda event: None)
1292
+ ```
1293
+
1294
+ User plugins load from `~/.kiwimatecoder/plugins/*.py`. Project plugins in
1295
+ `<workspace>/.kiwimatecoder/plugins/*.py` are **disabled by default** — cloning
1296
+ a repository must never execute code just because the CLI started in it. Opt in
1297
+ with `"plugins": {"allow_project": true}` in `~/.kiwimatecoder/config.json`, and
1298
+ skip individual plugins with `"plugins": {"disabled": ["name"]}`. A plugin that
1299
+ fails to import or register is reported as a dim warning and skipped; it never
1300
+ prevents startup.
1301
+
1302
+ ## MCP servers
1303
+
1304
+ MCP (Model Context Protocol) servers extend the agent with tools it discovers
1305
+ at session start. Configure them under `mcp_servers` in
1306
+ `~/.kiwimatecoder/config.json` — each entry is either a stdio subprocess or an
1307
+ HTTP endpoint:
1308
+
1309
+ ```json
1310
+ {
1311
+ "mcp_servers": {
1312
+ "files": {
1313
+ "command": "npx",
1314
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
1315
+ "env": {"SOME_TOKEN": "..."},
1316
+ "disabled": false
1317
+ },
1318
+ "remote": {
1319
+ "url": "https://mcp.example.com/mcp",
1320
+ "headers": {"Authorization": "Bearer sk-..."},
1321
+ "disabled": false
1322
+ }
1323
+ }
1324
+ }
1325
+ ```
1326
+
1327
+ From the shell, `kiwimatecoder config mcp add <name>` writes the same entries
1328
+ (set exactly one of `--command` or `--url`):
1329
+
1330
+ ```bash
1331
+ kiwimatecoder config mcp add files --command npx --args "-y @modelcontextprotocol/server-filesystem /tmp"
1332
+ kiwimatecoder config mcp add remote --url https://mcp.example.com/mcp -H "Authorization: Bearer sk-..."
1333
+ kiwimatecoder config mcp list
1334
+ kiwimatecoder config mcp remove remote
1335
+ ```
1336
+
1337
+ In the REPL, `/mcp list` shows every configured server, its status (connected,
1338
+ disabled, or the failure reason), its resources count, and the registered tools.
1339
+ `/mcp reload` reconnects each enabled server and re-registers its tools without
1340
+ restarting the session.
1341
+
1342
+ Each server tool is registered as `mcp__<server>__<tool>` (both parts sanitized
1343
+ to `[A-Za-z0-9_]`), with the server's JSON Schema used for arguments. Tools that
1344
+ declare `annotations.readOnlyHint` run without approval; every other MCP tool
1345
+ prompts for approval in `ask` mode, exactly like `write_file` or `run_bash`.
1346
+ A server that fails to start or initialize is reported as a dim warning and
1347
+ skipped — it never blocks startup. Connections close when the session exits.
1348
+
1349
+ Authentication is whatever headers (HTTP) or environment variables (stdio) you
1350
+ configure. Interactive OAuth is not implemented yet; see ROADMAP.md.
1351
+
1352
+ ## Language server diagnostics
1353
+
1354
+ When enabled, KiwiMateCoder can talk to language servers for compiler-grade
1355
+ diagnostics and navigation. It is **opt-in** and off by default; no server
1356
+ process starts until the feature is enabled and a matching file is queried.
1357
+
1358
+ - `lsp_diagnostics` — errors and warnings for one file, or for the five most
1359
+ recently touched files when no path is given.
1360
+ - `lsp_definition` / `lsp_references` — where a symbol is defined, and every
1361
+ place it is used. Positions are 1-based line and column numbers.
1362
+
1363
+ Built-in presets start automatically when their command is on `PATH`:
1364
+
1365
+ | Language | Command | Extensions |
1366
+ |----------|---------|------------|
1367
+ | python | `pyright-langserver --stdio` | `.py`, `.pyi` |
1368
+ | typescript | `typescript-language-server --stdio` | `.ts`, `.tsx`, `.js`, `.jsx` |
1369
+ | go | `gopls` | `.go` |
1370
+ | rust | `rust-analyzer` | `.rs` |
1371
+ | c/cpp | `clangd` | `.c`, `.h`, `.cpp`, `.hpp` |
1372
+
1373
+ After a successful `write_file`/`edit_file`, diagnostics for the edited file
1374
+ are appended to the tool result as `LSP:` lines (capped at ten) when
1375
+ `diagnostics_after_edits` is on. A timeout or missing server appends nothing,
1376
+ so LSP can never fail a turn or delay it beyond the configured timeout.
1377
+
1378
+ Enable it in-session with `/lsp on`, or from the shell:
1379
+
1380
+ ```bash
1381
+ kiwimatecoder config lsp enable on # on | off
1382
+ kiwimatecoder config lsp after-edits on # on | off
1383
+ kiwimatecoder config lsp show
1384
+ ```
1385
+
1386
+ Use `/lsp status` to see whether LSP is on, which server commands are
1387
+ installed, and which clients are running; `/lsp restart` stops running servers
1388
+ so they start fresh on next use. Settings live under `lsp` in
1389
+ `~/.kiwimatecoder/config.json`; add your own server or override a preset:
1390
+
1391
+ ```json
1392
+ {
1393
+ "lsp": {
1394
+ "enabled": true,
1395
+ "timeout": 10.0,
1396
+ "diagnostics_after_edits": true,
1397
+ "servers": {
1398
+ "python": {
1399
+ "command": "basedpyright-langserver",
1400
+ "args": ["--stdio"],
1401
+ "extensions": [".py", ".pyi"]
1402
+ }
1403
+ }
1404
+ }
1405
+ }
1406
+ ```
1407
+
1408
+ ## Codebase index and semantic search
1409
+
1410
+ `search` gains a third mode: `mode='semantic'` ranks files against a
1411
+ natural-language query using a local, persistent index instead of a regex, and
1412
+ returns paths, line numbers, and source snippets. The agent chooses it for
1413
+ questions like "where is authentication handled?", and grep/glob keep working
1414
+ exactly as before.
1415
+
1416
+ The index is built automatically the first time semantic search runs, then
1417
+ refreshed incrementally: only files whose size or modification time changed
1418
+ are re-tokenized, deleted files are dropped, and `.gitignore` plus the default
1419
+ skip directories (`node_modules`, `venv`, `__pycache__`, …) are respected.
1420
+ Binary files, files larger than the byte cap, and anything beyond the file cap
1421
+ are skipped. It is a cache: the store lives at
1422
+ `~/.kiwimatecoder/index/<hash-of-workspace>.json` and `clear` simply deletes it.
1423
+
1424
+ ```text
1425
+ /index # status: files, terms, store size, stale count, embeddings
1426
+ /index build # refresh incrementally; prints added/updated/removed
1427
+ /index clear # delete the store for this workspace
1428
+ ```
1429
+
1430
+ Ranking uses BM25 over file term frequencies, so there are no API calls and
1431
+ semantic search works out of the box. Settings live under the `index` key:
1432
+
1433
+ ```json
1434
+ {
1435
+ "index": {
1436
+ "enabled": true,
1437
+ "max_files": 5000,
1438
+ "max_file_bytes": 262144,
1439
+ "embeddings": { "provider": "", "model": "", "batch_size": 32 }
1440
+ }
1441
+ }
1442
+ ```
1443
+
1444
+ Embeddings are optional and **OpenAI-compatible only**: set a provider id and
1445
+ an embedding model (the provider must serve `POST /embeddings` and its API key
1446
+ is read from the same config/env as chat) to additionally store chunk vectors.
1447
+ When vectors exist, search blends the lexical and vector scores; if the
1448
+ embedding provider is unavailable or errors for any reason, search silently
1449
+ falls back to lexical ranking. Embeddings are never required to use the
1450
+ feature.
1451
+
1452
+ ```bash
1453
+ kiwimatecoder config index show
1454
+ kiwimatecoder config index embed-provider openai
1455
+ kiwimatecoder config index embed-model text-embedding-3-small
1456
+ kiwimatecoder config index embed-provider none # turn embeddings off
1457
+ kiwimatecoder config index clear
1458
+ ```
1459
+
1460
+ ## Subagents
1461
+
1462
+ The `task` tool delegates a focused, self-contained investigation to a
1463
+ subagent that runs in its own context with the same workspace, provider, and
1464
+ tools. The subagent's intermediate tool output stays out of the parent
1465
+ conversation; it returns a final report (plus a step/token count) as the tool
1466
+ result. Use it for broad searches or self-contained questions that would
1467
+ otherwise flood the main context.
1468
+
1469
+ - Spawning a subagent is approval-gated like a command because the subagent can
1470
+ write files and run commands. Its own actions still go through the normal
1471
+ permission gate (including plan mode and command rules), and its edits are
1472
+ checkpointed so `/undo` covers them.
1473
+ - Subagents cannot spawn nested subagents and cannot use `ask_user`; put every
1474
+ decision they need in the prompt.
1475
+ - A subagent shares the parent's remaining token budget and stops at the
1476
+ configured step limit, returning a partial report with a note when either cap
1477
+ is hit. While subagents are disabled, `task` is not advertised at all.
1478
+
1479
+ ```json
1480
+ {
1481
+ "subagents": {
1482
+ "enabled": true,
1483
+ "max_steps": 20,
1484
+ "model": ""
1485
+ }
1486
+ }
1487
+ ```
1488
+
1489
+ ```bash
1490
+ kiwimatecoder config subagents show
1491
+ kiwimatecoder config subagents enable on
1492
+ kiwimatecoder config subagents max-steps 10
1493
+ kiwimatecoder config subagents model gpt-5-mini
1494
+ ```
1495
+
1496
+ Or in the REPL: `/config subagents [show|enable on|off|max-steps <n>]`.
1497
+
1498
+ ## Sampling and output styles
1499
+
1500
+ Sampling parameters apply to every provider and are sent when set:
1501
+
1502
+ ```bash
1503
+ kiwimatecoder config sampling set temperature=0.2 top_p=0.9 max_tokens=4096 reasoning_effort=medium
1504
+ kiwimatecoder config sampling show
1505
+ kiwimatecoder config sampling reset
1506
+ ```
1507
+
1508
+ Output styles shape the agent's replies: `default`, `concise`, `explanatory`,
1509
+ or `code`. Set one with `config style set <name>` (or `/config style set`). For
1510
+ a fully custom instruction, add a system-prompt suffix with
1511
+ `config prompt set "<text>"` and remove it with `config prompt clear`.
1512
+
1513
+ ## Themes, output modes, and accessibility
1514
+
1515
+ Control color independently of your terminal, pick a theme, tune how much the
1516
+ agent prints, and switch to ASCII glyphs for screen readers and limited
1517
+ terminals:
1518
+
1519
+ ```bash
1520
+ kiwimatecoder config ui show
1521
+ kiwimatecoder config ui color never # auto | always | never
1522
+ kiwimatecoder config ui theme ocean # default | ocean | magenta | mono
1523
+ kiwimatecoder config ui output compact # normal | compact | verbose
1524
+ kiwimatecoder config ui ascii on # on | off
1525
+ kiwimatecoder config ui spinner off # auto | on | off
1526
+ ```
1527
+
1528
+ The same settings are available in-session with `/config ui ...`. Values live
1529
+ under the `ui` key in `~/.kiwimatecoder/config.json`:
1530
+
1531
+ ```json
1532
+ {
1533
+ "ui": {
1534
+ "theme": "ocean",
1535
+ "color": "auto",
1536
+ "output_mode": "normal",
1537
+ "ascii": false,
1538
+ "locale": "en",
1539
+ "keybindings": "emacs",
1540
+ "notify": "off",
1541
+ "notify_after_seconds": 20,
1542
+ "spinner": "auto"
1543
+ }
1544
+ }
1545
+ ```
1546
+
1547
+ Color precedence: an explicit `ui.color` of `always`/`never` wins; otherwise
1548
+ `NO_COLOR` set to anything non-empty disables color, then `FORCE_COLOR` set to
1549
+ anything non-empty enables it. With `auto` and neither variable exported, Rich
1550
+ still detects a pipe or log file and stays plain.
1551
+
1552
+ Output modes shape the tool log. `normal` prints a line per tool with a success
1553
+ or failure marker. `compact` hides successful tool lines while keeping failures,
1554
+ the thinking status, and the final answer. `verbose` adds a redacted argument
1555
+ block (secrets replaced, capped at ~500 characters) before each tool runs and
1556
+ the result size after.
1557
+
1558
+ ASCII mode replaces the check, cross, blocked, folder, and bullet glyphs with
1559
+ plain text (`[ok]`, `[fail]`, `[blocked]`, no folder prefix, `-`) and the CLI
1560
+ confirmations follow suit. Color, theme, ASCII, and output-mode changes apply
1561
+ to the next session.
1562
+
1563
+ Animated status spinners can be disabled for screen readers, tmux capture, or
1564
+ quiet terminals with `config ui spinner off` (or `/config ui spinner off`).
1565
+ For a fully plain single run, the global `--plain` flag forces ASCII glyphs, no
1566
+ color, compact tool output, and no spinner without persisting anything:
1567
+
1568
+ ```bash
1569
+ kiwimatecoder --plain
1570
+ kiwimatecoder --plain -p "Summarize this repository"
1571
+ ```
1572
+
1573
+ The full audit — what works today, what does not, and the concrete follow-ups
1574
+ — is in [docs/accessibility.md](docs/accessibility.md).
1575
+
1576
+ ### Language and locale
1577
+
1578
+ A representative subset of user-facing strings is translated: the banner hint,
1579
+ prompt and approval labels, common errors, `/help` group titles, and key CLI
1580
+ messages. Pick the language from `ui.locale`, the `KIWIMATECODER_LANG`
1581
+ environment variable, or English (in that precedence order):
1582
+
1583
+ ```bash
1584
+ kiwimatecoder config ui locale de # en | de | es
1585
+ KIWIMATECODER_LANG=es kiwimatecoder # per-run override
1586
+ ```
1587
+
1588
+ The migration is incremental: untranslated strings stay in English, and a
1589
+ locale that is missing a key falls back to English and then to the key itself.
1590
+ `/config ui locale <en|de|es>` switches the language for the current session
1591
+ immediately.
1592
+
1593
+ ### Keybindings and notifications
1594
+
1595
+ The prompt is Emacs-style by default; switch to Vim mode with
1596
+ `config ui keybindings vim` (or `/config ui keybindings vim`). Vim mode keeps
1597
+ the same completion and Alt+Enter bindings and adds modal editing.
1598
+
1599
+ `ui.notify` can ring the terminal bell (`bell`) or send a desktop notification
1600
+ (`desktop`: OSC 9 when stderr is a TTY, otherwise `osascript` on macOS or
1601
+ `notify-send` on Linux) when a turn takes at least `ui.notify_after_seconds`
1602
+ seconds (default 20; `0` notifies after every turn):
1603
+
1604
+ ```bash
1605
+ kiwimatecoder config ui notify bell
1606
+ kiwimatecoder config ui notify-after 30
1607
+ ```
1608
+
1609
+ ### `@`-mentions
1610
+
1611
+ Typing `@` offers workspace file-path completions (gitignored files are
1612
+ skipped). A sent line containing `@path/to/file` attaches that text file as a
1613
+ `[mentioned files]` context block ahead of the message — at most 5 files per
1614
+ turn, 64 KB each, with truncation markers. Image paths (`@shot.png`) use the
1615
+ image-attachment path instead, so pasting or dragging an image into the
1616
+ terminal works as before.
1617
+
1618
+ ## Model routing
1619
+
1620
+ Route short, plain requests to a cheaper model while keeping the session model
1621
+ for real work. Configure it under `model_routing` in
1622
+ `~/.kiwimatecoder/config.json`:
1623
+
1624
+ ```json
1625
+ {
1626
+ "model_routing": {
1627
+ "enabled": true,
1628
+ "simple_model": "gpt-5-mini",
1629
+ "simple_max_chars": 200,
1630
+ "exclude_keywords": ["refactor", "implement", "debug", "test"]
1631
+ }
1632
+ }
1633
+ ```
1634
+
1635
+ A turn is routed when routing is enabled, `simple_model` is set, the message is
1636
+ at most `simple_max_chars` long, and it contains no code fence, file path,
1637
+ slash command, or exclude keyword (whole-word, case-insensitive). The override
1638
+ applies to the primary provider only — fallback providers keep their own
1639
+ models — and the session's model is never changed.
1640
+
1641
+ ## Prompt caching
1642
+
1643
+ Native Anthropic providers support prompt caching. Enable it with
1644
+ `kiwimatecoder config cache on` (or `/config cache on`): requests then send the
1645
+ system prompt as a cacheable content block and mark the last tool definition as
1646
+ an ephemeral cache breakpoint, cutting latency and input cost when the same
1647
+ system prompt and tools repeat across turns. The toggle only changes native
1648
+ Anthropic payloads — OpenAI-compatible providers cache automatically, so their
1649
+ requests are byte-for-byte identical either way.
1650
+
1651
+ ## Auto-verify
1652
+
1653
+ Point the agent at your test/lint command and it runs automatically after any
1654
+ successful file edit, feeding the output back so it can fix failures:
1655
+
1656
+ ```bash
1657
+ kiwimatecoder config verify set "pytest -q"
1658
+ kiwimatecoder config verify show
1659
+ kiwimatecoder config verify clear
1660
+ ```
1661
+
1662
+ ## Budgets
1663
+
1664
+ Cap a session's spend by tokens, cost, or both. The agent warns at 80% and
1665
+ stops starting new turns once a limit is reached:
1666
+
1667
+ ```bash
1668
+ kiwimatecoder config budget tokens 500000
1669
+ kiwimatecoder config budget cost 5.00
1670
+ kiwimatecoder config budget show
1671
+ kiwimatecoder config budget clear
1672
+ ```
1673
+
1674
+ A token limit is a whole number from 1 to 1,000,000,000,000,000; use `clear`
1675
+ for no limit.
1676
+
1677
+ ## Audit log
1678
+
1679
+ Every tool decision (allowed, denied, dry-run, auto-verify) is appended to
1680
+ `~/.kiwimatecoder/audit.log` as one JSON line per action. Secrets are redacted
1681
+ before writing; the file is owner-only and safe to delete.
1682
+
1683
+ A `pre_tool` hook that exits non-zero blocks the action and is recorded with
1684
+ the `hook_blocked` decision.
1685
+
1686
+ ## Telemetry and debug logging
1687
+
1688
+ Telemetry is **opt-in, local-only, and off by default**. When enabled, events
1689
+ from the lifecycle bus (`session_start`, `session_end`, `pre_tool`,
1690
+ `post_tool`), provider errors and retries, and (at the `debug` level) provider
1691
+ HTTP metadata (method/host/status/duration only — never bodies or headers) are
1692
+ appended as one compact JSON object per line to
1693
+ `~/.kiwimatecoder/logs/kiwimatecoder.log`. Secret-looking strings are redacted
1694
+ with the same rules as the audit log, the file is owner-only, and it rotates to
1695
+ `.log.1` once it would grow past `max_log_bytes`:
1696
+
1697
+ ```bash
1698
+ kiwimatecoder config telemetry enable on
1699
+ kiwimatecoder config telemetry level info # off | error | info | debug
1700
+ kiwimatecoder config telemetry show
1701
+ ```
1702
+
1703
+ Slash equivalents: `/config telemetry show|enable on|off|level <lvl>`. Log
1704
+ files are never uploaded anywhere. Crash bundles (`crash-<timestamp>.json`
1705
+ containing a redacted traceback, version, platform, and recent log lines) are
1706
+ written only while telemetry is enabled at a level other than `off`, and
1707
+ `/doctor` lists the level, log path, and crash-report count.
1708
+
1709
+ Set `KIWIMATECODER_DEBUG=1` to force the `debug` level for one run without
1710
+ changing config (handy for diagnosing a stubborn provider or proxy issue).
1711
+
1712
+ An OTLP exporter is not implemented yet; see the roadmap (5.2 follow-up).
1713
+
1714
+ ## Lifecycle hooks
1715
+
1716
+ Run your own shell commands when the agent reaches a lifecycle event. Hooks
1717
+ live under the `hooks` key in `~/.kiwimatecoder/config.json` (a project
1718
+ `.kiwimatecoder.json` may add them too). Each event maps to a list of commands
1719
+ run with the session workspace as their working directory:
1720
+
1721
+ ```json
1722
+ {
1723
+ "hooks": {
1724
+ "session_start": ["echo session started in $KIWI_WORKSPACE"],
1725
+ "session_end": ["echo session ended"],
1726
+ "pre_tool": ["test \"$KIWI_TOOL_NAME\" != \"run_bash\" || ./scripts/safety-check.sh"],
1727
+ "post_tool": ["echo \"$KIWI_TOOL_NAME\" exited ok=$KIWI_TOOL_OK\" >> .kiwi-hooks.log"]
1728
+ }
1729
+ }
1730
+ ```
1731
+
1732
+ Events are `session_start`, `session_end`, `pre_tool`, and `post_tool`. Hooks
1733
+ receive `KIWI_EVENT` and `KIWI_WORKSPACE`, plus `KIWI_TOOL_NAME`,
1734
+ `KIWI_TOOL_OK` (`true`/`false`), `KIWI_TOOL_ARGS` (JSON; secrets redacted), and
1735
+ `KIWI_TOOL_DURATION_MS` for tool events. A non-zero exit from a `pre_tool` hook
1736
+ blocks the tool call; every hook times out after 60 seconds and never crashes
1737
+ the agent. Commands run through the platform shell (`/bin/sh` on POSIX,
1738
+ `cmd.exe` on Windows), so write them in that shell's syntax; the examples above
1739
+ are POSIX. `/config` does not manage hooks yet — edit the JSON directly.
1740
+
1741
+ ## Configuration
1742
+
1743
+ Global settings live in `~/.kiwimatecoder/config.json` (provider keys, the
1744
+ default provider, the model chosen for each provider under `provider_models`,
1745
+ default mode, sampling, output style, theme/color/output/ASCII preferences,
1746
+ custom prompt, and persisted tool approvals). The original single-key
1747
+ `~/.kiwimatecoder/config` format is read automatically, so existing setups keep
1748
+ working. Config files from before per-provider models (version 2 or older) are
1749
+ migrated on load: a model saved with `config model set` becomes the primary provider's
1750
+ choice, and a custom provider's `default_model` becomes its chosen model.
1751
+ Built-in providers that never had a model chosen ask for one. A custom provider
1752
+ whose id is now built in (a hand-made `kiwimate`) is renamed to
1753
+ `kiwimate-custom`, keeping its stored key, model, filter, and the profiles that
1754
+ used it; if it read its key from `KIWIMATE_API_KEY`, it now reads
1755
+ `KIWIMATE_CUSTOM_API_KEY` so the built-in and the custom provider never share a
1756
+ key.
1757
+
1758
+ A project can pin its own settings in `.kiwimatecoder.json` at the repository
1759
+ root (or wherever `KIWIMATECODER_PROJECT_CONFIG` points). Project values
1760
+ override global config — useful for pinning a provider, model, mode, sampling,
1761
+ or permissions per repository. A pinned `selected_model` applies to the primary
1762
+ provider only and wins over the model chosen for it. API keys are never read
1763
+ from project files.
1764
+
1765
+ A shared **team policy** file can be layered on top of both (see
1766
+ [Team policies and session sharing](#team-policies-and-session-sharing)); it is
1767
+ configured only in the global config, so a cloned repository can never disable
1768
+ or redirect it.
1769
+
1770
+ Fetched model catalogs are cached separately in
1771
+ `~/.kiwimatecoder/model_cache.json`. It holds no secrets and can be deleted at
1772
+ any time; the next `/model` rebuilds it.
1773
+
1774
+ Prompt history lives in `~/.kiwimatecoder/history` and session autosaves in
1775
+ `~/.kiwimatecoder/sessions/last.json`. Both can be deleted at any time.
1776
+
1777
+ Run `kiwimatecoder doctor` (or `/doctor`) to check config paths, key status,
1778
+ provider reachability, the model catalog, whether a model is chosen, and the
1779
+ workspace.
1780
+
1781
+ ## Profiles
1782
+
1783
+ Profiles are named presets of global settings: provider, model, mode, sampling,
1784
+ output style, custom system prompt, verify command, budget, trusted workspace,
1785
+ command rules, and persisted `always` approvals. Capture the current effective
1786
+ settings, then re-apply them anywhere:
1787
+
1788
+ ```bash
1789
+ kiwimatecoder config profile save work
1790
+ kiwimatecoder config profile list
1791
+ kiwimatecoder config profile show work
1792
+ kiwimatecoder config profile use work # writes the preset into config
1793
+ kiwimatecoder config profile remove work
1794
+ ```
1795
+
1796
+ Launch once with a profile without persisting it with `kiwimatecoder --profile
1797
+ work`. On a fresh session the provider, model, mode, and other session-level
1798
+ settings come from the profile; with `--resume`/`--continue` only the mode and
1799
+ model are overlaid so the restored conversation keeps its provider. Sampling
1800
+ and budget are global settings, so use `config profile use` to apply those.
1801
+ The REPL equivalent is `/config profile list|show|save|use|remove`.
1802
+
1803
+ ## Cross-machine session sync
1804
+
1805
+ Sync saved sessions across machines through a folder you already share (Dropbox,
1806
+ iCloud Drive, a network mount, or a git checkout). There is no server component
1807
+ and nothing is sent anywhere: the feature is off by default and only reads and
1808
+ writes the folder you point it at.
1809
+
1810
+ Enable it with an existing directory:
1811
+
1812
+ ```bash
1813
+ kiwimatecoder sync enable ~/Dropbox/kiwimatecoder
1814
+ ```
1815
+
1816
+ or edit `~/.kiwimatecoder/config.json` directly:
1817
+
1818
+ ```json
1819
+ {
1820
+ "sync": {
1821
+ "enabled": true,
1822
+ "path": "~/Dropbox/kiwimatecoder",
1823
+ "machine": "laptop",
1824
+ "include_autosave": false
1825
+ }
1826
+ }
1827
+ ```
1828
+
1829
+ The folder gets a `kiwimatecoder-sessions/` subdirectory holding the session
1830
+ JSON files plus a `manifest.json` index. `machine` defaults to a slug of the
1831
+ hostname; set it explicitly when two machines would otherwise share a name.
1832
+
1833
+ ```bash
1834
+ kiwimatecoder sync status # local/remote counts, pending changes, conflicts
1835
+ kiwimatecoder sync push # copy local sessions into the shared folder
1836
+ kiwimatecoder sync pull # copy newer shared sessions into the local store
1837
+ kiwimatecoder sync disable # opt out; the shared folder is left alone
1838
+ ```
1839
+
1840
+ The same actions are available in the REPL as `/sync [status|push|pull]`.
1841
+ Everything mirrors the local session store except the implicit `last.json`
1842
+ autosave, which is skipped by default (`include_autosave: true` opts in) because
1843
+ it changes on every exit. Unreadable or corrupt files are skipped and reported,
1844
+ never fatal.
1845
+
1846
+ **Conflicts.** Each machine remembers what it last pushed or pulled. On the next
1847
+ `push`, a shared file that changed elsewhere *and* whose local copy also changed
1848
+ is kept as both: the shared copy stays put and the local copy is uploaded as
1849
+ `<name>__<machine>.json`. Every other difference is last-write-wins by the
1850
+ session's `saved_at` timestamp. `pull` uses the same rule but renames the
1851
+ incoming file to `<name>__<remote-machine>.json` instead of overwriting the
1852
+ local one. Pass `--force` to `push`/`pull` to make the local copy (push) or the
1853
+ shared copy (pull) win unconditionally.
1854
+
1855
+ ## Team policies and session sharing
1856
+
1857
+ ### Shared team policies
1858
+
1859
+ A team can publish a shared policy JSON file (same shape as
1860
+ `.kiwimatecoder.json`) that is layered **on top of** global and project config,
1861
+ so policy values win. There is no server component and no identity provider:
1862
+ the file is read from the local path you configure, and a cloned repository can
1863
+ never disable or redirect it because `team` settings are taken from the global
1864
+ config only.
1865
+
1866
+ Point the global config at the shared file:
1867
+
1868
+ ```bash
1869
+ kiwimatecoder config team set-policy ~/team/kiwimatecoder-policy.json
1870
+ kiwimatecoder config team enforce on
1871
+ kiwimatecoder config team show
1872
+ ```
1873
+
1874
+ or edit `~/.kiwimatecoder/config.json` directly:
1875
+
1876
+ ```json
1877
+ {
1878
+ "team": {
1879
+ "policy_path": "/Users/you/team/kiwimatecoder-policy.json",
1880
+ "enforce": true
1881
+ }
1882
+ }
1883
+ ```
1884
+
1885
+ The policy file may only control these keys: `default_mode`,
1886
+ `selected_provider`, `active_providers`, `selected_model`,
1887
+ `model_filters`, `command_rules`, `tool_permissions`, `sampling`, `trusted_workspace`,
1888
+ `output_style`, `system_prompt`, `verify_command`, `budget`, `mcp_servers`,
1889
+ `plugins`, `subagents`, `sandbox`, `remote`, and `network`. `keys`, `version`,
1890
+ and `team` are ignored, so a policy can never carry API keys or weaken its own
1891
+ enforcement. Unknown keys are reported as warnings. The per-provider model
1892
+ choices (`provider_models`) are deliberately not a policy key — an enforced
1893
+ policy would replace every provider's choice at once — so a team pins the
1894
+ primary provider's model with `selected_model`.
1895
+
1896
+ - **Advisory** (`enforce: false`): policy values override global and project
1897
+ values, but project config still fills in any key the policy does not set.
1898
+ - **Enforced** (`enforce: true`): each policy key replaces the merged value
1899
+ wholesale, and project values for policy keys the policy does not define are
1900
+ ignored, so a repository cannot widen or weaken the policy namespace.
1901
+
1902
+ A missing or corrupt policy file never blocks startup: it is skipped and
1903
+ reported by `kiwimatecoder config validate`, `kiwimatecoder doctor`, and
1904
+ `/config team show`. The REPL equivalents are
1905
+ `/config team [show|set-policy <path>|enforce on|off]`.
1906
+
1907
+ ### Session sharing
1908
+
1909
+ Share a conversation as a redacted JSON bundle, either as a local file or as a
1910
+ **secret** GitHub gist through your own `gh` login (no token is read or stored
1911
+ by KiwiMateCoder):
1912
+
1913
+ ```bash
1914
+ kiwimatecoder share create # last session -> .kiwimatecoder/shares/
1915
+ kiwimatecoder share create my-session --output ~/Desktop/review.json
1916
+ kiwimatecoder share create --gist # uploads via `gh gist create`
1917
+ kiwimatecoder share import bundle.share.json --name from-teammate
1918
+ ```
1919
+
1920
+ In the REPL, `/share` bundles the current session, `/share gist` uploads it,
1921
+ and `/share import <path>` turns a bundle into a normal saved session.
1922
+
1923
+ Privacy notes:
1924
+
1925
+ - Every string is passed through the same secret redactor used for logs, so
1926
+ API keys and `token = ...` assignments never leave the machine.
1927
+ - Tool **results are omitted** (replaced with `[tool output omitted]`) unless
1928
+ you pass `--include-tool-output`; when included they are redacted and
1929
+ truncated to 2 KB. Tool call names are kept for context, and their arguments
1930
+ are redacted and clipped.
1931
+ - Image attachments are replaced with `[image omitted]` so no base64 image data
1932
+ is embedded in the bundle.
1933
+ - Bundles are capped at ~256 KB; when a conversation is larger the oldest
1934
+ messages are dropped and `truncated` / `truncated_messages` record it.
1935
+ - Sharing is local or gist-based only. **SSO/identity and any hosted sharing
1936
+ service are deferred** (see the roadmap) — there is no server to run.
1937
+
1938
+ ## Config validation
1939
+
1940
+ `kiwimatecoder config validate` checks the stored config and prints a table of
1941
+ issues, exiting non-zero when any error-level problem is found. It surfaces
1942
+ exactly what the tolerant getters would silently drop: unknown top-level keys
1943
+ (warning), malformed provider/model-filter/sampling/budget/hook/command-rule/
1944
+ profile/MCP/plugin entries, a model chosen for an unknown provider in
1945
+ `provider_models` (warning), invalid regexes, unknown hook events, bad network
1946
+ (proxy/CA/offline) values, bad ACP permission timeouts, a missing or corrupt
1947
+ team policy file, and bad default mode,
1948
+ output style, UI (theme/color/ASCII/output mode), or workspace-flag values.
1949
+
1950
+ ## Evals
1951
+
1952
+ `kiwimatecoder eval` runs declarative regression cases against any configured
1953
+ provider. A case is a small JSON file with a prompt, optional starting files,
1954
+ and deterministic expectations about the run:
1955
+
1956
+ ```json
1957
+ {
1958
+ "name": "create-file-from-prompt",
1959
+ "description": "Writes a requested file with exact content.",
1960
+ "prompt": "Create hello.txt whose contents are exactly 'hello from the eval'.",
1961
+ "files": {"notes.txt": "Starting workspace file."},
1962
+ "expect": {
1963
+ "text_contains": ["hello"],
1964
+ "text_not_contains": ["error"],
1965
+ "tools_called": ["write_file"],
1966
+ "tools_not_called": ["run_bash"],
1967
+ "files": {"hello.txt": ["hello from the eval"]},
1968
+ "success": true
1969
+ }
1970
+ }
1971
+ ```
1972
+
1973
+ List and run the committed cases:
1974
+
1975
+ ```bash
1976
+ kiwimatecoder eval list
1977
+ kiwimatecoder eval run --provider openrouter --model anthropic/claude-sonnet-5
1978
+ kiwimatecoder eval run --filter create --json --report eval-report.json
1979
+ ```
1980
+
1981
+ Every field in `expect` is optional: `text_contains`/`text_not_contains` check
1982
+ the final assistant text, `tools_called`/`tools_not_called` check the tools the
1983
+ run used, `files` maps workspace paths to substrings that must appear in the
1984
+ file after the run, and `success` checks the run's own success flag. A run
1985
+ error is always a failure unless the case explicitly expects `success: false`.
1986
+
1987
+ Cases live in `evals/cases/*.json` and are discovered sorted by `name`. Copy
1988
+ one as a starting point, or point `--dir` at another directory. The command
1989
+ exits `0` when every case passes, `1` when any case fails, and `2` on invalid
1990
+ input (bad directory, malformed JSON, unknown provider, or no `--model` passed
1991
+ and none chosen for the provider — `No model chosen for <provider>…`). Eval
1992
+ runs call a real model, so they need a configured provider key and a chosen
1993
+ model (`kiwimatecoder setup`) or `--model`; each
1994
+ case runs in a throwaway temp workspace and nothing is recorded beyond the
1995
+ report you ask for. Expectations are deterministic — there is no model-graded
1996
+ scoring yet.
1997
+
1998
+ ## Development
1999
+
2000
+ ```bash
2001
+ pip install -e ".[dev]"
2002
+ pytest
2003
+ ruff check kiwimatecoder tests
2004
+ mypy kiwimatecoder
2005
+ ```
2006
+
2007
+ ## Roadmap
2008
+
2009
+ The full prioritized plan lives in [ROADMAP.md](ROADMAP.md). P0 and P1 are
2010
+ implemented (checkpoints/undo, command rules, dry-run, redacted audit log,
2011
+ hunk-level approvals, todos, ask-user, parallel reads, compaction, auto-verify,
2012
+ budgets, trusted workspace, and message steering with interrupt recovery), and
2013
+ P2 is complete (event bus + hooks, the extensible tool registry, custom
2014
+ commands and prompt templates, on-demand Agent Skills, a plugin system, the MCP
2015
+ client, config profiles with schema validation, per-turn model routing,
2016
+ Anthropic prompt caching, and themes/output modes/NO_COLOR accessibility).