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
+97
View File
@@ -922,6 +922,103 @@ describe.runIf(enabled)('runtime end-to-end', () => {
180_000
)
it(
'compacts and continues a real bundled OpenCode session',
async () => {
const runtime = new OpenCodeRuntime({
embedded: true,
binaryPath: '',
bundledBinaryPath: join(
portableRoot,
'resources',
'runtimes',
'opencode',
'opencode.exe'
),
configPath: '',
defaultWorkspace: workspace,
modelProfile: {
id: crypto.randomUUID(),
name: 'E2E model',
baseUrl,
modelName,
apiKey,
protocol,
authentication: 'api-key'
}
})
const conversationId = crypto.randomUUID()
const signal = new AbortController().signal
try {
await expect(
collectText(
runtime.run(
{
requestId: crypto.randomUUID(),
conversationId,
workMode: 'ask',
prompt:
'Remember that the verification codename is NATIVE-COMPACT-739. Reply with exactly OPENCODE_COMPACT_READY.'
},
signal
)
)
).resolves.toContain('OPENCODE_COMPACT_READY')
await expect(
runtime.compactConversation(
{
requestId: crypto.randomUUID(),
conversationId,
runtimeSelection: { provider: 'opencode' },
history: [
{
role: 'user',
content:
'The verification codename is NATIVE-COMPACT-739.'
},
{
role: 'assistant',
content: 'OPENCODE_COMPACT_READY'
}
],
historyMessageIds: [
crypto.randomUUID(),
crypto.randomUUID()
]
},
signal
)
).resolves.toMatchObject({
result: {
provider: 'opencode',
strategy: 'native',
compacted: true
}
})
await expect(
collectText(
runtime.run(
{
requestId: crypto.randomUUID(),
conversationId,
workMode: 'ask',
prompt:
'Return exactly the verification codename from before and nothing else.'
},
signal
)
)
).resolves.toContain('NATIVE-COMPACT-739')
} finally {
await runtime.dispose()
}
},
180_000
)
it(
'completes an Execute file task through bundled Continue',
async () => {