dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
从本机登录文件完成 Trae 与 WorkBuddy 每日签到,侧边栏展示状态与积分。
DeepSeek Harness 签到插件:一个插件同时完成 Trae、WorkBuddy 与 Qoder 的每日签到,并在主页侧边栏提供签到状态与积分面板。登录态只读本机文件——不读取青龙环境变量里的 token / uid / 账号列表,也不把解出的 token 写入 settings 或状态文件。
包名与 entry id 沿用 dsh-dual-checkin:entry id 是加载层的稳定身份,状态文件也按旧名落盘,改名会让「当日已签」记忆失效、同日重复触发。三平台能力以 1.3.0 为准。sidebar.panellist),点击打开全宽面板——Trae、WorkBuddy 与 Qoder 各一张状态卡(已签到 / 未签到徽标 + 24 小时制签到时间 + 最近备注)。creditsBefore / creditsAfter 暴露(面板不单独成行)。积分快照按 TTL(默认 5 分钟,可用 creditsTtlSeconds 调整)自动重新查询,签到每天只发生一次。失败结果同样有 60 秒负缓存——上游故障时面板轮询不会再反复重打上游。qoderPat(令牌)与 qoderPatExpiresAt(到期时间)即可启用;剩余 ≤ qoderPatExpiringDays 天(默认 7)时面板 Qoder 卡片显示黄色提醒、日志同步 warn,过期显示红色提醒。不填令牌时回退读取 qoderCredentialRef 指向的凭据。Promise.allSettled 并行跑三个平台,一边失败 / 超时 / 未登录,另一边照常完成。/plugins/dsh-dual-checkin/status,GET 读快照、POST 强制重查积分,页内刷新按钮走 POST。CLI 从 GitHub 安装(推荐)
dsh plugin --profile desktop add github:G57651/dsh-dual-checkinWeb UI:Plugins 页 → Git 填 github:G57651/dsh-dual-checkin;或下载 Release / pnpm pack 产出的 tarball 后:
dsh plugin --profile desktop add dsh-dual-checkin-1.3.11.tgz克隆后本地安装
git clone https://github.com/G57651/dsh-dual-checkin.git
dsh plugin --profile desktop add ./dsh-dual-checkin平台 · 登录态来源 Trae · ~/Library/Application Support/TRAE SOLO CN/User/globalStorage/storage.json(以及 Trae CN / Trae / TRAE SOLO、CLI 的 trae-jwt-token) WorkBuddy · ~/Library/Application Support/CodeBuddyExtension/Data/Public/auth/workbuddy-desktop.info Qoder · DSH 凭据服务里的 Qoder PAT:首次启用可在插件配置直接填 qoderPat + qoderPatExpiresAt(到期时间,用于临期提醒);不填则读取 qoderCredentialRef(默认 QODER_MANAGED_CREDENTIAL,与 dsh-provider-qoder 同一份凭据);区域用 qoderRegion 切换 cn / intl
WorkBuddy 的明文 JWT 直接使用;$wbEncrypted 信封按 dsh-buddy-checkin v0.2.0 的方式,拉起本机 WorkBuddy.app 的 Electron 取 at-rest key,再用 AES-256-GCM 解开。
Qoder 不读取任何本机登录文件、不访问系统钥匙串、零解密代码、零子进程:直接复用你已在 DSH 配置好的 Qoder PAT,POST /api/v1/jobToken/exchange 换取短期 jobToken(进程内缓存、临期 5 分钟自动重换、401 自动重换一次再重试且不消耗重试次数)后调用签到接口。PAT 与 jobToken 只在 内存中使用,状态文件只存 uid / 昵称 / edition 与积分快照。未配置 PAT 时报可操作提示,不影响 Trae / WorkBuddy。
~/.dsh/.dsh-dual-checkin-trae.json — Trae 最近一次签到结果~/.dsh/.dsh-dual-checkin-workbuddy.json — WorkBuddy 最近一次签到结果~/.dsh/.dsh-dual-checkin-qoder.json — Qoder 最近一次签到结果文件名带 profile 维度:profile 名(DSH_PROFILE)合法时写成 …-trae-.json,否则沿用上面的全局名。升级后首次运行会先按新名查找、找不到再回退读旧名,因此不会因为改名而多签一次;旧文件保持原样不被改写,可以自行删除。快照带 schemaVersion,并在写入与读回前都剔除名字像凭据的字段(token / pat / authorization / cookie / secret / apiKey 等,含嵌套)。
状态路由 /plugins/dsh-dual-checkin/status:GET 查看本次结果(当日已完成且快照在 TTL 内时无网络请求,超过 TTL 只重查积分、不重复签到);POST 强制重查积分与状态(当日已签到的平台仍然跳过 claim,幂等)。
127.0.0.0/8、::1、::ffff:127.x)与回环 Host,Origin 限回环或桌面壳协议 dsh-app:;非法 authority(含 @ 或 /、端口非纯数字,如 localhost:80.evil.com)一律 403。对端地址不可解析时失败关闭——宿主把 webserver 绑到非回环地址时,本插件路由不会被局域网访问。~/.dsh/.credentials.yaml 前先校验权限,mode & 0o077 !== 0 时拒绝读取并提示 chmod 600(与宿主 credentials-local 的 GROUP_OTHER_BITS 语义一致)。qoderCredentialRef 只允许 [A-Za-z0-9_.-] 字符集并做逐行前缀匹配,不会把配置值当正则执行。auth.domain 必须匹配 (^|.)(workbuddy|codebuddy).cn$,且 URL 不得携带用户名 / 密码 / 端口 / 路径 / 查询,否则该账号按未登录处理。Trae 与 Qoder 的出口为硬编码常量。fetch 都显式 redirect: 'error'——跨源 3xx 会让请求头与请求体落到新源。usage_summary(total_amount − consumed_amount,权威口径),三天内到期按积分包 expire_time 逐包累加;WorkBuddy 走 get-user-resource 聚合——月度包看 Cycle* 字段(周期结束即重置),一次性包看 Capacity* 字段并剔除已过期 / 已用尽的(聚合规则与 dsh-connect-workbuddy 一致);Qoder 走 /sash/api/v2/me/usage,聚合响应里的配额桶与资源包,字段缺失时对应项为 null。checkin-activity-status 的 today_checked_in(无副作用),只在未签时调 daily-checkin;Trae 的 checked_in 为账号级状态,claim 按北京日幂等;Qoder 先读 me/campaigns 里 actionType=CLAIM_BENEFIT 且时间窗开启的那一轮(startAt/endAt 为秒级时间戳),claimStatus=CLAIMED 视为已签,否则 POST /claim(上游幂等,重复领取返回 replayed=true 不再发币)。settings.section,无手动签到入口。dsh-connect-trae、dsh-connect-workbuddy、dsh-connect-qoder、dsh-buddy-checkin,可并存。pnpm i # 只有 peerDependencies,用于让回归测试能加载 lib/index.mjs
pnpm test # node --test "test/*.test.mjs"回归用例把 HOME / DSH_HOME 重定向到临时目录并替换 globalThis.fetch,不使用任何真实凭据、不发出任何真实请求。
适配 DSH 0.2.1-rc.2(行为与接口零变化,仅清单声明与验证):
^0.2.0-rc.1 || ^0.2.1-rc.2。此前只有 engines.node,宿主对 dsh 的兼容性只能靠 @deepseek-ai/dsh-* peer 逐个判定。^0.2.1-rc.2:`@deepseek-ai/dsh-client-locale`、`dsh-client-ui-slots`、`dsh-host-webserver` 三个 peer 的原范围以 `^0.2.0-rc.1` 结尾。宿主 app-boot 的 `evaluatePluginCompatibility` 用 `semver.satisfies(..., { includePrerelease: true })` 判定,该范围能匹配 0.2.1-rc.2;但按 semver 默认语义(不带 `includePrerelease`)它不匹配**,pnpm 等按默认语义检查的工具会报 peer 冲突。补上显式版本消除这一歧义。pnpm test 88 条回归用例在 0.2.1-rc.2 的 devDependencies 下全绿;客户端 bundle 外壳(window.__ModuleLoader__.load / id / factory)与 require 解析(仅 react)经静态校验通过。Windows 平台适配(macOS 行为与显式 WORKBUDDY_ELECTRON_BIN 优先级均不变;回归用例扩到 88 条,新增 win32 路径用例与注入桩):
resolveElectronPath 只有 macOS 默认路径,Windows 一律抛「请设置 WORKBUDDY_ELECTRON_BIN」。现在 win32 分支按可靠性顺序自动探测:卸载表三个视图(HKCU / HKLM / HKLM WOW6432Node)里的 DisplayIcon(剥引号与图标索引,只接受 WorkBuddy.exe)与 InstallLocation,再到四个默认安装目录(%LOCALAPPDATA%\Programs、%LOCALAPPDATA%、%ProgramFiles%、%ProgramFiles(x86)% 下的 WorkBuddy\WorkBuddy.exe),候选统一走与显式配置一致的三重校验;自定义盘符安装(如 D:\Program Files\WorkBuddy)靠注册表命中。探测进程带 windowsHide,DSH 无控制台宿主下不再闪黑框。.credentials.yaml 的 POSIX 权限校验(mode & 0o077)在 NTFS 上对任何文件都判「过宽」(Windows 无 POSIX 位,文件恒报 666),回退直读通道此前在 Windows 上永远被拒;现在 win32 跳过该校验(实际防护由 NTFS ACL 承担,宿主 credentials-local 服务路径不受影响)。校验逻辑新增 platform 参数,POSIX 分支语义原样。APPDATA / LOCALAPPDATA 一并重定向到临时目录——Trae 与 WorkBuddy 在 win32 上经它们找凭据,此前 Windows 测试机会读到本机真实登录态,把「无凭据零网络请求」用例打穿;X_OK「不可执行」断言改为 POSIX 专属(win32 无可执行位概念);落盘失败用例按平台断言错误形态(POSIX 的 EISDIR / win32 的 EPERM);S-04 权限用例改为显式注入 darwin / win32 双平台互证。注册表解析、候选顺序与三重校验全部经 queryRegistry 注入桩覆盖,测试永不读本机注册表。结构收敛与纵深加固(对外行为兼容;配套回归用例 82 条,其中 14 条在 1.3.8 上失败):
lib/http.mjs(重试 / 退避 / 超时 / Retry-After / signal 透传 / redirect: 'error')。此前 Trae / Qoder / WorkBuddy 各自复制了一份 postJson / requestJson / tunables / sleep,重试语义与 defaults 形状四次漂移(WorkBuddy 的 defaults 只有 2 个键)。Retry-After(秒数或 HTTP 日期,上限 60 秒),否则按 retryDelayMs 做 ±20% 抖动,避免多平台同时重试对齐;retryDelayMs: 0 现在真的表示不等待(此前被回退成默认 5 秒)。apply 建 AbortController,dispose 时 abort 并清空内存里的 Qoder jobToken 与 WorkBuddy 解密密钥(旧实现只置 disposed 标志,请求照样跑完且旧闭包继续持有令牌)。stripSecrets 剔除凭据形状字段,快照带 schemaVersion: 1;读回磁盘上的历史快照时也过一遍(TTL 内直接复用的快路径会把快照原样回给面板)。process.env);WORKBUDDY_ELECTRON_BIN 需经 realpath + 常规文件 + X_OK 三重校验;缓存的解密密钥在 keyId 轮换后失效重取一次(此前会永久返回 0 个账号)。creditsBefore → creditsAfter 此前只在状态路由暴露);积分到期提醒上屏(expiringAlert 此前零引用);侧栏图标改用官方 usePanelInfo 读自己的选中态(aria-current / 高亮);删除死键 intro。安全与健壮性修复(全部在 lib/ 内,零新增依赖;配套回归用例 46 条,本版之前 20 条失败):
startsWith 前缀比对改为 hostnameOfHost() 精确匹配(剥端口、拒绝含 @ 或 / 的非法 authority、端口必须为纯数字),localhost:80.evil.com / 127.0.0.1:80.evil.com / [::1]:80.evil.com 这类绕过值不再放行;新增回环对端校验(req.socket.remoteAddress),宿主把 webserver 绑到 0.0.0.0 时局域网请求不再读得到状态;响应补 cache-control: no-store / x-content-type-options: nosniff / referrer-policy: no-referrer。qoderCredentialRef 先过 [A-Za-z0-9_.-] 白名单,再逐行做字符串前缀匹配。此前 .* / (A|B) / [ 之类的配置值会从 .credentials.yaml 里读出另一个 ref 的无关密钥,非法正则还会把原始错误字符串经 note 上屏。~/.dsh/.credentials.yaml 前校验 mode & 0o077,过宽即拒绝并提示 chmod 600(此前比宿主 credentials-local 更宽松)。auth.domain 必须匹配 (^|.)(workbuddy|codebuddy).cn$ 且不得携带用户名 / 密码 / 端口 / 路径 / 查询,避免把改过的本机文件里的任意主机当上游。fetch 显式 redirect: 'error'。saveState 与 runner 的 try/catch 解耦,写入失败改为在结果上带 persistError 并记 warn;此前状态文件写不进去时(例如路径被占成目录 → EISDIR)面板显示 ok:false 且 results:[],而 claim 其实已经成功、积分已到账,下次启动还会再签一次。\r\n 与 C0/C1 控制字符,避免上游响应片段伪造日志行或把不可见字符写进状态文件。5xx / 429 重试,4xx 快速失败;retryTimes 在三个平台语义一致;Qoder 的 401 重换 jobToken 不再额外消耗一次重试额度。mode: 0o700(此前跟随 umask,实测 755)。POST(此前按 GET 发,host 侧「强制重查积分」从未接线);超时由 15 秒提到 300 秒(host 侧最坏 210 秒,此前必然 abort 且服务端仍在跑);CSS 注入 effect 返回 cleanup(热重载不再堆积 `);平台清单抽为 PLATFORM_KEYS 单一来源;PAT 到期与签到徽标等 8 处文案改走 locale 字典;已签到时也显示 note;删除死代码 patNoteOf`。scripts.test(node --test "test/*.test.mjs")、repository 字段与 test/ 回归用例。CLAIMED(含 claim 返回 replayed: true)意味着本轮奖励今天已经到账——无论由 Qoder 客户端还是本插件领取——把本轮宣传金额(100 Credits)填入 gained,与 WorkBuddy already 分支行为一致;此前该场景 gained 为 null,卡片「本次获得」显示「—」。qoderPat(令牌,显式填写时优先于凭据引用)与 qoderPatExpiresAt(到期时间,YYYY-MM-DD 或 ISO)。qoderPatExpiringDays(默认 7 天)时面板 Qoder 卡片黄条提醒 + 日志 warn;过期红条提醒;到期状态在每次面板刷新时按当前配置实时重算,改配置立即生效。auth.v1.dat)读取路径与全部钥匙串 / 解密代码(security 子进程、PBKDF2、AES 全部删除,node:crypto 依赖归零),唯一凭据来源是 DSH 凭据服务里已配置的 Qoder PAT。auth.v1.dat(与桌面端同一份会话,token 由 Qoder 自己续期);文件不可用(未安装 / 未登录 / 钥匙串未授权 / 解密失败)时自动回退 DSH 已配置的 Qoder PAT,双源都失败时报合并的可操作错误。security + PBKDF2 + AES-CBC/GCM),不再读取 auth.v1.dat。PAT 与 dsh-provider-qoder 同源(ctx.credentials.resolve,服务缺失时回退直读 ~/.dsh/.credentials.yaml 的同名 refs 项),经 /api/v1/jobToken/exchange 换短期 jobToken 后调用签到接口。qoderCredentialRef(默认 QODER_MANAGED_CREDENTIAL)、qoderRegion(cn / intl,默认 cn)。startAt/endAt 是秒级时间戳,此前被按毫秒判定导致活动窗口永远视为已关闭(真机发现并修复)。com.qodercn.app.stable/auth.v1.dat(Chromium OSCrypt 信封),macOS 经钥匙串 Qoder CN App Safe Storage + PBKDF2(1003) + AES-CBC/GCM 回退链解密;签到走 me/campaigns + campaigns/{id}/claim(幂等)。国际版(openapi.qoder.sh)为尽力探测——其活动列表需要客户端 umid 设备头,本插件不伪造,缺失时明确报错。security find-generic-password 的各类退出码映射为可操作提示(未登录 / 授权被拒 / 需要交互);首次读取弹一次授权框,点「始终允许」后静默。retryTimes / retryDelayMs 重试,4xx 快速失败;401/403 判定为登录过期,不重试。GET/POST /plugins/dsh-dual-checkin/status 增加同名 qoder 键;GET/POST 共用 runAll 执行器;syncCredits 支持按本机重新解密刷新 Qoder 积分快照。ctx.logger(name) 返回具名 logger」):旧代码把 ctx.logger 当普通 { warn, info } 对象读,宿主为可调用服务形态时 logger.error / logger.info 均为 undefined,所有日志一行不打。现在按可调用形态优先(ctx.logger('dsh-dual-checkin')),对象形态回退,与 dsh-session-manager 0.1.2 的修法一致。inject = ['webServer'] 已保证 apply 运行前服务就绪(§2.1),apply 内不再二次 ctx.inject(['webServer']),路由直接经 ctx.effect 注册;webServer 服务消失时插件随依赖整体卸载、恢复后重载(§5.4),行为等价。handleStatus(仅 refreshCredits 标志不同);syncCredits 签名里从未使用的 runner 参数移除;once 更名为语义明确的 singleFlight;移除未使用的 workbuddyDefaults import。.tmp 名改为唯一随机名 + 原子改名,并发/崩溃不再可能留下可读到的半截 JSON。EXPIRING_WINDOW_MS 常量归位到常量区、defaults 直接引用它;postJson 重试参数名 retries → retryTimes 与 tunables 统一(模块内私有 API)。签到流程、请求端点与解密逻辑零变化。devDependencies(与 peerDependencies 同范围)。ide_user_ent_usage → web_user_ent_usage,请求体去掉 req_source: 2(与 dsh-connect-trae 的已验证只读端点一致)。creditsTtlSeconds(默认 300 秒)重新查询积分;面板刷新按钮改为强制重查(不重复签到)。credit,缺失时用签到状态响应的 daily_credit / today_credit 兜底,备注统一为「签到成功,获得 +N 积分」。get-user-resource 请求体新增 PackageEndTimeRangeBegin / PackageEndTimeRangeEnd。parseDateMs 只把 > 1e12 的数字当毫秒时间戳。Config schema(creditsTtlSeconds / retryTimes / retryDelayMs / reqTimeoutMs / expiringWindowMs),可调值从硬编码移入配置;入口只导出 name / inject / Config / apply;dsh.client.inject 改为真实客户端包名并补齐 peerDependencies。--dsw-alias-state-warn-primary(兜底 #f59e0b);「三天内到期」标签恢复为二级灰,仅在确有到期积分时整句提示。@deepseek-ai/dsh-host-webserver peer 范围放宽为 ^0.1.5-rc.1 || ^0.1.7-rc.1 || ^0.2.0-rc.1——0.2.0-rc.1 起宿主对 @deepseek-ai/dsh-* 命名空间的 peerDependencies 做兼容性预检(semver.satisfies 含 prerelease),旧范围在 0.2.0-rc.1 上会被预检禁用(stderr 报 "disabling profile plugin")。宿主 webServer 的 register(WebRoute{kind,path,handler}) API 实际未变,此改动仅为通过预检,宿主侧代码零改动。