@markusylisiurunen/tau 0.3.49 → 0.3.50

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 (57) hide show
  1. package/README.md +22 -908
  2. package/dist/core/commands/registry.js +4 -4
  3. package/dist/core/commands/registry.js.map +1 -1
  4. package/dist/core/personas.js +19 -10
  5. package/dist/core/personas.js.map +1 -1
  6. package/dist/core/runtime/runtime_bootstrap.js +14 -9
  7. package/dist/core/runtime/runtime_bootstrap.js.map +1 -1
  8. package/dist/core/static/tau_docs/client-tools.md +228 -0
  9. package/dist/core/static/tau_docs/config-reference.md +422 -0
  10. package/dist/core/static/tau_docs/configuration.md +210 -0
  11. package/dist/core/static/tau_docs/credentials.md +200 -0
  12. package/dist/core/static/tau_docs/getting-started.md +140 -0
  13. package/dist/core/static/tau_docs/history.md +163 -0
  14. package/dist/core/static/tau_docs/index.md +40 -0
  15. package/dist/core/static/tau_docs/manifest.json +28 -0
  16. package/dist/core/static/tau_docs/models.md +198 -0
  17. package/dist/core/static/tau_docs/node-sdk.md +399 -0
  18. package/dist/core/static/tau_docs/nook.md +264 -0
  19. package/dist/core/static/tau_docs/ownership-and-scope.md +104 -0
  20. package/dist/core/static/tau_docs/personas.md +199 -0
  21. package/dist/core/static/tau_docs/prompts-and-project-context.md +181 -0
  22. package/dist/core/static/tau_docs/remote-sessions.md +274 -0
  23. package/dist/core/static/tau_docs/security.md +188 -0
  24. package/dist/core/static/tau_docs/session-protocol-methods.md +577 -0
  25. package/dist/core/static/tau_docs/session-protocol.md +265 -0
  26. package/dist/core/static/tau_docs/sessions.md +223 -0
  27. package/dist/core/static/tau_docs/skills.md +176 -0
  28. package/dist/core/static/tau_docs/subagents.md +203 -0
  29. package/dist/core/static/tau_docs/telegram.md +342 -0
  30. package/dist/core/static/tau_docs/tools.md +203 -0
  31. package/dist/core/static/tau_docs/troubleshooting.md +292 -0
  32. package/dist/core/static/tau_docs/tui.md +224 -0
  33. package/dist/core/telegram/session_manager.js +4 -3
  34. package/dist/core/telegram/session_manager.js.map +1 -1
  35. package/dist/core/tools/catalog.js +3 -1
  36. package/dist/core/tools/catalog.js.map +1 -1
  37. package/dist/core/tools/presentation.js +12 -1
  38. package/dist/core/tools/presentation.js.map +1 -1
  39. package/dist/core/tools/tau_docs.js +115 -0
  40. package/dist/core/tools/tau_docs.js.map +1 -0
  41. package/dist/core/tools/tool_names.js +8 -0
  42. package/dist/core/tools/tool_names.js.map +1 -1
  43. package/dist/core/utils/repository.js +19 -0
  44. package/dist/core/utils/repository.js.map +1 -1
  45. package/dist/core/version.js +1 -1
  46. package/dist/host/client_tool_broker.js +3 -18
  47. package/dist/host/client_tool_broker.js.map +1 -1
  48. package/dist/protocol/session_protocol.d.ts +1 -0
  49. package/dist/protocol/session_protocol.js +2 -1
  50. package/dist/protocol/session_protocol.js.map +1 -1
  51. package/dist/tui/session_chat_app.js +1 -0
  52. package/dist/tui/session_chat_app.js.map +1 -1
  53. package/dist/tui/session_chat_controller.js +13 -13
  54. package/dist/tui/session_chat_controller.js.map +1 -1
  55. package/dist/tui/session_creation_attributes.js +3 -3
  56. package/dist/tui/session_creation_attributes.js.map +1 -1
  57. package/package.json +2 -2
@@ -0,0 +1,292 @@
1
+ # Troubleshooting
2
+
3
+ Tau failures usually become straightforward once the failing component is identified. The same path can mean a laptop path, a host path, or an execution-environment path, and the same configuration field can require a session reload, client restart, host restart, or new session.
4
+
5
+ Work from the observed symptom. Keep checks narrow, preserve durable state, and avoid dumping configuration, environments, snapshots, databases, or transcripts into diagnostics.
6
+
7
+ ## Start with the installed command and owner
8
+
9
+ Use the help shipped with the executable that is actually failing:
10
+
11
+ ```sh
12
+ tau --help
13
+ tau attach --help
14
+ tau auth --help
15
+ tau history --help
16
+ tau nook --help
17
+ tau telegram --help
18
+ ```
19
+
20
+ Help reflects that installed binary. The `tau_docs` corpus reflects the installed host binary. An attached TUI, remote host, and deployed History or Nook service can run different versions, so do not assume host documentation describes an older client's flags or a separately deployed service's behavior.
21
+
22
+ For a local startup, `tau --debug` resolves configuration and content from the current directory, prints warnings and effective catalog information, then exits without opening the TUI:
23
+
24
+ ```sh
25
+ cd /path/that-should-own-the-session
26
+ tau --debug
27
+ ```
28
+
29
+ Add `--persona <exact-id>` when checking one persona. Debug output includes complete model-facing project context. Keep it private and never use it as a convenient configuration dump. It cannot inspect a running remote host, a hosted target, or an attached client's effective state.
30
+
31
+ Inside the TUI, `/help` shows current commands, loaded skills, and injected context-file paths. It is useful for current session visibility, while `/reload` is the operation that asks the host to recollect runtime content.
32
+
33
+ ## A configuration change has no effect
34
+
35
+ Identify the consumer in [ownership and scope](ownership-and-scope.md). Session content and host tools come from the execution environment and host. Themes, speech, diff launchers, and TUI client tools come from the client. History and environment resolvers are host-owned. Telegram routing and workspaces come from its separate runner configuration.
36
+
37
+ Confirm that component's machine, `cwd`, home, and tool path. In an attached session these safe checks report the execution environment, not the laptop:
38
+
39
+ ```text
40
+ !!pwd
41
+ !!printf '%s\n' "$HOME"
42
+ !!command -v git
43
+ ```
44
+
45
+ A global Tau level is omitted when the relevant `cwd` is outside that component's home. Tau applies every recognized ancestor level using field-specific rules. Check warnings and [configuration](configuration.md) for these common causes:
46
+
47
+ - a nearer scalar, object, or `enabledClientTools` list replaced the broader value;
48
+ - a merging field kept keys from another level;
49
+ - a relative path resolved from the level that declared it;
50
+ - an invalid nearer value was skipped, leaving a broader value effective; or
51
+ - a misspelled unknown field was silently stripped.
52
+
53
+ Validate JSON without displaying it:
54
+
55
+ ```sh
56
+ node -e 'JSON.parse(require("node:fs").readFileSync(process.argv[1], "utf8"))' \
57
+ /path/to/config.json
58
+ ```
59
+
60
+ Use `tau --debug` from the intended directory for a new local startup. For a live session, run `/reload` while idle and read every warning.
61
+
62
+ | Change owner | Apply boundary |
63
+ | --- | --- |
64
+ | Current session runtime content | `/reload` while idle |
65
+ | Theme, diff, speech, or TUI client tools | Restart `tau` or `tau attach` |
66
+ | Host environment, History, resolver, listener, or binary | Restart the host |
67
+ | Default persona or environment identity | Create a new session if it must change |
68
+ | Telegram config, routing, speech, or workspaces | Restart the runner |
69
+
70
+ ## `/reload` is unavailable, refused, or insufficient
71
+
72
+ `/reload` is a TUI command backed by the current session. It is unavailable in a plain shell and is refused while a turn or conflicting session operation is active. Wait for the turn to settle or interrupt it deliberately, then run the command again.
73
+
74
+ Reload updates runtime configuration, `models.json`, personas, prompts, skills, `AGENTS.md` context, and the host-tool registry for future turns. It does not:
75
+
76
+ - alter the execution environment's kind, identity, `cwd`, or home;
77
+ - rebuild an attached client's themes, diff launcher, speech configuration, or advertised tools;
78
+ - reread environment variables into an already-running process;
79
+ - rebuild host-wide History or hosted-environment resolvers;
80
+ - update executable code or built-in documentation; or
81
+ - reconfigure an already spawned subagent thread.
82
+
83
+ A logical turn captures its persona, model settings, tools, and policies when it starts. Reasoning changes and reloads do not change that active turn or its steering continuations. A queued message captures current state only when it later starts. If behavior appears stale, let one independently submitted turn begin after reload before concluding that the change failed.
84
+
85
+ Protocol and SDK clients can call `session.reload` directly, but the same idle and ownership rules apply.
86
+
87
+ ## A persona, prompt, skill, model, or theme is missing
88
+
89
+ Session resources come from the execution environment; themes come from the TUI client. Check the exact discovery path and `/reload` warning.
90
+
91
+ ### Persona
92
+
93
+ For a new local session, run `tau --debug --persona <exact-id>`. The Markdown filename must match `id`; `provider` and `model` are required; `extends` can name only a shipped built-in. Startup IDs are exact and case-sensitive. If built-ins are disabled, at least one custom persona must remain. See [personas](personas.md).
94
+
95
+ ### Prompt
96
+
97
+ Run `/reload` after changing prompt metadata. Bodies load lazily, so an invocation can fail if the execution-environment file later becomes unreadable or invalid. `/prompt:<id>` only fills the editor; it does not submit. See [prompts and project context](prompts-and-project-context.md).
98
+
99
+ ### Skill
100
+
101
+ Use `/help` to inspect loaded skills. A skill needs uppercase `SKILL.md`, valid frontmatter, a lowercase-dash name, and a matching directory name. `.agents/skills` wins over `.tau/skills` at one level; nearer levels win overall.
102
+
103
+ The active persona can still exclude a discovered skill, and its trigger determines when the agent opens it. `allowed-tools` is currently ignored. See [skills](skills.md).
104
+
105
+ ### Model
106
+
107
+ Providers must be known and model IDs are exact and case-sensitive. Check warnings for malformed `models.json`, invalid metadata, or unknown provider/model references. `tau --debug --persona <id>` shows local resolution; a small request proves endpoint, account, and credential access. Reload overlays while idle. See [models](models.md).
108
+
109
+ ### Theme
110
+
111
+ Check the client `cwd` and home, exact filename ID, colors, `disableBuiltinThemes`, and `defaultTheme`. `/reload` does not reload themes. Restart the TUI, then select `/theme:<id>`. A remote host's themes do not supply an attached client's theme.
112
+
113
+ ## A tool or subagent is unavailable
114
+
115
+ Classify the missing capability before changing configuration.
116
+
117
+ For a persona-controlled host tool, inspect the active persona's exact `tools` list. An explicit list replaces defaults. Run `tau --debug --persona <id>` for a new local session or reload the current session while idle. Credentials can make a selected tool fail, but usually do not remove its schema. Nook is the exception: it also requires effective `nook` configuration.
118
+
119
+ For a subagent, check all four gates:
120
+
121
+ 1. The active persona defines or enables that subagent name.
122
+ 2. The main persona exposes `spawn_agent` and any other needed supervision tools.
123
+ 3. A requested launch model exactly matches the subagent's allowlist.
124
+ 4. Fewer than eight subagent runs are currently active.
125
+
126
+ An already spawned thread keeps its captured model, tools, and working directory after reload. Recovery does not restore subagent threads, so old agent IDs cannot receive follow-ups after a host restart. Use `list_agents` to inspect live records. See [subagents](subagents.md).
127
+
128
+ For `tau_docs` or main-session goal tools, absence indicates a host runtime or version problem, not a persona list. Confirm the host package and restart it.
129
+
130
+ ## A command client tool is missing or fails
131
+
132
+ A configured command client tool exists only while its owning client observes the session. Check the client side in this order:
133
+
134
+ 1. The definition is in eligible global configuration on the client machine.
135
+ 2. The entry is valid and has a root object JSON Schema.
136
+ 3. The nearest project `enabledClientTools` includes the exact case-sensitive name, or `defaultEnabled` applies because no project selection exists.
137
+ 4. The TUI was not started with `--no-client-tools`.
138
+ 5. No other observer or host tool already owns the same name.
139
+ 6. The client was restarted or reconnected after the configuration change.
140
+
141
+ Unknown selection names are ignored. An empty `enabledClientTools` intentionally selects none. `/reload` does not re-advertise client tools.
142
+
143
+ For execution failures, decide which half failed. “Command client tool” launch, permission, `PATH`, timeout, stderr, framing, and nonzero-exit errors belong to the client machine. Errors from `executionEnvironment.exec` belong to the session target. The executable runs directly, not through a shell, and inherits the client process's current directory and environment unchanged.
144
+
145
+ A detached owning client makes its tools unavailable and cancels active calls. Reconnect does not resume the previous process. See [client tools](client-tools.md).
146
+
147
+ ## A credential is reported missing or rejected
148
+
149
+ Find the process making the request:
150
+
151
+ | Operation | Owner |
152
+ | ------------------------------------------- | ------------ |
153
+ | Model, host `web`, `history`, or `nook` | Host |
154
+ | `/listen`, `/speak`, or TUI client tool | Client |
155
+ | Telegram bot or transcription | Runner |
156
+ | `tau nook`, `tau history`, or PDF unpack | Invoking CLI |
157
+ | Cloudflare Sandbox or Fly Sprite resolution | Host startup |
158
+
159
+ A laptop variable does not update a remote host. Environment changes require an owner restart. Runtime `apiKeys` can reload, but only from an eligible execution-environment level and subject to feature precedence.
160
+
161
+ Never print the secret, environment, or whole configuration. Privately confirm the expected source, read the missing-credential message, and make one small request. See [credentials](credentials.md). If failure followed a project change, inspect its `apiKeys`, model endpoint/headers, and persona; a nearer key can replace ambient authentication.
162
+
163
+ ## A Codex account cannot be selected
164
+
165
+ Run this on the session host, not an attached client:
166
+
167
+ ```sh
168
+ tau auth list
169
+ ```
170
+
171
+ The output shows stored account identities, enabled state, credential refresh health, usage windows, and current preference without showing tokens.
172
+
173
+ Use the supported commands for the condition shown:
174
+
175
+ ```sh
176
+ tau auth login codex
177
+ tau auth enable codex --account developer@example.com
178
+ tau auth disable codex --account developer@example.com
179
+ tau auth logout codex --account developer@example.com
180
+ ```
181
+
182
+ Re-login when credentials are expired or refresh failed. Enable an intentionally disabled account only after confirming that it should be usable. A forced `TAU_CODEX_ACCOUNT` must match an enabled stored account by email or ID and disables automatic failover. Changing that variable requires a host restart.
183
+
184
+ Account selection is stable within a session. After a quota error, a later request can choose another usable account unless selection is forced. Do not edit `~/.config/tau/auth.json`; the auth commands coordinate updates and preserve permissions.
185
+
186
+ ## Bash prints unexpected text, prompts, or reports no TTY
187
+
188
+ Every Tau command uses a fresh non-interactive login Bash in the execution environment. Reproduce startup safely with `!!bash -lc 'printf ok'`. Check `/etc/profile`, the first user login file, `BASH_ENV`, and any `.bashrc` sourced from them. A file that prints, reads stdin, prompts, runs terminal setup, or exits affects every command.
189
+
190
+ Use automation-safe command flags. Configure credentials before invocation, set Git and SSH up for noninteractive access, and avoid editors or tools that require terminal control. Shell aliases, variables, `cd`, and functions do not persist between calls, so pass `workingDirectory` or use a complete command each time.
191
+
192
+ For stdio or SSH attachment, stdout from `tau rpc` is protocol-only. A login banner or wrapper message on stdout can look like malformed JSON, an unsupported message, or a timeout waiting for the ready message. Remove it or send diagnostics to stderr. Running the remote command directly can reveal startup diagnostics, but do not copy protocol output or secrets into reports.
193
+
194
+ Local command sanitization removes inherited credential-shaped variable names. If a target command needs authentication, use the tool's own secure noninteractive credential mechanism rather than broad environment forwarding. Hosted targets use their own environment.
195
+
196
+ ## WebSocket attachment is unauthorized or unsafe
197
+
198
+ Confirm that client and server use the same token source. `--auth-token` wins when supplied; otherwise `TAU_WS_AUTH_TOKEN` can supply either process. Check presence and process configuration without logging the value.
199
+
200
+ Tau sends the token as the `tau_token` WebSocket query parameter. A reverse proxy must preserve the query string and WebSocket upgrade. It should also redact query strings from logs. An authentication failure currently appears to clients as an unexpected WebSocket close, so correlate it with the server or proxy's redacted status logs.
201
+
202
+ Tau does not terminate TLS. Use `wss://` behind a trusted TLS reverse proxy, or keep the server on loopback and use an SSH tunnel. An unauthenticated listener is acceptable only within a boundary where every reachable client is trusted with full session access.
203
+
204
+ If attachment reports an unsupported protocol version or invalid peer message, upgrade the host and client to the same Tau release and restart both. Do not downgrade a host that may have written newer session documents.
205
+
206
+ ## Remote attach uses the wrong directory or cannot create a session
207
+
208
+ For `tau attach --new`, `--cwd` must be an absolute path inside the selected execution environment. With the default local execution kind it is a host path, not a path on the attaching machine. Tau does not create the directory, clone a repository, or infer remote repository attributes.
209
+
210
+ For Cloudflare Sandbox or Fly Sprite creation, verify on the host that:
211
+
212
+ - the named bridge or API id exists in startup configuration;
213
+ - its credential is available to the host process;
214
+ - the named sandbox or Sprite already exists;
215
+ - the absolute target `cwd` exists there; and
216
+ - the configured execution home matches the intended target account.
217
+
218
+ Changing a resolver definition or credential requires a host restart. `/reload` cannot replace a session's environment identity or repair a missing target.
219
+
220
+ Without `--session` or `--new`, attach needs a TTY for its selector. In automation, pass one explicitly. Normal local startup `--persona` flags are not attach options; choose the host default for new sessions or switch the attached session with `/persona:<id>` while idle.
221
+
222
+ If an SSH attach closes when the TUI exits, that is expected: the attachment owns its one-shot `tau rpc` host. Use `tau serve` when work must continue after disconnect. See [remote sessions](remote-sessions.md).
223
+
224
+ ## A session is missing, interrupted, or will not recover
225
+
226
+ A selector shows only sessions this host can load and restore. Confirm its machine, OS user, home, Tau version, resolver configuration, and target still match the creator. Another user's `~/.config/tau/sessions` is a different store. Restore missing bridge/API definitions, credentials, local directory, sandbox, or Sprite. Never edit session JSON to substitute a target or `cwd`.
227
+
228
+ Recovery returns idle, aborts unfinished turns, cancels running maintenance, removes live subagents, and blocks an active goal. Review the last assistant and tools, then safely check `!!pwd` and `!!git status --short`. Resume a goal only after understanding the stop. Retry continues current history without rerunning completed tools automatically.
229
+
230
+ A WebSocket client disconnect does not interrupt the long-running host; server shutdown does. Closing a local TUI or stdio attachment shuts down its owned host, so interrupted recovery is expected.
231
+
232
+ A newer storage version requires that Tau version or later. For invalid JSON, snapshot, or ID errors, preserve the file and exact error, stop competing hosts, and investigate normal recovery. Do not edit or delete it first. Newer Tau migrates supported older documents automatically.
233
+
234
+ ## History is unavailable, empty, or not current
235
+
236
+ History is host-owned and independent of session snapshots. Its default database is in the host home, and a failure warns without stopping the session. Check the host user and home, permissions, free space, Node version, and unexpected competing processes. Restart the host after correction. Do not open, edit, replace, or delete SQLite files as an initial repair.
237
+
238
+ The active persona must select `history`, and its first call prints tool documentation. If the tool is missing, fix the persona and reload. Use it only when the user or another active instruction directly requests historical transcripts.
239
+
240
+ With remote History configured, queries use the remote collection while local SQLite remains the durable first write and outbox. Replication is asynchronous. An empty result can mean the wrong host/home, filters, endpoint, deployment credential, network path, or pending replication. Restart the host after changing the global target or environment, then run one narrow query.
241
+
242
+ Do not inspect outbox rows, databases, keys, or unrelated transcripts. Removing remote configuration does not erase replicated data. See [history](history.md).
243
+
244
+ ## Nook is missing, unauthorized, or serving the wrong visibility
245
+
246
+ The model-facing tool needs both `nook` in the active persona and effective session configuration. Fix the execution-environment level, `/reload` while idle, and start a later turn. Subagents cannot receive Nook.
247
+
248
+ The CLI instead uses the invoking machine's configuration and credentials. A laptop command does not prove a remote host tool works. Start with installed `tau nook --help` and `tau nook list`; the latter uses effective configured credentials and reports URLs and visibility without printing credential values.
249
+
250
+ For `401` or Access failures, verify the domain, client id, secret source, service-auth policy, and the deployed Worker's Access team domain and audience. Access must protect only `https://<domain>/__nook/*`, with the Cookie Path Attribute disabled. Private-browser redirect loops usually indicate Access or cookie configuration.
251
+
252
+ Deploys are private unless `--public` is supplied. Public assets are anonymous and public browser KV is anonymously writable. If visibility is wrong, verify with `list` and redeploy reviewed content without `--public`. Rotate exposed credentials immediately. Use deliberate `delete` only when taking the site offline is intended. KV survives redeploy, so remove sensitive KV with supported commands.
253
+
254
+ Copy needs an existing empty destination. Static deploys require `index.html`, reject hidden files and symlinks, and reserve `/__nook`. Setup and destroy also require noninteractive Wrangler authentication. Compare the [Nook](nook.md) page and installed help with the deployed Worker version before upgrading or changing infrastructure.
255
+
256
+ ## Telegram ignores messages or selects the wrong project
257
+
258
+ The Telegram runner uses the JSON file passed to `--config-file`, not a Tau project `config.json`. Relative workspace and project paths resolve from that file's directory. Restart the runner after editing it.
259
+
260
+ If a private message is ignored, check both `allowedChatIds` and `allowedUserIds`. An omitted list does not restrict private access by that dimension. If a group message is ignored, the group id must be in `allowedChatIds`, the triggering message must explicitly mention the bot, and the sender must pass `allowedUserIds` when that list is configured.
261
+
262
+ Messages in an allowed group that do not trigger the bot can be buffered as context for the next mentioned turn, including attachments, audio transcripts, and processing errors. Confirm that this sharing is intended before broadening a chat allowlist.
263
+
264
+ Each bot can restrict `allowedProjectIds`. `/use_<project>` changes the preference for future `/new` sessions but does not move the active session. Use `/status` to distinguish the active session's project from the saved preference.
265
+
266
+ Runner startup config errors name every invalid bot or project field. Use `tau telegram --help`, validate JSON syntax without printing the file, and fix all reported references, persona suffixes, project kinds, or allowlist IDs before restarting. Keep the file private because it contains bot tokens.
267
+
268
+ ## Telegram workspace preparation or recovery fails
269
+
270
+ Repository projects need runner-side `gh`, Git, network access, and noninteractive credentials. Check `repo`, `ref`, workspace-root permissions and space, and `workingDirectory` after checkout. Tau maintains a bare cache and can reinitialize it when the repository changes. Do not delete caches or workspaces first; preserve logs and fix access or configuration.
271
+
272
+ Persistent-directory projects require the configured directory to exist and intentionally share it across sessions. Recovery rejects a stored `cwd` that differs from current configuration. Restore the mapping or create a new session in the new directory, rather than editing state.
273
+
274
+ Tau reconstructs missing managed workspaces. New and reconstructed repositories may run executable `.tau/scripts/provision` asynchronously after the session is available; preserved workspaces skip it. Failure notifies chats but leaves the session usable. Fix the script or dependencies, then run it manually only when its contract allows, or create a fresh session to provision again.
275
+
276
+ Recovery needs the same `workspaceRoot`, project definitions, host home, and Tau sessions. Inspect runner logs and `/status`. Do not edit runner state, project preferences, snapshots, or managed workspaces to force a match.
277
+
278
+ ## Telegram audio or attachment processing fails
279
+
280
+ Telegram audio transcription uses the runner's `speechToText.provider`, which defaults to Mistral. Mistral needs `MISTRAL_API_KEY` or `apiKeys.mistral`; Gemini needs `GEMINI_API_KEY` or `apiKeys.google`. Set the credential for the runner process and restart it after changing the environment or provider.
281
+
282
+ Distinguish download, materialization, format, and transcription errors. The reply or runner log states which stage failed. Confirm Telegram can deliver the file to the bot, the attachment type is supported, the runner can write its temporary directory, and the selected provider accepts the media type. Do not log media bytes or transcripts merely to prove they exist.
283
+
284
+ Successful audio turns echo `transcribed: …` before submission. In groups, non-triggering audio can be buffered for later mentioned context. If that is inappropriate for the chat, narrow `allowedChatIds` or avoid enabling the group.
285
+
286
+ ## Telegram replies or notifications are delayed or missing
287
+
288
+ Each outbound chunk has a deadline and retries retryable failures twice. Telegram `retry_after` is honored, and per-chat ordering holds later notifications. Large replies are split, so only a later chunk may have failed.
289
+
290
+ Check runner logs for method, redacted status, retry class, attempt, chat, session, and message identity. Correct network, rate limit, token, or chat permissions on the runner. Before manual resend, check delivered chunks because ambiguous failures can duplicate them.
291
+
292
+ Failed/blocked turn and confirmed-unaccepted request notifications persist until delivery succeeds; runner restart rehydrates them. A delivery failure is not a Tau turn failure, and a provision failure is not a session failure. Use `/status` and logs to separate these states. Never repair delivery by editing runner state.
@@ -0,0 +1,224 @@
1
+ # Terminal interface
2
+
3
+ Tau’s terminal interface is both a local chat client and a remote session client. The same editor, commands, and review workflow are available in either mode, but their ownership matters: the session host owns conversation state and model work, while the TUI owns terminal presentation and client-local features such as themes, clipboard access, speech, and the diff-tool process.
4
+
5
+ ## Start the TUI
6
+
7
+ Run `tau` in the project directory for a new local session:
8
+
9
+ ```sh
10
+ cd ~/Code/tau
11
+ tau
12
+ ```
13
+
14
+ Tau creates a local execution environment rooted at that directory. A startup persona and reasoning level can be selected together:
15
+
16
+ ```sh
17
+ tau --persona gpt-5.6-sol-coder:high
18
+ ```
19
+
20
+ `-p` is the short form. `--no-agent-context-files` omits `AGENTS.md` and explicitly configured context files, and `--no-client-tools` prevents the TUI from advertising its built-in and configured [client tools](client-tools.md). On macOS, `--caffeinated` runs `caffeinate -i` while assistant turns are active. It is a no-op on Linux and is not an option for `tau attach`.
21
+
22
+ Piped stdin becomes the first message in a local TUI session:
23
+
24
+ ```sh
25
+ printf 'summarize the current changes' | tau
26
+ ```
27
+
28
+ Use `tau attach` for a session hosted elsewhere. The terminal, themes, clipboard, speech commands, custom diff launcher, and command-backed client tools still belong to the attaching machine. Bash tools, file access, project configuration, and model work use the session’s execution environment. See [remote sessions](remote-sessions.md) for transport and creation examples.
29
+
30
+ ## Work in the editor
31
+
32
+ Enter submits the editor. Shift+Enter or Ctrl+J inserts a newline. Up and Down move through the editor and recall prior submissions when the editor is empty.
33
+
34
+ Tau recognizes these mention forms and offers Tab completion:
35
+
36
+ - `@src/main.ts` mentions a file in the execution environment.
37
+ - `@@skill:code-review` explicitly activates an available skill.
38
+ - `@@agent:default` explicitly selects an available subagent.
39
+
40
+ The older `@file:`, `@skill:`, and `@agent:` forms are not mention syntax. Paths and available skill or agent names come from the hosted session, not from the attaching TUI’s filesystem.
41
+
42
+ Typing `/` at the start of a line opens command completion. Slash commands are recognized only for single-line submissions. A multiline input beginning with `/`, or an unknown slash-prefixed input, is sent to the agent as an ordinary message.
43
+
44
+ ## Submit, queue, and steer
45
+
46
+ When Tau is idle, Enter and Ctrl+Enter both start a normal turn. While a turn is active:
47
+
48
+ - Enter queues the text as a new turn to run when the session becomes idle.
49
+ - Ctrl+Enter steers the active turn. Tau applies steering at a safe continuation boundary rather than injecting it into a model response or tool execution in progress.
50
+ - Alt+Up cancels all pending queued messages and steering that has not yet been applied, then restores their text to the editor. Multiple messages are separated with `---`.
51
+
52
+ Pending input is session state shared by attached clients while the host remains alive. It is not durable across host restart or session recovery. A queued turn captures the persona, reasoning, tools, and model settings when that turn actually starts. Steering remains part of the active logical turn and keeps the settings captured when that turn began.
53
+
54
+ Escape interrupts foreground client work or the main session’s active work. If a local diff review, recording, or speech playback task owns the foreground, Escape stops that task first; otherwise it requests main-session interruption from the host. It does not stop independently running supervised subagents; select one with Alt+Down and use Ctrl+G. Press Escape twice to clear the current editor text.
55
+
56
+ Press Enter twice on an empty editor to retry from the current session history. Retry does not rewind or duplicate the last user message. Goal-controlled turns cannot be retried; resume a blocked goal instead.
57
+
58
+ ## Choose persona, reasoning, and thought visibility
59
+
60
+ The current persona and reasoning level appear in the editor header.
61
+
62
+ - `/persona:<id>` selects a persona by id.
63
+ - Ctrl+P cycles through available personas.
64
+ - Shift+Tab cycles through the current persona’s allowed reasoning levels.
65
+ - Ctrl+T shows or hides stored and streamed assistant thinking in this TUI.
66
+
67
+ Persona changes require the session to be idle because they can change the model, instructions, skills, and tools. Reasoning can be changed while a turn is running, but the active turn and its steering continuations keep their captured settings. The new reasoning level applies to the next independently started or queued turn.
68
+
69
+ Thought visibility is client-local presentation. Ctrl+T does not enable model reasoning, change its effort, or alter the session history.
70
+
71
+ For example:
72
+
73
+ ```text
74
+ /persona:opus-5-coder
75
+ ```
76
+
77
+ Then use Shift+Tab to select an allowed reasoning level. Newly added personas do not appear until session content has been reloaded.
78
+
79
+ ## Slash commands
80
+
81
+ `/help` prints the commands, keybindings, loaded skills, and context-file paths visible to the current session.
82
+
83
+ | Command | Behavior |
84
+ | --- | --- |
85
+ | `/help` | Show commands, keys, skills, and context paths. |
86
+ | `/new` | Create a fresh session in the same execution environment, carrying over the current persona, reasoning, and conventional repository attribute. |
87
+ | `/exit` | Close this TUI. It detaches from a long-running remote host rather than deleting the session. |
88
+ | `/rewind` | Pick an earlier user message, remove it and everything after it, and return its text to the editor. |
89
+ | `/diff [git diff args...]` | Open the client-local diff review tool for a snapshot captured from the execution environment. |
90
+ | `/goal [objective\|resume\|clear]` | Show, start, resume, or clear the persistent session goal. |
91
+ | `/compact-all [guidance]` | Replace model context with a generated summary. |
92
+ | `/compact-keep-last [guidance]` | Generate a summary that also includes the previous last assistant response when available. |
93
+ | `/reload` | Reload session-owned configuration and content from the execution environment. |
94
+ | `/listen` | Record speech and insert its transcript into the editor on macOS. |
95
+ | `/speak` | Read the last assistant response aloud on macOS. |
96
+ | `/copy-text` | Copy the last assistant response as plain text. |
97
+ | `/copy-code` | Copy code blocks from the last assistant response. |
98
+ | `/persona:<id>` | Switch persona while idle. |
99
+ | `/prompt:<id>` | Resolve a prompt from the execution environment and place it in the editor without submitting it. |
100
+ | `/theme:<id>` | Switch this TUI’s theme for the current run. |
101
+
102
+ Commands that mutate context, such as persona changes, compaction, rewind, and reload, should be run while idle. `/goal` display and clear, `/listen`, `/prompt:<id>`, and `/exit` have limited useful behavior during a running turn. Ordinary command submissions are otherwise held back until Tau is idle.
103
+
104
+ Compaction, rewind, goals, recovery, and retry are described in [sessions](sessions.md). Prompt discovery and insertion are covered in [prompts and project context](prompts-and-project-context.md).
105
+
106
+ ## Keyboard shortcuts
107
+
108
+ | Key | Behavior |
109
+ | --- | --- |
110
+ | Shift+Tab | Cycle reasoning effort. |
111
+ | Ctrl+P | Cycle persona while idle. |
112
+ | Ctrl+T | Toggle thought visibility in this TUI. |
113
+ | Ctrl+S | Copy the expanded editor contents to the local clipboard, then clear the editor. |
114
+ | Ctrl+Y | Start or stop voice recording. |
115
+ | Ctrl+Enter | Steer an active turn, or submit normally while idle. |
116
+ | Alt+Up | Cancel pending input and restore it to the editor. |
117
+ | Alt+Down | Cycle the selected active subagent. |
118
+ | Ctrl+G | Interrupt the selected active subagent. |
119
+ | Enter twice | Retry when the editor is empty and the session is idle. |
120
+ | Escape | Interrupt foreground client or main-session work. |
121
+ | Escape twice | Clear the current editor text. |
122
+ | Ctrl+C twice | Exit the TUI. |
123
+
124
+ Ctrl+C once asks for confirmation rather than interrupting the assistant. Use Escape for interruption.
125
+
126
+ ## Run direct Bash commands
127
+
128
+ A leading `!` runs a fresh non-interactive login Bash in the session execution environment without asking the model to create a tool call:
129
+
130
+ ```text
131
+ !git status --short
132
+ ```
133
+
134
+ The command and result are added to session context, so the agent can use them later. A double prefix runs the command without adding it to model context:
135
+
136
+ ```text
137
+ !!git diff --stat
138
+ ```
139
+
140
+ `!!` is useful for checks that should not consume context. Its transient card is still visible in the current TUI, but the command and output are not recorded as session conversation state.
141
+
142
+ Direct commands require the session to be idle. In an attached TUI, `!pwd` reports the execution environment’s directory, not the attaching machine’s directory. Command-backed [client tools](client-tools.md) are different: their processes run on the client machine and can explicitly request execution-environment commands through the session.
143
+
144
+ ## Use themes
145
+
146
+ Themes belong to the TUI process and never become session state. Tau loads built-in themes plus JSON files from these locations:
147
+
148
+ - `~/.config/tau/themes/<id>.json` for user themes, when the TUI cwd is under the user’s home.
149
+ - `.tau/themes/<id>.json` at discovered project configuration levels, with the nearest project definition winning by id.
150
+
151
+ The filename is the theme id. A custom theme is a flat JSON object from semantic palette token names to colors:
152
+
153
+ ```json
154
+ {
155
+ "brandAccent": "#8fb3ff",
156
+ "textMuted": "rgb(145, 151, 166)",
157
+ "feedbackError": "hsl(354, 70%, 72%)"
158
+ }
159
+ ```
160
+
161
+ Colors accept `#rgb`, `#rrggbb`, `rgb(r, g, b)`, and `hsl(h, s%, l%)`. Unknown tokens, non-string values, and invalid colors are ignored. Missing tokens render without a custom color. Custom themes are single-variant; built-in themes adapt to detected terminal appearance.
162
+
163
+ Set the startup theme with `defaultTheme` in the attaching client’s [configuration](configuration.md), or switch for the current run:
164
+
165
+ ```text
166
+ /theme:gold
167
+ ```
168
+
169
+ Theme ids are exact and case-sensitive. `/theme` does not persist the selection. `/reload` refreshes the hosted session, not the attaching client’s loaded theme files, so restart the TUI after adding or changing a theme. In remote use, changing theme files on the host has no effect unless the host and TUI are the same physical machine and the TUI loaded those files itself.
170
+
171
+ ## Review a diff
172
+
173
+ `/diff` captures a Git snapshot through the session execution environment, then launches a diff-tool process on the TUI machine. The built-in browser tool is the default. `tau diff-tool` is the standalone command for the built-in demo and diff-review protocol reference. `tau diff-tool --help` shows its help, while `/diff` supplies the environment required for normal reviews. Arguments are passed as Git diff arguments, for example:
174
+
175
+ ```text
176
+ /diff --staged
177
+ ```
178
+
179
+ A `diffTool` entry in the attaching client’s configuration replaces the launcher. Relative commands resolve from the configuration level that defines them:
180
+
181
+ ```json
182
+ {
183
+ "diffTool": {
184
+ "command": "/usr/local/bin/team-diff-review",
185
+ "args": ["--open"]
186
+ }
187
+ }
188
+ ```
189
+
190
+ The session host supplies ephemeral review agents, while the local tool owns its browser or interface process. Returned review feedback is recorded as a user entry in the session so it remains available, but Tau does not automatically start an assistant turn after the tool closes. Submit a follow-up message when the review should drive more work.
191
+
192
+ The TUI also advertises diff review as a client tool unless `--no-client-tools` is set. Manual `/diff` remains a TUI command even when model-facing client tools are disabled. See [client tools](client-tools.md) for attachment and multiple-client implications.
193
+
194
+ ## Use speech and keep-awake support
195
+
196
+ `/listen` and Ctrl+Y are currently macOS-only. Recording uses local `ffmpeg` with the AVFoundation audio input and stops when Ctrl+Y is pressed again, when Escape is pressed, or after five minutes. The transcript is inserted at the cursor for review and is not submitted automatically.
197
+
198
+ Install `ffmpeg` and configure a speech-to-text provider:
199
+
200
+ ```sh
201
+ brew install ffmpeg
202
+ ```
203
+
204
+ Mistral is the default and needs `MISTRAL_API_KEY` or `apiKeys.mistral`. Set `speechToText.provider` to `gemini` to use `GEMINI_API_KEY` or `apiKeys.google` instead. These settings and credentials are read by the TUI process, including during remote attachment.
205
+
206
+ `/speak` is also macOS-only. It rewrites the last assistant response for speech, generates audio with Gemini, and plays it through the local `afplay` command. It requires `GEMINI_API_KEY` or `apiKeys.google`, runs only while the session is idle, and can be stopped with Escape.
207
+
208
+ `tau --caffeinated` keeps macOS awake only during active assistant turns in that local TUI. It does not keep a remote host awake, and it is not accepted by `tau attach`.
209
+
210
+ ## Reload the right component
211
+
212
+ Run `/reload` while idle after changing session-owned configuration, model overlays, personas, prompts, skills, or AGENTS.md content in the execution environment. The host resolves them again from the session cwd, keeps the current persona when it still exists, and otherwise selects the first available persona. Warnings are shown in the transcript.
213
+
214
+ Restart the TUI instead after changing client-owned themes, the diff launcher, speech settings, or configured client tools. Effective model `apiKeys` in session configuration can update through `/reload`, and managed Codex auth storage is read again on later credential resolutions. Restart the host after changing its binary, process environment variables, WebSocket listener, or hosted execution-environment resolver configuration. [Credentials](credentials.md) has the canonical apply boundaries, and [remote sessions](remote-sessions.md) explains the component split.
215
+
216
+ ## Common mistakes
217
+
218
+ - `!` and `!!` run in the execution environment, not on the attaching client.
219
+ - Enter during a turn queues another turn. Use Ctrl+Enter to steer the active one.
220
+ - Ctrl+T changes visibility only. Use Shift+Tab to change reasoning effort.
221
+ - `/prompt:<id>` fills the editor but does not submit it.
222
+ - `/diff` records returned feedback but does not automatically ask the assistant to act on it.
223
+ - `/reload` does not reload client themes or client tools.
224
+ - Exiting a WebSocket attachment does not delete or necessarily stop the hosted session. Exiting a local TUI or one-shot stdio attachment also shuts down its owned host, so active work is interrupted and persisted before recovery where possible.
@@ -4,7 +4,7 @@ import { dirname, resolve } from "node:path";
4
4
  import { z } from "zod";
5
5
  import { TauSessionProtocolResponseError } from "../../transport/errors.js";
6
6
  import { extractAssistantText } from "../utils/messages.js";
7
- import { normalizeRepositoryReference } from "../utils/repository.js";
7
+ import { buildRepositoryAttribute, normalizeRepositoryReference } from "../utils/repository.js";
8
8
  import { formatTauUserText } from "../utils/user_metadata.js";
9
9
  import { cleanupWorkspacePath as cleanupWorkspacePathOnDisk, cleanupWorkspaceRootsOnStartup, prepareWorkspace, resolveWorkspacePath, } from "./workspace.js";
10
10
  const telegramSessionStateValueSchema = z.enum([
@@ -1153,11 +1153,12 @@ class TelegramSessionManagerImpl {
1153
1153
  return project && "repo" in project ? [project.repo] : [];
1154
1154
  })
1155
1155
  : [];
1156
- const repositories = configuredRepositories.map((repository) => normalizeRepositoryReference(repository, { defaultHost: "github.com" }) ?? repository);
1156
+ const repository = buildRepositoryAttribute(configuredRepositories.map((configuredRepository) => normalizeRepositoryReference(configuredRepository, { defaultHost: "github.com" }) ??
1157
+ configuredRepository));
1157
1158
  return {
1158
1159
  source: "telegram",
1159
1160
  project: entry.record.projectId,
1160
- ...(repositories.length > 0 ? { repository: repositories.join(",") } : {}),
1161
+ ...(repository ? { repository } : {}),
1161
1162
  };
1162
1163
  }
1163
1164
  buildClientOptions(entry, cwd) {