anchor.diff:          proc?on $ ("error", f |> unbox) |> ignore
           proc
   
  -    let spawn location linuxCmd (cmd : string) =
  -        let cmd' = splitArgs cmd |> ResizeArray
  -
  -        let options =
  -            createObj [
  -                "cwd" ==> workspace.rootPath
  -            ]
  -        if isWin () || linuxCmd = "" then
  -            node.childProcess.spawn(location, cmd', options)
  -        else
  -            let prms = seq { yield location; yield! cmd'} |> ResizeArray
  -            node.childProcess.spawn(linuxCmd, prms, options)
  -
  -    let spawnInDir location linuxCmd (cmd : string) =
  -        let cmd' = splitArgs cmd |> ResizeArray
  -
  -        let options =
  -            createObj [
  -                "cwd" ==> (node.path.dirname location)
  -            ]
  -        if isWin () || linuxCmd = "" then
  -
  -            node.childProcess.spawn(location, cmd', options)
  -        else
  -            let prms = seq { yield location; yield! cmd'} |> ResizeArray
  -            node.childProcess.spawn(linuxCmd, prms, options)
  -
  -    let spawnWithShell location linuxCmd (cmd : string) =
  -        let cmd' =
  -            if isWin() then
  -                splitArgs cmd
  -                |> Seq.map (fun c -> if c.Contains " " then sprintf "\"%s\"" c else c )
  -                |> ResizeArray
  -            else
  -                splitArgs cmd
  -                |> Seq.toArray
  -                |> ResizeArray
  -
  -        if isWin () || linuxCmd = "" then
  -            window.createTerminal("F# Application", location, U2.Case1 cmd')
  -        else
  -            let prms = seq { yield location; yield! cmd'} |> ResizeArray |> U2.Case1
  -            window.createTerminal("F# Application", linuxCmd, prms)
  -
  -
  -    let spawnWithNotification location linuxCmd (cmd : string) (outputChannel : OutputChannel) =
  -        spawn location linuxCmd cmd
  +    /// <summary>
  +    /// spawns a child process in a directory, using a prefix command on linux if required
  +    /// </summary>
  +    /// <param name="dir">the directory to run the command in</param>
  +    /// <param name="command">the 'base' command to execute</param>
  +    /// <param name="args">an array of additional CLI args</param>
  +    /// <returns></returns>
  +    let spawnInDir dir command args =
  +        let options = createEmpty<ExecOptions>
  +        options.cwd <- Some dir
  +        node.childProcess.spawn(command, args, options)
  +
  +    /// <summary>
  +    /// Spawns a child process with a prefix command on linux if required.
  +    /// </summary>
  +    /// <param name="command">the 'base' command to execute</param>
  +    /// <param name="args">an array of additional CLI args</param>
  +    /// <returns>a node child process</returns>
  +    let spawn command (args: ResizeArray<string>) =
  +        let options = createEmpty<ExecOptions>
  +        options.cwd <- workspace.rootPath
  +        crossSpawn.spawn(command, args, options)
  +
  +    /// <summary>
  +    /// Run a command in a local vscode terminal
  +    /// </summary>
  +    /// <param name="command">the 'base' command to execute</param>
  +    /// <param name="args">an array of additional CLI args</param>
  +    /// <returns>a vscode terminal</returns>
  +    let spawnWithShell command (args: ResizeArray<string>) =
  +        window.createTerminal("F# Application", command, U2.Case1 args)
  +
  +    /// <summary>
  +    /// fire off a command in the workspace root and write its output to a channel
  +    /// </summary>
  +    /// <param name="command">the 'base' command to execute</param>
  +    /// <param name="args">an array of additional CLI args</param>
  +    /// <param name="outputChannel">the output channel to write the stdout/stderr of the process to</param>
  +    /// <returns></returns>
  +    let spawnWithNotification command args (outputChannel : OutputChannel) =
  +        spawn command args
           |> onOutput(fun e -> e.toString () |> outputChannel.append)
           |> onError (fun e -> e.ToString () |> outputChannel.append)
           |> onErrorOutput(fun e -> e.toString () |> outputChannel.append)
   
  -    let spawnWithNotificationInDir location linuxCmd (cmd : string) (outputChannel : OutputChannel) =
  -        spawnInDir location linuxCmd cmd
  +
  +    /// <summary>
  +    /// fire off a command in a directory and write its output to a channel
  +    /// </summary>
  +    /// <param name="location">the directory to run the command in</param>
  +    /// <param name="command">the 'base' command to execute</param>
  +    /// <param name="args">an array of additional CLI args</param>
  +    /// <param name="outputChannel">the output channel to write the stdout/stderr of the process to</param>
  +    /// <returns></returns>
  +    let spawnWithNotificationInDir location command args (outputChannel : OutputChannel) =
  +        spawnInDir location command args
           |> onOutput(fun e -> e.toString () |> outputChannel.append)
           |> onError (fun e -> e.ToString () |> outputChannel.append)
           |> onErrorOutput(fun e -> e.toString () |> outputChannel.append)
  
positive.code:             |> ignore
          )
  
      let exec location linuxCmd cmd : JS.Promise<ExecError option * string * string> =
          let options = createEmpty<ExecOptions>
          options.cwd <- workspace.rootPath
          
          Promise.create (fun resolve error ->
              let execCmd =
                  if isWin () then location + " " + cmd
                  else linuxCmd + " " + location + " " + cmd
              node.childProcess.exec(execCmd, options,
                  (fun (e : ExecError option) (i : U2<string, Buffer.Buffer>) (o : U2<string, Buffer.Buffer>) ->
                      // As we don't specify an encoding, the documentation specifies that we'll receive strings
                      // "By default, Node.js will decode the output as UTF-8 and pass strings to the callback"
                      let arg = e, unbox<string> i, unbox<string> o
                      resolve arg)
              ) |> ignore
          )
  
  
  
negative.code:         |> Option.map (fun e -> e.extensionPath)
  
  
  module CrossSpawn = 
      open Node.ChildProcess
      type [<AllowNullLiteral>] IExports = 
          abstract spawn: command: string * options: ExecOptions -> ChildProcess
          abstract spawn: command: string * args: ResizeArray<string>  * ?options: ExecOptions -> ChildProcess
  
      let crossSpawn: IExports = Fable.Core.JsInterop.importAll "cross-spawn"
  
  //---------------------------------------------------
  //Process Helpers
  //---------------------------------------------------
  module Process =
  
      open Node
      open Node.ChildProcess
      open Fable.Import.VSCode.Vscode
      open Fable.Core.JsInterop
      open CrossSpawn
  
      module node = Node.Api
  
  