diff --git a/internal-plugins/setting/src/components/common/PluginDetail/PluginDetail.vue b/internal-plugins/setting/src/components/common/PluginDetail/PluginDetail.vue
index e9188ef1..8da96cf0 100644
--- a/internal-plugins/setting/src/components/common/PluginDetail/PluginDetail.vue
+++ b/internal-plugins/setting/src/components/common/PluginDetail/PluginDetail.vue
@@ -44,10 +44,13 @@ const {
isAutoKill,
isAutoDetach,
isAutoStart,
+ isMainPushEnabled,
+ pluginHasMainPush,
toggleSettingsDropdown,
toggleAutoKill,
toggleAutoDetach,
toggleAutoStart,
+ toggleMainPushEnabled,
// Tab
activeTab,
availableTabs,
@@ -102,6 +105,8 @@ function onSwitchTab(tabId: TabId): void {
:is-auto-kill="isAutoKill"
:is-auto-detach="isAutoDetach"
:is-auto-start="isAutoStart"
+ :is-main-push-enabled="isMainPushEnabled"
+ :show-main-push-toggle="pluginHasMainPush"
@open="emit('open')"
@kill="emit('kill')"
@open-folder="emit('open-folder')"
@@ -112,6 +117,7 @@ function onSwitchTab(tabId: TabId): void {
@toggle-auto-kill="toggleAutoKill"
@toggle-auto-detach="toggleAutoDetach"
@toggle-auto-start="toggleAutoStart"
+ @toggle-main-push-enabled="toggleMainPushEnabled"
/>
diff --git a/internal-plugins/setting/src/components/common/PluginDetail/PluginDetailToolbar.vue b/internal-plugins/setting/src/components/common/PluginDetail/PluginDetailToolbar.vue
index 73155acd..759a1136 100644
--- a/internal-plugins/setting/src/components/common/PluginDetail/PluginDetailToolbar.vue
+++ b/internal-plugins/setting/src/components/common/PluginDetail/PluginDetailToolbar.vue
@@ -14,6 +14,8 @@ defineProps<{
isAutoKill: boolean
isAutoDetach: boolean
isAutoStart: boolean
+ isMainPushEnabled: boolean
+ showMainPushToggle?: boolean
}>()
const emit = defineEmits<{
@@ -27,6 +29,7 @@ const emit = defineEmits<{
(e: 'toggle-auto-kill'): void
(e: 'toggle-auto-detach'): void
(e: 'toggle-auto-start'): void
+ (e: 'toggle-main-push-enabled'): void
}>()
function handleDisabledToggle(event: Event): void {
@@ -108,6 +111,20 @@ function handleDisabledToggle(event: Event): void {
+
退出即结束
diff --git a/internal-plugins/setting/src/components/common/PluginDetail/types.ts b/internal-plugins/setting/src/components/common/PluginDetail/types.ts
index 902b8787..b692260b 100644
--- a/internal-plugins/setting/src/components/common/PluginDetail/types.ts
+++ b/internal-plugins/setting/src/components/common/PluginDetail/types.ts
@@ -4,6 +4,7 @@ export interface PluginFeature {
explain?: string
icon?: string
cmds?: any[]
+ mainPush?: boolean
}
export interface PluginItem {
diff --git a/internal-plugins/setting/src/components/common/PluginDetail/usePluginDetail.ts b/internal-plugins/setting/src/components/common/PluginDetail/usePluginDetail.ts
index 704a88b8..ec52315c 100644
--- a/internal-plugins/setting/src/components/common/PluginDetail/usePluginDetail.ts
+++ b/internal-plugins/setting/src/components/common/PluginDetail/usePluginDetail.ts
@@ -2,6 +2,11 @@ import { marked } from 'marked'
import { computed, onMounted, onUnmounted, ref, watch, type Ref } from 'vue'
import { useToast } from '@/components'
import type { DocItem, PluginItem, PluginUninstallOptions, TabId, TabItem } from './types'
+import {
+ DISABLED_MAIN_PUSH_PLUGINS_KEY,
+ normalizeConfigList,
+ isMainPushPluginEnabled
+} from '@shared/pluginSettings'
// 配置 marked
marked.setOptions({
@@ -26,17 +31,17 @@ export function usePluginDetail(options: UsePluginDetailOptions) {
const isAutoKill = ref(false)
const isAutoDetach = ref(false)
const isAutoStart = ref(false)
+ const isMainPushEnabled = ref(true)
// 当前详情页插件的有效名称(已包含 __dev 后缀)
const currentPluginName = computed(() => plugin.value.name || null)
-
- /** 解析配置列表,兼容旧式 { pluginName, source } 和新式 string */
- function normalizeConfigList(data: unknown): string[] {
- if (!Array.isArray(data)) return []
- return data
- .map((item) => (typeof item === 'string' ? item : (item?.pluginName ?? '')))
- .filter(Boolean)
- }
+ const pluginHasMainPush = computed(() =>
+ Boolean(
+ plugin.value.features?.some(
+ (feature: any) => feature?.mainPush && Array.isArray(feature.cmds)
+ )
+ )
+ )
/** 切换字符串列表中的某项 */
function toggleInList(list: string[], name: string): string[] {
@@ -83,6 +88,18 @@ export function usePluginDetail(options: UsePluginDetailOptions) {
} catch (err) {
console.debug('未找到 autoStartPlugin 配置', err)
}
+
+ try {
+ const mainPushData = await window.ztools.internal.dbGet(DISABLED_MAIN_PUSH_PLUGINS_KEY)
+ if (currentPluginName.value) {
+ isMainPushEnabled.value = isMainPushPluginEnabled(
+ currentPluginName.value,
+ normalizeConfigList(mainPushData)
+ )
+ }
+ } catch (err) {
+ console.debug('未找到 disabledMainPushPlugin 配置', err)
+ }
}
// 切换「退出即结束」
@@ -136,6 +153,21 @@ export function usePluginDetail(options: UsePluginDetailOptions) {
isAutoStart.value = list.includes(currentPluginName.value)
}
+ async function toggleMainPushEnabled(): Promise {
+ if (!currentPluginName.value) return
+
+ const nextDisabled = isMainPushEnabled.value
+ const result = await window.ztools.internal.setPluginMainPushDisabled(
+ currentPluginName.value,
+ nextDisabled
+ )
+ if (result.success) {
+ isMainPushEnabled.value = !nextDisabled
+ } else {
+ error(`更新搜索栏推送状态失败: ${result.error || '未知错误'}`)
+ }
+ }
+
// Tab 状态
const activeTab = ref('detail')
@@ -493,11 +525,14 @@ export function usePluginDetail(options: UsePluginDetailOptions) {
isAutoKill,
isAutoDetach,
isAutoStart,
+ isMainPushEnabled,
+ pluginHasMainPush,
currentPluginName,
toggleSettingsDropdown,
toggleAutoKill,
toggleAutoDetach,
toggleAutoStart,
+ toggleMainPushEnabled,
// Tab 状态
activeTab,
diff --git a/internal-plugins/setting/src/env.d.ts b/internal-plugins/setting/src/env.d.ts
index 25e568dd..a267047e 100644
--- a/internal-plugins/setting/src/env.d.ts
+++ b/internal-plugins/setting/src/env.d.ts
@@ -57,6 +57,10 @@ declare global {
pluginPath: string,
disabled: boolean
) => Promise<{ success: boolean; error?: string }>
+ setPluginMainPushDisabled: (
+ pluginName: string,
+ disabled: boolean
+ ) => Promise<{ success: boolean; error?: string }>
getAllPlugins: () => Promise<
Array<{
name: string
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 00000000..4a0514e1
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,8 @@
+allowBuilds:
+ electron: true
+ electron-winstaller: true
+ esbuild: true
+ lmdb: true
+ msgpackr-extract: true
+ sharp: true
+ uiohook-napi: true
diff --git a/resources/preload.js b/resources/preload.js
index 3e2f7fcf..c7cf72e8 100644
--- a/resources/preload.js
+++ b/resources/preload.js
@@ -834,6 +834,12 @@ window.ztools = {
setPluginDisabled: async (pluginPath, disabled) =>
await electron.ipcRenderer.invoke('internal:set-plugin-disabled', pluginPath, disabled),
getAllPlugins: async () => await electron.ipcRenderer.invoke('internal:get-all-plugins'),
+ setPluginMainPushDisabled: async (pluginName, disabled) =>
+ await electron.ipcRenderer.invoke(
+ 'internal:set-plugin-main-push-disabled',
+ pluginName,
+ disabled
+ ),
selectPluginFile: async () => await electron.ipcRenderer.invoke('internal:select-plugin-file'),
importPlugin: async () => await electron.ipcRenderer.invoke('internal:import-plugin'),
getDevProjects: async () => await electron.ipcRenderer.invoke('internal:get-dev-projects'),
diff --git a/src/main/api/plugin/internal.ts b/src/main/api/plugin/internal.ts
index 0f53deee..af05e590 100644
--- a/src/main/api/plugin/internal.ts
+++ b/src/main/api/plugin/internal.ts
@@ -213,6 +213,16 @@ export class InternalPluginAPI {
return await pluginsAPI.getAllPlugins()
})
+ ipcMain.handle(
+ 'internal:set-plugin-main-push-disabled',
+ async (event, pluginName: string, disabled: boolean) => {
+ if (!requireInternalPlugin(this.pluginManager, event)) {
+ throw new PermissionDeniedError('internal:set-plugin-main-push-disabled')
+ }
+ return await pluginsAPI.setPluginMainPushDisabled(pluginName, disabled)
+ }
+ )
+
ipcMain.handle('internal:select-plugin-file', async (event) => {
if (!requireInternalPlugin(this.pluginManager, event)) {
throw new PermissionDeniedError('internal:select-plugin-file')
diff --git a/src/main/api/renderer/plugins.ts b/src/main/api/renderer/plugins.ts
index 84af4954..526f9623 100644
--- a/src/main/api/renderer/plugins.ts
+++ b/src/main/api/renderer/plugins.ts
@@ -18,9 +18,20 @@ import {
getPluginDataPrefix,
isDevelopmentPluginName
} from '../../../shared/pluginRuntimeNamespace'
+import {
+ DISABLED_MAIN_PUSH_PLUGINS_KEY,
+ normalizeConfigList,
+ removePluginNameFromSettingList
+} from '../../../shared/pluginSettings'
// 插件目录
const DISABLED_PLUGINS_KEY = 'disabled-plugins'
+const PLUGIN_NAME_SETTING_KEYS = [
+ 'outKillPlugin',
+ 'autoDetachPlugin',
+ 'autoStartPlugin',
+ DISABLED_MAIN_PUSH_PLUGINS_KEY
+]
export interface DeletePluginOptions {
deleteData?: boolean
@@ -474,6 +485,7 @@ export class PluginsAPI {
if (options.deleteData !== false) {
await databaseAPI.clearPluginData(pluginInfo.name)
+ this.removePluginNameConfigs(PLUGIN_NAME_SETTING_KEYS, pluginInfo.name)
}
// 删除禁用插件标识
@@ -503,6 +515,45 @@ export class PluginsAPI {
}
}
+ private removePluginNameConfigs(keys: string[], pluginName: string): void {
+ for (const key of keys) {
+ const current = databaseAPI.dbGet(key)
+ const normalized = normalizeConfigList(current)
+ const next = removePluginNameFromSettingList(normalized, pluginName)
+ if (next.length !== normalized.length) {
+ databaseAPI.dbPut(key, next)
+ }
+ }
+ }
+
+ public async setPluginMainPushDisabled(
+ pluginName: string,
+ disabled: boolean
+ ): Promise<{ success: boolean; error?: string }> {
+ try {
+ const disabledPluginNames = new Set(
+ normalizeConfigList(databaseAPI.dbGet(DISABLED_MAIN_PUSH_PLUGINS_KEY))
+ )
+ const isCurrentlyDisabled = disabledPluginNames.has(pluginName)
+ if (isCurrentlyDisabled === disabled) {
+ return { success: true }
+ }
+
+ if (disabled) {
+ disabledPluginNames.add(pluginName)
+ } else {
+ disabledPluginNames.delete(pluginName)
+ }
+
+ databaseAPI.dbPut(DISABLED_MAIN_PUSH_PLUGINS_KEY, [...disabledPluginNames])
+ this.notifyPluginsChanged()
+ return { success: true }
+ } catch (error: unknown) {
+ console.error('[Plugins] 更新插件 mainPush 状态失败:', error)
+ return { success: false, error: error instanceof Error ? error.message : '未知错误' }
+ }
+ }
+
// 获取运行中的插件
public getRunningPlugins(): string[] {
if (this.pluginManager) {
diff --git a/src/renderer/src/components/detached/DetachedTitlebar.vue b/src/renderer/src/components/detached/DetachedTitlebar.vue
index 3cafb9bb..ba93f561 100644
--- a/src/renderer/src/components/detached/DetachedTitlebar.vue
+++ b/src/renderer/src/components/detached/DetachedTitlebar.vue
@@ -123,6 +123,7 @@