diff --git a/.github/workflows/test-go-task.yml b/.github/workflows/test-go-task.yml
index f0bac8cb077..e11c59ba91e 100644
--- a/.github/workflows/test-go-task.yml
+++ b/.github/workflows/test-go-task.yml
@@ -154,11 +154,6 @@ jobs:
       - name: Run tests
         run: task go:test
 
-      - name: Run unit tests on the legacy package
-        # Run legacy tests on one platform only
-        if: runner.os == 'Linux'
-        run: task test-legacy
-
       - name: Upload coverage data to workflow artifact
         if: runner.os == 'Linux'
         uses: actions/upload-artifact@v3
@@ -167,7 +162,6 @@ jobs:
           name: ${{ env.COVERAGE_ARTIFACT }}
           path: |
             ./coverage_unit.txt
-            ./coverage_legacy.txt
 
   coverage-upload:
     runs-on: ubuntu-latest
diff --git a/Taskfile.yml b/Taskfile.yml
index 1373e1adde8..b7a4522d033 100755
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -284,21 +284,11 @@ tasks:
       - task: go:build
 
   test:
-    desc: Run the full testsuite, `legacy` will be skipped
+    desc: Run the full testsuite
     cmds:
       - task: go:test
       - task: go:integration-test
 
-  test-legacy:
-    desc: Run tests for the `legacy` package
-    cmds:
-      - |
-        go test \
-          {{ default "-v -failfast" .GOFLAGS }} \
-          -coverprofile=coverage_legacy.txt \
-          ./legacy/... \
-          {{.TEST_LDFLAGS}}
-
   test-unit-race:
     desc: Run unit tests only with race condition detection
     cmds:
@@ -311,18 +301,12 @@ tasks:
           {{.TEST_LDFLAGS}}
 
   check:
-    desc: Check fmt and lint, `legacy` will be skipped
+    desc: Check fmt and lint
     cmds:
       - task: go:vet
       - task: go:lint
       - task: protoc:check
 
-  check-legacy:
-    desc: Check fmt and lint for the `legacy` package
-    cmds:
-      - test -z $(go fmt ./legacy/...)
-      - go vet ./legacy/...
-
   rpc-client:
     desc: Run the rpc client test routine (server must be already started)
     cmds:
@@ -376,10 +360,10 @@ tasks:
 vars:
   PROJECT_NAME: "arduino-cli"
   DIST_DIR: "dist"
-  # all modules of this project except for "legacy/..." module and integration test
+  # all modules of this project except for integration test
   DEFAULT_GO_PACKAGES:
     sh: |
-      echo $(cd {{default "./" .GO_MODULE_PATH}} && go list ./... | grep -v internal/integrationtest | grep -v legacy | tr '\n' ' ' || echo '"ERROR: Unable to discover Go packages"')
+      echo $(cd {{default "./" .GO_MODULE_PATH}} && go list ./... | grep -v internal/integrationtest | tr '\n' ' ' || echo '"ERROR: Unable to discover Go packages"')
   DEFAULT_INTEGRATIONTEST_GO_PACKAGES:
     sh: |
       echo $(cd {{default "./" .GO_MODULE_PATH}} && go list ./... | grep internal/integrationtest | tr '\n' ' ' || echo '"ERROR: Unable to discover Go packages"')
diff --git a/arduino/builder/build_options_manager.go b/arduino/builder/build_options_manager.go
index 3079ecf9ea6..0d097bdb1e7 100644
--- a/arduino/builder/build_options_manager.go
+++ b/arduino/builder/build_options_manager.go
@@ -154,14 +154,16 @@ func (m *BuildOptionsManager) wipeBuildPath() error {
 		return wipe()
 	}
 
+	// Since we might apply a side effect we clone it
+	currentOptions := m.currentOptions.Clone()
 	// If SketchLocation path is different but filename is the same, consider it equal
-	if filepath.Base(m.currentOptions.Get("sketchLocation")) == filepath.Base(prevOpts.Get("sketchLocation")) {
-		m.currentOptions.Remove("sketchLocation")
+	if filepath.Base(currentOptions.Get("sketchLocation")) == filepath.Base(prevOpts.Get("sketchLocation")) {
+		currentOptions.Remove("sketchLocation")
 		prevOpts.Remove("sketchLocation")
 	}
 
 	// If options are not changed check if core has
-	if m.currentOptions.Equals(prevOpts) {
+	if currentOptions.Equals(prevOpts) {
 		// check if any of the files contained in the core folders has changed
 		// since the json was generated - like platform.txt or similar
 		// if so, trigger a "safety" wipe
diff --git a/arduino/builder/builder.go b/arduino/builder/builder.go
index a856106d574..64e06f82eb3 100644
--- a/arduino/builder/builder.go
+++ b/arduino/builder/builder.go
@@ -20,9 +20,11 @@ import (
 	"fmt"
 
 	"github.com/arduino/arduino-cli/arduino/builder/compilation"
+	"github.com/arduino/arduino-cli/arduino/builder/detector"
 	"github.com/arduino/arduino-cli/arduino/builder/logger"
 	"github.com/arduino/arduino-cli/arduino/builder/progress"
 	"github.com/arduino/arduino-cli/arduino/cores"
+	"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
 	"github.com/arduino/arduino-cli/arduino/sketch"
 	"github.com/arduino/go-paths-helper"
 	"github.com/arduino/go-properties-orderedmap"
@@ -77,6 +79,7 @@ type Builder struct {
 
 	buildArtifacts *BuildArtifacts
 
+	*detector.SketchLibrariesDetector
 	*BuildOptionsManager
 }
 
@@ -109,6 +112,9 @@ func NewBuilder(
 	sourceOverrides map[string]string,
 	onlyUpdateCompilationDatabase bool,
 	targetPlatform, actualPlatform *cores.PlatformRelease,
+	useCachedLibrariesResolution bool,
+	librariesManager *librariesmanager.LibrariesManager,
+	libraryDirs paths.PathList,
 	logger *logger.BuilderLogger,
 	progressStats *progress.Struct,
 ) (*Builder, error) {
@@ -163,6 +169,18 @@ func NewBuilder(
 		progressStats = progress.New(nil)
 	}
 
+	libsManager, libsResolver, verboseOut, err := detector.LibrariesLoader(
+		useCachedLibrariesResolution, librariesManager,
+		builtInLibrariesDirs, libraryDirs, otherLibrariesDirs,
+		actualPlatform, targetPlatform,
+	)
+	if err != nil {
+		return nil, err
+	}
+	if logger.Verbose() {
+		logger.Warn(string(verboseOut))
+	}
+
 	return &Builder{
 		sketch:                        sk,
 		buildProperties:               buildProperties,
@@ -183,6 +201,12 @@ func NewBuilder(
 		buildArtifacts:                &BuildArtifacts{},
 		targetPlatform:                targetPlatform,
 		actualPlatform:                actualPlatform,
+		SketchLibrariesDetector: detector.NewSketchLibrariesDetector(
+			libsManager, libsResolver,
+			useCachedLibrariesResolution,
+			onlyUpdateCompilationDatabase,
+			logger,
+		),
 		BuildOptionsManager: NewBuildOptionsManager(
 			hardwareDirs, builtInToolsDirs, otherLibrariesDirs,
 			builtInLibrariesDirs, buildPath,
@@ -208,29 +232,243 @@ func (b *Builder) GetBuildPath() *paths.Path {
 	return b.buildPath
 }
 
-// GetSketchBuildPath returns the sketch build path
-func (b *Builder) GetSketchBuildPath() *paths.Path {
-	return b.sketchBuildPath
+// ExecutableSectionsSize fixdoc
+func (b *Builder) ExecutableSectionsSize() ExecutablesFileSections {
+	return b.executableSectionsSize
 }
 
-// GetLibrariesBuildPath returns the libraries build path
-func (b *Builder) GetLibrariesBuildPath() *paths.Path {
-	return b.librariesBuildPath
+// Preprocess fixdoc
+func (b *Builder) Preprocess() error {
+	b.Progress.AddSubSteps(6)
+	defer b.Progress.RemoveSubSteps()
+	return b.preprocess()
 }
 
-// ExecutableSectionsSize fixdoc
-func (b *Builder) ExecutableSectionsSize() ExecutablesFileSections {
-	return b.executableSectionsSize
+func (b *Builder) preprocess() error {
+	if err := b.buildPath.MkdirAll(); err != nil {
+		return err
+	}
+
+	if err := b.BuildOptionsManager.WipeBuildPath(); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.hooks.prebuild", ".pattern", false); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.prepareSketchBuildPath(); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	b.logIfVerbose(false, tr("Detecting libraries used..."))
+	err := b.SketchLibrariesDetector.FindIncludes(
+		b.buildPath,
+		b.buildProperties.GetPath("build.core.path"),
+		b.buildProperties.GetPath("build.variant.path"),
+		b.sketchBuildPath,
+		b.sketch,
+		b.librariesBuildPath,
+		b.buildProperties,
+		b.targetPlatform.Platform.Architecture,
+	)
+	if err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	b.warnAboutArchIncompatibleLibraries(b.SketchLibrariesDetector.ImportedLibraries())
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	b.logIfVerbose(false, tr("Generating function prototypes..."))
+	if err := b.preprocessSketch(b.SketchLibrariesDetector.IncludeFolders()); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	// Output arduino-preprocessed source
+	preprocessedSketch, err := b.sketchBuildPath.Join(b.sketch.MainFile.Base() + ".cpp").ReadFile()
+	if err != nil {
+		return err
+	}
+	b.logger.WriteStdout(preprocessedSketch)
+
+	return nil
 }
 
-// SaveCompilationDatabase fixdoc
-func (b *Builder) SaveCompilationDatabase() {
-	if b.compilationDatabase != nil {
-		b.compilationDatabase.SaveToFile()
+func (b *Builder) logIfVerbose(warn bool, msg string) {
+	if !b.logger.Verbose() {
+		return
+	}
+	if warn {
+		b.logger.Warn(msg)
+		return
+	}
+	b.logger.Info(msg)
+}
+
+// Build fixdoc
+func (b *Builder) Build() error {
+	b.Progress.AddSubSteps(6 /** preprocess **/ + 21 /** build **/)
+	defer b.Progress.RemoveSubSteps()
+
+	if err := b.preprocess(); err != nil {
+		return err
+	}
+
+	buildErr := b.build()
+
+	b.SketchLibrariesDetector.PrintUsedAndNotUsedLibraries(buildErr != nil)
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	b.printUsedLibraries(b.SketchLibrariesDetector.ImportedLibraries())
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if buildErr != nil {
+		return buildErr
+	}
+	if err := b.exportProjectCMake(b.SketchLibrariesDetector.ImportedLibraries(), b.SketchLibrariesDetector.IncludeFolders()); err != nil {
+		return err
 	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.size(); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	return nil
 }
 
-// TargetPlatform fixdoc
-func (b *Builder) TargetPlatform() *cores.PlatformRelease {
-	return b.targetPlatform
+// Build fixdoc
+func (b *Builder) build() error {
+	b.logIfVerbose(false, tr("Compiling sketch..."))
+	if err := b.RunRecipe("recipe.hooks.sketch.prebuild", ".pattern", false); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.BuildSketch(b.SketchLibrariesDetector.IncludeFolders()); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.hooks.sketch.postbuild", ".pattern", true); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	b.logIfVerbose(false, tr("Compiling libraries..."))
+	if err := b.RunRecipe("recipe.hooks.libraries.prebuild", ".pattern", false); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.removeUnusedCompiledLibraries(b.SketchLibrariesDetector.ImportedLibraries()); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.buildLibraries(b.SketchLibrariesDetector.IncludeFolders(), b.SketchLibrariesDetector.ImportedLibraries()); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.hooks.libraries.postbuild", ".pattern", true); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	b.logIfVerbose(false, tr("Compiling core..."))
+	if err := b.RunRecipe("recipe.hooks.core.prebuild", ".pattern", false); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.buildCore(); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.hooks.core.postbuild", ".pattern", true); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	b.logIfVerbose(false, tr("Linking everything together..."))
+	if err := b.RunRecipe("recipe.hooks.linking.prelink", ".pattern", false); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.link(); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.hooks.linking.postlink", ".pattern", true); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.hooks.objcopy.preobjcopy", ".pattern", false); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.objcopy.", ".pattern", true); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.hooks.objcopy.postobjcopy", ".pattern", true); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.MergeSketchWithBootloader(); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if err := b.RunRecipe("recipe.hooks.postbuild", ".pattern", true); err != nil {
+		return err
+	}
+	b.Progress.CompleteStep()
+	b.Progress.PushProgress()
+
+	if b.compilationDatabase != nil {
+		b.compilationDatabase.SaveToFile()
+	}
+	return nil
 }
diff --git a/arduino/builder/core.go b/arduino/builder/core.go
index 2fcbb682a7c..9617d22cc11 100644
--- a/arduino/builder/core.go
+++ b/arduino/builder/core.go
@@ -30,8 +30,8 @@ import (
 	"github.com/pkg/errors"
 )
 
-// BuildCore fixdoc
-func (b *Builder) BuildCore() error {
+// buildCore fixdoc
+func (b *Builder) buildCore() error {
 	if err := b.coreBuildPath.MkdirAll(); err != nil {
 		return errors.WithStack(err)
 	}
diff --git a/arduino/builder/export_cmake.go b/arduino/builder/export_cmake.go
index de7bdf6db88..06360a55ec9 100644
--- a/arduino/builder/export_cmake.go
+++ b/arduino/builder/export_cmake.go
@@ -34,12 +34,8 @@ import (
 
 var lineMatcher = regexp.MustCompile(`^#line\s\d+\s"`)
 
-// ExportProjectCMake fixdoc
-func (b *Builder) ExportProjectCMake(
-	sketchError bool, // Was there an error while compiling the sketch?
-	importedLibraries libraries.List,
-	includeFolders paths.PathList,
-) error {
+// exportProjectCMake fixdoc
+func (b *Builder) exportProjectCMake(importedLibraries libraries.List, includeFolders paths.PathList) error {
 	// copies the contents of the file named src to the file named
 	// by dst. The file will be created if it does not already exist. If the
 	// destination file exists, all it's contents will be replaced by the contents
@@ -175,8 +171,8 @@ func (b *Builder) ExportProjectCMake(
 	}
 	var validStaticLibExtensions = []string{".a"}
 
-	//	If sketch error or cannot export Cmake project
-	if sketchError || b.buildProperties.Get("compiler.export_cmake") == "" {
+	//	If cannot export Cmake project
+	if b.buildProperties.Get("compiler.export_cmake") == "" {
 		return nil
 	}
 
@@ -241,7 +237,7 @@ func (b *Builder) ExportProjectCMake(
 		fmt.Println(err)
 	}
 
-	if err := b.PreprocessSketch(includeFolders); err != nil {
+	if err := b.preprocessSketch(includeFolders); err != nil {
 		return err
 	}
 
diff --git a/arduino/builder/libraries.go b/arduino/builder/libraries.go
index f5b6a46957b..9efa62df378 100644
--- a/arduino/builder/libraries.go
+++ b/arduino/builder/libraries.go
@@ -35,8 +35,8 @@ var (
 	FpuCflag      = "fpu"
 )
 
-// BuildLibraries fixdoc
-func (b *Builder) BuildLibraries(includesFolders paths.PathList, importedLibraries libraries.List) error {
+// buildLibraries fixdoc
+func (b *Builder) buildLibraries(includesFolders paths.PathList, importedLibraries libraries.List) error {
 	includes := f.Map(includesFolders.AsStrings(), cpp.WrapWithHyphenI)
 	libs := importedLibraries
 
@@ -254,8 +254,8 @@ func (b *Builder) compileLibrary(library *libraries.Library, includes []string)
 	return objectFiles, nil
 }
 
-// RemoveUnusedCompiledLibraries fixdoc
-func (b *Builder) RemoveUnusedCompiledLibraries(importedLibraries libraries.List) error {
+// removeUnusedCompiledLibraries fixdoc
+func (b *Builder) removeUnusedCompiledLibraries(importedLibraries libraries.List) error {
 	if b.librariesBuildPath.NotExist() {
 		return nil
 	}
@@ -287,8 +287,8 @@ func (b *Builder) RemoveUnusedCompiledLibraries(importedLibraries libraries.List
 	return nil
 }
 
-// WarnAboutArchIncompatibleLibraries fixdoc
-func (b *Builder) WarnAboutArchIncompatibleLibraries(importedLibraries libraries.List) {
+// warnAboutArchIncompatibleLibraries fixdoc
+func (b *Builder) warnAboutArchIncompatibleLibraries(importedLibraries libraries.List) {
 	archs := []string{b.targetPlatform.Platform.Architecture}
 	overrides, _ := b.buildProperties.GetOk("architecture.override_check")
 	if overrides != "" {
@@ -306,10 +306,10 @@ func (b *Builder) WarnAboutArchIncompatibleLibraries(importedLibraries libraries
 	}
 }
 
-// PrintUsedLibraries fixdoc
+// printUsedLibraries fixdoc
 // TODO here we can completly remove this part as it's duplicated in what we can
 // read in the gRPC response
-func (b *Builder) PrintUsedLibraries(importedLibraries libraries.List) {
+func (b *Builder) printUsedLibraries(importedLibraries libraries.List) {
 	if !b.logger.Verbose() || len(importedLibraries) == 0 {
 		return
 	}
diff --git a/arduino/builder/linker.go b/arduino/builder/linker.go
index a4a2eba3bec..60c09bcf6dd 100644
--- a/arduino/builder/linker.go
+++ b/arduino/builder/linker.go
@@ -24,8 +24,8 @@ import (
 	"github.com/pkg/errors"
 )
 
-// Link fixdoc
-func (b *Builder) Link() error {
+// link fixdoc
+func (b *Builder) link() error {
 	if b.onlyUpdateCompilationDatabase {
 		if b.logger.Verbose() {
 			b.logger.Info(tr("Skip linking of final executable."))
@@ -43,14 +43,6 @@ func (b *Builder) Link() error {
 		return errors.WithStack(err)
 	}
 
-	if err := b.link(objectFiles, coreDotARelPath, b.buildArtifacts.coreArchiveFilePath); err != nil {
-		return errors.WithStack(err)
-	}
-
-	return nil
-}
-
-func (b *Builder) link(objectFiles paths.PathList, coreDotARelPath *paths.Path, coreArchiveFilePath *paths.Path) error {
 	wrapWithDoubleQuotes := func(value string) string { return "\"" + value + "\"" }
 	objectFileList := strings.Join(f.Map(objectFiles.AsStrings(), wrapWithDoubleQuotes), " ")
 
@@ -101,7 +93,7 @@ func (b *Builder) link(objectFiles paths.PathList, coreDotARelPath *paths.Path,
 	properties.Set("compiler.c.elf.flags", properties.Get("compiler.c.elf.flags"))
 	properties.Set("compiler.warning_flags", properties.Get("compiler.warning_flags."+b.logger.WarningsLevel()))
 	properties.Set("archive_file", coreDotARelPath.String())
-	properties.Set("archive_file_path", coreArchiveFilePath.String())
+	properties.Set("archive_file_path", b.buildArtifacts.coreArchiveFilePath.String())
 	properties.Set("object_files", objectFileList)
 
 	command, err := utils.PrepareCommandForRecipe(properties, "recipe.c.combine.pattern", false)
@@ -113,5 +105,8 @@ func (b *Builder) link(objectFiles paths.PathList, coreDotARelPath *paths.Path,
 	if b.logger.Verbose() {
 		b.logger.Info(string(verboseInfo))
 	}
-	return err
+	if err != nil {
+		return err
+	}
+	return nil
 }
diff --git a/arduino/builder/preprocess_sketch.go b/arduino/builder/preprocess_sketch.go
index cf6adb208a2..c871495c335 100644
--- a/arduino/builder/preprocess_sketch.go
+++ b/arduino/builder/preprocess_sketch.go
@@ -20,8 +20,8 @@ import (
 	"github.com/arduino/go-paths-helper"
 )
 
-// PreprocessSketch fixdoc
-func (b *Builder) PreprocessSketch(includes paths.PathList) error {
+// preprocessSketch fixdoc
+func (b *Builder) preprocessSketch(includes paths.PathList) error {
 	// In the future we might change the preprocessor
 	normalOutput, verboseOutput, err := preprocessor.PreprocessSketchWithCtags(
 		b.sketch, b.buildPath, includes, b.lineOffset,
@@ -29,8 +29,9 @@ func (b *Builder) PreprocessSketch(includes paths.PathList) error {
 	)
 	if b.logger.Verbose() {
 		b.logger.WriteStdout(verboseOutput)
+	} else {
+		b.logger.WriteStdout(normalOutput)
 	}
-	b.logger.WriteStdout(normalOutput)
 
 	return err
 }
diff --git a/arduino/builder/recipe.go b/arduino/builder/recipe.go
index 1102e8d7568..385e6a03a87 100644
--- a/arduino/builder/recipe.go
+++ b/arduino/builder/recipe.go
@@ -27,10 +27,7 @@ import (
 )
 
 // RunRecipe fixdoc
-func (b *Builder) RunRecipe(
-	prefix, suffix string,
-	skipIfOnlyUpdatingCompilationDatabase bool,
-) error {
+func (b *Builder) RunRecipe(prefix, suffix string, skipIfOnlyUpdatingCompilationDatabase bool) error {
 	logrus.Debugf(fmt.Sprintf("Looking for recipes like %s", prefix+"*"+suffix))
 
 	// TODO is it necessary to use Clone?
diff --git a/arduino/builder/sizer.go b/arduino/builder/sizer.go
index 7f461f8292e..0924f9a62e4 100644
--- a/arduino/builder/sizer.go
+++ b/arduino/builder/sizer.go
@@ -50,9 +50,9 @@ func (s ExecutablesFileSections) ToRPCExecutableSectionSizeArray() []*rpc.Execut
 	return res
 }
 
-// Size fixdoc
-func (b *Builder) Size(sketchError bool) error {
-	if b.onlyUpdateCompilationDatabase || sketchError {
+// size fixdoc
+func (b *Builder) size() error {
+	if b.onlyUpdateCompilationDatabase {
 		return nil
 	}
 
diff --git a/arduino/builder/sketch.go b/arduino/builder/sketch.go
index dbab5b521bc..f54461fb74a 100644
--- a/arduino/builder/sketch.go
+++ b/arduino/builder/sketch.go
@@ -25,7 +25,6 @@ import (
 
 	"github.com/arduino/arduino-cli/arduino/builder/cpp"
 	"github.com/arduino/arduino-cli/arduino/builder/utils"
-	"github.com/arduino/arduino-cli/arduino/sketch"
 	"github.com/arduino/arduino-cli/i18n"
 	f "github.com/arduino/arduino-cli/internal/algorithms"
 	"github.com/arduino/go-paths-helper"
@@ -39,15 +38,10 @@ var (
 	tr               = i18n.Tr
 )
 
-// Sketch fixdoc
-func (b *Builder) Sketch() *sketch.Sketch {
-	return b.sketch
-}
-
-// PrepareSketchBuildPath copies the sketch source files in the build path.
+// prepareSketchBuildPath copies the sketch source files in the build path.
 // The .ino files are merged together to create a .cpp file (by the way, the
 // .cpp file still needs to be Arduino-preprocessed to compile).
-func (b *Builder) PrepareSketchBuildPath() error {
+func (b *Builder) prepareSketchBuildPath() error {
 	if err := b.sketchBuildPath.MkdirAll(); err != nil {
 		return errors.Wrap(err, tr("unable to create a folder to save the sketch"))
 	}
diff --git a/commands/compile/compile.go b/commands/compile/compile.go
index 5dcd028c34c..cd728eb5fa1 100644
--- a/commands/compile/compile.go
+++ b/commands/compile/compile.go
@@ -24,8 +24,7 @@ import (
 	"strings"
 
 	"github.com/arduino/arduino-cli/arduino"
-	bldr "github.com/arduino/arduino-cli/arduino/builder"
-	"github.com/arduino/arduino-cli/arduino/builder/detector"
+	"github.com/arduino/arduino-cli/arduino/builder"
 	"github.com/arduino/arduino-cli/arduino/builder/logger"
 	"github.com/arduino/arduino-cli/arduino/builder/progress"
 	"github.com/arduino/arduino-cli/arduino/cores"
@@ -37,8 +36,6 @@ import (
 	"github.com/arduino/arduino-cli/configuration"
 	"github.com/arduino/arduino-cli/i18n"
 	"github.com/arduino/arduino-cli/internal/inventory"
-	"github.com/arduino/arduino-cli/legacy/builder"
-	"github.com/arduino/arduino-cli/legacy/builder/types"
 	rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
 	paths "github.com/arduino/go-paths-helper"
 	"github.com/sirupsen/logrus"
@@ -174,16 +171,15 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
 		return nil, err
 	}
 
-	builderCtx := &types.Context{}
 	actualPlatform := buildPlatform
-	builtinLibrariesDir := configuration.IDEBuiltinLibrariesDir(configuration.Settings)
 	otherLibrariesDirs := paths.NewPathList(req.GetLibraries()...)
 	otherLibrariesDirs.Add(configuration.LibrariesDir(configuration.Settings))
 
-	builderLogger := logger.New(outStream, errStream, req.GetVerbose(), req.GetWarnings())
-	builderCtx.BuilderLogger = builderLogger
-
-	sketchBuilder, err := bldr.NewBuilder(
+	var libsManager *librariesmanager.LibrariesManager
+	if pme.GetProfile() != nil {
+		libsManager = lm
+	}
+	sketchBuilder, err := builder.NewBuilder(
 		sk,
 		boardBuildProperties,
 		buildPath,
@@ -194,53 +190,29 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
 		configuration.HardwareDirectories(configuration.Settings),
 		configuration.BuiltinToolsDirectories(configuration.Settings),
 		otherLibrariesDirs,
-		builtinLibrariesDir,
+		configuration.IDEBuiltinLibrariesDir(configuration.Settings),
 		fqbn,
 		req.GetClean(),
 		req.GetSourceOverride(),
 		req.GetCreateCompilationDatabaseOnly(),
-		actualPlatform, targetPlatform,
-		builderLogger,
+		targetPlatform, actualPlatform,
+		req.GetSkipLibrariesDiscovery(),
+		libsManager,
+		paths.NewPathList(req.Library...),
+		logger.New(outStream, errStream, req.GetVerbose(), req.GetWarnings()),
 		progress.New(progressCB),
 	)
 	if err != nil {
 		if strings.Contains(err.Error(), "invalid build properties") {
 			return nil, &arduino.InvalidArgumentError{Message: tr("Invalid build properties"), Cause: err}
 		}
-		if errors.Is(err, bldr.ErrSketchCannotBeLocatedInBuildPath) {
+		if errors.Is(err, builder.ErrSketchCannotBeLocatedInBuildPath) {
 			return r, &arduino.CompileFailedError{
 				Message: tr("Sketch cannot be located in build path. Please specify a different build path"),
 			}
 		}
 		return r, &arduino.CompileFailedError{Message: err.Error()}
 	}
-	builderCtx.Builder = sketchBuilder
-
-	var libsManager *librariesmanager.LibrariesManager
-	if pme.GetProfile() != nil {
-		libsManager = lm
-	}
-	useCachedLibrariesResolution := req.GetSkipLibrariesDiscovery()
-	libraryDir := paths.NewPathList(req.Library...)
-	libsManager, libsResolver, verboseOut, err := detector.LibrariesLoader(
-		useCachedLibrariesResolution, libsManager,
-		builtinLibrariesDir, libraryDir, otherLibrariesDirs,
-		actualPlatform, targetPlatform,
-	)
-	if err != nil {
-		return r, &arduino.CompileFailedError{Message: err.Error()}
-	}
-
-	if builderLogger.Verbose() {
-		builderLogger.Warn(string(verboseOut))
-	}
-
-	builderCtx.SketchLibrariesDetector = detector.NewSketchLibrariesDetector(
-		libsManager, libsResolver,
-		useCachedLibrariesResolution,
-		req.GetCreateCompilationDatabaseOnly(),
-		builderLogger,
-	)
 
 	defer func() {
 		if p := sketchBuilder.GetBuildPath(); p != nil {
@@ -270,7 +242,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
 
 	if req.GetPreprocess() {
 		// Just output preprocessed source code and exit
-		compileErr := builder.RunPreprocess(builderCtx)
+		compileErr := sketchBuilder.Preprocess()
 		if compileErr != nil {
 			compileErr = &arduino.CompileFailedError{Message: compileErr.Error()}
 		}
@@ -279,7 +251,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
 
 	defer func() {
 		importedLibs := []*rpc.Library{}
-		for _, lib := range builderCtx.SketchLibrariesDetector.ImportedLibraries() {
+		for _, lib := range sketchBuilder.SketchLibrariesDetector.ImportedLibraries() {
 			rpcLib, err := lib.ToRPCLibrary()
 			if err != nil {
 				msg := tr("Error getting information for library %s", lib.Name) + ": " + err.Error() + "\n"
@@ -315,7 +287,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
 				targetBoard.String(), "'build.board'", sketchBuilder.GetBuildProperties().Get("build.board")) + "\n"))
 	}
 
-	if err := builder.RunBuilder(builderCtx); err != nil {
+	if err := sketchBuilder.Build(); err != nil {
 		return r, &arduino.CompileFailedError{Message: err.Error()}
 	}
 
diff --git a/internal/integrationtest/daemon/daemon_test.go b/internal/integrationtest/daemon/daemon_test.go
index cbb227293c4..d550ea2ed09 100644
--- a/internal/integrationtest/daemon/daemon_test.go
+++ b/internal/integrationtest/daemon/daemon_test.go
@@ -187,7 +187,7 @@ func TestDaemonCompileOptions(t *testing.T) {
 	// https://github.com/arduino/arduino-cli/issues/2016
 	// assert that the task progress is increasing and doesn't contain multiple 100% values
 	results := analyzer.Results[""]
-	require.True(t, results[len(results)-1].Completed)
+	require.True(t, results[len(results)-1].Completed, fmt.Sprintf("latest percent value: %v", results[len(results)-1].Percent))
 	require.IsNonDecreasing(t, f.Map(results, (*commands.TaskProgress).GetPercent))
 }
 
diff --git a/legacy/builder/.gitignore b/legacy/builder/.gitignore
deleted file mode 100644
index 0df12e548b2..00000000000
--- a/legacy/builder/.gitignore
+++ /dev/null
@@ -1,81 +0,0 @@
-bin
-src/github.com
-src/golang.org
-./arduino-builder
-
-# Created by .ignore support plugin (hsz.mobi)
-### Go template
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-*.prof
-
-
-
-### JetBrains template
-# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
-
-*.iml
-
-## Directory-based project format:
-.idea/
-# if you remove the above rule, at least ignore the following:
-
-# User-specific stuff:
-# .idea/workspace.xml
-# .idea/tasks.xml
-# .idea/dictionaries
-
-# Sensitive or high-churn files:
-# .idea/dataSources.ids
-# .idea/dataSources.xml
-# .idea/sqlDataSources.xml
-# .idea/dynamic.xml
-# .idea/uiDesigner.xml
-
-# Gradle:
-# .idea/gradle.xml
-# .idea/libraries
-
-# Mongo Explorer plugin:
-# .idea/mongoSettings.xml
-
-## File-based project format:
-*.ipr
-*.iws
-
-## Plugin-specific files:
-
-# IntelliJ
-out/
-
-# mpeltonen/sbt-idea plugin
-.idea_modules/
-
-# JIRA plugin
-atlassian-ide-plugin.xml
-
-# Crashlytics plugin (for Android Studio and IntelliJ)
-com_crashlytics_export_strings.xml
-crashlytics.properties
-crashlytics-build.properties
diff --git a/legacy/builder/builder.go b/legacy/builder/builder.go
deleted file mode 100644
index e7fa77fc7f4..00000000000
--- a/legacy/builder/builder.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// 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.
-
-package builder
-
-import (
-	"reflect"
-	"time"
-
-	"github.com/arduino/arduino-cli/i18n"
-	"github.com/arduino/arduino-cli/legacy/builder/types"
-	"github.com/pkg/errors"
-	"github.com/sirupsen/logrus"
-)
-
-var tr = i18n.Tr
-
-type Builder struct{}
-
-func (s *Builder) Run(ctx *types.Context) error {
-	if err := ctx.Builder.GetBuildPath().MkdirAll(); err != nil {
-		return err
-	}
-
-	var mainErr error
-	commands := []types.Command{
-		containerBuildOptions(ctx),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.prebuild", ".pattern", false)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.PrepareSketchBuildPath()
-		}),
-
-		logIfVerbose(false, tr("Detecting libraries used...")),
-		findIncludes(ctx),
-
-		warnAboutArchIncompatibleLibraries(ctx),
-
-		logIfVerbose(false, tr("Generating function prototypes...")),
-		preprocessSketchCommand(ctx),
-
-		logIfVerbose(false, tr("Compiling sketch...")),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.sketch.prebuild", ".pattern", false)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.BuildSketch(ctx.SketchLibrariesDetector.IncludeFolders())
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.sketch.postbuild", ".pattern", true)
-		}),
-
-		logIfVerbose(false, tr("Compiling libraries...")),
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.libraries.prebuild", ".pattern", false)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.RemoveUnusedCompiledLibraries(
-				ctx.SketchLibrariesDetector.ImportedLibraries(),
-			)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.BuildLibraries(ctx.SketchLibrariesDetector.IncludeFolders(), ctx.SketchLibrariesDetector.ImportedLibraries())
-		}),
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.libraries.postbuild", ".pattern", true)
-		}),
-
-		logIfVerbose(false, tr("Compiling core...")),
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.core.prebuild", ".pattern", false)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.BuildCore()
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.core.postbuild", ".pattern", true)
-		}),
-
-		logIfVerbose(false, tr("Linking everything together...")),
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.linking.prelink", ".pattern", false)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.Link()
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.linking.postlink", ".pattern", true)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.objcopy.preobjcopy", ".pattern", false)
-		}),
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.objcopy.", ".pattern", true)
-		}),
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.objcopy.postobjcopy", ".pattern", true)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.MergeSketchWithBootloader()
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.postbuild", ".pattern", true)
-		}),
-	}
-
-	ctx.Builder.Progress.AddSubSteps(len(commands) + 5)
-	defer ctx.Builder.Progress.RemoveSubSteps()
-
-	for _, command := range commands {
-		PrintRingNameIfDebug(ctx, command)
-		err := command.Run(ctx)
-		if err != nil {
-			mainErr = errors.WithStack(err)
-			break
-		}
-		ctx.Builder.Progress.CompleteStep()
-		ctx.Builder.Progress.PushProgress()
-	}
-
-	ctx.Builder.SaveCompilationDatabase()
-
-	var otherErr error
-	commands = []types.Command{
-		types.BareCommand(func(ctx *types.Context) error {
-			ctx.SketchLibrariesDetector.PrintUsedAndNotUsedLibraries(mainErr != nil)
-			return nil
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			ctx.Builder.PrintUsedLibraries(ctx.SketchLibrariesDetector.ImportedLibraries())
-			return nil
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.ExportProjectCMake(
-				mainErr != nil,
-				ctx.SketchLibrariesDetector.ImportedLibraries(),
-				ctx.SketchLibrariesDetector.IncludeFolders(),
-			)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.Size(mainErr != nil)
-		}),
-	}
-	for _, command := range commands {
-		PrintRingNameIfDebug(ctx, command)
-		err := command.Run(ctx)
-		if err != nil {
-			otherErr = errors.WithStack(err)
-			break
-		}
-		ctx.Builder.Progress.CompleteStep()
-		ctx.Builder.Progress.PushProgress()
-	}
-
-	if mainErr != nil {
-		return mainErr
-	}
-
-	return otherErr
-}
-
-func preprocessSketchCommand(ctx *types.Context) types.BareCommand {
-	return func(ctx *types.Context) error {
-		return ctx.Builder.PreprocessSketch(ctx.SketchLibrariesDetector.IncludeFolders())
-	}
-}
-
-type Preprocess struct{}
-
-func (s *Preprocess) Run(ctx *types.Context) error {
-	if err := ctx.Builder.GetBuildPath().MkdirAll(); err != nil {
-		return err
-	}
-
-	commands := []types.Command{
-		containerBuildOptions(ctx),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return recipeByPrefixSuffixRunner(ctx, "recipe.hooks.prebuild", ".pattern", false)
-		}),
-
-		types.BareCommand(func(ctx *types.Context) error {
-			return ctx.Builder.PrepareSketchBuildPath()
-		}),
-
-		findIncludes(ctx),
-
-		warnAboutArchIncompatibleLibraries(ctx),
-
-		preprocessSketchCommand(ctx),
-	}
-
-	if err := runCommands(ctx, commands); err != nil {
-		return err
-	}
-
-	// Output arduino-preprocessed source
-	preprocessedSketch, err := ctx.Builder.GetSketchBuildPath().Join(ctx.Builder.Sketch().MainFile.Base() + ".cpp").ReadFile()
-	if err != nil {
-		return err
-	}
-	ctx.BuilderLogger.WriteStdout(preprocessedSketch)
-	return nil
-}
-
-func runCommands(ctx *types.Context, commands []types.Command) error {
-	ctx.Builder.Progress.AddSubSteps(len(commands))
-	defer ctx.Builder.Progress.RemoveSubSteps()
-
-	for _, command := range commands {
-		PrintRingNameIfDebug(ctx, command)
-		err := command.Run(ctx)
-		if err != nil {
-			return errors.WithStack(err)
-		}
-		ctx.Builder.Progress.CompleteStep()
-		ctx.Builder.Progress.PushProgress()
-	}
-	return nil
-}
-
-func PrintRingNameIfDebug(ctx *types.Context, command types.Command) {
-	logrus.Debugf("Ts: %d - Running: %s", time.Now().Unix(), reflect.Indirect(reflect.ValueOf(command)).Type().Name())
-}
-
-func RunBuilder(ctx *types.Context) error {
-	return runCommands(ctx, []types.Command{&Builder{}})
-}
-
-func RunPreprocess(ctx *types.Context) error {
-	command := Preprocess{}
-	return command.Run(ctx)
-}
-
-func findIncludes(ctx *types.Context) types.BareCommand {
-	return types.BareCommand(func(ctx *types.Context) error {
-		return ctx.SketchLibrariesDetector.FindIncludes(
-			ctx.Builder.GetBuildPath(),
-			ctx.Builder.GetBuildProperties().GetPath("build.core.path"),
-			ctx.Builder.GetBuildProperties().GetPath("build.variant.path"),
-			ctx.Builder.GetSketchBuildPath(),
-			ctx.Builder.Sketch(),
-			ctx.Builder.GetLibrariesBuildPath(),
-			ctx.Builder.GetBuildProperties(),
-			ctx.Builder.TargetPlatform().Platform.Architecture,
-		)
-	})
-}
-
-func logIfVerbose(warn bool, msg string) types.BareCommand {
-	return types.BareCommand(func(ctx *types.Context) error {
-		if !ctx.BuilderLogger.Verbose() {
-			return nil
-		}
-		if warn {
-			ctx.BuilderLogger.Warn(msg)
-		} else {
-			ctx.BuilderLogger.Info(msg)
-		}
-		return nil
-	})
-}
-
-func recipeByPrefixSuffixRunner(ctx *types.Context, prefix, suffix string, skipIfOnlyUpdatingCompilationDatabase bool) error {
-	return ctx.Builder.RunRecipe(prefix, suffix, skipIfOnlyUpdatingCompilationDatabase)
-}
-
-func containerBuildOptions(ctx *types.Context) types.BareCommand {
-	return types.BareCommand(func(ctx *types.Context) error {
-		return ctx.Builder.BuildOptionsManager.WipeBuildPath()
-	})
-}
-
-func warnAboutArchIncompatibleLibraries(ctx *types.Context) types.BareCommand {
-	return types.BareCommand(func(ctx *types.Context) error {
-		ctx.Builder.WarnAboutArchIncompatibleLibraries(
-			ctx.SketchLibrariesDetector.ImportedLibraries(),
-		)
-		return nil
-	})
-}
diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go
deleted file mode 100644
index 64b85c93fe2..00000000000
--- a/legacy/builder/types/context.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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.
-
-package types
-
-import (
-	"github.com/arduino/arduino-cli/arduino/builder"
-	"github.com/arduino/arduino-cli/arduino/builder/detector"
-	"github.com/arduino/arduino-cli/arduino/builder/logger"
-)
-
-// Context structure
-type Context struct {
-	Builder                 *builder.Builder
-	SketchLibrariesDetector *detector.SketchLibrariesDetector
-	BuilderLogger           *logger.BuilderLogger
-}
diff --git a/legacy/builder/types/types.go b/legacy/builder/types/types.go
deleted file mode 100644
index 8678fd2fe51..00000000000
--- a/legacy/builder/types/types.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.
-
-package types
-
-type Command interface {
-	Run(ctx *Context) error
-}
-
-type BareCommand func(ctx *Context) error
-
-func (cmd BareCommand) Run(ctx *Context) error {
-	return cmd(ctx)
-}