From 8f9dbd56eacf080b6af711173165255b9516e921 Mon Sep 17 00:00:00 2001 From: Felix Sargent Date: Tue, 9 Jun 2026 14:31:04 -0400 Subject: [PATCH 1/2] docs: add ignore create help --- cliv2/pkg/core/help_docs_audit_test.go | 56 +++++++++ help/cli-commands/ignore-create.md | 61 +++++++++ help/cli-commands/ignore.md | 4 + package.json | 1 + scripts/audit-cli-help-docs.js | 167 +++++++++++++++++++++++++ test/jest/acceptance/help.spec.ts | 17 +++ 6 files changed, 306 insertions(+) create mode 100644 cliv2/pkg/core/help_docs_audit_test.go create mode 100644 help/cli-commands/ignore-create.md create mode 100644 scripts/audit-cli-help-docs.js diff --git a/cliv2/pkg/core/help_docs_audit_test.go b/cliv2/pkg/core/help_docs_audit_test.go new file mode 100644 index 0000000000..0527bf178d --- /dev/null +++ b/cliv2/pkg/core/help_docs_audit_test.go @@ -0,0 +1,56 @@ +package core + +import ( + "encoding/json" + "fmt" + "os" + "sort" + "testing" + + "github.com/snyk/go-application-framework/pkg/configuration" + "github.com/snyk/go-application-framework/pkg/workflow" + "github.com/stretchr/testify/require" +) + +type registeredCommandForHelpAudit struct { + Command string `json:"command"` + Visible bool `json:"visible"` +} + +func TestPrintRegisteredCommandTreeForHelpAudit(t *testing.T) { + if os.Getenv("SNYK_HELP_AUDIT_PRINT_COMMANDS") != "1" { + t.Skip("set SNYK_HELP_AUDIT_PRINT_COMMANDS=1 to print registered commands") + } + + config := configuration.New() + engine := workflow.NewWorkFlowEngine(config) + initExtensions(engine, config, nil) + require.NoError(t, engine.Init()) + + commands := []registeredCommandForHelpAudit{} + for _, workflowID := range engine.GetWorkflows() { + command := workflow.GetCommandFromWorkflowIdentifier(workflowID) + if command == "" { + continue + } + + entry, ok := engine.GetWorkflow(workflowID) + if !ok { + continue + } + + commands = append(commands, registeredCommandForHelpAudit{ + Command: command, + Visible: entry.IsVisible(), + }) + } + + sort.Slice(commands, func(i, j int) bool { + return commands[i].Command < commands[j].Command + }) + + output, err := json.Marshal(commands) + require.NoError(t, err) + + fmt.Printf("SNYK_HELP_AUDIT_COMMANDS=%s\n", output) +} diff --git a/help/cli-commands/ignore-create.md b/help/cli-commands/ignore-create.md new file mode 100644 index 0000000000..d890e73dbd --- /dev/null +++ b/help/cli-commands/ignore-create.md @@ -0,0 +1,61 @@ +# Ignore create + +## Usage + +`snyk ignore create []` + +## Description + +The `snyk ignore create` command creates an ignore request for a finding in a Snyk Organization. + +This command creates an ignore request through the Snyk ignore workflow. It does not edit the local `.snyk` policy file. To add ignores to a local policy file, use the `snyk ignore` command. + +In interactive mode, the command prompts for missing values. In non-interactive mode, provide the required options. + +## Options + +### `--finding-id=` + +The ID of the finding to ignore. Required when `--interactive=false`. + +### `--ignore-type=` + +The ignore type to create. Required when `--interactive=false`. + +Supported values: + +- `not-vulnerable` +- `wont-fix` +- `temporary-ignore` + +### `--reason=` + +The reason for the ignore. Required when `--interactive=false`. + +### `--expiration=` + +The ignore expiration date. Use `YYYY-MM-DD` format, or `never` for no expiration. Required when `--interactive=false`. + +### `--remote-repo-url=` + +The remote repository URL for the project. The command detects this value automatically when possible. + +### `--interactive=` + +Run the command in interactive mode. + +Default: `true` + +### `--org=` + +Specify the Snyk Organization ID to use for the ignore request. The value must be an Organization UUID. + +## Examples + +Create an ignore request interactively: + +`$ snyk ignore create` + +Create a temporary ignore request without prompts: + +`$ snyk ignore create --finding-id= --ignore-type=temporary-ignore --reason='Temporarily accepted risk' --expiration=2026-07-01 --interactive=false` diff --git a/help/cli-commands/ignore.md b/help/cli-commands/ignore.md index 3174174bd6..b3bfa2dc6a 100644 --- a/help/cli-commands/ignore.md +++ b/help/cli-commands/ignore.md @@ -10,6 +10,10 @@ The `snyk ignore` command modifies the `.snyk` policy file to ignore a specified **Note:** Ignoring issues or vulnerabilities using the `.snyk` file is not supported for Snyk Code. +### Create ignore requests + +[`snyk ignore create`](ignore-create.md); `snyk ignore create --help`: creates an ignore request for a finding. + ### Exclude `snyk ignore [--expiry=] [--reason=] [--policy-path=] [--file-path=] [OPTIONS]` diff --git a/package.json b/package.json index cc8a4d9c65..53f71f6bab 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "clean": "npx rimraf node_modules dist binary-releases test-results *.tgz tsconfig.tsbuildinfo .eslintcache pysrc packages/*/node_modules packages/*/dist packages/*/tsconfig.tsbuildinfo packages/*/*.tgz", "format": "prettier --write '**/*.{js,ts,json,yaml,yml,md}' && npm run lint:js -- --fix", "format:changes": "./scripts/format/prettier-changes.sh", + "help:audit": "node scripts/audit-cli-help-docs.js", "lint": "npm-run-all --serial --continue-on-error lint:*", "lint:js": "eslint --quiet --color --cache '**/*.{js,ts}'", "lint:formatting": "prettier --check '**/*.{js,ts,json,yaml,yml,md}'", diff --git a/scripts/audit-cli-help-docs.js b/scripts/audit-cli-help-docs.js new file mode 100644 index 0000000000..e9fc50f546 --- /dev/null +++ b/scripts/audit-cli-help-docs.js @@ -0,0 +1,167 @@ +#!/usr/bin/env node + +const { spawnSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +const repoRoot = path.resolve(__dirname, '..'); +const helpDir = path.join(repoRoot, 'help', 'cli-commands'); +const failOnMissing = process.argv.includes('--fail-on-missing'); +const includeHidden = process.argv.includes('--include-hidden'); +const includeInternal = process.argv.includes('--include-internal'); + +const internalCommands = new Set([ + 'datatransformation', + 'filter', + 'help', + 'internal cleanup', + 'legacycli', + 'output', + 'reportanalytics', +]); + +function readFile(relativePath) { + return fs.readFileSync(path.join(repoRoot, relativePath), 'utf8'); +} + +function expectedHelpFile(command) { + return `${command.replace(/\s+/g, '-')}.md`; +} + +function addCommand(commands, command, source, visible = true) { + const normalizedCommand = command.trim().replace(/\s+/g, ' '); + if (!normalizedCommand) { + return; + } + + if (!commands.has(normalizedCommand)) { + commands.set(normalizedCommand, { + command: normalizedCommand, + sources: new Set(), + visible, + }); + } + + const entry = commands.get(normalizedCommand); + entry.sources.add(source); + entry.visible = entry.visible || visible; +} + +function legacyCommands() { + const commands = new Map(); + const commandIndex = readFile('src/cli/commands/index.js'); + + for (const match of commandIndex.matchAll( + /^\s*(?:'([^']+)'|"([^"]+)"|([a-zA-Z][\w-]*)):\s*async/gm, + )) { + addCommand(commands, match[1] || match[2] || match[3], 'legacy command'); + } + + const modes = readFile('src/cli/modes.ts'); + for (const match of modes.matchAll( + /^\s{2}([a-zA-Z][\w-]*):\s*{\s*allowedCommands:\s*\[([^\]]*)\]/gm, + )) { + const mode = match[1]; + const allowedCommands = Array.from( + match[2].matchAll(/'([^']+)'|"([^"]+)"/g), + (allowedCommandMatch) => allowedCommandMatch[1] || allowedCommandMatch[2], + ); + + addCommand(commands, mode, 'legacy mode'); + for (const allowedCommand of allowedCommands) { + addCommand(commands, `${mode} ${allowedCommand}`, 'legacy mode'); + } + } + + return commands; +} + +function nativeCommands() { + const result = spawnSync( + 'go', + [ + 'test', + './pkg/core', + '-run', + 'TestPrintRegisteredCommandTreeForHelpAudit', + '-count=1', + '-v', + ], + { + cwd: path.join(repoRoot, 'cliv2'), + encoding: 'utf8', + env: { + ...process.env, + SNYK_HELP_AUDIT_PRINT_COMMANDS: '1', + }, + }, + ); + + if (result.status !== 0) { + process.stderr.write(result.stdout); + process.stderr.write(result.stderr); + process.exit(result.status || 1); + } + + const match = result.stdout.match(/SNYK_HELP_AUDIT_COMMANDS=(\[.*\])/); + if (!match) { + process.stderr.write(result.stdout); + process.stderr.write(result.stderr); + throw new Error('Could not find registered command audit output.'); + } + + return JSON.parse(match[1]); +} + +function helpFiles() { + return new Set( + fs + .readdirSync(helpDir) + .filter( + (fileName) => fileName.endsWith('.md') && fileName !== 'README.md', + ), + ); +} + +function collectCommands() { + const commands = legacyCommands(); + + for (const nativeCommand of nativeCommands()) { + addCommand( + commands, + nativeCommand.command, + nativeCommand.visible ? 'native workflow' : 'native workflow hidden', + nativeCommand.visible, + ); + } + + return Array.from(commands.values()).map((entry) => ({ + ...entry, + sources: Array.from(entry.sources).sort(), + })); +} + +const docs = helpFiles(); +const missing = collectCommands() + .filter((entry) => includeInternal || !internalCommands.has(entry.command)) + .filter((entry) => includeHidden || entry.visible) + .filter((entry) => !docs.has(expectedHelpFile(entry.command))) + .sort((a, b) => a.command.localeCompare(b.command)); + +if (missing.length === 0) { + console.log('All discovered CLI commands have help docs.'); + process.exit(0); +} + +console.log('CLI commands without help docs:'); +for (const entry of missing) { + console.log( + `- snyk ${entry.command} -> help/cli-commands/${expectedHelpFile( + entry.command, + )} (${entry.sources.join(', ')})`, + ); +} + +if (failOnMissing) { + process.exit(1); +} diff --git a/test/jest/acceptance/help.spec.ts b/test/jest/acceptance/help.spec.ts index 4398ef6dbd..a1df5aff78 100644 --- a/test/jest/acceptance/help.spec.ts +++ b/test/jest/acceptance/help.spec.ts @@ -57,6 +57,23 @@ describe('help', () => { expect(stderr).toBe(''); }); + it('prints specific help info for ignore', async () => { + const { stdout, code, stderr } = await runSnykCLI('ignore --help'); + + expect(stdout).toContain('snyk ignore create'); + expect(code).toBe(0); + expect(stderr).toBe(''); + }); + + it('prints specific help info for ignore create', async () => { + const { stdout, code, stderr } = await runSnykCLI('ignore create --help'); + + expect(stdout).toContain('Ignore create'); + expect(stdout).toContain('snyk ignore create []'); + expect(code).toBe(0); + expect(stderr).toBe(''); + }); + it('prints specific help info when called with flag and equals sign', async () => { const { stdout, code, stderr } = await runSnykCLI('--help=iac'); From 8800e456878e29c36c00ac04bdfa50e482853f2e Mon Sep 17 00:00:00 2001 From: Felix Sargent Date: Tue, 9 Jun 2026 16:04:43 -0400 Subject: [PATCH 2/2] docs: add missing command help docs --- help/cli-commands/about.md | 15 +++ help/cli-commands/agent-scan.md | 65 ++++++++++ help/cli-commands/fix.md | 49 ++++++++ help/cli-commands/iac-rules-repl.md | 43 +++++++ help/cli-commands/redteam-get.md | 52 ++++++++ help/cli-commands/redteam-ping.md | 58 +++++++++ help/cli-commands/redteam-setup.md | 46 ++++++++ help/cli-commands/secrets-test.md | 111 ++++++++++++++++++ help/cli-commands/tools-connectivity-check.md | 49 ++++++++ .../cli-commands/tools-ide-directory-check.md | 31 +++++ help/cli-commands/version.md | 15 +++ scripts/audit-cli-help-docs.js | 14 +++ 12 files changed, 548 insertions(+) create mode 100644 help/cli-commands/about.md create mode 100644 help/cli-commands/agent-scan.md create mode 100644 help/cli-commands/fix.md create mode 100644 help/cli-commands/iac-rules-repl.md create mode 100644 help/cli-commands/redteam-get.md create mode 100644 help/cli-commands/redteam-ping.md create mode 100644 help/cli-commands/redteam-setup.md create mode 100644 help/cli-commands/secrets-test.md create mode 100644 help/cli-commands/tools-connectivity-check.md create mode 100644 help/cli-commands/tools-ide-directory-check.md create mode 100644 help/cli-commands/version.md diff --git a/help/cli-commands/about.md b/help/cli-commands/about.md new file mode 100644 index 0000000000..5ee9689f76 --- /dev/null +++ b/help/cli-commands/about.md @@ -0,0 +1,15 @@ +# About + +## Usage + +`snyk about` + +## Description + +The `snyk about` command prints open source attribution information for the Snyk CLI. + +The output includes the package names, versions, licenses, authors, source package locations, and license text for third-party packages bundled with the CLI. + +## Debug + +Use the `-d` option to output the debug logs. diff --git a/help/cli-commands/agent-scan.md b/help/cli-commands/agent-scan.md new file mode 100644 index 0000000000..fba310d968 --- /dev/null +++ b/help/cli-commands/agent-scan.md @@ -0,0 +1,65 @@ +# Agent scan + +**Warning:** The `snyk agent-scan` command is experimental. The `--experimental` flag is required. Behavior and options may change in future releases without notice. + +## Usage + +`snyk agent-scan --experimental [] []` + +## Description + +The `snyk agent-scan` command scans agent-related assets, including MCP server configuration and skills, and can upload scan results to Snyk Evo. + +If you provide a path, the command scans that path. If you do not provide a subcommand, the CLI runs the default `scan` action. + +The command downloads and runs the platform-specific `agent-scan` binary when needed. + +## Options + +### `--experimental` + +Required. Acknowledges that this command is experimental. + +### `--client-id=` + +Specify the client ID to use when uploading scan results. + +If you do not specify `--client-id`, the CLI attempts to discover one from your authenticated Snyk account. + +### `--tenant-id=` + +Specify the tenant ID to use for client ID discovery. + +You can also set the tenant ID with the `SNYK_TENANT_ID` environment variable. + +### `--json` + +Print the output as JSON. + +When using `--json`, provide `--tenant-id` if client ID discovery is required. + +### `--skills[=]` + +Scan skills in addition to MCP servers. + +You can use this option as a boolean flag or provide a folder path. + +### `--no-upload` + +Do not upload scan results to Snyk Evo. + +This option requires authentication. + +## Examples + +Scan the current directory: + +`$ snyk agent-scan --experimental` + +Scan a specific directory: + +`$ snyk agent-scan --experimental ./my-agent` + +Scan skills and print JSON: + +`$ snyk agent-scan --experimental --skills --json --tenant-id=` diff --git a/help/cli-commands/fix.md b/help/cli-commands/fix.md new file mode 100644 index 0000000000..5ed5c0b0b7 --- /dev/null +++ b/help/cli-commands/fix.md @@ -0,0 +1,49 @@ +# Fix + +## Usage + +`snyk fix [] []` + +## Description + +The `snyk fix` command applies available fixes for open-source vulnerabilities in supported projects. + +The command first runs `snyk test` for the target project and then applies supported remediation actions. + +## Configure the Snyk CLI + +You can use environment variables to configure the Snyk CLI and set variables for connecting with the Snyk API. See [Configure the Snyk CLI](https://docs.snyk.io/snyk-cli/configure-the-snyk-cli) + +## Debug + +Use the `-d` option to output the debug logs. + +## Options + +### `--dry-run` + +Preview the fixes that would be applied without changing files. + +### `--quiet` + +Reduce command output. + +### `--sequential` + +Apply fixes sequentially. + +### Options used by `snyk test` + +The `snyk fix` command uses `snyk test` to find vulnerabilities before applying fixes. Supported `snyk test` options can be used to control project detection and dependency resolution. + +For more information, see the [`snyk test` help](test.md); `snyk test --help`. + +## Examples + +Preview available fixes: + +`$ snyk fix --dry-run` + +Apply fixes in the current directory: + +`$ snyk fix` diff --git a/help/cli-commands/iac-rules-repl.md b/help/cli-commands/iac-rules-repl.md new file mode 100644 index 0000000000..22d82c5433 --- /dev/null +++ b/help/cli-commands/iac-rules-repl.md @@ -0,0 +1,43 @@ +# IaC rules repl + +## Usage + +**Feature availability:** This feature is in Early Access. + +`snyk iac rules repl []` + +## Description + +The `snyk iac rules repl` command starts an interactive Rego REPL for an IaC custom rules project. + +Run the command from an IaC custom rules project directory. You can load an input file and run initialization commands when the REPL starts. + +For a list of related commands run `snyk iac --help`. + +## Configure the Snyk CLI + +You can use environment variables and set variables for connecting with the Snyk API; see [Configure the Snyk CLI](https://docs.snyk.io/snyk-cli/configure-the-snyk-cli) + +## Debug + +Use the `-d` option to output the debug logs. + +## Options + +### `--repl-init=` + +Run commands on REPL initialization. + +This option can be provided more than once. + +### `--repl-input=` + +Load an IaC input file into the REPL. + +## Example + +Start the REPL with an input file: + +``` +snyk iac rules repl --repl-input=input.json +``` diff --git a/help/cli-commands/redteam-get.md b/help/cli-commands/redteam-get.md new file mode 100644 index 0000000000..1f7f35f6d5 --- /dev/null +++ b/help/cli-commands/redteam-get.md @@ -0,0 +1,52 @@ +# Redteam get + +**Warning:** The `snyk redteam get` command is experimental. The `--experimental` flag is required. Behavior and options may change in future releases without notice. + +`snyk redteam` will be deprecated on May 31, 2026. + +## Prerequisites + +- Snyk CLI v1.1303.1 or later. +- Authenticated Snyk CLI; run `snyk auth`. + +## Usage + +`snyk redteam get --experimental --id= []` + +## Description + +The `snyk redteam get` command retrieves results for a previously completed red team scan. + +For more information about red team scans and configuration, see the [`snyk redteam` help](redteam.md); `snyk redteam --help`. + +## Options + +### `--experimental` + +Required. Acknowledges that this command is experimental. + +### `--id=` + +Required. The UUID of the scan to retrieve results for. + +### `--html` + +Output the scan report in HTML format instead of JSON. + +### `--html-file-output=` + +Write the HTML report to the specified file path. Implies HTML output. + +### `--json-file-output=` + +Write the JSON report to the specified file path. + +### `--tenant-id=` + +Specify the Snyk tenant ID. The CLI attempts to discover the tenant ID from your authenticated Snyk account if it is not provided. + +## Example + +Retrieve scan results: + +`$ snyk redteam get --experimental --id=` diff --git a/help/cli-commands/redteam-ping.md b/help/cli-commands/redteam-ping.md new file mode 100644 index 0000000000..b942f5d4c7 --- /dev/null +++ b/help/cli-commands/redteam-ping.md @@ -0,0 +1,58 @@ +# Redteam ping + +**Warning:** The `snyk redteam ping` command is experimental. The `--experimental` flag is required. Behavior and options may change in future releases without notice. + +`snyk redteam` will be deprecated on May 31, 2026. + +## Prerequisites + +- Snyk CLI v1.1303.1 or later. +- Authenticated Snyk CLI; run `snyk auth`. + +## Usage + +`snyk redteam ping --experimental []` + +## Description + +The `snyk redteam ping` command sends a test request to the configured target endpoint. + +Use this command to verify target connectivity and response parsing before running a full red team scan. + +For more information about red team configuration, see the [`snyk redteam` help](redteam.md); `snyk redteam --help`. + +## Options + +### `--experimental` + +Required. Acknowledges that this command is experimental. + +### `--config=` + +Path to the YAML configuration file. + +Default: `redteam.yaml` in the current directory. + +### `--target-url=` + +URL of the target endpoint to test. Overrides `target.settings.url` from the configuration file. + +### `--request-body-template=