dsh-skill-importer 0.2.3 → 0.2.4
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 +20 -8
- package/README.zh.md +19 -7
- package/lib/client.js +715 -73
- package/lib/index.js +199 -41
- package/lib/types/client/SkillImporterSection.d.ts +1 -1
- package/lib/types/client/SkillsPicker.d.ts +1 -1
- package/lib/types/client/effectiveSkills.d.ts +3 -0
- package/lib/types/client/index.d.ts +11 -3
- package/lib/types/client/locales.d.ts +80 -2
- package/lib/types/index.d.ts +1 -0
- package/lib/types/server.d.ts +6 -2
- package/lib/types/types.d.ts +23 -3
- package/lib/types/update.d.ts +6 -0
- package/package.json +4 -1
- package/src/server.ts +85 -37
- package/src/types.ts +25 -3
- package/tests/batch-import.test.mjs +5 -5
- package/tests/effective-skills.test.mjs +25 -0
- package/tests/skill-list.test.mjs +50 -0
- package/tests/update.test.mjs +22 -0
package/lib/client.js
CHANGED
|
@@ -225,14 +225,24 @@ window.__ModuleLoader__.load({
|
|
|
225
225
|
});
|
|
226
226
|
}
|
|
227
227
|
/** The settings section's page body. */
|
|
228
|
-
function SkillImporterSection({ t, useSkills, useWorkspaces, actions }) {
|
|
228
|
+
function SkillImporterSection({ t, useSkills, useSkillIssues, useWorkspaces, actions }) {
|
|
229
229
|
const skills = useSkills((value) => value);
|
|
230
|
+
const skillIssues = useSkillIssues((value) => value);
|
|
230
231
|
const workspaces = useWorkspaces((value) => value);
|
|
231
|
-
const
|
|
232
|
+
const [selectedWorkspaceId, setSelectedWorkspaceId] = (0, react.useState)(() => workspaces.recentWorkspaceId ?? workspaces.items[0]?.workspaceId);
|
|
233
|
+
(0, react.useEffect)(() => {
|
|
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
|
+
]);
|
|
241
|
+
const workspace = (0, react.useMemo)(() => workspaces.items.find((item) => item.workspaceId === selectedWorkspaceId), [selectedWorkspaceId, workspaces.items]);
|
|
232
242
|
const [listState, setListState] = (0, react.useState)("idle");
|
|
233
243
|
const [listError, setListError] = (0, react.useState)();
|
|
234
244
|
const [listEpoch, setListEpoch] = (0, react.useState)(0);
|
|
235
|
-
const [
|
|
245
|
+
const [expandedGroups, setExpandedGroups] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
236
246
|
(0, react.useEffect)(() => {
|
|
237
247
|
let cancelled = false;
|
|
238
248
|
setListState("loading");
|
|
@@ -249,7 +259,10 @@ window.__ModuleLoader__.load({
|
|
|
249
259
|
};
|
|
250
260
|
}, [listEpoch, actions]);
|
|
251
261
|
const [mode, setMode] = (0, react.useState)("file");
|
|
252
|
-
const [target, setTarget] = (0, react.useState)("project-
|
|
262
|
+
const [target, setTarget] = (0, react.useState)("project-dsh");
|
|
263
|
+
(0, react.useEffect)(() => {
|
|
264
|
+
if (workspaces.items.length === 0 && target.startsWith("project-")) setTarget("user-dsh");
|
|
265
|
+
}, [target, workspaces.items.length]);
|
|
253
266
|
const [fileDraft, setFileDraft] = (0, react.useState)();
|
|
254
267
|
const [fileError, setFileError] = (0, react.useState)();
|
|
255
268
|
const [url, setUrl] = (0, react.useState)("");
|
|
@@ -262,8 +275,41 @@ window.__ModuleLoader__.load({
|
|
|
262
275
|
const [batchResults, setBatchResults] = (0, react.useState)();
|
|
263
276
|
const [replaceNames, setReplaceNames] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
264
277
|
const [pendingDelete, setPendingDelete] = (0, react.useState)();
|
|
278
|
+
const [locationOpen, setLocationOpen] = (0, react.useState)(false);
|
|
279
|
+
const [workspaceQuery, setWorkspaceQuery] = (0, react.useState)("");
|
|
280
|
+
const [draftTarget, setDraftTarget] = (0, react.useState)("project-dsh");
|
|
281
|
+
const [draftWorkspaceId, setDraftWorkspaceId] = (0, react.useState)();
|
|
282
|
+
const [updateState, setUpdateState] = (0, react.useState)("checking");
|
|
283
|
+
const [updateStatus, setUpdateStatus] = (0, react.useState)();
|
|
284
|
+
const [updateDialogOpen, setUpdateDialogOpen] = (0, react.useState)(false);
|
|
285
|
+
const [commandCopied, setCommandCopied] = (0, react.useState)(false);
|
|
265
286
|
const [batchConfirmation, setBatchConfirmation] = (0, react.useState)();
|
|
266
287
|
const fileInput = (0, react.useRef)(null);
|
|
288
|
+
const checkForUpdates = () => {
|
|
289
|
+
setUpdateState("checking");
|
|
290
|
+
actions.checkForUpdates().then((status) => {
|
|
291
|
+
setUpdateStatus(status);
|
|
292
|
+
setUpdateState(status.error === void 0 ? "ready" : "error");
|
|
293
|
+
}, () => setUpdateState("error"));
|
|
294
|
+
};
|
|
295
|
+
(0, react.useEffect)(() => {
|
|
296
|
+
let cancelled = false;
|
|
297
|
+
actions.checkForUpdates().then((status) => {
|
|
298
|
+
if (cancelled) return;
|
|
299
|
+
setUpdateStatus(status);
|
|
300
|
+
setUpdateState(status.error === void 0 ? "ready" : "error");
|
|
301
|
+
}, () => {
|
|
302
|
+
if (!cancelled) setUpdateState("error");
|
|
303
|
+
});
|
|
304
|
+
return () => {
|
|
305
|
+
cancelled = true;
|
|
306
|
+
};
|
|
307
|
+
}, [actions]);
|
|
308
|
+
const copyUpdateCommand = async () => {
|
|
309
|
+
if (updateStatus?.command === void 0) return;
|
|
310
|
+
await navigator.clipboard.writeText(updateStatus.command);
|
|
311
|
+
setCommandCopied(true);
|
|
312
|
+
};
|
|
267
313
|
const onFilePicked = async (file) => {
|
|
268
314
|
setFileDraft(void 0);
|
|
269
315
|
setFileError(void 0);
|
|
@@ -314,7 +360,7 @@ window.__ModuleLoader__.load({
|
|
|
314
360
|
if (await actions.deleteSkill({
|
|
315
361
|
name: skill.name,
|
|
316
362
|
source: skill.source,
|
|
317
|
-
workspacePath:
|
|
363
|
+
workspacePath: skill.workspacePath
|
|
318
364
|
})) {
|
|
319
365
|
setMessage(t("deleted"));
|
|
320
366
|
setPendingDelete(void 0);
|
|
@@ -454,7 +500,17 @@ window.__ModuleLoader__.load({
|
|
|
454
500
|
setTarget(next);
|
|
455
501
|
if (mode === "batch") resetBatchPreflight();
|
|
456
502
|
};
|
|
457
|
-
const
|
|
503
|
+
const chooseDestination = (nextTarget, nextWorkspaceId) => {
|
|
504
|
+
if (nextWorkspaceId !== void 0) setSelectedWorkspaceId(nextWorkspaceId);
|
|
505
|
+
changeTarget(nextTarget);
|
|
506
|
+
setLocationOpen(false);
|
|
507
|
+
};
|
|
508
|
+
const locationSummary = target === "project-dsh" ? t("locationSummaryProjectDsh", { title: workspace?.title ?? "" }) : target === "project-agents" ? t("locationSummaryProjectAgents", { title: workspace?.title ?? "" }) : target === "user-dsh" ? t("locationSummaryUserDsh") : t("locationSummaryUserAgents");
|
|
509
|
+
const filteredWorkspaces = workspaces.items.filter((item) => {
|
|
510
|
+
const query = workspaceQuery.trim().toLowerCase();
|
|
511
|
+
return query.length === 0 || item.title.toLowerCase().includes(query) || item.path.toLowerCase().includes(query);
|
|
512
|
+
});
|
|
513
|
+
const canSubmit = busy || mode === "file" && fileDraft === void 0 || mode === "url" && (url.trim().length === 0 || !/^https?:\/\//i.test(url.trim())) || mode === "batch" && batchPath === void 0 || target.startsWith("project-") && workspace === void 0;
|
|
458
514
|
const runPrimaryAction = () => {
|
|
459
515
|
if (mode !== "batch") {
|
|
460
516
|
submit();
|
|
@@ -468,13 +524,33 @@ window.__ModuleLoader__.load({
|
|
|
468
524
|
if (!skill.modelInvocable && skill.userInvocable) return t("userOnly");
|
|
469
525
|
if (skill.modelInvocable && !skill.userInvocable) return t("modelOnly");
|
|
470
526
|
};
|
|
471
|
-
const
|
|
472
|
-
|
|
527
|
+
const toggleGroup = (groupKey) => {
|
|
528
|
+
setExpandedGroups((current) => {
|
|
473
529
|
const next = new Set(current);
|
|
474
|
-
if (!next.delete(
|
|
530
|
+
if (!next.delete(groupKey)) next.add(groupKey);
|
|
475
531
|
return next;
|
|
476
532
|
});
|
|
477
533
|
};
|
|
534
|
+
const skillGroups = [
|
|
535
|
+
...workspaces.items.flatMap((item) => ["project-dsh", "project-agents"].map((source) => ({
|
|
536
|
+
key: `${item.workspaceId}:${source}`,
|
|
537
|
+
source,
|
|
538
|
+
workspacePath: item.path,
|
|
539
|
+
name: source === "project-dsh" ? t("targetProjectDsh", { title: item.title }) : t("targetProjectAgents", { title: item.title })
|
|
540
|
+
}))),
|
|
541
|
+
{
|
|
542
|
+
key: "user-dsh",
|
|
543
|
+
source: "user-dsh",
|
|
544
|
+
workspacePath: void 0,
|
|
545
|
+
name: t("targetUserDsh")
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
key: "user-agents",
|
|
549
|
+
source: "user-agents",
|
|
550
|
+
workspacePath: void 0,
|
|
551
|
+
name: t("targetUserAgents")
|
|
552
|
+
}
|
|
553
|
+
];
|
|
478
554
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
479
555
|
style: {
|
|
480
556
|
display: "flex",
|
|
@@ -529,23 +605,33 @@ window.__ModuleLoader__.load({
|
|
|
529
605
|
listError
|
|
530
606
|
]
|
|
531
607
|
}) : null,
|
|
608
|
+
listState !== "error" && skillIssues.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
609
|
+
style: {
|
|
610
|
+
...descriptionStyle,
|
|
611
|
+
color: "var(--dsw-alias-state-warn-label)"
|
|
612
|
+
},
|
|
613
|
+
children: [
|
|
614
|
+
t("installedPartial", { count: skillIssues.length }),
|
|
615
|
+
" ",
|
|
616
|
+
skillIssues[0]?.message
|
|
617
|
+
]
|
|
618
|
+
}) : null,
|
|
532
619
|
listState === "idle" && skills.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
533
620
|
style: descriptionStyle,
|
|
534
621
|
children: t("installedEmpty")
|
|
535
622
|
}) : null,
|
|
536
623
|
skills.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
537
624
|
style: skillGroupsStyle,
|
|
538
|
-
children:
|
|
539
|
-
const rows = skills.filter((skill) => skill.source === source);
|
|
625
|
+
children: skillGroups.map((group) => {
|
|
626
|
+
const rows = skills.filter((skill) => skill.source === group.source && (!group.source.startsWith("project-") || skill.workspacePath === group.workspacePath));
|
|
540
627
|
if (rows.length === 0) return null;
|
|
541
|
-
const
|
|
542
|
-
const open = !collapsedSources.has(source);
|
|
628
|
+
const open = expandedGroups.has(group.key);
|
|
543
629
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
544
630
|
style: skillGroupCardStyle,
|
|
545
631
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
546
632
|
type: "button",
|
|
547
633
|
"aria-expanded": open,
|
|
548
|
-
onClick: () =>
|
|
634
|
+
onClick: () => toggleGroup(group.key),
|
|
549
635
|
style: {
|
|
550
636
|
...skillGroupHeaderStyle,
|
|
551
637
|
borderBottom: open ? skillGroupHeaderStyle.borderBottom : "none"
|
|
@@ -559,7 +645,7 @@ window.__ModuleLoader__.load({
|
|
|
559
645
|
style: skillGroupIdentityStyle,
|
|
560
646
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
561
647
|
style: skillGroupNameStyle,
|
|
562
|
-
children:
|
|
648
|
+
children: group.name
|
|
563
649
|
})
|
|
564
650
|
}),
|
|
565
651
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -607,10 +693,10 @@ window.__ModuleLoader__.load({
|
|
|
607
693
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TrashIcon, {})
|
|
608
694
|
})
|
|
609
695
|
]
|
|
610
|
-
}, skill.source + ":" + skill.name);
|
|
696
|
+
}, skill.source + ":" + (skill.workspacePath ?? "") + ":" + skill.name);
|
|
611
697
|
})
|
|
612
698
|
}) : null]
|
|
613
|
-
},
|
|
699
|
+
}, group.key);
|
|
614
700
|
})
|
|
615
701
|
}) : null
|
|
616
702
|
]
|
|
@@ -1014,17 +1100,28 @@ window.__ModuleLoader__.load({
|
|
|
1014
1100
|
style: fieldLabelStyle,
|
|
1015
1101
|
children: t("targetLabel")
|
|
1016
1102
|
}),
|
|
1017
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1103
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1104
|
+
type: "button",
|
|
1105
|
+
onClick: () => {
|
|
1106
|
+
setWorkspaceQuery("");
|
|
1107
|
+
setDraftTarget(target);
|
|
1108
|
+
setDraftWorkspaceId(selectedWorkspaceId);
|
|
1109
|
+
setLocationOpen(true);
|
|
1110
|
+
},
|
|
1111
|
+
style: locationSummaryStyle,
|
|
1112
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1113
|
+
style: {
|
|
1114
|
+
minWidth: 0,
|
|
1115
|
+
flex: 1,
|
|
1116
|
+
overflow: "hidden",
|
|
1117
|
+
textOverflow: "ellipsis",
|
|
1118
|
+
whiteSpace: "nowrap",
|
|
1119
|
+
textAlign: "left"
|
|
1120
|
+
},
|
|
1121
|
+
children: locationSummary
|
|
1122
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1123
|
+
style: secondaryButtonStyle,
|
|
1124
|
+
children: t("locationChange")
|
|
1028
1125
|
})]
|
|
1029
1126
|
}),
|
|
1030
1127
|
workspace === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1057,6 +1154,191 @@ window.__ModuleLoader__.load({
|
|
|
1057
1154
|
]
|
|
1058
1155
|
})
|
|
1059
1156
|
}),
|
|
1157
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1158
|
+
style: versionFooterStyle,
|
|
1159
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1160
|
+
style: versionCopyStyle,
|
|
1161
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1162
|
+
style: versionLabelStyle,
|
|
1163
|
+
children: updateStatus === void 0 ? t("versionChecking") : t("versionCurrent", { version: updateStatus.currentVersion })
|
|
1164
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1165
|
+
style: descriptionStyle,
|
|
1166
|
+
children: updateState === "checking" ? t("versionChecking") : updateState === "error" ? t("versionCheckFailed") : updateStatus?.updateAvailable === true ? t("versionAvailable", { version: updateStatus.latestVersion ?? "" }) : t("versionLatest")
|
|
1167
|
+
})]
|
|
1168
|
+
}), updateState === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1169
|
+
type: "button",
|
|
1170
|
+
onClick: checkForUpdates,
|
|
1171
|
+
style: pillStyle,
|
|
1172
|
+
children: t("versionRetry")
|
|
1173
|
+
}) : updateStatus?.updateAvailable === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1174
|
+
type: "button",
|
|
1175
|
+
onClick: () => {
|
|
1176
|
+
setCommandCopied(false);
|
|
1177
|
+
setUpdateDialogOpen(true);
|
|
1178
|
+
},
|
|
1179
|
+
style: updateButtonStyle,
|
|
1180
|
+
children: t("versionUpdate")
|
|
1181
|
+
}) : null]
|
|
1182
|
+
}),
|
|
1183
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1184
|
+
open: locationOpen,
|
|
1185
|
+
onClose: () => setLocationOpen(false),
|
|
1186
|
+
title: t("locationTitle"),
|
|
1187
|
+
closeLabel: t("close"),
|
|
1188
|
+
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1189
|
+
variant: "outline",
|
|
1190
|
+
onClick: () => setLocationOpen(false),
|
|
1191
|
+
children: t("cancel")
|
|
1192
|
+
}),
|
|
1193
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1194
|
+
style: locationPanelStyle,
|
|
1195
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1196
|
+
style: locationScopeStyle,
|
|
1197
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1198
|
+
type: "button",
|
|
1199
|
+
onClick: () => {
|
|
1200
|
+
if (!draftTarget.startsWith("project-")) setDraftTarget("project-dsh");
|
|
1201
|
+
},
|
|
1202
|
+
style: {
|
|
1203
|
+
...locationScopeButtonStyle,
|
|
1204
|
+
...draftTarget.startsWith("project-") ? locationScopeButtonActiveStyle : {}
|
|
1205
|
+
},
|
|
1206
|
+
children: t("locationProject")
|
|
1207
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1208
|
+
type: "button",
|
|
1209
|
+
onClick: () => {
|
|
1210
|
+
if (draftTarget.startsWith("project-")) setDraftTarget("user-dsh");
|
|
1211
|
+
},
|
|
1212
|
+
style: {
|
|
1213
|
+
...locationScopeButtonStyle,
|
|
1214
|
+
...!draftTarget.startsWith("project-") ? locationScopeButtonActiveStyle : {}
|
|
1215
|
+
},
|
|
1216
|
+
children: t("locationGlobal")
|
|
1217
|
+
})]
|
|
1218
|
+
}), draftTarget.startsWith("project-") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1219
|
+
type: "search",
|
|
1220
|
+
value: workspaceQuery,
|
|
1221
|
+
onChange: (event) => setWorkspaceQuery(event.target.value),
|
|
1222
|
+
placeholder: t("workspaceSearch"),
|
|
1223
|
+
style: controlStyle
|
|
1224
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1225
|
+
style: locationWorkspaceListStyle,
|
|
1226
|
+
children: [filteredWorkspaces.map((item) => {
|
|
1227
|
+
const selected = item.workspaceId === draftWorkspaceId;
|
|
1228
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1229
|
+
style: {
|
|
1230
|
+
...locationWorkspaceGroupStyle,
|
|
1231
|
+
...selected ? locationWorkspaceActiveStyle : {}
|
|
1232
|
+
},
|
|
1233
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1234
|
+
type: "button",
|
|
1235
|
+
onClick: (event) => {
|
|
1236
|
+
const group = event.currentTarget.parentElement;
|
|
1237
|
+
setDraftWorkspaceId(selected ? void 0 : item.workspaceId);
|
|
1238
|
+
if (!selected) window.requestAnimationFrame(() => group?.scrollIntoView({
|
|
1239
|
+
block: "nearest",
|
|
1240
|
+
behavior: "smooth"
|
|
1241
|
+
}));
|
|
1242
|
+
},
|
|
1243
|
+
style: locationWorkspaceStyle,
|
|
1244
|
+
"aria-expanded": selected,
|
|
1245
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1246
|
+
style: {
|
|
1247
|
+
minWidth: 0,
|
|
1248
|
+
flex: 1,
|
|
1249
|
+
display: "flex",
|
|
1250
|
+
flexDirection: "column",
|
|
1251
|
+
gap: 2
|
|
1252
|
+
},
|
|
1253
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1254
|
+
style: skillNameStyle,
|
|
1255
|
+
children: item.title
|
|
1256
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1257
|
+
style: skillDescriptionStyle,
|
|
1258
|
+
children: item.path
|
|
1259
|
+
})]
|
|
1260
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1261
|
+
style: skillGroupChevronStyle,
|
|
1262
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronIcon, { open: selected })
|
|
1263
|
+
})]
|
|
1264
|
+
}), selected ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1265
|
+
style: locationExpandedRootsStyle,
|
|
1266
|
+
children: [
|
|
1267
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1268
|
+
style: locationRootHintStyle,
|
|
1269
|
+
children: t("chooseRootHint")
|
|
1270
|
+
}),
|
|
1271
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1272
|
+
type: "button",
|
|
1273
|
+
onClick: () => chooseDestination("project-dsh", item.workspaceId),
|
|
1274
|
+
style: locationOptionStyle,
|
|
1275
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1276
|
+
style: locationOptionCopyStyle,
|
|
1277
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("rootProjectDsh") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
|
|
1278
|
+
style: descriptionStyle,
|
|
1279
|
+
children: ".dsh/skills"
|
|
1280
|
+
})]
|
|
1281
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1282
|
+
style: priorityHighStyle,
|
|
1283
|
+
children: t("priorityHighest")
|
|
1284
|
+
})]
|
|
1285
|
+
}),
|
|
1286
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1287
|
+
type: "button",
|
|
1288
|
+
onClick: () => chooseDestination("project-agents", item.workspaceId),
|
|
1289
|
+
style: locationOptionStyle,
|
|
1290
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1291
|
+
style: locationOptionCopyStyle,
|
|
1292
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("rootProjectAgents") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
|
|
1293
|
+
style: descriptionStyle,
|
|
1294
|
+
children: ".agents/skills"
|
|
1295
|
+
})]
|
|
1296
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1297
|
+
style: priorityMediumStyle,
|
|
1298
|
+
children: t("priorityHigher")
|
|
1299
|
+
})]
|
|
1300
|
+
})
|
|
1301
|
+
]
|
|
1302
|
+
}) : null]
|
|
1303
|
+
}, item.workspaceId);
|
|
1304
|
+
}), filteredWorkspaces.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1305
|
+
style: descriptionStyle,
|
|
1306
|
+
children: t("workspaceNoMatch")
|
|
1307
|
+
}) : null]
|
|
1308
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1309
|
+
style: locationRootsStyle,
|
|
1310
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1311
|
+
type: "button",
|
|
1312
|
+
onClick: () => chooseDestination("user-dsh"),
|
|
1313
|
+
style: locationOptionStyle,
|
|
1314
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1315
|
+
style: locationOptionCopyStyle,
|
|
1316
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("rootUserDsh") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
|
|
1317
|
+
style: descriptionStyle,
|
|
1318
|
+
children: "~/.dsh/skills"
|
|
1319
|
+
})]
|
|
1320
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1321
|
+
style: priorityLowStyle,
|
|
1322
|
+
children: t("priorityLower")
|
|
1323
|
+
})]
|
|
1324
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1325
|
+
type: "button",
|
|
1326
|
+
onClick: () => chooseDestination("user-agents"),
|
|
1327
|
+
style: locationOptionStyle,
|
|
1328
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1329
|
+
style: locationOptionCopyStyle,
|
|
1330
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("rootUserAgents") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
|
|
1331
|
+
style: descriptionStyle,
|
|
1332
|
+
children: "~/.agents/skills"
|
|
1333
|
+
})]
|
|
1334
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1335
|
+
style: priorityLowStyle,
|
|
1336
|
+
children: t("priorityLowest")
|
|
1337
|
+
})]
|
|
1338
|
+
})]
|
|
1339
|
+
})]
|
|
1340
|
+
})
|
|
1341
|
+
}),
|
|
1060
1342
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1061
1343
|
open: pendingDelete !== void 0,
|
|
1062
1344
|
onClose: () => {
|
|
@@ -1100,6 +1382,34 @@ window.__ModuleLoader__.load({
|
|
|
1100
1382
|
},
|
|
1101
1383
|
children: busy ? t("batchWorking") : t("batchCommit")
|
|
1102
1384
|
})] })
|
|
1385
|
+
}),
|
|
1386
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1387
|
+
open: updateDialogOpen,
|
|
1388
|
+
onClose: () => setUpdateDialogOpen(false),
|
|
1389
|
+
title: t("updateTitle"),
|
|
1390
|
+
closeLabel: t("close"),
|
|
1391
|
+
description: t("updateDescription"),
|
|
1392
|
+
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1393
|
+
variant: "outline",
|
|
1394
|
+
onClick: () => setUpdateDialogOpen(false),
|
|
1395
|
+
children: t("cancel")
|
|
1396
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1397
|
+
variant: "primary",
|
|
1398
|
+
onClick: () => {
|
|
1399
|
+
copyUpdateCommand();
|
|
1400
|
+
},
|
|
1401
|
+
children: commandCopied ? t("commandCopied") : t("copyCommand")
|
|
1402
|
+
})] }),
|
|
1403
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1404
|
+
style: updateDialogBodyStyle,
|
|
1405
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
1406
|
+
style: updateCommandStyle,
|
|
1407
|
+
children: updateStatus?.command
|
|
1408
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1409
|
+
style: descriptionStyle,
|
|
1410
|
+
children: t("restartHint")
|
|
1411
|
+
})]
|
|
1412
|
+
})
|
|
1103
1413
|
})
|
|
1104
1414
|
]
|
|
1105
1415
|
});
|
|
@@ -1128,6 +1438,58 @@ window.__ModuleLoader__.load({
|
|
|
1128
1438
|
lineHeight: "18px",
|
|
1129
1439
|
color: "var(--dsw-alias-label-caption)"
|
|
1130
1440
|
};
|
|
1441
|
+
const versionFooterStyle = {
|
|
1442
|
+
minHeight: 58,
|
|
1443
|
+
padding: "12px 0",
|
|
1444
|
+
display: "flex",
|
|
1445
|
+
alignItems: "center",
|
|
1446
|
+
gap: 12,
|
|
1447
|
+
borderTop: "1px solid var(--dsw-alias-border-l2)"
|
|
1448
|
+
};
|
|
1449
|
+
const versionCopyStyle = {
|
|
1450
|
+
flex: 1,
|
|
1451
|
+
minWidth: 0,
|
|
1452
|
+
display: "flex",
|
|
1453
|
+
flexDirection: "column",
|
|
1454
|
+
gap: 2
|
|
1455
|
+
};
|
|
1456
|
+
const versionLabelStyle = {
|
|
1457
|
+
fontSize: 12,
|
|
1458
|
+
lineHeight: "18px",
|
|
1459
|
+
fontWeight: 500,
|
|
1460
|
+
color: "var(--dsw-alias-label-secondary)"
|
|
1461
|
+
};
|
|
1462
|
+
const updateButtonStyle = {
|
|
1463
|
+
display: "inline-flex",
|
|
1464
|
+
alignItems: "center",
|
|
1465
|
+
height: 28,
|
|
1466
|
+
padding: "0 12px",
|
|
1467
|
+
border: "1px solid var(--dsw-alias-interactive-border-primary)",
|
|
1468
|
+
borderRadius: 14,
|
|
1469
|
+
background: "transparent",
|
|
1470
|
+
font: "inherit",
|
|
1471
|
+
fontSize: 13,
|
|
1472
|
+
borderColor: "var(--dsw-alias-interactive-border-primary)",
|
|
1473
|
+
color: "var(--dsw-alias-interactive-label-primary)",
|
|
1474
|
+
cursor: "pointer"
|
|
1475
|
+
};
|
|
1476
|
+
const updateDialogBodyStyle = {
|
|
1477
|
+
display: "flex",
|
|
1478
|
+
flexDirection: "column",
|
|
1479
|
+
gap: 10
|
|
1480
|
+
};
|
|
1481
|
+
const updateCommandStyle = {
|
|
1482
|
+
display: "block",
|
|
1483
|
+
padding: "10px 12px",
|
|
1484
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
1485
|
+
borderRadius: 8,
|
|
1486
|
+
background: "var(--dsw-alias-bg-module-platform)",
|
|
1487
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1488
|
+
fontSize: 12,
|
|
1489
|
+
lineHeight: "18px",
|
|
1490
|
+
whiteSpace: "pre-wrap",
|
|
1491
|
+
wordBreak: "break-all"
|
|
1492
|
+
};
|
|
1131
1493
|
const pillStyle = {
|
|
1132
1494
|
display: "inline-flex",
|
|
1133
1495
|
alignItems: "center",
|
|
@@ -1305,18 +1667,7 @@ window.__ModuleLoader__.load({
|
|
|
1305
1667
|
color: "var(--dsw-alias-label-primary)",
|
|
1306
1668
|
outline: "none"
|
|
1307
1669
|
};
|
|
1308
|
-
|
|
1309
|
-
* (same treatment as the composer chips / models page selects). */
|
|
1310
|
-
const selectStyle = {
|
|
1311
|
-
...controlStyle,
|
|
1312
|
-
appearance: "none",
|
|
1313
|
-
paddingRight: 32,
|
|
1314
|
-
backgroundImage: "url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2712%27 height=%2712%27 viewBox=%270 0 12 12%27 fill=%27none%27%3E%3Cpath d=%27M3 4.5L6 7.5L9 4.5%27 stroke=%27%2381858C%27 stroke-width=%271.5%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E\")",
|
|
1315
|
-
backgroundRepeat: "no-repeat",
|
|
1316
|
-
backgroundPosition: "right 12px center",
|
|
1317
|
-
backgroundSize: "12px 12px",
|
|
1318
|
-
cursor: "pointer"
|
|
1319
|
-
};
|
|
1670
|
+
({ ...controlStyle });
|
|
1320
1671
|
const entryGridStyle = {
|
|
1321
1672
|
display: "grid",
|
|
1322
1673
|
gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
|
|
@@ -1417,6 +1768,127 @@ window.__ModuleLoader__.load({
|
|
|
1417
1768
|
fontSize: 12,
|
|
1418
1769
|
lineHeight: "18px"
|
|
1419
1770
|
};
|
|
1771
|
+
const locationSummaryStyle = {
|
|
1772
|
+
...controlStyle,
|
|
1773
|
+
display: "flex",
|
|
1774
|
+
alignItems: "center",
|
|
1775
|
+
gap: 10,
|
|
1776
|
+
cursor: "pointer"
|
|
1777
|
+
};
|
|
1778
|
+
const locationPanelStyle = {
|
|
1779
|
+
display: "flex",
|
|
1780
|
+
flexDirection: "column",
|
|
1781
|
+
gap: 14,
|
|
1782
|
+
minWidth: 0
|
|
1783
|
+
};
|
|
1784
|
+
const locationScopeStyle = {
|
|
1785
|
+
display: "grid",
|
|
1786
|
+
gridTemplateColumns: "1fr 1fr",
|
|
1787
|
+
gap: 4,
|
|
1788
|
+
padding: 4,
|
|
1789
|
+
borderRadius: 10,
|
|
1790
|
+
background: "var(--dsw-alias-bg-module-platform)"
|
|
1791
|
+
};
|
|
1792
|
+
const locationScopeButtonStyle = {
|
|
1793
|
+
border: "none",
|
|
1794
|
+
borderRadius: 7,
|
|
1795
|
+
padding: "8px 12px",
|
|
1796
|
+
background: "transparent",
|
|
1797
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
1798
|
+
cursor: "pointer",
|
|
1799
|
+
fontWeight: 500
|
|
1800
|
+
};
|
|
1801
|
+
const locationScopeButtonActiveStyle = {
|
|
1802
|
+
background: "var(--dsw-alias-bg-layer-1)",
|
|
1803
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1804
|
+
boxShadow: "0 1px 3px rgba(0,0,0,.08)"
|
|
1805
|
+
};
|
|
1806
|
+
const locationWorkspaceListStyle = {
|
|
1807
|
+
display: "flex",
|
|
1808
|
+
flexDirection: "column",
|
|
1809
|
+
gap: 4,
|
|
1810
|
+
maxHeight: "min(440px, 52vh)",
|
|
1811
|
+
overflowY: "auto",
|
|
1812
|
+
scrollPadding: "8px 0"
|
|
1813
|
+
};
|
|
1814
|
+
const locationWorkspaceGroupStyle = {
|
|
1815
|
+
overflow: "hidden",
|
|
1816
|
+
borderRadius: 10,
|
|
1817
|
+
transition: "background 140ms ease"
|
|
1818
|
+
};
|
|
1819
|
+
const locationWorkspaceStyle = {
|
|
1820
|
+
width: "100%",
|
|
1821
|
+
display: "flex",
|
|
1822
|
+
alignItems: "center",
|
|
1823
|
+
gap: 8,
|
|
1824
|
+
border: "none",
|
|
1825
|
+
borderRadius: 8,
|
|
1826
|
+
padding: "9px 10px",
|
|
1827
|
+
background: "transparent",
|
|
1828
|
+
cursor: "pointer",
|
|
1829
|
+
textAlign: "left"
|
|
1830
|
+
};
|
|
1831
|
+
const locationWorkspaceActiveStyle = { background: "var(--dsw-alias-bg-module-platform)" };
|
|
1832
|
+
const locationExpandedRootsStyle = {
|
|
1833
|
+
display: "flex",
|
|
1834
|
+
flexDirection: "column",
|
|
1835
|
+
gap: 8,
|
|
1836
|
+
padding: "2px 10px 10px 18px"
|
|
1837
|
+
};
|
|
1838
|
+
const locationRootHintStyle = {
|
|
1839
|
+
fontSize: 11,
|
|
1840
|
+
lineHeight: "16px",
|
|
1841
|
+
fontWeight: 500,
|
|
1842
|
+
color: "var(--dsw-alias-label-tertiary)"
|
|
1843
|
+
};
|
|
1844
|
+
const locationRootsStyle = {
|
|
1845
|
+
display: "flex",
|
|
1846
|
+
flexDirection: "column",
|
|
1847
|
+
gap: 8
|
|
1848
|
+
};
|
|
1849
|
+
const locationOptionStyle = {
|
|
1850
|
+
display: "flex",
|
|
1851
|
+
alignItems: "center",
|
|
1852
|
+
gap: 12,
|
|
1853
|
+
width: "100%",
|
|
1854
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
1855
|
+
borderRadius: 10,
|
|
1856
|
+
padding: "10px 12px",
|
|
1857
|
+
background: "var(--dsw-alias-bg-layer-1)",
|
|
1858
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1859
|
+
cursor: "pointer",
|
|
1860
|
+
textAlign: "left"
|
|
1861
|
+
};
|
|
1862
|
+
const locationOptionCopyStyle = {
|
|
1863
|
+
minWidth: 0,
|
|
1864
|
+
flex: 1,
|
|
1865
|
+
display: "flex",
|
|
1866
|
+
flexDirection: "column",
|
|
1867
|
+
gap: 2
|
|
1868
|
+
};
|
|
1869
|
+
const priorityBaseStyle = {
|
|
1870
|
+
flex: "none",
|
|
1871
|
+
borderRadius: 999,
|
|
1872
|
+
padding: "2px 7px",
|
|
1873
|
+
fontSize: 11,
|
|
1874
|
+
lineHeight: "16px",
|
|
1875
|
+
fontWeight: 600
|
|
1876
|
+
};
|
|
1877
|
+
const priorityHighStyle = {
|
|
1878
|
+
...priorityBaseStyle,
|
|
1879
|
+
color: "var(--dsw-alias-state-success-primary)",
|
|
1880
|
+
background: "var(--dsw-alias-bg-module-platform)"
|
|
1881
|
+
};
|
|
1882
|
+
const priorityMediumStyle = {
|
|
1883
|
+
...priorityBaseStyle,
|
|
1884
|
+
color: "var(--dsw-alias-label-primary)",
|
|
1885
|
+
background: "var(--dsw-alias-bg-module-platform)"
|
|
1886
|
+
};
|
|
1887
|
+
const priorityLowStyle = {
|
|
1888
|
+
...priorityBaseStyle,
|
|
1889
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
1890
|
+
background: "var(--dsw-alias-bg-module-platform)"
|
|
1891
|
+
};
|
|
1420
1892
|
const previewStyle = {
|
|
1421
1893
|
display: "flex",
|
|
1422
1894
|
flexDirection: "column",
|
|
@@ -1640,18 +2112,43 @@ window.__ModuleLoader__.load({
|
|
|
1640
2112
|
}
|
|
1641
2113
|
}
|
|
1642
2114
|
/** One row of the composer skill picker. */
|
|
1643
|
-
function SkillsPicker({ t, sessionId,
|
|
1644
|
-
const skills = useSkills((value) => value);
|
|
2115
|
+
function SkillsPicker({ t, sessionId, useInput, inputActions, actions }) {
|
|
1645
2116
|
const input = useInput((value) => value.draft);
|
|
2117
|
+
const [skills, setSkills] = (0, react.useState)([]);
|
|
1646
2118
|
const [open, setOpen] = (0, react.useState)(false);
|
|
2119
|
+
const [loading, setLoading] = (0, react.useState)(true);
|
|
1647
2120
|
const [query, setQuery] = (0, react.useState)("");
|
|
1648
2121
|
const rootRef = (0, react.useRef)(null);
|
|
1649
2122
|
const draftRef = (0, react.useRef)(input);
|
|
1650
2123
|
const skillNamesRef = (0, react.useRef)([]);
|
|
1651
2124
|
const caretFrameRef = (0, react.useRef)();
|
|
1652
2125
|
(0, react.useEffect)(() => {
|
|
1653
|
-
|
|
1654
|
-
|
|
2126
|
+
let cancelled = false;
|
|
2127
|
+
const refresh = (showLoading) => {
|
|
2128
|
+
if (showLoading) setLoading(true);
|
|
2129
|
+
actions.refreshSkillsForSession(sessionId).then((rows) => {
|
|
2130
|
+
if (!cancelled) {
|
|
2131
|
+
setSkills(rows);
|
|
2132
|
+
setLoading(false);
|
|
2133
|
+
}
|
|
2134
|
+
}, () => {
|
|
2135
|
+
if (!cancelled) {
|
|
2136
|
+
setSkills([]);
|
|
2137
|
+
setLoading(false);
|
|
2138
|
+
}
|
|
2139
|
+
});
|
|
2140
|
+
};
|
|
2141
|
+
refresh(true);
|
|
2142
|
+
const timer = open ? window.setInterval(() => refresh(false), 2e3) : void 0;
|
|
2143
|
+
return () => {
|
|
2144
|
+
cancelled = true;
|
|
2145
|
+
if (timer !== void 0) window.clearInterval(timer);
|
|
2146
|
+
};
|
|
2147
|
+
}, [
|
|
2148
|
+
actions,
|
|
2149
|
+
sessionId,
|
|
2150
|
+
open
|
|
2151
|
+
]);
|
|
1655
2152
|
(0, react.useEffect)(() => {
|
|
1656
2153
|
if (!open) return;
|
|
1657
2154
|
const onDown = (event) => {
|
|
@@ -1727,7 +2224,6 @@ window.__ModuleLoader__.load({
|
|
|
1727
2224
|
if (caretFrameRef.current !== void 0) window.cancelAnimationFrame(caretFrameRef.current);
|
|
1728
2225
|
};
|
|
1729
2226
|
}, [inputActions]);
|
|
1730
|
-
if (usable.length === 0) return null;
|
|
1731
2227
|
const filtered = query.trim().length === 0 ? usable : usable.filter((skill) => skill.name.toLowerCase().includes(query.trim().toLowerCase()));
|
|
1732
2228
|
const onSelect = (name) => {
|
|
1733
2229
|
const prefix = `/${name} `;
|
|
@@ -1743,7 +2239,10 @@ window.__ModuleLoader__.load({
|
|
|
1743
2239
|
type: "button",
|
|
1744
2240
|
"aria-label": t("pickerLabel"),
|
|
1745
2241
|
"aria-expanded": open,
|
|
1746
|
-
onClick: () =>
|
|
2242
|
+
onClick: () => {
|
|
2243
|
+
if (!open) setLoading(true);
|
|
2244
|
+
setOpen((value) => !value);
|
|
2245
|
+
},
|
|
1747
2246
|
style: triggerStyle,
|
|
1748
2247
|
children: [
|
|
1749
2248
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1775,7 +2274,10 @@ window.__ModuleLoader__.load({
|
|
|
1775
2274
|
placeholder: t("pickerSearchPlaceholder"),
|
|
1776
2275
|
style: searchStyle
|
|
1777
2276
|
}),
|
|
1778
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
2277
|
+
loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2278
|
+
style: emptyStyle,
|
|
2279
|
+
children: t("pickerLoading")
|
|
2280
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
1779
2281
|
style: listStyle,
|
|
1780
2282
|
children: filtered.map((skill) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1781
2283
|
type: "button",
|
|
@@ -1785,13 +2287,19 @@ window.__ModuleLoader__.load({
|
|
|
1785
2287
|
style: avatarStyle,
|
|
1786
2288
|
"aria-hidden": "true",
|
|
1787
2289
|
children: skill.name.charAt(0).toUpperCase()
|
|
1788
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1789
|
-
style:
|
|
1790
|
-
children:
|
|
2290
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2291
|
+
style: rowCopyStyle,
|
|
2292
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2293
|
+
style: rowLabelStyle,
|
|
2294
|
+
children: skill.name
|
|
2295
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2296
|
+
style: rowDetailStyle,
|
|
2297
|
+
children: skill.source === "project-dsh" ? t("pickerSourceProjectDsh") : skill.source === "project-agents" ? t("pickerSourceProjectAgents") : skill.source === "user-dsh" ? t("pickerSourceUserDsh") : t("pickerSourceUserAgents")
|
|
2298
|
+
})]
|
|
1791
2299
|
})]
|
|
1792
2300
|
}) }, skill.name))
|
|
1793
2301
|
}),
|
|
1794
|
-
filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2302
|
+
!loading && filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1795
2303
|
style: emptyStyle,
|
|
1796
2304
|
children: t("pickerEmpty")
|
|
1797
2305
|
}) : null
|
|
@@ -1906,12 +2414,41 @@ window.__ModuleLoader__.load({
|
|
|
1906
2414
|
minWidth: 0,
|
|
1907
2415
|
overflow: "hidden"
|
|
1908
2416
|
};
|
|
2417
|
+
const rowCopyStyle = {
|
|
2418
|
+
display: "flex",
|
|
2419
|
+
flexDirection: "column",
|
|
2420
|
+
minWidth: 0,
|
|
2421
|
+
flex: 1,
|
|
2422
|
+
lineHeight: "18px"
|
|
2423
|
+
};
|
|
2424
|
+
const rowDetailStyle = {
|
|
2425
|
+
overflow: "hidden",
|
|
2426
|
+
textOverflow: "ellipsis",
|
|
2427
|
+
whiteSpace: "nowrap",
|
|
2428
|
+
color: "var(--dsw-alias-label-caption)",
|
|
2429
|
+
fontSize: 11,
|
|
2430
|
+
lineHeight: "16px"
|
|
2431
|
+
};
|
|
1909
2432
|
const emptyStyle = {
|
|
1910
2433
|
padding: "8px 10px",
|
|
1911
2434
|
fontSize: 12,
|
|
1912
2435
|
color: "var(--dsw-alias-label-caption)"
|
|
1913
2436
|
};
|
|
1914
2437
|
//#endregion
|
|
2438
|
+
//#region src/client/effectiveSkills.ts
|
|
2439
|
+
const SOURCE_RANK = {
|
|
2440
|
+
"project-dsh": 100,
|
|
2441
|
+
"project-agents": 200,
|
|
2442
|
+
"user-dsh": 400,
|
|
2443
|
+
"user-agents": 500
|
|
2444
|
+
};
|
|
2445
|
+
/** Mirror DSH's name-based winner selection for one session-scoped catalog. */
|
|
2446
|
+
function effectiveSkills(rows) {
|
|
2447
|
+
const winners = /* @__PURE__ */ new Map();
|
|
2448
|
+
for (const row of [...rows].sort((a, b) => SOURCE_RANK[a.source] - SOURCE_RANK[b.source])) if (!winners.has(row.name)) winners.set(row.name, row);
|
|
2449
|
+
return [...winners.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
2450
|
+
}
|
|
2451
|
+
//#endregion
|
|
1915
2452
|
//#region src/client/locales.ts
|
|
1916
2453
|
/**
|
|
1917
2454
|
* Locale dictionaries for the skill importer settings section.
|
|
@@ -1928,7 +2465,12 @@ window.__ModuleLoader__.load({
|
|
|
1928
2465
|
pickerLabel: "技能",
|
|
1929
2466
|
pickerPlaceholder: "技能",
|
|
1930
2467
|
pickerSearchPlaceholder: "筛选技能…",
|
|
2468
|
+
pickerLoading: "正在同步当前项目技能…",
|
|
1931
2469
|
pickerEmpty: "没有匹配的技能",
|
|
2470
|
+
pickerSourceProjectDsh: "当前项目 · .dsh",
|
|
2471
|
+
pickerSourceProjectAgents: "当前项目 · .agents",
|
|
2472
|
+
pickerSourceUserDsh: "全局 · .dsh",
|
|
2473
|
+
pickerSourceUserAgents: "全局 · .agents",
|
|
1932
2474
|
commandDescription: "选择技能:弹出技能列表,选中后填入 /<名称>",
|
|
1933
2475
|
entryTitle: "技能入口",
|
|
1934
2476
|
entryDescription: "通过输入框工具行的技能下拉或 /skills 命令选择技能;也可直接输入 /<名称>。选中的技能会高亮并注入指令。",
|
|
@@ -1944,6 +2486,7 @@ window.__ModuleLoader__.load({
|
|
|
1944
2486
|
deleteFailed: "删除失败",
|
|
1945
2487
|
deleted: "已删除。",
|
|
1946
2488
|
installedFailed: "无法读取技能列表",
|
|
2489
|
+
installedPartial: "有 {count} 个技能目录暂时无法读取,其他技能已正常显示。",
|
|
1947
2490
|
userOnly: "仅斜杠可用",
|
|
1948
2491
|
modelOnly: "仅模型可用",
|
|
1949
2492
|
importTitle: "导入技能",
|
|
@@ -1994,15 +2537,48 @@ window.__ModuleLoader__.load({
|
|
|
1994
2537
|
batchStatusSkipped: "已跳过",
|
|
1995
2538
|
batchStatusError: "失败",
|
|
1996
2539
|
targetLabel: "安装到",
|
|
1997
|
-
|
|
1998
|
-
targetProjectAgents: "
|
|
2540
|
+
targetProjectDsh: "DSH 项目技能({title})",
|
|
2541
|
+
targetProjectAgents: "通用项目技能({title})",
|
|
2542
|
+
targetUserDsh: "DSH 全局技能",
|
|
2543
|
+
targetUserAgents: "通用全局技能",
|
|
2544
|
+
locationChange: "更改",
|
|
2545
|
+
locationTitle: "选择安装位置",
|
|
2546
|
+
locationProject: "项目技能",
|
|
2547
|
+
locationGlobal: "全局技能",
|
|
2548
|
+
workspaceSearch: "搜索工作区…",
|
|
2549
|
+
workspaceNoMatch: "没有匹配的工作区",
|
|
2550
|
+
chooseRootHint: "选择技能目录",
|
|
2551
|
+
rootProjectDsh: "DSH 项目技能",
|
|
2552
|
+
rootProjectAgents: "通用项目技能",
|
|
2553
|
+
rootUserDsh: "DSH 全局技能",
|
|
2554
|
+
rootUserAgents: "通用全局技能",
|
|
2555
|
+
priorityHighest: "最高",
|
|
2556
|
+
priorityHigher: "较高",
|
|
2557
|
+
priorityLower: "较低",
|
|
2558
|
+
priorityLowest: "最低",
|
|
2559
|
+
locationSummaryProjectDsh: "项目技能 · {title} · .dsh/skills",
|
|
2560
|
+
locationSummaryProjectAgents: "项目技能 · {title} · .agents/skills",
|
|
2561
|
+
locationSummaryUserDsh: "全局技能 · ~/.dsh/skills",
|
|
2562
|
+
locationSummaryUserAgents: "全局技能 · ~/.agents/skills",
|
|
1999
2563
|
targetProjectNoWorkspace: "项目技能(需先添加工作区)",
|
|
2000
2564
|
noWorkspace: "未注册工作区:请先在会话页选择/创建工作区,或改用用户技能目录。",
|
|
2001
2565
|
import: "导入",
|
|
2002
2566
|
importing: "导入中…",
|
|
2003
2567
|
imported: "已写入:",
|
|
2004
2568
|
importFailed: "导入失败",
|
|
2005
|
-
hostUnreachable: "无法连接 dsh 服务(插件路由未生效)。请确认插件已安装,并重启 dsh web 后刷新页面。"
|
|
2569
|
+
hostUnreachable: "无法连接 dsh 服务(插件路由未生效)。请确认插件已安装,并重启 dsh web 后刷新页面。",
|
|
2570
|
+
versionChecking: "正在检查更新…",
|
|
2571
|
+
versionCurrent: "当前版本 v{version}",
|
|
2572
|
+
versionLatest: "已是最新版本",
|
|
2573
|
+
versionAvailable: "发现新版本 v{version}",
|
|
2574
|
+
versionCheckFailed: "暂时无法检查更新",
|
|
2575
|
+
versionRetry: "重试",
|
|
2576
|
+
versionUpdate: "更新",
|
|
2577
|
+
updateTitle: "更新 dsh-skill-importer",
|
|
2578
|
+
updateDescription: "复制下面的精确版本命令,在终端运行后重启 dsh web。",
|
|
2579
|
+
copyCommand: "复制更新命令",
|
|
2580
|
+
commandCopied: "已复制",
|
|
2581
|
+
restartHint: "更新完成后需要重启 dsh web 才会生效。"
|
|
2006
2582
|
};
|
|
2007
2583
|
/** English dictionary, checked complete against the zh key set. */
|
|
2008
2584
|
const en = {
|
|
@@ -2010,7 +2586,12 @@ window.__ModuleLoader__.load({
|
|
|
2010
2586
|
pickerLabel: "Skills",
|
|
2011
2587
|
pickerPlaceholder: "Skills",
|
|
2012
2588
|
pickerSearchPlaceholder: "Filter skills…",
|
|
2589
|
+
pickerLoading: "Syncing skills for the current project…",
|
|
2013
2590
|
pickerEmpty: "No matching skills",
|
|
2591
|
+
pickerSourceProjectDsh: "Current project · .dsh",
|
|
2592
|
+
pickerSourceProjectAgents: "Current project · .agents",
|
|
2593
|
+
pickerSourceUserDsh: "Global · .dsh",
|
|
2594
|
+
pickerSourceUserAgents: "Global · .agents",
|
|
2014
2595
|
commandDescription: "Pick a skill: opens a popup list; selecting fills /<name>",
|
|
2015
2596
|
entryTitle: "Skill entry points",
|
|
2016
2597
|
entryDescription: "Pick a skill from the composer tool-row dropdown or the /skills command; or type /<name> directly. The picked skill is highlighted and its instructions are injected.",
|
|
@@ -2026,6 +2607,7 @@ window.__ModuleLoader__.load({
|
|
|
2026
2607
|
deleteFailed: "Failed to delete",
|
|
2027
2608
|
deleted: "Deleted.",
|
|
2028
2609
|
installedFailed: "Unable to read the skill list",
|
|
2610
|
+
installedPartial: "{count} skill directories are temporarily unreadable; other skills are still shown.",
|
|
2029
2611
|
userOnly: "Slash only",
|
|
2030
2612
|
modelOnly: "Model only",
|
|
2031
2613
|
importTitle: "Import a skill",
|
|
@@ -2076,15 +2658,48 @@ window.__ModuleLoader__.load({
|
|
|
2076
2658
|
batchStatusSkipped: "Skipped",
|
|
2077
2659
|
batchStatusError: "Failed",
|
|
2078
2660
|
targetLabel: "Install into",
|
|
2079
|
-
|
|
2080
|
-
targetProjectAgents: "
|
|
2661
|
+
targetProjectDsh: "DSH project skills ({title})",
|
|
2662
|
+
targetProjectAgents: "Shared project skills ({title})",
|
|
2663
|
+
targetUserDsh: "DSH global skills",
|
|
2664
|
+
targetUserAgents: "Shared global skills",
|
|
2665
|
+
locationChange: "Change",
|
|
2666
|
+
locationTitle: "Choose install location",
|
|
2667
|
+
locationProject: "Project skills",
|
|
2668
|
+
locationGlobal: "Global skills",
|
|
2669
|
+
workspaceSearch: "Search workspaces…",
|
|
2670
|
+
workspaceNoMatch: "No matching workspaces",
|
|
2671
|
+
chooseRootHint: "Choose a skill directory",
|
|
2672
|
+
rootProjectDsh: "DSH project skills",
|
|
2673
|
+
rootProjectAgents: "Shared project skills",
|
|
2674
|
+
rootUserDsh: "DSH global skills",
|
|
2675
|
+
rootUserAgents: "Shared global skills",
|
|
2676
|
+
priorityHighest: "Highest",
|
|
2677
|
+
priorityHigher: "Higher",
|
|
2678
|
+
priorityLower: "Lower",
|
|
2679
|
+
priorityLowest: "Lowest",
|
|
2680
|
+
locationSummaryProjectDsh: "Project · {title} · .dsh/skills",
|
|
2681
|
+
locationSummaryProjectAgents: "Project · {title} · .agents/skills",
|
|
2682
|
+
locationSummaryUserDsh: "Global · ~/.dsh/skills",
|
|
2683
|
+
locationSummaryUserAgents: "Global · ~/.agents/skills",
|
|
2081
2684
|
targetProjectNoWorkspace: "Project skills (add a workspace first)",
|
|
2082
2685
|
noWorkspace: "No registered workspace: create/select one in a session, or use the user skill directory.",
|
|
2083
2686
|
import: "Import",
|
|
2084
2687
|
importing: "Importing…",
|
|
2085
2688
|
imported: "Written to: ",
|
|
2086
2689
|
importFailed: "Import failed",
|
|
2087
|
-
hostUnreachable: "Cannot reach the dsh service (plugin routes are not active). Make sure the plugin is installed, restart dsh web, and refresh the page."
|
|
2690
|
+
hostUnreachable: "Cannot reach the dsh service (plugin routes are not active). Make sure the plugin is installed, restart dsh web, and refresh the page.",
|
|
2691
|
+
versionChecking: "Checking for updates…",
|
|
2692
|
+
versionCurrent: "Current version v{version}",
|
|
2693
|
+
versionLatest: "Up to date",
|
|
2694
|
+
versionAvailable: "Version v{version} is available",
|
|
2695
|
+
versionCheckFailed: "Unable to check for updates",
|
|
2696
|
+
versionRetry: "Retry",
|
|
2697
|
+
versionUpdate: "Update",
|
|
2698
|
+
updateTitle: "Update dsh-skill-importer",
|
|
2699
|
+
updateDescription: "Copy this exact-version command, run it in a terminal, then restart dsh web.",
|
|
2700
|
+
copyCommand: "Copy update command",
|
|
2701
|
+
commandCopied: "Copied",
|
|
2702
|
+
restartHint: "Restart dsh web after the update for it to take effect."
|
|
2088
2703
|
};
|
|
2089
2704
|
//#endregion
|
|
2090
2705
|
//#region src/client/index.ts
|
|
@@ -2101,7 +2716,8 @@ window.__ModuleLoader__.load({
|
|
|
2101
2716
|
importUrl: "/skill-importer/import-url",
|
|
2102
2717
|
delete: "/skill-importer/delete",
|
|
2103
2718
|
batchScan: "/skill-importer/batch/scan",
|
|
2104
|
-
batchCommit: "/skill-importer/batch/commit"
|
|
2719
|
+
batchCommit: "/skill-importer/batch/commit",
|
|
2720
|
+
updateStatus: "/skill-importer/update-status"
|
|
2105
2721
|
};
|
|
2106
2722
|
/** Fetch one route and unwrap the JSON envelope; throws on transport/HTTP errors. */
|
|
2107
2723
|
async function call(path, body) {
|
|
@@ -2134,7 +2750,10 @@ window.__ModuleLoader__.load({
|
|
|
2134
2750
|
en
|
|
2135
2751
|
}), "dsh-skill-importer: dictionaries");
|
|
2136
2752
|
const t = ctx.locale.bind(NS);
|
|
2753
|
+
const sourceLabel = (source) => source === "project-dsh" ? t("pickerSourceProjectDsh") : source === "project-agents" ? t("pickerSourceProjectAgents") : source === "user-dsh" ? t("pickerSourceUserDsh") : t("pickerSourceUserAgents");
|
|
2137
2754
|
let catalog = [];
|
|
2755
|
+
let issues = [];
|
|
2756
|
+
const sessionCatalogs = /* @__PURE__ */ new Map();
|
|
2138
2757
|
const listeners = /* @__PURE__ */ new Set();
|
|
2139
2758
|
const notify = () => {
|
|
2140
2759
|
for (const listener of [...listeners]) try {
|
|
@@ -2149,7 +2768,7 @@ window.__ModuleLoader__.load({
|
|
|
2149
2768
|
skillsApi.list = ((_request, _signal) => {
|
|
2150
2769
|
return Promise.reject(/* @__PURE__ */ new Error("skill group hidden: use the composer skill picker or /skills"));
|
|
2151
2770
|
});
|
|
2152
|
-
const usableNames = () =>
|
|
2771
|
+
const usableNames = () => [...new Set([...sessionCatalogs.values()].flat().filter((skill) => skill.userInvocable).map((skill) => skill.name))];
|
|
2153
2772
|
ctx.effect(() => {
|
|
2154
2773
|
return ctx.get("inputTriggers").registerSource({
|
|
2155
2774
|
trigger: "/",
|
|
@@ -2181,10 +2800,10 @@ window.__ModuleLoader__.load({
|
|
|
2181
2800
|
available: () => true,
|
|
2182
2801
|
ui: {
|
|
2183
2802
|
kind: "popupSelect",
|
|
2184
|
-
async options(
|
|
2185
|
-
return
|
|
2803
|
+
async options(session, _signal) {
|
|
2804
|
+
return (await refreshSkillsForSession(session.sessionId)).filter((skill) => skill.userInvocable).map((skill) => ({
|
|
2186
2805
|
id: skill.name,
|
|
2187
|
-
label: skill.name
|
|
2806
|
+
label: `${skill.name} · ${sourceLabel(skill.source)}`
|
|
2188
2807
|
}));
|
|
2189
2808
|
},
|
|
2190
2809
|
onSelect(option, session) {
|
|
@@ -2204,11 +2823,20 @@ window.__ModuleLoader__.load({
|
|
|
2204
2823
|
}
|
|
2205
2824
|
});
|
|
2206
2825
|
}, "dsh-skill-importer: /skills popupSelect command");
|
|
2207
|
-
const refreshSkills = async () => {
|
|
2208
|
-
|
|
2826
|
+
const refreshSkills = async (workspacePath) => {
|
|
2827
|
+
const result = await call(workspacePath === void 0 ? ROUTES.list : `${ROUTES.list}?workspacePath=${encodeURIComponent(workspacePath)}`);
|
|
2828
|
+
catalog = result.skills;
|
|
2829
|
+
issues = result.issues;
|
|
2209
2830
|
notify();
|
|
2210
2831
|
return catalog;
|
|
2211
2832
|
};
|
|
2833
|
+
const refreshSkillsForSession = async (sessionId) => {
|
|
2834
|
+
const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd;
|
|
2835
|
+
const effective = effectiveSkills((await call(cwd === void 0 ? `${ROUTES.list}?scope=global` : `${ROUTES.list}?workspacePath=${encodeURIComponent(cwd)}`)).skills);
|
|
2836
|
+
sessionCatalogs.set(sessionId, effective);
|
|
2837
|
+
notify();
|
|
2838
|
+
return effective;
|
|
2839
|
+
};
|
|
2212
2840
|
const importSkill = async (request) => {
|
|
2213
2841
|
return (await call(ROUTES.import, request)).path;
|
|
2214
2842
|
};
|
|
@@ -2225,24 +2853,38 @@ window.__ModuleLoader__.load({
|
|
|
2225
2853
|
};
|
|
2226
2854
|
const scanBatch = (request) => call(ROUTES.batchScan, request);
|
|
2227
2855
|
const commitBatch = (request) => call(ROUTES.batchCommit, request);
|
|
2856
|
+
const checkForUpdates = () => call(ROUTES.updateStatus);
|
|
2228
2857
|
const face = () => ({
|
|
2229
|
-
hooks: {
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2858
|
+
hooks: {
|
|
2859
|
+
skills: {
|
|
2860
|
+
getSnapshot: () => catalog,
|
|
2861
|
+
subscribe: (listener) => {
|
|
2862
|
+
listeners.add(listener);
|
|
2863
|
+
return () => {
|
|
2864
|
+
listeners.delete(listener);
|
|
2865
|
+
};
|
|
2866
|
+
}
|
|
2867
|
+
},
|
|
2868
|
+
skillIssues: {
|
|
2869
|
+
getSnapshot: () => issues,
|
|
2870
|
+
subscribe: (listener) => {
|
|
2871
|
+
listeners.add(listener);
|
|
2872
|
+
return () => {
|
|
2873
|
+
listeners.delete(listener);
|
|
2874
|
+
};
|
|
2875
|
+
}
|
|
2236
2876
|
}
|
|
2237
|
-
}
|
|
2877
|
+
},
|
|
2238
2878
|
actions: {
|
|
2239
2879
|
refreshSkills,
|
|
2880
|
+
refreshSkillsForSession,
|
|
2240
2881
|
importSkill,
|
|
2241
2882
|
importUrl,
|
|
2242
2883
|
deleteSkill,
|
|
2243
2884
|
pickDirectory,
|
|
2244
2885
|
scanBatch,
|
|
2245
|
-
commitBatch
|
|
2886
|
+
commitBatch,
|
|
2887
|
+
checkForUpdates
|
|
2246
2888
|
}
|
|
2247
2889
|
});
|
|
2248
2890
|
ctx.slots.inject("settings.section", () => ctx.slots.register({
|