@shgroup/dsh-serenity-hooks 1.104.0 → 1.105.0

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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-serenity-hooks",
3
- "version": "1.104.0",
3
+ "version": "1.105.0",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——13 个工具(container_fs/cognitive_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/IM 桥/认知轨迹唤醒注册表。轨迹声明 = 轨迹目录下的 trajectory.json(约束面 + 旧标识 uid + CRO 机器绑定 cro.host;旧名 trajectory-constraint.json / skiff.json 仍在读取族里);轨迹提示词 = 轨迹目录下的 PROMPT.md(一条轨迹「是谁、按什么章程工作」,所有轨迹通用,追加在容器层与质量层之后,不替换它们)。适配 DSH 0.1.7-rc.1 / 0.2.0-rc.1 / 0.2.1-rc.1(三档,deepseek-ai/deepseek-harness)。",
6
6
  "engines": {
@@ -73,6 +73,18 @@ function hostSettings(ctx) {
73
73
  function hostWeb(ctx) {
74
74
  return hostInjected(ctx, "web");
75
75
  }
76
+ /**
77
+ * 宿主默认模型选择(**没显式指定模型时**该用的那个)。
78
+ *
79
+ * 🔴 为什么需要这个读取器(v1.105.0,P0 回归修复):
80
+ * `agents.create` **不传** `agentOptions` ⇒ `agent.options.model === undefined`
81
+ * ⇒ 宿主的 persona 模板 `powered by the {{model}} model` **严格插值抛错** ⇒ 整轮失败。
82
+ * ⇒ 「不传」不等于「安全」:**下游有依赖方要求这个值必须存在**。
83
+ * 详见 `trajectory/session.ts` 的 `resolveAgentModel`。
84
+ */
85
+ function hostAgentDefaultModel(ctx) {
86
+ return hostInjected(ctx, "agentDefaultModel");
87
+ }
76
88
  //#endregion
77
89
  //#region src/kernel/ccc-roots.ts
78
90
  /**
@@ -239,4 +251,4 @@ async function listCccs(ctx, opts = {}) {
239
251
  }));
240
252
  }
241
253
  //#endregion
242
- export { ccc_roots_exports as a, hostInjected as c, hostSettings as d, hostWeb as f, cccRootForExec as i, hostService as l, agentCwdFor as n, listCccs as o, hostWebServer as p, cccRootForCwd as r, hostAgents as s, NO_CCC_FROM_AGENT_CWD as t, hostSessions as u };
254
+ export { ccc_roots_exports as a, hostAgents as c, hostSessions as d, hostSettings as f, cccRootForExec as i, hostInjected as l, hostWebServer as m, agentCwdFor as n, listCccs as o, hostWeb as p, cccRootForCwd as r, hostAgentDefaultModel as s, NO_CCC_FROM_AGENT_CWD as t, hostService as u };
@@ -1,4 +1,4 @@
1
- import { d as hostSettings } from "./ccc-roots-BIdg0EyM.js";
1
+ import { f as hostSettings } from "./ccc-roots-BPicjCsj.js";
2
2
  import { c as readWeixinSettings, o as readImSettings } from "./route-CmEoKp9w.js";
3
3
  import { isAbsolute, join, relative, resolve } from "node:path";
4
4
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
@@ -96,6 +96,36 @@ export declare function hostWeb(ctx: unknown): HostWeb | undefined;
96
96
  * (0.2.1-rc.1 起 `start` 消失、改由 `startActivation` 承担)。将来若再有委派需求,
97
97
  * 这份对照仍是唯一说明书 ⇒ **知识移到 `host/contract.ts` 的契约条目里,代码不留。**
98
98
  */
99
+ /**
100
+ * `ctx.agentDefaultModel`(**刻意不进 `inject`**,v1.105.0)。
101
+ *
102
+ * 契约原文(`dsh-agent-default-model/lib/types/index.d.ts` 逐字):
103
+ * *"Default model selection for Agents created **without an explicit model**."*
104
+ * ⇒ **这正是「没指定时该用什么」的权威出处**,不该由我们另造一份真相源。
105
+ *
106
+ * 为什么不进 `inject`:它是**可选**服务 —— 进了 inject 就把"可选"变"必需",
107
+ * 服务缺失会让整个 fiber 挂起(同 ACP 面 `resolveAcpSelection` 的既有裁决)。
108
+ * 本仓先例:`host/access.ts` 的教训 —— cordis 对未声明 inject 的服务名
109
+ * **直接属性读会抛错**,故必须走 `hostInjected`(先属性读、抛错回落 `ctx.get`)。
110
+ */
111
+ interface HostAgentDefaultModel {
112
+ /** 返回 `{ provider, model, reasoningEffort? }`(detached) */
113
+ currentSelection?: () => {
114
+ provider?: string;
115
+ model?: string;
116
+ reasoningEffort?: string;
117
+ } | undefined;
118
+ }
119
+ /**
120
+ * 宿主默认模型选择(**没显式指定模型时**该用的那个)。
121
+ *
122
+ * 🔴 为什么需要这个读取器(v1.105.0,P0 回归修复):
123
+ * `agents.create` **不传** `agentOptions` ⇒ `agent.options.model === undefined`
124
+ * ⇒ 宿主的 persona 模板 `powered by the {{model}} model` **严格插值抛错** ⇒ 整轮失败。
125
+ * ⇒ 「不传」不等于「安全」:**下游有依赖方要求这个值必须存在**。
126
+ * 详见 `trajectory/session.ts` 的 `resolveAgentModel`。
127
+ */
128
+ export declare function hostAgentDefaultModel(ctx: unknown): HostAgentDefaultModel | undefined;
99
129
  /**
100
130
  * 会话 cwd 列表(live 会话;形状不符时返回空数组而非抛错)
101
131
  */
package/lib/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { i as __toESM, n as __exportAll } from "./rolldown-runtime-B4iAMlE-.js";
2
- import { c as hostInjected, d as hostSettings, f as hostWeb, i as cccRootForExec, l as hostService, n as agentCwdFor, o as listCccs, p as hostWebServer, r as cccRootForCwd, s as hostAgents, t as NO_CCC_FROM_AGENT_CWD, u as hostSessions } from "./ccc-roots-BIdg0EyM.js";
2
+ import { c as hostAgents, d as hostSessions, f as hostSettings, i as cccRootForExec, l as hostInjected, m as hostWebServer, n as agentCwdFor, o as listCccs, p as hostWeb, r as cccRootForCwd, t as NO_CCC_FROM_AGENT_CWD, u as hostService } from "./ccc-roots-BPicjCsj.js";
3
3
  import { a as findSerenityRoot$1, c as matchBlacklist, d as readCccName$1, g as resolveInside, i as findGitRoot, l as pathInside, m as readSafeModeHiddenTools, n as SAFE_MODE_MARKER, o as isSafeModeOn, p as readExclusiveTools, r as classifyPath, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS, u as readBlacklist } from "./ccc-B-h_A7uc.js";
4
4
  import { A as namingTitleFor, B as summarize, C as createSession, E as getActiveSessionInfo, F as resolveSessionByTitle, G as readTrajectoryFile, H as useSession, I as sessionEvents, J as localHuman, K as isoLocal, L as sessionsRoot, M as parseTrajectoryCode, O as listActiveTrajectories, P as readTrajectoryUid, R as setActiveSessionInfo, S as clearActiveSessionInfo, T as findSession, U as TRAJECTORY_FILENAME, V as trajectoryDescOf, W as TRAJECTORY_LEGACY_FILENAMES, Y as localIdStamp, b as UID_FILENAME, c as replacesDefaultIdentity, i as listTrajectoryConstraints, j as parseSessionContextFromEvents, k as listSessions, l as trajectoryCodeForSession, n as findDirNameByCode, o as readTrajectoryConstraintAt, q as localFileStamp, r as isTrajectoryConstrained, s as readTrajectoryConstraintByCode, t as TRAJECTORY_CONSTRAINT_FILENAME, u as trajectoryConstraintForSession, v as COGNITIVE_TRAJECTORY_ACTIONS, w as extractSessionMdPathFromText, x as archiveSession, z as showSession } from "./profile-Dpg3wYO5.js";
5
5
  import { n as checkLocalstoreGitCompliance, o as readStore, s as runLocalStore, t as LOCALSTORE_SCOPES } from "./service-Cndtf7q4.js";
6
- import { _ as resolveConstraintSystemPrompt, a as listBoundSessionIds, d as constraintCognitiveTrajectory, f as constraintSystemPromptSource, g as profileWriteWhitelist, h as profileToolWhitelist, i as carrierState, l as TRAJECTORY_CONSTRAINT_HINT, n as PLUGIN_SOURCE, o as readLastBound, r as appendBound, s as resolveSessionCognitiveTrajectoryLabel, t as ACC_MESSAGE_KIND, v as ACC_VERSION, y as findPackageRoot } from "./message-source-CKJPJCzc.js";
7
- import { A as truncateContent, C as verifyTotpCode, D as buildResourceIndex, E as SKILL_ONTOLOGY_FILE, M as hasTrajectoryPrompt, O as buildResourceNameSuffix, S as MECHANISM_PORTS, T as REFERENCE_DIR, _ as projectKnownWorkspaces, a as trajectoryConstraintFor, b as verifyPassword, c as trajectoryWorkspaceMdPath, d as splitModel, f as registerCognitiveTrajectorySkillSection, g as migrateLegacyLocalstore, h as applyWirePatch, i as getTrajectoryAgent, j as TRAJECTORY_PROMPT_FILENAME, k as isSafeSkillName, l as unregisterTrajectorySession, m as registerEntrySkillSectionGlobal, n as deliverToTrajectory, o as trajectoryConstraintMsmGate, p as registerEntrySkillSection, r as ensureWorkspacePromptSection, s as trajectoryConstraintParticipates, t as createTrajectoryAgent, u as workspaceCognitiveTrajectoryLine, v as readAdvancedSettings, w as recordToolUsage, x as FACE_PORTS, y as toWire } from "./session-CaNqSHVB.js";
6
+ import { _ as resolveConstraintSystemPrompt, a as listBoundSessionIds, d as constraintCognitiveTrajectory, f as constraintSystemPromptSource, g as profileWriteWhitelist, h as profileToolWhitelist, i as carrierState, l as TRAJECTORY_CONSTRAINT_HINT, n as PLUGIN_SOURCE, o as readLastBound, r as appendBound, s as resolveSessionCognitiveTrajectoryLabel, t as ACC_MESSAGE_KIND, v as ACC_VERSION, y as findPackageRoot } from "./message-source-DoVtXnoe.js";
7
+ import { A as truncateContent, C as verifyTotpCode, D as buildResourceIndex, E as SKILL_ONTOLOGY_FILE, M as hasTrajectoryPrompt, O as buildResourceNameSuffix, S as MECHANISM_PORTS, T as REFERENCE_DIR, _ as projectKnownWorkspaces, a as trajectoryConstraintFor, b as verifyPassword, c as trajectoryWorkspaceMdPath, d as splitModel, f as registerCognitiveTrajectorySkillSection, g as migrateLegacyLocalstore, h as applyWirePatch, i as getTrajectoryAgent, j as TRAJECTORY_PROMPT_FILENAME, k as isSafeSkillName, l as unregisterTrajectorySession, m as registerEntrySkillSectionGlobal, n as deliverToTrajectory, o as trajectoryConstraintMsmGate, p as registerEntrySkillSection, r as ensureWorkspacePromptSection, s as trajectoryConstraintParticipates, t as createTrajectoryAgent, u as workspaceCognitiveTrajectoryLine, v as readAdvancedSettings, w as recordToolUsage, x as FACE_PORTS, y as toWire } from "./session-CYqyod3z.js";
8
8
  import { i as sessionsRootDir, n as findSessionLog, r as hasSessionLogById } from "./cleanup-CPl1SSaK.js";
9
- import { i as runImBridge, n as isImWiredTrajectory, o as readSimpleSettings, r as registerImChannel, s as registerSettingsSection, t as imChannelIds } from "./channels-BItMJUO8.js";
9
+ import { i as runImBridge, n as isImWiredTrajectory, o as readSimpleSettings, r as registerImChannel, s as registerSettingsSection, t as imChannelIds } from "./channels-bAiZlY07.js";
10
10
  import { a as readFeishuCredential, c as readWeixinSettings, d as weixinInboundDir, f as weixinSessionIdForTrajectory, i as matchWeixinRoute, n as extractWeixinText, r as hasVoiceItem, s as readWeixinCredential, t as extractWeixinMedia, u as sanitizeFileName$1 } from "./route-CmEoKp9w.js";
11
11
  import { REGISTERED_TOOLS } from "./invariant.js";
12
12
  import { c as sendTextMessage, i as getUpdates, l as sendTyping, n as downloadMedia, o as markdownToPlainText, r as getConfig, s as sendFileMessage, t as TypingStatus, u as sniffImageExt } from "./ilink-CsZ-f64q.js";
@@ -19939,7 +19939,7 @@ const MEDIA_MAX_BYTES = 20971520;
19939
19939
  */
19940
19940
  async function resolveCccRootByAlias(ctx, alias) {
19941
19941
  try {
19942
- const { listCccs } = await import("./ccc-roots-BIdg0EyM.js").then((n) => n.a);
19942
+ const { listCccs } = await import("./ccc-roots-BPicjCsj.js").then((n) => n.a);
19943
19943
  const entries = await listCccs(ctx);
19944
19944
  const byName = entries.find((e) => e.name === alias);
19945
19945
  if (byName) return byName.root;
@@ -20969,7 +20969,7 @@ function syncHumanChannel(ctx) {
20969
20969
  (async () => {
20970
20970
  try {
20971
20971
  stopMachineLoops();
20972
- const { listCccs } = await import("./ccc-roots-BIdg0EyM.js").then((n) => n.a);
20972
+ const { listCccs } = await import("./ccc-roots-BPicjCsj.js").then((n) => n.a);
20973
20973
  for (const entry of await listCccs(ctx)) syncCccBridge(ctx, entry.root);
20974
20974
  } catch {}
20975
20975
  })();
@@ -21262,7 +21262,7 @@ function matchCcc(input, candidates) {
21262
21262
  }
21263
21263
  /** 组装候选列表(`ccc-roots.listCccs` 投影 + `.serenity` 名;动态 import 保持本模块静态依赖轻量) */
21264
21264
  async function collectCandidates(ctx) {
21265
- const { listCccs } = await import("./ccc-roots-BIdg0EyM.js").then((n) => n.a);
21265
+ const { listCccs } = await import("./ccc-roots-BPicjCsj.js").then((n) => n.a);
21266
21266
  const entries = await listCccs(ctx, { defaultRoot: process.cwd() });
21267
21267
  const seen = /* @__PURE__ */ new Set();
21268
21268
  const out = [];
@@ -1,4 +1,4 @@
1
- import { r as cccRootForCwd } from "./ccc-roots-BIdg0EyM.js";
1
+ import { r as cccRootForCwd } from "./ccc-roots-BPicjCsj.js";
2
2
  import { g as resolveInside, h as readUtf8 } from "./ccc-B-h_A7uc.js";
3
3
  import { D as getLastActiveSessionInfo, E as getActiveSessionInfo, I as sessionEvents, L as sessionsRoot, M as parseTrajectoryCode, _ as readBindDeclaration, g as listBindDeclarations, h as isBindUsable, m as claimBinding } from "./profile-Dpg3wYO5.js";
4
4
  import { dirname, join } from "node:path";
@@ -1,8 +1,8 @@
1
- import { n as agentCwdFor, r as cccRootForCwd, s as hostAgents } from "./ccc-roots-BIdg0EyM.js";
1
+ import { c as hostAgents, n as agentCwdFor, r as cccRootForCwd, s as hostAgentDefaultModel } from "./ccc-roots-BPicjCsj.js";
2
2
  import { f as readCognitiveTrajectorySkills, h as readUtf8, o as isSafeModeOn, u as readBlacklist } from "./ccc-B-h_A7uc.js";
3
3
  import { K as isoLocal, L as sessionsRoot, N as readActiveSessionMd, d as registerTrajectorySession$1, f as trajectoryDirNameForSession, o as readTrajectoryConstraintAt, p as unregisterTrajectorySession$1, u as trajectoryConstraintForSession, y as DEFAULT_SESSION_SCOPE } from "./profile-Dpg3wYO5.js";
4
4
  import { a as readGitTrack, i as localstorePath } from "./service-Cndtf7q4.js";
5
- import { d as constraintCognitiveTrajectory, m as profileMsmWhitelist, n as PLUGIN_SOURCE, o as readLastBound, p as createProfilePromptReader, u as buildTrajectoryBasePrompt, v as ACC_VERSION } from "./message-source-CKJPJCzc.js";
5
+ import { d as constraintCognitiveTrajectory, m as profileMsmWhitelist, n as PLUGIN_SOURCE, o as readLastBound, p as createProfilePromptReader, u as buildTrajectoryBasePrompt, v as ACC_VERSION } from "./message-source-DoVtXnoe.js";
6
6
  import { basename, dirname, join, resolve } from "node:path";
7
7
  import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from "node:fs";
8
8
  import { createUserMessage } from "@deepseek-ai/dsh-llm";
@@ -2228,6 +2228,52 @@ function ensureWorkspacePromptSection(agent, scope, root) {
2228
2228
  /** 轨迹约束 agent 挂载的 DSH preset(平台工具面由 preset 决定;白名单再按轨迹过滤) */
2229
2229
  const TRAJECTORY_PRESET = "standard";
2230
2230
  /**
2231
+ * 解析「这条轨迹的载体该用哪个模型」—— **不能只返回 `''`**(v1.105.0,P0 回归修复)。
2232
+ *
2233
+ * ## 上一版错在哪(v1.102.0 → v1.104.0 之间的真实故障)
2234
+ *
2235
+ * v1.102.0 我删掉了「未声明 model ⇒ 回落到全局默认模型」这条回落,理由是它会让轨迹
2236
+ * **静默跑在别人的模型上**(真机实证:两条 IM 路由都没声明 model,却跑在 minimax 上)。
2237
+ * 修法写成「没声明 ⇒ 不传 `agentOptions` ⇒ 交给宿主」。
2238
+ *
2239
+ * 🔴 **「不传」不等于「安全」** —— 这是当时的判断错误:
2240
+ * 宿主 `system-prompt` 的 persona 模板是 `You are a coding agent powered by the {{model}} model.`
2241
+ * (`dsh-web-app/cordis.patch.yml` 逐字),而 `{{model}}` 是 **`agent.options.model`**
2242
+ * (`dsh-agent-loop/lib/index.js:1592`);
2243
+ * **插值是严格的** —— `dsh-system-prompt/lib/index.js:177`:
2244
+ * `if (value === void 0) throw new Error('prompt variable "{{model}}" has no value for this assembly')`
2245
+ * ⇒ `agent.options.model === undefined` ⇒ **每一轮装配都抛错 ⇒ 该轨迹完全不可用**。
2246
+ *
2247
+ * 我当时只验了"`agents.create` 不传 `agentOptions` 是合法的",
2248
+ * **没验下游有没有人要求这个值必须存在**(D256 同族:删之前先核谁在依赖)。
2249
+ *
2250
+ * ## 正确修法 = 回落到**宿主权威的默认值**,而不是回落到我们自己的某个配置
2251
+ *
2252
+ * 宿主契约逐字(`dsh-agent-default-model/lib/types/index.d.ts`):
2253
+ * *"Default model selection for Agents created **without an explicit model**."*
2254
+ * ⇒ 这正是「没指定时该用什么」的**权威出处** —— 拿它显式传下去,不是另造一份真相源
2255
+ * (这与 v1.58.1 修 ACP 面同一个报错时的做法一致:`resolveAcpSelection()`)。
2256
+ *
2257
+ * 与旧回落的关键区别(这是本次判断成立的依据):
2258
+ * · 旧回落读的是 **CCC 里某个工具段的配置**(`cheap-worker.defaultModel`)—— 那是**我们的**猜测,
2259
+ * 而且读的是**已退役**的段;
2260
+ * · 新回落读的是 **宿主自己承认的默认** —— 用户在界面换模型它跟着变,**不是第二个真相源**。
2261
+ *
2262
+ * @returns `provider/model` 串;拿不到宿主默认时返回 `''`(此时仍不传 agentOptions —— 那种宿主
2263
+ * 自己也没有默认模型,结果是宿主自己的问题,不该由我们编一个值出来)。
2264
+ */
2265
+ function resolveAgentModel(ctx, profile) {
2266
+ const declared = profile.model?.trim();
2267
+ if (declared) return declared;
2268
+ try {
2269
+ const sel = hostAgentDefaultModel(ctx)?.currentSelection?.();
2270
+ const provider = typeof sel?.provider === "string" ? sel.provider.trim() : "";
2271
+ const model = typeof sel?.model === "string" ? sel.model.trim() : "";
2272
+ if (provider && model) return `${provider}/${model}`;
2273
+ } catch {}
2274
+ return "";
2275
+ }
2276
+ /**
2231
2277
  * 创建(或复用)一个 轨迹约束会话。
2232
2278
  *
2233
2279
  * **固定 sessionId 的 resume-or-create**(v1.27.2):指定 sessionId 且磁盘已有持久化 log →
@@ -2239,7 +2285,7 @@ const TRAJECTORY_PRESET = "standard";
2239
2285
  */
2240
2286
  async function createTrajectoryAgent(ctx, root, profile, sessionId) {
2241
2287
  if (!ctx.agents) throw new Error("trajectory constraint: ctx.agents unavailable");
2242
- const model = profile.model?.trim() ?? "";
2288
+ const model = resolveAgentModel(ctx, profile);
2243
2289
  const id = sessionId ?? `轨迹约束-${profile.code}-${randomUUID()}`;
2244
2290
  const setup = async (agentCtx) => {
2245
2291
  try {
@@ -2248,6 +2294,7 @@ async function createTrajectoryAgent(ctx, root, profile, sessionId) {
2248
2294
  };
2249
2295
  const handle = await createOrResumeAgent(ctx, id, root, model, setup, sessionId !== void 0);
2250
2296
  const agent = handle.agent;
2297
+ if (model === "") console.warn(`[serenity-hooks] ✗ 轨迹「${profile.code}」的载体没有可用模型:trajectory.json 未声明 model,宿主 agentDefaultModel 也取不到选择(服务缺失或 currentSelection() 返回空)⇒ 该轨迹每一轮都会以 prompt variable "{{model}}" has no value 失败。 修法:在 trajectory.json 里给这条轨迹写一个 model(provider/model),或修好宿主 agent-default-model 那一行的配置。`);
2251
2298
  let readerPath = profile.systemPromptFile?.trim();
2252
2299
  let reader = createProfilePromptReader(root, profile);
2253
2300
  const livePrompt = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.104.0",
3
+ "version": "1.105.0",
4
4
  "description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:13 个工具(container_fs/cognitive_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/IM 桥/认知轨迹唤醒注册表。轨迹声明 = 轨迹目录下的 trajectory.json(约束面 + 旧标识 uid + CRO 机器绑定 cro.host;旧名 trajectory-constraint.json / skiff.json 仍在读取族里);轨迹提示词 = 轨迹目录下的 PROMPT.md(一条轨迹「是谁、按什么章程工作」,所有轨迹通用,追加在容器层与质量层之后,不替换它们)。适配 DSH 0.1.7-rc.1 / 0.2.0-rc.1 / 0.2.1-rc.1(三档)。",
5
5
  "license": "MIT",
6
6
  "repository": {