@markusylisiurunen/tau 0.3.81 → 0.3.83

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 (180) hide show
  1. package/README.md +1 -3
  2. package/dist/core/agent/agent_runtime.js +6 -4
  3. package/dist/core/agent/agent_runtime.js.map +1 -1
  4. package/dist/core/cli.js +2 -2
  5. package/dist/core/cli.js.map +1 -1
  6. package/dist/core/code_mode/models.js +61 -22
  7. package/dist/core/code_mode/models.js.map +1 -1
  8. package/dist/core/commands/registry.js +0 -22
  9. package/dist/core/commands/registry.js.map +1 -1
  10. package/dist/core/history/cli.js +48 -0
  11. package/dist/core/history/cli.js.map +1 -1
  12. package/dist/core/history/history_manager.js +9 -3
  13. package/dist/core/history/history_manager.js.map +1 -1
  14. package/dist/core/history/local_history_store.js +9 -2
  15. package/dist/core/history/local_history_store.js.map +1 -1
  16. package/dist/core/history/remote_history_client.js +18 -3
  17. package/dist/core/history/remote_history_client.js.map +1 -1
  18. package/dist/core/models/openrouter.js +17 -5
  19. package/dist/core/models/openrouter.js.map +1 -1
  20. package/dist/core/models/openrouter_decisions.js +16 -1
  21. package/dist/core/models/openrouter_decisions.js.map +1 -1
  22. package/dist/core/runtime/chat_runtime.js +2 -13
  23. package/dist/core/runtime/chat_runtime.js.map +1 -1
  24. package/dist/core/static/tau_docs/client-tools.md +53 -53
  25. package/dist/core/static/tau_docs/config-reference.md +46 -43
  26. package/dist/core/static/tau_docs/configuration.md +40 -36
  27. package/dist/core/static/tau_docs/credentials.md +32 -31
  28. package/dist/core/static/tau_docs/getting-started.md +28 -28
  29. package/dist/core/static/tau_docs/history.md +114 -79
  30. package/dist/core/static/tau_docs/image-generation.md +20 -18
  31. package/dist/core/static/tau_docs/index.md +30 -31
  32. package/dist/core/static/tau_docs/manifest.json +1 -0
  33. package/dist/core/static/tau_docs/models.md +17 -17
  34. package/dist/core/static/tau_docs/node-sdk.md +69 -72
  35. package/dist/core/static/tau_docs/nook.md +75 -69
  36. package/dist/core/static/tau_docs/openrouter.md +28 -13
  37. package/dist/core/static/tau_docs/ownership-and-scope.md +21 -23
  38. package/dist/core/static/tau_docs/pdf-unpacking.md +6 -6
  39. package/dist/core/static/tau_docs/personas.md +29 -27
  40. package/dist/core/static/tau_docs/prompts-and-project-context.md +41 -39
  41. package/dist/core/static/tau_docs/remote-sessions.md +38 -38
  42. package/dist/core/static/tau_docs/sdk-diff-review.md +16 -12
  43. package/dist/core/static/tau_docs/security.md +72 -72
  44. package/dist/core/static/tau_docs/session-protocol-methods.md +46 -91
  45. package/dist/core/static/tau_docs/session-protocol.md +54 -54
  46. package/dist/core/static/tau_docs/sessions.md +97 -107
  47. package/dist/core/static/tau_docs/skills.md +25 -20
  48. package/dist/core/static/tau_docs/speech-generation.md +5 -5
  49. package/dist/core/static/tau_docs/subagents.md +42 -44
  50. package/dist/core/static/tau_docs/telegram-projects.md +142 -0
  51. package/dist/core/static/tau_docs/telegram.md +65 -182
  52. package/dist/core/static/tau_docs/tools.md +72 -91
  53. package/dist/core/static/tau_docs/troubleshooting.md +94 -149
  54. package/dist/core/static/tau_docs/tui.md +124 -81
  55. package/dist/core/telegram/adapter.js +1 -6
  56. package/dist/core/telegram/adapter.js.map +1 -1
  57. package/dist/core/tool/image_generate.js +5 -17
  58. package/dist/core/tool/image_generate.js.map +1 -1
  59. package/dist/core/tool/openrouter.js +21 -2
  60. package/dist/core/tool/openrouter.js.map +1 -1
  61. package/dist/core/tools/catalog.js +0 -11
  62. package/dist/core/tools/catalog.js.map +1 -1
  63. package/dist/core/tools/tool_names.js +0 -6
  64. package/dist/core/tools/tool_names.js.map +1 -1
  65. package/dist/core/utils/gemini_transcription.js +103 -28
  66. package/dist/core/utils/gemini_transcription.js.map +1 -1
  67. package/dist/core/utils/model_stream.js +17 -1
  68. package/dist/core/utils/model_stream.js.map +1 -1
  69. package/dist/core/utils/user_metadata.js +0 -14
  70. package/dist/core/utils/user_metadata.js.map +1 -1
  71. package/dist/core/version.js +2 -2
  72. package/dist/diff_tool/app/dist/assets/{angular-html-BbLgbIhq.js → angular-html-x29PkEoY.js} +1 -1
  73. package/dist/diff_tool/app/dist/assets/{angular-ts-DXk17TRM.js → angular-ts-CsWCqoCf.js} +1 -1
  74. package/dist/diff_tool/app/dist/assets/{apl-BsvksCXR.js → apl-CEvdc7jl.js} +1 -1
  75. package/dist/diff_tool/app/dist/assets/{astro-DH775E4V.js → astro-Cgi6YxH2.js} +1 -1
  76. package/dist/diff_tool/app/dist/assets/{blade-Ck99Rm59.js → blade-B0pr7Zx6.js} +1 -1
  77. package/dist/diff_tool/app/dist/assets/{c-DJpHqu5J.js → c-DDVLgtVy.js} +1 -1
  78. package/dist/diff_tool/app/dist/assets/{chapel-Owff0Csy.js → chapel-Bk9M7Jej.js} +1 -1
  79. package/dist/diff_tool/app/dist/assets/{cobol-Cv2gZuhO.js → cobol-DyEvnPuC.js} +1 -1
  80. package/dist/diff_tool/app/dist/assets/{coffee-Bji0YCf_.js → coffee-Di2-m3Jq.js} +1 -1
  81. package/dist/diff_tool/app/dist/assets/{cpp-DTjA_yFF.js → cpp-CWpAaUgO.js} +1 -1
  82. package/dist/diff_tool/app/dist/assets/{crystal-Dd00NOeb.js → crystal-CUker9Zt.js} +1 -1
  83. package/dist/diff_tool/app/dist/assets/{css-D44TN1V6.js → css-D4XpBIiJ.js} +1 -1
  84. package/dist/diff_tool/app/dist/assets/{edge-CVmGSi2m.js → edge-CVxhhF7L.js} +1 -1
  85. package/dist/diff_tool/app/dist/assets/{elixir-B8Mq7no2.js → elixir-B_FS9APl.js} +1 -1
  86. package/dist/diff_tool/app/dist/assets/{elm-CXS0I3Z2.js → elm-1KyefTkH.js} +1 -1
  87. package/dist/diff_tool/app/dist/assets/{erb-B9oDKaUo.js → erb-CCgO9dRW.js} +1 -1
  88. package/dist/diff_tool/app/dist/assets/{git-rebase-DT-YFebH.js → git-rebase-D0VYo_oY.js} +1 -1
  89. package/dist/diff_tool/app/dist/assets/{glimmer-js-s0DXlNjq.js → glimmer-js-Ce07ngjZ.js} +1 -1
  90. package/dist/diff_tool/app/dist/assets/{glimmer-ts-QgEB5S2z.js → glimmer-ts-BmOM4djO.js} +1 -1
  91. package/dist/diff_tool/app/dist/assets/{glsl-NA0icwbY.js → glsl-D-jkLYJ8.js} +1 -1
  92. package/dist/diff_tool/app/dist/assets/{graphql-0_dOlfV0.js → graphql-DZOwJE5e.js} +1 -1
  93. package/dist/diff_tool/app/dist/assets/{hack-D-mr7l1l.js → hack-Cgvn19h8.js} +1 -1
  94. package/dist/diff_tool/app/dist/assets/{haml-B0-oQmz7.js → haml-JTmDSYQl.js} +1 -1
  95. package/dist/diff_tool/app/dist/assets/{handlebars-Yq9bXpWN.js → handlebars-CChh7Dy5.js} +1 -1
  96. package/dist/diff_tool/app/dist/assets/{html-B8bMmdRK.js → html-BKgzx_cb.js} +1 -1
  97. package/dist/diff_tool/app/dist/assets/{html-derivative-BpxSlQb_.js → html-derivative-CdFl0BmX.js} +1 -1
  98. package/dist/diff_tool/app/dist/assets/{http-hS_53mxt.js → http-DZeL7KvH.js} +1 -1
  99. package/dist/diff_tool/app/dist/assets/{hurl-B2ST1kwl.js → hurl-CqKevOlQ.js} +1 -1
  100. package/dist/diff_tool/app/dist/assets/index-BXyr8GCM.js +341 -0
  101. package/dist/diff_tool/app/dist/assets/{java-D4mj0lZJ.js → java-Sq3MCkId.js} +1 -1
  102. package/dist/diff_tool/app/dist/assets/{javascript-wC7rrKiV.js → javascript-CHZB4Nse.js} +1 -1
  103. package/dist/diff_tool/app/dist/assets/{jinja-DbQ3o87F.js → jinja-C4ucJVla.js} +1 -1
  104. package/dist/diff_tool/app/dist/assets/{jison-CrE9FdvP.js → jison-D3mprebA.js} +1 -1
  105. package/dist/diff_tool/app/dist/assets/{json-xjicDyWN.js → json-DgPfCYJ1.js} +1 -1
  106. package/dist/diff_tool/app/dist/assets/{jsx-m28lXojQ.js → jsx-BG-Tx0cw.js} +1 -1
  107. package/dist/diff_tool/app/dist/assets/{julia-19xkOmop.js → julia-B1GnFeUC.js} +1 -1
  108. package/dist/diff_tool/app/dist/assets/{just-Cf7OorTr.js → just-_MZzo0MF.js} +1 -1
  109. package/dist/diff_tool/app/dist/assets/{latex-DDb7GQOy.js → latex-DI0kqjQy.js} +1 -1
  110. package/dist/diff_tool/app/dist/assets/{liquid-DHOuQ0rf.js → liquid-BtMAPeHl.js} +1 -1
  111. package/dist/diff_tool/app/dist/assets/{lua-BGyIvonw.js → lua-CFxaP0To.js} +1 -1
  112. package/dist/diff_tool/app/dist/assets/{marko-DB5OqI1C.js → marko-BIJocuFI.js} +1 -1
  113. package/dist/diff_tool/app/dist/assets/{mdc-DTyNMupO.js → mdc-BAgrdjTH.js} +1 -1
  114. package/dist/diff_tool/app/dist/assets/{nginx-DfF0fMYD.js → nginx-DE-3CsYn.js} +1 -1
  115. package/dist/diff_tool/app/dist/assets/{nim-BbwsXuZD.js → nim-DOxeXLhb.js} +1 -1
  116. package/dist/diff_tool/app/dist/assets/{org-BkOBBl1f.js → org-KTfP0tHA.js} +1 -1
  117. package/dist/diff_tool/app/dist/assets/{perl-BTXTOl4K.js → perl-BH-NxpgK.js} +1 -1
  118. package/dist/diff_tool/app/dist/assets/{php-DIMVQWiA.js → php-vuiVEXZK.js} +1 -1
  119. package/dist/diff_tool/app/dist/assets/{pug-B_nrb4dJ.js → pug-VlIlTMUy.js} +1 -1
  120. package/dist/diff_tool/app/dist/assets/{qml-1PXi8G8Z.js → qml-k6wTtGG-.js} +1 -1
  121. package/dist/diff_tool/app/dist/assets/{r-CJrAkc2Z.js → r-Ccjcb2zh.js} +1 -1
  122. package/dist/diff_tool/app/dist/assets/{razor-DgPUftNd.js → razor-BNhYgSCv.js} +1 -1
  123. package/dist/diff_tool/app/dist/assets/{regexp-C2hS8XvL.js → regexp-C4LFejPu.js} +1 -1
  124. package/dist/diff_tool/app/dist/assets/{rst-CDouhKnc.js → rst-DXLxI-UJ.js} +1 -1
  125. package/dist/diff_tool/app/dist/assets/{ruby-CAjKW1uO.js → ruby-BPuL4jDV.js} +1 -1
  126. package/dist/diff_tool/app/dist/assets/{sas-qAHkHLc1.js → sas-B3Yz8snb.js} +1 -1
  127. package/dist/diff_tool/app/dist/assets/{scss-Bfx2Ydid.js → scss-B2AJ5vpk.js} +1 -1
  128. package/dist/diff_tool/app/dist/assets/{shellscript-Bu76R8y2.js → shellscript-zyDexxnC.js} +1 -1
  129. package/dist/diff_tool/app/dist/assets/{shellsession-BU8BL0oL.js → shellsession-C8b8xluk.js} +1 -1
  130. package/dist/diff_tool/app/dist/assets/{soy-FRl8ozP-.js → soy-DKWe_XML.js} +1 -1
  131. package/dist/diff_tool/app/dist/assets/{sql-BacQgsEs.js → sql-uEbz-Epf.js} +1 -1
  132. package/dist/diff_tool/app/dist/assets/{stata-B9kkG-ET.js → stata-DieRPmHY.js} +1 -1
  133. package/dist/diff_tool/app/dist/assets/{surrealql-qvETr7iY.js → surrealql-Dbk3Sp1P.js} +1 -1
  134. package/dist/diff_tool/app/dist/assets/{svelte-B0z1MgHc.js → svelte-CjPbRmkM.js} +1 -1
  135. package/dist/diff_tool/app/dist/assets/{templ-DTnPshKb.js → templ-Do_f5vc4.js} +1 -1
  136. package/dist/diff_tool/app/dist/assets/{tex-Cosab9_H.js → tex-UjLP4qUm.js} +1 -1
  137. package/dist/diff_tool/app/dist/assets/{ts-tags-DNYvLFUH.js → ts-tags-5L2FutA6.js} +1 -1
  138. package/dist/diff_tool/app/dist/assets/{tsx-Dstq6j1a.js → tsx-B1pNtpUr.js} +1 -1
  139. package/dist/diff_tool/app/dist/assets/{twig-BzqZdwaX.js → twig-O41Vg_IM.js} +1 -1
  140. package/dist/diff_tool/app/dist/assets/{typescript-YOQ_oE25.js → typescript-Bj9uwnnJ.js} +1 -1
  141. package/dist/diff_tool/app/dist/assets/{typst-DTffwfpc.js → typst-DsibO7oD.js} +1 -1
  142. package/dist/diff_tool/app/dist/assets/{vue-D4OMj_C5.js → vue-DPhaEurv.js} +1 -1
  143. package/dist/diff_tool/app/dist/assets/{vue-html-kT4WrHGK.js → vue-html-DDV9NSy1.js} +1 -1
  144. package/dist/diff_tool/app/dist/assets/{vue-vine-CxeapeMO.js → vue-vine-Dh4jOifx.js} +1 -1
  145. package/dist/diff_tool/app/dist/assets/{xml-DWVpuurg.js → xml-DtIulkQk.js} +1 -1
  146. package/dist/diff_tool/app/dist/assets/{xsl-C0ciup5a.js → xsl-DoWtb58Z.js} +1 -1
  147. package/dist/diff_tool/app/dist/assets/{yaml-98Fvyfpc.js → yaml-CZC-l1Dg.js} +1 -1
  148. package/dist/diff_tool/app/dist/index.html +1 -1
  149. package/dist/history/worker/index.js +87 -83
  150. package/dist/history/worker/index.js.map +1 -1
  151. package/dist/host/local_session_host.js +24 -318
  152. package/dist/host/local_session_host.js.map +1 -1
  153. package/dist/host/session_host.js.map +1 -1
  154. package/dist/host/session_protocol_handler.js +0 -98
  155. package/dist/host/session_protocol_handler.js.map +1 -1
  156. package/dist/main.js +6 -7
  157. package/dist/main.js.map +1 -1
  158. package/dist/protocol/index.d.ts +1 -1
  159. package/dist/protocol/index.js.map +1 -1
  160. package/dist/protocol/session_protocol.d.ts +3 -28
  161. package/dist/protocol/session_protocol.js +1 -56
  162. package/dist/protocol/session_protocol.js.map +1 -1
  163. package/dist/sdk/index.d.ts +1 -1
  164. package/dist/sdk/index.js.map +1 -1
  165. package/dist/sdk/session.js +0 -20
  166. package/dist/sdk/session.js.map +1 -1
  167. package/dist/sdk/types.d.ts +1 -7
  168. package/dist/store/session_snapshot_migrations.js +72 -1
  169. package/dist/store/session_snapshot_migrations.js.map +1 -1
  170. package/dist/tui/session_chat_controller.js +14 -30
  171. package/dist/tui/session_chat_controller.js.map +1 -1
  172. package/dist/tui/ui/footer.js +4 -9
  173. package/dist/tui/ui/footer.js.map +1 -1
  174. package/package.json +9 -9
  175. package/dist/core/session/goal.js +0 -54
  176. package/dist/core/session/goal.js.map +0 -1
  177. package/dist/core/tools/goal.js +0 -167
  178. package/dist/core/tools/goal.js.map +0 -1
  179. package/dist/diff_tool/app/dist/assets/index-CBT_sNIz.js +0 -340
  180. package/dist/nook/README.md +0 -123
@@ -1,27 +1,27 @@
1
1
  # Client tools
2
2
 
3
- Client tools let an attached client contribute capabilities that the host does not own. A TUI can open a local review interface, a Telegram runner can invoke a workspace-specific command, and an SDK client can provide an in-process handler. The model sees an ordinary tool schema, but execution stays with the client that advertised it.
3
+ Client tools are tools that an attached client adds to a session. A TUI can open a local review interface, a Telegram runner can run a workspace-specific command, and an SDK client can provide an in-process handler. The model sees an ordinary tool, but the tool runs in the client that offered it.
4
4
 
5
- This boundary matters in remote sessions. The client process, host, and execution environment may be three different machines. A command client tool starts on the client machine. If it needs to inspect or change the agent's workspace, it must use the provided execution-environment facade rather than assuming the same filesystem is locally mounted.
5
+ In a remote session, the client, the host, and the execution environment may be three different machines. A command client tool starts on the client machine. To read or change the agent's workspace, it must use the execution-environment API that Tau provides. It cannot assume the workspace is on its own filesystem.
6
6
 
7
7
  ## Which client advertises which tools
8
8
 
9
9
  Tau's TUI advertises two built-in client tools:
10
10
 
11
- - `diff_review` runs the TUI-local diff review flow while capturing repository data through the session execution environment.
11
+ - `diff_review` runs diff review on the TUI machine, reading repository data from the session's execution environment.
12
12
  - `prefill_input` puts a draft in an empty TUI editor for the user to edit and submit. It never submits the draft and does not replace existing editor text.
13
13
 
14
- The TUI also advertises the configured command client tools selected for its current client-side working directory. This is true for local `tau` and for `tau attach`. During remote attach, the command executable and its environment belong to the attaching machine, not the remote host.
14
+ The TUI also offers the configured command client tools selected for its own working directory, both with local `tau` and with `tau attach`. When attached to a remote host, the command and its environment are on the attaching machine, not on the host.
15
15
 
16
- A Telegram runner advertises the built-in `send_photo_to_telegram`, `send_video_to_telegram`, `send_audio_to_telegram`, and `send_document_to_telegram` tools, plus the configured command client tools selected from each prepared workspace's Tau configuration. The built-in [file delivery tools](tools.md#sending-files-to-telegram) send files to the session's chat and are independent of `enabledClientTools`. It does not advertise TUI-only tools. Repository, persistent-directory, and composite workspace preparation determines the client-side configuration scope used for that Telegram session. See [Telegram](telegram.md) for workspace ownership.
16
+ A Telegram runner offers the built-in `send_photo_to_telegram`, `send_video_to_telegram`, `send_audio_to_telegram`, and `send_document_to_telegram` tools, plus the command client tools selected by each prepared workspace's Tau configuration. The built-in [file delivery tools](tools.md#sending-files-to-telegram) send files to the session's chat and are not affected by `enabledClientTools`. The runner does not offer the TUI's tools. The session's workspace, whether repository, persistent directory, or composite, decides which configuration selects its tools. See [Telegram projects and workspaces](telegram-projects.md) for workspace types.
17
17
 
18
- Node SDK clients can supply `TauSdkClientTool` handlers directly when they initialize. The same session routing, cancellation, and execution-environment contracts apply.
18
+ Node SDK clients can pass `TauSdkClientTool` handlers when they initialize. The same rules for routing, cancellation, and execution-environment access apply.
19
19
 
20
- Only an observing client can contribute tools to a session. The tools disappear when that client detaches or disconnects. If several clients observe one session, at most one may advertise a given client-tool name. Tau rejects the later attachment on a name collision. Client-tool names must also not collide with host or intrinsic tools.
20
+ Only a client that is observing a session can add tools to it. The tools disappear when that client detaches or disconnects. When several clients observe one session, only one may offer a given tool name, and Tau rejects the later client if names collide. Client tool names also must not match host tools or built-in tools.
21
21
 
22
22
  ## Configure command client tools globally
23
23
 
24
- Executable client-tool definitions are accepted only from the global `~/.config/tau/config.json`, and that global level is in scope only when the client-side working directory is inside home. Project configuration cannot define executable commands. This prevents a checked-out repository from silently introducing a process that runs on the client machine.
24
+ Client tool commands can be defined only in the global `~/.config/tau/config.json`, and only when the client's working directory is inside home. Project configuration cannot define commands, so a cloned repository can never add a process that runs on your machine.
25
25
 
26
26
  A definition requires `name`, `defaultEnabled`, `description`, `parameters`, and `command`:
27
27
 
@@ -56,20 +56,20 @@ The exact fields are:
56
56
  | `name` | Required non-empty string. Names must be unique within `clientTools` and must not collide with tools already bound to the session. |
57
57
  | `defaultEnabled` | Required boolean. Controls selection when no project level supplies `enabledClientTools`. |
58
58
  | `description` | Required non-empty model-facing description. State when the tool should be used and any important side effects. |
59
- | `parameters` | Required object JSON Schema whose root has `"type": "object"`. Tau passes the remaining schema through and validates each invocation against it. |
59
+ | `parameters` | Required JSON Schema whose root has `"type": "object"`. Tau passes the rest of the schema through unchanged and validates every call against it. |
60
60
  | `command` | Required non-empty executable name or path. |
61
61
  | `args` | Optional array of literal string arguments. |
62
62
  | `executionTimeoutMs` | Optional positive integer. The default is 60,000 ms. |
63
63
 
64
- Unknown fields on a definition are discarded. Invalid entries are skipped with configuration diagnostics; valid siblings remain available. Duplicate names are exact and case-sensitive.
64
+ Unknown fields on a definition are ignored. An invalid entry is skipped with a configuration warning, and the other entries stay available. Names are compared exactly, including case, when checking for duplicates.
65
65
 
66
66
  ### Command path resolution
67
67
 
68
- A `command` containing `/` is resolved as a path from home, the root of the global configuration level. For example, `./bin/tau-notify` resolves to `~/bin/tau-notify`. A bare command such as `tau-notify` is left unchanged and resolved through the client process's `PATH` when invoked.
68
+ A `command` that contains `/` resolves from home, because the definition is global. For example, `./bin/tau-notify` resolves to `~/bin/tau-notify`. A bare command such as `tau-notify` resolves through the client process's `PATH` when the tool runs.
69
69
 
70
- Tau starts the executable directly with `args`. It does not use a shell, expand globs, interpolate variables, or process quoting syntax. If shell behavior is truly needed, configure an explicit shell executable and arguments, but a dedicated executable is easier to validate and cancel safely.
70
+ Tau starts the executable directly with `args`. It does not use a shell, expand globs, substitute variables, or process quotes. If you really need a shell, configure the shell as the command with explicit arguments, but a dedicated executable is easier to validate and to cancel safely.
71
71
 
72
- The process inherits the owning client process's environment unchanged. Unlike execution-environment Bash, Tau does not remove credential-shaped variables from command client tools. Treat every configured executable as trusted local code and give it only the credentials it needs.
72
+ The process inherits the client process's environment unchanged. The agent's Bash tool removes variables that look like credentials, but command client tools keep them. Treat every configured executable as trusted local code and give it only the credentials it needs.
73
73
 
74
74
  ## Select tools per project
75
75
 
@@ -81,17 +81,17 @@ Project `.tau/config.json` files may set `enabledClientTools` to an exact allowl
81
81
  }
82
82
  ```
83
83
 
84
- Tau uses the nearest project level that defines this field. It does not merge allowlists across project levels.
84
+ Tau uses the nearest project level that sets this field. Lists from different levels are not combined.
85
85
 
86
- Selection has three distinct states:
86
+ There are three cases:
87
87
 
88
88
  - If no project level defines `enabledClientTools`, Tau selects global definitions with `defaultEnabled: true`.
89
89
  - If the nearest definition is a non-empty array, Tau selects exactly the known names in that array, regardless of `defaultEnabled`.
90
90
  - If the nearest definition is `[]`, Tau disables every configured command client tool for that workspace.
91
91
 
92
- Unknown selected names are ignored without an error. Repeated names are deduplicated. Names are matched exactly and case-sensitively.
92
+ Unknown names are ignored without an error. Repeated names are removed. Names match exactly, including case.
93
93
 
94
- `enabledClientTools` selects trusted global definitions; it cannot change their command, arguments, schema, description, or timeout. The field is valid only at project scope. Conversely, `clientTools` is valid only at global scope.
94
+ `enabledClientTools` only selects global definitions. It cannot change their command, arguments, schema, description, or timeout. The field is allowed only in project configuration, and `clientTools` only in global configuration.
95
95
 
96
96
  For Telegram, `enabledClientTools: []` is the normal way to disable configured tools for a prepared workspace. For the TUI, the startup flag described below can disable all client tools at once.
97
97
 
@@ -109,9 +109,9 @@ For attach mode, place the flag with the attach options:
109
109
  tau attach --no-client-tools ws://host.example:8787
110
110
  ```
111
111
 
112
- This disables both configured command tools and the TUI's built-in `diff_review` and `prefill_input`. It does not disable host tools, intrinsic `tau_docs`, or session goal tools.
112
+ This disables the configured command tools and the TUI's built-in `diff_review` and `prefill_input`. Host tools and the built-in `tau_docs` tool are not affected.
113
113
 
114
- Client tools are selected and advertised when the owning client starts and connects. `/reload` refreshes host-side session configuration and content but does not recreate the TUI or Telegram client's advertised tool set. Restart or reconnect the owning client after changing `clientTools`, `enabledClientTools`, or `--no-client-tools` behavior.
114
+ A client selects and offers its tools when it starts and connects. `/reload` does not change the tools a TUI or Telegram client offers. Restart or reconnect the client after changing `clientTools`, `enabledClientTools`, or `--no-client-tools`.
115
115
 
116
116
  Diff review uses Tau’s built-in browser tool on the TUI machine, separately from command client-tool definitions. See [TUI](tui.md).
117
117
 
@@ -148,9 +148,9 @@ await runTauClientToolCommand({
148
148
  });
149
149
  ```
150
150
 
151
- `describe` is optional. When present, it runs before acknowledgement and may return a partial running presentation containing `subject`, `subjectWrap`, `details`, or `metadata`. The execution result may independently include the same partial shape for the terminal card. Tau supplies every omitted field, owns lifecycle actions and the operation derived from the registered tool name, and renders a complete fallback when execution ends without a result.
151
+ `describe` is optional. If present, it runs before the call is accepted and may return a partial presentation for the running tool card, with any of `subject`, `subjectWrap`, `details`, or `metadata`. The execution result may include the same partial shape for the finished card. Tau fills in every omitted field, controls the card's lifecycle and the operation label (derived from the tool name), and shows a complete default card if execution ends without a result.
152
152
 
153
- Tau preserves every explicit presentation field up to the protocol safety limits; it does not apply display truncation or normalize client text. `truncateTauClientToolText` provides optional caller-controlled `maxLines`, `maxLineChars`, and `head` or `middle` truncation. Its defaults match Tau's concise subject policy, but callers may select larger or smaller positive limits.
153
+ Tau keeps every presentation field you set, up to the protocol limits. It does not truncate or normalize client text for display. `truncateTauClientToolText` truncates text for you, with optional `maxLines`, `maxLineChars`, and a `head` or `middle` strategy. Its defaults match the length Tau uses for its own subjects, and you can choose larger or smaller limits.
154
154
 
155
155
  For a subject, use the returned string directly. For a block of detail text, split the returned string on `\n` and map each line to one `details` entry:
156
156
 
@@ -164,27 +164,27 @@ const details = truncateTauClientToolText(output, {
164
164
  .map((text) => ({ text }));
165
165
  ```
166
166
 
167
- Each detail or metadata entry is a single protocol line, so use `maxLines: 1` when assigning the helper's result directly to one entry. The helper shapes text for presentation; the protocol byte and collection limits still apply. Empty detail or metadata arrays explicitly suppress that phase's defaults.
167
+ Each detail or metadata entry is one line, so use `maxLines: 1` when putting the helper's result directly into one entry. The helper only shapes text; the protocol's byte and count limits still apply. An empty `details` or `metadata` array hides that phase's default content.
168
168
 
169
- `runTauClientToolCommand` reads the preparation, writes readiness and any running presentation, waits until the host accepts the call, then provides the standard execution context and writes the final result. It handles execution-environment request and cancellation framing and reacts to `SIGINT`, `SIGTERM`, and protocol input closure by aborting the handler.
169
+ `runTauClientToolCommand` reads the `prepare` frame, writes `ready` with any running presentation, waits until the host accepts the call, then runs your handler and writes the final result. It also handles execution-environment requests and their cancellation. On `SIGINT`, `SIGTERM`, or closed stdin, it aborts the handler.
170
170
 
171
171
  Reserve stdout for the helper's protocol. Write diagnostics to stderr. Return a string or `{ content, presentation? }` for success. Return `{ ok: false, error, presentation? }` for a structured tool failure. `content` may be a string or ordered text/image blocks; the helper wraps strings in text blocks.
172
172
 
173
173
  ### Version 5 frame reference
174
174
 
175
- Write each frame as one JSON object and a newline; unknown fields are invalid.
175
+ Write each frame as one JSON object followed by a newline. Unknown fields are invalid.
176
176
 
177
177
  Tau starts the exchange by writing:
178
178
 
179
- - `{ version: 5, type: "prepare", sessionId, agentId, callId, toolName, arguments }` exactly once. The identity fields are non-empty strings and `arguments` is the validated model input.
180
- - `{ version: 5, type: "execute" }` after accepting the command's ready frame. This authorizes execution.
179
+ - `{ version: 5, type: "prepare", sessionId, agentId, callId, toolName, arguments }` exactly once. The ID fields are non-empty strings, and `arguments` is the model's input after validation.
180
+ - `{ version: 5, type: "execute" }` after Tau accepts the command's `ready` frame. The command may not start work before this frame.
181
181
 
182
182
  The command writes:
183
183
 
184
184
  - `{ version: 5, type: "ready", presentation?: PresentationOverride }` exactly once after preparation.
185
- - `{ version: 5, type: "result", ok: true, content, presentation?: PresentationOverride }` or `{ version: 5, type: "result", ok: false, error, presentation?: PresentationOverride }` exactly once after authorization. `error` is a string. `content` is an ordered array of at most 1,024 text (`{ type: "text", text }`) or image (`{ type: "image", data, mimeType }`) blocks. At most 16 images are allowed: padded base64, at most 3.5 MiB decoded each, JPEG/PNG/WebP MIME types.
185
+ - `{ version: 5, type: "result", ok: true, content, presentation?: PresentationOverride }` or `{ version: 5, type: "result", ok: false, error, presentation?: PresentationOverride }` exactly once, after `execute`. `error` is a string. `content` is an ordered array of at most 1,024 text (`{ type: "text", text }`) or image (`{ type: "image", data, mimeType }`) blocks. At most 16 images are allowed: padded base64, at most 3.5 MiB decoded each, JPEG/PNG/WebP MIME types.
186
186
 
187
- During authorized execution, the command may write `{ version: 5, type: "exec", requestId, command, options }`. The non-empty `command` string runs in the session execution environment. `options` is required and may contain `args: string[]`, `env: Record<string, string>`, base64-encoded string `stdinBase64`, string `cwd`, positive integer `timeoutMs`, and positive integer `maxCaptureBytes`.
187
+ After `execute`, the command may write `{ version: 5, type: "exec", requestId, command, options }`. The non-empty `command` string runs in the session execution environment. `options` is required and may contain `args: string[]`, `env: Record<string, string>`, base64-encoded string `stdinBase64`, string `cwd`, positive integer `timeoutMs`, and positive integer `maxCaptureBytes`.
188
188
 
189
189
  Tau answers with the same `requestId` and either:
190
190
 
@@ -283,7 +283,7 @@ Make the file executable with `chmod +x`. Diagnostics and uncaught errors go to
283
283
 
284
284
  ### Implement a simple command tool in Bash
285
285
 
286
- A small command that needs only client-machine authority can also implement the handshake in Bash. This example depends on `jq` for safe JSON parsing and encoding:
286
+ A small command that only needs the client machine can also implement the handshake in Bash. This example depends on `jq` for safe JSON parsing and encoding:
287
287
 
288
288
  ```bash
289
289
  #!/usr/bin/env bash
@@ -332,7 +332,7 @@ Configure either executable as an argument-free command tool:
332
332
  }
333
333
  ```
334
334
 
335
- Both `ready.presentation` and `result.presentation` are optional partial objects with `subject`, `subjectWrap`, `details`, and `metadata`. The ready value applies while the call runs; the result value applies only to its terminal state. Omit either object, or any field within it, to use Tau's default for that phase. Empty `details` or `metadata` arrays suppress the corresponding default field. The script must emit `ready` before reading the authorization-bearing `execute` frame. Direct implementations can emit the same `exec` frames shown in the JavaScript example, but the TypeScript helper is preferable when the tool needs multiple target-environment requests, cancellation forwarding, or more involved protocol handling.
335
+ `ready.presentation` and `result.presentation` are optional partial objects with `subject`, `subjectWrap`, `details`, and `metadata`. The `ready` value applies while the call runs, and the `result` value applies to the finished card. Omit either object, or any field in it, to use Tau's default. An empty `details` or `metadata` array hides that default. The script must write `ready` before it reads the `execute` frame. Direct implementations can send the same `exec` frames as the JavaScript example, but the TypeScript helper is the better choice when the tool makes several execution-environment requests, needs to forward cancellation, or handles the protocol in more complex ways.
336
336
 
337
337
  The handler receives:
338
338
 
@@ -348,13 +348,13 @@ The handler receives:
348
348
  }
349
349
  ```
350
350
 
351
- `sessionId` routes the owning session. `agentId` identifies the owning agent for scratch-space and attribution purposes. `callId` identifies this invocation. Do not substitute one identity for another or cache context across calls.
351
+ `sessionId` identifies the session, `agentId` the agent that made the call (for scratch space and attribution), and `callId` this call. Never use one ID in place of another, and never reuse a context across calls.
352
352
 
353
- `signal` aborts when the assistant turn is interrupted, the host cancels or times out the tool, the owning client closes, the transport fails, or the protocol input closes. Pass it to all cancellable local work and to execution-environment calls.
353
+ `signal` aborts when the turn is interrupted, the host cancels or times out the tool, the client closes, the connection fails, or stdin closes. Pass it to all local work that can be cancelled and to execution-environment calls.
354
354
 
355
- ### Use the execution-environment facade
355
+ ### Run commands in the execution environment
356
356
 
357
- `context.executionEnvironment.exec()` runs a command in the session execution environment through the existing session execution boundary. It does not run on the client machine. Use it for agent-visible files, repository commands, and workspace state:
357
+ `context.executionEnvironment.exec()` runs a command in the session's execution environment, not on the client machine. Use it for the agent's files, repository commands, and workspace state:
358
358
 
359
359
  ```ts
360
360
  const result = await context.executionEnvironment.exec("git status --short", {
@@ -367,28 +367,28 @@ const result = await context.executionEnvironment.exec("git status --short", {
367
367
  return { content: result.output || "Working tree is clean." };
368
368
  ```
369
369
 
370
- The optional execution settings are `args`, `env`, binary `stdin`, `cwd`, `timeoutMs`, `maxCaptureBytes`, and `signal`. The result reports combined and split output, exit status, truncation, timeout, cancellation, and closing signal. Commands use the execution environment's login Bash behavior, path resolution, environment, and authority. `HOME` belongs to that environment and cannot be overridden through the session execution request.
370
+ The optional settings are `args`, `env`, binary `stdin`, `cwd`, `timeoutMs`, `maxCaptureBytes`, and `signal`. The result has combined and separate output, exit status, and whether output was truncated, timed out, or aborted, plus the closing signal. Commands run in the execution environment's login Bash, with its paths, environment, and permissions. `HOME` comes from that environment and cannot be overridden in the request.
371
371
 
372
- Up to eight execution requests may be active while their responses are being delivered. Each request ID is single-use. Cancelling one request does not cancel unrelated requests, although cancellation of the whole client-tool context aborts all of them.
372
+ Up to eight requests may be unresolved at once. Each request ID can be used only once. Cancelling one request does not affect the others, but cancelling the whole tool call aborts all of them.
373
373
 
374
374
  ## Implement code-mode client tools
375
375
 
376
- Tau exports two higher-level helpers for client tools that expose a bounded JavaScript API:
376
+ Tau exports two helpers for client tools that let the model run JavaScript against an API you define:
377
377
 
378
378
  - `createTauCodeModeClientTool` creates an in-process `TauSdkClientTool` for an SDK client.
379
379
  - `runTauCodeModeCommand` runs a code-mode definition as a command client-tool executable.
380
380
 
381
- Command tools need a parameters schema with required `code` string, optional `maxOutputTokens` integer (1–65,536), and no additional properties. SDK clients pass the helper's returned tool in `clientTools`.
381
+ Command tools need a parameters schema with a required `code` string, an optional `maxOutputTokens` integer (1–65,536), and no other properties. SDK clients pass the tool returned by the helper in `clientTools`.
382
382
 
383
- Both helpers supply invocation identities, cancellation, the execution-environment facade, `docs`, the API bridge, and output/truncation functions. Code is the truncated, character-wrapped card subject. Descriptions are caller input; the shared builder is optional.
383
+ Both helpers provide the call IDs, cancellation, the execution-environment API, `docs`, the bridge to your API, and output and truncation functions. The card subject is the submitted code, truncated and wrapped by character. You write the tool description; the shared description builder is optional.
384
384
 
385
385
  `await printImage(block)` emits ordered text/image blocks in `content`; see [tools](tools.md) for limits. `maxOutputTokens` defaults to 8,192 estimated tokens. Saving output requires a `persistOutput` callback.
386
386
 
387
- Disclose any additional process or network authority in the tool description.
387
+ If the tool can start processes or reach the network, say so in its description.
388
388
 
389
389
  ## Limits and failure behavior
390
390
 
391
- The command protocol is intentionally bounded:
391
+ The command protocol has fixed limits:
392
392
 
393
393
  - The command-to-client stdout NDJSON stream is limited to 512 frames and 192 MiB in total.
394
394
  - Each frame on that stdout stream is limited to 80 MiB.
@@ -396,35 +396,35 @@ The command protocol is intentionally bounded:
396
396
  - Captured stderr is limited to 1 MiB. Exceeding it terminates the command and fails the tool.
397
397
  - Execution-environment stdin is limited to 16 MiB decoded, and capture can be requested up to 24 MiB per execution.
398
398
  - At most eight execution requests may be unresolved concurrently.
399
- - Each client-tool presentation override is limited to 1 MiB in total. Its subject is limited to 256 KiB; metadata values to 16 KiB each; detail values to 256 KiB each; and detail and metadata collections to 1,024 entries each. These are safety limits, not recommended UI sizes. Tau preserves explicit values within those limits. Clients may use the exported helper when they want a concise preview.
399
+ - Each presentation override is limited to 1 MiB in total: the subject to 256 KiB, each metadata value to 16 KiB, each detail value to 256 KiB, and `details` and `metadata` to 1,024 entries each. These are safety limits, not recommended display sizes. Tau keeps values within them unchanged. Use the exported helper for a short preview.
400
400
 
401
- The configured `executionTimeoutMs` covers preparation and execution and defaults to 60 seconds. The host also requires the owning client to prepare and acknowledge a dispatched call promptly. Command executables emit readiness and any bounded running presentation before acknowledgement, then wait for Tau to authorize execution.
401
+ `executionTimeoutMs` covers both preparation and execution, and defaults to 60 seconds. The host also expects the client to prepare and accept each call promptly. A command writes `ready` and any running presentation first, then waits for Tau's `execute`.
402
402
 
403
- Tau starts each configured command in a detached process group. Cancellation sends termination to the group and escalates to `SIGKILL` after a short grace period, even if the original group leader exits first. The helper aborts pending execution-environment requests and stops accepting work when stdin closes.
403
+ Tau starts each command in its own process group. Cancellation sends a termination signal to the group and follows with `SIGKILL` after a short grace period, even if the main process has already exited. When stdin closes, the helper aborts pending execution-environment requests and accepts no more work.
404
404
 
405
- A successful protocol exchange must emit one version 5 ready frame, wait for the execute frame, emit one final version 5 result with `ok: true` or `ok: false`, and exit with status zero. An `ok: false` frame is a communicated tool failure; process and framing failures still use stderr and a nonzero exit. Missing or duplicate readiness, execution data before authorization, missing results, malformed framing, data after the result, reused execution request IDs, timeout, cancellation, excessive output, and protocol-limit violations fail the call.
405
+ A successful exchange writes one `ready` frame, waits for `execute`, writes one `result` frame with `ok: true` or `ok: false`, and exits with status zero. `ok: false` reports a tool failure the command handled. Process and framing failures still use stderr and a nonzero exit. The call fails on: a missing or repeated `ready`, output before `execute`, a missing result, malformed frames, output after the result, a reused request ID, timeout, cancellation, too much output, or any other limit violation.
406
406
 
407
407
  ## Disconnects, reconnects, and durability
408
408
 
409
- Client-tool execution is transient. Calls are not persisted for replay, and Tau does not move them to another client when the owner disappears.
409
+ Client tool calls are not saved. Tau never replays them and never moves them to another client when the owning client goes away.
410
410
 
411
- When an observing owner detaches, Tau removes its schemas from subsequent turns and cancels its active calls. Client close and terminal transport failure abort local handlers and targeted execution-environment commands. The client waits for active handlers to settle before close completes, but it does not send late results after the transport is terminal.
411
+ When the owning client detaches, Tau removes its tools from later turns and cancels its running calls. When the client closes or its connection fails for good, local handlers and the execution-environment commands they started are aborted. Closing waits for running handlers to finish, but no results are sent once the connection is gone.
412
412
 
413
- After reconnecting, the new client advertises its current tool definitions and must observe the session before they become available there. If another observer already owns one of those names, attachment fails on the collision. A reconnect does not resume a command process from the previous connection.
413
+ After reconnecting, the client offers its current tools again, and they become available once it observes the session. If another client already offers one of those names, the attachment fails. A reconnect never resumes a command process from the earlier connection.
414
414
 
415
415
  ## Security and troubleshooting
416
416
 
417
- Command client tools are trusted executables with the full environment and operating-system authority of the client process. Keep definitions in the user-owned global configuration, use narrow JSON Schemas, avoid shell interpolation, bound local work, honor cancellation, and return only data the model needs. A project allowlist is permission to select a global definition, not permission to provide executable code.
417
+ Command client tools are trusted executables with the client process's full environment and operating-system permissions. Keep definitions in your global configuration, use narrow JSON Schemas, avoid shell interpolation, limit local work, honor cancellation, and return only data the model needs. A project's `enabledClientTools` can only select global definitions; it can never supply code to run.
418
418
 
419
- The execution-environment facade is powerful in a different place. Validate every model-supplied argument before building commands, prefer fixed command names and argument arrays, avoid concatenating untrusted text into shell source, and use the context signal and bounded capture options.
419
+ The execution-environment API is just as powerful, on the session machine. Validate every argument from the model before building a command, prefer fixed command names and argument arrays, never concatenate untrusted text into shell code, and use the context signal and capture limits.
420
420
 
421
- When a tool is unexpectedly absent, check:
421
+ When a tool is missing, check:
422
422
 
423
423
  1. The owning client is currently observing the session.
424
- 2. The global definition is valid and in scope for the client-side `cwd`.
424
+ 2. The global definition is valid, and the client's `cwd` is inside home.
425
425
  3. The nearest `enabledClientTools` selection includes the exact name, or `defaultEnabled` applies.
426
426
  4. `--no-client-tools` is not active for the TUI.
427
427
  5. No other observer or host tool owns the same name.
428
428
  6. The client was restarted or reconnected after configuration changes.
429
429
 
430
- For execution failures, distinguish client-local process errors from `executionEnvironment.exec()` errors on the session machine. Check executable permissions, the client `PATH`, stderr diagnostics, timeout and framing limits, then the execution environment's own `cwd`, login startup files, and command availability. See [tools](tools.md), [security](security.md), and [troubleshooting](troubleshooting.md).
430
+ For failures, first tell apart errors from the local process and errors from `executionEnvironment.exec()` on the session machine. Check executable permissions, the client's `PATH`, stderr output, and timeout and framing limits. Then check the execution environment's `cwd`, login startup files, and whether the command exists there. See [tools](tools.md), [security](security.md), and [troubleshooting](troubleshooting.md).
@@ -1,27 +1,24 @@
1
1
  # Configuration reference
2
2
 
3
- `config.json` controls Tau defaults and integrations. The same schema is available at global and project levels, but a few fields are restricted to one scope and different components consume different results. This reference lists the current fields only.
3
+ `config.json` sets Tau defaults and integrations. Global and project levels use the same schema, but a few fields are allowed at only one level, and different parts of Tau read different fields.
4
4
 
5
- Read [configuration](configuration.md) first for discovery and precedence. In the tables below, **global** means `~/.config/tau/config.json` when that level is eligible, and **project** means an ancestor `.tau/config.json` discovered from the relevant `cwd`.
5
+ Read [configuration](configuration.md) first for discovery and precedence. In the tables below, **global** means `~/.config/tau/config.json` when that level applies, and **project** means a `.tau/config.json` found from the relevant `cwd` upward.
6
6
 
7
7
  ## Shipped defaults
8
8
 
9
- These are defaults built into this Tau version, not a dump of the effective configuration:
9
+ These are the defaults for fields you leave unset in this Tau version:
10
10
 
11
- | Behavior | Shipped default |
12
- | -------------------------------------- | -------------------- |
13
- | Default persona | `sonnet-5.5-coder` |
14
- | Default TUI theme | `gold` |
15
- | Built-in personas | Enabled |
16
- | Speech-to-text provider | Gemini |
17
- | Built-in diff tool code theme | `github-dark-dimmed` |
18
- | Command client tool timeout when unset | `60000` ms |
11
+ | Field | Default |
12
+ | ---------------------------------- | ------------------ |
13
+ | `defaultPersona` | `sonnet-5.5-coder` |
14
+ | `defaultTheme` | `gold` |
15
+ | `clientTools[].executionTimeoutMs` | `60000` ms |
19
16
 
20
- Project and global content can change which persona ids are available. A configured default must match an available persona or built-in theme; otherwise Tau reports a warning.
17
+ Project and global content can change which persona ids exist. A configured default must match an available persona or built-in theme. Otherwise Tau reports a warning.
21
18
 
22
19
  ## Field summary
23
20
 
24
- | Field | Type | Scope | Combination | Primary owner and apply boundary |
21
+ | Field | Type | Scope | Combination | Read by; when changes apply |
25
22
  | --- | --- | --- | --- | --- |
26
23
  | `apiKeys` | Object of string values | Global only | Provider-keyed map | Owning host or feature process; restart after changes |
27
24
  | `defaultPersona` | Non-empty string | Global, project | Most-specific wins | Session host; new session |
@@ -29,14 +26,14 @@ Project and global content can change which persona ids are available. A configu
29
26
  | `defaultTheme` | Non-empty string | Global, project | Most-specific wins | TUI client; client restart |
30
27
  | `clientTools` | Array of objects | Global only | One global definition list | Owning client; TUI restart or new Telegram session client |
31
28
  | `enabledClientTools` | String array | Project only | Most-specific project list | Owning client; TUI restart or new Telegram session client |
32
- | `subagents` | Object | Global, project | Field-wise, currently one selectable list | Session runtime; `/reload` or new session |
29
+ | `subagents` | Object | Global, project | Most-specific `launchModels` list | Session runtime; `/reload` or new session |
33
30
  | `modelSystemNotices` | String map | Global, project | Merge by model target | Session runtime; `/reload`, affects later inputs |
34
31
  | `flySprites` | Object | Global, project | Merge connection fields | Host startup; host restart |
35
32
  | `nook` | Object | Global, project | Most-specific complete object | Host tool runtime; `/reload` or new session |
36
33
  | `history` | Object | Global only | One global object | Host startup; host restart |
37
34
  | `mcpServers` | Object keyed by server name | Global and project | Merge names; nearer entry replaces | Host startup; host restart |
38
35
 
39
- Unknown fields are stripped without warnings. Wrong types and invalid known values produce warnings, and Tau continues with valid fields. A field at a forbidden scope is rejected.
36
+ Unknown fields are removed without a warning. Wrong types and invalid values produce warnings, and Tau continues with the valid fields. A field at a level where it is not allowed is rejected.
40
37
 
41
38
  ## Persona, model behavior, and context
42
39
 
@@ -50,17 +47,17 @@ A persona id, optionally followed by `:` and a reasoning level:
50
47
  }
51
48
  ```
52
49
 
53
- Allowed reasoning suffixes are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`. The persona id is matched exactly and case-sensitively during startup selection. The id must exist after built-in, global, and project personas are loaded.
50
+ Allowed reasoning suffixes are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`. The persona id must match exactly, including case, a persona that exists after built-in, global, and project personas are loaded.
54
51
 
55
- `defaultPersona` selects a new session when no CLI or session-creation override is supplied. Reloading an existing session retains its current persona id when possible. See [personas](personas.md).
52
+ `defaultPersona` sets the persona of a new session unless a CLI flag or creation request chooses another. Reloading an existing session keeps its current persona when it still exists. See [personas](personas.md).
56
53
 
57
54
  ### `subagents`
58
55
 
59
- The top-level subagent configuration currently accepts one optional field:
56
+ `subagents` accepts one optional field:
60
57
 
61
- | Nested field | Type | Contract |
62
- | -------------- | ------------ | -------------------------------------------- |
63
- | `launchModels` | String array | Allowlist for launch overrides for subagents |
58
+ | Nested field | Type | Contract |
59
+ | --- | --- | --- |
60
+ | `launchModels` | String array | Models an agent may choose when it starts a subagent |
64
61
 
65
62
  Each entry must use `<provider>/<model>:<effort>` and resolve against the merged model catalog:
66
63
 
@@ -75,7 +72,7 @@ Each entry must use `<provider>/<model>:<effort>` and resolve against the merged
75
72
  }
76
73
  ```
77
74
 
78
- A more-specific list replaces the broader list. The worker’s instructions and tools are inherited from the main persona; custom worker definitions are not supported. See [subagents](subagents.md).
75
+ A more specific list replaces the broader one. Subagents inherit instructions and tools from the main persona. Custom subagent definitions are not supported. See [subagents](subagents.md).
79
76
 
80
77
  ### `modelSystemNotices`
81
78
 
@@ -89,9 +86,9 @@ A map from exact `<provider>/<model>` targets to non-empty notice text:
89
86
  }
90
87
  ```
91
88
 
92
- Provider ids must be known, and model ids must resolve against the bundled and refreshed model catalog. Entries merge by normalized target, with the more-specific value winning. Tau prepends the matching notice to later committed main-session and subagent user input. Ephemeral agents and maintenance model calls do not receive a newly resolved notice.
89
+ Provider ids must be known, and model ids must exist in the model catalog. Entries merge by normalized target, and the more specific value wins. Tau adds the matching notice to the start of later user input in the main session and in subagents. Ephemeral agents and maintenance model calls do not receive a newly resolved notice.
93
90
 
94
- Use this for model-specific operational guidance, not for persona behavior that belongs in a persona file. See [models](models.md) and [personas](personas.md).
91
+ Use notices for guidance that applies to one model. Behavior that belongs to a persona goes in the persona file. See [models](models.md) and [personas](personas.md).
95
92
 
96
93
  ## Credentials and service selection
97
94
 
@@ -111,9 +108,9 @@ A map from provider or feature id to a string credential:
111
108
  }
112
109
  ```
113
110
 
114
- The global map accepts arbitrary non-empty provider names and string values. Values are trimmed when consumed; an empty string is not a usable credential.
111
+ The map accepts any non-empty provider name with a string value. Values are trimmed when used, and an empty string does not count as a credential.
115
112
 
116
- For model requests and feature helpers, provider-supported environment credentials take precedence over global `apiKeys`. Provider-supported ambient authentication remains available. Project `apiKeys` values are rejected. Codex managed OAuth uses the explicitly active account separately. See [credentials](credentials.md).
113
+ For model requests and features, a provider's environment variable wins over the same provider's entry in `apiKeys`. Other authentication a provider supports without a key still works. `apiKeys` in a project file is rejected. Codex OAuth does not use this map; it uses the active stored account. See [credentials](credentials.md).
117
114
 
118
115
  ### `speech`
119
116
 
@@ -137,15 +134,15 @@ For terminal recording, `recordingShortcut` replaces Ctrl+Y. Its required `key`
137
134
  }
138
135
  ```
139
136
 
140
- A double tap must arrive within 300 ms. For printable double-tap bindings, an unmatched first tap inserts the character after that delay; another key inserts it immediately before processing the new input. Single-press bindings reserve the character. Bracketed paste never triggers recording. Keyboard auto-repeat can count as repeated taps. Recording shortcuts apply only to the TUI, not Telegram.
137
+ A double tap must arrive within 300 ms. For printable double-tap bindings, an unmatched first tap inserts the character after that delay; another key inserts it immediately before processing the new input. A single-press binding reserves its character, so it can no longer be typed. Bracketed paste never triggers recording. Keyboard auto-repeat can count as repeated taps. Recording shortcuts apply only to the TUI, not Telegram.
141
138
 
142
- Without an override, Tau looks up Maisie (`QtY3JBOUKEB5xzrRfOKc`) before synthesis and tries Caleb (`AaOhDHYJ1XLZk74lXhdE`) only if ElevenLabs reports that Maisie was not found. If neither is available, speech fails. A configured voice is used exclusively: an unavailable custom voice is an error, not a request to use a default.
139
+ Without an override, Tau looks up Maisie (`QtY3JBOUKEB5xzrRfOKc`) before synthesis and tries Caleb (`AaOhDHYJ1XLZk74lXhdE`) only if ElevenLabs reports that Maisie was not found. If neither is available, speech fails. A configured voice is the only voice Tau tries. If it is unavailable, speech fails without falling back to a default.
143
140
 
144
- Voice lookup authentication, permission, rate-limit, and network errors do not trigger fallback. Successful metadata lookup fixes the voice for the entire reply; it does not guarantee synthesis permission. Synthesis failures never switch voices or automatically retry a potentially billable request.
141
+ Authentication, permission, rate-limit, and network errors during voice lookup do not trigger the fallback. Once lookup succeeds, that voice is used for the whole reply, although synthesis can still be refused. Synthesis failures never switch voices, and Tau never retries synthesis automatically because each request may be billed.
145
142
 
146
143
  Speech uses Eleven v4 Turbo, the delivery note `[Brisk but relaxed, speaking naturally to a colleague]`, and a 1.15× tempo adjustment. GPT-6 Luna rewrites the text with reasoning disabled before ElevenLabs synthesis, so both OpenAI and ElevenLabs credentials are required. Voice Library API access may require a paid ElevenLabs plan, and shared voices can become unavailable.
147
144
 
148
- The TUI reads this setting from its client-side configuration, including during remote attachment. Telegram reads it from the runner's startup configuration, not individual session workspaces. Restart the respective process after changes. This setting does not affect the explicit voices supplied to `tau tool speech-generate`.
145
+ The TUI reads this setting from its own client configuration, also when attached to a remote host. Telegram reads it from the runner's startup configuration, not from session workspaces. Restart the respective process after changes. This setting does not affect the explicit voices supplied to `tau tool speech-generate`.
149
146
 
150
147
  ### `nook`
151
148
 
@@ -168,7 +165,7 @@ Connection details for one existing Nook deployment:
168
165
  }
169
166
  ```
170
167
 
171
- Tau normalizes the domain to a lowercase hostname. A non-empty value from `accessClientSecretEnv` takes precedence over `accessClientSecret`. The `nook` tool is available only when both the active persona allows it and effective configuration contains this object. See [Nook](nook.md).
168
+ Tau normalizes the domain to a lowercase hostname. A non-empty value from `accessClientSecretEnv` wins over `accessClientSecret`. The `nook` tool is available only when the active persona allows it and the effective configuration contains this object. See [Nook](nook.md).
172
169
 
173
170
  ### `history`
174
171
 
@@ -189,11 +186,17 @@ A global-only remote history target:
189
186
  }
190
187
  ```
191
188
 
192
- Credential precedence is `TAU_HISTORY_API_KEY`, then the variable named by `apiKeyEnv`, then `apiKey`. Configuring an endpoint without an available key prevents the host service from starting. Without `history`, transcript storage and queries remain machine-local. See [history](history.md).
189
+ Tau uses the first key it finds: `TAU_HISTORY_API_KEY`, then the variable named by `apiKeyEnv`, then `apiKey`. If `history` is configured but no key is available, the host fails to start. Without `history`, history is stored and searched only on the host machine. See [history](history.md).
193
190
 
194
191
  ### `mcpServers`
195
192
 
196
- MCP servers are resolved at host startup from the global `~/.config/tau/config.json` and ancestor/project `.tau/config.json` layers for the host's launch directory. Server names accumulate across layers; a nearer definition replaces the entire same-named entry, including credentials. Use `enabled: false` to disable an inherited server. All sessions on that host share the resolved definitions, and subagents inherit their parent's access even in another working directory. Session execution-environment configuration does not contribute servers. Restart the host after changing definitions or credentials; `/reload` does not reload servers.
193
+ The host reads MCP servers once at startup, from the global config and the project levels of the directory where the host was launched.
194
+
195
+ - Server names add up across levels. A nearer definition replaces the whole entry with the same name, including credentials.
196
+ - Set `enabled: false` to turn off an inherited server.
197
+ - All sessions on the host share the same servers. Subagents have their parent's access, even in another working directory.
198
+ - Configuration in a session's execution environment never adds servers.
199
+ - Restart the host after changing definitions or credentials. `/reload` does not reload servers.
197
200
 
198
201
  ```json
199
202
  {
@@ -219,11 +222,11 @@ Server names use letters, digits, `_`, and `-`. Every entry requires an explicit
219
222
  - `http`: requires an HTTP(S) `url` without embedded username/password; accepts optional string-valued `headers`. This is streamable HTTP, not the legacy SSE transport.
220
223
  - Both accept `enabled` (default `true`), `timeoutMs` for tool calls and resource reads (integer from 1 to 900,000, default 300,000), and `discoveryTimeoutMs` for connection startup and discovery requests (integer from 1 to 60,000, default 30,000). The outer MCP code-mode program has a 15-minute deadline. All calls remain interruptible.
221
224
 
222
- Stdio executables run directly without a shell. Bare commands resolve through the host's `PATH`. Commands containing `/` and relative `cwd` values resolve from the directory owning the defining config layer; `~/` resolves from host home. An omitted `cwd` defaults to the defining layer's directory. Arguments are literal: Tau does not interpolate them or expand shell syntax.
225
+ Stdio executables run directly, without a shell. Bare commands resolve through the host's `PATH`. Commands that contain `/`, and relative `cwd` values, resolve from the directory of the config level that defines the server. `~/` resolves from the host user's home. Without `cwd`, the server starts in the defining level's directory. Arguments are passed literally, with no interpolation or shell expansion.
223
226
 
224
- Values in `env` and `headers` can reference host environment variables with `${NAME}`. Missing variables fail connection setup. Command substitution is not supported. Stdio servers inherit the host environment, with `env` overriding matching names. Keep secrets in the host environment rather than committing them to JSON.
227
+ Values in `env` and `headers` can reference host environment variables as `${NAME}`. A missing variable makes the connection fail. Command substitution is not supported. Stdio servers inherit the host environment, and `env` overrides matching names. Keep secrets in the host environment instead of committing them to JSON.
225
228
 
226
- Invalid entries are skipped with diagnostics while valid siblings remain configured. OAuth sign-in, MCP prompts, subscriptions, elicitation, sampling, execution-environment servers, and user approval dialogs are not supported. See [tools](tools.md#mcp) for discovery, calls, and result handling.
229
+ An invalid entry is skipped with a diagnostic, and the other servers stay configured. OAuth sign-in, MCP prompts, subscriptions, elicitation, sampling, execution-environment servers, and user approval dialogs are not supported. See [tools](tools.md#capabilities) for discovery, calls, and result handling.
227
230
 
228
231
  ## TUI presentation and diff review
229
232
 
@@ -237,7 +240,7 @@ The exact, case-sensitive id of a built-in theme. The shipped default is `gold`:
237
240
  }
238
241
  ```
239
242
 
240
- The attached TUI uses its client-local configuration. `/theme:<id>` changes the current client only and is not persisted into the session. See [TUI](tui.md).
243
+ An attached TUI uses its own client configuration. `/theme:<id>` changes only the current client and is not saved in the session. See [TUI](tui.md).
241
244
 
242
245
  ## Command client tools
243
246
 
@@ -276,9 +279,9 @@ A global-only array of commands exposed as client-provided tools:
276
279
  }
277
280
  ```
278
281
 
279
- Unknown properties inside `parameters` are preserved as part of the configured schema; unknown fields elsewhere in each tool object are stripped. A command containing `/` resolves from home because definitions are global. The command executes directly on the owning client without a shell and participates in Tau's bounded client-tool protocol.
282
+ Unknown properties inside `parameters` are kept as part of the schema. Unknown fields elsewhere in a tool object are removed. Because definitions are global, a command that contains `/` resolves from home. The command runs directly on the client, without a shell.
280
283
 
281
- TUI startup flag `--no-client-tools` disables both configured command tools and built-in TUI client tools. See [client tools](client-tools.md).
284
+ The TUI flag `--no-client-tools` disables both configured command tools and the TUI's built-in client tools. See [client tools](client-tools.md).
282
285
 
283
286
  ### `enabledClientTools`
284
287
 
@@ -290,13 +293,13 @@ A project-only exact allowlist of names from global `clientTools`:
290
293
  }
291
294
  ```
292
295
 
293
- Names are trimmed and duplicates removed. Unknown names are silently ignored. An empty list selects none. If the field is absent at every project level, Tau selects tools with `defaultEnabled: true`.
296
+ Names are trimmed and duplicates removed. Unknown names are ignored without a warning. An empty list selects no tools. If no project level sets the field, Tau selects the tools with `defaultEnabled: true`.
294
297
 
295
- The most-specific project list replaces broader project lists. Project configuration cannot define executable client tool commands.
298
+ The most specific project list replaces broader ones. Project configuration cannot define client tool commands.
296
299
 
297
300
  ## Hosted execution environments
298
301
 
299
- These fields configure resolvers owned by a host process. They do not provision Sprites. A client creating a session supplies an existing environment identity and `cwd` that references one of these host-known entries. See [remote sessions](remote-sessions.md).
302
+ These fields tell a host how to reach hosted execution environments. They do not create Sprites. A client that creates a session names an existing environment and a `cwd` on it, and the host connects using these settings. See [remote sessions](remote-sessions.md).
300
303
 
301
304
  ### `flySprites`
302
305
 
@@ -318,4 +321,4 @@ One configured connection:
318
321
  | `tokenEnv` | Non-empty string | No | Host environment variable used when `token` is absent |
319
322
  | `home` | Non-empty string | No | Sprite home, default `/home/sprite` |
320
323
 
321
- A usable token is required when the host resolves a Sprite. Select an existing Sprite by name. More-specific connection fields replace broader values.
324
+ The host needs a usable token when it connects to a Sprite. Sessions select an existing Sprite by name. More specific connection fields replace broader ones.