dsh-skill-importer 0.2.4 → 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 +2 -2
- package/README.zh.md +2 -2
- package/lib/client.js +106 -92
- package/lib/types/client/index.d.ts +3 -3
- package/package.json +39 -32
- package/tests/update.test.mjs +3 -1
- package/lib/types/client/composerFocus.d.ts +0 -9
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
[](https://www.npmjs.com/package/dsh-skill-importer)
|
|
13
13
|
[](https://www.npmjs.com/package/dsh-skill-importer)
|
|
14
|
-
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
15
|
[](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.
|
|
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
|
[](https://www.npmjs.com/package/dsh-skill-importer)
|
|
13
13
|
[](https://www.npmjs.com/package/dsh-skill-importer)
|
|
14
|
-
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
15
|
[](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.
|
|
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.
|
|
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.
|
|
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
|
|
@@ -2102,15 +2091,70 @@ window.__ModuleLoader__.load({
|
|
|
2102
2091
|
* with `/name ` — the native text gesture — highlighted via the plugin's
|
|
2103
2092
|
* lexicon contribution.
|
|
2104
2093
|
*/
|
|
2105
|
-
/** Find the one
|
|
2106
|
-
function
|
|
2094
|
+
/** Find the one legacy textarea or Lexical contenteditable owned by this picker. */
|
|
2095
|
+
function composerInputFor(root) {
|
|
2107
2096
|
let node = root?.parentElement;
|
|
2108
2097
|
while (node !== null && node !== void 0) {
|
|
2109
|
-
const
|
|
2110
|
-
if (
|
|
2098
|
+
const inputs = node.querySelectorAll("textarea, [data-composer-input]");
|
|
2099
|
+
if (inputs.length > 0) return inputs.length === 1 ? inputs[0] : void 0;
|
|
2111
2100
|
node = node.parentElement;
|
|
2112
2101
|
}
|
|
2113
2102
|
}
|
|
2103
|
+
function composerText(input) {
|
|
2104
|
+
return input instanceof HTMLTextAreaElement ? input.value : input.textContent ?? "";
|
|
2105
|
+
}
|
|
2106
|
+
function composerCaret(input) {
|
|
2107
|
+
if (input instanceof HTMLTextAreaElement) {
|
|
2108
|
+
if (input.selectionStart === null || input.selectionEnd === null) return void 0;
|
|
2109
|
+
return {
|
|
2110
|
+
start: input.selectionStart,
|
|
2111
|
+
end: input.selectionEnd
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
const selection = window.getSelection();
|
|
2115
|
+
if (selection === null || selection.rangeCount !== 1) return void 0;
|
|
2116
|
+
const range = selection.getRangeAt(0);
|
|
2117
|
+
if (!input.contains(range.startContainer) || !input.contains(range.endContainer)) return void 0;
|
|
2118
|
+
const offsetOf = (container, offset) => {
|
|
2119
|
+
const prefix = range.cloneRange();
|
|
2120
|
+
prefix.selectNodeContents(input);
|
|
2121
|
+
prefix.setEnd(container, offset);
|
|
2122
|
+
return prefix.toString().length;
|
|
2123
|
+
};
|
|
2124
|
+
return {
|
|
2125
|
+
start: offsetOf(range.startContainer, range.startOffset),
|
|
2126
|
+
end: offsetOf(range.endContainer, range.endOffset)
|
|
2127
|
+
};
|
|
2128
|
+
}
|
|
2129
|
+
function setComposerCaret(input, caret) {
|
|
2130
|
+
input.focus({ preventScroll: true });
|
|
2131
|
+
if (input instanceof HTMLTextAreaElement) {
|
|
2132
|
+
input.setSelectionRange(caret, caret);
|
|
2133
|
+
return;
|
|
2134
|
+
}
|
|
2135
|
+
const range = document.createRange();
|
|
2136
|
+
let remaining = caret;
|
|
2137
|
+
const walker = document.createTreeWalker(input, NodeFilter.SHOW_TEXT);
|
|
2138
|
+
let text = walker.nextNode();
|
|
2139
|
+
while (text !== null) {
|
|
2140
|
+
const length = text.textContent?.length ?? 0;
|
|
2141
|
+
if (remaining <= length) {
|
|
2142
|
+
range.setStart(text, remaining);
|
|
2143
|
+
range.collapse(true);
|
|
2144
|
+
const selection = window.getSelection();
|
|
2145
|
+
selection?.removeAllRanges();
|
|
2146
|
+
selection?.addRange(range);
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
remaining -= length;
|
|
2150
|
+
text = walker.nextNode();
|
|
2151
|
+
}
|
|
2152
|
+
range.selectNodeContents(input);
|
|
2153
|
+
range.collapse(false);
|
|
2154
|
+
const selection = window.getSelection();
|
|
2155
|
+
selection?.removeAllRanges();
|
|
2156
|
+
selection?.addRange(range);
|
|
2157
|
+
}
|
|
2114
2158
|
/** One row of the composer skill picker. */
|
|
2115
2159
|
function SkillsPicker({ t, sessionId, useInput, inputActions, actions }) {
|
|
2116
2160
|
const input = useInput((value) => value.draft);
|
|
@@ -2164,24 +2208,14 @@ window.__ModuleLoader__.load({
|
|
|
2164
2208
|
draftRef.current = input;
|
|
2165
2209
|
skillNamesRef.current = usable.map((skill) => skill.name);
|
|
2166
2210
|
const scheduleComposerFocus = (expectedDraft, caret) => {
|
|
2167
|
-
const
|
|
2211
|
+
const input = composerInputFor(rootRef.current);
|
|
2168
2212
|
if (caretFrameRef.current !== void 0) window.cancelAnimationFrame(caretFrameRef.current);
|
|
2169
2213
|
caretFrameRef.current = window.requestAnimationFrame(() => {
|
|
2170
2214
|
caretFrameRef.current = void 0;
|
|
2171
|
-
if (
|
|
2172
|
-
|
|
2173
|
-
textarea.setSelectionRange(caret, caret);
|
|
2215
|
+
if (input === void 0 || !input.isConnected || composerText(input) !== expectedDraft) return;
|
|
2216
|
+
setComposerCaret(input, caret);
|
|
2174
2217
|
});
|
|
2175
2218
|
};
|
|
2176
|
-
(0, react.useEffect)(() => {
|
|
2177
|
-
const onFocusRequest = (event) => {
|
|
2178
|
-
const request = event.detail;
|
|
2179
|
-
if (request.sessionId !== sessionId) return;
|
|
2180
|
-
scheduleComposerFocus(request.expectedDraft, request.caret);
|
|
2181
|
-
};
|
|
2182
|
-
window.addEventListener(COMPOSER_FOCUS_EVENT, onFocusRequest);
|
|
2183
|
-
return () => window.removeEventListener(COMPOSER_FOCUS_EVENT, onFocusRequest);
|
|
2184
|
-
}, [sessionId]);
|
|
2185
2219
|
(0, react.useEffect)(() => {
|
|
2186
2220
|
const onKeyDown = (event) => {
|
|
2187
2221
|
if (![
|
|
@@ -2192,18 +2226,20 @@ window.__ModuleLoader__.load({
|
|
|
2192
2226
|
if (event.defaultPrevented || event.isComposing || event.keyCode === 229) return;
|
|
2193
2227
|
if (event.metaKey || event.ctrlKey || event.altKey) return;
|
|
2194
2228
|
if (event.shiftKey && event.key !== "Backspace") return;
|
|
2195
|
-
const
|
|
2196
|
-
if (!(
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2229
|
+
const target = event.target;
|
|
2230
|
+
if (!(target instanceof Node)) return;
|
|
2231
|
+
const input = composerInputFor(rootRef.current);
|
|
2232
|
+
if (input === void 0 || document.activeElement !== input || !input.contains(target)) return;
|
|
2233
|
+
if (composerText(input) !== draftRef.current) return;
|
|
2234
|
+
const selection = composerCaret(input);
|
|
2235
|
+
if (selection === void 0 || selection.start !== selection.end) return;
|
|
2236
|
+
const start = selection.start;
|
|
2201
2237
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
2202
2238
|
const caret = atomicSkillArrow(draftRef.current, start, event.key === "ArrowLeft" ? "left" : "right", skillNamesRef.current);
|
|
2203
2239
|
if (caret === void 0) return;
|
|
2204
2240
|
event.preventDefault();
|
|
2205
2241
|
event.stopPropagation();
|
|
2206
|
-
|
|
2242
|
+
setComposerCaret(input, caret);
|
|
2207
2243
|
return;
|
|
2208
2244
|
}
|
|
2209
2245
|
const edit = atomicSkillBackspace(draftRef.current, start, skillNamesRef.current);
|
|
@@ -2214,8 +2250,8 @@ window.__ModuleLoader__.load({
|
|
|
2214
2250
|
if (caretFrameRef.current !== void 0) window.cancelAnimationFrame(caretFrameRef.current);
|
|
2215
2251
|
caretFrameRef.current = window.requestAnimationFrame(() => {
|
|
2216
2252
|
caretFrameRef.current = void 0;
|
|
2217
|
-
if (!
|
|
2218
|
-
|
|
2253
|
+
if (!input.isConnected || document.activeElement !== input || composerText(input) !== edit.draft) return;
|
|
2254
|
+
setComposerCaret(input, edit.caret);
|
|
2219
2255
|
});
|
|
2220
2256
|
};
|
|
2221
2257
|
document.addEventListener("keydown", onKeyDown, true);
|
|
@@ -2248,7 +2284,7 @@ window.__ModuleLoader__.load({
|
|
|
2248
2284
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2249
2285
|
style: triggerIconStyle,
|
|
2250
2286
|
"aria-hidden": "true",
|
|
2251
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
2287
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChecklistOutlineRegular, {})
|
|
2252
2288
|
}),
|
|
2253
2289
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2254
2290
|
style: triggerLabelStyle,
|
|
@@ -2260,7 +2296,7 @@ window.__ModuleLoader__.load({
|
|
|
2260
2296
|
transform: open ? "rotate(180deg)" : void 0
|
|
2261
2297
|
},
|
|
2262
2298
|
"aria-hidden": "true",
|
|
2263
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
2299
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, {})
|
|
2264
2300
|
})
|
|
2265
2301
|
]
|
|
2266
2302
|
}), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -2703,11 +2739,15 @@ window.__ModuleLoader__.load({
|
|
|
2703
2739
|
};
|
|
2704
2740
|
//#endregion
|
|
2705
2741
|
//#region src/client/index.ts
|
|
2706
|
-
/**
|
|
2742
|
+
/** Every client service used during apply is explicit; alpha DSH no longer tolerates load-order access. */
|
|
2707
2743
|
const inject = [
|
|
2708
2744
|
"slots",
|
|
2709
2745
|
"locale",
|
|
2710
|
-
"
|
|
2746
|
+
"remote",
|
|
2747
|
+
"remote.directoryPicker",
|
|
2748
|
+
"commandUi",
|
|
2749
|
+
"sessions",
|
|
2750
|
+
"conversation"
|
|
2711
2751
|
];
|
|
2712
2752
|
/** Same-origin route literals (mirrors the host half's ROUTES). */
|
|
2713
2753
|
const ROUTES = {
|
|
@@ -2753,7 +2793,6 @@ window.__ModuleLoader__.load({
|
|
|
2753
2793
|
const sourceLabel = (source) => source === "project-dsh" ? t("pickerSourceProjectDsh") : source === "project-agents" ? t("pickerSourceProjectAgents") : source === "user-dsh" ? t("pickerSourceUserDsh") : t("pickerSourceUserAgents");
|
|
2754
2794
|
let catalog = [];
|
|
2755
2795
|
let issues = [];
|
|
2756
|
-
const sessionCatalogs = /* @__PURE__ */ new Map();
|
|
2757
2796
|
const listeners = /* @__PURE__ */ new Set();
|
|
2758
2797
|
const notify = () => {
|
|
2759
2798
|
for (const listener of [...listeners]) try {
|
|
@@ -2762,63 +2801,39 @@ window.__ModuleLoader__.load({
|
|
|
2762
2801
|
console.error("[dsh-skill-importer] listener failed:", error);
|
|
2763
2802
|
}
|
|
2764
2803
|
};
|
|
2765
|
-
const connection = ctx.get("connection");
|
|
2766
|
-
const skillsApi = connection.api.skills;
|
|
2767
|
-
skillsApi.list.bind(skillsApi);
|
|
2768
|
-
skillsApi.list = ((_request, _signal) => {
|
|
2769
|
-
return Promise.reject(/* @__PURE__ */ new Error("skill group hidden: use the composer skill picker or /skills"));
|
|
2770
|
-
});
|
|
2771
|
-
const usableNames = () => [...new Set([...sessionCatalogs.values()].flat().filter((skill) => skill.userInvocable).map((skill) => skill.name))];
|
|
2772
|
-
ctx.effect(() => {
|
|
2773
|
-
return ctx.get("inputTriggers").registerSource({
|
|
2774
|
-
trigger: "/",
|
|
2775
|
-
name: "skill-importer",
|
|
2776
|
-
order: 99,
|
|
2777
|
-
async candidates() {
|
|
2778
|
-
throw new Error("skill group hidden: use the composer skill picker");
|
|
2779
|
-
},
|
|
2780
|
-
onPick() {},
|
|
2781
|
-
warm() {},
|
|
2782
|
-
lexicon() {
|
|
2783
|
-
return usableNames();
|
|
2784
|
-
},
|
|
2785
|
-
subscribeLexicon(_session, listener) {
|
|
2786
|
-
listeners.add(listener);
|
|
2787
|
-
return () => {
|
|
2788
|
-
listeners.delete(listener);
|
|
2789
|
-
};
|
|
2790
|
-
}
|
|
2791
|
-
});
|
|
2792
|
-
}, "dsh-skill-importer: lexicon source");
|
|
2793
2804
|
const commandUi = ctx.get("commandUi");
|
|
2794
2805
|
const sessions = ctx.get("sessions");
|
|
2795
|
-
|
|
2796
|
-
if (commandUi !== void 0 && sessions !== void 0 && conversation !== void 0) ctx.effect(() => {
|
|
2806
|
+
if (commandUi !== void 0 && sessions !== void 0) ctx.effect(() => {
|
|
2797
2807
|
return commandUi.register({
|
|
2798
2808
|
name: "skills",
|
|
2799
|
-
description: t("commandDescription"),
|
|
2809
|
+
description: () => t("commandDescription"),
|
|
2800
2810
|
available: () => true,
|
|
2801
2811
|
ui: {
|
|
2802
2812
|
kind: "popupSelect",
|
|
2813
|
+
searchMode: "fuzzy-label",
|
|
2803
2814
|
async options(session, _signal) {
|
|
2804
2815
|
return (await refreshSkillsForSession(session.sessionId)).filter((skill) => skill.userInvocable).map((skill) => ({
|
|
2805
2816
|
id: skill.name,
|
|
2806
|
-
label:
|
|
2817
|
+
label: skill.name,
|
|
2818
|
+
detail: sourceLabel(skill.source)
|
|
2807
2819
|
}));
|
|
2808
2820
|
},
|
|
2809
2821
|
onSelect(option, session) {
|
|
2810
2822
|
const actx = sessions.scope(session.sessionId);
|
|
2811
|
-
if (actx === void 0)
|
|
2812
|
-
const
|
|
2813
|
-
|
|
2814
|
-
const
|
|
2815
|
-
const nextDraft = `${
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2823
|
+
if (actx === void 0) throw new Error("this session is no longer available");
|
|
2824
|
+
const conversation = actx.get("conversation");
|
|
2825
|
+
if (conversation === void 0) throw new Error("conversation input is unavailable");
|
|
2826
|
+
const rest = conversation.input.for(actx).state.getSnapshot().draft.replace(/^\s*\/[a-zA-Z][a-zA-Z0-9-]*\s*/, "");
|
|
2827
|
+
const nextDraft = `${`/${option.id} `}${rest}`;
|
|
2828
|
+
window.setTimeout(() => {
|
|
2829
|
+
const liveScope = sessions.scope(session.sessionId);
|
|
2830
|
+
if (liveScope === void 0) return;
|
|
2831
|
+
const liveConversation = liveScope.get("conversation");
|
|
2832
|
+
if (liveConversation === void 0) return;
|
|
2833
|
+
const liveInput = liveConversation.input.for(liveScope);
|
|
2834
|
+
liveInput.setDraft(nextDraft);
|
|
2835
|
+
liveInput.focus();
|
|
2836
|
+
}, 0);
|
|
2822
2837
|
}
|
|
2823
2838
|
}
|
|
2824
2839
|
});
|
|
@@ -2833,7 +2848,6 @@ window.__ModuleLoader__.load({
|
|
|
2833
2848
|
const refreshSkillsForSession = async (sessionId) => {
|
|
2834
2849
|
const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd;
|
|
2835
2850
|
const effective = effectiveSkills((await call(cwd === void 0 ? `${ROUTES.list}?scope=global` : `${ROUTES.list}?workspacePath=${encodeURIComponent(cwd)}`)).skills);
|
|
2836
|
-
sessionCatalogs.set(sessionId, effective);
|
|
2837
2851
|
notify();
|
|
2838
2852
|
return effective;
|
|
2839
2853
|
};
|
|
@@ -2847,9 +2861,9 @@ window.__ModuleLoader__.load({
|
|
|
2847
2861
|
return (await call(ROUTES.delete, request)).removed;
|
|
2848
2862
|
};
|
|
2849
2863
|
const pickDirectory = async () => {
|
|
2850
|
-
const
|
|
2851
|
-
if (!
|
|
2852
|
-
return
|
|
2864
|
+
const result = await ctx.remote.directoryPicker.pick();
|
|
2865
|
+
if (!result.ok) throw new Error(result.error.message);
|
|
2866
|
+
return result.value;
|
|
2853
2867
|
};
|
|
2854
2868
|
const scanBatch = (request) => call(ROUTES.batchScan, request);
|
|
2855
2869
|
const commitBatch = (request) => call(ROUTES.batchCommit, request);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ClientContext } from '@deepseek-ai/
|
|
2
|
-
import type { SessionId } from '@deepseek-ai/dsh-
|
|
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';
|
|
@@ -43,7 +43,7 @@ export interface SkillImporterInjected {
|
|
|
43
43
|
checkForUpdates: () => Promise<UpdateStatusResponse>;
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
-
/**
|
|
46
|
+
/** Every client service used during apply is explicit; alpha DSH no longer tolerates load-order access. */
|
|
47
47
|
export declare const inject: string[];
|
|
48
48
|
/**
|
|
49
49
|
* Client plugin body: register the section and its dictionaries.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-skill-importer",
|
|
3
|
-
"version": "0.2.
|
|
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-
|
|
23
|
-
"@deepseek-ai/dsh-
|
|
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-
|
|
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-
|
|
59
|
-
"@deepseek-ai/dsh-
|
|
60
|
-
"@deepseek-ai/dsh-client-locale": "^0.
|
|
61
|
-
"@deepseek-ai/dsh-client-
|
|
62
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.
|
|
63
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.
|
|
64
|
-
"@deepseek-ai/dsh-client-ui-
|
|
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.
|
|
67
|
-
"@deepseek-ai/dsh-workspace": "^0.
|
|
68
|
-
"@deepseek-ai/dsh-
|
|
69
|
-
"@deepseek-ai/dsh-
|
|
70
|
-
"@deepseek-ai/dsh-client-ui-conversation": "^0.
|
|
71
|
-
"@deepseek-ai/dsh-client-ui-commands": "^0.
|
|
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": "
|
|
75
|
-
"@deepseek-ai/dsh-api-
|
|
76
|
-
"@deepseek-ai/dsh-
|
|
77
|
-
"@deepseek-ai/dsh-client-locale": "^0.1
|
|
78
|
-
"@deepseek-ai/dsh-client-
|
|
79
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1
|
|
80
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1
|
|
81
|
-
"@deepseek-ai/dsh-client-ui-
|
|
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
|
|
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
|
|
89
|
-
"@deepseek-ai/dsh-
|
|
90
|
-
"@deepseek-ai/dsh-
|
|
91
|
-
"@deepseek-ai/dsh-client-ui-conversation": "^0.1
|
|
92
|
-
"@deepseek-ai/dsh-client-ui-commands": "^0.1
|
|
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",
|
package/tests/update.test.mjs
CHANGED
|
@@ -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
|
-
|
|
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;
|