diff --git a/arduino-ide-extension/package.json b/arduino-ide-extension/package.json
index 7257b9883..8963b4f5a 100644
--- a/arduino-ide-extension/package.json
+++ b/arduino-ide-extension/package.json
@@ -72,6 +72,7 @@
     "fast-json-stable-stringify": "^2.1.0",
     "fast-safe-stringify": "^2.1.1",
     "filename-reserved-regex": "^2.0.0",
+    "fqbn": "^1.0.5",
     "glob": "^7.1.6",
     "google-protobuf": "^3.20.1",
     "hash.js": "^1.1.7",
@@ -169,13 +170,17 @@
   ],
   "arduino": {
     "arduino-cli": {
-      "version": "0.35.3"
+      "version": "0.36.0-rc.1"
     },
     "arduino-fwuploader": {
       "version": "2.4.1"
     },
     "arduino-language-server": {
-      "version": "0.7.6"
+      "version": {
+        "owner": "arduino",
+        "repo": "arduino-language-server",
+        "commitish": "91c2ba8"
+      }
     },
     "clangd": {
       "version": "14.0.0"
diff --git a/arduino-ide-extension/scripts/generate-protocol.js b/arduino-ide-extension/scripts/generate-protocol.js
index ec15850b3..703407a4f 100644
--- a/arduino-ide-extension/scripts/generate-protocol.js
+++ b/arduino-ide-extension/scripts/generate-protocol.js
@@ -3,7 +3,7 @@
 (async () => {
   const os = require('node:os');
   const path = require('node:path');
-  const { mkdirSync, promises: fs } = require('node:fs');
+  const { mkdirSync, promises: fs, rmSync } = require('node:fs');
   const { exec } = require('./utils');
   const glob = require('glob');
   const { SemVer, gte, valid: validSemVer } = require('semver');
@@ -140,6 +140,10 @@
 
   const rpc = path.join(repository, 'rpc');
   const out = path.join(__dirname, '..', 'src', 'node', 'cli-protocol');
+  // Must wipe the gen output folder. Otherwise, dangling service implementation remain in IDE2 code,
+  // although it has been removed from the proto file.
+  // For example, https://github.com/arduino/arduino-cli/commit/50a8bf5c3e61d5b661ccfcd6a055e82eeb510859.
+  rmSync(out, { recursive: true, maxRetries: 5, force: true });
   mkdirSync(out, { recursive: true });
 
   const protos = await new Promise((resolve) =>
diff --git a/arduino-ide-extension/src/browser/boards/boards-data-store.ts b/arduino-ide-extension/src/browser/boards/boards-data-store.ts
index e78f5b74b..1c23fb38f 100644
--- a/arduino-ide-extension/src/browser/boards/boards-data-store.ts
+++ b/arduino-ide-extension/src/browser/boards/boards-data-store.ts
@@ -12,6 +12,7 @@ import { ILogger } from '@theia/core/lib/common/logger';
 import { deepClone, deepFreeze } from '@theia/core/lib/common/objects';
 import type { Mutable } from '@theia/core/lib/common/types';
 import { inject, injectable, named } from '@theia/core/shared/inversify';
+import { FQBN } from 'fqbn';
 import {
   BoardDetails,
   BoardsService,
@@ -20,6 +21,7 @@ import {
   Programmer,
   isBoardIdentifierChangeEvent,
   isProgrammer,
+  sanitizeFqbn,
 } from '../../common/protocol';
 import { notEmpty } from '../../common/utils';
 import type {
@@ -29,6 +31,14 @@ import type {
 import { NotificationCenter } from '../notification-center';
 import { BoardsServiceProvider } from './boards-service-provider';
 
+export interface SelectConfigOptionParams {
+  readonly fqbn: string;
+  readonly optionsToUpdate: readonly Readonly<{
+    option: string;
+    selectedValue: string;
+  }>[];
+}
+
 @injectable()
 export class BoardsDataStore
   implements
@@ -64,7 +74,12 @@ export class BoardsDataStore
     this.toDispose.pushAll([
       this.boardsServiceProvider.onBoardsConfigDidChange((event) => {
         if (isBoardIdentifierChangeEvent(event)) {
-          this.updateSelectedBoardData(event.selectedBoard?.fqbn);
+          this.updateSelectedBoardData(
+            event.selectedBoard?.fqbn,
+            // If the change event comes from toolbar and the FQBN contains custom board options, change the currently selected options
+            // https://github.com/arduino/arduino-ide/issues/1588
+            event.reason === 'toolbar'
+          );
         }
       }),
       this.notificationCenter.onPlatformDidInstall(async ({ item }) => {
@@ -116,7 +131,7 @@ export class BoardsDataStore
     if (!fqbn) {
       return undefined;
     } else {
-      const data = await this.getData(fqbn);
+      const data = await this.getData(sanitizeFqbn(fqbn));
       if (data === BoardsDataStore.Data.EMPTY) {
         return undefined;
       }
@@ -125,9 +140,22 @@ export class BoardsDataStore
   }
 
   private async updateSelectedBoardData(
-    fqbn: string | undefined
+    fqbn: string | undefined,
+    updateConfigOptions = false
   ): Promise<void> {
     this._selectedBoardData = await this.getSelectedBoardData(fqbn);
+    if (fqbn && updateConfigOptions) {
+      const { options } = new FQBN(fqbn);
+      if (options) {
+        const optionsToUpdate = Object.entries(options).map(([key, value]) => ({
+          option: key,
+          selectedValue: value,
+        }));
+        const params = { fqbn, optionsToUpdate };
+        await this.selectConfigOption(params);
+        this._selectedBoardData = await this.getSelectedBoardData(fqbn); // reload the updated data
+      }
+    }
   }
 
   onStop(): void {
@@ -168,7 +196,7 @@ export class BoardsDataStore
       return undefined;
     }
     const { configOptions } = await this.getData(fqbn);
-    return ConfigOption.decorate(fqbn, configOptions);
+    return new FQBN(fqbn).withConfigOptions(...configOptions).toString();
   }
 
   async getData(fqbn: string | undefined): Promise<BoardsDataStore.Data> {
@@ -201,48 +229,63 @@ export class BoardsDataStore
     fqbn: string;
     selectedProgrammer: Programmer;
   }): Promise<boolean> {
-    const storedData = deepClone(await this.getData(fqbn));
+    const sanitizedFQBN = sanitizeFqbn(fqbn);
+    const storedData = deepClone(await this.getData(sanitizedFQBN));
     const { programmers } = storedData;
     if (!programmers.find((p) => Programmer.equals(selectedProgrammer, p))) {
       return false;
     }
 
-    const data = { ...storedData, selectedProgrammer };
-    await this.setData({ fqbn, data });
-    this.fireChanged({ fqbn, data });
+    const change: BoardsDataStoreChange = {
+      fqbn: sanitizedFQBN,
+      data: { ...storedData, selectedProgrammer },
+    };
+    await this.setData(change);
+    this.fireChanged(change);
     return true;
   }
 
-  async selectConfigOption({
-    fqbn,
-    option,
-    selectedValue,
-  }: {
-    fqbn: string;
-    option: string;
-    selectedValue: string;
-  }): Promise<boolean> {
-    const data = deepClone(await this.getData(fqbn));
-    const { configOptions } = data;
-    const configOption = configOptions.find((c) => c.option === option);
-    if (!configOption) {
+  async selectConfigOption(params: SelectConfigOptionParams): Promise<boolean> {
+    const { fqbn, optionsToUpdate } = params;
+    if (!optionsToUpdate.length) {
       return false;
     }
-    let updated = false;
-    for (const value of configOption.values) {
-      const mutable: Mutable<ConfigValue> = value;
-      if (mutable.value === selectedValue) {
-        mutable.selected = true;
-        updated = true;
-      } else {
-        mutable.selected = false;
+
+    const sanitizedFQBN = sanitizeFqbn(fqbn);
+    const mutableData = deepClone(await this.getData(sanitizedFQBN));
+    let didChange = false;
+
+    for (const { option, selectedValue } of optionsToUpdate) {
+      const { configOptions } = mutableData;
+      const configOption = configOptions.find((c) => c.option === option);
+      if (configOption) {
+        const configOptionValueIndex = configOption.values.findIndex(
+          (configOptionValue) => configOptionValue.value === selectedValue
+        );
+        if (configOptionValueIndex >= 0) {
+          // unselect all
+          configOption.values
+            .map((value) => value as Mutable<ConfigValue>)
+            .forEach((value) => (value.selected = false));
+          const mutableConfigValue: Mutable<ConfigValue> =
+            configOption.values[configOptionValueIndex];
+          // make the new value `selected`
+          mutableConfigValue.selected = true;
+          didChange = true;
+        }
       }
     }
-    if (!updated) {
+
+    if (!didChange) {
       return false;
     }
-    await this.setData({ fqbn, data });
-    this.fireChanged({ fqbn, data });
+
+    const change: BoardsDataStoreChange = {
+      fqbn: sanitizedFQBN,
+      data: mutableData,
+    };
+    await this.setData(change);
+    this.fireChanged(change);
     return true;
   }
 
diff --git a/arduino-ide-extension/src/browser/boards/boards-service-provider.ts b/arduino-ide-extension/src/browser/boards/boards-service-provider.ts
index f1182adbf..29bccb242 100644
--- a/arduino-ide-extension/src/browser/boards/boards-service-provider.ts
+++ b/arduino-ide-extension/src/browser/boards/boards-service-provider.ts
@@ -12,6 +12,7 @@ import { Emitter } from '@theia/core/lib/common/event';
 import { ILogger } from '@theia/core/lib/common/logger';
 import { MessageService } from '@theia/core/lib/common/message-service';
 import { nls } from '@theia/core/lib/common/nls';
+import { deepClone } from '@theia/core/lib/common/objects';
 import { Deferred } from '@theia/core/lib/common/promise-util';
 import type { Mutable } from '@theia/core/lib/common/types';
 import { inject, injectable, optional } from '@theia/core/shared/inversify';
@@ -21,31 +22,32 @@ import {
 } from '@theia/output/lib/browser/output-channel';
 import {
   BoardIdentifier,
-  boardIdentifierEquals,
+  BoardUserField,
+  BoardWithPackage,
   BoardsConfig,
   BoardsConfigChangeEvent,
   BoardsPackage,
   BoardsService,
-  BoardUserField,
-  BoardWithPackage,
   DetectedPorts,
+  Port,
+  PortIdentifier,
+  boardIdentifierEquals,
   emptyBoardsConfig,
   isBoardIdentifier,
   isBoardIdentifierChangeEvent,
   isPortIdentifier,
   isPortIdentifierChangeEvent,
-  Port,
-  PortIdentifier,
   portIdentifierEquals,
+  sanitizeFqbn,
   serializePlatformIdentifier,
 } from '../../common/protocol';
 import {
   BoardList,
   BoardListHistory,
-  createBoardList,
   EditBoardsConfigActionParams,
-  isBoardListHistory,
   SelectBoardsConfigActionParams,
+  createBoardList,
+  isBoardListHistory,
 } from '../../common/protocol/board-list';
 import type { Defined } from '../../common/types';
 import type {
@@ -104,6 +106,21 @@ type BoardListHistoryUpdateResult =
 type BoardToSelect = BoardIdentifier | undefined | 'ignore-board';
 type PortToSelect = PortIdentifier | undefined | 'ignore-port';
 
+function sanitizeBoardToSelectFQBN(board: BoardToSelect): BoardToSelect {
+  if (isBoardIdentifier(board)) {
+    return sanitizeBoardIdentifierFQBN(board);
+  }
+  return board;
+}
+function sanitizeBoardIdentifierFQBN(board: BoardIdentifier): BoardIdentifier {
+  if (board.fqbn) {
+    const copy: Mutable<BoardIdentifier> = deepClone(board);
+    copy.fqbn = sanitizeFqbn(board.fqbn);
+    return copy;
+  }
+  return board;
+}
+
 interface UpdateBoardListHistoryParams {
   readonly portToSelect: PortToSelect;
   readonly boardToSelect: BoardToSelect;
@@ -136,6 +153,9 @@ export interface BoardListUIActions {
 }
 export type BoardListUI = BoardList & BoardListUIActions;
 
+export type BoardsConfigChangeEventUI = BoardsConfigChangeEvent &
+  Readonly<{ reason?: UpdateBoardsConfigReason }>;
+
 @injectable()
 export class BoardListDumper implements Disposable {
   @inject(OutputChannelManager)
@@ -190,7 +210,7 @@ export class BoardsServiceProvider
   private _ready = new Deferred<void>();
 
   private readonly boardsConfigDidChangeEmitter =
-    new Emitter<BoardsConfigChangeEvent>();
+    new Emitter<BoardsConfigChangeEventUI>();
   readonly onBoardsConfigDidChange = this.boardsConfigDidChangeEmitter.event;
 
   private readonly boardListDidChangeEmitter = new Emitter<BoardListUI>();
@@ -353,7 +373,8 @@ export class BoardsServiceProvider
       portToSelect !== 'ignore-port' &&
       !portIdentifierEquals(portToSelect, previousSelectedPort);
     const boardDidChangeEvent = boardDidChange
-      ? { selectedBoard: boardToSelect, previousSelectedBoard }
+      ? // The change event must always contain any custom board options. Hence the board to select is not sanitized.
+        { selectedBoard: boardToSelect, previousSelectedBoard }
       : undefined;
     const portDidChangeEvent = portDidChange
       ? { selectedPort: portToSelect, previousSelectedPort }
@@ -374,16 +395,31 @@ export class BoardsServiceProvider
       return false;
     }
 
-    this.maybeUpdateBoardListHistory({ portToSelect, boardToSelect });
-    this.maybeUpdateBoardsData({ boardToSelect, reason });
+    // unlike for the board change event, every persistent state must not contain custom board config options in the FQBN
+    const sanitizedBoardToSelect = sanitizeBoardToSelectFQBN(boardToSelect);
+
+    this.maybeUpdateBoardListHistory({
+      portToSelect,
+      boardToSelect: sanitizedBoardToSelect,
+    });
+    this.maybeUpdateBoardsData({
+      boardToSelect: sanitizedBoardToSelect,
+      reason,
+    });
 
     if (isBoardIdentifierChangeEvent(event)) {
-      this._boardsConfig.selectedBoard = event.selectedBoard;
+      this._boardsConfig.selectedBoard = event.selectedBoard
+        ? sanitizeBoardIdentifierFQBN(event.selectedBoard)
+        : event.selectedBoard;
     }
     if (isPortIdentifierChangeEvent(event)) {
       this._boardsConfig.selectedPort = event.selectedPort;
     }
 
+    if (reason) {
+      event = Object.assign(event, { reason });
+    }
+
     this.boardsConfigDidChangeEmitter.fire(event);
     this.refreshBoardList();
     this.saveState();
diff --git a/arduino-ide-extension/src/browser/contributions/boards-data-menu-updater.ts b/arduino-ide-extension/src/browser/contributions/boards-data-menu-updater.ts
index ea085f5ba..382e0f2ef 100644
--- a/arduino-ide-extension/src/browser/contributions/boards-data-menu-updater.ts
+++ b/arduino-ide-extension/src/browser/contributions/boards-data-menu-updater.ts
@@ -87,8 +87,7 @@ export class BoardsDataMenuUpdater extends Contribution {
                   execute: () =>
                     this.boardsDataStore.selectConfigOption({
                       fqbn,
-                      option,
-                      selectedValue: value.value,
+                      optionsToUpdate: [{ option, selectedValue: value.value }],
                     }),
                   isToggled: () => value.selected,
                 };
diff --git a/arduino-ide-extension/src/browser/contributions/burn-bootloader.ts b/arduino-ide-extension/src/browser/contributions/burn-bootloader.ts
index 2ad150784..e951ac2f9 100644
--- a/arduino-ide-extension/src/browser/contributions/burn-bootloader.ts
+++ b/arduino-ide-extension/src/browser/contributions/burn-bootloader.ts
@@ -37,11 +37,15 @@ export class BurnBootloader extends CoreServiceContribution {
           'arduino/bootloader/burningBootloader',
           'Burning bootloader...'
         ),
-        task: (progressId, coreService) =>
-          coreService.burnBootloader({
-            ...options,
-            progressId,
-          }),
+        task: (progressId, coreService, token) =>
+          coreService.burnBootloader(
+            {
+              ...options,
+              progressId,
+            },
+            token
+          ),
+        cancelable: true,
       });
       this.messageService.info(
         nls.localize(
diff --git a/arduino-ide-extension/src/browser/contributions/contribution.ts b/arduino-ide-extension/src/browser/contributions/contribution.ts
index 8de4d8ff4..1a8ff5798 100644
--- a/arduino-ide-extension/src/browser/contributions/contribution.ts
+++ b/arduino-ide-extension/src/browser/contributions/contribution.ts
@@ -1,83 +1,89 @@
+import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
 import {
-  inject,
-  injectable,
-  interfaces,
-  postConstruct,
-} from '@theia/core/shared/inversify';
-import URI from '@theia/core/lib/common/uri';
-import { ILogger } from '@theia/core/lib/common/logger';
-import {
-  Disposable,
-  DisposableCollection,
-} from '@theia/core/lib/common/disposable';
-import { Saveable } from '@theia/core/lib/browser/saveable';
-import { FileService } from '@theia/filesystem/lib/browser/file-service';
-import { MaybePromise } from '@theia/core/lib/common/types';
-import { LabelProvider } from '@theia/core/lib/browser/label-provider';
-import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
-import { MessageService } from '@theia/core/lib/common/message-service';
-import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
-import { open, OpenerService } from '@theia/core/lib/browser/opener-service';
-import {
-  MenuModelRegistry,
-  MenuContribution,
-} from '@theia/core/lib/common/menu';
+  FrontendApplication,
+  FrontendApplicationContribution,
+} from '@theia/core/lib/browser/frontend-application';
+import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
 import {
-  KeybindingRegistry,
   KeybindingContribution,
+  KeybindingRegistry,
 } from '@theia/core/lib/browser/keybinding';
+import { LabelProvider } from '@theia/core/lib/browser/label-provider';
+import { OpenerService, open } from '@theia/core/lib/browser/opener-service';
+import { Saveable } from '@theia/core/lib/browser/saveable';
+import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
 import {
   TabBarToolbarContribution,
   TabBarToolbarRegistry,
 } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
-import {
-  FrontendApplicationContribution,
-  FrontendApplication,
-} from '@theia/core/lib/browser/frontend-application';
+import { CancellationToken } from '@theia/core/lib/common/cancellation';
 import {
   Command,
-  CommandRegistry,
   CommandContribution,
+  CommandRegistry,
   CommandService,
 } from '@theia/core/lib/common/command';
-import { SettingsService } from '../dialogs/settings/settings';
 import {
-  CurrentSketch,
-  SketchesServiceClientImpl,
-} from '../sketches-service-client-impl';
+  Disposable,
+  DisposableCollection,
+} from '@theia/core/lib/common/disposable';
+import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
+import { ILogger } from '@theia/core/lib/common/logger';
+import {
+  MenuContribution,
+  MenuModelRegistry,
+} from '@theia/core/lib/common/menu';
+import { MessageService } from '@theia/core/lib/common/message-service';
+import { MessageType } from '@theia/core/lib/common/message-service-protocol';
+import { nls } from '@theia/core/lib/common/nls';
+import { MaybePromise, isObject } from '@theia/core/lib/common/types';
+import URI from '@theia/core/lib/common/uri';
+import {
+  inject,
+  injectable,
+  interfaces,
+  postConstruct,
+} from '@theia/core/shared/inversify';
+import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
+import { FileService } from '@theia/filesystem/lib/browser/file-service';
+import { NotificationManager } from '@theia/messages/lib/browser/notifications-manager';
+import { OutputChannelSeverity } from '@theia/output/lib/browser/output-channel';
+import { MainMenuManager } from '../../common/main-menu-manager';
+import { userAbort } from '../../common/nls';
 import {
-  SketchesService,
-  FileSystemExt,
-  Sketch,
-  CoreService,
   CoreError,
+  CoreService,
+  FileSystemExt,
   ResponseServiceClient,
+  Sketch,
+  SketchesService,
 } from '../../common/protocol';
+import {
+  ExecuteWithProgress,
+  UserAbortApplicationError,
+} from '../../common/protocol/progressible';
 import { ArduinoPreferences } from '../arduino-preferences';
-import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
-import { nls } from '@theia/core';
-import { OutputChannelManager } from '../theia/output/output-channel';
-import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
-import { ExecuteWithProgress } from '../../common/protocol/progressible';
-import { BoardsServiceProvider } from '../boards/boards-service-provider';
 import { BoardsDataStore } from '../boards/boards-data-store';
-import { NotificationManager } from '@theia/messages/lib/browser/notifications-manager';
-import { MessageType } from '@theia/core/lib/common/message-service-protocol';
-import { WorkspaceService } from '../theia/workspace/workspace-service';
-import { MainMenuManager } from '../../common/main-menu-manager';
+import { BoardsServiceProvider } from '../boards/boards-service-provider';
 import { ConfigServiceClient } from '../config/config-service-client';
-import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
 import { DialogService } from '../dialog-service';
+import { SettingsService } from '../dialogs/settings/settings';
+import {
+  CurrentSketch,
+  SketchesServiceClientImpl,
+} from '../sketches-service-client-impl';
 import { ApplicationConnectionStatusContribution } from '../theia/core/connection-status-service';
+import { OutputChannelManager } from '../theia/output/output-channel';
+import { WorkspaceService } from '../theia/workspace/workspace-service';
 
 export {
   Command,
   CommandRegistry,
-  MenuModelRegistry,
   KeybindingRegistry,
+  MenuModelRegistry,
+  Sketch,
   TabBarToolbarRegistry,
   URI,
-  Sketch,
   open,
 };
 
@@ -247,6 +253,12 @@ export abstract class CoreServiceContribution extends SketchContribution {
   }
 
   protected handleError(error: unknown): void {
+    if (isObject(error) && UserAbortApplicationError.is(error)) {
+      this.outputChannelManager
+        .getChannel('Arduino')
+        .appendLine(userAbort, OutputChannelSeverity.Warning);
+      return;
+    }
     this.tryToastErrorMessage(error);
   }
 
@@ -293,7 +305,13 @@ export abstract class CoreServiceContribution extends SketchContribution {
   protected async doWithProgress<T>(options: {
     progressText: string;
     keepOutput?: boolean;
-    task: (progressId: string, coreService: CoreService) => Promise<T>;
+    task: (
+      progressId: string,
+      coreService: CoreService,
+      cancellationToken?: CancellationToken
+    ) => Promise<T>;
+    // false by default
+    cancelable?: boolean;
   }): Promise<T> {
     const toDisposeOnComplete = new DisposableCollection(
       this.maybeActivateMonitorWidget()
@@ -306,8 +324,10 @@ export abstract class CoreServiceContribution extends SketchContribution {
       messageService: this.messageService,
       responseService: this.responseService,
       progressText,
-      run: ({ progressId }) => task(progressId, this.coreService),
+      run: ({ progressId, cancellationToken }) =>
+        task(progressId, this.coreService, cancellationToken),
       keepOutput,
+      cancelable: options.cancelable,
     });
     toDisposeOnComplete.dispose();
     return result;
diff --git a/arduino-ide-extension/src/browser/contributions/ino-language.ts b/arduino-ide-extension/src/browser/contributions/ino-language.ts
index ab54c7ae4..4f336ef3d 100644
--- a/arduino-ide-extension/src/browser/contributions/ino-language.ts
+++ b/arduino-ide-extension/src/browser/contributions/ino-language.ts
@@ -9,7 +9,6 @@ import {
   BoardIdentifier,
   BoardsService,
   ExecutableService,
-  assertSanitizedFqbn,
   isBoardIdentifierChangeEvent,
   sanitizeFqbn,
 } from '../../common/protocol';
@@ -159,14 +158,11 @@ export class InoLanguage extends SketchContribution {
       this.notificationCenter.onDidReinitialize(() => forceRestart()),
       this.boardDataStore.onDidChange((event) => {
         if (this.languageServerFqbn) {
-          const sanitizedFqbn = sanitizeFqbn(this.languageServerFqbn);
-          if (!sanitizeFqbn) {
-            throw new Error(
-              `Failed to sanitize the FQBN of the running language server. FQBN with the board settings was: ${this.languageServerFqbn}`
-            );
-          }
+          const sanitizedFQBN = sanitizeFqbn(this.languageServerFqbn);
+          // The incoming FQBNs might contain custom boards configs, sanitize them before the comparison.
+          // https://github.com/arduino/arduino-ide/pull/2113#pullrequestreview-1499998328
           const matchingChange = event.changes.find(
-            (change) => change.fqbn === sanitizedFqbn
+            (change) => sanitizedFQBN === sanitizeFqbn(change.fqbn)
           );
           const { boardsConfig } = this.boardsServiceProvider;
           if (
@@ -196,11 +192,7 @@ export class InoLanguage extends SketchContribution {
     forceStart = false
   ): Promise<void> {
     const port = await this.daemon.tryGetPort();
-    if (!port) {
-      return;
-    }
-    const portNumber = Number.parseInt(port, 10); // TODO: IDE2 APIs should provide a number and not string
-    if (Number.isNaN(portNumber)) {
+    if (typeof port !== 'number') {
       return;
     }
     const release = await this.languageServerStartMutex.acquire();
@@ -232,7 +224,6 @@ export class InoLanguage extends SketchContribution {
         }
         return;
       }
-      assertSanitizedFqbn(fqbn);
       const fqbnWithConfig = await this.boardDataStore.appendConfigToFqbn(fqbn);
       if (!fqbnWithConfig) {
         throw new Error(
@@ -280,7 +271,7 @@ export class InoLanguage extends SketchContribution {
           lsPath,
           daemonAddress: {
             hostname: 'localhost',
-            port: portNumber,
+            port,
             instance: 1, // TODO: get it from the backend
           },
           clangdPath,
diff --git a/arduino-ide-extension/src/browser/contributions/upload-sketch.ts b/arduino-ide-extension/src/browser/contributions/upload-sketch.ts
index 75c591dba..9cee46abb 100644
--- a/arduino-ide-extension/src/browser/contributions/upload-sketch.ts
+++ b/arduino-ide-extension/src/browser/contributions/upload-sketch.ts
@@ -1,7 +1,8 @@
 import { Emitter } from '@theia/core/lib/common/event';
 import { nls } from '@theia/core/lib/common/nls';
 import { inject, injectable } from '@theia/core/shared/inversify';
-import { CoreService, sanitizeFqbn } from '../../common/protocol';
+import { FQBN } from 'fqbn';
+import { CoreService } from '../../common/protocol';
 import { ArduinoMenus } from '../menu/arduino-menus';
 import { CurrentSketch } from '../sketches-service-client-impl';
 import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
@@ -136,9 +137,10 @@ export class UploadSketch extends CoreServiceContribution {
 
       const uploadResponse = await this.doWithProgress({
         progressText: nls.localize('arduino/sketch/uploading', 'Uploading...'),
-        task: (progressId, coreService) =>
-          coreService.upload({ ...uploadOptions, progressId }),
+        task: (progressId, coreService, token) =>
+          coreService.upload({ ...uploadOptions, progressId }, token),
         keepOutput: true,
+        cancelable: true,
       });
       // the port update is NOOP if nothing has changed
       this.boardsServiceProvider.updateConfig(uploadResponse.portAfterUpload);
@@ -172,7 +174,11 @@ export class UploadSketch extends CoreServiceContribution {
     const [fqbn, { selectedProgrammer: programmer }, verify, verbose] =
       await Promise.all([
         verifyOptions.fqbn, // already decorated FQBN
-        this.boardsDataStore.getData(sanitizeFqbn(verifyOptions.fqbn)),
+        this.boardsDataStore.getData(
+          verifyOptions.fqbn
+            ? new FQBN(verifyOptions.fqbn).toString(true)
+            : undefined
+        ),
         this.preferences.get('arduino.upload.verify'),
         this.preferences.get('arduino.upload.verbose'),
       ]);
diff --git a/arduino-ide-extension/src/browser/contributions/verify-sketch.ts b/arduino-ide-extension/src/browser/contributions/verify-sketch.ts
index bd6b60ff8..999c3ec5c 100644
--- a/arduino-ide-extension/src/browser/contributions/verify-sketch.ts
+++ b/arduino-ide-extension/src/browser/contributions/verify-sketch.ts
@@ -1,18 +1,18 @@
-import { inject, injectable } from '@theia/core/shared/inversify';
 import { Emitter } from '@theia/core/lib/common/event';
+import { nls } from '@theia/core/lib/common/nls';
+import { inject, injectable } from '@theia/core/shared/inversify';
+import type { CoreService } from '../../common/protocol';
 import { ArduinoMenus } from '../menu/arduino-menus';
+import { CurrentSketch } from '../sketches-service-client-impl';
 import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
 import {
-  CoreServiceContribution,
   Command,
   CommandRegistry,
-  MenuModelRegistry,
+  CoreServiceContribution,
   KeybindingRegistry,
+  MenuModelRegistry,
   TabBarToolbarRegistry,
 } from './contribution';
-import { nls } from '@theia/core/lib/common';
-import { CurrentSketch } from '../sketches-service-client-impl';
-import { CoreService } from '../../common/protocol';
 import { CoreErrorHandler } from './core-error-handler';
 
 export interface VerifySketchParams {
@@ -131,11 +131,15 @@ export class VerifySketch extends CoreServiceContribution {
           'arduino/sketch/compile',
           'Compiling sketch...'
         ),
-        task: (progressId, coreService) =>
-          coreService.compile({
-            ...options,
-            progressId,
-          }),
+        task: (progressId, coreService, token) =>
+          coreService.compile(
+            {
+              ...options,
+              progressId,
+            },
+            token
+          ),
+        cancelable: true,
       });
       this.messageService.info(
         nls.localize('arduino/sketch/doneCompiling', 'Done compiling.'),
diff --git a/arduino-ide-extension/src/browser/library/library-list-widget.ts b/arduino-ide-extension/src/browser/library/library-list-widget.ts
index 690799923..660bcec06 100644
--- a/arduino-ide-extension/src/browser/library/library-list-widget.ts
+++ b/arduino-ide-extension/src/browser/library/library-list-widget.ts
@@ -12,15 +12,13 @@ import {
   LibrarySearch,
   LibraryService,
 } from '../../common/protocol/library-service';
-import {
-  ListWidget,
-  UserAbortError,
-} from '../widgets/component-list/list-widget';
+import { ListWidget } from '../widgets/component-list/list-widget';
 import { Installable } from '../../common/protocol';
 import { ListItemRenderer } from '../widgets/component-list/list-item-renderer';
 import { nls } from '@theia/core/lib/common';
 import { LibraryFilterRenderer } from '../widgets/component-list/filter-renderer';
 import { findChildTheiaButton, splitByBoldTag } from '../utils/dom';
+import { UserAbortError } from '../../common/protocol/progressible';
 
 @injectable()
 export class LibraryListWidget extends ListWidget<
diff --git a/arduino-ide-extension/src/browser/notification-center.ts b/arduino-ide-extension/src/browser/notification-center.ts
index e7d5c6676..9bb0e2ae4 100644
--- a/arduino-ide-extension/src/browser/notification-center.ts
+++ b/arduino-ide-extension/src/browser/notification-center.ts
@@ -46,7 +46,7 @@ export class NotificationCenter
     new Emitter<ProgressMessage>();
   private readonly indexUpdateDidFailEmitter =
     new Emitter<IndexUpdateDidFailParams>();
-  private readonly daemonDidStartEmitter = new Emitter<string>();
+  private readonly daemonDidStartEmitter = new Emitter<number>();
   private readonly daemonDidStopEmitter = new Emitter<void>();
   private readonly configDidChangeEmitter = new Emitter<ConfigState>();
   private readonly platformDidInstallEmitter = new Emitter<{
@@ -136,7 +136,7 @@ export class NotificationCenter
     this.indexUpdateDidFailEmitter.fire(params);
   }
 
-  notifyDaemonDidStart(port: string): void {
+  notifyDaemonDidStart(port: number): void {
     this.daemonDidStartEmitter.fire(port);
   }
 
diff --git a/arduino-ide-extension/src/browser/theia/core/connection-status-service.ts b/arduino-ide-extension/src/browser/theia/core/connection-status-service.ts
index 413e50645..f876f7c0a 100644
--- a/arduino-ide-extension/src/browser/theia/core/connection-status-service.ts
+++ b/arduino-ide-extension/src/browser/theia/core/connection-status-service.ts
@@ -74,8 +74,8 @@ export class DaemonPort implements FrontendApplicationContribution {
   @inject(NotificationCenter)
   private readonly notificationCenter: NotificationCenter;
 
-  private readonly onPortDidChangeEmitter = new Emitter<string | undefined>();
-  private _port: string | undefined;
+  private readonly onPortDidChangeEmitter = new Emitter<number | undefined>();
+  private _port: number | undefined;
 
   onStart(): void {
     this.daemon.tryGetPort().then(
@@ -91,15 +91,15 @@ export class DaemonPort implements FrontendApplicationContribution {
     this.onPortDidChangeEmitter.dispose();
   }
 
-  get port(): string | undefined {
+  get port(): number | undefined {
     return this._port;
   }
 
-  get onDidChangePort(): Event<string | undefined> {
+  get onDidChangePort(): Event<number | undefined> {
     return this.onPortDidChangeEmitter.event;
   }
 
-  private setPort(port: string | undefined): void {
+  private setPort(port: number | undefined): void {
     const oldPort = this._port;
     this._port = port;
     if (this._port !== oldPort) {
diff --git a/arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx b/arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx
index 1e13b1417..d5e320ee1 100644
--- a/arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx
+++ b/arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx
@@ -2,7 +2,7 @@ import React from '@theia/core/shared/react';
 import type { ArduinoComponent } from '../../../common/protocol/arduino-component';
 import { Installable } from '../../../common/protocol/installable';
 import type { ListItemRenderer } from './list-item-renderer';
-import { UserAbortError } from './list-widget';
+import { UserAbortError } from '../../../common/protocol/progressible';
 
 export class ComponentListItem<
   T extends ArduinoComponent
diff --git a/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx b/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx
index 0039d76d1..086ffbf4f 100644
--- a/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx
+++ b/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx
@@ -5,7 +5,10 @@ import { CommandService } from '@theia/core/lib/common/command';
 import { MessageService } from '@theia/core/lib/common/message-service';
 import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
 import { Searchable } from '../../../common/protocol/searchable';
-import { ExecuteWithProgress } from '../../../common/protocol/progressible';
+import {
+  ExecuteWithProgress,
+  UserAbortError,
+} from '../../../common/protocol/progressible';
 import {
   Installable,
   libraryInstallFailed,
@@ -13,7 +16,7 @@ import {
 } from '../../../common/protocol/installable';
 import { ArduinoComponent } from '../../../common/protocol/arduino-component';
 import { SearchBar } from './search-bar';
-import { ListWidget, UserAbortError } from './list-widget';
+import { ListWidget } from './list-widget';
 import { ComponentList } from './component-list';
 import { ListItemRenderer } from './list-item-renderer';
 import {
diff --git a/arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx b/arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx
index 7603f44c0..d13d4ac7d 100644
--- a/arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx
+++ b/arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx
@@ -192,10 +192,3 @@ export namespace ListWidget {
     readonly defaultSearchOptions: S;
   }
 }
-
-export class UserAbortError extends Error {
-  constructor(message = 'User abort') {
-    super(message);
-    Object.setPrototypeOf(this, UserAbortError.prototype);
-  }
-}
diff --git a/arduino-ide-extension/src/common/nls.ts b/arduino-ide-extension/src/common/nls.ts
index d824f1751..7514a45c8 100644
--- a/arduino-ide-extension/src/common/nls.ts
+++ b/arduino-ide-extension/src/common/nls.ts
@@ -39,3 +39,5 @@ export const noSketchOpened = nls.localize(
   'arduino/common/noSketchOpened',
   'No sketch opened'
 );
+
+export const userAbort = nls.localize('arduino/common/userAbort', 'User abort');
diff --git a/arduino-ide-extension/src/common/protocol/arduino-daemon.ts b/arduino-ide-extension/src/common/protocol/arduino-daemon.ts
index b59d4c617..b1b8456d8 100644
--- a/arduino-ide-extension/src/common/protocol/arduino-daemon.ts
+++ b/arduino-ide-extension/src/common/protocol/arduino-daemon.ts
@@ -5,14 +5,14 @@ export interface ArduinoDaemon {
    * Returns with a promise that resolves with the port
    * of the CLI daemon when it's up and running.
    */
-  getPort(): Promise<string>;
+  getPort(): Promise<number>;
   /**
    * Unlike `getPort` this method returns with a promise
    * that resolves to `undefined` when the daemon is not running.
    * Otherwise resolves to the CLI daemon port.
    */
-  tryGetPort(): Promise<string | undefined>;
-  start(): Promise<string>;
+  tryGetPort(): Promise<number | undefined>;
+  start(): Promise<number>;
   stop(): Promise<void>;
-  restart(): Promise<string>;
+  restart(): Promise<number>;
 }
diff --git a/arduino-ide-extension/src/common/protocol/boards-service.ts b/arduino-ide-extension/src/common/protocol/boards-service.ts
index ba1b9f575..d76406216 100644
--- a/arduino-ide-extension/src/common/protocol/boards-service.ts
+++ b/arduino-ide-extension/src/common/protocol/boards-service.ts
@@ -1,4 +1,5 @@
 import { nls } from '@theia/core/lib/common/nls';
+import { FQBN } from 'fqbn';
 import type { MaybePromise } from '@theia/core/lib/common/types';
 import type URI from '@theia/core/lib/common/uri';
 import {
@@ -75,6 +76,9 @@ export interface BoardsService
   }): Promise<BoardsPackage | undefined>;
   searchBoards({ query }: { query?: string }): Promise<BoardWithPackage[]>;
   getInstalledBoards(): Promise<BoardWithPackage[]>;
+  /**
+   * Returns with all installed platforms including the manually installed ones.
+   */
   getInstalledPlatforms(): Promise<BoardsPackage[]>;
   getBoardUserFields(options: {
     fqbn: string;
@@ -364,40 +368,6 @@ export interface ConfigOption {
   readonly values: ConfigValue[];
 }
 export namespace ConfigOption {
-  /**
-   * Appends the configuration options to the `fqbn` argument.
-   * Throws an error if the `fqbn` does not have the `segment(':'segment)*` format.
-   * The provided output format is always segment(':'segment)*(':'option'='value(','option'='value)*)?
-   */
-  export function decorate(
-    fqbn: string,
-    configOptions: ConfigOption[]
-  ): string {
-    if (!configOptions.length) {
-      return fqbn;
-    }
-
-    const toValue = (values: ConfigValue[]) => {
-      const selectedValue = values.find(({ selected }) => selected);
-      if (!selectedValue) {
-        console.warn(
-          `None of the config values was selected. Values were: ${JSON.stringify(
-            values
-          )}`
-        );
-        return undefined;
-      }
-      return selectedValue.value;
-    };
-    const options = configOptions
-      .map(({ option, values }) => [option, toValue(values)])
-      .filter(([, value]) => !!value)
-      .map(([option, value]) => `${option}=${value}`)
-      .join(',');
-
-    return `${fqbn}:${options}`;
-  }
-
   export class ConfigOptionError extends Error {
     constructor(message: string) {
       super(message);
@@ -571,28 +541,13 @@ export namespace Board {
   }
 }
 
-/**
- * Throws an error if the `fqbn` argument is not sanitized. A sanitized FQBN has the `VENDOR:ARCHITECTURE:BOARD_ID` construct.
- */
-export function assertSanitizedFqbn(fqbn: string): void {
-  if (fqbn.split(':').length !== 3) {
-    throw new Error(
-      `Expected a sanitized FQBN with three segments in the following format: 'VENDOR:ARCHITECTURE:BOARD_ID'. Got ${fqbn} instead.`
-    );
-  }
-}
-
 /**
  * Converts the `VENDOR:ARCHITECTURE:BOARD_ID[:MENU_ID=OPTION_ID[,MENU2_ID=OPTION_ID ...]]` FQBN to
  * `VENDOR:ARCHITECTURE:BOARD_ID` format.
  * See the details of the `{build.fqbn}` entry in the [specs](https://arduino.github.io/arduino-cli/latest/platform-specification/#global-predefined-properties).
  */
-export function sanitizeFqbn(fqbn: string | undefined): string | undefined {
-  if (!fqbn) {
-    return undefined;
-  }
-  const [vendor, arch, id] = fqbn.split(':');
-  return `${vendor}:${arch}:${id}`;
+export function sanitizeFqbn(fqbn: string): string {
+  return new FQBN(fqbn).sanitize().toString();
 }
 
 export type PlatformIdentifier = Readonly<{ vendorId: string; arch: string }>;
@@ -749,8 +704,8 @@ export function boardIdentifierEquals(
     return false; // TODO: This a strict now. Maybe compare name in the future.
   }
   if (left.fqbn && right.fqbn) {
-    const leftFqbn = options.looseFqbn ? sanitizeFqbn(left.fqbn) : left.fqbn;
-    const rightFqbn = options.looseFqbn ? sanitizeFqbn(right.fqbn) : right.fqbn;
+    const leftFqbn = new FQBN(left.fqbn).toString(options.looseFqbn);
+    const rightFqbn = new FQBN(right.fqbn).toString(options.looseFqbn);
     return leftFqbn === rightFqbn;
   }
   // No more Genuino hack.
diff --git a/arduino-ide-extension/src/common/protocol/core-service.ts b/arduino-ide-extension/src/common/protocol/core-service.ts
index 9104df01e..f3a681d48 100644
--- a/arduino-ide-extension/src/common/protocol/core-service.ts
+++ b/arduino-ide-extension/src/common/protocol/core-service.ts
@@ -1,4 +1,5 @@
 import { ApplicationError } from '@theia/core/lib/common/application-error';
+import type { CancellationToken } from '@theia/core/lib/common/cancellation';
 import { nls } from '@theia/core/lib/common/nls';
 import type {
   Location,
@@ -7,7 +8,7 @@ import type {
 } from '@theia/core/shared/vscode-languageserver-protocol';
 import type { CompileSummary as ApiCompileSummary } from 'vscode-arduino-api';
 import type { BoardUserField, Installable } from '../../common/protocol/';
-import { isPortIdentifier, PortIdentifier, Programmer } from './boards-service';
+import { PortIdentifier, Programmer, isPortIdentifier } from './boards-service';
 import type { IndexUpdateSummary } from './notification-service';
 import type { Sketch } from './sketches-service';
 
@@ -162,9 +163,18 @@ export function isUploadResponse(arg: unknown): arg is UploadResponse {
 export const CoreServicePath = '/services/core-service';
 export const CoreService = Symbol('CoreService');
 export interface CoreService {
-  compile(options: CoreService.Options.Compile): Promise<void>;
-  upload(options: CoreService.Options.Upload): Promise<UploadResponse>;
-  burnBootloader(options: CoreService.Options.Bootloader): Promise<void>;
+  compile(
+    options: CoreService.Options.Compile,
+    cancellationToken?: CancellationToken
+  ): Promise<void>;
+  upload(
+    options: CoreService.Options.Upload,
+    cancellationToken?: CancellationToken
+  ): Promise<UploadResponse>;
+  burnBootloader(
+    options: CoreService.Options.Bootloader,
+    cancellationToken?: CancellationToken
+  ): Promise<void>;
   /**
    * Refreshes the underling core gRPC client for the Arduino CLI.
    */
diff --git a/arduino-ide-extension/src/common/protocol/notification-service.ts b/arduino-ide-extension/src/common/protocol/notification-service.ts
index 9ad5c202d..7b0aea120 100644
--- a/arduino-ide-extension/src/common/protocol/notification-service.ts
+++ b/arduino-ide-extension/src/common/protocol/notification-service.ts
@@ -51,7 +51,7 @@ export interface NotificationServiceClient {
   notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void;
 
   // Daemon
-  notifyDaemonDidStart(port: string): void;
+  notifyDaemonDidStart(port: number): void;
   notifyDaemonDidStop(): void;
 
   // CLI config
diff --git a/arduino-ide-extension/src/common/protocol/progressible.ts b/arduino-ide-extension/src/common/protocol/progressible.ts
index c27737ccc..d01bc270d 100644
--- a/arduino-ide-extension/src/common/protocol/progressible.ts
+++ b/arduino-ide-extension/src/common/protocol/progressible.ts
@@ -1,22 +1,48 @@
+import { ApplicationError } from '@theia/core/lib/common/application-error';
 import type { CancellationToken } from '@theia/core/lib/common/cancellation';
 import { CancellationTokenSource } from '@theia/core/lib/common/cancellation';
 import type { MessageService } from '@theia/core/lib/common/message-service';
 import type { Progress } from '@theia/core/lib/common/message-service-protocol';
+import { userAbort } from '../nls';
 import type { ResponseServiceClient } from './response-service';
 
+export const UserAbortApplicationError = ApplicationError.declare(
+  9999,
+  (message: string, uri: string) => {
+    return {
+      message,
+      data: { uri },
+    };
+  }
+);
+
+export class UserAbortError extends Error {
+  constructor() {
+    super(userAbort);
+    Object.setPrototypeOf(this, UserAbortError.prototype);
+  }
+}
+
 export namespace ExecuteWithProgress {
   export async function doWithProgress<T>(options: {
-    run: ({ progressId }: { progressId: string }) => Promise<T>;
+    run: ({
+      progressId,
+      cancellationToken,
+    }: {
+      progressId: string;
+      cancellationToken?: CancellationToken;
+    }) => Promise<T>;
     messageService: MessageService;
     responseService: ResponseServiceClient;
     progressText: string;
     keepOutput?: boolean;
+    cancelable?: boolean;
   }): Promise<T> {
     return withProgress(
       options.progressText,
       options.messageService,
       // eslint-disable-next-line @typescript-eslint/no-unused-vars
-      async (progress, _token) => {
+      async (progress, token) => {
         const progressId = progress.id;
         const toDispose = options.responseService.onProgressDidChange(
           (progressMessage) => {
@@ -30,24 +56,29 @@ export namespace ExecuteWithProgress {
           if (!options.keepOutput) {
             options.responseService.clearOutput();
           }
-          const result = await options.run({ progressId });
+          const result = await options.run({
+            progressId,
+            cancellationToken: token,
+          });
           return result;
         } finally {
           toDispose.dispose();
         }
-      }
+      },
+      options.cancelable
     );
   }
 
   export async function withProgress<T>(
     text: string,
     messageService: MessageService,
-    cb: (progress: Progress, token: CancellationToken) => Promise<T>
+    cb: (progress: Progress, token: CancellationToken) => Promise<T>,
+    cancelable = false
   ): Promise<T> {
     const cancellationSource = new CancellationTokenSource();
     const { token } = cancellationSource;
     const progress = await messageService.showProgress(
-      { text, options: { cancelable: false } },
+      { text, options: { cancelable } },
       () => cancellationSource.cancel()
     );
     try {
diff --git a/arduino-ide-extension/src/node/arduino-core-service-client.ts b/arduino-ide-extension/src/node/arduino-core-service-client.ts
new file mode 100644
index 000000000..e753e206c
--- /dev/null
+++ b/arduino-ide-extension/src/node/arduino-core-service-client.ts
@@ -0,0 +1,53 @@
+import { credentials, makeClientConstructor } from '@grpc/grpc-js';
+import * as commandsGrpcPb from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
+import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
+
+export interface CreateClientOptions {
+  /**
+   * The port to the Arduino CLI daemon.
+   */
+  readonly port: number;
+  /**
+   * Defaults to `'localhost'`.
+   */
+  readonly host?: string;
+
+  /**
+   * gRCP channel options. Defaults to `createDefaultChannelOptions` with `'0.0.0'` `appVersion`
+   */
+  readonly channelOptions?: Record<string, unknown>;
+}
+
+export function createDefaultChannelOptions(
+  appVersion = '0.0.0'
+): Record<string, unknown> {
+  return {
+    'grpc.max_send_message_length': 512 * 1024 * 1024,
+    'grpc.max_receive_message_length': 512 * 1024 * 1024,
+    'grpc.primary_user_agent': `arduino-ide/${appVersion}`,
+  };
+}
+
+export function createArduinoCoreServiceClient(
+  options: CreateClientOptions
+): ArduinoCoreServiceClient {
+  const {
+    port,
+    host = 'localhost',
+    channelOptions = createDefaultChannelOptions(),
+  } = options;
+  const address = `${host}:${port}`;
+  // https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/doc/grpcjs_support.md#usage
+  const ArduinoCoreServiceClient = makeClientConstructor(
+    // @ts-expect-error: ignore
+    commandsGrpcPb['cc.arduino.cli.commands.v1.ArduinoCoreService'],
+    'ArduinoCoreServiceService'
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  ) as any;
+  const client = new ArduinoCoreServiceClient(
+    address,
+    credentials.createInsecure(),
+    channelOptions
+  ) as ArduinoCoreServiceClient;
+  return client;
+}
diff --git a/arduino-ide-extension/src/node/arduino-daemon-impl.ts b/arduino-ide-extension/src/node/arduino-daemon-impl.ts
index 16db90631..13e9bc18e 100644
--- a/arduino-ide-extension/src/node/arduino-daemon-impl.ts
+++ b/arduino-ide-extension/src/node/arduino-daemon-impl.ts
@@ -39,11 +39,11 @@ export class ArduinoDaemonImpl
   private readonly processUtils: ProcessUtils;
 
   private readonly toDispose = new DisposableCollection();
-  private readonly onDaemonStartedEmitter = new Emitter<string>();
+  private readonly onDaemonStartedEmitter = new Emitter<number>();
   private readonly onDaemonStoppedEmitter = new Emitter<void>();
 
   private _running = false;
-  private _port = new Deferred<string>();
+  private _port = new Deferred<number>();
 
   // Backend application lifecycle.
 
@@ -53,18 +53,18 @@ export class ArduinoDaemonImpl
 
   // Daemon API
 
-  async getPort(): Promise<string> {
+  async getPort(): Promise<number> {
     return this._port.promise;
   }
 
-  async tryGetPort(): Promise<string | undefined> {
+  async tryGetPort(): Promise<number | undefined> {
     if (this._running) {
       return this._port.promise;
     }
     return undefined;
   }
 
-  async start(): Promise<string> {
+  async start(): Promise<number> {
     try {
       this.toDispose.dispose(); // This will `kill` the previously started daemon process, if any.
       const cliPath = this.getExecPath();
@@ -101,13 +101,13 @@ export class ArduinoDaemonImpl
     this.toDispose.dispose();
   }
 
-  async restart(): Promise<string> {
+  async restart(): Promise<number> {
     return this.start();
   }
 
   // Backend only daemon API
 
-  get onDaemonStarted(): Event<string> {
+  get onDaemonStarted(): Event<number> {
     return this.onDaemonStartedEmitter.event;
   }
 
@@ -150,11 +150,11 @@ export class ArduinoDaemonImpl
 
   protected async spawnDaemonProcess(): Promise<{
     daemon: ChildProcess;
-    port: string;
+    port: number;
   }> {
     const args = await this.getSpawnArgs();
     const cliPath = this.getExecPath();
-    const ready = new Deferred<{ daemon: ChildProcess; port: string }>();
+    const ready = new Deferred<{ daemon: ChildProcess; port: number }>();
     const options = {
       env: { ...deepClone(process.env), NO_COLOR: String(true) },
     };
@@ -195,7 +195,13 @@ export class ArduinoDaemonImpl
 
         if (port.length && address.length) {
           grpcServerIsReady = true;
-          ready.resolve({ daemon, port });
+          const portNumber = Number.parseInt(port, 10);
+          if (Number.isNaN(portNumber)) {
+            ready.reject(
+              new Error(`Received a NaN port from the CLI: ${port}`)
+            );
+          }
+          ready.resolve({ daemon, port: portNumber });
         }
       }
     });
@@ -225,7 +231,7 @@ export class ArduinoDaemonImpl
     return ready.promise;
   }
 
-  private fireDaemonStarted(port: string): void {
+  private fireDaemonStarted(port: number): void {
     this._running = true;
     this._port.resolve(port);
     this.onDaemonStartedEmitter.fire(port);
@@ -238,7 +244,7 @@ export class ArduinoDaemonImpl
     }
     this._running = false;
     this._port.reject(); // Reject all pending.
-    this._port = new Deferred<string>();
+    this._port = new Deferred<number>();
     this.onDaemonStoppedEmitter.fire();
     this.notificationService.notifyDaemonDidStop();
   }
diff --git a/arduino-ide-extension/src/node/board-discovery.ts b/arduino-ide-extension/src/node/board-discovery.ts
index 628ed97ec..44a84ec38 100644
--- a/arduino-ide-extension/src/node/board-discovery.ts
+++ b/arduino-ide-extension/src/node/board-discovery.ts
@@ -267,24 +267,12 @@ export class BoardDiscovery
       const { port, boards } = detectedPort;
       const key = Port.keyOf(port);
       if (eventType === EventType.Add) {
-        const alreadyDetectedPort = newState[key];
-        if (alreadyDetectedPort) {
-          console.warn(
-            `Detected a new port that has been already discovered. The old value will be overridden. Old value: ${JSON.stringify(
-              alreadyDetectedPort
-            )}, new value: ${JSON.stringify(detectedPort)}`
-          );
-        }
+        // Note that, the serial discovery might detect port details (such as addressLabel) in chunks.
+        // For example, first, the Teensy 4.1 port is detected with the `[no_device] Triple Serial` address label,
+        // Then, when more refinements are available, the same port is detected with `/dev/cu.usbmodem127902301 Triple Serial` address label.
+        // In such cases, an `add` event is received from the CLI, and the the detected port is overridden in the state.
         newState[key] = { port, boards };
       } else if (eventType === EventType.Remove) {
-        const alreadyDetectedPort = newState[key];
-        if (!alreadyDetectedPort) {
-          console.warn(
-            `Detected a port removal but it has not been discovered. This is most likely a bug! Detected port was: ${JSON.stringify(
-              detectedPort
-            )}`
-          );
-        }
         delete newState[key];
       }
     }
diff --git a/arduino-ide-extension/src/node/boards-service-impl.ts b/arduino-ide-extension/src/node/boards-service-impl.ts
index 0d1926f9c..9eefeec9f 100644
--- a/arduino-ide-extension/src/node/boards-service-impl.ts
+++ b/arduino-ide-extension/src/node/boards-service-impl.ts
@@ -3,7 +3,6 @@ import { nls } from '@theia/core/lib/common/nls';
 import { notEmpty } from '@theia/core/lib/common/objects';
 import { inject, injectable } from '@theia/core/shared/inversify';
 import {
-  Board,
   BoardDetails,
   BoardSearch,
   BoardUserField,
@@ -32,11 +31,9 @@ import {
   BoardListAllResponse,
   BoardSearchRequest,
 } from './cli-protocol/cc/arduino/cli/commands/v1/board_pb';
-import { Platform } from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
+import { PlatformSummary } from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
 import {
   PlatformInstallRequest,
-  PlatformListRequest,
-  PlatformListResponse,
   PlatformSearchRequest,
   PlatformSearchResponse,
   PlatformUninstallRequest,
@@ -247,24 +244,22 @@ export class BoardsServiceImpl
 
   async getInstalledPlatforms(): Promise<BoardsPackage[]> {
     const { instance, client } = await this.coreClient;
-    return new Promise<BoardsPackage[]>((resolve, reject) => {
-      client.platformList(
-        new PlatformListRequest().setInstance(instance),
-        (err, response) => {
-          if (err) {
-            reject(err);
-            return;
-          }
-          resolve(
-            response
-              .getInstalledPlatformsList()
-              .map((platform, _, installedPlatforms) =>
-                toBoardsPackage(platform, installedPlatforms)
-              )
-          );
-        }
-      );
-    });
+    const resp = await new Promise<PlatformSearchResponse>(
+      (resolve, reject) => {
+        client.platformSearch(
+          new PlatformSearchRequest()
+            .setInstance(instance)
+            .setManuallyInstalled(true), // include core manually installed to the sketchbook
+          (err, resp) => (err ? reject(err) : resolve(resp))
+        );
+      }
+    );
+    const searchOutput = resp.getSearchOutputList();
+    return searchOutput
+      .map((message) => message.toObject(false))
+      .filter((summary) => summary.installedVersion) // only installed ones
+      .map(createBoardsPackage)
+      .filter(notEmpty);
   }
 
   private async handleListBoards(
@@ -287,12 +282,28 @@ export class BoardsServiceImpl
         for (const board of resp.getBoardsList()) {
           const platform = board.getPlatform();
           if (platform) {
-            const platformId = platform.getId();
+            const metadata = platform.getMetadata();
+            if (!metadata) {
+              console.warn(
+                `Platform metadata is missing for platform: ${JSON.stringify(
+                  platform.toObject(false)
+                )}. Skipping`
+              );
+              continue;
+            }
+            const platformId = metadata.getId();
+            const release = platform.getRelease();
+            if (!release) {
+              console.warn(
+                `Platform release is missing for platform: ${platformId}. Skipping`
+              );
+              continue;
+            }
             const fqbn = board.getFqbn() || undefined; // prefer undefined over empty string
             const parsedPlatformId = createPlatformIdentifier(platformId);
             if (!parsedPlatformId) {
               console.warn(
-                `Could not create platform identifier from platform ID input: ${platform.getId()}. Skipping`
+                `Could not create platform identifier from platform ID input: ${platformId}. Skipping`
               );
               continue;
             }
@@ -319,8 +330,8 @@ export class BoardsServiceImpl
               name: board.getName(),
               fqbn: board.getFqbn(),
               packageId: parsedPlatformId,
-              packageName: platform.getName(),
-              manuallyInstalled: platform.getManuallyInstalled(),
+              packageName: release.getName(),
+              manuallyInstalled: metadata.getManuallyInstalled(),
             });
           }
         }
@@ -375,89 +386,25 @@ export class BoardsServiceImpl
     const coreClient = await this.coreClient;
     const { client, instance } = coreClient;
 
-    const installedPlatformsReq = new PlatformListRequest();
-    installedPlatformsReq.setInstance(instance);
-    const installedPlatformsResp = await new Promise<PlatformListResponse>(
-      (resolve, reject) => {
-        client.platformList(installedPlatformsReq, (err, resp) => {
-          !!err ? reject(err) : resolve(resp);
-        });
-      }
-    );
-    const installedPlatforms =
-      installedPlatformsResp.getInstalledPlatformsList();
-
-    const req = new PlatformSearchRequest();
-    req.setSearchArgs(options.query || '');
-    req.setAllVersions(true);
-    req.setInstance(instance);
+    // `core search` returns with all platform versions when the command is executed via gRPC or with `--format json`
+    // The `--all` flag is applicable only when filtering for the human-readable (`--format text`) output of the CLI
     const resp = await new Promise<PlatformSearchResponse>(
       (resolve, reject) => {
-        client.platformSearch(req, (err, resp) => {
-          !!err ? reject(err) : resolve(resp);
-        });
+        client.platformSearch(
+          new PlatformSearchRequest()
+            .setInstance(instance)
+            .setSearchArgs(options.query ?? ''),
+          (err, resp) => (err ? reject(err) : resolve(resp))
+        );
       }
     );
-    const packages = new Map<string, BoardsPackage>();
-    // We must group the cores by ID, and sort platforms by, first the installed version, then version alphabetical order.
-    // Otherwise we lose the FQBN information.
-    const groupedById: Map<string, Platform[]> = new Map();
-    for (const platform of resp.getSearchOutputList()) {
-      const id = platform.getId();
-      const idGroup = groupedById.get(id);
-      if (idGroup) {
-        idGroup.push(platform);
-      } else {
-        groupedById.set(id, [platform]);
-      }
-    }
-    const installedAwareVersionComparator = (
-      left: Platform,
-      right: Platform
-    ) => {
-      // XXX: we cannot rely on `platform.getInstalled()`, it is always an empty string.
-      const leftInstalled = !!installedPlatforms.find(
-        (ip) =>
-          ip.getId() === left.getId() && ip.getInstalled() === left.getLatest()
-      );
-      const rightInstalled = !!installedPlatforms.find(
-        (ip) =>
-          ip.getId() === right.getId() &&
-          ip.getInstalled() === right.getLatest()
-      );
-      if (leftInstalled && !rightInstalled) {
-        return -1;
-      }
-      if (!leftInstalled && rightInstalled) {
-        return 1;
-      }
-
-      const invertedVersionComparator =
-        Installable.Version.COMPARATOR(left.getLatest(), right.getLatest()) *
-        -1;
-      // Higher version comes first.
-
-      return invertedVersionComparator;
-    };
-    for (const value of groupedById.values()) {
-      value.sort(installedAwareVersionComparator);
-    }
-
-    for (const value of groupedById.values()) {
-      for (const platform of value) {
-        const id = platform.getId();
-        const pkg = packages.get(id);
-        if (pkg) {
-          pkg.availableVersions.push(platform.getLatest());
-          pkg.availableVersions.sort(Installable.Version.COMPARATOR).reverse();
-        } else {
-          packages.set(id, toBoardsPackage(platform, installedPlatforms));
-        }
-      }
-    }
-
-    const filter = this.typePredicate(options);
-    const boardsPackages = [...packages.values()].filter(filter);
+    const typeFilter = this.typePredicate(options);
+    const searchOutput = resp.getSearchOutputList();
+    const boardsPackages = searchOutput
+      .map((message) => message.toObject(false))
+      .map(createBoardsPackage)
+      .filter(notEmpty)
+      .filter(typeFilter);
     return sortComponents(boardsPackages, boardsPackageSortGroup);
   }
 
@@ -624,36 +571,48 @@ function boardsPackageSortGroup(boardsPackage: BoardsPackage): SortGroup {
   return types.join('-') as SortGroup;
 }
 
-function toBoardsPackage(
-  platform: Platform,
-  installedPlatforms: Platform[]
-): BoardsPackage {
-  let installedVersion: string | undefined;
-  const matchingPlatform = installedPlatforms.find(
-    (ip) => ip.getId() === platform.getId()
-  );
-  if (!!matchingPlatform) {
-    installedVersion = matchingPlatform.getInstalled();
+function createBoardsPackage(
+  summary: PlatformSummary.AsObject
+): BoardsPackage | undefined {
+  if (!isPlatformSummaryWithMetadata(summary)) {
+    return undefined;
+  }
+  const versionReleaseMap = new Map(summary.releasesMap);
+  const actualRelease =
+    versionReleaseMap.get(summary.installedVersion) ??
+    versionReleaseMap.get(summary.latestVersion);
+  if (!actualRelease) {
+    return undefined;
+  }
+  const { name, typeList, boardsList, deprecated, compatible } = actualRelease;
+  if (!compatible) {
+    return undefined; // never show incompatible platforms
   }
+  const { id, website, maintainer } = summary.metadata;
+  const availableVersions = Array.from(versionReleaseMap.keys())
+    .sort(Installable.Version.COMPARATOR)
+    .reverse();
   return {
-    id: platform.getId(),
-    name: platform.getName(),
-    author: platform.getMaintainer(),
-    availableVersions: [platform.getLatest()],
-    description: platform
-      .getBoardsList()
-      .map((b) => b.getName())
-      .join(', '),
-    types: platform.getTypeList(),
-    deprecated: platform.getDeprecated(),
+    id,
+    name,
     summary: nls.localize(
       'arduino/component/boardsIncluded',
       'Boards included in this package:'
     ),
-    installedVersion,
-    boards: platform
-      .getBoardsList()
-      .map((b) => <Board>{ name: b.getName(), fqbn: b.getFqbn() }),
-    moreInfoLink: platform.getWebsite(),
+    description: boardsList.map(({ name }) => name).join(', '),
+    boards: boardsList,
+    types: typeList,
+    moreInfoLink: website,
+    author: maintainer,
+    deprecated,
+    availableVersions,
   };
 }
+
+type PlatformSummaryWithMetadata = PlatformSummary.AsObject &
+  Required<Pick<PlatformSummary.AsObject, 'metadata'>>;
+function isPlatformSummaryWithMetadata(
+  summary: PlatformSummary.AsObject
+): summary is PlatformSummaryWithMetadata {
+  return Boolean(summary.metadata);
+}
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb.d.ts
index d1692362f..651646fd8 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb.d.ts
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb.d.ts
@@ -15,6 +15,7 @@ import * as cc_arduino_cli_commands_v1_debug_pb from "../../../../../cc/arduino/
 import * as cc_arduino_cli_commands_v1_monitor_pb from "../../../../../cc/arduino/cli/commands/v1/monitor_pb";
 import * as cc_arduino_cli_commands_v1_upload_pb from "../../../../../cc/arduino/cli/commands/v1/upload_pb";
 import * as cc_arduino_cli_commands_v1_lib_pb from "../../../../../cc/arduino/cli/commands/v1/lib_pb";
+import * as cc_arduino_cli_commands_v1_settings_pb from "../../../../../cc/arduino/cli/commands/v1/settings_pb";
 
 interface IArduinoCoreServiceService extends grpc.ServiceDefinition<grpc.UntypedServiceImplementation> {
     create: IArduinoCoreServiceService_ICreate;
@@ -43,7 +44,6 @@ interface IArduinoCoreServiceService extends grpc.ServiceDefinition<grpc.Untyped
     listProgrammersAvailableForUpload: IArduinoCoreServiceService_IListProgrammersAvailableForUpload;
     burnBootloader: IArduinoCoreServiceService_IBurnBootloader;
     platformSearch: IArduinoCoreServiceService_IPlatformSearch;
-    platformList: IArduinoCoreServiceService_IPlatformList;
     libraryDownload: IArduinoCoreServiceService_ILibraryDownload;
     libraryInstall: IArduinoCoreServiceService_ILibraryInstall;
     libraryUpgrade: IArduinoCoreServiceService_ILibraryUpgrade;
@@ -59,6 +59,12 @@ interface IArduinoCoreServiceService extends grpc.ServiceDefinition<grpc.Untyped
     debug: IArduinoCoreServiceService_IDebug;
     isDebugSupported: IArduinoCoreServiceService_IIsDebugSupported;
     getDebugConfig: IArduinoCoreServiceService_IGetDebugConfig;
+    settingsGetAll: IArduinoCoreServiceService_ISettingsGetAll;
+    settingsMerge: IArduinoCoreServiceService_ISettingsMerge;
+    settingsGetValue: IArduinoCoreServiceService_ISettingsGetValue;
+    settingsSetValue: IArduinoCoreServiceService_ISettingsSetValue;
+    settingsWrite: IArduinoCoreServiceService_ISettingsWrite;
+    settingsDelete: IArduinoCoreServiceService_ISettingsDelete;
 }
 
 interface IArduinoCoreServiceService_ICreate extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.CreateRequest, cc_arduino_cli_commands_v1_commands_pb.CreateResponse> {
@@ -295,15 +301,6 @@ interface IArduinoCoreServiceService_IPlatformSearch extends grpc.MethodDefiniti
     responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse>;
     responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse>;
 }
-interface IArduinoCoreServiceService_IPlatformList extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, cc_arduino_cli_commands_v1_core_pb.PlatformListResponse> {
-    path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformList";
-    requestStream: false;
-    responseStream: false;
-    requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest>;
-    requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest>;
-    responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformListResponse>;
-    responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformListResponse>;
-}
 interface IArduinoCoreServiceService_ILibraryDownload extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse> {
     path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryDownload";
     requestStream: false;
@@ -439,6 +436,60 @@ interface IArduinoCoreServiceService_IGetDebugConfig extends grpc.MethodDefiniti
     responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse>;
     responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse>;
 }
+interface IArduinoCoreServiceService_ISettingsGetAll extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse> {
+    path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsGetAll";
+    requestStream: false;
+    responseStream: false;
+    requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest>;
+    requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest>;
+    responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse>;
+    responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse>;
+}
+interface IArduinoCoreServiceService_ISettingsMerge extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse> {
+    path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsMerge";
+    requestStream: false;
+    responseStream: false;
+    requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest>;
+    requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest>;
+    responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse>;
+    responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse>;
+}
+interface IArduinoCoreServiceService_ISettingsGetValue extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse> {
+    path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsGetValue";
+    requestStream: false;
+    responseStream: false;
+    requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest>;
+    requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest>;
+    responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse>;
+    responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse>;
+}
+interface IArduinoCoreServiceService_ISettingsSetValue extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse> {
+    path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsSetValue";
+    requestStream: false;
+    responseStream: false;
+    requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest>;
+    requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest>;
+    responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse>;
+    responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse>;
+}
+interface IArduinoCoreServiceService_ISettingsWrite extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse> {
+    path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsWrite";
+    requestStream: false;
+    responseStream: false;
+    requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest>;
+    requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest>;
+    responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse>;
+    responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse>;
+}
+interface IArduinoCoreServiceService_ISettingsDelete extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse> {
+    path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsDelete";
+    requestStream: false;
+    responseStream: false;
+    requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest>;
+    requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest>;
+    responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse>;
+    responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse>;
+}
 
 export const ArduinoCoreServiceService: IArduinoCoreServiceService;
 
@@ -469,7 +520,6 @@ export interface IArduinoCoreServiceServer extends grpc.UntypedServiceImplementa
     listProgrammersAvailableForUpload: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse>;
     burnBootloader: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest, cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse>;
     platformSearch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse>;
-    platformList: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, cc_arduino_cli_commands_v1_core_pb.PlatformListResponse>;
     libraryDownload: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
     libraryInstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
     libraryUpgrade: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeResponse>;
@@ -485,6 +535,12 @@ export interface IArduinoCoreServiceServer extends grpc.UntypedServiceImplementa
     debug: grpc.handleBidiStreamingCall<cc_arduino_cli_commands_v1_debug_pb.DebugRequest, cc_arduino_cli_commands_v1_debug_pb.DebugResponse>;
     isDebugSupported: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_debug_pb.IsDebugSupportedRequest, cc_arduino_cli_commands_v1_debug_pb.IsDebugSupportedResponse>;
     getDebugConfig: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigRequest, cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse>;
+    settingsGetAll: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse>;
+    settingsMerge: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse>;
+    settingsGetValue: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse>;
+    settingsSetValue: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse>;
+    settingsWrite: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse>;
+    settingsDelete: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest, cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse>;
 }
 
 export interface IArduinoCoreServiceClient {
@@ -554,9 +610,6 @@ export interface IArduinoCoreServiceClient {
     platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
     platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
     platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
-    platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
-    platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
-    platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
     libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
     libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
     libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
@@ -595,6 +648,24 @@ export interface IArduinoCoreServiceClient {
     getDebugConfig(request: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse) => void): grpc.ClientUnaryCall;
     getDebugConfig(request: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse) => void): grpc.ClientUnaryCall;
     getDebugConfig(request: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse) => void): grpc.ClientUnaryCall;
+    settingsGetAll(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse) => void): grpc.ClientUnaryCall;
+    settingsGetAll(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse) => void): grpc.ClientUnaryCall;
+    settingsGetAll(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse) => void): grpc.ClientUnaryCall;
+    settingsMerge(request: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse) => void): grpc.ClientUnaryCall;
+    settingsMerge(request: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse) => void): grpc.ClientUnaryCall;
+    settingsMerge(request: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse) => void): grpc.ClientUnaryCall;
+    settingsGetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse) => void): grpc.ClientUnaryCall;
+    settingsGetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse) => void): grpc.ClientUnaryCall;
+    settingsGetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse) => void): grpc.ClientUnaryCall;
+    settingsSetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse) => void): grpc.ClientUnaryCall;
+    settingsSetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse) => void): grpc.ClientUnaryCall;
+    settingsSetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse) => void): grpc.ClientUnaryCall;
+    settingsWrite(request: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse) => void): grpc.ClientUnaryCall;
+    settingsWrite(request: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse) => void): grpc.ClientUnaryCall;
+    settingsWrite(request: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse) => void): grpc.ClientUnaryCall;
+    settingsDelete(request: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse) => void): grpc.ClientUnaryCall;
+    settingsDelete(request: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse) => void): grpc.ClientUnaryCall;
+    settingsDelete(request: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse) => void): grpc.ClientUnaryCall;
 }
 
 export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCoreServiceClient {
@@ -665,9 +736,6 @@ export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCor
     public platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
     public platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
     public platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
-    public platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
-    public platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
-    public platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
     public libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
     public libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
     public libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
@@ -704,4 +772,22 @@ export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCor
     public getDebugConfig(request: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse) => void): grpc.ClientUnaryCall;
     public getDebugConfig(request: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse) => void): grpc.ClientUnaryCall;
     public getDebugConfig(request: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_debug_pb.GetDebugConfigResponse) => void): grpc.ClientUnaryCall;
+    public settingsGetAll(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse) => void): grpc.ClientUnaryCall;
+    public settingsGetAll(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse) => void): grpc.ClientUnaryCall;
+    public settingsGetAll(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse) => void): grpc.ClientUnaryCall;
+    public settingsMerge(request: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse) => void): grpc.ClientUnaryCall;
+    public settingsMerge(request: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse) => void): grpc.ClientUnaryCall;
+    public settingsMerge(request: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse) => void): grpc.ClientUnaryCall;
+    public settingsGetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse) => void): grpc.ClientUnaryCall;
+    public settingsGetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse) => void): grpc.ClientUnaryCall;
+    public settingsGetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse) => void): grpc.ClientUnaryCall;
+    public settingsSetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse) => void): grpc.ClientUnaryCall;
+    public settingsSetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse) => void): grpc.ClientUnaryCall;
+    public settingsSetValue(request: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse) => void): grpc.ClientUnaryCall;
+    public settingsWrite(request: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse) => void): grpc.ClientUnaryCall;
+    public settingsWrite(request: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse) => void): grpc.ClientUnaryCall;
+    public settingsWrite(request: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse) => void): grpc.ClientUnaryCall;
+    public settingsDelete(request: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse) => void): grpc.ClientUnaryCall;
+    public settingsDelete(request: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse) => void): grpc.ClientUnaryCall;
+    public settingsDelete(request: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse) => void): grpc.ClientUnaryCall;
 }
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb.js
index 671e361d0..6ea265e3c 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb.js
@@ -27,6 +27,7 @@ var cc_arduino_cli_commands_v1_debug_pb = require('../../../../../cc/arduino/cli
 var cc_arduino_cli_commands_v1_monitor_pb = require('../../../../../cc/arduino/cli/commands/v1/monitor_pb.js');
 var cc_arduino_cli_commands_v1_upload_pb = require('../../../../../cc/arduino/cli/commands/v1/upload_pb.js');
 var cc_arduino_cli_commands_v1_lib_pb = require('../../../../../cc/arduino/cli/commands/v1/lib_pb.js');
+var cc_arduino_cli_commands_v1_settings_pb = require('../../../../../cc/arduino/cli/commands/v1/settings_pb.js');
 
 function serialize_cc_arduino_cli_commands_v1_ArchiveSketchRequest(arg) {
   if (!(arg instanceof cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest)) {
@@ -688,28 +689,6 @@ function deserialize_cc_arduino_cli_commands_v1_PlatformInstallResponse(buffer_a
   return cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse.deserializeBinary(new Uint8Array(buffer_arg));
 }
 
-function serialize_cc_arduino_cli_commands_v1_PlatformListRequest(arg) {
-  if (!(arg instanceof cc_arduino_cli_commands_v1_core_pb.PlatformListRequest)) {
-    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.PlatformListRequest');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_commands_v1_PlatformListRequest(buffer_arg) {
-  return cc_arduino_cli_commands_v1_core_pb.PlatformListRequest.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_commands_v1_PlatformListResponse(arg) {
-  if (!(arg instanceof cc_arduino_cli_commands_v1_core_pb.PlatformListResponse)) {
-    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.PlatformListResponse');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_commands_v1_PlatformListResponse(buffer_arg) {
-  return cc_arduino_cli_commands_v1_core_pb.PlatformListResponse.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
 function serialize_cc_arduino_cli_commands_v1_PlatformSearchRequest(arg) {
   if (!(arg instanceof cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest)) {
     throw new Error('Expected argument of type cc.arduino.cli.commands.v1.PlatformSearchRequest');
@@ -798,6 +777,138 @@ function deserialize_cc_arduino_cli_commands_v1_SetSketchDefaultsResponse(buffer
   return cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse.deserializeBinary(new Uint8Array(buffer_arg));
 }
 
+function serialize_cc_arduino_cli_commands_v1_SettingsDeleteRequest(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsDeleteRequest');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsDeleteRequest(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsDeleteResponse(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsDeleteResponse');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsDeleteResponse(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsGetAllRequest(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsGetAllRequest');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsGetAllRequest(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsGetAllResponse(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsGetAllResponse');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsGetAllResponse(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsGetValueRequest(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsGetValueRequest');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsGetValueRequest(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsGetValueResponse(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsGetValueResponse');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsGetValueResponse(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsMergeRequest(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsMergeRequest');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsMergeRequest(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsMergeResponse(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsMergeResponse');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsMergeResponse(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsSetValueRequest(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsSetValueRequest');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsSetValueRequest(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsSetValueResponse(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsSetValueResponse');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsSetValueResponse(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsWriteRequest(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsWriteRequest');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsWriteRequest(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_cc_arduino_cli_commands_v1_SettingsWriteResponse(arg) {
+  if (!(arg instanceof cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse)) {
+    throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SettingsWriteResponse');
+  }
+  return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_cc_arduino_cli_commands_v1_SettingsWriteResponse(buffer_arg) {
+  return cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
 function serialize_cc_arduino_cli_commands_v1_SupportedUserFieldsRequest(arg) {
   if (!(arg instanceof cc_arduino_cli_commands_v1_upload_pb.SupportedUserFieldsRequest)) {
     throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SupportedUserFieldsRequest');
@@ -1276,18 +1387,6 @@ platformSearch: {
     responseSerialize: serialize_cc_arduino_cli_commands_v1_PlatformSearchResponse,
     responseDeserialize: deserialize_cc_arduino_cli_commands_v1_PlatformSearchResponse,
   },
-  // List all installed platforms.
-platformList: {
-    path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformList',
-    requestStream: false,
-    responseStream: false,
-    requestType: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest,
-    responseType: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse,
-    requestSerialize: serialize_cc_arduino_cli_commands_v1_PlatformListRequest,
-    requestDeserialize: deserialize_cc_arduino_cli_commands_v1_PlatformListRequest,
-    responseSerialize: serialize_cc_arduino_cli_commands_v1_PlatformListResponse,
-    responseDeserialize: deserialize_cc_arduino_cli_commands_v1_PlatformListResponse,
-  },
   // Download the archive file of an Arduino library in the libraries index to
 // the staging directory.
 libraryDownload: {
@@ -1470,5 +1569,77 @@ getDebugConfig: {
     responseSerialize: serialize_cc_arduino_cli_commands_v1_GetDebugConfigResponse,
     responseDeserialize: deserialize_cc_arduino_cli_commands_v1_GetDebugConfigResponse,
   },
+  // List all the settings.
+settingsGetAll: {
+    path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsGetAll',
+    requestStream: false,
+    responseStream: false,
+    requestType: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllRequest,
+    responseType: cc_arduino_cli_commands_v1_settings_pb.SettingsGetAllResponse,
+    requestSerialize: serialize_cc_arduino_cli_commands_v1_SettingsGetAllRequest,
+    requestDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsGetAllRequest,
+    responseSerialize: serialize_cc_arduino_cli_commands_v1_SettingsGetAllResponse,
+    responseDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsGetAllResponse,
+  },
+  // Set multiple settings values at once.
+settingsMerge: {
+    path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsMerge',
+    requestStream: false,
+    responseStream: false,
+    requestType: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeRequest,
+    responseType: cc_arduino_cli_commands_v1_settings_pb.SettingsMergeResponse,
+    requestSerialize: serialize_cc_arduino_cli_commands_v1_SettingsMergeRequest,
+    requestDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsMergeRequest,
+    responseSerialize: serialize_cc_arduino_cli_commands_v1_SettingsMergeResponse,
+    responseDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsMergeResponse,
+  },
+  // Get the value of a specific setting.
+settingsGetValue: {
+    path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsGetValue',
+    requestStream: false,
+    responseStream: false,
+    requestType: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueRequest,
+    responseType: cc_arduino_cli_commands_v1_settings_pb.SettingsGetValueResponse,
+    requestSerialize: serialize_cc_arduino_cli_commands_v1_SettingsGetValueRequest,
+    requestDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsGetValueRequest,
+    responseSerialize: serialize_cc_arduino_cli_commands_v1_SettingsGetValueResponse,
+    responseDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsGetValueResponse,
+  },
+  // Set the value of a specific setting.
+settingsSetValue: {
+    path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsSetValue',
+    requestStream: false,
+    responseStream: false,
+    requestType: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueRequest,
+    responseType: cc_arduino_cli_commands_v1_settings_pb.SettingsSetValueResponse,
+    requestSerialize: serialize_cc_arduino_cli_commands_v1_SettingsSetValueRequest,
+    requestDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsSetValueRequest,
+    responseSerialize: serialize_cc_arduino_cli_commands_v1_SettingsSetValueResponse,
+    responseDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsSetValueResponse,
+  },
+  // Writes to file settings currently stored in memory
+settingsWrite: {
+    path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsWrite',
+    requestStream: false,
+    responseStream: false,
+    requestType: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteRequest,
+    responseType: cc_arduino_cli_commands_v1_settings_pb.SettingsWriteResponse,
+    requestSerialize: serialize_cc_arduino_cli_commands_v1_SettingsWriteRequest,
+    requestDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsWriteRequest,
+    responseSerialize: serialize_cc_arduino_cli_commands_v1_SettingsWriteResponse,
+    responseDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsWriteResponse,
+  },
+  // Deletes an entry and rewrites the file settings
+settingsDelete: {
+    path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsDelete',
+    requestStream: false,
+    responseStream: false,
+    requestType: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteRequest,
+    responseType: cc_arduino_cli_commands_v1_settings_pb.SettingsDeleteResponse,
+    requestSerialize: serialize_cc_arduino_cli_commands_v1_SettingsDeleteRequest,
+    requestDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsDeleteRequest,
+    responseSerialize: serialize_cc_arduino_cli_commands_v1_SettingsDeleteResponse,
+    responseDeserialize: deserialize_cc_arduino_cli_commands_v1_SettingsDeleteResponse,
+  },
 };
 
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_pb.d.ts
index 981a4c793..79e01e887 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_pb.d.ts
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_pb.d.ts
@@ -14,6 +14,7 @@ import * as cc_arduino_cli_commands_v1_debug_pb from "../../../../../cc/arduino/
 import * as cc_arduino_cli_commands_v1_monitor_pb from "../../../../../cc/arduino/cli/commands/v1/monitor_pb";
 import * as cc_arduino_cli_commands_v1_upload_pb from "../../../../../cc/arduino/cli/commands/v1/upload_pb";
 import * as cc_arduino_cli_commands_v1_lib_pb from "../../../../../cc/arduino/cli/commands/v1/lib_pb";
+import * as cc_arduino_cli_commands_v1_settings_pb from "../../../../../cc/arduino/cli/commands/v1/settings_pb";
 
 export class CreateRequest extends jspb.Message { 
 
@@ -421,61 +422,12 @@ export namespace LoadSketchRequest {
     }
 }
 
-export class SketchProfile extends jspb.Message { 
-    getName(): string;
-    setName(value: string): SketchProfile;
-    getFqbn(): string;
-    setFqbn(value: string): SketchProfile;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): SketchProfile.AsObject;
-    static toObject(includeInstance: boolean, msg: SketchProfile): SketchProfile.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: SketchProfile, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): SketchProfile;
-    static deserializeBinaryFromReader(message: SketchProfile, reader: jspb.BinaryReader): SketchProfile;
-}
-
-export namespace SketchProfile {
-    export type AsObject = {
-        name: string,
-        fqbn: string,
-    }
-}
-
 export class LoadSketchResponse extends jspb.Message { 
-    getMainFile(): string;
-    setMainFile(value: string): LoadSketchResponse;
-    getLocationPath(): string;
-    setLocationPath(value: string): LoadSketchResponse;
-    clearOtherSketchFilesList(): void;
-    getOtherSketchFilesList(): Array<string>;
-    setOtherSketchFilesList(value: Array<string>): LoadSketchResponse;
-    addOtherSketchFiles(value: string, index?: number): string;
-    clearAdditionalFilesList(): void;
-    getAdditionalFilesList(): Array<string>;
-    setAdditionalFilesList(value: Array<string>): LoadSketchResponse;
-    addAdditionalFiles(value: string, index?: number): string;
-    clearRootFolderFilesList(): void;
-    getRootFolderFilesList(): Array<string>;
-    setRootFolderFilesList(value: Array<string>): LoadSketchResponse;
-    addRootFolderFiles(value: string, index?: number): string;
-    getDefaultFqbn(): string;
-    setDefaultFqbn(value: string): LoadSketchResponse;
-    getDefaultPort(): string;
-    setDefaultPort(value: string): LoadSketchResponse;
-    getDefaultProtocol(): string;
-    setDefaultProtocol(value: string): LoadSketchResponse;
-    clearProfilesList(): void;
-    getProfilesList(): Array<SketchProfile>;
-    setProfilesList(value: Array<SketchProfile>): LoadSketchResponse;
-    addProfiles(value?: SketchProfile, index?: number): SketchProfile;
-
-    hasDefaultProfile(): boolean;
-    clearDefaultProfile(): void;
-    getDefaultProfile(): SketchProfile | undefined;
-    setDefaultProfile(value?: SketchProfile): LoadSketchResponse;
+
+    hasSketch(): boolean;
+    clearSketch(): void;
+    getSketch(): cc_arduino_cli_commands_v1_common_pb.Sketch | undefined;
+    setSketch(value?: cc_arduino_cli_commands_v1_common_pb.Sketch): LoadSketchResponse;
 
     serializeBinary(): Uint8Array;
     toObject(includeInstance?: boolean): LoadSketchResponse.AsObject;
@@ -489,16 +441,7 @@ export class LoadSketchResponse extends jspb.Message {
 
 export namespace LoadSketchResponse {
     export type AsObject = {
-        mainFile: string,
-        locationPath: string,
-        otherSketchFilesList: Array<string>,
-        additionalFilesList: Array<string>,
-        rootFolderFilesList: Array<string>,
-        defaultFqbn: string,
-        defaultPort: string,
-        defaultProtocol: string,
-        profilesList: Array<SketchProfile.AsObject>,
-        defaultProfile?: SketchProfile.AsObject,
+        sketch?: cc_arduino_cli_commands_v1_common_pb.Sketch.AsObject,
     }
 }
 
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_pb.js
index 7c8f9d694..ebc76506d 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/commands_pb.js
@@ -39,6 +39,8 @@ var cc_arduino_cli_commands_v1_upload_pb = require('../../../../../cc/arduino/cl
 goog.object.extend(proto, cc_arduino_cli_commands_v1_upload_pb);
 var cc_arduino_cli_commands_v1_lib_pb = require('../../../../../cc/arduino/cli/commands/v1/lib_pb.js');
 goog.object.extend(proto, cc_arduino_cli_commands_v1_lib_pb);
+var cc_arduino_cli_commands_v1_settings_pb = require('../../../../../cc/arduino/cli/commands/v1/settings_pb.js');
+goog.object.extend(proto, cc_arduino_cli_commands_v1_settings_pb);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.ArchiveSketchRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.ArchiveSketchResponse', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.CreateRequest', null, global);
@@ -57,7 +59,6 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.NewSketchRequest', null, glo
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.NewSketchResponse', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SketchProfile', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UpdateIndexRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UpdateIndexResponse', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UpdateLibrariesIndexRequest', null, global);
@@ -421,27 +422,6 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.cc.arduino.cli.commands.v1.LoadSketchRequest.displayName = 'proto.cc.arduino.cli.commands.v1.LoadSketchRequest';
 }
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.cc.arduino.cli.commands.v1.SketchProfile, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.cc.arduino.cli.commands.v1.SketchProfile.displayName = 'proto.cc.arduino.cli.commands.v1.SketchProfile';
-}
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -453,7 +433,7 @@ if (goog.DEBUG && !COMPILED) {
  * @constructor
  */
 proto.cc.arduino.cli.commands.v1.LoadSketchResponse = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.cc.arduino.cli.commands.v1.LoadSketchResponse.repeatedFields_, null);
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
 goog.inherits(proto.cc.arduino.cli.commands.v1.LoadSketchResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
@@ -3222,173 +3202,6 @@ proto.cc.arduino.cli.commands.v1.LoadSketchRequest.prototype.setSketchPath = fun
 
 
 
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.commands.v1.SketchProfile.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    fqbn: jspb.Message.getFieldWithDefault(msg, 2, "")
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.commands.v1.SketchProfile;
-  return proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setFqbn(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getFqbn();
-  if (f.length > 0) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile} returns this
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * optional string fqbn = 2;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.getFqbn = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile} returns this
- */
-proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.setFqbn = function(value) {
-  return jspb.Message.setProto3StringField(this, 2, value);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.repeatedFields_ = [3,4,5,9];
-
-
-
 if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
  * Creates an object representation of this proto.
@@ -3418,17 +3231,7 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.toObject = functio
  */
 proto.cc.arduino.cli.commands.v1.LoadSketchResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
-    mainFile: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    locationPath: jspb.Message.getFieldWithDefault(msg, 2, ""),
-    otherSketchFilesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
-    additionalFilesList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f,
-    rootFolderFilesList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
-    defaultFqbn: jspb.Message.getFieldWithDefault(msg, 6, ""),
-    defaultPort: jspb.Message.getFieldWithDefault(msg, 7, ""),
-    defaultProtocol: jspb.Message.getFieldWithDefault(msg, 8, ""),
-    profilesList: jspb.Message.toObjectList(msg.getProfilesList(),
-    proto.cc.arduino.cli.commands.v1.SketchProfile.toObject, includeInstance),
-    defaultProfile: (f = msg.getDefaultProfile()) && proto.cc.arduino.cli.commands.v1.SketchProfile.toObject(includeInstance, f)
+    sketch: (f = msg.getSketch()) && cc_arduino_cli_commands_v1_common_pb.Sketch.toObject(includeInstance, f)
   };
 
   if (includeInstance) {
@@ -3466,46 +3269,9 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.deserializeBinaryFromReader
     var field = reader.getFieldNumber();
     switch (field) {
     case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setMainFile(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setLocationPath(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addOtherSketchFiles(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addAdditionalFiles(value);
-      break;
-    case 5:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addRootFolderFiles(value);
-      break;
-    case 6:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDefaultFqbn(value);
-      break;
-    case 7:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDefaultPort(value);
-      break;
-    case 8:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDefaultProtocol(value);
-      break;
-    case 9:
-      var value = new proto.cc.arduino.cli.commands.v1.SketchProfile;
-      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader);
-      msg.addProfiles(value);
-      break;
-    case 10:
-      var value = new proto.cc.arduino.cli.commands.v1.SketchProfile;
-      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader);
-      msg.setDefaultProfile(value);
+      var value = new cc_arduino_cli_commands_v1_common_pb.Sketch;
+      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Sketch.deserializeBinaryFromReader);
+      msg.setSketch(value);
       break;
     default:
       reader.skipField();
@@ -3536,336 +3302,33 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.serializeBinary =
  */
 proto.cc.arduino.cli.commands.v1.LoadSketchResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
-  f = message.getMainFile();
-  if (f.length > 0) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getLocationPath();
-  if (f.length > 0) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = message.getOtherSketchFilesList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      3,
-      f
-    );
-  }
-  f = message.getAdditionalFilesList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      4,
-      f
-    );
-  }
-  f = message.getRootFolderFilesList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      5,
-      f
-    );
-  }
-  f = message.getDefaultFqbn();
-  if (f.length > 0) {
-    writer.writeString(
-      6,
-      f
-    );
-  }
-  f = message.getDefaultPort();
-  if (f.length > 0) {
-    writer.writeString(
-      7,
-      f
-    );
-  }
-  f = message.getDefaultProtocol();
-  if (f.length > 0) {
-    writer.writeString(
-      8,
-      f
-    );
-  }
-  f = message.getProfilesList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      9,
-      f,
-      proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter
-    );
-  }
-  f = message.getDefaultProfile();
+  f = message.getSketch();
   if (f != null) {
     writer.writeMessage(
-      10,
+      1,
       f,
-      proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter
+      cc_arduino_cli_commands_v1_common_pb.Sketch.serializeBinaryToWriter
     );
   }
 };
 
 
 /**
- * optional string main_file = 1;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getMainFile = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setMainFile = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
-};
-
-
-/**
- * optional string location_path = 2;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getLocationPath = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
+ * optional Sketch sketch = 1;
+ * @return {?proto.cc.arduino.cli.commands.v1.Sketch}
  */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setLocationPath = function(value) {
-  return jspb.Message.setProto3StringField(this, 2, value);
+proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getSketch = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.Sketch} */ (
+    jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Sketch, 1));
 };
 
 
 /**
- * repeated string other_sketch_files = 3;
- * @return {!Array<string>}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getOtherSketchFilesList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setOtherSketchFilesList = function(value) {
-  return jspb.Message.setField(this, 3, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.addOtherSketchFiles = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearOtherSketchFilesList = function() {
-  return this.setOtherSketchFilesList([]);
-};
-
-
-/**
- * repeated string additional_files = 4;
- * @return {!Array<string>}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getAdditionalFilesList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 4));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setAdditionalFilesList = function(value) {
-  return jspb.Message.setField(this, 4, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.addAdditionalFiles = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearAdditionalFilesList = function() {
-  return this.setAdditionalFilesList([]);
-};
-
-
-/**
- * repeated string root_folder_files = 5;
- * @return {!Array<string>}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getRootFolderFilesList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 5));
-};
-
-
-/**
- * @param {!Array<string>} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setRootFolderFilesList = function(value) {
-  return jspb.Message.setField(this, 5, value || []);
-};
-
-
-/**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.addRootFolderFiles = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearRootFolderFilesList = function() {
-  return this.setRootFolderFilesList([]);
-};
-
-
-/**
- * optional string default_fqbn = 6;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getDefaultFqbn = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultFqbn = function(value) {
-  return jspb.Message.setProto3StringField(this, 6, value);
-};
-
-
-/**
- * optional string default_port = 7;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getDefaultPort = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultPort = function(value) {
-  return jspb.Message.setProto3StringField(this, 7, value);
-};
-
-
-/**
- * optional string default_protocol = 8;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getDefaultProtocol = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultProtocol = function(value) {
-  return jspb.Message.setProto3StringField(this, 8, value);
-};
-
-
-/**
- * repeated SketchProfile profiles = 9;
- * @return {!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getProfilesList = function() {
-  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.SketchProfile, 9));
-};
-
-
-/**
- * @param {!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>} value
+ * @param {?proto.cc.arduino.cli.commands.v1.Sketch|undefined} value
  * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
 */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setProfilesList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 9, value);
-};
-
-
-/**
- * @param {!proto.cc.arduino.cli.commands.v1.SketchProfile=} opt_value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.addProfiles = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 9, opt_value, proto.cc.arduino.cli.commands.v1.SketchProfile, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearProfilesList = function() {
-  return this.setProfilesList([]);
-};
-
-
-/**
- * optional SketchProfile default_profile = 10;
- * @return {?proto.cc.arduino.cli.commands.v1.SketchProfile}
- */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getDefaultProfile = function() {
-  return /** @type{?proto.cc.arduino.cli.commands.v1.SketchProfile} */ (
-    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.SketchProfile, 10));
-};
-
-
-/**
- * @param {?proto.cc.arduino.cli.commands.v1.SketchProfile|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
-*/
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultProfile = function(value) {
-  return jspb.Message.setWrapperField(this, 10, value);
+proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setSketch = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
 };
 
 
@@ -3873,8 +3336,8 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultProfile
  * Clears the message field making it undefined.
  * @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
  */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearDefaultProfile = function() {
-  return this.setDefaultProfile(undefined);
+proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearSketch = function() {
+  return this.setSketch(undefined);
 };
 
 
@@ -3882,8 +3345,8 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearDefaultProfil
  * Returns whether this field is set.
  * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.hasDefaultProfile = function() {
-  return jspb.Message.getField(this, 10) != null;
+proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.hasSketch = function() {
+  return jspb.Message.getField(this, 1) != null;
 };
 
 
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/common_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/common_pb.d.ts
index 76437e03f..686aaddc7 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/common_pb.d.ts
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/common_pb.d.ts
@@ -213,68 +213,154 @@ export namespace MissingProgrammerError {
 }
 
 export class Platform extends jspb.Message { 
+
+    hasMetadata(): boolean;
+    clearMetadata(): void;
+    getMetadata(): PlatformMetadata | undefined;
+    setMetadata(value?: PlatformMetadata): Platform;
+
+    hasRelease(): boolean;
+    clearRelease(): void;
+    getRelease(): PlatformRelease | undefined;
+    setRelease(value?: PlatformRelease): Platform;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): Platform.AsObject;
+    static toObject(includeInstance: boolean, msg: Platform): Platform.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: Platform, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): Platform;
+    static deserializeBinaryFromReader(message: Platform, reader: jspb.BinaryReader): Platform;
+}
+
+export namespace Platform {
+    export type AsObject = {
+        metadata?: PlatformMetadata.AsObject,
+        release?: PlatformRelease.AsObject,
+    }
+}
+
+export class PlatformSummary extends jspb.Message { 
+
+    hasMetadata(): boolean;
+    clearMetadata(): void;
+    getMetadata(): PlatformMetadata | undefined;
+    setMetadata(value?: PlatformMetadata): PlatformSummary;
+
+    getReleasesMap(): jspb.Map<string, PlatformRelease>;
+    clearReleasesMap(): void;
+    getInstalledVersion(): string;
+    setInstalledVersion(value: string): PlatformSummary;
+    getLatestVersion(): string;
+    setLatestVersion(value: string): PlatformSummary;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): PlatformSummary.AsObject;
+    static toObject(includeInstance: boolean, msg: PlatformSummary): PlatformSummary.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: PlatformSummary, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): PlatformSummary;
+    static deserializeBinaryFromReader(message: PlatformSummary, reader: jspb.BinaryReader): PlatformSummary;
+}
+
+export namespace PlatformSummary {
+    export type AsObject = {
+        metadata?: PlatformMetadata.AsObject,
+
+        releasesMap: Array<[string, PlatformRelease.AsObject]>,
+        installedVersion: string,
+        latestVersion: string,
+    }
+}
+
+export class PlatformMetadata extends jspb.Message { 
     getId(): string;
-    setId(value: string): Platform;
-    getInstalled(): string;
-    setInstalled(value: string): Platform;
-    getLatest(): string;
-    setLatest(value: string): Platform;
-    getName(): string;
-    setName(value: string): Platform;
+    setId(value: string): PlatformMetadata;
     getMaintainer(): string;
-    setMaintainer(value: string): Platform;
+    setMaintainer(value: string): PlatformMetadata;
     getWebsite(): string;
-    setWebsite(value: string): Platform;
+    setWebsite(value: string): PlatformMetadata;
     getEmail(): string;
-    setEmail(value: string): Platform;
-    clearBoardsList(): void;
-    getBoardsList(): Array<Board>;
-    setBoardsList(value: Array<Board>): Platform;
-    addBoards(value?: Board, index?: number): Board;
+    setEmail(value: string): PlatformMetadata;
     getManuallyInstalled(): boolean;
-    setManuallyInstalled(value: boolean): Platform;
+    setManuallyInstalled(value: boolean): PlatformMetadata;
     getDeprecated(): boolean;
-    setDeprecated(value: boolean): Platform;
+    setDeprecated(value: boolean): PlatformMetadata;
+    getIndexed(): boolean;
+    setIndexed(value: boolean): PlatformMetadata;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): PlatformMetadata.AsObject;
+    static toObject(includeInstance: boolean, msg: PlatformMetadata): PlatformMetadata.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: PlatformMetadata, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): PlatformMetadata;
+    static deserializeBinaryFromReader(message: PlatformMetadata, reader: jspb.BinaryReader): PlatformMetadata;
+}
+
+export namespace PlatformMetadata {
+    export type AsObject = {
+        id: string,
+        maintainer: string,
+        website: string,
+        email: string,
+        manuallyInstalled: boolean,
+        deprecated: boolean,
+        indexed: boolean,
+    }
+}
+
+export class PlatformRelease extends jspb.Message { 
+    getName(): string;
+    setName(value: string): PlatformRelease;
+    getVersion(): string;
+    setVersion(value: string): PlatformRelease;
     clearTypeList(): void;
     getTypeList(): Array<string>;
-    setTypeList(value: Array<string>): Platform;
+    setTypeList(value: Array<string>): PlatformRelease;
     addType(value: string, index?: number): string;
+    getInstalled(): boolean;
+    setInstalled(value: boolean): PlatformRelease;
+    clearBoardsList(): void;
+    getBoardsList(): Array<Board>;
+    setBoardsList(value: Array<Board>): PlatformRelease;
+    addBoards(value?: Board, index?: number): Board;
 
     hasHelp(): boolean;
     clearHelp(): void;
     getHelp(): HelpResources | undefined;
-    setHelp(value?: HelpResources): Platform;
-    getIndexed(): boolean;
-    setIndexed(value: boolean): Platform;
+    setHelp(value?: HelpResources): PlatformRelease;
     getMissingMetadata(): boolean;
-    setMissingMetadata(value: boolean): Platform;
+    setMissingMetadata(value: boolean): PlatformRelease;
+    getDeprecated(): boolean;
+    setDeprecated(value: boolean): PlatformRelease;
+    getCompatible(): boolean;
+    setCompatible(value: boolean): PlatformRelease;
 
     serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): Platform.AsObject;
-    static toObject(includeInstance: boolean, msg: Platform): Platform.AsObject;
+    toObject(includeInstance?: boolean): PlatformRelease.AsObject;
+    static toObject(includeInstance: boolean, msg: PlatformRelease): PlatformRelease.AsObject;
     static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
     static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: Platform, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): Platform;
-    static deserializeBinaryFromReader(message: Platform, reader: jspb.BinaryReader): Platform;
+    static serializeBinaryToWriter(message: PlatformRelease, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): PlatformRelease;
+    static deserializeBinaryFromReader(message: PlatformRelease, reader: jspb.BinaryReader): PlatformRelease;
 }
 
-export namespace Platform {
+export namespace PlatformRelease {
     export type AsObject = {
-        id: string,
-        installed: string,
-        latest: string,
         name: string,
-        maintainer: string,
-        website: string,
-        email: string,
-        boardsList: Array<Board.AsObject>,
-        manuallyInstalled: boolean,
-        deprecated: boolean,
+        version: string,
         typeList: Array<string>,
+        installed: boolean,
+        boardsList: Array<Board.AsObject>,
         help?: HelpResources.AsObject,
-        indexed: boolean,
         missingMetadata: boolean,
+        deprecated: boolean,
+        compatible: boolean,
     }
 }
 
@@ -372,3 +458,84 @@ export namespace HelpResources {
         online: string,
     }
 }
+
+export class Sketch extends jspb.Message { 
+    getMainFile(): string;
+    setMainFile(value: string): Sketch;
+    getLocationPath(): string;
+    setLocationPath(value: string): Sketch;
+    clearOtherSketchFilesList(): void;
+    getOtherSketchFilesList(): Array<string>;
+    setOtherSketchFilesList(value: Array<string>): Sketch;
+    addOtherSketchFiles(value: string, index?: number): string;
+    clearAdditionalFilesList(): void;
+    getAdditionalFilesList(): Array<string>;
+    setAdditionalFilesList(value: Array<string>): Sketch;
+    addAdditionalFiles(value: string, index?: number): string;
+    clearRootFolderFilesList(): void;
+    getRootFolderFilesList(): Array<string>;
+    setRootFolderFilesList(value: Array<string>): Sketch;
+    addRootFolderFiles(value: string, index?: number): string;
+    getDefaultFqbn(): string;
+    setDefaultFqbn(value: string): Sketch;
+    getDefaultPort(): string;
+    setDefaultPort(value: string): Sketch;
+    getDefaultProtocol(): string;
+    setDefaultProtocol(value: string): Sketch;
+    clearProfilesList(): void;
+    getProfilesList(): Array<SketchProfile>;
+    setProfilesList(value: Array<SketchProfile>): Sketch;
+    addProfiles(value?: SketchProfile, index?: number): SketchProfile;
+
+    hasDefaultProfile(): boolean;
+    clearDefaultProfile(): void;
+    getDefaultProfile(): SketchProfile | undefined;
+    setDefaultProfile(value?: SketchProfile): Sketch;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): Sketch.AsObject;
+    static toObject(includeInstance: boolean, msg: Sketch): Sketch.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: Sketch, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): Sketch;
+    static deserializeBinaryFromReader(message: Sketch, reader: jspb.BinaryReader): Sketch;
+}
+
+export namespace Sketch {
+    export type AsObject = {
+        mainFile: string,
+        locationPath: string,
+        otherSketchFilesList: Array<string>,
+        additionalFilesList: Array<string>,
+        rootFolderFilesList: Array<string>,
+        defaultFqbn: string,
+        defaultPort: string,
+        defaultProtocol: string,
+        profilesList: Array<SketchProfile.AsObject>,
+        defaultProfile?: SketchProfile.AsObject,
+    }
+}
+
+export class SketchProfile extends jspb.Message { 
+    getName(): string;
+    setName(value: string): SketchProfile;
+    getFqbn(): string;
+    setFqbn(value: string): SketchProfile;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SketchProfile.AsObject;
+    static toObject(includeInstance: boolean, msg: SketchProfile): SketchProfile.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SketchProfile, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SketchProfile;
+    static deserializeBinaryFromReader(message: SketchProfile, reader: jspb.BinaryReader): SketchProfile;
+}
+
+export namespace SketchProfile {
+    export type AsObject = {
+        name: string,
+        fqbn: string,
+    }
+}
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/common_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/common_pb.js
index 3f7418a1d..d30df0410 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/common_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/common_pb.js
@@ -32,8 +32,13 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.InstalledPlatformReference',
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Instance', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MissingProgrammerError', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Platform', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformMetadata', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformRelease', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformSummary', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Profile', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Programmer', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Sketch', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SketchProfile', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.TaskProgress', null, global);
 /**
  * Generated by JsPbCodeGenerator.
@@ -214,7 +219,7 @@ if (goog.DEBUG && !COMPILED) {
  * @constructor
  */
 proto.cc.arduino.cli.commands.v1.Platform = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.cc.arduino.cli.commands.v1.Platform.repeatedFields_, null);
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
 goog.inherits(proto.cc.arduino.cli.commands.v1.Platform, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
@@ -224,6 +229,69 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.cc.arduino.cli.commands.v1.Platform.displayName = 'proto.cc.arduino.cli.commands.v1.Platform';
 }
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.PlatformSummary = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.PlatformSummary, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.PlatformSummary.displayName = 'proto.cc.arduino.cli.commands.v1.PlatformSummary';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.PlatformMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.PlatformMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.PlatformMetadata.displayName = 'proto.cc.arduino.cli.commands.v1.PlatformMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.cc.arduino.cli.commands.v1.PlatformRelease.repeatedFields_, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.PlatformRelease, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.PlatformRelease.displayName = 'proto.cc.arduino.cli.commands.v1.PlatformRelease';
+}
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -308,6 +376,48 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.cc.arduino.cli.commands.v1.HelpResources.displayName = 'proto.cc.arduino.cli.commands.v1.HelpResources';
 }
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.Sketch = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.cc.arduino.cli.commands.v1.Sketch.repeatedFields_, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.Sketch, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.Sketch.displayName = 'proto.cc.arduino.cli.commands.v1.Sketch';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.SketchProfile = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.SketchProfile, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.SketchProfile.displayName = 'proto.cc.arduino.cli.commands.v1.SketchProfile';
+}
 
 
 
@@ -1710,13 +1820,6 @@ proto.cc.arduino.cli.commands.v1.MissingProgrammerError.serializeBinaryToWriter
 
 
 
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.cc.arduino.cli.commands.v1.Platform.repeatedFields_ = [8,11];
-
 
 
 if (jspb.Message.GENERATE_TO_OBJECT) {
@@ -1748,21 +1851,8 @@ proto.cc.arduino.cli.commands.v1.Platform.prototype.toObject = function(opt_incl
  */
 proto.cc.arduino.cli.commands.v1.Platform.toObject = function(includeInstance, msg) {
   var f, obj = {
-    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    installed: jspb.Message.getFieldWithDefault(msg, 2, ""),
-    latest: jspb.Message.getFieldWithDefault(msg, 3, ""),
-    name: jspb.Message.getFieldWithDefault(msg, 4, ""),
-    maintainer: jspb.Message.getFieldWithDefault(msg, 5, ""),
-    website: jspb.Message.getFieldWithDefault(msg, 6, ""),
-    email: jspb.Message.getFieldWithDefault(msg, 7, ""),
-    boardsList: jspb.Message.toObjectList(msg.getBoardsList(),
-    proto.cc.arduino.cli.commands.v1.Board.toObject, includeInstance),
-    manuallyInstalled: jspb.Message.getBooleanFieldWithDefault(msg, 9, false),
-    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 10, false),
-    typeList: (f = jspb.Message.getRepeatedField(msg, 11)) == null ? undefined : f,
-    help: (f = msg.getHelp()) && proto.cc.arduino.cli.commands.v1.HelpResources.toObject(includeInstance, f),
-    indexed: jspb.Message.getBooleanFieldWithDefault(msg, 13, false),
-    missingMetadata: jspb.Message.getBooleanFieldWithDefault(msg, 14, false)
+    metadata: (f = msg.getMetadata()) && proto.cc.arduino.cli.commands.v1.PlatformMetadata.toObject(includeInstance, f),
+    release: (f = msg.getRelease()) && proto.cc.arduino.cli.commands.v1.PlatformRelease.toObject(includeInstance, f)
   };
 
   if (includeInstance) {
@@ -1800,62 +1890,14 @@ proto.cc.arduino.cli.commands.v1.Platform.deserializeBinaryFromReader = function
     var field = reader.getFieldNumber();
     switch (field) {
     case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setId(value);
+      var value = new proto.cc.arduino.cli.commands.v1.PlatformMetadata;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.PlatformMetadata.deserializeBinaryFromReader);
+      msg.setMetadata(value);
       break;
     case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setInstalled(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setLatest(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    case 5:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setMaintainer(value);
-      break;
-    case 6:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setWebsite(value);
-      break;
-    case 7:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setEmail(value);
-      break;
-    case 8:
-      var value = new proto.cc.arduino.cli.commands.v1.Board;
-      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.Board.deserializeBinaryFromReader);
-      msg.addBoards(value);
-      break;
-    case 9:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setManuallyInstalled(value);
-      break;
-    case 10:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setDeprecated(value);
-      break;
-    case 11:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addType(value);
-      break;
-    case 12:
-      var value = new proto.cc.arduino.cli.commands.v1.HelpResources;
-      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinaryFromReader);
-      msg.setHelp(value);
-      break;
-    case 13:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setIndexed(value);
-      break;
-    case 14:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setMissingMetadata(value);
+      var value = new proto.cc.arduino.cli.commands.v1.PlatformRelease;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.PlatformRelease.deserializeBinaryFromReader);
+      msg.setRelease(value);
       break;
     default:
       reader.skipField();
@@ -1886,416 +1928,340 @@ proto.cc.arduino.cli.commands.v1.Platform.prototype.serializeBinary = function()
  */
 proto.cc.arduino.cli.commands.v1.Platform.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
-  f = message.getId();
-  if (f.length > 0) {
-    writer.writeString(
+  f = message.getMetadata();
+  if (f != null) {
+    writer.writeMessage(
       1,
-      f
-    );
-  }
-  f = message.getInstalled();
-  if (f.length > 0) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = message.getLatest();
-  if (f.length > 0) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-  f = message.getName();
-  if (f.length > 0) {
-    writer.writeString(
-      4,
-      f
-    );
-  }
-  f = message.getMaintainer();
-  if (f.length > 0) {
-    writer.writeString(
-      5,
-      f
-    );
-  }
-  f = message.getWebsite();
-  if (f.length > 0) {
-    writer.writeString(
-      6,
-      f
-    );
-  }
-  f = message.getEmail();
-  if (f.length > 0) {
-    writer.writeString(
-      7,
-      f
-    );
-  }
-  f = message.getBoardsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      8,
       f,
-      proto.cc.arduino.cli.commands.v1.Board.serializeBinaryToWriter
-    );
-  }
-  f = message.getManuallyInstalled();
-  if (f) {
-    writer.writeBool(
-      9,
-      f
-    );
-  }
-  f = message.getDeprecated();
-  if (f) {
-    writer.writeBool(
-      10,
-      f
+      proto.cc.arduino.cli.commands.v1.PlatformMetadata.serializeBinaryToWriter
     );
   }
-  f = message.getTypeList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      11,
-      f
-    );
-  }
-  f = message.getHelp();
+  f = message.getRelease();
   if (f != null) {
     writer.writeMessage(
-      12,
+      2,
       f,
-      proto.cc.arduino.cli.commands.v1.HelpResources.serializeBinaryToWriter
-    );
-  }
-  f = message.getIndexed();
-  if (f) {
-    writer.writeBool(
-      13,
-      f
-    );
-  }
-  f = message.getMissingMetadata();
-  if (f) {
-    writer.writeBool(
-      14,
-      f
+      proto.cc.arduino.cli.commands.v1.PlatformRelease.serializeBinaryToWriter
     );
   }
 };
 
 
 /**
- * optional string id = 1;
- * @return {string}
+ * optional PlatformMetadata metadata = 1;
+ * @return {?proto.cc.arduino.cli.commands.v1.PlatformMetadata}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getId = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+proto.cc.arduino.cli.commands.v1.Platform.prototype.getMetadata = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.PlatformMetadata} */ (
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.PlatformMetadata, 1));
 };
 
 
 /**
- * @param {string} value
+ * @param {?proto.cc.arduino.cli.commands.v1.PlatformMetadata|undefined} value
  * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setId = function(value) {
-  return jspb.Message.setProto3StringField(this, 1, value);
+*/
+proto.cc.arduino.cli.commands.v1.Platform.prototype.setMetadata = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
 };
 
 
 /**
- * optional string installed = 2;
- * @return {string}
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getInstalled = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+proto.cc.arduino.cli.commands.v1.Platform.prototype.clearMetadata = function() {
+  return this.setMetadata(undefined);
 };
 
 
 /**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * Returns whether this field is set.
+ * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setInstalled = function(value) {
-  return jspb.Message.setProto3StringField(this, 2, value);
+proto.cc.arduino.cli.commands.v1.Platform.prototype.hasMetadata = function() {
+  return jspb.Message.getField(this, 1) != null;
 };
 
 
 /**
- * optional string latest = 3;
- * @return {string}
+ * optional PlatformRelease release = 2;
+ * @return {?proto.cc.arduino.cli.commands.v1.PlatformRelease}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getLatest = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+proto.cc.arduino.cli.commands.v1.Platform.prototype.getRelease = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.PlatformRelease} */ (
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.PlatformRelease, 2));
 };
 
 
 /**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setLatest = function(value) {
-  return jspb.Message.setProto3StringField(this, 3, value);
-};
-
-
-/**
- * optional string name = 4;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * @param {string} value
+ * @param {?proto.cc.arduino.cli.commands.v1.PlatformRelease|undefined} value
  * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setName = function(value) {
-  return jspb.Message.setProto3StringField(this, 4, value);
-};
-
-
-/**
- * optional string maintainer = 5;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getMaintainer = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setMaintainer = function(value) {
-  return jspb.Message.setProto3StringField(this, 5, value);
-};
-
-
-/**
- * optional string website = 6;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getWebsite = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+*/
+proto.cc.arduino.cli.commands.v1.Platform.prototype.setRelease = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
 };
 
 
 /**
- * @param {string} value
+ * Clears the message field making it undefined.
  * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setWebsite = function(value) {
-  return jspb.Message.setProto3StringField(this, 6, value);
-};
-
-
-/**
- * optional string email = 7;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getEmail = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+proto.cc.arduino.cli.commands.v1.Platform.prototype.clearRelease = function() {
+  return this.setRelease(undefined);
 };
 
 
 /**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * Returns whether this field is set.
+ * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setEmail = function(value) {
-  return jspb.Message.setProto3StringField(this, 7, value);
+proto.cc.arduino.cli.commands.v1.Platform.prototype.hasRelease = function() {
+  return jspb.Message.getField(this, 2) != null;
 };
 
 
-/**
- * repeated Board boards = 8;
- * @return {!Array<!proto.cc.arduino.cli.commands.v1.Board>}
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getBoardsList = function() {
-  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.Board>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.Board, 8));
-};
-
 
-/**
- * @param {!Array<!proto.cc.arduino.cli.commands.v1.Board>} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
-*/
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setBoardsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 8, value);
-};
 
 
+if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * @param {!proto.cc.arduino.cli.commands.v1.Board=} opt_value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.Board}
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.addBoards = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 8, opt_value, proto.cc.arduino.cli.commands.v1.Board, opt_index);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.PlatformSummary.toObject(opt_includeInstance, this);
 };
 
 
 /**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformSummary} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.clearBoardsList = function() {
-  return this.setBoardsList([]);
-};
-
+proto.cc.arduino.cli.commands.v1.PlatformSummary.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    metadata: (f = msg.getMetadata()) && proto.cc.arduino.cli.commands.v1.PlatformMetadata.toObject(includeInstance, f),
+    releasesMap: (f = msg.getReleasesMap()) ? f.toObject(includeInstance, proto.cc.arduino.cli.commands.v1.PlatformRelease.toObject) : [],
+    installedVersion: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    latestVersion: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
 
-/**
- * optional bool manually_installed = 9;
- * @return {boolean}
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getManuallyInstalled = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 9, false));
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
 };
+}
 
 
 /**
- * @param {boolean} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformSummary}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setManuallyInstalled = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 9, value);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.PlatformSummary;
+  return proto.cc.arduino.cli.commands.v1.PlatformSummary.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
- * optional bool deprecated = 10;
- * @return {boolean}
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformSummary} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformSummary}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getDeprecated = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 10, false));
+proto.cc.arduino.cli.commands.v1.PlatformSummary.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.cc.arduino.cli.commands.v1.PlatformMetadata;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.PlatformMetadata.deserializeBinaryFromReader);
+      msg.setMetadata(value);
+      break;
+    case 2:
+      var value = msg.getReleasesMap();
+      reader.readMessage(value, function(message, reader) {
+        jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readMessage, proto.cc.arduino.cli.commands.v1.PlatformRelease.deserializeBinaryFromReader, "", new proto.cc.arduino.cli.commands.v1.PlatformRelease());
+         });
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInstalledVersion(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLatestVersion(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
 };
 
 
 /**
- * @param {boolean} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setDeprecated = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 10, value);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.PlatformSummary.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
 };
 
 
 /**
- * repeated string type = 11;
- * @return {!Array<string>}
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformSummary} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getTypeList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 11));
+proto.cc.arduino.cli.commands.v1.PlatformSummary.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMetadata();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.cc.arduino.cli.commands.v1.PlatformMetadata.serializeBinaryToWriter
+    );
+  }
+  f = message.getReleasesMap(true);
+  if (f && f.getLength() > 0) {
+    f.serializeBinary(2, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeMessage, proto.cc.arduino.cli.commands.v1.PlatformRelease.serializeBinaryToWriter);
+  }
+  f = message.getInstalledVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getLatestVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
 };
 
 
 /**
- * @param {!Array<string>} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * optional PlatformMetadata metadata = 1;
+ * @return {?proto.cc.arduino.cli.commands.v1.PlatformMetadata}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setTypeList = function(value) {
-  return jspb.Message.setField(this, 11, value || []);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.getMetadata = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.PlatformMetadata} */ (
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.PlatformMetadata, 1));
 };
 
 
 /**
- * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
- */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.addType = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 11, value, opt_index);
+ * @param {?proto.cc.arduino.cli.commands.v1.PlatformMetadata|undefined} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformSummary} returns this
+*/
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.setMetadata = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
 };
 
 
 /**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformSummary} returns this
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.clearTypeList = function() {
-  return this.setTypeList([]);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.clearMetadata = function() {
+  return this.setMetadata(undefined);
 };
 
 
 /**
- * optional HelpResources help = 12;
- * @return {?proto.cc.arduino.cli.commands.v1.HelpResources}
+ * Returns whether this field is set.
+ * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getHelp = function() {
-  return /** @type{?proto.cc.arduino.cli.commands.v1.HelpResources} */ (
-    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.HelpResources, 12));
-};
-
-
-/**
- * @param {?proto.cc.arduino.cli.commands.v1.HelpResources|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
-*/
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setHelp = function(value) {
-  return jspb.Message.setWrapperField(this, 12, value);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.hasMetadata = function() {
+  return jspb.Message.getField(this, 1) != null;
 };
 
 
 /**
- * Clears the message field making it undefined.
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * map<string, PlatformRelease> releases = 2;
+ * @param {boolean=} opt_noLazyCreate Do not create the map if
+ * empty, instead returning `undefined`
+ * @return {!jspb.Map<string,!proto.cc.arduino.cli.commands.v1.PlatformRelease>}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.clearHelp = function() {
-  return this.setHelp(undefined);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.getReleasesMap = function(opt_noLazyCreate) {
+  return /** @type {!jspb.Map<string,!proto.cc.arduino.cli.commands.v1.PlatformRelease>} */ (
+      jspb.Message.getMapField(this, 2, opt_noLazyCreate,
+      proto.cc.arduino.cli.commands.v1.PlatformRelease));
 };
 
 
 /**
- * Returns whether this field is set.
- * @return {boolean}
+ * Clears values from the map. The map will be non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformSummary} returns this
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.hasHelp = function() {
-  return jspb.Message.getField(this, 12) != null;
-};
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.clearReleasesMap = function() {
+  this.getReleasesMap().clear();
+  return this;};
 
 
 /**
- * optional bool indexed = 13;
- * @return {boolean}
+ * optional string installed_version = 3;
+ * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getIndexed = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 13, false));
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.getInstalledVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
 };
 
 
 /**
- * @param {boolean} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformSummary} returns this
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setIndexed = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 13, value);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.setInstalledVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
 };
 
 
 /**
- * optional bool missing_metadata = 14;
- * @return {boolean}
+ * optional string latest_version = 4;
+ * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.getMissingMetadata = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 14, false));
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.getLatestVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
 };
 
 
 /**
- * @param {boolean} value
- * @return {!proto.cc.arduino.cli.commands.v1.Platform} returns this
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformSummary} returns this
  */
-proto.cc.arduino.cli.commands.v1.Platform.prototype.setMissingMetadata = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 14, value);
+proto.cc.arduino.cli.commands.v1.PlatformSummary.prototype.setLatestVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
 };
 
 
@@ -2315,8 +2281,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.PlatformMetadata.toObject(opt_includeInstance, this);
 };
 
 
@@ -2325,16 +2291,19 @@ proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.toObject =
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.toObject = function(includeInstance, msg) {
   var f, obj = {
     id: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    version: jspb.Message.getFieldWithDefault(msg, 2, ""),
-    installDir: jspb.Message.getFieldWithDefault(msg, 3, ""),
-    packageUrl: jspb.Message.getFieldWithDefault(msg, 4, "")
+    maintainer: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    website: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    email: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    manuallyInstalled: jspb.Message.getBooleanFieldWithDefault(msg, 5, false),
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 6, false),
+    indexed: jspb.Message.getBooleanFieldWithDefault(msg, 7, false)
   };
 
   if (includeInstance) {
@@ -2348,23 +2317,23 @@ proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.toObject = function(
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference}
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata}
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.commands.v1.InstalledPlatformReference;
-  return proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.PlatformMetadata;
+  return proto.cc.arduino.cli.commands.v1.PlatformMetadata.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference}
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata}
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -2377,15 +2346,27 @@ proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.deserializeBinaryFro
       break;
     case 2:
       var value = /** @type {string} */ (reader.readString());
-      msg.setVersion(value);
+      msg.setMaintainer(value);
       break;
     case 3:
       var value = /** @type {string} */ (reader.readString());
-      msg.setInstallDir(value);
+      msg.setWebsite(value);
       break;
     case 4:
       var value = /** @type {string} */ (reader.readString());
-      msg.setPackageUrl(value);
+      msg.setEmail(value);
+      break;
+    case 5:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setManuallyInstalled(value);
+      break;
+    case 6:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 7:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIndexed(value);
       break;
     default:
       reader.skipField();
@@ -2400,9 +2381,9 @@ proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.deserializeBinaryFro
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.PlatformMetadata.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -2410,11 +2391,11 @@ proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.serializeB
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} message
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getId();
   if (f.length > 0) {
@@ -2423,102 +2404,184 @@ proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.serializeBinaryToWri
       f
     );
   }
-  f = message.getVersion();
+  f = message.getMaintainer();
   if (f.length > 0) {
     writer.writeString(
       2,
       f
     );
   }
-  f = message.getInstallDir();
+  f = message.getWebsite();
   if (f.length > 0) {
     writer.writeString(
       3,
       f
     );
   }
-  f = message.getPackageUrl();
+  f = message.getEmail();
   if (f.length > 0) {
     writer.writeString(
       4,
       f
     );
   }
-};
-
-
-/**
- * optional string id = 1;
- * @return {string}
+  f = message.getManuallyInstalled();
+  if (f) {
+    writer.writeBool(
+      5,
+      f
+    );
+  }
+  f = message.getDeprecated();
+  if (f) {
+    writer.writeBool(
+      6,
+      f
+    );
+  }
+  f = message.getIndexed();
+  if (f) {
+    writer.writeBool(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.getId = function() {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.getId = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} returns this
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.setId = function(value) {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.setId = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
 
 /**
- * optional string version = 2;
+ * optional string maintainer = 2;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.getVersion = function() {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.getMaintainer = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} returns this
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.setVersion = function(value) {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.setMaintainer = function(value) {
   return jspb.Message.setProto3StringField(this, 2, value);
 };
 
 
 /**
- * optional string install_dir = 3;
+ * optional string website = 3;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.getInstallDir = function() {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.getWebsite = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} returns this
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.setInstallDir = function(value) {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.setWebsite = function(value) {
   return jspb.Message.setProto3StringField(this, 3, value);
 };
 
 
 /**
- * optional string package_url = 4;
+ * optional string email = 4;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.getPackageUrl = function() {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.getEmail = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} returns this
  */
-proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.setPackageUrl = function(value) {
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.setEmail = function(value) {
   return jspb.Message.setProto3StringField(this, 4, value);
 };
 
 
+/**
+ * optional bool manually_installed = 5;
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.getManuallyInstalled = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.setManuallyInstalled = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 5, value);
+};
+
+
+/**
+ * optional bool deprecated = 6;
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 6, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.setDeprecated = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 6, value);
+};
+
+
+/**
+ * optional bool indexed = 7;
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.getIndexed = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 7, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformMetadata} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformMetadata.prototype.setIndexed = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 7, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.repeatedFields_ = [3,5];
 
 
 
@@ -2535,8 +2598,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.commands.v1.Board.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.commands.v1.Board.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.PlatformRelease.toObject(opt_includeInstance, this);
 };
 
 
@@ -2545,14 +2608,22 @@ proto.cc.arduino.cli.commands.v1.Board.prototype.toObject = function(opt_include
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.commands.v1.Board} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformRelease} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.Board.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.toObject = function(includeInstance, msg) {
   var f, obj = {
     name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    fqbn: jspb.Message.getFieldWithDefault(msg, 2, "")
+    version: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    typeList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    installed: jspb.Message.getBooleanFieldWithDefault(msg, 4, false),
+    boardsList: jspb.Message.toObjectList(msg.getBoardsList(),
+    proto.cc.arduino.cli.commands.v1.Board.toObject, includeInstance),
+    help: (f = msg.getHelp()) && proto.cc.arduino.cli.commands.v1.HelpResources.toObject(includeInstance, f),
+    missingMetadata: jspb.Message.getBooleanFieldWithDefault(msg, 7, false),
+    deprecated: jspb.Message.getBooleanFieldWithDefault(msg, 8, false),
+    compatible: jspb.Message.getBooleanFieldWithDefault(msg, 9, false)
   };
 
   if (includeInstance) {
@@ -2566,23 +2637,23 @@ proto.cc.arduino.cli.commands.v1.Board.toObject = function(includeInstance, msg)
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.commands.v1.Board}
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease}
  */
-proto.cc.arduino.cli.commands.v1.Board.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.commands.v1.Board;
-  return proto.cc.arduino.cli.commands.v1.Board.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.PlatformRelease;
+  return proto.cc.arduino.cli.commands.v1.PlatformRelease.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.commands.v1.Board} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformRelease} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.commands.v1.Board}
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease}
  */
-proto.cc.arduino.cli.commands.v1.Board.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -2595,7 +2666,37 @@ proto.cc.arduino.cli.commands.v1.Board.deserializeBinaryFromReader = function(ms
       break;
     case 2:
       var value = /** @type {string} */ (reader.readString());
-      msg.setFqbn(value);
+      msg.setVersion(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addType(value);
+      break;
+    case 4:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setInstalled(value);
+      break;
+    case 5:
+      var value = new proto.cc.arduino.cli.commands.v1.Board;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.Board.deserializeBinaryFromReader);
+      msg.addBoards(value);
+      break;
+    case 6:
+      var value = new proto.cc.arduino.cli.commands.v1.HelpResources;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinaryFromReader);
+      msg.setHelp(value);
+      break;
+    case 7:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setMissingMetadata(value);
+      break;
+    case 8:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDeprecated(value);
+      break;
+    case 9:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setCompatible(value);
       break;
     default:
       reader.skipField();
@@ -2610,9 +2711,9 @@ proto.cc.arduino.cli.commands.v1.Board.deserializeBinaryFromReader = function(ms
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.commands.v1.Board.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.Board.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.PlatformRelease.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -2620,11 +2721,11 @@ proto.cc.arduino.cli.commands.v1.Board.prototype.serializeBinary = function() {
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.Board} message
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformRelease} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.Board.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getName();
   if (f.length > 0) {
@@ -2633,13 +2734,64 @@ proto.cc.arduino.cli.commands.v1.Board.serializeBinaryToWriter = function(messag
       f
     );
   }
-  f = message.getFqbn();
+  f = message.getVersion();
   if (f.length > 0) {
     writer.writeString(
       2,
       f
     );
   }
+  f = message.getTypeList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getInstalled();
+  if (f) {
+    writer.writeBool(
+      4,
+      f
+    );
+  }
+  f = message.getBoardsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      5,
+      f,
+      proto.cc.arduino.cli.commands.v1.Board.serializeBinaryToWriter
+    );
+  }
+  f = message.getHelp();
+  if (f != null) {
+    writer.writeMessage(
+      6,
+      f,
+      proto.cc.arduino.cli.commands.v1.HelpResources.serializeBinaryToWriter
+    );
+  }
+  f = message.getMissingMetadata();
+  if (f) {
+    writer.writeBool(
+      7,
+      f
+    );
+  }
+  f = message.getDeprecated();
+  if (f) {
+    writer.writeBool(
+      8,
+      f
+    );
+  }
+  f = message.getCompatible();
+  if (f) {
+    writer.writeBool(
+      9,
+      f
+    );
+  }
 };
 
 
@@ -2647,115 +2799,1019 @@ proto.cc.arduino.cli.commands.v1.Board.serializeBinaryToWriter = function(messag
  * optional string name = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.Board.prototype.getName = function() {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getName = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.Board} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
  */
-proto.cc.arduino.cli.commands.v1.Board.prototype.setName = function(value) {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setName = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
 
 /**
- * optional string fqbn = 2;
+ * optional string version = 2;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.Board.prototype.getFqbn = function() {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getVersion = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.Board} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
  */
-proto.cc.arduino.cli.commands.v1.Board.prototype.setFqbn = function(value) {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setVersion = function(value) {
   return jspb.Message.setProto3StringField(this, 2, value);
 };
 
 
+/**
+ * repeated string type = 3;
+ * @return {!Array<string>}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getTypeList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
 
 
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
+ * @param {!Array<string>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
  */
-proto.cc.arduino.cli.commands.v1.Profile.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.commands.v1.Profile.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setTypeList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
 };
 
 
 /**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.commands.v1.Profile} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
  */
-proto.cc.arduino.cli.commands.v1.Profile.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    fqbn: jspb.Message.getFieldWithDefault(msg, 2, "")
-  };
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.addType = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
 
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.clearTypeList = function() {
+  return this.setTypeList([]);
 };
-}
 
 
 /**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.commands.v1.Profile}
+ * optional bool installed = 4;
+ * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.Profile.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.commands.v1.Profile;
-  return proto.cc.arduino.cli.commands.v1.Profile.deserializeBinaryFromReader(msg, reader);
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getInstalled = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));
 };
 
 
 /**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.commands.v1.Profile} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.commands.v1.Profile}
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
  */
-proto.cc.arduino.cli.commands.v1.Profile.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setInstalled = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 4, value);
+};
+
+
+/**
+ * repeated Board boards = 5;
+ * @return {!Array<!proto.cc.arduino.cli.commands.v1.Board>}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getBoardsList = function() {
+  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.Board>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.Board, 5));
+};
+
+
+/**
+ * @param {!Array<!proto.cc.arduino.cli.commands.v1.Board>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
+*/
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setBoardsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 5, value);
+};
+
+
+/**
+ * @param {!proto.cc.arduino.cli.commands.v1.Board=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.Board}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.addBoards = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.cc.arduino.cli.commands.v1.Board, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.clearBoardsList = function() {
+  return this.setBoardsList([]);
+};
+
+
+/**
+ * optional HelpResources help = 6;
+ * @return {?proto.cc.arduino.cli.commands.v1.HelpResources}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getHelp = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.HelpResources} */ (
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.HelpResources, 6));
+};
+
+
+/**
+ * @param {?proto.cc.arduino.cli.commands.v1.HelpResources|undefined} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
+*/
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setHelp = function(value) {
+  return jspb.Message.setWrapperField(this, 6, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.clearHelp = function() {
+  return this.setHelp(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.hasHelp = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+/**
+ * optional bool missing_metadata = 7;
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getMissingMetadata = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 7, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setMissingMetadata = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 7, value);
+};
+
+
+/**
+ * optional bool deprecated = 8;
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getDeprecated = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 8, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setDeprecated = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 8, value);
+};
+
+
+/**
+ * optional bool compatible = 9;
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.getCompatible = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 9, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformRelease} returns this
+ */
+proto.cc.arduino.cli.commands.v1.PlatformRelease.prototype.setCompatible = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 9, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    id: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    version: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    installDir: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    packageUrl: jspb.Message.getFieldWithDefault(msg, 4, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference}
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.InstalledPlatformReference;
+  return proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference}
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setId(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setVersion(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInstallDir(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPackageUrl(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getId();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getVersion();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getInstallDir();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getPackageUrl();
+  if (f.length > 0) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.getId = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} returns this
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.setId = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string version = 2;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.getVersion = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} returns this
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.setVersion = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string install_dir = 3;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.getInstallDir = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} returns this
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.setInstallDir = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional string package_url = 4;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.getPackageUrl = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} returns this
+ */
+proto.cc.arduino.cli.commands.v1.InstalledPlatformReference.prototype.setPackageUrl = function(value) {
+  return jspb.Message.setProto3StringField(this, 4, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.cc.arduino.cli.commands.v1.Board.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.Board.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.Board} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.Board.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    fqbn: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.Board}
+ */
+proto.cc.arduino.cli.commands.v1.Board.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.Board;
+  return proto.cc.arduino.cli.commands.v1.Board.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.Board} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.Board}
+ */
+proto.cc.arduino.cli.commands.v1.Board.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFqbn(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.Board.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.Board.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.Board} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.Board.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getFqbn();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.Board.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Board} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Board.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string fqbn = 2;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.Board.prototype.getFqbn = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Board} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Board.prototype.setFqbn = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.cc.arduino.cli.commands.v1.Profile.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.Profile.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.Profile} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.Profile.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    fqbn: jspb.Message.getFieldWithDefault(msg, 2, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.Profile}
+ */
+proto.cc.arduino.cli.commands.v1.Profile.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.Profile;
+  return proto.cc.arduino.cli.commands.v1.Profile.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.Profile} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.Profile}
+ */
+proto.cc.arduino.cli.commands.v1.Profile.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFqbn(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.Profile.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.Profile.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.Profile} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.Profile.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getFqbn();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.Profile.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Profile} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Profile.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string fqbn = 2;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.Profile.prototype.getFqbn = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Profile} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Profile.prototype.setFqbn = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.cc.arduino.cli.commands.v1.HelpResources.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.HelpResources.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.HelpResources} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.HelpResources.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    online: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.HelpResources}
+ */
+proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.HelpResources;
+  return proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.HelpResources} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.HelpResources}
+ */
+proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
       break;
     }
     var field = reader.getFieldNumber();
     switch (field) {
     case 1:
       var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
+      msg.setOnline(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.HelpResources.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.HelpResources.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.HelpResources} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.HelpResources.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOnline();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string online = 1;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.HelpResources.prototype.getOnline = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.HelpResources} returns this
+ */
+proto.cc.arduino.cli.commands.v1.HelpResources.prototype.setOnline = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.repeatedFields_ = [3,4,5,9];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.Sketch.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.Sketch} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    mainFile: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    locationPath: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    otherSketchFilesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
+    additionalFilesList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f,
+    rootFolderFilesList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
+    defaultFqbn: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    defaultPort: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    defaultProtocol: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    profilesList: jspb.Message.toObjectList(msg.getProfilesList(),
+    proto.cc.arduino.cli.commands.v1.SketchProfile.toObject, includeInstance),
+    defaultProfile: (f = msg.getDefaultProfile()) && proto.cc.arduino.cli.commands.v1.SketchProfile.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.Sketch;
+  return proto.cc.arduino.cli.commands.v1.Sketch.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.Sketch} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMainFile(value);
       break;
     case 2:
       var value = /** @type {string} */ (reader.readString());
-      msg.setFqbn(value);
+      msg.setLocationPath(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addOtherSketchFiles(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addAdditionalFiles(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addRootFolderFiles(value);
+      break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDefaultFqbn(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDefaultPort(value);
+      break;
+    case 8:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDefaultProtocol(value);
+      break;
+    case 9:
+      var value = new proto.cc.arduino.cli.commands.v1.SketchProfile;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader);
+      msg.addProfiles(value);
+      break;
+    case 10:
+      var value = new proto.cc.arduino.cli.commands.v1.SketchProfile;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader);
+      msg.setDefaultProfile(value);
       break;
     default:
       reader.skipField();
@@ -2770,9 +3826,9 @@ proto.cc.arduino.cli.commands.v1.Profile.deserializeBinaryFromReader = function(
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.commands.v1.Profile.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.Profile.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.Sketch.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -2780,65 +3836,363 @@ proto.cc.arduino.cli.commands.v1.Profile.prototype.serializeBinary = function()
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.Profile} message
+ * @param {!proto.cc.arduino.cli.commands.v1.Sketch} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.Profile.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.Sketch.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
-  f = message.getName();
+  f = message.getMainFile();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getLocationPath();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getOtherSketchFilesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      3,
+      f
+    );
+  }
+  f = message.getAdditionalFilesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      4,
+      f
+    );
+  }
+  f = message.getRootFolderFilesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      5,
+      f
+    );
+  }
+  f = message.getDefaultFqbn();
   if (f.length > 0) {
     writer.writeString(
-      1,
+      6,
       f
     );
   }
-  f = message.getFqbn();
+  f = message.getDefaultPort();
   if (f.length > 0) {
     writer.writeString(
-      2,
+      7,
+      f
+    );
+  }
+  f = message.getDefaultProtocol();
+  if (f.length > 0) {
+    writer.writeString(
+      8,
       f
     );
   }
+  f = message.getProfilesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      9,
+      f,
+      proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter
+    );
+  }
+  f = message.getDefaultProfile();
+  if (f != null) {
+    writer.writeMessage(
+      10,
+      f,
+      proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter
+    );
+  }
 };
 
 
 /**
- * optional string name = 1;
+ * optional string main_file = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.Profile.prototype.getName = function() {
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getMainFile = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.Profile} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
  */
-proto.cc.arduino.cli.commands.v1.Profile.prototype.setName = function(value) {
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setMainFile = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
 
 /**
- * optional string fqbn = 2;
+ * optional string location_path = 2;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.Profile.prototype.getFqbn = function() {
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getLocationPath = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.Profile} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
  */
-proto.cc.arduino.cli.commands.v1.Profile.prototype.setFqbn = function(value) {
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setLocationPath = function(value) {
   return jspb.Message.setProto3StringField(this, 2, value);
 };
 
 
+/**
+ * repeated string other_sketch_files = 3;
+ * @return {!Array<string>}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getOtherSketchFilesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setOtherSketchFilesList = function(value) {
+  return jspb.Message.setField(this, 3, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.addOtherSketchFiles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 3, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.clearOtherSketchFilesList = function() {
+  return this.setOtherSketchFilesList([]);
+};
+
+
+/**
+ * repeated string additional_files = 4;
+ * @return {!Array<string>}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getAdditionalFilesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 4));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setAdditionalFilesList = function(value) {
+  return jspb.Message.setField(this, 4, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.addAdditionalFiles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.clearAdditionalFilesList = function() {
+  return this.setAdditionalFilesList([]);
+};
+
+
+/**
+ * repeated string root_folder_files = 5;
+ * @return {!Array<string>}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getRootFolderFilesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 5));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setRootFolderFilesList = function(value) {
+  return jspb.Message.setField(this, 5, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.addRootFolderFiles = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 5, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.clearRootFolderFilesList = function() {
+  return this.setRootFolderFilesList([]);
+};
+
+
+/**
+ * optional string default_fqbn = 6;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getDefaultFqbn = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setDefaultFqbn = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
+/**
+ * optional string default_port = 7;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getDefaultPort = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setDefaultPort = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional string default_protocol = 8;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getDefaultProtocol = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setDefaultProtocol = function(value) {
+  return jspb.Message.setProto3StringField(this, 8, value);
+};
+
+
+/**
+ * repeated SketchProfile profiles = 9;
+ * @return {!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getProfilesList = function() {
+  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.SketchProfile, 9));
+};
+
+
+/**
+ * @param {!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+*/
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setProfilesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 9, value);
+};
+
+
+/**
+ * @param {!proto.cc.arduino.cli.commands.v1.SketchProfile=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.addProfiles = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 9, opt_value, proto.cc.arduino.cli.commands.v1.SketchProfile, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.clearProfilesList = function() {
+  return this.setProfilesList([]);
+};
+
+
+/**
+ * optional SketchProfile default_profile = 10;
+ * @return {?proto.cc.arduino.cli.commands.v1.SketchProfile}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.getDefaultProfile = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.SketchProfile} */ (
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.SketchProfile, 10));
+};
+
+
+/**
+ * @param {?proto.cc.arduino.cli.commands.v1.SketchProfile|undefined} value
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+*/
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.setDefaultProfile = function(value) {
+  return jspb.Message.setWrapperField(this, 10, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.Sketch} returns this
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.clearDefaultProfile = function() {
+  return this.setDefaultProfile(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.Sketch.prototype.hasDefaultProfile = function() {
+  return jspb.Message.getField(this, 10) != null;
+};
+
+
 
 
 
@@ -2855,8 +4209,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.commands.v1.HelpResources.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.commands.v1.HelpResources.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SketchProfile.toObject(opt_includeInstance, this);
 };
 
 
@@ -2865,13 +4219,14 @@ proto.cc.arduino.cli.commands.v1.HelpResources.prototype.toObject = function(opt
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.commands.v1.HelpResources} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.HelpResources.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SketchProfile.toObject = function(includeInstance, msg) {
   var f, obj = {
-    online: jspb.Message.getFieldWithDefault(msg, 1, "")
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    fqbn: jspb.Message.getFieldWithDefault(msg, 2, "")
   };
 
   if (includeInstance) {
@@ -2885,23 +4240,23 @@ proto.cc.arduino.cli.commands.v1.HelpResources.toObject = function(includeInstan
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.commands.v1.HelpResources}
+ * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
  */
-proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.commands.v1.HelpResources;
-  return proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SketchProfile;
+  return proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.commands.v1.HelpResources} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.commands.v1.HelpResources}
+ * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
  */
-proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -2910,7 +4265,11 @@ proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinaryFromReader = fun
     switch (field) {
     case 1:
       var value = /** @type {string} */ (reader.readString());
-      msg.setOnline(value);
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFqbn(value);
       break;
     default:
       reader.skipField();
@@ -2925,9 +4284,9 @@ proto.cc.arduino.cli.commands.v1.HelpResources.deserializeBinaryFromReader = fun
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.commands.v1.HelpResources.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.HelpResources.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -2935,38 +4294,63 @@ proto.cc.arduino.cli.commands.v1.HelpResources.prototype.serializeBinary = funct
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.HelpResources} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.HelpResources.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
-  f = message.getOnline();
+  f = message.getName();
   if (f.length > 0) {
     writer.writeString(
       1,
       f
     );
   }
+  f = message.getFqbn();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
 };
 
 
 /**
- * optional string online = 1;
+ * optional string name = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.HelpResources.prototype.getOnline = function() {
+proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.getName = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.HelpResources} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile} returns this
  */
-proto.cc.arduino.cli.commands.v1.HelpResources.prototype.setOnline = function(value) {
+proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.setName = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
 
+/**
+ * optional string fqbn = 2;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.getFqbn = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.SketchProfile} returns this
+ */
+proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.setFqbn = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
 goog.object.extend(exports, proto.cc.arduino.cli.commands.v1);
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/compile_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/compile_pb.d.ts
index d24160005..b5e832ec0 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/compile_pb.d.ts
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/compile_pb.d.ts
@@ -116,65 +116,110 @@ export namespace CompileRequest {
 }
 
 export class CompileResponse extends jspb.Message { 
+
+    hasOutStream(): boolean;
+    clearOutStream(): void;
     getOutStream(): Uint8Array | string;
     getOutStream_asU8(): Uint8Array;
     getOutStream_asB64(): string;
     setOutStream(value: Uint8Array | string): CompileResponse;
+
+    hasErrStream(): boolean;
+    clearErrStream(): void;
     getErrStream(): Uint8Array | string;
     getErrStream_asU8(): Uint8Array;
     getErrStream_asB64(): string;
     setErrStream(value: Uint8Array | string): CompileResponse;
+
+    hasProgress(): boolean;
+    clearProgress(): void;
+    getProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
+    setProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): CompileResponse;
+
+    hasResult(): boolean;
+    clearResult(): void;
+    getResult(): BuilderResult | undefined;
+    setResult(value?: BuilderResult): CompileResponse;
+
+    getMessageCase(): CompileResponse.MessageCase;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): CompileResponse.AsObject;
+    static toObject(includeInstance: boolean, msg: CompileResponse): CompileResponse.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: CompileResponse, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): CompileResponse;
+    static deserializeBinaryFromReader(message: CompileResponse, reader: jspb.BinaryReader): CompileResponse;
+}
+
+export namespace CompileResponse {
+    export type AsObject = {
+        outStream: Uint8Array | string,
+        errStream: Uint8Array | string,
+        progress?: cc_arduino_cli_commands_v1_common_pb.TaskProgress.AsObject,
+        result?: BuilderResult.AsObject,
+    }
+
+    export enum MessageCase {
+        MESSAGE_NOT_SET = 0,
+        OUT_STREAM = 1,
+        ERR_STREAM = 2,
+        PROGRESS = 3,
+        RESULT = 4,
+    }
+
+}
+
+export class BuilderResult extends jspb.Message { 
     getBuildPath(): string;
-    setBuildPath(value: string): CompileResponse;
+    setBuildPath(value: string): BuilderResult;
     clearUsedLibrariesList(): void;
     getUsedLibrariesList(): Array<cc_arduino_cli_commands_v1_lib_pb.Library>;
-    setUsedLibrariesList(value: Array<cc_arduino_cli_commands_v1_lib_pb.Library>): CompileResponse;
+    setUsedLibrariesList(value: Array<cc_arduino_cli_commands_v1_lib_pb.Library>): BuilderResult;
     addUsedLibraries(value?: cc_arduino_cli_commands_v1_lib_pb.Library, index?: number): cc_arduino_cli_commands_v1_lib_pb.Library;
     clearExecutableSectionsSizeList(): void;
     getExecutableSectionsSizeList(): Array<ExecutableSectionSize>;
-    setExecutableSectionsSizeList(value: Array<ExecutableSectionSize>): CompileResponse;
+    setExecutableSectionsSizeList(value: Array<ExecutableSectionSize>): BuilderResult;
     addExecutableSectionsSize(value?: ExecutableSectionSize, index?: number): ExecutableSectionSize;
 
     hasBoardPlatform(): boolean;
     clearBoardPlatform(): void;
     getBoardPlatform(): cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference | undefined;
-    setBoardPlatform(value?: cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference): CompileResponse;
+    setBoardPlatform(value?: cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference): BuilderResult;
 
     hasBuildPlatform(): boolean;
     clearBuildPlatform(): void;
     getBuildPlatform(): cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference | undefined;
-    setBuildPlatform(value?: cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference): CompileResponse;
-
-    hasProgress(): boolean;
-    clearProgress(): void;
-    getProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
-    setProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): CompileResponse;
+    setBuildPlatform(value?: cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference): BuilderResult;
     clearBuildPropertiesList(): void;
     getBuildPropertiesList(): Array<string>;
-    setBuildPropertiesList(value: Array<string>): CompileResponse;
+    setBuildPropertiesList(value: Array<string>): BuilderResult;
     addBuildProperties(value: string, index?: number): string;
+    clearDiagnosticsList(): void;
+    getDiagnosticsList(): Array<CompileDiagnostic>;
+    setDiagnosticsList(value: Array<CompileDiagnostic>): BuilderResult;
+    addDiagnostics(value?: CompileDiagnostic, index?: number): CompileDiagnostic;
 
     serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): CompileResponse.AsObject;
-    static toObject(includeInstance: boolean, msg: CompileResponse): CompileResponse.AsObject;
+    toObject(includeInstance?: boolean): BuilderResult.AsObject;
+    static toObject(includeInstance: boolean, msg: BuilderResult): BuilderResult.AsObject;
     static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
     static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: CompileResponse, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): CompileResponse;
-    static deserializeBinaryFromReader(message: CompileResponse, reader: jspb.BinaryReader): CompileResponse;
+    static serializeBinaryToWriter(message: BuilderResult, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): BuilderResult;
+    static deserializeBinaryFromReader(message: BuilderResult, reader: jspb.BinaryReader): BuilderResult;
 }
 
-export namespace CompileResponse {
+export namespace BuilderResult {
     export type AsObject = {
-        outStream: Uint8Array | string,
-        errStream: Uint8Array | string,
         buildPath: string,
         usedLibrariesList: Array<cc_arduino_cli_commands_v1_lib_pb.Library.AsObject>,
         executableSectionsSizeList: Array<ExecutableSectionSize.AsObject>,
         boardPlatform?: cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.AsObject,
         buildPlatform?: cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.AsObject,
-        progress?: cc_arduino_cli_commands_v1_common_pb.TaskProgress.AsObject,
         buildPropertiesList: Array<string>,
+        diagnosticsList: Array<CompileDiagnostic.AsObject>,
     }
 }
 
@@ -203,3 +248,103 @@ export namespace ExecutableSectionSize {
         maxSize: number,
     }
 }
+
+export class CompileDiagnostic extends jspb.Message { 
+    getSeverity(): string;
+    setSeverity(value: string): CompileDiagnostic;
+    getMessage(): string;
+    setMessage(value: string): CompileDiagnostic;
+    getFile(): string;
+    setFile(value: string): CompileDiagnostic;
+    getLine(): number;
+    setLine(value: number): CompileDiagnostic;
+    getColumn(): number;
+    setColumn(value: number): CompileDiagnostic;
+    clearContextList(): void;
+    getContextList(): Array<CompileDiagnosticContext>;
+    setContextList(value: Array<CompileDiagnosticContext>): CompileDiagnostic;
+    addContext(value?: CompileDiagnosticContext, index?: number): CompileDiagnosticContext;
+    clearNotesList(): void;
+    getNotesList(): Array<CompileDiagnosticNote>;
+    setNotesList(value: Array<CompileDiagnosticNote>): CompileDiagnostic;
+    addNotes(value?: CompileDiagnosticNote, index?: number): CompileDiagnosticNote;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): CompileDiagnostic.AsObject;
+    static toObject(includeInstance: boolean, msg: CompileDiagnostic): CompileDiagnostic.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: CompileDiagnostic, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): CompileDiagnostic;
+    static deserializeBinaryFromReader(message: CompileDiagnostic, reader: jspb.BinaryReader): CompileDiagnostic;
+}
+
+export namespace CompileDiagnostic {
+    export type AsObject = {
+        severity: string,
+        message: string,
+        file: string,
+        line: number,
+        column: number,
+        contextList: Array<CompileDiagnosticContext.AsObject>,
+        notesList: Array<CompileDiagnosticNote.AsObject>,
+    }
+}
+
+export class CompileDiagnosticContext extends jspb.Message { 
+    getMessage(): string;
+    setMessage(value: string): CompileDiagnosticContext;
+    getFile(): string;
+    setFile(value: string): CompileDiagnosticContext;
+    getLine(): number;
+    setLine(value: number): CompileDiagnosticContext;
+    getColumn(): number;
+    setColumn(value: number): CompileDiagnosticContext;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): CompileDiagnosticContext.AsObject;
+    static toObject(includeInstance: boolean, msg: CompileDiagnosticContext): CompileDiagnosticContext.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: CompileDiagnosticContext, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): CompileDiagnosticContext;
+    static deserializeBinaryFromReader(message: CompileDiagnosticContext, reader: jspb.BinaryReader): CompileDiagnosticContext;
+}
+
+export namespace CompileDiagnosticContext {
+    export type AsObject = {
+        message: string,
+        file: string,
+        line: number,
+        column: number,
+    }
+}
+
+export class CompileDiagnosticNote extends jspb.Message { 
+    getMessage(): string;
+    setMessage(value: string): CompileDiagnosticNote;
+    getFile(): string;
+    setFile(value: string): CompileDiagnosticNote;
+    getLine(): number;
+    setLine(value: number): CompileDiagnosticNote;
+    getColumn(): number;
+    setColumn(value: number): CompileDiagnosticNote;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): CompileDiagnosticNote.AsObject;
+    static toObject(includeInstance: boolean, msg: CompileDiagnosticNote): CompileDiagnosticNote.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: CompileDiagnosticNote, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): CompileDiagnosticNote;
+    static deserializeBinaryFromReader(message: CompileDiagnosticNote, reader: jspb.BinaryReader): CompileDiagnosticNote;
+}
+
+export namespace CompileDiagnosticNote {
+    export type AsObject = {
+        message: string,
+        file: string,
+        line: number,
+        column: number,
+    }
+}
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/compile_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/compile_pb.js
index 7dcaad1ee..affc77361 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/compile_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/compile_pb.js
@@ -27,8 +27,13 @@ var cc_arduino_cli_commands_v1_common_pb = require('../../../../../cc/arduino/cl
 goog.object.extend(proto, cc_arduino_cli_commands_v1_common_pb);
 var cc_arduino_cli_commands_v1_lib_pb = require('../../../../../cc/arduino/cli/commands/v1/lib_pb.js');
 goog.object.extend(proto, cc_arduino_cli_commands_v1_lib_pb);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.BuilderResult', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.CompileDiagnostic', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.CompileRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.CompileResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.CompileResponse.MessageCase', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.ExecutableSectionSize', null, global);
 /**
  * Generated by JsPbCodeGenerator.
@@ -62,7 +67,7 @@ if (goog.DEBUG && !COMPILED) {
  * @constructor
  */
 proto.cc.arduino.cli.commands.v1.CompileResponse = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.cc.arduino.cli.commands.v1.CompileResponse.repeatedFields_, null);
+  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_);
 };
 goog.inherits(proto.cc.arduino.cli.commands.v1.CompileResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
@@ -72,6 +77,27 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.cc.arduino.cli.commands.v1.CompileResponse.displayName = 'proto.cc.arduino.cli.commands.v1.CompileResponse';
 }
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.cc.arduino.cli.commands.v1.BuilderResult.repeatedFields_, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.BuilderResult, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.BuilderResult.displayName = 'proto.cc.arduino.cli.commands.v1.BuilderResult';
+}
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -93,6 +119,69 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.displayName = 'proto.cc.arduino.cli.commands.v1.ExecutableSectionSize';
 }
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.cc.arduino.cli.commands.v1.CompileDiagnostic.repeatedFields_, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.CompileDiagnostic, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.CompileDiagnostic.displayName = 'proto.cc.arduino.cli.commands.v1.CompileDiagnostic';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.displayName = 'proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.displayName = 'proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote';
+}
 
 /**
  * List of repeated fields within this message type.
@@ -1054,11 +1143,32 @@ proto.cc.arduino.cli.commands.v1.CompileRequest.prototype.setDoNotExpandBuildPro
 
 
 /**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array<!Array<number>>}
  * @const
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.repeatedFields_ = [4,5,9];
+proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_ = [[1,2,3,4]];
+
+/**
+ * @enum {number}
+ */
+proto.cc.arduino.cli.commands.v1.CompileResponse.MessageCase = {
+  MESSAGE_NOT_SET: 0,
+  OUT_STREAM: 1,
+  ERR_STREAM: 2,
+  PROGRESS: 3,
+  RESULT: 4
+};
+
+/**
+ * @return {proto.cc.arduino.cli.commands.v1.CompileResponse.MessageCase}
+ */
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getMessageCase = function() {
+  return /** @type {proto.cc.arduino.cli.commands.v1.CompileResponse.MessageCase} */(jspb.Message.computeOneofCase(this, proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_[0]));
+};
 
 
 
@@ -1093,15 +1203,8 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.toObject = function(includeInst
   var f, obj = {
     outStream: msg.getOutStream_asB64(),
     errStream: msg.getErrStream_asB64(),
-    buildPath: jspb.Message.getFieldWithDefault(msg, 3, ""),
-    usedLibrariesList: jspb.Message.toObjectList(msg.getUsedLibrariesList(),
-    cc_arduino_cli_commands_v1_lib_pb.Library.toObject, includeInstance),
-    executableSectionsSizeList: jspb.Message.toObjectList(msg.getExecutableSectionsSizeList(),
-    proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject, includeInstance),
-    boardPlatform: (f = msg.getBoardPlatform()) && cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.toObject(includeInstance, f),
-    buildPlatform: (f = msg.getBuildPlatform()) && cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.toObject(includeInstance, f),
     progress: (f = msg.getProgress()) && cc_arduino_cli_commands_v1_common_pb.TaskProgress.toObject(includeInstance, f),
-    buildPropertiesList: (f = jspb.Message.getRepeatedField(msg, 9)) == null ? undefined : f
+    result: (f = msg.getResult()) && proto.cc.arduino.cli.commands.v1.BuilderResult.toObject(includeInstance, f)
   };
 
   if (includeInstance) {
@@ -1147,37 +1250,14 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.deserializeBinaryFromReader = f
       msg.setErrStream(value);
       break;
     case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setBuildPath(value);
-      break;
-    case 4:
-      var value = new cc_arduino_cli_commands_v1_lib_pb.Library;
-      reader.readMessage(value,cc_arduino_cli_commands_v1_lib_pb.Library.deserializeBinaryFromReader);
-      msg.addUsedLibraries(value);
-      break;
-    case 5:
-      var value = new proto.cc.arduino.cli.commands.v1.ExecutableSectionSize;
-      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromReader);
-      msg.addExecutableSectionsSize(value);
-      break;
-    case 6:
-      var value = new cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference;
-      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.deserializeBinaryFromReader);
-      msg.setBoardPlatform(value);
-      break;
-    case 7:
-      var value = new cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference;
-      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.deserializeBinaryFromReader);
-      msg.setBuildPlatform(value);
-      break;
-    case 8:
       var value = new cc_arduino_cli_commands_v1_common_pb.TaskProgress;
       reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.TaskProgress.deserializeBinaryFromReader);
       msg.setProgress(value);
       break;
-    case 9:
-      var value = /** @type {string} */ (reader.readString());
-      msg.addBuildProperties(value);
+    case 4:
+      var value = new proto.cc.arduino.cli.commands.v1.BuilderResult;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.BuilderResult.deserializeBinaryFromReader);
+      msg.setResult(value);
       break;
     default:
       reader.skipField();
@@ -1208,72 +1288,34 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.serializeBinary = fun
  */
 proto.cc.arduino.cli.commands.v1.CompileResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
-  f = message.getOutStream_asU8();
-  if (f.length > 0) {
+  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
     writer.writeBytes(
       1,
       f
     );
   }
-  f = message.getErrStream_asU8();
-  if (f.length > 0) {
+  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
     writer.writeBytes(
       2,
       f
     );
   }
-  f = message.getBuildPath();
-  if (f.length > 0) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-  f = message.getUsedLibrariesList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      4,
-      f,
-      cc_arduino_cli_commands_v1_lib_pb.Library.serializeBinaryToWriter
-    );
-  }
-  f = message.getExecutableSectionsSizeList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      5,
-      f,
-      proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.serializeBinaryToWriter
-    );
-  }
-  f = message.getBoardPlatform();
-  if (f != null) {
-    writer.writeMessage(
-      6,
-      f,
-      cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.serializeBinaryToWriter
-    );
-  }
-  f = message.getBuildPlatform();
+  f = message.getProgress();
   if (f != null) {
     writer.writeMessage(
-      7,
+      3,
       f,
-      cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.serializeBinaryToWriter
+      cc_arduino_cli_commands_v1_common_pb.TaskProgress.serializeBinaryToWriter
     );
   }
-  f = message.getProgress();
+  f = message.getResult();
   if (f != null) {
     writer.writeMessage(
-      8,
+      4,
       f,
-      cc_arduino_cli_commands_v1_common_pb.TaskProgress.serializeBinaryToWriter
-    );
-  }
-  f = message.getBuildPropertiesList();
-  if (f.length > 0) {
-    writer.writeRepeatedString(
-      9,
-      f
+      proto.cc.arduino.cli.commands.v1.BuilderResult.serializeBinaryToWriter
     );
   }
 };
@@ -1317,7 +1359,25 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getOutStream_asU8 = f
  * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
  */
 proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setOutStream = function(value) {
-  return jspb.Message.setProto3BytesField(this, 1, value);
+  return jspb.Message.setOneofField(this, 1, proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearOutStream = function() {
+  return jspb.Message.setOneofField(this, 1, proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasOutStream = function() {
+  return jspb.Message.getField(this, 1) != null;
 };
 
 
@@ -1359,249 +1419,1319 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getErrStream_asU8 = f
  * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
  */
 proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setErrStream = function(value) {
-  return jspb.Message.setProto3BytesField(this, 2, value);
+  return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_[0], value);
 };
 
 
 /**
- * optional string build_path = 3;
- * @return {string}
+ * Clears the field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getBuildPath = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearErrStream = function() {
+  return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_[0], undefined);
 };
 
 
 /**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * Returns whether this field is set.
+ * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setBuildPath = function(value) {
-  return jspb.Message.setProto3StringField(this, 3, value);
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasErrStream = function() {
+  return jspb.Message.getField(this, 2) != null;
 };
 
 
 /**
- * repeated Library used_libraries = 4;
- * @return {!Array<!proto.cc.arduino.cli.commands.v1.Library>}
+ * optional TaskProgress progress = 3;
+ * @return {?proto.cc.arduino.cli.commands.v1.TaskProgress}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getUsedLibrariesList = function() {
-  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.Library>} */ (
-    jspb.Message.getRepeatedWrapperField(this, cc_arduino_cli_commands_v1_lib_pb.Library, 4));
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getProgress = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.TaskProgress} */ (
+    jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.TaskProgress, 3));
 };
 
 
 /**
- * @param {!Array<!proto.cc.arduino.cli.commands.v1.Library>} value
+ * @param {?proto.cc.arduino.cli.commands.v1.TaskProgress|undefined} value
  * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
 */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setUsedLibrariesList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 4, value);
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setProgress = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 3, proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_[0], value);
 };
 
 
 /**
- * @param {!proto.cc.arduino.cli.commands.v1.Library=} opt_value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.Library}
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.addUsedLibraries = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.cc.arduino.cli.commands.v1.Library, opt_index);
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearProgress = function() {
+  return this.setProgress(undefined);
 };
 
 
 /**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * Returns whether this field is set.
+ * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearUsedLibrariesList = function() {
-  return this.setUsedLibrariesList([]);
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasProgress = function() {
+  return jspb.Message.getField(this, 3) != null;
 };
 
 
 /**
- * repeated ExecutableSectionSize executable_sections_size = 5;
- * @return {!Array<!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize>}
+ * optional BuilderResult result = 4;
+ * @return {?proto.cc.arduino.cli.commands.v1.BuilderResult}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getExecutableSectionsSizeList = function() {
-  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize>} */ (
-    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.ExecutableSectionSize, 5));
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getResult = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.BuilderResult} */ (
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.BuilderResult, 4));
 };
 
 
 /**
- * @param {!Array<!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize>} value
+ * @param {?proto.cc.arduino.cli.commands.v1.BuilderResult|undefined} value
  * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
 */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setExecutableSectionsSizeList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 5, value);
-};
-
-
-/**
- * @param {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize=} opt_value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize}
- */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.addExecutableSectionsSize = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.cc.arduino.cli.commands.v1.ExecutableSectionSize, opt_index);
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setResult = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 4, proto.cc.arduino.cli.commands.v1.CompileResponse.oneofGroups_[0], value);
 };
 
 
 /**
- * Clears the list making it empty but non-null.
+ * Clears the message field making it undefined.
  * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearExecutableSectionsSizeList = function() {
-  return this.setExecutableSectionsSizeList([]);
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearResult = function() {
+  return this.setResult(undefined);
 };
 
 
 /**
- * optional InstalledPlatformReference board_platform = 6;
- * @return {?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference}
+ * Returns whether this field is set.
+ * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getBoardPlatform = function() {
-  return /** @type{?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} */ (
-    jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference, 6));
+proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasResult = function() {
+  return jspb.Message.getField(this, 4) != null;
 };
 
 
-/**
- * @param {?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
-*/
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setBoardPlatform = function(value) {
-  return jspb.Message.setWrapperField(this, 6, value);
-};
-
 
 /**
- * Clears the message field making it undefined.
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearBoardPlatform = function() {
-  return this.setBoardPlatform(undefined);
-};
+proto.cc.arduino.cli.commands.v1.BuilderResult.repeatedFields_ = [2,3,7,8];
 
 
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * Returns whether this field is set.
- * @return {boolean}
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasBoardPlatform = function() {
-  return jspb.Message.getField(this, 6) != null;
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.BuilderResult.toObject(opt_includeInstance, this);
 };
 
 
 /**
- * optional InstalledPlatformReference build_platform = 7;
- * @return {?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference}
- */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getBuildPlatform = function() {
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.BuilderResult} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    buildPath: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    usedLibrariesList: jspb.Message.toObjectList(msg.getUsedLibrariesList(),
+    cc_arduino_cli_commands_v1_lib_pb.Library.toObject, includeInstance),
+    executableSectionsSizeList: jspb.Message.toObjectList(msg.getExecutableSectionsSizeList(),
+    proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject, includeInstance),
+    boardPlatform: (f = msg.getBoardPlatform()) && cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.toObject(includeInstance, f),
+    buildPlatform: (f = msg.getBuildPlatform()) && cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.toObject(includeInstance, f),
+    buildPropertiesList: (f = jspb.Message.getRepeatedField(msg, 7)) == null ? undefined : f,
+    diagnosticsList: jspb.Message.toObjectList(msg.getDiagnosticsList(),
+    proto.cc.arduino.cli.commands.v1.CompileDiagnostic.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.BuilderResult;
+  return proto.cc.arduino.cli.commands.v1.BuilderResult.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.BuilderResult} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setBuildPath(value);
+      break;
+    case 2:
+      var value = new cc_arduino_cli_commands_v1_lib_pb.Library;
+      reader.readMessage(value,cc_arduino_cli_commands_v1_lib_pb.Library.deserializeBinaryFromReader);
+      msg.addUsedLibraries(value);
+      break;
+    case 3:
+      var value = new proto.cc.arduino.cli.commands.v1.ExecutableSectionSize;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromReader);
+      msg.addExecutableSectionsSize(value);
+      break;
+    case 4:
+      var value = new cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference;
+      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.deserializeBinaryFromReader);
+      msg.setBoardPlatform(value);
+      break;
+    case 5:
+      var value = new cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference;
+      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.deserializeBinaryFromReader);
+      msg.setBuildPlatform(value);
+      break;
+    case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addBuildProperties(value);
+      break;
+    case 8:
+      var value = new proto.cc.arduino.cli.commands.v1.CompileDiagnostic;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.CompileDiagnostic.deserializeBinaryFromReader);
+      msg.addDiagnostics(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.BuilderResult.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.BuilderResult} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getBuildPath();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getUsedLibrariesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      2,
+      f,
+      cc_arduino_cli_commands_v1_lib_pb.Library.serializeBinaryToWriter
+    );
+  }
+  f = message.getExecutableSectionsSizeList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      3,
+      f,
+      proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.serializeBinaryToWriter
+    );
+  }
+  f = message.getBoardPlatform();
+  if (f != null) {
+    writer.writeMessage(
+      4,
+      f,
+      cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.serializeBinaryToWriter
+    );
+  }
+  f = message.getBuildPlatform();
+  if (f != null) {
+    writer.writeMessage(
+      5,
+      f,
+      cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference.serializeBinaryToWriter
+    );
+  }
+  f = message.getBuildPropertiesList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      7,
+      f
+    );
+  }
+  f = message.getDiagnosticsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      8,
+      f,
+      proto.cc.arduino.cli.commands.v1.CompileDiagnostic.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string build_path = 1;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.getBuildPath = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.setBuildPath = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * repeated Library used_libraries = 2;
+ * @return {!Array<!proto.cc.arduino.cli.commands.v1.Library>}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.getUsedLibrariesList = function() {
+  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.Library>} */ (
+    jspb.Message.getRepeatedWrapperField(this, cc_arduino_cli_commands_v1_lib_pb.Library, 2));
+};
+
+
+/**
+ * @param {!Array<!proto.cc.arduino.cli.commands.v1.Library>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+*/
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.setUsedLibrariesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 2, value);
+};
+
+
+/**
+ * @param {!proto.cc.arduino.cli.commands.v1.Library=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.Library}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.addUsedLibraries = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.cc.arduino.cli.commands.v1.Library, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.clearUsedLibrariesList = function() {
+  return this.setUsedLibrariesList([]);
+};
+
+
+/**
+ * repeated ExecutableSectionSize executable_sections_size = 3;
+ * @return {!Array<!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize>}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.getExecutableSectionsSizeList = function() {
+  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.ExecutableSectionSize, 3));
+};
+
+
+/**
+ * @param {!Array<!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+*/
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.setExecutableSectionsSizeList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 3, value);
+};
+
+
+/**
+ * @param {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.addExecutableSectionsSize = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.cc.arduino.cli.commands.v1.ExecutableSectionSize, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.clearExecutableSectionsSizeList = function() {
+  return this.setExecutableSectionsSizeList([]);
+};
+
+
+/**
+ * optional InstalledPlatformReference board_platform = 4;
+ * @return {?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.getBoardPlatform = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} */ (
+    jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference, 4));
+};
+
+
+/**
+ * @param {?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference|undefined} value
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+*/
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.setBoardPlatform = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.clearBoardPlatform = function() {
+  return this.setBoardPlatform(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.hasBoardPlatform = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional InstalledPlatformReference build_platform = 5;
+ * @return {?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.getBuildPlatform = function() {
   return /** @type{?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference} */ (
-    jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference, 7));
+    jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference, 5));
+};
+
+
+/**
+ * @param {?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference|undefined} value
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+*/
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.setBuildPlatform = function(value) {
+  return jspb.Message.setWrapperField(this, 5, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.clearBuildPlatform = function() {
+  return this.setBuildPlatform(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.hasBuildPlatform = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * repeated string build_properties = 7;
+ * @return {!Array<string>}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.getBuildPropertiesList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 7));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.setBuildPropertiesList = function(value) {
+  return jspb.Message.setField(this, 7, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.addBuildProperties = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 7, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.clearBuildPropertiesList = function() {
+  return this.setBuildPropertiesList([]);
+};
+
+
+/**
+ * repeated CompileDiagnostic diagnostics = 8;
+ * @return {!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnostic>}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.getDiagnosticsList = function() {
+  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnostic>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.CompileDiagnostic, 8));
+};
+
+
+/**
+ * @param {!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnostic>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+*/
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.setDiagnosticsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 8, value);
+};
+
+
+/**
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic}
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.addDiagnostics = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 8, opt_value, proto.cc.arduino.cli.commands.v1.CompileDiagnostic, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.BuilderResult} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BuilderResult.prototype.clearDiagnosticsList = function() {
+  return this.setDiagnosticsList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    size: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    maxSize: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize}
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.ExecutableSectionSize;
+  return proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize}
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setSize(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setMaxSize(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getSize();
+  if (f !== 0) {
+    writer.writeInt64(
+      2,
+      f
+    );
+  }
+  f = message.getMaxSize();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} returns this
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional int64 size = 2;
+ * @return {number}
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.getSize = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} returns this
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.setSize = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional int64 max_size = 3;
+ * @return {number}
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.getMaxSize = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} returns this
+ */
+proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.setMaxSize = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.repeatedFields_ = [6,7];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.CompileDiagnostic.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    severity: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    message: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    file: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    line: jspb.Message.getFieldWithDefault(msg, 4, 0),
+    column: jspb.Message.getFieldWithDefault(msg, 5, 0),
+    contextList: jspb.Message.toObjectList(msg.getContextList(),
+    proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.toObject, includeInstance),
+    notesList: jspb.Message.toObjectList(msg.getNotesList(),
+    proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.CompileDiagnostic;
+  return proto.cc.arduino.cli.commands.v1.CompileDiagnostic.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setSeverity(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMessage(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFile(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setLine(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setColumn(value);
+      break;
+    case 6:
+      var value = new proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.deserializeBinaryFromReader);
+      msg.addContext(value);
+      break;
+    case 7:
+      var value = new proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.deserializeBinaryFromReader);
+      msg.addNotes(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.CompileDiagnostic.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSeverity();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getMessage();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getFile();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = message.getLine();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+  f = message.getColumn();
+  if (f !== 0) {
+    writer.writeInt64(
+      5,
+      f
+    );
+  }
+  f = message.getContextList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      6,
+      f,
+      proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.serializeBinaryToWriter
+    );
+  }
+  f = message.getNotesList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      7,
+      f,
+      proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional string severity = 1;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.getSeverity = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.setSeverity = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string message = 2;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.getMessage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.setMessage = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string file = 3;
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.getFile = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.setFile = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+/**
+ * optional int64 line = 4;
+ * @return {number}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.getLine = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.setLine = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
+/**
+ * optional int64 column = 5;
+ * @return {number}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.getColumn = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.setColumn = function(value) {
+  return jspb.Message.setProto3IntField(this, 5, value);
+};
+
+
+/**
+ * repeated CompileDiagnosticContext context = 6;
+ * @return {!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext>}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.getContextList = function() {
+  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext, 6));
+};
+
+
+/**
+ * @param {!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
+*/
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.setContextList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 6, value);
 };
 
 
 /**
- * @param {?proto.cc.arduino.cli.commands.v1.InstalledPlatformReference|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.addContext = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.clearContextList = function() {
+  return this.setContextList([]);
+};
+
+
+/**
+ * repeated CompileDiagnosticNote notes = 7;
+ * @return {!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote>}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.getNotesList = function() {
+  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote, 7));
+};
+
+
+/**
+ * @param {!Array<!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote>} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
 */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setBuildPlatform = function(value) {
-  return jspb.Message.setWrapperField(this, 7, value);
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.setNotesList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 7, value);
 };
 
 
 /**
- * Clears the message field making it undefined.
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearBuildPlatform = function() {
-  return this.setBuildPlatform(undefined);
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.addNotes = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 7, opt_value, proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote, opt_index);
 };
 
 
 /**
- * Returns whether this field is set.
- * @return {boolean}
+ * Clears the list making it empty but non-null.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnostic} returns this
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasBuildPlatform = function() {
-  return jspb.Message.getField(this, 7) != null;
+proto.cc.arduino.cli.commands.v1.CompileDiagnostic.prototype.clearNotesList = function() {
+  return this.setNotesList([]);
 };
 
 
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * optional TaskProgress progress = 8;
- * @return {?proto.cc.arduino.cli.commands.v1.TaskProgress}
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getProgress = function() {
-  return /** @type{?proto.cc.arduino.cli.commands.v1.TaskProgress} */ (
-    jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.TaskProgress, 8));
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.toObject(opt_includeInstance, this);
 };
 
 
 /**
- * @param {?proto.cc.arduino.cli.commands.v1.TaskProgress|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
-*/
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setProgress = function(value) {
-  return jspb.Message.setWrapperField(this, 8, value);
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    message: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    file: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    line: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    column: jspb.Message.getFieldWithDefault(msg, 4, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
 };
+}
 
 
 /**
- * Clears the message field making it undefined.
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearProgress = function() {
-  return this.setProgress(undefined);
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext;
+  return proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
- * Returns whether this field is set.
- * @return {boolean}
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasProgress = function() {
-  return jspb.Message.getField(this, 8) != null;
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMessage(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFile(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setLine(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setColumn(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
 };
 
 
 /**
- * repeated string build_properties = 9;
- * @return {!Array<string>}
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getBuildPropertiesList = function() {
-  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 9));
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
 };
 
 
 /**
- * @param {!Array<string>} value
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getMessage();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getFile();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getLine();
+  if (f !== 0) {
+    writer.writeInt64(
+      3,
+      f
+    );
+  }
+  f = message.getColumn();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string message = 1;
+ * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setBuildPropertiesList = function(value) {
-  return jspb.Message.setField(this, 9, value || []);
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.getMessage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext} returns this
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.addBuildProperties = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 9, value, opt_index);
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.setMessage = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
 };
 
 
 /**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
+ * optional string file = 2;
+ * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearBuildPropertiesList = function() {
-  return this.setBuildPropertiesList([]);
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.getFile = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.setFile = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 line = 3;
+ * @return {number}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.getLine = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.setLine = function(value) {
+  return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional int64 column = 4;
+ * @return {number}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.getColumn = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticContext.prototype.setColumn = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
 };
 
 
@@ -1621,8 +2751,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.toObject(opt_includeInstance, this);
 };
 
 
@@ -1631,15 +2761,16 @@ proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.toObject = func
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.toObject = function(includeInstance, msg) {
   var f, obj = {
-    name: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    size: jspb.Message.getFieldWithDefault(msg, 2, 0),
-    maxSize: jspb.Message.getFieldWithDefault(msg, 3, 0)
+    message: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    file: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    line: jspb.Message.getFieldWithDefault(msg, 3, 0),
+    column: jspb.Message.getFieldWithDefault(msg, 4, 0)
   };
 
   if (includeInstance) {
@@ -1653,23 +2784,23 @@ proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject = function(inclu
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize}
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote}
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.commands.v1.ExecutableSectionSize;
-  return proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote;
+  return proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize}
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote}
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -1678,15 +2809,19 @@ proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromRead
     switch (field) {
     case 1:
       var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
+      msg.setMessage(value);
       break;
     case 2:
-      var value = /** @type {number} */ (reader.readInt64());
-      msg.setSize(value);
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFile(value);
       break;
     case 3:
       var value = /** @type {number} */ (reader.readInt64());
-      msg.setMaxSize(value);
+      msg.setLine(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readInt64());
+      msg.setColumn(value);
       break;
     default:
       reader.skipField();
@@ -1701,9 +2836,9 @@ proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromRead
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -1711,88 +2846,113 @@ proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.serializeBinary
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} message
+ * @param {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
-  f = message.getName();
+  f = message.getMessage();
   if (f.length > 0) {
     writer.writeString(
       1,
       f
     );
   }
-  f = message.getSize();
-  if (f !== 0) {
-    writer.writeInt64(
+  f = message.getFile();
+  if (f.length > 0) {
+    writer.writeString(
       2,
       f
     );
   }
-  f = message.getMaxSize();
+  f = message.getLine();
   if (f !== 0) {
     writer.writeInt64(
       3,
       f
     );
   }
+  f = message.getColumn();
+  if (f !== 0) {
+    writer.writeInt64(
+      4,
+      f
+    );
+  }
 };
 
 
 /**
- * optional string name = 1;
+ * optional string message = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.getName = function() {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.getMessage = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote} returns this
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.setName = function(value) {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.setMessage = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
 
 /**
- * optional int64 size = 2;
- * @return {number}
+ * optional string file = 2;
+ * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.getSize = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.getFile = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
 };
 
 
 /**
- * @param {number} value
- * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} returns this
+ * @param {string} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote} returns this
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.setSize = function(value) {
-  return jspb.Message.setProto3IntField(this, 2, value);
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.setFile = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
 };
 
 
 /**
- * optional int64 max_size = 3;
+ * optional int64 line = 3;
  * @return {number}
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.getMaxSize = function() {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.getLine = function() {
   return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
 };
 
 
 /**
  * @param {number} value
- * @return {!proto.cc.arduino.cli.commands.v1.ExecutableSectionSize} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote} returns this
  */
-proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.prototype.setMaxSize = function(value) {
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.setLine = function(value) {
   return jspb.Message.setProto3IntField(this, 3, value);
 };
 
 
+/**
+ * optional int64 column = 4;
+ * @return {number}
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.getColumn = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote} returns this
+ */
+proto.cc.arduino.cli.commands.v1.CompileDiagnosticNote.prototype.setColumn = function(value) {
+  return jspb.Message.setProto3IntField(this, 4, value);
+};
+
+
 goog.object.extend(exports, proto.cc.arduino.cli.commands.v1);
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/core_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/core_pb.d.ts
index 99b25cb15..89b28e6ee 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/core_pb.d.ts
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/core_pb.d.ts
@@ -299,8 +299,8 @@ export class PlatformSearchRequest extends jspb.Message {
     setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): PlatformSearchRequest;
     getSearchArgs(): string;
     setSearchArgs(value: string): PlatformSearchRequest;
-    getAllVersions(): boolean;
-    setAllVersions(value: boolean): PlatformSearchRequest;
+    getManuallyInstalled(): boolean;
+    setManuallyInstalled(value: boolean): PlatformSearchRequest;
 
     serializeBinary(): Uint8Array;
     toObject(includeInstance?: boolean): PlatformSearchRequest.AsObject;
@@ -316,15 +316,15 @@ export namespace PlatformSearchRequest {
     export type AsObject = {
         instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
         searchArgs: string,
-        allVersions: boolean,
+        manuallyInstalled: boolean,
     }
 }
 
 export class PlatformSearchResponse extends jspb.Message { 
     clearSearchOutputList(): void;
-    getSearchOutputList(): Array<cc_arduino_cli_commands_v1_common_pb.Platform>;
-    setSearchOutputList(value: Array<cc_arduino_cli_commands_v1_common_pb.Platform>): PlatformSearchResponse;
-    addSearchOutput(value?: cc_arduino_cli_commands_v1_common_pb.Platform, index?: number): cc_arduino_cli_commands_v1_common_pb.Platform;
+    getSearchOutputList(): Array<cc_arduino_cli_commands_v1_common_pb.PlatformSummary>;
+    setSearchOutputList(value: Array<cc_arduino_cli_commands_v1_common_pb.PlatformSummary>): PlatformSearchResponse;
+    addSearchOutput(value?: cc_arduino_cli_commands_v1_common_pb.PlatformSummary, index?: number): cc_arduino_cli_commands_v1_common_pb.PlatformSummary;
 
     serializeBinary(): Uint8Array;
     toObject(includeInstance?: boolean): PlatformSearchResponse.AsObject;
@@ -338,57 +338,6 @@ export class PlatformSearchResponse extends jspb.Message {
 
 export namespace PlatformSearchResponse {
     export type AsObject = {
-        searchOutputList: Array<cc_arduino_cli_commands_v1_common_pb.Platform.AsObject>,
-    }
-}
-
-export class PlatformListRequest extends jspb.Message { 
-
-    hasInstance(): boolean;
-    clearInstance(): void;
-    getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
-    setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): PlatformListRequest;
-    getUpdatableOnly(): boolean;
-    setUpdatableOnly(value: boolean): PlatformListRequest;
-    getAll(): boolean;
-    setAll(value: boolean): PlatformListRequest;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): PlatformListRequest.AsObject;
-    static toObject(includeInstance: boolean, msg: PlatformListRequest): PlatformListRequest.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: PlatformListRequest, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): PlatformListRequest;
-    static deserializeBinaryFromReader(message: PlatformListRequest, reader: jspb.BinaryReader): PlatformListRequest;
-}
-
-export namespace PlatformListRequest {
-    export type AsObject = {
-        instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
-        updatableOnly: boolean,
-        all: boolean,
-    }
-}
-
-export class PlatformListResponse extends jspb.Message { 
-    clearInstalledPlatformsList(): void;
-    getInstalledPlatformsList(): Array<cc_arduino_cli_commands_v1_common_pb.Platform>;
-    setInstalledPlatformsList(value: Array<cc_arduino_cli_commands_v1_common_pb.Platform>): PlatformListResponse;
-    addInstalledPlatforms(value?: cc_arduino_cli_commands_v1_common_pb.Platform, index?: number): cc_arduino_cli_commands_v1_common_pb.Platform;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): PlatformListResponse.AsObject;
-    static toObject(includeInstance: boolean, msg: PlatformListResponse): PlatformListResponse.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: PlatformListResponse, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): PlatformListResponse;
-    static deserializeBinaryFromReader(message: PlatformListResponse, reader: jspb.BinaryReader): PlatformListResponse;
-}
-
-export namespace PlatformListResponse {
-    export type AsObject = {
-        installedPlatformsList: Array<cc_arduino_cli_commands_v1_common_pb.Platform.AsObject>,
+        searchOutputList: Array<cc_arduino_cli_commands_v1_common_pb.PlatformSummary.AsObject>,
     }
 }
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/core_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/core_pb.js
index 9e49ed462..00fe8d64a 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/core_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/core_pb.js
@@ -28,8 +28,6 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformDownloadRequest', nu
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformDownloadResponse', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformInstallRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformInstallResponse', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformListRequest', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformListResponse', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformLoadingError', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformSearchRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformSearchResponse', null, global);
@@ -289,48 +287,6 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.displayName = 'proto.cc.arduino.cli.commands.v1.PlatformSearchResponse';
 }
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.cc.arduino.cli.commands.v1.PlatformListRequest, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.cc.arduino.cli.commands.v1.PlatformListRequest.displayName = 'proto.cc.arduino.cli.commands.v1.PlatformListRequest';
-}
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.cc.arduino.cli.commands.v1.PlatformListResponse.repeatedFields_, null);
-};
-goog.inherits(proto.cc.arduino.cli.commands.v1.PlatformListResponse, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.cc.arduino.cli.commands.v1.PlatformListResponse.displayName = 'proto.cc.arduino.cli.commands.v1.PlatformListResponse';
-}
 
 
 
@@ -2408,7 +2364,7 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.toObject = function(inclu
   var f, obj = {
     instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
     searchArgs: jspb.Message.getFieldWithDefault(msg, 2, ""),
-    allVersions: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
+    manuallyInstalled: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
   };
 
   if (includeInstance) {
@@ -2456,7 +2412,7 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.deserializeBinaryFromRead
       break;
     case 3:
       var value = /** @type {boolean} */ (reader.readBool());
-      msg.setAllVersions(value);
+      msg.setManuallyInstalled(value);
       break;
     default:
       reader.skipField();
@@ -2502,7 +2458,7 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.serializeBinaryToWriter =
       f
     );
   }
-  f = message.getAllVersions();
+  f = message.getManuallyInstalled();
   if (f) {
     writer.writeBool(
       3,
@@ -2568,10 +2524,10 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.prototype.setSearchArgs =
 
 
 /**
- * optional bool all_versions = 3;
+ * optional bool manually_installed = 3;
  * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.prototype.getAllVersions = function() {
+proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.prototype.getManuallyInstalled = function() {
   return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
 };
 
@@ -2580,7 +2536,7 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.prototype.getAllVersions
  * @param {boolean} value
  * @return {!proto.cc.arduino.cli.commands.v1.PlatformSearchRequest} returns this
  */
-proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.prototype.setAllVersions = function(value) {
+proto.cc.arduino.cli.commands.v1.PlatformSearchRequest.prototype.setManuallyInstalled = function(value) {
   return jspb.Message.setProto3BooleanField(this, 3, value);
 };
 
@@ -2625,7 +2581,7 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.prototype.toObject = fun
 proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
     searchOutputList: jspb.Message.toObjectList(msg.getSearchOutputList(),
-    cc_arduino_cli_commands_v1_common_pb.Platform.toObject, includeInstance)
+    cc_arduino_cli_commands_v1_common_pb.PlatformSummary.toObject, includeInstance)
   };
 
   if (includeInstance) {
@@ -2663,8 +2619,8 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.deserializeBinaryFromRea
     var field = reader.getFieldNumber();
     switch (field) {
     case 1:
-      var value = new cc_arduino_cli_commands_v1_common_pb.Platform;
-      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Platform.deserializeBinaryFromReader);
+      var value = new cc_arduino_cli_commands_v1_common_pb.PlatformSummary;
+      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.PlatformSummary.deserializeBinaryFromReader);
       msg.addSearchOutput(value);
       break;
     default:
@@ -2701,24 +2657,24 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.serializeBinaryToWriter
     writer.writeRepeatedMessage(
       1,
       f,
-      cc_arduino_cli_commands_v1_common_pb.Platform.serializeBinaryToWriter
+      cc_arduino_cli_commands_v1_common_pb.PlatformSummary.serializeBinaryToWriter
     );
   }
 };
 
 
 /**
- * repeated Platform search_output = 1;
- * @return {!Array<!proto.cc.arduino.cli.commands.v1.Platform>}
+ * repeated PlatformSummary search_output = 1;
+ * @return {!Array<!proto.cc.arduino.cli.commands.v1.PlatformSummary>}
  */
 proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.prototype.getSearchOutputList = function() {
-  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.Platform>} */ (
-    jspb.Message.getRepeatedWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Platform, 1));
+  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.PlatformSummary>} */ (
+    jspb.Message.getRepeatedWrapperField(this, cc_arduino_cli_commands_v1_common_pb.PlatformSummary, 1));
 };
 
 
 /**
- * @param {!Array<!proto.cc.arduino.cli.commands.v1.Platform>} value
+ * @param {!Array<!proto.cc.arduino.cli.commands.v1.PlatformSummary>} value
  * @return {!proto.cc.arduino.cli.commands.v1.PlatformSearchResponse} returns this
 */
 proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.prototype.setSearchOutputList = function(value) {
@@ -2727,12 +2683,12 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.prototype.setSearchOutpu
 
 
 /**
- * @param {!proto.cc.arduino.cli.commands.v1.Platform=} opt_value
+ * @param {!proto.cc.arduino.cli.commands.v1.PlatformSummary=} opt_value
  * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.Platform}
+ * @return {!proto.cc.arduino.cli.commands.v1.PlatformSummary}
  */
 proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.prototype.addSearchOutput = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.cc.arduino.cli.commands.v1.Platform, opt_index);
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.cc.arduino.cli.commands.v1.PlatformSummary, opt_index);
 };
 
 
@@ -2745,375 +2701,4 @@ proto.cc.arduino.cli.commands.v1.PlatformSearchResponse.prototype.clearSearchOut
 };
 
 
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.commands.v1.PlatformListRequest.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.commands.v1.PlatformListRequest} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
-    updatableOnly: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
-    all: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListRequest}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.commands.v1.PlatformListRequest;
-  return proto.cc.arduino.cli.commands.v1.PlatformListRequest.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.commands.v1.PlatformListRequest} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListRequest}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = new cc_arduino_cli_commands_v1_common_pb.Instance;
-      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Instance.deserializeBinaryFromReader);
-      msg.setInstance(value);
-      break;
-    case 2:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setUpdatableOnly(value);
-      break;
-    case 3:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setAll(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.PlatformListRequest.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.PlatformListRequest} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getInstance();
-  if (f != null) {
-    writer.writeMessage(
-      1,
-      f,
-      cc_arduino_cli_commands_v1_common_pb.Instance.serializeBinaryToWriter
-    );
-  }
-  f = message.getUpdatableOnly();
-  if (f) {
-    writer.writeBool(
-      2,
-      f
-    );
-  }
-  f = message.getAll();
-  if (f) {
-    writer.writeBool(
-      3,
-      f
-    );
-  }
-};
-
-
-/**
- * optional Instance instance = 1;
- * @return {?proto.cc.arduino.cli.commands.v1.Instance}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.getInstance = function() {
-  return /** @type{?proto.cc.arduino.cli.commands.v1.Instance} */ (
-    jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Instance, 1));
-};
-
-
-/**
- * @param {?proto.cc.arduino.cli.commands.v1.Instance|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListRequest} returns this
-*/
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.setInstance = function(value) {
-  return jspb.Message.setWrapperField(this, 1, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListRequest} returns this
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.clearInstance = function() {
-  return this.setInstance(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.hasInstance = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional bool updatable_only = 2;
- * @return {boolean}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.getUpdatableOnly = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListRequest} returns this
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.setUpdatableOnly = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 2, value);
-};
-
-
-/**
- * optional bool all = 3;
- * @return {boolean}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.getAll = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListRequest} returns this
- */
-proto.cc.arduino.cli.commands.v1.PlatformListRequest.prototype.setAll = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 3, value);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.repeatedFields_ = [1];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * Creates an object representation of this proto.
- * Field names that are reserved in JavaScript and will be renamed to pb_name.
- * Optional fields that are not set will be set to undefined.
- * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
- * For the list of reserved names please see:
- *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
- * @param {boolean=} opt_includeInstance Deprecated. whether to include the
- *     JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @return {!Object}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.commands.v1.PlatformListResponse.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.commands.v1.PlatformListResponse} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    installedPlatformsList: jspb.Message.toObjectList(msg.getInstalledPlatformsList(),
-    cc_arduino_cli_commands_v1_common_pb.Platform.toObject, includeInstance)
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListResponse}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.commands.v1.PlatformListResponse;
-  return proto.cc.arduino.cli.commands.v1.PlatformListResponse.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.commands.v1.PlatformListResponse} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListResponse}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = new cc_arduino_cli_commands_v1_common_pb.Platform;
-      reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Platform.deserializeBinaryFromReader);
-      msg.addInstalledPlatforms(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.PlatformListResponse.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.PlatformListResponse} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = message.getInstalledPlatformsList();
-  if (f.length > 0) {
-    writer.writeRepeatedMessage(
-      1,
-      f,
-      cc_arduino_cli_commands_v1_common_pb.Platform.serializeBinaryToWriter
-    );
-  }
-};
-
-
-/**
- * repeated Platform installed_platforms = 1;
- * @return {!Array<!proto.cc.arduino.cli.commands.v1.Platform>}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.prototype.getInstalledPlatformsList = function() {
-  return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.Platform>} */ (
-    jspb.Message.getRepeatedWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Platform, 1));
-};
-
-
-/**
- * @param {!Array<!proto.cc.arduino.cli.commands.v1.Platform>} value
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListResponse} returns this
-*/
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.prototype.setInstalledPlatformsList = function(value) {
-  return jspb.Message.setRepeatedWrapperField(this, 1, value);
-};
-
-
-/**
- * @param {!proto.cc.arduino.cli.commands.v1.Platform=} opt_value
- * @param {number=} opt_index
- * @return {!proto.cc.arduino.cli.commands.v1.Platform}
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.prototype.addInstalledPlatforms = function(opt_value, opt_index) {
-  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.cc.arduino.cli.commands.v1.Platform, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.cc.arduino.cli.commands.v1.PlatformListResponse} returns this
- */
-proto.cc.arduino.cli.commands.v1.PlatformListResponse.prototype.clearInstalledPlatformsList = function() {
-  return this.setInstalledPlatformsList([]);
-};
-
-
 goog.object.extend(exports, proto.cc.arduino.cli.commands.v1);
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/lib_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/lib_pb.d.ts
index e0b50ba58..ae018a7a3 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/lib_pb.d.ts
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/lib_pb.d.ts
@@ -298,6 +298,8 @@ export class LibraryResolveDependenciesRequest extends jspb.Message {
     setName(value: string): LibraryResolveDependenciesRequest;
     getVersion(): string;
     setVersion(value: string): LibraryResolveDependenciesRequest;
+    getDoNotUpdateInstalledLibraries(): boolean;
+    setDoNotUpdateInstalledLibraries(value: boolean): LibraryResolveDependenciesRequest;
 
     serializeBinary(): Uint8Array;
     toObject(includeInstance?: boolean): LibraryResolveDependenciesRequest.AsObject;
@@ -314,6 +316,7 @@ export namespace LibraryResolveDependenciesRequest {
         instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
         name: string,
         version: string,
+        doNotUpdateInstalledLibraries: boolean,
     }
 }
 
@@ -371,8 +374,6 @@ export class LibrarySearchRequest extends jspb.Message {
     clearInstance(): void;
     getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
     setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibrarySearchRequest;
-    getQuery(): string;
-    setQuery(value: string): LibrarySearchRequest;
     getOmitReleasesDetails(): boolean;
     setOmitReleasesDetails(value: boolean): LibrarySearchRequest;
     getSearchArgs(): string;
@@ -391,7 +392,6 @@ export class LibrarySearchRequest extends jspb.Message {
 export namespace LibrarySearchRequest {
     export type AsObject = {
         instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
-        query: string,
         omitReleasesDetails: boolean,
         searchArgs: string,
     }
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/lib_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/lib_pb.js
index 7ec2e0bbf..53d6a21b0 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/lib_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/lib_pb.js
@@ -2648,7 +2648,8 @@ proto.cc.arduino.cli.commands.v1.LibraryResolveDependenciesRequest.toObject = fu
   var f, obj = {
     instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
     name: jspb.Message.getFieldWithDefault(msg, 2, ""),
-    version: jspb.Message.getFieldWithDefault(msg, 3, "")
+    version: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    doNotUpdateInstalledLibraries: jspb.Message.getBooleanFieldWithDefault(msg, 4, false)
   };
 
   if (includeInstance) {
@@ -2698,6 +2699,10 @@ proto.cc.arduino.cli.commands.v1.LibraryResolveDependenciesRequest.deserializeBi
       var value = /** @type {string} */ (reader.readString());
       msg.setVersion(value);
       break;
+    case 4:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setDoNotUpdateInstalledLibraries(value);
+      break;
     default:
       reader.skipField();
       break;
@@ -2749,6 +2754,13 @@ proto.cc.arduino.cli.commands.v1.LibraryResolveDependenciesRequest.serializeBina
       f
     );
   }
+  f = message.getDoNotUpdateInstalledLibraries();
+  if (f) {
+    writer.writeBool(
+      4,
+      f
+    );
+  }
 };
 
 
@@ -2825,6 +2837,24 @@ proto.cc.arduino.cli.commands.v1.LibraryResolveDependenciesRequest.prototype.set
 };
 
 
+/**
+ * optional bool do_not_update_installed_libraries = 4;
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.LibraryResolveDependenciesRequest.prototype.getDoNotUpdateInstalledLibraries = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.LibraryResolveDependenciesRequest} returns this
+ */
+proto.cc.arduino.cli.commands.v1.LibraryResolveDependenciesRequest.prototype.setDoNotUpdateInstalledLibraries = function(value) {
+  return jspb.Message.setProto3BooleanField(this, 4, value);
+};
+
+
 
 /**
  * List of repeated fields within this message type.
@@ -3208,9 +3238,8 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.toObject = funct
 proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.toObject = function(includeInstance, msg) {
   var f, obj = {
     instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
-    query: jspb.Message.getFieldWithDefault(msg, 2, ""),
-    omitReleasesDetails: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
-    searchArgs: jspb.Message.getFieldWithDefault(msg, 4, "")
+    omitReleasesDetails: jspb.Message.getBooleanFieldWithDefault(msg, 2, false),
+    searchArgs: jspb.Message.getFieldWithDefault(msg, 3, "")
   };
 
   if (includeInstance) {
@@ -3253,14 +3282,10 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.deserializeBinaryFromReade
       msg.setInstance(value);
       break;
     case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setQuery(value);
-      break;
-    case 3:
       var value = /** @type {boolean} */ (reader.readBool());
       msg.setOmitReleasesDetails(value);
       break;
-    case 4:
+    case 3:
       var value = /** @type {string} */ (reader.readString());
       msg.setSearchArgs(value);
       break;
@@ -3301,24 +3326,17 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.serializeBinaryToWriter =
       cc_arduino_cli_commands_v1_common_pb.Instance.serializeBinaryToWriter
     );
   }
-  f = message.getQuery();
-  if (f.length > 0) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
   f = message.getOmitReleasesDetails();
   if (f) {
     writer.writeBool(
-      3,
+      2,
       f
     );
   }
   f = message.getSearchArgs();
   if (f.length > 0) {
     writer.writeString(
-      4,
+      3,
       f
     );
   }
@@ -3363,29 +3381,11 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.hasInstance = fu
 
 
 /**
- * optional string query = 2;
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.getQuery = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.LibrarySearchRequest} returns this
- */
-proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.setQuery = function(value) {
-  return jspb.Message.setProto3StringField(this, 2, value);
-};
-
-
-/**
- * optional bool omit_releases_details = 3;
+ * optional bool omit_releases_details = 2;
  * @return {boolean}
  */
 proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.getOmitReleasesDetails = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false));
 };
 
 
@@ -3394,16 +3394,16 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.getOmitReleasesD
  * @return {!proto.cc.arduino.cli.commands.v1.LibrarySearchRequest} returns this
  */
 proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.setOmitReleasesDetails = function(value) {
-  return jspb.Message.setProto3BooleanField(this, 3, value);
+  return jspb.Message.setProto3BooleanField(this, 2, value);
 };
 
 
 /**
- * optional string search_args = 4;
+ * optional string search_args = 3;
  * @return {string}
  */
 proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.getSearchArgs = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
 };
 
 
@@ -3412,7 +3412,7 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.getSearchArgs =
  * @return {!proto.cc.arduino.cli.commands.v1.LibrarySearchRequest} returns this
  */
 proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.setSearchArgs = function(value) {
-  return jspb.Message.setProto3StringField(this, 4, value);
+  return jspb.Message.setProto3StringField(this, 3, value);
 };
 
 
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/monitor_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/monitor_pb.d.ts
index 49140fcb5..2e298b4c8 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/monitor_pb.d.ts
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/monitor_pb.d.ts
@@ -10,26 +10,29 @@ import * as cc_arduino_cli_commands_v1_port_pb from "../../../../../cc/arduino/c
 
 export class MonitorRequest extends jspb.Message { 
 
-    hasInstance(): boolean;
-    clearInstance(): void;
-    getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
-    setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): MonitorRequest;
+    hasOpenRequest(): boolean;
+    clearOpenRequest(): void;
+    getOpenRequest(): MonitorPortOpenRequest | undefined;
+    setOpenRequest(value?: MonitorPortOpenRequest): MonitorRequest;
 
-    hasPort(): boolean;
-    clearPort(): void;
-    getPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
-    setPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): MonitorRequest;
-    getFqbn(): string;
-    setFqbn(value: string): MonitorRequest;
+    hasTxData(): boolean;
+    clearTxData(): void;
     getTxData(): Uint8Array | string;
     getTxData_asU8(): Uint8Array;
     getTxData_asB64(): string;
     setTxData(value: Uint8Array | string): MonitorRequest;
 
-    hasPortConfiguration(): boolean;
-    clearPortConfiguration(): void;
-    getPortConfiguration(): MonitorPortConfiguration | undefined;
-    setPortConfiguration(value?: MonitorPortConfiguration): MonitorRequest;
+    hasUpdatedConfiguration(): boolean;
+    clearUpdatedConfiguration(): void;
+    getUpdatedConfiguration(): MonitorPortConfiguration | undefined;
+    setUpdatedConfiguration(value?: MonitorPortConfiguration): MonitorRequest;
+
+    hasClose(): boolean;
+    clearClose(): void;
+    getClose(): boolean;
+    setClose(value: boolean): MonitorRequest;
+
+    getMessageCase(): MonitorRequest.MessageCase;
 
     serializeBinary(): Uint8Array;
     toObject(includeInstance?: boolean): MonitorRequest.AsObject;
@@ -42,11 +45,57 @@ export class MonitorRequest extends jspb.Message {
 }
 
 export namespace MonitorRequest {
+    export type AsObject = {
+        openRequest?: MonitorPortOpenRequest.AsObject,
+        txData: Uint8Array | string,
+        updatedConfiguration?: MonitorPortConfiguration.AsObject,
+        close: boolean,
+    }
+
+    export enum MessageCase {
+        MESSAGE_NOT_SET = 0,
+        OPEN_REQUEST = 1,
+        TX_DATA = 2,
+        UPDATED_CONFIGURATION = 3,
+        CLOSE = 4,
+    }
+
+}
+
+export class MonitorPortOpenRequest extends jspb.Message { 
+
+    hasInstance(): boolean;
+    clearInstance(): void;
+    getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
+    setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): MonitorPortOpenRequest;
+
+    hasPort(): boolean;
+    clearPort(): void;
+    getPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
+    setPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): MonitorPortOpenRequest;
+    getFqbn(): string;
+    setFqbn(value: string): MonitorPortOpenRequest;
+
+    hasPortConfiguration(): boolean;
+    clearPortConfiguration(): void;
+    getPortConfiguration(): MonitorPortConfiguration | undefined;
+    setPortConfiguration(value?: MonitorPortConfiguration): MonitorPortOpenRequest;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): MonitorPortOpenRequest.AsObject;
+    static toObject(includeInstance: boolean, msg: MonitorPortOpenRequest): MonitorPortOpenRequest.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: MonitorPortOpenRequest, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): MonitorPortOpenRequest;
+    static deserializeBinaryFromReader(message: MonitorPortOpenRequest, reader: jspb.BinaryReader): MonitorPortOpenRequest;
+}
+
+export namespace MonitorPortOpenRequest {
     export type AsObject = {
         instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
         port?: cc_arduino_cli_commands_v1_port_pb.Port.AsObject,
         fqbn: string,
-        txData: Uint8Array | string,
         portConfiguration?: MonitorPortConfiguration.AsObject,
     }
 }
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/monitor_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/monitor_pb.js
index db4445ce3..24f22a3fb 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/monitor_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/monitor_pb.js
@@ -28,9 +28,11 @@ goog.object.extend(proto, cc_arduino_cli_commands_v1_port_pb);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsResponse', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MonitorPortSetting', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MonitorPortSettingDescriptor', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MonitorRequest', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MonitorRequest.MessageCase', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MonitorResponse', null, global);
 /**
  * Generated by JsPbCodeGenerator.
@@ -43,7 +45,7 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.MonitorResponse', null, glob
  * @constructor
  */
 proto.cc.arduino.cli.commands.v1.MonitorRequest = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_);
 };
 goog.inherits(proto.cc.arduino.cli.commands.v1.MonitorRequest, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
@@ -53,6 +55,27 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.cc.arduino.cli.commands.v1.MonitorRequest.displayName = 'proto.cc.arduino.cli.commands.v1.MonitorRequest';
 }
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.displayName = 'proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest';
+}
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -180,6 +203,34 @@ if (goog.DEBUG && !COMPILED) {
   proto.cc.arduino.cli.commands.v1.MonitorPortSettingDescriptor.displayName = 'proto.cc.arduino.cli.commands.v1.MonitorPortSettingDescriptor';
 }
 
+/**
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array<!Array<number>>}
+ * @const
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_ = [[1,2,3,4]];
+
+/**
+ * @enum {number}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.MessageCase = {
+  MESSAGE_NOT_SET: 0,
+  OPEN_REQUEST: 1,
+  TX_DATA: 2,
+  UPDATED_CONFIGURATION: 3,
+  CLOSE: 4
+};
+
+/**
+ * @return {proto.cc.arduino.cli.commands.v1.MonitorRequest.MessageCase}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getMessageCase = function() {
+  return /** @type {proto.cc.arduino.cli.commands.v1.MonitorRequest.MessageCase} */(jspb.Message.computeOneofCase(this, proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_[0]));
+};
+
 
 
 if (jspb.Message.GENERATE_TO_OBJECT) {
@@ -211,11 +262,10 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.toObject = function(op
  */
 proto.cc.arduino.cli.commands.v1.MonitorRequest.toObject = function(includeInstance, msg) {
   var f, obj = {
-    instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
-    port: (f = msg.getPort()) && cc_arduino_cli_commands_v1_port_pb.Port.toObject(includeInstance, f),
-    fqbn: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    openRequest: (f = msg.getOpenRequest()) && proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.toObject(includeInstance, f),
     txData: msg.getTxData_asB64(),
-    portConfiguration: (f = msg.getPortConfiguration()) && proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration.toObject(includeInstance, f)
+    updatedConfiguration: (f = msg.getUpdatedConfiguration()) && proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration.toObject(includeInstance, f),
+    close: jspb.Message.getBooleanFieldWithDefault(msg, 4, false)
   };
 
   if (includeInstance) {
@@ -246,6 +296,328 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.deserializeBinary = function(byt
  * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest}
  */
 proto.cc.arduino.cli.commands.v1.MonitorRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.deserializeBinaryFromReader);
+      msg.setOpenRequest(value);
+      break;
+    case 2:
+      var value = /** @type {!Uint8Array} */ (reader.readBytes());
+      msg.setTxData(value);
+      break;
+    case 3:
+      var value = new proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration;
+      reader.readMessage(value,proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration.deserializeBinaryFromReader);
+      msg.setUpdatedConfiguration(value);
+      break;
+    case 4:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setClose(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.cc.arduino.cli.commands.v1.MonitorRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.cc.arduino.cli.commands.v1.MonitorRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getOpenRequest();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeBytes(
+      2,
+      f
+    );
+  }
+  f = message.getUpdatedConfiguration();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeBool(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional MonitorPortOpenRequest open_request = 1;
+ * @return {?proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getOpenRequest = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} */ (
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest, 1));
+};
+
+
+/**
+ * @param {?proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest|undefined} value
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+*/
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setOpenRequest = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 1, proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearOpenRequest = function() {
+  return this.setOpenRequest(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasOpenRequest = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional bytes tx_data = 2;
+ * @return {!(string|Uint8Array)}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getTxData = function() {
+  return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * optional bytes tx_data = 2;
+ * This is a type-conversion wrapper around `getTxData()`
+ * @return {string}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getTxData_asB64 = function() {
+  return /** @type {string} */ (jspb.Message.bytesAsB64(
+      this.getTxData()));
+};
+
+
+/**
+ * optional bytes tx_data = 2;
+ * Note that Uint8Array is not supported on all browsers.
+ * @see http://caniuse.com/Uint8Array
+ * This is a type-conversion wrapper around `getTxData()`
+ * @return {!Uint8Array}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getTxData_asU8 = function() {
+  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
+      this.getTxData()));
+};
+
+
+/**
+ * @param {!(string|Uint8Array)} value
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setTxData = function(value) {
+  return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearTxData = function() {
+  return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasTxData = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional MonitorPortConfiguration updated_configuration = 3;
+ * @return {?proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getUpdatedConfiguration = function() {
+  return /** @type{?proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration} */ (
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration, 3));
+};
+
+
+/**
+ * @param {?proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration|undefined} value
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+*/
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setUpdatedConfiguration = function(value) {
+  return jspb.Message.setOneofWrapperField(this, 3, proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearUpdatedConfiguration = function() {
+  return this.setUpdatedConfiguration(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasUpdatedConfiguration = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional bool close = 4;
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getClose = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 4, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setClose = function(value) {
+  return jspb.Message.setOneofField(this, 4, proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearClose = function() {
+  return jspb.Message.setOneofField(this, 4, proto.cc.arduino.cli.commands.v1.MonitorRequest.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasClose = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
+    port: (f = msg.getPort()) && cc_arduino_cli_commands_v1_port_pb.Port.toObject(includeInstance, f),
+    fqbn: jspb.Message.getFieldWithDefault(msg, 3, ""),
+    portConfiguration: (f = msg.getPortConfiguration()) && proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest;
+  return proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest}
+ */
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -267,10 +639,6 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.deserializeBinaryFromReader = fu
       msg.setFqbn(value);
       break;
     case 4:
-      var value = /** @type {!Uint8Array} */ (reader.readBytes());
-      msg.setTxData(value);
-      break;
-    case 5:
       var value = new proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration;
       reader.readMessage(value,proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration.deserializeBinaryFromReader);
       msg.setPortConfiguration(value);
@@ -288,9 +656,9 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.deserializeBinaryFromReader = fu
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.commands.v1.MonitorRequest.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -298,11 +666,11 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.serializeBinary = func
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.commands.v1.MonitorRequest} message
+ * @param {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getInstance();
   if (f != null) {
@@ -327,17 +695,10 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.serializeBinaryToWriter = functi
       f
     );
   }
-  f = message.getTxData_asU8();
-  if (f.length > 0) {
-    writer.writeBytes(
-      4,
-      f
-    );
-  }
   f = message.getPortConfiguration();
   if (f != null) {
     writer.writeMessage(
-      5,
+      4,
       f,
       proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration.serializeBinaryToWriter
     );
@@ -349,7 +710,7 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.serializeBinaryToWriter = functi
  * optional Instance instance = 1;
  * @return {?proto.cc.arduino.cli.commands.v1.Instance}
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getInstance = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.getInstance = function() {
   return /** @type{?proto.cc.arduino.cli.commands.v1.Instance} */ (
     jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Instance, 1));
 };
@@ -357,18 +718,18 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getInstance = function
 
 /**
  * @param {?proto.cc.arduino.cli.commands.v1.Instance|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} returns this
 */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setInstance = function(value) {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.setInstance = function(value) {
   return jspb.Message.setWrapperField(this, 1, value);
 };
 
 
 /**
  * Clears the message field making it undefined.
- * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} returns this
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearInstance = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.clearInstance = function() {
   return this.setInstance(undefined);
 };
 
@@ -377,7 +738,7 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearInstance = functi
  * Returns whether this field is set.
  * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasInstance = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.hasInstance = function() {
   return jspb.Message.getField(this, 1) != null;
 };
 
@@ -386,7 +747,7 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasInstance = function
  * optional Port port = 2;
  * @return {?proto.cc.arduino.cli.commands.v1.Port}
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getPort = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.getPort = function() {
   return /** @type{?proto.cc.arduino.cli.commands.v1.Port} */ (
     jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_port_pb.Port, 2));
 };
@@ -394,18 +755,18 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getPort = function() {
 
 /**
  * @param {?proto.cc.arduino.cli.commands.v1.Port|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} returns this
 */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setPort = function(value) {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.setPort = function(value) {
   return jspb.Message.setWrapperField(this, 2, value);
 };
 
 
 /**
  * Clears the message field making it undefined.
- * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} returns this
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearPort = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.clearPort = function() {
   return this.setPort(undefined);
 };
 
@@ -414,7 +775,7 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearPort = function()
  * Returns whether this field is set.
  * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasPort = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.hasPort = function() {
   return jspb.Message.getField(this, 2) != null;
 };
 
@@ -423,86 +784,44 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasPort = function() {
  * optional string fqbn = 3;
  * @return {string}
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getFqbn = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.getFqbn = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} returns this
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setFqbn = function(value) {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.setFqbn = function(value) {
   return jspb.Message.setProto3StringField(this, 3, value);
 };
 
 
 /**
- * optional bytes tx_data = 4;
- * @return {!(string|Uint8Array)}
- */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getTxData = function() {
-  return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * optional bytes tx_data = 4;
- * This is a type-conversion wrapper around `getTxData()`
- * @return {string}
- */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getTxData_asB64 = function() {
-  return /** @type {string} */ (jspb.Message.bytesAsB64(
-      this.getTxData()));
-};
-
-
-/**
- * optional bytes tx_data = 4;
- * Note that Uint8Array is not supported on all browsers.
- * @see http://caniuse.com/Uint8Array
- * This is a type-conversion wrapper around `getTxData()`
- * @return {!Uint8Array}
- */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getTxData_asU8 = function() {
-  return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
-      this.getTxData()));
-};
-
-
-/**
- * @param {!(string|Uint8Array)} value
- * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
- */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setTxData = function(value) {
-  return jspb.Message.setProto3BytesField(this, 4, value);
-};
-
-
-/**
- * optional MonitorPortConfiguration port_configuration = 5;
+ * optional MonitorPortConfiguration port_configuration = 4;
  * @return {?proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration}
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.getPortConfiguration = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.getPortConfiguration = function() {
   return /** @type{?proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration} */ (
-    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration, 5));
+    jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration, 4));
 };
 
 
 /**
  * @param {?proto.cc.arduino.cli.commands.v1.MonitorPortConfiguration|undefined} value
- * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} returns this
 */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.setPortConfiguration = function(value) {
-  return jspb.Message.setWrapperField(this, 5, value);
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.setPortConfiguration = function(value) {
+  return jspb.Message.setWrapperField(this, 4, value);
 };
 
 
 /**
  * Clears the message field making it undefined.
- * @return {!proto.cc.arduino.cli.commands.v1.MonitorRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest} returns this
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearPortConfiguration = function() {
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.clearPortConfiguration = function() {
   return this.setPortConfiguration(undefined);
 };
 
@@ -511,8 +830,8 @@ proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.clearPortConfiguration
  * Returns whether this field is set.
  * @return {boolean}
  */
-proto.cc.arduino.cli.commands.v1.MonitorRequest.prototype.hasPortConfiguration = function() {
-  return jspb.Message.getField(this, 5) != null;
+proto.cc.arduino.cli.commands.v1.MonitorPortOpenRequest.prototype.hasPortConfiguration = function() {
+  return jspb.Message.getField(this, 4) != null;
 };
 
 
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_grpc_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_grpc_pb.js
new file mode 100644
index 000000000..97b3a2461
--- /dev/null
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_grpc_pb.js
@@ -0,0 +1 @@
+// GENERATED CODE -- NO SERVICES IN PROTO
\ No newline at end of file
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_pb.d.ts
new file mode 100644
index 000000000..b960375a5
--- /dev/null
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_pb.d.ts
@@ -0,0 +1,238 @@
+// package: cc.arduino.cli.commands.v1
+// file: cc/arduino/cli/commands/v1/settings.proto
+
+/* tslint:disable */
+/* eslint-disable */
+
+import * as jspb from "google-protobuf";
+
+export class SettingsGetAllResponse extends jspb.Message { 
+    getJsonData(): string;
+    setJsonData(value: string): SettingsGetAllResponse;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsGetAllResponse.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsGetAllResponse): SettingsGetAllResponse.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsGetAllResponse, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsGetAllResponse;
+    static deserializeBinaryFromReader(message: SettingsGetAllResponse, reader: jspb.BinaryReader): SettingsGetAllResponse;
+}
+
+export namespace SettingsGetAllResponse {
+    export type AsObject = {
+        jsonData: string,
+    }
+}
+
+export class SettingsMergeRequest extends jspb.Message { 
+    getJsonData(): string;
+    setJsonData(value: string): SettingsMergeRequest;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsMergeRequest.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsMergeRequest): SettingsMergeRequest.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsMergeRequest, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsMergeRequest;
+    static deserializeBinaryFromReader(message: SettingsMergeRequest, reader: jspb.BinaryReader): SettingsMergeRequest;
+}
+
+export namespace SettingsMergeRequest {
+    export type AsObject = {
+        jsonData: string,
+    }
+}
+
+export class SettingsGetValueResponse extends jspb.Message { 
+    getKey(): string;
+    setKey(value: string): SettingsGetValueResponse;
+    getJsonData(): string;
+    setJsonData(value: string): SettingsGetValueResponse;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsGetValueResponse.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsGetValueResponse): SettingsGetValueResponse.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsGetValueResponse, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsGetValueResponse;
+    static deserializeBinaryFromReader(message: SettingsGetValueResponse, reader: jspb.BinaryReader): SettingsGetValueResponse;
+}
+
+export namespace SettingsGetValueResponse {
+    export type AsObject = {
+        key: string,
+        jsonData: string,
+    }
+}
+
+export class SettingsSetValueRequest extends jspb.Message { 
+    getKey(): string;
+    setKey(value: string): SettingsSetValueRequest;
+    getJsonData(): string;
+    setJsonData(value: string): SettingsSetValueRequest;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsSetValueRequest.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsSetValueRequest): SettingsSetValueRequest.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsSetValueRequest, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsSetValueRequest;
+    static deserializeBinaryFromReader(message: SettingsSetValueRequest, reader: jspb.BinaryReader): SettingsSetValueRequest;
+}
+
+export namespace SettingsSetValueRequest {
+    export type AsObject = {
+        key: string,
+        jsonData: string,
+    }
+}
+
+export class SettingsGetAllRequest extends jspb.Message { 
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsGetAllRequest.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsGetAllRequest): SettingsGetAllRequest.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsGetAllRequest, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsGetAllRequest;
+    static deserializeBinaryFromReader(message: SettingsGetAllRequest, reader: jspb.BinaryReader): SettingsGetAllRequest;
+}
+
+export namespace SettingsGetAllRequest {
+    export type AsObject = {
+    }
+}
+
+export class SettingsGetValueRequest extends jspb.Message { 
+    getKey(): string;
+    setKey(value: string): SettingsGetValueRequest;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsGetValueRequest.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsGetValueRequest): SettingsGetValueRequest.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsGetValueRequest, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsGetValueRequest;
+    static deserializeBinaryFromReader(message: SettingsGetValueRequest, reader: jspb.BinaryReader): SettingsGetValueRequest;
+}
+
+export namespace SettingsGetValueRequest {
+    export type AsObject = {
+        key: string,
+    }
+}
+
+export class SettingsMergeResponse extends jspb.Message { 
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsMergeResponse.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsMergeResponse): SettingsMergeResponse.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsMergeResponse, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsMergeResponse;
+    static deserializeBinaryFromReader(message: SettingsMergeResponse, reader: jspb.BinaryReader): SettingsMergeResponse;
+}
+
+export namespace SettingsMergeResponse {
+    export type AsObject = {
+    }
+}
+
+export class SettingsSetValueResponse extends jspb.Message { 
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsSetValueResponse.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsSetValueResponse): SettingsSetValueResponse.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsSetValueResponse, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsSetValueResponse;
+    static deserializeBinaryFromReader(message: SettingsSetValueResponse, reader: jspb.BinaryReader): SettingsSetValueResponse;
+}
+
+export namespace SettingsSetValueResponse {
+    export type AsObject = {
+    }
+}
+
+export class SettingsWriteRequest extends jspb.Message { 
+    getFilePath(): string;
+    setFilePath(value: string): SettingsWriteRequest;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsWriteRequest.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsWriteRequest): SettingsWriteRequest.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsWriteRequest, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsWriteRequest;
+    static deserializeBinaryFromReader(message: SettingsWriteRequest, reader: jspb.BinaryReader): SettingsWriteRequest;
+}
+
+export namespace SettingsWriteRequest {
+    export type AsObject = {
+        filePath: string,
+    }
+}
+
+export class SettingsWriteResponse extends jspb.Message { 
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsWriteResponse.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsWriteResponse): SettingsWriteResponse.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsWriteResponse, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsWriteResponse;
+    static deserializeBinaryFromReader(message: SettingsWriteResponse, reader: jspb.BinaryReader): SettingsWriteResponse;
+}
+
+export namespace SettingsWriteResponse {
+    export type AsObject = {
+    }
+}
+
+export class SettingsDeleteRequest extends jspb.Message { 
+    getKey(): string;
+    setKey(value: string): SettingsDeleteRequest;
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsDeleteRequest.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsDeleteRequest): SettingsDeleteRequest.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsDeleteRequest, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsDeleteRequest;
+    static deserializeBinaryFromReader(message: SettingsDeleteRequest, reader: jspb.BinaryReader): SettingsDeleteRequest;
+}
+
+export namespace SettingsDeleteRequest {
+    export type AsObject = {
+        key: string,
+    }
+}
+
+export class SettingsDeleteResponse extends jspb.Message { 
+
+    serializeBinary(): Uint8Array;
+    toObject(includeInstance?: boolean): SettingsDeleteResponse.AsObject;
+    static toObject(includeInstance: boolean, msg: SettingsDeleteResponse): SettingsDeleteResponse.AsObject;
+    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+    static serializeBinaryToWriter(message: SettingsDeleteResponse, writer: jspb.BinaryWriter): void;
+    static deserializeBinary(bytes: Uint8Array): SettingsDeleteResponse;
+    static deserializeBinaryFromReader(message: SettingsDeleteResponse, reader: jspb.BinaryReader): SettingsDeleteResponse;
+}
+
+export namespace SettingsDeleteResponse {
+    export type AsObject = {
+    }
+}
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_pb.js
similarity index 59%
rename from arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_pb.js
rename to arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_pb.js
index a00c4ffe8..cabb89ab0 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/settings_pb.js
@@ -1,4 +1,4 @@
-// source: cc/arduino/cli/settings/v1/settings.proto
+// source: cc/arduino/cli/commands/v1/settings.proto
 /**
  * @fileoverview
  * @enhanceable
@@ -21,18 +21,18 @@ var global = (function() {
   return Function('return this')();
 }.call(null));
 
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.DeleteRequest', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.DeleteResponse', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.GetAllRequest', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.GetAllResponse', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.GetValueRequest', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.GetValueResponse', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.MergeRequest', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.MergeResponse', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.SetValueRequest', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.SetValueResponse', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.WriteRequest', null, global);
-goog.exportSymbol('proto.cc.arduino.cli.settings.v1.WriteResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsMergeRequest', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsMergeResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsWriteRequest', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SettingsWriteResponse', null, global);
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -43,16 +43,16 @@ goog.exportSymbol('proto.cc.arduino.cli.settings.v1.WriteResponse', null, global
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.GetAllResponse, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.GetAllResponse.displayName = 'proto.cc.arduino.cli.settings.v1.GetAllResponse';
+  proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -64,16 +64,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.MergeRequest, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsMergeRequest, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.MergeRequest.displayName = 'proto.cc.arduino.cli.settings.v1.MergeRequest';
+  proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsMergeRequest';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -85,16 +85,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.GetValueResponse, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.GetValueResponse.displayName = 'proto.cc.arduino.cli.settings.v1.GetValueResponse';
+  proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -106,16 +106,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.SetValueRequest, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.SetValueRequest.displayName = 'proto.cc.arduino.cli.settings.v1.SetValueRequest';
+  proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -127,16 +127,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.GetAllRequest = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.GetAllRequest, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.GetAllRequest.displayName = 'proto.cc.arduino.cli.settings.v1.GetAllRequest';
+  proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -148,16 +148,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.GetValueRequest, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.GetValueRequest.displayName = 'proto.cc.arduino.cli.settings.v1.GetValueRequest';
+  proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -169,16 +169,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.MergeResponse = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeResponse = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.MergeResponse, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsMergeResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.MergeResponse.displayName = 'proto.cc.arduino.cli.settings.v1.MergeResponse';
+  proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsMergeResponse';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -190,16 +190,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.SetValueResponse = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.SetValueResponse, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.SetValueResponse.displayName = 'proto.cc.arduino.cli.settings.v1.SetValueResponse';
+  proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -211,16 +211,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.WriteRequest, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsWriteRequest, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.WriteRequest.displayName = 'proto.cc.arduino.cli.settings.v1.WriteRequest';
+  proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsWriteRequest';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -232,16 +232,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.WriteResponse = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteResponse = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.WriteResponse, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsWriteResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.WriteResponse.displayName = 'proto.cc.arduino.cli.settings.v1.WriteResponse';
+  proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsWriteResponse';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -253,16 +253,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.DeleteRequest, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.DeleteRequest.displayName = 'proto.cc.arduino.cli.settings.v1.DeleteRequest';
+  proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest';
 }
 /**
  * Generated by JsPbCodeGenerator.
@@ -274,16 +274,16 @@ if (goog.DEBUG && !COMPILED) {
  * @extends {jspb.Message}
  * @constructor
  */
-proto.cc.arduino.cli.settings.v1.DeleteResponse = function(opt_data) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.cc.arduino.cli.settings.v1.DeleteResponse, jspb.Message);
+goog.inherits(proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
   /**
    * @public
    * @override
    */
-  proto.cc.arduino.cli.settings.v1.DeleteResponse.displayName = 'proto.cc.arduino.cli.settings.v1.DeleteResponse';
+  proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.displayName = 'proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse';
 }
 
 
@@ -301,8 +301,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.GetAllResponse.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.toObject(opt_includeInstance, this);
 };
 
 
@@ -311,11 +311,11 @@ proto.cc.arduino.cli.settings.v1.GetAllResponse.prototype.toObject = function(op
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.GetAllResponse} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
     jsonData: jspb.Message.getFieldWithDefault(msg, 1, "")
   };
@@ -331,23 +331,23 @@ proto.cc.arduino.cli.settings.v1.GetAllResponse.toObject = function(includeInsta
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.GetAllResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse}
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.GetAllResponse;
-  return proto.cc.arduino.cli.settings.v1.GetAllResponse.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse;
+  return proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.GetAllResponse} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.GetAllResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse}
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -371,9 +371,9 @@ proto.cc.arduino.cli.settings.v1.GetAllResponse.deserializeBinaryFromReader = fu
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.GetAllResponse.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -381,11 +381,11 @@ proto.cc.arduino.cli.settings.v1.GetAllResponse.prototype.serializeBinary = func
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.GetAllResponse} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getJsonData();
   if (f.length > 0) {
@@ -401,16 +401,16 @@ proto.cc.arduino.cli.settings.v1.GetAllResponse.serializeBinaryToWriter = functi
  * optional string json_data = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse.prototype.getJsonData = function() {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.prototype.getJsonData = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.GetAllResponse} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse} returns this
  */
-proto.cc.arduino.cli.settings.v1.GetAllResponse.prototype.setJsonData = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllResponse.prototype.setJsonData = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
@@ -431,8 +431,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.MergeRequest.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.toObject(opt_includeInstance, this);
 };
 
 
@@ -441,11 +441,11 @@ proto.cc.arduino.cli.settings.v1.MergeRequest.prototype.toObject = function(opt_
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.MergeRequest} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsMergeRequest} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.toObject = function(includeInstance, msg) {
   var f, obj = {
     jsonData: jspb.Message.getFieldWithDefault(msg, 1, "")
   };
@@ -461,23 +461,23 @@ proto.cc.arduino.cli.settings.v1.MergeRequest.toObject = function(includeInstanc
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.MergeRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsMergeRequest}
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.MergeRequest;
-  return proto.cc.arduino.cli.settings.v1.MergeRequest.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsMergeRequest;
+  return proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.MergeRequest} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsMergeRequest} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.MergeRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsMergeRequest}
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -501,9 +501,9 @@ proto.cc.arduino.cli.settings.v1.MergeRequest.deserializeBinaryFromReader = func
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.MergeRequest.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -511,11 +511,11 @@ proto.cc.arduino.cli.settings.v1.MergeRequest.prototype.serializeBinary = functi
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.MergeRequest} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsMergeRequest} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getJsonData();
   if (f.length > 0) {
@@ -531,16 +531,16 @@ proto.cc.arduino.cli.settings.v1.MergeRequest.serializeBinaryToWriter = function
  * optional string json_data = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest.prototype.getJsonData = function() {
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.prototype.getJsonData = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.MergeRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsMergeRequest} returns this
  */
-proto.cc.arduino.cli.settings.v1.MergeRequest.prototype.setJsonData = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeRequest.prototype.setJsonData = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
@@ -561,8 +561,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.GetValueResponse.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.toObject(opt_includeInstance, this);
 };
 
 
@@ -571,11 +571,11 @@ proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.toObject = function(
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.GetValueResponse} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
     key: jspb.Message.getFieldWithDefault(msg, 1, ""),
     jsonData: jspb.Message.getFieldWithDefault(msg, 2, "")
@@ -592,23 +592,23 @@ proto.cc.arduino.cli.settings.v1.GetValueResponse.toObject = function(includeIns
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.GetValueResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse}
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.GetValueResponse;
-  return proto.cc.arduino.cli.settings.v1.GetValueResponse.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse;
+  return proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.GetValueResponse} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.GetValueResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse}
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -636,9 +636,9 @@ proto.cc.arduino.cli.settings.v1.GetValueResponse.deserializeBinaryFromReader =
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.GetValueResponse.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -646,11 +646,11 @@ proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.serializeBinary = fu
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.GetValueResponse} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getKey();
   if (f.length > 0) {
@@ -673,16 +673,16 @@ proto.cc.arduino.cli.settings.v1.GetValueResponse.serializeBinaryToWriter = func
  * optional string key = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.getKey = function() {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.prototype.getKey = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.GetValueResponse} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse} returns this
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.setKey = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.prototype.setKey = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
@@ -691,16 +691,16 @@ proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.setKey = function(va
  * optional string json_data = 2;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.getJsonData = function() {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.prototype.getJsonData = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.GetValueResponse} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse} returns this
  */
-proto.cc.arduino.cli.settings.v1.GetValueResponse.prototype.setJsonData = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueResponse.prototype.setJsonData = function(value) {
   return jspb.Message.setProto3StringField(this, 2, value);
 };
 
@@ -721,8 +721,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.SetValueRequest.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.toObject(opt_includeInstance, this);
 };
 
 
@@ -731,11 +731,11 @@ proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.toObject = function(o
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.SetValueRequest} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.toObject = function(includeInstance, msg) {
   var f, obj = {
     key: jspb.Message.getFieldWithDefault(msg, 1, ""),
     jsonData: jspb.Message.getFieldWithDefault(msg, 2, "")
@@ -752,23 +752,23 @@ proto.cc.arduino.cli.settings.v1.SetValueRequest.toObject = function(includeInst
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.SetValueRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest}
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.SetValueRequest;
-  return proto.cc.arduino.cli.settings.v1.SetValueRequest.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest;
+  return proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.SetValueRequest} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.SetValueRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest}
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -796,9 +796,9 @@ proto.cc.arduino.cli.settings.v1.SetValueRequest.deserializeBinaryFromReader = f
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.SetValueRequest.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -806,11 +806,11 @@ proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.serializeBinary = fun
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.SetValueRequest} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getKey();
   if (f.length > 0) {
@@ -833,16 +833,16 @@ proto.cc.arduino.cli.settings.v1.SetValueRequest.serializeBinaryToWriter = funct
  * optional string key = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.getKey = function() {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.prototype.getKey = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.SetValueRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest} returns this
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.setKey = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.prototype.setKey = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
@@ -851,16 +851,16 @@ proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.setKey = function(val
  * optional string json_data = 2;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.getJsonData = function() {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.prototype.getJsonData = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.SetValueRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest} returns this
  */
-proto.cc.arduino.cli.settings.v1.SetValueRequest.prototype.setJsonData = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueRequest.prototype.setJsonData = function(value) {
   return jspb.Message.setProto3StringField(this, 2, value);
 };
 
@@ -881,8 +881,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.GetAllRequest.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.GetAllRequest.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.toObject(opt_includeInstance, this);
 };
 
 
@@ -891,11 +891,11 @@ proto.cc.arduino.cli.settings.v1.GetAllRequest.prototype.toObject = function(opt
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.GetAllRequest} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.GetAllRequest.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.toObject = function(includeInstance, msg) {
   var f, obj = {
 
   };
@@ -911,23 +911,23 @@ proto.cc.arduino.cli.settings.v1.GetAllRequest.toObject = function(includeInstan
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.GetAllRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest}
  */
-proto.cc.arduino.cli.settings.v1.GetAllRequest.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.GetAllRequest;
-  return proto.cc.arduino.cli.settings.v1.GetAllRequest.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest;
+  return proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.GetAllRequest} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.GetAllRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest}
  */
-proto.cc.arduino.cli.settings.v1.GetAllRequest.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -947,9 +947,9 @@ proto.cc.arduino.cli.settings.v1.GetAllRequest.deserializeBinaryFromReader = fun
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.GetAllRequest.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.GetAllRequest.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -957,11 +957,11 @@ proto.cc.arduino.cli.settings.v1.GetAllRequest.prototype.serializeBinary = funct
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.GetAllRequest} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.GetAllRequest.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsGetAllRequest.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
 };
 
@@ -982,8 +982,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.GetValueRequest.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.toObject(opt_includeInstance, this);
 };
 
 
@@ -992,11 +992,11 @@ proto.cc.arduino.cli.settings.v1.GetValueRequest.prototype.toObject = function(o
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.GetValueRequest} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.toObject = function(includeInstance, msg) {
   var f, obj = {
     key: jspb.Message.getFieldWithDefault(msg, 1, "")
   };
@@ -1012,23 +1012,23 @@ proto.cc.arduino.cli.settings.v1.GetValueRequest.toObject = function(includeInst
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.GetValueRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest}
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.GetValueRequest;
-  return proto.cc.arduino.cli.settings.v1.GetValueRequest.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest;
+  return proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.GetValueRequest} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.GetValueRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest}
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -1052,9 +1052,9 @@ proto.cc.arduino.cli.settings.v1.GetValueRequest.deserializeBinaryFromReader = f
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.GetValueRequest.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -1062,11 +1062,11 @@ proto.cc.arduino.cli.settings.v1.GetValueRequest.prototype.serializeBinary = fun
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.GetValueRequest} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getKey();
   if (f.length > 0) {
@@ -1082,16 +1082,16 @@ proto.cc.arduino.cli.settings.v1.GetValueRequest.serializeBinaryToWriter = funct
  * optional string key = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest.prototype.getKey = function() {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.prototype.getKey = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.GetValueRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest} returns this
  */
-proto.cc.arduino.cli.settings.v1.GetValueRequest.prototype.setKey = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsGetValueRequest.prototype.setKey = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
@@ -1112,8 +1112,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.MergeResponse.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.MergeResponse.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.toObject(opt_includeInstance, this);
 };
 
 
@@ -1122,11 +1122,11 @@ proto.cc.arduino.cli.settings.v1.MergeResponse.prototype.toObject = function(opt
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.MergeResponse} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsMergeResponse} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.MergeResponse.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
 
   };
@@ -1142,23 +1142,23 @@ proto.cc.arduino.cli.settings.v1.MergeResponse.toObject = function(includeInstan
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.MergeResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsMergeResponse}
  */
-proto.cc.arduino.cli.settings.v1.MergeResponse.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.MergeResponse;
-  return proto.cc.arduino.cli.settings.v1.MergeResponse.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsMergeResponse;
+  return proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.MergeResponse} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsMergeResponse} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.MergeResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsMergeResponse}
  */
-proto.cc.arduino.cli.settings.v1.MergeResponse.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -1178,9 +1178,9 @@ proto.cc.arduino.cli.settings.v1.MergeResponse.deserializeBinaryFromReader = fun
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.MergeResponse.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.MergeResponse.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -1188,11 +1188,11 @@ proto.cc.arduino.cli.settings.v1.MergeResponse.prototype.serializeBinary = funct
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.MergeResponse} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsMergeResponse} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.MergeResponse.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsMergeResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
 };
 
@@ -1213,8 +1213,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.SetValueResponse.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.SetValueResponse.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.toObject(opt_includeInstance, this);
 };
 
 
@@ -1223,11 +1223,11 @@ proto.cc.arduino.cli.settings.v1.SetValueResponse.prototype.toObject = function(
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.SetValueResponse} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.SetValueResponse.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
 
   };
@@ -1243,23 +1243,23 @@ proto.cc.arduino.cli.settings.v1.SetValueResponse.toObject = function(includeIns
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.SetValueResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse}
  */
-proto.cc.arduino.cli.settings.v1.SetValueResponse.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.SetValueResponse;
-  return proto.cc.arduino.cli.settings.v1.SetValueResponse.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse;
+  return proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.SetValueResponse} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.SetValueResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse}
  */
-proto.cc.arduino.cli.settings.v1.SetValueResponse.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -1279,9 +1279,9 @@ proto.cc.arduino.cli.settings.v1.SetValueResponse.deserializeBinaryFromReader =
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.SetValueResponse.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.SetValueResponse.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -1289,11 +1289,11 @@ proto.cc.arduino.cli.settings.v1.SetValueResponse.prototype.serializeBinary = fu
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.SetValueResponse} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.SetValueResponse.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsSetValueResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
 };
 
@@ -1314,8 +1314,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.WriteRequest.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.toObject(opt_includeInstance, this);
 };
 
 
@@ -1324,11 +1324,11 @@ proto.cc.arduino.cli.settings.v1.WriteRequest.prototype.toObject = function(opt_
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.WriteRequest} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsWriteRequest} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.toObject = function(includeInstance, msg) {
   var f, obj = {
     filePath: jspb.Message.getFieldWithDefault(msg, 1, "")
   };
@@ -1344,23 +1344,23 @@ proto.cc.arduino.cli.settings.v1.WriteRequest.toObject = function(includeInstanc
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.WriteRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsWriteRequest}
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.WriteRequest;
-  return proto.cc.arduino.cli.settings.v1.WriteRequest.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsWriteRequest;
+  return proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.WriteRequest} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsWriteRequest} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.WriteRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsWriteRequest}
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -1384,9 +1384,9 @@ proto.cc.arduino.cli.settings.v1.WriteRequest.deserializeBinaryFromReader = func
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.WriteRequest.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -1394,11 +1394,11 @@ proto.cc.arduino.cli.settings.v1.WriteRequest.prototype.serializeBinary = functi
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.WriteRequest} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsWriteRequest} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getFilePath();
   if (f.length > 0) {
@@ -1414,16 +1414,16 @@ proto.cc.arduino.cli.settings.v1.WriteRequest.serializeBinaryToWriter = function
  * optional string file_path = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest.prototype.getFilePath = function() {
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.prototype.getFilePath = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.WriteRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsWriteRequest} returns this
  */
-proto.cc.arduino.cli.settings.v1.WriteRequest.prototype.setFilePath = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteRequest.prototype.setFilePath = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
@@ -1444,8 +1444,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.WriteResponse.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.WriteResponse.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.toObject(opt_includeInstance, this);
 };
 
 
@@ -1454,11 +1454,11 @@ proto.cc.arduino.cli.settings.v1.WriteResponse.prototype.toObject = function(opt
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.WriteResponse} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsWriteResponse} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.WriteResponse.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
 
   };
@@ -1474,23 +1474,23 @@ proto.cc.arduino.cli.settings.v1.WriteResponse.toObject = function(includeInstan
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.WriteResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsWriteResponse}
  */
-proto.cc.arduino.cli.settings.v1.WriteResponse.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.WriteResponse;
-  return proto.cc.arduino.cli.settings.v1.WriteResponse.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsWriteResponse;
+  return proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.WriteResponse} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsWriteResponse} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.WriteResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsWriteResponse}
  */
-proto.cc.arduino.cli.settings.v1.WriteResponse.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -1510,9 +1510,9 @@ proto.cc.arduino.cli.settings.v1.WriteResponse.deserializeBinaryFromReader = fun
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.WriteResponse.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.WriteResponse.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -1520,11 +1520,11 @@ proto.cc.arduino.cli.settings.v1.WriteResponse.prototype.serializeBinary = funct
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.WriteResponse} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsWriteResponse} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.WriteResponse.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsWriteResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
 };
 
@@ -1545,8 +1545,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.DeleteRequest.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.toObject(opt_includeInstance, this);
 };
 
 
@@ -1555,11 +1555,11 @@ proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.toObject = function(opt
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.DeleteRequest} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.toObject = function(includeInstance, msg) {
   var f, obj = {
     key: jspb.Message.getFieldWithDefault(msg, 1, "")
   };
@@ -1575,23 +1575,23 @@ proto.cc.arduino.cli.settings.v1.DeleteRequest.toObject = function(includeInstan
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.DeleteRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest}
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.DeleteRequest;
-  return proto.cc.arduino.cli.settings.v1.DeleteRequest.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest;
+  return proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.DeleteRequest} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.DeleteRequest}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest}
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -1615,9 +1615,9 @@ proto.cc.arduino.cli.settings.v1.DeleteRequest.deserializeBinaryFromReader = fun
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.DeleteRequest.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -1625,11 +1625,11 @@ proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.serializeBinary = funct
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.DeleteRequest} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = message.getKey();
   if (f.length > 0) {
@@ -1645,16 +1645,16 @@ proto.cc.arduino.cli.settings.v1.DeleteRequest.serializeBinaryToWriter = functio
  * optional string key = 1;
  * @return {string}
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.getKey = function() {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.prototype.getKey = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
 /**
  * @param {string} value
- * @return {!proto.cc.arduino.cli.settings.v1.DeleteRequest} returns this
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest} returns this
  */
-proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.setKey = function(value) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteRequest.prototype.setKey = function(value) {
   return jspb.Message.setProto3StringField(this, 1, value);
 };
 
@@ -1675,8 +1675,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
  *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.cc.arduino.cli.settings.v1.DeleteResponse.prototype.toObject = function(opt_includeInstance) {
-  return proto.cc.arduino.cli.settings.v1.DeleteResponse.toObject(opt_includeInstance, this);
+proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.toObject(opt_includeInstance, this);
 };
 
 
@@ -1685,11 +1685,11 @@ proto.cc.arduino.cli.settings.v1.DeleteResponse.prototype.toObject = function(op
  * @param {boolean|undefined} includeInstance Deprecated. Whether to include
  *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.cc.arduino.cli.settings.v1.DeleteResponse} msg The msg instance to transform.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.DeleteResponse.toObject = function(includeInstance, msg) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
 
   };
@@ -1705,23 +1705,23 @@ proto.cc.arduino.cli.settings.v1.DeleteResponse.toObject = function(includeInsta
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.cc.arduino.cli.settings.v1.DeleteResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse}
  */
-proto.cc.arduino.cli.settings.v1.DeleteResponse.deserializeBinary = function(bytes) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.cc.arduino.cli.settings.v1.DeleteResponse;
-  return proto.cc.arduino.cli.settings.v1.DeleteResponse.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse;
+  return proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.cc.arduino.cli.settings.v1.DeleteResponse} msg The message object to deserialize into.
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.cc.arduino.cli.settings.v1.DeleteResponse}
+ * @return {!proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse}
  */
-proto.cc.arduino.cli.settings.v1.DeleteResponse.deserializeBinaryFromReader = function(msg, reader) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -1741,9 +1741,9 @@ proto.cc.arduino.cli.settings.v1.DeleteResponse.deserializeBinaryFromReader = fu
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.cc.arduino.cli.settings.v1.DeleteResponse.prototype.serializeBinary = function() {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.cc.arduino.cli.settings.v1.DeleteResponse.serializeBinaryToWriter(this, writer);
+  proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -1751,13 +1751,13 @@ proto.cc.arduino.cli.settings.v1.DeleteResponse.prototype.serializeBinary = func
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.cc.arduino.cli.settings.v1.DeleteResponse} message
+ * @param {!proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.cc.arduino.cli.settings.v1.DeleteResponse.serializeBinaryToWriter = function(message, writer) {
+proto.cc.arduino.cli.commands.v1.SettingsDeleteResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
 };
 
 
-goog.object.extend(exports, proto.cc.arduino.cli.settings.v1);
+goog.object.extend(exports, proto.cc.arduino.cli.commands.v1);
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/upload_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/upload_pb.d.ts
index 6c82e5557..b16f167e2 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/upload_pb.d.ts
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/upload_pb.d.ts
@@ -214,15 +214,23 @@ export namespace UploadUsingProgrammerRequest {
 }
 
 export class UploadUsingProgrammerResponse extends jspb.Message { 
+
+    hasOutStream(): boolean;
+    clearOutStream(): void;
     getOutStream(): Uint8Array | string;
     getOutStream_asU8(): Uint8Array;
     getOutStream_asB64(): string;
     setOutStream(value: Uint8Array | string): UploadUsingProgrammerResponse;
+
+    hasErrStream(): boolean;
+    clearErrStream(): void;
     getErrStream(): Uint8Array | string;
     getErrStream_asU8(): Uint8Array;
     getErrStream_asB64(): string;
     setErrStream(value: Uint8Array | string): UploadUsingProgrammerResponse;
 
+    getMessageCase(): UploadUsingProgrammerResponse.MessageCase;
+
     serializeBinary(): Uint8Array;
     toObject(includeInstance?: boolean): UploadUsingProgrammerResponse.AsObject;
     static toObject(includeInstance: boolean, msg: UploadUsingProgrammerResponse): UploadUsingProgrammerResponse.AsObject;
@@ -238,6 +246,13 @@ export namespace UploadUsingProgrammerResponse {
         outStream: Uint8Array | string,
         errStream: Uint8Array | string,
     }
+
+    export enum MessageCase {
+        MESSAGE_NOT_SET = 0,
+        OUT_STREAM = 1,
+        ERR_STREAM = 2,
+    }
+
 }
 
 export class BurnBootloaderRequest extends jspb.Message { 
@@ -290,15 +305,23 @@ export namespace BurnBootloaderRequest {
 }
 
 export class BurnBootloaderResponse extends jspb.Message { 
+
+    hasOutStream(): boolean;
+    clearOutStream(): void;
     getOutStream(): Uint8Array | string;
     getOutStream_asU8(): Uint8Array;
     getOutStream_asB64(): string;
     setOutStream(value: Uint8Array | string): BurnBootloaderResponse;
+
+    hasErrStream(): boolean;
+    clearErrStream(): void;
     getErrStream(): Uint8Array | string;
     getErrStream_asU8(): Uint8Array;
     getErrStream_asB64(): string;
     setErrStream(value: Uint8Array | string): BurnBootloaderResponse;
 
+    getMessageCase(): BurnBootloaderResponse.MessageCase;
+
     serializeBinary(): Uint8Array;
     toObject(includeInstance?: boolean): BurnBootloaderResponse.AsObject;
     static toObject(includeInstance: boolean, msg: BurnBootloaderResponse): BurnBootloaderResponse.AsObject;
@@ -314,6 +337,13 @@ export namespace BurnBootloaderResponse {
         outStream: Uint8Array | string,
         errStream: Uint8Array | string,
     }
+
+    export enum MessageCase {
+        MESSAGE_NOT_SET = 0,
+        OUT_STREAM = 1,
+        ERR_STREAM = 2,
+    }
+
 }
 
 export class ListProgrammersAvailableForUploadRequest extends jspb.Message { 
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/upload_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/upload_pb.js
index 937a819c4..3ff6946e1 100644
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/upload_pb.js
+++ b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/upload_pb.js
@@ -27,6 +27,7 @@ var cc_arduino_cli_commands_v1_port_pb = require('../../../../../cc/arduino/cli/
 goog.object.extend(proto, cc_arduino_cli_commands_v1_port_pb);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.BurnBootloaderRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.MessageCase', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.ProgrammerIsRequiredForUploadError', null, global);
@@ -38,6 +39,7 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadResponse.MessageCase',
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadResult', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse', null, global);
+goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.MessageCase', null, global);
 goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UserField', null, global);
 /**
  * Generated by JsPbCodeGenerator.
@@ -155,7 +157,7 @@ if (goog.DEBUG && !COMPILED) {
  * @constructor
  */
 proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.oneofGroups_);
 };
 goog.inherits(proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
@@ -197,7 +199,7 @@ if (goog.DEBUG && !COMPILED) {
  * @constructor
  */
 proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+  jspb.Message.initialize(this, opt_data, 0, -1, null, proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.oneofGroups_);
 };
 goog.inherits(proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
@@ -1837,6 +1839,32 @@ proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.prototype.clearUse
 
 
 
+/**
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array<!Array<number>>}
+ * @const
+ */
+proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.oneofGroups_ = [[1,2]];
+
+/**
+ * @enum {number}
+ */
+proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.MessageCase = {
+  MESSAGE_NOT_SET: 0,
+  OUT_STREAM: 1,
+  ERR_STREAM: 2
+};
+
+/**
+ * @return {proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.MessageCase}
+ */
+proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.getMessageCase = function() {
+  return /** @type {proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.MessageCase} */(jspb.Message.computeOneofCase(this, proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.oneofGroups_[0]));
+};
+
 
 
 if (jspb.Message.GENERATE_TO_OBJECT) {
@@ -1943,15 +1971,15 @@ proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.seriali
  */
 proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
-  f = message.getOutStream_asU8();
-  if (f.length > 0) {
+  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
     writer.writeBytes(
       1,
       f
     );
   }
-  f = message.getErrStream_asU8();
-  if (f.length > 0) {
+  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
     writer.writeBytes(
       2,
       f
@@ -1998,7 +2026,25 @@ proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.getOutS
  * @return {!proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse} returns this
  */
 proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.setOutStream = function(value) {
-  return jspb.Message.setProto3BytesField(this, 1, value);
+  return jspb.Message.setOneofField(this, 1, proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse} returns this
+ */
+proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.clearOutStream = function() {
+  return jspb.Message.setOneofField(this, 1, proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.hasOutStream = function() {
+  return jspb.Message.getField(this, 1) != null;
 };
 
 
@@ -2040,7 +2086,25 @@ proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.getErrS
  * @return {!proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse} returns this
  */
 proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.setErrStream = function(value) {
-  return jspb.Message.setProto3BytesField(this, 2, value);
+  return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse} returns this
+ */
+proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.clearErrStream = function() {
+  return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse.prototype.hasErrStream = function() {
+  return jspb.Message.getField(this, 2) != null;
 };
 
 
@@ -2430,6 +2494,32 @@ proto.cc.arduino.cli.commands.v1.BurnBootloaderRequest.prototype.clearUserFields
 
 
 
+/**
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array<!Array<number>>}
+ * @const
+ */
+proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.oneofGroups_ = [[1,2]];
+
+/**
+ * @enum {number}
+ */
+proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.MessageCase = {
+  MESSAGE_NOT_SET: 0,
+  OUT_STREAM: 1,
+  ERR_STREAM: 2
+};
+
+/**
+ * @return {proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.MessageCase}
+ */
+proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.getMessageCase = function() {
+  return /** @type {proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.MessageCase} */(jspb.Message.computeOneofCase(this, proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.oneofGroups_[0]));
+};
+
 
 
 if (jspb.Message.GENERATE_TO_OBJECT) {
@@ -2536,15 +2626,15 @@ proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.serializeBinar
  */
 proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
-  f = message.getOutStream_asU8();
-  if (f.length > 0) {
+  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
     writer.writeBytes(
       1,
       f
     );
   }
-  f = message.getErrStream_asU8();
-  if (f.length > 0) {
+  f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
     writer.writeBytes(
       2,
       f
@@ -2591,7 +2681,25 @@ proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.getOutStream_a
  * @return {!proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse} returns this
  */
 proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.setOutStream = function(value) {
-  return jspb.Message.setProto3BytesField(this, 1, value);
+  return jspb.Message.setOneofField(this, 1, proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.clearOutStream = function() {
+  return jspb.Message.setOneofField(this, 1, proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.hasOutStream = function() {
+  return jspb.Message.getField(this, 1) != null;
 };
 
 
@@ -2633,7 +2741,25 @@ proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.getErrStream_a
  * @return {!proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse} returns this
  */
 proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.setErrStream = function(value) {
-  return jspb.Message.setProto3BytesField(this, 2, value);
+  return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse} returns this
+ */
+proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.clearErrStream = function() {
+  return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.oneofGroups_[0], undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.cc.arduino.cli.commands.v1.BurnBootloaderResponse.prototype.hasErrStream = function() {
+  return jspb.Message.getField(this, 2) != null;
 };
 
 
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb.d.ts
deleted file mode 100644
index c5284c159..000000000
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb.d.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-// package: cc.arduino.cli.settings.v1
-// file: cc/arduino/cli/settings/v1/settings.proto
-
-/* tslint:disable */
-/* eslint-disable */
-
-import * as grpc from "@grpc/grpc-js";
-import * as cc_arduino_cli_settings_v1_settings_pb from "../../../../../cc/arduino/cli/settings/v1/settings_pb";
-
-interface ISettingsServiceService extends grpc.ServiceDefinition<grpc.UntypedServiceImplementation> {
-    getAll: ISettingsServiceService_IGetAll;
-    merge: ISettingsServiceService_IMerge;
-    getValue: ISettingsServiceService_IGetValue;
-    setValue: ISettingsServiceService_ISetValue;
-    write: ISettingsServiceService_IWrite;
-    delete: ISettingsServiceService_IDelete;
-}
-
-interface ISettingsServiceService_IGetAll extends grpc.MethodDefinition<cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, cc_arduino_cli_settings_v1_settings_pb.GetAllResponse> {
-    path: "/cc.arduino.cli.settings.v1.SettingsService/GetAll";
-    requestStream: false;
-    responseStream: false;
-    requestSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.GetAllRequest>;
-    requestDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.GetAllRequest>;
-    responseSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.GetAllResponse>;
-    responseDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.GetAllResponse>;
-}
-interface ISettingsServiceService_IMerge extends grpc.MethodDefinition<cc_arduino_cli_settings_v1_settings_pb.MergeRequest, cc_arduino_cli_settings_v1_settings_pb.MergeResponse> {
-    path: "/cc.arduino.cli.settings.v1.SettingsService/Merge";
-    requestStream: false;
-    responseStream: false;
-    requestSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.MergeRequest>;
-    requestDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.MergeRequest>;
-    responseSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.MergeResponse>;
-    responseDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.MergeResponse>;
-}
-interface ISettingsServiceService_IGetValue extends grpc.MethodDefinition<cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, cc_arduino_cli_settings_v1_settings_pb.GetValueResponse> {
-    path: "/cc.arduino.cli.settings.v1.SettingsService/GetValue";
-    requestStream: false;
-    responseStream: false;
-    requestSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.GetValueRequest>;
-    requestDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.GetValueRequest>;
-    responseSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.GetValueResponse>;
-    responseDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.GetValueResponse>;
-}
-interface ISettingsServiceService_ISetValue extends grpc.MethodDefinition<cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, cc_arduino_cli_settings_v1_settings_pb.SetValueResponse> {
-    path: "/cc.arduino.cli.settings.v1.SettingsService/SetValue";
-    requestStream: false;
-    responseStream: false;
-    requestSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.SetValueRequest>;
-    requestDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.SetValueRequest>;
-    responseSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.SetValueResponse>;
-    responseDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.SetValueResponse>;
-}
-interface ISettingsServiceService_IWrite extends grpc.MethodDefinition<cc_arduino_cli_settings_v1_settings_pb.WriteRequest, cc_arduino_cli_settings_v1_settings_pb.WriteResponse> {
-    path: "/cc.arduino.cli.settings.v1.SettingsService/Write";
-    requestStream: false;
-    responseStream: false;
-    requestSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.WriteRequest>;
-    requestDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.WriteRequest>;
-    responseSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.WriteResponse>;
-    responseDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.WriteResponse>;
-}
-interface ISettingsServiceService_IDelete extends grpc.MethodDefinition<cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, cc_arduino_cli_settings_v1_settings_pb.DeleteResponse> {
-    path: "/cc.arduino.cli.settings.v1.SettingsService/Delete";
-    requestStream: false;
-    responseStream: false;
-    requestSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.DeleteRequest>;
-    requestDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.DeleteRequest>;
-    responseSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.DeleteResponse>;
-    responseDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.DeleteResponse>;
-}
-
-export const SettingsServiceService: ISettingsServiceService;
-
-export interface ISettingsServiceServer extends grpc.UntypedServiceImplementation {
-    getAll: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, cc_arduino_cli_settings_v1_settings_pb.GetAllResponse>;
-    merge: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.MergeRequest, cc_arduino_cli_settings_v1_settings_pb.MergeResponse>;
-    getValue: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, cc_arduino_cli_settings_v1_settings_pb.GetValueResponse>;
-    setValue: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, cc_arduino_cli_settings_v1_settings_pb.SetValueResponse>;
-    write: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.WriteRequest, cc_arduino_cli_settings_v1_settings_pb.WriteResponse>;
-    delete: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, cc_arduino_cli_settings_v1_settings_pb.DeleteResponse>;
-}
-
-export interface ISettingsServiceClient {
-    getAll(request: cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetAllResponse) => void): grpc.ClientUnaryCall;
-    getAll(request: cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetAllResponse) => void): grpc.ClientUnaryCall;
-    getAll(request: cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetAllResponse) => void): grpc.ClientUnaryCall;
-    merge(request: cc_arduino_cli_settings_v1_settings_pb.MergeRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.MergeResponse) => void): grpc.ClientUnaryCall;
-    merge(request: cc_arduino_cli_settings_v1_settings_pb.MergeRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.MergeResponse) => void): grpc.ClientUnaryCall;
-    merge(request: cc_arduino_cli_settings_v1_settings_pb.MergeRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.MergeResponse) => void): grpc.ClientUnaryCall;
-    getValue(request: cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetValueResponse) => void): grpc.ClientUnaryCall;
-    getValue(request: cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetValueResponse) => void): grpc.ClientUnaryCall;
-    getValue(request: cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetValueResponse) => void): grpc.ClientUnaryCall;
-    setValue(request: cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.SetValueResponse) => void): grpc.ClientUnaryCall;
-    setValue(request: cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.SetValueResponse) => void): grpc.ClientUnaryCall;
-    setValue(request: cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.SetValueResponse) => void): grpc.ClientUnaryCall;
-    write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
-    write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
-    write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
-    delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
-    delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
-    delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
-}
-
-export class SettingsServiceClient extends grpc.Client implements ISettingsServiceClient {
-    constructor(address: string, credentials: grpc.ChannelCredentials, options?: Partial<grpc.ClientOptions>);
-    public getAll(request: cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetAllResponse) => void): grpc.ClientUnaryCall;
-    public getAll(request: cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetAllResponse) => void): grpc.ClientUnaryCall;
-    public getAll(request: cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetAllResponse) => void): grpc.ClientUnaryCall;
-    public merge(request: cc_arduino_cli_settings_v1_settings_pb.MergeRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.MergeResponse) => void): grpc.ClientUnaryCall;
-    public merge(request: cc_arduino_cli_settings_v1_settings_pb.MergeRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.MergeResponse) => void): grpc.ClientUnaryCall;
-    public merge(request: cc_arduino_cli_settings_v1_settings_pb.MergeRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.MergeResponse) => void): grpc.ClientUnaryCall;
-    public getValue(request: cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetValueResponse) => void): grpc.ClientUnaryCall;
-    public getValue(request: cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetValueResponse) => void): grpc.ClientUnaryCall;
-    public getValue(request: cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.GetValueResponse) => void): grpc.ClientUnaryCall;
-    public setValue(request: cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.SetValueResponse) => void): grpc.ClientUnaryCall;
-    public setValue(request: cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.SetValueResponse) => void): grpc.ClientUnaryCall;
-    public setValue(request: cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.SetValueResponse) => void): grpc.ClientUnaryCall;
-    public write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
-    public write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
-    public write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
-    public delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
-    public delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
-    public delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
-}
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb.js b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb.js
deleted file mode 100644
index 76c399866..000000000
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb.js
+++ /dev/null
@@ -1,231 +0,0 @@
-// GENERATED CODE -- DO NOT EDIT!
-
-// Original file comments:
-// This file is part of arduino-cli.
-//
-// Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
-//
-// This software is released under the GNU General Public License version 3,
-// which covers the main part of arduino-cli.
-// The terms of this license can be found at:
-// https://www.gnu.org/licenses/gpl-3.0.en.html
-//
-// You can be released from the requirements of the above licenses by purchasing
-// a commercial license. Buying such a license is mandatory if you want to
-// modify or otherwise use the software for commercial activities involving the
-// Arduino software without disclosing the source code of your own applications.
-// To purchase a commercial license, send an email to license@arduino.cc.
-//
-'use strict';
-var cc_arduino_cli_settings_v1_settings_pb = require('../../../../../cc/arduino/cli/settings/v1/settings_pb.js');
-
-function serialize_cc_arduino_cli_settings_v1_DeleteRequest(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.DeleteRequest)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.DeleteRequest');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_DeleteRequest(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.DeleteRequest.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_DeleteResponse(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.DeleteResponse)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.DeleteResponse');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_DeleteResponse(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.DeleteResponse.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_GetAllRequest(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.GetAllRequest)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.GetAllRequest');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_GetAllRequest(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.GetAllRequest.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_GetAllResponse(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.GetAllResponse)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.GetAllResponse');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_GetAllResponse(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.GetAllResponse.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_GetValueRequest(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.GetValueRequest)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.GetValueRequest');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_GetValueRequest(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.GetValueRequest.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_GetValueResponse(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.GetValueResponse)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.GetValueResponse');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_GetValueResponse(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.GetValueResponse.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_MergeRequest(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.MergeRequest)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.MergeRequest');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_MergeRequest(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.MergeRequest.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_MergeResponse(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.MergeResponse)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.MergeResponse');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_MergeResponse(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.MergeResponse.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_SetValueRequest(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.SetValueRequest)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.SetValueRequest');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_SetValueRequest(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.SetValueRequest.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_SetValueResponse(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.SetValueResponse)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.SetValueResponse');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_SetValueResponse(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.SetValueResponse.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_WriteRequest(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.WriteRequest)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.WriteRequest');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_WriteRequest(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.WriteRequest.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-function serialize_cc_arduino_cli_settings_v1_WriteResponse(arg) {
-  if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.WriteResponse)) {
-    throw new Error('Expected argument of type cc.arduino.cli.settings.v1.WriteResponse');
-  }
-  return Buffer.from(arg.serializeBinary());
-}
-
-function deserialize_cc_arduino_cli_settings_v1_WriteResponse(buffer_arg) {
-  return cc_arduino_cli_settings_v1_settings_pb.WriteResponse.deserializeBinary(new Uint8Array(buffer_arg));
-}
-
-
-// The SettingsService provides an interface to Arduino CLI configuration
-// options
-var SettingsServiceService = exports['cc.arduino.cli.settings.v1.SettingsService'] = {
-  // List all the settings.
-getAll: {
-    path: '/cc.arduino.cli.settings.v1.SettingsService/GetAll',
-    requestStream: false,
-    responseStream: false,
-    requestType: cc_arduino_cli_settings_v1_settings_pb.GetAllRequest,
-    responseType: cc_arduino_cli_settings_v1_settings_pb.GetAllResponse,
-    requestSerialize: serialize_cc_arduino_cli_settings_v1_GetAllRequest,
-    requestDeserialize: deserialize_cc_arduino_cli_settings_v1_GetAllRequest,
-    responseSerialize: serialize_cc_arduino_cli_settings_v1_GetAllResponse,
-    responseDeserialize: deserialize_cc_arduino_cli_settings_v1_GetAllResponse,
-  },
-  // Set multiple settings values at once.
-merge: {
-    path: '/cc.arduino.cli.settings.v1.SettingsService/Merge',
-    requestStream: false,
-    responseStream: false,
-    requestType: cc_arduino_cli_settings_v1_settings_pb.MergeRequest,
-    responseType: cc_arduino_cli_settings_v1_settings_pb.MergeResponse,
-    requestSerialize: serialize_cc_arduino_cli_settings_v1_MergeRequest,
-    requestDeserialize: deserialize_cc_arduino_cli_settings_v1_MergeRequest,
-    responseSerialize: serialize_cc_arduino_cli_settings_v1_MergeResponse,
-    responseDeserialize: deserialize_cc_arduino_cli_settings_v1_MergeResponse,
-  },
-  // Get the value of a specific setting.
-getValue: {
-    path: '/cc.arduino.cli.settings.v1.SettingsService/GetValue',
-    requestStream: false,
-    responseStream: false,
-    requestType: cc_arduino_cli_settings_v1_settings_pb.GetValueRequest,
-    responseType: cc_arduino_cli_settings_v1_settings_pb.GetValueResponse,
-    requestSerialize: serialize_cc_arduino_cli_settings_v1_GetValueRequest,
-    requestDeserialize: deserialize_cc_arduino_cli_settings_v1_GetValueRequest,
-    responseSerialize: serialize_cc_arduino_cli_settings_v1_GetValueResponse,
-    responseDeserialize: deserialize_cc_arduino_cli_settings_v1_GetValueResponse,
-  },
-  // Set the value of a specific setting.
-setValue: {
-    path: '/cc.arduino.cli.settings.v1.SettingsService/SetValue',
-    requestStream: false,
-    responseStream: false,
-    requestType: cc_arduino_cli_settings_v1_settings_pb.SetValueRequest,
-    responseType: cc_arduino_cli_settings_v1_settings_pb.SetValueResponse,
-    requestSerialize: serialize_cc_arduino_cli_settings_v1_SetValueRequest,
-    requestDeserialize: deserialize_cc_arduino_cli_settings_v1_SetValueRequest,
-    responseSerialize: serialize_cc_arduino_cli_settings_v1_SetValueResponse,
-    responseDeserialize: deserialize_cc_arduino_cli_settings_v1_SetValueResponse,
-  },
-  // Writes to file settings currently stored in memory
-write: {
-    path: '/cc.arduino.cli.settings.v1.SettingsService/Write',
-    requestStream: false,
-    responseStream: false,
-    requestType: cc_arduino_cli_settings_v1_settings_pb.WriteRequest,
-    responseType: cc_arduino_cli_settings_v1_settings_pb.WriteResponse,
-    requestSerialize: serialize_cc_arduino_cli_settings_v1_WriteRequest,
-    requestDeserialize: deserialize_cc_arduino_cli_settings_v1_WriteRequest,
-    responseSerialize: serialize_cc_arduino_cli_settings_v1_WriteResponse,
-    responseDeserialize: deserialize_cc_arduino_cli_settings_v1_WriteResponse,
-  },
-  // Deletes an entry and rewrites the file settings
-delete: {
-    path: '/cc.arduino.cli.settings.v1.SettingsService/Delete',
-    requestStream: false,
-    responseStream: false,
-    requestType: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest,
-    responseType: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse,
-    requestSerialize: serialize_cc_arduino_cli_settings_v1_DeleteRequest,
-    requestDeserialize: deserialize_cc_arduino_cli_settings_v1_DeleteRequest,
-    responseSerialize: serialize_cc_arduino_cli_settings_v1_DeleteResponse,
-    responseDeserialize: deserialize_cc_arduino_cli_settings_v1_DeleteResponse,
-  },
-};
-
diff --git a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_pb.d.ts
deleted file mode 100644
index 03fdbf449..000000000
--- a/arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/settings/v1/settings_pb.d.ts
+++ /dev/null
@@ -1,238 +0,0 @@
-// package: cc.arduino.cli.settings.v1
-// file: cc/arduino/cli/settings/v1/settings.proto
-
-/* tslint:disable */
-/* eslint-disable */
-
-import * as jspb from "google-protobuf";
-
-export class GetAllResponse extends jspb.Message { 
-    getJsonData(): string;
-    setJsonData(value: string): GetAllResponse;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): GetAllResponse.AsObject;
-    static toObject(includeInstance: boolean, msg: GetAllResponse): GetAllResponse.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: GetAllResponse, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): GetAllResponse;
-    static deserializeBinaryFromReader(message: GetAllResponse, reader: jspb.BinaryReader): GetAllResponse;
-}
-
-export namespace GetAllResponse {
-    export type AsObject = {
-        jsonData: string,
-    }
-}
-
-export class MergeRequest extends jspb.Message { 
-    getJsonData(): string;
-    setJsonData(value: string): MergeRequest;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): MergeRequest.AsObject;
-    static toObject(includeInstance: boolean, msg: MergeRequest): MergeRequest.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: MergeRequest, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): MergeRequest;
-    static deserializeBinaryFromReader(message: MergeRequest, reader: jspb.BinaryReader): MergeRequest;
-}
-
-export namespace MergeRequest {
-    export type AsObject = {
-        jsonData: string,
-    }
-}
-
-export class GetValueResponse extends jspb.Message { 
-    getKey(): string;
-    setKey(value: string): GetValueResponse;
-    getJsonData(): string;
-    setJsonData(value: string): GetValueResponse;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): GetValueResponse.AsObject;
-    static toObject(includeInstance: boolean, msg: GetValueResponse): GetValueResponse.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: GetValueResponse, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): GetValueResponse;
-    static deserializeBinaryFromReader(message: GetValueResponse, reader: jspb.BinaryReader): GetValueResponse;
-}
-
-export namespace GetValueResponse {
-    export type AsObject = {
-        key: string,
-        jsonData: string,
-    }
-}
-
-export class SetValueRequest extends jspb.Message { 
-    getKey(): string;
-    setKey(value: string): SetValueRequest;
-    getJsonData(): string;
-    setJsonData(value: string): SetValueRequest;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): SetValueRequest.AsObject;
-    static toObject(includeInstance: boolean, msg: SetValueRequest): SetValueRequest.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: SetValueRequest, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): SetValueRequest;
-    static deserializeBinaryFromReader(message: SetValueRequest, reader: jspb.BinaryReader): SetValueRequest;
-}
-
-export namespace SetValueRequest {
-    export type AsObject = {
-        key: string,
-        jsonData: string,
-    }
-}
-
-export class GetAllRequest extends jspb.Message { 
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): GetAllRequest.AsObject;
-    static toObject(includeInstance: boolean, msg: GetAllRequest): GetAllRequest.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: GetAllRequest, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): GetAllRequest;
-    static deserializeBinaryFromReader(message: GetAllRequest, reader: jspb.BinaryReader): GetAllRequest;
-}
-
-export namespace GetAllRequest {
-    export type AsObject = {
-    }
-}
-
-export class GetValueRequest extends jspb.Message { 
-    getKey(): string;
-    setKey(value: string): GetValueRequest;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): GetValueRequest.AsObject;
-    static toObject(includeInstance: boolean, msg: GetValueRequest): GetValueRequest.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: GetValueRequest, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): GetValueRequest;
-    static deserializeBinaryFromReader(message: GetValueRequest, reader: jspb.BinaryReader): GetValueRequest;
-}
-
-export namespace GetValueRequest {
-    export type AsObject = {
-        key: string,
-    }
-}
-
-export class MergeResponse extends jspb.Message { 
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): MergeResponse.AsObject;
-    static toObject(includeInstance: boolean, msg: MergeResponse): MergeResponse.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: MergeResponse, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): MergeResponse;
-    static deserializeBinaryFromReader(message: MergeResponse, reader: jspb.BinaryReader): MergeResponse;
-}
-
-export namespace MergeResponse {
-    export type AsObject = {
-    }
-}
-
-export class SetValueResponse extends jspb.Message { 
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): SetValueResponse.AsObject;
-    static toObject(includeInstance: boolean, msg: SetValueResponse): SetValueResponse.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: SetValueResponse, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): SetValueResponse;
-    static deserializeBinaryFromReader(message: SetValueResponse, reader: jspb.BinaryReader): SetValueResponse;
-}
-
-export namespace SetValueResponse {
-    export type AsObject = {
-    }
-}
-
-export class WriteRequest extends jspb.Message { 
-    getFilePath(): string;
-    setFilePath(value: string): WriteRequest;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): WriteRequest.AsObject;
-    static toObject(includeInstance: boolean, msg: WriteRequest): WriteRequest.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: WriteRequest, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): WriteRequest;
-    static deserializeBinaryFromReader(message: WriteRequest, reader: jspb.BinaryReader): WriteRequest;
-}
-
-export namespace WriteRequest {
-    export type AsObject = {
-        filePath: string,
-    }
-}
-
-export class WriteResponse extends jspb.Message { 
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): WriteResponse.AsObject;
-    static toObject(includeInstance: boolean, msg: WriteResponse): WriteResponse.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: WriteResponse, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): WriteResponse;
-    static deserializeBinaryFromReader(message: WriteResponse, reader: jspb.BinaryReader): WriteResponse;
-}
-
-export namespace WriteResponse {
-    export type AsObject = {
-    }
-}
-
-export class DeleteRequest extends jspb.Message { 
-    getKey(): string;
-    setKey(value: string): DeleteRequest;
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): DeleteRequest.AsObject;
-    static toObject(includeInstance: boolean, msg: DeleteRequest): DeleteRequest.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: DeleteRequest, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): DeleteRequest;
-    static deserializeBinaryFromReader(message: DeleteRequest, reader: jspb.BinaryReader): DeleteRequest;
-}
-
-export namespace DeleteRequest {
-    export type AsObject = {
-        key: string,
-    }
-}
-
-export class DeleteResponse extends jspb.Message { 
-
-    serializeBinary(): Uint8Array;
-    toObject(includeInstance?: boolean): DeleteResponse.AsObject;
-    static toObject(includeInstance: boolean, msg: DeleteResponse): DeleteResponse.AsObject;
-    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-    static serializeBinaryToWriter(message: DeleteResponse, writer: jspb.BinaryWriter): void;
-    static deserializeBinary(bytes: Uint8Array): DeleteResponse;
-    static deserializeBinaryFromReader(message: DeleteResponse, reader: jspb.BinaryReader): DeleteResponse;
-}
-
-export namespace DeleteResponse {
-    export type AsObject = {
-    }
-}
diff --git a/arduino-ide-extension/src/node/config-service-impl.ts b/arduino-ide-extension/src/node/config-service-impl.ts
index 1f56748cc..f112f7206 100644
--- a/arduino-ide-extension/src/node/config-service-impl.ts
+++ b/arduino-ide-extension/src/node/config-service-impl.ts
@@ -1,7 +1,6 @@
 import { promises as fs } from 'node:fs';
 import { dirname } from 'node:path';
 import yaml from 'js-yaml';
-import * as grpc from '@grpc/grpc-js';
 import { injectable, inject, named } from '@theia/core/shared/inversify';
 import URI from '@theia/core/lib/common/uri';
 import { ILogger } from '@theia/core/lib/common/logger';
@@ -16,18 +15,17 @@ import {
   ConfigState,
 } from '../common/protocol';
 import { spawnCommand } from './exec-util';
-import {
-  MergeRequest,
-  WriteRequest,
-} from './cli-protocol/cc/arduino/cli/settings/v1/settings_pb';
-import { SettingsServiceClient } from './cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb';
-import * as serviceGrpcPb from './cli-protocol/cc/arduino/cli/settings/v1/settings_grpc_pb';
 import { ArduinoDaemonImpl } from './arduino-daemon-impl';
 import { DefaultCliConfig, CLI_CONFIG } from './cli-config';
 import { Deferred } from '@theia/core/lib/common/promise-util';
 import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
 import { deepClone, nls } from '@theia/core';
 import { ErrnoException } from './utils/errors';
+import {
+  SettingsMergeRequest,
+  SettingsWriteRequest,
+} from './cli-protocol/cc/arduino/cli/commands/v1/settings_pb';
+import { createArduinoCoreServiceClient } from './arduino-core-service-client';
 
 const deepmerge = require('deepmerge');
 
@@ -97,7 +95,7 @@ export class ConfigServiceImpl
     };
     copyDefaultCliConfig.locale = locale || 'en';
     const proxy = Network.stringify(network);
-    copyDefaultCliConfig.network = { proxy };
+    copyDefaultCliConfig.network = proxy ? { proxy } : {}; // must be an empty object to unset the default prop with the `WriteRequest`.
 
     // always use the port of the daemon
     const port = await this.daemon.getPort();
@@ -293,16 +291,16 @@ export class ConfigServiceImpl
   }
 
   private async updateDaemon(
-    port: string | number,
+    port: number | number,
     config: DefaultCliConfig
   ): Promise<void> {
-    const client = this.createClient(port);
-    const req = new MergeRequest();
+    const client = createArduinoCoreServiceClient({ port });
+    const req = new SettingsMergeRequest();
     const json = JSON.stringify(config, null, 2);
     req.setJsonData(json);
     this.logger.info(`Updating daemon with 'data': ${json}`);
     return new Promise<void>((resolve, reject) => {
-      client.merge(req, (error) => {
+      client.settingsMerge(req, (error) => {
         try {
           if (error) {
             reject(error);
@@ -316,14 +314,14 @@ export class ConfigServiceImpl
     });
   }
 
-  private async writeDaemonState(port: string | number): Promise<void> {
-    const client = this.createClient(port);
-    const req = new WriteRequest();
+  private async writeDaemonState(port: number | number): Promise<void> {
+    const client = createArduinoCoreServiceClient({ port });
+    const req = new SettingsWriteRequest();
     const cliConfigUri = await this.getCliConfigFileUri();
     const cliConfigPath = FileUri.fsPath(cliConfigUri);
     req.setFilePath(cliConfigPath);
     return new Promise<void>((resolve, reject) => {
-      client.write(req, (error) => {
+      client.settingsWrite(req, (error) => {
         try {
           if (error) {
             reject(error);
@@ -337,19 +335,6 @@ export class ConfigServiceImpl
     });
   }
 
-  private createClient(port: string | number): SettingsServiceClient {
-    // https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/doc/grpcjs_support.md#usage
-    const SettingsServiceClient = grpc.makeClientConstructor(
-      // @ts-expect-error: ignore
-      serviceGrpcPb['cc.arduino.cli.settings.v1.SettingsService'],
-      'SettingsServiceService'
-    ) as any;
-    return new SettingsServiceClient(
-      `localhost:${port}`,
-      grpc.credentials.createInsecure()
-    ) as SettingsServiceClient;
-  }
-
   // #1445
   private async ensureUserDirExists(
     cliConfig: DefaultCliConfig
diff --git a/arduino-ide-extension/src/node/core-client-provider.ts b/arduino-ide-extension/src/node/core-client-provider.ts
index 28e8f028c..f113b96c5 100644
--- a/arduino-ide-extension/src/node/core-client-provider.ts
+++ b/arduino-ide-extension/src/node/core-client-provider.ts
@@ -17,7 +17,6 @@ import {
   UpdateLibrariesIndexRequest,
   UpdateLibrariesIndexResponse,
 } from './cli-protocol/cc/arduino/cli/commands/v1/commands_pb';
-import * as commandsGrpcPb from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
 import {
   IndexType,
   IndexUpdateDidCompleteParams,
@@ -43,6 +42,10 @@ import {
 } from './grpc-progressible';
 import type { DefaultCliConfig } from './cli-config';
 import { ServiceError } from './service-error';
+import {
+  createArduinoCoreServiceClient,
+  createDefaultChannelOptions,
+} from './arduino-core-service-client';
 
 @injectable()
 export class CoreClientProvider {
@@ -128,10 +131,9 @@ export class CoreClientProvider {
   /**
    * Encapsulates both the gRPC core client creation (`CreateRequest`) and initialization (`InitRequest`).
    */
-  private async create(port: string): Promise<CoreClientProvider.Client> {
+  private async create(port: number): Promise<CoreClientProvider.Client> {
     this.closeClient();
-    const address = this.address(port);
-    const client = await this.createClient(address);
+    const client = await this.createClient(port);
     this.toDisposeOnCloseClient.pushAll([
       Disposable.create(() => client.client.close()),
     ]);
@@ -195,22 +197,9 @@ export class CoreClientProvider {
     return this.toDisposeOnCloseClient.dispose();
   }
 
-  private async createClient(
-    address: string
-  ): Promise<CoreClientProvider.Client> {
-    // https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/doc/grpcjs_support.md#usage
-    const ArduinoCoreServiceClient = grpc.makeClientConstructor(
-      // @ts-expect-error: ignore
-      commandsGrpcPb['cc.arduino.cli.commands.v1.ArduinoCoreService'],
-      'ArduinoCoreServiceService'
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    ) as any;
-    const client = new ArduinoCoreServiceClient(
-      address,
-      grpc.credentials.createInsecure(),
-      this.channelOptions
-    ) as ArduinoCoreServiceClient;
-
+  private async createClient(port: number): Promise<CoreClientProvider.Client> {
+    const channelOptions = createDefaultChannelOptions(this.version);
+    const client = createArduinoCoreServiceClient({ port, channelOptions });
     const instance = await new Promise<Instance>((resolve, reject) => {
       client.create(new CreateRequest(), (err, resp) => {
         if (err) {
@@ -407,18 +396,6 @@ export class CoreClientProvider {
     });
   }
 
-  private address(port: string): string {
-    return `localhost:${port}`;
-  }
-
-  private get channelOptions(): Record<string, unknown> {
-    return {
-      'grpc.max_send_message_length': 512 * 1024 * 1024,
-      'grpc.max_receive_message_length': 512 * 1024 * 1024,
-      'grpc.primary_user_agent': `arduino-ide/${this.version}`,
-    };
-  }
-
   private _version: string | undefined;
   private get version(): string {
     if (this._version) {
diff --git a/arduino-ide-extension/src/node/core-service-impl.ts b/arduino-ide-extension/src/node/core-service-impl.ts
index a8dfab98b..9cb1c4584 100644
--- a/arduino-ide-extension/src/node/core-service-impl.ts
+++ b/arduino-ide-extension/src/node/core-service-impl.ts
@@ -1,22 +1,44 @@
+import type { ClientReadableStream } from '@grpc/grpc-js';
+import { ApplicationError } from '@theia/core/lib/common/application-error';
+import type { CancellationToken } from '@theia/core/lib/common/cancellation';
+import { CommandService } from '@theia/core/lib/common/command';
+import {
+  Disposable,
+  DisposableCollection,
+} from '@theia/core/lib/common/disposable';
+import { nls } from '@theia/core/lib/common/nls';
+import type { Mutable } from '@theia/core/lib/common/types';
 import { FileUri } from '@theia/core/lib/node/file-uri';
 import { inject, injectable } from '@theia/core/shared/inversify';
-import { relative } from 'node:path';
 import * as jspb from 'google-protobuf';
 import { BoolValue } from 'google-protobuf/google/protobuf/wrappers_pb';
-import type { ClientReadableStream } from '@grpc/grpc-js';
+import path from 'node:path';
+import {
+  UploadResponse as ApiUploadResponse,
+  OutputMessage,
+  Port,
+  PortIdentifier,
+  resolveDetectedPort,
+} from '../common/protocol';
 import {
+  CompileSummary,
   CompilerWarnings,
-  CoreService,
   CoreError,
-  CompileSummary,
+  CoreService,
   isCompileSummary,
   isUploadResponse,
 } from '../common/protocol/core-service';
+import { ResponseService } from '../common/protocol/response-service';
+import { firstToUpperCase, notEmpty } from '../common/utils';
+import { BoardDiscovery, createApiPort } from './board-discovery';
+import { tryParseError } from './cli-error-parser';
+import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
+import { Instance } from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
 import {
   CompileRequest,
   CompileResponse,
 } from './cli-protocol/cc/arduino/cli/commands/v1/compile_pb';
-import { CoreClientAware } from './core-client-provider';
+import { Port as RpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
 import {
   BurnBootloaderRequest,
   BurnBootloaderResponse,
@@ -25,26 +47,13 @@ import {
   UploadUsingProgrammerRequest,
   UploadUsingProgrammerResponse,
 } from './cli-protocol/cc/arduino/cli/commands/v1/upload_pb';
-import { ResponseService } from '../common/protocol/response-service';
-import {
-  resolveDetectedPort,
-  OutputMessage,
-  PortIdentifier,
-  Port,
-  UploadResponse as ApiUploadResponse,
-} from '../common/protocol';
-import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
-import { Port as RpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
-import { ApplicationError, CommandService, Disposable, nls } from '@theia/core';
+import { CoreClientAware } from './core-client-provider';
+import { ExecuteWithProgress, ProgressResponse } from './grpc-progressible';
 import { MonitorManager } from './monitor-manager';
-import { AutoFlushingBuffer } from './utils/buffers';
-import { tryParseError } from './cli-error-parser';
-import { Instance } from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
-import { firstToUpperCase, notEmpty } from '../common/utils';
 import { ServiceError } from './service-error';
-import { ExecuteWithProgress, ProgressResponse } from './grpc-progressible';
-import type { Mutable } from '@theia/core/lib/common/types';
-import { BoardDiscovery, createApiPort } from './board-discovery';
+import { AutoFlushingBuffer } from './utils/buffers';
+import { userAbort } from '../common/nls';
+import { UserAbortApplicationError } from '../common/protocol/progressible';
 
 namespace Uploadable {
   export type Request = UploadRequest | UploadUsingProgrammerRequest;
@@ -64,9 +73,13 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
   @inject(BoardDiscovery)
   private readonly boardDiscovery: BoardDiscovery;
 
-  async compile(options: CoreService.Options.Compile): Promise<void> {
+  async compile(
+    options: CoreService.Options.Compile,
+    cancellationToken?: CancellationToken
+  ): Promise<void> {
     const coreClient = await this.coreClient;
     const { client, instance } = coreClient;
+    const request = this.compileRequest(options, instance);
     const compileSummary = <CompileSummaryFragment>{};
     const progressHandler = this.createProgressHandler(options);
     const compileSummaryHandler = (response: CompileResponse) =>
@@ -75,10 +88,15 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
       progressHandler,
       compileSummaryHandler
     );
-    const request = this.compileRequest(options, instance);
+    const toDisposeOnFinally = new DisposableCollection(handler);
     return new Promise<void>((resolve, reject) => {
-      client
-        .compile(request)
+      const call = client.compile(request);
+      if (cancellationToken) {
+        toDisposeOnFinally.push(
+          cancellationToken.onCancellationRequested(() => call.cancel())
+        );
+      }
+      call
         .on('data', handler.onData)
         .on('error', (error) => {
           if (!ServiceError.is(error)) {
@@ -87,30 +105,39 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
               error
             );
             reject(error);
-          } else {
-            const compilerErrors = tryParseError({
-              content: handler.content,
-              sketch: options.sketch,
-            });
-            const message = nls.localize(
-              'arduino/compile/error',
-              'Compilation error: {0}',
-              compilerErrors
-                .map(({ message }) => message)
-                .filter(notEmpty)
-                .shift() ?? error.details
-            );
-            this.sendResponse(
-              error.details + '\n\n' + message,
-              OutputMessage.Severity.Error
-            );
-            reject(CoreError.VerifyFailed(message, compilerErrors));
+            return;
+          }
+          if (ServiceError.isCancel(error)) {
+            console.log(userAbort);
+            reject(UserAbortApplicationError());
+            return;
           }
+          const compilerErrors = tryParseError({
+            content: handler.content,
+            sketch: options.sketch,
+          });
+          const message = nls.localize(
+            'arduino/compile/error',
+            'Compilation error: {0}',
+            compilerErrors
+              .map(({ message }) => message)
+              .filter(notEmpty)
+              .shift() ?? error.details
+          );
+          this.sendResponse(
+            error.details + '\n\n' + message,
+            OutputMessage.Severity.Error
+          );
+          reject(CoreError.VerifyFailed(message, compilerErrors));
         })
         .on('end', resolve);
     }).finally(() => {
-      handler.dispose();
+      toDisposeOnFinally.dispose();
       if (!isCompileSummary(compileSummary)) {
+        if (cancellationToken && cancellationToken.isCancellationRequested) {
+          // NOOP
+          return;
+        }
         console.error(
           `Have not received the full compile summary from the CLI while running the compilation. ${JSON.stringify(
             compileSummary
@@ -176,7 +203,10 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
     return request;
   }
 
-  upload(options: CoreService.Options.Upload): Promise<ApiUploadResponse> {
+  upload(
+    options: CoreService.Options.Upload,
+    cancellationToken?: CancellationToken
+  ): Promise<ApiUploadResponse> {
     const { usingProgrammer } = options;
     return this.doUpload(
       options,
@@ -190,7 +220,8 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
       usingProgrammer
         ? CoreError.UploadUsingProgrammerFailed
         : CoreError.UploadFailed,
-      `upload${usingProgrammer ? ' using programmer' : ''}`
+      `upload${usingProgrammer ? ' using programmer' : ''}`,
+      cancellationToken
     );
   }
 
@@ -204,7 +235,8 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
       client: ArduinoCoreServiceClient
     ) => (request: REQ) => ClientReadableStream<RESP>,
     errorCtor: ApplicationError.Constructor<number, CoreError.ErrorLocation[]>,
-    task: string
+    task: string,
+    cancellationToken?: CancellationToken
   ): Promise<ApiUploadResponse> {
     const portBeforeUpload = options.port;
     const uploadResponseFragment: Mutable<Partial<ApiUploadResponse>> = {
@@ -241,33 +273,47 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
       progressHandler,
       updateUploadResponseFragmentHandler
     );
+    const toDisposeOnFinally = new DisposableCollection(handler);
     const grpcCall = responseFactory(client);
     return this.notifyUploadWillStart(options).then(() =>
       new Promise<ApiUploadResponse>((resolve, reject) => {
-        grpcCall(this.initUploadRequest(request, options, instance))
+        const call = grpcCall(
+          this.initUploadRequest(request, options, instance)
+        );
+        if (cancellationToken) {
+          toDisposeOnFinally.push(
+            cancellationToken.onCancellationRequested(() => call.cancel())
+          );
+        }
+        call
           .on('data', handler.onData)
           .on('error', (error) => {
             if (!ServiceError.is(error)) {
               console.error(`Unexpected error occurred while ${task}.`, error);
               reject(error);
-            } else {
-              const message = nls.localize(
-                'arduino/upload/error',
-                '{0} error: {1}',
-                firstToUpperCase(task),
-                error.details
-              );
-              this.sendResponse(error.details, OutputMessage.Severity.Error);
-              reject(
-                errorCtor(
-                  message,
-                  tryParseError({
-                    content: handler.content,
-                    sketch: options.sketch,
-                  })
-                )
-              );
+              return;
             }
+            if (ServiceError.isCancel(error)) {
+              console.log(userAbort);
+              reject(UserAbortApplicationError());
+              return;
+            }
+            const message = nls.localize(
+              'arduino/upload/error',
+              '{0} error: {1}',
+              firstToUpperCase(task),
+              error.details
+            );
+            this.sendResponse(error.details, OutputMessage.Severity.Error);
+            reject(
+              errorCtor(
+                message,
+                tryParseError({
+                  content: handler.content,
+                  sketch: options.sketch,
+                })
+              )
+            );
           })
           .on('end', () => {
             if (isUploadResponse(uploadResponseFragment)) {
@@ -285,7 +331,7 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
             }
           });
       }).finally(async () => {
-        handler.dispose();
+        toDisposeOnFinally.dispose();
         await this.notifyUploadDidFinish(
           Object.assign(options, {
             afterPort: uploadResponseFragment.portAfterUpload,
@@ -320,16 +366,25 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
     return request;
   }
 
-  async burnBootloader(options: CoreService.Options.Bootloader): Promise<void> {
+  async burnBootloader(
+    options: CoreService.Options.Bootloader,
+    cancellationToken?: CancellationToken
+  ): Promise<void> {
     const coreClient = await this.coreClient;
     const { client, instance } = coreClient;
     const progressHandler = this.createProgressHandler(options);
     const handler = this.createOnDataHandler(progressHandler);
     const request = this.burnBootloaderRequest(options, instance);
+    const toDisposeOnFinally = new DisposableCollection(handler);
     return this.notifyUploadWillStart(options).then(() =>
       new Promise<void>((resolve, reject) => {
-        client
-          .burnBootloader(request)
+        const call = client.burnBootloader(request);
+        if (cancellationToken) {
+          toDisposeOnFinally.push(
+            cancellationToken.onCancellationRequested(() => call.cancel())
+          );
+        }
+        call
           .on('data', handler.onData)
           .on('error', (error) => {
             if (!ServiceError.is(error)) {
@@ -338,23 +393,28 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
                 error
               );
               reject(error);
-            } else {
-              this.sendResponse(error.details, OutputMessage.Severity.Error);
-              reject(
-                CoreError.BurnBootloaderFailed(
-                  nls.localize(
-                    'arduino/burnBootloader/error',
-                    'Error while burning the bootloader: {0}',
-                    error.details
-                  ),
-                  tryParseError({ content: handler.content })
-                )
-              );
+              return;
             }
+            if (ServiceError.isCancel(error)) {
+              console.log(userAbort);
+              reject(UserAbortApplicationError());
+              return;
+            }
+            this.sendResponse(error.details, OutputMessage.Severity.Error);
+            reject(
+              CoreError.BurnBootloaderFailed(
+                nls.localize(
+                  'arduino/burnBootloader/error',
+                  'Error while burning the bootloader: {0}',
+                  error.details
+                ),
+                tryParseError({ content: handler.content })
+              )
+            );
           })
           .on('end', resolve);
       }).finally(async () => {
-        handler.dispose();
+        toDisposeOnFinally.dispose();
         await this.notifyUploadDidFinish(
           Object.assign(options, { afterPort: options.port })
         );
@@ -463,7 +523,7 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
     for (const uri of Object.keys(options.sourceOverride)) {
       const content = options.sourceOverride[uri];
       if (content) {
-        const relativePath = relative(sketchPath, FileUri.fsPath(uri));
+        const relativePath = path.relative(sketchPath, FileUri.fsPath(uri));
         req.getSourceOverrideMap().set(relativePath, content);
       }
     }
@@ -535,18 +595,31 @@ function updateCompileSummary(
   compileSummary: CompileSummaryFragment,
   response: CompileResponse
 ): CompileSummaryFragment {
-  const buildPath = response.getBuildPath();
+  const messageCase = response.getMessageCase();
+  if (messageCase !== CompileResponse.MessageCase.RESULT) {
+    return compileSummary;
+  }
+  const result = response.getResult();
+  if (!result) {
+    console.warn(
+      `Build result is missing from response: ${JSON.stringify(
+        response.toObject(false)
+      )}`
+    );
+    return compileSummary;
+  }
+  const buildPath = result.getBuildPath();
   if (buildPath) {
     compileSummary.buildPath = buildPath;
     compileSummary.buildOutputUri = FileUri.create(buildPath).toString();
   }
-  const executableSectionsSize = response.getExecutableSectionsSizeList();
+  const executableSectionsSize = result.getExecutableSectionsSizeList();
   if (executableSectionsSize) {
     compileSummary.executableSectionsSize = executableSectionsSize.map((item) =>
       item.toObject(false)
     );
   }
-  const usedLibraries = response.getUsedLibrariesList();
+  const usedLibraries = result.getUsedLibrariesList();
   if (usedLibraries) {
     compileSummary.usedLibraries = usedLibraries.map((item) => {
       const object = item.toObject(false);
@@ -575,15 +648,15 @@ function updateCompileSummary(
       return library;
     });
   }
-  const boardPlatform = response.getBoardPlatform();
+  const boardPlatform = result.getBoardPlatform();
   if (boardPlatform) {
     compileSummary.buildPlatform = boardPlatform.toObject(false);
   }
-  const buildPlatform = response.getBuildPlatform();
+  const buildPlatform = result.getBuildPlatform();
   if (buildPlatform) {
     compileSummary.buildPlatform = buildPlatform.toObject(false);
   }
-  const buildProperties = response.getBuildPropertiesList();
+  const buildProperties = result.getBuildPropertiesList();
   if (buildProperties) {
     compileSummary.buildProperties = buildProperties.slice();
   }
diff --git a/arduino-ide-extension/src/node/library-service-impl.ts b/arduino-ide-extension/src/node/library-service-impl.ts
index afdfae052..1b447bb4c 100644
--- a/arduino-ide-extension/src/node/library-service-impl.ts
+++ b/arduino-ide-extension/src/node/library-service-impl.ts
@@ -81,7 +81,7 @@ export class LibraryServiceImpl
     }
 
     const req = new LibrarySearchRequest();
-    req.setQuery(options.query || '');
+    req.setSearchArgs(options.query || '');
     req.setInstance(instance);
     req.setOmitReleasesDetails(true);
     const resp = await new Promise<LibrarySearchResponse>((resolve, reject) =>
diff --git a/arduino-ide-extension/src/node/monitor-service.ts b/arduino-ide-extension/src/node/monitor-service.ts
index e6c3172f1..2e48f7f79 100644
--- a/arduino-ide-extension/src/node/monitor-service.ts
+++ b/arduino-ide-extension/src/node/monitor-service.ts
@@ -23,6 +23,7 @@ import {
   EnumerateMonitorPortSettingsRequest,
   EnumerateMonitorPortSettingsResponse,
   MonitorPortConfiguration,
+  MonitorPortOpenRequest,
   MonitorPortSetting,
   MonitorRequest,
   MonitorResponse,
@@ -229,16 +230,16 @@ export class MonitorService extends CoreClientAware implements Disposable {
       const coreClient = await this.coreClient;
 
       const { instance } = coreClient;
-      const monitorRequest = new MonitorRequest();
-      monitorRequest.setInstance(instance);
+      const openPortRequest = new MonitorPortOpenRequest();
+      openPortRequest.setInstance(instance);
       if (this.board?.fqbn) {
-        monitorRequest.setFqbn(this.board.fqbn);
+        openPortRequest.setFqbn(this.board.fqbn);
       }
       if (this.port?.address && this.port?.protocol) {
         const rpcPort = new RpcPort();
         rpcPort.setAddress(this.port.address);
         rpcPort.setProtocol(this.port.protocol);
-        monitorRequest.setPort(rpcPort);
+        openPortRequest.setPort(rpcPort);
       }
       const config = new MonitorPortConfiguration();
       for (const id in this.settings.pluggableMonitorSettings) {
@@ -247,9 +248,9 @@ export class MonitorService extends CoreClientAware implements Disposable {
         s.setValue(this.settings.pluggableMonitorSettings[id].selectedValue);
         config.addSettings(s);
       }
-      monitorRequest.setPortConfiguration(config);
+      openPortRequest.setPortConfiguration(config);
 
-      await this.pollWriteToStream(monitorRequest);
+      await this.pollWriteToStream(openPortRequest);
       // Only store the config, if the monitor has successfully started.
       this.currentPortConfigSnapshot = MonitorPortConfiguration.toObject(
         false,
@@ -344,7 +345,7 @@ export class MonitorService extends CoreClientAware implements Disposable {
     }
   }
 
-  pollWriteToStream(request: MonitorRequest): Promise<void> {
+  pollWriteToStream(request: MonitorPortOpenRequest): Promise<void> {
     const createWriteToStreamExecutor =
       (duplex: ClientDuplexStream<MonitorRequest, MonitorResponse>) =>
       (resolve: () => void, reject: (reason?: unknown) => void) => {
@@ -380,7 +381,7 @@ export class MonitorService extends CoreClientAware implements Disposable {
         ];
 
         this.setDuplexHandlers(duplex, resolvingDuplexHandlers);
-        duplex.write(request);
+        duplex.write(new MonitorRequest().setOpenRequest(request));
       };
 
     return Promise.race([
@@ -409,6 +410,8 @@ export class MonitorService extends CoreClientAware implements Disposable {
     ]) as Promise<unknown> as Promise<void>;
   }
 
+  private endingDuplex: Promise<void> | undefined;
+
   /**
    * Pauses the currently running monitor, it still closes the gRPC connection
    * with the underlying monitor process but it doesn't stop the message handlers
@@ -418,29 +421,43 @@ export class MonitorService extends CoreClientAware implements Disposable {
    * @returns
    */
   async pause(): Promise<void> {
-    return new Promise(async (resolve) => {
-      if (!this.duplex) {
-        this.logger.warn(
-          `monitor to ${this.port?.address} using ${this.port?.protocol} already stopped`
-        );
-        return resolve();
-      }
-      // It's enough to close the connection with the client
-      // to stop the monitor process
-      this.duplex.end();
-      this.logger.info(
-        `stopped monitor to ${this.port?.address} using ${this.port?.protocol}`
+    const duplex = this.duplex;
+    if (!duplex) {
+      this.logger.warn(
+        `monitor to ${this.port?.address} using ${this.port?.protocol} already stopped`
       );
+      return;
+    }
+    if (this.endingDuplex) {
+      return this.endingDuplex;
+    }
+    const deferredEnd = new Deferred<void>();
+    this.endingDuplex = deferredEnd.promise;
 
-      this.duplex.on('end', resolve);
+    // to terminate the monitor connection, send a close request, and wait for the end event
+    duplex.once('end', () => {
+      deferredEnd.resolve();
     });
+    try {
+      await new Promise((resolve) =>
+        duplex.write(new MonitorRequest().setClose(true), resolve)
+      );
+      await this.endingDuplex;
+    } finally {
+      this.endingDuplex = undefined;
+    }
+    // Sanity check
+    // Duplexes are allowed to be half open, check whether the monitor server (the readable) has ended
+    if (!duplex.readableEnded) {
+      throw new Error('Could not end the monitor connection');
+    }
   }
 
   /**
    * Stop the monitor currently running
    */
   async stop(): Promise<void> {
-    return this.pause().finally(this.stopMessagesHandlers.bind(this));
+    return this.pause().finally(() => this.stopMessagesHandlers());
   }
 
   /**
@@ -454,11 +471,7 @@ export class MonitorService extends CoreClientAware implements Disposable {
     if (!this.duplex) {
       throw createNotConnectedError(this.port);
     }
-    const coreClient = await this.coreClient;
-    const { instance } = coreClient;
-
     const req = new MonitorRequest();
-    req.setInstance(instance);
     req.setTxData(new TextEncoder().encode(message));
     return new Promise<void>((resolve, reject) => {
       if (this.duplex) {
@@ -588,17 +601,13 @@ export class MonitorService extends CoreClientAware implements Disposable {
       return;
     }
 
-    const coreClient = await this.coreClient;
-    const { instance } = coreClient;
-
     this.logger.info(
       `Sending monitor request with new port configuration: ${JSON.stringify(
         MonitorPortConfiguration.toObject(false, diffConfig)
       )}`
     );
     const req = new MonitorRequest();
-    req.setInstance(instance);
-    req.setPortConfiguration(diffConfig);
+    req.setUpdatedConfiguration(diffConfig);
     this.duplex.write(req);
   }
 
diff --git a/arduino-ide-extension/src/node/notification-service-server.ts b/arduino-ide-extension/src/node/notification-service-server.ts
index cd3cac91e..bcbdb99d8 100644
--- a/arduino-ide-extension/src/node/notification-service-server.ts
+++ b/arduino-ide-extension/src/node/notification-service-server.ts
@@ -43,7 +43,7 @@ export class NotificationServiceServerImpl
     this.clients.forEach((client) => client.notifyIndexUpdateDidFail(params));
   }
 
-  notifyDaemonDidStart(port: string): void {
+  notifyDaemonDidStart(port: number): void {
     this.clients.forEach((client) => client.notifyDaemonDidStart(port));
   }
 
diff --git a/arduino-ide-extension/src/node/sketches-service-impl.ts b/arduino-ide-extension/src/node/sketches-service-impl.ts
index 6e1b987bc..21320000e 100644
--- a/arduino-ide-extension/src/node/sketches-service-impl.ts
+++ b/arduino-ide-extension/src/node/sketches-service-impl.ts
@@ -167,7 +167,16 @@ export class SketchesServiceImpl
           reject(rejectWith);
           return;
         }
-        const responseSketchPath = maybeNormalizeDrive(resp.getLocationPath());
+        const sketch = resp.getSketch();
+        if (!sketch) {
+          reject(
+            new Error(`Incomplete LoadSketch response. Sketch is missing.`)
+          );
+          return;
+        }
+        const responseSketchPath = maybeNormalizeDrive(
+          sketch.getLocationPath()
+        );
         if (requestSketchPath !== responseSketchPath) {
           this.logger.warn(
             `Warning! The request sketch path was different than the response sketch path from the CLI. This could be a potential bug. Request: <${requestSketchPath}>, response: <${responseSketchPath}>.`
@@ -185,14 +194,14 @@ export class SketchesServiceImpl
         resolve({
           name: path.basename(responseSketchPath),
           uri: FileUri.create(responseSketchPath).toString(),
-          mainFileUri: FileUri.create(resp.getMainFile()).toString(),
-          otherSketchFileUris: resp
+          mainFileUri: FileUri.create(sketch.getMainFile()).toString(),
+          otherSketchFileUris: sketch
             .getOtherSketchFilesList()
             .map((p) => FileUri.create(p).toString()),
-          additionalFileUris: resp
+          additionalFileUris: sketch
             .getAdditionalFilesList()
             .map((p) => FileUri.create(p).toString()),
-          rootFolderFileUris: resp
+          rootFolderFileUris: sketch
             .getRootFolderFilesList()
             .map((p) => FileUri.create(p).toString()),
           mtimeMs,
diff --git a/arduino-ide-extension/src/test/browser/board-service-provider.test.ts b/arduino-ide-extension/src/test/browser/board-service-provider.test.ts
index 54d3aa8ba..dd733a2c6 100644
--- a/arduino-ide-extension/src/test/browser/board-service-provider.test.ts
+++ b/arduino-ide-extension/src/test/browser/board-service-provider.test.ts
@@ -170,6 +170,36 @@ describe('board-service-provider', () => {
     expect(events).deep.equals([expectedEvent]);
   });
 
+  it('should ignore custom board configs from the FQBN', () => {
+    boardsServiceProvider['_boardsConfig'] = {
+      selectedBoard: uno,
+      selectedPort: unoSerialPort,
+    };
+    const events: BoardsConfigChangeEvent[] = [];
+    toDisposeAfterEach.push(
+      boardsServiceProvider.onBoardsConfigDidChange((event) =>
+        events.push(event)
+      )
+    );
+    const mkr1000WithCustomOptions = {
+      ...mkr1000,
+      fqbn: `${mkr1000.fqbn}:c1=v1`,
+    };
+    const didUpdate = boardsServiceProvider.updateConfig(
+      mkr1000WithCustomOptions
+    );
+    expect(didUpdate).to.be.true;
+    const expectedEvent: BoardIdentifierChangeEvent = {
+      previousSelectedBoard: uno,
+      selectedBoard: mkr1000WithCustomOptions, // the even has the custom board options
+    };
+    expect(events).deep.equals([expectedEvent]);
+    // the persisted state does not have the config options property
+    expect(boardsServiceProvider.boardsConfig.selectedBoard?.fqbn).to.equal(
+      mkr1000.fqbn
+    );
+  });
+
   it('should not update the board if did not change (board identifier)', () => {
     boardsServiceProvider['_boardsConfig'] = {
       selectedBoard: uno,
diff --git a/arduino-ide-extension/src/test/browser/boards-data-store.test.ts b/arduino-ide-extension/src/test/browser/boards-data-store.test.ts
index 791c74e72..2ed808ad1 100644
--- a/arduino-ide-extension/src/test/browser/boards-data-store.test.ts
+++ b/arduino-ide-extension/src/test/browser/boards-data-store.test.ts
@@ -15,11 +15,14 @@ import {
   DisposableCollection,
 } from '@theia/core/lib/common/disposable';
 import { MessageService } from '@theia/core/lib/common/message-service';
-import { wait } from '@theia/core/lib/common/promise-util';
+import { wait, waitForEvent } from '@theia/core/lib/common/promise-util';
 import { Container, ContainerModule } from '@theia/core/shared/inversify';
 import { expect } from 'chai';
 import { BoardsDataStore } from '../../browser/boards/boards-data-store';
-import { BoardsServiceProvider } from '../../browser/boards/boards-service-provider';
+import {
+  BoardsServiceProvider,
+  UpdateBoardsConfigParams,
+} from '../../browser/boards/boards-service-provider';
 import { NotificationCenter } from '../../browser/notification-center';
 import {
   BoardDetails,
@@ -30,6 +33,7 @@ import {
 } from '../../common/protocol/boards-service';
 import { NotificationServiceServer } from '../../common/protocol/notification-service';
 import { bindBrowser } from './browser-test-bindings';
+import { unoSerialPort } from '../common/fixtures';
 
 disableJSDOM();
 
@@ -256,8 +260,12 @@ describe('boards-data-store', function () {
 
     const result = await boardsDataStore.selectConfigOption({
       fqbn,
-      option: configOption1.option,
-      selectedValue: configOption1.values[1].value,
+      optionsToUpdate: [
+        {
+          option: configOption1.option,
+          selectedValue: configOption1.values[1].value,
+        },
+      ],
     });
     expect(result).to.be.ok;
 
@@ -409,8 +417,129 @@ describe('boards-data-store', function () {
     );
     const result = await boardsDataStore.selectConfigOption({
       fqbn,
-      option: configOption1.option,
-      selectedValue: configOption1.values[1].value,
+      optionsToUpdate: [
+        {
+          option: configOption1.option,
+          selectedValue: configOption1.values[1].value,
+        },
+      ],
+    });
+    expect(result).to.be.ok;
+    expect(didChangeCounter).to.be.equal(1);
+
+    data = await boardsDataStore.getData(fqbn);
+    expect(data).to.be.deep.equal({
+      configOptions: [
+        {
+          ...configOption1,
+          values: [
+            { label: 'C1V1', selected: false, value: 'v1' },
+            { label: 'C1V2', selected: true, value: 'v2' },
+          ],
+        },
+      ],
+      programmers: [edbg, jlink],
+    });
+  });
+
+  it('should select multiple config options', async () => {
+    // reconfigure the board details mock for this test case to have multiple config options
+    toDisposeAfterEach.push(
+      mockBoardDetails([
+        {
+          fqbn,
+          ...baseDetails,
+          configOptions: [configOption1, configOption2],
+        },
+      ])
+    );
+
+    let data = await boardsDataStore.getData(fqbn);
+    expect(data).to.be.deep.equal({
+      configOptions: [configOption1, configOption2],
+      programmers: [edbg, jlink],
+    });
+
+    let didChangeCounter = 0;
+    toDisposeAfterEach.push(
+      boardsDataStore.onDidChange(() => didChangeCounter++)
+    );
+    const result = await boardsDataStore.selectConfigOption({
+      fqbn,
+      optionsToUpdate: [
+        {
+          option: configOption1.option,
+          selectedValue: configOption1.values[1].value,
+        },
+        {
+          option: configOption2.option,
+          selectedValue: configOption2.values[1].value,
+        },
+      ],
+    });
+    expect(result).to.be.ok;
+    expect(didChangeCounter).to.be.equal(1);
+
+    data = await boardsDataStore.getData(fqbn);
+    expect(data).to.be.deep.equal({
+      configOptions: [
+        {
+          ...configOption1,
+          values: [
+            { label: 'C1V1', selected: false, value: 'v1' },
+            { label: 'C1V2', selected: true, value: 'v2' },
+          ],
+        },
+        {
+          ...configOption2,
+          values: [
+            { label: 'C2V1', selected: false, value: 'v1' },
+            { label: 'C2V2', selected: true, value: 'v2' },
+          ],
+        },
+      ],
+      programmers: [edbg, jlink],
+    });
+  });
+
+  it('should emit a did change event when updating with multiple config options and at least one of them is known (valid option + valid value)', async () => {
+    // reconfigure the board details mock for this test case to have multiple config options
+    toDisposeAfterEach.push(
+      mockBoardDetails([
+        {
+          fqbn,
+          ...baseDetails,
+          configOptions: [configOption1, configOption2],
+        },
+      ])
+    );
+
+    let data = await boardsDataStore.getData(fqbn);
+    expect(data).to.be.deep.equal({
+      configOptions: [configOption1, configOption2],
+      programmers: [edbg, jlink],
+    });
+
+    let didChangeCounter = 0;
+    toDisposeAfterEach.push(
+      boardsDataStore.onDidChange(() => didChangeCounter++)
+    );
+    const result = await boardsDataStore.selectConfigOption({
+      fqbn,
+      optionsToUpdate: [
+        {
+          option: 'an unknown option',
+          selectedValue: configOption1.values[1].value,
+        },
+        {
+          option: configOption1.option,
+          selectedValue: configOption1.values[1].value,
+        },
+        {
+          option: configOption2.option,
+          selectedValue: 'an unknown value',
+        },
+      ],
     });
     expect(result).to.be.ok;
     expect(didChangeCounter).to.be.equal(1);
@@ -425,6 +554,103 @@ describe('boards-data-store', function () {
             { label: 'C1V2', selected: true, value: 'v2' },
           ],
         },
+        configOption2,
+      ],
+      programmers: [edbg, jlink],
+    });
+  });
+
+  it('should not emit a did change event when updating with multiple config options and all of the are unknown', async () => {
+    let data = await boardsDataStore.getData(fqbn);
+    expect(data).to.be.deep.equal({
+      configOptions: [configOption1],
+      programmers: [edbg, jlink],
+    });
+
+    let didChangeCounter = 0;
+    toDisposeAfterEach.push(
+      boardsDataStore.onDidChange(() => didChangeCounter++)
+    );
+    const result = await boardsDataStore.selectConfigOption({
+      fqbn,
+      optionsToUpdate: [
+        {
+          option: 'an unknown option',
+          selectedValue: configOption1.values[1].value,
+        },
+        {
+          option: configOption1.option,
+          selectedValue: 'an unknown value',
+        },
+      ],
+    });
+    expect(result).to.be.not.ok;
+    expect(didChangeCounter).to.be.equal(0);
+
+    data = await boardsDataStore.getData(fqbn);
+    expect(data).to.be.deep.equal({
+      configOptions: [configOption1],
+      programmers: [edbg, jlink],
+    });
+  });
+
+  it("should automatically update the selected config options if the boards config change 'reason' is the 'toolbar' and the (CLI) detected FQBN has config options", async () => {
+    // reconfigure the board details mock for this test case to have multiple config options
+    toDisposeAfterEach.push(
+      mockBoardDetails([
+        {
+          fqbn,
+          ...baseDetails,
+          configOptions: [configOption1, configOption2],
+        },
+      ])
+    );
+
+    let data = await boardsDataStore.getData(fqbn);
+    expect(data).to.be.deep.equal({
+      configOptions: [configOption1, configOption2],
+      programmers: [edbg, jlink],
+    });
+
+    let didChangeCounter = 0;
+    toDisposeAfterEach.push(
+      boardsDataStore.onDidChange(() => didChangeCounter++)
+    );
+
+    const boardsConfig = {
+      selectedPort: unoSerialPort, // the port value does not matter here, but the change must come from a toolbar as a boards config: with port+board,
+      selectedBoard: {
+        fqbn: `${board.fqbn}:${configOption1.option}=${configOption1.values[1].value},${configOption2.option}=${configOption2.values[1].value}`,
+        name: board.name,
+      },
+    };
+    const params: UpdateBoardsConfigParams = {
+      ...boardsConfig,
+      reason: 'toolbar',
+    };
+    const updated = boardsServiceProvider.updateConfig(params);
+    expect(updated).to.be.ok;
+
+    await waitForEvent(boardsDataStore.onDidChange, 100);
+
+    expect(didChangeCounter).to.be.equal(1);
+    data = await boardsDataStore.getData(fqbn);
+    expect(data).to.be.deep.equal({
+      configOptions: [
+        {
+          ...configOption1,
+          values: [
+            { label: 'C1V1', selected: false, value: 'v1' },
+            { label: 'C1V2', selected: true, value: 'v2' },
+          ],
+        },
+        {
+          ...configOption2,
+          values: [
+            { label: 'C2V1', selected: false, value: 'v1' },
+            { label: 'C2V2', selected: true, value: 'v2' },
+          ],
+        },
       ],
       programmers: [edbg, jlink],
     });
@@ -444,8 +670,9 @@ describe('boards-data-store', function () {
     );
     const result = await boardsDataStore.selectConfigOption({
       fqbn,
-      option: 'missing',
-      selectedValue: configOption1.values[1].value,
+      optionsToUpdate: [
+        { option: 'missing', selectedValue: configOption1.values[1].value },
+      ],
     });
     expect(result).to.be.not.ok;
     expect(didChangeCounter).to.be.equal(0);
@@ -470,8 +697,9 @@ describe('boards-data-store', function () {
     );
     const result = await boardsDataStore.selectConfigOption({
       fqbn,
-      option: configOption1.option,
-      selectedValue: 'missing',
+      optionsToUpdate: [
+        { option: configOption1.option, selectedValue: 'missing' },
+      ],
     });
     expect(result).to.be.not.ok;
     expect(didChangeCounter).to.be.equal(0);
diff --git a/arduino-ide-extension/src/test/node/arduino-daemon-impl.test.ts b/arduino-ide-extension/src/test/node/arduino-daemon-impl.test.ts
index 635bbeeb3..ed5149102 100644
--- a/arduino-ide-extension/src/test/node/arduino-daemon-impl.test.ts
+++ b/arduino-ide-extension/src/test/node/arduino-daemon-impl.test.ts
@@ -21,7 +21,7 @@ class SilentArduinoDaemonImpl extends ArduinoDaemonImpl {
 
   override async spawnDaemonProcess(): Promise<{
     daemon: ChildProcess;
-    port: string;
+    port: number;
   }> {
     return super.spawnDaemonProcess();
   }
diff --git a/arduino-ide-extension/src/test/node/boards-service-impl.slow-test.ts b/arduino-ide-extension/src/test/node/boards-service-impl.slow-test.ts
index fbd5aeb4d..767bb9d6e 100644
--- a/arduino-ide-extension/src/test/node/boards-service-impl.slow-test.ts
+++ b/arduino-ide-extension/src/test/node/boards-service-impl.slow-test.ts
@@ -1,7 +1,7 @@
 import { DisposableCollection } from '@theia/core/lib/common/disposable';
 import { Container } from '@theia/core/shared/inversify';
 import { expect } from 'chai';
-import { BoardSearch, BoardsService } from '../../common/protocol';
+import { BoardSearch, BoardsService, Installable } from '../../common/protocol';
 import { createBaseContainer, startDaemon } from './node-test-bindings';
 
 describe('boards-service-impl', () => {
@@ -24,6 +24,29 @@ describe('boards-service-impl', () => {
       expect(result).is.not.empty;
     });
 
+    it('should order the available platform release versions in descending order', async function () {
+      const result = await boardService.search({});
+      result.forEach((platform) =>
+        platform.availableVersions.forEach(
+          (currentVersion, index, versions) => {
+            if (index < versions.length - 2) {
+              const nextArrayElement = versions[index + 1];
+              const actual = Installable.Version.COMPARATOR(
+                currentVersion,
+                nextArrayElement
+              );
+              expect(actual).to.be.greaterThan(
+                0,
+                `Expected '${currentVersion}' to be gt '${nextArrayElement}'. All versions: ${JSON.stringify(
+                  versions
+                )}`
+              );
+            }
+          }
+        )
+      );
+    });
+
     it("should boost a result when 'types' includes 'arduino', and lower the score if deprecated", async () => {
       const result = await boardService.search({});
       const arduinoIndexes: number[] = [];
diff --git a/arduino-ide-extension/src/test/node/config-service-impl.slow-test.ts b/arduino-ide-extension/src/test/node/config-service-impl.slow-test.ts
new file mode 100644
index 000000000..fe585bb7d
--- /dev/null
+++ b/arduino-ide-extension/src/test/node/config-service-impl.slow-test.ts
@@ -0,0 +1,178 @@
+import {
+  Disposable,
+  DisposableCollection,
+} from '@theia/core/lib/common/disposable';
+import { deepClone } from '@theia/core/lib/common/objects';
+import type { MaybePromise, Mutable } from '@theia/core/lib/common/types';
+import type { Container } from '@theia/core/shared/inversify';
+import { expect } from 'chai';
+import { load as parseYaml } from 'js-yaml';
+import { promises as fs } from 'node:fs';
+import { join } from 'node:path';
+import temp from 'temp';
+import {
+  Config,
+  Network,
+  ProxySettings,
+} from '../../common/protocol/config-service';
+import { CLI_CONFIG, DefaultCliConfig } from '../../node/cli-config';
+import { ConfigServiceImpl } from '../../node/config-service-impl';
+import { ConfigDirUriProvider } from '../../node/theia/env-variables/env-variables-server';
+import {
+  createBaseContainer,
+  createCliConfig,
+  startDaemon,
+} from './node-test-bindings';
+
+describe('config-service-impl', () => {
+  const noProxy = 'none';
+  const manualProxy: ProxySettings = {
+    protocol: 'http',
+    hostname: 'hostname',
+    password: 'secret',
+    username: 'username',
+    port: '1234',
+  };
+
+  describe('setConfiguration', () => {
+    let configService: ConfigServiceImpl;
+    let toDispose: DisposableCollection;
+    let cliConfigPath: string;
+
+    beforeEach(async () => {
+      const container = await createBaseContainer();
+      toDispose = new DisposableCollection();
+      await startDaemon(container, toDispose);
+      configService = container.get<ConfigServiceImpl>(ConfigServiceImpl);
+      cliConfigPath = getCliConfigPath(container);
+    });
+
+    afterEach(() => toDispose.dispose());
+
+    it("should detect 'none' proxy with th default config", async () => {
+      const state = await configService.getConfiguration();
+      expect(state.config).to.be.not.undefined;
+      const config = <Config>state.config;
+      expect(config.network).to.be.equal(noProxy);
+      expect(Network.stringify(config.network)).is.undefined;
+      await assertRawConfigModel(cliConfigPath, (actualModel) => {
+        expect(actualModel.network).to.be.undefined;
+      });
+    });
+
+    it('should ignore noop changes', async () => {
+      const beforeState = await configService.getConfiguration();
+      const config = <Mutable<Config>>deepClone(beforeState).config;
+      let eventCounter = 0;
+      toDispose.push(configService.onConfigChange(() => eventCounter++));
+      await configService.setConfiguration(config);
+      const afterState = await configService.getConfiguration();
+      expect(beforeState.config).to.be.deep.equal(afterState.config);
+      expect(eventCounter).to.be.equal(0);
+    });
+
+    it('should set the manual proxy', async () => {
+      const beforeState = await configService.getConfiguration();
+      const config = <Mutable<Config>>deepClone(beforeState).config;
+      config.network = manualProxy;
+      let eventCounter = 0;
+      toDispose.push(configService.onConfigChange(() => eventCounter++));
+      await configService.setConfiguration(config);
+      const afterState = await configService.getConfiguration();
+      expect(beforeState.config).to.be.not.deep.equal(afterState.config);
+      expect(afterState.config?.network).to.be.deep.equal(manualProxy);
+      expect(eventCounter).to.be.equal(1);
+      await assertRawConfigModel(cliConfigPath, (actualModel) => {
+        expect(actualModel.network?.proxy).to.be.equal(
+          Network.stringify(manualProxy)
+        );
+      });
+    });
+
+    it('should unset the manual proxy', async () => {
+      const initialState = await configService.getConfiguration();
+      const config = <Mutable<Config>>deepClone(initialState).config;
+      config.network = manualProxy;
+      let eventCounter = 0;
+      toDispose.push(configService.onConfigChange(() => eventCounter++));
+      await configService.setConfiguration(config);
+      const beforeState = await configService.getConfiguration();
+      const config2 = <Mutable<Config>>deepClone(config);
+      config2.network = noProxy;
+      await configService.setConfiguration(config2);
+      const afterState = await configService.getConfiguration();
+      expect(beforeState.config).to.be.not.deep.equal(afterState.config);
+      expect(afterState.config?.network).to.be.deep.equal(noProxy);
+      expect(eventCounter).to.be.equal(2);
+      await assertRawConfigModel(cliConfigPath, (actualModel) => {
+        expect(actualModel.network?.proxy).to.be.undefined;
+      });
+    });
+  });
+
+  describe('setConfiguration (multiple CLI daemon sessions)', () => {
+    let tracked: typeof temp;
+    let toDispose: DisposableCollection;
+
+    before(() => {
+      tracked = temp.track();
+      toDispose = new DisposableCollection(
+        Disposable.create(() => tracked.cleanupSync())
+      );
+    });
+
+    after(() => toDispose.dispose());
+
+    it("should unset the 'network#proxy' config value between daemon sessions", async () => {
+      const configDirPath = tracked.mkdirSync();
+      const cliConfigPath = join(configDirPath, CLI_CONFIG);
+      const cliConfig = await createCliConfig(configDirPath);
+      const setupContainer = await createBaseContainer({
+        cliConfig,
+        configDirPath,
+      });
+      const toDisposeAfterFirstStart = new DisposableCollection();
+      toDispose.push(toDisposeAfterFirstStart);
+      await startDaemon(setupContainer, toDisposeAfterFirstStart);
+      toDisposeAfterFirstStart.dispose();
+
+      // second startup when the indexes are all downloaded and the daemon is initialized with the network#proxy
+      cliConfig.network = { proxy: Network.stringify(manualProxy) };
+      const container = await createBaseContainer({ cliConfig, configDirPath });
+      await startDaemon(container, toDispose);
+      const configService = container.get<ConfigServiceImpl>(ConfigServiceImpl);
+      let eventCounter = 0;
+      toDispose.push(configService.onConfigChange(() => eventCounter++));
+
+      const beforeState = await configService.getConfiguration();
+      const config = <Mutable<Config>>deepClone(beforeState.config);
+      config.network = noProxy;
+      await configService.setConfiguration(config);
+      const afterState = await configService.getConfiguration();
+      expect(beforeState.config).to.be.not.deep.equal(afterState.config);
+      expect(afterState.config?.network).to.be.deep.equal(noProxy);
+      expect(eventCounter).to.be.equal(1);
+      await assertRawConfigModel(cliConfigPath, (actualModel) => {
+        expect(actualModel.network?.proxy).to.be.undefined; // currently fails due to arduino/arduino-cli#2275
+      });
+    });
+  });
+
+  async function assertRawConfigModel(
+    cliConfigPath: string,
+    assert: (actual: DefaultCliConfig) => MaybePromise<void>
+  ): Promise<void> {
+    const raw = await fs.readFile(cliConfigPath, { encoding: 'utf8' });
+    const model = parseYaml(raw);
+    await assert(model);
+  }
+
+  function getCliConfigPath(container: Container): string {
+    const configDirUriProvider =
+      container.get<ConfigDirUriProvider>(ConfigDirUriProvider);
+    return configDirUriProvider
+      .configDirUri()
+      .resolve(CLI_CONFIG)
+      .path.fsPath();
+  }
+});
diff --git a/arduino-ide-extension/src/test/node/node-test-bindings.ts b/arduino-ide-extension/src/test/node/node-test-bindings.ts
index 29ff09f52..0f2ca5e35 100644
--- a/arduino-ide-extension/src/test/node/node-test-bindings.ts
+++ b/arduino-ide-extension/src/test/node/node-test-bindings.ts
@@ -111,7 +111,7 @@ class TestNotificationServiceServer implements NotificationServiceServer {
   notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void {
     this.events.push(`notifyIndexUpdateDidFail:${JSON.stringify(params)}`);
   }
-  notifyDaemonDidStart(port: string): void {
+  notifyDaemonDidStart(port: number): void {
     this.events.push(`notifyDaemonDidStart:${port}`);
   }
   notifyDaemonDidStop(): void {
diff --git a/i18n/en.json b/i18n/en.json
index 234781e58..c83d280c1 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -152,7 +152,8 @@
       "serialMonitor": "Serial Monitor",
       "type": "Type",
       "unknown": "Unknown",
-      "updateable": "Updatable"
+      "updateable": "Updatable",
+      "userAbort": "User abort"
     },
     "compile": {
       "error": "Compilation error: {0}"
diff --git a/yarn.lock b/yarn.lock
index fe12ae342..71a0d2acb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3885,6 +3885,14 @@ ardunno-cli@^0.1.2:
     nice-grpc-common "^2.0.2"
     protobufjs "^7.2.3"
 
+ardunno-cli@^0.1.7:
+  version "0.1.8"
+  resolved "https://registry.yarnpkg.com/ardunno-cli/-/ardunno-cli-0.1.8.tgz#c70b11b2ee0256227689079d01b828328bb1bfb6"
+  integrity sha512-DfyI98EFHdpc26nPYq2IXK6ZNypwBY0Fg+CAjYeGI/mjgQ1O9QUjNgz6NADwr+pcQ/ikhvLc88Ud9qR08CFTyg==
+  dependencies:
+    nice-grpc-common "^2.0.2"
+    protobufjs "^7.2.3"
+
 are-we-there-yet@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c"
@@ -4126,6 +4134,11 @@ available-typed-arrays@^1.0.5:
   resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
   integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
 
+available-typed-arrays@^1.0.6:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz#ac812d8ce5a6b976d738e1c45f08d0b00bc7d725"
+  integrity sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==
+
 axios@^1.0.0, axios@^1.6.2, axios@^1.6.7:
   version "1.6.7"
   resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7"
@@ -4557,6 +4570,16 @@ call-bind@^1.0.0, call-bind@^1.0.2:
     function-bind "^1.1.1"
     get-intrinsic "^1.0.2"
 
+call-bind@^1.0.5:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.6.tgz#6c46675fc7a5e9de82d75a233d586c8b7ac0d931"
+  integrity sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==
+  dependencies:
+    es-errors "^1.3.0"
+    function-bind "^1.1.2"
+    get-intrinsic "^1.2.3"
+    set-function-length "^1.2.0"
+
 callsites@^3.0.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
@@ -5513,6 +5536,30 @@ deep-eql@^4.1.3:
   dependencies:
     type-detect "^4.0.0"
 
+deep-equal@^2.2.3:
+  version "2.2.3"
+  resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1"
+  integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==
+  dependencies:
+    array-buffer-byte-length "^1.0.0"
+    call-bind "^1.0.5"
+    es-get-iterator "^1.1.3"
+    get-intrinsic "^1.2.2"
+    is-arguments "^1.1.1"
+    is-array-buffer "^3.0.2"
+    is-date-object "^1.0.5"
+    is-regex "^1.1.4"
+    is-shared-array-buffer "^1.0.2"
+    isarray "^2.0.5"
+    object-is "^1.1.5"
+    object-keys "^1.1.1"
+    object.assign "^4.1.4"
+    regexp.prototype.flags "^1.5.1"
+    side-channel "^1.0.4"
+    which-boxed-primitive "^1.0.2"
+    which-collection "^1.0.1"
+    which-typed-array "^1.1.13"
+
 deep-extend@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
@@ -5554,6 +5601,16 @@ define-data-property@^1.0.1:
     gopd "^1.0.1"
     has-property-descriptors "^1.0.0"
 
+define-data-property@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.2.tgz#f3c33b4f0102360cd7c0f5f28700f5678510b63a"
+  integrity sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==
+  dependencies:
+    es-errors "^1.3.0"
+    get-intrinsic "^1.2.2"
+    gopd "^1.0.1"
+    has-property-descriptors "^1.0.1"
+
 define-lazy-prop@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
@@ -6102,6 +6159,26 @@ es-abstract@^1.22.1:
     unbox-primitive "^1.0.2"
     which-typed-array "^1.1.11"
 
+es-errors@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
+  integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
+
+es-get-iterator@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6"
+  integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==
+  dependencies:
+    call-bind "^1.0.2"
+    get-intrinsic "^1.1.3"
+    has-symbols "^1.0.3"
+    is-arguments "^1.1.1"
+    is-map "^2.0.2"
+    is-set "^2.0.2"
+    is-string "^1.0.7"
+    isarray "^2.0.5"
+    stop-iteration-iterator "^1.0.0"
+
 es-iterator-helpers@^1.0.12:
   version "1.0.15"
   resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40"
@@ -6881,6 +6958,15 @@ forwarded@0.2.0:
   resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
   integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
 
+fqbn@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/fqbn/-/fqbn-1.0.5.tgz#4a4ea6babadeffc12c4637d5a4f5ef57c7ef317b"
+  integrity sha512-ImcK5biXDRSQHsvC8XXhEZH/YPmW7lRrmTABv6m5D7HQz3Xzi5foHZxTxmeXekcrRkZOfIrDWWtpk2wtUJgPPA==
+  dependencies:
+    ardunno-cli "^0.1.7"
+    clone "^2.1.2"
+    deep-equal "^2.2.3"
+
 fresh@0.5.2:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
@@ -6981,6 +7067,11 @@ function-bind@^1.1.1:
   resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
   integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
 
+function-bind@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+  integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
+
 function.prototype.name@^1.1.5, function.prototype.name@^1.1.6:
   version "1.1.6"
   resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd"
@@ -7069,6 +7160,17 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@
     has-proto "^1.0.1"
     has-symbols "^1.0.3"
 
+get-intrinsic@^1.2.2, get-intrinsic@^1.2.3:
+  version "1.2.4"
+  resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
+  integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
+  dependencies:
+    es-errors "^1.3.0"
+    function-bind "^1.1.2"
+    has-proto "^1.0.1"
+    has-symbols "^1.0.3"
+    hasown "^2.0.0"
+
 get-own-enumerable-property-symbols@^3.0.0:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
@@ -7443,6 +7545,13 @@ has-property-descriptors@^1.0.0:
   dependencies:
     get-intrinsic "^1.1.1"
 
+has-property-descriptors@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340"
+  integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==
+  dependencies:
+    get-intrinsic "^1.2.2"
+
 has-proto@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
@@ -7460,6 +7569,13 @@ has-tostringtag@^1.0.0:
   dependencies:
     has-symbols "^1.0.2"
 
+has-tostringtag@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
+  integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
+  dependencies:
+    has-symbols "^1.0.3"
+
 has-unicode@2.0.1, has-unicode@^2.0.0, has-unicode@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -7478,6 +7594,13 @@ hash.js@^1.1.7:
     inherits "^2.0.3"
     minimalistic-assert "^1.0.1"
 
+hasown@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
+  integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
+  dependencies:
+    function-bind "^1.1.2"
+
 hast-util-whitespace@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz#0ec64e257e6fc216c7d14c8a1b74d27d650b4557"
@@ -7814,6 +7937,15 @@ inspect-with-kind@^1.0.5:
   dependencies:
     kind-of "^6.0.2"
 
+internal-slot@^1.0.4:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802"
+  integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==
+  dependencies:
+    es-errors "^1.3.0"
+    hasown "^2.0.0"
+    side-channel "^1.0.4"
+
 internal-slot@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986"
@@ -7848,7 +7980,7 @@ ipaddr.js@1.9.1:
   resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
   integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
 
-is-arguments@^1.0.4:
+is-arguments@^1.0.4, is-arguments@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
   integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==
@@ -8002,7 +8134,7 @@ is-lambda@^1.0.1:
   resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5"
   integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==
 
-is-map@^2.0.1:
+is-map@^2.0.1, is-map@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127"
   integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==
@@ -8099,7 +8231,7 @@ is-regexp@^1.0.0:
   resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
   integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==
 
-is-set@^2.0.1:
+is-set@^2.0.1, is-set@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec"
   integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==
@@ -10207,6 +10339,14 @@ object-inspect@^1.12.3, object-inspect@^1.9.0:
   resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9"
   integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==
 
+object-is@^1.1.5:
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
+  integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.3"
+
 object-keys@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
@@ -11914,6 +12054,18 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
   resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
   integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
 
+set-function-length@^1.2.0:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.1.tgz#47cc5945f2c771e2cf261c6737cf9684a2a5e425"
+  integrity sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==
+  dependencies:
+    define-data-property "^1.1.2"
+    es-errors "^1.3.0"
+    function-bind "^1.1.2"
+    get-intrinsic "^1.2.3"
+    gopd "^1.0.1"
+    has-property-descriptors "^1.0.1"
+
 set-function-name@^2.0.0, set-function-name@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a"
@@ -12273,6 +12425,13 @@ statuses@2.0.1:
   resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
   integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
 
+stop-iteration-iterator@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4"
+  integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==
+  dependencies:
+    internal-slot "^1.0.4"
+
 stream-combiner@~0.0.4:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
@@ -13711,6 +13870,17 @@ which-typed-array@^1.1.11, which-typed-array@^1.1.2, which-typed-array@^1.1.9:
     gopd "^1.0.1"
     has-tostringtag "^1.0.0"
 
+which-typed-array@^1.1.13:
+  version "1.1.14"
+  resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.14.tgz#1f78a111aee1e131ca66164d8bdc3ab062c95a06"
+  integrity sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==
+  dependencies:
+    available-typed-arrays "^1.0.6"
+    call-bind "^1.0.5"
+    for-each "^0.3.3"
+    gopd "^1.0.1"
+    has-tostringtag "^1.0.1"
+
 which@^1.2.9:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"