Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [1.1.123](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.123) - 2026-06-18

### Added
- `socket scan create --reach` and `socket scan reach` now accept unit suffixes on `--reach-analysis-timeout` (`s`, `m`, `h` — e.g. `90s`, `10m`, `1h`) and `--reach-analysis-memory-limit` (`MB`, `GB` — e.g. `512MB`, `8GB`). Plain numbers keep working as before.

### Changed
- Updated the Coana CLI to v `15.5.0`.

## [1.1.122](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.122) - 2026-06-17

### Changed
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "socket",
"version": "1.1.122",
"version": "1.1.123",
"description": "CLI for Socket.dev",
"homepage": "https://github.com/SocketDev/socket-cli",
"license": "MIT",
Expand Down Expand Up @@ -96,7 +96,7 @@
"@babel/preset-typescript": "7.27.1",
"@babel/runtime": "7.28.4",
"@biomejs/biome": "2.2.4",
"@coana-tech/cli": "15.4.6",
"@coana-tech/cli": "15.5.0",
"@cyclonedx/cdxgen": "12.1.2",
"@dotenvx/dotenvx": "1.49.0",
"@eslint/compat": "1.3.2",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/commands/ci/handle-ci.mts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ export async function handleCi(autoManifest: boolean): Promise<void> {
pullRequest: 0,
reach: {
excludePaths: [],
reachAnalysisMemoryLimit: 0,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down
27 changes: 19 additions & 8 deletions src/commands/scan/cmd-scan-create.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { assertValidExcludePaths } from './exclude-paths.mts'
import { handleCreateNewScan } from './handle-create-new-scan.mts'
import { outputCreateNewScan } from './output-create-new-scan.mts'
import { excludePathsFlag, reachabilityFlags } from './reachability-flags.mts'
import {
isOmittedReachValue,
reachMemoryLimitToMb,
} from './reachability-units.mts'
import { suggestOrgSlug } from './suggest-org-slug.mts'
import { suggestTarget } from './suggest_target.mts'
import { validateReachabilityTarget } from './validate-reachability-target.mts'
Expand Down Expand Up @@ -284,8 +288,8 @@ async function run(
tmp: boolean
// Reachability flags.
reach: boolean
reachAnalysisMemoryLimit: number
reachAnalysisTimeout: number
reachAnalysisMemoryLimit: string
reachAnalysisTimeout: string
reachConcurrency: number
reachContinueOnAnalysisErrors: boolean
reachContinueOnInstallErrors: boolean
Expand Down Expand Up @@ -485,12 +489,19 @@ async function run(

const hasReachExcludePaths = reachExcludePaths.length > 0

// Compare by resolved magnitude, not string identity: 8192, 8192MB and 8GB
// all mean the default, and an omitted/zero timeout means "use the default".
// A naive string compare would flag those equivalents as non-default and
// wrongly require --reach.
const memoryLimitMb = reachMemoryLimitToMb(reachAnalysisMemoryLimit)
const isUsingNonDefaultMemoryLimit =
reachAnalysisMemoryLimit !==
reachabilityFlags['reachAnalysisMemoryLimit']?.default
memoryLimitMb !== null &&
memoryLimitMb !==
reachMemoryLimitToMb(
String(reachabilityFlags['reachAnalysisMemoryLimit']?.default ?? ''),
)

const isUsingNonDefaultTimeout =
reachAnalysisTimeout !== reachabilityFlags['reachAnalysisTimeout']?.default
const isUsingNonDefaultTimeout = !isOmittedReachValue(reachAnalysisTimeout)

const isUsingNonDefaultConcurrency =
reachConcurrency !== reachabilityFlags['reachConcurrency']?.default
Expand Down Expand Up @@ -633,8 +644,8 @@ async function run(
})
: undefined,
excludePaths,
reachAnalysisMemoryLimit: Number(reachAnalysisMemoryLimit),
reachAnalysisTimeout: Number(reachAnalysisTimeout),
reachAnalysisMemoryLimit,
reachAnalysisTimeout,
reachConcurrency: Number(reachConcurrency),
reachContinueOnAnalysisErrors: Boolean(reachContinueOnAnalysisErrors),
reachContinueOnInstallErrors: Boolean(reachContinueOnInstallErrors),
Expand Down
54 changes: 52 additions & 2 deletions src/commands/scan/cmd-scan-create.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ describe('socket scan create', async () => {
--workspace The workspace in the Socket Organization that the repository is in to associate with the full scan.

Reachability Options (when --reach is used)
--reach-analysis-memory-limit The maximum memory in MB to use for the reachability analysis. The default is 8192MB.
--reach-analysis-timeout Set timeout for the reachability analysis. Split analysis runs may cause the total scan time to exceed this timeout significantly.
--reach-analysis-memory-limit The maximum memory for the reachability analysis as a whole number optionally followed by MB or GB (e.g. 512MB, 8GB). The default is 8GB.
--reach-analysis-timeout Set the timeout for the reachability analysis as a whole number optionally followed by s, m or h (e.g. 90s, 10m, 1h). Defaults to 10m. Split analysis runs may cause the total scan time to exceed this timeout significantly.
--reach-concurrency Set the maximum number of concurrent reachability analysis runs. It is recommended to choose a concurrency level that ensures each analysis run has at least the --reach-analysis-memory-limit amount of memory available.
--reach-continue-on-analysis-errors Continue reachability analysis when errors occur (timeouts, OOM, parse errors, etc.), falling back to precomputed (Tier 2) results. By default, the CLI halts on analysis errors.
--reach-continue-on-install-errors Continue reachability analysis when package installation fails, falling back to precomputed (Tier 2) results. By default, the CLI halts on installation errors.
Expand Down Expand Up @@ -266,6 +266,56 @@ describe('socket scan create', async () => {
},
)

cmdit(
[
'scan',
'create',
FLAG_ORG,
'fakeOrg',
'target',
FLAG_DRY_RUN,
'--repo',
'xyz',
'--branch',
'abc',
'--reach-analysis-memory-limit',
'8GB',
FLAG_CONFIG,
'{"apiToken":"fakeToken"}',
],
'should succeed when --reach-analysis-memory-limit equals the default in a different unit (8GB) without --reach',
async cmd => {
const { code, stdout } = await spawnSocketCli(binCliPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(code, 'should treat 8GB as the default 8192MB').toBe(0)
},
)

cmdit(
[
'scan',
'create',
FLAG_ORG,
'fakeOrg',
'target',
FLAG_DRY_RUN,
'--repo',
'xyz',
'--branch',
'abc',
'--reach-analysis-timeout',
'0',
FLAG_CONFIG,
'{"apiToken":"fakeToken"}',
],
'should succeed when --reach-analysis-timeout is the zero/omit sentinel without --reach',
async cmd => {
const { code, stdout } = await spawnSocketCli(binCliPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(code, 'should treat 0 as the default (omit) timeout').toBe(0)
},
)

cmdit(
[
'scan',
Expand Down
8 changes: 4 additions & 4 deletions src/commands/scan/cmd-scan-reach.mts
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ async function run(
markdown: boolean
org: string
output: string
reachAnalysisMemoryLimit: number
reachAnalysisTimeout: number
reachAnalysisMemoryLimit: string
reachAnalysisTimeout: string
reachConcurrency: number
reachContinueOnAnalysisErrors: boolean
reachContinueOnInstallErrors: boolean
Expand Down Expand Up @@ -277,8 +277,8 @@ async function run(
outputPath: outputPath || '',
reachabilityOptions: {
excludePaths,
reachAnalysisMemoryLimit: Number(reachAnalysisMemoryLimit),
reachAnalysisTimeout: Number(reachAnalysisTimeout),
reachAnalysisMemoryLimit,
reachAnalysisTimeout,
reachConcurrency: Number(reachConcurrency),
reachContinueOnAnalysisErrors: Boolean(reachContinueOnAnalysisErrors),
reachContinueOnInstallErrors: Boolean(reachContinueOnInstallErrors),
Expand Down
16 changes: 8 additions & 8 deletions src/commands/scan/cmd-scan-reach.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ describe('socket scan reach', async () => {

Reachability Options
--exclude-paths List of glob patterns to exclude from the scan, including SCA/SBOM manifest discovery and (when --reach is enabled) Tier 1 reachability analysis. Patterns are anchored micromatch globs matched relative to the Socket scan root, which is the command working directory (\`--cwd\` if set), not the reachability target: \`tests\` matches only \`<cwd>/tests\`; use \`**/tests\` to match at any depth. Negation patterns (\`!path\`) are not supported. Accepts a comma-separated value or multiple flags.
--reach-analysis-memory-limit The maximum memory in MB to use for the reachability analysis. The default is 8192MB.
--reach-analysis-timeout Set timeout for the reachability analysis. Split analysis runs may cause the total scan time to exceed this timeout significantly.
--reach-analysis-memory-limit The maximum memory for the reachability analysis as a whole number optionally followed by MB or GB (e.g. 512MB, 8GB). The default is 8GB.
--reach-analysis-timeout Set the timeout for the reachability analysis as a whole number optionally followed by s, m or h (e.g. 90s, 10m, 1h). Defaults to 10m. Split analysis runs may cause the total scan time to exceed this timeout significantly.
--reach-concurrency Set the maximum number of concurrent reachability analysis runs. It is recommended to choose a concurrency level that ensures each analysis run has at least the --reach-analysis-memory-limit amount of memory available.
--reach-continue-on-analysis-errors Continue reachability analysis when errors occur (timeouts, OOM, parse errors, etc.), falling back to precomputed (Tier 2) results. By default, the CLI halts on analysis errors.
--reach-continue-on-install-errors Continue reachability analysis when package installation fails, falling back to precomputed (Tier 2) results. By default, the CLI halts on installation errors.
Expand Down Expand Up @@ -1050,7 +1050,7 @@ describe('socket scan reach', async () => {
FLAG_CONFIG,
'{"apiToken":"fake-token"}',
],
'should show clear error for invalid memory limit',
'should forward an unrecognized memory value to Coana without locally rejecting it',
async cmd => {
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
const output = stdout + stderr
Expand All @@ -1065,13 +1065,13 @@ describe('socket scan reach', async () => {
'reach',
FLAG_DRY_RUN,
'--reach-analysis-memory-limit',
'-1',
'512kb',
'--org',
'fakeOrg',
FLAG_CONFIG,
'{"apiToken":"fake-token"}',
],
'should show clear error for negative memory limit',
'should forward an unsupported memory unit to Coana without locally rejecting it',
async cmd => {
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
const output = stdout + stderr
Expand All @@ -1092,7 +1092,7 @@ describe('socket scan reach', async () => {
FLAG_CONFIG,
'{"apiToken":"fake-token"}',
],
'should show clear error for invalid timeout value',
'should forward an unrecognized timeout value to Coana without locally rejecting it',
async cmd => {
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
const output = stdout + stderr
Expand All @@ -1107,13 +1107,13 @@ describe('socket scan reach', async () => {
'reach',
FLAG_DRY_RUN,
'--reach-analysis-timeout',
'0',
'10m',
'--org',
'fakeOrg',
FLAG_CONFIG,
'{"apiToken":"fake-token"}',
],
'should show clear error for zero timeout',
'should accept a timeout value with a unit suffix',
async cmd => {
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
const output = stdout + stderr
Expand Down
4 changes: 2 additions & 2 deletions src/commands/scan/create-scan-from-github.mts
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ async function scanOneRepo(
pullRequest: 0,
reach: {
excludePaths: [],
reachAnalysisMemoryLimit: 0,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down
4 changes: 2 additions & 2 deletions src/commands/scan/exclude-paths.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ function makeReachOptions(
): ReachabilityOptions {
return {
excludePaths: [],
reachAnalysisMemoryLimit: 8192,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '8192',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down
24 changes: 12 additions & 12 deletions src/commands/scan/handle-create-new-scan.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ function createConfig(
pullRequest: 0,
reach: {
excludePaths: [],
reachAnalysisMemoryLimit: 8192,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '8192',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down Expand Up @@ -198,8 +198,8 @@ describe('handleCreateNewScan excludePaths', () => {
pullRequest: 0,
reach: {
excludePaths: ['tests', 'packages/*'],
reachAnalysisMemoryLimit: 8192,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '8192',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down Expand Up @@ -260,8 +260,8 @@ describe('handleCreateNewScan excludePaths', () => {
pullRequest: 0,
reach: {
excludePaths: ['apps/api/tests', '**/dist'],
reachAnalysisMemoryLimit: 8192,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '8192',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down Expand Up @@ -328,8 +328,8 @@ describe('handleCreateNewScan excludePaths', () => {
pullRequest: 0,
reach: {
excludePaths: ['tests'],
reachAnalysisMemoryLimit: 8192,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '8192',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down Expand Up @@ -386,8 +386,8 @@ describe('handleCreateNewScan excludePaths', () => {
pullRequest: 0,
reach: {
excludePaths: ['apps/api'],
reachAnalysisMemoryLimit: 8192,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '8192',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down Expand Up @@ -444,8 +444,8 @@ describe('handleCreateNewScan excludePaths', () => {
pullRequest: 0,
reach: {
excludePaths: ['tests'],
reachAnalysisMemoryLimit: 8192,
reachAnalysisTimeout: 0,
reachAnalysisMemoryLimit: '8192',
reachAnalysisTimeout: '',
reachConcurrency: 1,
reachContinueOnAnalysisErrors: false,
reachContinueOnInstallErrors: false,
Expand Down
Loading
Loading