@snapvisor/cli
Advanced tools
+25
-25
@@ -36,3 +36,3 @@ import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises"; | ||
| function uploadCommand(program) { | ||
| program.command("upload").argument("<directory>", "Directory to upload").description("Upload screenshots to Snapvisor").option("-f, --files <patterns...>", "One or more globs matching image file paths to upload", "**/*.{png,jpg,jpeg}").option("-i, --ignore <patterns...>", "One or more globs matching image file paths to ignore (ex: \"**/*.png **/diff.jpg\")").addOption(tokenOption).addOption(projectOption).addOption(buildNameOption).addOption(new Option("--mode <string>", "Mode of comparison applied. CI for visual regression testing, monitoring for visual monitoring.").default("ci").choices(["ci", "monitoring"])).addOption(new Option("--parallel", "Enable parallel mode. Run multiple Argos builds and combine them at the end.\nCan also be set via the ARGOS_PARALLEL environment variable.")).addOption(new Option("--parallel-total <number>", "The number of parallel nodes being ran")).addOption(parallelNonceOption).addOption(new Option("--parallel-index <number>", "The index of the parallel node being ran (must be at least 1)")).addOption(new Option("--reference-branch <string>", "Branch used as baseline for screenshot comparison")).addOption(new Option("--reference-commit <string>", "Commit used as baseline for screenshot comparison")).addOption(new Option("--threshold <number>", "Sensitivity threshold between 0 and 1. The higher the threshold, the less sensitive the diff will be. Default to 0.5")).addOption(new Option("--subset", "Whether this build contains only a subset of screenshots.\nThis is useful when a build is created from an incomplete test suite where some tests are skipped.\nCan also be set via the ARGOS_SUBSET environment variable.")).action(async (directory, options) => { | ||
| program.command("upload").argument("<directory>", "Directory to upload").description("Upload screenshots to Snapvisor").option("-f, --files <patterns...>", "One or more globs matching image file paths to upload", "**/*.{png,jpg,jpeg}").option("-i, --ignore <patterns...>", "One or more globs matching image file paths to ignore (ex: \"**/*.png **/diff.jpg\")").addOption(tokenOption).addOption(projectOption).addOption(buildNameOption).addOption(new Option("--mode <string>", "Mode of comparison applied. CI for visual regression testing, monitoring for visual monitoring.").default("ci").choices(["ci", "monitoring"])).addOption(new Option("--parallel", "Enable parallel mode. Run multiple Snapvisor builds and combine them at the end.\nCan also be set via the ARGOS_PARALLEL environment variable.")).addOption(new Option("--parallel-total <number>", "The number of parallel nodes being ran")).addOption(parallelNonceOption).addOption(new Option("--parallel-index <number>", "The index of the parallel node being ran (must be at least 1)")).addOption(new Option("--reference-branch <string>", "Branch used as baseline for screenshot comparison")).addOption(new Option("--reference-commit <string>", "Commit used as baseline for screenshot comparison")).addOption(new Option("--threshold <number>", "Sensitivity threshold between 0 and 1. The higher the threshold, the less sensitive the diff will be. Default to 0.5")).addOption(new Option("--subset", "Whether this build contains only a subset of screenshots.\nThis is useful when a build is created from an incomplete test suite where some tests are skipped.\nCan also be set via the ARGOS_SUBSET environment variable.")).action(async (directory, options) => { | ||
| const spinner = ora("Uploading screenshots").start(); | ||
@@ -82,3 +82,3 @@ try { | ||
| //#region src/commands/finalize.ts | ||
| const skipIfEmptyOption = new Option("--skip-if-empty", "Create a skipped build when no parallel build matches the nonce.\nUseful when uploads are conditional (e.g. skipped by a CI cache) and Argos is a required status check: the skipped build reports a success status even though nothing was uploaded."); | ||
| const skipIfEmptyOption = new Option("--skip-if-empty", "Create a skipped build when no parallel build matches the nonce.\nUseful when uploads are conditional (e.g. skipped by a CI cache) and Snapvisor is a required status check: the skipped build reports a success status even though nothing was uploaded."); | ||
| function finalizeCommand(program) { | ||
@@ -130,3 +130,3 @@ program.command("finalize").description("Finalize pending parallel builds").addOption(parallelNonceOption).addOption(tokenOption).addOption(skipIfEmptyOption).addOption(buildNameOption).action(async (options) => { | ||
| } | ||
| /** Create an Argos API client authenticated with the given token. */ | ||
| /** Create an Snapvisor API client authenticated with the given token. */ | ||
| function createApiClient(authToken) { | ||
@@ -160,3 +160,3 @@ return createClient({ | ||
| const lines = [ | ||
| `Logged in to Argos as ${formatValue(me.user.name)}.`, | ||
| `Logged in to Snapvisor as ${formatValue(me.user.name)}.`, | ||
| `Name: ${formatValue(me.user.name)}`, | ||
@@ -382,6 +382,6 @@ `Email: ${formatValue(me.user.email)}` | ||
| * | ||
| * The authorization server is the Argos app origin; endpoints and token | ||
| * validation are implemented in the main Argos repo (`apps/backend/src/oauth`). | ||
| * The authorization server is the Snapvisor app origin; endpoints and token | ||
| * validation are implemented in the main Snapvisor repo (`apps/backend/src/oauth`). | ||
| */ | ||
| /** First-party public client id, seeded in the Argos database. */ | ||
| /** First-party public client id, seeded in the Snapvisor database. */ | ||
| const OAUTH_CLIENT_ID = "argos-cli"; | ||
@@ -572,4 +572,4 @@ /** | ||
| if (config.token) return config.token; | ||
| if (err instanceof OAuthTokenError) console.warn("Warning: Your Argos session has expired. Run `argos login` again."); | ||
| else console.warn("Warning: Could not reach Argos to refresh your session. Check your connection and try again."); | ||
| if (err instanceof OAuthTokenError) console.warn("Warning: Your Snapvisor session has expired. Run `argos login` again."); | ||
| else console.warn("Warning: Could not reach Snapvisor to refresh your session. Check your connection and try again."); | ||
| return; | ||
@@ -597,3 +597,3 @@ } | ||
| * Parse a build reference, accepting either a bare build number (`"1234"`) or a | ||
| * full Argos build URL. Returns `null` when the input is neither. | ||
| * full Snapvisor build URL. Returns `null` when the input is neither. | ||
| */ | ||
@@ -617,3 +617,3 @@ function parseBuildReference(reference) { | ||
| const parsed = parseBuildReference(reference); | ||
| if (!parsed) fail(`Build reference must be a valid build number or Argos build URL (https://app.argos-ci.com/.../builds/<number>), got "${reference}".`); | ||
| if (!parsed) fail(`Build reference must be a valid build number or Snapvisor build URL (https://app.snapvisor.io/.../builds/<number>), got "${reference}".`); | ||
| return parsed; | ||
@@ -651,3 +651,3 @@ } | ||
| const token = options.token || process.env["ARGOS_TOKEN"] || await getAccessToken(); | ||
| if (!token) fail("No Argos token found. Use --token, set ARGOS_TOKEN, or run `argos login`."); | ||
| if (!token) fail("No Snapvisor token found. Use --token, set ARGOS_TOKEN, or run `argos login`."); | ||
| return token; | ||
@@ -832,3 +832,3 @@ } | ||
| * | ||
| * The Argos API also accepts a rich-text JSON document, but that form is only | ||
| * The Snapvisor API also accepts a rich-text JSON document, but that form is only | ||
| * needed for `@mentions` (which require user ids); the CLI exposes Markdown | ||
@@ -856,3 +856,3 @@ * only, which the API converts server-side. | ||
| function registerReviewCreate(review) { | ||
| review.command("create").description("Submit a review on a build").argument("<buildReference>", "Build number or Argos build URL").addOption(new Option("--event <event>", "Review event to apply to the build").choices(Object.keys(events)).makeOptionMandatory()).option("--body <markdown>", "Markdown comment to attach to the review").option("--body-file <path>", "Read the review comment from a Markdown file").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, options) => runBuildAction({ | ||
| review.command("create").description("Submit a review on a build").argument("<buildReference>", "Build number or Snapvisor build URL").addOption(new Option("--event <event>", "Review event to apply to the build").choices(Object.keys(events)).makeOptionMandatory()).option("--body <markdown>", "Markdown comment to attach to the review").option("--body-file <path>", "Read the review comment from a Markdown file").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, options) => runBuildAction({ | ||
| reference, | ||
@@ -881,3 +881,3 @@ options, | ||
| function registerReviewDismiss(review) { | ||
| review.command("dismiss").description("Dismiss a submitted review on a build").argument("<buildReference>", "Build number or Argos build URL").argument("<reviewId>", "ID of the review to dismiss").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, reviewId, options) => runBuildAction({ | ||
| review.command("dismiss").description("Dismiss a submitted review on a build").argument("<buildReference>", "Build number or Snapvisor build URL").argument("<reviewId>", "ID of the review to dismiss").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, reviewId, options) => runBuildAction({ | ||
| reference, | ||
@@ -898,3 +898,3 @@ options, | ||
| function registerReviewList(review) { | ||
| review.command("list").description("List the reviews submitted on a build").argument("<buildReference>", "Build number or Argos build URL").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, options) => runBuildAction({ | ||
| review.command("list").description("List the reviews submitted on a build").argument("<buildReference>", "Build number or Snapvisor build URL").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, options) => runBuildAction({ | ||
| reference, | ||
@@ -959,3 +959,3 @@ options, | ||
| function registerCommentCreate(comment) { | ||
| comment.command("create").description("Post a comment (or reply) on a build").argument("<buildReference>", "Build number or Argos build URL").option("--body <markdown>", "Markdown body of the comment").option("--body-file <path>", "Read the comment body from a Markdown file").option("--reply-to <threadId>", "Reply to an existing thread (its root comment ID)").option("--diff <screenshotDiffId>", "Anchor the comment to a screenshot diff").option("--anchor-point <x,y>", "Point on the diff in normalized 0-1 coordinates (requires --diff)").option("--anchor-lines <from,to>", "1-based inclusive line range on the diff (requires --diff)").option("--draft", "Attach to your pending review instead of posting immediately").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, options) => runBuildAction({ | ||
| comment.command("create").description("Post a comment (or reply) on a build").argument("<buildReference>", "Build number or Snapvisor build URL").option("--body <markdown>", "Markdown body of the comment").option("--body-file <path>", "Read the comment body from a Markdown file").option("--reply-to <threadId>", "Reply to an existing thread (its root comment ID)").option("--diff <screenshotDiffId>", "Anchor the comment to a screenshot diff").option("--anchor-point <x,y>", "Point on the diff in normalized 0-1 coordinates (requires --diff)").option("--anchor-lines <from,to>", "1-based inclusive line range on the diff (requires --diff)").option("--draft", "Attach to your pending review instead of posting immediately").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, options) => runBuildAction({ | ||
| reference, | ||
@@ -995,3 +995,3 @@ options, | ||
| return (comment) => { | ||
| comment.command(opts.name).description(opts.description).argument("<buildReference>", "Build number or Argos build URL").argument("<commentId>", "ID of the comment").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, commentId, options) => runBuildAction({ | ||
| comment.command(opts.name).description(opts.description).argument("<buildReference>", "Build number or Snapvisor build URL").argument("<commentId>", "ID of the comment").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, commentId, options) => runBuildAction({ | ||
| reference, | ||
@@ -1026,3 +1026,3 @@ options, | ||
| function registerCommentEdit(comment) { | ||
| comment.command("edit").description("Update the body of a comment (author only)").argument("<buildReference>", "Build number or Argos build URL").argument("<commentId>", "ID of the comment").option("--body <markdown>", "New Markdown body of the comment").option("--body-file <path>", "Read the new body from a Markdown file").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, commentId, options) => runBuildAction({ | ||
| comment.command("edit").description("Update the body of a comment (author only)").argument("<buildReference>", "Build number or Snapvisor build URL").argument("<commentId>", "ID of the comment").option("--body <markdown>", "New Markdown body of the comment").option("--body-file <path>", "Read the new body from a Markdown file").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, commentId, options) => runBuildAction({ | ||
| reference, | ||
@@ -1061,3 +1061,3 @@ options, | ||
| function registerCommentList(comment) { | ||
| comment.command("list").description("List the comments on a build").argument("<buildReference>", "Build number or Argos build URL").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, options) => runBuildAction({ | ||
| comment.command("list").description("List the comments on a build").argument("<buildReference>", "Build number or Snapvisor build URL").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, options) => runBuildAction({ | ||
| reference, | ||
@@ -1077,3 +1077,3 @@ options, | ||
| function registerCommentReact(comment) { | ||
| comment.command("react").description("Add an emoji reaction to a comment").argument("<buildReference>", "Build number or Argos build URL").argument("<commentId>", "ID of the comment").argument("<emoji>", "Emoji to react with").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, commentId, emoji, options) => runBuildAction({ | ||
| comment.command("react").description("Add an emoji reaction to a comment").argument("<buildReference>", "Build number or Snapvisor build URL").argument("<commentId>", "ID of the comment").argument("<emoji>", "Emoji to react with").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, commentId, emoji, options) => runBuildAction({ | ||
| reference, | ||
@@ -1121,3 +1121,3 @@ options, | ||
| function registerCommentUnreact(comment) { | ||
| comment.command("unreact").description("Remove one of your emoji reactions from a comment").argument("<buildReference>", "Build number or Argos build URL").argument("<commentId>", "ID of the comment").argument("<emoji>", "Emoji reaction to remove").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, commentId, emoji, options) => runBuildAction({ | ||
| comment.command("unreact").description("Remove one of your emoji reactions from a comment").argument("<buildReference>", "Build number or Snapvisor build URL").argument("<commentId>", "ID of the comment").argument("<emoji>", "Emoji reaction to remove").addOption(tokenOption).addOption(projectPathOption).addOption(jsonOption).action((reference, commentId, emoji, options) => runBuildAction({ | ||
| reference, | ||
@@ -1185,3 +1185,3 @@ options, | ||
| <meta charset="UTF-8"> | ||
| <title>Argos CLI</title> | ||
| <title>Snapvisor CLI</title> | ||
| </head> | ||
@@ -1320,3 +1320,3 @@ <body> | ||
| } | ||
| console.log(successColor("Logged in to Argos successfully.")); | ||
| console.log(successColor("Logged in to Snapvisor successfully.")); | ||
| }); | ||
@@ -1335,3 +1335,3 @@ } | ||
| await clearStoredCredentials(); | ||
| console.log("Logged out from Argos."); | ||
| console.log("Logged out from Snapvisor."); | ||
| }); | ||
@@ -1338,0 +1338,0 @@ } |
+7
-7
| { | ||
| "name": "@snapvisor/cli", | ||
| "description": "Command-line (CLI) for visual testing with Snapvisor.", | ||
| "version": "6.4.1", | ||
| "version": "7.0.0", | ||
| "bin": { | ||
@@ -15,6 +15,6 @@ "snapvisor": "./bin/argos-cli.js", | ||
| "type": "git", | ||
| "url": "https://github.com/argos-ci/argos-javascript.git", | ||
| "directory": "packages/core" | ||
| "url": "git+https://github.com/DevinoSolutions/snapvisor-js.git", | ||
| "directory": "packages/cli" | ||
| }, | ||
| "homepage": "https://argos-ci.com/docs/reference/argos-command-line-interface-cli", | ||
| "homepage": "https://snapvisor.io/docs", | ||
| "bugs": { | ||
@@ -39,4 +39,4 @@ "url": "https://github.com/argos-ci/argos-javascript/issues" | ||
| "dependencies": { | ||
| "@snapvisor/api-client": "0.26.0", | ||
| "@snapvisor/core": "6.6.2", | ||
| "@snapvisor/api-client": "0.27.0", | ||
| "@snapvisor/core": "7.0.0", | ||
| "commander": "^15.0.0", | ||
@@ -60,3 +60,3 @@ "open": "^11.0.0", | ||
| }, | ||
| "gitHead": "7c74326b53f6f513ac4087385b88e8fbd7e92eac" | ||
| "gitHead": "b27308a53667724cc3c4f3e5eb7811bce3321f15" | ||
| } |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
62472
0.01%1513
0.07%+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
Updated
Updated