From 1315bdaa5438ea79eec1bcb1becaaff832c8efca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=BB=D0=B8=D1=8F?= Date: Sun, 19 Apr 2026 01:53:22 +0300 Subject: [PATCH 1/2] Update image in README.md Replaced demo image with a new image in README. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 709df800..522f3bf9 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,7 @@ Free desktop app for AI agent teams. Auto-detects Claude/Codex. Use the provider access you already have - subscriptions or API keys. Not just coding agents.

-demo - +image From 2c62909e89b8e573f0d1562b63c7d0c64a75b57f Mon Sep 17 00:00:00 2001 From: Artem Rootman <4586640+artemrootman@users.noreply.github.com> Date: Sat, 18 Apr 2026 23:07:45 +0000 Subject: [PATCH 2/2] Handle legacy multimodel MCP diagnostics --- .../runtime/ExtensionsRuntimeAdapter.ts | 62 +++++++++++++++---- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/main/services/extensions/runtime/ExtensionsRuntimeAdapter.ts b/src/main/services/extensions/runtime/ExtensionsRuntimeAdapter.ts index 716236db..46521eeb 100644 --- a/src/main/services/extensions/runtime/ExtensionsRuntimeAdapter.ts +++ b/src/main/services/extensions/runtime/ExtensionsRuntimeAdapter.ts @@ -61,6 +61,8 @@ export class ClaudeExtensionsAdapter implements ExtensionsRuntimeAdapter { export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter { readonly flavor = 'agent_teams_orchestrator' as const; + constructor(private readonly stateReader = new McpConfigStateReader()) {} + async buildManagementCliEnv(binaryPath: string): Promise { return buildManagementCliEnvForBinary(binaryPath); } @@ -72,13 +74,21 @@ export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter { } const env = await this.buildManagementCliEnv(binaryPath); - const { stdout } = await execCli(binaryPath, ['mcp', 'list', '--json'], { - timeout: MCP_LIST_TIMEOUT_MS, - cwd: projectPath, - env, - }); + try { + const { stdout } = await execCli(binaryPath, ['mcp', 'list', '--json'], { + timeout: MCP_LIST_TIMEOUT_MS, + cwd: projectPath, + env, + }); - return parseInstalledMcpJsonOutput(stdout); + return parseInstalledMcpJsonOutput(stdout); + } catch (error) { + if (!isUnsupportedMcpJsonContractError(error)) { + throw error; + } + + return this.stateReader.readInstalled(projectPath); + } } async diagnoseMcp(projectPath?: string): Promise { @@ -88,16 +98,44 @@ export class MultimodelExtensionsAdapter implements ExtensionsRuntimeAdapter { } const env = await this.buildManagementCliEnv(binaryPath); - const { stdout } = await execCli(binaryPath, ['mcp', 'diagnose', '--json'], { - timeout: MCP_DIAGNOSE_TIMEOUT_MS, - cwd: projectPath, - env, - }); + try { + const { stdout } = await execCli(binaryPath, ['mcp', 'diagnose', '--json'], { + timeout: MCP_DIAGNOSE_TIMEOUT_MS, + cwd: projectPath, + env, + }); - return parseMcpDiagnosticsJsonOutput(stdout); + return parseMcpDiagnosticsJsonOutput(stdout); + } catch (error) { + if (!isUnsupportedMcpJsonContractError(error)) { + throw error; + } + + const { stdout, stderr } = await execCli(binaryPath, ['mcp', 'list'], { + timeout: MCP_DIAGNOSE_TIMEOUT_MS, + cwd: projectPath, + env, + }); + + return parseMcpDiagnosticsOutput([stdout, stderr].filter(Boolean).join('\n')); + } } } +function isUnsupportedMcpJsonContractError(error: unknown): boolean { + const message = error instanceof Error ? error.message : String(error); + const normalized = message.toLowerCase(); + + return ( + normalized.includes("unknown command 'diagnose'") || + normalized.includes('unknown command "diagnose"') || + normalized.includes('unknown option') || + normalized.includes('unknown argument') || + normalized.includes('unexpected argument') || + normalized.includes('unrecognized option') + ); +} + class RuntimeSwitchingExtensionsAdapter implements ExtensionsRuntimeAdapter { constructor( private readonly claudeAdapter: ClaudeExtensionsAdapter,