diff --git a/arduino/cores/packageindex/index.go b/arduino/cores/packageindex/index.go
index a55c8d1f33e..ab25e781f0a 100644
--- a/arduino/cores/packageindex/index.go
+++ b/arduino/cores/packageindex/index.go
@@ -35,6 +35,7 @@ type indexPackage struct {
 	Name       string                  `json:"name,required"`
 	Maintainer string                  `json:"maintainer,required"`
 	WebsiteURL string                  `json:"websiteUrl"`
+	URL        string                  `json:"Url"`
 	Email      string                  `json:"email"`
 	Platforms  []*indexPlatformRelease `json:"platforms,required"`
 	Tools      []*indexToolRelease     `json:"tools,required"`
@@ -94,7 +95,7 @@ type indexHelp struct {
 }
 
 // MergeIntoPackages converts the Index data into a cores.Packages and merge them
-// with the existing conents of the cores.Packages passed as parameter.
+// with the existing contents of the cores.Packages passed as parameter.
 func (index Index) MergeIntoPackages(outPackages cores.Packages) {
 	for _, inPackage := range index.Packages {
 		inPackage.extractPackageIn(outPackages)
@@ -105,7 +106,9 @@ func (inPackage indexPackage) extractPackageIn(outPackages cores.Packages) {
 	outPackage := outPackages.GetOrCreatePackage(inPackage.Name)
 	outPackage.Maintainer = inPackage.Maintainer
 	outPackage.WebsiteURL = inPackage.WebsiteURL
+	outPackage.URL = inPackage.URL
 	outPackage.Email = inPackage.Email
+	outPackage.Help = cores.PackageHelp{Online: inPackage.Help.Online}
 
 	for _, inTool := range inPackage.Tools {
 		inTool.extractToolIn(outPackage)
diff --git a/arduino/cores/packagemanager/package_manager.go b/arduino/cores/packagemanager/package_manager.go
index d7016566ef4..7c7437d0384 100644
--- a/arduino/cores/packagemanager/package_manager.go
+++ b/arduino/cores/packagemanager/package_manager.go
@@ -201,8 +201,18 @@ func (pm *PackageManager) ResolveFQBN(fqbn *cores.FQBN) (
 
 // LoadPackageIndex loads a package index by looking up the local cached file from the specified URL
 func (pm *PackageManager) LoadPackageIndex(URL *url.URL) error {
-	_, err := pm.LoadPackageIndexFromFile(pm.IndexDir.Join(path.Base(URL.Path)))
-	return err
+	indexPath := pm.IndexDir.Join(path.Base(URL.Path))
+	index, err := packageindex.LoadIndex(indexPath)
+	if err != nil {
+		return fmt.Errorf("loading json index file %s: %s", indexPath, err)
+	}
+
+	for _, p := range index.Packages {
+		p.URL = URL.String()
+	}
+
+	index.MergeIntoPackages(pm.Packages)
+	return nil
 }
 
 // LoadPackageIndexFromFile load a package index from the specified file
diff --git a/arduino/cores/status.go b/arduino/cores/status.go
index 13f89eda90b..9c469abf5ca 100644
--- a/arduino/cores/status.go
+++ b/arduino/cores/status.go
@@ -30,14 +30,21 @@ func NewPackages() Packages {
 	return map[string]*Package{}
 }
 
+// PackageHelp contains info on how to reach maintainers for help
+type PackageHelp struct {
+	Online string `json:"online,omitempty"`
+}
+
 // Package represents a package in the system.
 type Package struct {
 	Name       string               // Name of the package.
 	Maintainer string               // Name of the maintainer.
 	WebsiteURL string               // Website of maintainer.
+	URL        string               // origin URL for package index json file.
 	Email      string               // Email of maintainer.
 	Platforms  map[string]*Platform // The platforms in the system.
 	Tools      map[string]*Tool     // The tools in the system.
+	Help       PackageHelp          `json:"-"`
 	Packages   Packages             `json:"-"`
 }
 
diff --git a/cli/board/board.go b/cli/board/board.go
index 658adde9d43..613130a28b7 100644
--- a/cli/board/board.go
+++ b/cli/board/board.go
@@ -34,7 +34,7 @@ func NewCommand() *cobra.Command {
 	}
 
 	boardCommand.AddCommand(initAttachCommand())
-	boardCommand.AddCommand(detailsCommand)
+	boardCommand.AddCommand(initDetailsCommand())
 	boardCommand.AddCommand(initListCommand())
 	boardCommand.AddCommand(listAllCommand)
 
diff --git a/cli/board/details.go b/cli/board/details.go
index 909cddef101..1b3d4ebe00a 100644
--- a/cli/board/details.go
+++ b/cli/board/details.go
@@ -17,8 +17,7 @@ package board
 
 import (
 	"context"
-	"os"
-
+	"fmt"
 	"github.com/arduino/arduino-cli/cli/errorcodes"
 	"github.com/arduino/arduino-cli/cli/feedback"
 	"github.com/arduino/arduino-cli/cli/instance"
@@ -27,15 +26,24 @@ import (
 	"github.com/arduino/arduino-cli/table"
 	"github.com/fatih/color"
 	"github.com/spf13/cobra"
+	"os"
 )
 
-var detailsCommand = &cobra.Command{
-	Use:     "details <FQBN>",
-	Short:   "Print details about a board.",
-	Long:    "Show information about a board, in particular if the board has options to be specified in the FQBN.",
-	Example: "  " + os.Args[0] + " board details arduino:avr:nano",
-	Args:    cobra.ExactArgs(1),
-	Run:     runDetailsCommand,
+var showFullDetails bool
+
+func initDetailsCommand() *cobra.Command {
+	var detailsCommand = &cobra.Command{
+		Use:     "details <FQBN>",
+		Short:   "Print details about a board.",
+		Long:    "Show information about a board, in particular if the board has options to be specified in the FQBN.",
+		Example: "  " + os.Args[0] + " board details arduino:avr:nano",
+		Args:    cobra.ExactArgs(1),
+		Run:     runDetailsCommand,
+	}
+
+	detailsCommand.Flags().BoolVarP(&showFullDetails, "full", "f", false, "Include full details in text output")
+
+	return detailsCommand
 }
 
 func runDetailsCommand(cmd *cobra.Command, args []string) {
@@ -85,18 +93,58 @@ func (dr detailsResult) String() string {
 	t := table.New()
 	t.SetColumnWidthMode(1, table.Average)
 	t.AddRow("Board name:", details.Name)
+	t.AddRow("Board fqbn:", details.Fqbn)
+	t.AddRow("Board propertiesId:", details.PropertiesId)
+	t.AddRow("Board version:", details.Version)
+
+	if details.Official {
+		t.AddRow() // get some space from above
+		t.AddRow("Official Arduino board:",
+			table.NewCell("✔", color.New(color.FgGreen)))
+	}
 
-	for i, tool := range details.RequiredTools {
+	for i, idp := range details.IdentificationPref {
 		if i == 0 {
 			t.AddRow() // get some space from above
-			t.AddRow("Required tools:", tool.Packager+":"+tool.Name, "", tool.Version)
+			t.AddRow("Identification Preferences:", "VID:"+idp.UsbID.VID+" PID:"+idp.UsbID.PID)
 			continue
 		}
-		t.AddRow("", tool.Packager+":"+tool.Name, "", tool.Version)
+		t.AddRow("", "VID:"+idp.UsbID.VID+" PID:"+idp.UsbID.PID)
 	}
 
-	for _, option := range details.ConfigOptions {
+	t.AddRow() // get some space from above
+	t.AddRow("Package name:", details.Package.Name)
+	t.AddRow("Package maintainer:", details.Package.Maintainer)
+	t.AddRow("Package URL:", details.Package.Url)
+	t.AddRow("Package websiteURL:", details.Package.WebsiteURL)
+	t.AddRow("Package online help:", details.Package.Help.Online)
+
+	t.AddRow() // get some space from above
+	t.AddRow("Platform name:", details.Platform.Name)
+	t.AddRow("Platform category:", details.Platform.Category)
+	t.AddRow("Platform architecture:", details.Platform.Architecture)
+	t.AddRow("Platform URL:", details.Platform.Url)
+	t.AddRow("Platform file name:", details.Platform.ArchiveFileName)
+	t.AddRow("Platform size (bytes):", fmt.Sprint(details.Platform.Size))
+	t.AddRow("Platform checksum:", details.Platform.Checksum)
+
+	t.AddRow() // get some space from above
+	for _, tool := range details.ToolsDependencies {
+		t.AddRow("Required tools:", tool.Packager+":"+tool.Name, "", tool.Version)
+		if showFullDetails {
+			for _, sys := range tool.Systems {
+				t.AddRow("", "OS:", "", sys.Host)
+				t.AddRow("", "File:", "", sys.ArchiveFileName)
+				t.AddRow("", "Size (bytes):", "", fmt.Sprint(sys.Size))
+				t.AddRow("", "Checksum:", "", sys.Checksum)
+				t.AddRow("", "URL:", "", sys.Url)
+				t.AddRow() // get some space from above
+			}
+		}
 		t.AddRow() // get some space from above
+	}
+
+	for _, option := range details.ConfigOptions {
 		t.AddRow("Option:", option.OptionLabel, "", option.Option)
 		for _, value := range option.Values {
 			green := color.New(color.FgGreen)
diff --git a/commands/board/details.go b/commands/board/details.go
index a49edfc7f84..9fb440c1f57 100644
--- a/commands/board/details.go
+++ b/commands/board/details.go
@@ -25,7 +25,8 @@ import (
 	rpc "github.com/arduino/arduino-cli/rpc/commands"
 )
 
-// Details FIXMEDOC
+// Details returns all details for a board including tools and HW identifiers.
+// This command basically gather al the information and translates it into the required grpc struct properties
 func Details(ctx context.Context, req *rpc.BoardDetailsReq) (*rpc.BoardDetailsResp, error) {
 	pm := commands.GetPackageManager(req.GetInstance().GetId())
 	if pm == nil {
@@ -37,13 +38,47 @@ func Details(ctx context.Context, req *rpc.BoardDetailsReq) (*rpc.BoardDetailsRe
 		return nil, fmt.Errorf("parsing fqbn: %s", err)
 	}
 
-	_, _, board, _, _, err := pm.ResolveFQBN(fqbn)
+	boardPackage, boardPlatform, board, _, _, err := pm.ResolveFQBN(fqbn)
 	if err != nil {
 		return nil, fmt.Errorf("loading board data: %s", err)
 	}
 
 	details := &rpc.BoardDetailsResp{}
 	details.Name = board.Name()
+	details.Fqbn = board.FQBN()
+	details.PropertiesId = board.BoardID
+	details.Official = fqbn.Package == "arduino"
+	details.Version = board.PlatformRelease.Version.String()
+
+	details.Package = &rpc.Package{
+		Name:       boardPackage.Name,
+		Maintainer: boardPackage.Maintainer,
+		WebsiteURL: boardPackage.WebsiteURL,
+		Email:      boardPackage.Email,
+		Help:       &rpc.Help{Online: boardPackage.Help.Online},
+		Url:        boardPackage.URL,
+	}
+
+	details.Platform = &rpc.BoardPlatform{
+		Architecture:    boardPlatform.Platform.Architecture,
+		Category:        boardPlatform.Platform.Category,
+		Url:             boardPlatform.Resource.URL,
+		ArchiveFileName: boardPlatform.Resource.ArchiveFileName,
+		Checksum:        boardPlatform.Resource.Checksum,
+		Size:            boardPlatform.Resource.Size,
+		Name:            boardPlatform.Platform.Name,
+	}
+
+	details.IdentificationPref = []*rpc.IdentificationPref{}
+	vids := board.Properties.SubTree("vid")
+	pids := board.Properties.SubTree("pid")
+	for id, vid := range vids.AsMap() {
+		if pid, ok := pids.GetOk(id); ok {
+			idPref := rpc.IdentificationPref{UsbID: &rpc.USBID{VID: vid, PID: pid}}
+			details.IdentificationPref = append(details.IdentificationPref, &idPref)
+		}
+	}
+
 	details.ConfigOptions = []*rpc.ConfigOption{}
 	options := board.GetConfigOptions()
 	for _, option := range options.Keys() {
@@ -60,7 +95,6 @@ func Details(ctx context.Context, req *rpc.BoardDetailsReq) (*rpc.BoardDetailsRe
 			} else if !hasSelected && i == 0 {
 				configValue.Selected = true
 			}
-
 			configValue.Value = value
 			configValue.ValueLabel = values.Get(value)
 			configOption.Values = append(configOption.Values, configValue)
@@ -69,12 +103,26 @@ func Details(ctx context.Context, req *rpc.BoardDetailsReq) (*rpc.BoardDetailsRe
 		details.ConfigOptions = append(details.ConfigOptions, configOption)
 	}
 
-	details.RequiredTools = []*rpc.RequiredTool{}
-	for _, reqTool := range board.PlatformRelease.Dependencies {
-		details.RequiredTools = append(details.RequiredTools, &rpc.RequiredTool{
-			Name:     reqTool.ToolName,
-			Packager: reqTool.ToolPackager,
-			Version:  reqTool.ToolVersion.String(),
+	details.ToolsDependencies = []*rpc.ToolsDependencies{}
+	for _, tool := range boardPlatform.Dependencies {
+		toolRelease := pm.FindToolDependency(tool)
+		var systems []*rpc.Systems
+		if toolRelease != nil {
+			for _, f := range toolRelease.Flavors {
+				systems = append(systems, &rpc.Systems{
+					Checksum:        f.Resource.Checksum,
+					Size:            f.Resource.Size,
+					Host:            f.OS,
+					ArchiveFileName: f.Resource.ArchiveFileName,
+					Url:             f.Resource.URL,
+				})
+			}
+		}
+		details.ToolsDependencies = append(details.ToolsDependencies, &rpc.ToolsDependencies{
+			Name:     tool.ToolName,
+			Packager: tool.ToolPackager,
+			Version:  tool.ToolVersion.String(),
+			Systems:  systems,
 		})
 	}
 
diff --git a/rpc/commands/board.pb.go b/rpc/commands/board.pb.go
index 33314fae378..7da990db9af 100644
--- a/rpc/commands/board.pb.go
+++ b/rpc/commands/board.pb.go
@@ -68,12 +68,22 @@ func (m *BoardDetailsReq) GetFqbn() string {
 }
 
 type BoardDetailsResp struct {
-	Name                 string          `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	ConfigOptions        []*ConfigOption `protobuf:"bytes,3,rep,name=config_options,json=configOptions,proto3" json:"config_options,omitempty"`
-	RequiredTools        []*RequiredTool `protobuf:"bytes,4,rep,name=required_tools,json=requiredTools,proto3" json:"required_tools,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
-	XXX_unrecognized     []byte          `json:"-"`
-	XXX_sizecache        int32           `json:"-"`
+	Fqbn                 string                `protobuf:"bytes,1,opt,name=fqbn,proto3" json:"fqbn,omitempty"`
+	Name                 string                `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Version              string                `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
+	PropertiesId         string                `protobuf:"bytes,4,opt,name=propertiesId,proto3" json:"propertiesId,omitempty"`
+	Alias                string                `protobuf:"bytes,5,opt,name=alias,proto3" json:"alias,omitempty"`
+	Official             bool                  `protobuf:"varint,6,opt,name=official,proto3" json:"official,omitempty"`
+	Pinout               string                `protobuf:"bytes,7,opt,name=pinout,proto3" json:"pinout,omitempty"`
+	Package              *Package              `protobuf:"bytes,8,opt,name=package,proto3" json:"package,omitempty"`
+	Platform             *BoardPlatform        `protobuf:"bytes,9,opt,name=platform,proto3" json:"platform,omitempty"`
+	ToolsDependencies    []*ToolsDependencies  `protobuf:"bytes,10,rep,name=toolsDependencies,proto3" json:"toolsDependencies,omitempty"`
+	ConfigOptions        []*ConfigOption       `protobuf:"bytes,11,rep,name=config_options,json=configOptions,proto3" json:"config_options,omitempty"`
+	XTools               []*Tool               `protobuf:"bytes,12,rep,name=_tools,json=Tools,proto3" json:"_tools,omitempty"`
+	IdentificationPref   []*IdentificationPref `protobuf:"bytes,13,rep,name=identification_pref,json=identificationPref,proto3" json:"identification_pref,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
+	XXX_unrecognized     []byte                `json:"-"`
+	XXX_sizecache        int32                 `json:"-"`
 }
 
 func (m *BoardDetailsResp) Reset()         { *m = BoardDetailsResp{} }
@@ -101,6 +111,13 @@ func (m *BoardDetailsResp) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_BoardDetailsResp proto.InternalMessageInfo
 
+func (m *BoardDetailsResp) GetFqbn() string {
+	if m != nil {
+		return m.Fqbn
+	}
+	return ""
+}
+
 func (m *BoardDetailsResp) GetName() string {
 	if m != nil {
 		return m.Name
@@ -108,6 +125,62 @@ func (m *BoardDetailsResp) GetName() string {
 	return ""
 }
 
+func (m *BoardDetailsResp) GetVersion() string {
+	if m != nil {
+		return m.Version
+	}
+	return ""
+}
+
+func (m *BoardDetailsResp) GetPropertiesId() string {
+	if m != nil {
+		return m.PropertiesId
+	}
+	return ""
+}
+
+func (m *BoardDetailsResp) GetAlias() string {
+	if m != nil {
+		return m.Alias
+	}
+	return ""
+}
+
+func (m *BoardDetailsResp) GetOfficial() bool {
+	if m != nil {
+		return m.Official
+	}
+	return false
+}
+
+func (m *BoardDetailsResp) GetPinout() string {
+	if m != nil {
+		return m.Pinout
+	}
+	return ""
+}
+
+func (m *BoardDetailsResp) GetPackage() *Package {
+	if m != nil {
+		return m.Package
+	}
+	return nil
+}
+
+func (m *BoardDetailsResp) GetPlatform() *BoardPlatform {
+	if m != nil {
+		return m.Platform
+	}
+	return nil
+}
+
+func (m *BoardDetailsResp) GetToolsDependencies() []*ToolsDependencies {
+	if m != nil {
+		return m.ToolsDependencies
+	}
+	return nil
+}
+
 func (m *BoardDetailsResp) GetConfigOptions() []*ConfigOption {
 	if m != nil {
 		return m.ConfigOptions
@@ -115,13 +188,445 @@ func (m *BoardDetailsResp) GetConfigOptions() []*ConfigOption {
 	return nil
 }
 
-func (m *BoardDetailsResp) GetRequiredTools() []*RequiredTool {
+func (m *BoardDetailsResp) GetXTools() []*Tool {
+	if m != nil {
+		return m.XTools
+	}
+	return nil
+}
+
+func (m *BoardDetailsResp) GetIdentificationPref() []*IdentificationPref {
+	if m != nil {
+		return m.IdentificationPref
+	}
+	return nil
+}
+
+type IdentificationPref struct {
+	UsbID                *USBID   `protobuf:"bytes,1,opt,name=usbID,proto3" json:"usbID,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *IdentificationPref) Reset()         { *m = IdentificationPref{} }
+func (m *IdentificationPref) String() string { return proto.CompactTextString(m) }
+func (*IdentificationPref) ProtoMessage()    {}
+func (*IdentificationPref) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0882eeddaa6507ab, []int{2}
+}
+
+func (m *IdentificationPref) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_IdentificationPref.Unmarshal(m, b)
+}
+func (m *IdentificationPref) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_IdentificationPref.Marshal(b, m, deterministic)
+}
+func (m *IdentificationPref) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_IdentificationPref.Merge(m, src)
+}
+func (m *IdentificationPref) XXX_Size() int {
+	return xxx_messageInfo_IdentificationPref.Size(m)
+}
+func (m *IdentificationPref) XXX_DiscardUnknown() {
+	xxx_messageInfo_IdentificationPref.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IdentificationPref proto.InternalMessageInfo
+
+func (m *IdentificationPref) GetUsbID() *USBID {
 	if m != nil {
-		return m.RequiredTools
+		return m.UsbID
 	}
 	return nil
 }
 
+type USBID struct {
+	VID                  string   `protobuf:"bytes,1,opt,name=VID,proto3" json:"VID,omitempty"`
+	PID                  string   `protobuf:"bytes,2,opt,name=PID,proto3" json:"PID,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *USBID) Reset()         { *m = USBID{} }
+func (m *USBID) String() string { return proto.CompactTextString(m) }
+func (*USBID) ProtoMessage()    {}
+func (*USBID) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0882eeddaa6507ab, []int{3}
+}
+
+func (m *USBID) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_USBID.Unmarshal(m, b)
+}
+func (m *USBID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_USBID.Marshal(b, m, deterministic)
+}
+func (m *USBID) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_USBID.Merge(m, src)
+}
+func (m *USBID) XXX_Size() int {
+	return xxx_messageInfo_USBID.Size(m)
+}
+func (m *USBID) XXX_DiscardUnknown() {
+	xxx_messageInfo_USBID.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_USBID proto.InternalMessageInfo
+
+func (m *USBID) GetVID() string {
+	if m != nil {
+		return m.VID
+	}
+	return ""
+}
+
+func (m *USBID) GetPID() string {
+	if m != nil {
+		return m.PID
+	}
+	return ""
+}
+
+type Package struct {
+	Maintainer           string   `protobuf:"bytes,1,opt,name=maintainer,proto3" json:"maintainer,omitempty"`
+	Url                  string   `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
+	WebsiteURL           string   `protobuf:"bytes,3,opt,name=websiteURL,proto3" json:"websiteURL,omitempty"`
+	Email                string   `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"`
+	Name                 string   `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"`
+	Help                 *Help    `protobuf:"bytes,6,opt,name=help,proto3" json:"help,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Package) Reset()         { *m = Package{} }
+func (m *Package) String() string { return proto.CompactTextString(m) }
+func (*Package) ProtoMessage()    {}
+func (*Package) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0882eeddaa6507ab, []int{4}
+}
+
+func (m *Package) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Package.Unmarshal(m, b)
+}
+func (m *Package) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Package.Marshal(b, m, deterministic)
+}
+func (m *Package) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Package.Merge(m, src)
+}
+func (m *Package) XXX_Size() int {
+	return xxx_messageInfo_Package.Size(m)
+}
+func (m *Package) XXX_DiscardUnknown() {
+	xxx_messageInfo_Package.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Package proto.InternalMessageInfo
+
+func (m *Package) GetMaintainer() string {
+	if m != nil {
+		return m.Maintainer
+	}
+	return ""
+}
+
+func (m *Package) GetUrl() string {
+	if m != nil {
+		return m.Url
+	}
+	return ""
+}
+
+func (m *Package) GetWebsiteURL() string {
+	if m != nil {
+		return m.WebsiteURL
+	}
+	return ""
+}
+
+func (m *Package) GetEmail() string {
+	if m != nil {
+		return m.Email
+	}
+	return ""
+}
+
+func (m *Package) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *Package) GetHelp() *Help {
+	if m != nil {
+		return m.Help
+	}
+	return nil
+}
+
+type Help struct {
+	Online               string   `protobuf:"bytes,1,opt,name=online,proto3" json:"online,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Help) Reset()         { *m = Help{} }
+func (m *Help) String() string { return proto.CompactTextString(m) }
+func (*Help) ProtoMessage()    {}
+func (*Help) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0882eeddaa6507ab, []int{5}
+}
+
+func (m *Help) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Help.Unmarshal(m, b)
+}
+func (m *Help) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Help.Marshal(b, m, deterministic)
+}
+func (m *Help) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Help.Merge(m, src)
+}
+func (m *Help) XXX_Size() int {
+	return xxx_messageInfo_Help.Size(m)
+}
+func (m *Help) XXX_DiscardUnknown() {
+	xxx_messageInfo_Help.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Help proto.InternalMessageInfo
+
+func (m *Help) GetOnline() string {
+	if m != nil {
+		return m.Online
+	}
+	return ""
+}
+
+type BoardPlatform struct {
+	Architecture         string   `protobuf:"bytes,1,opt,name=architecture,proto3" json:"architecture,omitempty"`
+	Category             string   `protobuf:"bytes,2,opt,name=category,proto3" json:"category,omitempty"`
+	Url                  string   `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"`
+	ArchiveFileName      string   `protobuf:"bytes,4,opt,name=archiveFileName,proto3" json:"archiveFileName,omitempty"`
+	Checksum             string   `protobuf:"bytes,5,opt,name=checksum,proto3" json:"checksum,omitempty"`
+	Size                 int64    `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"`
+	Name                 string   `protobuf:"bytes,7,opt,name=name,proto3" json:"name,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *BoardPlatform) Reset()         { *m = BoardPlatform{} }
+func (m *BoardPlatform) String() string { return proto.CompactTextString(m) }
+func (*BoardPlatform) ProtoMessage()    {}
+func (*BoardPlatform) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0882eeddaa6507ab, []int{6}
+}
+
+func (m *BoardPlatform) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_BoardPlatform.Unmarshal(m, b)
+}
+func (m *BoardPlatform) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_BoardPlatform.Marshal(b, m, deterministic)
+}
+func (m *BoardPlatform) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_BoardPlatform.Merge(m, src)
+}
+func (m *BoardPlatform) XXX_Size() int {
+	return xxx_messageInfo_BoardPlatform.Size(m)
+}
+func (m *BoardPlatform) XXX_DiscardUnknown() {
+	xxx_messageInfo_BoardPlatform.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BoardPlatform proto.InternalMessageInfo
+
+func (m *BoardPlatform) GetArchitecture() string {
+	if m != nil {
+		return m.Architecture
+	}
+	return ""
+}
+
+func (m *BoardPlatform) GetCategory() string {
+	if m != nil {
+		return m.Category
+	}
+	return ""
+}
+
+func (m *BoardPlatform) GetUrl() string {
+	if m != nil {
+		return m.Url
+	}
+	return ""
+}
+
+func (m *BoardPlatform) GetArchiveFileName() string {
+	if m != nil {
+		return m.ArchiveFileName
+	}
+	return ""
+}
+
+func (m *BoardPlatform) GetChecksum() string {
+	if m != nil {
+		return m.Checksum
+	}
+	return ""
+}
+
+func (m *BoardPlatform) GetSize() int64 {
+	if m != nil {
+		return m.Size
+	}
+	return 0
+}
+
+func (m *BoardPlatform) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+type ToolsDependencies struct {
+	Packager             string     `protobuf:"bytes,1,opt,name=packager,proto3" json:"packager,omitempty"`
+	Name                 string     `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Version              string     `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"`
+	Systems              []*Systems `protobuf:"bytes,4,rep,name=systems,proto3" json:"systems,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
+	XXX_unrecognized     []byte     `json:"-"`
+	XXX_sizecache        int32      `json:"-"`
+}
+
+func (m *ToolsDependencies) Reset()         { *m = ToolsDependencies{} }
+func (m *ToolsDependencies) String() string { return proto.CompactTextString(m) }
+func (*ToolsDependencies) ProtoMessage()    {}
+func (*ToolsDependencies) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0882eeddaa6507ab, []int{7}
+}
+
+func (m *ToolsDependencies) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ToolsDependencies.Unmarshal(m, b)
+}
+func (m *ToolsDependencies) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ToolsDependencies.Marshal(b, m, deterministic)
+}
+func (m *ToolsDependencies) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ToolsDependencies.Merge(m, src)
+}
+func (m *ToolsDependencies) XXX_Size() int {
+	return xxx_messageInfo_ToolsDependencies.Size(m)
+}
+func (m *ToolsDependencies) XXX_DiscardUnknown() {
+	xxx_messageInfo_ToolsDependencies.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ToolsDependencies proto.InternalMessageInfo
+
+func (m *ToolsDependencies) GetPackager() string {
+	if m != nil {
+		return m.Packager
+	}
+	return ""
+}
+
+func (m *ToolsDependencies) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *ToolsDependencies) GetVersion() string {
+	if m != nil {
+		return m.Version
+	}
+	return ""
+}
+
+func (m *ToolsDependencies) GetSystems() []*Systems {
+	if m != nil {
+		return m.Systems
+	}
+	return nil
+}
+
+type Systems struct {
+	Checksum             string   `protobuf:"bytes,1,opt,name=checksum,proto3" json:"checksum,omitempty"`
+	Host                 string   `protobuf:"bytes,2,opt,name=host,proto3" json:"host,omitempty"`
+	ArchiveFileName      string   `protobuf:"bytes,3,opt,name=archiveFileName,proto3" json:"archiveFileName,omitempty"`
+	Url                  string   `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"`
+	Size                 int64    `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Systems) Reset()         { *m = Systems{} }
+func (m *Systems) String() string { return proto.CompactTextString(m) }
+func (*Systems) ProtoMessage()    {}
+func (*Systems) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0882eeddaa6507ab, []int{8}
+}
+
+func (m *Systems) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Systems.Unmarshal(m, b)
+}
+func (m *Systems) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Systems.Marshal(b, m, deterministic)
+}
+func (m *Systems) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Systems.Merge(m, src)
+}
+func (m *Systems) XXX_Size() int {
+	return xxx_messageInfo_Systems.Size(m)
+}
+func (m *Systems) XXX_DiscardUnknown() {
+	xxx_messageInfo_Systems.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Systems proto.InternalMessageInfo
+
+func (m *Systems) GetChecksum() string {
+	if m != nil {
+		return m.Checksum
+	}
+	return ""
+}
+
+func (m *Systems) GetHost() string {
+	if m != nil {
+		return m.Host
+	}
+	return ""
+}
+
+func (m *Systems) GetArchiveFileName() string {
+	if m != nil {
+		return m.ArchiveFileName
+	}
+	return ""
+}
+
+func (m *Systems) GetUrl() string {
+	if m != nil {
+		return m.Url
+	}
+	return ""
+}
+
+func (m *Systems) GetSize() int64 {
+	if m != nil {
+		return m.Size
+	}
+	return 0
+}
+
 type ConfigOption struct {
 	Option               string         `protobuf:"bytes,1,opt,name=option,proto3" json:"option,omitempty"`
 	OptionLabel          string         `protobuf:"bytes,2,opt,name=option_label,json=optionLabel,proto3" json:"option_label,omitempty"`
@@ -135,7 +640,7 @@ func (m *ConfigOption) Reset()         { *m = ConfigOption{} }
 func (m *ConfigOption) String() string { return proto.CompactTextString(m) }
 func (*ConfigOption) ProtoMessage()    {}
 func (*ConfigOption) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{2}
+	return fileDescriptor_0882eeddaa6507ab, []int{9}
 }
 
 func (m *ConfigOption) XXX_Unmarshal(b []byte) error {
@@ -190,7 +695,7 @@ func (m *ConfigValue) Reset()         { *m = ConfigValue{} }
 func (m *ConfigValue) String() string { return proto.CompactTextString(m) }
 func (*ConfigValue) ProtoMessage()    {}
 func (*ConfigValue) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{3}
+	return fileDescriptor_0882eeddaa6507ab, []int{10}
 }
 
 func (m *ConfigValue) XXX_Unmarshal(b []byte) error {
@@ -232,7 +737,7 @@ func (m *ConfigValue) GetSelected() bool {
 	return false
 }
 
-type RequiredTool struct {
+type Tool struct {
 	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
 	Version              string   `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
 	Packager             string   `protobuf:"bytes,3,opt,name=packager,proto3" json:"packager,omitempty"`
@@ -241,46 +746,46 @@ type RequiredTool struct {
 	XXX_sizecache        int32    `json:"-"`
 }
 
-func (m *RequiredTool) Reset()         { *m = RequiredTool{} }
-func (m *RequiredTool) String() string { return proto.CompactTextString(m) }
-func (*RequiredTool) ProtoMessage()    {}
-func (*RequiredTool) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{4}
+func (m *Tool) Reset()         { *m = Tool{} }
+func (m *Tool) String() string { return proto.CompactTextString(m) }
+func (*Tool) ProtoMessage()    {}
+func (*Tool) Descriptor() ([]byte, []int) {
+	return fileDescriptor_0882eeddaa6507ab, []int{11}
 }
 
-func (m *RequiredTool) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_RequiredTool.Unmarshal(m, b)
+func (m *Tool) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Tool.Unmarshal(m, b)
 }
-func (m *RequiredTool) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_RequiredTool.Marshal(b, m, deterministic)
+func (m *Tool) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Tool.Marshal(b, m, deterministic)
 }
-func (m *RequiredTool) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_RequiredTool.Merge(m, src)
+func (m *Tool) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Tool.Merge(m, src)
 }
-func (m *RequiredTool) XXX_Size() int {
-	return xxx_messageInfo_RequiredTool.Size(m)
+func (m *Tool) XXX_Size() int {
+	return xxx_messageInfo_Tool.Size(m)
 }
-func (m *RequiredTool) XXX_DiscardUnknown() {
-	xxx_messageInfo_RequiredTool.DiscardUnknown(m)
+func (m *Tool) XXX_DiscardUnknown() {
+	xxx_messageInfo_Tool.DiscardUnknown(m)
 }
 
-var xxx_messageInfo_RequiredTool proto.InternalMessageInfo
+var xxx_messageInfo_Tool proto.InternalMessageInfo
 
-func (m *RequiredTool) GetName() string {
+func (m *Tool) GetName() string {
 	if m != nil {
 		return m.Name
 	}
 	return ""
 }
 
-func (m *RequiredTool) GetVersion() string {
+func (m *Tool) GetVersion() string {
 	if m != nil {
 		return m.Version
 	}
 	return ""
 }
 
-func (m *RequiredTool) GetPackager() string {
+func (m *Tool) GetPackager() string {
 	if m != nil {
 		return m.Packager
 	}
@@ -301,7 +806,7 @@ func (m *BoardAttachReq) Reset()         { *m = BoardAttachReq{} }
 func (m *BoardAttachReq) String() string { return proto.CompactTextString(m) }
 func (*BoardAttachReq) ProtoMessage()    {}
 func (*BoardAttachReq) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{5}
+	return fileDescriptor_0882eeddaa6507ab, []int{12}
 }
 
 func (m *BoardAttachReq) XXX_Unmarshal(b []byte) error {
@@ -361,7 +866,7 @@ func (m *BoardAttachResp) Reset()         { *m = BoardAttachResp{} }
 func (m *BoardAttachResp) String() string { return proto.CompactTextString(m) }
 func (*BoardAttachResp) ProtoMessage()    {}
 func (*BoardAttachResp) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{6}
+	return fileDescriptor_0882eeddaa6507ab, []int{13}
 }
 
 func (m *BoardAttachResp) XXX_Unmarshal(b []byte) error {
@@ -400,7 +905,7 @@ func (m *BoardListReq) Reset()         { *m = BoardListReq{} }
 func (m *BoardListReq) String() string { return proto.CompactTextString(m) }
 func (*BoardListReq) ProtoMessage()    {}
 func (*BoardListReq) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{7}
+	return fileDescriptor_0882eeddaa6507ab, []int{14}
 }
 
 func (m *BoardListReq) XXX_Unmarshal(b []byte) error {
@@ -439,7 +944,7 @@ func (m *BoardListResp) Reset()         { *m = BoardListResp{} }
 func (m *BoardListResp) String() string { return proto.CompactTextString(m) }
 func (*BoardListResp) ProtoMessage()    {}
 func (*BoardListResp) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{8}
+	return fileDescriptor_0882eeddaa6507ab, []int{15}
 }
 
 func (m *BoardListResp) XXX_Unmarshal(b []byte) error {
@@ -481,7 +986,7 @@ func (m *DetectedPort) Reset()         { *m = DetectedPort{} }
 func (m *DetectedPort) String() string { return proto.CompactTextString(m) }
 func (*DetectedPort) ProtoMessage()    {}
 func (*DetectedPort) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{9}
+	return fileDescriptor_0882eeddaa6507ab, []int{16}
 }
 
 func (m *DetectedPort) XXX_Unmarshal(b []byte) error {
@@ -542,7 +1047,7 @@ func (m *BoardListAllReq) Reset()         { *m = BoardListAllReq{} }
 func (m *BoardListAllReq) String() string { return proto.CompactTextString(m) }
 func (*BoardListAllReq) ProtoMessage()    {}
 func (*BoardListAllReq) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{10}
+	return fileDescriptor_0882eeddaa6507ab, []int{17}
 }
 
 func (m *BoardListAllReq) XXX_Unmarshal(b []byte) error {
@@ -588,7 +1093,7 @@ func (m *BoardListAllResp) Reset()         { *m = BoardListAllResp{} }
 func (m *BoardListAllResp) String() string { return proto.CompactTextString(m) }
 func (*BoardListAllResp) ProtoMessage()    {}
 func (*BoardListAllResp) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{11}
+	return fileDescriptor_0882eeddaa6507ab, []int{18}
 }
 
 func (m *BoardListAllResp) XXX_Unmarshal(b []byte) error {
@@ -628,7 +1133,7 @@ func (m *BoardListItem) Reset()         { *m = BoardListItem{} }
 func (m *BoardListItem) String() string { return proto.CompactTextString(m) }
 func (*BoardListItem) ProtoMessage()    {}
 func (*BoardListItem) Descriptor() ([]byte, []int) {
-	return fileDescriptor_0882eeddaa6507ab, []int{12}
+	return fileDescriptor_0882eeddaa6507ab, []int{19}
 }
 
 func (m *BoardListItem) XXX_Unmarshal(b []byte) error {
@@ -666,9 +1171,16 @@ func (m *BoardListItem) GetFQBN() string {
 func init() {
 	proto.RegisterType((*BoardDetailsReq)(nil), "cc.arduino.cli.commands.BoardDetailsReq")
 	proto.RegisterType((*BoardDetailsResp)(nil), "cc.arduino.cli.commands.BoardDetailsResp")
+	proto.RegisterType((*IdentificationPref)(nil), "cc.arduino.cli.commands.IdentificationPref")
+	proto.RegisterType((*USBID)(nil), "cc.arduino.cli.commands.USBID")
+	proto.RegisterType((*Package)(nil), "cc.arduino.cli.commands.Package")
+	proto.RegisterType((*Help)(nil), "cc.arduino.cli.commands.Help")
+	proto.RegisterType((*BoardPlatform)(nil), "cc.arduino.cli.commands.BoardPlatform")
+	proto.RegisterType((*ToolsDependencies)(nil), "cc.arduino.cli.commands.ToolsDependencies")
+	proto.RegisterType((*Systems)(nil), "cc.arduino.cli.commands.Systems")
 	proto.RegisterType((*ConfigOption)(nil), "cc.arduino.cli.commands.ConfigOption")
 	proto.RegisterType((*ConfigValue)(nil), "cc.arduino.cli.commands.ConfigValue")
-	proto.RegisterType((*RequiredTool)(nil), "cc.arduino.cli.commands.RequiredTool")
+	proto.RegisterType((*Tool)(nil), "cc.arduino.cli.commands.Tool")
 	proto.RegisterType((*BoardAttachReq)(nil), "cc.arduino.cli.commands.BoardAttachReq")
 	proto.RegisterType((*BoardAttachResp)(nil), "cc.arduino.cli.commands.BoardAttachResp")
 	proto.RegisterType((*BoardListReq)(nil), "cc.arduino.cli.commands.BoardListReq")
@@ -682,46 +1194,74 @@ func init() {
 func init() { proto.RegisterFile("commands/board.proto", fileDescriptor_0882eeddaa6507ab) }
 
 var fileDescriptor_0882eeddaa6507ab = []byte{
-	// 656 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xdd, 0x6e, 0x13, 0x3b,
-	0x10, 0xd6, 0x36, 0x69, 0x4e, 0x32, 0x49, 0x7a, 0x8e, 0xac, 0x9e, 0x73, 0x56, 0xe5, 0x82, 0x74,
-	0x45, 0x51, 0x24, 0xd4, 0x44, 0x2a, 0x17, 0x5c, 0xf0, 0x23, 0xb5, 0x54, 0x48, 0x45, 0x01, 0x8a,
-	0x55, 0x10, 0x42, 0x42, 0x8b, 0xe3, 0x75, 0x13, 0x2b, 0x9b, 0xf5, 0xc6, 0x76, 0xfa, 0x0a, 0x3c,
-	0x0c, 0xb7, 0x3c, 0x01, 0x4f, 0x86, 0xfc, 0xb7, 0xda, 0x4a, 0x84, 0x4a, 0xd0, 0xab, 0x9d, 0x99,
-	0xfd, 0x3c, 0xf3, 0xcd, 0xcc, 0x67, 0xc3, 0x2e, 0x15, 0xcb, 0x25, 0x29, 0x32, 0x35, 0x9e, 0x0a,
-	0x22, 0xb3, 0x51, 0x29, 0x85, 0x16, 0xe8, 0x7f, 0x4a, 0x47, 0x44, 0x66, 0x6b, 0x5e, 0x88, 0x11,
-	0xcd, 0xf9, 0x28, 0x80, 0xf6, 0xfe, 0xad, 0xe0, 0xc6, 0x10, 0x85, 0xc3, 0x27, 0x19, 0xfc, 0x7d,
-	0x62, 0x8e, 0x9f, 0x32, 0x4d, 0x78, 0xae, 0x30, 0x5b, 0xa1, 0xa7, 0xd0, 0xe6, 0x85, 0xd2, 0xa4,
-	0xa0, 0x2c, 0x8e, 0x06, 0xd1, 0xb0, 0x7b, 0xb4, 0x3f, 0xda, 0x90, 0x75, 0x74, 0xe6, 0x81, 0xb8,
-	0x3a, 0x82, 0x10, 0x34, 0x2f, 0x57, 0xd3, 0x22, 0xde, 0x1a, 0x44, 0xc3, 0x0e, 0xb6, 0x76, 0xf2,
-	0x3d, 0x82, 0x7f, 0xae, 0x97, 0x51, 0xa5, 0x01, 0x16, 0x64, 0xc9, 0x02, 0xd0, 0xd8, 0x68, 0x02,
-	0x3b, 0x54, 0x14, 0x97, 0x7c, 0x96, 0x8a, 0x52, 0x73, 0x51, 0xa8, 0xb8, 0x31, 0x68, 0x0c, 0xbb,
-	0x47, 0x07, 0x1b, 0x19, 0x3c, 0xb7, 0xf0, 0x37, 0x16, 0x8d, 0xfb, 0xb4, 0xe6, 0x29, 0x93, 0x4d,
-	0xb2, 0xd5, 0x9a, 0x4b, 0x96, 0xa5, 0x5a, 0x88, 0x5c, 0xc5, 0xcd, 0x1b, 0xb2, 0x61, 0x0f, 0xbf,
-	0x10, 0x22, 0xc7, 0x7d, 0x59, 0xf3, 0x54, 0xf2, 0x25, 0x82, 0x5e, 0xbd, 0x1a, 0xfa, 0x0f, 0x5a,
-	0x8e, 0xa5, 0x1d, 0x53, 0x07, 0x7b, 0x0f, 0xed, 0x43, 0xcf, 0x59, 0x69, 0x4e, 0xa6, 0x2c, 0xf7,
-	0x0d, 0x76, 0x5d, 0x6c, 0x62, 0x42, 0xe8, 0x09, 0xb4, 0xae, 0x48, 0xbe, 0x66, 0xa1, 0xbf, 0x7b,
-	0x37, 0xf4, 0xf7, 0xde, 0x80, 0xb1, 0x3f, 0x93, 0x7c, 0x86, 0x6e, 0x2d, 0x8c, 0x76, 0x61, 0xdb,
-	0xfe, 0xf0, 0x34, 0x9c, 0x83, 0xee, 0x42, 0xd7, 0x1a, 0xd7, 0x48, 0x80, 0x0d, 0x39, 0x0e, 0x7b,
-	0xd0, 0x56, 0x2c, 0x67, 0x54, 0xb3, 0x2c, 0x6e, 0x0c, 0xa2, 0x61, 0x1b, 0x57, 0x7e, 0xf2, 0x01,
-	0x7a, 0xf5, 0x51, 0x54, 0xbb, 0x8a, 0x6a, 0xbb, 0x8a, 0xe1, 0xaf, 0x2b, 0x26, 0x95, 0xe9, 0xdf,
-	0x25, 0x0f, 0xae, 0xc9, 0x5c, 0x12, 0xba, 0x20, 0x33, 0x26, 0x6d, 0xe6, 0x0e, 0xae, 0xfc, 0xe4,
-	0x5b, 0x04, 0x3b, 0x56, 0x0a, 0xc7, 0x5a, 0x13, 0x3a, 0xbf, 0x05, 0xc1, 0xdd, 0x81, 0x8e, 0xbd,
-	0x01, 0xe9, 0x5a, 0x72, 0xcf, 0xa4, 0x6d, 0x03, 0xef, 0x24, 0x37, 0x53, 0x50, 0x0b, 0xa6, 0xe9,
-	0x3c, 0x2d, 0x89, 0x9e, 0x7b, 0x36, 0xe0, 0x42, 0xe7, 0x44, 0xcf, 0xd1, 0x01, 0xec, 0x28, 0x46,
-	0x24, 0x9d, 0xa7, 0x9a, 0x2f, 0x99, 0x58, 0xeb, 0xb8, 0x69, 0x31, 0x7d, 0x17, 0xbd, 0x70, 0xc1,
-	0xe4, 0x93, 0xbf, 0x27, 0x81, 0xb5, 0x2a, 0xd1, 0x4b, 0xe8, 0x6b, 0xa2, 0x16, 0x69, 0x29, 0xc5,
-	0x4c, 0x32, 0xa5, 0x3c, 0xf7, 0xcd, 0xe2, 0xba, 0x20, 0x6a, 0x71, 0xee, 0xc1, 0xb8, 0xa7, 0x6b,
-	0x5e, 0xf2, 0x0a, 0x7a, 0x36, 0xfd, 0x84, 0x2b, 0xfd, 0xe7, 0x23, 0x49, 0x26, 0xd0, 0xaf, 0xa5,
-	0x53, 0x25, 0x7a, 0x0c, 0xdb, 0xa5, 0x90, 0xda, 0x70, 0xfc, 0xf5, 0x05, 0x38, 0x65, 0xda, 0x2a,
-	0xe0, 0x5c, 0x48, 0x8d, 0xdd, 0x99, 0xe4, 0x6b, 0x04, 0xbd, 0x7a, 0xdc, 0x6c, 0x9e, 0x64, 0x59,
-	0xd5, 0x73, 0x07, 0x07, 0xd7, 0x6e, 0xde, 0xbc, 0x2b, 0x54, 0x04, 0xc5, 0x55, 0xbe, 0x99, 0x74,
-	0xb0, 0xbd, 0x26, 0xdd, 0x36, 0xfa, 0x21, 0xea, 0x64, 0xf9, 0x0c, 0x5a, 0x76, 0x7b, 0xe1, 0xb2,
-	0xde, 0xdf, 0xc8, 0xb5, 0x6a, 0xf1, 0x4c, 0xb3, 0x25, 0xf6, 0xa7, 0x92, 0x95, 0xdf, 0x94, 0xf9,
-	0x71, 0x9c, 0xe7, 0xb7, 0x20, 0x30, 0xa3, 0x21, 0x27, 0x11, 0x22, 0x67, 0x2a, 0xde, 0x1a, 0x34,
-	0xac, 0x86, 0x6c, 0xe8, 0x58, 0xce, 0x54, 0x82, 0xfd, 0xeb, 0x56, 0x95, 0x54, 0x65, 0xad, 0x8d,
-	0xe8, 0xb7, 0xda, 0x78, 0x54, 0x5b, 0xa1, 0xf9, 0xf1, 0xd3, 0x2b, 0x88, 0xa0, 0xf9, 0xe2, 0xed,
-	0xc9, 0xeb, 0xf0, 0x84, 0x1a, 0xfb, 0xe4, 0xf0, 0xe3, 0x83, 0x19, 0xd7, 0xf3, 0xf5, 0xd4, 0x54,
-	0x18, 0xfb, 0x8a, 0xe1, 0x7b, 0x48, 0x73, 0x3e, 0x96, 0x25, 0x1d, 0x87, 0xea, 0xd3, 0x96, 0x9d,
-	0xfe, 0xc3, 0x1f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x88, 0xae, 0x33, 0x62, 0x4f, 0x06, 0x00, 0x00,
+	// 1094 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xeb, 0x6e, 0x1b, 0x45,
+	0x14, 0xd6, 0xc6, 0xd7, 0x1c, 0xdb, 0x69, 0x3b, 0x14, 0x58, 0x05, 0x11, 0xdc, 0x15, 0x45, 0x11,
+	0x51, 0x1d, 0x51, 0x2a, 0x21, 0x95, 0x8b, 0x94, 0x60, 0x55, 0xb8, 0x0a, 0xc5, 0x4c, 0x93, 0x0a,
+	0x21, 0x90, 0x19, 0x8f, 0xc7, 0xf6, 0x28, 0xeb, 0x9d, 0xcd, 0xcc, 0x38, 0xa8, 0xbc, 0x00, 0xe2,
+	0x11, 0x78, 0x06, 0xfe, 0xf2, 0x83, 0xb7, 0xe0, 0x8d, 0x10, 0x9a, 0xdb, 0x66, 0xdd, 0xc4, 0xa9,
+	0xa0, 0xfd, 0xe5, 0x73, 0xbe, 0x3d, 0xe7, 0xcc, 0xb9, 0x7c, 0x67, 0x3c, 0x70, 0x9b, 0x8a, 0xc5,
+	0x82, 0x64, 0x13, 0xb5, 0x3f, 0x16, 0x44, 0x4e, 0x7a, 0xb9, 0x14, 0x5a, 0xa0, 0xb7, 0x29, 0xed,
+	0x11, 0x39, 0x59, 0xf2, 0x4c, 0xf4, 0x68, 0xca, 0x7b, 0xc1, 0x68, 0xfb, 0xcd, 0xc2, 0xdc, 0x08,
+	0x22, 0x73, 0xf6, 0xc9, 0x04, 0x6e, 0x1c, 0x1a, 0xf7, 0x3e, 0xd3, 0x84, 0xa7, 0x0a, 0xb3, 0x33,
+	0xf4, 0x39, 0x34, 0x79, 0xa6, 0x34, 0xc9, 0x28, 0x8b, 0xa3, 0x6e, 0xb4, 0xdb, 0xba, 0x7f, 0xa7,
+	0xb7, 0x26, 0x6a, 0x6f, 0xe0, 0x0d, 0x71, 0xe1, 0x82, 0x10, 0x54, 0xa7, 0x67, 0xe3, 0x2c, 0xde,
+	0xe8, 0x46, 0xbb, 0x9b, 0xd8, 0xca, 0xc9, 0x3f, 0x55, 0xb8, 0xb9, 0x7a, 0x8c, 0xca, 0x0b, 0xc3,
+	0xe8, 0xc2, 0xd0, 0x60, 0x19, 0x59, 0xb0, 0xe0, 0x6c, 0x64, 0x14, 0x43, 0xe3, 0x9c, 0x49, 0xc5,
+	0x45, 0x16, 0x57, 0x2c, 0x1c, 0x54, 0x94, 0x40, 0x3b, 0x97, 0x22, 0x67, 0x52, 0x73, 0xa6, 0x06,
+	0x93, 0xb8, 0x6a, 0x3f, 0xaf, 0x60, 0xe8, 0x36, 0xd4, 0x48, 0xca, 0x89, 0x8a, 0x6b, 0xf6, 0xa3,
+	0x53, 0xd0, 0x36, 0x34, 0xc5, 0x74, 0xca, 0x29, 0x27, 0x69, 0x5c, 0xef, 0x46, 0xbb, 0x4d, 0x5c,
+	0xe8, 0xe8, 0x2d, 0xa8, 0xe7, 0x3c, 0x13, 0x4b, 0x1d, 0x37, 0xac, 0x8b, 0xd7, 0xd0, 0x43, 0x68,
+	0xe4, 0x84, 0x9e, 0x92, 0x19, 0x8b, 0x9b, 0xb6, 0x2d, 0xdd, 0xb5, 0x6d, 0x19, 0x3a, 0x3b, 0x1c,
+	0x1c, 0xd0, 0x21, 0x34, 0xf3, 0x94, 0xe8, 0xa9, 0x90, 0x8b, 0x78, 0xd3, 0x3a, 0x7f, 0xb0, 0xd6,
+	0xd9, 0x36, 0x6a, 0xe8, 0xad, 0x71, 0xe1, 0x87, 0xbe, 0x83, 0x5b, 0x5a, 0x88, 0x54, 0xf5, 0x59,
+	0xce, 0xb2, 0x09, 0xcb, 0x28, 0x67, 0x2a, 0x86, 0x6e, 0x65, 0xb7, 0x75, 0xff, 0xc3, 0xb5, 0xc1,
+	0x8e, 0x5f, 0xf4, 0xc0, 0x97, 0x83, 0xa0, 0x23, 0xd8, 0xa2, 0x22, 0x9b, 0xf2, 0xd9, 0x48, 0xe4,
+	0x9a, 0x8b, 0x4c, 0xc5, 0x2d, 0x1b, 0xf6, 0xee, 0xda, 0xb0, 0x5f, 0x5a, 0xf3, 0x6f, 0xac, 0x35,
+	0xee, 0xd0, 0x92, 0xa6, 0xd0, 0x03, 0xa8, 0x8f, 0xec, 0x19, 0x71, 0xdb, 0x46, 0x79, 0xf7, 0xda,
+	0xe4, 0x70, 0xcd, 0xa6, 0x88, 0x7e, 0x80, 0x37, 0xf8, 0x84, 0x65, 0x9a, 0x4f, 0x39, 0x25, 0x26,
+	0xd0, 0x28, 0x97, 0x6c, 0x1a, 0x77, 0x6c, 0x88, 0xbd, 0xf5, 0x04, 0x5c, 0xf1, 0x19, 0x4a, 0x36,
+	0xc5, 0x88, 0x5f, 0xc2, 0x92, 0xc7, 0x80, 0x2e, 0x5b, 0xa2, 0x07, 0x50, 0x5b, 0xaa, 0xf1, 0xa0,
+	0xef, 0x69, 0xbe, 0xb3, 0xf6, 0x94, 0x93, 0xa7, 0x87, 0x83, 0x3e, 0x76, 0xc6, 0xc9, 0x1e, 0xd4,
+	0xac, 0x8e, 0x6e, 0x42, 0xe5, 0x99, 0x77, 0xde, 0xc4, 0x46, 0x34, 0xc8, 0x70, 0xd0, 0xf7, 0xec,
+	0x35, 0x62, 0xf2, 0x57, 0x04, 0x0d, 0xcf, 0x06, 0xb4, 0x03, 0xb0, 0x20, 0x3c, 0xd3, 0x84, 0x67,
+	0x4c, 0x7a, 0xb7, 0x12, 0x62, 0xbc, 0x97, 0x32, 0x0d, 0xde, 0x4b, 0x99, 0x1a, 0x8f, 0x9f, 0xd9,
+	0x58, 0x71, 0xcd, 0x4e, 0xf0, 0x91, 0x67, 0x7f, 0x09, 0x31, 0xe4, 0x66, 0x0b, 0xc2, 0x53, 0xcf,
+	0x7c, 0xa7, 0x14, 0x4b, 0x54, 0x2b, 0x2d, 0xd1, 0x47, 0x50, 0x9d, 0xb3, 0x34, 0xb7, 0x64, 0xbf,
+	0x6e, 0x24, 0x5f, 0xb1, 0x34, 0xc7, 0xd6, 0x34, 0xd9, 0x81, 0xaa, 0xd1, 0xcc, 0x3e, 0x88, 0x2c,
+	0xe5, 0x19, 0xf3, 0x29, 0x7b, 0x2d, 0xf9, 0x3b, 0x82, 0xce, 0x0a, 0x57, 0xcd, 0x3e, 0x12, 0x49,
+	0xe7, 0x5c, 0x33, 0xaa, 0x97, 0x32, 0xd8, 0xaf, 0x60, 0x66, 0xf3, 0x28, 0xd1, 0x6c, 0x26, 0xe4,
+	0x73, 0x5f, 0x69, 0xa1, 0x87, 0x06, 0x54, 0x2e, 0x1a, 0xb0, 0x0b, 0x37, 0xac, 0xf7, 0x39, 0x7b,
+	0xc4, 0x53, 0xf6, 0xc4, 0x54, 0xe5, 0x4a, 0x7d, 0x11, 0xb6, 0x71, 0xe7, 0x8c, 0x9e, 0xaa, 0xe5,
+	0xc2, 0x17, 0x5e, 0xe8, 0xa6, 0x21, 0x8a, 0xff, 0xc2, 0x6c, 0xf1, 0x15, 0x6c, 0xe5, 0xa2, 0x49,
+	0x8d, 0x8b, 0x26, 0x25, 0xbf, 0x47, 0x70, 0xeb, 0xd2, 0xc2, 0x98, 0xc8, 0x7e, 0x8d, 0xc3, 0xd0,
+	0x0a, 0xfd, 0x3f, 0xde, 0x57, 0x0f, 0xa1, 0xa1, 0x9e, 0x2b, 0xcd, 0x16, 0x2a, 0xae, 0x5a, 0x5e,
+	0xaf, 0xbf, 0x41, 0x9e, 0x3a, 0x3b, 0x1c, 0x1c, 0x92, 0xdf, 0x22, 0x68, 0x78, 0x70, 0xa5, 0xd6,
+	0xe8, 0x72, 0xad, 0x73, 0xa1, 0x74, 0xc8, 0xc8, 0xc8, 0x57, 0x75, 0xb1, 0x72, 0x75, 0x17, 0xfd,
+	0x04, 0xaa, 0x17, 0x13, 0x08, 0xbd, 0xab, 0x5d, 0xf4, 0x2e, 0xf9, 0x35, 0x82, 0x76, 0xf9, 0x06,
+	0xb0, 0x14, 0xb1, 0x52, 0x41, 0x11, 0x87, 0xdf, 0x81, 0xb6, 0x93, 0x46, 0x29, 0x19, 0xb3, 0x40,
+	0xed, 0x96, 0xc3, 0x8e, 0x0c, 0x84, 0x3e, 0x83, 0xfa, 0x39, 0x49, 0x97, 0x4c, 0xc5, 0x15, 0xdb,
+	0x92, 0xf7, 0x5f, 0x72, 0xe7, 0x3c, 0x33, 0xc6, 0xd8, 0xfb, 0x24, 0x3f, 0x41, 0xab, 0x04, 0x9b,
+	0x7d, 0xb0, 0x1f, 0x7c, 0x1a, 0x4e, 0x41, 0xef, 0x41, 0xcb, 0x0a, 0x2b, 0x49, 0x80, 0x85, 0x5c,
+	0x0e, 0xdb, 0xd0, 0x54, 0x2c, 0x65, 0x54, 0xb3, 0x89, 0x6d, 0x4c, 0x13, 0x17, 0x7a, 0x32, 0x84,
+	0xaa, 0xa1, 0x44, 0x31, 0xe9, 0xe8, 0xea, 0x49, 0x6f, 0xac, 0x4e, 0xba, 0xcc, 0x99, 0xca, 0x2a,
+	0x67, 0x92, 0x3f, 0x23, 0xd8, 0xb2, 0x7b, 0x73, 0xa0, 0x35, 0xa1, 0xf3, 0xd7, 0xf0, 0x97, 0xfb,
+	0x0e, 0x6c, 0xda, 0x37, 0xc0, 0x68, 0x29, 0x79, 0x58, 0x2a, 0x0b, 0x9c, 0x48, 0x6e, 0xaa, 0x57,
+	0xa7, 0x4c, 0xd3, 0xf9, 0x28, 0x27, 0x7a, 0x1e, 0x2e, 0x11, 0x07, 0x0d, 0x89, 0x9e, 0xa3, 0xbb,
+	0xb0, 0xa5, 0x98, 0x21, 0xc2, 0x48, 0xf3, 0x05, 0x33, 0xff, 0x7b, 0x6e, 0xfc, 0x1d, 0x87, 0x1e,
+	0x3b, 0x30, 0xf9, 0xd1, 0xbf, 0x14, 0x42, 0xd6, 0x2a, 0x47, 0x8f, 0xa1, 0xa3, 0x89, 0x3a, 0x1d,
+	0xe5, 0x52, 0xcc, 0x24, 0x53, 0xca, 0xe7, 0xbe, 0xfe, 0x6f, 0xe3, 0x98, 0xa8, 0xd3, 0xa1, 0x37,
+	0xc6, 0x6d, 0x5d, 0xd2, 0x92, 0xaf, 0xa1, 0x6d, 0xc3, 0x1f, 0x71, 0xa5, 0x5f, 0xbd, 0x25, 0xc9,
+	0x91, 0xbf, 0x9b, 0x5c, 0x38, 0x95, 0xa3, 0x4f, 0xa1, 0x96, 0x0b, 0xa9, 0x4d, 0x8e, 0xd7, 0xff,
+	0xb5, 0xf5, 0x99, 0xb6, 0x93, 0x1f, 0x0a, 0xa9, 0xb1, 0xf3, 0x49, 0xfe, 0x88, 0xa0, 0x5d, 0xc6,
+	0xcd, 0xe4, 0xc9, 0x64, 0x52, 0xd4, 0xbc, 0x89, 0x83, 0x6a, 0x27, 0x6f, 0x5e, 0x56, 0x54, 0x04,
+	0xa6, 0x15, 0xba, 0xe9, 0x74, 0x90, 0x3d, 0x17, 0xdd, 0x34, 0x3a, 0x01, 0x75, 0x74, 0xfc, 0x02,
+	0xea, 0x76, 0x7a, 0xe1, 0x96, 0x78, 0xc9, 0x53, 0xc1, 0x94, 0x38, 0xd0, 0x6c, 0x81, 0xbd, 0x57,
+	0x72, 0xe6, 0x27, 0x65, 0x3e, 0x1c, 0xa4, 0xe9, 0x6b, 0x20, 0x98, 0xe1, 0x90, 0xa3, 0x08, 0x91,
+	0x33, 0x15, 0x6f, 0x74, 0x2b, 0x96, 0x43, 0x16, 0x3a, 0x90, 0x33, 0x95, 0x60, 0xff, 0xbe, 0x2b,
+	0x8e, 0x54, 0x79, 0xa9, 0x8c, 0xe8, 0x7f, 0x95, 0xf1, 0x49, 0x69, 0x84, 0xe6, 0xc3, 0x95, 0x2b,
+	0x88, 0xa0, 0xfa, 0xe8, 0xdb, 0xc3, 0x27, 0xe1, 0xba, 0x33, 0xf2, 0xe1, 0xbd, 0xef, 0xf7, 0x66,
+	0x5c, 0xcf, 0x97, 0x63, 0x73, 0xc2, 0xbe, 0x3f, 0x31, 0xfc, 0xde, 0xa3, 0x29, 0xdf, 0x97, 0x39,
+	0xdd, 0x0f, 0xa7, 0x8f, 0xeb, 0xb6, 0xfb, 0x1f, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xaa,
+	0x5f, 0xf5, 0x51, 0x0b, 0x00, 0x00,
 }
diff --git a/rpc/commands/board.proto b/rpc/commands/board.proto
index 12d9a028dcb..65e9b234830 100644
--- a/rpc/commands/board.proto
+++ b/rpc/commands/board.proto
@@ -22,70 +22,129 @@ option go_package = "github.com/arduino/arduino-cli/rpc/commands";
 import "commands/common.proto";
 
 message BoardDetailsReq {
-  Instance instance = 1;
-  string fqbn = 2;
+    Instance instance = 1;
+    string fqbn = 2;
 }
 
 message BoardDetailsResp {
-  string name = 2;
-  repeated ConfigOption config_options = 3;
-  repeated RequiredTool required_tools = 4;
+    string fqbn = 1;
+    string name = 2;
+    string version = 3;
+    string propertiesId = 4;
+    string alias = 5;
+    bool official = 6;
+    string pinout = 7;
+    Package package = 8;
+    BoardPlatform platform = 9;
+    repeated ToolsDependencies toolsDependencies = 10;
+    repeated ConfigOption config_options = 11;
+    repeated Tool _tools = 12;
+    repeated IdentificationPref identification_pref = 13;
 }
 
+message IdentificationPref {
+    USBID usbID = 1;
+}
+
+message USBID {
+    string VID = 1;
+    string PID = 2;
+}
+
+message Package {
+    string maintainer = 1;
+    string url = 2;
+    string websiteURL = 3;
+    string email = 4;
+    string name = 5;
+    Help help = 6;
+}
+
+message Help {
+    string online = 1;
+}
+
+message BoardPlatform {
+    string architecture = 1;
+    string category = 2;
+    string url = 3;
+    string archiveFileName = 4;
+    string checksum = 5;
+    int64 size = 6;
+    string name = 7;
+}
+
+
+message ToolsDependencies {
+    string packager = 1;
+    string name = 2;
+    string version = 3;
+    repeated Systems systems = 4;
+}
+
+message Systems {
+    string checksum = 1;
+    string host = 2;
+    string archiveFileName = 3;
+    string url = 4;
+    int64 size = 5;
+}
+
+
 message ConfigOption {
-  string option = 1;
-  string option_label = 2;
-  repeated ConfigValue values = 3;
+    string option = 1;
+    string option_label = 2;
+    repeated ConfigValue values = 3;
 }
 
 message ConfigValue {
-  string value = 1;
-  string value_label = 2;
-  bool selected = 3;
+    string value = 1;
+    string value_label = 2;
+    bool selected = 3;
 }
 
-message RequiredTool {
-  string name = 1;
-  string version = 2;
-  string packager = 3;
+message Tool {
+    string name = 1;
+    string version = 2;
+    string packager = 3;
 }
 
 message BoardAttachReq {
-  Instance instance = 1;
-  string board_uri = 2;
-  string sketch_path = 3;
-  string search_timeout = 4;
+    Instance instance = 1;
+    string board_uri = 2;
+    string sketch_path = 3;
+    string search_timeout = 4;
 }
 
 message BoardAttachResp {
-  TaskProgress task_progress = 1;
+    TaskProgress task_progress = 1;
 }
 
 message BoardListReq {
-  Instance instance = 1;
+    Instance instance = 1;
 }
 
 message BoardListResp {
-  repeated DetectedPort ports = 1;
+    repeated DetectedPort ports = 1;
 }
 
 message DetectedPort {
-  string address = 1;
-  string protocol = 2;
-  string protocol_label = 3;
-  repeated BoardListItem boards = 4;
+    string address = 1;
+    string protocol = 2;
+    string protocol_label = 3;
+    repeated BoardListItem boards = 4;
 }
 
 message BoardListAllReq {
-  Instance instance = 1;
-	repeated string search_args = 2;
+    Instance instance = 1;
+    repeated string search_args = 2;
 }
 
 message BoardListAllResp {
-  repeated BoardListItem boards = 1;
+    repeated BoardListItem boards = 1;
 }
 
 message BoardListItem {
-	string name = 1;
-	string FQBN = 2;
+    string name = 1;
+    string FQBN = 2;
 }
diff --git a/rpc/commands/lib.pb.go b/rpc/commands/lib.pb.go
index 3906f264c8a..93eb441985b 100644
--- a/rpc/commands/lib.pb.go
+++ b/rpc/commands/lib.pb.go
@@ -1416,85 +1416,88 @@ func init() {
 func init() { proto.RegisterFile("commands/lib.proto", fileDescriptor_9feed0d29806df6c) }
 
 var fileDescriptor_9feed0d29806df6c = []byte{
-	// 1276 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xcd, 0x6f, 0xdc, 0x44,
-	0x14, 0xaf, 0x77, 0xdb, 0x64, 0xf7, 0x6d, 0xd2, 0x38, 0xd3, 0xb4, 0x75, 0x53, 0xda, 0x2e, 0x16,
-	0x1f, 0xdb, 0x54, 0xd9, 0xa0, 0x22, 0x55, 0xa8, 0x52, 0x41, 0x85, 0xb4, 0xa8, 0x28, 0xaa, 0x22,
-	0xf7, 0xe3, 0x00, 0x48, 0xd6, 0xac, 0xfd, 0xb2, 0x19, 0x65, 0xd6, 0x76, 0x67, 0xc6, 0x5b, 0x2d,
-	0x17, 0xbe, 0xae, 0x5c, 0xb8, 0x73, 0xe0, 0x86, 0xc4, 0x1f, 0xc7, 0x95, 0x2b, 0x9a, 0xf1, 0xd8,
-	0xfb, 0x91, 0x6c, 0x12, 0x50, 0x54, 0x10, 0xa7, 0xf8, 0x7d, 0xce, 0xef, 0xcd, 0x7b, 0xef, 0x67,
-	0x67, 0x81, 0x44, 0xe9, 0x60, 0x40, 0x93, 0x58, 0x6e, 0x71, 0xd6, 0xeb, 0x66, 0x22, 0x55, 0x29,
-	0xb9, 0x1a, 0x45, 0x5d, 0x2a, 0xe2, 0x9c, 0x25, 0x69, 0x37, 0xe2, 0xac, 0x5b, 0xba, 0xac, 0x5f,
-	0xae, 0x9c, 0xf5, 0x43, 0x9a, 0x14, 0xfe, 0xfe, 0xf7, 0x0e, 0x90, 0x1d, 0xd6, 0x13, 0x54, 0x8c,
-	0xb6, 0xd3, 0xd7, 0x09, 0x4f, 0x69, 0x1c, 0xe0, 0x2b, 0xf2, 0x00, 0x1a, 0x2c, 0x91, 0x8a, 0x26,
-	0x11, 0x7a, 0x4e, 0xdb, 0xe9, 0xb4, 0xee, 0xbe, 0xdd, 0x9d, 0x93, 0xb9, 0xfb, 0xc4, 0x3a, 0x06,
-	0x55, 0x08, 0x21, 0x70, 0x3e, 0xa1, 0x03, 0xf4, 0x6a, 0x6d, 0xa7, 0xd3, 0x0c, 0xcc, 0x33, 0xf1,
-	0x60, 0x71, 0x88, 0x42, 0xb2, 0x34, 0xf1, 0xea, 0x46, 0x5d, 0x8a, 0xfe, 0xd7, 0x70, 0xe9, 0x10,
-	0x04, 0x99, 0x91, 0x47, 0xd0, 0xc8, 0x44, 0xda, 0x17, 0x28, 0xa5, 0xc5, 0x70, 0x7b, 0x2e, 0x86,
-	0x32, 0x70, 0xd7, 0x06, 0x04, 0x55, 0xa8, 0xff, 0x9d, 0x03, 0xab, 0x36, 0xbd, 0x41, 0xca, 0xf9,
-	0x1b, 0x2f, 0xf0, 0xb7, 0xf1, 0x25, 0x57, 0x10, 0xce, 0xac, 0x40, 0xf2, 0x05, 0x2c, 0x2b, 0x2a,
-	0x0f, 0xc2, 0x2a, 0x57, 0xcd, 0xe4, 0x7a, 0x77, 0x6e, 0xae, 0xe7, 0x54, 0x1e, 0x54, 0x79, 0x96,
-	0xd4, 0x84, 0xe4, 0xff, 0xe0, 0x54, 0xbd, 0x78, 0x91, 0xb0, 0x7f, 0xe9, 0xba, 0x7a, 0xb0, 0x76,
-	0x18, 0x83, 0xcc, 0x0e, 0x17, 0xea, 0xfc, 0xf3, 0x42, 0x5f, 0x8c, 0xcf, 0xc8, 0xfa, 0x82, 0xc6,
-	0xf8, 0xf0, 0x2c, 0x0a, 0xf5, 0x7f, 0x77, 0xe0, 0xf2, 0x11, 0x79, 0xff, 0x9b, 0xcd, 0xfe, 0xc9,
-	0x81, 0x1b, 0x16, 0x6c, 0x80, 0x32, 0xe5, 0x43, 0xdc, 0xc6, 0x0c, 0x93, 0x18, 0x93, 0x88, 0xa1,
-	0x7c, 0xe3, 0x6d, 0x1f, 0xc2, 0xcd, 0xe3, 0xd0, 0xc8, 0x8c, 0x3c, 0x87, 0xa5, 0x78, 0x42, 0xe7,
-	0x39, 0xed, 0x7a, 0xa7, 0x75, 0xf7, 0x83, 0xb9, 0x90, 0x4a, 0x56, 0x29, 0x63, 0x46, 0xcf, 0x14,
-	0x55, 0xb9, 0x0c, 0xa6, 0xb2, 0xf8, 0x3f, 0x3a, 0x70, 0x75, 0x8e, 0x67, 0x55, 0x81, 0x33, 0x51,
-	0x41, 0x07, 0x56, 0x2c, 0xe4, 0x00, 0x5f, 0xe5, 0x4c, 0x60, 0x6c, 0x0b, 0x9c, 0x55, 0x93, 0x0d,
-	0x70, 0xad, 0xca, 0xae, 0x3d, 0xc6, 0xb6, 0xe8, 0x43, 0x7a, 0xbf, 0x0f, 0xae, 0x05, 0xf1, 0x0c,
-	0xa9, 0x88, 0xf6, 0xcf, 0xe0, 0xfa, 0xd7, 0xe0, 0xc2, 0xab, 0x1c, 0xc5, 0xc8, 0xc2, 0x2b, 0x04,
-	0xff, 0xab, 0x8a, 0x0e, 0xcb, 0x83, 0x64, 0x46, 0x1e, 0x43, 0x93, 0x1b, 0xe5, 0xf8, 0x5a, 0x3b,
-	0x73, 0x8f, 0x2a, 0xe2, 0x30, 0x2e, 0xbb, 0x35, 0x0e, 0xf5, 0x7f, 0xad, 0xc1, 0xca, 0x8c, 0xf9,
-	0xc8, 0x3b, 0x0c, 0xa0, 0x21, 0x90, 0x23, 0x95, 0xa8, 0x27, 0x58, 0x1f, 0x77, 0xef, 0xb4, 0xc7,
-	0x75, 0x03, 0x1b, 0xf8, 0x28, 0x51, 0x62, 0x14, 0x54, 0x79, 0xc8, 0x27, 0xb0, 0xc0, 0xa9, 0x42,
-	0xa9, 0xcc, 0x1d, 0xb7, 0xee, 0xbe, 0x7f, 0xd2, 0x5c, 0xd8, 0x44, 0x81, 0x0d, 0x5b, 0x8f, 0x61,
-	0x79, 0x2a, 0x37, 0x71, 0xa1, 0x7e, 0x80, 0x23, 0x0b, 0x5c, 0x3f, 0x92, 0x07, 0x70, 0x61, 0x48,
-	0x79, 0x8e, 0x76, 0xed, 0x4e, 0x7d, 0x44, 0x11, 0x75, 0xbf, 0xf6, 0x91, 0xe3, 0xff, 0x51, 0x87,
-	0x8b, 0xd3, 0x56, 0x72, 0x05, 0x16, 0x68, 0xae, 0xf6, 0x53, 0x61, 0x8f, 0xb2, 0xd2, 0xe4, 0xae,
-	0xd4, 0xa6, 0x76, 0x85, 0xdc, 0x04, 0x18, 0x50, 0x96, 0x28, 0xca, 0x12, 0x14, 0x76, 0xa6, 0x26,
-	0x34, 0x64, 0x1d, 0x1a, 0x12, 0x13, 0x85, 0x7a, 0x72, 0xce, 0x1b, 0x6b, 0x25, 0x93, 0xb7, 0xa0,
-	0x99, 0x51, 0x41, 0xfb, 0x82, 0x66, 0xfb, 0xde, 0x05, 0x63, 0x1c, 0x2b, 0xf4, 0x99, 0xaf, 0xb1,
-	0x27, 0x99, 0x42, 0x6f, 0xa1, 0x38, 0xd3, 0x8a, 0x3a, 0x67, 0x44, 0x15, 0xf6, 0x53, 0x31, 0xf2,
-	0x16, 0x8b, 0x9c, 0xa5, 0x4c, 0xde, 0x81, 0x65, 0xdd, 0x24, 0xa6, 0x30, 0x52, 0xb9, 0x40, 0xe9,
-	0x35, 0xda, 0xf5, 0x4e, 0x33, 0x98, 0x56, 0xea, 0x81, 0x54, 0xa3, 0x0c, 0xa5, 0xd7, 0x34, 0xd6,
-	0x42, 0x20, 0x9f, 0x43, 0x53, 0xa0, 0x4c, 0x73, 0x11, 0xa1, 0xf4, 0xe0, 0x94, 0xd4, 0x18, 0xd8,
-	0x88, 0x60, 0x1c, 0xab, 0xa1, 0x73, 0x16, 0x61, 0x22, 0xd1, 0x6b, 0x15, 0xd0, 0xad, 0x48, 0xee,
-	0xc0, 0x6a, 0x26, 0xd2, 0x21, 0x8b, 0x51, 0x86, 0x2c, 0x89, 0x78, 0x1e, 0xa3, 0xf4, 0x96, 0x0c,
-	0x08, 0xb7, 0x34, 0x3c, 0xb1, 0x7a, 0xf2, 0x74, 0x86, 0x65, 0x96, 0xcd, 0x7c, 0x6e, 0x9c, 0x9e,
-	0x65, 0x66, 0xf8, 0xe5, 0x65, 0xb5, 0x70, 0x63, 0x97, 0x23, 0x97, 0x62, 0x13, 0x88, 0xed, 0x6f,
-	0x18, 0xa5, 0x89, 0x54, 0x42, 0xf7, 0xd3, 0x76, 0x7e, 0xd5, 0x5a, 0x3e, 0xab, 0x0c, 0xfe, 0x2f,
-	0x0e, 0xb8, 0xb3, 0xd7, 0xa1, 0x47, 0x36, 0x17, 0xbc, 0x1c, 0xd9, 0x5c, 0x70, 0x4d, 0x57, 0xa6,
-	0x0b, 0x43, 0xdc, 0x63, 0x1c, 0x27, 0xf8, 0x78, 0x56, 0x6d, 0x1a, 0xbc, 0x8f, 0xd1, 0x81, 0xcc,
-	0x07, 0x76, 0xa4, 0x2a, 0x59, 0xe3, 0x95, 0xec, 0x9b, 0x62, 0x98, 0xea, 0x81, 0x79, 0xd6, 0x83,
-	0x14, 0xd1, 0x68, 0x1f, 0x33, 0xaa, 0xaa, 0x41, 0xaa, 0x14, 0xfe, 0xb7, 0xd5, 0x98, 0xef, 0x30,
-	0xa9, 0xce, 0x80, 0xce, 0x5c, 0xa8, 0x53, 0xce, 0x0d, 0xf8, 0x46, 0xa0, 0x1f, 0x35, 0x80, 0x3c,
-	0x8b, 0xa9, 0xa2, 0x3d, 0x8e, 0x06, 0x71, 0x23, 0x18, 0x2b, 0x7c, 0x06, 0x2b, 0x53, 0x00, 0x64,
-	0x46, 0x5e, 0xc2, 0x2a, 0x2b, 0x19, 0x37, 0x2c, 0x58, 0x6b, 0x64, 0xe9, 0xee, 0xf6, 0xf1, 0x50,
-	0x74, 0x44, 0xb9, 0xb5, 0x2e, 0x9b, 0xd1, 0xf8, 0x3f, 0x3b, 0xe0, 0xce, 0xba, 0x91, 0xfb, 0x7a,
-	0x1c, 0xcb, 0x23, 0x74, 0xb5, 0xed, 0x13, 0xd9, 0xa2, 0x0c, 0x20, 0x0f, 0x61, 0xd1, 0xf2, 0xda,
-	0xdf, 0x65, 0x9a, 0x32, 0xce, 0xff, 0x73, 0x01, 0x16, 0x8f, 0xa3, 0xe0, 0x31, 0xe9, 0xd4, 0xa6,
-	0x48, 0xe7, 0xff, 0x44, 0x2d, 0xb7, 0xa0, 0x65, 0x7b, 0x15, 0xc6, 0x4c, 0x18, 0x72, 0x69, 0x06,
-	0x60, 0x55, 0xdb, 0x4c, 0x90, 0x1b, 0x00, 0xc5, 0xe2, 0x18, 0x7b, 0xc1, 0x1a, 0xcd, 0x42, 0xa3,
-	0xcd, 0xb7, 0xa0, 0x95, 0x2b, 0xc6, 0x99, 0x1a, 0x19, 0xfb, 0x52, 0x11, 0x6f, 0x55, 0xda, 0x61,
-	0x53, 0xff, 0x13, 0x66, 0x6f, 0x26, 0xcc, 0x38, 0x55, 0x7b, 0xa9, 0x18, 0x78, 0x17, 0x8b, 0x95,
-	0xad, 0x2c, 0xbb, 0xd6, 0x40, 0xae, 0x6b, 0xaa, 0xa3, 0x3c, 0x34, 0xcd, 0x70, 0x8b, 0x42, 0xb5,
-	0xe2, 0xa9, 0x6e, 0x88, 0x0f, 0xcb, 0x71, 0xaa, 0x42, 0x1a, 0x72, 0x96, 0x1c, 0xd0, 0x3e, 0x7a,
-	0xab, 0x66, 0xa2, 0x5b, 0x71, 0xaa, 0x1e, 0xee, 0x14, 0x2a, 0xd2, 0x86, 0x56, 0x26, 0x30, 0x4a,
-	0x07, 0x19, 0xd3, 0x1f, 0x13, 0xa4, 0xf0, 0x98, 0x50, 0x91, 0x6b, 0xd0, 0xe0, 0x71, 0xb8, 0xc7,
-	0x69, 0x5f, 0x7a, 0x97, 0x2c, 0x0b, 0xc6, 0x8f, 0xb5, 0xa8, 0x4f, 0x67, 0x32, 0xe4, 0xd8, 0xa7,
-	0xd1, 0xc8, 0x5b, 0x33, 0xa1, 0x0d, 0x26, 0x77, 0x8c, 0x3c, 0xf9, 0xae, 0xb9, 0x3c, 0xfd, 0xae,
-	0x99, 0xa0, 0xd5, 0x2b, 0xd3, 0xb4, 0xba, 0x0b, 0x90, 0x89, 0x34, 0x43, 0xa1, 0x34, 0x4f, 0x5e,
-	0x3d, 0xdd, 0xd7, 0x58, 0x77, 0xb7, 0x0a, 0x29, 0xde, 0xe0, 0x13, 0x39, 0xc8, 0x36, 0x34, 0x78,
-	0x1a, 0x51, 0xa5, 0x61, 0x78, 0x6d, 0xa7, 0x73, 0xf1, 0x98, 0xcf, 0x90, 0x72, 0xb9, 0xad, 0x7f,
-	0x50, 0x45, 0x92, 0x8f, 0xf5, 0x97, 0xc0, 0x28, 0xcd, 0x95, 0x77, 0xcd, 0xe4, 0x78, 0xef, 0xc4,
-	0x1c, 0xc6, 0x3b, 0xb0, 0x51, 0xeb, 0x0f, 0x60, 0x65, 0x06, 0xe4, 0x11, 0x9f, 0x02, 0x6b, 0x93,
-	0x9f, 0x02, 0xcd, 0x89, 0x37, 0xfc, 0xc6, 0x3d, 0x58, 0x9e, 0xca, 0x4b, 0x56, 0xa0, 0xb5, 0xc7,
-	0xa9, 0x0a, 0x8b, 0xf4, 0xee, 0x39, 0xb2, 0x06, 0xae, 0xc0, 0x28, 0x17, 0x92, 0x0d, 0xb1, 0xd4,
-	0x3a, 0x1b, 0xd1, 0x98, 0xb0, 0xca, 0x4a, 0x56, 0xa0, 0xc5, 0x62, 0x0c, 0x7b, 0x39, 0xe3, 0x8a,
-	0x25, 0xee, 0x39, 0xd2, 0x80, 0xf3, 0xb9, 0x44, 0xe1, 0x3a, 0x3a, 0x47, 0x39, 0x70, 0x95, 0xbd,
-	0x46, 0x6e, 0xc1, 0x75, 0x81, 0x7b, 0x28, 0xf4, 0x3a, 0xc6, 0xe1, 0x21, 0x87, 0xfa, 0xa7, 0x9b,
-	0x5f, 0xde, 0xe9, 0x33, 0xb5, 0x9f, 0xf7, 0xf4, 0x25, 0x6c, 0xd9, 0x4b, 0x29, 0xff, 0x6e, 0x46,
-	0x9c, 0x6d, 0x89, 0x2c, 0xda, 0x2a, 0x2f, 0xa8, 0xb7, 0x60, 0x7e, 0x26, 0xf8, 0xf0, 0xaf, 0x00,
-	0x00, 0x00, 0xff, 0xff, 0x9c, 0x45, 0xeb, 0x72, 0x6c, 0x10, 0x00, 0x00,
+	// 1318 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xcb, 0x6f, 0xdb, 0x46,
+	0x13, 0x0f, 0xad, 0x44, 0x96, 0x46, 0x76, 0x4c, 0x6f, 0x9c, 0x84, 0x71, 0xbe, 0x24, 0xfe, 0x88,
+	0x3e, 0x14, 0xa7, 0x96, 0x0b, 0x17, 0x08, 0x8a, 0x00, 0x69, 0x91, 0xd6, 0x49, 0x91, 0xc2, 0x08,
+	0x0c, 0xe6, 0x71, 0x28, 0x0a, 0x10, 0x2b, 0x72, 0x2c, 0x2f, 0xbc, 0x22, 0x99, 0xdd, 0xa5, 0x02,
+	0xf5, 0xd2, 0xd7, 0xb5, 0x97, 0xde, 0x7b, 0x68, 0x4f, 0x05, 0xfa, 0xc7, 0xf5, 0xda, 0x6b, 0xb1,
+	0xcb, 0x25, 0x45, 0xc9, 0x76, 0xec, 0x16, 0x46, 0x5a, 0xf4, 0x64, 0xce, 0xfb, 0x37, 0x3b, 0xb3,
+	0x3f, 0x52, 0x06, 0x12, 0xa5, 0xc3, 0x21, 0x4d, 0x62, 0xb9, 0xc9, 0x59, 0xbf, 0x97, 0x89, 0x54,
+	0xa5, 0xe4, 0x6a, 0x14, 0xf5, 0xa8, 0x88, 0x73, 0x96, 0xa4, 0xbd, 0x88, 0xb3, 0x5e, 0xe9, 0xb2,
+	0x7a, 0xb9, 0x72, 0xd6, 0x0f, 0x69, 0x52, 0xf8, 0xfb, 0xdf, 0x3a, 0x40, 0x76, 0x58, 0x5f, 0x50,
+	0x31, 0xde, 0x4e, 0x5f, 0x25, 0x3c, 0xa5, 0x71, 0x80, 0x2f, 0xc9, 0x7d, 0x68, 0xb1, 0x44, 0x2a,
+	0x9a, 0x44, 0xe8, 0x39, 0x6b, 0x4e, 0xb7, 0xb3, 0xf5, 0xff, 0xde, 0x31, 0x99, 0x7b, 0x8f, 0xad,
+	0x63, 0x50, 0x85, 0x10, 0x02, 0xe7, 0x13, 0x3a, 0x44, 0x6f, 0x6e, 0xcd, 0xe9, 0xb6, 0x03, 0xf3,
+	0x4c, 0x3c, 0x98, 0x1f, 0xa1, 0x90, 0x2c, 0x4d, 0xbc, 0x86, 0x51, 0x97, 0xa2, 0xff, 0x25, 0x5c,
+	0x3a, 0x04, 0x41, 0x66, 0xe4, 0x21, 0xb4, 0x32, 0x91, 0x0e, 0x04, 0x4a, 0x69, 0x31, 0xdc, 0x3e,
+	0x16, 0x43, 0x19, 0xb8, 0x6b, 0x03, 0x82, 0x2a, 0xd4, 0xff, 0xc6, 0x81, 0x65, 0x9b, 0xde, 0x20,
+	0xe5, 0xfc, 0x8d, 0x37, 0xf8, 0xeb, 0xe4, 0x90, 0x2b, 0x08, 0x67, 0xd6, 0x20, 0xf9, 0x1c, 0x16,
+	0x15, 0x95, 0x07, 0x61, 0x95, 0x6b, 0xce, 0xe4, 0x7a, 0xfb, 0xd8, 0x5c, 0xcf, 0xa8, 0x3c, 0xa8,
+	0xf2, 0x2c, 0xa8, 0x9a, 0xe4, 0x7f, 0xe7, 0x54, 0xb3, 0x78, 0x9e, 0xb0, 0x7f, 0xe8, 0xb8, 0xfa,
+	0xb0, 0x72, 0x18, 0x83, 0xcc, 0x0e, 0x37, 0xea, 0xfc, 0xfd, 0x46, 0x9f, 0x4f, 0x6a, 0x64, 0x03,
+	0x41, 0x63, 0x7c, 0x70, 0x16, 0x8d, 0xfa, 0xbf, 0x39, 0x70, 0xf9, 0x88, 0xbc, 0xff, 0xce, 0x61,
+	0xff, 0xe0, 0xc0, 0x0d, 0x0b, 0x36, 0x40, 0x99, 0xf2, 0x11, 0x6e, 0x63, 0x86, 0x49, 0x8c, 0x49,
+	0xc4, 0x50, 0xbe, 0xf1, 0xb1, 0x8f, 0xe0, 0xe6, 0xeb, 0xd0, 0xc8, 0x8c, 0x3c, 0x83, 0x85, 0xb8,
+	0xa6, 0xf3, 0x9c, 0xb5, 0x46, 0xb7, 0xb3, 0xf5, 0xfe, 0xb1, 0x90, 0x4a, 0x56, 0x29, 0x63, 0xc6,
+	0x4f, 0x15, 0x55, 0xb9, 0x0c, 0xa6, 0xb2, 0xf8, 0xdf, 0x3b, 0x70, 0xf5, 0x18, 0xcf, 0xaa, 0x03,
+	0xa7, 0xd6, 0x41, 0x17, 0x96, 0x2c, 0xe4, 0x00, 0x5f, 0xe6, 0x4c, 0x60, 0x6c, 0x1b, 0x9c, 0x55,
+	0x93, 0x75, 0x70, 0xad, 0xca, 0x5e, 0x7b, 0x8c, 0x6d, 0xd3, 0x87, 0xf4, 0xfe, 0x00, 0x5c, 0x0b,
+	0xe2, 0x29, 0x52, 0x11, 0xed, 0x9f, 0xc1, 0xf1, 0xaf, 0xc0, 0x85, 0x97, 0x39, 0x8a, 0xb1, 0x85,
+	0x57, 0x08, 0xfe, 0x2f, 0x13, 0x3e, 0x2c, 0x2b, 0xc9, 0x8c, 0x3c, 0x82, 0x36, 0x37, 0xca, 0xc9,
+	0xb9, 0x76, 0x8f, 0xad, 0x55, 0xc4, 0x61, 0x5c, 0x8e, 0x6b, 0x12, 0x4a, 0xb6, 0xa1, 0x29, 0xcd,
+	0xd1, 0x99, 0xa2, 0x17, 0xb7, 0xde, 0x3b, 0x69, 0x38, 0x45, 0x2e, 0x3b, 0x18, 0x1b, 0xeb, 0xff,
+	0x3c, 0x07, 0x4b, 0x33, 0x45, 0x8e, 0x1c, 0x45, 0x00, 0x2d, 0x81, 0x1c, 0xa9, 0x44, 0x5d, 0x4f,
+	0x83, 0xbe, 0x7b, 0x5a, 0xd0, 0xbd, 0xc0, 0x06, 0x3e, 0x4c, 0x94, 0x18, 0x07, 0x55, 0x1e, 0xf2,
+	0x31, 0x34, 0x39, 0x55, 0x28, 0x95, 0x19, 0x55, 0x67, 0xeb, 0xdd, 0x93, 0x3a, 0xb0, 0x89, 0x02,
+	0x1b, 0xb6, 0x1a, 0xc3, 0xe2, 0x54, 0x6e, 0xe2, 0x42, 0xe3, 0x00, 0xc7, 0x16, 0xb8, 0x7e, 0x24,
+	0xf7, 0xe1, 0xc2, 0x88, 0xf2, 0x1c, 0xed, 0xed, 0x3d, 0x75, 0x89, 0x22, 0xea, 0xde, 0xdc, 0x87,
+	0x8e, 0xff, 0x7b, 0x03, 0x2e, 0x4e, 0x5b, 0xc9, 0x15, 0x68, 0xd2, 0x5c, 0xed, 0xa7, 0xc2, 0x96,
+	0xb2, 0x52, 0xfd, 0xca, 0xcd, 0x4d, 0x5d, 0x39, 0x72, 0x13, 0x60, 0x48, 0x59, 0xa2, 0x28, 0x4b,
+	0x50, 0xd8, 0xd5, 0xac, 0x69, 0xc8, 0x2a, 0xb4, 0x24, 0x26, 0x0a, 0xf5, 0x02, 0x9e, 0x37, 0xd6,
+	0x4a, 0x26, 0xff, 0x83, 0x76, 0x46, 0x05, 0x1d, 0x08, 0x9a, 0xed, 0x7b, 0x17, 0x8c, 0x71, 0xa2,
+	0xd0, 0x35, 0x5f, 0x61, 0x5f, 0x32, 0x85, 0x5e, 0xb3, 0xa8, 0x69, 0x45, 0x9d, 0x33, 0xa2, 0x0a,
+	0x07, 0xa9, 0x18, 0x7b, 0xf3, 0x45, 0xce, 0x52, 0x26, 0x6f, 0xc1, 0xa2, 0x1e, 0x12, 0x53, 0x18,
+	0xa9, 0x5c, 0xa0, 0xf4, 0x5a, 0x6b, 0x8d, 0x6e, 0x3b, 0x98, 0x56, 0xea, 0xbd, 0x56, 0xe3, 0x0c,
+	0xa5, 0xd7, 0x36, 0xd6, 0x42, 0x20, 0x9f, 0x41, 0x5b, 0xa0, 0x4c, 0x73, 0x11, 0xa1, 0xf4, 0xe0,
+	0x94, 0x0c, 0x1b, 0xd8, 0x88, 0x60, 0x12, 0xab, 0xa1, 0x73, 0x16, 0x61, 0x22, 0xd1, 0xeb, 0x14,
+	0xd0, 0xad, 0x48, 0xee, 0xc0, 0x72, 0x26, 0xd2, 0x11, 0x8b, 0x51, 0x86, 0x2c, 0x89, 0x78, 0x1e,
+	0xa3, 0xf4, 0x16, 0x0c, 0x08, 0xb7, 0x34, 0x3c, 0xb6, 0x7a, 0xf2, 0x64, 0x86, 0xac, 0x16, 0xcd,
+	0x7e, 0xae, 0x9f, 0x9e, 0xac, 0x66, 0x68, 0xea, 0x45, 0x75, 0x6d, 0x27, 0x2e, 0x47, 0x5e, 0x8a,
+	0x0d, 0x20, 0x76, 0xbe, 0x61, 0x94, 0x26, 0x52, 0x09, 0x3d, 0x4f, 0x3b, 0xf9, 0x65, 0x6b, 0xf9,
+	0xb4, 0x32, 0xf8, 0x3f, 0x39, 0xe0, 0xce, 0x1e, 0x87, 0x5e, 0xd9, 0x5c, 0xf0, 0x72, 0x65, 0x73,
+	0xc1, 0x35, 0xeb, 0x99, 0x29, 0x8c, 0x70, 0x8f, 0x71, 0xac, 0xd1, 0xfa, 0xac, 0xda, 0x0c, 0x78,
+	0x1f, 0xa3, 0x03, 0x99, 0x0f, 0xed, 0x4a, 0x55, 0xb2, 0xc6, 0x2b, 0xd9, 0x57, 0xc5, 0x32, 0x35,
+	0x02, 0xf3, 0xac, 0x17, 0x29, 0xa2, 0xd1, 0x3e, 0x66, 0x54, 0x55, 0x8b, 0x54, 0x29, 0xfc, 0xaf,
+	0xab, 0x35, 0xdf, 0x61, 0x52, 0x9d, 0x01, 0x2b, 0xba, 0xd0, 0xa0, 0x9c, 0x1b, 0xf0, 0xad, 0x40,
+	0x3f, 0x6a, 0x00, 0x79, 0x16, 0x53, 0x45, 0xfb, 0x1c, 0x0d, 0xe2, 0x56, 0x30, 0x51, 0xf8, 0x0c,
+	0x96, 0xa6, 0x00, 0xc8, 0x8c, 0xbc, 0x80, 0x65, 0x56, 0x12, 0x77, 0x58, 0x70, 0xdf, 0xd8, 0x92,
+	0xe6, 0xed, 0xd7, 0x43, 0xd1, 0x11, 0xe5, 0xad, 0x75, 0xd9, 0x8c, 0xc6, 0xff, 0xd1, 0x01, 0x77,
+	0xd6, 0x8d, 0xdc, 0xd3, 0xeb, 0x58, 0x96, 0xd0, 0xdd, 0xae, 0x9d, 0xc8, 0x16, 0x65, 0x00, 0x79,
+	0x00, 0xf3, 0x96, 0xd7, 0xfe, 0x2a, 0xd3, 0x94, 0x71, 0xfe, 0x1f, 0x4d, 0x98, 0x7f, 0x1d, 0x05,
+	0x4f, 0x48, 0x67, 0x6e, 0x8a, 0x74, 0xfe, 0x4b, 0xd4, 0x72, 0x0b, 0x3a, 0x76, 0x56, 0x61, 0xcc,
+	0x84, 0x21, 0x97, 0x76, 0x00, 0x56, 0xb5, 0xcd, 0x04, 0xb9, 0x01, 0x50, 0x5c, 0x1c, 0x63, 0x2f,
+	0x58, 0xa3, 0x5d, 0x68, 0xb4, 0xf9, 0x16, 0x74, 0x72, 0xc5, 0x38, 0x53, 0x63, 0x63, 0x5f, 0x28,
+	0xe2, 0xad, 0x4a, 0x3b, 0x6c, 0xe8, 0xdf, 0x72, 0xf6, 0x64, 0xc2, 0x8c, 0x53, 0xb5, 0x97, 0x8a,
+	0xa1, 0x77, 0xb1, 0xb8, 0xb2, 0x95, 0x65, 0xd7, 0x1a, 0xc8, 0x75, 0x4d, 0x75, 0x94, 0x87, 0x66,
+	0x18, 0x6e, 0xd1, 0xa8, 0x56, 0x3c, 0xd1, 0x03, 0xf1, 0x61, 0x31, 0x4e, 0x55, 0x48, 0x43, 0xce,
+	0x92, 0x03, 0x3a, 0x40, 0x6f, 0xd9, 0x6c, 0x74, 0x27, 0x4e, 0xd5, 0x83, 0x9d, 0x42, 0x45, 0xd6,
+	0xa0, 0x93, 0x09, 0x8c, 0xd2, 0x61, 0xc6, 0xf4, 0x37, 0x09, 0x29, 0x3c, 0x6a, 0x2a, 0x72, 0x0d,
+	0x5a, 0x3c, 0x0e, 0xf7, 0x38, 0x1d, 0x48, 0xef, 0x92, 0x65, 0xc1, 0xf8, 0x91, 0x16, 0x75, 0x75,
+	0x26, 0x43, 0x8e, 0x03, 0x1a, 0x8d, 0xbd, 0x15, 0x13, 0xda, 0x62, 0x72, 0xc7, 0xc8, 0xf5, 0x77,
+	0xcd, 0xe5, 0xe9, 0x77, 0x4d, 0x8d, 0x56, 0xaf, 0x4c, 0xd3, 0xea, 0x2e, 0x40, 0x26, 0xd2, 0x0c,
+	0x85, 0xd2, 0x3c, 0x79, 0xf5, 0x74, 0x1f, 0x75, 0xbd, 0xdd, 0x2a, 0xa4, 0x78, 0x83, 0xd7, 0x72,
+	0x90, 0x6d, 0x68, 0xf1, 0x34, 0xa2, 0x4a, 0xc3, 0xf0, 0xcc, 0x77, 0x48, 0xf7, 0xa4, 0x7c, 0x3b,
+	0xd6, 0x3f, 0xa8, 0x22, 0xc9, 0x47, 0xfa, 0x4b, 0x60, 0x9c, 0xe6, 0xca, 0xbb, 0x66, 0x72, 0xbc,
+	0x73, 0x62, 0x0e, 0xe3, 0x1d, 0xd8, 0xa8, 0xd5, 0xfb, 0xb0, 0x34, 0x03, 0xf2, 0x88, 0x4f, 0x81,
+	0x95, 0xfa, 0xa7, 0x40, 0xbb, 0xf6, 0x86, 0x5f, 0xef, 0x55, 0x3f, 0xc5, 0xea, 0xdf, 0x48, 0x04,
+	0xa0, 0xb9, 0x47, 0xf5, 0x8c, 0xdc, 0x73, 0xa4, 0x03, 0xf3, 0x32, 0x8f, 0x22, 0x94, 0xd2, 0x75,
+	0xd6, 0xef, 0xc2, 0xe2, 0x14, 0x0e, 0xb2, 0x04, 0x9d, 0x3d, 0x4e, 0x55, 0x58, 0xc0, 0x71, 0xcf,
+	0x91, 0x15, 0x70, 0x05, 0x46, 0xb9, 0x90, 0x6c, 0x84, 0xa5, 0xd6, 0x59, 0x8f, 0x26, 0x04, 0x57,
+	0x76, 0xbe, 0x04, 0x1d, 0x16, 0x63, 0xd8, 0xcf, 0x19, 0x57, 0x2c, 0x71, 0xcf, 0x91, 0x16, 0x9c,
+	0xcf, 0x25, 0x0a, 0xd7, 0xd1, 0x39, 0xca, 0x05, 0xad, 0xec, 0x73, 0xe4, 0x16, 0x5c, 0x17, 0xb8,
+	0x87, 0x42, 0x5f, 0xdf, 0x38, 0x3c, 0xe4, 0xd0, 0xf8, 0x64, 0xe3, 0x8b, 0x3b, 0x03, 0xa6, 0xf6,
+	0xf3, 0xbe, 0x3e, 0xb4, 0x4d, 0x7b, 0x88, 0xe5, 0xdf, 0x8d, 0x88, 0xb3, 0x4d, 0x91, 0x45, 0x9b,
+	0xe5, 0x81, 0xf6, 0x9b, 0xe6, 0xbf, 0x13, 0x1f, 0xfc, 0x19, 0x00, 0x00, 0xff, 0xff, 0x01, 0x14,
+	0xc2, 0xc0, 0xe3, 0x10, 0x00, 0x00,
 }
diff --git a/test/test_board.py b/test/test_board.py
index 8432d96673a..7ccbf0997d6 100644
--- a/test/test_board.py
+++ b/test/test_board.py
@@ -38,3 +38,368 @@ def test_board_listall(run_command):
     result = run_command("board listall")
     assert result.ok
     assert ["Board", "Name", "FQBN"] == result.stdout.splitlines()[0].strip().split()
+
+def test_board_details(run_command):
+    gold_board_details = """
+    {
+  "fqbn": "arduino:samd:nano_33_iot",
+  "name": "Arduino NANO 33 IoT",
+  "version": "1.8.6",
+  "propertiesId": "nano_33_iot",
+  "official": true,
+  "package": {
+    "maintainer": "Arduino",
+    "url": "https://downloads.arduino.cc/packages/package_index.json",
+    "websiteURL": "http://www.arduino.cc/",
+    "email": "packages@arduino.cc",
+    "name": "arduino",
+    "help": {
+      "online": "http://www.arduino.cc/en/Reference/HomePage"
+    }
+  },
+  "platform": {
+    "architecture": "samd",
+    "category": "Arduino",
+    "url": "http://downloads.arduino.cc/cores/samd-1.8.6.tar.bz2",
+    "archiveFileName": "samd-1.8.6.tar.bz2",
+    "checksum": "SHA-256:68a4fffa6fe6aa7886aab2e69dff7d3f94c02935bbbeb42de37f692d7daf823b",
+    "size": 2980953,
+    "name": "Arduino SAMD Boards (32-bits ARM Cortex-M0+)"
+  },
+  "toolsDependencies": [
+    {
+      "packager": "arduino",
+      "name": "arm-none-eabi-gcc",
+      "version": "7-2017q4",
+      "systems": [
+        {
+          "checksum": "SHA-256:34180943d95f759c66444a40b032f7dd9159a562670fc334f049567de140c51b",
+          "host": "arm-linux-gnueabihf",
+          "archiveFileName": "gcc-arm-none-eabi-7-2019-q4-major-linuxarm.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2019-q4-major-linuxarm.tar.bz2",
+          "size": 96613739
+        },
+        {
+          "checksum": "SHA-256:6fb5752fb4d11012bd0a1ceb93a19d0641ff7cf29d289b3e6b86b99768e66f76",
+          "host": "aarch64-linux-gnu",
+          "archiveFileName": "gcc-arm-none-eabi-7-2018-q2-update-linuxarm64.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2018-q2-update-linuxarm64.tar.bz2",
+          "size": 99558726
+        },
+        {
+          "checksum": "SHA-256:96dd0091856f4d2eb21046eba571321feecf7d50b9c156f708b2a8b683903382",
+          "host": "i686-mingw32",
+          "archiveFileName": "gcc-arm-none-eabi-7-2017-q4-major-win32-arduino1.zip",
+          "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2017-q4-major-win32-arduino1.zip",
+          "size": 131761924
+        },
+        {
+          "checksum": "SHA-256:89b776c7cf0591c810b5b60067e4dc113b5b71bc50084a536e71b894a97fdccb",
+          "host": "x86_64-apple-darwin",
+          "archiveFileName": "gcc-arm-none-eabi-7-2017-q4-major-mac.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2017-q4-major-mac.tar.bz2",
+          "size": 104550003
+        },
+        {
+          "checksum": "SHA-256:96a029e2ae130a1210eaa69e309ea40463028eab18ba19c1086e4c2dafe69a6a",
+          "host": "x86_64-pc-linux-gnu",
+          "archiveFileName": "gcc-arm-none-eabi-7-2017-q4-major-linux64.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2017-q4-major-linux64.tar.bz2",
+          "size": 99857645
+        },
+        {
+          "checksum": "SHA-256:090a0bc2b1956bc49392dff924a6c30fa57c88130097b1972204d67a45ce3cf3",
+          "host": "i686-pc-linux-gnu",
+          "archiveFileName": "gcc-arm-none-eabi-7-2018-q2-update-linux32.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2018-q2-update-linux32.tar.bz2",
+          "size": 97427309
+        }
+      ]
+    },
+    {
+      "packager": "arduino",
+      "name": "bossac",
+      "version": "1.7.0-arduino3",
+      "systems": [
+        {
+          "checksum": "SHA-256:62745cc5a98c26949ec9041ef20420643c561ec43e99dae659debf44e6836526",
+          "host": "i686-mingw32",
+          "archiveFileName": "bossac-1.7.0-arduino3-windows.tar.gz",
+          "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-windows.tar.gz",
+          "size": 3607421
+        },
+        {
+          "checksum": "SHA-256:adb3c14debd397d8135e9e970215c6972f0e592c7af7532fa15f9ce5e64b991f",
+          "host": "x86_64-apple-darwin",
+          "archiveFileName": "bossac-1.7.0-arduino3-osx.tar.gz",
+          "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-osx.tar.gz",
+          "size": 75510
+        },
+        {
+          "checksum": "SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100",
+          "host": "x86_64-pc-linux-gnu",
+          "archiveFileName": "bossac-1.7.0-arduino3-linux64.tar.gz",
+          "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz",
+          "size": 207271
+        },
+        {
+          "checksum": "SHA-256:4ac4354746d1a09258f49a43ef4d1baf030d81c022f8434774268b00f55d3ec3",
+          "host": "i686-pc-linux-gnu",
+          "archiveFileName": "bossac-1.7.0-arduino3-linux32.tar.gz",
+          "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux32.tar.gz",
+          "size": 193577
+        },
+        {
+          "checksum": "SHA-256:626c6cc548046901143037b782bf019af1663bae0d78cf19181a876fb9abbb90",
+          "host": "arm-linux-gnueabihf",
+          "archiveFileName": "bossac-1.7.0-arduino3-linuxarm.tar.gz",
+          "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linuxarm.tar.gz",
+          "size": 193941
+        },
+        {
+          "checksum": "SHA-256:a098b2cc23e29f0dc468416210d097c4a808752cd5da1a7b9b8b7b931a04180b",
+          "host": "aarch64-linux-gnu",
+          "archiveFileName": "bossac-1.7.0-arduino3-linuxaarch64.tar.gz",
+          "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linuxaarch64.tar.gz",
+          "size": 268365
+        }
+      ]
+    },
+    {
+      "packager": "arduino",
+      "name": "openocd",
+      "version": "0.10.0-arduino7",
+      "systems": [
+        {
+          "checksum": "SHA-256:f8e0d783e80a3d5f75ee82e9542315871d46e1e283a97447735f1cbcd8986b06",
+          "host": "arm-linux-gnueabihf",
+          "archiveFileName": "openocd-0.10.0-arduino7-static-arm-linux-gnueabihf.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-arm-linux-gnueabihf.tar.bz2",
+          "size": 1638575
+        },
+        {
+          "checksum": "SHA-256:d47d728a9a8d98f28dc22e31d7127ced9de0d5e268292bf935e050ef1d2bdfd0",
+          "host": "aarch64-linux-gnu",
+          "archiveFileName": "openocd-0.10.0-arduino7-static-aarch64-linux-gnu.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-aarch64-linux-gnu.tar.bz2",
+          "size": 1580739
+        },
+        {
+          "checksum": "SHA-256:1e539a587a0c54a551ce0dc542af10a2520b1c93bbfe2ca4ebaef4c83411df1a",
+          "host": "i386-apple-darwin11",
+          "archiveFileName": "openocd-0.10.0-arduino7-static-x86_64-apple-darwin13.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-x86_64-apple-darwin13.tar.bz2",
+          "size": 1498970
+        },
+        {
+          "checksum": "SHA-256:91d418bd309ec1e98795c622cd25c936aa537c0b3828fa5bcb191389378a1b27",
+          "host": "x86_64-linux-gnu",
+          "archiveFileName": "openocd-0.10.0-arduino7-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2",
+          "size": 1701581
+        },
+        {
+          "checksum": "SHA-256:08a18f39d72a5626383503053a30a5da89eed7fdccb6f514b20b77403eb1b2b4",
+          "host": "i686-linux-gnu",
+          "archiveFileName": "openocd-0.10.0-arduino7-static-i686-ubuntu12.04-linux-gnu.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-i686-ubuntu12.04-linux-gnu.tar.bz2",
+          "size": 1626347
+        },
+        {
+          "checksum": "SHA-256:f251aec5471296e18aa540c3078d66475357a76a77c16c06a2d9345f4e12b3d5",
+          "host": "i686-mingw32",
+          "archiveFileName": "openocd-0.10.0-arduino7-static-i686-w64-mingw32.zip",
+          "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-i686-w64-mingw32.zip",
+          "size": 2016965
+        }
+      ]
+    },
+    {
+      "packager": "arduino",
+      "name": "CMSIS",
+      "version": "4.5.0",
+      "systems": [
+        {
+          "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d",
+          "host": "i686-mingw32",
+          "archiveFileName": "CMSIS-4.5.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2",
+          "size": 31525196
+        },
+        {
+          "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d",
+          "host": "x86_64-apple-darwin",
+          "archiveFileName": "CMSIS-4.5.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2",
+          "size": 31525196
+        },
+        {
+          "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d",
+          "host": "x86_64-pc-linux-gnu",
+          "archiveFileName": "CMSIS-4.5.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2",
+          "size": 31525196
+        },
+        {
+          "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d",
+          "host": "i686-pc-linux-gnu",
+          "archiveFileName": "CMSIS-4.5.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2",
+          "size": 31525196
+        },
+        {
+          "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d",
+          "host": "arm-linux-gnueabihf",
+          "archiveFileName": "CMSIS-4.5.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2",
+          "size": 31525196
+        },
+        {
+          "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d",
+          "host": "aarch64-linux-gnu",
+          "archiveFileName": "CMSIS-4.5.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2",
+          "size": 31525196
+        },
+        {
+          "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d",
+          "host": "all",
+          "archiveFileName": "CMSIS-4.5.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2",
+          "size": 31525196
+        }
+      ]
+    },
+    {
+      "packager": "arduino",
+      "name": "CMSIS-Atmel",
+      "version": "1.2.0",
+      "systems": [
+        {
+          "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5",
+          "host": "i686-mingw32",
+          "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2",
+          "size": 2221805
+        },
+        {
+          "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5",
+          "host": "x86_64-apple-darwin",
+          "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2",
+          "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2",
+          "size": 2221805
+        },
+        {
+          "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5",
+          "host": "x86_64-pc-linux-gnu",
+          "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2",
+          "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2",
+          "size": 2221805
+        },
+        {
+          "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5",
+          "host": "i686-pc-linux-gnu",
+          "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2",
+          "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2",
+          "size": 2221805
+        },
+        {
+          "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5",
+          "host": "arm-linux-gnueabihf",
+          "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2",
+          "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2",
+          "size": 2221805
+        },
+        {
+          "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5",
+          "host": "aarch64-linux-gnu",
+          "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2",
+          "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2",
+          "size": 2221805
+        },
+        {
+          "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5",
+          "host": "all",
+          "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2",
+          "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2",
+          "size": 2221805
+        }
+      ]
+    },
+    {
+      "packager": "arduino",
+      "name": "arduinoOTA",
+      "version": "1.2.1",
+      "systems": [
+        {
+          "checksum": "SHA-256:2ffdf64b78486c1d0bf28dc23d0ca36ab75ca92e84b9487246da01888abea6d4",
+          "host": "i686-linux-gnu",
+          "archiveFileName": "arduinoOTA-1.2.1-linux_386.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-linux_386.tar.bz2",
+          "size": 2133779
+        },
+        {
+          "checksum": "SHA-256:5b82310d53688480f34a916aac31cd8f2dd2be65dd8fa6c2445262262e1948f9",
+          "host": "x86_64-linux-gnu",
+          "archiveFileName": "arduinoOTA-1.2.1-linux_amd64.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-linux_amd64.tar.bz2",
+          "size": 2257689
+        },
+        {
+          "checksum": "SHA-256:ad54b3dcd586212941fd992bab573b53d13207a419a3f2981c970a085ae0e9e0",
+          "host": "arm-linux-gnueabihf",
+          "archiveFileName": "arduinoOTA-1.2.1-linux_arm.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-linux_arm.tar.bz2",
+          "size": 2093132
+        },
+        {
+          "checksum": "SHA-256:ad54b3dcd586212941fd992bab573b53d13207a419a3f2981c970a085ae0e9e0",
+          "host": "aarch64-linux-gnu",
+          "archiveFileName": "arduinoOTA-1.2.1-linux_arm.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-linux_arm.tar.bz2",
+          "size": 2093132
+        },
+        {
+          "checksum": "SHA-256:93a6d9f9c0c765d237be1665bf7a0a8e2b0b6d2a8531eae92db807f5515088a7",
+          "host": "i386-apple-darwin11",
+          "archiveFileName": "arduinoOTA-1.2.1-darwin_amd64.tar.bz2",
+          "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-darwin_amd64.tar.bz2",
+          "size": 2244088
+        },
+        {
+          "checksum": "SHA-256:e1ebf21f2c073fce25c09548c656da90d4ef6c078401ec6f323e0c58335115e5",
+          "host": "i686-mingw32",
+          "archiveFileName": "arduinoOTA-1.2.1-windows_386.zip",
+          "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-windows_386.zip",
+          "size": 2237511
+        }
+      ]
+    }
+  ],
+  "identification_pref": [
+    {
+      "usbID": {
+        "VID": "0x2341",
+        "PID": "0x8057"
+      }
+    },
+    {
+      "usbID": {
+        "VID": "0x2341",
+        "PID": "0x0057"
+      }
+    }
+  ]
+}
+"""
+    result = run_command("core update-index")
+    assert result.ok
+    # Download samd core pinned to 1.8.6
+    result = run_command("core install arduino:samd@1.8.6")
+    assert result.ok
+    result = run_command("board details arduino:samd:nano_33_iot --format json")
+    assert result.ok
+    # Sort everything before compare
+    sorted_result = json.dumps(json.loads(result.stdout), sort_keys=True)
+    sorted_gold_board_details = json.dumps(json.loads(gold_board_details), sort_keys=True)
+    assert sorted_result == sorted_gold_board_details