prompt-skill-armory 0.10.0 → 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 +132 -133
- 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 +10 -11
- package/packages/client-ui-switchblade/src/client/store.ts +66 -68
- 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.10.
|
|
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.10.
|
|
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.10.
|
|
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.10.
|
|
131
|
+
> 有新版本 vX.Y.Z(当前 v0.10.1) [一键更新]
|
|
132
132
|
|
|
133
133
|
点击「一键更新」→ Host 端运行官方安装器原地重装 → 提示「更新完成,请重启客户端生效」。
|
|
134
134
|
|
package/package.json
CHANGED
|
@@ -155,14 +155,26 @@ window.__ModuleLoader__.load({
|
|
|
155
155
|
const GLASS_ATTR = "data-ar-glass";
|
|
156
156
|
const CSS_TAG = "prompt-skill-armory/background";
|
|
157
157
|
const BACKGROUND_CSS = `
|
|
158
|
-
|
|
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; }
|
|
159
162
|
.ar-bg-layer .ar-bg-image { width: 100%; height: 100%; display: block; border: 0;
|
|
160
163
|
object-fit: var(--ar-bg-fit, cover); opacity: var(--ar-bg-opacity, 1);
|
|
161
164
|
filter: blur(var(--ar-bg-blur, 0px)); transform: scale(var(--ar-bg-scale, 1)); transform-origin: center; }
|
|
162
|
-
.ar-bg-scrim { position: fixed; inset: 0; z-index:
|
|
165
|
+
.ar-bg-scrim { position: fixed; inset: 0; z-index: 0; pointer-events: none;
|
|
163
166
|
background: rgba(255,255,255, var(--ar-bg-scrim, 0.25)); }
|
|
164
167
|
body[data-ds-dark-theme] .ar-bg-scrim { background: rgba(0,0,0, var(--ar-bg-scrim, 0.25)); }
|
|
165
|
-
|
|
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
|
+
|
|
166
178
|
body[${GLASS_ATTR}] [data-composer-card],
|
|
167
179
|
body[${GLASS_ATTR}] [class*="_bubble"]:not([role="tooltip"]),
|
|
168
180
|
body[${GLASS_ATTR}] .md-code-block,
|
|
@@ -230,7 +242,11 @@ window.__ModuleLoader__.load({
|
|
|
230
242
|
try {
|
|
231
243
|
injectBackgroundCss();
|
|
232
244
|
const hasSource = settings.url !== "" || settings.uploadId !== "";
|
|
233
|
-
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
|
+
]) {
|
|
234
250
|
this.rememberOnce(prop);
|
|
235
251
|
document.body.style.setProperty(prop, "transparent");
|
|
236
252
|
}
|
|
@@ -357,17 +373,17 @@ window.__ModuleLoader__.load({
|
|
|
357
373
|
const notifyBg = () => {
|
|
358
374
|
for (const l of bgListeners) l();
|
|
359
375
|
};
|
|
360
|
-
let
|
|
361
|
-
/** Bind the transport to
|
|
362
|
-
function initBackgroundClient(
|
|
363
|
-
|
|
376
|
+
let bgScope;
|
|
377
|
+
/** Bind the transport to the switchblade settings scope (set once at plugin apply). */
|
|
378
|
+
function initBackgroundClient(scope) {
|
|
379
|
+
bgScope = scope;
|
|
364
380
|
}
|
|
365
381
|
/** Surface key: separate wallpaper per web vs desktop (they share the settings doc). */
|
|
366
382
|
const isDesktopSurface = typeof navigator !== "undefined" && navigator.userAgent.toLowerCase().includes("electron");
|
|
367
383
|
const surfaceKey = () => isDesktopSurface ? "backgroundDesktop" : "backgroundWeb";
|
|
368
384
|
/** Read the background section for the current surface from the switchblade settings. */
|
|
369
385
|
function readSection(value) {
|
|
370
|
-
const raw =
|
|
386
|
+
const raw = value?.[surfaceKey()];
|
|
371
387
|
return {
|
|
372
388
|
...DEFAULT_BACKGROUND,
|
|
373
389
|
...typeof raw === "object" && raw !== null ? raw : {}
|
|
@@ -385,15 +401,15 @@ window.__ModuleLoader__.load({
|
|
|
385
401
|
},
|
|
386
402
|
/** Fetch the durable section. @returns true on success (status ready). */
|
|
387
403
|
async load() {
|
|
388
|
-
if (
|
|
404
|
+
if (bgScope === void 0) {
|
|
389
405
|
bgState.status = "error";
|
|
390
406
|
return false;
|
|
391
407
|
}
|
|
392
408
|
try {
|
|
393
|
-
const
|
|
394
|
-
if (
|
|
409
|
+
const snap = bgScope.getSnapshot();
|
|
410
|
+
if (snap.status !== "ready" || snap.value === void 0) return false;
|
|
395
411
|
bgState.status = "ready";
|
|
396
|
-
bgState.value = readSection(
|
|
412
|
+
bgState.value = readSection(snap.value);
|
|
397
413
|
notifyBg();
|
|
398
414
|
return true;
|
|
399
415
|
} catch {
|
|
@@ -402,17 +418,13 @@ window.__ModuleLoader__.load({
|
|
|
402
418
|
}
|
|
403
419
|
},
|
|
404
420
|
async save(section) {
|
|
405
|
-
if (
|
|
421
|
+
if (bgScope === void 0) return;
|
|
406
422
|
try {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
value: section
|
|
413
|
-
}]
|
|
414
|
-
});
|
|
415
|
-
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
|
+
}]);
|
|
416
428
|
bgState.status = "ready";
|
|
417
429
|
bgState.value = { ...section };
|
|
418
430
|
} catch {
|
|
@@ -957,7 +969,7 @@ window.__ModuleLoader__.load({
|
|
|
957
969
|
});
|
|
958
970
|
}
|
|
959
971
|
/** Bump with every release; keep in sync with package.json version + CHANGELOG. */
|
|
960
|
-
const ARMORY_VERSION = "0.10.
|
|
972
|
+
const ARMORY_VERSION = "0.10.1";
|
|
961
973
|
/** Compact duration: 45.2s / 2m42s / 1h05m. */
|
|
962
974
|
function fmtDuration(ms) {
|
|
963
975
|
const s = ms / 1e3;
|
|
@@ -3240,14 +3252,27 @@ window.__ModuleLoader__.load({
|
|
|
3240
3252
|
return error instanceof Error ? error.message : String(error);
|
|
3241
3253
|
}
|
|
3242
3254
|
var SwitchbladeSectionController = class {
|
|
3243
|
-
|
|
3255
|
+
scope;
|
|
3256
|
+
remote;
|
|
3244
3257
|
sessionId;
|
|
3245
3258
|
/** Snapshot store backing the section's view state. */
|
|
3246
3259
|
store = createSnapshotStore(IDLE);
|
|
3247
|
-
constructor(
|
|
3248
|
-
this.
|
|
3260
|
+
constructor(scope, remote, sessionId) {
|
|
3261
|
+
this.scope = scope;
|
|
3262
|
+
this.remote = remote;
|
|
3249
3263
|
this.sessionId = sessionId;
|
|
3250
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
|
+
}
|
|
3251
3276
|
/**
|
|
3252
3277
|
* Load skills, prompts, and installed skills. Prompts and installed
|
|
3253
3278
|
* skills come from the `switchblade` settings namespace (the Host watches
|
|
@@ -3260,16 +3285,14 @@ window.__ModuleLoader__.load({
|
|
|
3260
3285
|
});
|
|
3261
3286
|
try {
|
|
3262
3287
|
const sessionId = this.sessionId?.();
|
|
3263
|
-
const calls = [this.
|
|
3264
|
-
if (sessionId !== void 0) calls.push(this.
|
|
3265
|
-
const [
|
|
3266
|
-
|
|
3267
|
-
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) => ({
|
|
3268
3292
|
name: skill.name,
|
|
3269
3293
|
description: skill.description,
|
|
3270
3294
|
modelInvocable: skill.modelInvocable
|
|
3271
3295
|
})) : [];
|
|
3272
|
-
const switchbladeSection = this.sectionFromSettings(settingsRes.result.value, "switchblade");
|
|
3273
3296
|
const prompts = Array.isArray(switchbladeSection?.prompts) ? switchbladeSection.prompts : [];
|
|
3274
3297
|
const installedSkills = Array.isArray(switchbladeSection?.installedSkills) ? switchbladeSection.installedSkills.map((s) => ({
|
|
3275
3298
|
name: s.name ?? "",
|
|
@@ -3311,9 +3334,13 @@ window.__ModuleLoader__.load({
|
|
|
3311
3334
|
});
|
|
3312
3335
|
}
|
|
3313
3336
|
}
|
|
3314
|
-
/** 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. */
|
|
3315
3340
|
sectionFromSettings(value, ns) {
|
|
3316
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;
|
|
3317
3344
|
const entries = value.namespaces;
|
|
3318
3345
|
if (!Array.isArray(entries)) return void 0;
|
|
3319
3346
|
for (const entry of entries) {
|
|
@@ -3326,24 +3353,20 @@ window.__ModuleLoader__.load({
|
|
|
3326
3353
|
}
|
|
3327
3354
|
/** Add a prompt. */
|
|
3328
3355
|
async addPrompt(input) {
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
isDefault: this.currentPrompts().length === 0,
|
|
3342
|
-
...input.scope === void 0 || input.scope.type === "global" ? {} : { scope: input.scope }
|
|
3343
|
-
}]
|
|
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 }
|
|
3344
3368
|
}]
|
|
3345
|
-
});
|
|
3346
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3369
|
+
}]);
|
|
3347
3370
|
await this.load();
|
|
3348
3371
|
}
|
|
3349
3372
|
/** Toggle one prompt's enabled state. */
|
|
@@ -3380,15 +3403,11 @@ window.__ModuleLoader__.load({
|
|
|
3380
3403
|
}
|
|
3381
3404
|
/** Persist the prompt list through the settings RPC. */
|
|
3382
3405
|
async writePrompts(prompts) {
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
value: prompts
|
|
3389
|
-
}]
|
|
3390
|
-
});
|
|
3391
|
-
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
|
+
}]);
|
|
3392
3411
|
await this.load();
|
|
3393
3412
|
}
|
|
3394
3413
|
/** Current prompt list from the loaded snapshot. */
|
|
@@ -3408,15 +3427,11 @@ window.__ModuleLoader__.load({
|
|
|
3408
3427
|
content: input.content,
|
|
3409
3428
|
enabled: true
|
|
3410
3429
|
}];
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
value: next
|
|
3417
|
-
}]
|
|
3418
|
-
});
|
|
3419
|
-
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
|
+
}]);
|
|
3420
3435
|
await this.load();
|
|
3421
3436
|
}
|
|
3422
3437
|
/** Toggle one installed skill's enabled state. */
|
|
@@ -3425,29 +3440,21 @@ window.__ModuleLoader__.load({
|
|
|
3425
3440
|
...s,
|
|
3426
3441
|
enabled
|
|
3427
3442
|
} : s);
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
value: next
|
|
3434
|
-
}]
|
|
3435
|
-
});
|
|
3436
|
-
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
|
+
}]);
|
|
3437
3448
|
await this.load();
|
|
3438
3449
|
}
|
|
3439
3450
|
/** Uninstall one installed skill. */
|
|
3440
3451
|
async uninstallSkill(name) {
|
|
3441
3452
|
const next = this.currentInstalledSkills().filter((s) => s.name !== name);
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
value: next
|
|
3448
|
-
}]
|
|
3449
|
-
});
|
|
3450
|
-
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
|
+
}]);
|
|
3451
3458
|
await this.load();
|
|
3452
3459
|
}
|
|
3453
3460
|
/** Update an installed skill's name/description/content. */
|
|
@@ -3458,15 +3465,11 @@ window.__ModuleLoader__.load({
|
|
|
3458
3465
|
description: patch.description ?? s.description,
|
|
3459
3466
|
content: patch.content ?? s.content
|
|
3460
3467
|
} : s);
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
value: next
|
|
3467
|
-
}]
|
|
3468
|
-
});
|
|
3469
|
-
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
|
+
}]);
|
|
3470
3473
|
await this.load();
|
|
3471
3474
|
}
|
|
3472
3475
|
/** Current installed skills from the loaded snapshot. */
|
|
@@ -3478,18 +3481,14 @@ window.__ModuleLoader__.load({
|
|
|
3478
3481
|
* watch sees pendingZip and installs it (skil-filesystem then discovers it).
|
|
3479
3482
|
*/
|
|
3480
3483
|
async installSkillFromZip(name, dataBase64) {
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
}
|
|
3490
|
-
}]
|
|
3491
|
-
});
|
|
3492
|
-
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
|
+
}]);
|
|
3493
3492
|
await new Promise((r) => setTimeout(r, 500));
|
|
3494
3493
|
await this.load();
|
|
3495
3494
|
}
|
|
@@ -3526,32 +3525,24 @@ window.__ModuleLoader__.load({
|
|
|
3526
3525
|
* after a short delay so the panel shows the fresh tool list / error.
|
|
3527
3526
|
*/
|
|
3528
3527
|
async testMcpServer(name) {
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
}
|
|
3538
|
-
}]
|
|
3539
|
-
});
|
|
3540
|
-
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
|
+
}]);
|
|
3541
3536
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
3542
3537
|
await this.load();
|
|
3543
3538
|
}
|
|
3544
3539
|
/** Persist the MCP server config list. */
|
|
3545
3540
|
async writeMcpServers(servers) {
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
value: servers
|
|
3552
|
-
}]
|
|
3553
|
-
});
|
|
3554
|
-
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
|
+
}]);
|
|
3555
3546
|
await this.load();
|
|
3556
3547
|
}
|
|
3557
3548
|
/** Current MCP server list from the loaded snapshot. */
|
|
@@ -3561,11 +3552,18 @@ window.__ModuleLoader__.load({
|
|
|
3561
3552
|
};
|
|
3562
3553
|
//#endregion
|
|
3563
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
|
+
*/
|
|
3564
3561
|
/** Required services (cordis fiber inject). */
|
|
3565
3562
|
const inject = [
|
|
3566
3563
|
"slots",
|
|
3567
3564
|
"locale",
|
|
3568
|
-
"
|
|
3565
|
+
"settingsScope",
|
|
3566
|
+
"remote",
|
|
3569
3567
|
"sessions"
|
|
3570
3568
|
];
|
|
3571
3569
|
/**
|
|
@@ -3577,11 +3575,12 @@ window.__ModuleLoader__.load({
|
|
|
3577
3575
|
zh,
|
|
3578
3576
|
en
|
|
3579
3577
|
}), "ui-switchblade: dictionaries");
|
|
3580
|
-
const
|
|
3578
|
+
const scope = ctx.get("settingsScope").bind({ namespace: "switchblade" });
|
|
3579
|
+
const remote = ctx.get("remote");
|
|
3581
3580
|
const sessions = ctx.get("sessions");
|
|
3582
3581
|
applyHintStyle();
|
|
3583
3582
|
try {
|
|
3584
|
-
initBackgroundClient(
|
|
3583
|
+
initBackgroundClient(scope);
|
|
3585
3584
|
const paintBackground = () => {
|
|
3586
3585
|
const s = backgroundClient.getSnapshot();
|
|
3587
3586
|
if (s.status === "ready") applyBackground(s.value);
|
|
@@ -3596,7 +3595,7 @@ window.__ModuleLoader__.load({
|
|
|
3596
3595
|
} catch (error) {
|
|
3597
3596
|
console.warn("[switchblade] background init skipped:", error);
|
|
3598
3597
|
}
|
|
3599
|
-
const controller = new SwitchbladeSectionController(
|
|
3598
|
+
const controller = new SwitchbladeSectionController(scope, remote, () => {
|
|
3600
3599
|
const state = sessions.list.getSnapshot();
|
|
3601
3600
|
return state.current === void 0 ? void 0 : state.current;
|
|
3602
3601
|
});
|