feat(plugins): add marketplace banner, docs link and card polish

This commit is contained in:
t8y2
2026-09-15 01:27:32 +08:00
parent a81ae9f455
commit 1ea822b80e
9 changed files with 80 additions and 19 deletions
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, h, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { Check, ChevronRight, CircleAlert, Download, ExternalLink, FileUp, FolderTree, Globe, LayoutGrid, Link2, List, Loader2, PackageCheck, Pencil, Plus, RefreshCw, RotateCcw, Search, Settings2, ShieldCheck, Store, Trash2 } from "@lucide/vue";
import { computed, defineComponent, h, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { Check, ChevronRight, CircleAlert, Download, ExternalLink, FileUp, FolderTree, Globe, Info, LayoutGrid, Link2, List, Loader2, PackageCheck, Pencil, Plus, RefreshCw, RotateCcw, Search, Settings2, ShieldCheck, Store, Trash2 } from "@lucide/vue";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -32,15 +32,18 @@ const emit = defineEmits<{
}>();
// lucide no longer ships brand icons; mirror the inline glyph used in AppToolbar.
const GithubIcon = {
const GithubIcon = defineComponent({
props: {
iconClass: { type: String, default: "size-3" },
},
render() {
return h("svg", { class: "size-3", viewBox: "0 0 24 24", fill: "currentColor" }, [
return h("svg", { class: this.iconClass, viewBox: "0 0 24 24", fill: "currentColor" }, [
h("path", {
d: "M12 0C5.37 0 0 5.37 0 12c0 5.3 3.438 9.8 8.205 11.387.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.387-1.333-1.756-1.333-1.756-1.09-.745.083-.729.083-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 21.795 24 17.295 24 12 24 5.37 18.627 0 12 0z",
}),
]);
},
};
});
const PLUGIN_ALLOW_UNSIGNED_STORAGE_KEY = "dbx-plugin-allow-unsigned";
@@ -107,6 +110,7 @@ const filteredMarketplaceListings = computed(() => filterMarketplacePluginListin
const catalogErrors = computed(() => catalogResults.value.filter((result) => result.error));
const customRepositories = computed(() => repositories.value.filter((repository) => !repository.managed));
const showCustomRepositoryTrustSettings = computed(() => customRepositories.value.length > 0 || trustedKeys.value.length > 0);
const pluginDevelopmentDocsUrl = computed(() => `https://dbxio.com/${appLocale.value.startsWith("zh") ? "cn" : "en"}/docs/plugin-development`);
function openExternal(url?: string) {
const target = url?.trim();
@@ -559,6 +563,13 @@ onBeforeUnmount(() => {
<TabsContent value="marketplace" class="m-0 min-h-0 flex-1 overflow-y-auto">
<div class="flex min-h-full w-full flex-col gap-4 pb-2">
<div class="flex items-start gap-2.5 rounded-xl border bg-card/70 px-4 py-3">
<Info class="mt-0.5 size-3.5 shrink-0 text-primary" />
<div class="min-w-0 flex-1 text-xs leading-5 text-muted-foreground">
<span class="font-medium text-foreground">{{ t("pluginPlatform.marketplaceGuideTitle") }}</span>
<span class="mx-1.5 text-border">·</span>{{ t("pluginPlatform.marketplaceGuideDescription") }}
</div>
</div>
<div class="flex w-full flex-col gap-2 rounded-xl border bg-card/70 p-3 sm:flex-row sm:items-center">
<div class="relative">
<Search class="pointer-events-none absolute left-2.5 top-2.5 size-3.5 text-muted-foreground" />
@@ -622,15 +633,17 @@ onBeforeUnmount(() => {
</div>
<div class="mt-1 flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground">
<span class="truncate">{{ listing.plugin.publisher }} · {{ listing.repository.name }}</span>
<button v-if="listing.plugin.source" type="button" class="shrink-0 rounded p-0.5 opacity-60 transition-opacity hover:opacity-100" :title="t('pluginPlatform.sourceRepository')" :aria-label="t('pluginPlatform.sourceRepository')" @click.stop="openExternal(listing.plugin.source)">
<GithubIcon />
</button>
<button v-if="listing.plugin.homepage" type="button" class="shrink-0 rounded p-0.5 opacity-60 transition-opacity hover:opacity-100" :title="t('pluginPlatform.pluginHomepage')" :aria-label="t('pluginPlatform.pluginHomepage')" @click.stop="openExternal(listing.plugin.homepage)">
<Globe class="size-3" />
</button>
</div>
</div>
<Badge variant="outline" class="h-5 px-1.5 text-[10px]">v{{ listing.plugin.latestVersion }}</Badge>
<div class="flex shrink-0 items-center gap-1">
<button v-if="listing.plugin.source" type="button" class="rounded p-0.5 opacity-60 transition-opacity hover:opacity-100" :title="t('pluginPlatform.sourceRepository')" :aria-label="t('pluginPlatform.sourceRepository')" @click.stop="openExternal(listing.plugin.source)">
<GithubIcon icon-class="size-3.5" />
</button>
<button v-if="listing.plugin.homepage" type="button" class="rounded p-0.5 opacity-60 transition-opacity hover:opacity-100" :title="t('pluginPlatform.pluginHomepage')" :aria-label="t('pluginPlatform.pluginHomepage')" @click.stop="openExternal(listing.plugin.homepage)">
<Globe class="size-3.5" />
</button>
<Badge variant="outline" class="h-5 px-1.5 text-[10px]">v{{ listing.plugin.latestVersion }}</Badge>
</div>
</div>
<p class="mt-3 line-clamp-3 text-xs leading-5 text-muted-foreground">{{ listing.description || t("pluginPlatform.noDescription") }}</p>
<div class="mt-3 flex flex-wrap gap-1.5">
@@ -667,16 +680,16 @@ onBeforeUnmount(() => {
<div class="flex min-w-0 items-center gap-2">
<span class="truncate text-sm font-semibold">{{ listing.name }}</span>
<Badge v-if="listing.verified" variant="secondary" class="hidden h-5 shrink-0 gap-1 px-1.5 text-[10px] sm:inline-flex"><ShieldCheck class="size-3" />{{ t("pluginPlatform.verified") }}</Badge>
<button v-if="listing.plugin.source" type="button" class="shrink-0 rounded p-0.5 opacity-60 transition-opacity hover:opacity-100" :title="t('pluginPlatform.sourceRepository')" :aria-label="t('pluginPlatform.sourceRepository')" @click.stop="openExternal(listing.plugin.source)">
<GithubIcon icon-class="size-3.5" />
</button>
<button v-if="listing.plugin.homepage" type="button" class="shrink-0 rounded p-0.5 opacity-60 transition-opacity hover:opacity-100" :title="t('pluginPlatform.pluginHomepage')" :aria-label="t('pluginPlatform.pluginHomepage')" @click.stop="openExternal(listing.plugin.homepage)">
<Globe class="size-3.5" />
</button>
<Badge variant="outline" class="h-5 shrink-0 px-1.5 text-[10px]">v{{ listing.plugin.latestVersion }}</Badge>
</div>
<div class="mt-0.5 flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground">
<span class="truncate">{{ listing.plugin.publisher }} · {{ listing.repository.name }}</span>
<button v-if="listing.plugin.source" type="button" class="shrink-0 rounded p-0.5 opacity-60 transition-opacity hover:opacity-100" :title="t('pluginPlatform.sourceRepository')" :aria-label="t('pluginPlatform.sourceRepository')" @click.stop="openExternal(listing.plugin.source)">
<GithubIcon />
</button>
<button v-if="listing.plugin.homepage" type="button" class="shrink-0 rounded p-0.5 opacity-60 transition-opacity hover:opacity-100" :title="t('pluginPlatform.pluginHomepage')" :aria-label="t('pluginPlatform.pluginHomepage')" @click.stop="openExternal(listing.plugin.homepage)">
<Globe class="size-3" />
</button>
</div>
<p class="mt-1 truncate text-xs text-muted-foreground">{{ listing.description || t("pluginPlatform.noDescription") }}</p>
</div>
@@ -794,7 +807,7 @@ onBeforeUnmount(() => {
<Button size="sm" class="gap-1.5" @click="createConnection"><Plus class="size-3.5" />{{ t("pluginPlatform.newConnection") }}</Button>
<div v-for="connection in providerConnections" :key="connection.id" class="inline-flex items-center">
<Button size="sm" class="rounded-r-none" :variant="selectedConnectionId === connection.id ? 'secondary' : 'outline'" @click="selectConnection(connection.id)">{{ connection.name }}</Button>
<Button size="icon" variant="outline" class="h-8 w-8 rounded-l-none border-l-0" :title="t('common.edit')" :aria-label="t('common.edit')" @click="editConnection(connection.id)"><Pencil class="size-3.5" /></Button>
<Button size="icon-sm" class="rounded-l-none border-l-0" :variant="selectedConnectionId === connection.id ? 'secondary' : 'outline'" :title="t('common.edit')" :aria-label="t('common.edit')" @click="editConnection(connection.id)"><Pencil class="size-3.5" /></Button>
</div>
</div>
<div class="rounded-md border border-dashed bg-muted/20 p-3 text-xs leading-5 text-muted-foreground">{{ t("pluginPlatform.connectionManagedInDialog") }}</div>
@@ -904,6 +917,14 @@ onBeforeUnmount(() => {
<div class="text-xs leading-5">{{ t("pluginPlatform.developerOptionsWarning") }}</div>
</div>
<div class="flex items-center justify-between gap-4 rounded-lg border bg-background p-3">
<div class="min-w-0">
<div class="text-xs font-medium">{{ t("pluginPlatform.pluginDevelopmentDocsTitle") }}</div>
<div class="mt-1 text-[11px] leading-5 text-muted-foreground">{{ t("pluginPlatform.pluginDevelopmentDocsDescription") }}</div>
</div>
<Button size="sm" variant="outline" class="shrink-0 gap-1.5" @click="openExternal(pluginDevelopmentDocsUrl)"><ExternalLink class="size-3.5" />{{ t("pluginPlatform.pluginDevelopmentDocsOpen") }}</Button>
</div>
<div class="flex items-start justify-between gap-4 rounded-lg border bg-background p-3">
<div class="min-w-0">
<Label for="allow-unsigned-plugin-package" class="text-xs font-medium">{{ t("pluginPlatform.allowUnsignedDevelopmentPackage") }}</Label>
+5
View File
@@ -173,6 +173,8 @@ export default {
settings: "Settings",
searchMarketplace: "Search plugins, publishers, or tags",
allRepositories: "All repositories",
marketplaceGuideTitle: "Plugins are maintained by community developers",
marketplaceGuideDescription: "For plugin issues or feature requests, please open an issue in the plugin's own repository (use the source repository link on the plugin card); the main DBX repository only handles issues with the app itself.",
loadingMarketplace: "Loading plugin marketplace",
noMarketplacePlugins: "No plugins to show",
noMarketplacePluginsDescription: "Configure a repository in Settings, or adjust the current search and filters.",
@@ -218,6 +220,9 @@ export default {
signedPackagesVerifiedAutomatically: "Signatures are verified automatically",
developerOptionsTitle: "Third-party and developer options",
developerOptionsDescription: "Use only for custom repositories or local plugin development.",
pluginDevelopmentDocsTitle: "Plugin development documentation",
pluginDevelopmentDocsDescription: "Learn how to develop, package, and publish DBX plugins to the marketplace.",
pluginDevelopmentDocsOpen: "View documentation",
developerOptionsWarning: "Unsigned plugins can run native code with your user permissions. Enable this only for packages you built and trust.",
connectionManagedInDialog: "Create and edit connections in the unified New Connection dialog. This page only manages plugins and shows their capabilities.",
allowUnsignedDevelopmentPackage: "Allow unsigned development packages",
+5
View File
@@ -175,6 +175,8 @@ export default withEnglishFallback({
settings: "Ajustes",
searchMarketplace: "Buscar plugins, editores o etiquetas",
allRepositories: "Todos los repositorios",
marketplaceGuideTitle: "Los plugins los mantienen desarrolladores de la comunidad",
marketplaceGuideDescription: "Para problemas o sugerencias sobre un plugin, abre una issue en el repositorio del propio plugin (usa el enlace del repositorio de origen en la tarjeta); el repositorio principal de DBX solo atiende problemas de la propia aplicación.",
loadingMarketplace: "Cargando marketplace de plugins",
noMarketplacePlugins: "No hay plugins para mostrar",
noMarketplacePluginsDescription: "Configura un repositorio en Ajustes o cambia la búsqueda y los filtros.",
@@ -211,6 +213,9 @@ export default withEnglishFallback({
signedPackagesVerifiedAutomatically: "Integridad y firmas verificadas automáticamente",
developerOptionsTitle: "Opciones de terceros y desarrollo",
developerOptionsDescription: "Úsalas solo para repositorios personalizados o desarrollo local de plugins.",
pluginDevelopmentDocsTitle: "Documentación de desarrollo de plugins",
pluginDevelopmentDocsDescription: "Aprende a desarrollar, empaquetar y publicar plugins de DBX en el marketplace.",
pluginDevelopmentDocsOpen: "Ver documentación",
developerOptionsWarning: "Los plugins sin firma pueden ejecutar código nativo con tus permisos de usuario. Actívalo solo para paquetes creados y verificados por ti.",
connectionManagedInDialog: "Crea y edita conexiones en el cuadro unificado Nueva conexión. Esta página solo administra plugins y muestra sus capacidades.",
allowUnsignedDevelopmentPackage: "Permitir paquetes de desarrollo sin firmar",
+5
View File
@@ -174,6 +174,8 @@ export default withEnglishFallback({
settings: "Impostazioni",
searchMarketplace: "Cerca plugin, autori o tag",
allRepositories: "Tutti i repository",
marketplaceGuideTitle: "I plugin sono mantenuti dagli sviluppatori della community",
marketplaceGuideDescription: "Per problemi o suggerimenti su un plugin, apri una issue nel repository del plugin stesso (usa il link del repository sorgente sulla scheda); il repository principale di DBX gestisce solo i problemi dell'applicazione.",
loadingMarketplace: "Caricamento marketplace plugin",
noMarketplacePlugins: "Nessun plugin da mostrare",
noMarketplacePluginsDescription: "Configura un repository nelle Impostazioni oppure modifica ricerca e filtri.",
@@ -210,6 +212,9 @@ export default withEnglishFallback({
signedPackagesVerifiedAutomatically: "Integrità e firme verificate automaticamente",
developerOptionsTitle: "Opzioni di terze parti e sviluppo",
developerOptionsDescription: "Usale solo per repository personalizzati o sviluppo locale di plugin.",
pluginDevelopmentDocsTitle: "Documentazione sullo sviluppo di plugin",
pluginDevelopmentDocsDescription: "Scopri come sviluppare, pacchettizzare e pubblicare plugin DBX nel marketplace.",
pluginDevelopmentDocsOpen: "Visualizza documentazione",
developerOptionsWarning: "I plugin non firmati possono eseguire codice nativo con i permessi dell'utente corrente. Abilitali solo per pacchetti creati e verificati da te.",
connectionManagedInDialog: "Crea e modifica le connessioni nella finestra unificata Nuova connessione. Questa pagina gestisce solo i plugin e ne mostra le capacità.",
allowUnsignedDevelopmentPackage: "Consenti pacchetti di sviluppo non firmati",
+5
View File
@@ -175,6 +175,8 @@ export default withEnglishFallback({
settings: "設定",
searchMarketplace: "プラグイン、発行者、タグを検索",
allRepositories: "すべてのリポジトリ",
marketplaceGuideTitle: "プラグインはコミュニティ開発者がメンテナンスしています",
marketplaceGuideDescription: "プラグインの問題や機能要望は、プラグインカードのソースリポジトリリンクから該当リポジトリに Issue を投稿してください。DBX メインリポジトリはアプリ本体の問題のみを受け付けています。",
loadingMarketplace: "プラグインマーケットプレイスを読み込み中",
noMarketplacePlugins: "表示できるプラグインがありません",
noMarketplacePluginsDescription: "設定でリポジトリを追加するか、検索条件を変更してください。",
@@ -211,6 +213,9 @@ export default withEnglishFallback({
signedPackagesVerifiedAutomatically: "整合性と署名を自動検証",
developerOptionsTitle: "サードパーティと開発者向けオプション",
developerOptionsDescription: "カスタムリポジトリまたはローカルプラグイン開発時のみ使用してください。",
pluginDevelopmentDocsTitle: "プラグイン開発ドキュメント",
pluginDevelopmentDocsDescription: "DBX プラグインの開発・パッケージ化・マーケットプレイスへの公開方法をご確認ください。",
pluginDevelopmentDocsOpen: "ドキュメントを見る",
developerOptionsWarning: "未署名プラグインは現在のユーザー権限でネイティブコードを実行できます。自分でビルドし信頼できる開発パッケージにのみ有効化してください。",
connectionManagedInDialog: "接続の作成と編集は共通の「新しい接続」ダイアログで行います。この画面はプラグイン管理と機能表示専用です。",
allowUnsignedDevelopmentPackage: "未署名の開発パッケージを許可",
+5
View File
@@ -174,6 +174,8 @@ export default withEnglishFallback({
settings: "설정",
searchMarketplace: "플러그인, 게시자 또는 태그 검색",
allRepositories: "모든 저장소",
marketplaceGuideTitle: "플러그인은 커뮤니티 개발자가 유지 관리합니다",
marketplaceGuideDescription: "플러그인 문제나 기능 제안은 플러그인 카드의 소스 저장소 링크를 통해 해당 저장소에 Issue를 등록해 주세요. DBX 메인 저장소는 앱 자체의 문제만 처리합니다.",
loadingMarketplace: "플러그인 마켓플레이스 로드 중",
noMarketplacePlugins: "표시할 플러그인이 없습니다",
noMarketplacePluginsDescription: "설정에서 저장소를 구성하거나 현재 검색 및 필터를 조정하세요.",
@@ -219,6 +221,9 @@ export default withEnglishFallback({
signedPackagesVerifiedAutomatically: "서명이 자동으로 검증됩니다",
developerOptionsTitle: "타사 및 개발자 옵션",
developerOptionsDescription: "사용자 지정 저장소 또는 로컬 플러그인 개발에만 사용하세요.",
pluginDevelopmentDocsTitle: "플러그인 개발 문서",
pluginDevelopmentDocsDescription: "DBX 플러그인을 개발하고 패키징하여 마켓플레이스에 게시하는 방법을 알아보세요.",
pluginDevelopmentDocsOpen: "문서 보기",
developerOptionsWarning: "서명되지 않은 플러그인은 사용자 권한으로 네이티브 코드를 실행할 수 있습니다. 직접 빌드하고 신뢰하는 패키지에만 활성화하세요.",
connectionManagedInDialog: "통합된 새 연결 대화상자에서 연결을 만들고 편집하세요. 이 페이지는 플러그인 관리와 기능 표시에만 사용됩니다.",
allowUnsignedDevelopmentPackage: "서명되지 않은 개발 패키지 허용",
+5
View File
@@ -175,6 +175,8 @@ export default withEnglishFallback({
settings: "Configurações",
searchMarketplace: "Buscar plugins, publicadores ou tags",
allRepositories: "Todos os repositórios",
marketplaceGuideTitle: "Os plugins são mantidos por desenvolvedores da comunidade",
marketplaceGuideDescription: "Para problemas ou sugestões sobre um plugin, abra uma issue no repositório do próprio plugin (use o link do repositório de origem no cartão); o repositório principal do DBX trata apenas de problemas do próprio aplicativo.",
loadingMarketplace: "Carregando marketplace de plugins",
noMarketplacePlugins: "Nenhum plugin para exibir",
noMarketplacePluginsDescription: "Configure um repositório nas Configurações ou ajuste a busca e os filtros.",
@@ -211,6 +213,9 @@ export default withEnglishFallback({
signedPackagesVerifiedAutomatically: "Integridade e assinaturas verificadas automaticamente",
developerOptionsTitle: "Opções de terceiros e desenvolvimento",
developerOptionsDescription: "Use somente para repositórios personalizados ou desenvolvimento local de plugins.",
pluginDevelopmentDocsTitle: "Documentação de desenvolvimento de plugins",
pluginDevelopmentDocsDescription: "Saiba como desenvolver, empacotar e publicar plugins do DBX no marketplace.",
pluginDevelopmentDocsOpen: "Ver documentação",
developerOptionsWarning: "Plugins sem assinatura podem executar código nativo com suas permissões de usuário. Ative apenas para pacotes criados e verificados por você.",
connectionManagedInDialog: "Crie e edite conexões na janela unificada Nova conexão. Esta página apenas gerencia plugins e exibe seus recursos.",
allowUnsignedDevelopmentPackage: "Permitir pacotes de desenvolvimento não assinados",
+5
View File
@@ -98,6 +98,8 @@ export default withEnglishFallback({
settings: "设置",
searchMarketplace: "搜索插件、发布者或标签",
allRepositories: "全部仓库",
marketplaceGuideTitle: "插件由社区开发者维护",
marketplaceGuideDescription: "插件问题或功能建议请通过插件卡片上的源码仓库入口,前往对应插件仓库提交 Issue;DBX 主仓库仅受理应用本身的问题。",
loadingMarketplace: "正在加载插件商店",
noMarketplacePlugins: "暂无可展示的插件",
noMarketplacePluginsDescription: "请在设置中配置插件仓库,或调整当前搜索与筛选条件。",
@@ -134,6 +136,9 @@ export default withEnglishFallback({
signedPackagesVerifiedAutomatically: "自动校验完整性和签名",
developerOptionsTitle: "第三方与开发者选项",
developerOptionsDescription: "在接入第三方仓库或开发本地插件时使用。",
pluginDevelopmentDocsTitle: "插件开发文档",
pluginDevelopmentDocsDescription: "了解如何开发、打包并向插件商店发布 DBX 插件。",
pluginDevelopmentDocsOpen: "查看文档",
developerOptionsWarning: "未签名插件可以使用当前用户权限运行原生代码。只应为自己构建且确认可信的开发包开启。",
connectionManagedInDialog: "连接统一在“新建连接”对话框中创建和编辑;这里仅负责插件管理与能力展示。",
allowUnsignedDevelopmentPackage: "允许安装未签名开发包",
+5
View File
@@ -175,6 +175,8 @@ export default withEnglishFallback({
settings: "設定",
searchMarketplace: "搜尋外掛、發佈者或標籤",
allRepositories: "全部倉庫",
marketplaceGuideTitle: "外掛由社群開發者維護",
marketplaceGuideDescription: "外掛問題或功能建議請透過外掛卡片上的原始碼倉庫入口,前往對應外掛倉庫提交 Issue;DBX 主倉庫僅受理應用程式本身的問題。",
loadingMarketplace: "正在載入外掛商店",
noMarketplacePlugins: "沒有可顯示的外掛",
noMarketplacePluginsDescription: "請在設定中配置外掛倉庫,或調整目前的搜尋與篩選條件。",
@@ -211,6 +213,9 @@ export default withEnglishFallback({
signedPackagesVerifiedAutomatically: "自動驗證完整性與簽章",
developerOptionsTitle: "第三方與開發者選項",
developerOptionsDescription: "在接入第三方倉庫或開發本機外掛時使用。",
pluginDevelopmentDocsTitle: "外掛開發文件",
pluginDevelopmentDocsDescription: "了解如何開發、打包並向外掛商店發佈 DBX 外掛。",
pluginDevelopmentDocsOpen: "查看文件",
developerOptionsWarning: "未簽署外掛可以使用目前使用者權限執行原生程式碼。只應為自行建置且確認可信的開發套件啟用。",
connectionManagedInDialog: "連線統一在「新增連線」對話框中建立與編輯;此處僅負責外掛管理與能力展示。",
allowUnsignedDevelopmentPackage: "允許安裝未簽署開發套件",