From 3cb7db65e2d689f2b0d6ab687c16cbca6fe75708 Mon Sep 17 00:00:00 2001 From: asteroida123 <264808420+asteroida123@users.noreply.github.com> Date: Fri, 14 Aug 2026 11:17:14 +0800 Subject: [PATCH 1/7] Add DeepSeek Harness (DSH) as a built-in ACP agent Registers DSH as a first-class built-in alongside the other twelve: - AgentType::Dsh variant (wire name 'dsh', registry id 'dsh-acp') - Launch metadata: npx @asteroida/dsh-codeg-adapter, supports_mcp=false (DSH's automation-only ACP bridge rejects mcpServers) - Transcript parser reuses acp_native (DSH keeps no codeg-readable store) - Frontend: BuiltinAgentType union, labels, colors, display order cargo check + targeted tests pass; tsc introduces no new errors. --- src-tauri/src/acp/custom_registry.rs | 2 +- src-tauri/src/acp/file_system_runtime.rs | 1 + src-tauri/src/acp/registry.rs | 33 +++++++++++++++++++--- src-tauri/src/acp/remote_registry.rs | 2 +- src-tauri/src/commands/acp.rs | 7 +++++ src-tauri/src/commands/conversations.rs | 2 ++ src-tauri/src/commands/mcp.rs | 3 ++ src-tauri/src/db/service/import_service.rs | 3 +- src-tauri/src/models/agent.rs | 12 ++++++-- src/lib/types.ts | 7 ++++- 10 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src-tauri/src/acp/custom_registry.rs b/src-tauri/src/acp/custom_registry.rs index fc6c71df3..4b9a62ed6 100644 --- a/src-tauri/src/acp/custom_registry.rs +++ b/src-tauri/src/acp/custom_registry.rs @@ -664,7 +664,7 @@ struct Entry { meta: &'static AcpAgentMeta, /// Display icon, kept beside the launch metadata rather than inside /// [`AcpAgentMeta`]: it is presentation, not launch data, and every one of - /// the twelve built-in metas would otherwise need a field it never uses. + /// the thirteen built-in metas would otherwise need a field it never uses. icon: Option<&'static str>, /// Whether the user declared the agent reads the shared `.agents/skills` /// store. Beside the meta for the same reason as `icon`: it drives the diff --git a/src-tauri/src/acp/file_system_runtime.rs b/src-tauri/src/acp/file_system_runtime.rs index d2fffdc92..804ca2dbd 100644 --- a/src-tauri/src/acp/file_system_runtime.rs +++ b/src-tauri/src/acp/file_system_runtime.rs @@ -541,6 +541,7 @@ fn agent_root_slots(agent_type: AgentType) -> &'static [RootSlot] { // A custom ACP agent has no codeg-known private directory layout — // codeg never reads its store (history comes from codeg's own ACP // transcript), so there is nothing to widen the sandbox roots for. + AgentType::Dsh => &[], AgentType::Custom(_) => &[], } } diff --git a/src-tauri/src/acp/registry.rs b/src-tauri/src/acp/registry.rs index 7602229a4..e33cb92fb 100644 --- a/src-tauri/src/acp/registry.rs +++ b/src-tauri/src/acp/registry.rs @@ -138,7 +138,7 @@ pub fn current_platform() -> &'static str { } } -/// The twelve built-in agents. Excludes user-registered custom agents — use +/// The thirteen built-in agents. Excludes user-registered custom agents — use /// [`all_acp_agents`] for the live set. pub fn builtin_acp_agents() -> Vec { vec![ @@ -154,10 +154,11 @@ pub fn builtin_acp_agents() -> Vec { AgentType::Pi, AgentType::Grok, AgentType::Cursor, + AgentType::Dsh, ] } -/// Every agent codeg can currently drive: the twelve built-ins followed by the +/// Every agent codeg can currently drive: the thirteen built-ins followed by the /// user's registered custom ACP agents (sorted by id). pub fn all_acp_agents() -> Vec { let mut agents = builtin_acp_agents(); @@ -179,6 +180,7 @@ pub fn registry_id_for(agent_type: AgentType) -> &'static str { AgentType::Pi => "pi-acp", AgentType::Grok => "grok-build", AgentType::Cursor => "cursor", + AgentType::Dsh => "dsh-acp", // A custom agent's registry id IS its identity. AgentType::Custom(id) => id, } @@ -198,6 +200,7 @@ pub fn from_registry_id(id: &str) -> Option { "pi-acp" => Some(AgentType::Pi), "grok-build" => Some(AgentType::Grok), "cursor" => Some(AgentType::Cursor), + "dsh-acp" => Some(AgentType::Dsh), // Only ids the user has actually registered resolve. An unregistered // id must stay `None` so the ACP-registry picker still offers it as // "addable" rather than treating it as already supported. @@ -744,6 +747,22 @@ pub fn get_agent_meta(agent_type: AgentType) -> AcpAgentMeta { }), }, }, + AgentType::Dsh => AcpAgentMeta { + agent_type, + // DSH's automation-only ACP bridge rejects mcpServers, same as + // OpenClaw; forwarding any entry makes session/new fail. + supports_mcp: false, + name: "DeepSeek Harness (DSH)", + description: "DeepSeek Harness coding agent (ACP, automation-only)", + distribution: AgentDistribution::Npx { + version: "0.1.0", + package: "@asteroida/dsh-codeg-adapter@0.1.0", + cmd: "dsh-codeg", + args: &[], + env: &[], + node_required: Some("20.0.0"), + }, + }, // Handled by the early return above; kept so the match stays // exhaustive without a catch-all that could swallow a new built-in. AgentType::Custom(_) => unreachable!("custom agents resolve via custom_registry"), @@ -929,6 +948,12 @@ mod tests { "hermes-agent@0.20.0", Some("20.0.0"), ); + assert_npx_version( + AgentType::Dsh, + "0.1.0", + "@asteroida/dsh-codeg-adapter@0.1.0", + Some("20.0.0"), + ); } // The Hermes launch command must be the wrapper's `hermes` bin with the @@ -986,12 +1011,12 @@ mod tests { // (`CustomAgentDef::supports_mcp`), so a registry hydrated by another test // may legitimately hold an opted-out one. #[test] - fn only_builtin_openclaw_opts_out_of_mcp() { + fn only_openclaw_and_dsh_opt_out_of_mcp() { for agent_type in builtin_acp_agents() { let meta = get_agent_meta(agent_type); assert_eq!( meta.supports_mcp, - agent_type != AgentType::OpenClaw, + agent_type != AgentType::OpenClaw && agent_type != AgentType::Dsh, "unexpected supports_mcp for {agent_type:?}" ); } diff --git a/src-tauri/src/acp/remote_registry.rs b/src-tauri/src/acp/remote_registry.rs index 19c39a8a6..13a2dbd82 100644 --- a/src-tauri/src/acp/remote_registry.rs +++ b/src-tauri/src/acp/remote_registry.rs @@ -271,7 +271,7 @@ pub async fn fetch_catalog( /// id is `kimi-code`. const BUILTIN_REGISTRY_ALIASES: &[&str] = &["kimi"]; -/// Whether an id is one of codeg's twelve hand-written agents. Deliberately +/// Whether an id is one of codeg's thirteen hand-written agents. Deliberately /// does NOT consult the custom registry (unlike `registry::from_registry_id`, /// which resolves registered custom ids too) — the picker needs "codeg ships /// this natively", not "codeg can currently launch this". diff --git a/src-tauri/src/commands/acp.rs b/src-tauri/src/commands/acp.rs index 77774684d..8f949f589 100644 --- a/src-tauri/src/commands/acp.rs +++ b/src-tauri/src/commands/acp.rs @@ -6996,6 +6996,9 @@ pub(crate) fn skill_storage_spec(agent_type: AgentType) -> Option None, // codeg cannot detect where an arbitrary ACP agent loads skills from, // so custom agents are gated on the user's own declaration: that the // agent reads the shared `.agents/skills` store (the cross-agent @@ -8241,6 +8244,10 @@ fn cascade_update_agent_config( // (`acpUpdateAgentEnv`); it does not write provider creds into // ~/.grok/config.toml and does not participate in the cascade. } + AgentType::Dsh => { + // DSH reads DEEPSEEK_API_KEY from the environment (no on-disk + // config file), so there is nothing to cascade into a file. + } AgentType::Custom(_) => { // Custom agents are deliberately configuration-free: codeg writes // no config file for them and they are excluded from the diff --git a/src-tauri/src/commands/conversations.rs b/src-tauri/src/commands/conversations.rs index 72112a914..76ffb14c5 100644 --- a/src-tauri/src/commands/conversations.rs +++ b/src-tauri/src/commands/conversations.rs @@ -295,6 +295,7 @@ pub async fn get_conversation( AgentType::Pi => Box::new(PiParser::new()), AgentType::Grok => Box::new(GrokParser::new()), AgentType::Cursor => Box::new(CursorParser::new()), + AgentType::Dsh => Box::new(AcpNativeParser::new(agent_type)), // Custom ACP agents have no native store to reverse-engineer; // their history is codeg's own ACP transcript. AgentType::Custom(_) => Box::new(AcpNativeParser::new(agent_type)), @@ -1037,6 +1038,7 @@ pub async fn get_folder_conversation_core( AgentType::Pi => Box::new(PiParser::new()), AgentType::Grok => Box::new(GrokParser::new()), AgentType::Cursor => Box::new(CursorParser::new()), + AgentType::Dsh => Box::new(AcpNativeParser::new(at)), AgentType::Custom(_) => Box::new(AcpNativeParser::new(at)), }; match parser.get_conversation(&eid) { diff --git a/src-tauri/src/commands/mcp.rs b/src-tauri/src/commands/mcp.rs index 80930bc50..68602fbe2 100644 --- a/src-tauri/src/commands/mcp.rs +++ b/src-tauri/src/commands/mcp.rs @@ -2459,6 +2459,9 @@ pub fn read_servers_for_agent_type( // pi-acp drops ACP-wire MCP and pi has no native MCP (it needs a // third-party extension), so codeg manages no MCP servers for pi (v1). AgentType::Pi => Ok(BTreeMap::new()), + // DSH's automation-only ACP bridge rejects mcpServers; codeg manages + // no MCP servers for it, and it has no native MCP config to read. + AgentType::Dsh => Ok(BTreeMap::new()), // Custom agents get MCP purely over the ACP wire (`session/new`'s // `mcpServers`); codeg deliberately knows nothing about their native // config files, so there is no per-agent store to read back here. diff --git a/src-tauri/src/db/service/import_service.rs b/src-tauri/src/db/service/import_service.rs index 809ad81e3..0584848d2 100644 --- a/src-tauri/src/db/service/import_service.rs +++ b/src-tauri/src/db/service/import_service.rs @@ -51,6 +51,7 @@ fn build_parser(agent_type: AgentType) -> Box { AgentType::Pi => Box::new(PiParser::new()), AgentType::Grok => Box::new(GrokParser::new()), AgentType::Cursor => Box::new(CursorParser::new()), + AgentType::Dsh => Box::new(crate::parsers::acp_native::AcpNativeParser::new(agent_type)), // Custom agents' history lives in codeg's own ACP transcript. AgentType::Custom(_) => Box::new(crate::parsers::acp_native::AcpNativeParser::new( agent_type, @@ -103,7 +104,7 @@ where let mut seen: std::collections::HashSet<(AgentType, String)> = std::collections::HashSet::new(); let mut done = 0u32; - // Awaiting in parser order only affects callback ordering — all twelve + // Awaiting in parser order only affects callback ordering — all thirteen // walks already run concurrently on the blocking pool. for (at, task) in tasks { let mut count = 0u32; diff --git a/src-tauri/src/models/agent.rs b/src-tauri/src/models/agent.rs index d12f39d79..1a4668bda 100644 --- a/src-tauri/src/models/agent.rs +++ b/src-tauri/src/models/agent.rs @@ -8,7 +8,7 @@ pub const CUSTOM_AGENT_WIRE_PREFIX: &str = "custom:"; /// Which agent backs a conversation. /// -/// The twelve named variants are compile-time built-ins with hand-written +/// The thirteen named variants are compile-time built-ins with hand-written /// launch metadata (`acp::registry`) and a dedicated transcript parser /// (`parsers::*`). [`AgentType::Custom`] is the open end: a user-registered /// ACP agent whose launch metadata lives in the database @@ -33,12 +33,13 @@ pub enum AgentType { Pi, Grok, Cursor, + Dsh, /// A user-registered ACP agent, identified by its ACP-registry id /// (interned). Ordered last so built-ins keep their relative order. Custom(&'static str), } -/// The twelve compile-time agents, in declaration order. Does NOT include +/// The thirteen compile-time agents, in declaration order. Does NOT include /// custom agents — use [`crate::acp::registry::all_acp_agents`] for the live /// set that includes them. pub const BUILTIN_AGENT_TYPES: &[AgentType] = &[ @@ -54,6 +55,7 @@ pub const BUILTIN_AGENT_TYPES: &[AgentType] = &[ AgentType::Pi, AgentType::Grok, AgentType::Cursor, + AgentType::Dsh, ]; impl AgentType { @@ -98,6 +100,7 @@ impl AgentType { AgentType::Pi => Cow::Borrowed("pi"), AgentType::Grok => Cow::Borrowed("grok"), AgentType::Cursor => Cow::Borrowed("cursor"), + AgentType::Dsh => Cow::Borrowed("dsh"), AgentType::Custom(id) => Cow::Owned(format!("{CUSTOM_AGENT_WIRE_PREFIX}{id}")), } } @@ -118,6 +121,7 @@ impl AgentType { "pi" => Some(AgentType::Pi), "grok" => Some(AgentType::Grok), "cursor" => Some(AgentType::Cursor), + "dsh" => Some(AgentType::Dsh), other => other .strip_prefix(CUSTOM_AGENT_WIRE_PREFIX) .and_then(AgentType::custom), @@ -157,6 +161,7 @@ pub fn is_valid_custom_agent_id(id: &str) -> bool { | "pi" | "grok" | "cursor" + | "dsh" ) } @@ -189,6 +194,7 @@ impl fmt::Display for AgentType { AgentType::Pi => write!(f, "Pi"), AgentType::Grok => write!(f, "Grok"), AgentType::Cursor => write!(f, "Cursor"), + AgentType::Dsh => write!(f, "DeepSeek Harness (DSH)"), // Prefer the registered display name; fall back to the raw id when // the registry has not been hydrated (or the agent was deleted // while conversations still reference it). @@ -221,6 +227,7 @@ mod tests { (AgentType::Pi, "pi"), (AgentType::Grok, "grok"), (AgentType::Cursor, "cursor"), + (AgentType::Dsh, "dsh"), ]; for (agent, wire) in expected { assert_eq!(agent.as_wire(), wire); @@ -288,6 +295,7 @@ mod tests { // Shadowing a built-in would make `from_wire` ambiguous. "codex", "claude_code", + "dsh", ] { assert!( !is_valid_custom_agent_id(bad), diff --git a/src/lib/types.ts b/src/lib/types.ts index 107c5afe3..44028d373 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,4 +1,4 @@ -/** The twelve agents codeg ships hand-written support for. */ +/** The thirteen agents codeg ships hand-written support for. */ export type BuiltinAgentType = | "claude_code" | "codex" @@ -12,6 +12,7 @@ export type BuiltinAgentType = | "pi" | "grok" | "cursor" + | "dsh" /** * Which agent backs a conversation. @@ -694,6 +695,7 @@ export const AGENT_DISPLAY_ORDER: BuiltinAgentType[] = [ "pi", "grok", "cursor", + "dsh", ] const AGENT_DISPLAY_ORDER_INDEX = new Map( @@ -725,6 +727,7 @@ export const ALL_AGENT_TYPES: BuiltinAgentType[] = [ "pi", "grok", "cursor", + "dsh", ] export const MODEL_PROVIDER_AGENT_TYPES: BuiltinAgentType[] = [ @@ -1033,6 +1036,7 @@ export const AGENT_LABELS: Record = { pi: "Pi", grok: "Grok", cursor: "Cursor", + dsh: "DeepSeek Harness (DSH)", } export const AGENT_COLORS: Record = { @@ -1048,6 +1052,7 @@ export const AGENT_COLORS: Record = { pi: "bg-[#0D9488]", grok: "bg-neutral-900", cursor: "bg-zinc-800", + dsh: "bg-[#4D6BFE]", } // ACP connection status (matches Rust ConnectionStatus) From 97dbc3fabbfe94a86806e9160611edcb703e9f25 Mon Sep 17 00:00:00 2001 From: asteroida123 <264808420+asteroida123@users.noreply.github.com> Date: Fri, 14 Aug 2026 12:23:01 +0800 Subject: [PATCH 2/7] Enable DSH by default in agent settings DSH was missing from default_enabled(), so it landed disabled and the launch gate rejected connect with 'DeepSeek Harness (DSH) is disabled in settings'. Add the arm plus a regression test asserting every built-in is enabled by default (the pattern is a matches!, not an exhaustive match, so the compiler cannot catch the omission). --- .../src/db/service/agent_setting_service.rs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src-tauri/src/db/service/agent_setting_service.rs b/src-tauri/src/db/service/agent_setting_service.rs index 528ab1c11..ff0d9ff0e 100644 --- a/src-tauri/src/db/service/agent_setting_service.rs +++ b/src-tauri/src/db/service/agent_setting_service.rs @@ -40,6 +40,7 @@ fn default_enabled(agent_type: AgentType) -> bool { | AgentType::Pi | AgentType::Grok | AgentType::Cursor + | AgentType::Dsh // A user who just registered a custom agent wants to use it. | AgentType::Custom(_) ) @@ -228,3 +229,27 @@ fn is_sqlite_full_error(err: &DbError) -> bool { let message = err.to_string(); message.contains("database or disk is full") || message.contains("(code: 13)") } + +#[cfg(test)] +mod tests { + use super::*; + + /// Every built-in must be enabled by default. A newly added built-in + /// without a `default_enabled` arm silently lands disabled in settings, + /// and the launch gate then rejects it at connect time — this test turns + /// that into a compile-visible failure instead of a runtime surprise. + #[test] + fn every_builtin_agent_is_enabled_by_default() { + for agent_type in crate::acp::registry::builtin_acp_agents() { + assert!( + default_enabled(agent_type), + "built-in {agent_type:?} must be enabled by default" + ); + } + } + + #[test] + fn custom_agents_are_enabled_by_default() { + assert!(default_enabled(AgentType::custom("goose").unwrap())); + } +} From 32648ced8b078a5a6078936b68f913a99258c6d2 Mon Sep 17 00:00:00 2001 From: asteroida123 <264808420+asteroida123@users.noreply.github.com> Date: Fri, 14 Aug 2026 12:34:46 +0800 Subject: [PATCH 3/7] Add DeepSeek Harness (DSH) whale icon --- src/components/agent-icon.tsx | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/components/agent-icon.tsx b/src/components/agent-icon.tsx index b2c72f015..f6ff9d9c1 100644 --- a/src/components/agent-icon.tsx +++ b/src/components/agent-icon.tsx @@ -389,6 +389,34 @@ const CursorMonoIcon = memo(function CursorMonoIcon({ ) }) +const DshColorIcon = memo(function DshColorIcon({ size = "1em" }: IconProps) { + // DeepSeek whale mark, approximated in the brand blue. + return ( + + DeepSeek Harness + + + + + ) +}) + // eslint-disable-next-line @typescript-eslint/no-explicit-any type AnyIcon = React.ComponentType @@ -399,6 +427,7 @@ const COLOR_ICONS: Partial> = { open_claw: OpenClawColorIcon, kimi_code: KimiCodeColorIcon, pi: PiColorIcon, + dsh: DshColorIcon, } const MONO_ICONS: Partial> = { From f49649aa3942b694d8ed2dfbecfc173f2d0d27f4 Mon Sep 17 00:00:00 2001 From: asteroida123 <264808420+asteroida123@users.noreply.github.com> Date: Fri, 14 Aug 2026 12:39:29 +0800 Subject: [PATCH 4/7] Use official DeepSeek whale mark for DSH icon --- src/components/agent-icon.tsx | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/components/agent-icon.tsx b/src/components/agent-icon.tsx index f6ff9d9c1..2dabbe6ce 100644 --- a/src/components/agent-icon.tsx +++ b/src/components/agent-icon.tsx @@ -390,29 +390,17 @@ const CursorMonoIcon = memo(function CursorMonoIcon({ }) const DshColorIcon = memo(function DshColorIcon({ size = "1em" }: IconProps) { - // DeepSeek whale mark, approximated in the brand blue. + // Official DeepSeek whale mark (deepseek-harness website/public/favicon.svg). return ( DeepSeek Harness - - - + ) }) From b4b98117f9e8a83e64592a33ead625d9c5aba23a Mon Sep 17 00:00:00 2001 From: asteroida123 <264808420+asteroida123@users.noreply.github.com> Date: Fri, 14 Aug 2026 12:40:48 +0800 Subject: [PATCH 5/7] Pin DSH adapter to 0.1.1 --- src-tauri/src/acp/registry.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src-tauri/src/acp/registry.rs b/src-tauri/src/acp/registry.rs index e33cb92fb..3aead59ae 100644 --- a/src-tauri/src/acp/registry.rs +++ b/src-tauri/src/acp/registry.rs @@ -755,8 +755,8 @@ pub fn get_agent_meta(agent_type: AgentType) -> AcpAgentMeta { name: "DeepSeek Harness (DSH)", description: "DeepSeek Harness coding agent (ACP, automation-only)", distribution: AgentDistribution::Npx { - version: "0.1.0", - package: "@asteroida/dsh-codeg-adapter@0.1.0", + version: "0.1.1", + package: "@asteroida/dsh-codeg-adapter@0.1.1", cmd: "dsh-codeg", args: &[], env: &[], @@ -950,8 +950,8 @@ mod tests { ); assert_npx_version( AgentType::Dsh, - "0.1.0", - "@asteroida/dsh-codeg-adapter@0.1.0", + "0.1.1", + "@asteroida/dsh-codeg-adapter@0.1.1", Some("20.0.0"), ); } From 67fcb6fd11c05af134d7fbf6a69267e4e9b3cb22 Mon Sep 17 00:00:00 2001 From: asteroida123 <264808420+asteroida123@users.noreply.github.com> Date: Fri, 14 Aug 2026 12:50:07 +0800 Subject: [PATCH 6/7] Shorten DSH label to DeepSeek Harness --- src-tauri/src/acp/registry.rs | 2 +- src-tauri/src/models/agent.rs | 2 +- src/lib/types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/acp/registry.rs b/src-tauri/src/acp/registry.rs index 3aead59ae..03d7ff959 100644 --- a/src-tauri/src/acp/registry.rs +++ b/src-tauri/src/acp/registry.rs @@ -752,7 +752,7 @@ pub fn get_agent_meta(agent_type: AgentType) -> AcpAgentMeta { // DSH's automation-only ACP bridge rejects mcpServers, same as // OpenClaw; forwarding any entry makes session/new fail. supports_mcp: false, - name: "DeepSeek Harness (DSH)", + name: "DeepSeek Harness", description: "DeepSeek Harness coding agent (ACP, automation-only)", distribution: AgentDistribution::Npx { version: "0.1.1", diff --git a/src-tauri/src/models/agent.rs b/src-tauri/src/models/agent.rs index 1a4668bda..ddb2bbcd1 100644 --- a/src-tauri/src/models/agent.rs +++ b/src-tauri/src/models/agent.rs @@ -194,7 +194,7 @@ impl fmt::Display for AgentType { AgentType::Pi => write!(f, "Pi"), AgentType::Grok => write!(f, "Grok"), AgentType::Cursor => write!(f, "Cursor"), - AgentType::Dsh => write!(f, "DeepSeek Harness (DSH)"), + AgentType::Dsh => write!(f, "DeepSeek Harness"), // Prefer the registered display name; fall back to the raw id when // the registry has not been hydrated (or the agent was deleted // while conversations still reference it). diff --git a/src/lib/types.ts b/src/lib/types.ts index 44028d373..f282b3587 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1036,7 +1036,7 @@ export const AGENT_LABELS: Record = { pi: "Pi", grok: "Grok", cursor: "Cursor", - dsh: "DeepSeek Harness (DSH)", + dsh: "DeepSeek Harness", } export const AGENT_COLORS: Record = { From 13208cd09c467907270bd207b6ed31cd8bccd1ac Mon Sep 17 00:00:00 2001 From: asteroida123 <264808420+asteroida123@users.noreply.github.com> Date: Sat, 15 Aug 2026 00:17:33 +0800 Subject: [PATCH 7/7] Fix prettier formatting for DSH icon --- src/components/agent-icon.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/agent-icon.tsx b/src/components/agent-icon.tsx index 2dabbe6ce..83141f7b6 100644 --- a/src/components/agent-icon.tsx +++ b/src/components/agent-icon.tsx @@ -400,7 +400,11 @@ const DshColorIcon = memo(function DshColorIcon({ size = "1em" }: IconProps) { xmlns="http://www.w3.org/2000/svg" > DeepSeek Harness - + ) })