From 2e9680a7fc03b60d6d5323c53a3f4c1a7c87e635 Mon Sep 17 00:00:00 2001 From: ehl-jf Date: Thu, 21 May 2026 16:27:36 +0200 Subject: [PATCH] JGC-473 - Add AI-agent help text to security commands Populate components.Command.AIDescription on commands. The new field (added in jfrog-cli-core JGC-473) makes the conversion layer render agent-oriented text when JFROG_CLI_AI_HELP is truthy or an AI agent is auto-detected. Empty AIDescription falls back to Description, so command output is unchanged in human mode. Scope: 15 help.go files + 26 components.Command literals across cli/scancommands.go, cli/gitcommands.go, cli/xraycommands.go. Hidden commands intentionally included (see PR description). Targets the dev branch. TEMPORARY go.mod pin: the require for github.com/jfrog/jfrog-cli-core/v2 points at JGC-473-devbase (commit d507b5c6) - a coordination branch that cherry-picks JGC-473 onto core's pinned commit 908527b4 (the last commit before core master removed yarn.IsVersionSupported and IsInstalledYarnVersionSupported, which downstream callers in jfrog-cli-artifactory still depend on). This require MUST be updated to the merged master commit's pseudo-version after the jfrog-cli-core JGC-473 PR merges. Do not merge this PR until the require is re-pinned. --- cli/docs/auditspecific/help.go | 41 ++++++ cli/docs/enrich/help.go | 25 ++++ cli/docs/git/audit/help.go | 27 ++++ cli/docs/git/contributors/help.go | 28 ++++ cli/docs/maliciousscan/help.go | 25 ++++ cli/docs/mcp/help.go | 24 ++++ cli/docs/sastserver/help.go | 24 ++++ cli/docs/scan/audit/help.go | 30 +++++ cli/docs/scan/buildscan/help.go | 28 ++++ cli/docs/scan/curation/help.go | 29 +++++ cli/docs/scan/dockerscan/help.go | 27 ++++ cli/docs/scan/scan/help.go | 29 +++++ cli/docs/upload/help.go | 23 ++++ cli/docs/xray/curl/help.go | 24 ++++ cli/docs/xray/offlineupdate/help.go | 27 ++++ cli/gitcommands.go | 26 ++-- cli/scancommands.go | 190 +++++++++++++++------------- cli/xraycommands.go | 80 ++++++------ go.mod | 28 ++-- go.sum | 60 ++++----- 20 files changed, 616 insertions(+), 179 deletions(-) diff --git a/cli/docs/auditspecific/help.go b/cli/docs/auditspecific/help.go index 9a2e99961..273a639ba 100644 --- a/cli/docs/auditspecific/help.go +++ b/cli/docs/auditspecific/help.go @@ -6,26 +6,67 @@ import "fmt" const descFormat = "Execute an audit %s command, using the configured Xray details." +const aiDescFormat = `Run a tech-restricted audit limited to %s dependencies. Deprecated: prefer ` + "`jf audit --%s`" + ` over this dedicated subcommand. Use only when integrating with legacy scripts that still call the per-technology audit command. + +When to use: +- Maintaining older CI scripts that have not yet migrated to the unified jf audit interface. + +Prerequisites: +- Configured JFrog Platform server (jf c add) with Xray entitlement. +- The %s toolchain installed and reachable on PATH. + +Common patterns: + $ jf audit --%s + +Gotchas: +- This command emits a deprecation warning at runtime and will be removed in the next CLI major version. + +Related: jf audit` + func GetGoDescription() string { return fmt.Sprintf(descFormat, "Go") } +func GetGoAIDescription() string { + return fmt.Sprintf(aiDescFormat, "Go", "go", "Go", "go") +} + func GetGradleDescription() string { return fmt.Sprintf(descFormat, "Gradle") } +func GetGradleAIDescription() string { + return fmt.Sprintf(aiDescFormat, "Gradle", "gradle", "Gradle", "gradle") +} + func GetMvnDescription() string { return fmt.Sprintf(descFormat, "Maven") } +func GetMvnAIDescription() string { + return fmt.Sprintf(aiDescFormat, "Maven", "mvn", "Maven", "mvn") +} + func GetNpmDescription() string { return fmt.Sprintf(descFormat, "Npm") } +func GetNpmAIDescription() string { + return fmt.Sprintf(aiDescFormat, "npm", "npm", "Node.js/npm", "npm") +} + func GetPipDescription() string { return fmt.Sprintf(descFormat, "Pip") } +func GetPipAIDescription() string { + return fmt.Sprintf(aiDescFormat, "Pip (Python)", "pip", "Python with pip", "pip") +} + func GetPipenvDescription() string { return fmt.Sprintf(descFormat, "Pipenv") } + +func GetPipenvAIDescription() string { + return fmt.Sprintf(aiDescFormat, "Pipenv (Python)", "pipenv", "Python with Pipenv", "pipenv") +} diff --git a/cli/docs/enrich/help.go b/cli/docs/enrich/help.go index fa06653a9..89b0bcdec 100644 --- a/cli/docs/enrich/help.go +++ b/cli/docs/enrich/help.go @@ -8,6 +8,31 @@ func GetDescription() string { return "Enrich sbom format JSON located on the local file-system with Xray." } +func GetAIDescription() string { + return `Send an existing CycloneDX SBOM JSON file to Xray for enrichment with vulnerability and license metadata. Use when an agent has produced an SBOM from another tool (Syft, CDXgen, Maven, etc.) and wants Xray's intelligence layered on top without rerunning a full dependency resolution. + +When to use: +- Annotate a third-party-generated CycloneDX SBOM with Xray vulnerability and license data. +- Add Xray context to SBOMs produced earlier in a CI pipeline. +- Bridge external SBOM tooling with the JFrog Platform. + +Prerequisites: +- A configured JFrog Platform server (jf c add) with Xray entitlement. +- An input CycloneDX SBOM JSON file on the local filesystem. +- The SBOM must contain components Xray can resolve (purl identifiers). + +Common patterns: + $ jf sbom-enrich path/to/sbom.cdx.json + $ jf se path/to/sbom.cdx.json --threads=4 + +Gotchas: +- Input must be CycloneDX JSON; SPDX or other formats are not accepted. +- Components without a resolvable purl will not be enriched. +- The command requires the file-path argument; no spec-based input is supported. + +Related: jf audit, jf scan, jf upload-cdx` +} + func GetArguments() []components.Argument { return []components.Argument{{Name: "File path", Description: `Specifies the local file system path of the JSON to be scanned.`}} } diff --git a/cli/docs/git/audit/help.go b/cli/docs/git/audit/help.go index ff04d8e47..37968d38a 100644 --- a/cli/docs/git/audit/help.go +++ b/cli/docs/git/audit/help.go @@ -3,3 +3,30 @@ package audit func GetDescription() string { return "Audit your local git repository project for security issues." } + +func GetAIDescription() string { + return `Audit a local Git repository for security issues by combining SCA dependency scanning with JAS scans (SAST, Secrets, IaC, Applicability) and correlating findings to Git/VCS metadata (remote URL, branch, commit) so results surface in the Platform under the right Git context. Use when an agent wants jf audit results tagged with repository identity for cross-PR/cross-branch tracking. + +When to use: +- Scan a working tree the same way a PR/CI bot would, with Git context attached. +- Aggregate audit findings per repository in the JFrog Platform UI. +- Run a snippet-aware SAST scan on changed files. + +Prerequisites: +- Configured JFrog Platform server (jf c add) with Xray (and JAS for advanced scans). +- The current working directory must be inside a Git repository (with a remote and at least one commit). +- analyzerManager binary (auto-installed) for JAS scans. + +Common patterns: + $ jf git audit + $ jf git audit --format=sarif --output-dir=./results + $ jf git audit --watches=my-watch --fail=true + $ jf git audit --sast --secrets --threads=4 + +Gotchas: +- Requires a Git repo with valid remote metadata; otherwise context resolution fails. +- The command is currently hidden from top-level help. +- Without --watches or --project, only general vulnerabilities are reported. + +Related: jf audit, jf scan, jf git count-contributors` +} diff --git a/cli/docs/git/contributors/help.go b/cli/docs/git/contributors/help.go index 1cfc4fbea..10e761796 100644 --- a/cli/docs/git/contributors/help.go +++ b/cli/docs/git/contributors/help.go @@ -3,3 +3,31 @@ package contributors func GetContContributorsDescription() string { return "List all GIT providers' contributing developers." } + +func GetContContributorsAIDescription() string { + return `Count unique contributing developers across one or more Git repositories on GitHub, GitLab, or Bitbucket Server over a configurable time window. Use when an agent needs developer-count data for JFrog licensing/seat reporting or compliance audits. + +When to use: +- Compute the developer-seat count for a JFrog license review. +- Produce a per-repo or per-organization contributor report for compliance. +- Aggregate counts across many repositories from an input file. + +Prerequisites: +- A personal access token for the SCM provider with read access to the target repos. +- Either --input-file pointing to a repo list JSON, or the full set of mandatory flags: --scm-type, --token (or env var), --owner, --scm-api-url. +- Supported --scm-type values: github, gitlab, bitbucketServer. +- Optional env vars for tokens: JFROG_CLI_GITHUB_TOKEN, JFROG_CLI_GITLAB_TOKEN, JFROG_CLI_BITBUCKET_TOKEN, or the generic JFROG_CLI_GIT_TOKEN. + +Common patterns: + $ jf git count-contributors --scm-type=github --token=$GITHUB_TOKEN --owner=my-org --scm-api-url=https://api.github.com + $ jf git cc --scm-type=gitlab --owner=my-group --scm-api-url=https://gitlab.com/api/v4 --repo-name="repo-a;repo-b" + $ jf git count-contributors --input-file=repos.json --months=12 --detailed-summary + +Gotchas: +- --months must be a positive integer; defaults to a built-in window if omitted. +- When --input-file is used, the other mandatory flags are ignored. +- --repo-name is a semicolon-separated list, not comma-separated. +- The command is currently hidden from top-level help. + +Related: jf git audit` +} diff --git a/cli/docs/maliciousscan/help.go b/cli/docs/maliciousscan/help.go index acc4d674d..15f3abd0a 100644 --- a/cli/docs/maliciousscan/help.go +++ b/cli/docs/maliciousscan/help.go @@ -8,6 +8,31 @@ func GetDescription() string { return "[Beta] Scan malicious models (pickle files, etc.) located in the working directory." } +func GetAIDescription() string { + return `[Beta] Scan the working directory for malicious ML model artifacts (Python pickle files, serialized models) using the JAS analyzerManager. Use when an agent ingests untrusted models from public registries (HuggingFace, model zoos) and needs to detect embedded code-execution payloads before loading them. + +When to use: +- Vet downloaded .pkl, .pt, .pth, .joblib, .h5, .pb model files before loading into a Python runtime. +- Add a malicious-model gate to ML supply-chain pipelines. + +Prerequisites: +- A configured JFrog Platform server (jf c add) with JFrog Advanced Security entitlement. +- The analyzerManager binary (auto-installed); pass --analyzer-manager-path to override. +- Run from the directory containing the model files, or pass --working-dirs. + +Common patterns: + $ jf malicious-scan + $ jf ms --working-dirs=./models --format=sarif + $ jf malicious-scan --min-severity=High --project=my-project + +Gotchas: +- Beta surface; flags and output schema may change. +- Only known malicious-model patterns are detected; this is not a general SCA or SAST scan. +- Without --working-dirs, only the current directory is scanned. + +Related: jf audit, jf scan` +} + func GetArguments() []components.Argument { return []components.Argument{} } diff --git a/cli/docs/mcp/help.go b/cli/docs/mcp/help.go index 020109edd..dba01593d 100644 --- a/cli/docs/mcp/help.go +++ b/cli/docs/mcp/help.go @@ -8,6 +8,30 @@ func GetDescription() string { return "Runs a local source code analysis as a local MCP server, allowing access to tools which reflect source code analysis" } +func GetAIDescription() string { + return `Launch a local Model Context Protocol (MCP) server that exposes JFrog source-code analysis (SCA + JAS scans) as MCP tools over stdio. Use when an AI coding agent needs interactive, tool-callable access to scan results on the developer's machine; the agent (Claude Code, Cursor, etc.) starts this process and communicates via JSON-RPC on stdin/stdout. + +When to use: +- Wire JFrog security scanning into an MCP-aware AI client as a local tool provider. +- Provide an agent with on-demand vulnerability, secret, SAST, and IaC scans of the user's codebase. + +Prerequisites: +- A configured JFrog Platform server (jf c add) with Xray and JFrog Advanced Security entitlements. +- analyzerManager binary available (auto-installed on first run). +- The host process must be an MCP client capable of speaking JSON-RPC over the spawned process's stdio. + +Common patterns: + $ jf source-mcp /path/to/project + $ jf source-mcp ./ + +Gotchas: +- This command is intended to be spawned by an MCP client, not run interactively in a terminal; stdout is reserved for JSON-RPC frames. +- Logs go to stderr; do not pipe stderr into the MCP transport. +- The command is currently hidden from top-level help while the integration matures. + +Related: jf audit, jf scan, jf sast-server` +} + func GetArguments() []components.Argument { return []components.Argument{{Name: "Source path", Description: `Specifies the local file system path of source code to analyze.`}} } diff --git a/cli/docs/sastserver/help.go b/cli/docs/sastserver/help.go index 459a98b05..fc654c82b 100644 --- a/cli/docs/sastserver/help.go +++ b/cli/docs/sastserver/help.go @@ -3,3 +3,27 @@ package sast_server func GetDescription() string { return "Runs a local source code analysis as a local SAST server, allowing access to tools which reflect source code analysis" } + +func GetAIDescription() string { + return `Start a local HTTP server that exposes JFrog SAST source-code analysis endpoints, enabling other tools (IDE plugins, AI agents, custom integrations) to request scans over HTTP instead of spawning the CLI per call. Use when a long-running client needs to invoke SAST repeatedly against changing files. + +When to use: +- Back an IDE extension or AI agent with a persistent local SAST endpoint. +- Avoid analyzerManager startup overhead by serving multiple scan requests from one process. + +Prerequisites: +- A configured JFrog Platform server (jf c add) with JFrog Advanced Security entitlement. +- analyzerManager binary available (auto-installed on first run). +- A free TCP port for the server to bind to (passed via --port). + +Common patterns: + $ jf sast-server --port=8080 + $ jf sast-server --port=9000 + +Gotchas: +- --port is mandatory; the command exits with an error if it is omitted. +- The server binds only to localhost; it is not intended for remote access. +- The command is currently hidden from top-level help. + +Related: jf audit, jf source-mcp` +} diff --git a/cli/docs/scan/audit/help.go b/cli/docs/scan/audit/help.go index e5ff1a9cd..83a392836 100644 --- a/cli/docs/scan/audit/help.go +++ b/cli/docs/scan/audit/help.go @@ -3,3 +3,33 @@ package audit func GetDescription() string { return "Scan your source code on demand to detect CVEs, license issues, misconfigurations, secrets, and other risks, with results shown in the terminal and in the JFrog Platform." } + +func GetAIDescription() string { + return `Run a local source-code security audit against the JFrog Platform (Xray + JAS). Combines Software Composition Analysis (SCA) on the project's dependency graph with optional JFrog Advanced Security scans: Applicability/Contextual Analysis, IAC, Secrets Detection, SAST, and Malicious Code. Use this when an agent needs to assess a checked-out project before committing, opening a PR, or releasing. + +When to use: +- Inspect a local repo for CVEs, license violations, IaC misconfigurations, leaked secrets, or SAST findings. +- Gate a build by failing on policy violations from configured watches or a project key. +- Produce SARIF or SBOM (CycloneDX) output for IDE/CI consumption. + +Prerequisites: +- A configured JFrog Platform server (jf c add) with Xray entitlement. +- For JAS scans (SAST/IAC/Secrets/Applicability): a JFrog Advanced Security subscription. +- The auto-installed analyzerManager binary; pass --analyzer-manager-path to override or --skip-auto-install to use a pre-staged copy. +- Package-manager tooling (e.g., mvn, gradle, npm, pip, go) must be on PATH for tech-specific dependency resolution. + +Common patterns: + $ jf audit + $ jf audit --format=sarif --output-dir=./scan-results + $ jf audit --watches=my-watch1,my-watch2 --fail=true + $ jf audit --project=my-project --vuln --licenses + $ jf audit --sca --sast --secrets --working-dirs=services/api,services/web + +Gotchas: +- Without --watches, --project, or --repo-path, no policy violations are evaluated; the command only reports raw vulnerabilities. +- --fail defaults to true: a CI run will exit non-zero on findings unless explicitly set to false. +- Technology flags (--mvn, --gradle, --npm, --go, --pip, --pipenv, --nuget, --yarn) restrict the scan; otherwise auto-detection runs every detected stack. +- --add-sast-rules requires --sast to be active. + +Related: jf scan, jf build-scan, jf curation-audit, jf sbom-enrich` +} diff --git a/cli/docs/scan/buildscan/help.go b/cli/docs/scan/buildscan/help.go index a8e5a7501..d9033520a 100644 --- a/cli/docs/scan/buildscan/help.go +++ b/cli/docs/scan/buildscan/help.go @@ -6,6 +6,34 @@ func GetDescription() string { return "Scan a published build-info with Xray." } +func GetAIDescription() string { + return `Trigger an Xray scan against an already-published build-info record in Artifactory. Use when an agent has run jf rt build-publish for a CI build and wants to fetch the Xray verdict (vulnerabilities and violations) for that exact build/number pair before promoting or distributing it. + +When to use: +- Gate promotion/distribution on a build's Xray scan results. +- Wait for Xray to finish scanning a freshly published build and surface findings. +- Re-scan an existing build after policy or DB updates. + +Prerequisites: +- A configured JFrog Platform server (jf c add) with Xray entitlement. +- The build-info must already be published to Artifactory (jf rt build-publish). +- For violations: the build must be associated with a project key or matched by Xray watches. + +Common patterns: + $ jf build-scan my-build 42 + $ jf bs my-build 42 --fail=true --format=sarif + $ jf build-scan my-build 42 --project=my-project --vuln --violations + $ jf build-scan my-build 42 --rescan=true --extended-table + +Gotchas: +- If build name/number are omitted, values from the build configuration env or jfrog-cli build context are used. +- --fail defaults to true; set --fail=false to inspect results without exiting non-zero. +- Xray may need time to index the build; --trigger-scan-retries controls how long the CLI waits. +- Without project/watches, no violations are produced even if --violations is set. + +Related: jf audit, jf scan, jf rt build-publish` +} + func GetArguments() []components.Argument { return []components.Argument{ { diff --git a/cli/docs/scan/curation/help.go b/cli/docs/scan/curation/help.go index 42521f783..182736e7e 100644 --- a/cli/docs/scan/curation/help.go +++ b/cli/docs/scan/curation/help.go @@ -3,3 +3,32 @@ package curation func GetDescription() string { return "Audit your project dependencies for their curation status." } + +func GetAIDescription() string { + return `Inspect the project's package-manager dependencies against the JFrog Curation service and report which packages were blocked by curation policy along with the matching policies. Use when an agent suspects a package install failure was due to curation, or wants a preemptive curation report. + +When to use: +- Diagnose 403/forbidden errors during npm/pip/maven/gradle/nuget/go install steps in a curation-enabled remote. +- Produce a curation-status report (blocked packages and policies) for the current project. +- Run automatically after a failed install via the JFROG_CLI_SKIP_CURATION_AFTER_FAILURE workflow. + +Prerequisites: +- A configured JFrog Platform server (jf c add) with JFrog Curation entitlement. +- Project must use a supported package manager (npm, yarn, pip, maven, gradle, nuget, go) resolved through a curation-configured remote. +- The package manager and its lockfile must be present in the working directory. + +Common patterns: + $ jf curation-audit + $ jf ca --working-dirs=services/api,services/web + $ jf curation-audit --format=json --threads=4 + $ jf curation-audit --requirements-file=requirements-dev.txt + $ jf curation-audit --docker-image=my-image:tag + +Gotchas: +- The user/token must be entitled for Curation; otherwise the command exits with an entitlement notice. +- Requires the project's package manager binary on PATH (npm, mvn, etc.). +- Run from the project root or pass --working-dirs. +- For Maven multi-module: --use-wrapper if mvnw is used. + +Related: jf audit, jf rt npm-install, jf rt mvn` +} diff --git a/cli/docs/scan/dockerscan/help.go b/cli/docs/scan/dockerscan/help.go index 9b50851dd..48c6fe4f7 100644 --- a/cli/docs/scan/dockerscan/help.go +++ b/cli/docs/scan/dockerscan/help.go @@ -6,6 +6,33 @@ func GetDescription() string { return "Scan local docker image using the docker client and Xray." } +func GetAIDescription() string { + return `Scan a local Docker image (resolved via the local docker daemon) against Xray and JAS for vulnerabilities, license issues, secrets, and applicability. Invoked as the sub-command of jf docker. Use when an agent has built or pulled an image and wants Xray's verdict on it before pushing or running. + +When to use: +- Inspect a freshly built image (e.g., from a Dockerfile) before pushing to a registry. +- Scan a third-party image pulled to the local daemon. +- Generate SARIF or CycloneDX for CI gating of container builds. + +Prerequisites: +- Configured JFrog Platform server (jf c add) with Xray entitlement; JAS scans require Advanced Security. +- A running Docker daemon and the image present locally (docker images shows it). +- For applicability/JAS layers: the analyzerManager binary (auto-installed). + +Common patterns: + $ jf docker scan my-image:latest + $ jf docker scan my-image:1.2.3 --format=sarif --fail=true + $ jf docker scan my-registry/my-image:tag --watches=prod-watch --vuln + $ jf docker scan my-image:tag --bypass-archive-limits --threads=4 + +Gotchas: +- The image must already be loaded into the local Docker daemon; this command does not pull from a registry. +- --bypass-archive-limits may be required for large layers. +- Without --watches or --project, only general vulnerabilities are reported (no violations). + +Related: jf scan, jf audit, jf build-scan` +} + func GetArguments() []components.Argument { return []components.Argument{ { diff --git a/cli/docs/scan/scan/help.go b/cli/docs/scan/scan/help.go index f4de68b02..656aed78c 100644 --- a/cli/docs/scan/scan/help.go +++ b/cli/docs/scan/scan/help.go @@ -9,6 +9,35 @@ func GetDescription() string { return "Scan files located on the local file-system with Xray." } +func GetAIDescription() string { + return `Scan local files or archives against Xray (binary scan) to detect vulnerabilities and license issues without resolving a project's dependency graph. Use when an agent already has a built artifact (tar.gz, jar, zip, container layer, package file) and needs an Xray verdict before publishing or distributing it. + +When to use: +- Inspect already-built artifacts, third-party binaries, or downloaded packages before promotion. +- Scan a directory tree of release candidates using a file spec or wildcard pattern. +- Produce SARIF, JSON, table, or CycloneDX output for CI gating. + +Prerequisites: +- Configured JFrog Platform server (jf c add) with Xray entitlement. +- Either a positional source-pattern argument OR --spec pointing to a file-spec JSON. +- For policy-based gating: --watches, --project, or --repo-path mapped to Xray watches. + +Common patterns: + $ jf scan path/to/file.tgz + $ jf scan "build/libs/*.jar" --format=sarif + $ jf scan ./dist --recursive --min-severity=High --fail=true + $ jf scan --spec=scan-spec.json --threads=4 + $ jf scan ./artifact.zip --watches=prod-watch --project=my-project --vuln + +Gotchas: +- Without --watches, --project, or --repo-path, vulnerabilities are included by default but no violations are evaluated. +- Wildcards must be quoted to avoid shell expansion. +- --bypass-archive-limits is required for archives that exceed Xray's default size limit. +- --fail defaults to true and exits non-zero on findings. + +Related: jf audit, jf build-scan, jf docker scan, jf sbom-enrich` +} + func GetArguments() []components.Argument { return []components.Argument{{Name: "source pattern", ReplaceWithFlag: docs.SpecFlag, Description: `Specifies the local file system path of the files to be scanned. You can specify multiple files by using wildcards, Ant pattern or a regular expression. diff --git a/cli/docs/upload/help.go b/cli/docs/upload/help.go index cc2765353..dcc88fbdf 100644 --- a/cli/docs/upload/help.go +++ b/cli/docs/upload/help.go @@ -6,6 +6,29 @@ func GetDescription() string { return "Upload a CycloneDX SBOM file to a JFrog repository." } +func GetAIDescription() string { + return `Upload a CycloneDX SBOM (.cdx.json) to a target JFrog Artifactory repository so it can be associated with a build/project and indexed by Xray. Use when an agent has generated an SBOM (via jf audit, jf sbom-enrich, or an external tool) and needs to persist it on the platform. + +When to use: +- Persist a generated SBOM for downstream Xray indexing or compliance reporting. +- Attach an SBOM to a project/build artifact pipeline. + +Prerequisites: +- Configured JFrog Platform server (jf c add) with write permission to the target repo. +- Input file must have a .cdx.json extension and contain a valid CycloneDX JSON document. +- A target repository (--repo-path) that accepts SBOM uploads. + +Common patterns: + $ jf upload-cdx ./build/bom.cdx.json --repo-path=my-repo + $ jf ucdx ./bom.cdx.json --repo-path=sbom-repo --project=my-project + +Gotchas: +- File extension must be exactly .cdx.json; other extensions are rejected. +- The command is currently hidden from top-level help while the upload flow stabilizes. + +Related: jf sbom-enrich, jf audit, jf rt upload` +} + func GetArguments() []components.Argument { return []components.Argument{{Name: "cycloneDx file path", Description: "Path to the JSON CycloneDX file to upload. (must be a '.cdx.json' extension)"}} } diff --git a/cli/docs/xray/curl/help.go b/cli/docs/xray/curl/help.go index ebba48062..da1284f17 100644 --- a/cli/docs/xray/curl/help.go +++ b/cli/docs/xray/curl/help.go @@ -6,6 +6,30 @@ func GetDescription() string { return "Execute a cURL command, using the configured Xray details." } +func GetAIDescription() string { + return `Issue an arbitrary HTTP request to the Xray REST API using credentials from the active jf config, much like curl but with the Xray URL and auth headers injected automatically. Use when an agent needs to call Xray endpoints that have no dedicated CLI wrapper. + +When to use: +- Call Xray admin or reporting endpoints not yet exposed via dedicated subcommands. +- Quickly script Xray API calls without manually assembling auth headers. + +Prerequisites: +- A configured JFrog Platform server (jf c add) whose Xray URL is set; the command errors out otherwise. +- The active user/token must have permission for the targeted endpoint. + +Common patterns: + $ jf xr curl -XGET /api/v1/system/ping + $ jf xr cl -XGET /api/v2/policies + $ jf xr curl -XPOST /api/v1/binMgr/search -H 'Content-Type: application/json' -d '{"sha1":"abc..."}' + +Gotchas: +- Paths are relative to the Xray base URL; do not prepend the full host. +- The leading -- separator may be required to stop the CLI from intercepting curl flags. +- The configured server must have a non-empty XrayUrl; older configs without an Xray URL fail with a clear error. + +Related: jf rt curl, jf c show, jf xr offline-update` +} + func GetArguments() []components.Argument { return []components.Argument{{Name: "curl command", Description: "cURL command to run."}} } diff --git a/cli/docs/xray/offlineupdate/help.go b/cli/docs/xray/offlineupdate/help.go index f37f8f848..2aad4bd01 100644 --- a/cli/docs/xray/offlineupdate/help.go +++ b/cli/docs/xray/offlineupdate/help.go @@ -3,3 +3,30 @@ package offlineupdate func GetDescription() string { return "Download Xray offline updates." } + +func GetAIDescription() string { + return `Download Xray vulnerability/component database updates as offline bundles so they can be loaded into an air-gapped Xray instance. Use when an agent operates in (or supplies updates to) a network-isolated environment that cannot reach the JFrog update servers directly. + +When to use: +- Refresh an air-gapped Xray's vulnerability database. +- Periodically mirror Xray updates to an internal artifact store. +- Stage a one-shot update window between two dates. + +Prerequisites: +- A valid Xray offline-update license ID (--license-id is mandatory). +- Network access to https://updates.jfrog.io from the host running the command. +- Sufficient local disk space at --target for the downloaded bundle. + +Common patterns: + $ jf xr offline-update --license-id=ABC-123 --version=3 + $ jf xr ou --license-id=ABC-123 --stream=core --periodic --target=./xray-updates + $ jf xr offline-update --license-id=ABC-123 --from=2024-01-01 --to=2024-02-01 + +Gotchas: +- --license-id is required; the command exits with an error if omitted. +- --periodic is only valid together with --stream. +- --from and --to must both be set when using V1 date-range mode and use YYYY-MM-DD format. +- Stream values are validated; an invalid --stream value rejects the call. + +Related: jf xr curl, jf c show` +} diff --git a/cli/gitcommands.go b/cli/gitcommands.go index 19883685b..ff3e44e54 100644 --- a/cli/gitcommands.go +++ b/cli/gitcommands.go @@ -22,21 +22,23 @@ import ( func getGitNameSpaceCommands() []components.Command { return []components.Command{ { - Name: "audit", - Aliases: []string{"a"}, - Description: gitAuditDocs.GetDescription(), - Flags: flags.GetCommandFlags(flags.GitAudit), - Hidden: true, - Action: GitAuditCmd, + Name: "audit", + Aliases: []string{"a"}, + Description: gitAuditDocs.GetDescription(), + AIDescription: gitAuditDocs.GetAIDescription(), + Flags: flags.GetCommandFlags(flags.GitAudit), + Hidden: true, + Action: GitAuditCmd, }, // TODO: Move cc cmd to Frogbot/Script { - Name: "count-contributors", - Aliases: []string{"cc"}, - Flags: flags.GetCommandFlags(flags.GitCountContributors), - Description: gitContributorsDocs.GetContContributorsDescription(), - Hidden: true, - Action: GitCountContributorsCmd, + Name: "count-contributors", + Aliases: []string{"cc"}, + Flags: flags.GetCommandFlags(flags.GitCountContributors), + Description: gitContributorsDocs.GetContContributorsDescription(), + AIDescription: gitContributorsDocs.GetContContributorsAIDescription(), + Hidden: true, + Action: GitCountContributorsCmd, }, } } diff --git a/cli/scancommands.go b/cli/scancommands.go index f74abfa44..98c28fee6 100644 --- a/cli/scancommands.go +++ b/cli/scancommands.go @@ -62,146 +62,162 @@ const SkipCurationAfterFailureEnv = "JFROG_CLI_SKIP_CURATION_AFTER_FAILURE" func getAuditAndScansCommands() []components.Command { return []components.Command{ { - Name: "scan", - Aliases: []string{"s"}, - Flags: flags.GetCommandFlags(flags.XrScan), - Description: scanDocs.GetDescription(), - Arguments: scanDocs.GetArguments(), - Category: securityCategory, - Action: ScanCmd, + Name: "scan", + Aliases: []string{"s"}, + Flags: flags.GetCommandFlags(flags.XrScan), + Description: scanDocs.GetDescription(), + AIDescription: scanDocs.GetAIDescription(), + Arguments: scanDocs.GetArguments(), + Category: securityCategory, + Action: ScanCmd, }, { - Name: "sbom-enrich", - Aliases: []string{"se"}, - Flags: flags.GetCommandFlags(flags.Enrich), - Description: enrichDocs.GetDescription(), - Arguments: enrichDocs.GetArguments(), - Category: securityCategory, - Action: EnrichCmd, + Name: "sbom-enrich", + Aliases: []string{"se"}, + Flags: flags.GetCommandFlags(flags.Enrich), + Description: enrichDocs.GetDescription(), + AIDescription: enrichDocs.GetAIDescription(), + Arguments: enrichDocs.GetArguments(), + Category: securityCategory, + Action: EnrichCmd, }, { - Name: "malicious-scan", - Aliases: []string{"ms"}, - Flags: flags.GetCommandFlags(flags.MaliciousScan), - Description: maliciousScanDocs.GetDescription(), - Arguments: maliciousScanDocs.GetArguments(), - Category: securityCategory, - Action: MaliciousScanCmd, + Name: "malicious-scan", + Aliases: []string{"ms"}, + Flags: flags.GetCommandFlags(flags.MaliciousScan), + Description: maliciousScanDocs.GetDescription(), + AIDescription: maliciousScanDocs.GetAIDescription(), + Arguments: maliciousScanDocs.GetArguments(), + Category: securityCategory, + Action: MaliciousScanCmd, }, { - Name: "build-scan", - Aliases: []string{"bs"}, - Flags: flags.GetCommandFlags(flags.BuildScan), - Description: buildScanDocs.GetDescription(), - Arguments: buildScanDocs.GetArguments(), - Category: securityCategory, - Action: BuildScan, + Name: "build-scan", + Aliases: []string{"bs"}, + Flags: flags.GetCommandFlags(flags.BuildScan), + Description: buildScanDocs.GetDescription(), + AIDescription: buildScanDocs.GetAIDescription(), + Arguments: buildScanDocs.GetArguments(), + Category: securityCategory, + Action: BuildScan, }, { // this command is hidden and have no logic, it will be run to provide 'help' as a part of the buildtools CLI for 'docker' commands. ('jf docker scan') // CLI buildtools will run the command if requested: https://github.com/jfrog/jfrog-cli/blob/v2/buildtools/cli.go - Name: DockerScanCmdHiddenName, - Flags: flags.GetCommandFlags(flags.DockerScan), - Description: dockerScanDocs.GetDescription(), - Arguments: dockerScanDocs.GetArguments(), - UsageOptions: &components.UsageOptions{CommandName: "docker scan"}, - Hidden: true, + Name: DockerScanCmdHiddenName, + Flags: flags.GetCommandFlags(flags.DockerScan), + Description: dockerScanDocs.GetDescription(), + AIDescription: dockerScanDocs.GetAIDescription(), + Arguments: dockerScanDocs.GetArguments(), + UsageOptions: &components.UsageOptions{CommandName: "docker scan"}, + Hidden: true, }, { - Name: "audit", - Aliases: []string{"aud"}, - Flags: flags.GetCommandFlags(flags.Audit), - Description: auditDocs.GetDescription(), - Category: securityCategory, - Action: AuditCmd, + Name: "audit", + Aliases: []string{"aud"}, + Flags: flags.GetCommandFlags(flags.Audit), + Description: auditDocs.GetDescription(), + AIDescription: auditDocs.GetAIDescription(), + Category: securityCategory, + Action: AuditCmd, }, { - Name: "curation-audit", - Aliases: []string{"ca"}, - Flags: flags.GetCommandFlags(flags.CurationAudit), - Description: curationDocs.GetDescription(), - Category: securityCategory, - Action: CurationCmd, + Name: "curation-audit", + Aliases: []string{"ca"}, + Flags: flags.GetCommandFlags(flags.CurationAudit), + Description: curationDocs.GetDescription(), + AIDescription: curationDocs.GetAIDescription(), + Category: securityCategory, + Action: CurationCmd, }, { - Name: "source-mcp", - Description: mcpDocs.GetDescription(), - Action: SourceMcpCmd, - Hidden: true, + Name: "source-mcp", + Description: mcpDocs.GetDescription(), + AIDescription: mcpDocs.GetAIDescription(), + Action: SourceMcpCmd, + Hidden: true, }, { - Name: "sast-server", - Description: sastServerDocs.GetDescription(), - Flags: flags.GetCommandFlags(flags.SastServer), - Action: SastServerCmd, - Hidden: true, + Name: "sast-server", + Description: sastServerDocs.GetDescription(), + AIDescription: sastServerDocs.GetAIDescription(), + Flags: flags.GetCommandFlags(flags.SastServer), + Action: SastServerCmd, + Hidden: true, }, { - Name: flags.UploadCdx, - Aliases: []string{"ucdx"}, - Flags: flags.GetCommandFlags(flags.UploadCdx), - Arguments: uploadCdxDocs.GetArguments(), - Description: uploadCdxDocs.GetDescription(), - Category: securityCategory, - Action: UploadCdxCmd, - Hidden: true, + Name: flags.UploadCdx, + Aliases: []string{"ucdx"}, + Flags: flags.GetCommandFlags(flags.UploadCdx), + Arguments: uploadCdxDocs.GetArguments(), + Description: uploadCdxDocs.GetDescription(), + AIDescription: uploadCdxDocs.GetAIDescription(), + Category: securityCategory, + Action: UploadCdxCmd, + Hidden: true, }, // TODO: Deprecated commands (remove at next CLI major version) { - Name: "audit-mvn", - Aliases: []string{"am"}, - Flags: flags.GetCommandFlags(flags.AuditMvn), - Description: auditSpecificDocs.GetMvnDescription(), + Name: "audit-mvn", + Aliases: []string{"am"}, + Flags: flags.GetCommandFlags(flags.AuditMvn), + Description: auditSpecificDocs.GetMvnDescription(), + AIDescription: auditSpecificDocs.GetMvnAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Maven) }, Hidden: true, }, { - Name: "audit-gradle", - Aliases: []string{"ag"}, - Flags: flags.GetCommandFlags(flags.AuditGradle), - Description: auditSpecificDocs.GetGradleDescription(), + Name: "audit-gradle", + Aliases: []string{"ag"}, + Flags: flags.GetCommandFlags(flags.AuditGradle), + Description: auditSpecificDocs.GetGradleDescription(), + AIDescription: auditSpecificDocs.GetGradleAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Gradle) }, Hidden: true, }, { - Name: "audit-npm", - Aliases: []string{"an"}, - Flags: flags.GetCommandFlags(flags.AuditNpm), - Description: auditSpecificDocs.GetNpmDescription(), + Name: "audit-npm", + Aliases: []string{"an"}, + Flags: flags.GetCommandFlags(flags.AuditNpm), + Description: auditSpecificDocs.GetNpmDescription(), + AIDescription: auditSpecificDocs.GetNpmAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Npm) }, Hidden: true, }, { - Name: "audit-go", - Aliases: []string{"ago"}, - Flags: flags.GetCommandFlags(flags.AuditGo), - Description: auditSpecificDocs.GetGoDescription(), + Name: "audit-go", + Aliases: []string{"ago"}, + Flags: flags.GetCommandFlags(flags.AuditGo), + Description: auditSpecificDocs.GetGoDescription(), + AIDescription: auditSpecificDocs.GetGoAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Go) }, Hidden: true, }, { - Name: "audit-pip", - Aliases: []string{"ap"}, - Flags: flags.GetCommandFlags(flags.AuditPip), - Description: auditSpecificDocs.GetPipDescription(), + Name: "audit-pip", + Aliases: []string{"ap"}, + Flags: flags.GetCommandFlags(flags.AuditPip), + Description: auditSpecificDocs.GetPipDescription(), + AIDescription: auditSpecificDocs.GetPipAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Pip) }, Hidden: true, }, { - Name: "audit-pipenv", - Aliases: []string{"ape"}, - Flags: flags.GetCommandFlags(flags.AuditPipenv), - Description: auditSpecificDocs.GetPipenvDescription(), + Name: "audit-pipenv", + Aliases: []string{"ape"}, + Flags: flags.GetCommandFlags(flags.AuditPipenv), + Description: auditSpecificDocs.GetPipenvDescription(), + AIDescription: auditSpecificDocs.GetPipenvAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Pipenv) }, diff --git a/cli/xraycommands.go b/cli/xraycommands.go index 0d1fe377a..41e769f79 100644 --- a/cli/xraycommands.go +++ b/cli/xraycommands.go @@ -26,76 +26,84 @@ func getXrayNameSpaceCommands() []components.Command { Aliases: []string{"cl"}, Flags: flags.GetCommandFlags(flags.XrCurl), Description: curlDocs.GetDescription(), + AIDescription: curlDocs.GetAIDescription(), Arguments: curlDocs.GetArguments(), SkipFlagParsing: true, Action: curlCmd, }, { - Name: "offline-update", - Aliases: []string{"ou"}, - Flags: flags.GetCommandFlags(flags.OfflineUpdate), - Description: offlineupdateDocs.GetDescription(), - Action: offlineUpdates, + Name: "offline-update", + Aliases: []string{"ou"}, + Flags: flags.GetCommandFlags(flags.OfflineUpdate), + Description: offlineupdateDocs.GetDescription(), + AIDescription: offlineupdateDocs.GetAIDescription(), + Action: offlineUpdates, }, // TODO: Deprecated commands (remove at next CLI major version) { - Name: "scan", - Hidden: true, - Aliases: []string{"s"}, - Flags: flags.GetCommandFlags(flags.XrScan), - Description: scanDocs.GetDescription(), - Arguments: scanDocs.GetArguments(), + Name: "scan", + Hidden: true, + Aliases: []string{"s"}, + Flags: flags.GetCommandFlags(flags.XrScan), + Description: scanDocs.GetDescription(), + AIDescription: scanDocs.GetAIDescription(), + Arguments: scanDocs.GetArguments(), Action: func(c *components.Context) error { return pluginsCommon.RunCmdWithDeprecationWarning("scan", "xr", c, ScanCmd) }, }, { - Name: "audit-mvn", - Hidden: true, - Aliases: []string{"am"}, - Flags: flags.GetCommandFlags(flags.AuditMvn), - Description: auditSpecificDocs.GetMvnDescription(), + Name: "audit-mvn", + Hidden: true, + Aliases: []string{"am"}, + Flags: flags.GetCommandFlags(flags.AuditMvn), + Description: auditSpecificDocs.GetMvnDescription(), + AIDescription: auditSpecificDocs.GetMvnAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Maven) }, }, { - Name: "audit-gradle", - Hidden: true, - Aliases: []string{"ag"}, - Flags: flags.GetCommandFlags(flags.AuditGradle), - Description: auditSpecificDocs.GetGradleDescription(), + Name: "audit-gradle", + Hidden: true, + Aliases: []string{"ag"}, + Flags: flags.GetCommandFlags(flags.AuditGradle), + Description: auditSpecificDocs.GetGradleDescription(), + AIDescription: auditSpecificDocs.GetGradleAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Gradle) }, }, { - Name: "audit-npm", - Hidden: true, - Aliases: []string{"an"}, - Flags: flags.GetCommandFlags(flags.AuditNpm), - Description: auditSpecificDocs.GetNpmDescription(), + Name: "audit-npm", + Hidden: true, + Aliases: []string{"an"}, + Flags: flags.GetCommandFlags(flags.AuditNpm), + Description: auditSpecificDocs.GetNpmDescription(), + AIDescription: auditSpecificDocs.GetNpmAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Npm) }, }, { - Name: "audit-go", - Hidden: true, - Aliases: []string{"ago"}, - Flags: flags.GetCommandFlags(flags.AuditGo), - Description: auditSpecificDocs.GetGoDescription(), + Name: "audit-go", + Hidden: true, + Aliases: []string{"ago"}, + Flags: flags.GetCommandFlags(flags.AuditGo), + Description: auditSpecificDocs.GetGoDescription(), + AIDescription: auditSpecificDocs.GetGoAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Go) }, }, { - Name: "audit-pip", - Hidden: true, - Aliases: []string{"ap"}, - Flags: flags.GetCommandFlags(flags.AuditPip), - Description: auditSpecificDocs.GetPipDescription(), + Name: "audit-pip", + Hidden: true, + Aliases: []string{"ap"}, + Flags: flags.GetCommandFlags(flags.AuditPip), + Description: auditSpecificDocs.GetPipDescription(), + AIDescription: auditSpecificDocs.GetPipAIDescription(), Action: func(c *components.Context) error { return AuditSpecificCmd(c, techutils.Pip) }, diff --git a/go.mod b/go.mod index 53c109b0a..54cbdd07d 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,10 @@ go 1.25.7 require ( github.com/CycloneDX/cyclonedx-go v0.10.0 github.com/beevik/etree v1.6.0 - github.com/go-git/go-git/v5 v5.18.0 + github.com/go-git/go-git/v5 v5.19.1 github.com/google/go-github/v56 v56.0.0 github.com/google/uuid v1.6.0 - github.com/gookit/color v1.6.0 + github.com/gookit/color v1.6.1 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-plugin v1.6.3 github.com/jfrog/build-info-go v1.13.1-0.20260429070557-93b98034d295 @@ -16,7 +16,7 @@ require ( github.com/jfrog/gofrog v1.7.6 github.com/jfrog/jfrog-apps-config v1.0.1 github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260501071051-3c8035fc662b - github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260504054219-ba16d20c7b0f + github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260521114102-d507b5c64941 github.com/jfrog/jfrog-client-go v1.55.1-0.20260505115216-b6c67f807bc3 github.com/magiconair/properties v1.8.10 github.com/owenrumney/go-sarif/v3 v3.2.3 @@ -24,10 +24,10 @@ require ( github.com/stretchr/testify v1.11.1 github.com/urfave/cli v1.22.17 github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 - golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 + golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f golang.org/x/sync v0.20.0 - golang.org/x/sys v0.42.0 - golang.org/x/text v0.35.0 + golang.org/x/sys v0.44.0 + golang.org/x/text v0.37.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -39,7 +39,7 @@ require ( github.com/VividCortex/ewma v1.2.0 // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/andybalholm/brotli v1.2.0 // indirect - github.com/buger/jsonparser v1.1.2 // indirect + github.com/buger/jsonparser v1.2.0 // indirect github.com/c-bata/go-prompt v0.2.6 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect @@ -65,7 +65,7 @@ require ( github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gfleury/go-bitbucket-v1 v0.0.0-20240917142304-df385efaac68 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.8.0 // indirect + github.com/go-git/go-billy/v5 v5.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect @@ -82,7 +82,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.8 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/jedib0t/go-pretty/v6 v6.7.8 // indirect + github.com/jedib0t/go-pretty/v6 v6.7.10 // indirect github.com/jfrog/archiver/v3 v3.6.3 // indirect github.com/kevinburke/ssh_config v1.6.0 // indirect github.com/klauspost/compress v1.18.5 // indirect @@ -107,7 +107,7 @@ require ( github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pelletier/go-toml/v2 v2.3.0 // indirect github.com/pierrec/lz4/v4 v4.1.26 // indirect - github.com/pjbgf/sha1cd v0.5.0 // indirect + github.com/pjbgf/sha1cd v0.6.0 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/term v1.2.0-beta.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -138,11 +138,11 @@ require ( go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/trace v1.42.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.49.0 // indirect - golang.org/x/mod v0.34.0 // indirect - golang.org/x/net v0.52.0 // indirect + golang.org/x/crypto v0.50.0 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/term v0.41.0 // indirect + golang.org/x/term v0.43.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/grpc v1.79.3 // indirect diff --git a/go.sum b/go.sum index f7df21ca3..e06dc3ed3 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oM github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= -github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= -github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/buger/jsonparser v1.2.0 h1:4EFcvK1kD4jyj6YqNK6skK6w+y7FHHBR+XBCtxwu/6g= +github.com/buger/jsonparser v1.2.0/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -98,12 +98,12 @@ github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0= -github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY= +github.com/go-git/go-billy/v5 v5.9.0 h1:jItGXszUDRtR/AlferWPTMN4j38BQ88XnXKbilmmBPA= +github.com/go-git/go-billy/v5 v5.9.0/go.mod h1:jCnQMLj9eUgGU7+ludSTYoZL/GGmii14RxKFj7ROgHw= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM= -github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= +github.com/go-git/go-git/v5 v5.19.1 h1:nX27AnaU43/K5bKktKwgBmR9lawoYVe1Ckg0rgzzN00= +github.com/go-git/go-git/v5 v5.19.1/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhEGMH7zjDKQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -139,8 +139,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0= github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E= -github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA= -github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= +github.com/gookit/color v1.6.1 h1:KoTnDxJPRgrL0SoX0f8rCFg2zI0t4E3GZZBMo2nN8LU= +github.com/gookit/color v1.6.1/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/grokify/mogo v0.74.0 h1:+/Q8+C0IaaLhBf9+TBcw/AbBQppTz7Ypa/uUqLpLClY= @@ -157,8 +157,8 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jedib0t/go-pretty/v6 v6.7.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o= -github.com/jedib0t/go-pretty/v6 v6.7.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jedib0t/go-pretty/v6 v6.7.10 h1:B/2qW2Bkv2L6n14PP8o1kx75kWzHOQ3YTluWzg9icac= +github.com/jedib0t/go-pretty/v6 v6.7.10/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/jfrog/archiver/v3 v3.6.3 h1:hkAmPjBw393tPmQ07JknLNWFNZjXdy2xFEnOW9wwOxI= github.com/jfrog/archiver/v3 v3.6.3/go.mod h1:5V9l+Fte30Y4qe9dUOAd3yNTf8lmtVNuhKNrvI8PMhg= github.com/jfrog/build-info-go v1.13.1-0.20260429070557-93b98034d295 h1:EH0h86KwGvNHWyEBQoHoU9WfMMKy1GJ6jJQNmfy6E0U= @@ -171,8 +171,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260501071051-3c8035fc662b h1:FthglG4ivcUSQLNPWWdKzbBHR9FCCG1WJSO5fpbLkY4= github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260501071051-3c8035fc662b/go.mod h1:teaYcsWBYyYa0mhofzOJkEqWRMZ/1gS7uhy6HT64XXg= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260504054219-ba16d20c7b0f h1:l5BPLF8GYBSvXmNqurqAP291lVHr1iCo4nwc5xe7KNM= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260504054219-ba16d20c7b0f/go.mod h1:bjAkVD8c2W+jg4whqy10bSXDC/c+Se8/ll/GPp5F/+0= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260521114102-d507b5c64941 h1:+IcNl7eGzY35UaaS/IoK7G2C+xfq9r2H5kbhSCV1eP8= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260521114102-d507b5c64941/go.mod h1:D9afcOJmauUYcQZ3WGDg7HejyoBmCQr2XrwXHeN1YY8= github.com/jfrog/jfrog-client-go v1.55.1-0.20260505115216-b6c67f807bc3 h1:yjPAmowZM/2yDpgYVwWBuFFm8IETnYkCe5OLp6zFsQA= github.com/jfrog/jfrog-client-go v1.55.1-0.20260505115216-b6c67f807bc3/go.mod h1:sCE06+GngPoyrGO0c+vmhgMoVSP83UMNiZnIuNPzU8U= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= @@ -252,8 +252,8 @@ github.com/pelletier/go-toml/v2 v2.3.0 h1:k59bC/lIZREW0/iVaQR8nDHxVq8OVlIzYCOJf4 github.com/pelletier/go-toml/v2 v2.3.0/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= -github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= -github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= +github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU= +github.com/pjbgf/sha1cd v0.6.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -354,14 +354,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= -golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -372,8 +372,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -411,16 +411,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -428,16 +428,16 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= -golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=