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:
@@ -15,6 +15,13 @@ function extension(
|
||||
}
|
||||
}
|
||||
|
||||
function blockEventLoop(durationMs: number): void {
|
||||
const deadline = Date.now() + durationMs
|
||||
while (Date.now() <= deadline) {
|
||||
// Deliberately model finite synchronous CommonJS/plugin startup work.
|
||||
}
|
||||
}
|
||||
|
||||
describe('DeepSeek Harness extension loader', () => {
|
||||
it('loads named Cordis plugin exports and keeps working extensions active', async () => {
|
||||
const ctx = new Context()
|
||||
@@ -157,4 +164,91 @@ describe('DeepSeek Harness extension loader', () => {
|
||||
expect(apply).not.toHaveBeenCalled()
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
it('rejects a synchronous import that returns after its budget', async () => {
|
||||
const ctx = new Context()
|
||||
const apply = vi.fn()
|
||||
|
||||
const result = await loadControlledHarnessExtensions(
|
||||
ctx,
|
||||
[extension('slow-import')],
|
||||
{
|
||||
activationTimeoutMs: 10,
|
||||
importModule: async () => {
|
||||
blockEventLoop(25)
|
||||
return { apply }
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
expect(result).toEqual({
|
||||
loadedIds: [],
|
||||
failedIds: ['slow-import'],
|
||||
failures: [
|
||||
{
|
||||
id: 'slow-import',
|
||||
message:
|
||||
'DeepSeek Harness extension activation timed out'
|
||||
}
|
||||
]
|
||||
})
|
||||
expect(apply).not.toHaveBeenCalled()
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
it('rejects over-budget synchronous apply and loads the next extension', async () => {
|
||||
const ctx = new Context()
|
||||
const laterApply = vi.fn()
|
||||
|
||||
const result = await loadControlledHarnessExtensions(
|
||||
ctx,
|
||||
[extension('slow-apply'), extension('later')],
|
||||
{
|
||||
activationTimeoutMs: 10,
|
||||
totalActivationTimeoutMs: 100,
|
||||
importModule: async (url) =>
|
||||
url.includes('slow-apply')
|
||||
? {
|
||||
apply() {
|
||||
blockEventLoop(25)
|
||||
}
|
||||
}
|
||||
: { apply: laterApply }
|
||||
}
|
||||
)
|
||||
|
||||
expect(result.loadedIds).toEqual(['later'])
|
||||
expect(result.failedIds).toEqual(['slow-apply'])
|
||||
expect(result.failures[0]?.message).toBe(
|
||||
'DeepSeek Harness extension activation timed out'
|
||||
)
|
||||
expect(laterApply).toHaveBeenCalledOnce()
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
it('times out asynchronous activation and disposes its effects', async () => {
|
||||
const ctx = new Context()
|
||||
const cleanup = vi.fn()
|
||||
|
||||
const result = await loadControlledHarnessExtensions(
|
||||
ctx,
|
||||
[extension('async-slow')],
|
||||
{
|
||||
activationTimeoutMs: 10,
|
||||
importModule: async () => ({
|
||||
apply(pluginContext: Context) {
|
||||
pluginContext.effect(() => cleanup)
|
||||
return new Promise<void>((resolve) =>
|
||||
setTimeout(resolve, 30)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
expect(result.failedIds).toEqual(['async-slow'])
|
||||
expect(result.failures[0]?.message).toContain('timed out')
|
||||
expect(cleanup).toHaveBeenCalledOnce()
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user