dsh-plugin-settings-custom 1.0.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.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # dsh-plugin-settings-custom
2
+
3
+ 设置页“自定义”页签(容器)。提供一个 .dsh-custom-host 容器,供 dsh-plugin-global-instructions / skill-manager / mcp-manager 三个插件的面板挂载。
@@ -0,0 +1,4 @@
1
+ # dsh-plugin-settings-custom —— DSH bundle patch
2
+ - insert:
3
+ - id: dsh-plugin-settings-custom
4
+ name: dsh-plugin-settings-custom
package/lib/client.js ADDED
@@ -0,0 +1,404 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-plugin-settings-custom",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
+ let react = require("react");
9
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
10
+ let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
11
+ //#region locales
12
+ /** Simplified Chinese dictionary (key-set source of truth). */
13
+ const zh = {
14
+ "nav": "自定义",
15
+ "global.title": "全局指令(AGENTS.md)",
16
+ "global.description": "写入此文件的内容会自动注入到所有会话的系统提示中,新消息立即生效,支持 Markdown。",
17
+ "global.placeholder": "# 全局指令\n\n在这里写入对所有对话都生效的规则、偏好或背景信息…",
18
+ "global.save": "保存",
19
+ "global.saving": "保存中…",
20
+ "global.saved": "已保存 ✓",
21
+ "global.loadFailed": "读取失败:{msg}",
22
+ "global.saveFailed": "保存失败:{msg}",
23
+ "skills.title": "技能(Skills)",
24
+ "skills.description": "管理已安装的技能:启用、停用或删除。停用后模型将无法调用该技能。",
25
+ "skills.empty": "暂无已安装的技能",
26
+ "skills.enable": "启用",
27
+ "skills.disable": "停用",
28
+ "skills.delete": "删除",
29
+ "skills.deleting": "删除中…",
30
+ "skills.failed": "操作失败:{msg}",
31
+ "mcp.title": "MCP 服务器",
32
+ "mcp.description": "管理 MCP 服务器配置:启用、停用或删除。修改后需要重启生效。",
33
+ "mcp.empty": "暂未配置 MCP 服务器",
34
+ "mcp.enable": "启用",
35
+ "mcp.disable": "停用",
36
+ "mcp.delete": "删除",
37
+ "mcp.failed": "操作失败:{msg}"
38
+ };
39
+ /** English dictionary, checked complete against the zh key set. */
40
+ const en = {
41
+ "nav": "Custom",
42
+ "global.title": "Global instructions (AGENTS.md)",
43
+ "global.description": "Content written here is injected into every session's system prompt. New messages pick it up immediately. Markdown supported.",
44
+ "global.placeholder": "# Global instructions\n\nWrite rules, preferences, or background that apply to all conversations…",
45
+ "global.save": "Save",
46
+ "global.saving": "Saving…",
47
+ "global.saved": "Saved ✓",
48
+ "global.loadFailed": "Failed to load: {msg}",
49
+ "global.saveFailed": "Failed to save: {msg}",
50
+ "skills.title": "Skills",
51
+ "skills.description": "Manage installed skills: enable, disable, or delete. Disabled skills are unavailable to the model.",
52
+ "skills.empty": "No skills installed",
53
+ "skills.enable": "Enable",
54
+ "skills.disable": "Disable",
55
+ "skills.delete": "Delete",
56
+ "skills.deleting": "Deleting…",
57
+ "skills.failed": "Operation failed: {msg}",
58
+ "mcp.title": "MCP servers",
59
+ "mcp.description": "Manage MCP server configuration: enable, disable, or delete. Changes apply after a restart.",
60
+ "mcp.empty": "No MCP servers configured",
61
+ "mcp.enable": "Enable",
62
+ "mcp.disable": "Disable",
63
+ "mcp.delete": "Delete",
64
+ "mcp.failed": "Operation failed: {msg}"
65
+ };
66
+ const NS = "dsh-plugin-settings-custom";
67
+ //#endregion
68
+ //#region styles
69
+ const css = `
70
+ .scc_card{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-specific-card-bg,var(--dsw-alias-surface-1));border-radius:12px;padding:16px;margin:0 0 16px}
71
+ .scc_heading{font-size:14px;font-weight:600;line-height:20px;color:var(--dsw-alias-label-primary);margin:0 0 4px}
72
+ .scc_desc{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);margin:0 0 12px}
73
+ .scc_textarea{box-sizing:border-box;width:100%;min-height:240px;resize:vertical;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-input-bg,var(--dsw-alias-surface-2));color:var(--dsw-alias-label-primary);border-radius:8px;padding:10px 12px;font-size:13px;line-height:20px;font-family:var(--dsw-font-family-mono,Consolas,monospace);outline:none}
74
+ .scc_textarea:focus{border-color:var(--dsw-alias-interactive-border-hover,var(--dsw-alias-label-tertiary))}
75
+ .scc_footer{align-items:center;gap:10px;margin-top:10px;display:flex}
76
+ .scc_status{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary)}
77
+ .scc_status.scc_err{color:var(--dsw-alias-state-error-primary)}
78
+ .scc_row{align-items:center;gap:10px;min-width:0;padding:8px 0;display:flex;flex-wrap:nowrap}
79
+ .scc_row+.scc_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1)}
80
+ .scc_rowName{min-width:0;flex:1 1 auto;font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}
81
+ .scc_rowMeta{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary);flex:none;margin-left:6px}
82
+ .scc_rowActions{flex:none;align-items:center;gap:6px;display:flex;flex-wrap:nowrap}
83
+ `;
84
+ const tagId = "@deepseek-ai/dsh-client-ui-settings-custom/styles";
85
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
86
+ const tag = document.createElement("style");
87
+ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-settings-custom";
88
+ tag.dataset.pluginCss = tagId;
89
+ tag.textContent = css;
90
+ document.head.appendChild(tag);
91
+ }
92
+ //#endregion
93
+ //#region GlobalInstructionsSection
94
+ /**
95
+ * Edit `$DSH_HOME/AGENTS.md` in place. Saving writes through the host
96
+ * `settings.custom.globalInstructionsWrite` RPC; the agent-instructions
97
+ * plugin picks the file up on the next message (no restart needed).
98
+ */
99
+ function GlobalInstructionsCard({ api, t }) {
100
+ const [content, setContent] = (0, react.useState)("");
101
+ const [loaded, setLoaded] = (0, react.useState)(false);
102
+ const [saving, setSaving] = (0, react.useState)(false);
103
+ const [status, setStatus] = (0, react.useState)(null);
104
+ const [error, setError] = (0, react.useState)(null);
105
+ (0, react.useEffect)(() => {
106
+ let stale = false;
107
+ api.settings.custom.globalInstructionsRead({}).then((resp) => {
108
+ if (stale) return;
109
+ if (resp.result.ok) {
110
+ setContent(resp.result.value.content);
111
+ setLoaded(true);
112
+ } else {
113
+ setError(t("global.loadFailed", { msg: resp.result.error.message }));
114
+ }
115
+ }).catch((e) => {
116
+ if (!stale) setError(t("global.loadFailed", { msg: e && e.message ? e.message : String(e) }));
117
+ });
118
+ return () => { stale = true; };
119
+ }, [api, t]);
120
+ const save = () => {
121
+ if (saving) return;
122
+ setSaving(true);
123
+ setError(null);
124
+ setStatus(null);
125
+ api.settings.custom.globalInstructionsWrite({ content }).then((resp) => {
126
+ setSaving(false);
127
+ if (resp.result.ok) setStatus(t("global.saved"));
128
+ else setError(t("global.saveFailed", { msg: resp.result.error.message }));
129
+ }).catch((e) => {
130
+ setSaving(false);
131
+ setError(t("global.saveFailed", { msg: e && e.message ? e.message : String(e) }));
132
+ });
133
+ };
134
+ return react_jsx_runtime.jsx("div", {
135
+ className: "scc_card",
136
+ children: [
137
+ react_jsx_runtime.jsx("h3", { className: "scc_heading", children: t("global.title") }),
138
+ react_jsx_runtime.jsx("p", { className: "scc_desc", children: t("global.description") }),
139
+ react_jsx_runtime.jsx("textarea", {
140
+ className: "scc_textarea",
141
+ value: content,
142
+ placeholder: t("global.placeholder"),
143
+ disabled: !loaded || saving,
144
+ spellCheck: false,
145
+ onChange: (e) => {
146
+ setContent(e.target.value);
147
+ setStatus(null);
148
+ }
149
+ }),
150
+ react_jsx_runtime.jsx("div", {
151
+ className: "scc_footer",
152
+ children: [
153
+ react_jsx_runtime.jsx(_deepseek_ai_dsh_client_ui_primitives.Button, {
154
+ variant: "primary",
155
+ disabled: !loaded || saving,
156
+ onClick: save,
157
+ children: saving ? t("global.saving") : t("global.save")
158
+ }),
159
+ status !== null && react_jsx_runtime.jsx("span", { className: "scc_status", children: status }),
160
+ error !== null && react_jsx_runtime.jsx("span", { className: "scc_status scc_err", role: "alert", children: error })
161
+ ]
162
+ })
163
+ ]
164
+ });
165
+ }
166
+ //#endregion
167
+ //#region SkillsCard
168
+ /** List installed skills with enable/disable/delete controls. */
169
+ function SkillsCard({ api, t }) {
170
+ const [skills, setSkills] = (0, react.useState)(null);
171
+ const [error, setError] = (0, react.useState)(null);
172
+ const [busyName, setBusyName] = (0, react.useState)(null);
173
+ const load = (0, react.useCallback)(() => {
174
+ api.settings.custom.skillsList({}).then((resp) => {
175
+ if (resp.result.ok) {
176
+ setSkills(resp.result.value.skills);
177
+ setError(null);
178
+ } else {
179
+ setError(t("skills.failed", { msg: resp.result.error.message }));
180
+ }
181
+ }).catch((e) => {
182
+ setError(t("skills.failed", { msg: e && e.message ? e.message : String(e) }));
183
+ });
184
+ }, [api, t]);
185
+ (0, react.useEffect)(() => {
186
+ load();
187
+ }, [load]);
188
+ const toggle = (skill) => {
189
+ setBusyName(skill.name);
190
+ setError(null);
191
+ api.settings.custom.skillsSetEnabled({ name: skill.name, enabled: !skill.enabled }).then((resp) => {
192
+ setBusyName(null);
193
+ if (resp.result.ok) load();
194
+ else setError(t("skills.failed", { msg: resp.result.error.message }));
195
+ }).catch((e) => {
196
+ setBusyName(null);
197
+ setError(t("skills.failed", { msg: e && e.message ? e.message : String(e) }));
198
+ });
199
+ };
200
+ const remove = (skill) => {
201
+ if (busyName !== null) return;
202
+ if (typeof window !== "undefined" && !window.confirm(`${t("skills.delete")}: ${skill.name}?`)) return;
203
+ setBusyName(skill.name);
204
+ setError(null);
205
+ api.settings.custom.skillsRemove({ name: skill.name }).then((resp) => {
206
+ setBusyName(null);
207
+ if (resp.result.ok) load();
208
+ else setError(t("skills.failed", { msg: resp.result.error.message }));
209
+ }).catch((e) => {
210
+ setBusyName(null);
211
+ setError(t("skills.failed", { msg: e && e.message ? e.message : String(e) }));
212
+ });
213
+ };
214
+ return react_jsx_runtime.jsx("div", {
215
+ className: "scc_card",
216
+ children: [
217
+ react_jsx_runtime.jsx("h3", { className: "scc_heading", children: t("skills.title") }),
218
+ react_jsx_runtime.jsx("p", { className: "scc_desc", children: t("skills.description") }),
219
+ error !== null && react_jsx_runtime.jsx("div", { className: "scc_status scc_err", role: "alert", children: error }),
220
+ skills === null ? null : skills.length === 0 ? react_jsx_runtime.jsx("p", { className: "scc_status", children: t("skills.empty") }) : skills.map((skill) => react_jsx_runtime.jsxs("div", {
221
+ className: "scc_row",
222
+ title: skill.description.length > 0 ? skill.description : void 0,
223
+ children: [
224
+ react_jsx_runtime.jsxs("div", {
225
+ className: "scc_rowName",
226
+ children: [skill.name, skill.enabled ? null : react_jsx_runtime.jsx("span", { className: "scc_rowMeta", children: " (已停用)" })]
227
+ }),
228
+ react_jsx_runtime.jsxs("div", {
229
+ className: "scc_rowActions",
230
+ children: [
231
+ react_jsx_runtime.jsx(_deepseek_ai_dsh_client_ui_primitives.Button, {
232
+ variant: "outline",
233
+ disabled: busyName !== null,
234
+ onClick: () => toggle(skill),
235
+ children: skill.enabled ? t("skills.disable") : t("skills.enable")
236
+ }),
237
+ react_jsx_runtime.jsx(_deepseek_ai_dsh_client_ui_primitives.Button, {
238
+ variant: "outline",
239
+ disabled: busyName !== null,
240
+ onClick: () => remove(skill),
241
+ children: busyName === skill.name ? t("skills.deleting") : t("skills.delete")
242
+ })
243
+ ]
244
+ })
245
+ ]
246
+ }, skill.name))
247
+ ]
248
+ });
249
+ }
250
+ //#endregion
251
+ //#region McpCard
252
+ /** List configured MCP servers with enable/disable/delete controls. */
253
+ function McpCard({ api, t }) {
254
+ const [servers, setServers] = (0, react.useState)(null);
255
+ const [error, setError] = (0, react.useState)(null);
256
+ const [busyId, setBusyId] = (0, react.useState)(null);
257
+ const load = (0, react.useCallback)(() => {
258
+ api.settings.custom.mcpList({}).then((resp) => {
259
+ if (resp.result.ok) {
260
+ setServers(resp.result.value.servers);
261
+ setError(null);
262
+ } else {
263
+ setError(t("mcp.failed", { msg: resp.result.error.message }));
264
+ }
265
+ }).catch((e) => {
266
+ setError(t("mcp.failed", { msg: e && e.message ? e.message : String(e) }));
267
+ });
268
+ }, [api, t]);
269
+ (0, react.useEffect)(() => {
270
+ load();
271
+ }, [load]);
272
+ const toggle = (server) => {
273
+ setBusyId(server.id);
274
+ setError(null);
275
+ api.settings.custom.mcpSetEnabled({ id: server.id, enabled: !server.enabled }).then((resp) => {
276
+ setBusyId(null);
277
+ if (resp.result.ok) load();
278
+ else setError(t("mcp.failed", { msg: resp.result.error.message }));
279
+ }).catch((e) => {
280
+ setBusyId(null);
281
+ setError(t("mcp.failed", { msg: e && e.message ? e.message : String(e) }));
282
+ });
283
+ };
284
+ const remove = (server) => {
285
+ if (busyId !== null) return;
286
+ if (typeof window !== "undefined" && !window.confirm(`${t("mcp.delete")}: ${server.serverName}?`)) return;
287
+ setBusyId(server.id);
288
+ setError(null);
289
+ api.settings.custom.mcpRemove({ id: server.id }).then((resp) => {
290
+ setBusyId(null);
291
+ if (resp.result.ok) load();
292
+ else setError(t("mcp.failed", { msg: resp.result.error.message }));
293
+ }).catch((e) => {
294
+ setBusyId(null);
295
+ setError(t("mcp.failed", { msg: e && e.message ? e.message : String(e) }));
296
+ });
297
+ };
298
+ return react_jsx_runtime.jsx("div", {
299
+ className: "scc_card",
300
+ children: [
301
+ react_jsx_runtime.jsx("h3", { className: "scc_heading", children: t("mcp.title") }),
302
+ react_jsx_runtime.jsx("p", { className: "scc_desc", children: t("mcp.description") }),
303
+ error !== null && react_jsx_runtime.jsx("div", { className: "scc_status scc_err", role: "alert", children: error }),
304
+ servers === null ? null : servers.length === 0 ? react_jsx_runtime.jsx("p", { className: "scc_status", children: t("mcp.empty") }) : servers.map((server) => react_jsx_runtime.jsxs("div", {
305
+ className: "scc_row",
306
+ children: [
307
+ react_jsx_runtime.jsxs("div", {
308
+ className: "scc_rowName",
309
+ children: [server.serverName, server.enabled ? null : react_jsx_runtime.jsx("span", { className: "scc_rowMeta", children: " (已停用)" })]
310
+ }),
311
+ react_jsx_runtime.jsxs("div", {
312
+ className: "scc_rowActions",
313
+ children: [
314
+ react_jsx_runtime.jsx(_deepseek_ai_dsh_client_ui_primitives.Button, {
315
+ variant: "outline",
316
+ disabled: busyId !== null,
317
+ onClick: () => toggle(server),
318
+ children: server.enabled ? t("mcp.disable") : t("mcp.enable")
319
+ }),
320
+ react_jsx_runtime.jsx(_deepseek_ai_dsh_client_ui_primitives.Button, {
321
+ variant: "outline",
322
+ disabled: busyId !== null,
323
+ onClick: () => remove(server),
324
+ children: t("mcp.delete")
325
+ })
326
+ ]
327
+ })
328
+ ]
329
+ }, server.id))
330
+ ]
331
+ });
332
+ }
333
+ //#endregion
334
+ //#region CustomSection
335
+ /** Settings section shell: global instructions, skill management, and MCP management. */
336
+ function CustomSection({ api, t }) {
337
+ if (api === void 0 || t === void 0) return null;
338
+ return react_jsx_runtime.jsx("div", {
339
+ children: [
340
+ react_jsx_runtime.jsx(GlobalInstructionsCard, { api, t }),
341
+ react_jsx_runtime.jsx(SkillsCard, { api, t }),
342
+ react_jsx_runtime.jsx(McpCard, { api, t })
343
+ ]
344
+ });
345
+ }
346
+ //#endregion
347
+ //#region plugin
348
+ //#region fetch adapter (replaces patched RPCs with the plugin's HTTP routes)
349
+ function makeApi() {
350
+ function get(path) {
351
+ return fetch(path).then(function(r){return r.json()}).then(function(d){
352
+ if (d && d.ok === false) return { result: { ok: false, error: { message: d.error || "failed" } } };
353
+ return { result: { ok: true, value: d } };
354
+ }).catch(function(e){ return { result: { ok: false, error: { message: String(e && e.message || e) } } }; });
355
+ }
356
+ function post(path, body) {
357
+ return fetch(path, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body || {}) }).then(function(r){return r.json()}).then(function(d){
358
+ if (d && d.ok === false) return { result: { ok: false, error: { message: d.error || "failed" } } };
359
+ return { result: { ok: true, value: d } };
360
+ }).catch(function(e){ return { result: { ok: false, error: { message: String(e && e.message || e) } } }; });
361
+ }
362
+ return { settings: { custom: {
363
+ globalInstructionsRead: function(){ return get("/dsh-plugin-global-instructions/global.json"); },
364
+ globalInstructionsWrite: function(p){ return post("/dsh-plugin-global-instructions/global.json", { content: p && p.content }); },
365
+ skillsList: function(){ return get("/dsh-plugin-skill-manager/skills.json"); },
366
+ skillsSetEnabled: function(p){ return post("/dsh-plugin-skill-manager/skills.json", { action: "setEnabled", name: p && p.name, enabled: p && p.enabled }); },
367
+ skillsRemove: function(p){ return post("/dsh-plugin-skill-manager/skills.json", { action: "remove", name: p && p.name }); },
368
+ mcpList: function(){ return get("/dsh-plugin-mcp-manager/mcp.json"); },
369
+ mcpSetEnabled: function(p){ return post("/dsh-plugin-mcp-manager/mcp.json", { action: "setEnabled", id: p && p.id, enabled: p && p.enabled }); },
370
+ mcpRemove: function(p){ return post("/dsh-plugin-mcp-manager/mcp.json", { action: "remove", id: p && p.id }); }
371
+ } } };
372
+ }
373
+ //#endregion
374
+
375
+ const inject = [
376
+ "slots",
377
+ "locale"
378
+ ];
379
+ function apply(ctx) {
380
+ ctx.effect(() => ctx.locale.register(NS, {
381
+ zh,
382
+ en
383
+ }), "ui-settings-custom: copy dictionaries");
384
+
385
+ const t = ctx.locale.bind(NS);
386
+ const injected = () => ({
387
+ api: makeApi(),
388
+ t
389
+ });
390
+ ctx.slots.inject("settings.section", () => ctx.slots.register({
391
+ name: "settings.section",
392
+ id: "custom",
393
+ order: 30,
394
+ label: () => t("nav"),
395
+ locale: NS,
396
+ inject: injected
397
+ }, CustomSection));
398
+ }
399
+ //#endregion
400
+ exports.apply = apply;
401
+ exports.inject = inject;
402
+ return module.exports;
403
+ }
404
+ });
package/lib/index.js ADDED
@@ -0,0 +1,30 @@
1
+ import path from 'node:path'
2
+ import { fileURLToPath } from 'node:url'
3
+ const CLIENT_JS = `(function(){
4
+ if (window.__dshSettingsCustom) return
5
+ window.__dshSettingsCustom = true
6
+ // 在设置页导航里加“自定义”入口,并提供一个容器 .dsh-custom-host 供 1/3/4 插件面板挂载
7
+ function boot(){
8
+ var nav = document.querySelector('[class*="settings"] nav, [role="tablist"], [class*="setting-nav"], nav')
9
+ var host = document.querySelector('[class*="settings"], [data-role="settings"], main, body')
10
+ if (!host) return setTimeout(boot, 300)
11
+ if (!host.querySelector('.dsh-custom-host')) {
12
+ var c = document.createElement('div'); c.className='dsh-custom-host'
13
+ c.innerHTML='<div class="dsh-custom-title">自定义</div>'
14
+ host.appendChild(c)
15
+ }
16
+ // 有导航则追加一个“自定义” tab(尽力)
17
+ if (nav && !nav.querySelector('[data-dsh-custom-tab]')) {
18
+ var t=document.createElement('button'); t.setAttribute('data-dsh-custom-tab','1'); t.textContent='自定义'
19
+ t.className='dsh-custom-tab'; nav.appendChild(t)
20
+ }
21
+ }
22
+ if (document.readyState==='loading') document.addEventListener('DOMContentLoaded', boot)
23
+ else boot()
24
+ })()`
25
+ const name = 'dsh-plugin-settings-custom'
26
+ const inject = ['webServer']
27
+ function apply(ctx){
28
+
29
+ }
30
+ export { name, inject, apply }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "dsh-plugin-settings-custom",
3
+ "version": "1.0.0",
4
+ "description": "DSH 设置页\"自定义\"页签(容纳全局指令/Skill/MCP 面板)",
5
+ "keywords": [
6
+ "dsh",
7
+ "dsh-plugin",
8
+ "deepseek-harness",
9
+ "settings",
10
+ "custom"
11
+ ],
12
+ "type": "module",
13
+ "main": "lib/index.js",
14
+ "files": [
15
+ "lib",
16
+ "cordis.patch.yml",
17
+ "README.md"
18
+ ],
19
+ "dsh": {
20
+ "bundle": {
21
+ "patch": "./cordis.patch.yml"
22
+ },
23
+ "client": {
24
+ "inject": [
25
+ "@deepseek-ai/dsh-client-runtime",
26
+ "@deepseek-ai/dsh-client-locale",
27
+ "@deepseek-ai/dsh-client-ui-settings"
28
+ ],
29
+ "platform": "web"
30
+ }
31
+ },
32
+ "license": "MIT",
33
+ "exports": {
34
+ ".": "./lib/index.js",
35
+ "./client": "./lib/client.js",
36
+ "./package.json": "./package.json"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/mengyu-arch/dsh-plugins.git"
44
+ }
45
+ }