Chat tabs, chat mode, own modes, compaction notice, CLI binaries again

- Terminals and file managers as tabs of a chat; chat terminals keep running on
  the server (no idle timeout) and re-attach from any device
- "Just chat" in New session and a built-in chat mode with a lean prompt and only
  web tools; custom modes with kind (coding/conversation), read-only and tool picker
- Mode selector as a dropdown
- The chat shows running compactions (automatic: tokens and share of the limit)
  and labels summaries
- Docker image builds and serves the terminal client binaries again
- Fix: atomic session updates; background title/usage writes no longer undo each
  other (auto compaction triggered one turn late)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-09 11:24:58 +01:00
1 parent 242b80605c
commit c850586a81
29 files changed
+831 -187

No files matched your search

+2 -2
View File
@@ -508,7 +508,7 @@ impl Agent {
let who = if matches!(m.role, Role::User) { "USER" } else { "ASSISTANT" };
for p in &m.parts {
let line = match p {
Part::Text { text } | Part::Summary { text } => text.clone(),
Part::Text { text } | Part::Summary { text, .. } => text.clone(),
Part::ToolCall { name, input, .. } => format!("[tool call {name}: {}]", input.to_string().chars().take(1500).collect::<String>()),
Part::ToolResult { name, content, .. } => format!("[result of {name}]\n{}", content.chars().take(3000).collect::<String>()),
_ => continue,
@@ -524,7 +524,7 @@ impl Agent {
if summary.trim().is_empty() {
return Err(anyhow!("compaction produced no summary"));
}
self.session.messages.push(Message::new(Role::User, vec![Part::Summary { text: summary }]));
self.session.messages.push(Message::new(Role::User, vec![Part::Summary { text: summary, auto: false, tokens: None }]));
self.session.context_tokens = 0;
self.read_files.lock().unwrap().clear();
let _ = self.session.save();