fix(client): a core-bundle red line still left its verb in English (#401)

The scanner's detail is itself a sentence — "overrides bundle …" or
"disables bundle …" — and the translation was pasting that detail
through. A reader then had to parse the English verb to learn whether
the install would replace a part of DSH or switch one off. Those two
shapes are the only details the scanner emits.
This commit is contained in:
Liu Wenjie
2026-09-26 16:14:54 +08:00
parent d8b53972e6
commit 57fe7bfa97
4 changed files with 42 additions and 1 deletions
+9
View File
@@ -272,6 +272,8 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
capRedInstallScriptScripts: "安装时会立刻运行 {0},不需要你打开插件",
capRedCoreTamper: "会改动 DSH 自带的组件",
capRedCoreTamperDetail: "会改动 DSH 自带的组件({0})",
capRedCoreOverride: "会覆盖 DSH 自带的组件({0})",
capRedCoreDisable: "会禁用 DSH 自带的组件({0})",
favoriteAdd: "加入收藏",
favoriteRemove: "取消收藏",
favoritesEmpty: "还没有收藏。在「发现」或「主题」里点书签图标即可收藏。",
@@ -920,6 +922,8 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
capRedInstallScriptScripts: "runs {0} the moment you install — you do not have to open the plugin",
capRedCoreTamper: "replaces parts of DSH itself",
capRedCoreTamperDetail: "replaces parts of DSH itself ({0})",
capRedCoreOverride: "overrides a part of DSH itself ({0})",
capRedCoreDisable: "disables a part of DSH itself ({0})",
favoriteAdd: "Add to favorites",
favoriteRemove: "Remove from favorites",
favoritesEmpty: "No favorites yet. Click the bookmark icon in Discover or Themes to add one.",
@@ -9764,6 +9768,11 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
if (literalIp !== null) return t("capRedLiteralIp").replace("{0}", literalIp[1]);
const installScript = /^runs code at install time(?: \((.+)\))?$/.exec(line);
if (installScript !== null) return installScript[1] === void 0 ? t("capRedInstallScript") : t("capRedInstallScriptScripts").replace("{0}", installScript[1]);
const coreVerb = /^tampers with a core bundle \((overrides|disables) bundle (.+)\)$/.exec(line);
if (coreVerb !== null) {
const key = coreVerb[1] === "overrides" ? "capRedCoreOverride" : "capRedCoreDisable";
return t(key).replace("{0}", coreVerb[2]);
}
const coreTamper = /^tampers with a core bundle(?: \((.+)\))?$/.exec(line);
if (coreTamper !== null) return coreTamper[1] === void 0 ? t("capRedCoreTamper") : t("capRedCoreTamperDetail").replace("{0}", coreTamper[1]);
return line;
+9
View File
@@ -3980,6 +3980,15 @@ export function MarketSection(props: MarketSectionProps) {
? t('capRedInstallScript')
: t('capRedInstallScriptScripts').replace('{0}', installScript[1])
}
// The parenthesised detail is not a name. The scanner emits exactly two
// shapes — "overrides bundle <id>" and "disables bundle <id>" — and pasting
// either through leaves the verb in English. That verb is the fact: the
// install would replace a part of DSH, or switch one off.
const coreVerb = /^tampers with a core bundle \((overrides|disables) bundle (.+)\)$/.exec(line)
if (coreVerb !== null) {
const key = coreVerb[1] === 'overrides' ? 'capRedCoreOverride' : 'capRedCoreDisable'
return t(key).replace('{0}', coreVerb[2]!)
}
const coreTamper = /^tampers with a core bundle(?: \((.+)\))?$/.exec(line)
if (coreTamper !== null) {
return coreTamper[1] === undefined
+4
View File
@@ -81,6 +81,8 @@ export const zh = {
capRedInstallScriptScripts: '安装时会立刻运行 {0},不需要你打开插件',
capRedCoreTamper: '会改动 DSH 自带的组件',
capRedCoreTamperDetail: '会改动 DSH 自带的组件({0})',
capRedCoreOverride: '会覆盖 DSH 自带的组件({0})',
capRedCoreDisable: '会禁用 DSH 自带的组件({0})',
favoriteAdd: '加入收藏',
favoriteRemove: '取消收藏',
favoritesEmpty: '还没有收藏。在「发现」或「主题」里点书签图标即可收藏。',
@@ -746,6 +748,8 @@ export const en: Record<MarketKey, string> = {
capRedInstallScriptScripts: 'runs {0} the moment you install — you do not have to open the plugin',
capRedCoreTamper: 'replaces parts of DSH itself',
capRedCoreTamperDetail: 'replaces parts of DSH itself ({0})',
capRedCoreOverride: 'overrides a part of DSH itself ({0})',
capRedCoreDisable: 'disables a part of DSH itself ({0})',
favoriteAdd: 'Add to favorites',
favoriteRemove: 'Remove from favorites',
favoritesEmpty: 'No favorites yet. Click the bookmark icon in Discover or Themes to add one.',
+20 -1
View File
@@ -3821,7 +3821,7 @@ describe('capability disclosure (#401)', () => {
['uses plaintext http:// to schemas.example.org', en.capRedPlaintextHttp.replace('{0}', 'schemas.example.org')],
['uses literal IP 169.254.169.254 for network access', en.capRedLiteralIp.replace('{0}', '169.254.169.254')],
['runs code at install time (postinstall, preinstall)', en.capRedInstallScriptScripts.replace('{0}', 'postinstall, preinstall')],
['tampers with a core bundle (dsh-base)', en.capRedCoreTamperDetail.replace('{0}', 'dsh-base')],
['tampers with a core bundle (overrides bundle @deepseek-ai/dsh-base)', en.capRedCoreOverride.replace('{0}', '@deepseek-ai/dsh-base')],
]
withEntry({ capabilities: ['network'], capabilityRedLines: families.map(([line]) => line) })
render(<MarketSection {...props()} />)
@@ -3836,6 +3836,25 @@ describe('capability disclosure (#401)', () => {
for (const [, label] of families) expect(dialog.getByText(label)).toBeTruthy()
})
it('says whether a core part is overridden or disabled, instead of leaving the verb in English', async () => {
// These two sentences are the only core-tamper details the scanner emits.
// The verb is the fact a reader has to weigh before installing; a translation
// that still says "overrides bundle" has not translated it.
const override = 'tampers with a core bundle (overrides bundle @deepseek-ai/dsh-base)'
const disable = 'tampers with a core bundle (disables bundle @deepseek-ai/dsh-core)'
withEntry({
capabilities: ['host-runtime'],
capabilityRedLines: [override, disable],
})
render(<MarketSection {...props()} />)
await screen.findByText('dsh-probe-target')
const dialog = await openDetail()
expect(dialog.getByText(en.capRedCoreOverride.replace('{0}', '@deepseek-ai/dsh-base'))).toBeTruthy()
expect(dialog.getByText(en.capRedCoreDisable.replace('{0}', '@deepseek-ai/dsh-core'))).toBeTruthy()
expect(dialog.queryByText(/overrides bundle/)).toBeNull()
expect(dialog.queryByText(/disables bundle/)).toBeNull()
})
it('separates "nothing found" from "never scanned"', async () => {
withEntry({ capabilities: [], capabilityRedLines: [] })
render(<MarketSection {...props()} />)