feat: 动态插件系统 M0-M3(两层能力模型 + pi 原生契约 + Obsidian 式 SDK)

This commit is contained in:
Rick Ye
2026-09-10 02:15:55 +08:00
parent 2b69a9aa13
commit 367f3f5c5b
37 changed files with 2009 additions and 5773 deletions
+17 -1
View File
@@ -1,11 +1,20 @@
import { app, BrowserWindow, ipcMain, Menu, nativeTheme, shell } from 'electron'
import { app, BrowserWindow, ipcMain, Menu, nativeTheme, protocol, shell } from 'electron'
import { existsSync } from 'node:fs'
import { join } from 'node:path'
import { registerIpc } from './ipc'
import { getPluginHost } from './plugins/plugin-host'
import { getBrowserController } from './browser/browser-controller'
process.env.APP_ROOT = join(__dirname, '..')
// 外置插件页的特权协议(必须在 app ready 之前注册):
// - plugin://<id>/<file> → userData/plugins/<id>/ 内文件(宿主做路径穿越防护)
// - peer://assets/tokens.css → 主题 token 样式表(插件页 <link> 引用,保证深浅色/accent 连续)
protocol.registerSchemesAsPrivileged([
{ scheme: 'plugin', privileges: { standard: true, secure: true, supportFetchAPI: true, stream: true } },
{ scheme: 'peer', privileges: { standard: true, secure: true, supportFetchAPI: true } }
])
export const VITE_DEV_SERVER_URL = process.env.ELECTRON_RENDERER_URL ?? process.env.VITE_DEV_SERVER_URL
export const RENDERER_DIST = join(process.env.APP_ROOT, 'renderer')
@@ -134,6 +143,13 @@ if (!app.requestSingleInstanceLock()) {
app.setAppUserModelId('com.inkreach.agent')
}
Menu.setApplicationMenu(null)
// 插件宿主:扫描/装载 + 协议映射 + 插件启停后重建 agent 运行时
const pluginHost = getPluginHost()
pluginHost.init()
pluginHost.registerProtocols()
pluginHost.setRuntimeRebuilder(() => agentService.rebuildRuntime())
void createWindow()
app.on('activate', () => {