Codewhale 集成 DeepSeek Harness(DSH):codewhale integrations dsh官方连接指南
【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale
codewhale integrations dsh把用户已安装的官方 DeepSeek Harness(dsh,npm 包@deepseek-ai/dsh)接入 Codewhale,让 DSH 成为一个「集成式 harness 表面」,而 Codewhale 继续保有 Fleet 配置、Provider/模型选择、权限、凭据与生命周期的一切主导权。读完本文,你将掌握:连接前如何理解 Codewhale 与 DSH 各自的数据与权限边界、八种连接状态及对应的处置命令、overlay 补丁的生成规则、可选的 DSH 插件 bundle(皮肤与海洋动画场景)机制,以及彻底移除连接而完全不触碰$DSH_HOME的方法。
本文依据仓库文档 docs/INTEGRATIONS_DSH.md 撰写,并对照其参考实现(crates/tui/src/integrations/dsh/ 下的mod.rs、detect.rs、identity.rs、bundle.rs、skin.rs、scene.rs、brand.rs、receipt.rs与配套测试tests.rs)逐条印证。
连接什么,不连接什么:边界先行的设计
整个集成建立在“DSH 保持独立、Codewhale 保持权威”的信任模型之上。DSH 不是第二个 Fleet 调度器,也绝不是对 Codewhale 权限体系的绕过。Codewhale 只使用 DSH公开文档化的接缝(seam),见下表:
| DSH 接缝 | Codewhale 的用法 |
|---|---|
dsh --version/dsh --help | 只读探测(绝不初始化任何 profile) |
$DSH_HOME(或~/.dsh) | 只读盘点:profile 名称、settings.yaml顶层命名空间、.credentials.yaml是否存在且权限为0600。只读结构,从不读值 |
--patch <file>overlay | Codewhale 在自己的 home 下写入唯一一份overlay,启动时传给 DSH |
DSH_PERMISSION_MODE环境变量 | 镜像 Codewhale 的权限姿态 |
--profile web/--profile headless | DSH 随发行版自带的两个 profile;由 DSH 自己首次启动时初始化(其自有文档化行为) |
实现层面对“只读探测”有硬性约束。在 detect.rs 中,DshDetection只记录dsh --version输出、launcher help 是否宣称支持--patch、$DSH_HOME是否存在及来源、profiles/目录名、settings.yaml顶层键、凭据文件的存在性与权限位——字段注释明确写着“values are never read / Credential values are never read”。即使调用dsh --version/--help,ProcessRunner也会注入DSH_TELEMETRY_DISABLED=1作为硬性遥测退出开关(见 detect.rs),探测进程以/dev/null作为 stdin、从不初始化 profile。
Codewhale 只会写入$CODEWHALE_HOME/integrations/dsh/目录(mod.rs 定义了INTEGRATION_DIR、OVERLAY_FILE、RECEIPT_FILE等常量),其中:
codewhale.patch.yml— overlay 补丁。只含身份信息:Provider 路由、模型、base URL、以及(原生 DeepSeek 路由下的)reasoningEffort。对所有非原生路由,它会在 DSH 的llm-pi-ai适配器上声明一条codewhale-<provider>路由,并用api:声明该路由自己的 wire 方言(openai-completions、openai-responses或anthropic-messages),用apiKeyEnv指向 Provider 的标准环境变量——只写变量名,绝不写值。无密钥的本地路由(回环 Ollama / LM Studio / vLLM / SGLang)不携带任何凭据引用。receipt.json— 当前连接记录,外加connect/update/disable/enable/remove事件的只追加历史,每条含 overlay SHA-256、dsh 版本、$DSH_HOME、映射身份、权限模式与时间戳(文档另见 docs/RECEIPTS.md)。每个事件同时追加进$CODEWHALE_HOME/audit.log(mod.rs 的apply_plan中调用audit::log_sensitive_event)。bundle/— 仅在install-bundle之后出现(详见下文)。Codewhale 调色板皮肤与 ambient 海洋场景放在这里、位于 bundle 的 client 半区——不导出任何样式表。
Codewhale绝不:
- 复制、打印或内嵌 API Key、OAuth 文档、环境机密、提示词或文件系统内容。特别地:如果 Codewhale 自己通过
--api-key或 keyring 把某个凭据物化到了当前进程,该凭据会在启动子进程时被剥离;而用户自己在 shell 里导出的密钥则保持原样(mod.rs 的launch_env_strip_list只剥离“Codewhale 桥接”的变量,区分依据是凭据来源); - 写入
$DSH_HOME(settings、凭据、profiles、会话); - 修改已安装的
@deepseek-ai/dsh包文件; - 静默切换到云模型或放宽权限:Codewhale
read-only→ DSHread-only;其余情况 →workspace-write;只有同时满足--allow-full-access且Codewhale 处于全访问姿态(sandbox_mode = "danger-full-access"/ yolo)时才授予danger-full-access。
这套“只写自己名下、只读对方结构”的边界在模块文档字符串里写得很明确(mod.rs),并在 tests.rs 中用大量 StubRunner 测试锁定。
八种连接状态:谁可启动、如何处置
集成状态是一个显式枚举(mod.rs 的DshIntegrationState,序列化为 kebab-case 标签),status/plan依据compute_status的结果映射状态并给出下一步动作:
| 状态 | 含义 | 启动(launch) |
|---|---|---|
not-installed | dsh不在PATH上 | 拒绝 |
offline | 存在dsh但--version执行失败(含输出无法解析) | 拒绝 |
incompatible | 版本低于0.1.0-rc.6,或 launcher 未宣称支持--patch | 拒绝 |
detected | dsh 可用但尚无 Codewhale overlay | 拒绝(需先connect) |
connected | overlay 与当前 Codewhale 路由一致 | 允许 |
stale-config | 路由变更、overlay 被 Codewhale 外部修改,或 overlay 缺失 | 拒绝(需update) |
stale-version | 已连接,但 dsh 比验证版本更新 | 允许,但标记为“未验证” |
disabled | overlay 保留但启动被拒绝 | 拒绝(需enable) |
版本判定是精确的语义化版本比较。dsh的版本字符串形如MAJOR.MINOR.PATCH[-rc.N],detect.rs 中的DshVersion::parse与cmp_semver正确处理了“同一 base 下任何 rc 都排在正式版之前”的语义;classify_version再结合 launcher help 是否出现--patch得出Verified/NewerUnverified/Incompatible/Offline/Unparsed五档兼容性(detect.rs)。集成验证基准版本常量写死为VERIFIED_DSH_VERSION = "0.1.0-rc.6"(detect.rs),与文档表述一致。
一个常见且容易踩的坑:stale-config不只由“Codewhale 路由变了”触发。compute_status(mod.rs)会比对磁盘上 overlay 的 SHA-256与 receipt 里记录的overlay_sha256,只要 overlay 文件被手工编辑过即视为 drift;对已安装 bundle 的情况,还会检查cordis.patch.yml、lib/client.js、profile manifest 是否一致(详见下文 bundle 章节)。
status、plan、/setup tools(Tools 与 MCP 步骤)以及codewhale doctor都是无副作用操作:它们只读文件系统与调用dsh --version/--help。模块里compute_status与status_line的注释都强调这一点(mod.rs)。
命令参考
codewhale integrations dsh status [--json] codewhale integrations dsh plan [--profile web|headless] [--allow-full-access] [--skin] [--json] codewhale integrations dsh connect [--profile web|headless] [--allow-full-access] [--skin] [--yes] codewhale integrations dsh update [--profile …] [--allow-full-access] [--skin true|false] [--ocean true|false] [--yes] codewhale integrations dsh launch [--profile web|headless] [--dry-run] [-- <dsh app args>] codewhale integrations dsh disable codewhale integrations dsh enable codewhale integrations dsh remove [--yes] codewhale integrations dsh install-bundle [--app web|headless] [--yes] codewhale integrations dsh remove-bundle [--yes]命令族注册在integrations dsh之下(CLI 帮助文案见 crates/cli/src/lib.rs),具体分发与打印逻辑位于 crates/tui/src/integrations/cli.rs。
各子命令行为要点:
status [--json]— 无副作用汇报上述八种状态、当前路由可携带性(carry-ability)、shadowing 命名空间与插件路径可用性;--json输出结构化结果。Detected 状态的一行汇报会提前把“当前路由能否被 DSH 承载”说出来,让用户在运行plan之前就看到潜在的拒绝(mod.rs)。plan [--profile …] [--allow-full-access] [--skin] [--json]— 精确列出将要写入的文件、映射身份、权限模式、disclosure 与overlay 全文,但什么都不写(mod.rs 的plan返回DshPlan,overlay_text、overlay_sha256、launch_command、env_exports、disclosures一应俱全)。connect— 执行计划:创建$CODEWHALE_HOME/integrations/dsh/(POSIX 下目录权限0700,见 mod.rs)、原子写入 overlay、落 receipt、写审计日志。update— 重写 overlay 与 receipt;若已安装 bundle,则就地重建cordis.patch.yml(及皮肤文件),无需 pnpm 重跑。皮肤 / 海洋的开关语义见下文。launch [--dry-run] [-- <dsh app args>]— 在 Codewhale 工作区运行DSH_PERMISSION_MODE=<mode> dsh --profile <p> --patch <overlay> …,使用用户自己的$DSH_HOME,因此凭据、会话与 profile 始终归用户所有;--dry-run只打印将执行的进程(LaunchSpec::display),并不真的 spawn。bundle 已安装时默认改用--profile codewhale且不带--patch(profile 自身携带身份);launch --profile web|headless则仍走 overlay。子进程继承了 stdio(mod.rs 的launch_spec/spawn_launch)。disable/enable— 切换disabled标志。overlay 保留在磁盘上,disable后一切启动被拒绝,enable恢复(mod.rs)。remove [--yes]— 仅删除 overlay 与历史遗留的 0.9.8 皮肤文件,追加removereceipt,绝不触碰$DSH_HOME;若 bundle 仍安装着则拒绝(mod.rs)。install-bundle/remove-bundle— 见下文插件路径章节。
connect、update、remove都会先打印精确计划(文件、身份、权限模式、disclosure 与 overlay 文本),并要求确认;当 stdin 不是终端时需--yes。
overlay 补丁长什么样:身份即全部
overlay 由 identity.rs 的render_overlay确定性生成——对同一身份输入,输出字节完全一致,这正是它能被 SHA-256 追踪 drift 的前提。文件首部是固定的注释块(声明生成来源、禁止手改、不写凭据),随后是配置行。
原生 DeepSeek Chat Completions 路由(provider=deepseek且 wire 方言为 Chat Completions)映射到 DSH 自带的@deepseek-ai/dsh-llm-deepseek(路由 iddeepseek-official),生成的 overlay 形如(示意,值取决于你的实际配置):
# DeepSeek Harness connected through Codewhale. # Generated by `codewhale integrations dsh connect`; do not edit by hand. # Identity only: no API key, token, or credential document is written here. # codewhale.provider=deepseek codewhale.model=deepseek-chat codewhale.workspace=/path/to/workspace - id: agent-default-model name: '@deepseek-ai/dsh-agent-default-model' config: provider: deepseek-official model: 'deepseek-chat' - id: llm-deepseek name: '@deepseek-ai/dsh-llm-deepseek' config: baseURL: 'https://api.deepseek.com' reasoningEffort: high models: - id: 'deepseek-chat' name: 'deepseek-chat'非原生 / 非 Chat Completions 方言的路由则在@deepseek-ai/dsh-llm-pi-ai上声明一条codewhale-<provider>路由(路由 id 由 provider id 规范化生成,见 identity.rs),示意:
- id: agent-default-model name: '@deepseek-ai/dsh-agent-default-model' config: provider: codewhale-<provider> model: '<model-id>' - id: llm-pi-ai name: '@deepseek-ai/dsh-llm-pi-ai' config: providers: 'codewhale-<provider>': displayName: '<Provider 显示名> (via Codewhale)' apiKeyEnv: '<标准密钥环境变量名>' api: openai-completions # 或 openai-responses / anthropic-messages baseURL: 'https://<endpoint>' models: - id: '<model-id>' name: '<model-id>'注意几处细节:
- 无密钥本地路由(keyless loopback Ollama/LM Studio/vLLM/SGLang)没有
apiKeyEnv行;有凭据的路由只写环境变量名字。向 DSH 的凭据发现机制(自身环境或$DSH_HOME/.credentials.yaml)负责解析值——Codewhale 从不转交密钥(identity.rs 的 disclosure 文本明示这一点)。 - wire 方言被原样携带,绝不被近似:Chat Completions 路由声明
api: openai-completions,OpenAI Responses 方言的路由(例如默认的deepseek/deepseek-v4-flash)声明api: openai-responses,Anthropic Messages 方言声明api: anthropic-messages。这依据的是已安装适配器自身的声明(对@deepseek-ai/dsh@0.1.0-rc.6验证过):@deepseek-ai/dsh-llm-deepseek的deepseek-official路由只说 Chat Completions(其唯一 wire 调用 POST 到<baseURL>/chat/completions,无协议切换),而@deepseek-ai/dsh-llm-pi-ai的手写路由 schema 对api:恰好接受openai-completions | openai-responses | anthropic-messages(identity.rs)。因此:DeepSeek Chat 路由走原生适配器(可带推理档位),其余方言——包括 DeepSeek 自己的 Responses 方言模型——都走一条声明自己方言的codewhale-*pi-ai 路由。
推理档位(reasoning tier)如何映射
只有原生 DeepSeek 路由会映射推理档位,且收敛到 DSH 的三个取值:off | high | max。映射函数在 identity.rs,测试覆盖见 tests.rs:
| Codewhale 推理档位 | DSHreasoningEffort |
|---|---|
off/none/disabled/false | off |
minimal/low/medium/mid/high/auto | high |
xhigh/max/maximum/highest/ultra/ultracode | max |
| 其余未知值 / 未显式配置 | 不写该字段(DSH 用自身默认) |
手写声明(hand-declared)的codewhale-*路由不发送任何 effort 参数——因为各 Provider 的 wire 拼写未经逐一验证,overlay 宁可省略也不猜测;对应的 disclosure 会明确告知这一点。
权限如何镜像
权限映射规则(identity.rs 的permission_mode_for):
- Codewhale
sandbox_mode = read-only→ DSHread-only; - 其余默认 →
workspace-write(即使 Codewhale 审批策略为never,DSH 也保持自己的 workspace-write + 每次文件操作前询问,不照搬 deny); - 仅当 Codewhale 处于全访问姿态(
yolo=true或sandbox_mode ∈ {danger-full-access, external-sandbox})且显式传了--allow-full-access时 → DSHdanger-full-access;否则即使 Codewhale 全访问,DSH 也会被压回workspace-write并给出提示。
任何缩权或无法传达的事实都会变成plan的 disclosure,而不是静默吞掉。
plan 必须披露什么
- shadowing 命名空间:DSH 会按字段把用户
settings.yaml的agent-default-model、llm-deepseek、llm-pi-ai各节逐字段层叠在 overlay 之上。如果这些节存在,DSH 里已保存的选择可能盖住被钉死的身份,直到用户在 DSH 中清除它;status/plan会把它们列出来(mod.rs)。 - 推理档位只在原生 DeepSeek 路由下映射;手写声明路由不发送 effort 参数。
- wire 方言原样携带(见上),不做近似。
- 什么会被拒绝:内嵌凭据的 base URL(userinfo,即
http://user:pass@host)或带 query/fragment 的 base URL 永远不会被复制进 overlay——plan直接失败并点名当前provider/model与原因;status则会在plan运行之前就显示当前路由的可携带性。这一检查实现在 identity.rs 的base_url_is_structural,同时校验 scheme 必须是http/https。 - profile 尚未初始化时,会提示 DSH 将在首次启动时自行创建
$DSH_HOME/profiles/<p>(DSH 自己的文档化行为)。 --skin/--ocean相关披露(见下)。
DSH 插件路径:install-bundle的皮肤与场景
--patch是默认路径,因为它只需要 launcher。而DSH 文档化的插件机制则作为显式 opt-in 提供:
codewhale integrations dsh install-bundle [--app web|headless] [--yes] codewhale integrations dsh remove-bundle [--yes]install-bundle需要一个已存在的连接,并且PATH上必须有pnpm(dsh 会向外调用它)。没有 pnpm 时status显示plugin path: not available: pnpm missing …且命令拒绝执行(探测逻辑见 bundle.rs)。它做三件事:
- 物化一个 npm 形状的 bundle 包到
$CODEWHALE_HOME/integrations/dsh/bundle/,由 bundle.rs 的render_bundle_files生成:package.json:包名codewhale-dsh-bundle、private、MIT、版本形如<codewhale version>+dsh.<patch sha12>(bundle.rs);"dsh": {"bundle": {"patch": "./cordis.patch.yml"}};额外携带codewhale元数据块(generated_by、patch_sha256、skin、ocean、skin_sha256、brand_sha256、ocean_scene_sha256等);cordis.patch.yml:身份 overlay(与--patch文件内容一致),皮肤开启时末尾追加一行 skin insert;README.md、NOTICE.md(保留 DSH 的 MIT 声明);- 皮肤开启时还有
lib/index.js+lib/client.js(palette 插件,除非--ocean false否则内嵌海洋场景)。
- 运行文档化的
dsh plugin --profile codewhale add <path>两次(bundle.rs):第一次加 DSH 自带的 app bundle(@deepseek-ai/dsh-web-app或dsh-headless,从已安装 launcher 链接过来以便 profile 能启动,无需联网),第二次加 Codewhale bundle,让它的行最后 patch。DSH 会创建专用profile$DSH_HOME/profiles/codewhale(package.json里是link:依赖、pnpm-lock.yaml、node_modules链接)。用户的web/headlessprofile绝不被触碰。 - 记录
install_bundlereceipt:profile 目录、bundle 目录、包版本、patch SHA-256、app bundle 来源、pnpm 版本,以及dsh plugin输出的 SHA-256 摘要——输出文本本身不落盘(只存摘要)。
之后dsh --profile codewhale单独启动即携带身份(可用dsh --profile codewhale --dump-config验证),launch默认使用该 profile、不再需要--patch;而launch --profile web|headless仍走 overlay。因为 profile 依赖是指向 Codewhale 所辖目录的link:,update可以就地重写cordis.patch.yml与皮肤文件——不需要 pnpm 重跑。
Stale 检测覆盖 bundle(mod.rs 与 bundle.rs):bundle patch 被改动或缺失、patch 与 overlay 不一致、lib/client.js缺失/被改/在 receipt 记录 skin=off 时却存在、海洋场景与 receipt 的ocean决定不一致、或 profile manifest 不再列出codewhale-dsh-bundle——任何一条都会报告stale-config并指向update(若 profile 清单本身异常,则提示先remove-bundle再install-bundle)。
remove-bundle运行dsh plugin --profile codewhale remove codewhale-dsh-bundle并只删除 Codewhale 自己拥有的 bundle 文件。profile 目录本身(连同 dsh 记录在其中的 app bundle 链接)属于 DSH,原样保留,receipt 中会注明。remove在 bundle 仍安装时拒绝执行。
皮肤:通过overrideTokens施加的 Codewhale 调色板
DSH 0.1.0-rc.6 有一个文档化的 token 级主题接缝:ThemeService.overrideTokens(source, tokens)(位于@deepseek-ai/dsh-client-ui-theme),它把一薄层--dsw-alias-*变量叠在当前主题之上(逐 token、后层生效)并返回 disposer。Codewhale 皮肤用的正是这个机制(skin.rs 模块头注释),并且只能通过 bundle profile 生效(dsh --profile codewhale);--patchoverlay 从不携带皮肤代码,所以launch --profile web|headless保持纯 overlay + 原生主题。
install-bundle默认开启皮肤。开启时 bundle 是一个双面(dual-face)DSH 插件:
package.json增加"dsh": {"client": {"platform": "web", "immediately": true, "inject": ["@deepseek-ai/dsh-client-ui-theme"]}}和完整的exportsmap(.、./client、./package.json)。Node 的 exports map 是穷举式的:cordis loader 导入裸包名(需要.),dsh-client-modules 要解析<name>/package.json(需要./package.json),两者缺一就会报ERR_PACKAGE_PATH_NOT_EXPORTED、导致 client 半区被静默丢弃——注释里特别点明了这个坑(bundle.rs);lib/index.js是 no-op 的 Node cordis 入口(让行能挂载);lib/client.js是一个纯window.__ModuleLoader__.load({ id, factory })脚本,其 factory 在ctx.effect内调用ctx.theme.overrideTokens("codewhale-dsh-bundle", TOKENS)并返回 disposer(inject: ["theme"]保证在 theme service 存在之后才执行);cordis.patch.yml在身份行之后以- insert: [{ id: codewhale-skin, name: codewhale-dsh-bundle }]收尾。
TOKENS是一张有界的--dsw-alias-*映射表(背景、边框、brand、按钮、标签、error/success/warn 状态、代码块、滚动条、toast、tooltip),对应 light/dark 两套取值,全部由 TUI 的真实调色板(crate::palette,Blue Stage 暗/亮两套)渲染而来(skin.rs)——只含调色板常量,不含任何用户数据或环境信息。receipt 记录skin: true|false与skin_sha256(渲染出的 TOKENS JSON 的 SHA-256);package.json里codewhale.skin_sha256携带同一哈希,任何一侧被改都会在状态机里暴露为 drift。
Whale Brothers / Codewhale 身份落款
皮肤还会挂载一个小型插件自有的落款,位于界面右上角,内容为WHALE BROTHERS、CODEWHALE、× DEEPSEEK HARNESS。它是增量式的:通过 DSH 帧级shell.overlay槽位注册,不替换也不重写 DeepSeek Harness 的 branding 或控件;使用当前皮肤的 token、忽略指针输入、在宽度低于 760px 时收成一个紧凑的 whale 标记,随 client 插件卸载而移除。package.json以codewhale.brand_sha256记录生成片段的哈希。
海洋场景(鲸与字形小鱼)
皮肤开启时lib/client.js还携带一个 ambient 海洋场景:一个全视口<canvas>(position: fixed; inset: 0; z-index: -1; pointer-events: none,画在#root之下、body 背景之上),含可见的深度渐变、一近一远两头鲸剪影(钝头、低背鳍隆起、长胸鳍、水平尾鳍 ±10° 摆动),沿柔和正弦缓缓横穿,位置偏向画面下半部与顶边以免越过 composer 卡片;头部偶尔喷出一小串气泡;一小群 Codewhale 字形小鱼(><>/><o>,等宽字体)跟随漫游的领队做精简版群游;另有淡出的上升气泡。调色取自皮肤自身 token(surface_bg、accent_primary、text_body、text_dim,明暗两套);场景监听 DSH 的theme/change事件,随应用一起切换明暗。
为了在 canvas 后透出画面,client 在场景开启时把两个背景 token 以半透明 rgba 重新下发(在原本不透明的表格之上):--dsw-alias-bg-base(α 0.42;边框与中央列都会绘制它)与--dsw-specific-sidebar-fill(α 0.78,保持导航区可辨)。面板、composer、代码块及所有其他层保持不透明。设计细节与透明度遮罩常量见 scene.rs。
性能预算:requestAnimationFrame限制在约 30 fps、document.hidden时暂停、prefers-reduced-motion: reduce下只画一帧静态画面、感知 device-pixel-ratio、无每帧分配(复用 typed array)。场景只能随client.js发布,因为 dsh-client-modules 每个 client 插件只服务一个文件(/plugins/<id>/client.js),没有lib/scene.js——场景脚本以include_str!("scene.js")内嵌(scene.rs)。package.json记录codewhale.ocean与codewhale.ocean_scene_sha256,receipt 记录ocean: true|false。
下图是在 DSH 0.1.0-rc.6 上对两种配色方案的实际验证结果(明/暗,1100×687):
该集成在两种 scheme 下均无 console 错误、帧画面确有差异、文字保持可读。
关闭开关,从小到大排列:
- 在浏览器里设
localStorage["codewhale.ocean"] = "off",或给<body>加类codewhale-ocean-off——只在该机器上同时跳过 canvas 与半透明 token; - 控制台调用
window.__codewhaleOcean.stop()/.start()/.setIntensity(0..1)(句柄常量见 scene.rs); codewhale integrations dsh update --ocean false重新生成不含场景的client.js(默认开启;裸update保持上一次的选择;--skin false隐含无场景)。
逃生舱:codewhale integrations dsh update --skin false重新生成不带 client 半区、不带 insert 行的 bundle(无需 pnpm——link:依赖让文件就地生效);update --skin true重新打开;裸update保持上次选择。install-bundle本身不接受--skin旗标;connect --skin/plan --skin只是把同样的决定记下来供之后的 bundle 安装使用,不写额外文件。remove-bundle会连同 Codewhale 所辖 bundle 文件一起删掉 client 半区,overrideTokens层随插件卸载而被 dispose,DSH 原生主题随即恢复。
0.9.8 时代的--skinCSS/预览导出(codewhale-dsh-skin.css、codewhale-dsh-skin-preview.html)已经移除:因为dsh-client-ui-layout把 alias token 写为内联body.style属性,任何样式表规则在构造上都会输给它。connect/update会顺手删除这些遗留文件(mod.rs)。
移除与归属
remove只删除$CODEWHALE_HOME/integrations/dsh/下的 overlay(以及任何 0.9.8 皮肤/预览遗留),追加一条removereceipt,从不触碰$DSH_HOME或已安装的包。DSH 在连接前后的行为完全一致,集成随时可以干干净净地撤走。
最后一点归属说明:DeepSeek Harness © 2026 DeepSeek,MIT 许可;本集成只是调用用户已安装的 launcher,并不重新分发它。这也不是Codewhale 的原生功能——所有界面上的标注都是 “DeepSeek Harness connected through Codewhale”(常量RELATIONSHIP_LABEL见 mod.rs),身份与归属始终如实呈现。
【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考