fix: remove redundant confirmation for configuration changes

Configuration apply previously required a separate native confirmation even in Agent Runtime Execute mode, and failed in clients without an approval callback. Use existing work-mode and tool authorization instead, preserving Ask read-only access and request-scoped plan validation. Update regression tests, tool descriptions and documentation.

Validation: 267 focused tests passed; typecheck and changed-file lint passed. Full tests timed out with failures in other modules; repository lint reported errors in unchanged files.

Release note: Execute 模式下通过 Agent Runtime 修改 GoodBuddy 配置不再额外弹出确认框,Ask 模式仍保持只读。
This commit is contained in:
mesalogo
2026-10-02 19:39:44 +08:00
parent dc635d185e
commit 02a6f5c4e7
14 changed files with 152 additions and 247 deletions
@@ -34,7 +34,7 @@ function fixture() {
settingsStore: { getResolvedSettings: async () => settings },
applicationSettingsStore: { get: async () => application },
capabilities: { getRuntimeSkillContext: async () => ({ packages: [{ directory: '/skills/test', id: 'test', digest: 'one' }] }),
getResolvedMcpServers: async () => [{ id: 'custom' }], getEnabledBuiltinMcpServerIds: async () => ['knowledge-base', 'obsidian'],
getResolvedMcpServers: async () => [{ id: 'custom' }], getEnabledBuiltinMcpServerIds: async () => ['knowledge-base', 'obsidian', 'goodbuddy-config'],
getObsidianSettings: async () => ({}) },
executionSpaceResolver: { resolveProject: () => ({ kind: 'local', rootPath: '/workspace', cacheIdentity: '/workspace' }) },
terminalManager: { closeOwner: vi.fn() }, localEnvironment: { launchEnvironmentProvider: () => process.env },
@@ -83,12 +83,22 @@ describe('native client coordinator', () => {
const { coordinator, gateway, start, conversation } = fixture()
await coordinator.open(1, 'conversation')
expect(gateway.grantCustomMcp).not.toHaveBeenCalled()
expect(gateway.grant).toHaveBeenLastCalledWith(
expect.any(String), ['library'], expect.any(AbortSignal), 'none',
{ access: 'read', workspacePath: '/workspace' },
undefined, undefined, undefined, { settings: {}, access: 'read' }, undefined
)
expect(start.mock.calls[0]![0]).toMatchObject({ skillDirectories: ['/skills/test'], mcpServers: [
{ serverName: 'goodbuddy-0', readOnlyTools: ['knowledge_search', 'obsidian_read_note'] }
] })
conversation.workMode = 'execute'
await coordinator.open(1, 'conversation')
expect(gateway.grantCustomMcp).toHaveBeenCalledOnce()
expect(gateway.grant).toHaveBeenLastCalledWith(
expect.any(String), ['library'], expect.any(AbortSignal), 'none',
{ access: 'write', workspacePath: '/workspace' },
undefined, undefined, undefined, { settings: {}, access: 'write' }, undefined
)
expect(start.mock.calls[1]![0].mcpServers).toHaveLength(2)
await coordinator.closeOwner(1)
await expect(coordinator.open(1, 'conversation')).rejects.toThrow('closed')