Files
workbuddy_skills/dsh-local-env/SKILL.md
T
admin e03465c398 按用户令提交:把此前未纳管的 9 个技能目录一并入库
用户令逐字:「E:/ProgramData/.workbuddy/skills  提交仓库是指的这里」——
即本目录就是仓库(2026-10-07 已在本目录建仓,见当日日志 §22),本轮把余下未纳管的 9 个技能一并提交。

本次入库(9 个技能,46 个文件):
1、`AI HOT`
2、`draw-ui`
3、`dsh-diagnose`
4、`dsh-knowledge`
5、`dsh-local-env`
6、`dsh-opensource-release`
7、`dsh-workflow`
8、`oil-motion`
9、`skills-security-check`

提交前核对:
· **凭据类扫描**(`*.env` / `*token*` / `*.key` / `*secret*` / `*.pem`)⇒ **零命中** ✓;
· 体积合计约 20 MB(`draw-ui` 12M + `oil-motion` 6.5M 是大头,形态为配图/素材 ——
  仓库 `.gitignore` 里明写「`assets/*.png` 是内容不是产物」⇒ 属刻意入库);
· 运行产物仍按既定规则排除(`__pycache__` / `logs/` / `tmp/` / `.venv/` / `*.egg-info` / `uv.lock` / `.workbuddy/`)。
2026-10-08 22:29:08 +08:00

91 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: dsh-local-env
description: 「**在 Windows 本机把官方 dsh 跑起来 / 本机开发环境**」的总入口 —— 覆盖两半:① **本机跑起官方 dsh 并端到端取证**(web 实例 `apps/cli` 的 `dsh` CLI:起实例 / 查回环监听 / token+cookie jar 取 200 / 探测 Windows 沙箱后端;桌面壳 `apps/desktop`:源码构建、Electron 参数、CDP 真跑取证、**离线可用**验证、自研 client 插件真跑)② **环境引导 / 搬迁 / 改名**(「换电脑了」「改了工作区路径」「迁移到新环境」「规则会不会丢」「新环境还没配好」;以及**改名/搬家后的路径残留清理**)。⚠️ **边界**:本技能管**本机源码/开发态**;「**服务器上**单个用户实例打不开 / OOM / 崩溃重启」⇒ `dsh-diagnose`;「**服务器实例里**插件没 UI / 没生效」⇒ `dsh-diagnose`。核心 = 两形态先选对入口 + **Node 22** + **监听 ≠ 就绪** + **判据写窄=假红** + 换环境的"**规则齐备优先**"顺序 + **路径残留分类要细到「行」**。判据实体在主干,**全文在 `references/`(2 档)**。
version: 1.0.3
updated_at: 2026-09-30
last_change: 【2026-09-30 · 三改】§1 新增「🔴 **headless 起法:普通 node 直起 `apps/desktop-host` + 计划任务常驻**」——`@deepseek-ai/dsh-desktop-host` **src/lib 零 `electron` 引用**、官方壳自己就是把它当独立 node 子进程 spawn(`host-process.ts:188-190`)⇒ **可无窗口直起**;给出 argv 四段(`[2]`=runtimeDir、`[3]`=**`$DSH_HOME/profiles/desktop`**、`[4]`=primaryRuntime、`[5]/[6]`=pnpm/nodeBin)+ 必需 env(含 🔴 `CODEBUDDY_SAFE_DELETE_BULK_THRESHOLD` 不调高会"起了但口不开且零报错");**durable 只能靠计划任务**(`detached` 因 Job 不可逃逸=`err=5` 无效);⚠️ 更正一条半对说法「没有口令也不妨碍先起来」—— 口令缺失确实不阻止 `listen`,但 `workbuddy` 模式**先发现后监听 fail-closed**,**发现失败 ⇒ 永不监听**;§6c.4 四枪判据 + §6c.5 两条新坑(子进程 env 要**枚举删**;`Get-CimInstance -match` 数进程会被**探针自己的命令行**污染)。 (2026-09-29 · 二改)§1 新增「🔴 **「装上了」≠「口会开」—— 自研插件的 opt-in 回环口**」:`mount-*-into-profile.mjs verify` 的 `rc=0` 是**假绿**(绿只判 bundles+junction、opt-in 开关仅打印);分诊三步(合成插件树探针 → 插件自己的诊断路由 404/401 → 才查运行期);「**开机一次性发现 + fail-closed 永不重试**」+「**Electron 单实例锁让"再拉一份"无效**」这对组合会让故障**永远修不好** ⇒ 入口必须带**幂等闸**。详情档已补 §6。 【2026-09-29】§1 新增「**无人值守轮里只跑到骨架落盘**」姿势(启动器末尾 `spawn Electron` 常驻 ⇒ 用 `DSH_DESKTOP_PRIMARY_RUNTIME_DIR` 不存在路径当哨兵、在 `initProfile` 之后自停;挂载由 `DEVKIT_MOUNT_PLUGINS=1`/`DEVKIT_SKIP_*` 控制)。【2026-09-28】**由 `dsh-desktop-dev-shell`(v1.3.1)+ `dsh-env-bootstrap`(v1.2.0)合并而成**(两个原名退役)。按 `dsh-knowledge-upkeep §10`「主干 + 详情档」形态:判据实体留主干、全文下沉 `references/`(**内容守恒:逐行 0 丢失**,含原 frontmatter 变更历史)。合并理由:两者都是「**本机环境**」域 —— 一个管"把 dsh 跑起来并取证",一个管"换环境/改路径后规则与残留"。⚠️ 并按对账结论处置了版本分叉:`desktop-dev-shell` 本机版为**超集**(比文档库多 §11.6–11.8 等 131 行)⇒ 取**本机版**;`env-bootstrap` 本机版为**超集**(多 §3 迁移清理 67 行,文档库的"设计红线/自检"是其真子集)⇒ 取**本机版**。⛔ 未删任何判据。
agent_created: true
---
# dsh-local-env — Windows 本机 dsh 环境总入口
> ## 🔴 第 0 步:先分诊
>
> | 情形 | 去哪 |
> |---|---|
> | 要在**本机跑起 dsh**(web 实例 / 桌面壳)并取证 | **§1** |
> | 改了插件后**界面没变化** / 壳起不来 / pnpm 卡住 | **§1** |
> | **换电脑 / 改工作区路径 / 迁移 / 改名** | **§2** |
> | 改名后发现还有地方指着旧路径 | **§2 → 路径残留清理(分类细到「行」)** |
> | **服务器上**实例崩了 / OOM / 插件没 UI | ⛔ 不属本技能 ⇒ `dsh-diagnose` |
---
## 1. 本机跑起官方 dsh 并取证
**先选对入口(两个形态别混)**:**web 实例**(`apps/cli` 的 `dsh` CLI)|**桌面壳**(`apps/desktop`,需源码构建,可挂自研 client 插件做真跑验证)。
🔴 **三条必须先知道的判断**:
1. **Node 22**(版本不对会以各种"像工程问题"的方式失败);
2. 🔴 **「监听 ≠ 就绪」** —— 端口在听 **不代表** 实例能服务(实测:监听起来了但仍是 401/白屏)⇒ 判据必须做到"**能取到 200**"这一层;
3. 🔴 **判据写窄=假红** —— 会把**本来正确的产品行为**判成故障,然后你去改对的东西。⚠️ 同类:**陈旧写锁**会让实例**永久起不来**。
**依赖安装**:pnpm 在本机"卡在 added ~100"有**真根因**(不是慢)⇒ 见详情档。
**启动**:⛔ **不要用 `pnpm run dev:desktop`**;Electron 启动参数与 `--no-sandbox` 判据见详情档。
**改插件后必须重启壳**(插件树不热加载)。
**🔴 无人值守轮里"只跑到骨架落盘"的姿势(2026-09-29 实测 · 省一整类事故)**:dev 启动器末尾会 `spawn Electron` 并**常驻** ⇒ 自动化轮里跑它只有两条坏路 —— 放进**会话后台任务**(每轮输出唤醒宿主会话)或留一个无人关的窗口(残留)。
✅ 正解 = **跑同一份启动器代码**(同 tsx / 同 `DEVKIT_*` 开关),拿一个**排在校验序列后面的必需项**当哨兵 —— 桌面 0.1.7 启动器的 `DSH_DESKTOP_PRIMARY_RUNTIME_DIR` 校验发生在 `initProfile` **之后** ⇒ 指向不存在的路径即可**骨架落盘即自停**(`exit=1`、报错文本就是那一条,属预期)。零窗口、零 `electron.exe` 残留。
⚠️ 配套:挂什么插件由 `DEVKIT_MOUNT_PLUGINS=1` + `DEVKIT_SKIP_*` 精确控制(缺省 = 官方初始状态,一个都不挂)。
**🔴 「装上了」≠「口会开」—— 自研插件的 opt-in 回环口(2026-09-29 实测 · 一整轮排查换来的)**:
- 症状:profile 里包挂好、插件**自己的路由也能命中**,**但那个回环口就是不 LISTENING**。
- 🔴 **`mount-*-into-profile.mjs verify` 的 `rc=0` 是假绿** —— 它只判 `bundles + junction`,**opt-in 开关只在输出里打印**。判"口会不会开"**只能看口有没有 LISTENING**。
- **最快分诊(⛔ 先别重启客户端)**:① 用官方 `loadProfileDirectory()` + `composeEntries()` 打印**合成后**的插件树,确认那条 `config` **真的落到插件**(⛔ **别**调 `loadProfile()` —— 它会写 profile 目录;另注意 `cordis.patch.yml` 的 id 定向覆盖要能命中 bundle 自己 insert 的 id);② 打插件**自己的**诊断路由区分 **404 = 没装载 / 401 = 已装载**;③ 前两步都正常,才去怀疑运行期(动态发现失败 / `listen` 失败)。
- **一个"永远修不好"的陷阱**:模块若在**开机一次性**做上游动态发现且 **fail-closed 永不重试**,那一次失败 ⇒ 该客户端**整条生命周期**都不开;而守护进程"再拉一份"会被 **Electron 单实例锁**顶掉(新进程秒退,日志一片 `address already in use` + `exited: 0` —— **看着像起不来,其实头一份活得好好的**)⇒ **启动入口必须带幂等闸**:口在听/正在启动(宽限期)⇒ **零副作用早退**(⛔ 别为"发现不必启动"而先把 runtimeDir 重铺一遍);旧客户端活着但口不通 ⇒ **先按命令级甄别停旧的、再拉新的**。
- ⚠️ **模块自己的日志可能进不了客户端日志**(`grep` 零命中)⇒ 失败原因**离线不可见**;⇒ 入口侧要**自己落一行判定**(实测做法:客户端日志里出现 `device-access=ok(...)`)。
- 细节(探针脚本、读数、判据脚本)⇒ 详情档 §「opt-in 回环口」。
**🔴 headless 起法(要"无窗口"或要"活过会话"时用这条 · 2026-09-30 实测)**:那个口所在的 **DSH host 本身可以用普通 node 直起**(`apps/desktop-host` src/lib **零 `electron` 引用**,官方壳也只是把它当独立 node 子进程 spawn)⇒ **不弹窗口、不依赖 Electron**;要**跨会话常驻**则只能交给 **Windows 计划任务**(`detached` 在本机因 Job 不可逃逸而无效)。⚠️ 两条必记:① argv `[3]` 是 **`$DSH_HOME/profiles/desktop`**(⛔ 不是 runtimeDir)② 少了 `CODEBUDDY_SAFE_DELETE_BULK_THRESHOLD` 会变成「**进程起了、口永远不开、且零报错**」。⚠️ 另更正一条半对说法:**口令缺失不阻止 `listen`,但"网关发现失败"会**(`workbuddy` 模式 = 先发现后监听,fail-closed ⇒ 永不监听)。
📂 **全文 ⇒ 详情档 §6c**(argv/env 对照表、计划任务动作形状、`schtasks` 被拦只能经脚本 spawn、UTF-16 必带 BOM、四枪判据、两条新坑)。
**真跑取证(怎么拿到硬证据)**:用 **CDP** 连真窗口。⚠️ 选 CDP 目标时 **DevTools 自己也是一个 `type:'page'`** ⇒ 别选错。
**「离线可用」怎么验**:⛔ **别用"没人监听的端口"**造断网(那验不出东西);要用黑洞服务造"挂起" + **有界超时** + 如实状态。
⚠️ **造假的 `ctx` 有个必踩的语义坑**(假 ctx 与真 ctx 的语义差异 ⇒ 会让你得出错误结论)。
**两条本机环境坑**:`safe-delete` 护栏(**删 `node_modules` 前必读**);⚠️ Windows 上 `taskkill /F` 会被 MSYS **路径改写**成 `taskkill 'F:/'` ⇒ 报"无效参数"。
📂 **全文 ⇒ `references/00-本机跑起来与取证.md`**(含两形态完整命令与判据、pnpm 卡安装真根因、Electron 参数实测、CDP 取证配方、离线可用验证、`safe-delete` 护栏、自研 client bundle 必须 lazy-CJS 封包、真 host 的 RPC 调用(token→cookie + 信封口径)、桌面快捷方式链路)
---
## 2. 环境引导 / 搬迁 / 改名后的路径残留
**换环境的正确顺序**:🔴 **把"规则齐备"放在第一步**(先确认工作区常驻规则带着走,再谈别的)。
**工具**:`references/dsh-env-bootstrap/resident-rules.py` —— `--check`(校验关键规则齐备,**默认只报不改**)/ `--inject`(标记块内替换,首次需 `--init`)/ `--env-check`(路径与 hooks 命令自检)/ `--snapshot`(由权威重生成快照)。
🔴 **设计红线**:**权威方向单向**(规则文件为权威,快照为副本)⇒ ⛔ 别把它用成"第二真相源"。
🔴 **路径残留清理:分类要细到「行」,⛔ 不能只到「文件」**(血的教训):
- **第一层|文件分两类**:**活载体**(会被读取并据以行动:状态脚本 / 规则文件头部的路径声明 / 可执行脚本 / 当前工作线入口与接续包)⇒ **改写**;**历史档案**(记录过去某一棒做过什么:日志 · 归档 · tmp · 交付物 · 历史草案)⇒ ⛔ **不动**。
- 🔴 **第二层(最易漏、代价最大)|同一个"活载体"文件里,也有**不能改的行**:① **「污染源」记录本身**(改了就变成"它们写成了正确路径"⇒ **事故记录自毁**)② **`旧 A → 新 B` 配对里的 A 侧**(改了就成 `新 → 新`,脚本参数变重复)。
- **两类「改不动」的残留**:⛔ 别硬改、⛔ 别猜。
- **改名必须同步的「机制层」两处**:⛔ 漏了会**静默失效**。
📂 **全文 ⇒ `references/01-环境引导与迁移.md`**(含脚本完整参数、换环境顺序、分类细则与三类"不能改的行"、改不动的残留清单、机制层两处、三条可复跑验收)
📂 **快照 ⇒ `references/dsh-env-bootstrap/常驻规则-快照.md`** | **脚本 ⇒ `references/dsh-env-bootstrap/resident-rules.py`**
---
## 3. 详情档索引(跨档引用按此表定位)
| 档 | 覆盖的原技能 | 原章节 |
|---|---|---|
| `references/00-本机跑起来与取证.md` | `dsh-desktop-dev-shell`(**v1.3.1 本机超集版**,全文) | §0 为什么存在 / §1 两形态 / §2 桌面壳三判断 / §3 pnpm 卡安装 / §4 启动 / §5 Electron 参数 / §6 真跑验证 / **§6b opt-in 回环口(09-29 新增)** / **§6c headless 主机 + 计划任务常驻(09-30 新增)** / §7 本机环境坑 / §8 壳里打开不是登录页(**不是 bug**)/ §9 `safe-delete` 护栏 / §10 纪律 / §11 web 实例形态(含 **§11.6–11.8 本机独有**) |
| `references/01-环境引导与迁移.md` | `dsh-env-bootstrap`(**v1.2.0 本机超集版**,全文) | §0 为什么存在 / §1 命令 / §2 换环境顺序 / §3 迁移·改名后的路径残留清理(含 §3.1–§3.5)/ §4 设计红线 / §5 自检 |
| `references/dsh-env-bootstrap/` | 原附属档 | `常驻规则-快照.md` · `resident-rules.py` |
🔴 **两个原名已退役**(`dsh-desktop-dev-shell` / `dsh-env-bootstrap`)⇒ 别处见到按本技能对应档读。
⚠️ **边界**:本技能管「**本机**」;服务器侧的实例与插件 ⇒ `dsh-diagnose`。
⚠️ **已并入的版本分叉**:文档库侧旧版比本机少 §11.6–11.8(本机为超集)⇒ 已按**本机版**定稿,⛔ 别用旧副本反向覆盖。