Hi @justin_2990, We are actually in the process of developing dedicated npm operations, but we do have anything ready as of yet. The easiest way to call npm commands is to use the Exec operation in OtterScript. Due to how the npm CLI writes it's output, you need to add ErrorOutputLogLevel: Warning to the Exec operation. Here is an example of the npm install and npm publish commands: set $NpmPath = C:\Program Files\nodejs\npm.cmd; set $NodePath = C:\Program Files\nodejs\node.exe; # Install Dependencies Exec ( FileName: $NpmPath, Arguments: install, WorkingDirectory: ~\Source, ErrorOutputLogLevel: Warning ); # Publish Package Exec ( FileName: $NpmPath, Arguments: publish Source, WorkingDirectory: ~\, ErrorOutputLogLevel: Warning ); When it comes to ProGet::Scan, it should work with all npm packages. It just reads the package-lock.json and records the dependencies in ProGet. You can see our implementation on the pgscan GitHub repository. If that doesn't work, you can always use a tool like CycloneDX to generate an SBOM and upload it to ProGet via the SCA API which has an endpoint for importing an SBOM file directly. One last thing, you mentioned that you are using ProGet. You can create an OtterScript module to register ProGet as your package source for npm. I do this with the following: ConfigureNpmRegistry OtterScript Module ##AH:UseTextMode module ConfigureNpmRegistry<$NpmPath, $ResourceName, $CredentialName> { set $ProGetNpmRegistry = $SecureResourceProperty($ResourceName, ServerUrl); Exec ( FileName: $NpmPath, Arguments: config set registry $ProGetNpmRegistry, WorkingDirectory: ~\, ErrorOutputLogLevel: Warning ); set $AuthToken = $SecureCredentialProperty($CredentialName, Token); PSCall Base64Encode ( Text: api:$AuthToken, EncodedText => $AuthKey ); Exec ( FileName: $NpmPath, Arguments: config set always-auth true, WorkingDirectory: ~\, ErrorOutputLogLevel: Warning ); Exec ( FileName: $NpmPath, Arguments: config set _auth $AuthKey, WorkingDirectory: ~\, ErrorOutputLogLevel: Warning, LogArguments: false ); Exec ( FileName: $NpmPath, Arguments: config set email support@inedo.com, WorkingDirectory: ~\, ErrorOutputLogLevel: Warning ); } I also had to add a PowerShell script to handle the base64 encoding of the credentials: <# .SYNOPSIS Base64 Encodes a string .PARAMETER Text Text to be encoded .PARAMETER EncodedText Encoded text string #> param( [Parameter(Mandatory=$true)] [string]$Text, [ref]$EncodedText ) $Bytes = [System.Text.Encoding]::UTF8.GetBytes($Text) $EncodedText =[Convert]::ToBase64String($Bytes) I then call this using: # Setup registry call ConfigureNpmRegistry ( NpmPath: $NpmPath, ResourceName: global::ProGetNpmRepo, CredentialName: global::ProGetNpmCredentials ); These are all operations we plan to build into the npm extension, but these are currently the workaround until we get that extension up and running. I hope this helps! Please let me know if you have any questions. Thanks, Rich