feat: add native runtime customization
OpenCode and Continue customization was previously planned but unavailable, and Runtime-native capabilities were not represented consistently across providers. GoodBuddy now provides secure Main-owned customization settings, truthful native inventories, OpenCode Agents and Commands, Continue Rules and Prompts, DSH Web Search/Fetch, MCP Prompt and Resource metadata, and manual compaction where supported. Native capabilities are presented in eleven accessible tabs with Tools separated from Commands, LSP, and Formatters. Tool source and Ask/Execute availability are explicit, external OpenCode remains connection-only, Continue reports unsupported static tool discovery instead of advertising unreachable Skills, and disposable inventory probes avoid retaining background runtimes. Ask remains read-only at the Runtime boundary, Execute keeps the existing authorization controls, and credentials remain confined to Main. Release note: 新增 OpenCode、Continue 与 DeepSeek Harness 的 Runtime 原生定制与真实能力清单;工具来源、Ask/Execute 可用性、上下文压缩和 MCP 元数据现在可清晰查看,同时继续保持 Main 进程凭据保护与现有权限边界。
This commit is contained in:
@@ -16,6 +16,29 @@ function runtime() {
|
||||
supportsToolExecution: true,
|
||||
detail: 'ready'
|
||||
}))
|
||||
const getNativeSnapshot = vi.fn(async () => ({
|
||||
provider: 'opencode' as const,
|
||||
available: true,
|
||||
inventoryStatus: 'available' as const,
|
||||
detail: 'ready',
|
||||
agents: [],
|
||||
tools: [],
|
||||
toolsSupported: true,
|
||||
commands: [],
|
||||
lsp: [],
|
||||
formatters: [],
|
||||
mcpServers: [],
|
||||
skills: [],
|
||||
rules: [],
|
||||
prompts: [],
|
||||
resources: [],
|
||||
resourcesSupported: true,
|
||||
context: {
|
||||
strategy: 'native' as const,
|
||||
manualCompact: true,
|
||||
detail: 'ready'
|
||||
}
|
||||
}))
|
||||
const value: AgentRuntime = {
|
||||
runtimeId: 'model',
|
||||
requiresToolApproval: false,
|
||||
@@ -29,6 +52,7 @@ function runtime() {
|
||||
detail: 'ready'
|
||||
})),
|
||||
testConnection,
|
||||
getNativeSnapshot,
|
||||
async *run(
|
||||
request: AgentExecutionRequest
|
||||
): AsyncGenerator<RuntimeEvent, void, void> {
|
||||
@@ -40,7 +64,13 @@ function runtime() {
|
||||
releaseConversation,
|
||||
dispose
|
||||
}
|
||||
return { value, releaseConversation, dispose, testConnection }
|
||||
return {
|
||||
value,
|
||||
releaseConversation,
|
||||
dispose,
|
||||
testConnection,
|
||||
getNativeSnapshot
|
||||
}
|
||||
}
|
||||
|
||||
describe('SelectedRuntimeManager', () => {
|
||||
@@ -153,6 +183,30 @@ describe('SelectedRuntimeManager', () => {
|
||||
await manager.dispose()
|
||||
})
|
||||
|
||||
it('disposes a native-inventory runtime without caching it', async () => {
|
||||
const inspected = runtime()
|
||||
const cached = runtime()
|
||||
const create = vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce(inspected.value)
|
||||
.mockResolvedValueOnce(cached.value)
|
||||
const manager = new SelectedRuntimeManager(create)
|
||||
const selection = { provider: 'opencode' as const }
|
||||
|
||||
await expect(
|
||||
manager.getNativeSnapshot(selection, 'C:\\Projects\\One')
|
||||
).resolves.toMatchObject({
|
||||
provider: 'opencode',
|
||||
inventoryStatus: 'available'
|
||||
})
|
||||
expect(inspected.getNativeSnapshot).toHaveBeenCalledOnce()
|
||||
expect(inspected.dispose).toHaveBeenCalledOnce()
|
||||
|
||||
await manager.getRuntime(selection, 'C:\\Projects\\One')
|
||||
expect(create).toHaveBeenCalledTimes(2)
|
||||
await manager.dispose()
|
||||
})
|
||||
|
||||
it('waits for a pending connection-test runtime during shutdown', async () => {
|
||||
let finishCreate!: (value: AgentRuntime) => void
|
||||
const pendingCreate = new Promise<AgentRuntime>((resolve) => {
|
||||
|
||||
Reference in New Issue
Block a user