dsh-skill-importer 0.2.5 → 0.2.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
@@ -11,7 +11,7 @@
11
11
 
12
12
  [![npm](https://img.shields.io/npm/v/dsh-skill-importer?style=flat-square&color=5dd8bd&label=npm)](https://www.npmjs.com/package/dsh-skill-importer)
13
13
  [![downloads](https://img.shields.io/npm/dm/dsh-skill-importer?style=flat-square&color=6da8ff)](https://www.npmjs.com/package/dsh-skill-importer)
14
- [![DeepSeek Harness](https://img.shields.io/badge/DeepSeek_Harness-%E2%89%A50.1.0--rc.6-5965f2?style=flat-square)](https://github.com/deepseek-ai/deepseek-harness)
14
+ [![DeepSeek Harness](https://img.shields.io/badge/DeepSeek_Harness-%E2%89%A50.2.0--rc.2-5965f2?style=flat-square)](https://github.com/deepseek-ai/deepseek-harness)
15
15
  [![license](https://img.shields.io/badge/license-MIT-a786ff?style=flat-square)](LICENSE)
16
16
 
17
17
  <br />
@@ -118,7 +118,7 @@ Replace both `X.Y.Z` placeholders with the same target version. This opts that v
118
118
 
119
119
  Open **Settings → Skills**. Import a Markdown file or URL, or choose **Batch import** to migrate another agent's complete skills directory. Choose a target and the imported skills will appear as soon as the filesystem watcher discovers them.
120
120
 
121
- > Requires DeepSeek Harness `>= 0.1.0-rc.6`.
121
+ > Requires DeepSeek Harness `>= 0.2.0-rc.2`.
122
122
 
123
123
  ### Duplicate plugin after upgrading
124
124
 
package/README.zh.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  [![npm](https://img.shields.io/npm/v/dsh-skill-importer?style=flat-square&color=5dd8bd&label=npm)](https://www.npmjs.com/package/dsh-skill-importer)
13
13
  [![downloads](https://img.shields.io/npm/dm/dsh-skill-importer?style=flat-square&color=6da8ff)](https://www.npmjs.com/package/dsh-skill-importer)
14
- [![DeepSeek Harness](https://img.shields.io/badge/DeepSeek_Harness-%E2%89%A50.1.0--rc.6-5965f2?style=flat-square)](https://github.com/deepseek-ai/deepseek-harness)
14
+ [![DeepSeek Harness](https://img.shields.io/badge/DeepSeek_Harness-%E2%89%A50.2.0--rc.2-5965f2?style=flat-square)](https://github.com/deepseek-ai/deepseek-harness)
15
15
  [![license](https://img.shields.io/badge/license-MIT-a786ff?style=flat-square)](LICENSE)
16
16
 
17
17
  <br />
@@ -118,7 +118,7 @@ minimumReleaseAgeExclude:
118
118
 
119
119
  打开 **设置 → 技能**,选择 Markdown 文件、粘贴 URL,或通过「批量导入」迁移其他 Agent 的完整技能目录,再选择目标范围。文件系统 watcher 发现后,技能会立即出现。
120
120
 
121
- > 需要 DeepSeek Harness `>= 0.1.0-rc.6`。
121
+ > 需要 DeepSeek Harness `>= 0.2.0-rc.2`。
122
122
 
123
123
  ### 旧配置导致重复插件
124
124
 
package/lib/client.js CHANGED
@@ -229,15 +229,11 @@ window.__ModuleLoader__.load({
229
229
  const skills = useSkills((value) => value);
230
230
  const skillIssues = useSkillIssues((value) => value);
231
231
  const workspaces = useWorkspaces((value) => value);
232
- const [selectedWorkspaceId, setSelectedWorkspaceId] = (0, react.useState)(() => workspaces.recentWorkspaceId ?? workspaces.items[0]?.workspaceId);
232
+ const [selectedWorkspaceId, setSelectedWorkspaceId] = (0, react.useState)(() => workspaces.items[0]?.workspaceId);
233
233
  (0, react.useEffect)(() => {
234
234
  if (selectedWorkspaceId !== void 0 && workspaces.items.some((item) => item.workspaceId === selectedWorkspaceId)) return;
235
- setSelectedWorkspaceId(workspaces.recentWorkspaceId ?? workspaces.items[0]?.workspaceId);
236
- }, [
237
- selectedWorkspaceId,
238
- workspaces.items,
239
- workspaces.recentWorkspaceId
240
- ]);
235
+ setSelectedWorkspaceId(workspaces.items[0]?.workspaceId);
236
+ }, [selectedWorkspaceId, workspaces.items]);
241
237
  const workspace = (0, react.useMemo)(() => workspaces.items.find((item) => item.workspaceId === selectedWorkspaceId), [selectedWorkspaceId, workspaces.items]);
242
238
  const [listState, setListState] = (0, react.useState)("idle");
243
239
  const [listError, setListError] = (0, react.useState)();
@@ -2085,13 +2081,6 @@ window.__ModuleLoader__.load({
2085
2081
  if (direction === "right" && caret >= 0 && caret < token.boundaryEnd) return token.boundaryEnd;
2086
2082
  }
2087
2083
  //#endregion
2088
- //#region src/client/composerFocus.ts
2089
- const COMPOSER_FOCUS_EVENT = "dsh-skill-importer/composer-focus";
2090
- /** Ask the mounted picker in one session to restore its composer focus. */
2091
- function requestComposerFocus(request) {
2092
- window.dispatchEvent(new CustomEvent(COMPOSER_FOCUS_EVENT, { detail: request }));
2093
- }
2094
- //#endregion
2095
2084
  //#region src/client/SkillsPicker.tsx
2096
2085
  /**
2097
2086
  * Composer skill picker: a compact pill trigger in the composer's tool row
@@ -2227,15 +2216,6 @@ window.__ModuleLoader__.load({
2227
2216
  setComposerCaret(input, caret);
2228
2217
  });
2229
2218
  };
2230
- (0, react.useEffect)(() => {
2231
- const onFocusRequest = (event) => {
2232
- const request = event.detail;
2233
- if (request.sessionId !== sessionId) return;
2234
- scheduleComposerFocus(request.expectedDraft, request.caret);
2235
- };
2236
- window.addEventListener(COMPOSER_FOCUS_EVENT, onFocusRequest);
2237
- return () => window.removeEventListener(COMPOSER_FOCUS_EVENT, onFocusRequest);
2238
- }, [sessionId]);
2239
2219
  (0, react.useEffect)(() => {
2240
2220
  const onKeyDown = (event) => {
2241
2221
  if (![
@@ -2304,7 +2284,7 @@ window.__ModuleLoader__.load({
2304
2284
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2305
2285
  style: triggerIconStyle,
2306
2286
  "aria-hidden": "true",
2307
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChecklistOutline14, {})
2287
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChecklistOutlineRegular, {})
2308
2288
  }),
2309
2289
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2310
2290
  style: triggerLabelStyle,
@@ -2316,7 +2296,7 @@ window.__ModuleLoader__.load({
2316
2296
  transform: open ? "rotate(180deg)" : void 0
2317
2297
  },
2318
2298
  "aria-hidden": "true",
2319
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {})
2299
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, {})
2320
2300
  })
2321
2301
  ]
2322
2302
  }), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -2763,42 +2743,12 @@ window.__ModuleLoader__.load({
2763
2743
  const inject = [
2764
2744
  "slots",
2765
2745
  "locale",
2766
- "connection",
2767
2746
  "remote",
2768
- "remote.skills",
2769
2747
  "remote.directoryPicker",
2770
- "inputTriggers",
2771
2748
  "commandUi",
2772
2749
  "sessions",
2773
2750
  "conversation"
2774
2751
  ];
2775
- const popupEscapeHandlers = /* @__PURE__ */ new WeakMap();
2776
- /** Restore keyboard ownership when DSH opens this plugin's popup from the composer. */
2777
- function focusSkillsPopupSearch(options) {
2778
- const focus = () => {
2779
- for (const input of document.querySelectorAll("input[type=\"text\"]")) {
2780
- let node = input;
2781
- while (node !== null) {
2782
- if ((node.getAttribute("aria-label") ?? "").toLowerCase().includes("skills")) {
2783
- const previous = popupEscapeHandlers.get(input);
2784
- if (previous !== void 0) input.removeEventListener("keydown", previous);
2785
- const onKeyDown = (event) => {
2786
- if (event.key !== "Escape") return;
2787
- window.setTimeout(options.onEscape, 0);
2788
- };
2789
- popupEscapeHandlers.set(input, onKeyDown);
2790
- input.addEventListener("keydown", onKeyDown);
2791
- input.focus({ preventScroll: true });
2792
- options.resetActive();
2793
- return;
2794
- }
2795
- node = node.parentElement;
2796
- }
2797
- }
2798
- };
2799
- window.requestAnimationFrame(focus);
2800
- window.setTimeout(focus, 0);
2801
- }
2802
2752
  /** Same-origin route literals (mirrors the host half's ROUTES). */
2803
2753
  const ROUTES = {
2804
2754
  list: "/skill-importer/list",
@@ -2843,7 +2793,6 @@ window.__ModuleLoader__.load({
2843
2793
  const sourceLabel = (source) => source === "project-dsh" ? t("pickerSourceProjectDsh") : source === "project-agents" ? t("pickerSourceProjectAgents") : source === "user-dsh" ? t("pickerSourceUserDsh") : t("pickerSourceUserAgents");
2844
2794
  let catalog = [];
2845
2795
  let issues = [];
2846
- const sessionCatalogs = /* @__PURE__ */ new Map();
2847
2796
  const listeners = /* @__PURE__ */ new Set();
2848
2797
  const notify = () => {
2849
2798
  for (const listener of [...listeners]) try {
@@ -2852,67 +2801,21 @@ window.__ModuleLoader__.load({
2852
2801
  console.error("[dsh-skill-importer] listener failed:", error);
2853
2802
  }
2854
2803
  };
2855
- const legacyApi = ctx.get("connection").api;
2856
- const remote = ctx.remote ?? ctx.get("remote");
2857
- const skillsApi = remote?.skills ?? legacyApi?.skills;
2858
- if (skillsApi !== void 0) skillsApi.list = () => Promise.reject(/* @__PURE__ */ new Error("skill group hidden: use the composer skill picker or /skills"));
2859
- const usableNames = () => [...new Set([...sessionCatalogs.values()].flat().filter((skill) => skill.userInvocable).map((skill) => skill.name))];
2860
- ctx.effect(() => {
2861
- return ctx.get("inputTriggers").registerSource({
2862
- trigger: "/",
2863
- name: "skill-importer",
2864
- order: 99,
2865
- async candidates() {
2866
- throw new Error("skill group hidden: use the composer skill picker");
2867
- },
2868
- onPick() {},
2869
- warm() {},
2870
- lexicon() {
2871
- return usableNames();
2872
- },
2873
- subscribeLexicon(_session, listener) {
2874
- listeners.add(listener);
2875
- return () => {
2876
- listeners.delete(listener);
2877
- };
2878
- }
2879
- });
2880
- }, "dsh-skill-importer: lexicon source");
2881
2804
  const commandUi = ctx.get("commandUi");
2882
2805
  const sessions = ctx.get("sessions");
2883
2806
  if (commandUi !== void 0 && sessions !== void 0) ctx.effect(() => {
2884
2807
  return commandUi.register({
2885
2808
  name: "skills",
2886
- description: t("commandDescription"),
2809
+ description: () => t("commandDescription"),
2887
2810
  available: () => true,
2888
2811
  ui: {
2889
2812
  kind: "popupSelect",
2813
+ searchMode: "fuzzy-label",
2890
2814
  async options(session, _signal) {
2891
- const rows = await refreshSkillsForSession(session.sessionId);
2892
- const restoreComposerFocus = () => {
2893
- const actx = sessions.scope(session.sessionId);
2894
- if (actx === void 0) return;
2895
- const conversation = actx.get("conversation");
2896
- if (conversation === void 0) return;
2897
- const draft = conversation.input.for(actx).state.getSnapshot().draft;
2898
- requestComposerFocus({
2899
- sessionId: session.sessionId,
2900
- expectedDraft: draft,
2901
- caret: draft.length
2902
- });
2903
- };
2904
- const resetActive = () => {
2905
- const actx = sessions.scope(session.sessionId);
2906
- if (actx === void 0) return;
2907
- commandUi.popupFor(actx).highlight?.(0);
2908
- };
2909
- focusSkillsPopupSearch({
2910
- onEscape: restoreComposerFocus,
2911
- resetActive
2912
- });
2913
- return rows.filter((skill) => skill.userInvocable).map((skill) => ({
2815
+ return (await refreshSkillsForSession(session.sessionId)).filter((skill) => skill.userInvocable).map((skill) => ({
2914
2816
  id: skill.name,
2915
- label: `${skill.name} · ${sourceLabel(skill.source)}`
2817
+ label: skill.name,
2818
+ detail: sourceLabel(skill.source)
2916
2819
  }));
2917
2820
  },
2918
2821
  onSelect(option, session) {
@@ -2921,19 +2824,15 @@ window.__ModuleLoader__.load({
2921
2824
  const conversation = actx.get("conversation");
2922
2825
  if (conversation === void 0) throw new Error("conversation input is unavailable");
2923
2826
  const rest = conversation.input.for(actx).state.getSnapshot().draft.replace(/^\s*\/[a-zA-Z][a-zA-Z0-9-]*\s*/, "");
2924
- const prefix = `/${option.id} `;
2925
- const nextDraft = `${prefix}${rest}`;
2827
+ const nextDraft = `${`/${option.id} `}${rest}`;
2926
2828
  window.setTimeout(() => {
2927
2829
  const liveScope = sessions.scope(session.sessionId);
2928
2830
  if (liveScope === void 0) return;
2929
2831
  const liveConversation = liveScope.get("conversation");
2930
2832
  if (liveConversation === void 0) return;
2931
- liveConversation.input.for(liveScope).setDraft(nextDraft);
2932
- requestComposerFocus({
2933
- sessionId: session.sessionId,
2934
- expectedDraft: nextDraft,
2935
- caret: prefix.length
2936
- });
2833
+ const liveInput = liveConversation.input.for(liveScope);
2834
+ liveInput.setDraft(nextDraft);
2835
+ liveInput.focus();
2937
2836
  }, 0);
2938
2837
  }
2939
2838
  }
@@ -2949,7 +2848,6 @@ window.__ModuleLoader__.load({
2949
2848
  const refreshSkillsForSession = async (sessionId) => {
2950
2849
  const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd;
2951
2850
  const effective = effectiveSkills((await call(cwd === void 0 ? `${ROUTES.list}?scope=global` : `${ROUTES.list}?workspacePath=${encodeURIComponent(cwd)}`)).skills);
2952
- sessionCatalogs.set(sessionId, effective);
2953
2851
  notify();
2954
2852
  return effective;
2955
2853
  };
@@ -2963,15 +2861,9 @@ window.__ModuleLoader__.load({
2963
2861
  return (await call(ROUTES.delete, request)).removed;
2964
2862
  };
2965
2863
  const pickDirectory = async () => {
2966
- if (remote?.directoryPicker !== void 0) {
2967
- const result = await remote.directoryPicker.pick();
2968
- if (!result.ok) throw new Error(result.error.message);
2969
- return result.value;
2970
- }
2971
- if (legacyApi?.host === void 0) throw new Error("当前 DSH 未提供目录选择能力");
2972
- const response = await legacyApi.host.pickDirectory({});
2973
- if (!response.result.ok) throw new Error(response.result.error.message);
2974
- return response.result.value.path;
2864
+ const result = await ctx.remote.directoryPicker.pick();
2865
+ if (!result.ok) throw new Error(result.error.message);
2866
+ return result.value;
2975
2867
  };
2976
2868
  const scanBatch = (request) => call(ROUTES.batchScan, request);
2977
2869
  const commitBatch = (request) => call(ROUTES.batchCommit, request);
@@ -1,5 +1,5 @@
1
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
2
- import type { SessionId } from '@deepseek-ai/dsh-api-remotes/client';
1
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
2
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
3
3
  import type { HostObservable } from '@deepseek-ai/dsh-client-ui-slots';
4
4
  import type { SkillImporterProps } from './SkillImporterSection.tsx';
5
5
  import type { SkillsPickerProps } from './SkillsPicker.tsx';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-skill-importer",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Web UI plugin for DeepSeek Harness: import skills from local Markdown files or URLs into the skill roots the harness discovers automatically",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -19,13 +19,16 @@
19
19
  "dsh": {
20
20
  "client": {
21
21
  "inject": [
22
- "@deepseek-ai/dsh-client-runtime",
23
- "@deepseek-ai/dsh-client-connection",
22
+ "@deepseek-ai/dsh-api-session-controller",
23
+ "@deepseek-ai/dsh-api-workspace-controller",
24
24
  "@deepseek-ai/dsh-client-locale",
25
+ "@deepseek-ai/dsh-client-ui-renderer",
26
+ "@deepseek-ai/dsh-client-ui-session",
25
27
  "@deepseek-ai/dsh-client-ui-slots",
26
28
  "@deepseek-ai/dsh-client-ui-settings",
27
29
  "@deepseek-ai/dsh-client-ui-primitives",
28
- "@deepseek-ai/dsh-api-remotes"
30
+ "@deepseek-ai/dsh-client-ui-conversation",
31
+ "@deepseek-ai/dsh-client-ui-commands"
29
32
  ],
30
33
  "platform": "web"
31
34
  },
@@ -54,42 +57,46 @@
54
57
  },
55
58
  "license": "MIT",
56
59
  "peerDependencies": {
57
- "@deepseek-ai/cordis": "^4.0.1",
58
- "@deepseek-ai/dsh-api-remotes": "^0.1.0-rc.6",
59
- "@deepseek-ai/dsh-client-connection": "^0.1.0-rc.6",
60
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
61
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
62
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
63
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
64
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
60
+ "@deepseek-ai/cordis": "^4.0.4 || ^4.0.5-alpha.1",
61
+ "@deepseek-ai/dsh-api-session-controller": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
62
+ "@deepseek-ai/dsh-api-workspace-controller": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
63
+ "@deepseek-ai/dsh-client-locale": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
64
+ "@deepseek-ai/dsh-client-store": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
65
+ "@deepseek-ai/dsh-client-ui-settings": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
66
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
67
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
68
+ "@deepseek-ai/dsh-client-ui-session": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
69
+ "@deepseek-ai/dsh-client-ui-slots": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
65
70
  "react": "^18.2.0",
66
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
67
- "@deepseek-ai/dsh-workspace": "^0.1.0-rc.6",
68
- "@deepseek-ai/dsh-commands": "^0.1.0-rc.6",
69
- "@deepseek-ai/dsh-skill": "^0.1.0-rc.6",
70
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
71
- "@deepseek-ai/dsh-client-ui-commands": "^0.1.0-rc.6"
71
+ "@deepseek-ai/dsh-host-webserver": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
72
+ "@deepseek-ai/dsh-workspace": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
73
+ "@deepseek-ai/dsh-skill": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
74
+ "@deepseek-ai/dsh-session": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
75
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.2.0-rc.2 || ^0.2.1-alpha.1",
76
+ "@deepseek-ai/dsh-client-ui-commands": "^0.2.0-rc.2 || ^0.2.1-alpha.1"
72
77
  },
73
78
  "devDependencies": {
74
- "@deepseek-ai/cordis": "^4.0.1",
75
- "@deepseek-ai/dsh-api-remotes": "^0.1.0-rc.6",
76
- "@deepseek-ai/dsh-client-connection": "^0.1.0-rc.6",
77
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
78
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
79
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
80
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
81
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
79
+ "@deepseek-ai/cordis": "4.0.5-alpha.1",
80
+ "@deepseek-ai/dsh-api-session-controller": "^0.2.1-alpha.1",
81
+ "@deepseek-ai/dsh-api-workspace-controller": "^0.2.1-alpha.1",
82
+ "@deepseek-ai/dsh-client-locale": "^0.2.1-alpha.1",
83
+ "@deepseek-ai/dsh-client-store": "^0.2.1-alpha.1",
84
+ "@deepseek-ai/dsh-client-ui-settings": "^0.2.1-alpha.1",
85
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.2.1-alpha.1",
86
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.2.1-alpha.1",
87
+ "@deepseek-ai/dsh-client-ui-session": "^0.2.1-alpha.1",
88
+ "@deepseek-ai/dsh-client-ui-slots": "^0.2.1-alpha.1",
82
89
  "@types/react": "^18.3.0",
83
90
  "react": "^18.2.0",
84
91
  "tsdown": "^0.22.2",
85
92
  "typescript": "^6.0.3",
86
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
93
+ "@deepseek-ai/dsh-host-webserver": "^0.2.1-alpha.1",
87
94
  "@types/node": "^24.0.0",
88
- "@deepseek-ai/dsh-workspace": "^0.1.0-rc.6",
89
- "@deepseek-ai/dsh-commands": "^0.1.0-rc.6",
90
- "@deepseek-ai/dsh-skill": "^0.1.0-rc.6",
91
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
92
- "@deepseek-ai/dsh-client-ui-commands": "^0.1.0-rc.6"
95
+ "@deepseek-ai/dsh-workspace": "^0.2.1-alpha.1",
96
+ "@deepseek-ai/dsh-skill": "^0.2.1-alpha.1",
97
+ "@deepseek-ai/dsh-session": "^0.2.1-alpha.1",
98
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.2.1-alpha.1",
99
+ "@deepseek-ai/dsh-client-ui-commands": "^0.2.1-alpha.1"
93
100
  },
94
101
  "repository": {
95
102
  "type": "git",
@@ -1,5 +1,6 @@
1
1
  import assert from 'node:assert/strict'
2
2
  import test from 'node:test'
3
+ import { readFileSync } from 'node:fs'
3
4
  import { compareVersions, currentVersion, updateCommand } from '../src/update.ts'
4
5
 
5
6
  test('compares stable semantic versions', () => {
@@ -14,7 +15,8 @@ test('orders prereleases before stable releases', () => {
14
15
  })
15
16
 
16
17
  test('reads package version and produces an exact update command', () => {
17
- assert.equal(currentVersion(), '0.2.5')
18
+ const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
19
+ assert.equal(currentVersion(), manifest.version)
18
20
  assert.equal(
19
21
  updateCommand('0.2.4'),
20
22
  'npx @deepseek-ai/dsh plugin --profile web add dsh-skill-importer@0.2.4',
@@ -1,9 +0,0 @@
1
- /** Session-routed request emitted after a non-React command popup edits the draft. */
2
- export interface ComposerFocusRequest {
3
- readonly sessionId: string;
4
- readonly expectedDraft: string;
5
- readonly caret: number;
6
- }
7
- export declare const COMPOSER_FOCUS_EVENT = "dsh-skill-importer/composer-focus";
8
- /** Ask the mounted picker in one session to restore its composer focus. */
9
- export declare function requestComposerFocus(request: ComposerFocusRequest): void;