prompt-skill-armory 0.10.0 → 0.10.2
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 +146 -139
- 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 +43 -29
- 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.2
|
|
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.2) [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.2
|
|
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.2) [一键更新]
|
|
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 {
|
|
@@ -449,7 +461,10 @@ window.__ModuleLoader__.load({
|
|
|
449
461
|
applyHintStyle();
|
|
450
462
|
}
|
|
451
463
|
let hintObserver;
|
|
452
|
-
/** Inject (or clear) the per-surface style for the composer
|
|
464
|
+
/** Inject (or clear) the per-surface style for the composer hint + input card.
|
|
465
|
+
* DSH 2.0.9 removed the old `[data-decoration="hint"]` row; the composer card
|
|
466
|
+
* (`[data-composer-card]`) is the stable surface that carries the input
|
|
467
|
+
* placeholder and inline claim hints, so the style lands there. */
|
|
453
468
|
function applyHintStyle() {
|
|
454
469
|
try {
|
|
455
470
|
const hint = (bgState.value ?? DEFAULT_BACKGROUND).hint ?? DEFAULT_BACKGROUND.hint;
|
|
@@ -470,7 +485,15 @@ window.__ModuleLoader__.load({
|
|
|
470
485
|
const size = hint.size || 11;
|
|
471
486
|
const gradPreset = GRADIENTS.find((g) => g.id === (hint.gradient ?? ""));
|
|
472
487
|
const grad = gradPreset !== void 0 ? gradPreset.css : "";
|
|
473
|
-
|
|
488
|
+
const props = [
|
|
489
|
+
"font-size:" + size + "px",
|
|
490
|
+
"letter-spacing:0.3px",
|
|
491
|
+
"font-weight:600",
|
|
492
|
+
"opacity:0.95",
|
|
493
|
+
grad !== "" ? `background-image:${grad};-webkit-background-clip:text;background-clip:text;color:transparent` : `color:${color}`
|
|
494
|
+
].join(";");
|
|
495
|
+
tag.textContent = `[data-composer-card] input::placeholder,[data-composer-card] textarea::placeholder{${props}}
|
|
496
|
+
[data-composer-card] [class*="_hint"]{${props}}`;
|
|
474
497
|
const statsStyle = (root) => {
|
|
475
498
|
if (grad !== "") {
|
|
476
499
|
root.style.backgroundImage = grad;
|
|
@@ -487,10 +510,6 @@ window.__ModuleLoader__.load({
|
|
|
487
510
|
root.style.fontWeight = "600";
|
|
488
511
|
root.style.opacity = "0.95";
|
|
489
512
|
};
|
|
490
|
-
if (grad !== "") hintCss += `background-image:${grad};-webkit-background-clip:text;background-clip:text;color:transparent`;
|
|
491
|
-
else hintCss += `color:${color}`;
|
|
492
|
-
hintCss += "}";
|
|
493
|
-
tag.textContent = hintCss;
|
|
494
513
|
const applyStats = () => {
|
|
495
514
|
try {
|
|
496
515
|
const seps = Array.from(document.querySelectorAll("span[aria-hidden]"));
|
|
@@ -957,7 +976,7 @@ window.__ModuleLoader__.load({
|
|
|
957
976
|
});
|
|
958
977
|
}
|
|
959
978
|
/** Bump with every release; keep in sync with package.json version + CHANGELOG. */
|
|
960
|
-
const ARMORY_VERSION = "0.10.
|
|
979
|
+
const ARMORY_VERSION = "0.10.2";
|
|
961
980
|
/** Compact duration: 45.2s / 2m42s / 1h05m. */
|
|
962
981
|
function fmtDuration(ms) {
|
|
963
982
|
const s = ms / 1e3;
|
|
@@ -3240,14 +3259,27 @@ window.__ModuleLoader__.load({
|
|
|
3240
3259
|
return error instanceof Error ? error.message : String(error);
|
|
3241
3260
|
}
|
|
3242
3261
|
var SwitchbladeSectionController = class {
|
|
3243
|
-
|
|
3262
|
+
scope;
|
|
3263
|
+
remote;
|
|
3244
3264
|
sessionId;
|
|
3245
3265
|
/** Snapshot store backing the section's view state. */
|
|
3246
3266
|
store = createSnapshotStore(IDLE);
|
|
3247
|
-
constructor(
|
|
3248
|
-
this.
|
|
3267
|
+
constructor(scope, remote, sessionId) {
|
|
3268
|
+
this.scope = scope;
|
|
3269
|
+
this.remote = remote;
|
|
3249
3270
|
this.sessionId = sessionId;
|
|
3250
3271
|
}
|
|
3272
|
+
/** 2.0.9 settings read: scope mirror snapshot (never the old api.settings). */
|
|
3273
|
+
describeSettings() {
|
|
3274
|
+
const snap = this.scope.getSnapshot();
|
|
3275
|
+
if (snap.status !== "ready" || snap.value === void 0) return void 0;
|
|
3276
|
+
return this.sectionFromSettings(snap.value, "switchblade");
|
|
3277
|
+
}
|
|
3278
|
+
/** 2.0.9 settings write: scope.mutate(ops) — Host fold + re-inject. */
|
|
3279
|
+
async mutateSettings(ops) {
|
|
3280
|
+
if (this.scope.getSnapshot().status !== "ready") throw new Error("settings scope not ready");
|
|
3281
|
+
await this.scope.mutate(ops);
|
|
3282
|
+
}
|
|
3251
3283
|
/**
|
|
3252
3284
|
* Load skills, prompts, and installed skills. Prompts and installed
|
|
3253
3285
|
* skills come from the `switchblade` settings namespace (the Host watches
|
|
@@ -3260,16 +3292,14 @@ window.__ModuleLoader__.load({
|
|
|
3260
3292
|
});
|
|
3261
3293
|
try {
|
|
3262
3294
|
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) => ({
|
|
3295
|
+
const calls = [Promise.resolve(this.describeSettings())];
|
|
3296
|
+
if (sessionId !== void 0) calls.push(this.remote.skills.list({ sessionId }));
|
|
3297
|
+
const [switchbladeSection, skillRes] = await Promise.all(calls);
|
|
3298
|
+
const skills = skillRes !== void 0 && skillRes.ok && skillRes.value !== void 0 ? skillRes.value.skills.map((skill) => ({
|
|
3268
3299
|
name: skill.name,
|
|
3269
3300
|
description: skill.description,
|
|
3270
3301
|
modelInvocable: skill.modelInvocable
|
|
3271
3302
|
})) : [];
|
|
3272
|
-
const switchbladeSection = this.sectionFromSettings(settingsRes.result.value, "switchblade");
|
|
3273
3303
|
const prompts = Array.isArray(switchbladeSection?.prompts) ? switchbladeSection.prompts : [];
|
|
3274
3304
|
const installedSkills = Array.isArray(switchbladeSection?.installedSkills) ? switchbladeSection.installedSkills.map((s) => ({
|
|
3275
3305
|
name: s.name ?? "",
|
|
@@ -3311,9 +3341,13 @@ window.__ModuleLoader__.load({
|
|
|
3311
3341
|
});
|
|
3312
3342
|
}
|
|
3313
3343
|
}
|
|
3314
|
-
/** Read one namespace's
|
|
3344
|
+
/** Read one namespace's section from a settings value. The 2.0.9 scope
|
|
3345
|
+
* snapshot carries the bound namespace's own value; older describe payloads
|
|
3346
|
+
* carry a `namespaces[]` table — accept both. */
|
|
3315
3347
|
sectionFromSettings(value, ns) {
|
|
3316
3348
|
if (typeof value !== "object" || value === null) return void 0;
|
|
3349
|
+
const asSection = value;
|
|
3350
|
+
if (Array.isArray(asSection.prompts) || Array.isArray(asSection.installedSkills) || asSection.mcpServers !== void 0) return asSection;
|
|
3317
3351
|
const entries = value.namespaces;
|
|
3318
3352
|
if (!Array.isArray(entries)) return void 0;
|
|
3319
3353
|
for (const entry of entries) {
|
|
@@ -3326,24 +3360,20 @@ window.__ModuleLoader__.load({
|
|
|
3326
3360
|
}
|
|
3327
3361
|
/** Add a prompt. */
|
|
3328
3362
|
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
|
-
}]
|
|
3363
|
+
await this.mutateSettings([{
|
|
3364
|
+
op: "set",
|
|
3365
|
+
path: ["prompts"],
|
|
3366
|
+
value: [...this.currentPrompts(), {
|
|
3367
|
+
id: this.slugify(input.name),
|
|
3368
|
+
name: input.name,
|
|
3369
|
+
description: input.description,
|
|
3370
|
+
content: input.content,
|
|
3371
|
+
order: this.currentPrompts().length,
|
|
3372
|
+
enabled: true,
|
|
3373
|
+
isDefault: this.currentPrompts().length === 0,
|
|
3374
|
+
...input.scope === void 0 || input.scope.type === "global" ? {} : { scope: input.scope }
|
|
3344
3375
|
}]
|
|
3345
|
-
});
|
|
3346
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3376
|
+
}]);
|
|
3347
3377
|
await this.load();
|
|
3348
3378
|
}
|
|
3349
3379
|
/** Toggle one prompt's enabled state. */
|
|
@@ -3380,15 +3410,11 @@ window.__ModuleLoader__.load({
|
|
|
3380
3410
|
}
|
|
3381
3411
|
/** Persist the prompt list through the settings RPC. */
|
|
3382
3412
|
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);
|
|
3413
|
+
await this.mutateSettings([{
|
|
3414
|
+
op: "set",
|
|
3415
|
+
path: ["prompts"],
|
|
3416
|
+
value: prompts
|
|
3417
|
+
}]);
|
|
3392
3418
|
await this.load();
|
|
3393
3419
|
}
|
|
3394
3420
|
/** Current prompt list from the loaded snapshot. */
|
|
@@ -3408,15 +3434,11 @@ window.__ModuleLoader__.load({
|
|
|
3408
3434
|
content: input.content,
|
|
3409
3435
|
enabled: true
|
|
3410
3436
|
}];
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
value: next
|
|
3417
|
-
}]
|
|
3418
|
-
});
|
|
3419
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3437
|
+
await this.mutateSettings([{
|
|
3438
|
+
op: "set",
|
|
3439
|
+
path: ["installedSkills"],
|
|
3440
|
+
value: next
|
|
3441
|
+
}]);
|
|
3420
3442
|
await this.load();
|
|
3421
3443
|
}
|
|
3422
3444
|
/** Toggle one installed skill's enabled state. */
|
|
@@ -3425,29 +3447,21 @@ window.__ModuleLoader__.load({
|
|
|
3425
3447
|
...s,
|
|
3426
3448
|
enabled
|
|
3427
3449
|
} : s);
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
value: next
|
|
3434
|
-
}]
|
|
3435
|
-
});
|
|
3436
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3450
|
+
await this.mutateSettings([{
|
|
3451
|
+
op: "set",
|
|
3452
|
+
path: ["installedSkills"],
|
|
3453
|
+
value: next
|
|
3454
|
+
}]);
|
|
3437
3455
|
await this.load();
|
|
3438
3456
|
}
|
|
3439
3457
|
/** Uninstall one installed skill. */
|
|
3440
3458
|
async uninstallSkill(name) {
|
|
3441
3459
|
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);
|
|
3460
|
+
await this.mutateSettings([{
|
|
3461
|
+
op: "set",
|
|
3462
|
+
path: ["installedSkills"],
|
|
3463
|
+
value: next
|
|
3464
|
+
}]);
|
|
3451
3465
|
await this.load();
|
|
3452
3466
|
}
|
|
3453
3467
|
/** Update an installed skill's name/description/content. */
|
|
@@ -3458,15 +3472,11 @@ window.__ModuleLoader__.load({
|
|
|
3458
3472
|
description: patch.description ?? s.description,
|
|
3459
3473
|
content: patch.content ?? s.content
|
|
3460
3474
|
} : s);
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
value: next
|
|
3467
|
-
}]
|
|
3468
|
-
});
|
|
3469
|
-
if (!res.result.ok) throw new Error(res.result.error.message);
|
|
3475
|
+
await this.mutateSettings([{
|
|
3476
|
+
op: "set",
|
|
3477
|
+
path: ["installedSkills"],
|
|
3478
|
+
value: next
|
|
3479
|
+
}]);
|
|
3470
3480
|
await this.load();
|
|
3471
3481
|
}
|
|
3472
3482
|
/** Current installed skills from the loaded snapshot. */
|
|
@@ -3478,18 +3488,14 @@ window.__ModuleLoader__.load({
|
|
|
3478
3488
|
* watch sees pendingZip and installs it (skil-filesystem then discovers it).
|
|
3479
3489
|
*/
|
|
3480
3490
|
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);
|
|
3491
|
+
await this.mutateSettings([{
|
|
3492
|
+
op: "set",
|
|
3493
|
+
path: ["pendingZip"],
|
|
3494
|
+
value: {
|
|
3495
|
+
name,
|
|
3496
|
+
dataBase64
|
|
3497
|
+
}
|
|
3498
|
+
}]);
|
|
3493
3499
|
await new Promise((r) => setTimeout(r, 500));
|
|
3494
3500
|
await this.load();
|
|
3495
3501
|
}
|
|
@@ -3526,32 +3532,24 @@ window.__ModuleLoader__.load({
|
|
|
3526
3532
|
* after a short delay so the panel shows the fresh tool list / error.
|
|
3527
3533
|
*/
|
|
3528
3534
|
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);
|
|
3535
|
+
await this.mutateSettings([{
|
|
3536
|
+
op: "set",
|
|
3537
|
+
path: ["mcpTestRequest"],
|
|
3538
|
+
value: {
|
|
3539
|
+
serverName: name,
|
|
3540
|
+
ts: Date.now()
|
|
3541
|
+
}
|
|
3542
|
+
}]);
|
|
3541
3543
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
3542
3544
|
await this.load();
|
|
3543
3545
|
}
|
|
3544
3546
|
/** Persist the MCP server config list. */
|
|
3545
3547
|
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);
|
|
3548
|
+
await this.mutateSettings([{
|
|
3549
|
+
op: "set",
|
|
3550
|
+
path: ["mcpServers"],
|
|
3551
|
+
value: servers
|
|
3552
|
+
}]);
|
|
3555
3553
|
await this.load();
|
|
3556
3554
|
}
|
|
3557
3555
|
/** Current MCP server list from the loaded snapshot. */
|
|
@@ -3561,11 +3559,19 @@ window.__ModuleLoader__.load({
|
|
|
3561
3559
|
};
|
|
3562
3560
|
//#endregion
|
|
3563
3561
|
//#region src/client/index.ts
|
|
3562
|
+
/**
|
|
3563
|
+
* Switchblade management page, browser half: registers the `settings.section`
|
|
3564
|
+
* navigation entry and renders the edgelord panel from the connection RPC
|
|
3565
|
+
* state. Global scope (root) — one management seat for every session.
|
|
3566
|
+
* @module @deepseek-ai/dsh-client-ui-switchblade
|
|
3567
|
+
*/
|
|
3564
3568
|
/** Required services (cordis fiber inject). */
|
|
3565
3569
|
const inject = [
|
|
3566
3570
|
"slots",
|
|
3567
3571
|
"locale",
|
|
3568
|
-
"
|
|
3572
|
+
"settingsScope",
|
|
3573
|
+
"remote",
|
|
3574
|
+
"remote.skills",
|
|
3569
3575
|
"sessions"
|
|
3570
3576
|
];
|
|
3571
3577
|
/**
|
|
@@ -3577,11 +3583,12 @@ window.__ModuleLoader__.load({
|
|
|
3577
3583
|
zh,
|
|
3578
3584
|
en
|
|
3579
3585
|
}), "ui-switchblade: dictionaries");
|
|
3580
|
-
const
|
|
3586
|
+
const scope = ctx.get("settingsScope").bind({ namespace: "switchblade" });
|
|
3587
|
+
const remote = ctx.get("remote");
|
|
3581
3588
|
const sessions = ctx.get("sessions");
|
|
3582
3589
|
applyHintStyle();
|
|
3583
3590
|
try {
|
|
3584
|
-
initBackgroundClient(
|
|
3591
|
+
initBackgroundClient(scope);
|
|
3585
3592
|
const paintBackground = () => {
|
|
3586
3593
|
const s = backgroundClient.getSnapshot();
|
|
3587
3594
|
if (s.status === "ready") applyBackground(s.value);
|
|
@@ -3596,7 +3603,7 @@ window.__ModuleLoader__.load({
|
|
|
3596
3603
|
} catch (error) {
|
|
3597
3604
|
console.warn("[switchblade] background init skipped:", error);
|
|
3598
3605
|
}
|
|
3599
|
-
const controller = new SwitchbladeSectionController(
|
|
3606
|
+
const controller = new SwitchbladeSectionController(scope, remote, () => {
|
|
3600
3607
|
const state = sessions.list.getSnapshot();
|
|
3601
3608
|
return state.current === void 0 ? void 0 : state.current;
|
|
3602
3609
|
});
|