dsh-plugin-shop 0.4.13 → 0.4.14
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 +3 -3
- package/lib/client.js +109 -83
- package/lib/index.js +22 -9
- package/lib/typert.host.js +14 -12
- package/lib/typert.remote-client.js +11 -9
- package/lib/types/host/catalog.d.ts +3 -2
- package/lib/types/host/index.d.ts +4 -1
- package/lib/types/host/types.d.ts +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,9 +52,9 @@ install them once with `npm install -g @deepseek-ai/dsh pnpm` and verify with
|
|
|
52
52
|
# holds back very recent releases, so a bare `add dsh-plugin-shop` can hand
|
|
53
53
|
# you an older version for a while. Pin the current release — refresh it
|
|
54
54
|
# with `npm view dsh-plugin-shop version`.
|
|
55
|
-
dsh plugin --profile web add dsh-plugin-shop@0.4.
|
|
55
|
+
dsh plugin --profile web add dsh-plugin-shop@0.4.14
|
|
56
56
|
# or straight through npx, nothing installed:
|
|
57
|
-
npx -y @deepseek-ai/dsh plugin --profile web add dsh-plugin-shop@0.4.
|
|
57
|
+
npx -y @deepseek-ai/dsh plugin --profile web add dsh-plugin-shop@0.4.14
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Replace `web` with your profile if you use another one. Then restart `dsh` once — a
|
|
@@ -84,7 +84,7 @@ ls -1 "${DSH_HOME:-$HOME/.dsh}/profiles" | grep -v '^node_modules$'
|
|
|
84
84
|
cooldown, and deterministic installs are the point of the agent path.
|
|
85
85
|
|
|
86
86
|
```sh
|
|
87
|
-
dsh plugin --profile <profile> add dsh-plugin-shop@0.4.
|
|
87
|
+
dsh plugin --profile <profile> add dsh-plugin-shop@0.4.14
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
**3. Verify — do not skip this.** A zero exit from step 2 means pnpm resolved the
|
package/lib/client.js
CHANGED
|
@@ -4301,7 +4301,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4301
4301
|
"capabilities": array(string())
|
|
4302
4302
|
})]).optional(),
|
|
4303
4303
|
"source": union([literal("npm"), literal("github")]),
|
|
4304
|
-
"repo": union([_undefined(), string()]).optional()
|
|
4304
|
+
"repo": union([_undefined(), string()]).optional(),
|
|
4305
|
+
"subdir": union([_undefined(), string()]).optional()
|
|
4305
4306
|
})),
|
|
4306
4307
|
"denied": array(object({
|
|
4307
4308
|
"name": string(),
|
|
@@ -4313,7 +4314,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4313
4314
|
"name": string(),
|
|
4314
4315
|
"installed": string(),
|
|
4315
4316
|
"latest": string(),
|
|
4316
|
-
"outdated": boolean()
|
|
4317
|
+
"outdated": boolean(),
|
|
4318
|
+
"enabled": boolean()
|
|
4317
4319
|
}));
|
|
4318
4320
|
const dsh_plugin_shop_shop_installStart_parameter_0$schema = object({
|
|
4319
4321
|
"name": string(),
|
|
@@ -4414,7 +4416,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4414
4416
|
},
|
|
4415
4417
|
sourceLocation: {
|
|
4416
4418
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4417
|
-
"line":
|
|
4419
|
+
"line": 275,
|
|
4418
4420
|
"column": 9
|
|
4419
4421
|
}
|
|
4420
4422
|
},
|
|
@@ -4432,7 +4434,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4432
4434
|
},
|
|
4433
4435
|
sourceLocation: {
|
|
4434
4436
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4435
|
-
"line":
|
|
4437
|
+
"line": 380,
|
|
4436
4438
|
"column": 9
|
|
4437
4439
|
}
|
|
4438
4440
|
},
|
|
@@ -4460,7 +4462,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4460
4462
|
},
|
|
4461
4463
|
sourceLocation: {
|
|
4462
4464
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4463
|
-
"line":
|
|
4465
|
+
"line": 301,
|
|
4464
4466
|
"column": 9
|
|
4465
4467
|
}
|
|
4466
4468
|
},
|
|
@@ -4487,7 +4489,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4487
4489
|
},
|
|
4488
4490
|
sourceLocation: {
|
|
4489
4491
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4490
|
-
"line":
|
|
4492
|
+
"line": 369,
|
|
4491
4493
|
"column": 3
|
|
4492
4494
|
}
|
|
4493
4495
|
},
|
|
@@ -4505,7 +4507,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4505
4507
|
},
|
|
4506
4508
|
sourceLocation: {
|
|
4507
4509
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4508
|
-
"line":
|
|
4510
|
+
"line": 491,
|
|
4509
4511
|
"column": 9
|
|
4510
4512
|
}
|
|
4511
4513
|
},
|
|
@@ -4532,7 +4534,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4532
4534
|
},
|
|
4533
4535
|
sourceLocation: {
|
|
4534
4536
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4535
|
-
"line":
|
|
4537
|
+
"line": 241,
|
|
4536
4538
|
"column": 3
|
|
4537
4539
|
}
|
|
4538
4540
|
},
|
|
@@ -4560,7 +4562,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4560
4562
|
},
|
|
4561
4563
|
sourceLocation: {
|
|
4562
4564
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4563
|
-
"line":
|
|
4565
|
+
"line": 451,
|
|
4564
4566
|
"column": 9
|
|
4565
4567
|
}
|
|
4566
4568
|
},
|
|
@@ -4587,7 +4589,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4587
4589
|
},
|
|
4588
4590
|
sourceLocation: {
|
|
4589
4591
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4590
|
-
"line":
|
|
4592
|
+
"line": 540,
|
|
4591
4593
|
"column": 9
|
|
4592
4594
|
}
|
|
4593
4595
|
},
|
|
@@ -4605,7 +4607,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4605
4607
|
},
|
|
4606
4608
|
sourceLocation: {
|
|
4607
4609
|
"file": "packages/dsh-plugin-shop/src/host/index.ts",
|
|
4608
|
-
"line":
|
|
4610
|
+
"line": 525,
|
|
4609
4611
|
"column": 9
|
|
4610
4612
|
}
|
|
4611
4613
|
}
|
|
@@ -5084,7 +5086,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5084
5086
|
}
|
|
5085
5087
|
//#endregion
|
|
5086
5088
|
//#region \0dsh-plugin-shop-css:e3675a89
|
|
5087
|
-
const css = "/* Shop tab styles — a market shelf inside the settings surface. The visual\n * language is the dsh theme's alias tokens ONLY (the four tokens the previous\n * styles referenced that do not exist — bg-layer-3, interactive-bg-hover,\n * state-error, state-success — are corrected to bg-layer-2 and the\n * state-*-primary set). The signature is the category spine: one HUE per\n * category (six fixed hues, not the brand token — the brand resolves to\n * near-black in the light theme, so six brand opacities read as six shades\n * of gray), with the category name as the cover label in the same hue. Class names are mapped to content-derived names at bundle time\n * (tsdown.s8583e3_client.s942a79_config.s5f67aa_ts) and stubbed in tests; only the keys are relied\n * on.\n *\n * One token rule the theme forces: the background LAYERS do not carry\n * contrast. In the light theme bg-base, bg-layer-1, bg-layer-2 and\n * bg-layer-3 all resolve to the same white; only the dark theme spreads them\n * (950/875/850/800). So a layer-2 fill on a layer-1 ground is invisible for\n * half of all users, and anything whose fill is its ONLY affordance — the\n * loading skeleton, the borderless capability chips — derives its fill from\n * label-primary instead, which inverts with the theme by construction.\n * Elements that also carry a border or text may keep a layer fill.\n * `css-tokens.s8583e3_client.sfd9d8a_spec.s5f67aa_ts` pins this. */\n\n.s255e5a_panel {\n display: flex;\n flex-direction: column;\n gap: 14px;\n /* The shelf never scrolls sideways: a card too wide for its track wraps\n * its badges rather than widening the panel. */\n overflow-x: hidden;\n}\n\n.s44a3ec_stateLine {\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* Visually hidden but screen-reader readable (the loading copy while the\n * skeleton stands in visually). */\n.s3a0ece_srOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n overflow: hidden;\n white-space: nowrap;\n}\n\n/* The loading shelf: ghost cards with the same geometry as the real grid, so\n * the swap to content is a same-shape handoff instead of a jump. */\n.se0c3b4_skeletonGrid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 8px;\n}\n\n.s520416_skeletonCard {\n position: relative;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n}\n\n/* The shimmer sweep: one gradient band travels across each ghost card while\n * the bars breathe, so the loading state reads as \"the shelf is scanning\". */\n.s520416_skeletonCard::after {\n content: '';\n position: absolute;\n inset: 0;\n background: linear-gradient(\n 100deg,\n transparent 25%,\n color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent) 50%,\n transparent 75%\n );\n transform: translateX(-100%);\n animation: dshShopSkeletonSweep 1.4s ease-in-out infinite;\n pointer-events: none;\n}\n\n@keyframes dshShopSkeletonSweep {\n to { transform: translateX(100%); }\n}\n\n.s8c7d6f_skeletonName {\n width: 55%;\n height: 14px;\n margin: 10px 12px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.sf5179e_skeletonSummary {\n width: 92%;\n height: 12px;\n margin: 10px 12px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.sbb0d25_skeletonSummaryShort {\n width: 68%;\n height: 12px;\n margin: 6px 12px 10px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n/* The ghost of the action line, right where the real buttons land. */\n.s96e910_skeletonActions {\n display: block;\n width: 84px;\n height: 24px;\n margin: 0 12px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.s520416_skeletonCard span {\n animation: dshShopSkeletonPulse 1.6s ease-in-out infinite;\n}\n\n@keyframes dshShopSkeletonPulse {\n 0%, 100% { opacity: 0.5; }\n 50% { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s520416_skeletonCard span { animation: none; opacity: 0.75; }\n .s520416_skeletonCard::after { content: none; }\n}\n\n.s73242a_actionButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s73242a_actionButton:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.s73242a_actionButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s646509_toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.s745e3c_toolbarRight {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* The shop's own version, right of the search box: `v0.4.4`, plus the\n * update button when the version check found a newer release. */\n.s4fe61f_versionBlock {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sb9b924_versionText {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa04455_updateSelfButton {\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-brand-primary);\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n color: var(--dsw-alias-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n\n.sa04455_updateSelfButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 20%, transparent);\n}\n\n.sa04455_updateSelfButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The on-demand re-check next to the version number: a quiet pill; the\n * border and text carry it in the light theme where bg layers are white. */\n.s614a38_checkUpdateButton {\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.s614a38_checkUpdateButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n color: var(--dsw-alias-label-primary);\n}\n\n.s614a38_checkUpdateButton:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n.s614a38_checkUpdateButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The project's GitHub mark, right of the version row: a quiet icon link.\n * The octocat carries itself — color shift on hover, no text, no border. */\n.sa987f7_githubLink {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 3px;\n border-radius: 6px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa987f7_githubLink:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.sa987f7_githubLink:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The self-update's expanded states (running log / done + restart /\n * failure detail) sit under the toolbar, above the category bar. */\n.sb81ba5_selfUpdatePanel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 8px;\n}\n\n.s232ec4_searchInput {\n width: min(280px, 100%);\n padding: 6px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n.s232ec4_searchInput:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s1555aa_staleBlock {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.s3946f1_staleBadge {\n padding: 2px 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n color: var(--dsw-alias-state-warn-primary);\n font-size: 12px;\n}\n\n.sb2c859_categoryBar {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n\n.s26d58e_categoryButton {\n padding: 3px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.s26d58e_categoryButton:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.s5f68c4_categoryButtonOn {\n border-color: var(--dsw-alias-brand-primary);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n color: var(--dsw-alias-brand-primary);\n font-weight: 600;\n}\n\n.s26d58e_categoryButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s668774_catalogHeading {\n margin: 2px 0 0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-primary);\n}\n\n.sccc4d1_catalogStats {\n margin: 6px 0 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s6de1ab_emptyLine {\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* The shelf: a responsive grid of cards. */\n/* Single-line rows: one full-width column, one plugin per line. */\n.sf657f5_cards {\n display: grid;\n grid-template-columns: 1fr;\n max-width: 100%;\n gap: 8px;\n list-style: none;\n margin: 0;\n padding: 0;\n animation: dshShopCardsIn 220ms ease;\n}\n\n@keyframes dshShopCardsIn {\n from { opacity: 0; transform: translateY(3px); }\n to { opacity: 1; transform: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sf657f5_cards { animation: none; }\n}\n\n.s65f383_card {\n position: relative;\n display: flex;\n flex-direction: column;\n /* A grid item's min-width is auto by default: its content would widen the\n * 1fr track past the panel and overflow horizontally. */\n min-width: 0;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;\n /* Off-screen cards skip layout and paint; the placeholder keeps scrollbar\n * estimation sane before the browser has measured the real height. */\n content-visibility: auto;\n contain-intrinsic-size: auto 140px;\n}\n\n/* The sentinel that triggers the next shelf batch: zero visual footprint. */\n.sd7ee01_cardsSentry {\n height: 1px;\n margin: 0;\n padding: 0;\n}\n\n.s705cc6_showingLine {\n margin: 0;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s65f383_card:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l1));\n transform: translateY(-1px);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s65f383_card { transition: none; }\n .s65f383_card:hover { transform: none; }\n}\n\n/* The signature: a spine and cover in the category's own hue. The hues are\n * fixed mid-bright colors that read on both themes; `other` deliberately\n * stays a neutral gray so the fallback category does not compete. */\n.s4ce25d_cardSpine {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 3px;\n background: var(--spine-hue, #8B8E96);\n}\n\n.s65f383_card[data-category='tool'] { --spine-hue: #4C8DFF; }\n.s65f383_card[data-category='provider'] { --spine-hue: #A78BFA; }\n.s65f383_card[data-category='ui'] { --spine-hue: #2DD4BF; }\n.s65f383_card[data-category='workflow'] { --spine-hue: #F59E0B; }\n.s65f383_card[data-category='integration'] { --spine-hue: #34D399; }\n.s65f383_card[data-category='other'] { --spine-hue: #8B8E96; }\n\n/* The category sits in the badge row as a quiet chip in the category's own\n * hue — the border carries it where the light theme's white layers cannot\n * (the same lesson as the check button). */\n.s9c8eaa_categoryBadge {\n padding: 1px 7px;\n border: 1px solid color-mix(in srgb, var(--spine-hue, #8B8E96) 45%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--spine-hue, #8B8E96);\n white-space: nowrap;\n}\n\n.sa97234_entryHeader {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n min-width: 0;\n padding: 8px 12px 2px;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.sa97234_entryHeader:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n/* The name fills the row and truncates rather than wraps; the badges stay\n * intact beside it. */\n.sc3f149_name {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n font-weight: 600;\n flex: 1 1 auto;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--dsw-alias-label-primary);\n}\n\n.s513026_badges {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n/* The action line: buttons side by side; an active install/uninstall flow\n * (gate, log, notices) takes the full width below them. */\n.s9b5048_cardActions {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 10px;\n}\n\n.s9b5048_cardActions > .sc4f2ac_gate,\n.s9b5048_cardActions > .s4d374c_installPanel,\n.s9b5048_cardActions > .sf53ca0_installedActions {\n flex-basis: 100%;\n}\n\n/* The entry's version, always visible on the card (the expanded detail\n * repeats it in the version row) — the same quiet mono as the toolbar. */\n.sc6ec6e_cardVersion {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* The octocat marking a github-sourced entry, beside its short commit. */\n.s71f10f_sourceBadge {\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s5e82cb_tierBadge {\n padding: 1px 7px;\n border-radius: 999px;\n font-size: 11px;\n line-height: 1.6;\n}\n\n.s5e82cb_tierBadge[data-tier='verified'] {\n color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-success-primary) 40%, transparent);\n}\n\n.s5e82cb_tierBadge[data-tier='verified-stale'] {\n color: var(--dsw-alias-state-warn-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n}\n\n.s5e82cb_tierBadge[data-tier='community'] {\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-2);\n border: 1px solid var(--dsw-alias-border-l2);\n}\n\n.sff43b4_starsBadge {\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s73f7fb_chevron, .s61393c_chevronOpen {\n color: var(--dsw-alias-label-secondary);\n transition: transform 120ms ease;\n}\n\n.s61393c_chevronOpen { transform: rotate(180deg); }\n\n@media (prefers-reduced-motion: reduce) {\n .s73f7fb_chevron, .s61393c_chevronOpen { transition: none; }\n}\n\n.s820ebf_body {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 12px;\n}\n\n.sb8fbc8_summary {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.se507db_summaryZh {\n margin: -4px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Expanded cards show the full summary: the clamp is lifted, never raised —\n * a higher number would still truncate the author's text, just later. */\n.s10baf0_summaryExpanded {\n -webkit-line-clamp: unset;\n display: block;\n}\n\n.sb9dba9_summaryZhExpanded {\n -webkit-line-clamp: unset;\n display: block;\n}\n\n.s9d2029_capabilitiesBlock {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.s3bdbd5_capabilitiesNote {\n margin: 0;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s441702_capabilities {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.s441702_capabilities li {\n padding: 1px 6px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sde3f0c_detail {\n border-top: 1px solid var(--dsw-alias-border-l1);\n padding-top: 8px;\n}\n\n.se98179_detailRows {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin: 0;\n}\n\n.sfb4d2f_detailRow {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n font-size: 12px;\n}\n\n.sfb4d2f_detailRow dt {\n color: var(--dsw-alias-label-secondary);\n}\n\n.sfb4d2f_detailRow dd {\n margin: 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n overflow-wrap: anywhere;\n text-align: right;\n color: var(--dsw-alias-label-primary);\n}\n\n.sfb4d2f_detailRow a {\n color: var(--dsw-alias-brand-primary);\n text-decoration: none;\n}\n\n.sfb4d2f_detailRow a:hover {\n text-decoration: underline;\n}\n\n.sfb4d2f_detailRow a:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.sd58c6d_reviewedLine {\n margin: 8px 0 0;\n padding: 6px 8px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n font-size: 12px;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n/* Install flow. */\n.s4d374c_installPanel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 2px;\n}\n\n.se7aaed_installButton, .sb43a49_confirmButton, .s6e45d1_cancelButton {\n align-self: flex-start;\n padding: 5px 14px;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n}\n\n.se7aaed_installButton {\n border: 1px solid var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.se7aaed_installButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 88%, var(--dsw-alias-label-primary));\n}\n\n.sb43a49_confirmButton {\n border: 1px solid var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.sb43a49_confirmButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 88%, var(--dsw-alias-label-primary));\n}\n\n.s6e45d1_cancelButton {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n}\n\n.s6e45d1_cancelButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n}\n\n.se7aaed_installButton:focus-visible, .sb43a49_confirmButton:focus-visible, .s6e45d1_cancelButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The shelf card of a plugin that is installed and current carries this\n * non-interactive label instead of an install button. Border + text do the\n * work in the light theme, where every bg-layer token resolves to white. */\n.sb6fc74_installedLabel {\n align-self: flex-start;\n margin: 0;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n font-size: 13px;\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n/* An installed card's controls: the installed label or the update button,\n * plus the uninstall button. The install panel's running/failed states are\n * column layouts and sit as one item of this row. */\n.sf53ca0_installedActions {\n display: flex;\n align-items: flex-start;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n/* Uninstall revokes privilege; the quiet outline keeps it from competing\n * with the primary action, and the error tint says \"removes\". */\n.s96967f_uninstallButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 55%, transparent);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-state-error-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s96967f_uninstallButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);\n}\n\n.s96967f_uninstallButton:focus-visible {\n outline: 2px solid var(--dsw-alias-state-error-primary);\n outline-offset: 1px;\n}\n\n/* The restart dsh button on a done install: quiet outline, same rank as\n * the other secondary actions. */\n.s6ac237_restartButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s6ac237_restartButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n}\n\n.s6ac237_restartButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.sc4f2ac_gate {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n border: 1px solid var(--dsw-alias-state-warn-primary);\n border-radius: 8px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n.s559c38_gateTitle {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.s3c0ace_gateBody {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n.s4b2373_gateActions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.s52b5a5_installing {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s64ab71_log {\n max-height: 160px;\n overflow: auto;\n margin: 0;\n padding: 8px;\n border-radius: 6px;\n background: var(--dsw-alias-bg-base);\n border: 1px solid var(--dsw-alias-border-l1);\n list-style: none;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n line-height: 1.5;\n}\n\n.s1531a8_logLine {\n white-space: pre-wrap;\n word-break: break-all;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sf20dda_notice {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-state-success-primary);\n}\n\n.seb9b08_failedHeading {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.sfd3021_failedDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n.s50ba35_rejectedCode {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.se75489_rejectedDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n/* Installed section. */\n.sa276cf_outdatedSection {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 6px;\n}\n\n.sceae6e_outdatedList {\n display: flex;\n flex-direction: column;\n gap: 8px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.s8d2072_outdatedRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n flex-wrap: wrap;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-1);\n}\n\n.s5c2545_outdatedInfo {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.s5c2545_outdatedInfo strong {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n word-break: break-all;\n color: var(--dsw-alias-label-primary);\n}\n\n.s877c68_outdatedVersions {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa1f556_outdatedActions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n/* The enable/disable switch. */\n.s11c019_switch {\n position: relative;\n width: 32px;\n height: 18px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n.s7580e8_switchOn {\n border-color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 55%, transparent);\n}\n\n.saab2b3_switchKnob {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 12px;\n height: 12px;\n border-radius: 999px;\n background: var(--dsw-alias-label-primary);\n transition: transform 120ms ease, background 120ms ease;\n}\n\n.s7580e8_switchOn .saab2b3_switchKnob {\n transform: translateX(14px);\n background: var(--dsw-alias-bg-base);\n}\n\n.s11c019_switch:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s11c019_switch, .saab2b3_switchKnob { transition: none; }\n}\n";
|
|
5089
|
+
const css = "/* Shop tab styles — a market shelf inside the settings surface. The visual\n * language is the dsh theme's alias tokens ONLY (the four tokens the previous\n * styles referenced that do not exist — bg-layer-3, interactive-bg-hover,\n * state-error, state-success — are corrected to bg-layer-2 and the\n * state-*-primary set). The signature is the category spine: one HUE per\n * category (six fixed hues, not the brand token — the brand resolves to\n * near-black in the light theme, so six brand opacities read as six shades\n * of gray), with the category name as the cover label in the same hue. Class names are mapped to content-derived names at bundle time\n * (tsdown.s8583e3_client.s942a79_config.s5f67aa_ts) and stubbed in tests; only the keys are relied\n * on.\n *\n * One token rule the theme forces: the background LAYERS do not carry\n * contrast. In the light theme bg-base, bg-layer-1, bg-layer-2 and\n * bg-layer-3 all resolve to the same white; only the dark theme spreads them\n * (950/875/850/800). So a layer-2 fill on a layer-1 ground is invisible for\n * half of all users, and anything whose fill is its ONLY affordance — the\n * loading skeleton, the borderless capability chips — derives its fill from\n * label-primary instead, which inverts with the theme by construction.\n * Elements that also carry a border or text may keep a layer fill.\n * `css-tokens.s8583e3_client.sfd9d8a_spec.s5f67aa_ts` pins this. */\n\n.s255e5a_panel {\n display: flex;\n flex-direction: column;\n gap: 14px;\n /* The shelf never scrolls sideways: a card too wide for its track wraps\n * its badges rather than widening the panel. */\n overflow-x: hidden;\n}\n\n.s44a3ec_stateLine {\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* Visually hidden but screen-reader readable (the loading copy while the\n * skeleton stands in visually). */\n.s3a0ece_srOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n overflow: hidden;\n white-space: nowrap;\n}\n\n/* The loading shelf: ghost cards with the same geometry as the real grid, so\n * the swap to content is a same-shape handoff instead of a jump. */\n.se0c3b4_skeletonGrid {\n display: grid;\n grid-template-columns: 1fr;\n gap: 8px;\n}\n\n.s520416_skeletonCard {\n position: relative;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n}\n\n/* The shimmer sweep: one gradient band travels across each ghost card while\n * the bars breathe, so the loading state reads as \"the shelf is scanning\". */\n.s520416_skeletonCard::after {\n content: '';\n position: absolute;\n inset: 0;\n background: linear-gradient(\n 100deg,\n transparent 25%,\n color-mix(in srgb, var(--dsw-alias-label-primary) 14%, transparent) 50%,\n transparent 75%\n );\n transform: translateX(-100%);\n animation: dshShopSkeletonSweep 1.4s ease-in-out infinite;\n pointer-events: none;\n}\n\n@keyframes dshShopSkeletonSweep {\n to { transform: translateX(100%); }\n}\n\n.s8c7d6f_skeletonName {\n width: 55%;\n height: 14px;\n margin: 10px 12px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.sf5179e_skeletonSummary {\n width: 92%;\n height: 12px;\n margin: 10px 12px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.sbb0d25_skeletonSummaryShort {\n width: 68%;\n height: 12px;\n margin: 6px 12px 10px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n/* The ghost of the action line, right where the real buttons land. */\n.s96e910_skeletonActions {\n display: block;\n width: 84px;\n height: 24px;\n margin: 0 12px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);\n}\n\n.s520416_skeletonCard span {\n animation: dshShopSkeletonPulse 1.6s ease-in-out infinite;\n}\n\n@keyframes dshShopSkeletonPulse {\n 0%, 100% { opacity: 0.5; }\n 50% { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s520416_skeletonCard span { animation: none; opacity: 0.75; }\n .s520416_skeletonCard::after { content: none; }\n}\n\n.s73242a_actionButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s73242a_actionButton:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.s73242a_actionButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s646509_toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.s745e3c_toolbarRight {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* The shop's own version, right of the search box: `v0.4.4`, plus the\n * update button when the version check found a newer release. */\n.s4fe61f_versionBlock {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sb9b924_versionText {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa04455_updateSelfButton {\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-brand-primary);\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n color: var(--dsw-alias-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n\n.sa04455_updateSelfButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 20%, transparent);\n}\n\n.sa04455_updateSelfButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The on-demand re-check next to the version number: a quiet pill; the\n * border and text carry it in the light theme where bg layers are white. */\n.s614a38_checkUpdateButton {\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.s614a38_checkUpdateButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n color: var(--dsw-alias-label-primary);\n}\n\n.s614a38_checkUpdateButton:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n.s614a38_checkUpdateButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The project's GitHub mark, right of the version row: a quiet icon link.\n * The octocat carries itself — color shift on hover, no text, no border. */\n.sa987f7_githubLink {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 3px;\n border-radius: 6px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa987f7_githubLink:hover {\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.sa987f7_githubLink:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The self-update's expanded states (running log / done + restart /\n * failure detail) sit under the toolbar, above the category bar. */\n.sb81ba5_selfUpdatePanel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 8px;\n}\n\n.s232ec4_searchInput {\n width: min(280px, 100%);\n padding: 6px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n.s232ec4_searchInput:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s1555aa_staleBlock {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.s3946f1_staleBadge {\n padding: 2px 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n color: var(--dsw-alias-state-warn-primary);\n font-size: 12px;\n}\n\n.sb2c859_categoryBar {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 6px;\n}\n\n.s26d58e_categoryButton {\n padding: 3px 10px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-secondary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.s26d58e_categoryButton:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l2));\n color: var(--dsw-alias-brand-primary);\n}\n\n.s5f68c4_categoryButtonOn {\n border-color: var(--dsw-alias-brand-primary);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n color: var(--dsw-alias-brand-primary);\n font-weight: 600;\n}\n\n.s26d58e_categoryButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.s668774_catalogHeading {\n margin: 2px 0 0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-primary);\n}\n\n.sccc4d1_catalogStats {\n margin: 6px 0 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s6de1ab_emptyLine {\n margin: 0;\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n}\n\n/* The shelf: a responsive grid of cards. */\n/* Single-line rows: one full-width column, one plugin per line. */\n.sf657f5_cards {\n display: grid;\n grid-template-columns: 1fr;\n max-width: 100%;\n gap: 8px;\n list-style: none;\n margin: 0;\n padding: 0;\n animation: dshShopCardsIn 220ms ease;\n}\n\n@keyframes dshShopCardsIn {\n from { opacity: 0; transform: translateY(3px); }\n to { opacity: 1; transform: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sf657f5_cards { animation: none; }\n}\n\n.s65f383_card {\n position: relative;\n display: flex;\n flex-direction: column;\n /* A grid item's min-width is auto by default: its content would widen the\n * 1fr track past the panel and overflow horizontally. */\n min-width: 0;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1);\n overflow: hidden;\n transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;\n /* Off-screen cards skip layout and paint; the placeholder keeps scrollbar\n * estimation sane before the browser has measured the real height. */\n content-visibility: auto;\n contain-intrinsic-size: auto 140px;\n}\n\n/* The sentinel that triggers the next shelf batch: zero visual footprint. */\n.sd7ee01_cardsSentry {\n height: 1px;\n margin: 0;\n padding: 0;\n}\n\n.s705cc6_showingLine {\n margin: 0;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s65f383_card:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary) 45%, var(--dsw-alias-border-l1));\n transform: translateY(-1px);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--dsw-alias-brand-primary) 12%, transparent);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s65f383_card { transition: none; }\n .s65f383_card:hover { transform: none; }\n}\n\n/* The signature: a spine and cover in the category's own hue. The hues are\n * fixed mid-bright colors that read on both themes; `other` deliberately\n * stays a neutral gray so the fallback category does not compete. */\n.s4ce25d_cardSpine {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 3px;\n background: var(--spine-hue, #8B8E96);\n}\n\n.s65f383_card[data-category='tool'] { --spine-hue: #4C8DFF; }\n.s65f383_card[data-category='provider'] { --spine-hue: #A78BFA; }\n.s65f383_card[data-category='ui'] { --spine-hue: #2DD4BF; }\n.s65f383_card[data-category='workflow'] { --spine-hue: #F59E0B; }\n.s65f383_card[data-category='integration'] { --spine-hue: #34D399; }\n.s65f383_card[data-category='other'] { --spine-hue: #8B8E96; }\n\n/* The category sits in the badge row as a quiet chip in the category's own\n * hue — the border carries it where the light theme's white layers cannot\n * (the same lesson as the check button). */\n.s9c8eaa_categoryBadge {\n padding: 1px 7px;\n border: 1px solid color-mix(in srgb, var(--spine-hue, #8B8E96) 45%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--spine-hue, #8B8E96);\n white-space: nowrap;\n}\n\n.sa97234_entryHeader {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n min-width: 0;\n padding: 8px 12px 2px;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.sa97234_entryHeader:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n\n/* The name fills the row and truncates rather than wraps; the badges stay\n * intact beside it. */\n.sc3f149_name {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n font-weight: 600;\n flex: 1 1 auto;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--dsw-alias-label-primary);\n}\n\n.s513026_badges {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n/* The action line: buttons side by side; an active install/uninstall flow\n * (gate, log, notices) takes the full width below them. */\n.s9b5048_cardActions {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 10px;\n}\n\n.s9b5048_cardActions > .sc4f2ac_gate,\n.s9b5048_cardActions > .s4d374c_installPanel,\n.s9b5048_cardActions > .sf53ca0_installedActions {\n flex-basis: 100%;\n}\n\n/* The entry's version, always visible on the card (the expanded detail\n * repeats it in the version row) — the same quiet mono as the toolbar. */\n.sc6ec6e_cardVersion {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n letter-spacing: 0.02em;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* The octocat marking a github-sourced entry, beside its short commit. */\n.s71f10f_sourceBadge {\n display: inline-flex;\n align-items: center;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s5e82cb_tierBadge {\n padding: 1px 7px;\n border-radius: 999px;\n font-size: 11px;\n line-height: 1.6;\n}\n\n.s5e82cb_tierBadge[data-tier='verified'] {\n color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-success-primary) 40%, transparent);\n}\n\n.s5e82cb_tierBadge[data-tier='verified-stale'] {\n color: var(--dsw-alias-state-warn-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 14%, transparent);\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary) 40%, transparent);\n}\n\n.s5e82cb_tierBadge[data-tier='community'] {\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-2);\n border: 1px solid var(--dsw-alias-border-l2);\n}\n\n.sff43b4_starsBadge {\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s73f7fb_chevron, .s61393c_chevronOpen {\n color: var(--dsw-alias-label-secondary);\n transition: transform 120ms ease;\n}\n\n.s61393c_chevronOpen { transform: rotate(180deg); }\n\n@media (prefers-reduced-motion: reduce) {\n .s73f7fb_chevron, .s61393c_chevronOpen { transition: none; }\n}\n\n.s820ebf_body {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 12px;\n}\n\n.sb8fbc8_summary {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.se507db_summaryZh {\n margin: -4px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Expanded cards show the full summary: the clamp is lifted, never raised —\n * a higher number would still truncate the author's text, just later. */\n.s10baf0_summaryExpanded {\n -webkit-line-clamp: unset;\n display: block;\n}\n\n.sb9dba9_summaryZhExpanded {\n -webkit-line-clamp: unset;\n display: block;\n}\n\n.s9d2029_capabilitiesBlock {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.s3bdbd5_capabilitiesNote {\n margin: 0;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s441702_capabilities {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.s441702_capabilities li {\n padding: 1px 6px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sde3f0c_detail {\n border-top: 1px solid var(--dsw-alias-border-l1);\n padding-top: 8px;\n}\n\n.se98179_detailRows {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin: 0;\n}\n\n.sfb4d2f_detailRow {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n font-size: 12px;\n}\n\n.sfb4d2f_detailRow dt {\n color: var(--dsw-alias-label-secondary);\n}\n\n.sfb4d2f_detailRow dd {\n margin: 0;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n overflow-wrap: anywhere;\n text-align: right;\n color: var(--dsw-alias-label-primary);\n}\n\n.sfb4d2f_detailRow a {\n color: var(--dsw-alias-brand-primary);\n text-decoration: none;\n}\n\n.sfb4d2f_detailRow a:hover {\n text-decoration: underline;\n}\n\n.sfb4d2f_detailRow a:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.sd58c6d_reviewedLine {\n margin: 8px 0 0;\n padding: 6px 8px;\n border-radius: 6px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 12%, transparent);\n font-size: 12px;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n/* Install flow. */\n.s4d374c_installPanel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 2px;\n}\n\n.se7aaed_installButton, .sb43a49_confirmButton, .s6e45d1_cancelButton {\n align-self: flex-start;\n padding: 5px 14px;\n border-radius: 6px;\n font-size: 13px;\n cursor: pointer;\n}\n\n.se7aaed_installButton {\n border: 1px solid var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.se7aaed_installButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 88%, var(--dsw-alias-label-primary));\n}\n\n.sb43a49_confirmButton {\n border: 1px solid var(--dsw-alias-brand-primary);\n background: var(--dsw-alias-brand-primary);\n color: var(--dsw-alias-bg-base);\n}\n\n.sb43a49_confirmButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary) 88%, var(--dsw-alias-label-primary));\n}\n\n.s6e45d1_cancelButton {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n}\n\n.s6e45d1_cancelButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n}\n\n.se7aaed_installButton:focus-visible, .sb43a49_confirmButton:focus-visible, .s6e45d1_cancelButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* The shelf card of a plugin that is installed and current carries this\n * non-interactive label instead of an install button. Border + text do the\n * work in the light theme, where every bg-layer token resolves to white. */\n.sb6fc74_installedLabel {\n align-self: flex-start;\n margin: 0;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n font-size: 13px;\n color: var(--dsw-alias-label-secondary);\n background: var(--dsw-alias-bg-layer-2);\n}\n\n/* An installed card's controls: the installed label or the update button,\n * plus the uninstall button. The install panel's running/failed states are\n * column layouts and sit as one item of this row. */\n.sf53ca0_installedActions {\n display: flex;\n align-items: flex-start;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n/* Uninstall revokes privilege; the quiet outline keeps it from competing\n * with the primary action, and the error tint says \"removes\". */\n.s96967f_uninstallButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 55%, transparent);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-state-error-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s96967f_uninstallButton:hover {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);\n}\n\n.s96967f_uninstallButton:focus-visible {\n outline: 2px solid var(--dsw-alias-state-error-primary);\n outline-offset: 1px;\n}\n\n/* The restart dsh button on a done install: quiet outline, same rank as\n * the other secondary actions. */\n.s6ac237_restartButton {\n align-self: flex-start;\n padding: 5px 14px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 6px;\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n cursor: pointer;\n}\n\n.s6ac237_restartButton:hover {\n border-color: var(--dsw-alias-label-secondary);\n}\n\n.s6ac237_restartButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n.sc4f2ac_gate {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px;\n border: 1px solid var(--dsw-alias-state-warn-primary);\n border-radius: 8px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary) 8%, transparent);\n}\n\n.s559c38_gateTitle {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-state-warn-primary);\n}\n\n.s3c0ace_gateBody {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n.s4b2373_gateActions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.s52b5a5_installing {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.s64ab71_log {\n max-height: 160px;\n overflow: auto;\n margin: 0;\n padding: 8px;\n border-radius: 6px;\n background: var(--dsw-alias-bg-base);\n border: 1px solid var(--dsw-alias-border-l1);\n list-style: none;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n line-height: 1.5;\n}\n\n.s1531a8_logLine {\n white-space: pre-wrap;\n word-break: break-all;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sf20dda_notice {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-state-success-primary);\n}\n\n.seb9b08_failedHeading {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.sfd3021_failedDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n.s50ba35_rejectedCode {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--dsw-alias-state-error-primary);\n}\n\n.se75489_rejectedDetail {\n margin: 0;\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary);\n}\n\n/* Installed section. */\n.sa276cf_outdatedSection {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 6px;\n}\n\n.sceae6e_outdatedList {\n display: flex;\n flex-direction: column;\n gap: 8px;\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.s8d2072_outdatedRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n flex-wrap: wrap;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-1);\n}\n\n.s5c2545_outdatedInfo {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.s5c2545_outdatedInfo strong {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 13px;\n word-break: break-all;\n color: var(--dsw-alias-label-primary);\n}\n\n.s877c68_outdatedVersions {\n font-size: 12px;\n color: var(--dsw-alias-label-secondary);\n}\n\n.sa1f556_outdatedActions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n/* The enable/disable switch. */\n.s11c019_switch {\n position: relative;\n width: 32px;\n height: 18px;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n\n.s7580e8_switchOn {\n border-color: var(--dsw-alias-state-success-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 55%, transparent);\n}\n\n.saab2b3_switchKnob {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 12px;\n height: 12px;\n border-radius: 999px;\n background: var(--dsw-alias-label-primary);\n transition: transform 120ms ease, background 120ms ease;\n}\n\n.s7580e8_switchOn .saab2b3_switchKnob {\n transform: translateX(14px);\n background: var(--dsw-alias-bg-base);\n}\n\n.s11c019_switch:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .s11c019_switch, .saab2b3_switchKnob { transition: none; }\n}\n\n/* The hot enable/disable switch on installed rows: the knob button plus the\n * §8 hot-apply / failure notices rendered beside it. */\n.sd9f9e4_switchWrap {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n";
|
|
5088
5090
|
if (typeof document !== "undefined" && !document.querySelector("style[data-plugin-css=\"e3675a89\"]")) {
|
|
5089
5091
|
const tag = document.createElement("style");
|
|
5090
5092
|
tag.dataset.pluginCss = "e3675a89";
|
|
@@ -5179,7 +5181,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5179
5181
|
"outdatedActions": "sa1f556_outdatedActions",
|
|
5180
5182
|
"switch": "s11c019_switch",
|
|
5181
5183
|
"switchOn": "s7580e8_switchOn",
|
|
5182
|
-
"switchKnob": "saab2b3_switchKnob"
|
|
5184
|
+
"switchKnob": "saab2b3_switchKnob",
|
|
5185
|
+
"switchWrap": "sd9f9e4_switchWrap"
|
|
5183
5186
|
};
|
|
5184
5187
|
//#endregion
|
|
5185
5188
|
//#region src/client/ShopTab.tsx
|
|
@@ -5209,7 +5212,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5209
5212
|
* install controls. An installed plugin's card carries its installed row:
|
|
5210
5213
|
* current → the non-interactive installed label, behind → the update button;
|
|
5211
5214
|
* uninstalled → the install button. */
|
|
5212
|
-
const EntryCard = (0, react.memo)(function EntryCard({ entry, stars, installed, t, install, installStatus, uninstall, restart }) {
|
|
5215
|
+
const EntryCard = (0, react.memo)(function EntryCard({ entry, stars, installed, t, install, installStatus, uninstall, restart, setEnabled }) {
|
|
5213
5216
|
const [open, setOpen] = (0, react.useState)(false);
|
|
5214
5217
|
const detailId = (0, react.useId)();
|
|
5215
5218
|
const summary = entry.catalog?.summary;
|
|
@@ -5330,26 +5333,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5330
5333
|
install,
|
|
5331
5334
|
installStatus,
|
|
5332
5335
|
restart
|
|
5333
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5336
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
5337
|
+
installed.outdated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstallPanel, {
|
|
5338
|
+
name: entry.name,
|
|
5339
|
+
version: entry.version,
|
|
5340
|
+
tier: entry.tier,
|
|
5341
|
+
variant: "update",
|
|
5342
|
+
t,
|
|
5343
|
+
install,
|
|
5344
|
+
installStatus,
|
|
5345
|
+
restart
|
|
5346
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5347
|
+
className: _dsh_plugin_shop_css_e3675a89_default.installedLabel,
|
|
5348
|
+
"data-shop-installed": true,
|
|
5349
|
+
children: t("installed")
|
|
5350
|
+
}),
|
|
5351
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EnabledSwitch, {
|
|
5352
|
+
row: installed,
|
|
5353
|
+
t,
|
|
5354
|
+
setEnabled
|
|
5355
|
+
}),
|
|
5356
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(UninstallPanel, {
|
|
5357
|
+
name: entry.name,
|
|
5358
|
+
t,
|
|
5359
|
+
uninstall,
|
|
5360
|
+
installStatus,
|
|
5361
|
+
restart
|
|
5362
|
+
})
|
|
5363
|
+
] })
|
|
5353
5364
|
})
|
|
5354
5365
|
]
|
|
5355
5366
|
});
|
|
@@ -5624,14 +5635,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5624
5635
|
children: t("restart")
|
|
5625
5636
|
});
|
|
5626
5637
|
}
|
|
5627
|
-
/**
|
|
5628
|
-
*
|
|
5629
|
-
*
|
|
5630
|
-
*
|
|
5631
|
-
*
|
|
5632
|
-
*
|
|
5633
|
-
|
|
5634
|
-
|
|
5638
|
+
/**
|
|
5639
|
+
* The hot enable/disable switch (§8). The initial state is the Host's
|
|
5640
|
+
* inventory verdict carried on the installed row; the click is optimistic
|
|
5641
|
+
* (the value flips on success) and a success renders the §8 hot note. A
|
|
5642
|
+
* transport throw renders the localized failure line — its private detail
|
|
5643
|
+
* (which can name hosts and ports) never reaches the UI.
|
|
5644
|
+
*/
|
|
5645
|
+
function EnabledSwitch({ row, t, setEnabled }) {
|
|
5646
|
+
const [enabled, setEnabledState] = (0, react.useState)(row.enabled);
|
|
5635
5647
|
const [toggle, setToggle] = (0, react.useState)({ kind: "idle" });
|
|
5636
5648
|
const onToggle = async () => {
|
|
5637
5649
|
if (toggle.kind === "saving") return;
|
|
@@ -5657,47 +5669,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5657
5669
|
}
|
|
5658
5670
|
};
|
|
5659
5671
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5660
|
-
className: _dsh_plugin_shop_css_e3675a89_default.
|
|
5661
|
-
"data-shop-
|
|
5672
|
+
className: _dsh_plugin_shop_css_e3675a89_default.switchWrap,
|
|
5673
|
+
"data-shop-enabled-switch": row.name,
|
|
5662
5674
|
children: [
|
|
5663
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5674
|
-
className: _dsh_plugin_shop_css_e3675a89_default.outdatedVersion,
|
|
5675
|
-
children: t("latestVersion", { version: row.latest })
|
|
5676
|
-
})]
|
|
5677
|
-
})]
|
|
5678
|
-
}),
|
|
5679
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5680
|
-
className: _dsh_plugin_shop_css_e3675a89_default.outdatedActions,
|
|
5681
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5682
|
-
type: "button",
|
|
5683
|
-
role: "switch",
|
|
5684
|
-
"aria-checked": enabled,
|
|
5685
|
-
"aria-label": t("enabledSwitch"),
|
|
5686
|
-
"data-shop-toggle": true,
|
|
5687
|
-
className: `${_dsh_plugin_shop_css_e3675a89_default.switch} ${enabled ? _dsh_plugin_shop_css_e3675a89_default.switchOn : ""}`,
|
|
5688
|
-
onClick: () => void onToggle(),
|
|
5689
|
-
disabled: toggle.kind === "saving",
|
|
5690
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: _dsh_plugin_shop_css_e3675a89_default.switchKnob })
|
|
5691
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstallPanel, {
|
|
5692
|
-
name: row.name,
|
|
5693
|
-
version: row.latest,
|
|
5694
|
-
tier,
|
|
5695
|
-
variant: "update",
|
|
5696
|
-
t,
|
|
5697
|
-
install,
|
|
5698
|
-
installStatus,
|
|
5699
|
-
restart
|
|
5700
|
-
})]
|
|
5675
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5676
|
+
type: "button",
|
|
5677
|
+
role: "switch",
|
|
5678
|
+
"aria-checked": enabled,
|
|
5679
|
+
"aria-label": t("enabledSwitch"),
|
|
5680
|
+
"data-shop-toggle": true,
|
|
5681
|
+
className: `${_dsh_plugin_shop_css_e3675a89_default.switch} ${enabled ? _dsh_plugin_shop_css_e3675a89_default.switchOn : ""}`,
|
|
5682
|
+
onClick: () => void onToggle(),
|
|
5683
|
+
disabled: toggle.kind === "saving",
|
|
5684
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: _dsh_plugin_shop_css_e3675a89_default.switchKnob })
|
|
5701
5685
|
}),
|
|
5702
5686
|
toggle.kind === "saved" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5703
5687
|
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
@@ -5712,6 +5696,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5712
5696
|
]
|
|
5713
5697
|
});
|
|
5714
5698
|
}
|
|
5699
|
+
/** One outdated install row (§7.3): the name, the installed and latest
|
|
5700
|
+
* versions, the hot enable/disable switch, and the update button (the
|
|
5701
|
+
* install flow for `name@latest`, reusing `InstallPanel`). */
|
|
5702
|
+
function OutdatedRow({ row, tier, source, t, setEnabled, install, installStatus, restart }) {
|
|
5703
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5704
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedRow,
|
|
5705
|
+
"data-shop-outdated-entry": row.name,
|
|
5706
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5707
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedInfo,
|
|
5708
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5709
|
+
className: _dsh_plugin_shop_css_e3675a89_default.name,
|
|
5710
|
+
children: row.name
|
|
5711
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
5712
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedVersions,
|
|
5713
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5714
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedVersion,
|
|
5715
|
+
children: t("installedVersion", { version: source === "github" ? row.installed.slice(0, 7) : row.installed })
|
|
5716
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5717
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedVersion,
|
|
5718
|
+
children: t("latestVersion", { version: row.latest })
|
|
5719
|
+
})]
|
|
5720
|
+
})]
|
|
5721
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5722
|
+
className: _dsh_plugin_shop_css_e3675a89_default.outdatedActions,
|
|
5723
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EnabledSwitch, {
|
|
5724
|
+
row,
|
|
5725
|
+
t,
|
|
5726
|
+
setEnabled
|
|
5727
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstallPanel, {
|
|
5728
|
+
name: row.name,
|
|
5729
|
+
version: row.latest,
|
|
5730
|
+
tier,
|
|
5731
|
+
variant: "update",
|
|
5732
|
+
t,
|
|
5733
|
+
install,
|
|
5734
|
+
installStatus,
|
|
5735
|
+
restart
|
|
5736
|
+
})]
|
|
5737
|
+
})]
|
|
5738
|
+
});
|
|
5739
|
+
}
|
|
5715
5740
|
/** The §7.3 installed list, rendered as the "installed" section: each row
|
|
5716
5741
|
* shows both versions, a switch, and an update button. The rows are the
|
|
5717
5742
|
* installed entries filtered to `outdated` — a current install is already
|
|
@@ -6133,7 +6158,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6133
6158
|
install,
|
|
6134
6159
|
installStatus,
|
|
6135
6160
|
uninstall,
|
|
6136
|
-
restart
|
|
6161
|
+
restart,
|
|
6162
|
+
setEnabled
|
|
6137
6163
|
}) }, entry.name)), incremental && visibleCount < filtered.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
6138
6164
|
ref: sentinelRef,
|
|
6139
6165
|
className: _dsh_plugin_shop_css_e3675a89_default.cardsSentry,
|
package/lib/index.js
CHANGED
|
@@ -59,7 +59,8 @@ const entrySchema = z.object({
|
|
|
59
59
|
capabilities: z.array(z.string())
|
|
60
60
|
}).optional(),
|
|
61
61
|
source: z.enum(["npm", "github"]).default("npm"),
|
|
62
|
-
repo: z.string().optional()
|
|
62
|
+
repo: z.string().optional(),
|
|
63
|
+
subdir: z.string().regex(/^(?!.*(^|\/)\.\.?(\/|$))[A-Za-z0-9._-]+(\/[A-Za-z0-9._-]+)*$/).optional()
|
|
63
64
|
});
|
|
64
65
|
const dataSchema = z.object({
|
|
65
66
|
schemaVersion: z.number(),
|
|
@@ -143,13 +144,13 @@ async function loadCatalog(options) {
|
|
|
143
144
|
const readCached = () => {
|
|
144
145
|
try {
|
|
145
146
|
const pointer = pointerSchema.parse(JSON.parse(fsImpl.read(indexPath)));
|
|
146
|
-
if (pointer.schemaVersion >
|
|
147
|
+
if (pointer.schemaVersion > 4) throw new Error(`catalog schemaVersion ${pointer.schemaVersion} is newer than this build supports (4)`);
|
|
147
148
|
const dataPath = join(cacheDir, basename(pointer.plugins.url));
|
|
148
149
|
const dataText = fsImpl.read(dataPath);
|
|
149
150
|
const actual = createHash("sha256").update(dataText).digest("hex");
|
|
150
151
|
if (actual !== pointer.plugins.sha256) throw new Error(`cached catalog data failed integrity check: expected ${pointer.plugins.sha256}, got ${actual}`);
|
|
151
152
|
const data = dataSchema.parse(JSON.parse(dataText));
|
|
152
|
-
if (data.schemaVersion >
|
|
153
|
+
if (data.schemaVersion > 4) throw new Error(`catalog schemaVersion ${data.schemaVersion} is newer than this build supports (4)`);
|
|
153
154
|
let stars = {};
|
|
154
155
|
if (pointer.stars !== void 0) try {
|
|
155
156
|
const starsText = fsImpl.read(join(cacheDir, basename(pointer.stars.url)));
|
|
@@ -190,7 +191,7 @@ async function loadCatalog(options) {
|
|
|
190
191
|
throw error;
|
|
191
192
|
}
|
|
192
193
|
const pointer = pointerSchema.parse(JSON.parse(pointerText));
|
|
193
|
-
if (pointer.schemaVersion >
|
|
194
|
+
if (pointer.schemaVersion > 4) throw new Error(`catalog schemaVersion ${pointer.schemaVersion} is newer than this build supports (4)`);
|
|
194
195
|
const dataUrl = resolveDataUrl(baseUrl, pointer.plugins.url);
|
|
195
196
|
let dataText;
|
|
196
197
|
try {
|
|
@@ -208,7 +209,7 @@ async function loadCatalog(options) {
|
|
|
208
209
|
const actual = createHash("sha256").update(dataText).digest("hex");
|
|
209
210
|
if (actual !== pointer.plugins.sha256) throw new Error(`catalog data failed integrity check: expected ${pointer.plugins.sha256}, got ${actual}`);
|
|
210
211
|
const data = dataSchema.parse(JSON.parse(dataText));
|
|
211
|
-
if (data.schemaVersion >
|
|
212
|
+
if (data.schemaVersion > 4) throw new Error(`catalog schemaVersion ${data.schemaVersion} is newer than this build supports (4)`);
|
|
212
213
|
let stars = {};
|
|
213
214
|
if (pointer.stars !== void 0) try {
|
|
214
215
|
const starsResponse = await fetchImpl(resolveDataUrl(baseUrl, pointer.stars.url));
|
|
@@ -851,8 +852,14 @@ let ShopGateway = (() => {
|
|
|
851
852
|
}
|
|
852
853
|
/** Enable or disable one installed plugin, hot (§8): a disable writes the
|
|
853
854
|
* row to the user layer, an enable drops it again so the bundle default
|
|
854
|
-
* rules — the CLI's watchUserPatches applies either through HMR.
|
|
855
|
+
* rules — the CLI's watchUserPatches applies either through HMR. The shop's
|
|
856
|
+
* own row and the framework's bundles are never toggleable: disabling the
|
|
857
|
+
* host chain would break HMR itself. */
|
|
855
858
|
setEnabled(args) {
|
|
859
|
+
if (args.name === "dsh-plugin-shop" || args.name.startsWith("@deepseek-ai/")) return {
|
|
860
|
+
ok: false,
|
|
861
|
+
detail: `dsh-plugin-shop: ${args.name} is part of the harness chain and cannot be toggled from the shop`
|
|
862
|
+
};
|
|
856
863
|
const entry = this.listInventory().find((entry) => entry.moduleName === args.name);
|
|
857
864
|
if (entry === void 0) return {
|
|
858
865
|
ok: false,
|
|
@@ -937,7 +944,7 @@ let ShopGateway = (() => {
|
|
|
937
944
|
code: "git-missing",
|
|
938
945
|
detail: "dsh-plugin-shop: git is not on PATH, which github installs require; install git and retry"
|
|
939
946
|
};
|
|
940
|
-
spec = `github:${entry.repo}#${args.version}`;
|
|
947
|
+
spec = `github:${entry.repo}#${args.version}${entry.subdir !== void 0 ? `&path:${entry.subdir}` : ""}`;
|
|
941
948
|
} else spec = `${args.name}@${args.version}`;
|
|
942
949
|
const running = startInstall({
|
|
943
950
|
profile: this.profile,
|
|
@@ -1001,6 +1008,10 @@ let ShopGateway = (() => {
|
|
|
1001
1008
|
}
|
|
1002
1009
|
const dependencies = readProfileManifest("dsh-plugin-shop", this.profileDirResolved()).dependencies ?? {};
|
|
1003
1010
|
const pins = readRepoPins(this.pinFs, this.pinsPath());
|
|
1011
|
+
let byName = /* @__PURE__ */ new Map();
|
|
1012
|
+
try {
|
|
1013
|
+
byName = new Map(this.listInventory().map((entry) => [entry.moduleName, entry.enabled]));
|
|
1014
|
+
} catch {}
|
|
1004
1015
|
const installed = [];
|
|
1005
1016
|
for (const entry of this.lastSnapshot.entries) {
|
|
1006
1017
|
const spec = dependencies[entry.name];
|
|
@@ -1011,13 +1022,15 @@ let ShopGateway = (() => {
|
|
|
1011
1022
|
name: entry.name,
|
|
1012
1023
|
installed: pin ?? spec,
|
|
1013
1024
|
latest: entry.version,
|
|
1014
|
-
outdated: pin !== void 0 && pin !== entry.version
|
|
1025
|
+
outdated: pin !== void 0 && pin !== entry.version,
|
|
1026
|
+
enabled: byName.get(entry.name) ?? true
|
|
1015
1027
|
});
|
|
1016
1028
|
} else installed.push({
|
|
1017
1029
|
name: entry.name,
|
|
1018
1030
|
installed: spec,
|
|
1019
1031
|
latest: entry.version,
|
|
1020
|
-
outdated: this.isBehind(spec, entry.version)
|
|
1032
|
+
outdated: this.isBehind(spec, entry.version),
|
|
1033
|
+
enabled: byName.get(entry.name) ?? true
|
|
1021
1034
|
});
|
|
1022
1035
|
}
|
|
1023
1036
|
return installed;
|
package/lib/typert.host.js
CHANGED
|
@@ -34,6 +34,7 @@ const dsh_plugin_shop_shop_catalog_result$schema = z.object({
|
|
|
34
34
|
})]).optional(),
|
|
35
35
|
'source': z.union([z.literal("npm"), z.literal("github")]),
|
|
36
36
|
'repo': z.union([z.undefined(), z.string()]).optional(),
|
|
37
|
+
'subdir': z.union([z.undefined(), z.string()]).optional(),
|
|
37
38
|
})),
|
|
38
39
|
'denied': z.array(z.object({
|
|
39
40
|
'name': z.string(),
|
|
@@ -46,6 +47,7 @@ const dsh_plugin_shop_shop_installed_result$schema = z.array(z.object({
|
|
|
46
47
|
'installed': z.string(),
|
|
47
48
|
'latest': z.string(),
|
|
48
49
|
'outdated': z.boolean(),
|
|
50
|
+
'enabled': z.boolean(),
|
|
49
51
|
}))
|
|
50
52
|
const dsh_plugin_shop_shop_installStart_parameter_0$schema = z.object({
|
|
51
53
|
'name': z.string(),
|
|
@@ -140,7 +142,7 @@ export const TYPERT = {
|
|
|
140
142
|
typeSymbol: 'dsh-plugin-shop/types#ShopCatalogResult',
|
|
141
143
|
schema: dsh_plugin_shop_shop_catalog_result$schema,
|
|
142
144
|
},
|
|
143
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
145
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":275,"column":9},
|
|
144
146
|
},
|
|
145
147
|
{
|
|
146
148
|
id: 'dsh-plugin-shop#shop/installed',
|
|
@@ -155,7 +157,7 @@ export const TYPERT = {
|
|
|
155
157
|
typeSymbol: 'dsh-plugin-shop#shop/installed:result',
|
|
156
158
|
schema: dsh_plugin_shop_shop_installed_result$schema,
|
|
157
159
|
},
|
|
158
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
160
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":380,"column":9},
|
|
159
161
|
},
|
|
160
162
|
{
|
|
161
163
|
id: 'dsh-plugin-shop#shop/installStart',
|
|
@@ -181,7 +183,7 @@ export const TYPERT = {
|
|
|
181
183
|
typeSymbol: 'dsh-plugin-shop/types#ShopInstallResult',
|
|
182
184
|
schema: dsh_plugin_shop_shop_installStart_result$schema,
|
|
183
185
|
},
|
|
184
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
186
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":301,"column":9},
|
|
185
187
|
},
|
|
186
188
|
{
|
|
187
189
|
id: 'dsh-plugin-shop#shop/installStatus',
|
|
@@ -206,7 +208,7 @@ export const TYPERT = {
|
|
|
206
208
|
typeSymbol: 'dsh-plugin-shop/types#ShopInstallStatusResult',
|
|
207
209
|
schema: dsh_plugin_shop_shop_installStatus_result$schema,
|
|
208
210
|
},
|
|
209
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
211
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":369,"column":3},
|
|
210
212
|
},
|
|
211
213
|
{
|
|
212
214
|
id: 'dsh-plugin-shop#shop/restart',
|
|
@@ -221,7 +223,7 @@ export const TYPERT = {
|
|
|
221
223
|
typeSymbol: 'dsh-plugin-shop/types#ShopRestartResult',
|
|
222
224
|
schema: dsh_plugin_shop_shop_restart_result$schema,
|
|
223
225
|
},
|
|
224
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
226
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":491,"column":9},
|
|
225
227
|
},
|
|
226
228
|
{
|
|
227
229
|
id: 'dsh-plugin-shop#shop/setEnabled',
|
|
@@ -246,7 +248,7 @@ export const TYPERT = {
|
|
|
246
248
|
typeSymbol: 'dsh-plugin-shop/types#ShopSetEnabledResult',
|
|
247
249
|
schema: dsh_plugin_shop_shop_setEnabled_result$schema,
|
|
248
250
|
},
|
|
249
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
251
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":241,"column":3},
|
|
250
252
|
},
|
|
251
253
|
{
|
|
252
254
|
id: 'dsh-plugin-shop#shop/uninstallStart',
|
|
@@ -272,7 +274,7 @@ export const TYPERT = {
|
|
|
272
274
|
typeSymbol: 'dsh-plugin-shop/types#ShopUninstallResult',
|
|
273
275
|
schema: dsh_plugin_shop_shop_uninstallStart_result$schema,
|
|
274
276
|
},
|
|
275
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
277
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":451,"column":9},
|
|
276
278
|
},
|
|
277
279
|
{
|
|
278
280
|
id: 'dsh-plugin-shop#shop/updateStart',
|
|
@@ -297,7 +299,7 @@ export const TYPERT = {
|
|
|
297
299
|
typeSymbol: 'dsh-plugin-shop/types#ShopUpdateResult',
|
|
298
300
|
schema: dsh_plugin_shop_shop_updateStart_result$schema,
|
|
299
301
|
},
|
|
300
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
302
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":540,"column":9},
|
|
301
303
|
},
|
|
302
304
|
{
|
|
303
305
|
id: 'dsh-plugin-shop#shop/version',
|
|
@@ -312,7 +314,7 @@ export const TYPERT = {
|
|
|
312
314
|
typeSymbol: 'dsh-plugin-shop/types#ShopVersionResult',
|
|
313
315
|
schema: dsh_plugin_shop_shop_version_result$schema,
|
|
314
316
|
},
|
|
315
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
317
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":525,"column":9},
|
|
316
318
|
},
|
|
317
319
|
],
|
|
318
320
|
model: {
|
|
@@ -336,7 +338,7 @@ export const TYPERT = {
|
|
|
336
338
|
"name": "setEnabled",
|
|
337
339
|
"signature": "@Remote('setEnabled') setEnabled(args: { name: string; enabled: boolean }): ShopSetEnabledResult",
|
|
338
340
|
"summary": "Enable or disable one installed plugin, hot (§8): a disable writes the row to the user layer, an enable drops it again so the bundle default rules — the CLI's watchUserPatches applies either through HMR.",
|
|
339
|
-
"jsDoc": "/** Enable or disable one installed plugin, hot (§8): a disable writes the\n * row to the user layer, an enable drops it again so the bundle default\n * rules — the CLI's watchUserPatches applies either through HMR. */"
|
|
341
|
+
"jsDoc": "/** Enable or disable one installed plugin, hot (§8): a disable writes the\n * row to the user layer, an enable drops it again so the bundle default\n * rules — the CLI's watchUserPatches applies either through HMR. The shop's\n * own row and the framework's bundles are never toggleable: disabling the\n * host chain would break HMR itself. */"
|
|
340
342
|
},
|
|
341
343
|
{
|
|
342
344
|
"kind": "method",
|
|
@@ -398,7 +400,7 @@ export const TYPERT = {
|
|
|
398
400
|
"types": [
|
|
399
401
|
{
|
|
400
402
|
"name": "CatalogEntry",
|
|
401
|
-
"declaration": "export interface CatalogEntry {\n name: string;\n version: string;\n integrity: string | null;\n publishedAt: string | null;\n repository: string | null;\n license: string | null;\n tier: 'verified' | 'verified-stale' | 'community';\n metadata: 'declared' | 'derived';\n review?: { reviewedVersion?: string; reviewedCommit?: string; reviewer: string; reviewCommit: string; notes: string; };\n catalog?: CatalogSection;\n source: 'npm' | 'github';\n repo?: string;\n}"
|
|
403
|
+
"declaration": "export interface CatalogEntry {\n name: string;\n version: string;\n integrity: string | null;\n publishedAt: string | null;\n repository: string | null;\n license: string | null;\n tier: 'verified' | 'verified-stale' | 'community';\n metadata: 'declared' | 'derived';\n review?: { reviewedVersion?: string; reviewedCommit?: string; reviewer: string; reviewCommit: string; notes: string; };\n catalog?: CatalogSection;\n source: 'npm' | 'github';\n repo?: string;\n subdir?: string;\n}"
|
|
402
404
|
},
|
|
403
405
|
{
|
|
404
406
|
"name": "CatalogSection",
|
|
@@ -438,7 +440,7 @@ export const TYPERT = {
|
|
|
438
440
|
},
|
|
439
441
|
{
|
|
440
442
|
"name": "ShopInstalledEntry",
|
|
441
|
-
"declaration": "export interface ShopInstalledEntry {\n name: string;\n installed: string;\n latest: string;\n outdated: boolean;\n}"
|
|
443
|
+
"declaration": "export interface ShopInstalledEntry {\n name: string;\n installed: string;\n latest: string;\n outdated: boolean;\n enabled: boolean;\n}"
|
|
442
444
|
},
|
|
443
445
|
{
|
|
444
446
|
"name": "ShopInstallResult",
|
|
@@ -34,6 +34,7 @@ const dsh_plugin_shop_shop_catalog_result$schema = z.object({
|
|
|
34
34
|
})]).optional(),
|
|
35
35
|
'source': z.union([z.literal("npm"), z.literal("github")]),
|
|
36
36
|
'repo': z.union([z.undefined(), z.string()]).optional(),
|
|
37
|
+
'subdir': z.union([z.undefined(), z.string()]).optional(),
|
|
37
38
|
})),
|
|
38
39
|
'denied': z.array(z.object({
|
|
39
40
|
'name': z.string(),
|
|
@@ -46,6 +47,7 @@ const dsh_plugin_shop_shop_installed_result$schema = z.array(z.object({
|
|
|
46
47
|
'installed': z.string(),
|
|
47
48
|
'latest': z.string(),
|
|
48
49
|
'outdated': z.boolean(),
|
|
50
|
+
'enabled': z.boolean(),
|
|
49
51
|
}))
|
|
50
52
|
const dsh_plugin_shop_shop_installStart_parameter_0$schema = z.object({
|
|
51
53
|
'name': z.string(),
|
|
@@ -137,7 +139,7 @@ export const TYPERT_REMOTE = {
|
|
|
137
139
|
typeSymbol: 'dsh-plugin-shop/types#ShopCatalogResult',
|
|
138
140
|
schema: dsh_plugin_shop_shop_catalog_result$schema,
|
|
139
141
|
},
|
|
140
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
142
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":275,"column":9},
|
|
141
143
|
},
|
|
142
144
|
{
|
|
143
145
|
id: 'dsh-plugin-shop#shop/installed',
|
|
@@ -152,7 +154,7 @@ export const TYPERT_REMOTE = {
|
|
|
152
154
|
typeSymbol: 'dsh-plugin-shop#shop/installed:result',
|
|
153
155
|
schema: dsh_plugin_shop_shop_installed_result$schema,
|
|
154
156
|
},
|
|
155
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
157
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":380,"column":9},
|
|
156
158
|
},
|
|
157
159
|
{
|
|
158
160
|
id: 'dsh-plugin-shop#shop/installStart',
|
|
@@ -178,7 +180,7 @@ export const TYPERT_REMOTE = {
|
|
|
178
180
|
typeSymbol: 'dsh-plugin-shop/types#ShopInstallResult',
|
|
179
181
|
schema: dsh_plugin_shop_shop_installStart_result$schema,
|
|
180
182
|
},
|
|
181
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
183
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":301,"column":9},
|
|
182
184
|
},
|
|
183
185
|
{
|
|
184
186
|
id: 'dsh-plugin-shop#shop/installStatus',
|
|
@@ -203,7 +205,7 @@ export const TYPERT_REMOTE = {
|
|
|
203
205
|
typeSymbol: 'dsh-plugin-shop/types#ShopInstallStatusResult',
|
|
204
206
|
schema: dsh_plugin_shop_shop_installStatus_result$schema,
|
|
205
207
|
},
|
|
206
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
208
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":369,"column":3},
|
|
207
209
|
},
|
|
208
210
|
{
|
|
209
211
|
id: 'dsh-plugin-shop#shop/restart',
|
|
@@ -218,7 +220,7 @@ export const TYPERT_REMOTE = {
|
|
|
218
220
|
typeSymbol: 'dsh-plugin-shop/types#ShopRestartResult',
|
|
219
221
|
schema: dsh_plugin_shop_shop_restart_result$schema,
|
|
220
222
|
},
|
|
221
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
223
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":491,"column":9},
|
|
222
224
|
},
|
|
223
225
|
{
|
|
224
226
|
id: 'dsh-plugin-shop#shop/setEnabled',
|
|
@@ -243,7 +245,7 @@ export const TYPERT_REMOTE = {
|
|
|
243
245
|
typeSymbol: 'dsh-plugin-shop/types#ShopSetEnabledResult',
|
|
244
246
|
schema: dsh_plugin_shop_shop_setEnabled_result$schema,
|
|
245
247
|
},
|
|
246
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
248
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":241,"column":3},
|
|
247
249
|
},
|
|
248
250
|
{
|
|
249
251
|
id: 'dsh-plugin-shop#shop/uninstallStart',
|
|
@@ -269,7 +271,7 @@ export const TYPERT_REMOTE = {
|
|
|
269
271
|
typeSymbol: 'dsh-plugin-shop/types#ShopUninstallResult',
|
|
270
272
|
schema: dsh_plugin_shop_shop_uninstallStart_result$schema,
|
|
271
273
|
},
|
|
272
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
274
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":451,"column":9},
|
|
273
275
|
},
|
|
274
276
|
{
|
|
275
277
|
id: 'dsh-plugin-shop#shop/updateStart',
|
|
@@ -294,7 +296,7 @@ export const TYPERT_REMOTE = {
|
|
|
294
296
|
typeSymbol: 'dsh-plugin-shop/types#ShopUpdateResult',
|
|
295
297
|
schema: dsh_plugin_shop_shop_updateStart_result$schema,
|
|
296
298
|
},
|
|
297
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
299
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":540,"column":9},
|
|
298
300
|
},
|
|
299
301
|
{
|
|
300
302
|
id: 'dsh-plugin-shop#shop/version',
|
|
@@ -309,7 +311,7 @@ export const TYPERT_REMOTE = {
|
|
|
309
311
|
typeSymbol: 'dsh-plugin-shop/types#ShopVersionResult',
|
|
310
312
|
schema: dsh_plugin_shop_shop_version_result$schema,
|
|
311
313
|
},
|
|
312
|
-
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":
|
|
314
|
+
sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":525,"column":9},
|
|
313
315
|
},
|
|
314
316
|
],
|
|
315
317
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/** Catalog fetch, verification, and disk cache — the Host's only network path. */
|
|
2
2
|
import type { CatalogEntry, DeniedEntry } from './types.ts';
|
|
3
3
|
/** Highest schemaVersion this build understands; a higher one is refused (§10).
|
|
4
|
-
* 3 adds `source` and repo entries (github install channel)
|
|
5
|
-
|
|
4
|
+
* 3 adds `source` and repo entries (github install channel); 4 adds `subdir`
|
|
5
|
+
* for monorepo-subpackage entries (2026-08-31 hub-borrowings A). */
|
|
6
|
+
export declare const SUPPORTED_SCHEMA_VERSION = 4;
|
|
6
7
|
export interface CatalogSnapshot {
|
|
7
8
|
schemaVersion: number;
|
|
8
9
|
builtAt: string;
|
|
@@ -114,6 +114,7 @@ export interface ShopInstalledEntry {
|
|
|
114
114
|
installed: string;
|
|
115
115
|
latest: string;
|
|
116
116
|
outdated: boolean;
|
|
117
|
+
enabled: boolean;
|
|
117
118
|
}
|
|
118
119
|
/** `shop/catalog` result (§7.3), plus the denied list for the install gate's UI. */
|
|
119
120
|
export interface ShopCatalogResult {
|
|
@@ -179,7 +180,9 @@ export declare class ShopGateway extends TypertRemoteService {
|
|
|
179
180
|
private listInventory;
|
|
180
181
|
/** Enable or disable one installed plugin, hot (§8): a disable writes the
|
|
181
182
|
* row to the user layer, an enable drops it again so the bundle default
|
|
182
|
-
* rules — the CLI's watchUserPatches applies either through HMR.
|
|
183
|
+
* rules — the CLI's watchUserPatches applies either through HMR. The shop's
|
|
184
|
+
* own row and the framework's bundles are never toggleable: disabling the
|
|
185
|
+
* host chain would break HMR itself. */
|
|
183
186
|
setEnabled(args: {
|
|
184
187
|
name: string;
|
|
185
188
|
enabled: boolean;
|
|
@@ -29,6 +29,9 @@ export interface CatalogEntry {
|
|
|
29
29
|
source: 'npm' | 'github';
|
|
30
30
|
/** `owner/slug`; present exactly when `source` is github. */
|
|
31
31
|
repo?: string;
|
|
32
|
+
/** Subpackage directory inside the repo; present exactly when the entry is
|
|
33
|
+
* a monorepo subpackage rather than the repo root. */
|
|
34
|
+
subdir?: string;
|
|
32
35
|
}
|
|
33
36
|
export interface DeniedEntry {
|
|
34
37
|
name: string;
|
package/package.json
CHANGED