Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/assets/client-zed.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 31 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ dirs = "5"

# SQLite database support (bundled for cross-compilation)
rusqlite = { version = "0.32", features = ["bundled"] }
zstd = "0.13"

# Lazy static initialization
once_cell = "1"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
| <img width="48px" src=".github/assets/client-crush.png" alt="Crush" /> | [Crush](https://crush.ai/) | `$XDG_DATA_HOME/crush/projects.json` (project registry; fallback: `~/.local/share/crush/projects.json`) | ✅ Yes |
| <img width="48px" src=".github/assets/client-goose.png" alt="Goose" /> | [Goose](https://github.com/aaif-goose/goose) | `~/.local/share/goose/sessions/sessions.db` (+ macOS Application Support, legacy Block/goose paths; override via `GOOSE_PATH_ROOT`) | ✅ Yes |
| <img width="48px" src=".github/assets/client-antigravity.png" alt="Antigravity" /> | [Google Antigravity](https://antigravity.google/) | Cached via `tokscale antigravity sync` to `~/.config/tokscale/antigravity-cache/sessions/*.jsonl` (live RPC against the local language server) | ✅ Yes |
| <img width="48px" src=".github/assets/client-zed.webp" alt="Zed Agent" /> | [Zed Agent](https://zed.dev/docs/ai/agent-panel) | `~/.local/share/zed/threads/threads.db` (macOS: `~/Library/Application Support/Zed/threads/threads.db`; Windows: `%LOCALAPPDATA%/Zed/threads/threads.db`; hosted Zed models only, not external ACP agents) | ✅ Yes |
| <img width="48px" src=".github/assets/client-synthetic.png" alt="Synthetic" /> | [Synthetic](https://synthetic.new/) | Re-attributed from other sources via `hf:` model prefix or `synthetic` provider (+ [Octofriend](https://github.com/synthetic-lab/octofriend): `~/.local/share/octofriend/sqlite.db`) | ✅ Yes |

Get real-time pricing calculations using [🚅 LiteLLM's pricing data](https://github.com/BerriAI/litellm), with support for tiered pricing models and cache token discounts.
Expand Down
19 changes: 19 additions & 0 deletions crates/tokscale-cli/src/commands/wrapped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,7 @@ fn client_display_name(client: &str) -> Option<&'static str> {
"crush" => Some("Crush"),
"goose" => Some("Goose"),
"antigravity" => Some("Antigravity"),
"zed" => Some("Zed Agent"),
"synthetic" => Some("Synthetic"),
_ => None,
}
Expand Down Expand Up @@ -1479,6 +1480,9 @@ fn client_logo_url(client_name: &str) -> Option<&'static str> {
"Antigravity" => Some(
"https://raw.githubusercontent.com/junhoyeo/tokscale/main/.github/assets/client-antigravity.png",
),
"Zed Agent" => Some(
"https://raw.githubusercontent.com/junhoyeo/tokscale/main/.github/assets/client-zed.webp",
),
"Synthetic" => Some("https://tokscale.ai/assets/logos/synthetic.png"),
_ => None,
}
Expand Down Expand Up @@ -2425,6 +2429,11 @@ mod tests {
assert_eq!(client_display_name("antigravity"), Some("Antigravity"));
}

#[test]
fn test_client_display_name_zed() {
assert_eq!(client_display_name("zed"), Some("Zed Agent"));
}

#[test]
fn test_client_display_name_unknown() {
assert_eq!(client_display_name("unknown"), None);
Expand Down Expand Up @@ -2590,6 +2599,16 @@ mod tests {
);
}

#[test]
fn test_client_logo_url_zed() {
assert_eq!(
client_logo_url("Zed Agent"),
Some(
"https://raw.githubusercontent.com/junhoyeo/tokscale/main/.github/assets/client-zed.webp"
)
);
}

#[test]
fn test_client_logo_url_unknown() {
assert_eq!(client_logo_url("Unknown"), None);
Expand Down
29 changes: 28 additions & 1 deletion crates/tokscale-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,7 @@ pub enum ClientFilter {
Goose,
Codebuff,
Antigravity,
Zed,
Synthetic,
}

Expand Down Expand Up @@ -716,6 +717,7 @@ impl ClientFilter {
Self::Goose => "goose",
Self::Codebuff => "codebuff",
Self::Antigravity => "antigravity",
Self::Zed => "zed",
Self::Synthetic => "synthetic",
}
}
Expand Down Expand Up @@ -749,6 +751,7 @@ impl ClientFilter {
Self::Goose => Some(ClientId::Goose),
Self::Codebuff => Some(ClientId::Codebuff),
Self::Antigravity => Some(ClientId::Antigravity),
Self::Zed => Some(ClientId::Zed),
Self::Synthetic => None,
}
}
Expand Down Expand Up @@ -779,6 +782,7 @@ impl ClientFilter {
ClientId::Goose => Self::Goose,
ClientId::Codebuff => Self::Codebuff,
ClientId::Antigravity => Self::Antigravity,
ClientId::Zed => Self::Zed,
}
}

Expand Down Expand Up @@ -874,6 +878,8 @@ pub struct ClientFlags {
#[arg(long, hide = true)]
pub antigravity: bool,
#[arg(long, hide = true)]
pub zed: bool,
#[arg(long, hide = true)]
pub synthetic: bool,
}

Expand Down Expand Up @@ -927,7 +933,7 @@ fn build_client_filter_with_defaults(
}
}

let legacy: [(bool, ClientFilter); 22] = [
let legacy: [(bool, ClientFilter); 23] = [
(flags.opencode, ClientFilter::Opencode),
(flags.claude, ClientFilter::Claude),
(flags.codex, ClientFilter::Codex),
Expand All @@ -949,6 +955,7 @@ fn build_client_filter_with_defaults(
(flags.copilot, ClientFilter::Copilot),
(flags.goose, ClientFilter::Goose),
(flags.antigravity, ClientFilter::Antigravity),
(flags.zed, ClientFilter::Zed),
(flags.synthetic, ClientFilter::Synthetic),
];

Expand Down Expand Up @@ -4459,6 +4466,7 @@ mod tests {
crush: true,
goose: true,
antigravity: true,
zed: true,
synthetic: true,
..ClientFlags::default()
};
Expand Down Expand Up @@ -4490,6 +4498,7 @@ mod tests {
"crush",
"goose",
"antigravity",
"zed",
"synthetic",
] {
assert!(
Expand Down Expand Up @@ -4868,6 +4877,7 @@ mod tests {
fn test_default_submit_clients_excludes_crush() {
let clients = default_submit_clients();
assert!(clients.contains(&"synthetic".to_string()));
assert!(clients.contains(&"zed".to_string()));
assert!(!clients.contains(&"crush".to_string()));
}

Expand Down Expand Up @@ -4904,6 +4914,23 @@ mod tests {
);
}

#[test]
fn test_client_filter_zed_round_trip() {
assert_eq!(
ClientFilter::from_filter_str("zed"),
Some(ClientFilter::Zed)
);
assert_eq!(ClientFilter::Zed.as_filter_str(), "zed");
assert_eq!(
ClientFilter::Zed.to_client_id(),
Some(tokscale_core::ClientId::Zed)
);
assert_eq!(
ClientFilter::from_client_id(tokscale_core::ClientId::Zed),
ClientFilter::Zed
);
}

#[test]
fn test_client_filter_default_set_includes_goose() {
let default = ClientFilter::default_set();
Expand Down
4 changes: 4 additions & 0 deletions crates/tokscale-cli/src/tui/client_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ pub const CLIENT_UI: [ClientUi; ClientId::COUNT] = [
display_name: "Antigravity",
hotkey: 'a',
},
ClientUi {
display_name: "Zed Agent",
hotkey: 'z',
},
];

pub fn display_name(client: ClientId) -> &'static str {
Expand Down
9 changes: 8 additions & 1 deletion crates/tokscale-cli/src/tui/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ mod tests {
#[test]
fn test_client_all() {
let clients = ClientId::ALL;
assert_eq!(clients.len(), 21);
assert_eq!(clients.len(), 22);
assert_eq!(clients[0], ClientId::OpenCode);
assert_eq!(clients[1], ClientId::Claude);
assert_eq!(clients[2], ClientId::Codex);
Expand All @@ -1166,6 +1166,7 @@ mod tests {
assert_eq!(clients[18], ClientId::Goose);
assert_eq!(clients[19], ClientId::Codebuff);
assert_eq!(clients[20], ClientId::Antigravity);
assert_eq!(clients[21], ClientId::Zed);
}

#[test]
Expand Down Expand Up @@ -1235,6 +1236,10 @@ mod tests {
crate::tui::client_ui::display_name(ClientId::Antigravity),
"Antigravity"
);
assert_eq!(
crate::tui::client_ui::display_name(ClientId::Zed),
"Zed Agent"
);
}

#[test]
Expand All @@ -1259,6 +1264,7 @@ mod tests {
assert_eq!(crate::tui::client_ui::hotkey(ClientId::Hermes), 'e');
assert_eq!(crate::tui::client_ui::hotkey(ClientId::Codebuff), 'b');
assert_eq!(crate::tui::client_ui::hotkey(ClientId::Antigravity), 'a');
assert_eq!(crate::tui::client_ui::hotkey(ClientId::Zed), 'z');
}

#[test]
Expand Down Expand Up @@ -1334,6 +1340,7 @@ mod tests {
crate::tui::client_ui::from_hotkey('a'),
Some(ClientId::Antigravity)
);
assert_eq!(crate::tui::client_ui::from_hotkey('z'), Some(ClientId::Zed));
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions crates/tokscale-cli/src/tui/ui/widgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ pub fn get_client_color(client: &str) -> Color {
"goose" => Color::Rgb(100, 180, 220), // #64b4dc
"codebuff" => Color::Rgb(124, 58, 237), // #7C3AED Codebuff brand purple
"antigravity" => Color::Rgb(99, 102, 241), // #6366F1 Antigravity indigo
"zed" => Color::Rgb(8, 76, 207), // #084CCF Zed blue
_ => Color::Rgb(136, 136, 136), // #888888
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/tokscale-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ tokio = { workspace = true }
dirs = { workspace = true }
once_cell = { workspace = true }
rusqlite = { workspace = true }
zstd = { workspace = true }
tracing = { workspace = true }
sha2 = { workspace = true }
libc = { workspace = true }
Expand Down
24 changes: 23 additions & 1 deletion crates/tokscale-core/src/clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,15 @@ define_clients!(
headless: false,
parse_local: true,
submit_default: false
},
Zed = 21 => {
id: "zed",
root: PathRoot::XdgData,
relative: "zed/threads/threads.db",
pattern: "threads.db",
headless: false,
parse_local: true,
submit_default: true
}
);

Expand Down Expand Up @@ -414,7 +423,7 @@ mod tests {

#[test]
fn test_client_id_count() {
assert_eq!(ClientId::COUNT, 21);
assert_eq!(ClientId::COUNT, 22);
}

#[test]
Expand Down Expand Up @@ -689,4 +698,17 @@ mod tests {
fn test_antigravity_submit_default_is_false() {
assert!(!ClientId::Antigravity.submit_default());
}

#[test]
fn test_zed_data_dir_path() {
assert_eq!(
ClientId::Zed.data().resolve_path("/tmp/home"),
"/tmp/home/.local/share/zed/threads/threads.db"
);
}

#[test]
fn test_zed_submit_default_is_true() {
assert!(ClientId::Zed.submit_default());
}
}
Loading
Loading