[feature] add command to change build out dir

Bug: 435708291
Change-Id: I215400ceb45dd99c4193c98b6bc7fc234b5fb271
Reviewed-on: https://fuchsia-review.googlesource.com/c/vscode-plugins/+/1354825
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Darren Chan <chandarren@google.com>
Reviewed-by: Adam Barth <abarth@google.com>
diff --git a/package.json b/package.json
index 5b4aada..48f9d7b 100644
--- a/package.json
+++ b/package.json
@@ -250,6 +250,11 @@
         "category": "Fuchsia"
       },
       {
+        "command": "fuchsia.fx.use",
+        "title": "Change build directory",
+        "category": "Fuchsia"
+      },
+      {
         "command": "fuchsia.refreshComponentExplorer",
         "title": "Refresh component explorer",
         "icon": "$(refresh)",
diff --git a/src/workflow/index.ts b/src/workflow/index.ts
index 1edc816..0fa600d 100644
--- a/src/workflow/index.ts
+++ b/src/workflow/index.ts
@@ -9,7 +9,7 @@
 import { registerCommandWithAnalyticsEvent } from '../analytics/vscode_events';
 import { registerBuildCommands } from './build';
 import { FuchsiaDiagnostics } from './problem_matcher';
-import { PkgHistory, registerSetCommand } from './set';
+import { PkgHistory, registerSetCommand, toList } from './set';
 
 /**
  * initialize fuchsia workflow interaction commands
@@ -62,4 +62,38 @@
         logger.error(err);
       });
   });
+
+  /** Register `fuchsia.fx.use` */
+  registerCommandWithAnalyticsEvent('fuchsia.fx.use', () => {
+    setup.fx.runAsync(['use'],
+      (data) => {
+        void (async () => {
+          const msg = new TextDecoder().decode(data);
+          const list = toList(msg.split('\n'));
+          const selected = await window.showQuickPick(list, {
+            title: 'Select build directory'
+          });
+          let dir = selected?.label;
+
+          if (!dir?.includes('(current)')) {
+            /** callback to handle buffer from process */
+            function handleData(buffer: Buffer) {
+              logger.info(new TextDecoder().decode(buffer), 'fx use');
+            }
+            let cmd = setup.fx.runAsync(['use', `${dir}`], handleData, handleData);
+
+            let exitCode = await cmd?.exitCode;
+            if (exitCode !== 0) {
+              logger.error(`fx use ${dir} exited with code ${exitCode}`, 'fx use');
+              throw new Error('fx use returned a nonzero exit code');
+            }
+            logger.info(`Build directory changed to: ${dir}`, 'fx use');
+          }
+        })();
+      }, () => {
+        // Ignore since err returns 'INFO: listing build directories:'
+      }
+    );
+  });
+
 }