@dungsil/dsh-plugin-ui-setting-skills 0.0.0-stage → 0.2.0

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.
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: dungsil-ui-setting-skills
3
+ name: '@dungsil/dsh-plugin-ui-setting-skills'
package/dist/client.js ADDED
@@ -0,0 +1,272 @@
1
+ window.__ModuleLoader__.load({ id: "@dungsil/dsh-plugin-ui-setting-skills", factory(require) { const module = { exports: {} }; const exports = module.exports;
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ let react = require("react");
4
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
5
+ let react_jsx_runtime = require("react/jsx-runtime");
6
+ // locale/en.json
7
+ var en_default = {
8
+ meta: {
9
+ "title": "Skills Settings",
10
+ "description": "View loaded user skills in settings."
11
+ },
12
+ ui: {
13
+ "nav": "Skills",
14
+ "description": "This setting applies only to DSH.",
15
+ "agents": "Shared skills",
16
+ "dsh": "DSH skills",
17
+ "loading": "Loading skills…",
18
+ "empty": "No loaded skills from this source.",
19
+ "error": "Could not load skills. Close and reopen this settings section to try again.",
20
+ "incomplete": "Some skill sources could not be loaded. This list may be incomplete.",
21
+ "use": "Use",
22
+ "disabled": "Off",
23
+ "saveError": "Could not save the setting. Close and reopen this section to check the saved state before trying again."
24
+ }
25
+ };
26
+ // locale/ko.json
27
+ var ko_default = {
28
+ meta: {
29
+ "title": "스킬 설정",
30
+ "description": "설정 화면에서 로드된 사용자 스킬을 확인합니다."
31
+ },
32
+ ui: {
33
+ "nav": "스킬",
34
+ "description": "이 설정은 DSH에만 적용됩니다.",
35
+ "agents": "공용 스킬",
36
+ "dsh": "DSH 스킬",
37
+ "loading": "스킬을 불러오는 중입니다…",
38
+ "empty": "이 경로에서 로드된 스킬이 없습니다.",
39
+ "error": "스킬을 불러오지 못했습니다. 이 설정 항목을 닫았다가 다시 열어 주세요.",
40
+ "incomplete": "일부 스킬 소스를 불러오지 못해 목록이 완전하지 않을 수 있습니다.",
41
+ "use": "사용",
42
+ "disabled": "꺼짐",
43
+ "saveError": "설정을 저장하지 못했습니다. 이 설정 항목을 닫았다가 다시 열어 저장 상태를 확인한 후 다시 시도해 주세요."
44
+ }
45
+ };
46
+ // locale/zh.json
47
+ var zh_default = {
48
+ meta: {
49
+ "title": "技能设置",
50
+ "description": "在设置中查看已加载的用户技能。"
51
+ },
52
+ ui: {
53
+ "nav": "技能",
54
+ "description": "此设置仅适用于 DSH。",
55
+ "agents": "共享技能",
56
+ "dsh": "DSH 技能",
57
+ "loading": "正在加载技能…",
58
+ "empty": "未从此目录加载任何技能。",
59
+ "error": "无法加载技能。请关闭并重新打开此设置项后重试。",
60
+ "incomplete": "部分技能源无法加载,列表可能不完整。",
61
+ "use": "使用",
62
+ "disabled": "已关闭",
63
+ "saveError": "无法保存设置。请关闭并重新打开此设置项,确认已保存的状态后重试。"
64
+ }
65
+ };
66
+ // src/protocol.ts
67
+ const channel = "/api";
68
+ const method = "dungsil-ui-setting-skills/list";
69
+ const saveMethod = "dungsil-ui-setting-skills/save";
70
+ // src/client.tsx
71
+ const name = "dungsil-ui-setting-skills";
72
+ const inject = [
73
+ "connection",
74
+ "locale",
75
+ "slots"
76
+ ];
77
+ const localizedCopy = (language) => (language.startsWith("ko") ? ko_default : language.startsWith("zh") ? zh_default : en_default).ui;
78
+ const styles = `
79
+ .dsh-skills-settings { container-type: inline-size; color: var(--dsw-alias-label-primary); font: 14px/22px var(--dsw-font-family, system-ui); }
80
+ .dsh-skills-settings p { margin: 4px 0; }
81
+ .dsh-skills-settings-tabs { margin: 20px 0 12px; }
82
+ .dsh-skills-settings .dsh-skills-muted { color: var(--dsw-alias-label-secondary); }
83
+ .dsh-skills-settings ul { list-style: none; margin: 0; padding: 0; }
84
+ .dsh-skills-settings code { font-size: 12px; overflow-wrap: anywhere; }
85
+ .dsh-skills-settings [role=alert] { color: var(--dsw-alias-state-error-primary, #b54424); }
86
+ .dsh-skills-settings li { display: flex; align-items: flex-start; gap: 16px; border-bottom: .5px solid var(--dsw-alias-border-l2); }
87
+ .dsh-skills-settings details { flex: 1; min-width: 0; }
88
+ .dsh-skills-settings summary { display: flex; align-items: center; gap: 12px; padding: 16px 0; list-style: none; cursor: pointer; border-radius: var(--dsw-radius-md); }
89
+ .dsh-skills-settings summary::-webkit-details-marker { display: none; }
90
+ .dsh-skills-settings summary:hover { background: var(--dsw-alias-interactive-bg-hover); }
91
+ .dsh-skills-settings summary:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary-new-colorprimary-new-color); outline-offset: 2px; }
92
+ .dsh-skills-settings summary svg { flex: none; }
93
+ .dsh-skills-settings details[open] summary svg { transform: rotate(90deg); }
94
+ .dsh-skills-summary-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
95
+ .dsh-skills-title { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
96
+ .dsh-skills-title strong { min-width: 0; overflow-wrap: anywhere; }
97
+ .dsh-skills-title .dsh-skills-muted { flex: none; font-size: 12px; }
98
+ .dsh-skills-preview { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
99
+ .dsh-skills-detail { padding: 0 0 16px 28px; overflow-wrap: anywhere; }
100
+ .dsh-skills-toggle { flex: none; padding-top: 27px; }
101
+ .dsh-skills-list-header { display: flex; justify-content: space-between; gap: 16px; padding: 8px 0; border-bottom: .5px solid var(--dsw-alias-border-l2); }
102
+ `;
103
+ function SkillsSettings({ ctx }) {
104
+ const locale = (0, react.useSyncExternalStore)((listener) => ctx.locale.subscribe(listener), () => ctx.locale.getSnapshot());
105
+ const text = localizedCopy(locale.active);
106
+ const id = (0, react.useId)();
107
+ const connection = ctx.get("connection");
108
+ const [view, setView] = (0, react.useState)();
109
+ const [error, setError] = (0, react.useState)(false);
110
+ const [saveError, setSaveError] = (0, react.useState)(false);
111
+ const [busy, setBusy] = (0, react.useState)(false);
112
+ const pending = (0, react.useRef)(false);
113
+ const mounted = (0, react.useRef)(false);
114
+ const [source, setSource] = (0, react.useState)("user-agents");
115
+ const groups = ["user-agents", "user-dsh"].map((value) => ({
116
+ value,
117
+ label: value === "user-agents" ? text.agents : text.dsh,
118
+ skills: view?.skills.filter((skill) => skill.source === value) ?? []
119
+ }));
120
+ (0, react.useEffect)(() => {
121
+ const controller = new AbortController();
122
+ mounted.current = true;
123
+ setView(void 0);
124
+ setError(false);
125
+ (async () => {
126
+ try {
127
+ const result = await connection.rpc.call(channel, method, {}, controller.signal);
128
+ if (controller.signal.aborted) return;
129
+ if (!result.ok) throw new Error("Could not load skills");
130
+ setView(result.value);
131
+ } catch {
132
+ if (!controller.signal.aborted) setError(true);
133
+ }
134
+ })();
135
+ return () => {
136
+ mounted.current = false;
137
+ controller.abort();
138
+ };
139
+ }, [connection]);
140
+ async function save(name, disabled) {
141
+ if (pending.current) return;
142
+ pending.current = true;
143
+ setBusy(true);
144
+ setSaveError(false);
145
+ try {
146
+ const result = await connection.rpc.call(channel, saveMethod, {
147
+ name,
148
+ disabled
149
+ });
150
+ if (!result.ok) throw new Error("Could not save skills");
151
+ const value = result.value;
152
+ if (mounted.current) setView((current) => current && {
153
+ ...current,
154
+ disabled: value.disabled
155
+ });
156
+ } catch {
157
+ if (mounted.current) setSaveError(true);
158
+ } finally {
159
+ pending.current = false;
160
+ if (mounted.current) setBusy(false);
161
+ }
162
+ }
163
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
164
+ className: "dsh-skills-settings",
165
+ "aria-label": text.nav,
166
+ "aria-busy": !view && !error,
167
+ children: [
168
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
169
+ className: "dsh-skills-muted",
170
+ children: text.description
171
+ }),
172
+ !view && !error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
173
+ role: "status",
174
+ children: text.loading
175
+ }),
176
+ error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
177
+ role: "alert",
178
+ children: text.error
179
+ }),
180
+ saveError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
181
+ role: "alert",
182
+ children: text.saveError
183
+ }),
184
+ view && !view.complete && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
185
+ role: "alert",
186
+ children: text.incomplete
187
+ }),
188
+ view && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SegmentedControl, {
189
+ id,
190
+ className: "dsh-skills-settings-tabs",
191
+ value: source,
192
+ options: groups.map((group) => ({
193
+ value: group.value,
194
+ label: `${group.label} ${group.skills.length}`
195
+ })),
196
+ onChange: setSource,
197
+ label: text.nav
198
+ }), groups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
199
+ id: `${id}-${group.value}-panel`,
200
+ role: "tabpanel",
201
+ "aria-labelledby": `${id}-${group.value}`,
202
+ hidden: source !== group.value,
203
+ tabIndex: 0,
204
+ children: group.skills.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
205
+ className: "dsh-skills-muted",
206
+ children: text.empty
207
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
208
+ className: "dsh-skills-list-header dsh-skills-muted",
209
+ "aria-hidden": "true",
210
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
211
+ text.nav,
212
+ " ",
213
+ group.skills.length
214
+ ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: text.use })]
215
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", { children: group.skills.map((skill) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
216
+ "aria-label": skill.name,
217
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, {
218
+ size: 16,
219
+ "aria-hidden": "true"
220
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
221
+ className: "dsh-skills-summary-text",
222
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
223
+ className: "dsh-skills-title",
224
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: skill.name }), view.disabled.includes(skill.name) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
225
+ className: "dsh-skills-muted",
226
+ children: text.disabled
227
+ })]
228
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
229
+ className: "dsh-skills-preview dsh-skills-muted",
230
+ "aria-hidden": "true",
231
+ children: skill.description
232
+ })]
233
+ })]
234
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
235
+ className: "dsh-skills-detail",
236
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: skill.description }), skill.path && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
237
+ className: "dsh-skills-muted",
238
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: skill.path })
239
+ })]
240
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
241
+ className: "dsh-skills-toggle",
242
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
243
+ label: `${text.use}: ${skill.name}`,
244
+ checked: !view.disabled.includes(skill.name),
245
+ disabled: busy || saveError,
246
+ onChange: (enabled) => void save(skill.name, !enabled)
247
+ })
248
+ })] }, skill.path ?? skill.name)) })] })
249
+ }, group.value))] })
250
+ ]
251
+ });
252
+ }
253
+ function apply(ctx) {
254
+ ctx.effect(() => {
255
+ const style = document.createElement("style");
256
+ style.textContent = styles;
257
+ document.head.append(style);
258
+ return () => style.remove();
259
+ }, "ui-setting-skills: styles");
260
+ ctx.slots.inject("settings.section", () => ctx.slots.register({
261
+ name: "settings.section",
262
+ id: name,
263
+ order: 16,
264
+ label: () => localizedCopy(ctx.locale.getSnapshot().active).nav,
265
+ inject: () => ({ ctx })
266
+ }, SkillsSettings));
267
+ }
268
+ exports.apply = apply;
269
+ exports.inject = inject;
270
+ exports.name = name;
271
+
272
+ return module.exports; } });