feat: expand multi-runtime workflows for 0.10.0

GoodBuddy previously exposed Runtime capabilities, MCP assignments, plugin controls, context compaction, usage reporting, and task-completion behavior through incomplete or inconsistent paths. This release unifies managed OpenCode, Continue, and DeepSeek Harness controls; adds DSH plugin and image workflows; strengthens MCP and Runtime lifecycle bounds; fixes Windows notification activation; validates cross-architecture packages; and presents the approved bilingual four-section release notes.

The DSH plugin marketplace remains a default-off preview whose trusted third-party code runs with current-user permissions. Ask remains read-only, Execute keeps approval controls, and context compaction may use the selected model without deleting GoodBuddy chat history.

Release note: GoodBuddy 0.10.0 重点完善多 Runtime 工作流,统一 OpenCode、Continue 与 DeepSeek Harness 的能力、MCP、插件和上下文管理,并提升长对话、多会话与任务通知的连贯性。
This commit is contained in:
mesalogo
2026-08-17 12:57:12 +08:00
parent f5ee9b2198
commit cbbe30896e
50 changed files with 4077 additions and 605 deletions
+70 -4
View File
@@ -6,6 +6,7 @@ import {
Menu,
safeStorage,
session,
shell,
Tray,
utilityProcess
} from 'electron'
@@ -88,6 +89,12 @@ import {
DshNpmExtensionInstaller,
DshNpmMarketplaceCatalog
} from './agent/dsh-extension-marketplace'
import { registerDesktopNotificationActivation } from './desktop-notification'
import {
isInstalledWindowsBuild,
repairStaleWindowsNotificationShortcuts,
resolveWindowsAppUserModelId
} from './windows-notification-identity'
const shortcut = 'CommandOrControl+Shift+Space'
const mainModuleDirectory = dirname(fileURLToPath(import.meta.url))
@@ -99,8 +106,18 @@ const portableUserDataPath = resolvePortableUserDataPath({
if (portableUserDataPath) {
app.setPath('userData', portableUserDataPath)
}
const installedWindowsBuild = isInstalledWindowsBuild({
packaged: app.isPackaged,
platform: process.platform,
executablePath: process.execPath
})
if (process.platform === 'win32') {
app.setAppUserModelId('live.digiman.goodbuddy')
app.setAppUserModelId(
resolveWindowsAppUserModelId({
installed: installedWindowsBuild,
executablePath: process.execPath
})
)
}
const hasSingleInstanceLock = app.requestSingleInstanceLock()
@@ -122,6 +139,7 @@ let globalTlsPolicy: GlobalTlsPolicy | undefined
let documentOcrBroker: DocumentOcrBroker | undefined
let documentOcrModelManager: DocumentOcrModelManager | undefined
let stopRuntimeReconfiguration: (() => Promise<void>) | undefined
let dshExtensionInstaller: DshNpmExtensionInstaller | undefined
function createEmbeddingProvider(
settings: ResolvedRuntimeSettings
@@ -367,6 +385,7 @@ if (hasSingleInstanceLock) {
)
mainWindow = createMainWindow(() => isQuitting)
registerDesktopNotificationActivation(mainWindow)
tray = buildTray()
const defaultWorkspace = process.env.GOODBUDDY_WORKSPACE ?? homedir()
const secureCipher = {
@@ -452,7 +471,7 @@ if (hasSingleInstanceLock) {
app.getPath('userData'),
'deepseek-harness'
)
const dshExtensionInstaller = new DshNpmExtensionInstaller({
const startupDshExtensionInstaller = new DshNpmExtensionInstaller({
dshHome: deepSeekHarnessHome,
npmCliPath: app.isPackaged
? join(
@@ -470,11 +489,13 @@ if (hasSingleInstanceLock) {
'npm-cli.js'
)
})
dshExtensionInstaller = startupDshExtensionInstaller
const runtimeExtensionStore = new RuntimeExtensionStore(
app.getPath('userData'),
{
catalog: new DshNpmMarketplaceCatalog(),
install: (input) => dshExtensionInstaller.install(input)
install: (input) =>
startupDshExtensionInstaller.install(input)
}
)
const launchDeepSeekHarness =
@@ -713,6 +734,48 @@ if (hasSingleInstanceLock) {
runtimeExtensionStore
)
loadMainWindow(mainWindow)
setImmediate(() => {
void repairStaleWindowsNotificationShortcuts({
platform: process.platform,
installed: installedWindowsBuild,
executablePath: process.execPath,
programsDirectory: join(
app.getPath('appData'),
'Microsoft',
'Windows',
'Start Menu',
'Programs'
),
shortcutAccess: {
readShortcutLink: (shortcutPath) =>
shell.readShortcutLink(shortcutPath),
writeShortcutLink: (
shortcutPath,
operation,
options
) =>
shell.writeShortcutLink(
shortcutPath,
operation,
options
)
}
}).then(
({ failed }) => {
if (failed > 0) {
console.warn(
`Failed to repair ${failed} stale notification shortcut(s)`
)
}
},
(error: unknown) => {
console.warn(
'Failed to inspect stale notification shortcuts',
error
)
}
)
})
app.on('activate', () => {
if (mainWindow) {
@@ -744,7 +807,10 @@ app.on('before-quit', (event) => {
void (async () => {
try {
const cleanup = settleCleanupPhases([
[() => removeIpcHandlers?.()],
[
() => dshExtensionInstaller?.dispose(),
() => removeIpcHandlers?.()
],
[() => stopRuntimeReconfiguration?.()],
[
() => runtime?.dispose(),