dsh-agent-skills 0.1.4 → 0.1.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/README.md CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  通过 [DSH 插件市场](https://github.com/dsh-market/dsh-market) 安装,或打开 DSH 的「设置 → 插件市场」,搜索 **Agent Skills**,点击安装。市场会优先使用 npm 包,安装速度快,也不需要在本机重新构建。
27
27
 
28
- 安装后继续完成下面的「开启接管 DSH 技能」步骤,再重启 DSH Web。
28
+ 安装后继续完成下面的「开启接管 DSH 技能」步骤,页面会直接提供重启按钮。
29
29
 
30
30
  ### 方式二:从 npm 安装
31
31
 
@@ -47,10 +47,12 @@ dsh plugin --profile web add github:minivv/dsh-agent-skills
47
47
 
48
48
  1. 打开 DSH 的「设置 → Agent Skills」。
49
49
  2. 点击 **开启接管 DSH 技能**。
50
- 3. 看到“已开启”提示后重启 DSH Web。
50
+ 3. 点击页面出现的 **重启 DSH**,等待服务恢复并自动刷新页面。
51
51
 
52
52
  开启后,页面会在 `standard` 与 `code` preset 中用 `dsh-agent-skills/preset` 替换原来的 `skill-filesystem` provider,让目录和技能开关真正控制 Agent 可见的技能。它不会创建第二个 `agentSkills` host 服务;卸载脚本会恢复官方 provider。
53
53
 
54
+ 需要恢复 DSH 原来的技能来源时,点击 **取消接管**,再点击 **重启 DSH**。页面刷新后,`standard` 与 `code` preset 会重新使用官方 `@deepseek-ai/dsh-skill-filesystem` provider。
55
+
54
56
  如果页面无法定位 DSH 安装位置,可以使用备用命令:
55
57
 
56
58
  ```bash
@@ -58,7 +60,7 @@ DSH_INSTALL_ROOT="$(npm root -g)/@deepseek-ai/dsh" \
58
60
  node ~/.dsh/profiles/web/node_modules/dsh-agent-skills/scripts/install-preset.mjs
59
61
  ```
60
62
 
61
- 执行后重启 DSH Web。DSH 升级可能覆盖内置 preset;如果页面重新显示“开启接管 DSH 技能”,点击一次即可恢复。
63
+ 执行后重启 DSH Web。DSH 升级可能覆盖内置 preset;如果页面重新显示“开启接管 DSH 技能”,点击一次并按页面提示重启即可恢复。
62
64
 
63
65
  ## 使用
64
66
 
@@ -97,7 +99,9 @@ description: Explain when this skill should be used.
97
99
 
98
100
  ## 卸载
99
101
 
100
- 先恢复 DSH 官方的 `skill-filesystem` provider,再卸载 npm 包:
102
+ 推荐先在「设置 Agent Skills」点击 **取消接管** **重启 DSH**,再从插件市场卸载。
103
+
104
+ 如果设置页无法打开,也可以用命令恢复 DSH 官方的 `skill-filesystem` provider,再卸载 npm 包:
101
105
 
102
106
  ```bash
103
107
  DSH_INSTALL_ROOT="$(npm root -g)/@deepseek-ai/dsh" \
package/lib/client.js CHANGED
@@ -40,10 +40,16 @@ var zh = {
40
40
  takeoverDescription: "\u5F00\u542F\u540E\uFF0C\u8FD9\u91CC\u7684\u76EE\u5F55\u548C\u6280\u80FD\u5F00\u5173\u4F1A\u771F\u6B63\u63A7\u5236 Agent \u53EF\u89C1\u7684\u6280\u80FD\u3002",
41
41
  takeoverEnabledTitle: "\u5DF2\u63A5\u7BA1 DSH \u6280\u80FD",
42
42
  takeoverEnabledDescription: "\u76EE\u5F55\u548C\u6280\u80FD\u5F00\u5173\u5DF2\u63A5\u5165 standard \u4E0E code \u9884\u8BBE\u3002",
43
- takeoverRestartDescription: "\u5DF2\u5F00\u542F\uFF0C\u8BF7\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
43
+ takeoverRestartDescription: "\u63A5\u7BA1\u5DF2\u5F00\u542F\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
44
+ takeoverDisableRestartDescription: "\u63A5\u7BA1\u5DF2\u53D6\u6D88\uFF0C\u91CD\u542F DSH \u540E\u6062\u590D\u5B98\u65B9\u6280\u80FD\u6765\u6E90\u3002",
44
45
  takeoverPartialDescription: "\u5DF2\u63A5\u5165 {configured}/{total} \u4E2A\u9884\u8BBE\uFF0C\u70B9\u51FB\u7EE7\u7EED\u5B8C\u6210\u3002",
45
46
  takeoverUnavailableDescription: "\u672A\u627E\u5230 DSH \u5B89\u88C5\u4F4D\u7F6E\uFF0C\u8BF7\u786E\u8BA4\u5F53\u524D\u9875\u9762\u7531 DSH \u542F\u52A8\u540E\u91CD\u8BD5\u3002",
46
47
  takeoverAction: "\u5F00\u542F\u63A5\u7BA1 DSH \u6280\u80FD",
48
+ takeoverDisableAction: "\u53D6\u6D88\u63A5\u7BA1",
49
+ restartDsh: "\u91CD\u542F DSH",
50
+ restartingDsh: "\u6B63\u5728\u91CD\u542F\u2026",
51
+ restartFailed: "\u91CD\u542F\u5931\u8D25\uFF1A{message}",
52
+ restartTimeout: "\u7B49\u5F85 DSH \u91CD\u542F\u8D85\u65F6\uFF0C\u8BF7\u67E5\u770B\u7EC8\u7AEF\u6216\u4E34\u65F6\u76EE\u5F55\u4E2D\u7684\u91CD\u542F\u65E5\u5FD7\u3002",
47
53
  searchPlaceholder: "\u641C\u7D22\u6280\u80FD\u540D\u79F0\u6216\u63CF\u8FF0\u2026",
48
54
  sources: "\u6765\u6E90",
49
55
  validCount: "\u4E2A\u6709\u6548",
@@ -90,10 +96,16 @@ var en = {
90
96
  takeoverDescription: "Connect these source and skill switches to the skills visible to the Agent.",
91
97
  takeoverEnabledTitle: "DSH skills are managed here",
92
98
  takeoverEnabledDescription: "Source and skill switches are connected to the standard and code presets.",
93
- takeoverRestartDescription: "Enabled. Restart DSH to apply the change.",
99
+ takeoverRestartDescription: "Takeover is enabled. Restart DSH to apply it.",
100
+ takeoverDisableRestartDescription: "Takeover is cancelled. Restart DSH to restore the official skill source.",
94
101
  takeoverPartialDescription: "Connected to {configured}/{total} presets. Continue to finish setup.",
95
102
  takeoverUnavailableDescription: "DSH could not be located. Open this page from DSH and try again.",
96
103
  takeoverAction: "Enable DSH skill takeover",
104
+ takeoverDisableAction: "Cancel takeover",
105
+ restartDsh: "Restart DSH",
106
+ restartingDsh: "Restarting\u2026",
107
+ restartFailed: "Restart failed: {message}",
108
+ restartTimeout: "DSH did not restart in time. Check the terminal or the restart logs in the temporary directory.",
97
109
  searchPlaceholder: "Search skills by name or description\u2026",
98
110
  sources: "Sources",
99
111
  validCount: "valid",
@@ -137,6 +149,26 @@ var en = {
137
149
  var import_react = require("react");
138
150
  var import_jsx_runtime = require("react/jsx-runtime");
139
151
  var clamp = (value, max) => value.length <= max ? value : value.slice(0, max - 1) + "\u2026";
152
+ var TAKEOVER_RESTART_KEY = "dsh-agent-skills:takeover-restart";
153
+ function readPendingRestart() {
154
+ try {
155
+ const raw = window.sessionStorage.getItem(TAKEOVER_RESTART_KEY);
156
+ if (raw === null) return void 0;
157
+ const parsed = JSON.parse(raw);
158
+ if (typeof parsed.boot === "string" && typeof parsed.baselineEnabled === "boolean") {
159
+ return { boot: parsed.boot, baselineEnabled: parsed.baselineEnabled };
160
+ }
161
+ } catch {
162
+ }
163
+ return void 0;
164
+ }
165
+ function writePendingRestart(pending) {
166
+ try {
167
+ if (pending === void 0) window.sessionStorage.removeItem(TAKEOVER_RESTART_KEY);
168
+ else window.sessionStorage.setItem(TAKEOVER_RESTART_KEY, JSON.stringify(pending));
169
+ } catch {
170
+ }
171
+ }
140
172
  function Switch({ checked, disabled, onChange, label }) {
141
173
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "as-switch", title: label, "aria-label": label, children: [
142
174
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked, disabled, onChange: (event) => onChange(event.target.checked) }),
@@ -180,7 +212,7 @@ function DirCard({
180
212
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-dir-actions", children: [
181
213
  dir.auto === true && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-tag as-tag-auto", children: t("autoBadge") }),
182
214
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-tag", children: dir.tag === "builtin" ? t("dirTagBuiltin") : t("dirTagUser") }),
183
- dir.kind === "custom" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "as-btn as-btn-danger", onClick: onRemove, title: t("removeDir"), children: t("removeDir") }),
215
+ dir.kind === "custom" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "as-btn as-btn-danger as-dir-remove", onClick: onRemove, title: t("removeDir"), children: t("removeDir") }),
184
216
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Switch, { checked: dir.enabled, onChange: onToggleEnabled, label: dir.enabled ? t("enabled") : t("disabled") })
185
217
  ] })
186
218
  ] }),
@@ -204,6 +236,7 @@ function AgentSkillsSection({ api, t }) {
204
236
  const [view, setView] = (0, import_react.useState)(void 0);
205
237
  const [takeover, setTakeover] = (0, import_react.useState)(void 0);
206
238
  const [takeoverRestartRequired, setTakeoverRestartRequired] = (0, import_react.useState)(false);
239
+ const [restarting, setRestarting] = (0, import_react.useState)(false);
207
240
  const [busy, setBusy] = (0, import_react.useState)(true);
208
241
  const [error51, setError] = (0, import_react.useState)("");
209
242
  const [query, setQuery] = (0, import_react.useState)("");
@@ -246,6 +279,10 @@ function AgentSkillsSection({ api, t }) {
246
279
  const result2 = await refresh();
247
280
  if (result2.ok) {
248
281
  setTakeover(result2.value);
282
+ const pending = readPendingRestart();
283
+ const stillPending = result2.value.boot !== void 0 && pending?.boot === result2.value.boot && result2.value.enabled !== pending.baselineEnabled;
284
+ setTakeoverRestartRequired(stillPending);
285
+ if (pending !== void 0 && !stillPending) writePendingRestart(void 0);
249
286
  } else {
250
287
  setError(t("errorLoad", { message: result2.error.message }));
251
288
  }
@@ -275,21 +312,81 @@ function AgentSkillsSection({ api, t }) {
275
312
  setSaving(false);
276
313
  }
277
314
  }, [t, updatePendingCount]);
278
- const enableTakeover = (0, import_react.useCallback)(async () => {
315
+ const changeTakeover = (0, import_react.useCallback)(async (enabled) => {
279
316
  setSaving(true);
280
317
  setError("");
281
318
  try {
282
- const result2 = await api.enableTakeover();
319
+ const result2 = enabled ? await api.enableTakeover() : await api.disableTakeover();
283
320
  if (result2.ok) {
321
+ const pending = readPendingRestart();
322
+ const baselineEnabled2 = result2.value.boot !== void 0 && pending?.boot === result2.value.boot ? pending.baselineEnabled : takeover?.enabled ?? !enabled;
323
+ const restartRequired = result2.value.enabled !== baselineEnabled2;
284
324
  setTakeover(result2.value);
285
- setTakeoverRestartRequired(result2.value.enabled);
325
+ setTakeoverRestartRequired(restartRequired);
326
+ writePendingRestart(restartRequired && result2.value.boot !== void 0 ? { boot: result2.value.boot, baselineEnabled: baselineEnabled2 } : void 0);
286
327
  } else {
287
328
  setError(t("errorSave", { message: result2.error.message }));
288
329
  }
289
330
  } finally {
290
331
  setSaving(false);
291
332
  }
292
- }, [api, t]);
333
+ }, [api, t, takeover?.enabled]);
334
+ const restartDsh = (0, import_react.useCallback)(async () => {
335
+ if (restarting) return;
336
+ const previousBoot = takeover?.boot;
337
+ setRestarting(true);
338
+ setError("");
339
+ const deadline = Date.now() + 6e4;
340
+ let sawOffline = false;
341
+ const retry = () => {
342
+ if (Date.now() > deadline) {
343
+ setRestarting(false);
344
+ setError(t("restartTimeout"));
345
+ return;
346
+ }
347
+ window.setTimeout(() => void poll(), 700);
348
+ };
349
+ const poll = async () => {
350
+ try {
351
+ const response = await fetch(`${window.location.origin}/?dsh-agent-skills-restart=${Date.now()}`, {
352
+ cache: "no-store"
353
+ });
354
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
355
+ } catch {
356
+ sawOffline = true;
357
+ retry();
358
+ return;
359
+ }
360
+ if (previousBoot !== void 0) {
361
+ try {
362
+ const status = await api.takeoverStatus();
363
+ if (status.ok && status.value.boot !== void 0 && status.value.boot !== previousBoot) {
364
+ window.location.reload();
365
+ return;
366
+ }
367
+ } catch {
368
+ sawOffline = true;
369
+ retry();
370
+ return;
371
+ }
372
+ }
373
+ if (sawOffline) {
374
+ window.location.reload();
375
+ return;
376
+ }
377
+ retry();
378
+ };
379
+ try {
380
+ const result2 = await api.restartDsh();
381
+ if (!result2.ok) {
382
+ setRestarting(false);
383
+ setError(t("restartFailed", { message: result2.error.message }));
384
+ return;
385
+ }
386
+ } catch {
387
+ }
388
+ retry();
389
+ }, [api, restarting, t, takeover?.boot]);
293
390
  const toggleDirExpanded = (path) => {
294
391
  setDirExpanded((prev) => {
295
392
  const next = new Set(prev);
@@ -332,26 +429,58 @@ function AgentSkillsSection({ api, t }) {
332
429
  ] });
333
430
  }
334
431
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-wrap", "data-plugin": "dsh-agent-skills", children: [
335
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "as-title", children: t("title") }),
336
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "as-subtitle", children: t("subtitle") }),
337
- takeover !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: takeover.enabled ? "as-takeover as-takeover-enabled" : "as-takeover", children: [
338
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-takeover-icon", "aria-hidden": "true", children: takeover.enabled ? "\u2713" : "\u2192" }),
339
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-takeover-copy", children: [
340
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: takeover.enabled ? t("takeoverEnabledTitle") : t("takeoverTitle") }),
341
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: takeoverRestartRequired ? t("takeoverRestartDescription") : takeover.enabled ? t("takeoverEnabledDescription") : takeover.available && takeover.configured > 0 ? t("takeoverPartialDescription", { configured: takeover.configured, total: takeover.total }) : takeover.available ? t("takeoverDescription") : t("takeoverUnavailableDescription") })
432
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-sticky-top", children: [
433
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "as-title", children: t("title") }),
434
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "as-subtitle", children: t("subtitle") }),
435
+ takeover !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: takeover.enabled ? "as-takeover as-takeover-enabled" : "as-takeover", children: [
436
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-takeover-icon", "aria-hidden": "true", children: takeover.enabled ? "\u2713" : "\u2192" }),
437
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-takeover-copy", children: [
438
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: takeover.enabled ? t("takeoverEnabledTitle") : t("takeoverTitle") }),
439
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: takeoverRestartRequired ? takeover.enabled ? t("takeoverRestartDescription") : t("takeoverDisableRestartDescription") : takeover.enabled ? t("takeoverEnabledDescription") : takeover.available && takeover.configured > 0 ? t("takeoverPartialDescription", { configured: takeover.configured, total: takeover.total }) : takeover.available ? t("takeoverDescription") : t("takeoverUnavailableDescription") })
440
+ ] }),
441
+ takeover.available && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-takeover-actions", children: [
442
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
443
+ "button",
444
+ {
445
+ type: "button",
446
+ className: takeover.enabled || takeoverRestartRequired ? "as-btn as-takeover-action" : "as-btn as-btn-primary as-takeover-action",
447
+ disabled: saving || restarting,
448
+ onClick: () => void changeTakeover(!takeover.enabled),
449
+ children: takeover.enabled ? t("takeoverDisableAction") : t("takeoverAction")
450
+ }
451
+ ),
452
+ takeoverRestartRequired && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
453
+ "button",
454
+ {
455
+ type: "button",
456
+ className: "as-btn as-btn-primary as-takeover-action",
457
+ disabled: saving || restarting,
458
+ onClick: () => void restartDsh(),
459
+ children: [
460
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: "\u21BB" }),
461
+ " ",
462
+ restarting ? t("restartingDsh") : t("restartDsh")
463
+ ]
464
+ }
465
+ )
466
+ ] })
342
467
  ] }),
343
- !takeover.enabled && takeover.available && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "as-btn as-btn-primary as-takeover-action", disabled: saving, onClick: () => void enableTakeover(), children: t("takeoverAction") })
468
+ pendingSkillCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-refresh-card", role: "status", children: [
469
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-refresh-icon", "aria-hidden": "true", children: "\u21BB" }),
470
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-refresh-message", children: t("refreshPending", { n: pendingSkillCount }) }),
471
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "as-btn as-refresh-action", onClick: () => window.location.reload(), children: t("refreshPage") })
472
+ ] }),
473
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
474
+ "input",
475
+ {
476
+ className: "as-search",
477
+ type: "search",
478
+ value: query,
479
+ onChange: (event) => setQuery(event.target.value),
480
+ placeholder: t("searchPlaceholder")
481
+ }
482
+ )
344
483
  ] }),
345
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
346
- "input",
347
- {
348
- className: "as-search",
349
- type: "search",
350
- value: query,
351
- onChange: (event) => setQuery(event.target.value),
352
- placeholder: t("searchPlaceholder")
353
- }
354
- ),
355
484
  error51 !== "" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "as-error", children: error51 }),
356
485
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-sources-row", children: [
357
486
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-sources-label", children: t("sources") }),
@@ -467,11 +596,6 @@ function AgentSkillsSection({ api, t }) {
467
596
  builtin: view.counts.builtin
468
597
  }) })
469
598
  ] }),
470
- pendingSkillCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "as-refresh-card", role: "status", children: [
471
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-refresh-icon", "aria-hidden": "true", children: "\u21BB" }),
472
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "as-refresh-message", children: t("refreshPending", { n: pendingSkillCount }) }),
473
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "as-btn as-refresh-action", onClick: () => window.location.reload(), children: t("refreshPage") })
474
- ] }),
475
599
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "as-skill-grid", children: filteredSkills.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "as-empty", children: query.trim() === "" ? t("noSkills") : t("noMatch") }) : filteredSkills.map((skill) => {
476
600
  const tagClass = skill.kind === "custom" ? "as-tag-custom" : skill.kind === "builtin" ? "as-tag-builtin" : "as-tag-global";
477
601
  const tagLabel = skill.kind === "custom" ? t("tagCustom") : skill.kind === "builtin" ? t("tagBuiltin") : t("tagGlobal");
@@ -521,6 +645,7 @@ var CSS = `
521
645
  }
522
646
 
523
647
  .as-wrap { display: flex; flex-direction: column; gap: 14px; width: 100%; max-width: 860px; }
648
+ .as-sticky-top { position: sticky; top: 0; z-index: 4; display: flex; flex-direction: column; gap: 14px; padding-bottom: 1px; background: var(--dsw-alias-bg-layer-1, Canvas); }
524
649
  .as-title { font-size: 20px; font-weight: 650; margin: 0; line-height: 1.3; }
525
650
  .as-subtitle { font-size: 13px; color: var(--as-muted); margin: 0; line-height: 1.5; }
526
651
  .as-search { width: 100%; box-sizing: border-box; padding: 8px 12px; border-radius: 8px; border: 1px solid var(--as-border); background: transparent; color: inherit; font-size: 13px; outline: none; }
@@ -533,7 +658,8 @@ var CSS = `
533
658
  .as-takeover-copy { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 2px; }
534
659
  .as-takeover-copy strong { font-size: 13px; font-weight: 600; line-height: 1.35; text-wrap: balance; }
535
660
  .as-takeover-copy span { font-size: 12px; line-height: 1.45; color: var(--as-muted); text-wrap: pretty; }
536
- .as-takeover-action { min-height: 40px; flex: none; transition-property: transform, background-color; transition-duration: 120ms; }
661
+ .as-takeover-actions { display: flex; align-items: center; gap: 7px; flex: none; }
662
+ .as-takeover-action { min-height: 32px; flex: none; transition-property: transform, background-color; transition-duration: 120ms; }
537
663
  .as-takeover-action:active:not(:disabled) { transform: scale(0.96); }
538
664
 
539
665
  .as-sources-row { display: flex; align-items: baseline; gap: 10px; }
@@ -564,6 +690,8 @@ var CSS = `
564
690
  .as-dir-path { font-size: 13px; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-break: break-all; }
565
691
  .as-dir-meta { font-size: 11px; color: var(--as-muted); }
566
692
  .as-dir-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
693
+ .as-dir-remove { position: relative; min-height: 24px; padding: 2px 8px; border-radius: 6px; font-size: 11px; line-height: 1.2; }
694
+ .as-dir-remove::after { content: ""; position: absolute; inset: -7px -4px; }
567
695
  .as-tag { font-size: 11px; padding: 1px 7px; border-radius: 999px; border: 1px solid var(--as-border); color: var(--as-muted); white-space: nowrap; }
568
696
  .as-tag-custom { color: #58a6ff; border-color: rgba(88, 166, 255, 0.4); }
569
697
  .as-tag-global { color: #d29922; border-color: rgba(210, 153, 34, 0.4); }
@@ -582,10 +710,10 @@ var CSS = `
582
710
  .as-skills-header { display: flex; align-items: baseline; gap: 7px; font-size: 13px; font-weight: 550; margin: 4px 0 0; text-wrap: balance; }
583
711
  .as-skills-header-title { color: var(--as-text); }
584
712
  .as-skills-header-stats { font-size: 11px; font-weight: 450; color: var(--as-muted-2); font-variant-numeric: tabular-nums; }
585
- .as-refresh-card { display: flex; align-items: center; gap: 9px; min-height: 48px; padding: 4px 5px 4px 11px; border: 1px solid rgba(210, 153, 34, 0.28); border-radius: var(--as-radius); background: var(--as-warning-soft); box-sizing: border-box; }
586
- .as-refresh-icon { flex: none; color: var(--as-warning); font-size: 17px; line-height: 1; }
587
- .as-refresh-message { flex: 1; min-width: 0; color: var(--as-text); font-size: 12px; line-height: 1.45; font-variant-numeric: tabular-nums; text-wrap: pretty; }
588
- .as-refresh-action { min-height: 40px; flex: none; border-color: rgba(210, 153, 34, 0.42); background: rgba(210, 153, 34, 0.08); transition-property: transform, background-color; transition-duration: 120ms; }
713
+ .as-refresh-card { display: flex; align-items: center; gap: 8px; min-height: 36px; padding: 3px 4px 3px 9px; border: 1px solid rgba(210, 153, 34, 0.28); border-radius: var(--as-radius); background: var(--as-warning-soft); box-sizing: border-box; }
714
+ .as-refresh-icon { flex: none; color: var(--as-warning); font-size: 15px; line-height: 1; }
715
+ .as-refresh-message { flex: 1; min-width: 0; color: var(--as-text); font-size: 12px; line-height: 1.3; font-variant-numeric: tabular-nums; }
716
+ .as-refresh-action { min-height: 28px; padding-block: 3px; flex: none; border-color: rgba(210, 153, 34, 0.42); background: rgba(210, 153, 34, 0.08); transition-property: transform, background-color; transition-duration: 120ms; }
589
717
  .as-refresh-action:hover { background: rgba(210, 153, 34, 0.14); }
590
718
  .as-refresh-action:active { transform: scale(0.96); }
591
719
  .as-skill-grid { display: flex; flex-direction: column; gap: 8px; }
@@ -638,14 +766,12 @@ var CSS = `
638
766
  flex: 1;
639
767
  }
640
768
  .as-takeover { align-items: flex-start; flex-wrap: wrap; }
641
- .as-takeover-action { width: 100%; }
769
+ .as-takeover-actions { width: 100%; justify-content: flex-end; flex-wrap: wrap; }
642
770
  .as-actions-row { flex-wrap: wrap; }
643
771
  .as-dir-row { align-items: flex-start; flex-wrap: wrap; }
644
772
  .as-dir-path { flex: 1; min-width: 120px; }
645
773
  .as-skill-row { align-items: flex-start; flex-wrap: wrap; }
646
- .as-refresh-card { flex-wrap: wrap; padding: 8px 9px; }
647
- .as-refresh-message { min-width: calc(100% - 34px); }
648
- .as-refresh-action { width: 100%; }
774
+ .as-refresh-card { padding: 3px 4px 3px 8px; }
649
775
  }
650
776
  `;
651
777
  var installed;
@@ -15242,7 +15368,12 @@ var presetTakeoverStatusSchema = external_exports.object({
15242
15368
  /** Number of preset files that already contain the managed row. */
15243
15369
  configured: external_exports.number().int().min(0),
15244
15370
  /** Number of supported preset files found in this DSH installation. */
15245
- total: external_exports.number().int().min(0)
15371
+ total: external_exports.number().int().min(0),
15372
+ /** Identifies the running DSH process; changes after a successful restart. */
15373
+ boot: external_exports.string().optional()
15374
+ });
15375
+ var restartResultSchema = external_exports.object({
15376
+ scheduled: external_exports.literal(true)
15246
15377
  });
15247
15378
  var toggleSkillInputSchema = external_exports.object({
15248
15379
  name: external_exports.string(),
@@ -15298,6 +15429,24 @@ var TYPERT_REMOTE = {
15298
15429
  parameters: [],
15299
15430
  result: result("PresetTakeoverStatus", presetTakeoverStatusSchema)
15300
15431
  },
15432
+ {
15433
+ id: `${PKG}#agentSkills/disableTakeover`,
15434
+ service: "agentSkills",
15435
+ namespace: "agentSkills",
15436
+ method: "disableTakeover",
15437
+ invocation: direct,
15438
+ parameters: [],
15439
+ result: result("PresetTakeoverStatus", presetTakeoverStatusSchema)
15440
+ },
15441
+ {
15442
+ id: `${PKG}#agentSkills/restartDsh`,
15443
+ service: "agentSkills",
15444
+ namespace: "agentSkills",
15445
+ method: "restartDsh",
15446
+ invocation: direct,
15447
+ parameters: [],
15448
+ result: result("RestartResult", restartResultSchema)
15449
+ },
15301
15450
  {
15302
15451
  id: `${PKG}#agentSkills/toggleSkill`,
15303
15452
  service: "agentSkills",