npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-qoder-link

v1.0.8

Published

DeepSeek Harness LLM adapter for Qoder CN subscriptions, built on the official @qodercn-ai/qodercn-agent-sdk. Reuses the local qoderclicn login, and exposes a fully configurable settings page (per-model context window, session pool, timeouts, model deny l

Readme

dsh-qoder-link

把 Qoder CN 订阅接入 DeepSeek Harness(DSH) 的 LLM 适配器插件。

  • 基于官方 CN Agent SDK @qodercn-ai/qodercn-agent-sdk, 不逆向协议、不伪造客户端身份。
  • 零凭据:复用本机 qoderclicn 登录态,不需要 API key。
  • 带独立设置页:模型逐个启用/关闭、逐个指定上下文窗口,改动即时生效。

为什么需要它

上游 @jiamingzang/dsh-llm-qoder 只依赖国际版 SDK @qoder-ai/qoder-agent-sdk,而那个包的品牌是编译期硬编码的:

var xr = "global", zn = xr === "cn"          // ← 永远选不中 CN 分支
v = zn ? { cliCommands: ["qoderclicn"], configDirName: ".qoder-cn" }
       : { cliCommands: ["qodercli"],   configDirName: ".qoder"   }

于是只装了 qoderclicn、登录态在 ~/.qoder-cn 的机器上,它永远找不到 CLI,模型选择器里 什么都不出现。本插件改用官方 CN 包(brand: cn),从根上解决。

安装

第一步:装插件

点侧边栏的 插件 → 添加插件,把 dsh-qoder-link 填进输入框,然后点「安装」。

也可以换成另外两种来源:

  • github:k1-h2/dsh-qoder-link(或 https://github.com/k1-h2/dsh-qoder-link)——装仓库的最新提交
  • 本地目录路径——装你自己改过的版本

安装源保持默认即可(中国大陆镜像源),它只决定插件及其 npm 依赖从哪里下载。

SDK 声明了安装脚本(下载它自己的 worker runtime),pnpm 默认不执行,所以界面会弹出 「需要允许安装脚本」——点「允许这些脚本并重试」就行。授权记在当前 profile 里,只问这 一次;不授权也能用,SDK 会回退到 PATH 上的系统 qoderclicn。

装完按界面提示重启 DSH(「已安装,下次启动后加载」)。重启后设置里出现 Qoder CN 一项。

第二步:装好并登录 Qoder CN CLI

插件不持有任何凭据,内层会话直接复用本机 CLI 的登录态(SDK 的 qodercliAuth()),所以 CLI 必须装好、登录,模型列表才有内容。

设置 → Qoder CN,页面底部「Qoder CN CLI」分组点 一键配置:跑的就是随包发布的 scripts/setup-qoderclicn.bat——缺 CLI 就装,未登录就拉起浏览器 授权,输出实时打在页面上;跑完 1 秒自动收起,点「查看输出」可以再翻出来,同时模型列表自动刷新。 重新登录只重跑授权那一步,用来换账号或补一次过期的登录。这一步只支持 Windows,因为脚本是 .bat;脚本自己的输出是英文——批处理里放中文时,cmd.exe 在没有控制台被调用(正是页面这种调用 方式)会算错文件位置,把半行当命令跑,详见 NOTICE。

不想点按钮,就自己按顺序执行——那个脚本做的正是这几步:

npm install -g @qodercn-ai/qoderclicn   # CLI 本体,官网 https://qoder.com/cli
qoderclicn --version                    # 能打印版本号才算装上
qoderclicn login                        # 拉起浏览器,用 Qoder CN 账号登录
qoderclicn status                       # 列出 Username / User Type 即登录成功
qoderclicn --list-models                # 列出订阅实际可用的模型
  • 也可以直接双击 scripts/setup-qoderclicn.bat:一次做完上面全部,结尾停住等你看输出。
  • login 没有非交互参数,走浏览器授权;成功后凭证落在 ~/.qoder-cn/.auth(国际版是 .qoder, 本插件只认 CN 这一份)。
  • 登录过期或换账号:页面上点「重新登录」,或者自己重跑一次 qoderclicn login 覆盖旧凭证。
  • CLI 自带升级:qoderclicn update,装坏了用 qoderclicn rollback。
  • status 里没有 Username、或 --list-models 拉不出模型,DSH 里的模型列表就一定为空—— 先修这一步,再查插件。

设置页

设置 → Qoder CN(与「通用设置 / 模型 / 内置插件」并列的独立一项)。整页就是一张模型清单:

模型                              启用      上下文窗口
☑  Qwen3.8-Max · x0.5             ▢         [默认 · 200K  ▾]     (200K / 400K / 1M)
☑  Qwen3.8-Flash · 免费           ▢         [默认 · 200K  ▾]
☐  Kimi-K3 · x1.4                 ▢         [默认 · 200K  ▾]
  • 列表来自账号实时目录,不是写死的:上游新增的模型自动出现且默认启用。这也是「关闭」用 拒绝清单而不是允许清单存储的原因——允许清单会把后来新增的模型静默藏掉。
  • 倍率取自上游 priceFactor:0 显示为「免费」;上游没给倍率的模型不显示后缀,不凭空补数。
  • 窗口下拉列出上游为该模型声明的所有可选窗口,默认档跟随上游声明的会话窗口。 窗口越大,DSH 的自动压缩触发得越晚。
  • 顶部有搜索、只看已启用、刷新列表、全部启用 / 全部关闭,并显示 已启用 N / 总数。

高级设置(可折叠,默认收起)收纳其余 10 个标量参数:分组名称、并发会话数、列表缓存、默认 思考档位、输出上限、三个超时(工具结果 / 模型列表 / 中断宽限)、旁路轮次、模型别名。每项带中文 说明,改过的项旁边会出现「恢复默认」。

Qoder CN CLI 分组在页面底部,管第二步那件事:「一键配置」「重新登录」两个按钮,加一块只在跑 的时候展开的输出区域——结束后 1 秒自动收起,「查看输出」可以随时再展开。模型列表拉不出来时,页面 直接红字说明是本机 CLI 没配置好,并把「一键配置」放在那句提示旁边。浏览器起不了本地进程,所以按钮 走的是宿主侧的 POST /api/llm-qoder-cn/setup(mode 只有 configure 和 login 两个取值),由 插件去跑随包发布的脚本。

只服务官方模型。 Qoder CN 也提供「账号自己添加的模型」(自带 API Key 的 BYOK 路线,上游另用 一条 qoder-byok 路由承载),但 DSH 这边用不上——插件只走订阅自己的目录,因此只注册一个 provider 路由 qoder-cn,并在目录层丢弃上游标记为 user/custom 的条目。模型选择器里因此只有一个 Qoder CN 分组,没有第二个自定义分组。

用 YAML 配置

设置页之外,也可以直接在 profile 的 cordis.patch.yml 里写:

- id: llm-qoder-cn
  name: dsh-qoder-link
  config:
    displayName: Qoder CN (工作号)
    maxSessions: 4
    disabledModels: [mmodel]              # 关闭的模型,不出现在选择器里
    modelContextWindows:
      qmodel_38max: 1000000               # 按模型指定窗口(token)

常见问题

缓存命中一直显示 0%? v1.0.5 已修。根因不在映射:CLI 每轮都算出了真实用量,但在把用量帧 送出来之前会主动清零四个 token 计数(input_tokens / output_tokens / cache_read_input_tokens / cache_creation_input_tokens),只留 credits 与 context_usage_ratio;它自带一个开关(env 目录里的 EXPOSE_TOKEN_USAGE),打开后才原样送出。 src/cli.ts 现在把这个开关随子进程环境一起交给 CLI——CN 包读 QODERCN_EXPOSE_TOKEN_USAGE,国际包读 QODER_EXPOSE_TOKEN_USAGE,两个都设,因为由哪个包应答 是查找决定的。

实测(本插件跑通,同一段前缀连续两轮):

| 轮 | CLI 报的 input_tokens | 其中 cache_read | 插件上报 | 界面 | |---|---|---|---|---| | 1 | 9 811 | 0 | 输入 9 811 / 输出 860 / 缓存 0 | 命中 0% | | 2 | 10 686 | 9 805 | 输入 881 / 缓存读 9 805 / 输出 100 | 命中 92% |

第二轮那个 input_tokens 是整个 prompt(CLI 自己的 context_usage_ratio 就是 input_tokens ÷ 窗口),缓存的那部分含在里面,所以 meteredUsage() 把两个 cache 桶从 inputTokens 里减出去——DSH 的四个桶互不重叠,不减等于把缓存前缀算两遍。四个桶(含 0) 与 totalTokens 也必须齐全:harness 只在记账完整时展示每轮用量行,少一个桶又没有 totalTokens 佐证,整轮的用量详情都不显示。

哪个用量帧能信? CLI 会把用量记录挂在好几个帧上, 而只有一个是真的属于「这一次请求」:message_delta,即每次 provider 请求结束时发出的那一帧。 其余三个都是坑——message_start 与组装后的 assistant 消息里的四个计数恒为 0(请求没结束前 没有数);result 帧则是内层整轮的总和,把这个回合里每一次 provider 请求的用量全部相加。

一个宿主 step 只对应一次 provider 请求,但内层的一"轮"要等模型不再调用工具才结束——宿主工具每往返 一次就是一次新请求,全部发生在同一个内层回合里。所以 result 帧的数在长 agentic 运行后会是真实 prompt 的若干倍:实测一个让模型连调四次工具的回合,各请求分别用 608/705/771/837,result 帧报 2 921。若把这个数当成当前上下文,长跑结束后 DSH 的上下文计量会被顶到 ~9.8M / 1M(100%)并一直挂着,直到下一次取样才回正(开发中确实这么踩过一次)。

现在占用样本只由 requestUsageSample() 提供:仅接受带真实计数(至少一个桶 > 0) 的 stream_event 帧,assistant 与 result 帧一律不采信。contextUsageRatio 仍是每请求的 prompt 比率,所以回退路径不受影响。

仍然退回估算的只有三种情况:CLI 版本早于这个开关、SDK 回退到进程内 worker transport(拿不到自定义 环境)、某一轮在结果帧之前就结束了。那时 usage() 按「真实用量帧 → CLI 的 context 比率 → 字符 估算」三级回退,上游一旦有数就立刻切过去。

上下文占用是按什么算的? 拿到真实计量时就是 provider 自己数的最后一次请求的 prompt: inputTokens + cacheRead + cacheWrite,除以窗口。拿不到时,上游每帧仍带 context_usage_ratio ——它自己量出的「上下文用了多少」——本插件把它乘上窗口换成 token,再交给 DSH 的计量环。

这条回退路径上有个坑(v1.0.1 踩过、v1.0.2 修):这个比率的分母是 CLI 实际运行的窗口, 不是你配置的窗口。 CLI 只接受模型自己声明的窗口(见目录里的 availableContextWindows),配一个它不支持的窗口会被 静默忽略——例如给只支持 200K 的 auto 配 1M,CLI 仍按 200K 跑,若拿 1M 去乘就虚高 5 倍。 所以插件现在分两个窗口:给 DSH 的是你配置的值,给比率做分母的是 cliContextWindow() (模型声明里匹配得上就用你的,匹配不上就用模型自己的)。同时窗口会经 resolveModel.parameters.contextWindow 真正下发给 CLI——在此之前它只告诉了 DSH,CLI 一直按默认 200K 跑,配了 1M 也白配。

比率本身是可信的:实测在 257/1007/2257 字符三档下,比率 × 窗口 与 CLI 自报的 getContextUsage().usedPercentage 在量化误差内一致,且随内容线性增长。注意 DSH 环上的总数 (inputTokens + cacheRead + cacheWrite)包含 qodercli 自身的开销——它自己的系统提示、skills 与工具定义,约 120–200 token。环里「系统提示词 / 工具定义 / 对话消息」三项是 DSH 自己按 4 字符/token 估的本地分类,合计会低于总数,这是正常的,不是虚高。

tok/s 为什么偏低? DSH 算 tok/s = 输出 token ÷ 解码耗时,而输出 token 由本插件上报。 v1.0.5 起这个数是 provider 自己数的 output_tokens(同一个计量开关),所以下面的估算修正只在拿不到 计量时生效——凡是模型生成的内容都必须计入,估算那一侧曾是两个原因,v1.0.3 与 v1.0.4 各修一个:

  1. 换算率(v1.0.3)。实测本后端的分词器:中文 1.77 字符/token、英文 5.20 字符/token, 而原先统一按 4 字符/token 估,中文因此被低估 2.26 倍。现在按字符集分别计价。
  2. 工具调用参数(v1.0.4)。原先只统计正文与思考,工具调用的 name/arguments 一个字符都没算, 而 agentic 回合里输出的大头正是它——实测一个三次工具调用的回合中占 86% 的字符。DSH 自己的 计量器是把工具调用计价为 name + arguments 的(dsh-token-meter 的 estimateContent), 漏掉它会让多步任务的 tok/s 低到十分之一量级。

实测效果:同一段中文回复 20.9 → 45.8 tok/s;一个工具调用回合 72.5 → 311.2 tok/s。 计数逻辑在 src/tokens.ts 的 TurnOutputAccounting,由 14 个单元测试钉住,其中一条专门断言 「工具参数必须计入」。

设置点了没反应、一直「保存中」? v0.6.0 已修。原因是 .volatile() 字段的改动不会重启 插件,而适配器在挂载时把配置抄进了自己的字段,于是永远按旧值作答——写入成功、磁盘正确、 插件读不到。详见下方「开发须知」。

回答完模型的问题、或工具调用结束后,有时等好几秒才继续,有时干脆不再回复? v1.0.6 已修。 根因是工具结果的配对状态被当成了"每轮"的,而它其实是"每会话"的。

qodercli 会用两个不同身份通知同一次工具调用:canUseTool 先拿到它自己的 tool_use id,而真正 需要宿主结果的那个 MCP tools/call handler 拿不到任何 id。两者顺序一致,靠一个 FIFO 配对。 实测(真实 CLI,1.1.68)这个 handler 会在它所属的那一轮已经结束之后才触发——宿主一看到工具 调用块就立刻把结果交回来,而 CLI 过几毫秒才派发 MCP 消息:

6198ms  [endTurn] kind=tool-calls
6198ms  [host] 没有 parked handler -> 缓冲在 key=call_80d292a7…
6217ms  [mcp handler] ENTER | shift 到 toolUseId=undefined
6217ms  [mcp handler] PARK 在 key=anonymous-1
14226ms [mcp handler] TIMED OUT after 8009ms

而 resetTurnState() 恰恰在每轮开始时清空了那个 id 队列,于是把 handler 正要认领的 id 丢掉了: handler 落到兜底键、park 满整个 toolResultTimeoutSeconds(默认 120 秒),宿主那条结果则永远 留在缓冲里没人读。为什么是"有概率":宿主工具慢(pwsh 跑几秒)时 handler 在轮次结束前就 park 好了,走的是另一条路;工具快(read、ask_user_question)时才输掉这个竞态。所以"问模型 问题"和"工具刚结束"这两类操作最容易中招。而 120 秒远超人的耐心,表现就是"一直不回复",只能停掉 对话重发——重发后模型重新发一次调用,这次竞态恰好落在另一边,于是"好了",但修的是运气不是 bug。

现在配对状态由会话持有,只在确实会取消派发的地方丢弃:轮次被 abort / 失败时丢掉这一轮没能 认领的通知(否则会把下一轮的 handler 挤错一个位置),会话销毁时整体释放。逻辑抽成了 ToolResultPairing,由 7 条单元测试钉住;其中"快结果必须交给轮次结束后才到达的 handler"一条 是会分辨的那条——在它与 claim 之间插一次 forgetUnclaimed()(即旧 resetTurnState() 在轮次 边界做的事),它就会 park 满超时并拿到 toolUseId=anonymous-1 的取消文本,与线上实测的失败 形态逐字一致。

同一个症状,换了一个原因? v1.0.7 已修。v1.0.6 之后日志里仍能看到 120 秒超时,但这次不是配对 丢了,而是超时用错了对象。

宿主要等这一轮的所有工具执行完,才在下一次模型请求里一次性带回全部结果。所以只要有一个工具 跑得久(构建、目录扫描、自带 300 秒预算的 pwsh),同批里早已完成的调用也得一起等——它的结果 明明已经就绪,只等着随下一次请求送达。旧实现从 handler 进入时开始计 120 秒,到点就把这次调用当成 "宿主没回"取消掉:

10:07:53  [mcp handler] PARK call_00_QFqbaum…   (write,结果其实立刻就有)
10:07:53  [host]         pwsh 开始执行(自身预算 300 秒)
10:09:53  [mcp handler] TIMED OUT after 120s    ← 把 write 误杀
10:10:38  [host]         第一次请求到达,带着全部三条结果

单工具同样会中:10-20 16:41 的一次 pwsh 超过 120 秒,16:43 被超时取消,而宿主当时还在执行它。

现在成对调用不再有墙钟期限:结果只可能随宿主的下一次请求到达,等多久取决于宿主工具,而不是 一个常数。真正能判定"这次调用没人会回答"的信号也正是那次请求本身——请求边界 (beginHostRequest())会立即结算宿主没有带回结果的已 park 调用,并把尚未触发的通知标记为已作废 (handler 之后到达时直接拿到取消结果,而不是再 park 两分钟)。只有完全没配上对的 handler (拿不到 toolUseId,无法把结果与调用对应)才继续用 toolResultTimeoutSeconds 兜底,默认仍是 120 秒。

工具调用结束后整轮再也不回复? v1.0.8 已修。v1.0.7 拿掉了成对调用的墙钟,但漏了一种没人能 来救的情况:请求边界只结算"它运行时已经 park 好"的 handler,而边界之后才到达的通知它管不 到——如果那次调用宿主压根没见过,就永远不会有人结算它,而唯一能结算它的下一次请求边界,偏偏要等 这一轮先结束,这一轮又正卡在这个 handler 上。

触发它的是一次裸名工具调用。内层模型偶尔不写限定名(write 而不是 mcp__dsh-host__write), qodercli 自己解析不到,就地判错并不等宿主继续跑它自己的循环——内层循环因此比宿主的轮次边界跑 前面一轮;它随即带限定名重试,而重试的工具块落在两次宿主请求之间的窗口里,会话当时没有可投递 的宿主流,块被丢弃,宿主从未见过这次调用,但 CLI 照样把它派发给了 MCP handler:

22:38:49.444 [cli]  模型以裸名 write 调用 -> Error: Tool "write" not found(就地失败,不等宿主)
22:38:49.506 [host] 宿主照常执行 write,文件确实写出了;22:38:52.812 开下一轮
22:38:52.786 [cli]  带限定名重试的工具块到达 -> 此刻没有宿主流 -> 丢弃(宿主从未见到)
22:40:37.687 [mcp handler] PARK call_2b54e8a6…   ← 没有任何请求会为它带回结果
22:48:24.594 [user] 点停止 -> CLI 取消挂起的工具调用,轮次才解开(实测静默 572 秒)

现在 claim() 在 park 之前先确认这次调用宿主确实见过(hostVisible:适配器真的把工具块投递 给宿主的那些 id)。宿主没见过的 id 立即拿到与请求边界相同的取消文本,不再空等;宿主见过的调用依旧 没有墙钟,pwsh 跑几分钟照样等它的真实结果。判别性的一条测试是「宿主从未见过的调用要立即失 败」——修复前它会 park 满 600 秒(测试超时失败),修复后立刻返回取消结果。

实现要点

  • warm 会话:每个宿主 session id 对应一个常驻内层 query() 子进程,对话延续与工具轮次都 发生在会话内部,超出 maxSessions 按插入序 LRU 淘汰。
  • 工具桥接:宿主工具经进程内 MCP server 暴露给内层模型,qodercli 一次执行一个调用、宿主 一次回传整轮结果;配对状态(ToolResultPairing)由会话持有而不是轮次,因为 handler 可能在 它那一轮结束之后才触发。成对调用等待宿主的下一次请求并由该请求结算;只有未配上对的 handler 受 toolResultTimeoutSeconds 兜底。宿主从未见过的调用(工具块落在两次宿主请求之间被丢弃, 而 CLI 仍派发了 MCP 消息)不 park,立即返回取消结果——否则这一轮没人能解开。
  • 旁路请求:标题生成、压缩摘要走冷启动一次性调用,不占用 warm 会话。
  • 真实计量:CLI 默认把用量帧里的 token 计数清零,插件在启动子进程时带上它的 EXPOSE_TOKEN_USAGE 开关;总量、缓存命中与 tok/s 因此都是 provider 实测值,只有拿不到计量时才 按「context 比率 → 字符估算」兜底。占用样本只取自每次请求结束的那一帧(requestUsageSample() ,见「哪个用量帧能信?」),内层整轮的合计值不参与上下文计算。
  • 溢出可恢复:内层上下文超限按 CONTEXT_WINDOW_EXCEEDED 上报,交给 harness 自动压缩, 而不是让整轮报废。

开发须知

改这个仓库前,有两点 DSH 行为必须先知道,否则会「毫无提示地坏掉」。

1. 字段不 .volatile(),设置页就永远不出现。 DSH 用 volatileForm(schema) 构造表单,它 只保留带 meta.volatile 的节点;字段全是非 volatile 的 object 会塌缩成 undefined, describe() 随即 return [] 丢掉整个命名空间——插件照常加载、模型照常可用,但命名空间 从未下发到客户端。此外,DSH 的自动配置页渲染在「内置插件」分区内部,要独立顶层导航项就得 自带 client.js 注册 settings.section。

2. .volatile() 的值必须在「用的时候」读,不能在挂载时读。 一次只改 volatile 字段的写入, loader 会把新值写进运行中插件已经持有的那个 Volatile 引用,然后跳过重启——apply() 不会再被调用(cordis-plugin-loader 的 Entry.update → _commitVolatile):

const pending = volatileOnly && this._commitVolatile() ? [] : changes
if (!pending.length && !force) return          // 不重启,不重新 apply

在 apply()(或构造函数)里把配置抄进自己的字段,就等于永久冻结。本插件的做法:

  • src/live.ts:Live<T>(值或 thunk)+ readLive(),选项既接受普通值,也 接受读取实时单元格的 thunk。
  • src/config.ts 的 liveConfig():每个字段返回 thunk,每次读取才从 Volatile 取值;resolveConfig() 在它之上实现,两者语义不会漂移。
  • 适配器、会话池、模型目录一律按需读。updateVolatile() 只把新值写进同一个引用,所以 thunk 天然看到新值——不用重启,也不丢 warm 会话。
  • 只有 displayName 会被复制进选择器的分组目录,无法惰性化;插件监听 loader/volatile-update,只在这个字段变化时用 replace() 就地重发。

test/live.test.ts 精确复现 loader 的就地提交并断言适配器在不重新 apply() 的情况下跟着变;用 0.5.0 的构建跑同一段代码会失败。

本插件的读写链路。 读走插件自建路由 GET /api/llm-qoder-cn/models(模型目录来自 CLI,进 不了配置表单);写走 ctx.configForms,与官方「模型」页共用带修订号的写入队列,并发编辑会被 拒绝而不是静默覆盖。宿主提交完成后才回应写入,页面因此先按新状态显示、随后核对,核对不 通过才报错;单次写入 20 秒未落定会放弃并解除控件禁用,避免一个卡住的调用锁死整页。

构建与测试

pnpm install          # 首次会下载 qoderclicn worker runtime
pnpm run build:clean   # 清掉 lib/ 再构建;tsc 出 .d.ts,tsdown 出 lib/index.js
pnpm test              # vitest

别用 pnpm build 验证改动。 它的命令是 tsc && tsdown:类型一错,&& 就短路,tsdown 根本不跑,于是 lib/index.js 保持旧内容——而 lib/ 才是 DSH 真正加载、npm 真正发布的东西。 如果只盯着源码或只跑测试,会误以为改动已生效。发布路径上的 prepublishOnly 用的是 build:clean(先删 lib/ 再构建),所以类型错误会让发布失败而不是发出陈旧包。

注意 pnpm build 与 pnpm run build 在 PowerShell 里可能给出不同的退出码(前者经 pnpm 的内置脚本别名,后者经 run)。判断构建是否成功请直接看 lib/index.js 的时间戳, 或跑 build:clean——不要只信退出码。

合规与风险

本插件通过官方 Agent SDK 复用你自己的 Qoder 账号登录态:不逆向私有协议、不伪造客户端身份 或请求头、不自动化领取签到积分,也不向任何第三方域名发送数据(只与 Qoder 官方服务通信)。

但请自行判断:

  1. 「以订阅额度驱动第三方宿主」是否符合你的 Qoder 服务条款,由你自行判断。 本项目无法替 Qoder 解释,也不保证账号不被限制。
  2. 上游接口与 SDK 随时可能变更,届时本插件可能失效。
  3. 请仅用于驱动你自己的账号,勿转售或超出个人合理使用范围。

许可

MIT。本仓库是 JiamingZang/dsh-llm-qodersdk (MIT)的衍生作品,上游许可原文与版权声明保留在 LICENSE.original, 出处与改动清单见 NOTICE。