prompt-skill-armory 0.9.9 → 0.10.1
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.en.md +3 -3
- package/README.md +3 -3
- package/package.json +1 -1
- package/packages/client-ui-switchblade/lib/client.js +153 -135
- package/packages/client-ui-switchblade/lib/client.js.map +1 -1
- package/packages/client-ui-switchblade/package.json +1 -1
- package/packages/client-ui-switchblade/src/client/SwitchbladeSection.tsx +1 -1
- package/packages/client-ui-switchblade/src/client/background.ts +28 -19
- package/packages/client-ui-switchblade/src/client/index.ts +38 -13
- package/packages/client-ui-switchblade/src/client/store.ts +92 -69
- package/packages/switchblade/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
|--|--|--|--|
|
|
13
13
|
| <img src="docs/preview/preview-6.png" width="220"/> | <img src="docs/preview/preview-7.png" width="220"/> | | |
|
|
14
14
|
|
|
15
|
-

|
|
16
16
|

|
|
17
17
|

|
|
18
18
|

|
|
19
19
|
|
|
20
20
|
```
|
|
21
|
-
✦ Armory v0.
|
|
21
|
+
✦ Armory v0.10.1
|
|
22
22
|
┌─────────┬─────────┬─────┬────────────┬──────┬──────┐
|
|
23
23
|
│ Prompts │ Skills │ MCP │ Wallpaper │ Chat │ Stats│
|
|
24
24
|
│ global │ merged │ hub │ wallpaper │ sync │ usage│
|
|
@@ -125,7 +125,7 @@ Achieved via profile composition (the installer mounts the panel into each profi
|
|
|
125
125
|
|
|
126
126
|
Every time the panel opens it queries npm for the latest `prompt-skill-armory` version; when a newer version exists a banner appears:
|
|
127
127
|
|
|
128
|
-
> New version vX.Y.Z (current v0.
|
|
128
|
+
> New version vX.Y.Z (current v0.10.1) [Update now]
|
|
129
129
|
|
|
130
130
|
Clicking "Update now" makes the Host re-run the official installer in place → "Update complete, please restart the client".
|
|
131
131
|
|
package/README.md
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
|--|--|--|--|
|
|
13
13
|
| <img src="docs/preview/preview-6.png" width="220"/> | <img src="docs/preview/preview-7.png" width="220"/> | | |
|
|
14
14
|
|
|
15
|
-

|
|
16
16
|

|
|
17
17
|

|
|
18
18
|

|
|
19
19
|
|
|
20
20
|
```
|
|
21
|
-
✦ Armory v0.
|
|
21
|
+
✦ Armory v0.10.1
|
|
22
22
|
┌─────────┬─────────┬─────┬────────────┬──────┬──────┐
|
|
23
23
|
│ 提示词 │ 技能 │ MCP │ Wallpaper │ 对话 │ 统计 │
|
|
24
24
|
│ 全局注入 │ 合并管理 │ 连接 │ 壁纸·特效 │ 导入 │ 用量 │
|
|
@@ -128,7 +128,7 @@ pnpm dsh web
|
|
|
128
128
|
|
|
129
129
|
插件面板每次打开会自动查询 npm 上 `prompt-skill-armory` 的最新版本;发现新版本时顶部显示横幅:
|
|
130
130
|
|
|
131
|
-
> 有新版本 vX.Y.Z(当前 v0.
|
|
131
|
+
> 有新版本 vX.Y.Z(当前 v0.10.1) [一键更新]
|
|
132
132
|
|
|
133
133
|
点击「一键更新」→ Host 端运行官方安装器原地重装 → 提示「更新完成,请重启客户端生效」。
|
|
134
134
|
|
package/package.json
CHANGED
|
@@ -6,7 +6,6 @@ window.__ModuleLoader__.load({
|
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let react = require("react");
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
-
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
10
9
|
//#region src/client/locales.ts
|
|
11
10
|
/**
|
|
12
11
|
* Switchblade management page dictionaries.
|
|
@@ -156,14 +155,26 @@ window.__ModuleLoader__.load({
|
|
|
156
155
|
const GLASS_ATTR = "data-ar-glass";
|
|
157
156
|
const CSS_TAG = "prompt-skill-armory/background";
|
|
158
157
|
const BACKGROUND_CSS = `
|
|
159
|
-
|
|
158
|
+
/* Backdrop pinned to the viewport at the very bottom of the stacking order.
|
|
159
|
+
z-index 0 + forcing DSH surfaces transparent lets it show through every
|
|
160
|
+
chrome (sidebar / conversation / rightbar), not just the chat area. */
|
|
161
|
+
.ar-bg-layer { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
|
|
160
162
|
.ar-bg-layer .ar-bg-image { width: 100%; height: 100%; display: block; border: 0;
|
|
161
163
|
object-fit: var(--ar-bg-fit, cover); opacity: var(--ar-bg-opacity, 1);
|
|
162
164
|
filter: blur(var(--ar-bg-blur, 0px)); transform: scale(var(--ar-bg-scale, 1)); transform-origin: center; }
|
|
163
|
-
.ar-bg-scrim { position: fixed; inset: 0; z-index:
|
|
165
|
+
.ar-bg-scrim { position: fixed; inset: 0; z-index: 0; pointer-events: none;
|
|
164
166
|
background: rgba(255,255,255, var(--ar-bg-scrim, 0.25)); }
|
|
165
167
|
body[data-ds-dark-theme] .ar-bg-scrim { background: rgba(0,0,0, var(--ar-bg-scrim, 0.25)); }
|
|
166
|
-
|
|
168
|
+
|
|
169
|
+
/* Lift the app chrome above the backdrop so it stays interactive, while
|
|
170
|
+
every DSH surface background becomes transparent to reveal the wallpaper. */
|
|
171
|
+
body[${ACTIVE_ATTR}] #root { position: relative; z-index: 1; background: transparent; }
|
|
172
|
+
body[${ACTIVE_ATTR}] .dshDesktopFrame,
|
|
173
|
+
body[${ACTIVE_ATTR}] .dshDesktopConversationSurface,
|
|
174
|
+
body[${ACTIVE_ATTR}] .dshDesktopSidebarSurface,
|
|
175
|
+
body[${ACTIVE_ATTR}] .dshDesktopRightbarSurface { background: transparent !important; }
|
|
176
|
+
body[${ACTIVE_ATTR}] { --dsw-alias-bg-base: transparent; --dsw-alias-bg-layer-1: transparent; --dsw-specific-sidebar-fill: transparent; }
|
|
177
|
+
|
|
167
178
|
body[${GLASS_ATTR}] [data-composer-card],
|
|
168
179
|
body[${GLASS_ATTR}] [class*="_bubble"]:not([role="tooltip"]),
|
|
169
180
|
body[${GLASS_ATTR}] .md-code-block,
|
|
@@ -231,7 +242,11 @@ window.__ModuleLoader__.load({
|
|
|
231
242
|
try {
|
|
232
243
|
injectBackgroundCss();
|
|
233
244
|
const hasSource = settings.url !== "" || settings.uploadId !== "";
|
|
234
|
-
for (const prop of [
|
|
245
|
+
for (const prop of [
|
|
246
|
+
"--dsw-alias-bg-base",
|
|
247
|
+
"--dsw-alias-bg-layer-1",
|
|
248
|
+
"--dsw-specific-sidebar-fill"
|
|
249
|
+
]) {
|
|
235
250
|
this.rememberOnce(prop);
|
|
236
251
|
document.body.style.setProperty(prop, "transparent");
|
|
237
252
|
}
|
|
@@ -358,17 +373,17 @@ window.__ModuleLoader__.load({
|
|
|
358
373
|
const notifyBg = () => {
|
|
359
374
|
for (const l of bgListeners) l();
|
|
360
375
|
};
|
|
361
|
-
let
|
|
362
|
-
/** Bind the transport to
|
|
363
|
-
function initBackgroundClient(
|
|
364
|
-
|
|
376
|
+
let bgScope;
|
|
377
|
+
/** Bind the transport to the switchblade settings scope (set once at plugin apply). */
|
|
378
|
+
function initBackgroundClient(scope) {
|
|
379
|
+
bgScope = scope;
|
|
365
380
|
}
|
|
366
381
|
/** Surface key: separate wallpaper per web vs desktop (they share the settings doc). */
|
|
367
382
|
const isDesktopSurface = typeof navigator !== "undefined" && navigator.userAgent.toLowerCase().includes("electron");
|
|
368
383
|
const surfaceKey = () => isDesktopSurface ? "backgroundDesktop" : "backgroundWeb";
|
|
369
384
|
/** Read the background section for the current surface from the switchblade settings. */
|
|
370
385
|
function readSection(value) {
|
|
371
|
-
const raw =
|
|
386
|
+
const raw = value?.[surfaceKey()];
|
|
372
387
|
return {
|
|
373
388
|
...DEFAULT_BACKGROUND,
|
|
374
389
|
...typeof raw === "object" && raw !== null ? raw : {}
|
|
@@ -386,15 +401,15 @@ window.__ModuleLoader__.load({
|
|
|
386
401
|
},
|
|
387
402
|
/** Fetch the durable section. @returns true on success (status ready). */
|
|
388
403
|
async load() {
|
|
389
|
-
if (
|
|
404
|
+
if (bgScope === void 0) {
|
|
390
405
|
bgState.status = "error";
|
|
391
406
|
return false;
|
|
392
407
|
}
|
|
393
408
|
try {
|
|
394
|
-
const
|
|
395
|
-
if (
|
|
409
|
+
const snap = bgScope.getSnapshot();
|
|
410
|
+
if (snap.status !== "ready" || snap.value === void 0) return false;
|
|
396
411
|
bgState.status = "ready";
|
|
397
|
-
bgState.value = readSection(
|
|
412
|
+
bgState.value = readSection(snap.value);
|
|
398
413
|
notifyBg();
|
|
399
414
|
return true;
|
|
400
415
|
} catch {
|
|
@@ -403,17 +418,13 @@ window.__ModuleLoader__.load({
|
|
|
403
418
|
}
|
|
404
419
|
},
|
|
405
420
|
async save(section) {
|
|
406
|
-
if (
|
|
421
|
+
if (bgScope === void 0) return;
|
|
407
422
|
try {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
value: section
|
|
414
|
-
}]
|
|
415
|
-
});
|
|
416
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
423
|
+
await bgScope.mutate([{
|
|
424
|
+
op: "set",
|
|
425
|
+
path: [surfaceKey()],
|
|
426
|
+
value: section
|
|
427
|
+
}]);
|
|
417
428
|
bgState.status = "ready";
|
|
418
429
|
bgState.value = { ...section };
|
|
419
430
|
} catch {
|
|
@@ -958,7 +969,7 @@ window.__ModuleLoader__.load({
|
|
|
958
969
|
});
|
|
959
970
|
}
|
|
960
971
|
/** Bump with every release; keep in sync with package.json version + CHANGELOG. */
|
|
961
|
-
const ARMORY_VERSION = "0.
|
|
972
|
+
const ARMORY_VERSION = "0.10.1";
|
|
962
973
|
/** Compact duration: 45.2s / 2m42s / 1h05m. */
|
|
963
974
|
function fmtDuration(ms) {
|
|
964
975
|
const s = ms / 1e3;
|
|
@@ -3207,6 +3218,26 @@ window.__ModuleLoader__.load({
|
|
|
3207
3218
|
}
|
|
3208
3219
|
//#endregion
|
|
3209
3220
|
//#region src/client/store.ts
|
|
3221
|
+
/** Local snapshot store engine (plain observable, sync flush). */
|
|
3222
|
+
function createSnapshotStore(init) {
|
|
3223
|
+
let current = init;
|
|
3224
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
3225
|
+
return {
|
|
3226
|
+
getSnapshot: () => current,
|
|
3227
|
+
subscribe(listener) {
|
|
3228
|
+
listeners.add(listener);
|
|
3229
|
+
return () => {
|
|
3230
|
+
listeners.delete(listener);
|
|
3231
|
+
};
|
|
3232
|
+
},
|
|
3233
|
+
set(next) {
|
|
3234
|
+
current = next;
|
|
3235
|
+
for (const l of [...listeners]) try {
|
|
3236
|
+
l();
|
|
3237
|
+
} catch {}
|
|
3238
|
+
}
|
|
3239
|
+
};
|
|
3240
|
+
}
|
|
3210
3241
|
/** Initial (idle) state. */
|
|
3211
3242
|
const IDLE = {
|
|
3212
3243
|
status: "idle",
|
|
@@ -3221,14 +3252,27 @@ window.__ModuleLoader__.load({
|
|
|
3221
3252
|
return error instanceof Error ? error.message : String(error);
|
|
3222
3253
|
}
|
|
3223
3254
|
var SwitchbladeSectionController = class {
|
|
3224
|
-
|
|
3255
|
+
scope;
|
|
3256
|
+
remote;
|
|
3225
3257
|
sessionId;
|
|
3226
3258
|
/** Snapshot store backing the section's view state. */
|
|
3227
|
-
store =
|
|
3228
|
-
constructor(
|
|
3229
|
-
this.
|
|
3259
|
+
store = createSnapshotStore(IDLE);
|
|
3260
|
+
constructor(scope, remote, sessionId) {
|
|
3261
|
+
this.scope = scope;
|
|
3262
|
+
this.remote = remote;
|
|
3230
3263
|
this.sessionId = sessionId;
|
|
3231
3264
|
}
|
|
3265
|
+
/** 2.0.9 settings read: scope mirror snapshot (never the old api.settings). */
|
|
3266
|
+
describeSettings() {
|
|
3267
|
+
const snap = this.scope.getSnapshot();
|
|
3268
|
+
if (snap.status !== "ready" || snap.value === void 0) return void 0;
|
|
3269
|
+
return this.sectionFromSettings(snap.value, "switchblade");
|
|
3270
|
+
}
|
|
3271
|
+
/** 2.0.9 settings write: scope.mutate(ops) — Host fold + re-inject. */
|
|
3272
|
+
async mutateSettings(ops) {
|
|
3273
|
+
if (this.scope.getSnapshot().status !== "ready") throw new Error("settings scope not ready");
|
|
3274
|
+
await this.scope.mutate(ops);
|
|
3275
|
+
}
|
|
3232
3276
|
/**
|
|
3233
3277
|
* Load skills, prompts, and installed skills. Prompts and installed
|
|
3234
3278
|
* skills come from the `switchblade` settings namespace (the Host watches
|
|
@@ -3241,16 +3285,14 @@ window.__ModuleLoader__.load({
|
|
|
3241
3285
|
});
|
|
3242
3286
|
try {
|
|
3243
3287
|
const sessionId = this.sessionId?.();
|
|
3244
|
-
const calls = [this.
|
|
3245
|
-
if (sessionId !== void 0) calls.push(this.
|
|
3246
|
-
const [
|
|
3247
|
-
|
|
3248
|
-
const skills = skillRes !== void 0 && skillRes.result.ok ? skillRes.result.value.skills.map((skill) => ({
|
|
3288
|
+
const calls = [Promise.resolve(this.describeSettings())];
|
|
3289
|
+
if (sessionId !== void 0) calls.push(this.remote.skills.list({ request: { sessionId } }));
|
|
3290
|
+
const [switchbladeSection, skillRes] = await Promise.all(calls);
|
|
3291
|
+
const skills = skillRes !== void 0 && skillRes.ok && skillRes.value !== void 0 ? skillRes.value.skills.map((skill) => ({
|
|
3249
3292
|
name: skill.name,
|
|
3250
3293
|
description: skill.description,
|
|
3251
3294
|
modelInvocable: skill.modelInvocable
|
|
3252
3295
|
})) : [];
|
|
3253
|
-
const switchbladeSection = this.sectionFromSettings(settingsRes.result.value, "switchblade");
|
|
3254
3296
|
const prompts = Array.isArray(switchbladeSection?.prompts) ? switchbladeSection.prompts : [];
|
|
3255
3297
|
const installedSkills = Array.isArray(switchbladeSection?.installedSkills) ? switchbladeSection.installedSkills.map((s) => ({
|
|
3256
3298
|
name: s.name ?? "",
|
|
@@ -3292,9 +3334,13 @@ window.__ModuleLoader__.load({
|
|
|
3292
3334
|
});
|
|
3293
3335
|
}
|
|
3294
3336
|
}
|
|
3295
|
-
/** Read one namespace's
|
|
3337
|
+
/** Read one namespace's section from a settings value. The 2.0.9 scope
|
|
3338
|
+
* snapshot carries the bound namespace's own value; older describe payloads
|
|
3339
|
+
* carry a `namespaces[]` table — accept both. */
|
|
3296
3340
|
sectionFromSettings(value, ns) {
|
|
3297
3341
|
if (typeof value !== "object" || value === null) return void 0;
|
|
3342
|
+
const asSection = value;
|
|
3343
|
+
if (Array.isArray(asSection.prompts) || Array.isArray(asSection.installedSkills) || asSection.mcpServers !== void 0) return asSection;
|
|
3298
3344
|
const entries = value.namespaces;
|
|
3299
3345
|
if (!Array.isArray(entries)) return void 0;
|
|
3300
3346
|
for (const entry of entries) {
|
|
@@ -3307,24 +3353,20 @@ window.__ModuleLoader__.load({
|
|
|
3307
3353
|
}
|
|
3308
3354
|
/** Add a prompt. */
|
|
3309
3355
|
async addPrompt(input) {
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
isDefault: this.currentPrompts().length === 0,
|
|
3323
|
-
...input.scope === void 0 || input.scope.type === "global" ? {} : { scope: input.scope }
|
|
3324
|
-
}]
|
|
3356
|
+
await this.mutateSettings([{
|
|
3357
|
+
op: "set",
|
|
3358
|
+
path: ["prompts"],
|
|
3359
|
+
value: [...this.currentPrompts(), {
|
|
3360
|
+
id: this.slugify(input.name),
|
|
3361
|
+
name: input.name,
|
|
3362
|
+
description: input.description,
|
|
3363
|
+
content: input.content,
|
|
3364
|
+
order: this.currentPrompts().length,
|
|
3365
|
+
enabled: true,
|
|
3366
|
+
isDefault: this.currentPrompts().length === 0,
|
|
3367
|
+
...input.scope === void 0 || input.scope.type === "global" ? {} : { scope: input.scope }
|
|
3325
3368
|
}]
|
|
3326
|
-
});
|
|
3327
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3369
|
+
}]);
|
|
3328
3370
|
await this.load();
|
|
3329
3371
|
}
|
|
3330
3372
|
/** Toggle one prompt's enabled state. */
|
|
@@ -3361,15 +3403,11 @@ window.__ModuleLoader__.load({
|
|
|
3361
3403
|
}
|
|
3362
3404
|
/** Persist the prompt list through the settings RPC. */
|
|
3363
3405
|
async writePrompts(prompts) {
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
value: prompts
|
|
3370
|
-
}]
|
|
3371
|
-
});
|
|
3372
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3406
|
+
await this.mutateSettings([{
|
|
3407
|
+
op: "set",
|
|
3408
|
+
path: ["prompts"],
|
|
3409
|
+
value: prompts
|
|
3410
|
+
}]);
|
|
3373
3411
|
await this.load();
|
|
3374
3412
|
}
|
|
3375
3413
|
/** Current prompt list from the loaded snapshot. */
|
|
@@ -3389,15 +3427,11 @@ window.__ModuleLoader__.load({
|
|
|
3389
3427
|
content: input.content,
|
|
3390
3428
|
enabled: true
|
|
3391
3429
|
}];
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
value: next
|
|
3398
|
-
}]
|
|
3399
|
-
});
|
|
3400
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3430
|
+
await this.mutateSettings([{
|
|
3431
|
+
op: "set",
|
|
3432
|
+
path: ["installedSkills"],
|
|
3433
|
+
value: next
|
|
3434
|
+
}]);
|
|
3401
3435
|
await this.load();
|
|
3402
3436
|
}
|
|
3403
3437
|
/** Toggle one installed skill's enabled state. */
|
|
@@ -3406,29 +3440,21 @@ window.__ModuleLoader__.load({
|
|
|
3406
3440
|
...s,
|
|
3407
3441
|
enabled
|
|
3408
3442
|
} : s);
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
value: next
|
|
3415
|
-
}]
|
|
3416
|
-
});
|
|
3417
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3443
|
+
await this.mutateSettings([{
|
|
3444
|
+
op: "set",
|
|
3445
|
+
path: ["installedSkills"],
|
|
3446
|
+
value: next
|
|
3447
|
+
}]);
|
|
3418
3448
|
await this.load();
|
|
3419
3449
|
}
|
|
3420
3450
|
/** Uninstall one installed skill. */
|
|
3421
3451
|
async uninstallSkill(name) {
|
|
3422
3452
|
const next = this.currentInstalledSkills().filter((s) => s.name !== name);
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
value: next
|
|
3429
|
-
}]
|
|
3430
|
-
});
|
|
3431
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3453
|
+
await this.mutateSettings([{
|
|
3454
|
+
op: "set",
|
|
3455
|
+
path: ["installedSkills"],
|
|
3456
|
+
value: next
|
|
3457
|
+
}]);
|
|
3432
3458
|
await this.load();
|
|
3433
3459
|
}
|
|
3434
3460
|
/** Update an installed skill's name/description/content. */
|
|
@@ -3439,15 +3465,11 @@ window.__ModuleLoader__.load({
|
|
|
3439
3465
|
description: patch.description ?? s.description,
|
|
3440
3466
|
content: patch.content ?? s.content
|
|
3441
3467
|
} : s);
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
value: next
|
|
3448
|
-
}]
|
|
3449
|
-
});
|
|
3450
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3468
|
+
await this.mutateSettings([{
|
|
3469
|
+
op: "set",
|
|
3470
|
+
path: ["installedSkills"],
|
|
3471
|
+
value: next
|
|
3472
|
+
}]);
|
|
3451
3473
|
await this.load();
|
|
3452
3474
|
}
|
|
3453
3475
|
/** Current installed skills from the loaded snapshot. */
|
|
@@ -3459,18 +3481,14 @@ window.__ModuleLoader__.load({
|
|
|
3459
3481
|
* watch sees pendingZip and installs it (skil-filesystem then discovers it).
|
|
3460
3482
|
*/
|
|
3461
3483
|
async installSkillFromZip(name, dataBase64) {
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
}
|
|
3471
|
-
}]
|
|
3472
|
-
});
|
|
3473
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3484
|
+
await this.mutateSettings([{
|
|
3485
|
+
op: "set",
|
|
3486
|
+
path: ["pendingZip"],
|
|
3487
|
+
value: {
|
|
3488
|
+
name,
|
|
3489
|
+
dataBase64
|
|
3490
|
+
}
|
|
3491
|
+
}]);
|
|
3474
3492
|
await new Promise((r) => setTimeout(r, 500));
|
|
3475
3493
|
await this.load();
|
|
3476
3494
|
}
|
|
@@ -3507,32 +3525,24 @@ window.__ModuleLoader__.load({
|
|
|
3507
3525
|
* after a short delay so the panel shows the fresh tool list / error.
|
|
3508
3526
|
*/
|
|
3509
3527
|
async testMcpServer(name) {
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
}
|
|
3519
|
-
}]
|
|
3520
|
-
});
|
|
3521
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3528
|
+
await this.mutateSettings([{
|
|
3529
|
+
op: "set",
|
|
3530
|
+
path: ["mcpTestRequest"],
|
|
3531
|
+
value: {
|
|
3532
|
+
serverName: name,
|
|
3533
|
+
ts: Date.now()
|
|
3534
|
+
}
|
|
3535
|
+
}]);
|
|
3522
3536
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
3523
3537
|
await this.load();
|
|
3524
3538
|
}
|
|
3525
3539
|
/** Persist the MCP server config list. */
|
|
3526
3540
|
async writeMcpServers(servers) {
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
value: servers
|
|
3533
|
-
}]
|
|
3534
|
-
});
|
|
3535
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3541
|
+
await this.mutateSettings([{
|
|
3542
|
+
op: "set",
|
|
3543
|
+
path: ["mcpServers"],
|
|
3544
|
+
value: servers
|
|
3545
|
+
}]);
|
|
3536
3546
|
await this.load();
|
|
3537
3547
|
}
|
|
3538
3548
|
/** Current MCP server list from the loaded snapshot. */
|
|
@@ -3542,11 +3552,18 @@ window.__ModuleLoader__.load({
|
|
|
3542
3552
|
};
|
|
3543
3553
|
//#endregion
|
|
3544
3554
|
//#region src/client/index.ts
|
|
3555
|
+
/**
|
|
3556
|
+
* Switchblade management page, browser half: registers the `settings.section`
|
|
3557
|
+
* navigation entry and renders the edgelord panel from the connection RPC
|
|
3558
|
+
* state. Global scope (root) — one management seat for every session.
|
|
3559
|
+
* @module @deepseek-ai/dsh-client-ui-switchblade
|
|
3560
|
+
*/
|
|
3545
3561
|
/** Required services (cordis fiber inject). */
|
|
3546
3562
|
const inject = [
|
|
3547
3563
|
"slots",
|
|
3548
3564
|
"locale",
|
|
3549
|
-
"
|
|
3565
|
+
"settingsScope",
|
|
3566
|
+
"remote",
|
|
3550
3567
|
"sessions"
|
|
3551
3568
|
];
|
|
3552
3569
|
/**
|
|
@@ -3558,11 +3575,12 @@ window.__ModuleLoader__.load({
|
|
|
3558
3575
|
zh,
|
|
3559
3576
|
en
|
|
3560
3577
|
}), "ui-switchblade: dictionaries");
|
|
3561
|
-
const
|
|
3578
|
+
const scope = ctx.get("settingsScope").bind({ namespace: "switchblade" });
|
|
3579
|
+
const remote = ctx.get("remote");
|
|
3562
3580
|
const sessions = ctx.get("sessions");
|
|
3563
3581
|
applyHintStyle();
|
|
3564
3582
|
try {
|
|
3565
|
-
initBackgroundClient(
|
|
3583
|
+
initBackgroundClient(scope);
|
|
3566
3584
|
const paintBackground = () => {
|
|
3567
3585
|
const s = backgroundClient.getSnapshot();
|
|
3568
3586
|
if (s.status === "ready") applyBackground(s.value);
|
|
@@ -3577,7 +3595,7 @@ window.__ModuleLoader__.load({
|
|
|
3577
3595
|
} catch (error) {
|
|
3578
3596
|
console.warn("[switchblade] background init skipped:", error);
|
|
3579
3597
|
}
|
|
3580
|
-
const controller = new SwitchbladeSectionController(
|
|
3598
|
+
const controller = new SwitchbladeSectionController(scope, remote, () => {
|
|
3581
3599
|
const state = sessions.list.getSnapshot();
|
|
3582
3600
|
return state.current === void 0 ? void 0 : state.current;
|
|
3583
3601
|
});
|