dsh-plugin-shop 0.4.12 → 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 +121 -84
- package/lib/index.js +22 -9
- package/lib/typert.host.js +14 -12
- package/lib/typert.remote-client.js +11 -9
- package/lib/types/client/locales.d.ts +2 -4
- package/lib/types/client/present.d.ts +7 -4
- package/lib/types/host/catalog.d.ts +3 -2
- package/lib/types/host/index.d.ts +8 -3
- package/lib/types/host/types.d.ts +3 -0
- package/package.json +9 -8
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
|
}
|
|
@@ -4641,6 +4643,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4641
4643
|
function displayVersion(entry) {
|
|
4642
4644
|
return entry.source === "github" ? entry.version.slice(0, 7) : entry.version;
|
|
4643
4645
|
}
|
|
4646
|
+
/**
|
|
4647
|
+
* Whether the license value is the npm idiom `SEE LICENSE IN <file>` — a
|
|
4648
|
+
* valid SPDX form meaning "custom license, text ships in that file". The
|
|
4649
|
+
* catalog keeps the author's verbatim value; the shelf renders it as a
|
|
4650
|
+
* localized "Custom license" label. Everything else renders verbatim.
|
|
4651
|
+
*/
|
|
4652
|
+
function isCustomLicense(license) {
|
|
4653
|
+
return license !== null && /^SEE LICENSE IN /i.test(license);
|
|
4654
|
+
}
|
|
4644
4655
|
/** §7.2 once-per-second poll cadence, as a named constant. */
|
|
4645
4656
|
const INSTALL_POLL_MS = 1e3;
|
|
4646
4657
|
/** How long the check-update button reports "up to date" after a re-check
|
|
@@ -4819,6 +4830,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4819
4830
|
showing: "显示前 {shown} 个(共 {total})· 继续滚动加载",
|
|
4820
4831
|
repository: "仓库",
|
|
4821
4832
|
license: "许可",
|
|
4833
|
+
customLicense: "自定义许可",
|
|
4822
4834
|
reviewedVersionLine: "已审核 v{reviewed} / 当前 v{current} 未审核",
|
|
4823
4835
|
deniedCode: "已拒绝",
|
|
4824
4836
|
notInCatalogCode: "不在目录中",
|
|
@@ -4890,6 +4902,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
4890
4902
|
showing: "showing first {shown} of {total} — scroll to load more",
|
|
4891
4903
|
repository: "Repository",
|
|
4892
4904
|
license: "License",
|
|
4905
|
+
customLicense: "Custom license",
|
|
4893
4906
|
reviewedVersionLine: "reviewed v{reviewed} / current v{current} unreviewed",
|
|
4894
4907
|
deniedCode: "Denied",
|
|
4895
4908
|
notInCatalogCode: "Not in the catalog",
|
|
@@ -5073,7 +5086,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5073
5086
|
}
|
|
5074
5087
|
//#endregion
|
|
5075
5088
|
//#region \0dsh-plugin-shop-css:e3675a89
|
|
5076
|
-
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";
|
|
5077
5090
|
if (typeof document !== "undefined" && !document.querySelector("style[data-plugin-css=\"e3675a89\"]")) {
|
|
5078
5091
|
const tag = document.createElement("style");
|
|
5079
5092
|
tag.dataset.pluginCss = "e3675a89";
|
|
@@ -5168,7 +5181,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5168
5181
|
"outdatedActions": "sa1f556_outdatedActions",
|
|
5169
5182
|
"switch": "s11c019_switch",
|
|
5170
5183
|
"switchOn": "s7580e8_switchOn",
|
|
5171
|
-
"switchKnob": "saab2b3_switchKnob"
|
|
5184
|
+
"switchKnob": "saab2b3_switchKnob",
|
|
5185
|
+
"switchWrap": "sd9f9e4_switchWrap"
|
|
5172
5186
|
};
|
|
5173
5187
|
//#endregion
|
|
5174
5188
|
//#region src/client/ShopTab.tsx
|
|
@@ -5198,7 +5212,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5198
5212
|
* install controls. An installed plugin's card carries its installed row:
|
|
5199
5213
|
* current → the non-interactive installed label, behind → the update button;
|
|
5200
5214
|
* uninstalled → the install button. */
|
|
5201
|
-
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 }) {
|
|
5202
5216
|
const [open, setOpen] = (0, react.useState)(false);
|
|
5203
5217
|
const detailId = (0, react.useId)();
|
|
5204
5218
|
const summary = entry.catalog?.summary;
|
|
@@ -5297,7 +5311,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5297
5311
|
}) : entry.repository })]
|
|
5298
5312
|
}), entry.license !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5299
5313
|
className: _dsh_plugin_shop_css_e3675a89_default.detailRow,
|
|
5300
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("license") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: entry.license })]
|
|
5314
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("license") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: isCustomLicense(entry.license) ? t("customLicense") : entry.license })]
|
|
5301
5315
|
})]
|
|
5302
5316
|
}), entry.tier === "verified-stale" && entry.review !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5303
5317
|
className: _dsh_plugin_shop_css_e3675a89_default.reviewedLine,
|
|
@@ -5319,26 +5333,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5319
5333
|
install,
|
|
5320
5334
|
installStatus,
|
|
5321
5335
|
restart
|
|
5322
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
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
|
+
] })
|
|
5342
5364
|
})
|
|
5343
5365
|
]
|
|
5344
5366
|
});
|
|
@@ -5613,14 +5635,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5613
5635
|
children: t("restart")
|
|
5614
5636
|
});
|
|
5615
5637
|
}
|
|
5616
|
-
/**
|
|
5617
|
-
*
|
|
5618
|
-
*
|
|
5619
|
-
*
|
|
5620
|
-
*
|
|
5621
|
-
*
|
|
5622
|
-
|
|
5623
|
-
|
|
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);
|
|
5624
5647
|
const [toggle, setToggle] = (0, react.useState)({ kind: "idle" });
|
|
5625
5648
|
const onToggle = async () => {
|
|
5626
5649
|
if (toggle.kind === "saving") return;
|
|
@@ -5646,47 +5669,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5646
5669
|
}
|
|
5647
5670
|
};
|
|
5648
5671
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5649
|
-
className: _dsh_plugin_shop_css_e3675a89_default.
|
|
5650
|
-
"data-shop-
|
|
5672
|
+
className: _dsh_plugin_shop_css_e3675a89_default.switchWrap,
|
|
5673
|
+
"data-shop-enabled-switch": row.name,
|
|
5651
5674
|
children: [
|
|
5652
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5663
|
-
className: _dsh_plugin_shop_css_e3675a89_default.outdatedVersion,
|
|
5664
|
-
children: t("latestVersion", { version: row.latest })
|
|
5665
|
-
})]
|
|
5666
|
-
})]
|
|
5667
|
-
}),
|
|
5668
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5669
|
-
className: _dsh_plugin_shop_css_e3675a89_default.outdatedActions,
|
|
5670
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5671
|
-
type: "button",
|
|
5672
|
-
role: "switch",
|
|
5673
|
-
"aria-checked": enabled,
|
|
5674
|
-
"aria-label": t("enabledSwitch"),
|
|
5675
|
-
"data-shop-toggle": true,
|
|
5676
|
-
className: `${_dsh_plugin_shop_css_e3675a89_default.switch} ${enabled ? _dsh_plugin_shop_css_e3675a89_default.switchOn : ""}`,
|
|
5677
|
-
onClick: () => void onToggle(),
|
|
5678
|
-
disabled: toggle.kind === "saving",
|
|
5679
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: _dsh_plugin_shop_css_e3675a89_default.switchKnob })
|
|
5680
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstallPanel, {
|
|
5681
|
-
name: row.name,
|
|
5682
|
-
version: row.latest,
|
|
5683
|
-
tier,
|
|
5684
|
-
variant: "update",
|
|
5685
|
-
t,
|
|
5686
|
-
install,
|
|
5687
|
-
installStatus,
|
|
5688
|
-
restart
|
|
5689
|
-
})]
|
|
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 })
|
|
5690
5685
|
}),
|
|
5691
5686
|
toggle.kind === "saved" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
5692
5687
|
className: _dsh_plugin_shop_css_e3675a89_default.notice,
|
|
@@ -5701,6 +5696,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5701
5696
|
]
|
|
5702
5697
|
});
|
|
5703
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
|
+
}
|
|
5704
5740
|
/** The §7.3 installed list, rendered as the "installed" section: each row
|
|
5705
5741
|
* shows both versions, a switch, and an update button. The rows are the
|
|
5706
5742
|
* installed entries filtered to `outdated` — a current install is already
|
|
@@ -6122,7 +6158,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6122
6158
|
install,
|
|
6123
6159
|
installStatus,
|
|
6124
6160
|
uninstall,
|
|
6125
|
-
restart
|
|
6161
|
+
restart,
|
|
6162
|
+
setEnabled
|
|
6126
6163
|
}) }, entry.name)), incremental && visibleCount < filtered.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
6127
6164
|
ref: sentinelRef,
|
|
6128
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
|
}
|
|
@@ -21,7 +21,6 @@ export declare const zh: {
|
|
|
21
21
|
tierVerified: string;
|
|
22
22
|
tierVerifiedStale: string;
|
|
23
23
|
tierCommunity: string;
|
|
24
|
-
unclaimed: string;
|
|
25
24
|
capabilitiesNote: string;
|
|
26
25
|
install: string;
|
|
27
26
|
confirm: string;
|
|
@@ -36,9 +35,9 @@ export declare const zh: {
|
|
|
36
35
|
refresh: string;
|
|
37
36
|
staleLabel: string;
|
|
38
37
|
showing: string;
|
|
39
|
-
version: string;
|
|
40
38
|
repository: string;
|
|
41
39
|
license: string;
|
|
40
|
+
customLicense: string;
|
|
42
41
|
reviewedVersionLine: string;
|
|
43
42
|
deniedCode: string;
|
|
44
43
|
notInCatalogCode: string;
|
|
@@ -96,7 +95,6 @@ export declare const en: {
|
|
|
96
95
|
tierVerified: string;
|
|
97
96
|
tierVerifiedStale: string;
|
|
98
97
|
tierCommunity: string;
|
|
99
|
-
unclaimed: string;
|
|
100
98
|
capabilitiesNote: string;
|
|
101
99
|
install: string;
|
|
102
100
|
confirm: string;
|
|
@@ -111,9 +109,9 @@ export declare const en: {
|
|
|
111
109
|
refresh: string;
|
|
112
110
|
staleLabel: string;
|
|
113
111
|
showing: string;
|
|
114
|
-
version: string;
|
|
115
112
|
repository: string;
|
|
116
113
|
license: string;
|
|
114
|
+
customLicense: string;
|
|
117
115
|
reviewedVersionLine: string;
|
|
118
116
|
deniedCode: string;
|
|
119
117
|
notInCatalogCode: string;
|
|
@@ -5,10 +5,6 @@ import type { ShopLocaleKey } from './locales.ts';
|
|
|
5
5
|
import type { CatalogEntry, InstallRejectionCode } from '../host/index.ts';
|
|
6
6
|
/** Tier → locale key, for the entry-card tier badge (§6.2). */
|
|
7
7
|
export declare function tierKey(tier: CatalogEntry['tier']): ShopLocaleKey;
|
|
8
|
-
/** A derived listing has no author-declared catalog section; the shop
|
|
9
|
-
* presents it as unclaimed, which is the signal that prompts an author to add
|
|
10
|
-
* one (§6.1). Never present a derived entry as though the author wrote it. */
|
|
11
|
-
export declare function isUnclaimed(entry: CatalogEntry): boolean;
|
|
12
8
|
/** Spec §9.3 verbatim — the community-tier acknowledgement. The zh dictionary
|
|
13
9
|
* states the same facts in its own register; never soften this wording. */
|
|
14
10
|
export declare const ACKNOWLEDGEMENT_EN = "Once installed, this plugin holds the same privileges as a built-in one: reading and writing your files, running shell commands, and reading and modifying the requests sent to the model. It has not been reviewed.";
|
|
@@ -22,6 +18,13 @@ export declare function displayVersion(entry: {
|
|
|
22
18
|
source: 'npm' | 'github';
|
|
23
19
|
version: string;
|
|
24
20
|
}): string;
|
|
21
|
+
/**
|
|
22
|
+
* Whether the license value is the npm idiom `SEE LICENSE IN <file>` — a
|
|
23
|
+
* valid SPDX form meaning "custom license, text ships in that file". The
|
|
24
|
+
* catalog keeps the author's verbatim value; the shelf renders it as a
|
|
25
|
+
* localized "Custom license" label. Everything else renders verbatim.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isCustomLicense(license: string | null): boolean;
|
|
25
28
|
/** One polled install status (§7.3 wire data), structural. */
|
|
26
29
|
export interface InstallStatusShape {
|
|
27
30
|
found: boolean;
|
|
@@ -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;
|
|
@@ -105,13 +105,16 @@ export type ShopUpdateResult = {
|
|
|
105
105
|
};
|
|
106
106
|
/** `shop/installed` entry (§7.3): one installed catalog plugin. `installed`
|
|
107
107
|
* is the profile manifest's dependency spec verbatim (a range, a tag, or
|
|
108
|
-
* `workspace:*`)
|
|
109
|
-
*
|
|
108
|
+
* `workspace:*`) — for a github entry it is the pinned commit the shop
|
|
109
|
+
* installed, falling back to the `github:owner/slug` spec when the pin is
|
|
110
|
+
* unknown; `outdated` is the Host's verdict that the installed version sits
|
|
111
|
+
* behind the catalog's — the client never does version math. */
|
|
110
112
|
export interface ShopInstalledEntry {
|
|
111
113
|
name: string;
|
|
112
114
|
installed: string;
|
|
113
115
|
latest: string;
|
|
114
116
|
outdated: boolean;
|
|
117
|
+
enabled: boolean;
|
|
115
118
|
}
|
|
116
119
|
/** `shop/catalog` result (§7.3), plus the denied list for the install gate's UI. */
|
|
117
120
|
export interface ShopCatalogResult {
|
|
@@ -177,7 +180,9 @@ export declare class ShopGateway extends TypertRemoteService {
|
|
|
177
180
|
private listInventory;
|
|
178
181
|
/** Enable or disable one installed plugin, hot (§8): a disable writes the
|
|
179
182
|
* row to the user layer, an enable drops it again so the bundle default
|
|
180
|
-
* 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. */
|
|
181
186
|
setEnabled(args: {
|
|
182
187
|
name: string;
|
|
183
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-shop",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
4
4
|
"description": "The DeepSeek Harness plugin shop: browse, install, enable, and update dsh plugins from a git-auditable catalog.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -61,6 +61,12 @@
|
|
|
61
61
|
"platform": "web"
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"prepublishOnly": "pnpm build",
|
|
66
|
+
"build": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\" && tsdown && tsc && tsdown -c tsdown.client.config.ts",
|
|
67
|
+
"test": "tsdown && tsdown -c tsdown.client.config.ts && vitest run",
|
|
68
|
+
"typecheck": "tsdown && tsc --noEmit && tsc -p tsconfig.test.json"
|
|
69
|
+
},
|
|
64
70
|
"dependencies": {
|
|
65
71
|
"js-yaml": "^4.2.0",
|
|
66
72
|
"semver": "^7.6.3",
|
|
@@ -97,7 +103,7 @@
|
|
|
97
103
|
"@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
|
|
98
104
|
"@deepseek-ai/dsh-home-paths": "^0.1.1-rc.2",
|
|
99
105
|
"@deepseek-ai/dsh-typert-generator": "^0.1.1-rc.2",
|
|
100
|
-
"@deepseek-ai/dsh-typert-protocol": "
|
|
106
|
+
"@deepseek-ai/dsh-typert-protocol": "workspace:^0.1.1-rc.2",
|
|
101
107
|
"@testing-library/react": "^16.1.0",
|
|
102
108
|
"@types/js-yaml": "^4.0.9",
|
|
103
109
|
"@types/node": "^22.9.0",
|
|
@@ -111,10 +117,5 @@
|
|
|
111
117
|
"tsdown": "^0.22.2",
|
|
112
118
|
"typescript": "^5.6.3",
|
|
113
119
|
"vitest": "^2.1.4"
|
|
114
|
-
},
|
|
115
|
-
"scripts": {
|
|
116
|
-
"build": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\" && tsdown && tsc && tsdown -c tsdown.client.config.ts",
|
|
117
|
-
"test": "tsdown && tsdown -c tsdown.client.config.ts && vitest run",
|
|
118
|
-
"typecheck": "tsdown && tsc --noEmit && tsc -p tsconfig.test.json"
|
|
119
120
|
}
|
|
120
|
-
}
|
|
121
|
+
}
|