{
  "meta": {
    "plugin": "@deepseek-ai/dsh-manager",
    "version": "0.35.6",
    "commit": "ebbe995a114a61e6f760d45041a759071560f391",
    "analyzed_at": "2026-08-22",
    "baseline": "dsh 0.1.0-rc.7（知识库 05-source/dsh-rc7）",
    "knowledge_base": "https://github.com/zako-mio/deepseek-harness-plugin-dag",
    "evidence_framework": "E1 编译依赖 / E2 运行时依赖 / E3 组合依赖（三硬依据 + 源码行引用）"
  },
  "nodes": [
    {"id": "mgmt-server-entry", "name": "lib/index.js", "kind": "core", "half": "node", "loc": 4514,
     "desc": "宿主半边入口。ESM 具名导出 name='dsh-manager'(:67)，inject=['webServer'](:70)，apply(ctx)(:2818)。经 webServer.register 挂单一 exact 路由 POST /api/dsh-manager(:4409-4429)：body{method,args} 单路 RPC 分发 61 个 handler（技能/观察/补丁/仓库/AI 讲解/本地服务六组）；同源校验 sameOrigin 为唯一写操作边界(:1050-1059,:4419)；SERVICE_MUTATING_METHODS 经 serializedSvc 串行队列(:913-917)。启动时注册包内 6 个技能进宿主 skills 注册表(:1180-1242)；dispose 注销路由并杀全部非 detached 本地服务(:4438-4513)",
     "provides": ["POST /api/dsh-manager HTTP 路由（61 方法 RPC 面）", "包内 6 技能注册（source='custom'/provider='dsh-manager'）", "两个 dispose 型 effect（路由 + 服务生命周期对账）"]},
    {"id": "mgmt-service-core", "name": "lib/service-core.js", "kind": "core", "half": "node", "loc": 406,
     "desc": "本地服务引擎纯逻辑：services.json 状态账本、启停/重启/批量操作、阶梯探活（net 探测）、日志流管理、外部占用进程检测（netstat/tasklist/wmic）、detached 去-shell 启动(:57-66)。DSH_HOME 解析 ~/.dsh(:34-36)"},
    {"id": "mgmt-repo-core", "name": "lib/repo-core.js", "kind": "core", "half": "node", "loc": 292,
     "desc": "仓库治理纯逻辑：多根目录递归扫描（跳过 node_modules/.git/_governance/_snapshots）、SKILL.md 枚举、repos.json/MANIFEST.md 治理账本"},
    {"id": "mgmt-ai-core", "name": "lib/ai-core.js", "kind": "core", "half": "node", "loc": 82,
     "desc": "AI 讲解支撑纯逻辑：atomicWrite 同卷临时文件+rename(:11-20)、中文代码讲解 prompt 构造(:22-35)、宽容 JSON 提取(:50-64)、AI 缓存读写 _governance/ai-explanations.json(:66-81)。真正 LLM 调用在 index.js 经宿主 ctx.get('llm').stream(:2716-2743)，key 不落盘——settings 引用 apiKeyEnv 由 credentials.resolve 解析(:2859-2881)"},
    {"id": "mgmt-client", "name": "lib/client.js", "kind": "core", "half": "browser", "loc": 4626,
     "desc": "浏览器半区。window.__ModuleLoader__.load 包装(:8)，React 经平台模块表 require('react')(:12)。inject=['slots'](:1956)，apply(ctx)(:4238)：软取 locale/workspaces/conversation/sessions(:4239-4242)、inputTriggers.registerSource '/' 技能别名菜单源(order:3, 五级拼音匹配)(:4252-4285)、locale.register('skill-manager',{zh,en}) 双语字典约450键(:18-940,:4290)、注入 <style> 内联 CSS 约300行(:4292-4302,:4322-4619)、8 次 slots.inject 注册 4 触发器(sidebar.footer.action)+4 全屏面板(shell.overlay)(:4312-4319)。与宿主半边经同源 fetch POST /api/dsh-manager JSON-RPC（120s 超时）(:944-961)，port 门面约 60 方法(:991-1055)。四大面板：Skills(:1515-1723)/Patch(:1744-1954)/Repo(:2085-3236)/Service(:3237-4236)"}
  ],
  "stubs": [
    {"id": "dsh-host-webserver", "name": "@deepseek-ai/dsh-host-webserver", "group": "G25 宿主服务", "layer": 0,
     "mech": "E2", "consumer": "mgmt-server-entry",
     "evidence": "lib/index.js:70（inject ['webServer']）；lib/index.js:4409-4429（webServer.register exact 路由）",
     "purpose": "HTTP 路由注册 API——插件唯一的宿主传输面挂载点"},
    {"id": "dsh-skill", "name": "@deepseek-ai/dsh-skill(-filesystem)", "group": "G18 技能", "layer": 1,
     "mech": "E2", "consumer": "mgmt-server-entry",
     "evidence": "lib/index.js:1181,:972,:3113（ctx.get('skills') 软消费）；svc.register 包内技能 :1220；catalog 按 definition.path 写回 :39-41",
     "purpose": "skills 注册表：catalog 五分组枚举、开关直写 SKILL.md frontmatter(:1018-1028,:3326-3340)、EDITABLE_SOURCES 白名单(:72,:985-994)"},
    {"id": "dsh-session", "name": "@deepseek-ai/dsh-session", "group": "G03 核心服务", "layer": 1,
     "mech": "E2", "consumer": "mgmt-server-entry + mgmt-client",
     "evidence": "lib/index.js:956-958（sessions 服务会话视角合并）；client.js:4241-4242（conversation.input.for(sessionsService.scope(id)) 写输入框草稿）",
     "purpose": "会话作用域解析与输入框草稿写入（只读面板→生成指令的核心交互）"},
    {"id": "dsh-agent-presets", "name": "@deepseek-ai/dsh-agent-presets", "group": "G25 宿主服务", "layer": 3,
     "mech": "E2", "consumer": "mgmt-server-entry",
     "evidence": "lib/index.js:956-958,:1305-1370（agentPresets 预设视角合并 + 未挂载预设 customSkillDirs preview）",
     "purpose": "预设维度技能目录视图"},
    {"id": "dsh-llm", "name": "@deepseek-ai/dsh-llm(+pi-ai)", "group": "G04/G05 LLM核心/适配", "layer": 0,
     "mech": "E2", "consumer": "mgmt-server-entry",
     "evidence": "lib/index.js:2849（ctx.get('llm')）；llm.stream 流式生成 :2716-2743；providerHasKey 经 settings+credentials :2859-2881",
     "purpose": "AI 讲解/诊断/日志摘要/配置草稿四个量产点；凭证不经插件持有"},
    {"id": "dsh-settings-file", "name": "@deepseek-ai/dsh-settings-file", "group": "G11 凭据设置", "layer": 0,
     "mech": "E2", "consumer": "mgmt-server-entry",
     "evidence": "lib/index.js:2859（settings section('llm-pi-ai')）",
     "purpose": "LLM 提供方配置读取"},
    {"id": "dsh-credentials-local", "name": "@deepseek-ai/dsh-credentials-local", "group": "G11 凭据设置", "layer": 0,
     "mech": "E2", "consumer": "mgmt-server-entry",
     "evidence": "lib/index.js:2860（credentials.resolve）",
     "purpose": "apiKeyEnv 引用解析，key 不落盘不进插件"},
    {"id": "dsh-cordis", "name": "@deepseek-ai/cordis", "group": "框架容器", "layer": null,
     "mech": "E1+E3", "consumer": "两端",
     "evidence": "package.json peerDependencies；cordis.patch.yml insert 装配（唯一装配声明，9 行）",
     "purpose": "DI 容器与插件生命周期；E3 组合依赖=插入 profile 组合的 id:dsh-manager"},
    {"id": "pinyin-pro", "name": "pinyin-pro", "group": "npm依赖", "layer": null,
     "mech": "E1", "consumer": "mgmt-server-entry",
     "evidence": "package.json dependencies ^3.29.2；lib/index.js:86-104（宿主端一次性转换全拼+首字母，缓存 Map :84）",
     "purpose": "拼音索引在宿主端生成后随 notesGet/catalog 下发，客户端零依赖"},
    {"id": "js-yaml", "name": "js-yaml", "group": "npm依赖", "layer": null,
     "mech": "E1", "consumer": "mgmt-server-entry",
     "evidence": "package.json dependencies ^4.1.0（开关直写 frontmatter 用行级改写而非 YAML 重解析 :1018-1028）",
     "purpose": "YAML 解析兜底"},
    {"id": "react", "name": "react", "group": "peer依赖", "layer": null,
     "mech": "E1", "consumer": "mgmt-client",
     "evidence": "package.json peerDependencies ^18.2.0；client.js:12（require('react') 取自宿主平台模块表，不打包）",
     "purpose": "UI 渲染；h=React.createElement 无 JSX"},
    {"id": "dsh-client-modules", "name": "@deepseek-ai/dsh-client-modules", "group": "G26 客户端runtime", "layer": 6,
     "mech": "E3", "consumer": "mgmt-client",
     "evidence": "package.json dsh.client.platform='web'(:29-31)+exports[\"./client\"](:9)；cordis.patch.yml:4-5 注释（client-modules 扫描后注入 window.__DSH_BOOT__ 为 /plugins/<包名>/client.js）；client.js:8 __ModuleLoader__.load 包装",
     "purpose": "客户端模块注入机制：bundle 扫描→boot 图→懒 CJS 物化"},
    {"id": "dsh-client-ui-slots", "name": "@deepseek-ai/dsh-client-ui-slots", "group": "G29 UI底座", "layer": 0,
     "mech": "E1", "consumer": "mgmt-client",
     "evidence": "package.json peerDependencies；client.js:1956（inject ['slots']）；8 次 slots.inject sidebar.footer.action×4 + shell.overlay×4 (:4312-4319)",
     "purpose": "SlotRegistry 注册 API 与 props share 类型底座；本插件未做 declare module 类型合并、未自声明新槽（纯 JS 运行时注册）"},
    {"id": "dsh-client-locale", "name": "@deepseek-ai/dsh-client-locale", "group": "G26 客户端runtime", "layer": 11,
     "mech": "E2", "consumer": "mgmt-client",
     "evidence": "client.js:4239（ctx.get('locale')）；locale.register(NS,{zh,en}) :4290；t 经 slots.register({locale:NS}) 由宿主透传 props.t",
     "purpose": "skill-manager 单命名空间 zh/en 双语字典与 t 座位"},
    {"id": "dsh-client-runtime", "name": "@deepseek-ai/dsh-client-runtime", "group": "G26 客户端runtime", "layer": 9,
     "mech": "E2", "consumer": "mgmt-client",
     "evidence": "client.js:1516-1519,:2086-2089,:3238（props.useSessions/useWorkspaces 选择器函数透传）",
     "purpose": "宿主 PropsStore 座位：面板工作区下拉与会话数据订阅"},
    {"id": "dsh-client-ui-workspace", "name": "@deepseek-ai/dsh-client-ui-workspace", "group": "G27 会话交互UI", "layer": 15,
     "mech": "E2(间接)", "consumer": "mgmt-client",
     "evidence": "client.js:1052-1054（workspacesService openPath 打开目录）；:1519 工作区下拉",
     "purpose": "openPath 目录打开能力（peerDependencies 显式声明）"},
    {"id": "dsh-client-ui-conversation", "name": "@deepseek-ai/dsh-client-ui-conversation", "group": "G27 会话交互UI", "layer": 14,
     "mech": "E2", "consumer": "mgmt-client",
     "evidence": "client.js:4241,:968-980（input.for(scope).actions.setDraft 写草稿 + focusComposer 聚焦）",
     "purpose": "『只读面板+生成指令』模式的目标面：把 git 指令写进当前会话输入框"},
    {"id": "dsh-client-ui-input-trigger", "name": "@deepseek-ai/dsh-client-ui-input-trigger", "group": "G28 设置输入UI", "layer": 12,
     "mech": "E2", "consumer": "mgmt-client",
     "evidence": "client.js:4252-4285（inputTriggers.registerSource '/' 菜单技能别名源 order:3，五级拼音/模糊匹配候选 :1958-2083）",
     "purpose": "'/' 触发菜单集成"}
  ],
  "edges_core": [
    {"from": "mgmt-client", "to": "mgmt-server-entry", "mech": "RPC", "label": "同源 POST /api/dsh-manager JSON-RPC（约60方法门面）", "evidence": "client.js:944-961,:991-1055 ↔ index.js:4409-4429"},
    {"from": "mgmt-server-entry", "to": "mgmt-service-core", "mech": "E1", "label": "import ./service-core.js", "evidence": "lib/index.js 顶部 import"},
    {"from": "mgmt-server-entry", "to": "mgmt-repo-core", "mech": "E1", "label": "import ./repo-core.js", "evidence": "lib/index.js 顶部 import"},
    {"from": "mgmt-server-entry", "to": "mgmt-ai-core", "mech": "E1", "label": "import ./ai-core.js", "evidence": "lib/index.js:63"},
    {"from": "mgmt-client", "to": "dsh-client-ui-slots", "mech": "E1", "label": "inject['slots']+8×slots.inject", "evidence": "client.js:1956,:4312-4319"},
    {"from": "mgmt-client", "to": "dsh-client-locale", "mech": "E2", "label": "locale.register 字典+t座位", "evidence": "client.js:4239,:4290"},
    {"from": "mgmt-client", "to": "dsh-client-runtime", "mech": "E2", "label": "useSessions/useWorkspaces 座位", "evidence": "client.js:1516-1519,:2086-2089"},
    {"from": "mgmt-client", "to": "dsh-client-ui-workspace", "mech": "E2", "label": "openPath", "evidence": "client.js:1052-1054"},
    {"from": "mgmt-client", "to": "dsh-client-ui-conversation", "mech": "E2", "label": "setDraft/focusComposer", "evidence": "client.js:968-980,:4241"},
    {"from": "mgmt-client", "to": "dsh-client-ui-input-trigger", "mech": "E2", "label": "registerSource '/' 别名源", "evidence": "client.js:4252-4285"},
    {"from": "mgmt-client", "to": "react", "mech": "E1", "label": "require('react') 平台模块表", "evidence": "client.js:12"},
    {"from": "mgmt-client", "to": "dsh-client-modules", "mech": "E3", "label": "__DSH_BOOT__ 注入", "evidence": "package.json:29-31; cordis.patch.yml:4-5"},
    {"from": "mgmt-server-entry", "to": "dsh-host-webserver", "mech": "E2", "label": "webServer.register 路由", "evidence": "index.js:70,:4409"},
    {"from": "mgmt-server-entry", "to": "dsh-skill", "mech": "E2", "label": "catalog/开关/回收站/技能注册", "evidence": "index.js:972,:1180-1242,:3113-3340"},
    {"from": "mgmt-server-entry", "to": "dsh-session", "mech": "E2", "label": "sessions 会话视角", "evidence": "index.js:956-958"},
    {"from": "mgmt-server-entry", "to": "dsh-agent-presets", "mech": "E2", "label": "预设视角合并+preview", "evidence": "index.js:1305-1370"},
    {"from": "mgmt-server-entry", "to": "dsh-llm", "mech": "E2", "label": "llm.stream 四量产点", "evidence": "index.js:2716-2743,:4308,:4331,:4357"},
    {"from": "mgmt-server-entry", "to": "dsh-settings-file", "mech": "E2", "label": "section('llm-pi-ai')", "evidence": "index.js:2859"},
    {"from": "mgmt-server-entry", "to": "dsh-credentials-local", "mech": "E2", "label": "credentials.resolve", "evidence": "index.js:2860-2881"},
    {"from": "mgmt-server-entry", "to": "dsh-cordis", "mech": "E1", "label": "peerDep 容器契约", "evidence": "package.json peerDependencies"},
    {"from": "mgmt-server-entry", "to": "pinyin-pro", "mech": "E1", "label": "拼音索引宿主端生成", "evidence": "index.js:86-104"},
    {"from": "mgmt-server-entry", "to": "js-yaml", "mech": "E1", "label": "YAML 兜底解析", "evidence": "package.json dependencies"},
    {"from": "mgmt-server-entry", "to": "dsh-cordis", "mech": "E3", "label": "cordis.patch.yml insert 装配（id:dsh-manager 插入 profile 组合）", "evidence": "cordis.patch.yml:7-9"}
  ],
  "features": {
    "skills": "技能统一管理：五来源分组（global/project/plugin/preset/builtin）catalog 合并视图；开关=行级直写 SKILL.md frontmatter（disable-model-invocation/user-invocable）；回收站 ~/.dsh/skills-trash/<id>.json 备份后 unlink，还原校验目标不存在；备注别名 ~/.dsh/skills-notes.json promise 队列串行 RMW；拼音索引宿主端 pinyin-pro 一次转换随下发；sessionStorage 秒显缓存",
    "patches": "部署补丁管理器：replace(find/count 恰等校验)/script(node:vm 沙箱 3s 超时 64MB 上限，官方注释自认非硬安全边界)/override 三类；官方快照内容寻址去重共享(.state/snapshots/<sha256>)；状态=校验和比对不重放(applied/clean/lost/error 四态)；启用事务=前置/互斥校验→干跑整链 replay→先全快照→原子写→失败回滚；禁用=快照重放去 id 新链；adoption 反推求逆；RECOVERY.md 每次变更原子重写（含官方备份绝对路径表+CLI 还原命令）；CLI 兜底 reapply-deployment-patches.ps1",
    "repo": "本地仓库面板：多根目录 roots[] 扫描自动分类（git origin 第三方→mirror/无 origin 或 as1350→local）；三层缓存（内存 SWR 20s→磁盘指纹→全量重建）；核心交互=『只读面板+生成指令』draft() 把 git 操作指令写入会话输入框；skill 应用到全局/项目/插件（safeSkillName 防穿越）；GitHub 克隆向导；AI commit 讲解流式轮询",
    "service": "本地服务面板（第四面板，最大 UI）：services.json 账本静默启动+autoStart 对账、阶梯探活、日志查看器（3s 刷新/搜索/下载）、外部占用进程检测杀死、AI 诊断/日志摘要/配置草稿"
  },
  "requirements": [
    "痛点1 技能散在多来源无法统一查看与控制调用 → catalog 五分组+frontmatter 开关直写",
    "痛点2 技能删除不可逆 → 回收站+备注/拼音别名",
    "痛点3 官方升级覆盖本地定制（如 slash-seed 改输入框行为被 npm 升级冲掉）→ 补丁引擎+官方快照链重放+RECOVERY.md+CLI 兜底",
    "痛点4 多仓库克隆/镜像/更新状态无账本 → 多根扫描+治理账本+AI commit 讲解",
    "痛点5 本地 venv/node 服务手动拉起烦琐 → services.json 静默启动+探活+AI 诊断",
    "痛点6 面板冷启动 7-8s 性能债 → 多层 SWR 缓存改造（0.35.x 主线）"
  ],
  "design_issues": [
    {"sev": "高", "issue": "鉴权弱于宿主信任栅栏", "detail": "唯一写操作边界=sameOrigin(req)（Origin host===Host header, index.js:1050-1059），为自制实现；宿主 web 表面有 browser-trust fence（isTrustedApiRequest 防 DNS-rebinding/跨站，PRIVILEGED_METHODS 钉 loopback）。webServer.register 路由是否被宿主 fence 二次包裹未确认，若否则管理面（含任意命令启动/RCE 级能力）防护弱于宿主标准", "suggestion": "对齐宿主：复用 isTrustedApiRequest 栅栏或迁移到 api-gateway 受信方法通道；管理类 mutating 方法建议钉 loopback-only 开关"},
    {"sev": "高", "issue": "script 类补丁沙箱自认非硬边界 + 服务启动=RCE 面", "detail": "node:vm runInNewContext 仅靠无 IO 沙箱+3s 超时+64MB 上限（index.js:384-394 官方注释承认不是硬安全边界）；serviceStart 可执行 services.json 配置的任意命令（spawn shell:true 普通模式, service-core.js:57-66）；resolveCustomSkillDir 还对预设 YAML 表达式跑 vm（:1280-1298）", "suggestion": "落地 BACKLOG#15：导入补丁强制哈希签名校验；allowExecutable 总闸默认关+逐次确认已部分覆盖，可加命令白名单模板；vm 表达式限定安全子集或换 expr-eval 类库"},
    {"sev": "中", "issue": "双单体文件：4626 行 client.js + 4514 行 index.js", "detail": "client.js 混装 4 功能域+双语字典（占 20% 行数）+300 行内联 CSS+模糊匹配算法；无 declare module 类型合并（纯 JS 运行时注册，偏离 ui-* 插件 TS 惯例）；CSS 以模板字符串注入 <style>", "suggestion": "拆分为 locale JSON 文件（构建期并入）/独立 css/四面板子模块；引入 tsc + d.ts 恢复 SlotMap/LocaleNamespaceMap 声明合并类型面，与宿主 UI 插件体系对齐"},
    {"sev": "中", "issue": "依赖声明不实：inject=['slots'] 但实际消费 6 服务", "detail": "client.js:1956 仅声明 slots；apply 还软取 locale/workspaces/conversation/sessions/inputTriggers（undefined 守卫 :4239-4242,:4253）——E1/E2 判定边界模糊，违背知识图谱『三硬依据』可判定性原则，也丢失了 cordis 的启动顺序保证", "suggestion": "inject 补全硬依赖；可选依赖以 optionalInjects 元数据显式声明（若宿主支持）或在 README 依赖表中列明软依赖及降级行为"},
    {"sev": "中", "issue": "轮询增殖：7 个独立 setInterval 无统一调度", "detail": "6s 技能目录(:1608)/6s 补丁扫描(:1779)/15s 角标(:1738)/60s 镜像巡检(:2405)/800ms AI 状态(:2204)/3s 日志(:3397)/5s 服务列表(:3379)", "suggestion": "统一 PollScheduler：指数退避+document.visibilitychange 暂停+面板失焦降频；共享一个 tick 循环分发"},
    {"sev": "中", "issue": "状态目录无 GC + CLI 双实现漂移（BACKLOG 已列）", "detail": ".state 快照孤儿无回收策略；reapply-deployment-patches.ps1 与 node 侧逻辑双实现存在漂移风险（README:333-342）", "suggestion": "快照按 chain 引用计数 GC；ps1 退化为薄壳调 node 入口脚本（单一实现源）"},
    {"sev": "低", "issue": "死代码与重复样板", "detail": "prefetchRepo(client.js:1213-1228) 定义后从未调用；两击删除确认在 SkillCard(:1357-1367)/TrashCard(:1430-1439)/补丁删除(:1790-1792) 三处重复；result.error 检查+catch 转 message 样板约 30 处", "suggestion": "删除 prefetchRepo；抽公共 useConfirmTwoStep() 与 rpc() 统一错误处理 helper"},
    {"sev": "低", "issue": "硬编码本机路径与中文指令模板", "detail": "git 指令模板含机器特定路径 D:\\Desktop\\Dsh\\...、C:\\Users\\ThinkBook\\...（client.js:2545 附近），未走 locale 字典也不可移植", "suggestion": "模板参数化（占位符由服务端 roots 配置填充），文案迁入 locale 字典"},
    {"sev": "低", "issue": "render-phase setState 反模式", "detail": "Panel 渲染体内直接 setGroupId 自动跳组(client.js:1640)", "suggestion": "移至 useEffect/初始化 effect"}
  ]
}
