dsh-vscode-mode 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +607 -88
- package/lib/index.js.map +1 -1
- package/package.json +4 -1
- package/src/index.ts +4 -1
- package/src/rpc.ts +10 -24
- package/src/search/fallback.ts +76 -0
- package/src/search/orchestrator.ts +276 -0
- package/src/search/query.ts +62 -0
- package/src/search/ranker.ts +48 -0
- package/src/search/ripgrep.ts +144 -0
- package/src/search/types.ts +47 -0
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/shared/rpc.ts","../src/routes.ts","../src/shared/diff.ts","../src/model.ts","../src/store.ts","../src/registry.ts","../src/capture.ts","../src/workspace.ts","../src/revert.ts","../src/mcp.ts","../src/mcpProject.ts","../src/rpc.ts","../src/mcpIsolation.ts","../src/index.ts"],"sourcesContent":["/**\n * dsh-vscode-mode RPC contract — method names, per-method request/ok payloads,\n * and the typed handler map shared by the host dispatcher and the client\n * fetch wrapper. 载荷形状与历史实现一字不差,仅把隐式约定类型化。\n *\n * Purity rule: no node/react imports (same as types.ts).\n * 作者 ddj 2026-08-20\n */\nimport type {\n ArchiveBatch,\n ArchiveEntry,\n RecordView,\n StaleHunk,\n} from './types.js'\nimport type { MpcConfig, MpcProject, MpcProjectSaveInput, MpcServer } from './mcp.js'\n\n/** webServer 精确路由。 */\nexport const RPC_PATH = '/edrv/rpc'\n\n/** 决策作用域:call=整条记录,hunk=单个差异块。 */\nexport type RpcScope = 'call' | 'hunk'\n\n/** 每个方法的请求参数(sessionId 为公共可选字段)。 */\nexport interface RpcRequestMap {\n 'edrv.list': { sessionId?: string; callIds?: string[] }\n 'edrv.accept': { sessionId?: string; callId: string; scope?: RpcScope; hunkIndex?: number }\n 'edrv.reject': { sessionId?: string; callId: string; scope?: RpcScope; hunkIndex?: number }\n 'edrv.read': { sessionId?: string; path: string }\n 'edrv.original': { sessionId?: string; path: string }\n 'edrv.save': { sessionId?: string; path: string; content: string }\n 'edrv.archiveList': { sessionId?: string }\n 'edrv.archiveRead': { sessionId?: string; path?: string }\n 'edrv.rollback': { sessionId?: string; path: string; batch?: number }\n 'edrv.debug': { sessionId?: string; text: string }\n 'edrv.searchFiles': { sessionId?: string; query: string }\n 'mcp.list': {}\n 'mcp.save': { config: MpcConfig }\n 'mcp.remove': { id: string }\n 'mcp.toggle': { id: string; enabled: boolean }\n 'mcp.refresh': { id: string }\n 'mcp.projects': {}\n 'mcp.projectSave': MpcProjectSaveInput\n 'mcp.projectRemove': { workspacePath: string; serverName: string }\n 'mcp.projectToggle': { workspacePath: string; serverName: string; enabled: boolean }\n 'mcp.projectRefresh': { workspacePath: string; serverName: string }\n}\n\nexport type RpcMethod = keyof RpcRequestMap\n\n/** 每个方法成功(ok:true)时的附加载荷。 */\nexport interface RpcOkMap {\n 'edrv.list': { records: RecordView[] }\n 'edrv.accept': { record: RecordView }\n 'edrv.reject': { record: RecordView }\n 'edrv.read': { content: string; size: number }\n 'edrv.original': { content: string; size: number; stale: StaleHunk[]; fallback: boolean }\n 'edrv.save': object\n 'edrv.archiveList': { entries: ArchiveEntry[] }\n 'edrv.archiveRead': { batches: ArchiveBatch[] }\n 'edrv.rollback': { path: string; batch: number | null }\n 'edrv.debug': object\n 'edrv.searchFiles': { files: string[]; truncated: boolean }\n 'mcp.list': { servers: MpcServer[] }\n 'mcp.save': { server: MpcServer }\n 'mcp.remove': object\n 'mcp.toggle': { server: MpcServer }\n 'mcp.refresh': { server: MpcServer }\n 'mcp.projects': { projects: MpcProject[] }\n 'mcp.projectSave': { project: MpcProject }\n 'mcp.projectRemove': { project: MpcProject }\n 'mcp.projectToggle': { project: MpcProject }\n 'mcp.projectRefresh': { project: MpcProject }\n}\n\n/** 统一响应:{ok:true, ...payload} 或 {ok:false, error}。 */\nexport type RpcResult<M extends RpcMethod> =\n | ({ ok: true } & RpcOkMap[M])\n | { ok: false; error: string }\n\n/** 每个方法的 handler 签名(host 分发表与 client 类型检查共用)。 */\nexport type RpcHandler<M extends RpcMethod> = (\n args: RpcRequestMap[M],\n) => Promise<RpcResult<M>>\n\n/** host RPC 分发表:method → handler。 */\nexport type RpcHandlerMap = {\n [M in RpcMethod]: RpcHandler<M>\n}\n","/**\n * dsh-vscode-mode host — webServer 路由注册(/edrv/rpc、/edrv/assets/*、/edrv/vendor/*)。\n * 迁移自原 src/index.ts 的路由部分,路径/行为一字不改。\n * 作者 ddj 2026-08-20\n */\nimport { readFile } from 'node:fs/promises'\nimport { dirname, extname, join, normalize, resolve, sep } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { RPC_PATH } from './shared/rpc.js'\nimport type { RpcMethod, RpcRequestMap } from './shared/rpc.js'\nimport type { Ctx } from './store.js'\n\nconst IMG_ROUTES = [\n { url: '/edrv/assets/compare-idle.png', file: 'compare_idle.png' },\n { url: '/edrv/assets/compare-select.png', file: 'compare_select.png' },\n]\n\n/** Monaco AMD 构建静态资源(随包发布,离线可用;前缀路由 /edrv/vendor/*)。 */\nconst VENDOR_PREFIX = '/edrv/vendor'\nconst VENDOR_MIME: Record<string, string> = {\n '.js': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json',\n '.map': 'application/json',\n '.ts': 'text/plain; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.gif': 'image/gif',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.html': 'text/html; charset=utf-8',\n '.md': 'text/markdown',\n}\n\n/** 图标目录:默认插件包内 assets/(随包发布);config.imageDir 可覆盖(用于自定义换图)。 */\nfunction imageDirOf(config: unknown): string {\n const cfg = config as { imageDir?: unknown } | undefined\n if (cfg && typeof cfg.imageDir === 'string' && cfg.imageDir) return cfg.imageDir.replace(/\\\\/g, '/')\n return join(dirname(fileURLToPath(import.meta.url)), '..', 'assets')\n}\n\n/** Monaco AMD 静态目录(随包发布)。 */\nconst vendorDir = join(dirname(fileURLToPath(import.meta.url)), '..', 'assets', 'vendor')\n\n/**\n * 注册全部 webServer 路由。\n * @author ddj 2026年08月20号\n * @param ctx DSH 上下文\n * @param config 插件配置(可选 imageDir 等)\n * @param handleRpc RPC 分发入口(method,args → RpcResult)\n */\nexport function registerRoutes(\n ctx: Ctx,\n config: unknown,\n handleRpc: <M extends RpcMethod>(method: M, args: RpcRequestMap[M]) => Promise<unknown>,\n): void {\n const imgDir = imageDirOf(config)\n const web = ctx.get('webServer')\n if (!web) return\n\n ctx.effect(() => web.register({\n kind: 'exact',\n path: RPC_PATH,\n handler: async (req: unknown, res: { statusCode?: number; setHeader: (k: string, v: string) => void; end: (b?: string) => void }) => {\n try {\n const chunks: Uint8Array[] = []\n for await (const chunk of req as AsyncIterable<Uint8Array>) chunks.push(chunk)\n let input: { method?: string; args?: unknown } = {}\n try {\n input = JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}')\n } catch (error) {\n input = {}\n }\n const method = (typeof input.method === 'string' ? input.method : '') as RpcMethod\n const result = await handleRpc(method, (input.args ?? {}) as never)\n res.statusCode = 200\n res.setHeader('content-type', 'application/json')\n res.end(JSON.stringify(result))\n } catch (error) {\n res.statusCode = 500\n res.end(JSON.stringify({ ok: false, error: String(error) }))\n }\n },\n }), 'edrv: /edrv/rpc route')\n\n for (const r of IMG_ROUTES) {\n ctx.effect(() => web.register({\n kind: 'exact',\n path: r.url,\n handler: async (req: unknown, res: { statusCode?: number; setHeader: (k: string, v: string) => void; end: (b?: string | Uint8Array) => void }) => {\n try {\n const body = await readFile(imgDir + '/' + r.file)\n res.statusCode = 200\n res.setHeader('content-type', 'image/png')\n res.setHeader('cache-control', 'no-cache')\n res.end(body)\n } catch (error) {\n res.statusCode = 404\n res.end()\n }\n },\n }), 'edrv: static ' + r.file)\n }\n\n // Monaco Editor AMD 构建:/edrv/vendor/* → assets/vendor/*(路径穿越防护 + 按扩展名 MIME)\n ctx.effect(() => web.register({\n kind: 'prefix',\n path: VENDOR_PREFIX,\n handler: async (req: { method?: string; url?: string }, res: { statusCode?: number; setHeader: (k: string, v: string) => void; end: (b?: string | Uint8Array) => void }) => {\n try {\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n res.statusCode = 405\n res.end()\n return\n }\n const pathname = new URL(req.url ?? '/', 'http://x').pathname\n const rel = decodeURIComponent(pathname.slice(VENDOR_PREFIX.length)).replace(/^\\/+/, '')\n if (!rel) { res.statusCode = 404; res.end(); return }\n const target = resolve(normalize(join(vendorDir, rel)))\n if (target !== vendorDir && !target.startsWith(vendorDir + sep)) {\n res.statusCode = 403\n res.end()\n return\n }\n const body = await readFile(target)\n res.statusCode = 200\n res.setHeader('content-type', VENDOR_MIME[extname(target)] ?? 'application/octet-stream')\n res.setHeader('cache-control', 'public, max-age=3600')\n res.end(body)\n } catch (error) {\n res.statusCode = 404\n res.end()\n }\n },\n }), 'edrv: /edrv/vendor prefix')\n}\n","/**\n * dsh-vscode-mode shared diff primitives — 快照指纹、hunk 规范化与安全定位。\n * 不依赖 Node/React,host 与 browser 共用,避免各层用不同 indexOf 语义。\n * 作者 ddj 2026-08-24\n */\nimport type { Hunk, RecordBase } from './types.js'\n\n/** 文件读取状态,区分真实空文件与无法读取/过大的文件。 */\nexport type ReadState =\n | { kind: 'content'; content: string }\n | { kind: 'missing' }\n | { kind: 'unavailable' }\n\n/** 文本中的一个半开区间 [start,end)。 */\nexport interface TextRange {\n start: number\n end: number\n}\n\n/** 一条 hunk 在当前内容中的定位结果。 */\nexport interface HunkLocation extends TextRange {\n idx: number\n hunk: Hunk\n matched: boolean\n}\n\n/** 统一取对应 hunk;callHunk 只用于旧记录缺失 hunks 时兼容。 */\nexport function preciseHunk(record: Pick<RecordBase, 'hunks' | 'callHunk'>, idx: number): Hunk | null {\n return hunkOf(record, idx)\n}\n\n/** 轻量、确定性的字符串指纹;不引入 Node crypto。 */\nexport function fingerprint(text: string | null | undefined): string | null {\n if (typeof text !== 'string') return null\n let hash = 2166136261\n for (let i = 0; i < text.length; i++) {\n hash ^= text.charCodeAt(i)\n hash = Math.imul(hash, 16777619)\n }\n return 'fnv1a:' + (hash >>> 0).toString(16) + ':' + text.length\n}\n\n/** 取记录第 idx 个有效 hunk;只有记录缺 hunk 时才回退 callHunk。 */\nexport function hunkOf(record: Pick<RecordBase, 'hunks' | 'callHunk'>, idx: number): Hunk | null {\n const hunk = Array.isArray(record.hunks) ? record.hunks[idx] : undefined\n if (hunk && typeof hunk.newText === 'string') return hunk\n if (idx === 0 && record.callHunk && typeof record.callHunk.newText === 'string') return record.callHunk\n return null\n}\n\n/** hunk 是否表示没有实际内容变化。 */\nexport function isNoopHunk(hunk: Hunk | null | undefined): boolean {\n return !!hunk && hunk.oldText !== null && hunk.oldText === hunk.newText\n}\n\n/** splitLines 的空文本语义:真实空文件没有一行变更内容。 */\nexport function splitLines(text: string): string[] {\n return text.length ? text.split('\\n') : []\n}\n\n/** 为执行后 hunk 写入快照坐标;空 newText 通过 before/after 公共边界定位删除点。 */\nexport function annotateHunk(hunk: Hunk, before: string | null, after: string | null): Hunk {\n return annotateHunks([hunk], before, after)[0]\n}\n\n/** 按文件顺序为多 hunk 写入不重复的 after 坐标。 */\nexport function annotateHunks(hunks: Hunk[], before: string | null, after: string | null): Hunk[] {\n if (typeof after !== 'string') return hunks\n let cursor = 0\n return hunks.map((hunk) => {\n if (hunk.newText.length > 0) {\n const start = after.indexOf(hunk.newText, cursor)\n if (start >= 0) {\n cursor = start + hunk.newText.length\n return { ...hunk, afterStart: start, afterEnd: cursor }\n }\n return hunk\n }\n if (hunks.length !== 1 || typeof before !== 'string' || before === after || hunk.oldText === null) return hunk\n const prefix = commonPrefix(before, after)\n const suffix = commonSuffix(before, after, prefix)\n const removedStart = prefix\n const removedEnd = Math.max(removedStart, before.length - suffix)\n return { ...hunk, afterStart: removedStart, afterEnd: removedStart, beforeStart: removedStart, beforeEnd: removedEnd }\n })\n}\n\n/** 计算两个文本的最长公共前缀长度。 */\nfunction commonPrefix(left: string, right: string): number {\n const limit = Math.min(left.length, right.length)\n let i = 0\n while (i < limit && left.charCodeAt(i) === right.charCodeAt(i)) i++\n return i\n}\n\n/** 计算不与 prefix 重叠的最长公共后缀长度。 */\nfunction commonSuffix(left: string, right: string, prefix: number): number {\n const limit = Math.min(left.length, right.length) - prefix\n let i = 0\n while (i < limit && left.charCodeAt(left.length - 1 - i) === right.charCodeAt(right.length - 1 - i)) i++\n return i\n}\n\n/** 计算 index 前的 0 基行数。 */\nexport function lineBefore(text: string, index: number): number {\n let n = 0\n const end = Math.max(0, Math.min(index, text.length))\n for (let i = 0; i < end; i++) if (text.charCodeAt(i) === 10) n++\n return n\n}\n\n/** 找出文本的全部非重叠出现位置。 */\nfunction allMatches(content: string, needle: string): TextRange[] {\n if (!needle.length) return []\n const out: TextRange[] = []\n let from = 0\n while (from <= content.length - needle.length) {\n const at = content.indexOf(needle, from)\n if (at < 0) break\n out.push({ start: at, end: at + needle.length })\n from = at + Math.max(1, needle.length)\n }\n return out\n}\n\n/**\n * 从 after 快照定位所有 hunk,按 hunk 顺序优先选未占用且靠近前一块的候选。\n * 若 hunk 带 afterStart/afterEnd,则优先验证快照坐标,避免重复文本错配。\n * @author ddj 2026年08月24号\n * @param content 当前文件内容\n * @param hunks 待定位 hunk\n * @returns 每个 hunk 一个结果,matched=false 表示冲突/stale\n */\nexport function locateHunks(content: string, hunks: Hunk[]): HunkLocation[] {\n const locations: HunkLocation[] = []\n let cursor = 0\n const occupied: TextRange[] = []\n for (let idx = 0; idx < hunks.length; idx++) {\n const hunk = hunks[idx]\n const newText = hunk.newText\n const snapshot = Number.isInteger(hunk.afterStart) && Number.isInteger(hunk.afterEnd)\n ? { start: hunk.afterStart as number, end: hunk.afterEnd as number }\n : null\n const snapshotMatches = snapshot && snapshot.start >= 0 && snapshot.end >= snapshot.start\n && (newText.length === 0 || content.slice(snapshot.start, snapshot.end) === newText)\n ? snapshot\n : null\n const candidates = snapshotMatches ? [snapshotMatches] : allMatches(content, newText)\n const candidate = candidates.find((range) => range.start >= cursor && !occupied.some((used) => overlaps(range, used)))\n ?? candidates.find((range) => !occupied.some((used) => overlaps(range, used)))\n if (candidate) {\n locations.push({ idx, hunk, ...candidate, matched: true })\n occupied.push(candidate)\n cursor = Math.max(cursor, candidate.end)\n continue\n }\n if (newText.length === 0 && hunk.afterStart === undefined && hunk.afterEnd === undefined && content.length === 0) {\n const point = { start: 0, end: 0 }\n locations.push({ idx, hunk, ...point, matched: true })\n continue\n }\n if (newText.length === 0 && hunk.afterStart !== undefined && hunk.afterEnd !== undefined\n && hunk.afterStart === hunk.afterEnd && hunk.afterStart >= 0 && hunk.afterStart <= content.length) {\n const point = { start: hunk.afterStart, end: hunk.afterEnd }\n if (!occupied.some((used) => overlaps(point, used))) {\n locations.push({ idx, hunk, ...point, matched: true })\n occupied.push(point)\n cursor = Math.max(cursor, point.end)\n continue\n }\n }\n locations.push({ idx, hunk, start: -1, end: -1, matched: false })\n }\n return locations\n}\n\n/** 判断两个半开区间是否重叠。零长度区间只与同一位置的零长度区间重叠。 */\nfunction overlaps(left: TextRange, right: TextRange): boolean {\n if (left.start === left.end || right.start === right.end) return left.start === right.start && left.end === right.end\n return left.start < right.end && right.start < left.end\n}\n\n/** 在可定位区间上执行一次 hunk 反向替换。 */\nexport function replaceRange(content: string, location: HunkLocation, reverse = false): string | null {\n if (!location.matched || location.start < 0) return null\n const replacement = reverse ? (location.hunk.oldText ?? '') : location.hunk.newText\n return content.slice(0, location.start) + replacement + content.slice(location.end)\n}\n\n/** 按当前内容中出现的位置从后向前应用 hunk,避免前块长度变化影响后块。 */\nexport function applyLocations(content: string, locations: HunkLocation[], reverse = false): { content: string; stale: number[] } {\n const stale = locations.filter((location) => !location.matched).map((location) => location.idx)\n let out = content\n const matched = locations.filter((location) => location.matched).sort((a, b) => b.start - a.start)\n for (const location of matched) {\n const next = replaceRange(out, location, reverse)\n if (next === null) stale.push(location.idx)\n else out = next\n }\n return { content: out, stale: stale.sort((a, b) => a - b) }\n}\n","/**\n * dsh-vscode-mode host — 纯域逻辑(无 ctx/fs/IO 依赖,可直接单测)。\n * 迁移自原 src/index.ts 的纯函数部分,语义一字不改。\n * 作者 ddj 2026-08-20\n */\nimport type { Decision, DiffRecord, Hunk, RecordSummary } from './shared/types.js'\nimport { applyLocations, fingerprint, isNoopHunk, locateHunks, preciseHunk } from './shared/diff.js'\n\n/** 工作区记录桶上限(超过后按 at 最旧剔除)。 */\nexport const MAX_RECORDS = 200\n\n/**\n * 归一化一条持久化记录(容忍旧版/损坏字段)。\n * @author ddj 2026年08月20号\n * @param raw 反序列化的原始记录\n * @returns 合法记录或 null\n */\nexport function normalizeRecord(raw: unknown): DiffRecord | null {\n if (!raw || typeof raw !== 'object') return null\n const r = raw as Record<string, unknown>\n if (typeof r.callId !== 'string' || typeof r.path !== 'string') return null\n const hunks: Hunk[] = Array.isArray(r.hunks)\n ? (r.hunks as unknown[]).filter((h) => h && typeof (h as { newText?: unknown }).newText === 'string').map((h) => {\n const item = h as Record<string, unknown>\n return {\n oldText: typeof item.oldText === 'string' ? item.oldText : null,\n newText: item.newText as string,\n ...(Number.isInteger(item.afterStart) ? { afterStart: item.afterStart as number } : {}),\n ...(Number.isInteger(item.afterEnd) ? { afterEnd: item.afterEnd as number } : {}),\n ...(Number.isInteger(item.beforeStart) ? { beforeStart: item.beforeStart as number } : {}),\n ...(Number.isInteger(item.beforeEnd) ? { beforeEnd: item.beforeEnd as number } : {}),\n }\n })\n : []\n const toolName: DiffRecord['toolName'] = r.toolName === 'write' ? 'write' : 'edit'\n const rawDecisions = r.decisions && typeof r.decisions === 'object' ? r.decisions as Record<string, unknown> : {}\n const call = rawDecisions.call === 'accepted' || rawDecisions.call === 'rejected' ? rawDecisions.call : 'pending'\n const rawPerHunk = Array.isArray(rawDecisions.perHunk) ? rawDecisions.perHunk : []\n const perHunk = hunks.map((_, i) => {\n const value = rawPerHunk[i]\n if (value === 'accepted' || value === 'rejected') return value\n return call === 'accepted' || call === 'rejected' ? call : 'pending'\n })\n const before = typeof r.before === 'string' ? r.before : null\n const hasAfter = Object.prototype.hasOwnProperty.call(r, 'after')\n const after = typeof r.after === 'string' ? r.after : null\n return {\n callId: r.callId,\n toolName,\n path: r.path,\n before,\n after,\n baseFingerprint: typeof r.baseFingerprint === 'string' ? r.baseFingerprint : fingerprint(before),\n afterFingerprint: typeof r.afterFingerprint === 'string' ? r.afterFingerprint : fingerprint(after),\n legacy: !hasAfter,\n conflict: r.conflict === true,\n create: r.create === true,\n callHunk: r.callHunk && typeof (r.callHunk as { oldText?: unknown }).oldText === 'string' && typeof (r.callHunk as { newText?: unknown }).newText === 'string'\n ? { oldText: (r.callHunk as { oldText: string }).oldText, newText: (r.callHunk as { newText: string }).newText }\n : null,\n hunks,\n decisions: { call: call as Decision, perHunk },\n note: typeof r.note === 'string' ? r.note : null,\n superseded: r.superseded === true,\n archived: r.archived === true,\n batch: Number.isInteger(r.batch) ? (r.batch as number) : 0,\n at: typeof r.at === 'string' ? r.at : new Date().toISOString(),\n }\n}\n\n/**\n * 写决策到记录(scope=call 整体 / hunk 单个块)。\n * @author ddj 2026年08月20号\n * @param record 记录\n * @param scope 作用域\n * @param idx hunk 下标(仅 scope=hunk 时生效)\n * @param value 决策值\n * @returns 更新后的记录(原对象就地修改)\n */\nexport function markDecision(record: DiffRecord, scope: string, idx: number | undefined, value: Decision): DiffRecord {\n const dec = record.decisions\n if (scope === 'hunk' && Array.isArray(dec.perHunk) && Number.isInteger(idx)) {\n const i = idx as number\n if (i >= 0 && i < dec.perHunk.length) dec.perHunk[i] = value\n } else {\n dec.call = value\n if (Array.isArray(dec.perHunk)) dec.perHunk = dec.perHunk.map(() => value)\n }\n record.at = new Date().toISOString()\n return record\n}\n\n/** 记录是否已无任何待决策差异(superseded 或全部已决策)。 */\nexport function recordResolved(record: DiffRecord): boolean {\n if (record.superseded === true) return true\n const hunks = Array.isArray(record.hunks) ? record.hunks : []\n const perHunk = Array.isArray(record.decisions.perHunk) ? record.decisions.perHunk : []\n const count = Math.max(hunks.length, perHunk.length)\n if (!count) return record.decisions.call === 'accepted' || record.decisions.call === 'rejected'\n for (let idx = 0; idx < count; idx++) {\n const precise = preciseHunk(record, idx)\n const value = perHunk[idx] ?? record.decisions.call\n if (isNoopHunk(precise) && value === 'pending') return false\n if (value !== 'accepted' && value !== 'rejected') return false\n }\n return true\n}\n\n/**\n * 记录决策摘要(采纳/拒绝/待处理计数,superseded 标记)。\n * @author ddj 2026年08月20号\n * @param record 记录\n * @returns 摘要\n */\nexport function recSummary(record: DiffRecord): RecordSummary {\n const hunks = Array.isArray(record.hunks) ? record.hunks : []\n const perHunk = Array.isArray(record.decisions.perHunk) ? record.decisions.perHunk : []\n const n = Math.max(1, hunks.length, perHunk.length)\n let accepted = 0\n let rejected = 0\n let pending = 0\n for (let i = 0; i < n; i++) {\n const hunk = preciseHunk(record, i)\n const value = perHunk[i] ?? record.decisions.call\n if (i < hunks.length && isNoopHunk(hunk) && value === 'pending') continue\n if (value === 'accepted') accepted++\n else if (value === 'rejected') rejected++\n else pending++\n }\n return { accepted, rejected, pending, superseded: record.superseded === true }\n}\n\n/**\n * 重建\"本批次修改前\"内容:把仍待处理(pending)的差异块按 新→旧 顺序从当前内容反解\n * (newText → oldText)。已采纳/已拒绝的块跳过。反解失败的块标记为 stale。\n * @author ddj 2026年08月20号\n * @param records 该文件的活动记录\n * @param content 当前磁盘内容\n * @returns 重建内容与 stale 定位\n */\nexport function reconstructOriginal(records: DiffRecord[], content: string): { content: string; stale: Array<{ callId: string; idx: number }> } {\n const pending: Array<{ rec: DiffRecord; idx: number; hunk: Hunk }> = []\n for (const rec of records) {\n for (let i = 0; i < rec.hunks.length; i++) {\n const st = rec.decisions.perHunk[i] ?? rec.decisions.call\n const hunk = preciseHunk(rec, i)\n if (st === 'pending' && hunk && !isNoopHunk(hunk)) pending.push({ rec, idx: i, hunk })\n }\n }\n pending.sort((a, b) => (a.rec.at < b.rec.at ? 1 : a.rec.at > b.rec.at ? -1 : 0))\n const locations = locateHunks(content, pending.map((item) => item.hunk))\n const rebuilt = applyLocations(content, locations, true)\n return {\n content: rebuilt.content,\n stale: rebuilt.stale.map((idx) => ({ callId: pending[idx].rec.callId, idx: pending[idx].idx })),\n }\n}\n\n/** 文件当前最大批次号(无记录为 0)。 */\nexport function fileMaxBatch(records: Map<string, DiffRecord>, path: string): number {\n let m = 0\n for (const r of records.values()) {\n if (r.path === path && Number.isInteger(r.batch) && r.batch > m) m = r.batch\n }\n return m\n}\n\n/** 记录桶裁剪:超出 MAX_RECORDS 时剔除最旧的。 */\nexport function prune(map: Map<string, DiffRecord>, max = MAX_RECORDS): void {\n if (map.size <= max) return\n const sorted = [...map.values()].sort((a, b) => (a.at < b.at ? -1 : 1))\n for (let i = 0; i < sorted.length - max; i++) map.delete(sorted[i].callId)\n}\n\n/** 按批次分组记录。 */\nexport function groupByBatch(recs: DiffRecord[]): Map<number | null, DiffRecord[]> {\n const map = new Map<number | null, DiffRecord[]>()\n for (const r of recs) {\n const k = Number.isInteger(r.batch) ? r.batch : null\n if (!map.has(k)) map.set(k, [])\n map.get(k)!.push(r)\n }\n return map\n}\n\n/**\n * 归档条目构造(一条批次一条)。\n * @author ddj 2026年08月20号\n * @param recs 同批次记录(非空)\n * @param cwd 工作区\n * @param reason 归档原因\n */\nexport function archiveEntryFor(recs: DiffRecord[], cwd: string, reason: string): {\n at: string\n cwd: string\n path: string\n batch: number | null\n reason: string\n records: Array<Record<string, unknown>>\n} {\n const first = recs[0]\n return {\n at: new Date().toISOString(),\n cwd,\n path: first.path,\n batch: Number.isInteger(first.batch) ? first.batch : null,\n reason,\n records: recs.map((r) => ({\n callId: r.callId,\n toolName: r.toolName,\n path: r.path,\n create: r.create === true,\n callHunk: r.callHunk,\n hunks: r.hunks,\n decisions: r.decisions,\n note: r.note ?? null,\n before: typeof r.before === 'string' ? r.before : null,\n after: typeof r.after === 'string' ? r.after : null,\n baseFingerprint: r.baseFingerprint ?? null,\n afterFingerprint: r.afterFingerprint ?? null,\n conflict: r.conflict === true,\n legacy: r.legacy === true,\n superseded: r.superseded === true,\n batch: Number.isInteger(r.batch) ? r.batch : null,\n at: r.at,\n summary: recSummary(r),\n })),\n }\n}\n","/**\n * dsh-vscode-mode host — 存储层(sidecar 读写合并 + 归档持久化 + stale 检测)。\n * 迁移自原 src/index.ts 的 fs/ctx IO 部分,语义一字不改。\n * 作者 ddj 2026-08-20\n */\nimport type { ArchiveBatch, ArchiveData, DiffRecord, SidecarData } from './shared/types.js'\nimport type { ReadState } from './shared/diff.js'\nimport { fingerprint, isNoopHunk, locateHunks, preciseHunk } from './shared/diff.js'\nimport { archiveEntryFor, groupByBatch, normalizeRecord } from './model.js'\n\nexport const SIDECAR = '.dsh-edit-review.json'\nexport const SIDECAR_ARCHIVE = '.dsh-edit-review-archive.json'\nexport const READ_CAP = 8 * 1024 * 1024\n\n/** DSH 上下文与会话类型较宽松:本地无 dsh 类型声明,显式 any + 文档约束。 */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Ctx = any\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Session = any\n\n/** 会话沙箱策略(policyOf):可能不存在,调用方需容忍 undefined。 */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function policyOf(ctx: Ctx, session: Session | undefined): any {\n const svc = ctx.get('sandboxPolicy')\n if (!svc) return undefined\n return session ? svc.resolve({ session }) : svc.resolve()\n}\n\n/** 按会话 cwd 解析目标路径。 */\nexport async function resolveTarget(ctx: Ctx, session: Session | undefined, path: string): Promise<string> {\n const fs = ctx.get('fs')\n const cwd = session?.header?.cwd\n return fs.resolve(path, cwd ? { cwd } : {})\n}\n\n/** 读取工作区主 sidecar 文本(缺失/失败 → null)。 */\nasync function readSidecarText(ctx: Ctx, cwd: string | null): Promise<string | null> {\n const fs = ctx.get('fs')\n if (!fs || !cwd) return null\n try {\n return await fs.readText(await fs.resolve(SIDECAR, { cwd }))\n } catch (error) {\n return null\n }\n}\n\n/**\n * 解析主 sidecar:v2 直接返回;v1 迁移为 v2 结构(按会话 cwd 分桶)。\n * @author ddj 2026年08月20号\n * @param text sidecar 文本\n * @returns v2 数据或 null\n */\nexport function parseSidecar(text: string | null): SidecarData | null {\n if (!text) return null\n try {\n const data = JSON.parse(text)\n if (data && typeof data === 'object' && data.version === 2 && data.workspaces && typeof data.workspaces === 'object') {\n return data as SidecarData\n }\n if (data && data.version === 1 && data.sessions && typeof data.sessions === 'object') {\n const workspaces: SidecarData['workspaces'] = {}\n for (const bucket of Object.values(data.sessions)) {\n const b = bucket as { cwd?: unknown; records?: unknown; at?: unknown }\n if (typeof b.cwd === 'string' && b.records) {\n workspaces[b.cwd] = { at: typeof b.at === 'number' ? b.at : Date.now(), records: b.records as Record<string, DiffRecord> }\n }\n }\n return { version: 2, updatedAt: typeof data.updatedAt === 'string' ? data.updatedAt : new Date().toISOString(), workspaces }\n }\n return null\n } catch (error) {\n return null\n }\n}\n\n/** 加载某工作区的记录桶(内存 Map;缺失 → 空)。 */\nexport async function loadBucket(ctx: Ctx, cwd: string): Promise<Map<string, DiffRecord>> {\n const text = await readSidecarText(ctx, cwd)\n const data = parseSidecar(text)\n const map = new Map<string, DiffRecord>()\n if (data && data.workspaces[cwd] && typeof data.workspaces[cwd].records === 'object') {\n for (const rec of Object.values(data.workspaces[cwd].records)) {\n const n = normalizeRecord(rec)\n if (n) map.set(n.callId, n)\n }\n }\n return map\n}\n\n/** 保存某工作区的记录桶(写前合并,不覆盖其他工作区)。 */\nexport async function saveBucket(ctx: Ctx, cwd: string, recsMap: Map<string, DiffRecord>, session?: Session): Promise<void> {\n const fs = ctx.get('fs')\n if (!fs || !cwd) return\n try {\n const target = await fs.resolve(SIDECAR, { cwd })\n const existing = parseSidecar(await readSidecarText(ctx, cwd)) ?? { version: 2, updatedAt: '', workspaces: {} } as SidecarData\n existing.workspaces[cwd] = { at: Date.now(), records: Object.fromEntries(recsMap) }\n existing.updatedAt = new Date().toISOString()\n await fs.writeText(target, JSON.stringify(existing), void 0, void 0, policyOf(ctx, session))\n } catch (error) {\n console.error('edrv saveBucket failed', error)\n }\n}\n\n/**\n * 读取记录目标文件内容(按 path 缓存一次;缺失/过大/失败 → null/'' 占位)。\n * @author ddj 2026年08月20号\n * @param cache path → 内容(null=缺失/读取失败,''=过大跳过)\n */\nexport async function readForCache(ctx: Ctx, session: Session, cache: Map<string, ReadState>, path: string): Promise<ReadState> {\n const cached = cache.get(path)\n if (cached) return cached\n const fs = ctx.get('fs')\n if (!fs) { const state: ReadState = { kind: 'unavailable' }; cache.set(path, state); return state }\n try {\n const target = await resolveTarget(ctx, session, path)\n const info = await fs.stat(target)\n if (!info || info.type !== 'file') { const state: ReadState = { kind: 'missing' }; cache.set(path, state); return state }\n if ((info.size ?? 0) > READ_CAP) { const state: ReadState = { kind: 'unavailable' }; cache.set(path, state); return state }\n const state: ReadState = { kind: 'content', content: await fs.readText(target) }\n cache.set(path, state)\n return state\n } catch (error) {\n const state: ReadState = { kind: 'unavailable' }\n cache.set(path, state)\n return state\n }\n}\n\n/**\n * 判断记录是否已无任何可操作差异(stale):待决策 hunk 的新文本在磁盘均找不到,\n * 或新建文件已不存在,或全为空差异。满足则应由 host 自动归档。\n * @author ddj 2026年08月20号\n */\nexport async function recordIsStale(ctx: Ctx, session: Session, cache: Map<string, ReadState>, rec: DiffRecord): Promise<boolean> {\n if (rec.superseded === true) return true\n if (!Array.isArray(rec.hunks) || !rec.hunks.length) return true\n const state = await readForCache(ctx, session, cache, rec.path)\n if (state.kind === 'unavailable') return false\n if (state.kind === 'missing') return true\n if (rec.create === true) return false\n const pending = rec.hunks.map((_, idx) => ({ idx, hunk: preciseHunk(rec, idx), status: rec.decisions.perHunk[idx] ?? rec.decisions.call }))\n .filter((item) => item.status === 'pending' && item.hunk && !isNoopHunk(item.hunk))\n if (!pending.length) return true\n const currentFingerprint = fingerprint(state.content)\n if (rec.afterFingerprint && currentFingerprint === rec.afterFingerprint) { rec.conflict = false; return false }\n const locations = locateHunks(state.content, pending.map((item) => item.hunk!))\n if (locations.some((location) => location.matched)) { rec.conflict = false; return false }\n rec.conflict = true\n return false\n}\n\n/**\n * edrv.list 全量轮询时自动清理 stale 记录:标记 superseded 并归档,\n * 防止\"幽灵差异\"长期留在审查列表且无法操作。\n * @author ddj 2026年08月20号\n * @returns 自动归档条数\n */\nexport async function autoArchiveStale(ctx: Ctx, session: Session, cwd: string, bucket: Map<string, DiffRecord>): Promise<number> {\n const fs = ctx.get('fs')\n if (!fs) return 0\n const cache = new Map<string, ReadState>()\n const stale: DiffRecord[] = []\n for (const rec of bucket.values()) {\n if (rec.archived || rec.superseded === true) continue\n if (await recordIsStale(ctx, session, cache, rec)) stale.push(rec)\n }\n if (!stale.length) return 0\n for (const r of stale) { r.superseded = true; r.at = new Date().toISOString() }\n await archiveRecords(ctx, session, cwd, bucket, stale, '差异无法定位(已被后续修改覆盖),自动归档')\n return stale.length\n}\n\n/** 读取归档 sidecar 文本(缺失/失败 → null)。 */\nexport async function readArchiveText(ctx: Ctx, cwd: string | null): Promise<string | null> {\n const fs = ctx.get('fs')\n if (!fs || !cwd) return null\n try {\n return await fs.readText(await fs.resolve(SIDECAR_ARCHIVE, { cwd }))\n } catch (error) {\n return null\n }\n}\n\n/** 解析归档 sidecar(损坏 → 空数组)。 */\nexport function parseArchive(text: string | null): ArchiveBatch[] {\n if (!text) return []\n try {\n const data = JSON.parse(text)\n if (data && typeof data === 'object' && Array.isArray(data.batches)) return data.batches as ArchiveBatch[]\n } catch (error) { /* 忽略损坏 */ }\n return []\n}\n\n/** 追加归档条目(按 cwd+path+batch 合并,同 callId 去重)。 */\nexport async function appendArchiveEntries(ctx: Ctx, cwd: string, entries: Array<ReturnType<typeof archiveEntryFor>>, session?: Session): Promise<void> {\n const fs = ctx.get('fs')\n if (!fs || !cwd) return\n try {\n const target = await fs.resolve(SIDECAR_ARCHIVE, { cwd })\n const existing = parseArchive(await readArchiveText(ctx, cwd))\n for (const e of entries) {\n const idx = existing.findIndex((x) => x.cwd === e.cwd && x.path === e.path && x.batch === e.batch)\n if (idx >= 0) {\n const exist = existing[idx]\n const seen = new Set((exist.records || []).map((r) => r.callId))\n for (const rec of e.records) {\n if (!seen.has(String(rec.callId))) {\n exist.records.push(rec as unknown as ArchiveBatch['records'][number])\n seen.add(String(rec.callId))\n }\n }\n exist.lastAt = e.at\n exist.reason = e.reason\n } else {\n existing.push(e as unknown as ArchiveBatch)\n }\n }\n const data: ArchiveData = { version: 1, updatedAt: new Date().toISOString(), batches: existing }\n await fs.writeText(target, JSON.stringify(data), void 0, void 0, policyOf(ctx, session))\n } catch (error) {\n console.error('edrv appendArchiveEntries failed', error)\n }\n}\n\n/** 归档记录:标记 archived、按批次写入归档、落盘工作区桶。 */\nexport async function archiveRecords(\n ctx: Ctx,\n session: Session,\n cwd: string,\n bucket: Map<string, DiffRecord>,\n recs: DiffRecord[],\n reason: string,\n): Promise<void> {\n if (!recs.length) return\n const fresh = recs.filter((r) => !r.archived)\n for (const r of recs) r.archived = true\n const entries: Array<ReturnType<typeof archiveEntryFor>> = []\n for (const list of groupByBatch(recs).values()) entries.push(archiveEntryFor(list, cwd, reason))\n await appendArchiveEntries(ctx, cwd, entries, session)\n if (fresh.length) await saveBucket(ctx, cwd, bucket, session)\n}\n","/**\n * dsh-vscode-mode host — 工作区记录桶注册表与会话助手。\n * 迁移自原 src/index.ts 的 registry/sessionOf/cwdOf/bucketOf,语义不改。\n * 作者 ddj 2026-08-20\n */\nimport type { DiffRecord } from './shared/types.js'\nimport type { Ctx, Session } from './store.js'\nimport { loadBucket } from './store.js'\n\n/** cwd → 记录桶(内存缓存;随会话销毁清理)。 */\nexport type Registry = Map<string, Map<string, DiffRecord>>\n\n/** 按 sessionId 取会话;缺省时仅当唯一活跃会话才返回。 */\nexport function sessionOf(ctx: Ctx, sessionId?: string): Session | undefined {\n const sessions = ctx.get('sessions')\n if (!sessions) return undefined\n if (sessionId) return sessions.get(sessionId)\n const live = sessions.list().filter((s: Session) => s.id)\n return live.length === 1 ? live[0] : undefined\n}\n\n/** 会话工作区 cwd。 */\nexport function cwdOf(session: Session | undefined): string | null {\n return session?.header?.cwd ?? null\n}\n\n/** 取(或加载)某工作区记录桶。 */\nexport function bucketOf(registry: Registry, ctx: Ctx, cwd: string): Promise<Map<string, DiffRecord>> {\n const existing = registry.get(cwd)\n if (existing) return Promise.resolve(existing)\n return loadBucket(ctx, cwd).then((map) => {\n registry.set(cwd, map)\n return map\n })\n}\n","/**\n * dsh-vscode-mode host — 捕获层:监听 tools/result,把 edit/write 差异落成审查记录。\n * 迁移自原 src/index.ts 的 tools/result 处理,语义不改。\n * 作者 ddj 2026-08-20\n */\nimport type { DiffRecord, Hunk } from './shared/types.js'\nimport { annotateHunks, fingerprint } from './shared/diff.js'\nimport type { Ctx, Session } from './store.js'\nimport { archiveRecords, loadBucket, saveBucket } from './store.js'\nimport { fileMaxBatch, prune, recordResolved } from './model.js'\nimport type { Registry } from './registry.js'\nimport { cwdOf } from './registry.js'\n\n/** 校验并提取工具 result meta 中的文件 hunk。 */\nfunction validHunks(raw: unknown): Hunk[] {\n if (!Array.isArray(raw)) return []\n const hunks: Hunk[] = []\n for (const item of raw) {\n if (!item || typeof item !== 'object') continue\n const hunk = item as Record<string, unknown>\n if (typeof hunk.newText !== 'string') continue\n if (hunk.oldText !== null && typeof hunk.oldText !== 'string') continue\n hunks.push({ oldText: hunk.oldText as string | null, newText: hunk.newText })\n }\n return hunks\n}\n\n/** 已有文件 write 的元数据缺失时,用权威整文件快照保底。 */\nfunction fallbackHunks(toolName: string, args: Record<string, unknown>, before: string | null, after: string | null, create: boolean): Hunk[] {\n if (create) return [{ oldText: null, newText: after ?? (typeof args.content === 'string' ? args.content : '') }]\n if (toolName === 'edit' && typeof args.old_string === 'string' && typeof args.new_string === 'string') {\n return [{ oldText: args.old_string, newText: args.new_string }]\n }\n if (toolName === 'write' && before !== null && after !== null && before !== after) {\n return [{ oldText: before, newText: after }]\n }\n if (toolName === 'write' && after !== null) return [{ oldText: null, newText: after }]\n return []\n}\n\n/**\n * 捕获一次工具执行结果(tools/result):edit/write 成功时构造记录、\n * 递增文件批次、融合归档被后续修改取代的旧差异、落盘。\n * @author ddj 2026年08月20号\n * @param ctx DSH 上下文\n * @param registry 工作区记录桶注册表\n * @param exec 工具执行描述(name/arguments/callId/agent.session)\n * @param result 执行结果(value/meta/isError)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function captureToolResult(ctx: Ctx, registry: Registry, exec: any, result: any): Promise<void> {\n const session: Session | undefined = exec?.agent?.session\n if (!session || (exec?.name !== 'edit' && exec?.name !== 'write')) return\n if (result?.isError || !result?.value) return\n try {\n const cwd = cwdOf(session)\n if (!cwd) return\n const value = result.value\n const args = (exec.arguments || {}) as Record<string, unknown>\n const path = typeof value.path === 'string' ? value.path : args.file_path\n if (typeof path !== 'string' || !path) return\n const before = typeof value.before === 'string' ? value.before : null\n const after = typeof value.after === 'string' ? value.after : (typeof args.content === 'string' ? args.content : null)\n const create = exec.name === 'write' && value.before === null\n const callHunk = exec.name === 'edit' && typeof args.old_string === 'string' && typeof args.new_string === 'string'\n ? { oldText: args.old_string, newText: args.new_string }\n : null\n const metaHunks = validHunks(result.meta?.diffs)\n const rawHunks = metaHunks.length ? metaHunks : fallbackHunks(exec.name, args, before, after, create)\n const hunks = annotateHunks(rawHunks, before, after)\n if (!hunks.length || typeof exec.callId !== 'string') return\n const record: DiffRecord = {\n callId: exec.callId,\n toolName: exec.name,\n path,\n before,\n after,\n baseFingerprint: fingerprint(before),\n afterFingerprint: fingerprint(after),\n legacy: false,\n conflict: false,\n create,\n callHunk,\n hunks,\n decisions: { call: 'pending', perHunk: hunks.map(() => 'pending') },\n note: create ? '新建文件:全部拒绝将删除该文件' : before === null ? '未捕获修改前内容(大文件)' : null,\n superseded: false,\n archived: false,\n batch: 0,\n at: new Date().toISOString(),\n }\n let bucket = registry.get(cwd)\n if (!bucket) { bucket = await loadBucket(ctx, cwd); registry.set(cwd, bucket) }\n record.batch = fileMaxBatch(bucket, path) + 1\n bucket.set(exec.callId, record)\n // 融合:文件被再次修改(batch 递增)时,早于最新批次的未归档差异一律归档(内容已含其效果/被取代)\n const prior: DiffRecord[] = []\n for (const r of bucket.values()) {\n if (r.path === path && r.callId !== exec.callId && !r.archived && (r.batch ?? 0) < record.batch) prior.push(r)\n }\n if (prior.length) {\n await archiveRecords(ctx, session, cwd, bucket, prior, prior.every(recordResolved) ? '已处理且被后续修改取代' : '被后续修改融合(内容已含其效果)')\n }\n prune(bucket)\n await saveBucket(ctx, cwd, bucket, session)\n } catch (error) {\n console.error('edrv capture failed', error)\n }\n}\n","/**\n * dsh-vscode-mode host — 工作区文件清单扫描与缓存(快速打开/搜索用)。\n * 迁移自原 src/index.ts 的 listWorkspaceFiles,语义不改。\n * 作者 ddj 2026-08-20\n */\nimport type { Ctx, Session } from './store.js'\nimport { policyOf } from './store.js'\n\n/** 文件清单缓存 TTL 与扫描上限(避免大工作区反复全量扫描)。 */\nconst FILE_INDEX_TTL = 60_000\nconst SCAN_CAP = 6000\n/** cwd → { at, files }(随会话销毁清理)。 */\nconst fileIndex = new Map<string, { at: number; files: string[] }>()\n\n/**\n * 扫描工作区文件清单(快速打开/搜索用):subprocess(Windows powershell / POSIX find),\n * 排除常见重目录,容量上限 SCAN_CAP;结果缓存(TTL FILE_INDEX_TTL)。失败返回 null。\n * @author ddj 2026年08月20号\n * @param ctx DSH 上下文\n * @param session 会话(取工作区根)\n * @param cwd 工作区目录\n * @returns 绝对路径清单;不可用(无 subprocess/fs)或扫描失败返回 null\n */\nexport async function listWorkspaceFiles(ctx: Ctx, session: Session, cwd: string): Promise<string[] | null> {\n const cached = fileIndex.get(cwd)\n if (cached && Date.now() - cached.at < FILE_INDEX_TTL) return cached.files\n const sub = ctx.get('subprocess')\n const fs = ctx.get('fs')\n if (!sub || !fs) return null\n const policy = policyOf(ctx, session)\n let root: string\n try {\n const rootTarget = await fs.resolve(policy?.workspaceRoot ?? '.', {})\n root = fs.processPath(rootTarget)\n } catch (error) {\n root = cwd\n }\n const lines: string[] = []\n const run = async (argv: string[]): Promise<void> => {\n const handle = sub.spawn({\n argv,\n stdio: { stdout: { maxBytes: 8 << 20 }, stderr: { maxBytes: 1 << 16 }, stdin: 'ignore' },\n graceMs: 20000,\n })\n const outcome = await handle.done\n const code = outcome?.exitCode ?? outcome?.code\n if (code !== 0) throw new Error('scan exit ' + code)\n const text = handle.collected?.stdout?.readFrom(0).text ?? ''\n for (const ln of text.split(/\\r?\\n/)) {\n const s = ln.trim()\n if (s) lines.push(s)\n }\n }\n try {\n if (process.platform === 'win32') {\n const cmd = 'Get-ChildItem -LiteralPath \"' + String(root).replace(/\"/g, '\"\"') + '\" -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch \\'(node_modules|\\\\.git|\\\\.tmp|\\\\.cache|dist|build|vendor|coverage|__pycache__)\\' } | Select-Object -First ' + SCAN_CAP + ' | ForEach-Object { $_.FullName }'\n await run(['powershell', '-NoProfile', '-NonInteractive', '-Command', cmd])\n } else {\n const cmd = 'find ' + JSON.stringify(root) + ' -type f -not -path \\'*/node_modules/*\\' -not -path \\'*/.git/*\\' -not -path \\'*/.tmp/*\\' -not -path \\'*/.cache/*\\' -not -path \\'*/dist/*\\' -not -path \\'*/build/*\\' -not -path \\'*/vendor/*\\' -not -path \\'*/coverage/*\\' 2>/dev/null | head -n ' + SCAN_CAP\n await run(['/bin/sh', '-c', cmd])\n }\n } catch (error) {\n console.error('edrv scan failed', error)\n return null\n }\n const files = lines.slice(0, SCAN_CAP)\n if (files.length) fileIndex.set(cwd, { at: Date.now(), files })\n return files\n}\n\n/** 会话销毁时清理文件索引缓存。 */\nexport function dropFileIndex(cwd: string): void {\n fileIndex.delete(cwd)\n}\n","/**\n * dsh-vscode-mode host — 回滚/删除(fs + subprocess 操作)。\n * 迁移自原 src/index.ts 的 revertCall/revertHunk/deleteCreated/restoreFile,语义不改。\n * 作者 ddj 2026-08-20\n */\nimport type { DiffRecord } from './shared/types.js'\nimport type { Ctx, Session } from './store.js'\nimport { policyOf, resolveTarget } from './store.js'\nimport { applyLocations, locateHunks, preciseHunk } from './shared/diff.js'\n\nexport type Result = { ok: true } | { ok: false; error: string }\n\n/**\n * 删除新建文件(拒绝创建时):subprocess 删除,路径先经 fs.contains 校验工作区边界。\n * @author ddj 2026年08月20号\n * @returns 成功或失败原因\n */\nexport async function deleteCreated(ctx: Ctx, session: Session, record: DiffRecord): Promise<Result> {\n const sub = ctx.get('subprocess')\n const fs = ctx.get('fs')\n if (!sub || !fs) return { ok: false, error: '回滚不可用:缺少 subprocess/fs' }\n const policy = policyOf(ctx, session)\n const rootTarget = await fs.resolve(policy?.workspaceRoot ?? '.', {})\n const target = await resolveTarget(ctx, session, record.path)\n if (!fs.contains(rootTarget, target)) return { ok: false, error: '拒绝删除:目标不在会话工作区内' }\n const p = fs.processPath(target)\n // subprocess 契约:spawn({ argv, stdio, graceMs }),done → { exitCode },输出走 handle.collected\n const attempt = async (argv: string[]): Promise<void> => {\n const handle = sub.spawn({\n argv,\n stdio: { stdout: { maxBytes: 1 << 16 }, stderr: { maxBytes: 1 << 16 }, stdin: 'ignore' },\n graceMs: 10000,\n })\n const outcome = await handle.done\n const code = outcome?.exitCode ?? outcome?.code\n if (code !== 0) {\n const err = handle.collected?.stderr?.readFrom(0).text ?? ''\n throw new Error('exit ' + code + ' ' + err)\n }\n }\n try {\n await attempt(['powershell', '-NoProfile', '-NonInteractive', '-Command', 'Remove-Item -LiteralPath \"' + p + '\" -Force'])\n return { ok: true }\n } catch (error) {\n try {\n await attempt(['/bin/rm', '-f', '--', p])\n return { ok: true }\n } catch (error2) {\n return { ok: false, error: '删除失败(文件仍存在):' + String(error) + ' / ' + String(error2) }\n }\n }\n}\n\n/** 整调用回滚:write/编辑用 before 整文件恢复;新建文件转 deleteCreated。 */\nexport async function revertCall(ctx: Ctx, session: Session, record: DiffRecord): Promise<Result> {\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '回滚不可用:缺少 fs' }\n if (record.before === null) {\n if (!record.create) return { ok: false, error: '无法回滚:缺少修改前内容(大文件或旧记录)' }\n return deleteCreated(ctx, session, record)\n }\n try {\n const target = await resolveTarget(ctx, session, record.path)\n await fs.writeText(target, record.before, void 0, void 0, policyOf(ctx, session))\n return { ok: true }\n } catch (error) {\n return { ok: false, error: '回滚失败:' + String(error) }\n }\n}\n\n/** 单 hunk 回滚:用 callHunk(edit 单 hunk 精确串)经 fs.editText 反替换。 */\nexport async function revertHunk(ctx: Ctx, session: Session, record: DiffRecord, idx: number): Promise<Result> {\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '回滚不可用:缺少 fs' }\n const precise = preciseHunk(record, idx)\n if (!precise) return { ok: false, error: '找不到该差异块' }\n try {\n const target = await resolveTarget(ctx, session, record.path)\n const info = await fs.stat(target)\n if (!info || info.type !== 'file') return { ok: false, error: '回滚失败:文件不存在' }\n if ((info.size ?? 0) > 8 * 1024 * 1024) return { ok: false, error: '回滚失败:文件过大,无法安全定位' }\n const content = await fs.readText(target)\n const location = locateHunks(content, [precise])[0]\n if (!location?.matched) return { ok: false, error: '回滚失败:该区域可能已被后续修改影响' }\n const result = applyLocations(content, [location], true)\n await fs.writeText(target, result.content, void 0, void 0, policyOf(ctx, session))\n return { ok: true }\n } catch (error) {\n return { ok: false, error: '回滚失败:该区域可能已被后续修改影响(' + String(error) + ')' }\n }\n}\n\n/**\n * 恢复文件到记录对应状态(批次回滚用):返回错误文案或 null(成功)。\n * @author ddj 2026年08月20号\n */\nexport async function restoreFile(ctx: Ctx, session: Session, rec: DiffRecord): Promise<string | null> {\n const fs = ctx.get('fs')\n if (!fs) return '缺少 fs'\n if (rec.before === null || rec.before === undefined) {\n if (rec.create === true) {\n const out = await deleteCreated(ctx, session, rec)\n return out.ok ? null : out.error\n }\n return '缺少修改前内容(大文件或旧记录),无法回滚'\n }\n try {\n const target = await resolveTarget(ctx, session, rec.path)\n await fs.writeText(target, rec.before, void 0, void 0, policyOf(ctx, session))\n return null\n } catch (error) {\n return '回滚失败:' + String(error)\n }\n}\n","/**\n * dsh-vscode-mode host — MCP 运行时管理适配层。\n * 只操作已装配的 @deepseek-ai/dsh-mcp-client loader entry,不在浏览器侧连接 MCP。\n * 作者 ddj 2026年08月22号\n */\nimport type { MpcConfig, MpcServer, MpcTool } from './shared/mcp.js'\nimport type { Ctx } from './store.js'\n\nconst MCP_PACKAGE = '@deepseek-ai/dsh-mcp-client'\n/** 项目级 MCP 的 loader entry id 固定前缀(区分 profile 全局 MCP;注意 loader id 不能用 ':' 分隔,故用 '.')。 */\nexport const PROJECT_ENTRY_PREFIX = 'vsm-mcp.'\nconst LEGACY_PROJECT_PREFIX = 'vsm-mcp:'\n\n/** 判断新旧格式项目 entry id,避免旧残留被显示为全局 MCP。 */\nexport function isProjectEntryId(id: string): boolean {\n return id.startsWith(PROJECT_ENTRY_PREFIX) || id.startsWith(LEGACY_PROJECT_PREFIX)\n}\n\n/** 列出当前 loader 中的 MCP entry。 */\nfunction entriesOf(ctx: Ctx): any[] {\n const loader = ctx.get('loader')\n if (!loader || typeof loader.entries !== 'function') return []\n return [...loader.entries()].filter((entry) => entry?.options?.name === MCP_PACKAGE)\n}\nexport { entriesOf }\n\n/** 脱敏配置并保留可编辑字段的存在性。 */\nexport function publicConfig(config: Record<string, unknown>): MpcConfig {\n const out = { ...config } as Record<string, unknown>\n if (out.env && typeof out.env === 'object') out.env = Object.fromEntries(Object.keys(out.env as object).map((key) => [key, '••••••']))\n if (out.headers && typeof out.headers === 'object') out.headers = Object.fromEntries(Object.keys(out.headers as object).map((key) => [key, '••••••']))\n return out as unknown as MpcConfig\n}\n\n/** 从工具注册表读取服务器命名空间下的工具摘要。 */\nexport function toolsOf(ctx: Ctx, serverName: string): MpcTool[] {\n const tools = ctx.get('tools')\n const view = tools?.view?.(void 0)\n const visible = view?.visible\n if (!(visible instanceof Map)) return []\n const prefix = `mcp__${serverName}__`\n return [...visible.entries()].filter(([name]) => String(name).startsWith(prefix)).map(([name, definition]) => ({\n name: String(name).slice(prefix.length),\n description: typeof definition?.description === 'string' ? definition.description : undefined,\n }))\n}\n\n/** 将 loader entry 映射为设置页摘要。 */\nexport function serverOf(ctx: Ctx, entry: any): MpcServer {\n const config = (entry.options?.config ?? {}) as Record<string, unknown>\n const serverName = typeof config.serverName === 'string' ? config.serverName : entry.options?.id ?? 'unknown'\n const tools = toolsOf(ctx, serverName)\n const state = entry.fiber?.state\n return {\n id: String(entry.id ?? entry.options?.id ?? serverName),\n serverName,\n enabled: entry.disabled !== true,\n transport: config.transport === 'streamable-http' ? 'streamable-http' : 'stdio',\n config: publicConfig(config),\n status: state === 2 ? 'connected' : state === 1 ? 'connecting' : 'error',\n toolCount: tools.length,\n tools,\n error: state === 3 ? 'MCP 插件未正常运行' : undefined,\n }\n}\n\n/** 校验 MCP 配置。 */\nexport function validateConfig(config: MpcConfig): void {\n if (!/^[A-Za-z0-9_-]{1,32}$/.test(config.serverName)) throw new Error('serverName 只能包含字母、数字、下划线和连字符(最多 32 位)')\n if (config.transport === 'stdio' && !config.command?.trim()) throw new Error('stdio MCP 必须填写 command')\n if (config.transport === 'streamable-http' && !/^https?:\\/\\//.test(config.url ?? '')) throw new Error('HTTP MCP 必须填写 http(s) URL')\n}\n\n/** 列出全局(profile)MCP 服务,过滤掉新旧格式的项目级条目。 */\nexport function listMcp(ctx: Ctx): { servers: MpcServer[] } {\n return { servers: entriesOf(ctx).filter((entry) => !isProjectEntryId(String(entry.id ?? entry.options?.id ?? ''))).map((entry) => serverOf(ctx, entry)) }\n}\n\n/** 保存 MCP 服务配置并触发 loader 热更新。 */\nexport async function saveMcp(ctx: Ctx, config: MpcConfig): Promise<MpcServer> {\n validateConfig(config)\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const existing = entriesOf(ctx).find((entry) => !isProjectEntryId(String(entry.id ?? entry.options?.id ?? '')) && entry.options?.config?.serverName === config.serverName)\n if (existing) {\n await loader.update(existing.id, { config: { ...config } })\n return serverOf(ctx, loader.resolve(existing.id))\n }\n const id = await loader.create({ name: MCP_PACKAGE, config: { ...config } })\n return serverOf(ctx, loader.resolve(id))\n}\n\n/** 删除 MCP 服务。 */\nexport async function removeMcp(ctx: Ctx, id: string): Promise<void> {\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id) === id)\n if (!entry) throw new Error('MCP 服务不存在')\n await loader.remove(entry.id)\n}\n\n/** 切换 MCP 服务启用状态。 */\nexport async function toggleMcp(ctx: Ctx, id: string, enabled: boolean): Promise<MpcServer> {\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id) === id)\n if (!entry) throw new Error('MCP 服务不存在')\n await loader.update(entry.id, { disabled: !enabled })\n return serverOf(ctx, loader.resolve(entry.id))\n}\n\n/** 重新加载 MCP 服务。 */\nexport async function refreshMcp(ctx: Ctx, id: string): Promise<MpcServer> {\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id) === id)\n if (!entry) throw new Error('MCP 服务不存在')\n await loader.update(entry.id, { config: { ...(entry.options?.config ?? {}) } })\n return serverOf(ctx, loader.resolve(entry.id))\n}\n\nexport type { MpcConfig, MpcServer }\nexport const mcpPackageName = MCP_PACKAGE\n","/**\n * dsh-vscode-mode host — 项目级 MCP 管理。\n * 配置以项目根目录 .mcp.json(mcpServers 格式,对齐 Claude Code/Cursor)存储;\n * 工具经 loader 动态激活(entry id 带 PROJECT_ENTRY_PREFIX,全局生效)。\n * 重启后由本项目从各 .mcp.json 恢复激活;.mcp.json 为持久真相,reconcile 以文件为准。\n * 作者 ddj 2026年08月22号\n */\nimport { createHash } from 'node:crypto'\nimport { PROJECT_ENTRY_PREFIX, entriesOf, serverOf, validateConfig } from './mcp.js'\nimport type { MpcConfig, MpcProject, MpcServer } from './shared/mcp.js'\nimport type { Ctx } from './store.js'\n\nconst FILE_NAME = '.mcp.json'\n\n/** 校验项目路径属于 DSH 已注册 workspace,避免 RPC 写入任意目录。 */\nfunction requireWorkspace(ctx: Ctx, workspacePath: string): { path: string; title?: string } {\n const workspace = (ctx.get('workspaceRegistry')?.list?.() ?? []).find((item: { path: string }) => item.path === workspacePath)\n if (!workspace) throw new Error('项目未注册为 DSH workspace,不能管理项目 MCP')\n return workspace\n}\n\n/** 用户显式 GUI 管理操作的写策略:danger-full-access(写入路径固定为 workspacePath/.mcp.json)。 */\nfunction fullPolicy(ctx: Ctx): unknown {\n const svc = ctx.get('sandboxPolicy')\n if (!svc || typeof svc.resolve !== 'function') return undefined\n return svc.resolve({ mode: 'danger-full-access' })\n}\n\n/** workspace 路径 → 确定性短哈希(entry id 归属段,重启后稳定可解码)。 */\nexport function hashWorkspace(path: string): string {\n return createHash('sha1').update(path).digest('hex').slice(0, 10)\n}\n\n/** 项目 MCP 的 loader entry id:vsm-mcp.<pathHash>.<serverName>(loader id 不能用冒号)。 */\nexport function projectEntryId(workspacePath: string, serverName: string): string {\n return PROJECT_ENTRY_PREFIX + hashWorkspace(workspacePath) + '.' + serverName\n}\n\n/** 读取项目 .mcp.json 顶层对象(缺失 → 空;非法 → 抛错带文案)。 */\nasync function readProjectJson(ctx: Ctx, workspacePath: string): Promise<Record<string, unknown>> {\n const fs = ctx.get('fs')\n if (!fs) throw new Error('缺少 fs 服务')\n const target = await fs.resolve(FILE_NAME, { cwd: workspacePath })\n let text: string\n try {\n text = await fs.readText(target)\n } catch (error) {\n return {}\n }\n let data: unknown\n try {\n data = JSON.parse(text)\n } catch (error) {\n throw new Error('.mcp.json 解析失败:' + String(error))\n }\n if (data === null || typeof data !== 'object' || Array.isArray(data)) throw new Error('.mcp.json 顶层必须是对象')\n return data as Record<string, unknown>\n}\n\n/** 读取并校验 .mcp.json 的 mcpServers 映射(纯函数,可单测)。 */\nexport function serversOf(data: Record<string, unknown>): Record<string, Record<string, unknown>> {\n const raw = data.mcpServers\n if (raw === undefined) return {}\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) throw new Error('.mcp.json 的 mcpServers 必须是对象')\n const out: Record<string, Record<string, unknown>> = {}\n for (const [name, value] of Object.entries(raw)) {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) continue\n out[name] = value as Record<string, unknown>\n }\n return out\n}\n\n/** 把 .mcp.json 单条 server 定义归一化为 MpcConfig(缺传输必填 → null,纯函数可单测)。 */\nexport function configFromDef(def: Record<string, unknown> | undefined, serverName: string): MpcConfig | null {\n if (!def) return null\n const transport = typeof def.url === 'string' ? 'streamable-http' : 'stdio'\n const config: MpcConfig = { serverName, transport }\n if (transport === 'stdio') {\n config.command = typeof def.command === 'string' ? def.command : ''\n config.args = Array.isArray(def.args) ? def.args.map(String) : []\n if (typeof def.cwd === 'string') config.cwd = def.cwd\n if (def.env && typeof def.env === 'object') config.env = Object.fromEntries(Object.entries(def.env as Record<string, unknown>).map(([k, v]) => [k, String(v)]))\n } else {\n config.url = def.url as string\n if (def.headers && typeof def.headers === 'object') config.headers = Object.fromEntries(Object.entries(def.headers as Record<string, unknown>).map(([k, v]) => [k, String(v)]))\n }\n if (typeof def.toolCallTimeoutMs === 'number') config.toolCallTimeoutMs = def.toolCallTimeoutMs\n return config\n}\n\n/** 写回 .mcp.json(保留顶层未知字段与其余 mcpServers,仅改目标 serverName)。 */\nasync function writeProjectJson(ctx: Ctx, workspacePath: string, data: Record<string, unknown>, mcpServers: Record<string, Record<string, unknown>>): Promise<void> {\n const fs = ctx.get('fs')\n if (!fs) throw new Error('缺少 fs 服务')\n const target = await fs.resolve(FILE_NAME, { cwd: workspacePath })\n const next = { ...data, mcpServers }\n await fs.writeText(target, JSON.stringify(next, null, 2) + '\\n', void 0, void 0, fullPolicy(ctx))\n}\n\n/** 查重:目标 serverName 是否已被其他 loader entry(全局或他项目)占用。 */\nfunction findConflict(ctx: Ctx, workspacePath: string, serverName: string): string | null {\n const ownId = projectEntryId(workspacePath, serverName)\n for (const entry of entriesOf(ctx)) {\n if (String(entry.id ?? entry.options?.id ?? '') === ownId) continue\n if (entry.options?.config?.serverName === serverName) {\n return 'serverName \"' + serverName + '\" 已被另一个 MCP 使用(全局或其他项目),请换一个名称'\n }\n }\n return null\n}\n\n/** 激活一个项目 MCP:校验 + 查重 + loader.create。 */\nexport async function activateProjectMcp(ctx: Ctx, workspacePath: string, config: MpcConfig): Promise<MpcServer> {\n validateConfig(config)\n const conflict = findConflict(ctx, workspacePath, config.serverName)\n if (conflict) throw new Error(conflict)\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const id = projectEntryId(workspacePath, config.serverName)\n const existing = entriesOf(ctx).find((entry) => String(entry.id ?? entry.options?.id ?? '') === id)\n if (existing) {\n await loader.update(existing.id, { config: { ...config } })\n return serverOf(ctx, loader.resolve(existing.id))\n }\n const created = await loader.create({ id, name: '@deepseek-ai/dsh-mcp-client', config: { ...config } })\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id ?? candidate.options?.id ?? '') === id)\n if (!entry) throw new Error('MCP 已创建但未能找到 entry(id=' + id + ')')\n return serverOf(ctx, entry)\n}\n\n/** 停用一个项目 MCP(按 entry id)。 */\nexport async function deactivateMcp(ctx: Ctx, entryId: string): Promise<void> {\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id ?? candidate.options?.id ?? '') === entryId)\n if (!entry) return\n await loader.remove(entry.id)\n}\n\n/** 以 .mcp.json 为真相 reconcile 该项目的激活状态(幂等)。 */\nexport async function reconcileProject(ctx: Ctx, workspacePath: string): Promise<void> {\n const data = await readProjectJson(ctx, workspacePath)\n const fileServers = new Set(Object.keys(serversOf(data)))\n const prefix = PROJECT_ENTRY_PREFIX + hashWorkspace(workspacePath) + '.'\n for (const entry of entriesOf(ctx)) {\n const id = String(entry.id ?? entry.options?.id ?? '')\n if (!id.startsWith(prefix)) continue\n const serverName = id.slice(prefix.length)\n if (fileServers.has(serverName)) continue\n await deactivateMcp(ctx, id)\n }\n for (const serverName of fileServers) {\n const config = await configOfServer(ctx, workspacePath, serverName)\n if (config === null) continue\n const id = projectEntryId(workspacePath, serverName)\n if (entriesOf(ctx).some((entry) => String(entry.id ?? entry.options?.id ?? '') === id)) continue\n await activateProjectMcp(ctx, workspacePath, { ...config, serverName })\n }\n}\n\n/** 把 .mcp.json 单条 server 定义归一化为 MpcConfig(缺传输必填 → null)。 */\nasync function configOfServer(ctx: Ctx, workspacePath: string, serverName: string): Promise<MpcConfig | null> {\n const data = await readProjectJson(ctx, workspacePath)\n return configFromDef(serversOf(data)[serverName], serverName)\n}\n\n/** 单个项目的完整视图(fileData + 激活状态合并)。 */\nasync function projectOf(ctx: Ctx, workspacePath: string, title: string): Promise<MpcProject> {\n const fs = ctx.get('fs')\n if (!fs) return { workspacePath, title, servers: [], source: 'project' }\n try {\n const target = await fs.resolve(workspacePath)\n const info = await fs.stat(target)\n if (!info || info.type !== 'directory') return { workspacePath, title, servers: [], source: 'project', missingDir: true }\n } catch (error) {\n return { workspacePath, title, servers: [], source: 'project', missingDir: true }\n }\n await reconcileProject(ctx, workspacePath)\n let servers: MpcServer[] = []\n let fileError: string | undefined\n try {\n const data = await readProjectJson(ctx, workspacePath)\n const prefix = PROJECT_ENTRY_PREFIX + hashWorkspace(workspacePath) + '.'\n servers = entriesOf(ctx).filter((entry) => String(entry.id ?? entry.options?.id ?? '').startsWith(prefix)).map((entry) => serverOf(ctx, entry))\n servers.sort((a, b) => (a.serverName < b.serverName ? -1 : 1))\n } catch (error) {\n fileError = String(error)\n }\n return { workspacePath, title, servers, source: 'project', fileError }\n}\n\n/** 列出全部项目及其项目级 MCP。 */\nexport async function listProjects(ctx: Ctx): Promise<{ projects: MpcProject[] }> {\n const registry = ctx.get('workspaceRegistry')\n const workspaces = registry?.list?.() ?? []\n const projects: MpcProject[] = []\n for (const ws of workspaces) projects.push(await projectOf(ctx, ws.path, ws.title ?? ''))\n return { projects }\n}\n\n/** 保存(新增/更新)一个项目 MCP:写 .mcp.json → 激活。 */\nexport async function projectSave(ctx: Ctx, workspacePath: string, serverName: string, config: MpcConfig): Promise<MpcProject> {\n const workspace = requireWorkspace(ctx, workspacePath)\n validateConfig({ ...config, serverName })\n const conflict = findConflict(ctx, workspacePath, serverName)\n if (conflict) throw new Error(conflict)\n const data = await readProjectJson(ctx, workspacePath)\n const servers = serversOf(data)\n const next = { ...config } as unknown as Record<string, unknown>\n delete next.serverName\n delete next.transport\n delete next.disabled // disabled 由 projectToggle 管理,保存恒为启用\n servers[serverName] = next\n await writeProjectJson(ctx, workspacePath, data, servers)\n await activateProjectMcp(ctx, workspacePath, { ...config, serverName })\n return projectOf(ctx, workspacePath, workspace.title ?? '')\n}\n\n/** 删除一个项目 MCP:停用 → 从 .mcp.json 移除。 */\nexport async function projectRemove(ctx: Ctx, workspacePath: string, serverName: string): Promise<MpcProject> {\n const workspace = requireWorkspace(ctx, workspacePath)\n await deactivateMcp(ctx, projectEntryId(workspacePath, serverName))\n const data = await readProjectJson(ctx, workspacePath)\n const servers = serversOf(data)\n delete servers[serverName]\n await writeProjectJson(ctx, workspacePath, data, servers)\n return projectOf(ctx, workspacePath, workspace.title ?? '')\n}\n\n/** 切换项目 MCP 启用状态(持久化到 .mcp.json + loader.update)。 */\nexport async function projectToggle(ctx: Ctx, workspacePath: string, serverName: string, enabled: boolean): Promise<MpcProject> {\n const workspace = requireWorkspace(ctx, workspacePath)\n const data = await readProjectJson(ctx, workspacePath)\n const servers = serversOf(data)\n const def = servers[serverName]\n if (!def) throw new Error('项目中不存在该 MCP')\n if (enabled) delete def.disabled\n else def.disabled = true\n await writeProjectJson(ctx, workspacePath, data, servers)\n const loader = ctx.get('loader')\n if (loader) {\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id ?? candidate.options?.id ?? '') === projectEntryId(workspacePath, serverName))\n if (entry) await loader.update(entry.id, { disabled: !enabled })\n }\n return projectOf(ctx, workspacePath, workspace.title ?? '')\n}\n\n/** 刷新(重连)项目 MCP。 */\nexport async function projectRefresh(ctx: Ctx, workspacePath: string, serverName: string): Promise<MpcProject> {\n const workspace = requireWorkspace(ctx, workspacePath)\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const id = projectEntryId(workspacePath, serverName)\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id ?? candidate.options?.id ?? '') === id)\n if (!entry) throw new Error('该项目 MCP 未激活')\n await loader.update(entry.id, { config: { ...(entry.options?.config ?? {}) } })\n return projectOf(ctx, workspacePath, workspace.title ?? '')\n}\n","/**\n * dsh-vscode-mode host — RPC 分发:类型化方法表替代巨型 switch。\n * 迁移自原 src/index.ts 的 handleRpc,方法名/载荷/错误文案一字不改。\n * 新功能 = shared/rpc.ts 加方法 + 这里加一个 handler,不改其他模块。\n * 作者 ddj 2026-08-20\n */\nimport type { RpcHandlerMap, RpcMethod, RpcRequestMap, RpcResult } from './shared/rpc.js'\nimport type { DiffRecord, RecordView } from './shared/types.js'\nimport type { Ctx, Session } from './store.js'\nimport {\n READ_CAP,\n appendArchiveEntries,\n archiveRecords,\n autoArchiveStale,\n parseArchive,\n policyOf,\n readArchiveText,\n resolveTarget,\n saveBucket,\n} from './store.js'\nimport { archiveEntryFor, markDecision, recordResolved, reconstructOriginal } from './model.js'\nimport type { Registry } from './registry.js'\nimport { bucketOf, cwdOf, sessionOf } from './registry.js'\nimport { listWorkspaceFiles } from './workspace.js'\nimport { restoreFile, revertCall, revertHunk } from './revert.js'\nimport { listMcp, refreshMcp, removeMcp, saveMcp, toggleMcp } from './mcp.js'\nimport { listProjects, projectRefresh, projectRemove, projectSave, projectToggle } from './mcpProject.js'\n\n/** cwd → Promise 链:串行化 debug 日志追加(fs read+write 非原子,避免并发丢行)。 */\nconst debugWriteQueues = new Map<string, Promise<void>>()\n\n/** 记录 → 客户端视图(不含 before 全文,仅长度)。 */\nfunction recView(record: DiffRecord): RecordView {\n return {\n callId: record.callId,\n toolName: record.toolName,\n path: record.path,\n beforeLen: typeof record.before === 'string' ? record.before.length : 0,\n create: record.create === true,\n callHunk: record.callHunk,\n hunks: record.hunks,\n decisions: record.decisions,\n note: record.note ?? null,\n superseded: record.superseded === true,\n after: record.after ?? null,\n baseFingerprint: record.baseFingerprint ?? null,\n afterFingerprint: record.afterFingerprint ?? null,\n conflict: record.conflict === true,\n legacy: record.legacy === true,\n at: record.at,\n }\n}\n\n/** 会话/工作区公共前置:返回 {session,cwd} 或错误文案。 */\nasync function requireSession(ctx: Ctx, sessionId: string | undefined): Promise<\n { session: Session; cwd: string } | { err: string }\n> {\n const session = sessionOf(ctx, sessionId)\n if (!session) return { err: '会话不存在' }\n const cwd = cwdOf(session)\n if (!cwd) return { err: '会话无工作区' }\n return { session, cwd }\n}\n\n/** 各方法 handler 表(类型由 shared/rpc 的 RpcHandlerMap 约束)。 */\nexport function buildHandlers(ctx: Ctx, registry: Registry): RpcHandlerMap {\n return {\n 'edrv.list': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const want = Array.isArray(args.callIds) ? new Set(args.callIds) : null\n if (!want) await autoArchiveStale(ctx, sc.session, sc.cwd, bucket) // 全量轮询时自动清理 stale 幽灵差异\n const out: RecordView[] = []\n for (const rec of bucket.values()) {\n // 面板全量查询过滤已归档;聊天条按 callId 查询保留(状态徽章仍需正确显示)\n if (!want && rec.archived) continue\n if (want && !want.has(rec.callId)) continue\n out.push(recView(rec))\n }\n out.sort((a, b) => (a.at < b.at ? -1 : 1))\n return { ok: true, records: out }\n },\n 'edrv.accept': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const record = bucket.get(args.callId)\n if (!record) return { ok: false, error: '记录不存在' }\n markDecision(record, args.scope ?? 'call', args.hunkIndex, 'accepted')\n if (recordResolved(record)) await archiveRecords(ctx, sc.session, sc.cwd, bucket, [record], '已处理')\n else await saveBucket(ctx, sc.cwd, bucket, sc.session)\n return { ok: true, record: recView(record) }\n },\n 'edrv.reject': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const record = bucket.get(args.callId)\n if (!record) return { ok: false, error: '记录不存在' }\n const scope = args.scope ?? 'call'\n const outcome = scope === 'hunk' ? await revertHunk(ctx, sc.session, record, args.hunkIndex ?? -1) : await revertCall(ctx, sc.session, record)\n if (!outcome.ok) return { ok: false, error: outcome.error }\n markDecision(record, scope, args.hunkIndex, 'rejected')\n record.at = new Date().toISOString()\n if (recordResolved(record)) await archiveRecords(ctx, sc.session, sc.cwd, bucket, [record], '已处理(回滚)')\n else await saveBucket(ctx, sc.cwd, bucket, sc.session)\n return { ok: true, record: recView(record) }\n },\n 'edrv.read': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '缺少 fs' }\n try {\n const target = await resolveTarget(ctx, sc.session, args.path)\n const info = await fs.stat(target)\n if (!info || info.type !== 'file') return { ok: false, error: '文件不存在' }\n if ((info.size ?? 0) > READ_CAP) return { ok: false, error: '文件过大(>8MB),不支持整文件预览' }\n const content = await fs.readText(target)\n return { ok: true, content, size: content.length }\n } catch (error) {\n return { ok: false, error: '读取失败:' + String(error) }\n }\n },\n 'edrv.original': async (args) => {\n // 重建\"本批次修改前\"内容:DiffEditor 原始侧。仅反解 pending 块;\n // 全部反解失败时回退到最早记录的整体 before(若存在)。\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '缺少 fs' }\n try {\n const target = await resolveTarget(ctx, sc.session, args.path)\n const info = await fs.stat(target)\n if (!info || info.type !== 'file') return { ok: false, error: '文件不存在' }\n if ((info.size ?? 0) > READ_CAP) return { ok: false, error: '文件过大(>8MB),不支持差异重建' }\n const content = await fs.readText(target)\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const records = [...bucket.values()].filter((r) => r.path === args.path && !r.archived).sort((a, b) => (a.at < b.at ? -1 : 1))\n if (!records.length) return { ok: true, content, size: content.length, stale: [], fallback: false }\n const rebuilt = reconstructOriginal(records, content)\n if (rebuilt.stale.length && records[0].before !== null) {\n return { ok: true, content: records[0].before, size: records[0].before.length, stale: rebuilt.stale, fallback: true }\n }\n return { ok: true, content: rebuilt.content, size: rebuilt.content.length, stale: rebuilt.stale, fallback: false }\n } catch (error) {\n return { ok: false, error: '重建失败:' + String(error) }\n }\n },\n 'edrv.save': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '缺少 fs' }\n try {\n const target = await resolveTarget(ctx, sc.session, args.path)\n await fs.writeText(target, args.content, void 0, void 0, policyOf(ctx, sc.session))\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n let changed = false\n for (const rec of bucket.values()) {\n if (rec.path === args.path && rec.superseded !== true) { rec.superseded = true; rec.at = new Date().toISOString(); changed = true }\n }\n if (changed) {\n const done: DiffRecord[] = []\n for (const rec of bucket.values()) if (rec.path === args.path && rec.superseded) done.push(rec)\n if (done.length) await archiveRecords(ctx, sc.session, sc.cwd, bucket, done, '被手动编辑覆盖')\n else await saveBucket(ctx, sc.cwd, bucket, sc.session)\n }\n return { ok: true }\n } catch (error) {\n return { ok: false, error: '保存失败:' + String(error) }\n }\n },\n 'edrv.archiveList': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const batches = parseArchive(await readArchiveText(ctx, sc.cwd)).filter((b) => b.cwd === sc.cwd)\n const entries = batches.map((b) => {\n const recs = Array.isArray(b.records) ? b.records : []\n const sum = recs.reduce((s, r) => {\n const sm = r.summary || { accepted: 0, rejected: 0, pending: 0, superseded: false }\n s.accepted += sm.accepted || 0\n s.rejected += sm.rejected || 0\n s.pending += sm.pending || 0\n if (sm.superseded) s.superseded++\n return s\n }, { accepted: 0, rejected: 0, pending: 0, superseded: 0 })\n return { at: b.at, lastAt: b.lastAt || b.at, path: b.path, batch: b.batch ?? null, reason: b.reason ?? null, nRecords: recs.length, summary: sum }\n })\n entries.sort((a, b) => (Number(b.batch ?? -1) - Number(a.batch ?? -1)) || (a.at < b.at ? 1 : -1))\n return { ok: true, entries }\n },\n 'edrv.archiveRead': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const batchPath = args.path\n const batches = parseArchive(await readArchiveText(ctx, sc.cwd)).filter((b) => b.cwd === sc.cwd && (!batchPath || b.path === batchPath))\n return { ok: true, batches }\n },\n 'edrv.rollback': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '缺少 fs' }\n const batch = args.batch\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n let affected: DiffRecord[] = []\n let beforeRec: DiffRecord | null = null\n if (batch !== undefined) {\n const all = parseArchive(await readArchiveText(ctx, sc.cwd)).filter((b) => b.cwd === sc.cwd && b.path === args.path)\n const recs: DiffRecord[] = []\n for (const b of all) if (b.batch === batch) for (const r of (b.records || [])) recs.push(r as unknown as DiffRecord)\n if (!recs.length) return { ok: false, error: '归档中找不到该批次' }\n recs.sort((a, b2) => (a.at < b2.at ? -1 : 1))\n beforeRec = recs[0]\n affected = recs\n } else {\n for (const r of bucket.values()) if (r.path === args.path && !r.archived) affected.push(r)\n if (!affected.length) return { ok: false, error: '该文件没有可回滚的差异' }\n affected.sort((a, b2) => (a.at < b2.at ? -1 : 1))\n beforeRec = affected[0]\n }\n const rerr = await restoreFile(ctx, sc.session, beforeRec)\n if (rerr) return { ok: false, error: rerr }\n if (batch === undefined) {\n await archiveRecords(ctx, sc.session, sc.cwd, bucket, affected, '已回滚')\n } else {\n const all = parseArchive(await readArchiveText(ctx, sc.cwd)).filter((b) => b.cwd === sc.cwd && b.path === args.path && b.batch === batch)\n const sumRecs = all.reduce((s, b) => s + ((b.records || []).length), 0)\n const logRec = Object.assign({}, affected[0], { note: (affected[0].note ? affected[0].note + ';' : '') + '回滚至本批次前(批次 ' + batch + ')' })\n await appendArchiveEntries(ctx, sc.cwd, [archiveEntryFor([logRec], sc.cwd, '已回滚(批次 ' + batch + ',' + sumRecs + ' 条)')], sc.session)\n // 批次回滚恢复的是旧内容,文件当前活跃差异已失效,一并归档\n const activeRecs: DiffRecord[] = []\n for (const r of bucket.values()) if (r.path === args.path && !r.archived) activeRecs.push(r)\n if (activeRecs.length) await archiveRecords(ctx, sc.session, sc.cwd, bucket, activeRecs, '已回滚(批次回滚覆盖)')\n }\n return { ok: true, path: args.path, batch: batch ?? null }\n },\n 'edrv.debug': async (args) => {\n // 诊断日志:client 上报 → 写入工作区旁车 .dsh-edit-review-debug.log(console 不一定落盘,文件可靠)\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n const text = String(args.text ?? '')\n const prev = debugWriteQueues.get(sc.cwd) || Promise.resolve()\n const task = prev.then(async () => {\n try {\n const target = await fs.resolve('.dsh-edit-review-debug.log', { cwd: sc.cwd })\n const old = await fs.readText(target).catch(() => '')\n const line = new Date().toISOString() + ' ' + text + '\\n'\n await fs.writeText(target, (old || '') + line, void 0, void 0, policyOf(ctx, sc.session))\n } catch (e) { /* 写日志失败忽略 */ }\n })\n debugWriteQueues.set(sc.cwd, task)\n await task\n console.error('[edrv-debug] ' + text)\n return { ok: true }\n },\n 'edrv.searchFiles': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const query = String(args.query ?? '').trim().toLowerCase()\n const files: string[] = []\n if (query.length >= 2) {\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const pool = new Set<string>()\n // 活跃差异路径恒并入(保证差异文件一定可搜到,即使工作区扫描不可用)\n for (const rec of bucket.values()) if (rec.path) pool.add(rec.path)\n const listed = await listWorkspaceFiles(ctx, sc.session, sc.cwd)\n if (listed) for (const f of listed) pool.add(f)\n const score = (p: string): number => {\n const pl = p.toLowerCase()\n const base = pl.split(/[\\\\/]/).pop() || ''\n if (base.includes(query)) return 0\n if (pl.includes(query)) return 1\n return -1\n }\n const hit = [...pool].filter((p) => score(p) >= 0)\n hit.sort((a, b) => (score(a) - score(b)) || (a < b ? -1 : 1))\n files.push(...hit.slice(0, 50))\n }\n return { ok: true, files, truncated: files.length >= 50 }\n },\n 'mcp.list': async () => ({ ok: true, ...listMcp(ctx) }),\n 'mcp.save': async (args) => {\n try { return { ok: true, server: await saveMcp(ctx, args.config) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.remove': async (args) => {\n try { await removeMcp(ctx, args.id); return { ok: true } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.toggle': async (args) => {\n try { return { ok: true, server: await toggleMcp(ctx, args.id, args.enabled) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.refresh': async (args) => {\n try { return { ok: true, server: await refreshMcp(ctx, args.id) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projects': async () => {\n try { return { ok: true, ...await listProjects(ctx) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projectSave': async (args) => {\n try { return { ok: true, project: await projectSave(ctx, args.workspacePath, args.serverName, args.config) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projectRemove': async (args) => {\n try { return { ok: true, project: await projectRemove(ctx, args.workspacePath, args.serverName) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projectToggle': async (args) => {\n try { return { ok: true, project: await projectToggle(ctx, args.workspacePath, args.serverName, args.enabled) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projectRefresh': async (args) => {\n try { return { ok: true, project: await projectRefresh(ctx, args.workspacePath, args.serverName) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n }\n}\n\n/**\n * 统一入口:按方法分发到 handler 表。\n * @author ddj 2026年08月20号\n */\nexport async function handleRpc<M extends RpcMethod>(\n ctx: Ctx,\n registry: Registry,\n method: M,\n args: RpcRequestMap[M],\n): Promise<RpcResult<M>> {\n const handlers = buildHandlers(ctx, registry)\n const handler = handlers[method]\n if (!handler) return { ok: false, error: '未知方法: ' + String(method) } as RpcResult<M>\n return handler(args)\n}\n","/**\n * dsh-vscode-mode host — 项目 MCP 的 agent 级隔离。\n * 项目 MCP 连接仍由 Host 维护,但每个 agent 只继承当前 workspace 的项目工具;\n * tools.restrict() 负责模型可见性,tools.guard() 负责执行层兜底拒绝。\n * 作者 ddj 2026年08月22号\n */\nimport { PROJECT_ENTRY_PREFIX, entriesOf } from './mcp.js'\nimport { hashWorkspace } from './mcpProject.js'\nimport type { Ctx } from './store.js'\n\nconst LEGACY_PREFIX = 'vsm-mcp:'\nconst UNKNOWN_PROJECT = '__unknown_project__'\n\ntype ToolProjects = Map<string, string>\ntype AgentState = { dispose?: () => void; denyKey: string }\n\n/** 统一 workspace 路径,供 cwd 父路径匹配。 */\nexport function normalizePath(path: string): string {\n const value = String(path ?? '').replace(/\\\\/g, '/').replace(/\\/+/g, '/')\n return value.replace(/\\/$/, '').toLowerCase()\n}\n\n/** 在已注册 workspace 中匹配 cwd,优先最长父路径。 */\nexport function matchWorkspace(cwd: string | undefined, paths: string[]): string | undefined {\n if (!cwd) return undefined\n const target = normalizePath(cwd)\n const matches = paths.filter((path) => {\n const root = normalizePath(path)\n return target === root || target.startsWith(root + '/')\n })\n matches.sort((a, b) => normalizePath(b).length - normalizePath(a).length)\n return matches[0]\n}\n\n/** 根据 entry id 判断是否为新旧格式项目 MCP。 */\nexport function isProjectEntry(id: string): boolean {\n return id.startsWith(PROJECT_ENTRY_PREFIX) || id.startsWith(LEGACY_PREFIX)\n}\n\n/** 从项目 entry id 解析 workspace hash。 */\nfunction entryHash(id: string): string | undefined {\n if (id.startsWith(PROJECT_ENTRY_PREFIX)) return id.slice(PROJECT_ENTRY_PREFIX.length).split('.')[0]\n if (id.startsWith(LEGACY_PREFIX)) return id.slice(LEGACY_PREFIX.length).split(':')[0]\n return undefined\n}\n\n/** 返回一个 agent 不应继承的项目工具名。 */\nexport function denyTools(toolProjects: ToolProjects, currentPath: string | undefined): string[] {\n return [...toolProjects.entries()].filter(([, owner]) => owner !== currentPath).map(([name]) => name).sort()\n}\n\n/** 从 loader entry 和工具注册表建立工具到项目路径的映射。 */\nfunction projectTools(ctx: Ctx): ToolProjects {\n const result: ToolProjects = new Map()\n const registry = ctx.get('workspaceRegistry')\n const workspaces = registry?.list?.() ?? []\n const byHash: Map<string, string> = new Map(workspaces.map((ws: { path: string }) => [hashWorkspace(ws.path), ws.path] as [string, string]))\n const visible = ctx.get('tools')?.view?.(void 0)?.visible\n if (!(visible instanceof Map)) return result\n for (const entry of entriesOf(ctx)) {\n const id = String(entry.id ?? entry.options?.id ?? '')\n if (!isProjectEntry(id)) continue\n const hash = entryHash(id)\n const owner = hash ? byHash.get(hash) ?? UNKNOWN_PROJECT : UNKNOWN_PROJECT\n const serverName = entry.options?.config?.serverName\n if (typeof serverName !== 'string') continue\n const prefix = `mcp__${serverName}__`\n for (const name of visible.keys()) if (String(name).startsWith(prefix)) result.set(String(name), owner)\n }\n return result\n}\n\n/** 取得 agent 当前 cwd 所属 workspace。 */\nfunction agentWorkspace(ctx: Ctx, agent: any): string | undefined {\n const cwd = agent?.session?.header?.cwd\n const paths = (ctx.get('workspaceRegistry')?.list?.() ?? []).map((ws: { path: string }) => ws.path)\n return matchWorkspace(cwd, paths)\n}\n\n/** 同步一个 agent 的项目工具 deny 列表。 */\nfunction syncAgent(ctx: Ctx, state: AgentState, agent: any, tools: ToolProjects): void {\n const current = agentWorkspace(ctx, agent)\n const denied = denyTools(tools, current)\n const nextKey = denied.join('\\n')\n if (state.denyKey === nextKey) return\n state.dispose?.()\n state.dispose = undefined\n if (denied.length > 0) {\n try {\n state.dispose = agent.ctx.tools.restrict({ deny: denied })\n } catch (error) {\n ctx.logger?.warn?.('[dsh-vscode-mode] MCP agent restriction failed: ' + String(error))\n return\n }\n }\n state.denyKey = nextKey\n}\n\n/** 为当前 Host 安装项目 MCP 的 agent restriction 与执行 guard。 */\nexport function installIsolation(ctx: Ctx): void {\n const tools = ctx.get('tools')\n const agents = ctx.get('agents')\n if (!tools || !agents) return\n const states = new Map<any, AgentState>()\n let toolProjects = projectTools(ctx)\n let scheduled = false\n let syncing = false\n\n const syncAll = () => {\n if (syncing) return\n syncing = true\n try {\n toolProjects = projectTools(ctx)\n for (const agent of agents.list?.() ?? []) {\n const state = states.get(agent) ?? { denyKey: '' }\n states.set(agent, state)\n syncAgent(ctx, state, agent, toolProjects)\n }\n } finally {\n syncing = false\n }\n }\n const scheduleSync = () => {\n if (scheduled) return\n scheduled = true\n queueMicrotask(() => {\n scheduled = false\n syncAll()\n })\n }\n const onCreated = ctx.on('agent/created', ({ agent }: { agent: any }) => {\n const state = { denyKey: '' }\n states.set(agent, state)\n syncAgent(ctx, state, agent, toolProjects)\n })\n const onDisposed = ctx.on('agent/disposed', ({ agent }: { agent: any }) => {\n const state = states.get(agent)\n state?.dispose?.()\n states.delete(agent)\n })\n const onToolsChange = ctx.on('tools/change', scheduleSync)\n const stopGuard = tools.guard((exec: any) => {\n const owner = toolProjects.get(String(exec?.name ?? ''))\n if (!owner) return undefined\n const current = agentWorkspace(ctx, exec.agent)\n if (owner === current) return undefined\n return current === undefined\n ? '项目 MCP 需要在已注册工作区的对话中使用'\n : '已拒绝:当前对话工作区不能使用其他项目的 MCP'\n })\n syncAll()\n ctx.effect(() => () => {\n onCreated?.()\n onDisposed?.()\n onToolsChange?.()\n stopGuard?.()\n for (const state of states.values()) state.dispose?.()\n states.clear()\n }, 'vscode-mode:mcp-isolation')\n}\n","/**\n * @dsh-external 生态 → dsh-vscode-mode:DSH 上的类 VSCode 编码体验(Host 半入口)。\n * 职责:装配 capture(tools/result 捕获 edit/write 差异)、RPC 分发(11 个 edrv.* 方法)、\n * webServer 路由(/edrv/rpc、/edrv/assets/*、/edrv/vendor/*)、工作区旁车持久化。\n * 结构:shared/(双面契约) + model/store/capture/workspace/revert/registry/rpc/routes(host 模块)。\n * 作者 ddj 2026-08-20\n */\nimport { registerRoutes } from './routes.js'\nimport { captureToolResult } from './capture.js'\nimport { handleRpc } from './rpc.js'\nimport { installIsolation } from './mcpIsolation.js'\nimport { dropFileIndex } from './workspace.js'\nimport { cwdOf } from './registry.js'\nimport type { Registry } from './registry.js'\nimport type { Ctx } from './store.js'\n\nexport const name = \"dsh-vscode-mode\"\nexport const inject = ['sessions', 'fs', 'webServer', 'loader', 'tools', 'workspaceRegistry', 'agents']\n\n/**\n * 装配插件:挂事件监听、注册路由。\n * @author ddj 2026年08月20号\n * @param ctx DSH 上下文(sessions/fs/webServer 由 inject 提供;sandboxPolicy/subprocess 惰性获取)\n * @param config 插件配置(可选 imageDir 覆盖图标目录)\n */\nexport function apply(ctx: Ctx, config?: unknown): void {\n const registry: Registry = new Map()\n\n ctx.on('tools/result', (exec: unknown, result: unknown) => {\n void captureToolResult(ctx, registry, exec, result)\n })\n\n ctx.on('session/disposed', (session: unknown) => {\n const cwd = cwdOf(session as never)\n if (cwd) {\n registry.delete(cwd)\n dropFileIndex(cwd)\n }\n })\n\n registerRoutes(ctx, config, (method, args) => handleRpc(ctx, registry, method, args))\n installIsolation(ctx)\n\n ctx.logger?.info?.('[' + name + '] 编辑差异审查已装配(/edrv/rpc 路由就绪,项目 MCP 隔离已启用)')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/shared/rpc.ts","../src/routes.ts","../src/shared/diff.ts","../src/model.ts","../src/store.ts","../src/registry.ts","../src/capture.ts","../src/search/query.ts","../src/search/ripgrep.ts","../src/search/fallback.ts","../src/search/ranker.ts","../src/search/orchestrator.ts","../src/revert.ts","../src/mcp.ts","../src/mcpProject.ts","../src/rpc.ts","../src/mcpIsolation.ts","../src/workspace.ts","../src/index.ts"],"sourcesContent":["/**\n * dsh-vscode-mode RPC contract — method names, per-method request/ok payloads,\n * and the typed handler map shared by the host dispatcher and the client\n * fetch wrapper. 载荷形状与历史实现一字不差,仅把隐式约定类型化。\n *\n * Purity rule: no node/react imports (same as types.ts).\n * 作者 ddj 2026-08-20\n */\nimport type {\n ArchiveBatch,\n ArchiveEntry,\n RecordView,\n StaleHunk,\n} from './types.js'\nimport type { MpcConfig, MpcProject, MpcProjectSaveInput, MpcServer } from './mcp.js'\n\n/** webServer 精确路由。 */\nexport const RPC_PATH = '/edrv/rpc'\n\n/** 决策作用域:call=整条记录,hunk=单个差异块。 */\nexport type RpcScope = 'call' | 'hunk'\n\n/** 每个方法的请求参数(sessionId 为公共可选字段)。 */\nexport interface RpcRequestMap {\n 'edrv.list': { sessionId?: string; callIds?: string[] }\n 'edrv.accept': { sessionId?: string; callId: string; scope?: RpcScope; hunkIndex?: number }\n 'edrv.reject': { sessionId?: string; callId: string; scope?: RpcScope; hunkIndex?: number }\n 'edrv.read': { sessionId?: string; path: string }\n 'edrv.original': { sessionId?: string; path: string }\n 'edrv.save': { sessionId?: string; path: string; content: string }\n 'edrv.archiveList': { sessionId?: string }\n 'edrv.archiveRead': { sessionId?: string; path?: string }\n 'edrv.rollback': { sessionId?: string; path: string; batch?: number }\n 'edrv.debug': { sessionId?: string; text: string }\n 'edrv.searchFiles': { sessionId?: string; query: string }\n 'mcp.list': {}\n 'mcp.save': { config: MpcConfig }\n 'mcp.remove': { id: string }\n 'mcp.toggle': { id: string; enabled: boolean }\n 'mcp.refresh': { id: string }\n 'mcp.projects': {}\n 'mcp.projectSave': MpcProjectSaveInput\n 'mcp.projectRemove': { workspacePath: string; serverName: string }\n 'mcp.projectToggle': { workspacePath: string; serverName: string; enabled: boolean }\n 'mcp.projectRefresh': { workspacePath: string; serverName: string }\n}\n\nexport type RpcMethod = keyof RpcRequestMap\n\n/** 每个方法成功(ok:true)时的附加载荷。 */\nexport interface RpcOkMap {\n 'edrv.list': { records: RecordView[] }\n 'edrv.accept': { record: RecordView }\n 'edrv.reject': { record: RecordView }\n 'edrv.read': { content: string; size: number }\n 'edrv.original': { content: string; size: number; stale: StaleHunk[]; fallback: boolean }\n 'edrv.save': object\n 'edrv.archiveList': { entries: ArchiveEntry[] }\n 'edrv.archiveRead': { batches: ArchiveBatch[] }\n 'edrv.rollback': { path: string; batch: number | null }\n 'edrv.debug': object\n 'edrv.searchFiles': { files: string[]; truncated: boolean }\n 'mcp.list': { servers: MpcServer[] }\n 'mcp.save': { server: MpcServer }\n 'mcp.remove': object\n 'mcp.toggle': { server: MpcServer }\n 'mcp.refresh': { server: MpcServer }\n 'mcp.projects': { projects: MpcProject[] }\n 'mcp.projectSave': { project: MpcProject }\n 'mcp.projectRemove': { project: MpcProject }\n 'mcp.projectToggle': { project: MpcProject }\n 'mcp.projectRefresh': { project: MpcProject }\n}\n\n/** 统一响应:{ok:true, ...payload} 或 {ok:false, error}。 */\nexport type RpcResult<M extends RpcMethod> =\n | ({ ok: true } & RpcOkMap[M])\n | { ok: false; error: string }\n\n/** 每个方法的 handler 签名(host 分发表与 client 类型检查共用)。 */\nexport type RpcHandler<M extends RpcMethod> = (\n args: RpcRequestMap[M],\n) => Promise<RpcResult<M>>\n\n/** host RPC 分发表:method → handler。 */\nexport type RpcHandlerMap = {\n [M in RpcMethod]: RpcHandler<M>\n}\n","/**\n * dsh-vscode-mode host — webServer 路由注册(/edrv/rpc、/edrv/assets/*、/edrv/vendor/*)。\n * 迁移自原 src/index.ts 的路由部分,路径/行为一字不改。\n * 作者 ddj 2026-08-20\n */\nimport { readFile } from 'node:fs/promises'\nimport { dirname, extname, join, normalize, resolve, sep } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { RPC_PATH } from './shared/rpc.js'\nimport type { RpcMethod, RpcRequestMap } from './shared/rpc.js'\nimport type { Ctx } from './store.js'\n\nconst IMG_ROUTES = [\n { url: '/edrv/assets/compare-idle.png', file: 'compare_idle.png' },\n { url: '/edrv/assets/compare-select.png', file: 'compare_select.png' },\n]\n\n/** Monaco AMD 构建静态资源(随包发布,离线可用;前缀路由 /edrv/vendor/*)。 */\nconst VENDOR_PREFIX = '/edrv/vendor'\nconst VENDOR_MIME: Record<string, string> = {\n '.js': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json',\n '.map': 'application/json',\n '.ts': 'text/plain; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.gif': 'image/gif',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.html': 'text/html; charset=utf-8',\n '.md': 'text/markdown',\n}\n\n/** 图标目录:默认插件包内 assets/(随包发布);config.imageDir 可覆盖(用于自定义换图)。 */\nfunction imageDirOf(config: unknown): string {\n const cfg = config as { imageDir?: unknown } | undefined\n if (cfg && typeof cfg.imageDir === 'string' && cfg.imageDir) return cfg.imageDir.replace(/\\\\/g, '/')\n return join(dirname(fileURLToPath(import.meta.url)), '..', 'assets')\n}\n\n/** Monaco AMD 静态目录(随包发布)。 */\nconst vendorDir = join(dirname(fileURLToPath(import.meta.url)), '..', 'assets', 'vendor')\n\n/**\n * 注册全部 webServer 路由。\n * @author ddj 2026年08月20号\n * @param ctx DSH 上下文\n * @param config 插件配置(可选 imageDir 等)\n * @param handleRpc RPC 分发入口(method,args → RpcResult)\n */\nexport function registerRoutes(\n ctx: Ctx,\n config: unknown,\n handleRpc: <M extends RpcMethod>(method: M, args: RpcRequestMap[M]) => Promise<unknown>,\n): void {\n const imgDir = imageDirOf(config)\n const web = ctx.get('webServer')\n if (!web) return\n\n ctx.effect(() => web.register({\n kind: 'exact',\n path: RPC_PATH,\n handler: async (req: unknown, res: { statusCode?: number; setHeader: (k: string, v: string) => void; end: (b?: string) => void }) => {\n try {\n const chunks: Uint8Array[] = []\n for await (const chunk of req as AsyncIterable<Uint8Array>) chunks.push(chunk)\n let input: { method?: string; args?: unknown } = {}\n try {\n input = JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}')\n } catch (error) {\n input = {}\n }\n const method = (typeof input.method === 'string' ? input.method : '') as RpcMethod\n const result = await handleRpc(method, (input.args ?? {}) as never)\n res.statusCode = 200\n res.setHeader('content-type', 'application/json')\n res.end(JSON.stringify(result))\n } catch (error) {\n res.statusCode = 500\n res.end(JSON.stringify({ ok: false, error: String(error) }))\n }\n },\n }), 'edrv: /edrv/rpc route')\n\n for (const r of IMG_ROUTES) {\n ctx.effect(() => web.register({\n kind: 'exact',\n path: r.url,\n handler: async (req: unknown, res: { statusCode?: number; setHeader: (k: string, v: string) => void; end: (b?: string | Uint8Array) => void }) => {\n try {\n const body = await readFile(imgDir + '/' + r.file)\n res.statusCode = 200\n res.setHeader('content-type', 'image/png')\n res.setHeader('cache-control', 'no-cache')\n res.end(body)\n } catch (error) {\n res.statusCode = 404\n res.end()\n }\n },\n }), 'edrv: static ' + r.file)\n }\n\n // Monaco Editor AMD 构建:/edrv/vendor/* → assets/vendor/*(路径穿越防护 + 按扩展名 MIME)\n ctx.effect(() => web.register({\n kind: 'prefix',\n path: VENDOR_PREFIX,\n handler: async (req: { method?: string; url?: string }, res: { statusCode?: number; setHeader: (k: string, v: string) => void; end: (b?: string | Uint8Array) => void }) => {\n try {\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n res.statusCode = 405\n res.end()\n return\n }\n const pathname = new URL(req.url ?? '/', 'http://x').pathname\n const rel = decodeURIComponent(pathname.slice(VENDOR_PREFIX.length)).replace(/^\\/+/, '')\n if (!rel) { res.statusCode = 404; res.end(); return }\n const target = resolve(normalize(join(vendorDir, rel)))\n if (target !== vendorDir && !target.startsWith(vendorDir + sep)) {\n res.statusCode = 403\n res.end()\n return\n }\n const body = await readFile(target)\n res.statusCode = 200\n res.setHeader('content-type', VENDOR_MIME[extname(target)] ?? 'application/octet-stream')\n res.setHeader('cache-control', 'public, max-age=3600')\n res.end(body)\n } catch (error) {\n res.statusCode = 404\n res.end()\n }\n },\n }), 'edrv: /edrv/vendor prefix')\n}\n","/**\n * dsh-vscode-mode shared diff primitives — 快照指纹、hunk 规范化与安全定位。\n * 不依赖 Node/React,host 与 browser 共用,避免各层用不同 indexOf 语义。\n * 作者 ddj 2026-08-24\n */\nimport type { Hunk, RecordBase } from './types.js'\n\n/** 文件读取状态,区分真实空文件与无法读取/过大的文件。 */\nexport type ReadState =\n | { kind: 'content'; content: string }\n | { kind: 'missing' }\n | { kind: 'unavailable' }\n\n/** 文本中的一个半开区间 [start,end)。 */\nexport interface TextRange {\n start: number\n end: number\n}\n\n/** 一条 hunk 在当前内容中的定位结果。 */\nexport interface HunkLocation extends TextRange {\n idx: number\n hunk: Hunk\n matched: boolean\n}\n\n/** 统一取对应 hunk;callHunk 只用于旧记录缺失 hunks 时兼容。 */\nexport function preciseHunk(record: Pick<RecordBase, 'hunks' | 'callHunk'>, idx: number): Hunk | null {\n return hunkOf(record, idx)\n}\n\n/** 轻量、确定性的字符串指纹;不引入 Node crypto。 */\nexport function fingerprint(text: string | null | undefined): string | null {\n if (typeof text !== 'string') return null\n let hash = 2166136261\n for (let i = 0; i < text.length; i++) {\n hash ^= text.charCodeAt(i)\n hash = Math.imul(hash, 16777619)\n }\n return 'fnv1a:' + (hash >>> 0).toString(16) + ':' + text.length\n}\n\n/** 取记录第 idx 个有效 hunk;只有记录缺 hunk 时才回退 callHunk。 */\nexport function hunkOf(record: Pick<RecordBase, 'hunks' | 'callHunk'>, idx: number): Hunk | null {\n const hunk = Array.isArray(record.hunks) ? record.hunks[idx] : undefined\n if (hunk && typeof hunk.newText === 'string') return hunk\n if (idx === 0 && record.callHunk && typeof record.callHunk.newText === 'string') return record.callHunk\n return null\n}\n\n/** hunk 是否表示没有实际内容变化。 */\nexport function isNoopHunk(hunk: Hunk | null | undefined): boolean {\n return !!hunk && hunk.oldText !== null && hunk.oldText === hunk.newText\n}\n\n/** splitLines 的空文本语义:真实空文件没有一行变更内容。 */\nexport function splitLines(text: string): string[] {\n return text.length ? text.split('\\n') : []\n}\n\n/** 为执行后 hunk 写入快照坐标;空 newText 通过 before/after 公共边界定位删除点。 */\nexport function annotateHunk(hunk: Hunk, before: string | null, after: string | null): Hunk {\n return annotateHunks([hunk], before, after)[0]\n}\n\n/** 按文件顺序为多 hunk 写入不重复的 after 坐标。 */\nexport function annotateHunks(hunks: Hunk[], before: string | null, after: string | null): Hunk[] {\n if (typeof after !== 'string') return hunks\n let cursor = 0\n return hunks.map((hunk) => {\n if (hunk.newText.length > 0) {\n const start = after.indexOf(hunk.newText, cursor)\n if (start >= 0) {\n cursor = start + hunk.newText.length\n return { ...hunk, afterStart: start, afterEnd: cursor }\n }\n return hunk\n }\n if (hunks.length !== 1 || typeof before !== 'string' || before === after || hunk.oldText === null) return hunk\n const prefix = commonPrefix(before, after)\n const suffix = commonSuffix(before, after, prefix)\n const removedStart = prefix\n const removedEnd = Math.max(removedStart, before.length - suffix)\n return { ...hunk, afterStart: removedStart, afterEnd: removedStart, beforeStart: removedStart, beforeEnd: removedEnd }\n })\n}\n\n/** 计算两个文本的最长公共前缀长度。 */\nfunction commonPrefix(left: string, right: string): number {\n const limit = Math.min(left.length, right.length)\n let i = 0\n while (i < limit && left.charCodeAt(i) === right.charCodeAt(i)) i++\n return i\n}\n\n/** 计算不与 prefix 重叠的最长公共后缀长度。 */\nfunction commonSuffix(left: string, right: string, prefix: number): number {\n const limit = Math.min(left.length, right.length) - prefix\n let i = 0\n while (i < limit && left.charCodeAt(left.length - 1 - i) === right.charCodeAt(right.length - 1 - i)) i++\n return i\n}\n\n/** 计算 index 前的 0 基行数。 */\nexport function lineBefore(text: string, index: number): number {\n let n = 0\n const end = Math.max(0, Math.min(index, text.length))\n for (let i = 0; i < end; i++) if (text.charCodeAt(i) === 10) n++\n return n\n}\n\n/** 找出文本的全部非重叠出现位置。 */\nfunction allMatches(content: string, needle: string): TextRange[] {\n if (!needle.length) return []\n const out: TextRange[] = []\n let from = 0\n while (from <= content.length - needle.length) {\n const at = content.indexOf(needle, from)\n if (at < 0) break\n out.push({ start: at, end: at + needle.length })\n from = at + Math.max(1, needle.length)\n }\n return out\n}\n\n/**\n * 从 after 快照定位所有 hunk,按 hunk 顺序优先选未占用且靠近前一块的候选。\n * 若 hunk 带 afterStart/afterEnd,则优先验证快照坐标,避免重复文本错配。\n * @author ddj 2026年08月24号\n * @param content 当前文件内容\n * @param hunks 待定位 hunk\n * @returns 每个 hunk 一个结果,matched=false 表示冲突/stale\n */\nexport function locateHunks(content: string, hunks: Hunk[]): HunkLocation[] {\n const locations: HunkLocation[] = []\n let cursor = 0\n const occupied: TextRange[] = []\n for (let idx = 0; idx < hunks.length; idx++) {\n const hunk = hunks[idx]\n const newText = hunk.newText\n const snapshot = Number.isInteger(hunk.afterStart) && Number.isInteger(hunk.afterEnd)\n ? { start: hunk.afterStart as number, end: hunk.afterEnd as number }\n : null\n const snapshotMatches = snapshot && snapshot.start >= 0 && snapshot.end >= snapshot.start\n && (newText.length === 0 || content.slice(snapshot.start, snapshot.end) === newText)\n ? snapshot\n : null\n const candidates = snapshotMatches ? [snapshotMatches] : allMatches(content, newText)\n const candidate = candidates.find((range) => range.start >= cursor && !occupied.some((used) => overlaps(range, used)))\n ?? candidates.find((range) => !occupied.some((used) => overlaps(range, used)))\n if (candidate) {\n locations.push({ idx, hunk, ...candidate, matched: true })\n occupied.push(candidate)\n cursor = Math.max(cursor, candidate.end)\n continue\n }\n if (newText.length === 0 && hunk.afterStart === undefined && hunk.afterEnd === undefined && content.length === 0) {\n const point = { start: 0, end: 0 }\n locations.push({ idx, hunk, ...point, matched: true })\n continue\n }\n if (newText.length === 0 && hunk.afterStart !== undefined && hunk.afterEnd !== undefined\n && hunk.afterStart === hunk.afterEnd && hunk.afterStart >= 0 && hunk.afterStart <= content.length) {\n const point = { start: hunk.afterStart, end: hunk.afterEnd }\n if (!occupied.some((used) => overlaps(point, used))) {\n locations.push({ idx, hunk, ...point, matched: true })\n occupied.push(point)\n cursor = Math.max(cursor, point.end)\n continue\n }\n }\n locations.push({ idx, hunk, start: -1, end: -1, matched: false })\n }\n return locations\n}\n\n/** 判断两个半开区间是否重叠。零长度区间只与同一位置的零长度区间重叠。 */\nfunction overlaps(left: TextRange, right: TextRange): boolean {\n if (left.start === left.end || right.start === right.end) return left.start === right.start && left.end === right.end\n return left.start < right.end && right.start < left.end\n}\n\n/** 在可定位区间上执行一次 hunk 反向替换。 */\nexport function replaceRange(content: string, location: HunkLocation, reverse = false): string | null {\n if (!location.matched || location.start < 0) return null\n const replacement = reverse ? (location.hunk.oldText ?? '') : location.hunk.newText\n return content.slice(0, location.start) + replacement + content.slice(location.end)\n}\n\n/** 按当前内容中出现的位置从后向前应用 hunk,避免前块长度变化影响后块。 */\nexport function applyLocations(content: string, locations: HunkLocation[], reverse = false): { content: string; stale: number[] } {\n const stale = locations.filter((location) => !location.matched).map((location) => location.idx)\n let out = content\n const matched = locations.filter((location) => location.matched).sort((a, b) => b.start - a.start)\n for (const location of matched) {\n const next = replaceRange(out, location, reverse)\n if (next === null) stale.push(location.idx)\n else out = next\n }\n return { content: out, stale: stale.sort((a, b) => a - b) }\n}\n","/**\n * dsh-vscode-mode host — 纯域逻辑(无 ctx/fs/IO 依赖,可直接单测)。\n * 迁移自原 src/index.ts 的纯函数部分,语义一字不改。\n * 作者 ddj 2026-08-20\n */\nimport type { Decision, DiffRecord, Hunk, RecordSummary } from './shared/types.js'\nimport { applyLocations, fingerprint, isNoopHunk, locateHunks, preciseHunk } from './shared/diff.js'\n\n/** 工作区记录桶上限(超过后按 at 最旧剔除)。 */\nexport const MAX_RECORDS = 200\n\n/**\n * 归一化一条持久化记录(容忍旧版/损坏字段)。\n * @author ddj 2026年08月20号\n * @param raw 反序列化的原始记录\n * @returns 合法记录或 null\n */\nexport function normalizeRecord(raw: unknown): DiffRecord | null {\n if (!raw || typeof raw !== 'object') return null\n const r = raw as Record<string, unknown>\n if (typeof r.callId !== 'string' || typeof r.path !== 'string') return null\n const hunks: Hunk[] = Array.isArray(r.hunks)\n ? (r.hunks as unknown[]).filter((h) => h && typeof (h as { newText?: unknown }).newText === 'string').map((h) => {\n const item = h as Record<string, unknown>\n return {\n oldText: typeof item.oldText === 'string' ? item.oldText : null,\n newText: item.newText as string,\n ...(Number.isInteger(item.afterStart) ? { afterStart: item.afterStart as number } : {}),\n ...(Number.isInteger(item.afterEnd) ? { afterEnd: item.afterEnd as number } : {}),\n ...(Number.isInteger(item.beforeStart) ? { beforeStart: item.beforeStart as number } : {}),\n ...(Number.isInteger(item.beforeEnd) ? { beforeEnd: item.beforeEnd as number } : {}),\n }\n })\n : []\n const toolName: DiffRecord['toolName'] = r.toolName === 'write' ? 'write' : 'edit'\n const rawDecisions = r.decisions && typeof r.decisions === 'object' ? r.decisions as Record<string, unknown> : {}\n const call = rawDecisions.call === 'accepted' || rawDecisions.call === 'rejected' ? rawDecisions.call : 'pending'\n const rawPerHunk = Array.isArray(rawDecisions.perHunk) ? rawDecisions.perHunk : []\n const perHunk = hunks.map((_, i) => {\n const value = rawPerHunk[i]\n if (value === 'accepted' || value === 'rejected') return value\n return call === 'accepted' || call === 'rejected' ? call : 'pending'\n })\n const before = typeof r.before === 'string' ? r.before : null\n const hasAfter = Object.prototype.hasOwnProperty.call(r, 'after')\n const after = typeof r.after === 'string' ? r.after : null\n return {\n callId: r.callId,\n toolName,\n path: r.path,\n before,\n after,\n baseFingerprint: typeof r.baseFingerprint === 'string' ? r.baseFingerprint : fingerprint(before),\n afterFingerprint: typeof r.afterFingerprint === 'string' ? r.afterFingerprint : fingerprint(after),\n legacy: !hasAfter,\n conflict: r.conflict === true,\n create: r.create === true,\n callHunk: r.callHunk && typeof (r.callHunk as { oldText?: unknown }).oldText === 'string' && typeof (r.callHunk as { newText?: unknown }).newText === 'string'\n ? { oldText: (r.callHunk as { oldText: string }).oldText, newText: (r.callHunk as { newText: string }).newText }\n : null,\n hunks,\n decisions: { call: call as Decision, perHunk },\n note: typeof r.note === 'string' ? r.note : null,\n superseded: r.superseded === true,\n archived: r.archived === true,\n batch: Number.isInteger(r.batch) ? (r.batch as number) : 0,\n at: typeof r.at === 'string' ? r.at : new Date().toISOString(),\n }\n}\n\n/**\n * 写决策到记录(scope=call 整体 / hunk 单个块)。\n * @author ddj 2026年08月20号\n * @param record 记录\n * @param scope 作用域\n * @param idx hunk 下标(仅 scope=hunk 时生效)\n * @param value 决策值\n * @returns 更新后的记录(原对象就地修改)\n */\nexport function markDecision(record: DiffRecord, scope: string, idx: number | undefined, value: Decision): DiffRecord {\n const dec = record.decisions\n if (scope === 'hunk' && Array.isArray(dec.perHunk) && Number.isInteger(idx)) {\n const i = idx as number\n if (i >= 0 && i < dec.perHunk.length) dec.perHunk[i] = value\n } else {\n dec.call = value\n if (Array.isArray(dec.perHunk)) dec.perHunk = dec.perHunk.map(() => value)\n }\n record.at = new Date().toISOString()\n return record\n}\n\n/** 记录是否已无任何待决策差异(superseded 或全部已决策)。 */\nexport function recordResolved(record: DiffRecord): boolean {\n if (record.superseded === true) return true\n const hunks = Array.isArray(record.hunks) ? record.hunks : []\n const perHunk = Array.isArray(record.decisions.perHunk) ? record.decisions.perHunk : []\n const count = Math.max(hunks.length, perHunk.length)\n if (!count) return record.decisions.call === 'accepted' || record.decisions.call === 'rejected'\n for (let idx = 0; idx < count; idx++) {\n const precise = preciseHunk(record, idx)\n const value = perHunk[idx] ?? record.decisions.call\n if (isNoopHunk(precise) && value === 'pending') return false\n if (value !== 'accepted' && value !== 'rejected') return false\n }\n return true\n}\n\n/**\n * 记录决策摘要(采纳/拒绝/待处理计数,superseded 标记)。\n * @author ddj 2026年08月20号\n * @param record 记录\n * @returns 摘要\n */\nexport function recSummary(record: DiffRecord): RecordSummary {\n const hunks = Array.isArray(record.hunks) ? record.hunks : []\n const perHunk = Array.isArray(record.decisions.perHunk) ? record.decisions.perHunk : []\n const n = Math.max(1, hunks.length, perHunk.length)\n let accepted = 0\n let rejected = 0\n let pending = 0\n for (let i = 0; i < n; i++) {\n const hunk = preciseHunk(record, i)\n const value = perHunk[i] ?? record.decisions.call\n if (i < hunks.length && isNoopHunk(hunk) && value === 'pending') continue\n if (value === 'accepted') accepted++\n else if (value === 'rejected') rejected++\n else pending++\n }\n return { accepted, rejected, pending, superseded: record.superseded === true }\n}\n\n/**\n * 重建\"本批次修改前\"内容:把仍待处理(pending)的差异块按 新→旧 顺序从当前内容反解\n * (newText → oldText)。已采纳/已拒绝的块跳过。反解失败的块标记为 stale。\n * @author ddj 2026年08月20号\n * @param records 该文件的活动记录\n * @param content 当前磁盘内容\n * @returns 重建内容与 stale 定位\n */\nexport function reconstructOriginal(records: DiffRecord[], content: string): { content: string; stale: Array<{ callId: string; idx: number }> } {\n const pending: Array<{ rec: DiffRecord; idx: number; hunk: Hunk }> = []\n for (const rec of records) {\n for (let i = 0; i < rec.hunks.length; i++) {\n const st = rec.decisions.perHunk[i] ?? rec.decisions.call\n const hunk = preciseHunk(rec, i)\n if (st === 'pending' && hunk && !isNoopHunk(hunk)) pending.push({ rec, idx: i, hunk })\n }\n }\n pending.sort((a, b) => (a.rec.at < b.rec.at ? 1 : a.rec.at > b.rec.at ? -1 : 0))\n const locations = locateHunks(content, pending.map((item) => item.hunk))\n const rebuilt = applyLocations(content, locations, true)\n return {\n content: rebuilt.content,\n stale: rebuilt.stale.map((idx) => ({ callId: pending[idx].rec.callId, idx: pending[idx].idx })),\n }\n}\n\n/** 文件当前最大批次号(无记录为 0)。 */\nexport function fileMaxBatch(records: Map<string, DiffRecord>, path: string): number {\n let m = 0\n for (const r of records.values()) {\n if (r.path === path && Number.isInteger(r.batch) && r.batch > m) m = r.batch\n }\n return m\n}\n\n/** 记录桶裁剪:超出 MAX_RECORDS 时剔除最旧的。 */\nexport function prune(map: Map<string, DiffRecord>, max = MAX_RECORDS): void {\n if (map.size <= max) return\n const sorted = [...map.values()].sort((a, b) => (a.at < b.at ? -1 : 1))\n for (let i = 0; i < sorted.length - max; i++) map.delete(sorted[i].callId)\n}\n\n/** 按批次分组记录。 */\nexport function groupByBatch(recs: DiffRecord[]): Map<number | null, DiffRecord[]> {\n const map = new Map<number | null, DiffRecord[]>()\n for (const r of recs) {\n const k = Number.isInteger(r.batch) ? r.batch : null\n if (!map.has(k)) map.set(k, [])\n map.get(k)!.push(r)\n }\n return map\n}\n\n/**\n * 归档条目构造(一条批次一条)。\n * @author ddj 2026年08月20号\n * @param recs 同批次记录(非空)\n * @param cwd 工作区\n * @param reason 归档原因\n */\nexport function archiveEntryFor(recs: DiffRecord[], cwd: string, reason: string): {\n at: string\n cwd: string\n path: string\n batch: number | null\n reason: string\n records: Array<Record<string, unknown>>\n} {\n const first = recs[0]\n return {\n at: new Date().toISOString(),\n cwd,\n path: first.path,\n batch: Number.isInteger(first.batch) ? first.batch : null,\n reason,\n records: recs.map((r) => ({\n callId: r.callId,\n toolName: r.toolName,\n path: r.path,\n create: r.create === true,\n callHunk: r.callHunk,\n hunks: r.hunks,\n decisions: r.decisions,\n note: r.note ?? null,\n before: typeof r.before === 'string' ? r.before : null,\n after: typeof r.after === 'string' ? r.after : null,\n baseFingerprint: r.baseFingerprint ?? null,\n afterFingerprint: r.afterFingerprint ?? null,\n conflict: r.conflict === true,\n legacy: r.legacy === true,\n superseded: r.superseded === true,\n batch: Number.isInteger(r.batch) ? r.batch : null,\n at: r.at,\n summary: recSummary(r),\n })),\n }\n}\n","/**\n * dsh-vscode-mode host — 存储层(sidecar 读写合并 + 归档持久化 + stale 检测)。\n * 迁移自原 src/index.ts 的 fs/ctx IO 部分,语义一字不改。\n * 作者 ddj 2026-08-20\n */\nimport type { ArchiveBatch, ArchiveData, DiffRecord, SidecarData } from './shared/types.js'\nimport type { ReadState } from './shared/diff.js'\nimport { fingerprint, isNoopHunk, locateHunks, preciseHunk } from './shared/diff.js'\nimport { archiveEntryFor, groupByBatch, normalizeRecord } from './model.js'\n\nexport const SIDECAR = '.dsh-edit-review.json'\nexport const SIDECAR_ARCHIVE = '.dsh-edit-review-archive.json'\nexport const READ_CAP = 8 * 1024 * 1024\n\n/** DSH 上下文与会话类型较宽松:本地无 dsh 类型声明,显式 any + 文档约束。 */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Ctx = any\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Session = any\n\n/** 会话沙箱策略(policyOf):可能不存在,调用方需容忍 undefined。 */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function policyOf(ctx: Ctx, session: Session | undefined): any {\n const svc = ctx.get('sandboxPolicy')\n if (!svc) return undefined\n return session ? svc.resolve({ session }) : svc.resolve()\n}\n\n/** 按会话 cwd 解析目标路径。 */\nexport async function resolveTarget(ctx: Ctx, session: Session | undefined, path: string): Promise<string> {\n const fs = ctx.get('fs')\n const cwd = session?.header?.cwd\n return fs.resolve(path, cwd ? { cwd } : {})\n}\n\n/** 读取工作区主 sidecar 文本(缺失/失败 → null)。 */\nasync function readSidecarText(ctx: Ctx, cwd: string | null): Promise<string | null> {\n const fs = ctx.get('fs')\n if (!fs || !cwd) return null\n try {\n return await fs.readText(await fs.resolve(SIDECAR, { cwd }))\n } catch (error) {\n return null\n }\n}\n\n/**\n * 解析主 sidecar:v2 直接返回;v1 迁移为 v2 结构(按会话 cwd 分桶)。\n * @author ddj 2026年08月20号\n * @param text sidecar 文本\n * @returns v2 数据或 null\n */\nexport function parseSidecar(text: string | null): SidecarData | null {\n if (!text) return null\n try {\n const data = JSON.parse(text)\n if (data && typeof data === 'object' && data.version === 2 && data.workspaces && typeof data.workspaces === 'object') {\n return data as SidecarData\n }\n if (data && data.version === 1 && data.sessions && typeof data.sessions === 'object') {\n const workspaces: SidecarData['workspaces'] = {}\n for (const bucket of Object.values(data.sessions)) {\n const b = bucket as { cwd?: unknown; records?: unknown; at?: unknown }\n if (typeof b.cwd === 'string' && b.records) {\n workspaces[b.cwd] = { at: typeof b.at === 'number' ? b.at : Date.now(), records: b.records as Record<string, DiffRecord> }\n }\n }\n return { version: 2, updatedAt: typeof data.updatedAt === 'string' ? data.updatedAt : new Date().toISOString(), workspaces }\n }\n return null\n } catch (error) {\n return null\n }\n}\n\n/** 加载某工作区的记录桶(内存 Map;缺失 → 空)。 */\nexport async function loadBucket(ctx: Ctx, cwd: string): Promise<Map<string, DiffRecord>> {\n const text = await readSidecarText(ctx, cwd)\n const data = parseSidecar(text)\n const map = new Map<string, DiffRecord>()\n if (data && data.workspaces[cwd] && typeof data.workspaces[cwd].records === 'object') {\n for (const rec of Object.values(data.workspaces[cwd].records)) {\n const n = normalizeRecord(rec)\n if (n) map.set(n.callId, n)\n }\n }\n return map\n}\n\n/** 保存某工作区的记录桶(写前合并,不覆盖其他工作区)。 */\nexport async function saveBucket(ctx: Ctx, cwd: string, recsMap: Map<string, DiffRecord>, session?: Session): Promise<void> {\n const fs = ctx.get('fs')\n if (!fs || !cwd) return\n try {\n const target = await fs.resolve(SIDECAR, { cwd })\n const existing = parseSidecar(await readSidecarText(ctx, cwd)) ?? { version: 2, updatedAt: '', workspaces: {} } as SidecarData\n existing.workspaces[cwd] = { at: Date.now(), records: Object.fromEntries(recsMap) }\n existing.updatedAt = new Date().toISOString()\n await fs.writeText(target, JSON.stringify(existing), void 0, void 0, policyOf(ctx, session))\n } catch (error) {\n console.error('edrv saveBucket failed', error)\n }\n}\n\n/**\n * 读取记录目标文件内容(按 path 缓存一次;缺失/过大/失败 → null/'' 占位)。\n * @author ddj 2026年08月20号\n * @param cache path → 内容(null=缺失/读取失败,''=过大跳过)\n */\nexport async function readForCache(ctx: Ctx, session: Session, cache: Map<string, ReadState>, path: string): Promise<ReadState> {\n const cached = cache.get(path)\n if (cached) return cached\n const fs = ctx.get('fs')\n if (!fs) { const state: ReadState = { kind: 'unavailable' }; cache.set(path, state); return state }\n try {\n const target = await resolveTarget(ctx, session, path)\n const info = await fs.stat(target)\n if (!info || info.type !== 'file') { const state: ReadState = { kind: 'missing' }; cache.set(path, state); return state }\n if ((info.size ?? 0) > READ_CAP) { const state: ReadState = { kind: 'unavailable' }; cache.set(path, state); return state }\n const state: ReadState = { kind: 'content', content: await fs.readText(target) }\n cache.set(path, state)\n return state\n } catch (error) {\n const state: ReadState = { kind: 'unavailable' }\n cache.set(path, state)\n return state\n }\n}\n\n/**\n * 判断记录是否已无任何可操作差异(stale):待决策 hunk 的新文本在磁盘均找不到,\n * 或新建文件已不存在,或全为空差异。满足则应由 host 自动归档。\n * @author ddj 2026年08月20号\n */\nexport async function recordIsStale(ctx: Ctx, session: Session, cache: Map<string, ReadState>, rec: DiffRecord): Promise<boolean> {\n if (rec.superseded === true) return true\n if (!Array.isArray(rec.hunks) || !rec.hunks.length) return true\n const state = await readForCache(ctx, session, cache, rec.path)\n if (state.kind === 'unavailable') return false\n if (state.kind === 'missing') return true\n if (rec.create === true) return false\n const pending = rec.hunks.map((_, idx) => ({ idx, hunk: preciseHunk(rec, idx), status: rec.decisions.perHunk[idx] ?? rec.decisions.call }))\n .filter((item) => item.status === 'pending' && item.hunk && !isNoopHunk(item.hunk))\n if (!pending.length) return true\n const currentFingerprint = fingerprint(state.content)\n if (rec.afterFingerprint && currentFingerprint === rec.afterFingerprint) { rec.conflict = false; return false }\n const locations = locateHunks(state.content, pending.map((item) => item.hunk!))\n if (locations.some((location) => location.matched)) { rec.conflict = false; return false }\n rec.conflict = true\n return false\n}\n\n/**\n * edrv.list 全量轮询时自动清理 stale 记录:标记 superseded 并归档,\n * 防止\"幽灵差异\"长期留在审查列表且无法操作。\n * @author ddj 2026年08月20号\n * @returns 自动归档条数\n */\nexport async function autoArchiveStale(ctx: Ctx, session: Session, cwd: string, bucket: Map<string, DiffRecord>): Promise<number> {\n const fs = ctx.get('fs')\n if (!fs) return 0\n const cache = new Map<string, ReadState>()\n const stale: DiffRecord[] = []\n for (const rec of bucket.values()) {\n if (rec.archived || rec.superseded === true) continue\n if (await recordIsStale(ctx, session, cache, rec)) stale.push(rec)\n }\n if (!stale.length) return 0\n for (const r of stale) { r.superseded = true; r.at = new Date().toISOString() }\n await archiveRecords(ctx, session, cwd, bucket, stale, '差异无法定位(已被后续修改覆盖),自动归档')\n return stale.length\n}\n\n/** 读取归档 sidecar 文本(缺失/失败 → null)。 */\nexport async function readArchiveText(ctx: Ctx, cwd: string | null): Promise<string | null> {\n const fs = ctx.get('fs')\n if (!fs || !cwd) return null\n try {\n return await fs.readText(await fs.resolve(SIDECAR_ARCHIVE, { cwd }))\n } catch (error) {\n return null\n }\n}\n\n/** 解析归档 sidecar(损坏 → 空数组)。 */\nexport function parseArchive(text: string | null): ArchiveBatch[] {\n if (!text) return []\n try {\n const data = JSON.parse(text)\n if (data && typeof data === 'object' && Array.isArray(data.batches)) return data.batches as ArchiveBatch[]\n } catch (error) { /* 忽略损坏 */ }\n return []\n}\n\n/** 追加归档条目(按 cwd+path+batch 合并,同 callId 去重)。 */\nexport async function appendArchiveEntries(ctx: Ctx, cwd: string, entries: Array<ReturnType<typeof archiveEntryFor>>, session?: Session): Promise<void> {\n const fs = ctx.get('fs')\n if (!fs || !cwd) return\n try {\n const target = await fs.resolve(SIDECAR_ARCHIVE, { cwd })\n const existing = parseArchive(await readArchiveText(ctx, cwd))\n for (const e of entries) {\n const idx = existing.findIndex((x) => x.cwd === e.cwd && x.path === e.path && x.batch === e.batch)\n if (idx >= 0) {\n const exist = existing[idx]\n const seen = new Set((exist.records || []).map((r) => r.callId))\n for (const rec of e.records) {\n if (!seen.has(String(rec.callId))) {\n exist.records.push(rec as unknown as ArchiveBatch['records'][number])\n seen.add(String(rec.callId))\n }\n }\n exist.lastAt = e.at\n exist.reason = e.reason\n } else {\n existing.push(e as unknown as ArchiveBatch)\n }\n }\n const data: ArchiveData = { version: 1, updatedAt: new Date().toISOString(), batches: existing }\n await fs.writeText(target, JSON.stringify(data), void 0, void 0, policyOf(ctx, session))\n } catch (error) {\n console.error('edrv appendArchiveEntries failed', error)\n }\n}\n\n/** 归档记录:标记 archived、按批次写入归档、落盘工作区桶。 */\nexport async function archiveRecords(\n ctx: Ctx,\n session: Session,\n cwd: string,\n bucket: Map<string, DiffRecord>,\n recs: DiffRecord[],\n reason: string,\n): Promise<void> {\n if (!recs.length) return\n const fresh = recs.filter((r) => !r.archived)\n for (const r of recs) r.archived = true\n const entries: Array<ReturnType<typeof archiveEntryFor>> = []\n for (const list of groupByBatch(recs).values()) entries.push(archiveEntryFor(list, cwd, reason))\n await appendArchiveEntries(ctx, cwd, entries, session)\n if (fresh.length) await saveBucket(ctx, cwd, bucket, session)\n}\n","/**\n * dsh-vscode-mode host — 工作区记录桶注册表与会话助手。\n * 迁移自原 src/index.ts 的 registry/sessionOf/cwdOf/bucketOf,语义不改。\n * 作者 ddj 2026-08-20\n */\nimport type { DiffRecord } from './shared/types.js'\nimport type { Ctx, Session } from './store.js'\nimport { loadBucket } from './store.js'\n\n/** cwd → 记录桶(内存缓存;随会话销毁清理)。 */\nexport type Registry = Map<string, Map<string, DiffRecord>>\n\n/** 按 sessionId 取会话;缺省时仅当唯一活跃会话才返回。 */\nexport function sessionOf(ctx: Ctx, sessionId?: string): Session | undefined {\n const sessions = ctx.get('sessions')\n if (!sessions) return undefined\n if (sessionId) return sessions.get(sessionId)\n const live = sessions.list().filter((s: Session) => s.id)\n return live.length === 1 ? live[0] : undefined\n}\n\n/** 会话工作区 cwd。 */\nexport function cwdOf(session: Session | undefined): string | null {\n return session?.header?.cwd ?? null\n}\n\n/** 取(或加载)某工作区记录桶。 */\nexport function bucketOf(registry: Registry, ctx: Ctx, cwd: string): Promise<Map<string, DiffRecord>> {\n const existing = registry.get(cwd)\n if (existing) return Promise.resolve(existing)\n return loadBucket(ctx, cwd).then((map) => {\n registry.set(cwd, map)\n return map\n })\n}\n","/**\n * dsh-vscode-mode host — 捕获层:监听 tools/result,把 edit/write 差异落成审查记录。\n * 迁移自原 src/index.ts 的 tools/result 处理,语义不改。\n * 作者 ddj 2026-08-20\n */\nimport type { DiffRecord, Hunk } from './shared/types.js'\nimport { annotateHunks, fingerprint } from './shared/diff.js'\nimport type { Ctx, Session } from './store.js'\nimport { archiveRecords, loadBucket, saveBucket } from './store.js'\nimport { fileMaxBatch, prune, recordResolved } from './model.js'\nimport type { Registry } from './registry.js'\nimport { cwdOf } from './registry.js'\n\n/** 校验并提取工具 result meta 中的文件 hunk。 */\nfunction validHunks(raw: unknown): Hunk[] {\n if (!Array.isArray(raw)) return []\n const hunks: Hunk[] = []\n for (const item of raw) {\n if (!item || typeof item !== 'object') continue\n const hunk = item as Record<string, unknown>\n if (typeof hunk.newText !== 'string') continue\n if (hunk.oldText !== null && typeof hunk.oldText !== 'string') continue\n hunks.push({ oldText: hunk.oldText as string | null, newText: hunk.newText })\n }\n return hunks\n}\n\n/** 已有文件 write 的元数据缺失时,用权威整文件快照保底。 */\nfunction fallbackHunks(toolName: string, args: Record<string, unknown>, before: string | null, after: string | null, create: boolean): Hunk[] {\n if (create) return [{ oldText: null, newText: after ?? (typeof args.content === 'string' ? args.content : '') }]\n if (toolName === 'edit' && typeof args.old_string === 'string' && typeof args.new_string === 'string') {\n return [{ oldText: args.old_string, newText: args.new_string }]\n }\n if (toolName === 'write' && before !== null && after !== null && before !== after) {\n return [{ oldText: before, newText: after }]\n }\n if (toolName === 'write' && after !== null) return [{ oldText: null, newText: after }]\n return []\n}\n\n/**\n * 捕获一次工具执行结果(tools/result):edit/write 成功时构造记录、\n * 递增文件批次、融合归档被后续修改取代的旧差异、落盘。\n * @author ddj 2026年08月20号\n * @param ctx DSH 上下文\n * @param registry 工作区记录桶注册表\n * @param exec 工具执行描述(name/arguments/callId/agent.session)\n * @param result 执行结果(value/meta/isError)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function captureToolResult(ctx: Ctx, registry: Registry, exec: any, result: any): Promise<void> {\n const session: Session | undefined = exec?.agent?.session\n if (!session || (exec?.name !== 'edit' && exec?.name !== 'write')) return\n if (result?.isError || !result?.value) return\n try {\n const cwd = cwdOf(session)\n if (!cwd) return\n const value = result.value\n const args = (exec.arguments || {}) as Record<string, unknown>\n const path = typeof value.path === 'string' ? value.path : args.file_path\n if (typeof path !== 'string' || !path) return\n const before = typeof value.before === 'string' ? value.before : null\n const after = typeof value.after === 'string' ? value.after : (typeof args.content === 'string' ? args.content : null)\n const create = exec.name === 'write' && value.before === null\n const callHunk = exec.name === 'edit' && typeof args.old_string === 'string' && typeof args.new_string === 'string'\n ? { oldText: args.old_string, newText: args.new_string }\n : null\n const metaHunks = validHunks(result.meta?.diffs)\n const rawHunks = metaHunks.length ? metaHunks : fallbackHunks(exec.name, args, before, after, create)\n const hunks = annotateHunks(rawHunks, before, after)\n if (!hunks.length || typeof exec.callId !== 'string') return\n const record: DiffRecord = {\n callId: exec.callId,\n toolName: exec.name,\n path,\n before,\n after,\n baseFingerprint: fingerprint(before),\n afterFingerprint: fingerprint(after),\n legacy: false,\n conflict: false,\n create,\n callHunk,\n hunks,\n decisions: { call: 'pending', perHunk: hunks.map(() => 'pending') },\n note: create ? '新建文件:全部拒绝将删除该文件' : before === null ? '未捕获修改前内容(大文件)' : null,\n superseded: false,\n archived: false,\n batch: 0,\n at: new Date().toISOString(),\n }\n let bucket = registry.get(cwd)\n if (!bucket) { bucket = await loadBucket(ctx, cwd); registry.set(cwd, bucket) }\n record.batch = fileMaxBatch(bucket, path) + 1\n bucket.set(exec.callId, record)\n // 融合:文件被再次修改(batch 递增)时,早于最新批次的未归档差异一律归档(内容已含其效果/被取代)\n const prior: DiffRecord[] = []\n for (const r of bucket.values()) {\n if (r.path === path && r.callId !== exec.callId && !r.archived && (r.batch ?? 0) < record.batch) prior.push(r)\n }\n if (prior.length) {\n await archiveRecords(ctx, session, cwd, bucket, prior, prior.every(recordResolved) ? '已处理且被后续修改取代' : '被后续修改融合(内容已含其效果)')\n }\n prune(bucket)\n await saveBucket(ctx, cwd, bucket, session)\n } catch (error) {\n console.error('edrv capture failed', error)\n }\n}\n","/**\n * dsh-vscode-mode host — 搜索 query 与路径规范化。\n * 查询只按字面连续片段比较,不解释为正则或 shell 语句。\n * 作者 ddj 2026年08月24号\n */\nimport { isAbsolute, resolve } from 'node:path'\nimport type { PreparedQuery } from './types.js'\n\n/**\n * 规范化用户搜索文本。\n * @author ddj 2026年08月24号\n * @param raw 原始搜索文本\n * @returns 用于比较和缓存的 query\n */\nexport function prepareQuery(raw: unknown): PreparedQuery {\n const value = String(raw ?? '').trim()\n return { raw: value, text: value.replaceAll('\\\\', '/').toLocaleLowerCase('en-US') }\n}\n\n/**\n * 归一化路径分隔符并移除无意义前缀。\n * @author ddj 2026年08月24号\n * @param value 原始路径\n * @returns 比较用路径\n */\nexport function pathText(value: string): string {\n return value.replaceAll('\\\\', '/').replace(/^\\.\\//, '')\n}\n\n/**\n * 生成不区分大小写的路径 key。\n * @author ddj 2026年08月24号\n * @param value 原始路径\n * @returns 去重 key\n */\nexport function pathKey(value: string): string {\n return pathText(value).toLocaleLowerCase('en-US')\n}\n\n/**\n * 将相对文件路径映射到 provider 根目录。\n * @author ddj 2026年08月24号\n * @param value 文件路径\n * @param root 工作区根目录\n * @returns 可供 edrv.read 使用的路径\n */\nexport function displayPath(value: string, root: string): string {\n const normalized = pathText(value)\n if (isAbsolute(normalized) || /^[A-Za-z]:\\//.test(normalized) || normalized.startsWith('//')) return normalized\n return resolve(root, normalized)\n}\n\n/**\n * 判断路径是否包含连续 query。\n * @author ddj 2026年08月24号\n * @param value 文件路径\n * @param query 已规范化 query\n * @returns 是否命中\n */\nexport function pathMatch(value: string, query: PreparedQuery): boolean {\n return pathText(value).toLocaleLowerCase('en-US').includes(query.text)\n}\n","/**\n * dsh-vscode-mode host — ripgrep 文件发现 provider。\n * 通过独立 argv 调用打包 rg,避免先构建巨型全量文件数组。\n * 作者 ddj 2026年08月24号\n */\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { createRequire } from 'node:module'\nimport type { Ctx, Session } from '../store.js'\nimport { policyOf } from '../store.js'\nimport { prepareQuery, pathText } from './query.js'\nimport type { WorkspaceSearchInput, WorkspaceSearchProvider, WorkspaceSearchResult } from './types.js'\n\nconst STDOUT_CAP = 4 << 20\nconst STDERR_CAP = 64 << 10\nconst GRACE_MS = 20_000\nconst EXCLUDES = [\n 'node_modules', '.git', '.tmp', '.cache', 'dist', 'build', 'vendor',\n 'coverage', '__pycache__',\n]\n\ninterface SearchHandle {\n done: Promise<{ exitCode: number | null; code?: number | null }>\n collected?: {\n stdout?: { readFrom(offset: number): { text: string; lossy?: boolean } }\n stderr?: { readFrom(offset: number): { text: string } }\n }\n}\n\ninterface SearchSubprocess {\n spawn(spec: {\n argv: readonly string[]\n cwd: string\n stdio: { stdin: 'ignore'; stdout: { maxBytes: number }; stderr: { maxBytes: number } }\n graceMs: number\n signal?: AbortSignal\n }): SearchHandle\n}\n\n/**\n * 将 query 转成 rg 的字面 glob。\n * @author ddj 2026年08月24号\n * @param query 已规范化 query\n * @returns 安全 glob\n */\nexport function queryGlob(query: string): string {\n const value = pathText(query)\n const escaped = value.replace(/[\\*?\\[\\]{}!]/g, (char) => '\\\\' + char)\n return '**/*' + escaped + '*'\n}\n\n/**\n * 返回当前平台的 rg 可执行文件路径,不让可选依赖影响模块加载。\n * @author ddj 2026年08月24号\n * @returns rg 路径或 null\n */\nexport function ripgrepPath(): string | null {\n try {\n const require = createRequire(import.meta.url)\n const ripgrep = require('@vscode/ripgrep') as { rgPath?: unknown }\n if (typeof ripgrep.rgPath !== 'string' || !existsSync(ripgrep.rgPath)) return null\n return join(ripgrep.rgPath)\n } catch (error) {\n return null\n }\n}\n\n/**\n * 解析会话搜索根目录,并转换到 subprocess 执行世界。\n * @author ddj 2026年08月24号\n * @param ctx DSH 上下文\n * @param session 当前会话\n * @returns subprocess 可访问的根目录\n */\nexport async function searchRoot(ctx: Ctx, session: Session): Promise<string> {\n const fs = ctx.get('fs')\n if (!fs) throw new Error('缺少 fs')\n const policy = policyOf(ctx, session)\n const cwd = session?.header?.cwd\n const rootTarget = await fs.resolve(policy?.workspaceRoot ?? '.', cwd ? { cwd } : {})\n return fs.processPath(rootTarget)\n}\n\n/**\n * 读取收集输出并解析为路径候选。\n * @author ddj 2026年08月24号\n * @param handle subprocess handle\n * @param maxResults 候选上限\n * @returns 路径与完整性状态\n */\nexport function parseOutput(handle: SearchHandle, maxResults: number): { files: string[]; truncated: boolean; complete: boolean } {\n const reader = handle.collected?.stdout\n if (!reader) return { files: [], truncated: false, complete: false }\n const output = reader.readFrom(0)\n const values = output.text.split(/\\r?\\n/).map((line) => line.trim()).filter(Boolean)\n const unique = [...new Set(values)]\n const truncated = Boolean(output.lossy) || unique.length > maxResults\n return { files: unique.slice(0, maxResults).map(pathText), truncated, complete: !truncated }\n}\n\n/**\n * 使用打包 ripgrep 搜索工作区文件。\n * @author ddj 2026年08月24号\n * @param input provider 输入\n * @returns 有界搜索结果\n */\nexport async function searchRipgrep(input: WorkspaceSearchInput): Promise<WorkspaceSearchResult> {\n const sub = input.ctx.get('subprocess') as SearchSubprocess | undefined\n if (!sub) throw new Error('缺少 subprocess')\n const binary = ripgrepPath()\n if (!binary) throw new Error('ripgrep 不可用')\n const root = input.root ?? await searchRoot(input.ctx, input.session)\n const query = prepareQuery(input.query)\n const argv = [binary, '--no-config', '--files', '--hidden', '--no-ignore', '--glob-case-insensitive', '--glob', queryGlob(query.text)]\n for (const excluded of EXCLUDES) argv.push('--glob', '!**/' + excluded + '/**')\n argv.push('--', root)\n const handle = sub.spawn({\n argv,\n cwd: root,\n stdio: { stdin: 'ignore', stdout: { maxBytes: STDOUT_CAP }, stderr: { maxBytes: STDERR_CAP } },\n graceMs: GRACE_MS,\n signal: input.signal,\n })\n let outcome: { exitCode: number | null; code?: number | null }\n try {\n outcome = await handle.done\n } catch (error) {\n throw new Error('ripgrep 启动失败:' + String(error))\n }\n const code = outcome.exitCode ?? outcome.code\n if (code !== 0 && code !== 1) throw new Error('ripgrep 退出码:' + String(code))\n const parsed = parseOutput(handle, input.maxResults)\n if (!handle.collected?.stdout) throw new Error('ripgrep stdout 不可用')\n return { ...parsed, source: 'ripgrep' }\n}\n\n/**\n * 构造 ripgrep provider。\n * @author ddj 2026年08月24号\n * @returns provider 实例\n */\nexport function newRgProvider(): WorkspaceSearchProvider {\n return { search: searchRipgrep }\n}\n","/**\n * dsh-vscode-mode host — fs.listDir 查询感知 fallback。\n * provider 不可用时边遍历边匹配,不再伪装有限全量扫描为完整索引。\n * 作者 ddj 2026年08月24号\n */\nimport type { Ctx, Session } from '../store.js'\nimport { policyOf } from '../store.js'\nimport { pathText, pathMatch } from './query.js'\nimport { searchRoot } from './ripgrep.js'\nimport type { WorkspaceSearchInput, WorkspaceSearchProvider, WorkspaceSearchResult } from './types.js'\n\ninterface FsTarget { displayPath?: string }\ninterface FsEntry { name: string; type: 'file' | 'directory' | 'other'; target: FsTarget }\ninterface SearchFs {\n resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): Promise<FsTarget>\n listDir(target: FsTarget, signal?: AbortSignal): Promise<FsEntry[]>\n}\n\nconst RESULT_CAP = 500\nconst EXCLUDED = new Set(['node_modules', '.git', '.tmp', '.cache', 'dist', 'build', 'vendor', 'coverage', '__pycache__'])\n\n/**\n * 在一个目录树中递归查找匹配文件。\n * @author ddj 2026年08月24号\n * @param fs 文件系统能力\n * @param target 当前目录目标\n * @param input 搜索输入\n * @param files 已保留候选\n * @param signal 取消信号\n * @returns 是否因达到上限而截断\n */\nasync function walk(fs: SearchFs, target: FsTarget, input: WorkspaceSearchInput, files: string[], signal: AbortSignal): Promise<boolean> {\n if (signal.aborted) throw new DOMException('搜索已取消', 'AbortError')\n const entries = await fs.listDir(target, signal)\n for (const entry of entries) {\n if (signal.aborted) throw new DOMException('搜索已取消', 'AbortError')\n if (entry.type === 'directory') {\n if (EXCLUDED.has(entry.name)) continue\n if (await walk(fs, entry.target, input, files, signal)) return true\n continue\n }\n if (entry.type !== 'file') continue\n const path = pathText(entry.target.displayPath ?? entry.name)\n if (!pathMatch(path, { raw: input.query, text: pathText(input.query).toLocaleLowerCase('en-US') })) continue\n files.push(path)\n if (files.length >= Math.min(input.maxResults, RESULT_CAP)) return true\n }\n return false\n}\n\n/**\n * 使用 ctx.fs.listDir 搜索文件。\n * @author ddj 2026年08月24号\n * @param input provider 输入\n * @returns 有界 fallback 结果\n */\nexport async function searchFallback(input: WorkspaceSearchInput): Promise<WorkspaceSearchResult> {\n const fs = input.ctx.get('fs') as SearchFs | undefined\n if (!fs) throw new Error('缺少 fs')\n const policy = policyOf(input.ctx, input.session)\n const cwd = input.session?.header?.cwd\n const rootTarget = await fs.resolve(policy?.workspaceRoot ?? '.', cwd ? { cwd, signal: input.signal } : { signal: input.signal })\n const signal = input.signal ?? new AbortController().signal\n const files: string[] = []\n const truncated = await walk(fs, rootTarget, input, files, signal)\n return { files, truncated, complete: !truncated, source: 'fallback' }\n}\n\n/**\n * 构造 fallback provider。\n * @author ddj 2026年08月24号\n * @returns provider 实例\n */\nexport function newFallback(): WorkspaceSearchProvider {\n return { search: searchFallback }\n}\n","/**\n * dsh-vscode-mode host — 可替换的连续匹配排序器。\n * 第一版保持 basename 优先和稳定路径序,后续可接 fuzzy scorer。\n * 作者 ddj 2026年08月24号\n */\nimport type { CandidateRanker, PreparedQuery, SearchCandidate } from './types.js'\nimport { pathText } from './query.js'\n\n/**\n * 生成搜索候选。\n * @author ddj 2026年08月24号\n * @param path 文件路径\n * @param source 候选来源\n * @returns 内部候选\n */\nexport function candidateOf(path: string, source: SearchCandidate['source']): SearchCandidate {\n const normalizedPath = pathText(path)\n const basename = normalizedPath.split('/').pop() ?? normalizedPath\n return { path, basename, normalizedPath: normalizedPath.toLocaleLowerCase('en-US'), source }\n}\n\n/**\n * 对连续匹配候选进行排序。\n * @author ddj 2026年08月24号\n * @param candidates 候选列表\n * @param query 已规范化 query\n * @returns 排序后的候选\n */\nexport function rankCandidates(candidates: SearchCandidate[], query: PreparedQuery): SearchCandidate[] {\n const text = query.text\n const score = (candidate: SearchCandidate): number => {\n const base = candidate.basename.toLocaleLowerCase('en-US')\n if (base.startsWith(text)) return 0\n if (base.includes(text)) return 1\n if (candidate.normalizedPath.includes(text)) return 2\n return 3\n }\n return [...candidates].sort((left, right) => score(left) - score(right) || left.normalizedPath.localeCompare(right.normalizedPath, 'en-US'))\n}\n\n/**\n * 默认候选排序器。\n * @author ddj 2026年08月24号\n * @returns 排序器\n */\nexport function substringRanker(): CandidateRanker {\n return { rank: rankCandidates }\n}\n","/**\n * dsh-vscode-mode host — 搜索编排、缓存和旧任务取消。\n * 对外只返回旧 RPC 所需的 files/truncated,内部保留 provider 边界。\n * 作者 ddj 2026年08月24号\n */\nimport type { Ctx, Session } from '../store.js'\nimport { policyOf } from '../store.js'\nimport { pathKey, pathMatch, pathText, prepareQuery } from './query.js'\nimport { searchRoot } from './ripgrep.js'\nimport { newRgProvider } from './ripgrep.js'\nimport { newFallback } from './fallback.js'\nimport { candidateOf, rankCandidates } from './ranker.js'\nimport type { CandidateRanker, SearchCandidate, WorkspaceSearchProvider, WorkspaceSearchResult } from './types.js'\n\nconst CACHE_TTL = 60_000\nconst CACHE_LIMIT = 100\nconst RESULT_LIMIT = 50\nconst PROVIDER_VERSION = 'ripgrep-v1'\nconst POLICY_VERSION = 'search-policy-v1'\n\ntype CacheEntry = { at: number; result: WorkspaceSearchResult }\ntype SearchRequest = { session: Session; cwd: string; query: string; activePaths: string[] }\ntype SearchResponse = { files: string[]; truncated: boolean }\n\n/**\n * 短期有界搜索缓存。\n * @author ddj 2026年08月24号\n * @returns 缓存对象\n */\nexport class SearchCache {\n private readonly entries = new Map<string, CacheEntry>()\n\n /**\n * 读取未过期条目。\n * @author ddj 2026年08月24号\n * @param key 缓存 key\n * @param now 当前时间\n * @returns 缓存结果或 undefined\n */\n get(key: string, now = Date.now()): WorkspaceSearchResult | undefined {\n const entry = this.entries.get(key)\n if (!entry) return undefined\n if (now - entry.at >= CACHE_TTL) { this.entries.delete(key); return undefined }\n this.entries.delete(key)\n this.entries.set(key, entry)\n return { ...entry.result, files: [...entry.result.files] }\n }\n\n /**\n * 写入成功 provider 结果。\n * @author ddj 2026年08月24号\n * @param key 缓存 key\n * @param result provider 结果\n * @param now 当前时间\n */\n set(key: string, result: WorkspaceSearchResult, now = Date.now()): void {\n this.entries.delete(key)\n this.entries.set(key, { at: now, result: { ...result, files: [...result.files] } })\n while (this.entries.size > CACHE_LIMIT) this.entries.delete(this.entries.keys().next().value as string)\n }\n\n /**\n * 清理指定根目录的缓存。\n * @author ddj 2026年08月24号\n * @param root 工作区根目录\n */\n clearRoot(root: string): void {\n for (const key of this.entries.keys()) if (key.startsWith(root + '|')) this.entries.delete(key)\n }\n\n /**\n * 清空全部缓存。\n * @author ddj 2026年08月24号\n */\n clear(): void { this.entries.clear() }\n}\n\n/**\n * 获取 policy 版本,未知策略使用固定插件版本。\n * @author ddj 2026年08月24号\n * @param ctx DSH 上下文\n * @param session 当前会话\n * @returns 稳定版本文本\n */\nfunction policyVersion(ctx: Ctx, session: Session): string {\n const policy = policyOf(ctx, session)\n const version = policy?.version ?? policy?.policyVersion\n return typeof version === 'string' || typeof version === 'number' ? String(version) : POLICY_VERSION\n}\n\n/**\n * 将 root 内绝对路径统一成相对显示路径。\n * @author ddj 2026年08月24号\n * @param value 原始路径\n * @param root 搜索根\n * @returns 兼容 edrv.read 的路径\n */\nfunction displayPath(value: string, root: string): string {\n const path = pathText(value)\n const base = pathText(root).replace(/\\/$/, '')\n const lowerPath = path.toLocaleLowerCase('en-US')\n const lowerBase = base.toLocaleLowerCase('en-US')\n if (lowerPath === lowerBase) return '.'\n if (lowerPath.startsWith(lowerBase + '/')) return path.slice(base.length + 1)\n return path\n}\n\n/**\n * 为显示路径生成跨绝对/相对形式的去重 key。\n * @author ddj 2026年08月24号\n * @param value 原始路径\n * @param root 搜索根\n * @returns 去重 key\n */\nfunction displayKey(value: string, root: string): string {\n return pathKey(displayPath(value, root))\n}\n\n/**\n * 合并 provider 与 active diff 候选并去重。\n * @author ddj 2026年08月24号\n * @param result provider 结果\n * @param activePaths 活跃差异路径\n * @param root 搜索根\n * @param query 已规范化 query\n * @returns 候选列表\n */\nfunction mergeCandidates(result: WorkspaceSearchResult, activePaths: string[], root: string, query: ReturnType<typeof prepareQuery>): SearchCandidate[] {\n const candidates = new Map<string, SearchCandidate>()\n for (const path of result.files) {\n const shown = displayPath(path, root)\n if (pathMatch(shown, query)) candidates.set(displayKey(path, root), candidateOf(shown, 'workspace'))\n }\n for (const path of activePaths) {\n const shown = displayPath(path, root)\n if (!pathMatch(shown, query)) continue\n const key = displayKey(path, root)\n if (!candidates.has(key)) candidates.set(key, candidateOf(shown, 'active-diff'))\n }\n return [...candidates.values()]\n}\n\n/**\n * 搜索编排器。\n * @author ddj 2026年08月24号\n */\nexport class SearchOrchestrator {\n private readonly cache = new SearchCache()\n private readonly inflight = new Map<string, AbortController>()\n private readonly rootsByCwd = new Map<string, Set<string>>()\n private readonly provider: WorkspaceSearchProvider\n private readonly fallback: WorkspaceSearchProvider\n private readonly ranker: CandidateRanker\n\n /**\n * 创建搜索编排器。\n * @author ddj 2026年08月24号\n * @param ctx DSH 上下文\n * @param provider 主 provider,可替换测试\n * @param fallback 降级 provider,可替换测试\n * @param ranker 排序器,可替换测试\n */\n constructor(private readonly ctx: Ctx, provider = newRgProvider(), fallback = newFallback(), ranker: CandidateRanker = { rank: rankCandidates }) {\n this.provider = provider\n this.fallback = fallback\n this.ranker = ranker\n }\n\n /**\n * 执行一次工作区搜索。\n * @author ddj 2026年08月24号\n * @param request 搜索请求\n * @returns 旧 RPC 响应字段\n */\n async search(request: SearchRequest): Promise<SearchResponse> {\n const query = prepareQuery(request.query)\n if (query.text.length < 2) return { files: [], truncated: false }\n let root: string\n try { root = await searchRoot(this.ctx, request.session) } catch (error) {\n return this.rankActive(request.activePaths, request.cwd, query)\n }\n const rootKey = pathText(root)\n const roots = this.rootsByCwd.get(request.cwd) ?? new Set<string>()\n roots.add(rootKey)\n this.rootsByCwd.set(request.cwd, roots)\n const key = [rootKey, query.text, policyVersion(this.ctx, request.session), PROVIDER_VERSION].join('|')\n const cached = this.cache.get(key)\n if (cached) return this.finish(cached, request.activePaths, root, query)\n this.inflight.get(root)?.abort()\n const controller = new AbortController()\n this.inflight.set(root, controller)\n try {\n let result: WorkspaceSearchResult\n let providerOk = true\n try {\n result = await this.provider.search({ ctx: this.ctx, session: request.session, cwd: request.cwd, query: query.raw, maxResults: 500, signal: controller.signal, root })\n } catch (error) {\n providerOk = false\n if (controller.signal.aborted) return { files: [], truncated: false }\n try {\n result = await this.fallback.search({ ctx: this.ctx, session: request.session, cwd: request.cwd, query: query.raw, maxResults: 500, signal: controller.signal, root })\n } catch (fallbackError) {\n return this.rankActive(request.activePaths, root, query)\n }\n }\n if (controller.signal.aborted) return { files: [], truncated: false }\n if (providerOk) this.cache.set(key, result)\n return this.finish(result, request.activePaths, root, query)\n } finally {\n if (this.inflight.get(root) === controller) this.inflight.delete(root)\n }\n }\n\n /**\n * 清理会话对应根目录的缓存和在途搜索。\n * @author ddj 2026年08月24号\n * @param cwd 会话工作区\n */\n dispose(cwd: string): void {\n const roots = this.rootsByCwd.get(cwd) ?? new Set<string>([cwd])\n for (const root of roots) {\n this.inflight.get(root)?.abort()\n this.inflight.delete(root)\n this.cache.clearRoot(root)\n }\n this.rootsByCwd.delete(cwd)\n }\n\n /**\n * 清理全部状态。\n * @author ddj 2026年08月24号\n */\n disposeAll(): void {\n for (const controller of this.inflight.values()) controller.abort()\n this.inflight.clear()\n this.rootsByCwd.clear()\n this.cache.clear()\n }\n\n /**\n * 将 provider 结果与 active diff 合并、排序和截断。\n * @author ddj 2026年08月24号\n * @param result provider 结果\n * @param activePaths active diff 路径\n * @param root 搜索根\n * @param query 已规范化 query\n * @returns 旧 RPC 响应字段\n */\n private finish(result: WorkspaceSearchResult, activePaths: string[], root: string, query: ReturnType<typeof prepareQuery>): SearchResponse {\n const candidates = this.ranker.rank(mergeCandidates(result, activePaths, root, query), query)\n return { files: candidates.slice(0, RESULT_LIMIT).map((candidate) => candidate.path), truncated: result.truncated || candidates.length > RESULT_LIMIT }\n }\n\n /**\n * provider 失败时仅保留 active diff 命中。\n * @author ddj 2026年08月24号\n * @param paths active diff 路径\n * @param root 搜索根\n * @param query 已规范化 query\n * @returns 旧 RPC 响应字段\n */\n private rankActive(paths: string[], root: string, query: ReturnType<typeof prepareQuery>): SearchResponse {\n const result: WorkspaceSearchResult = { files: [], truncated: false, complete: true, source: 'active-diff' }\n return this.finish(result, paths, root, query)\n }\n}\n\n/**\n * 创建默认编排器。\n * @author ddj 2026年08月24号\n * @param ctx DSH 上下文\n * @returns 搜索编排器\n */\nexport function newSearcher(ctx: Ctx): SearchOrchestrator {\n return new SearchOrchestrator(ctx)\n}\n","/**\n * dsh-vscode-mode host — 回滚/删除(fs + subprocess 操作)。\n * 迁移自原 src/index.ts 的 revertCall/revertHunk/deleteCreated/restoreFile,语义不改。\n * 作者 ddj 2026-08-20\n */\nimport type { DiffRecord } from './shared/types.js'\nimport type { Ctx, Session } from './store.js'\nimport { policyOf, resolveTarget } from './store.js'\nimport { applyLocations, locateHunks, preciseHunk } from './shared/diff.js'\n\nexport type Result = { ok: true } | { ok: false; error: string }\n\n/**\n * 删除新建文件(拒绝创建时):subprocess 删除,路径先经 fs.contains 校验工作区边界。\n * @author ddj 2026年08月20号\n * @returns 成功或失败原因\n */\nexport async function deleteCreated(ctx: Ctx, session: Session, record: DiffRecord): Promise<Result> {\n const sub = ctx.get('subprocess')\n const fs = ctx.get('fs')\n if (!sub || !fs) return { ok: false, error: '回滚不可用:缺少 subprocess/fs' }\n const policy = policyOf(ctx, session)\n const rootTarget = await fs.resolve(policy?.workspaceRoot ?? '.', {})\n const target = await resolveTarget(ctx, session, record.path)\n if (!fs.contains(rootTarget, target)) return { ok: false, error: '拒绝删除:目标不在会话工作区内' }\n const p = fs.processPath(target)\n // subprocess 契约:spawn({ argv, stdio, graceMs }),done → { exitCode },输出走 handle.collected\n const attempt = async (argv: string[]): Promise<void> => {\n const handle = sub.spawn({\n argv,\n stdio: { stdout: { maxBytes: 1 << 16 }, stderr: { maxBytes: 1 << 16 }, stdin: 'ignore' },\n graceMs: 10000,\n })\n const outcome = await handle.done\n const code = outcome?.exitCode ?? outcome?.code\n if (code !== 0) {\n const err = handle.collected?.stderr?.readFrom(0).text ?? ''\n throw new Error('exit ' + code + ' ' + err)\n }\n }\n try {\n await attempt(['powershell', '-NoProfile', '-NonInteractive', '-Command', 'Remove-Item -LiteralPath \"' + p + '\" -Force'])\n return { ok: true }\n } catch (error) {\n try {\n await attempt(['/bin/rm', '-f', '--', p])\n return { ok: true }\n } catch (error2) {\n return { ok: false, error: '删除失败(文件仍存在):' + String(error) + ' / ' + String(error2) }\n }\n }\n}\n\n/** 整调用回滚:write/编辑用 before 整文件恢复;新建文件转 deleteCreated。 */\nexport async function revertCall(ctx: Ctx, session: Session, record: DiffRecord): Promise<Result> {\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '回滚不可用:缺少 fs' }\n if (record.before === null) {\n if (!record.create) return { ok: false, error: '无法回滚:缺少修改前内容(大文件或旧记录)' }\n return deleteCreated(ctx, session, record)\n }\n try {\n const target = await resolveTarget(ctx, session, record.path)\n await fs.writeText(target, record.before, void 0, void 0, policyOf(ctx, session))\n return { ok: true }\n } catch (error) {\n return { ok: false, error: '回滚失败:' + String(error) }\n }\n}\n\n/** 单 hunk 回滚:用 callHunk(edit 单 hunk 精确串)经 fs.editText 反替换。 */\nexport async function revertHunk(ctx: Ctx, session: Session, record: DiffRecord, idx: number): Promise<Result> {\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '回滚不可用:缺少 fs' }\n const precise = preciseHunk(record, idx)\n if (!precise) return { ok: false, error: '找不到该差异块' }\n try {\n const target = await resolveTarget(ctx, session, record.path)\n const info = await fs.stat(target)\n if (!info || info.type !== 'file') return { ok: false, error: '回滚失败:文件不存在' }\n if ((info.size ?? 0) > 8 * 1024 * 1024) return { ok: false, error: '回滚失败:文件过大,无法安全定位' }\n const content = await fs.readText(target)\n const location = locateHunks(content, [precise])[0]\n if (!location?.matched) return { ok: false, error: '回滚失败:该区域可能已被后续修改影响' }\n const result = applyLocations(content, [location], true)\n await fs.writeText(target, result.content, void 0, void 0, policyOf(ctx, session))\n return { ok: true }\n } catch (error) {\n return { ok: false, error: '回滚失败:该区域可能已被后续修改影响(' + String(error) + ')' }\n }\n}\n\n/**\n * 恢复文件到记录对应状态(批次回滚用):返回错误文案或 null(成功)。\n * @author ddj 2026年08月20号\n */\nexport async function restoreFile(ctx: Ctx, session: Session, rec: DiffRecord): Promise<string | null> {\n const fs = ctx.get('fs')\n if (!fs) return '缺少 fs'\n if (rec.before === null || rec.before === undefined) {\n if (rec.create === true) {\n const out = await deleteCreated(ctx, session, rec)\n return out.ok ? null : out.error\n }\n return '缺少修改前内容(大文件或旧记录),无法回滚'\n }\n try {\n const target = await resolveTarget(ctx, session, rec.path)\n await fs.writeText(target, rec.before, void 0, void 0, policyOf(ctx, session))\n return null\n } catch (error) {\n return '回滚失败:' + String(error)\n }\n}\n","/**\n * dsh-vscode-mode host — MCP 运行时管理适配层。\n * 只操作已装配的 @deepseek-ai/dsh-mcp-client loader entry,不在浏览器侧连接 MCP。\n * 作者 ddj 2026年08月22号\n */\nimport type { MpcConfig, MpcServer, MpcTool } from './shared/mcp.js'\nimport type { Ctx } from './store.js'\n\nconst MCP_PACKAGE = '@deepseek-ai/dsh-mcp-client'\n/** 项目级 MCP 的 loader entry id 固定前缀(区分 profile 全局 MCP;注意 loader id 不能用 ':' 分隔,故用 '.')。 */\nexport const PROJECT_ENTRY_PREFIX = 'vsm-mcp.'\nconst LEGACY_PROJECT_PREFIX = 'vsm-mcp:'\n\n/** 判断新旧格式项目 entry id,避免旧残留被显示为全局 MCP。 */\nexport function isProjectEntryId(id: string): boolean {\n return id.startsWith(PROJECT_ENTRY_PREFIX) || id.startsWith(LEGACY_PROJECT_PREFIX)\n}\n\n/** 列出当前 loader 中的 MCP entry。 */\nfunction entriesOf(ctx: Ctx): any[] {\n const loader = ctx.get('loader')\n if (!loader || typeof loader.entries !== 'function') return []\n return [...loader.entries()].filter((entry) => entry?.options?.name === MCP_PACKAGE)\n}\nexport { entriesOf }\n\n/** 脱敏配置并保留可编辑字段的存在性。 */\nexport function publicConfig(config: Record<string, unknown>): MpcConfig {\n const out = { ...config } as Record<string, unknown>\n if (out.env && typeof out.env === 'object') out.env = Object.fromEntries(Object.keys(out.env as object).map((key) => [key, '••••••']))\n if (out.headers && typeof out.headers === 'object') out.headers = Object.fromEntries(Object.keys(out.headers as object).map((key) => [key, '••••••']))\n return out as unknown as MpcConfig\n}\n\n/** 从工具注册表读取服务器命名空间下的工具摘要。 */\nexport function toolsOf(ctx: Ctx, serverName: string): MpcTool[] {\n const tools = ctx.get('tools')\n const view = tools?.view?.(void 0)\n const visible = view?.visible\n if (!(visible instanceof Map)) return []\n const prefix = `mcp__${serverName}__`\n return [...visible.entries()].filter(([name]) => String(name).startsWith(prefix)).map(([name, definition]) => ({\n name: String(name).slice(prefix.length),\n description: typeof definition?.description === 'string' ? definition.description : undefined,\n }))\n}\n\n/** 将 loader entry 映射为设置页摘要。 */\nexport function serverOf(ctx: Ctx, entry: any): MpcServer {\n const config = (entry.options?.config ?? {}) as Record<string, unknown>\n const serverName = typeof config.serverName === 'string' ? config.serverName : entry.options?.id ?? 'unknown'\n const tools = toolsOf(ctx, serverName)\n const state = entry.fiber?.state\n return {\n id: String(entry.id ?? entry.options?.id ?? serverName),\n serverName,\n enabled: entry.disabled !== true,\n transport: config.transport === 'streamable-http' ? 'streamable-http' : 'stdio',\n config: publicConfig(config),\n status: state === 2 ? 'connected' : state === 1 ? 'connecting' : 'error',\n toolCount: tools.length,\n tools,\n error: state === 3 ? 'MCP 插件未正常运行' : undefined,\n }\n}\n\n/** 校验 MCP 配置。 */\nexport function validateConfig(config: MpcConfig): void {\n if (!/^[A-Za-z0-9_-]{1,32}$/.test(config.serverName)) throw new Error('serverName 只能包含字母、数字、下划线和连字符(最多 32 位)')\n if (config.transport === 'stdio' && !config.command?.trim()) throw new Error('stdio MCP 必须填写 command')\n if (config.transport === 'streamable-http' && !/^https?:\\/\\//.test(config.url ?? '')) throw new Error('HTTP MCP 必须填写 http(s) URL')\n}\n\n/** 列出全局(profile)MCP 服务,过滤掉新旧格式的项目级条目。 */\nexport function listMcp(ctx: Ctx): { servers: MpcServer[] } {\n return { servers: entriesOf(ctx).filter((entry) => !isProjectEntryId(String(entry.id ?? entry.options?.id ?? ''))).map((entry) => serverOf(ctx, entry)) }\n}\n\n/** 保存 MCP 服务配置并触发 loader 热更新。 */\nexport async function saveMcp(ctx: Ctx, config: MpcConfig): Promise<MpcServer> {\n validateConfig(config)\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const existing = entriesOf(ctx).find((entry) => !isProjectEntryId(String(entry.id ?? entry.options?.id ?? '')) && entry.options?.config?.serverName === config.serverName)\n if (existing) {\n await loader.update(existing.id, { config: { ...config } })\n return serverOf(ctx, loader.resolve(existing.id))\n }\n const id = await loader.create({ name: MCP_PACKAGE, config: { ...config } })\n return serverOf(ctx, loader.resolve(id))\n}\n\n/** 删除 MCP 服务。 */\nexport async function removeMcp(ctx: Ctx, id: string): Promise<void> {\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id) === id)\n if (!entry) throw new Error('MCP 服务不存在')\n await loader.remove(entry.id)\n}\n\n/** 切换 MCP 服务启用状态。 */\nexport async function toggleMcp(ctx: Ctx, id: string, enabled: boolean): Promise<MpcServer> {\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id) === id)\n if (!entry) throw new Error('MCP 服务不存在')\n await loader.update(entry.id, { disabled: !enabled })\n return serverOf(ctx, loader.resolve(entry.id))\n}\n\n/** 重新加载 MCP 服务。 */\nexport async function refreshMcp(ctx: Ctx, id: string): Promise<MpcServer> {\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id) === id)\n if (!entry) throw new Error('MCP 服务不存在')\n await loader.update(entry.id, { config: { ...(entry.options?.config ?? {}) } })\n return serverOf(ctx, loader.resolve(entry.id))\n}\n\nexport type { MpcConfig, MpcServer }\nexport const mcpPackageName = MCP_PACKAGE\n","/**\n * dsh-vscode-mode host — 项目级 MCP 管理。\n * 配置以项目根目录 .mcp.json(mcpServers 格式,对齐 Claude Code/Cursor)存储;\n * 工具经 loader 动态激活(entry id 带 PROJECT_ENTRY_PREFIX,全局生效)。\n * 重启后由本项目从各 .mcp.json 恢复激活;.mcp.json 为持久真相,reconcile 以文件为准。\n * 作者 ddj 2026年08月22号\n */\nimport { createHash } from 'node:crypto'\nimport { PROJECT_ENTRY_PREFIX, entriesOf, serverOf, validateConfig } from './mcp.js'\nimport type { MpcConfig, MpcProject, MpcServer } from './shared/mcp.js'\nimport type { Ctx } from './store.js'\n\nconst FILE_NAME = '.mcp.json'\n\n/** 校验项目路径属于 DSH 已注册 workspace,避免 RPC 写入任意目录。 */\nfunction requireWorkspace(ctx: Ctx, workspacePath: string): { path: string; title?: string } {\n const workspace = (ctx.get('workspaceRegistry')?.list?.() ?? []).find((item: { path: string }) => item.path === workspacePath)\n if (!workspace) throw new Error('项目未注册为 DSH workspace,不能管理项目 MCP')\n return workspace\n}\n\n/** 用户显式 GUI 管理操作的写策略:danger-full-access(写入路径固定为 workspacePath/.mcp.json)。 */\nfunction fullPolicy(ctx: Ctx): unknown {\n const svc = ctx.get('sandboxPolicy')\n if (!svc || typeof svc.resolve !== 'function') return undefined\n return svc.resolve({ mode: 'danger-full-access' })\n}\n\n/** workspace 路径 → 确定性短哈希(entry id 归属段,重启后稳定可解码)。 */\nexport function hashWorkspace(path: string): string {\n return createHash('sha1').update(path).digest('hex').slice(0, 10)\n}\n\n/** 项目 MCP 的 loader entry id:vsm-mcp.<pathHash>.<serverName>(loader id 不能用冒号)。 */\nexport function projectEntryId(workspacePath: string, serverName: string): string {\n return PROJECT_ENTRY_PREFIX + hashWorkspace(workspacePath) + '.' + serverName\n}\n\n/** 读取项目 .mcp.json 顶层对象(缺失 → 空;非法 → 抛错带文案)。 */\nasync function readProjectJson(ctx: Ctx, workspacePath: string): Promise<Record<string, unknown>> {\n const fs = ctx.get('fs')\n if (!fs) throw new Error('缺少 fs 服务')\n const target = await fs.resolve(FILE_NAME, { cwd: workspacePath })\n let text: string\n try {\n text = await fs.readText(target)\n } catch (error) {\n return {}\n }\n let data: unknown\n try {\n data = JSON.parse(text)\n } catch (error) {\n throw new Error('.mcp.json 解析失败:' + String(error))\n }\n if (data === null || typeof data !== 'object' || Array.isArray(data)) throw new Error('.mcp.json 顶层必须是对象')\n return data as Record<string, unknown>\n}\n\n/** 读取并校验 .mcp.json 的 mcpServers 映射(纯函数,可单测)。 */\nexport function serversOf(data: Record<string, unknown>): Record<string, Record<string, unknown>> {\n const raw = data.mcpServers\n if (raw === undefined) return {}\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) throw new Error('.mcp.json 的 mcpServers 必须是对象')\n const out: Record<string, Record<string, unknown>> = {}\n for (const [name, value] of Object.entries(raw)) {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) continue\n out[name] = value as Record<string, unknown>\n }\n return out\n}\n\n/** 把 .mcp.json 单条 server 定义归一化为 MpcConfig(缺传输必填 → null,纯函数可单测)。 */\nexport function configFromDef(def: Record<string, unknown> | undefined, serverName: string): MpcConfig | null {\n if (!def) return null\n const transport = typeof def.url === 'string' ? 'streamable-http' : 'stdio'\n const config: MpcConfig = { serverName, transport }\n if (transport === 'stdio') {\n config.command = typeof def.command === 'string' ? def.command : ''\n config.args = Array.isArray(def.args) ? def.args.map(String) : []\n if (typeof def.cwd === 'string') config.cwd = def.cwd\n if (def.env && typeof def.env === 'object') config.env = Object.fromEntries(Object.entries(def.env as Record<string, unknown>).map(([k, v]) => [k, String(v)]))\n } else {\n config.url = def.url as string\n if (def.headers && typeof def.headers === 'object') config.headers = Object.fromEntries(Object.entries(def.headers as Record<string, unknown>).map(([k, v]) => [k, String(v)]))\n }\n if (typeof def.toolCallTimeoutMs === 'number') config.toolCallTimeoutMs = def.toolCallTimeoutMs\n return config\n}\n\n/** 写回 .mcp.json(保留顶层未知字段与其余 mcpServers,仅改目标 serverName)。 */\nasync function writeProjectJson(ctx: Ctx, workspacePath: string, data: Record<string, unknown>, mcpServers: Record<string, Record<string, unknown>>): Promise<void> {\n const fs = ctx.get('fs')\n if (!fs) throw new Error('缺少 fs 服务')\n const target = await fs.resolve(FILE_NAME, { cwd: workspacePath })\n const next = { ...data, mcpServers }\n await fs.writeText(target, JSON.stringify(next, null, 2) + '\\n', void 0, void 0, fullPolicy(ctx))\n}\n\n/** 查重:目标 serverName 是否已被其他 loader entry(全局或他项目)占用。 */\nfunction findConflict(ctx: Ctx, workspacePath: string, serverName: string): string | null {\n const ownId = projectEntryId(workspacePath, serverName)\n for (const entry of entriesOf(ctx)) {\n if (String(entry.id ?? entry.options?.id ?? '') === ownId) continue\n if (entry.options?.config?.serverName === serverName) {\n return 'serverName \"' + serverName + '\" 已被另一个 MCP 使用(全局或其他项目),请换一个名称'\n }\n }\n return null\n}\n\n/** 激活一个项目 MCP:校验 + 查重 + loader.create。 */\nexport async function activateProjectMcp(ctx: Ctx, workspacePath: string, config: MpcConfig): Promise<MpcServer> {\n validateConfig(config)\n const conflict = findConflict(ctx, workspacePath, config.serverName)\n if (conflict) throw new Error(conflict)\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const id = projectEntryId(workspacePath, config.serverName)\n const existing = entriesOf(ctx).find((entry) => String(entry.id ?? entry.options?.id ?? '') === id)\n if (existing) {\n await loader.update(existing.id, { config: { ...config } })\n return serverOf(ctx, loader.resolve(existing.id))\n }\n const created = await loader.create({ id, name: '@deepseek-ai/dsh-mcp-client', config: { ...config } })\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id ?? candidate.options?.id ?? '') === id)\n if (!entry) throw new Error('MCP 已创建但未能找到 entry(id=' + id + ')')\n return serverOf(ctx, entry)\n}\n\n/** 停用一个项目 MCP(按 entry id)。 */\nexport async function deactivateMcp(ctx: Ctx, entryId: string): Promise<void> {\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id ?? candidate.options?.id ?? '') === entryId)\n if (!entry) return\n await loader.remove(entry.id)\n}\n\n/** 以 .mcp.json 为真相 reconcile 该项目的激活状态(幂等)。 */\nexport async function reconcileProject(ctx: Ctx, workspacePath: string): Promise<void> {\n const data = await readProjectJson(ctx, workspacePath)\n const fileServers = new Set(Object.keys(serversOf(data)))\n const prefix = PROJECT_ENTRY_PREFIX + hashWorkspace(workspacePath) + '.'\n for (const entry of entriesOf(ctx)) {\n const id = String(entry.id ?? entry.options?.id ?? '')\n if (!id.startsWith(prefix)) continue\n const serverName = id.slice(prefix.length)\n if (fileServers.has(serverName)) continue\n await deactivateMcp(ctx, id)\n }\n for (const serverName of fileServers) {\n const config = await configOfServer(ctx, workspacePath, serverName)\n if (config === null) continue\n const id = projectEntryId(workspacePath, serverName)\n if (entriesOf(ctx).some((entry) => String(entry.id ?? entry.options?.id ?? '') === id)) continue\n await activateProjectMcp(ctx, workspacePath, { ...config, serverName })\n }\n}\n\n/** 把 .mcp.json 单条 server 定义归一化为 MpcConfig(缺传输必填 → null)。 */\nasync function configOfServer(ctx: Ctx, workspacePath: string, serverName: string): Promise<MpcConfig | null> {\n const data = await readProjectJson(ctx, workspacePath)\n return configFromDef(serversOf(data)[serverName], serverName)\n}\n\n/** 单个项目的完整视图(fileData + 激活状态合并)。 */\nasync function projectOf(ctx: Ctx, workspacePath: string, title: string): Promise<MpcProject> {\n const fs = ctx.get('fs')\n if (!fs) return { workspacePath, title, servers: [], source: 'project' }\n try {\n const target = await fs.resolve(workspacePath)\n const info = await fs.stat(target)\n if (!info || info.type !== 'directory') return { workspacePath, title, servers: [], source: 'project', missingDir: true }\n } catch (error) {\n return { workspacePath, title, servers: [], source: 'project', missingDir: true }\n }\n await reconcileProject(ctx, workspacePath)\n let servers: MpcServer[] = []\n let fileError: string | undefined\n try {\n const data = await readProjectJson(ctx, workspacePath)\n const prefix = PROJECT_ENTRY_PREFIX + hashWorkspace(workspacePath) + '.'\n servers = entriesOf(ctx).filter((entry) => String(entry.id ?? entry.options?.id ?? '').startsWith(prefix)).map((entry) => serverOf(ctx, entry))\n servers.sort((a, b) => (a.serverName < b.serverName ? -1 : 1))\n } catch (error) {\n fileError = String(error)\n }\n return { workspacePath, title, servers, source: 'project', fileError }\n}\n\n/** 列出全部项目及其项目级 MCP。 */\nexport async function listProjects(ctx: Ctx): Promise<{ projects: MpcProject[] }> {\n const registry = ctx.get('workspaceRegistry')\n const workspaces = registry?.list?.() ?? []\n const projects: MpcProject[] = []\n for (const ws of workspaces) projects.push(await projectOf(ctx, ws.path, ws.title ?? ''))\n return { projects }\n}\n\n/** 保存(新增/更新)一个项目 MCP:写 .mcp.json → 激活。 */\nexport async function projectSave(ctx: Ctx, workspacePath: string, serverName: string, config: MpcConfig): Promise<MpcProject> {\n const workspace = requireWorkspace(ctx, workspacePath)\n validateConfig({ ...config, serverName })\n const conflict = findConflict(ctx, workspacePath, serverName)\n if (conflict) throw new Error(conflict)\n const data = await readProjectJson(ctx, workspacePath)\n const servers = serversOf(data)\n const next = { ...config } as unknown as Record<string, unknown>\n delete next.serverName\n delete next.transport\n delete next.disabled // disabled 由 projectToggle 管理,保存恒为启用\n servers[serverName] = next\n await writeProjectJson(ctx, workspacePath, data, servers)\n await activateProjectMcp(ctx, workspacePath, { ...config, serverName })\n return projectOf(ctx, workspacePath, workspace.title ?? '')\n}\n\n/** 删除一个项目 MCP:停用 → 从 .mcp.json 移除。 */\nexport async function projectRemove(ctx: Ctx, workspacePath: string, serverName: string): Promise<MpcProject> {\n const workspace = requireWorkspace(ctx, workspacePath)\n await deactivateMcp(ctx, projectEntryId(workspacePath, serverName))\n const data = await readProjectJson(ctx, workspacePath)\n const servers = serversOf(data)\n delete servers[serverName]\n await writeProjectJson(ctx, workspacePath, data, servers)\n return projectOf(ctx, workspacePath, workspace.title ?? '')\n}\n\n/** 切换项目 MCP 启用状态(持久化到 .mcp.json + loader.update)。 */\nexport async function projectToggle(ctx: Ctx, workspacePath: string, serverName: string, enabled: boolean): Promise<MpcProject> {\n const workspace = requireWorkspace(ctx, workspacePath)\n const data = await readProjectJson(ctx, workspacePath)\n const servers = serversOf(data)\n const def = servers[serverName]\n if (!def) throw new Error('项目中不存在该 MCP')\n if (enabled) delete def.disabled\n else def.disabled = true\n await writeProjectJson(ctx, workspacePath, data, servers)\n const loader = ctx.get('loader')\n if (loader) {\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id ?? candidate.options?.id ?? '') === projectEntryId(workspacePath, serverName))\n if (entry) await loader.update(entry.id, { disabled: !enabled })\n }\n return projectOf(ctx, workspacePath, workspace.title ?? '')\n}\n\n/** 刷新(重连)项目 MCP。 */\nexport async function projectRefresh(ctx: Ctx, workspacePath: string, serverName: string): Promise<MpcProject> {\n const workspace = requireWorkspace(ctx, workspacePath)\n const loader = ctx.get('loader')\n if (!loader) throw new Error('缺少 loader 服务')\n const id = projectEntryId(workspacePath, serverName)\n const entry = entriesOf(ctx).find((candidate) => String(candidate.id ?? candidate.options?.id ?? '') === id)\n if (!entry) throw new Error('该项目 MCP 未激活')\n await loader.update(entry.id, { config: { ...(entry.options?.config ?? {}) } })\n return projectOf(ctx, workspacePath, workspace.title ?? '')\n}\n","/**\n * dsh-vscode-mode host — RPC 分发:类型化方法表替代巨型 switch。\n * 迁移自原 src/index.ts 的 handleRpc,方法名/载荷/错误文案一字不改。\n * 新功能 = shared/rpc.ts 加方法 + 这里加一个 handler,不改其他模块。\n * 作者 ddj 2026-08-20\n */\nimport type { RpcHandlerMap, RpcMethod, RpcRequestMap, RpcResult } from './shared/rpc.js'\nimport type { DiffRecord, RecordView } from './shared/types.js'\nimport type { Ctx, Session } from './store.js'\nimport {\n READ_CAP,\n appendArchiveEntries,\n archiveRecords,\n autoArchiveStale,\n parseArchive,\n policyOf,\n readArchiveText,\n resolveTarget,\n saveBucket,\n} from './store.js'\nimport { archiveEntryFor, markDecision, recordResolved, reconstructOriginal } from './model.js'\nimport type { Registry } from './registry.js'\nimport { bucketOf, cwdOf, sessionOf } from './registry.js'\nimport type { SearchOrchestrator } from './search/orchestrator.js'\nimport { newSearcher } from './search/orchestrator.js'\nimport { restoreFile, revertCall, revertHunk } from './revert.js'\nimport { listMcp, refreshMcp, removeMcp, saveMcp, toggleMcp } from './mcp.js'\nimport { listProjects, projectRefresh, projectRemove, projectSave, projectToggle } from './mcpProject.js'\n\n/** cwd → Promise 链:串行化 debug 日志追加(fs read+write 非原子,避免并发丢行)。 */\nconst debugWriteQueues = new Map<string, Promise<void>>()\n\n/** 记录 → 客户端视图(不含 before 全文,仅长度)。 */\nfunction recView(record: DiffRecord): RecordView {\n return {\n callId: record.callId,\n toolName: record.toolName,\n path: record.path,\n beforeLen: typeof record.before === 'string' ? record.before.length : 0,\n create: record.create === true,\n callHunk: record.callHunk,\n hunks: record.hunks,\n decisions: record.decisions,\n note: record.note ?? null,\n superseded: record.superseded === true,\n after: record.after ?? null,\n baseFingerprint: record.baseFingerprint ?? null,\n afterFingerprint: record.afterFingerprint ?? null,\n conflict: record.conflict === true,\n legacy: record.legacy === true,\n at: record.at,\n }\n}\n\n/** 会话/工作区公共前置:返回 {session,cwd} 或错误文案。 */\nasync function requireSession(ctx: Ctx, sessionId: string | undefined): Promise<\n { session: Session; cwd: string } | { err: string }\n> {\n const session = sessionOf(ctx, sessionId)\n if (!session) return { err: '会话不存在' }\n const cwd = cwdOf(session)\n if (!cwd) return { err: '会话无工作区' }\n return { session, cwd }\n}\n\n/** 各方法 handler 表(类型由 shared/rpc 的 RpcHandlerMap 约束)。 */\nexport function buildHandlers(ctx: Ctx, registry: Registry, searcher = newSearcher(ctx)): RpcHandlerMap {\n return {\n 'edrv.list': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const want = Array.isArray(args.callIds) ? new Set(args.callIds) : null\n if (!want) await autoArchiveStale(ctx, sc.session, sc.cwd, bucket) // 全量轮询时自动清理 stale 幽灵差异\n const out: RecordView[] = []\n for (const rec of bucket.values()) {\n // 面板全量查询过滤已归档;聊天条按 callId 查询保留(状态徽章仍需正确显示)\n if (!want && rec.archived) continue\n if (want && !want.has(rec.callId)) continue\n out.push(recView(rec))\n }\n out.sort((a, b) => (a.at < b.at ? -1 : 1))\n return { ok: true, records: out }\n },\n 'edrv.accept': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const record = bucket.get(args.callId)\n if (!record) return { ok: false, error: '记录不存在' }\n markDecision(record, args.scope ?? 'call', args.hunkIndex, 'accepted')\n if (recordResolved(record)) await archiveRecords(ctx, sc.session, sc.cwd, bucket, [record], '已处理')\n else await saveBucket(ctx, sc.cwd, bucket, sc.session)\n return { ok: true, record: recView(record) }\n },\n 'edrv.reject': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const record = bucket.get(args.callId)\n if (!record) return { ok: false, error: '记录不存在' }\n const scope = args.scope ?? 'call'\n const outcome = scope === 'hunk' ? await revertHunk(ctx, sc.session, record, args.hunkIndex ?? -1) : await revertCall(ctx, sc.session, record)\n if (!outcome.ok) return { ok: false, error: outcome.error }\n markDecision(record, scope, args.hunkIndex, 'rejected')\n record.at = new Date().toISOString()\n if (recordResolved(record)) await archiveRecords(ctx, sc.session, sc.cwd, bucket, [record], '已处理(回滚)')\n else await saveBucket(ctx, sc.cwd, bucket, sc.session)\n return { ok: true, record: recView(record) }\n },\n 'edrv.read': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '缺少 fs' }\n try {\n const target = await resolveTarget(ctx, sc.session, args.path)\n const info = await fs.stat(target)\n if (!info || info.type !== 'file') return { ok: false, error: '文件不存在' }\n if ((info.size ?? 0) > READ_CAP) return { ok: false, error: '文件过大(>8MB),不支持整文件预览' }\n const content = await fs.readText(target)\n return { ok: true, content, size: content.length }\n } catch (error) {\n return { ok: false, error: '读取失败:' + String(error) }\n }\n },\n 'edrv.original': async (args) => {\n // 重建\"本批次修改前\"内容:DiffEditor 原始侧。仅反解 pending 块;\n // 全部反解失败时回退到最早记录的整体 before(若存在)。\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '缺少 fs' }\n try {\n const target = await resolveTarget(ctx, sc.session, args.path)\n const info = await fs.stat(target)\n if (!info || info.type !== 'file') return { ok: false, error: '文件不存在' }\n if ((info.size ?? 0) > READ_CAP) return { ok: false, error: '文件过大(>8MB),不支持差异重建' }\n const content = await fs.readText(target)\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const records = [...bucket.values()].filter((r) => r.path === args.path && !r.archived).sort((a, b) => (a.at < b.at ? -1 : 1))\n if (!records.length) return { ok: true, content, size: content.length, stale: [], fallback: false }\n const rebuilt = reconstructOriginal(records, content)\n if (rebuilt.stale.length && records[0].before !== null) {\n return { ok: true, content: records[0].before, size: records[0].before.length, stale: rebuilt.stale, fallback: true }\n }\n return { ok: true, content: rebuilt.content, size: rebuilt.content.length, stale: rebuilt.stale, fallback: false }\n } catch (error) {\n return { ok: false, error: '重建失败:' + String(error) }\n }\n },\n 'edrv.save': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '缺少 fs' }\n try {\n const target = await resolveTarget(ctx, sc.session, args.path)\n await fs.writeText(target, args.content, void 0, void 0, policyOf(ctx, sc.session))\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n let changed = false\n for (const rec of bucket.values()) {\n if (rec.path === args.path && rec.superseded !== true) { rec.superseded = true; rec.at = new Date().toISOString(); changed = true }\n }\n if (changed) {\n const done: DiffRecord[] = []\n for (const rec of bucket.values()) if (rec.path === args.path && rec.superseded) done.push(rec)\n if (done.length) await archiveRecords(ctx, sc.session, sc.cwd, bucket, done, '被手动编辑覆盖')\n else await saveBucket(ctx, sc.cwd, bucket, sc.session)\n }\n return { ok: true }\n } catch (error) {\n return { ok: false, error: '保存失败:' + String(error) }\n }\n },\n 'edrv.archiveList': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const batches = parseArchive(await readArchiveText(ctx, sc.cwd)).filter((b) => b.cwd === sc.cwd)\n const entries = batches.map((b) => {\n const recs = Array.isArray(b.records) ? b.records : []\n const sum = recs.reduce((s, r) => {\n const sm = r.summary || { accepted: 0, rejected: 0, pending: 0, superseded: false }\n s.accepted += sm.accepted || 0\n s.rejected += sm.rejected || 0\n s.pending += sm.pending || 0\n if (sm.superseded) s.superseded++\n return s\n }, { accepted: 0, rejected: 0, pending: 0, superseded: 0 })\n return { at: b.at, lastAt: b.lastAt || b.at, path: b.path, batch: b.batch ?? null, reason: b.reason ?? null, nRecords: recs.length, summary: sum }\n })\n entries.sort((a, b) => (Number(b.batch ?? -1) - Number(a.batch ?? -1)) || (a.at < b.at ? 1 : -1))\n return { ok: true, entries }\n },\n 'edrv.archiveRead': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const batchPath = args.path\n const batches = parseArchive(await readArchiveText(ctx, sc.cwd)).filter((b) => b.cwd === sc.cwd && (!batchPath || b.path === batchPath))\n return { ok: true, batches }\n },\n 'edrv.rollback': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n if (!fs) return { ok: false, error: '缺少 fs' }\n const batch = args.batch\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n let affected: DiffRecord[] = []\n let beforeRec: DiffRecord | null = null\n if (batch !== undefined) {\n const all = parseArchive(await readArchiveText(ctx, sc.cwd)).filter((b) => b.cwd === sc.cwd && b.path === args.path)\n const recs: DiffRecord[] = []\n for (const b of all) if (b.batch === batch) for (const r of (b.records || [])) recs.push(r as unknown as DiffRecord)\n if (!recs.length) return { ok: false, error: '归档中找不到该批次' }\n recs.sort((a, b2) => (a.at < b2.at ? -1 : 1))\n beforeRec = recs[0]\n affected = recs\n } else {\n for (const r of bucket.values()) if (r.path === args.path && !r.archived) affected.push(r)\n if (!affected.length) return { ok: false, error: '该文件没有可回滚的差异' }\n affected.sort((a, b2) => (a.at < b2.at ? -1 : 1))\n beforeRec = affected[0]\n }\n const rerr = await restoreFile(ctx, sc.session, beforeRec)\n if (rerr) return { ok: false, error: rerr }\n if (batch === undefined) {\n await archiveRecords(ctx, sc.session, sc.cwd, bucket, affected, '已回滚')\n } else {\n const all = parseArchive(await readArchiveText(ctx, sc.cwd)).filter((b) => b.cwd === sc.cwd && b.path === args.path && b.batch === batch)\n const sumRecs = all.reduce((s, b) => s + ((b.records || []).length), 0)\n const logRec = Object.assign({}, affected[0], { note: (affected[0].note ? affected[0].note + ';' : '') + '回滚至本批次前(批次 ' + batch + ')' })\n await appendArchiveEntries(ctx, sc.cwd, [archiveEntryFor([logRec], sc.cwd, '已回滚(批次 ' + batch + ',' + sumRecs + ' 条)')], sc.session)\n // 批次回滚恢复的是旧内容,文件当前活跃差异已失效,一并归档\n const activeRecs: DiffRecord[] = []\n for (const r of bucket.values()) if (r.path === args.path && !r.archived) activeRecs.push(r)\n if (activeRecs.length) await archiveRecords(ctx, sc.session, sc.cwd, bucket, activeRecs, '已回滚(批次回滚覆盖)')\n }\n return { ok: true, path: args.path, batch: batch ?? null }\n },\n 'edrv.debug': async (args) => {\n // 诊断日志:client 上报 → 写入工作区旁车 .dsh-edit-review-debug.log(console 不一定落盘,文件可靠)\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const fs = ctx.get('fs')\n const text = String(args.text ?? '')\n const prev = debugWriteQueues.get(sc.cwd) || Promise.resolve()\n const task = prev.then(async () => {\n try {\n const target = await fs.resolve('.dsh-edit-review-debug.log', { cwd: sc.cwd })\n const old = await fs.readText(target).catch(() => '')\n const line = new Date().toISOString() + ' ' + text + '\\n'\n await fs.writeText(target, (old || '') + line, void 0, void 0, policyOf(ctx, sc.session))\n } catch (e) { /* 写日志失败忽略 */ }\n })\n debugWriteQueues.set(sc.cwd, task)\n await task\n console.error('[edrv-debug] ' + text)\n return { ok: true }\n },\n 'edrv.searchFiles': async (args) => {\n const sc = await requireSession(ctx, args.sessionId)\n if ('err' in sc) return { ok: false, error: sc.err }\n const bucket = await bucketOf(registry, ctx, sc.cwd)\n const activePaths: string[] = []\n for (const record of bucket.values()) if (record.path) activePaths.push(record.path)\n const result = await searcher.search({ session: sc.session, cwd: sc.cwd, query: args.query, activePaths })\n return { ok: true, ...result }\n },\n 'mcp.list': async () => ({ ok: true, ...listMcp(ctx) }),\n 'mcp.save': async (args) => {\n try { return { ok: true, server: await saveMcp(ctx, args.config) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.remove': async (args) => {\n try { await removeMcp(ctx, args.id); return { ok: true } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.toggle': async (args) => {\n try { return { ok: true, server: await toggleMcp(ctx, args.id, args.enabled) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.refresh': async (args) => {\n try { return { ok: true, server: await refreshMcp(ctx, args.id) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projects': async () => {\n try { return { ok: true, ...await listProjects(ctx) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projectSave': async (args) => {\n try { return { ok: true, project: await projectSave(ctx, args.workspacePath, args.serverName, args.config) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projectRemove': async (args) => {\n try { return { ok: true, project: await projectRemove(ctx, args.workspacePath, args.serverName) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projectToggle': async (args) => {\n try { return { ok: true, project: await projectToggle(ctx, args.workspacePath, args.serverName, args.enabled) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n 'mcp.projectRefresh': async (args) => {\n try { return { ok: true, project: await projectRefresh(ctx, args.workspacePath, args.serverName) } }\n catch (error) { return { ok: false, error: String(error) } }\n },\n }\n}\n\n/**\n * 统一入口:按方法分发到 handler 表。\n * @author ddj 2026年08月20号\n */\nexport async function handleRpc<M extends RpcMethod>(\n ctx: Ctx,\n registry: Registry,\n method: M,\n args: RpcRequestMap[M],\n searcher = newSearcher(ctx),\n): Promise<RpcResult<M>> {\n const handlers = buildHandlers(ctx, registry, searcher)\n const handler = handlers[method]\n if (!handler) return { ok: false, error: '未知方法: ' + String(method) } as RpcResult<M>\n return handler(args)\n}\n","/**\n * dsh-vscode-mode host — 项目 MCP 的 agent 级隔离。\n * 项目 MCP 连接仍由 Host 维护,但每个 agent 只继承当前 workspace 的项目工具;\n * tools.restrict() 负责模型可见性,tools.guard() 负责执行层兜底拒绝。\n * 作者 ddj 2026年08月22号\n */\nimport { PROJECT_ENTRY_PREFIX, entriesOf } from './mcp.js'\nimport { hashWorkspace } from './mcpProject.js'\nimport type { Ctx } from './store.js'\n\nconst LEGACY_PREFIX = 'vsm-mcp:'\nconst UNKNOWN_PROJECT = '__unknown_project__'\n\ntype ToolProjects = Map<string, string>\ntype AgentState = { dispose?: () => void; denyKey: string }\n\n/** 统一 workspace 路径,供 cwd 父路径匹配。 */\nexport function normalizePath(path: string): string {\n const value = String(path ?? '').replace(/\\\\/g, '/').replace(/\\/+/g, '/')\n return value.replace(/\\/$/, '').toLowerCase()\n}\n\n/** 在已注册 workspace 中匹配 cwd,优先最长父路径。 */\nexport function matchWorkspace(cwd: string | undefined, paths: string[]): string | undefined {\n if (!cwd) return undefined\n const target = normalizePath(cwd)\n const matches = paths.filter((path) => {\n const root = normalizePath(path)\n return target === root || target.startsWith(root + '/')\n })\n matches.sort((a, b) => normalizePath(b).length - normalizePath(a).length)\n return matches[0]\n}\n\n/** 根据 entry id 判断是否为新旧格式项目 MCP。 */\nexport function isProjectEntry(id: string): boolean {\n return id.startsWith(PROJECT_ENTRY_PREFIX) || id.startsWith(LEGACY_PREFIX)\n}\n\n/** 从项目 entry id 解析 workspace hash。 */\nfunction entryHash(id: string): string | undefined {\n if (id.startsWith(PROJECT_ENTRY_PREFIX)) return id.slice(PROJECT_ENTRY_PREFIX.length).split('.')[0]\n if (id.startsWith(LEGACY_PREFIX)) return id.slice(LEGACY_PREFIX.length).split(':')[0]\n return undefined\n}\n\n/** 返回一个 agent 不应继承的项目工具名。 */\nexport function denyTools(toolProjects: ToolProjects, currentPath: string | undefined): string[] {\n return [...toolProjects.entries()].filter(([, owner]) => owner !== currentPath).map(([name]) => name).sort()\n}\n\n/** 从 loader entry 和工具注册表建立工具到项目路径的映射。 */\nfunction projectTools(ctx: Ctx): ToolProjects {\n const result: ToolProjects = new Map()\n const registry = ctx.get('workspaceRegistry')\n const workspaces = registry?.list?.() ?? []\n const byHash: Map<string, string> = new Map(workspaces.map((ws: { path: string }) => [hashWorkspace(ws.path), ws.path] as [string, string]))\n const visible = ctx.get('tools')?.view?.(void 0)?.visible\n if (!(visible instanceof Map)) return result\n for (const entry of entriesOf(ctx)) {\n const id = String(entry.id ?? entry.options?.id ?? '')\n if (!isProjectEntry(id)) continue\n const hash = entryHash(id)\n const owner = hash ? byHash.get(hash) ?? UNKNOWN_PROJECT : UNKNOWN_PROJECT\n const serverName = entry.options?.config?.serverName\n if (typeof serverName !== 'string') continue\n const prefix = `mcp__${serverName}__`\n for (const name of visible.keys()) if (String(name).startsWith(prefix)) result.set(String(name), owner)\n }\n return result\n}\n\n/** 取得 agent 当前 cwd 所属 workspace。 */\nfunction agentWorkspace(ctx: Ctx, agent: any): string | undefined {\n const cwd = agent?.session?.header?.cwd\n const paths = (ctx.get('workspaceRegistry')?.list?.() ?? []).map((ws: { path: string }) => ws.path)\n return matchWorkspace(cwd, paths)\n}\n\n/** 同步一个 agent 的项目工具 deny 列表。 */\nfunction syncAgent(ctx: Ctx, state: AgentState, agent: any, tools: ToolProjects): void {\n const current = agentWorkspace(ctx, agent)\n const denied = denyTools(tools, current)\n const nextKey = denied.join('\\n')\n if (state.denyKey === nextKey) return\n state.dispose?.()\n state.dispose = undefined\n if (denied.length > 0) {\n try {\n state.dispose = agent.ctx.tools.restrict({ deny: denied })\n } catch (error) {\n ctx.logger?.warn?.('[dsh-vscode-mode] MCP agent restriction failed: ' + String(error))\n return\n }\n }\n state.denyKey = nextKey\n}\n\n/** 为当前 Host 安装项目 MCP 的 agent restriction 与执行 guard。 */\nexport function installIsolation(ctx: Ctx): void {\n const tools = ctx.get('tools')\n const agents = ctx.get('agents')\n if (!tools || !agents) return\n const states = new Map<any, AgentState>()\n let toolProjects = projectTools(ctx)\n let scheduled = false\n let syncing = false\n\n const syncAll = () => {\n if (syncing) return\n syncing = true\n try {\n toolProjects = projectTools(ctx)\n for (const agent of agents.list?.() ?? []) {\n const state = states.get(agent) ?? { denyKey: '' }\n states.set(agent, state)\n syncAgent(ctx, state, agent, toolProjects)\n }\n } finally {\n syncing = false\n }\n }\n const scheduleSync = () => {\n if (scheduled) return\n scheduled = true\n queueMicrotask(() => {\n scheduled = false\n syncAll()\n })\n }\n const onCreated = ctx.on('agent/created', ({ agent }: { agent: any }) => {\n const state = { denyKey: '' }\n states.set(agent, state)\n syncAgent(ctx, state, agent, toolProjects)\n })\n const onDisposed = ctx.on('agent/disposed', ({ agent }: { agent: any }) => {\n const state = states.get(agent)\n state?.dispose?.()\n states.delete(agent)\n })\n const onToolsChange = ctx.on('tools/change', scheduleSync)\n const stopGuard = tools.guard((exec: any) => {\n const owner = toolProjects.get(String(exec?.name ?? ''))\n if (!owner) return undefined\n const current = agentWorkspace(ctx, exec.agent)\n if (owner === current) return undefined\n return current === undefined\n ? '项目 MCP 需要在已注册工作区的对话中使用'\n : '已拒绝:当前对话工作区不能使用其他项目的 MCP'\n })\n syncAll()\n ctx.effect(() => () => {\n onCreated?.()\n onDisposed?.()\n onToolsChange?.()\n stopGuard?.()\n for (const state of states.values()) state.dispose?.()\n states.clear()\n }, 'vscode-mode:mcp-isolation')\n}\n","/**\n * dsh-vscode-mode host — 工作区文件清单扫描与缓存(快速打开/搜索用)。\n * 迁移自原 src/index.ts 的 listWorkspaceFiles,语义不改。\n * 作者 ddj 2026-08-20\n */\nimport type { Ctx, Session } from './store.js'\nimport { policyOf } from './store.js'\n\n/** 文件清单缓存 TTL 与扫描上限(避免大工作区反复全量扫描)。 */\nconst FILE_INDEX_TTL = 60_000\nconst SCAN_CAP = 6000\n/** cwd → { at, files }(随会话销毁清理)。 */\nconst fileIndex = new Map<string, { at: number; files: string[] }>()\n\n/**\n * 扫描工作区文件清单(快速打开/搜索用):subprocess(Windows powershell / POSIX find),\n * 排除常见重目录,容量上限 SCAN_CAP;结果缓存(TTL FILE_INDEX_TTL)。失败返回 null。\n * @author ddj 2026年08月20号\n * @param ctx DSH 上下文\n * @param session 会话(取工作区根)\n * @param cwd 工作区目录\n * @returns 绝对路径清单;不可用(无 subprocess/fs)或扫描失败返回 null\n */\nexport async function listWorkspaceFiles(ctx: Ctx, session: Session, cwd: string): Promise<string[] | null> {\n const cached = fileIndex.get(cwd)\n if (cached && Date.now() - cached.at < FILE_INDEX_TTL) return cached.files\n const sub = ctx.get('subprocess')\n const fs = ctx.get('fs')\n if (!sub || !fs) return null\n const policy = policyOf(ctx, session)\n let root: string\n try {\n const rootTarget = await fs.resolve(policy?.workspaceRoot ?? '.', {})\n root = fs.processPath(rootTarget)\n } catch (error) {\n root = cwd\n }\n const lines: string[] = []\n const run = async (argv: string[]): Promise<void> => {\n const handle = sub.spawn({\n argv,\n stdio: { stdout: { maxBytes: 8 << 20 }, stderr: { maxBytes: 1 << 16 }, stdin: 'ignore' },\n graceMs: 20000,\n })\n const outcome = await handle.done\n const code = outcome?.exitCode ?? outcome?.code\n if (code !== 0) throw new Error('scan exit ' + code)\n const text = handle.collected?.stdout?.readFrom(0).text ?? ''\n for (const ln of text.split(/\\r?\\n/)) {\n const s = ln.trim()\n if (s) lines.push(s)\n }\n }\n try {\n if (process.platform === 'win32') {\n const cmd = 'Get-ChildItem -LiteralPath \"' + String(root).replace(/\"/g, '\"\"') + '\" -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch \\'(node_modules|\\\\.git|\\\\.tmp|\\\\.cache|dist|build|vendor|coverage|__pycache__)\\' } | Select-Object -First ' + SCAN_CAP + ' | ForEach-Object { $_.FullName }'\n await run(['powershell', '-NoProfile', '-NonInteractive', '-Command', cmd])\n } else {\n const cmd = 'find ' + JSON.stringify(root) + ' -type f -not -path \\'*/node_modules/*\\' -not -path \\'*/.git/*\\' -not -path \\'*/.tmp/*\\' -not -path \\'*/.cache/*\\' -not -path \\'*/dist/*\\' -not -path \\'*/build/*\\' -not -path \\'*/vendor/*\\' -not -path \\'*/coverage/*\\' 2>/dev/null | head -n ' + SCAN_CAP\n await run(['/bin/sh', '-c', cmd])\n }\n } catch (error) {\n console.error('edrv scan failed', error)\n return null\n }\n const files = lines.slice(0, SCAN_CAP)\n if (files.length) fileIndex.set(cwd, { at: Date.now(), files })\n return files\n}\n\n/** 会话销毁时清理文件索引缓存。 */\nexport function dropFileIndex(cwd: string): void {\n fileIndex.delete(cwd)\n}\n","/**\n * @dsh-external 生态 → dsh-vscode-mode:DSH 上的类 VSCode 编码体验(Host 半入口)。\n * 职责:装配 capture(tools/result 捕获 edit/write 差异)、RPC 分发(11 个 edrv.* 方法)、\n * webServer 路由(/edrv/rpc、/edrv/assets/*、/edrv/vendor/*)、工作区旁车持久化。\n * 结构:shared/(双面契约) + model/store/capture/workspace/revert/registry/rpc/routes(host 模块)。\n * 作者 ddj 2026-08-20\n */\nimport { registerRoutes } from './routes.js'\nimport { captureToolResult } from './capture.js'\nimport { handleRpc } from './rpc.js'\nimport { newSearcher } from './search/orchestrator.js'\nimport { installIsolation } from './mcpIsolation.js'\nimport { dropFileIndex } from './workspace.js'\nimport { cwdOf } from './registry.js'\nimport type { Registry } from './registry.js'\nimport type { Ctx } from './store.js'\n\nexport const name = \"dsh-vscode-mode\"\nexport const inject = ['sessions', 'fs', 'webServer', 'loader', 'tools', 'workspaceRegistry', 'agents']\n\n/**\n * 装配插件:挂事件监听、注册路由。\n * @author ddj 2026年08月20号\n * @param ctx DSH 上下文(sessions/fs/webServer 由 inject 提供;sandboxPolicy/subprocess 惰性获取)\n * @param config 插件配置(可选 imageDir 覆盖图标目录)\n */\nexport function apply(ctx: Ctx, config?: unknown): void {\n const registry: Registry = new Map()\n const searcher = newSearcher(ctx)\n\n ctx.on('tools/result', (exec: unknown, result: unknown) => {\n void captureToolResult(ctx, registry, exec, result)\n })\n\n ctx.on('session/disposed', (session: unknown) => {\n const cwd = cwdOf(session as never)\n if (cwd) {\n registry.delete(cwd)\n dropFileIndex(cwd)\n searcher.dispose(cwd)\n }\n })\n\n registerRoutes(ctx, config, (method, args) => handleRpc(ctx, registry, method, args, searcher))\n installIsolation(ctx)\n\n ctx.logger?.info?.('[' + name + '] 编辑差异审查已装配(/edrv/rpc 路由就绪,项目 MCP 隔离已启用)')\n}\n"],"mappings":"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"}
|