dsh-vscode-mode 0.1.14 → 0.1.15

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 CHANGED
@@ -4,6 +4,8 @@ import { dirname, extname, join, normalize, resolve, sep } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { existsSync } from "node:fs";
6
6
  import { createHash } from "node:crypto";
7
+ import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
8
+ import z from "schemastery";
7
9
  //#region src/shared/rpc.ts
8
10
  /** webServer 精确路由。 */
9
11
  const RPC_PATH = "/edrv/rpc";
@@ -890,9 +892,6 @@ async function captureToolResult(ctx, registry, exec, result) {
890
892
  }
891
893
  record.batch = fileMaxBatch(bucket, path) + 1;
892
894
  bucket.set(exec.callId, record);
893
- const prior = [];
894
- for (const r of bucket.values()) if (r.path === path && r.callId !== exec.callId && !r.archived && (r.batch ?? 0) < record.batch) prior.push(r);
895
- if (prior.length) await archiveRecords(ctx, session, cwd, bucket, prior, prior.every(recordResolved) ? "已处理且被后续修改取代" : "被后续修改融合(内容已含其效果)");
896
895
  prune(bucket);
897
896
  await saveBucket(ctx, cwd, bucket, session);
898
897
  } catch (error) {
@@ -2024,6 +2023,74 @@ async function projectRefresh(ctx, workspacePath, serverName) {
2024
2023
  return projectOf(ctx, workspacePath, workspace.title ?? "");
2025
2024
  }
2026
2025
  //#endregion
2026
+ //#region src/fileOpenSettings.ts
2027
+ /**
2028
+ * dsh-vscode-mode host — 文件链接打开工具的持久化设置。
2029
+ * @author ddj 2026年08月24号
2030
+ */
2031
+ const FILE_OPEN_SETTINGS_NS = settingsNamespace("dsh-vscode-mode");
2032
+ const FILE_OPEN_DEFAULT = "auto";
2033
+ const FILE_OPEN_SCHEMA = z.object({ fileOpenTool: z.string().default(FILE_OPEN_DEFAULT) });
2034
+ function normalizeValue(value) {
2035
+ if (typeof value !== "string" || value.trim() === "") return FILE_OPEN_DEFAULT;
2036
+ return value.trim();
2037
+ }
2038
+ function configValue(config) {
2039
+ return normalizeValue(config?.fileOpenTool);
2040
+ }
2041
+ /**
2042
+ * 注册设置命名空间,并提供 host 侧的读取与更新状态。
2043
+ * @author ddj 2026年08月24号
2044
+ * @param ctx DSH host 上下文
2045
+ * @param config 插件组合配置
2046
+ * @param onChange 设置变化回调
2047
+ * @returns 设置状态
2048
+ */
2049
+ function setupOpenSettings(ctx, config, onChange) {
2050
+ let current = configValue(config);
2051
+ let revision;
2052
+ let provider;
2053
+ const notify = (value) => {
2054
+ current = normalizeValue(value);
2055
+ onChange(current);
2056
+ };
2057
+ const syncRevision = () => {
2058
+ revision = (provider?.describe?.({ redactSecrets: true })?.find((item) => item.ns === FILE_OPEN_SETTINGS_NS))?.revision;
2059
+ };
2060
+ const setSource = (source) => notify(source().fileOpenTool);
2061
+ const settingsChange = () => syncRevision();
2062
+ installSettingsSection(ctx, FILE_OPEN_SETTINGS_NS, FILE_OPEN_SCHEMA, { fileOpenTool: current }, {
2063
+ setSource,
2064
+ onChange: settingsChange
2065
+ });
2066
+ ctx.inject?.(["settings"], (settingsCtx) => {
2067
+ provider = settingsCtx.get("settings");
2068
+ syncRevision();
2069
+ });
2070
+ return {
2071
+ get value() {
2072
+ return current;
2073
+ },
2074
+ get revision() {
2075
+ return revision;
2076
+ },
2077
+ update: async (value, expectedRevision) => {
2078
+ const next = normalizeValue(value);
2079
+ if (!provider?.update) {
2080
+ notify(next);
2081
+ return;
2082
+ }
2083
+ await provider.update(FILE_OPEN_SETTINGS_NS, { fileOpenTool: next }, expectedRevision);
2084
+ const stored = (provider.describe?.({ redactSecrets: true })?.find((item) => item.ns === FILE_OPEN_SETTINGS_NS))?.value;
2085
+ notify(stored?.fileOpenTool ?? next);
2086
+ syncRevision();
2087
+ }
2088
+ };
2089
+ }
2090
+ function normalizeFileOpenTool(value) {
2091
+ return normalizeValue(value);
2092
+ }
2093
+ //#endregion
2027
2094
  //#region src/rpc.ts
2028
2095
  /** cwd → Promise 链:串行化 debug 日志追加(fs read+write 非原子,避免并发丢行)。 */
2029
2096
  const debugWriteQueues = /* @__PURE__ */ new Map();
@@ -2519,6 +2586,37 @@ function buildHandlers(ctx, registry, searcher = newSearcher(ctx)) {
2519
2586
  error: String(error)
2520
2587
  };
2521
2588
  }
2589
+ },
2590
+ "vscode.fileOpenSettingsGet": async () => {
2591
+ const descriptor = ctx.get("settings")?.describe?.({ redactSecrets: true })?.find((item) => item.ns === FILE_OPEN_SETTINGS_NS);
2592
+ const value = descriptor?.value;
2593
+ return {
2594
+ ok: true,
2595
+ fileOpenTool: normalizeFileOpenTool(value?.fileOpenTool ?? "auto"),
2596
+ revision: descriptor?.revision
2597
+ };
2598
+ },
2599
+ "vscode.fileOpenSettingsUpdate": async (args) => {
2600
+ const settings = ctx.get("settings");
2601
+ if (!settings?.update) return {
2602
+ ok: false,
2603
+ error: "设置服务不可用"
2604
+ };
2605
+ try {
2606
+ await settings.update(FILE_OPEN_SETTINGS_NS, { fileOpenTool: normalizeFileOpenTool(args.fileOpenTool) }, args.expectedRevision);
2607
+ const descriptor = settings.describe?.({ redactSecrets: true })?.find((item) => item.ns === FILE_OPEN_SETTINGS_NS);
2608
+ const value = descriptor?.value;
2609
+ return {
2610
+ ok: true,
2611
+ fileOpenTool: normalizeFileOpenTool(value?.fileOpenTool),
2612
+ revision: descriptor?.revision
2613
+ };
2614
+ } catch (error) {
2615
+ return {
2616
+ ok: false,
2617
+ error: String(error)
2618
+ };
2619
+ }
2522
2620
  }
2523
2621
  };
2524
2622
  }
@@ -2705,6 +2803,7 @@ const inject = [
2705
2803
  function apply(ctx, config) {
2706
2804
  const registry = /* @__PURE__ */ new Map();
2707
2805
  const searcher = newSearcher(ctx);
2806
+ setupOpenSettings(ctx, config, () => {});
2708
2807
  ctx.on("tools/result", (exec, result) => {
2709
2808
  captureToolResult(ctx, registry, exec, result);
2710
2809
  });