dsh-plugin-shop 0.7.2-beta.0 → 0.7.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -4318,6 +4318,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4318
4318
  "detail": string(),
4319
4319
  "replacement": union([_undefined(), string()]).optional()
4320
4320
  })),
4321
+ "notAShop": union([_undefined(), array(string())]).optional(),
4321
4322
  "stars": record(string(), number()),
4322
4323
  "incompatible": record(string(), array(string()))
4323
4324
  });
@@ -4436,7 +4437,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4436
4437
  },
4437
4438
  sourceLocation: {
4438
4439
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4439
- "line": 574,
4440
+ "line": 577,
4440
4441
  "column": 9
4441
4442
  }
4442
4443
  },
@@ -4454,7 +4455,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4454
4455
  },
4455
4456
  sourceLocation: {
4456
4457
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4457
- "line": 759,
4458
+ "line": 763,
4458
4459
  "column": 9
4459
4460
  }
4460
4461
  },
@@ -4482,7 +4483,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4482
4483
  },
4483
4484
  sourceLocation: {
4484
4485
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4485
- "line": 624,
4486
+ "line": 628,
4486
4487
  "column": 9
4487
4488
  }
4488
4489
  },
@@ -4509,7 +4510,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4509
4510
  },
4510
4511
  sourceLocation: {
4511
4512
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4512
- "line": 748,
4513
+ "line": 752,
4513
4514
  "column": 3
4514
4515
  }
4515
4516
  },
@@ -4527,7 +4528,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4527
4528
  },
4528
4529
  sourceLocation: {
4529
4530
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4530
- "line": 909,
4531
+ "line": 913,
4531
4532
  "column": 9
4532
4533
  }
4533
4534
  },
@@ -4554,7 +4555,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4554
4555
  },
4555
4556
  sourceLocation: {
4556
4557
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4557
- "line": 466,
4558
+ "line": 469,
4558
4559
  "column": 9
4559
4560
  }
4560
4561
  },
@@ -4582,7 +4583,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4582
4583
  },
4583
4584
  sourceLocation: {
4584
4585
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4585
- "line": 851,
4586
+ "line": 855,
4586
4587
  "column": 9
4587
4588
  }
4588
4589
  },
@@ -4609,7 +4610,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4609
4610
  },
4610
4611
  sourceLocation: {
4611
4612
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4612
- "line": 977,
4613
+ "line": 981,
4613
4614
  "column": 9
4614
4615
  }
4615
4616
  },
@@ -4627,13 +4628,87 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4627
4628
  },
4628
4629
  sourceLocation: {
4629
4630
  "file": "packages/dsh-plugin-shop/src/host/index.ts",
4630
- "line": 960,
4631
+ "line": 964,
4631
4632
  "column": 9
4632
4633
  }
4633
4634
  }
4634
4635
  ]
4635
4636
  };
4636
4637
  //#endregion
4638
+ //#region src/shared/shop-like.ts
4639
+ /**
4640
+ * Whether a package name reads as a competing plugin marketplace.
4641
+ *
4642
+ * Shared on purpose. The registry needs it to pick which newly harvested names
4643
+ * to send for a market verdict, and the client needs it to hide the ones no
4644
+ * verdict has reached yet. When each had a copy they drifted — that is exactly
4645
+ * how the shelf came to disagree with its own count — so there is one.
4646
+ *
4647
+ * It lives under the published package rather than beside the registry because
4648
+ * the dependency can only point this way: the package's tsconfig pins
4649
+ * `rootDir: "src"`, so nothing outside it can be imported, while the registry
4650
+ * scripts are internal and may reach in.
4651
+ *
4652
+ * This is a NAME heuristic and nothing more. It cannot tell a plugin that
4653
+ * stores tea from one that sells plugins — on the live catalog it caught 73
4654
+ * names of which 20 were innocent — so `registry/markets.yml` carries the
4655
+ * verdict per name and overrides it either way.
4656
+ *
4657
+ * @module shared/shop-like
4658
+ */
4659
+ const SHOP_KEYWORDS = [
4660
+ "store",
4661
+ "market",
4662
+ "mall",
4663
+ "shop",
4664
+ "marketplace"
4665
+ ];
4666
+ /**
4667
+ * Competing plugin marketplaces whose names carry no store/market keyword
4668
+ * and so escape the pattern rules below (spec §7.2). Each is a real npm
4669
+ * package that presents its own catalog of dsh plugins inside the Harness:
4670
+ * `dsh-plugin` is the npm package of github.com/dshplugin/dsh-plugin-hub,
4671
+ * `dsh-plugin-hub` and `@lanbaolu/dsh-plugin-hub` are app-store packages,
4672
+ * and `@mutocenew/dsh-plugin-catalog` ships a plugin directory with agent
4673
+ * query tools. Exact names only — nothing here is a pattern.
4674
+ */
4675
+ const SHOP_LIKE_NAMES = [
4676
+ "dsh-plugin",
4677
+ "dsh-plugin-hub",
4678
+ "@lanbaolu/dsh-plugin-hub",
4679
+ "@mutocenew/dsh-plugin-catalog"
4680
+ ];
4681
+ /**
4682
+ * Whether a package name reads as a plugin shop (a marketplace for dsh
4683
+ * plugins, e.g. `dsh-plugin-shop`, `dsh-store`, `pluginstore`). The shop
4684
+ * tab hides these so the market does not list competing markets.
4685
+ *
4686
+ * Precision over recall: a name merely CONTAINING a keyword segment without
4687
+ * a plugin qualifier or a keyword ending (`market-data-provider`,
4688
+ * `marketplace-hub`) is NOT a shop plugin, and `dsh-restore` must never
4689
+ * match on the substring "store". The keyword list keeps "store" on purpose:
4690
+ * it matches other people's package names, not ours.
4691
+ */
4692
+ function isShopLike(name) {
4693
+ if (SHOP_LIKE_NAMES.includes(name.toLowerCase())) return true;
4694
+ const segments = name.toLowerCase().split(/[-_.]+/);
4695
+ const hasPlugin = segments.includes("plugin");
4696
+ if (segments.some((segment) => /plugin(store|market|mall|shop|marketplace)/.test(segment) || /(store|market|mall|shop|marketplace)plugin/.test(segment))) return true;
4697
+ if (segments.some((segment) => segment.startsWith("dsh") && SHOP_KEYWORDS.some((keyword) => segment === `dsh${keyword}`))) return true;
4698
+ if (segments.length >= 2 && (segments[0] === "dsh" || segments[0]?.endsWith("/dsh") === true) && SHOP_KEYWORDS.includes(segments[1]) && (segments.length === 2 || segments[2] !== void 0 && [
4699
+ "plus",
4700
+ "pro",
4701
+ "hub",
4702
+ "center",
4703
+ "centre",
4704
+ "max",
4705
+ "free",
4706
+ "lite"
4707
+ ].includes(segments[2]))) return true;
4708
+ if (segments.filter((segment) => SHOP_KEYWORDS.includes(segment)).length === 0) return false;
4709
+ return hasPlugin || SHOP_KEYWORDS.includes(segments.at(-1));
4710
+ }
4711
+ //#endregion
4637
4712
  //#region src/client/present.ts
4638
4713
  /** Hot-mount reason code → locale key, so the notice reads in the language
4639
4714
  * the person set in dsh. An absent (or unrecognized) reason keeps the generic
@@ -4750,58 +4825,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4750
4825
  }
4751
4826
  }
4752
4827
  }
4753
- const SHOP_KEYWORDS = [
4754
- "store",
4755
- "market",
4756
- "mall",
4757
- "shop",
4758
- "marketplace"
4759
- ];
4760
- /**
4761
- * Competing plugin marketplaces whose names carry no store/market keyword
4762
- * and so escape the pattern rules below (spec §7.2). Each is a real npm
4763
- * package that presents its own catalog of dsh plugins inside the Harness:
4764
- * `dsh-plugin` is the npm package of github.com/dshplugin/dsh-plugin-hub,
4765
- * `dsh-plugin-hub` and `@lanbaolu/dsh-plugin-hub` are app-store packages,
4766
- * and `@mutocenew/dsh-plugin-catalog` ships a plugin directory with agent
4767
- * query tools. Exact names only — nothing here is a pattern.
4768
- */
4769
- const SHOP_LIKE_NAMES = [
4770
- "dsh-plugin",
4771
- "dsh-plugin-hub",
4772
- "@lanbaolu/dsh-plugin-hub",
4773
- "@mutocenew/dsh-plugin-catalog"
4774
- ];
4775
- /**
4776
- * Whether a package name reads as a plugin shop (a marketplace for dsh
4777
- * plugins, e.g. `dsh-plugin-shop`, `dsh-store`, `pluginstore`). The shop
4778
- * tab hides these so the market does not list competing markets.
4779
- *
4780
- * Precision over recall: a name merely CONTAINING a keyword segment without
4781
- * a plugin qualifier or a keyword ending (`market-data-provider`,
4782
- * `marketplace-hub`) is NOT a shop plugin, and `dsh-restore` must never
4783
- * match on the substring "store". The keyword list keeps "store" on purpose:
4784
- * it matches other people's package names, not ours.
4785
- */
4786
- function isShopLike(name) {
4787
- if (SHOP_LIKE_NAMES.includes(name.toLowerCase())) return true;
4788
- const segments = name.toLowerCase().split(/[-_.]+/);
4789
- const hasPlugin = segments.includes("plugin");
4790
- if (segments.some((segment) => /plugin(store|market|mall|shop|marketplace)/.test(segment) || /(store|market|mall|shop|marketplace)plugin/.test(segment))) return true;
4791
- if (segments.some((segment) => segment.startsWith("dsh") && SHOP_KEYWORDS.some((keyword) => segment === `dsh${keyword}`))) return true;
4792
- if (segments.length >= 2 && (segments[0] === "dsh" || segments[0]?.endsWith("/dsh") === true) && SHOP_KEYWORDS.includes(segments[1]) && (segments.length === 2 || segments[2] !== void 0 && [
4793
- "plus",
4794
- "pro",
4795
- "hub",
4796
- "center",
4797
- "centre",
4798
- "max",
4799
- "free",
4800
- "lite"
4801
- ].includes(segments[2]))) return true;
4802
- if (segments.filter((segment) => SHOP_KEYWORDS.includes(segment)).length === 0) return false;
4803
- return hasPlugin || SHOP_KEYWORDS.includes(segments.at(-1));
4804
- }
4805
4828
  const CATEGORY_KEYS = {
4806
4829
  tool: "categoryTool",
4807
4830
  provider: "categoryProvider",
@@ -5033,6 +5056,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5033
5056
  updateFailed: "更新失败",
5034
5057
  updateTransportFailed: "更新请求未能送达。请稍后重试。",
5035
5058
  checkUpdate: "检查更新",
5059
+ checkUpdateTitle: "检查更新",
5036
5060
  upToDate: "已是最新版本",
5037
5061
  github: "GitHub",
5038
5062
  enabledSwitch: "启用",
@@ -5122,7 +5146,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5122
5146
  restartDisabledNotice: "This dsh process runs as a systemd service, so the shop cannot restart it safely. Restart the service manually, or set allowRestart: true in the shop row config.",
5123
5147
  updateFailed: "Update failed",
5124
5148
  updateTransportFailed: "The update request could not be delivered. Please retry.",
5125
- checkUpdate: "Check for updates",
5149
+ checkUpdate: "Check",
5150
+ checkUpdateTitle: "Check for updates",
5126
5151
  upToDate: "Up to date",
5127
5152
  github: "GitHub",
5128
5153
  enabledSwitch: "Enable",
@@ -6152,11 +6177,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6152
6177
  if (installedState.kind === "ready") for (const entry of installedState.entries) map.set(entry.name, entry);
6153
6178
  return map;
6154
6179
  }, [installedState]);
6155
- const filtered = (0, react.useMemo)(() => {
6180
+ const browsable = (0, react.useMemo)(() => {
6156
6181
  if (catalogState.kind !== "ready") return [];
6182
+ const cleared = new Set(catalogState.result.notAShop ?? []);
6183
+ return catalogState.result.plugins.filter((entry) => cleared.has(entry.name) || !isShopLike(entry.name) && (entry.repo === void 0 || !isShopLike(entry.repo)));
6184
+ }, [catalogState]);
6185
+ const filtered = (0, react.useMemo)(() => {
6157
6186
  const q = query.trim().toLowerCase();
6158
- return catalogState.result.plugins.filter((entry) => {
6159
- if (isShopLike(entry.name) || entry.repo !== void 0 && isShopLike(entry.repo)) return false;
6187
+ return browsable.filter((entry) => {
6160
6188
  if (category === "installed") {
6161
6189
  if (!installedByName.has(entry.name)) return false;
6162
6190
  } else if (category !== null && categoryKey(entry) !== categoryLocaleKey(category)) return false;
@@ -6166,7 +6194,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6166
6194
  return entry.name.toLowerCase().includes(q) || summaryEn.toLowerCase().includes(q) || summaryZh.toLowerCase().includes(q);
6167
6195
  });
6168
6196
  }, [
6169
- catalogState,
6197
+ browsable,
6170
6198
  query,
6171
6199
  category,
6172
6200
  installedByName
@@ -6191,14 +6219,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6191
6219
  const visible = incremental ? sorted.slice(0, visibleCount) : sorted;
6192
6220
  const categoryCounts = (0, react.useMemo)(() => {
6193
6221
  const counts = /* @__PURE__ */ new Map();
6194
- if (catalogState.kind === "ready") for (const entry of catalogState.result.plugins) {
6195
- if (isShopLike(entry.name) || entry.repo !== void 0 && isShopLike(entry.repo)) continue;
6222
+ for (const entry of browsable) {
6196
6223
  const key = categoryKey(entry);
6197
6224
  const bare = CATEGORY_ORDER.find((c) => categoryLocaleKey(c) === key);
6198
6225
  if (bare !== void 0) counts.set(bare, (counts.get(bare) ?? 0) + 1);
6199
6226
  }
6200
6227
  return counts;
6201
- }, [catalogState]);
6228
+ }, [browsable]);
6202
6229
  const installedCount = (0, react.useMemo)(() => {
6203
6230
  if (installedState.kind !== "ready") return 0;
6204
6231
  return installedState.entries.filter((entry) => !isShopLike(entry.name)).length;
@@ -6289,6 +6316,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6289
6316
  type: "button",
6290
6317
  className: _dsh_plugin_shop_css_e3675a89_default.checkUpdateButton,
6291
6318
  "data-shop-check-update": true,
6319
+ title: t("checkUpdateTitle"),
6292
6320
  disabled: checkState !== "idle",
6293
6321
  onClick: () => void checkVersion(),
6294
6322
  children: checkState === "up-to-date" ? t("upToDate") : t("checkUpdate")
@@ -6393,10 +6421,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6393
6421
  setCategory(null);
6394
6422
  setVisibleCount(48);
6395
6423
  },
6424
+ "data-shop-category-all": true,
6396
6425
  children: [
6397
6426
  t("all"),
6398
6427
  " ",
6399
- [...categoryCounts.values()].reduce((a, b) => a + b, 0)
6428
+ browsable.length
6400
6429
  ]
6401
6430
  }),
6402
6431
  CATEGORY_ORDER.map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
@@ -6434,8 +6463,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6434
6463
  children: [
6435
6464
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6436
6465
  className: _dsh_plugin_shop_css_e3675a89_default.catalogStats,
6466
+ "data-shop-catalog-stats": true,
6437
6467
  children: t("catalogStats", {
6438
- count: String(result.plugins.length),
6468
+ count: String(browsable.length),
6439
6469
  date: result.builtAt.slice(0, 10)
6440
6470
  })
6441
6471
  }),
package/lib/index.js CHANGED
@@ -405,7 +405,13 @@ const dataSchema = z.object({
405
405
  name: z.string(),
406
406
  detail: z.string(),
407
407
  replacement: z.string().optional()
408
- })).default([])
408
+ })).default([]),
409
+ /** Names the client's shop-like NAME filter must NOT hide: entries whose
410
+ * name reads like a competing plugin market but which are not one
411
+ * (registry/not-a-shop.yml). Defaulted, so a catalog built before this key
412
+ * existed still parses — the data file is non-strict for the same reason
413
+ * the pointer is. */
414
+ notAShop: z.array(z.string()).default([])
409
415
  });
410
416
  /** The tarball URL must be the entry's own GitHub release — path segments
411
417
  * `/<owner>/<repo>/releases/...` matching the entry's `repo` (case-
@@ -515,6 +521,7 @@ async function loadCatalog(options) {
515
521
  builtAt: pointer.builtAt,
516
522
  entries: data.plugins,
517
523
  denied: data.denied,
524
+ notAShop: data.notAShop,
518
525
  stars
519
526
  };
520
527
  };
@@ -582,6 +589,7 @@ async function loadCatalog(options) {
582
589
  builtAt: pointer.builtAt,
583
590
  entries: data.plugins,
584
591
  denied: data.denied,
592
+ notAShop: data.notAShop,
585
593
  stars
586
594
  };
587
595
  fsImpl.write(indexPath, JSON.stringify(pointer));
@@ -2175,6 +2183,7 @@ let ShopGateway = (() => {
2175
2183
  stale,
2176
2184
  plugins: snapshot.entries,
2177
2185
  denied: snapshot.denied,
2186
+ notAShop: snapshot.notAShop ?? [],
2178
2187
  stars: snapshot.stars,
2179
2188
  incompatible
2180
2189
  };
@@ -49,6 +49,7 @@ const dsh_plugin_shop_shop_catalog_result$schema = z.object({
49
49
  'detail': z.string(),
50
50
  'replacement': z.union([z.undefined(), z.string()]).optional(),
51
51
  })),
52
+ 'notAShop': z.union([z.undefined(), z.array(z.string())]).optional(),
52
53
  'stars': z.record(z.string(), z.number()),
53
54
  'incompatible': z.record(z.string(), z.array(z.string())),
54
55
  })
@@ -154,7 +155,7 @@ export const TYPERT = {
154
155
  typeSymbol: 'dsh-plugin-shop/types#ShopCatalogResult',
155
156
  schema: dsh_plugin_shop_shop_catalog_result$schema,
156
157
  },
157
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":574,"column":9},
158
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":577,"column":9},
158
159
  },
159
160
  {
160
161
  id: 'dsh-plugin-shop#shop/installed',
@@ -169,7 +170,7 @@ export const TYPERT = {
169
170
  typeSymbol: 'dsh-plugin-shop#shop/installed:result',
170
171
  schema: dsh_plugin_shop_shop_installed_result$schema,
171
172
  },
172
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":759,"column":9},
173
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":763,"column":9},
173
174
  },
174
175
  {
175
176
  id: 'dsh-plugin-shop#shop/installStart',
@@ -195,7 +196,7 @@ export const TYPERT = {
195
196
  typeSymbol: 'dsh-plugin-shop/types#ShopInstallResult',
196
197
  schema: dsh_plugin_shop_shop_installStart_result$schema,
197
198
  },
198
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":624,"column":9},
199
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":628,"column":9},
199
200
  },
200
201
  {
201
202
  id: 'dsh-plugin-shop#shop/installStatus',
@@ -220,7 +221,7 @@ export const TYPERT = {
220
221
  typeSymbol: 'dsh-plugin-shop/types#ShopInstallStatusResult',
221
222
  schema: dsh_plugin_shop_shop_installStatus_result$schema,
222
223
  },
223
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":748,"column":3},
224
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":752,"column":3},
224
225
  },
225
226
  {
226
227
  id: 'dsh-plugin-shop#shop/restart',
@@ -235,7 +236,7 @@ export const TYPERT = {
235
236
  typeSymbol: 'dsh-plugin-shop/types#ShopRestartResult',
236
237
  schema: dsh_plugin_shop_shop_restart_result$schema,
237
238
  },
238
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":909,"column":9},
239
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":913,"column":9},
239
240
  },
240
241
  {
241
242
  id: 'dsh-plugin-shop#shop/setEnabled',
@@ -260,7 +261,7 @@ export const TYPERT = {
260
261
  typeSymbol: 'dsh-plugin-shop/types#ShopSetEnabledResult',
261
262
  schema: dsh_plugin_shop_shop_setEnabled_result$schema,
262
263
  },
263
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":466,"column":9},
264
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":469,"column":9},
264
265
  },
265
266
  {
266
267
  id: 'dsh-plugin-shop#shop/uninstallStart',
@@ -286,7 +287,7 @@ export const TYPERT = {
286
287
  typeSymbol: 'dsh-plugin-shop/types#ShopUninstallResult',
287
288
  schema: dsh_plugin_shop_shop_uninstallStart_result$schema,
288
289
  },
289
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":851,"column":9},
290
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":855,"column":9},
290
291
  },
291
292
  {
292
293
  id: 'dsh-plugin-shop#shop/updateStart',
@@ -311,7 +312,7 @@ export const TYPERT = {
311
312
  typeSymbol: 'dsh-plugin-shop/types#ShopUpdateResult',
312
313
  schema: dsh_plugin_shop_shop_updateStart_result$schema,
313
314
  },
314
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":977,"column":9},
315
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":981,"column":9},
315
316
  },
316
317
  {
317
318
  id: 'dsh-plugin-shop#shop/version',
@@ -326,7 +327,7 @@ export const TYPERT = {
326
327
  typeSymbol: 'dsh-plugin-shop/types#ShopVersionResult',
327
328
  schema: dsh_plugin_shop_shop_version_result$schema,
328
329
  },
329
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":960,"column":9},
330
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":964,"column":9},
330
331
  },
331
332
  ],
332
333
  model: {
@@ -452,7 +453,7 @@ export const TYPERT = {
452
453
  },
453
454
  {
454
455
  "name": "ShopCatalogResult",
455
- "declaration": "export interface ShopCatalogResult {\n schemaVersion: number;\n builtAt: string;\n stale: boolean;\n plugins: CatalogEntry[];\n denied: DeniedEntry[];\n stars: Record<string, number>;\n incompatible: Record<string, string[]>;\n}"
456
+ "declaration": "export interface ShopCatalogResult {\n schemaVersion: number;\n builtAt: string;\n stale: boolean;\n plugins: CatalogEntry[];\n denied: DeniedEntry[];\n notAShop?: string[];\n stars: Record<string, number>;\n incompatible: Record<string, string[]>;\n}"
456
457
  },
457
458
  {
458
459
  "name": "ShopInstalledEntry",
@@ -49,6 +49,7 @@ const dsh_plugin_shop_shop_catalog_result$schema = z.object({
49
49
  'detail': z.string(),
50
50
  'replacement': z.union([z.undefined(), z.string()]).optional(),
51
51
  })),
52
+ 'notAShop': z.union([z.undefined(), z.array(z.string())]).optional(),
52
53
  'stars': z.record(z.string(), z.number()),
53
54
  'incompatible': z.record(z.string(), z.array(z.string())),
54
55
  })
@@ -151,7 +152,7 @@ export const TYPERT_REMOTE = {
151
152
  typeSymbol: 'dsh-plugin-shop/types#ShopCatalogResult',
152
153
  schema: dsh_plugin_shop_shop_catalog_result$schema,
153
154
  },
154
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":574,"column":9},
155
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":577,"column":9},
155
156
  },
156
157
  {
157
158
  id: 'dsh-plugin-shop#shop/installed',
@@ -166,7 +167,7 @@ export const TYPERT_REMOTE = {
166
167
  typeSymbol: 'dsh-plugin-shop#shop/installed:result',
167
168
  schema: dsh_plugin_shop_shop_installed_result$schema,
168
169
  },
169
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":759,"column":9},
170
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":763,"column":9},
170
171
  },
171
172
  {
172
173
  id: 'dsh-plugin-shop#shop/installStart',
@@ -192,7 +193,7 @@ export const TYPERT_REMOTE = {
192
193
  typeSymbol: 'dsh-plugin-shop/types#ShopInstallResult',
193
194
  schema: dsh_plugin_shop_shop_installStart_result$schema,
194
195
  },
195
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":624,"column":9},
196
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":628,"column":9},
196
197
  },
197
198
  {
198
199
  id: 'dsh-plugin-shop#shop/installStatus',
@@ -217,7 +218,7 @@ export const TYPERT_REMOTE = {
217
218
  typeSymbol: 'dsh-plugin-shop/types#ShopInstallStatusResult',
218
219
  schema: dsh_plugin_shop_shop_installStatus_result$schema,
219
220
  },
220
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":748,"column":3},
221
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":752,"column":3},
221
222
  },
222
223
  {
223
224
  id: 'dsh-plugin-shop#shop/restart',
@@ -232,7 +233,7 @@ export const TYPERT_REMOTE = {
232
233
  typeSymbol: 'dsh-plugin-shop/types#ShopRestartResult',
233
234
  schema: dsh_plugin_shop_shop_restart_result$schema,
234
235
  },
235
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":909,"column":9},
236
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":913,"column":9},
236
237
  },
237
238
  {
238
239
  id: 'dsh-plugin-shop#shop/setEnabled',
@@ -257,7 +258,7 @@ export const TYPERT_REMOTE = {
257
258
  typeSymbol: 'dsh-plugin-shop/types#ShopSetEnabledResult',
258
259
  schema: dsh_plugin_shop_shop_setEnabled_result$schema,
259
260
  },
260
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":466,"column":9},
261
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":469,"column":9},
261
262
  },
262
263
  {
263
264
  id: 'dsh-plugin-shop#shop/uninstallStart',
@@ -283,7 +284,7 @@ export const TYPERT_REMOTE = {
283
284
  typeSymbol: 'dsh-plugin-shop/types#ShopUninstallResult',
284
285
  schema: dsh_plugin_shop_shop_uninstallStart_result$schema,
285
286
  },
286
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":851,"column":9},
287
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":855,"column":9},
287
288
  },
288
289
  {
289
290
  id: 'dsh-plugin-shop#shop/updateStart',
@@ -308,7 +309,7 @@ export const TYPERT_REMOTE = {
308
309
  typeSymbol: 'dsh-plugin-shop/types#ShopUpdateResult',
309
310
  schema: dsh_plugin_shop_shop_updateStart_result$schema,
310
311
  },
311
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":977,"column":9},
312
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":981,"column":9},
312
313
  },
313
314
  {
314
315
  id: 'dsh-plugin-shop#shop/version',
@@ -323,7 +324,7 @@ export const TYPERT_REMOTE = {
323
324
  typeSymbol: 'dsh-plugin-shop/types#ShopVersionResult',
324
325
  schema: dsh_plugin_shop_shop_version_result$schema,
325
326
  },
326
- sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":960,"column":9},
327
+ sourceLocation: {"file":"packages/dsh-plugin-shop/src/host/index.ts","line":964,"column":9},
327
328
  },
328
329
  ],
329
330
  }
@@ -83,6 +83,7 @@ export declare const zh: {
83
83
  updateFailed: string;
84
84
  updateTransportFailed: string;
85
85
  checkUpdate: string;
86
+ checkUpdateTitle: string;
86
87
  upToDate: string;
87
88
  github: string;
88
89
  enabledSwitch: string;
@@ -175,6 +176,7 @@ export declare const en: {
175
176
  updateFailed: string;
176
177
  updateTransportFailed: string;
177
178
  checkUpdate: string;
179
+ checkUpdateTitle: string;
178
180
  upToDate: string;
179
181
  github: string;
180
182
  enabledSwitch: string;
@@ -1,6 +1,7 @@
1
1
  /** Pure presentation core for the shop tab (§5.1 Client half). No React, no
2
2
  * timers, no I/O: every function here maps a value to a value, so fixtures
3
3
  * drive all of it. */
4
+ export { isShopLike } from '../shared/shop-like.ts';
4
5
  import type { ShopLocaleKey } from './locales.ts';
5
6
  import type { CatalogEntry, HotRestartReason, InstallRejectionCode } from '../host/index.ts';
6
7
  /** Hot-mount reason code → locale key, so the notice reads in the language
@@ -103,18 +104,6 @@ export declare function nextVisibleCount(visible: number, total: number, batch:
103
104
  * view is tracking — a status for an install it never started (idle) is an
104
105
  * unrelated event and a no-op, like any other event it does not recognize. */
105
106
  export declare function reduceInstall(state: InstallView, event: InstallEvent): InstallView;
106
- /**
107
- * Whether a package name reads as a plugin shop (a marketplace for dsh
108
- * plugins, e.g. `dsh-plugin-shop`, `dsh-store`, `pluginstore`). The shop
109
- * tab hides these so the market does not list competing markets.
110
- *
111
- * Precision over recall: a name merely CONTAINING a keyword segment without
112
- * a plugin qualifier or a keyword ending (`market-data-provider`,
113
- * `marketplace-hub`) is NOT a shop plugin, and `dsh-restore` must never
114
- * match on the substring "store". The keyword list keeps "store" on purpose:
115
- * it matches other people's package names, not ours.
116
- */
117
- export declare function isShopLike(name: string): boolean;
118
107
  declare const CATEGORY_KEYS: {
119
108
  readonly tool: "categoryTool";
120
109
  readonly provider: "categoryProvider";
@@ -222,4 +211,3 @@ export declare function starsOf(entry: CatalogEntry, stars: Record<string, numbe
222
211
  export declare function sortByStars(entries: CatalogEntry[], stars: Record<string, number>): CatalogEntry[];
223
212
  /** 999 → "999"; 1000 → "1k"; 1234 → "1.2k"; 1500 → "1.5k"; 99999 → "100k". */
224
213
  export declare function formatStars(n: number): string;
225
- export {};
@@ -14,6 +14,11 @@ export interface CatalogSnapshot {
14
14
  builtAt: string;
15
15
  entries: CatalogEntry[];
16
16
  denied: DeniedEntry[];
17
+ /** Names the shop-like NAME filter must not hide (registry/not-a-shop.yml).
18
+ * Absent for a catalog built before the key existed, which is why it is
19
+ * optional rather than defaulted here: the parse defaults it, a snapshot
20
+ * assembled by hand need not carry it. */
21
+ notAShop?: string[];
17
22
  /** GitHub star counts by package name; {} when the pointer names no
18
23
  * sidecar or the sidecar could not be fetched/verified (spec §5). */
19
24
  stars: Record<string, number>;
@@ -186,6 +186,9 @@ export interface ShopCatalogResult {
186
186
  stale: boolean;
187
187
  plugins: CatalogEntry[];
188
188
  denied: DeniedEntry[];
189
+ /** Names whose shop-like NAME must not hide them from the shelf
190
+ * (registry/not-a-shop.yml). Absent for a catalog built before the key. */
191
+ notAShop?: string[];
189
192
  /** GitHub star counts by package name; {} when the pointer names no sidecar
190
193
  * or the sidecar could not be fetched/verified (§5). */
191
194
  stars: Record<string, number>;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Whether a package name reads as a competing plugin marketplace.
3
+ *
4
+ * Shared on purpose. The registry needs it to pick which newly harvested names
5
+ * to send for a market verdict, and the client needs it to hide the ones no
6
+ * verdict has reached yet. When each had a copy they drifted — that is exactly
7
+ * how the shelf came to disagree with its own count — so there is one.
8
+ *
9
+ * It lives under the published package rather than beside the registry because
10
+ * the dependency can only point this way: the package's tsconfig pins
11
+ * `rootDir: "src"`, so nothing outside it can be imported, while the registry
12
+ * scripts are internal and may reach in.
13
+ *
14
+ * This is a NAME heuristic and nothing more. It cannot tell a plugin that
15
+ * stores tea from one that sells plugins — on the live catalog it caught 73
16
+ * names of which 20 were innocent — so `registry/markets.yml` carries the
17
+ * verdict per name and overrides it either way.
18
+ *
19
+ * @module shared/shop-like
20
+ */
21
+ /**
22
+ * Whether a package name reads as a plugin shop (a marketplace for dsh
23
+ * plugins, e.g. `dsh-plugin-shop`, `dsh-store`, `pluginstore`). The shop
24
+ * tab hides these so the market does not list competing markets.
25
+ *
26
+ * Precision over recall: a name merely CONTAINING a keyword segment without
27
+ * a plugin qualifier or a keyword ending (`market-data-provider`,
28
+ * `marketplace-hub`) is NOT a shop plugin, and `dsh-restore` must never
29
+ * match on the substring "store". The keyword list keeps "store" on purpose:
30
+ * it matches other people's package names, not ours.
31
+ */
32
+ export declare function isShopLike(name: string): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-shop",
3
- "version": "0.7.2-beta.0",
3
+ "version": "0.7.2-beta.1",
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",