dsh-plugin-tool-management 0.16.5 → 0.16.6
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/CHANGELOG.md +18 -0
- package/docs/update.md +10 -0
- package/lib/skills/core.js +132 -39
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,24 @@
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## [0.16.6] - 2026-09-30
|
|
14
|
+
|
|
15
|
+
官方内置技能管理补全 web 侧:web 宿主照注的沙盒诊断技能接入技能页(可见、可停),Office 三件套按裁定在 web 上一并暴露;并补齐接管后缺失的 LibreOffice Kit 路径段。
|
|
16
|
+
|
|
17
|
+
### 修复
|
|
18
|
+
|
|
19
|
+
- **web 宿主注入的沙盒诊断技能现在看得见、关得掉了**(0.16.5 的误判):0.16.5 按「web 不注入官方技能」把 web 整个挡在官方内置管理之外,但官方宿主的沙盒技能门控是 `process.platform === "win32"`(`dsh-sandbox-local` 源码核对)——只看操作系统,web 照样向每个会话注入 diagnose-windows-sandbox-acl,于是 web 上「页面不显示、会话照注入」。现在 web 也物化官方技能并以 rank 599 接管:来源出现在技能页,停用即不注入。
|
|
20
|
+
- **接管后缺「Installed LibreOffice Kit」段**(0.16.5 桌面上已存在):官方 provider 在返回 office 技能正文时追加一段 LibreOffice Kit 的 node/cli 绝对路径,SKILL.md 明文要求使用这段路径、且禁止自行搜索;以 rank 599 接管后官方 provider 不再被问到,这段就丢了 —— office 技能里的 LibreOffice 渲染/转换命令实际没有可用路径。现在由插件按官方 `officeRuntime()` 契约逐字复刻补上:桌面 node 取宿主自带的独立 node(`<resources>/runtime/primary-runtime/dependencies/node/bin/`,官方明令 packaged 应用必须独立 node,electron 本体不行;`DSH_PRIMARY_RUNTIME` / `DSH_BUNDLED_PRIMARY_RUNTIME` 环境变量优先,SDK 部署照官方取值),cli 取 `app.asar.unpacked` 里的真实文件(独立 node 读不了 asar 内部);web node 即宿主 node 进程(官方默认 `process.execPath`),cli 走宿主进程解析链。任一路径不是真实文件时改用官方口径的「LibreOffice Kit is disabled in this deployment」降级文案 —— 绝不给跑不起来的路径。
|
|
21
|
+
|
|
22
|
+
### 变更
|
|
23
|
+
|
|
24
|
+
- **官方内置技能按宿主形态各物化一份**:物化目录从各宿主共用 `$DSH_HOME/tool-management/official-skills/` 改为 `official-skills/<desktop|web>/` 各写各的 —— 0.16.5 靠「web 完全不参与」压住竞态(web 重建会把桌面物化好的 4 个清成它解析到的 1 个,实测),分形态目录让 web 也能参与管理而不互踩;0.16.5 共享布局的顶层残留按已知名单自动清理。启停状态按技能名记在来源 `official` 下,两种形态共用一份。
|
|
25
|
+
- **web 技能页也暴露 Office 三件套**(用户裁定):web 宿主不装配 office 插件、不注入,但 npm 包自带完整 assets —— web 上从宿主进程解析链物化后照常列出、可启停(启用后随技能目录注入会话)。
|
|
26
|
+
|
|
27
|
+
### 说明
|
|
28
|
+
|
|
29
|
+
- **实测**:官方源码逐处核对(沙盒技能门控 `dsh-sandbox-local` 只看 win32;office 插件仅桌面装配;`officeRuntime()` 契约与桌面装配的 node/cli 落点),本机桌面安装核实独立 node 与 unpacked cli 真实存在。合成夹具四模式全过:web(4 个技能物化,Kit 段 node=宿主进程、cli=解析链包内 cli)、web 无 libreoffice-kit(官方降级文案)、桌面(Kit 段 node=primary-runtime 独立 node、cli=app.asar.unpacked 真实文件)、桌面目录布局不同(office/沙盒全走解析链兜底物化,Kit 降级文案,正文不含指向不存在布局的路径)。
|
|
30
|
+
|
|
13
31
|
## [0.16.5] - 2026-09-30
|
|
14
32
|
|
|
15
33
|
issue #1 收尾与桌面版第二轮适配:兼容页身份比对改为逐包解析、逐包核对(桌面版不再误报「两份不同拷贝」),「全部可用」与「N 项不可用」不再同屏;桌面版注入会话的 4 个官方内置技能接入技能页管理。
|
package/docs/update.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
| 版本 | 发布 | 主题 |
|
|
6
6
|
| ---------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| [0.16.6](#0166---2026-09-30) | 2026-09-30 | 官方内置技能补全 web 侧:web 照注的沙盒诊断技能可见可停 + Office 三件套 web 也暴露 + 补上接管后缺失的 LibreOffice Kit 路径段(0.16.5 桌面已缺) |
|
|
7
8
|
| [0.16.5](#0165---2026-09-30) | 2026-09-30 | 桌面版误报 5 条「两份拷贝」修掉(身份逐包核对)+ 「全部可用」与红卡不再同屏 + 官方内置技能接入管理(桌面版注入的 4 个可启停;web 不出现) |
|
|
8
9
|
| [0.16.0](#0160---2026-09-29) | 2026-09-29 | 桌面版宿主身份误判修好(归档宿主按版本核对,带空格路径的宿主版本不再显示 unknown)+ 兼容页三张指标卡各删一行、适配版本改标 0.2.0-rc.2 + 四个域的行状态统一成名字后面的胶囊(已启用 / 未启用,停用类改灰)+ MCP 体检点挪到名字前 + 体检补端点探测 + 删除同步清引用 + 轮询不空转 + 子智能体补上「已启用」 |
|
|
9
10
|
| [0.15.0](#0150---2026-09-28) | 2026-09-28 | 适配 DSH 0.1.7-rc.2:修好 MCP 列表与注入 + 预设边界与极简兜底注入 + 会话标题 + 设置令牌 + host-deps / doctor;新增 MCP 导入导出、配置体检、最近改动流水、场景绑工具表方案、整机迁移快照;功能总览英文补齐、兼容页收弹窗与界面打磨 |
|
|
@@ -25,6 +26,15 @@
|
|
|
25
26
|
|
|
26
27
|
---
|
|
27
28
|
|
|
29
|
+
## 0.16.6 - 2026-09-30
|
|
30
|
+
|
|
31
|
+
- **web 上注入的沙盒诊断技能看得见、关得掉了**:官方宿主的沙盒技能门控只看 Windows(web 照样向每个会话注入),0.16.5 却把 web 挡在官方内置管理之外——页面不显示、会话照注入。现在 web 也物化官方技能、以更高优先级接管,停用即不注入。
|
|
32
|
+
- **web 技能页也列出 Office 三件套**:web 宿主不装配 office 插件(不注入),但包里自带完整资源——按裁定照常暴露,可启停(启用后会进会话技能目录)。
|
|
33
|
+
- **补上接管后缺失的 LibreOffice Kit 路径段**:官方 provider 返回 office 技能正文时会追加一段 LibreOffice 的 node/cli 绝对路径(SKILL.md 明文要用、禁止自己找),接管后这段丢了(0.16.5 桌面已缺)——渲染/转换命令实际没有可用路径。现在由插件按官方契约补上:桌面用宿主自带的独立 node + asar 解包出来的真实 cli,web 用宿主 node 进程 + 包内 cli;路径取不到时给官方的「已停用」文案,绝不给跑不起来的路径。
|
|
34
|
+
- **官方内置技能按宿主形态各存一份**(`official-skills/desktop/` 与 `/web/`):互不覆盖,0.16.5 共享目录的竞态由此根治;旧布局残留自动清理,启停状态两种形态通用。
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
28
38
|
## 0.16.5 - 2026-09-30
|
|
29
39
|
|
|
30
40
|
- **桌面版不再误报 5 条「两份不同拷贝」**:宿主侧身份比对把第一个包(cordis)的路径当成其余五个包的,五条全部比成「不同」。现在逐包解析、逐包核对。
|
package/lib/skills/core.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// 文件写入错误由路由返回给调用方。
|
|
14
14
|
import { homedir } from "node:os";
|
|
15
15
|
import { join, basename, dirname, resolve, isAbsolute, } from "node:path";
|
|
16
|
-
import { promises as fs, existsSync, mkdirSync, readdirSync, copyFileSync, rmSync, } from "node:fs";
|
|
16
|
+
import { promises as fs, existsSync, mkdirSync, readdirSync, copyFileSync, rmSync, statSync, } from "node:fs";
|
|
17
17
|
import { createRequire } from "node:module";
|
|
18
18
|
import { createHash, randomUUID } from "node:crypto";
|
|
19
19
|
import { unzipSync } from "fflate";
|
|
@@ -60,25 +60,27 @@ export function resolveAgentsHome() {
|
|
|
60
60
|
}
|
|
61
61
|
// ── 官方内置技能来源(随宿主注入会话上下文的内置技能)──────────────────────
|
|
62
62
|
//
|
|
63
|
-
//
|
|
64
|
-
// office-pptx / office-xlsx(dsh-skill-office
|
|
65
|
-
// `<resources>/runtime/office-skills
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
63
|
+
// 宿主按形态注入不同的官方技能(官方源码逐一核对,2026-09-30):
|
|
64
|
+
// - 桌面版 4 个:office-docx / office-pptx / office-xlsx(dsh-skill-office 只在桌面
|
|
65
|
+
// 宿主装配,assetRoot 指到 `<resources>/runtime/office-skills`)+ diagnose-windows-
|
|
66
|
+
// sandbox-acl(dsh-sandbox-local 的门控是 `process.platform === "win32"`,rank 600)。
|
|
67
|
+
// - web 版:沙盒诊断技能由宿主注入(门控只看 win32 —— 用户 2026-09-30 截图实锤,
|
|
68
|
+
// 0.16.5 按「web 不注入」的误判把 web 挡在门外,导致页面不显示、宿主照注);office
|
|
69
|
+
// 插件 web 宿主不装配、不注入,但用户裁定(2026-09-30)技能页照样把这三个暴露出来
|
|
70
|
+
// 统一管理(npm 包自带完整 assets,接管后可启停)。
|
|
71
71
|
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
72
|
+
// 它们或住在官方 asar 里、或由官方 provider 复制进临时目录自管,插件直接扫描/接管有两个
|
|
73
|
+
// 坑:宿主子进程里对 asar 的 promises 读法与拦截器解析都出现过时灵时不灵(同机两次启动
|
|
74
|
+
// 一组 4/1、一组全 0,实测);沙盒技能的脚本要交给 PowerShell 子进程,asar 路径读不了。
|
|
75
|
+
//
|
|
76
|
+
// 因此这里把来源**物化**成插件自有的一份真实目录,**每种宿主形态各一份**
|
|
77
|
+
// (`$DSH_HOME/tool-management/official-skills/<desktop|web>/`):每次宿主启动从官方源头
|
|
78
|
+
// 整目录覆盖拷贝(与官方 provider 的「私有资源副本」同一做法),扫描、启停、overlay、
|
|
79
|
+
// 脚本执行全部落在真实文件上。599 压过宿主 provider 的 600,停用即不注入。分形态是竞态
|
|
80
|
+
// 教训:0.16.5 之前共用一份目录,web 启动把它解析到的沙盒技能盖进去,桌面物化好的
|
|
81
|
+
// 4 个只剩 1 个(实测);改成各写各的子目录,互不清对方的账。共享布局的残留(旧条目
|
|
82
|
+
// 直接躺在 official-skills/ 下)按已知名单清理。
|
|
75
83
|
//
|
|
76
|
-
// 两个边界(都出过事):
|
|
77
|
-
// - 只有桌面版(有 process.resourcesPath)才允许进来。物化目录在 $DSH_HOME 下
|
|
78
|
-
// 与各宿主**共用**,而 web 宿主进程里的官方模块拦截器能把 @deepseek-ai 裸名
|
|
79
|
-
// 解析到宿主副本 —— web 若也进来重建,会把桌面物化好的整目录清成它解析到的
|
|
80
|
-
// 那几个(2026-09-30 实测:桌面物化好 4 个,web 一启动,两份 UI 同时只剩沙盒
|
|
81
|
-
// 1 个)。所以非桌面在碰目录**之前**就退出,一个技能都不列。
|
|
82
84
|
// - 预设参考技能(dsh-agent-preset/skills)不注入会话上下文,不列入(用户裁定)。
|
|
83
85
|
//
|
|
84
86
|
// 单个来源、随 DSH 技能之后排列,来源层语义同默认来源(不可移除、无来源开关)。
|
|
@@ -133,29 +135,90 @@ function resolvedPackageDir(packageName, subpath) {
|
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
137
|
/**
|
|
136
|
-
* office
|
|
137
|
-
*
|
|
138
|
-
*
|
|
138
|
+
* office 技能源头。桌面版由宿主挂载:运行时真实目录优先(官方 assetRoot),其次 asar
|
|
139
|
+
* 包内 assets。web 宿主不装配 office 插件(不注入),但 npm 包自带完整 assets —— 用户
|
|
140
|
+
* 裁定(2026-09-30)技能页照样暴露这三个技能,走宿主进程解析链取包内一份。解析不到
|
|
141
|
+
* 一律 null —— 不把拿不到真实文件的技能凭空列出来。
|
|
139
142
|
*/
|
|
140
143
|
function officialOfficeSource() {
|
|
141
144
|
const resources = resourcesDir();
|
|
142
|
-
if (resources
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
145
|
+
if (resources !== null) {
|
|
146
|
+
const runtimeDir = join(resources, "runtime", "office-skills");
|
|
147
|
+
if (existsSync(join(runtimeDir, "office-docx")))
|
|
148
|
+
return runtimeDir;
|
|
149
|
+
const asarDir = desktopPackageDir("@deepseek-ai/dsh-skill-office", "assets");
|
|
150
|
+
if (asarDir !== null && existsSync(join(asarDir, "office-docx")))
|
|
151
|
+
return asarDir;
|
|
152
|
+
}
|
|
153
|
+
return resolvedPackageDir("@deepseek-ai/dsh-skill-office", "assets");
|
|
154
|
+
}
|
|
155
|
+
/** 沙盒诊断技能源头(桌面 asar 直连优先,其次宿主进程解析链;宿主门控仅看 win32,web/桌面皆注入)。 */
|
|
153
156
|
function officialSandboxSource() {
|
|
154
157
|
if (process.platform !== "win32")
|
|
155
158
|
return null;
|
|
156
159
|
return (desktopPackageDir("@deepseek-ai/dsh-sandbox-windows-acl", "assets/diagnose-windows-sandbox-acl") ??
|
|
157
160
|
resolvedPackageDir("@deepseek-ai/dsh-sandbox-windows-acl", "assets/diagnose-windows-sandbox-acl"));
|
|
158
161
|
}
|
|
162
|
+
// ── office 技能的「Installed LibreOffice Kit」段 ────────────────────────────
|
|
163
|
+
//
|
|
164
|
+
// 官方 dsh-office provider 在 get 时给三个 office 技能的正文**追加**一段
|
|
165
|
+
// 「Installed LibreOffice Kit」:SKILL.md 明文要求「使用这段提供的 libreofficeKit.node
|
|
166
|
+
// 与 .cli 绝对路径,禁止自行搜索/猜测」。我们以 599 接管后官方 provider 不再被问到,
|
|
167
|
+
// 这段必须由我们补上 —— 否则模型拿到的 office 技能缺执行 LibreOffice 命令所需的全部
|
|
168
|
+
// 路径(这个缺口 0.16.5 在桌面上就已存在)。文案与 JSON 形状逐字取自官方
|
|
169
|
+
// dsh-skill-office lib/index.js 的 officeRuntime();node/cli 的落点按宿主形态各自核实:
|
|
170
|
+
// - 桌面:官方明确要求 packaged 应用必须给**独立 node**(electron 本体不行)。
|
|
171
|
+
// 实测桌面把运行时装在 `<resources>/runtime/primary-runtime/`(DSH_PRIMARY_RUNTIME
|
|
172
|
+
// 指向它,SDK 部署可被同名环境变量改写),node 在其 dependencies/node/bin 下;cli
|
|
173
|
+
// 必须用 `app.asar.unpacked` 里的真实文件 —— 独立 node 读不了 asar 内部。
|
|
174
|
+
// - web:官方默认 process.execPath(宿主是普通 node 进程),cli 从宿主进程解析链取。
|
|
175
|
+
// 任一路径不是真实文件 → 用官方口径的「已停用」文案(SKILL.md 自有降级分支,模型不会
|
|
176
|
+
// 去猜路径),绝不给一个跑不起来的路径。
|
|
177
|
+
const OFFICE_SKILL_NAMES = new Set([
|
|
178
|
+
"office-docx",
|
|
179
|
+
"office-pptx",
|
|
180
|
+
"office-xlsx",
|
|
181
|
+
]);
|
|
182
|
+
const OFFICE_RUNTIME_DISABLED = "\n\nLibreOffice Kit is disabled in this deployment.";
|
|
183
|
+
let officeRuntimeSectionCache;
|
|
184
|
+
/** 官方 provider 在 get 时追加的 LibreOffice Kit 段(每进程算一次,路径不随会话变)。 */
|
|
185
|
+
function officialOfficeRuntimeSection() {
|
|
186
|
+
if (officeRuntimeSectionCache === undefined)
|
|
187
|
+
officeRuntimeSectionCache = computeOfficeRuntimeSection();
|
|
188
|
+
return officeRuntimeSectionCache;
|
|
189
|
+
}
|
|
190
|
+
function computeOfficeRuntimeSection() {
|
|
191
|
+
const resources = resourcesDir();
|
|
192
|
+
let node;
|
|
193
|
+
let cli;
|
|
194
|
+
const runtimeRoot = process.env.DSH_PRIMARY_RUNTIME || process.env.DSH_BUNDLED_PRIMARY_RUNTIME;
|
|
195
|
+
if (runtimeRoot) {
|
|
196
|
+
// SDK / 容器部署:官方配置从运行时根推导(cordis 装配逐字核对)。
|
|
197
|
+
node = join(resolve(runtimeRoot), "dependencies", "node", "bin", process.platform === "win32" ? "node.exe" : "node");
|
|
198
|
+
cli = resolvedPackageDir("@deepseek-ai/libreoffice-kit", "lib/cli.js");
|
|
199
|
+
}
|
|
200
|
+
else if (resources !== null) {
|
|
201
|
+
node = join(resources, "runtime", "primary-runtime", "dependencies", "node", "bin", process.platform === "win32" ? "node.exe" : "node");
|
|
202
|
+
// 桌面的 cli 只认 unpacked 真实文件(独立 node 读不了 asar;electron 的 fs 补丁
|
|
203
|
+
// 会让 existsSync 对 asar 内部也返回真,所以这里不用解析链兜底)。
|
|
204
|
+
cli = join(resources, "app.asar.unpacked", "dsh", "node_modules", "@deepseek-ai", "libreoffice-kit", "lib", "cli.js");
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
node = process.execPath;
|
|
208
|
+
cli = resolvedPackageDir("@deepseek-ai/libreoffice-kit", "lib/cli.js");
|
|
209
|
+
}
|
|
210
|
+
const usable = (path) => {
|
|
211
|
+
try {
|
|
212
|
+
return isAbsolute(path) && statSync(path).isFile();
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
if (!usable(node) || cli === null || !usable(cli))
|
|
219
|
+
return OFFICE_RUNTIME_DISABLED;
|
|
220
|
+
return `\n\n## Installed LibreOffice Kit\n\nUse these absolute paths for every LibreOffice Kit command. Pass the CLI entry as the first argument to Node.\n\n${JSON.stringify({ libreofficeKit: { node, cli } }, null, 2)}`;
|
|
221
|
+
}
|
|
159
222
|
function copyDirectorySync(from, to) {
|
|
160
223
|
mkdirSync(to, { recursive: true });
|
|
161
224
|
for (const entry of readdirSync(from, { withFileTypes: true })) {
|
|
@@ -172,17 +235,40 @@ function copyDirectorySync(from, to) {
|
|
|
172
235
|
* 每次宿主启动整目录重建(官方包只随宿主更新变化,宿主更新必然重启宿主)。
|
|
173
236
|
*/
|
|
174
237
|
let officialRootCache;
|
|
238
|
+
/** 宿主形态子目录名:桌面(有 process.resourcesPath)与 web 等普通 node 进程各物化一份。 */
|
|
239
|
+
function officialFormName() {
|
|
240
|
+
return resourcesDir() === null ? "web" : "desktop";
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 0.16.5 之前各形态共用一份目录(旧条目直接躺在 official-skills/ 下);分形态目录后
|
|
244
|
+
* 这些残留只会变成幽灵条目,按这份已知名单清掉。只清名单内的名字,绝不碰旁边的
|
|
245
|
+
* `<form>/` 子目录 —— 那是另一种形态物化的现役目录。
|
|
246
|
+
*/
|
|
247
|
+
const LEGACY_OFFICIAL_ENTRY_NAMES = Object.freeze([
|
|
248
|
+
"office-docx",
|
|
249
|
+
"office-pptx",
|
|
250
|
+
"office-xlsx",
|
|
251
|
+
"scripts",
|
|
252
|
+
"diagnose-windows-sandbox-acl",
|
|
253
|
+
]);
|
|
254
|
+
function cleanupLegacyOfficialLayout(root) {
|
|
255
|
+
for (const name of LEGACY_OFFICIAL_ENTRY_NAMES) {
|
|
256
|
+
try {
|
|
257
|
+
rmSync(join(root, name), { recursive: true, force: true });
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
/* 残留清理失败不影响物化,下轮启动再试 */
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
175
264
|
function materializeOfficialSkills() {
|
|
176
|
-
// 非桌面宿主(web 等普通 node 进程)一个官方技能都不注入,也不许碰共享的物化
|
|
177
|
-
// 目录 —— 否则 web 启动会把它解析到的那几个盖进目录,桌面版物化好的就没了
|
|
178
|
-
// (见上方块注释)。必须在任何 fs 访问之前退出。
|
|
179
|
-
if (resourcesDir() === null)
|
|
180
|
-
return null;
|
|
181
265
|
const office = officialOfficeSource();
|
|
182
266
|
const sandbox = officialSandboxSource();
|
|
183
267
|
if (office === null && sandbox === null)
|
|
184
268
|
return null;
|
|
185
|
-
|
|
269
|
+
// 每种宿主形态只整目录重建**自己**这份(竞态教训见上方块注释);对方形态的子目录
|
|
270
|
+
// 与共享层残留清理互不干涉。
|
|
271
|
+
const root = join(resolveDshHome(), "tool-management", "official-skills", officialFormName());
|
|
186
272
|
try {
|
|
187
273
|
rmSync(root, { recursive: true, force: true });
|
|
188
274
|
// office:整个 assets 根拷进来(office-*/ 与 scripts/ 的相对结构必须保留 ——
|
|
@@ -192,6 +278,7 @@ function materializeOfficialSkills() {
|
|
|
192
278
|
if (sandbox !== null) {
|
|
193
279
|
copyDirectorySync(sandbox, join(root, basename(sandbox)));
|
|
194
280
|
}
|
|
281
|
+
cleanupLegacyOfficialLayout(dirname(root));
|
|
195
282
|
return root;
|
|
196
283
|
}
|
|
197
284
|
catch (error) {
|
|
@@ -3139,6 +3226,12 @@ export async function getProviderSkill(candidate, options = {}) {
|
|
|
3139
3226
|
const summary = entryOf(locator.entryName, entry.kind, entry.docPath, doc);
|
|
3140
3227
|
if (!summary.loadable || summary.declaredName !== candidate.name)
|
|
3141
3228
|
return undefined;
|
|
3229
|
+
// 官方 office 技能:补上官方 provider 在 get 时追加的 LibreOffice Kit 段
|
|
3230
|
+
// (SKILL.md 明文引用这段的 node/cli 路径,见上方块注释)。
|
|
3231
|
+
const officeRuntime = locator.rootKey === OFFICIAL_SOURCE_KEY &&
|
|
3232
|
+
OFFICE_SKILL_NAMES.has(locator.entryName)
|
|
3233
|
+
? officialOfficeRuntimeSection()
|
|
3234
|
+
: "";
|
|
3142
3235
|
return {
|
|
3143
3236
|
name: candidate.name,
|
|
3144
3237
|
description: candidate.description,
|
|
@@ -3148,7 +3241,7 @@ export async function getProviderSkill(candidate, options = {}) {
|
|
|
3148
3241
|
resourceBase: candidate.resourceBase,
|
|
3149
3242
|
path: candidate.path,
|
|
3150
3243
|
metadata: candidate.metadata,
|
|
3151
|
-
content: doc.body.trim(),
|
|
3244
|
+
content: doc.body.trim() + officeRuntime,
|
|
3152
3245
|
};
|
|
3153
3246
|
}
|
|
3154
3247
|
catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-tool-management",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.6",
|
|
4
4
|
"description": "DSH plugin: one settings panel for MCP servers, skills, scenes, memories, subagent personas and AGENTS.md presets — a scene switches the whole environment, and the model can drive it from chat too.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|