tag:github.com,2008:https://github.com/SocketDev/socket-python-cli/releasesTags from socket-python-cli2026-06-19T12:47:22Ztag:github.com,2008:Repository/802230750/v2.4.122026-06-19T12:47:55Zv2.4.12<p>Consolidate coana launcher env vars into SOCKET_CLI_COANA_LAUNCHER (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/233">#233</a></p>
<p><a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/233"></a>)</p>
<p>Replace the SOCKET_CLI_COANA_FORCE_NPM_INSTALL and
<br />SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK toggles with a single
<br />SOCKET_CLI_COANA_LAUNCHER variable (auto | npx | npm-install), mirroring
<br />the Socket Node CLI. The legacy variables remain supported when the new
<br />variable is unset, but are deprecated and no longer documented.</p>
<p>Follow-up from the review thread on PR <a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/230">#230</a>.</p>mtorptag:github.com,2008:Repository/802230750/v2.4.112026-06-19T07:28:27Zv2.4.11<p>Add units to reachability timeout/memory-limit flags (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/236">#236</a>)</p>
<p>--reach-analysis-timeout now accepts an optional duration unit (s/m/h, e.g.
<br />90s, 10m, 1h) and --reach-analysis-memory-limit an optional size unit (MB/GB,
<br />case-insensitive, e.g. 512MB, 8GB). Values are forwarded verbatim to the
<br />reachability engine (@coana-tech/cli), which owns parsing and validation, so
<br />the unit grammar and error messages live in a single source of truth.</p>
<p>To pass values through unchanged, the four flags (incl. the hidden
<br />--reach-timeout/--reach-memory-limit aliases) drop type=int and accept raw
<br />strings; the dataclass fields become Optional[str]. A defensive str() is kept
<br />at the coana forward point so config-file JSON numbers (which bypass argparse's
<br />type converter via set_defaults) still reach subprocess as strings, and the
<br />guard uses `is not None` so an explicit empty string flows through and triggers
<br />coana's own error rather than being silently dropped.</p>
<p>Bare numbers remain accepted for backward compatibility (seconds for the
<br />timeout, MB for the memory limit) but are no longer documented. Bumped the
<br />pinned @coana-tech/cli version to 15.5.0, which ships the unit parser.</p>
<p>Docs (cli-reference) and CHANGELOG updated; unit tests cover unit-bearing
<br />values, bare-int back-compat, and int coercion.</p>mtorptag:github.com,2008:Repository/802230750/v2.4.102026-06-12T21:43:50Zv2.4.10<p>Add --include-dirs flag to scan normally-excluded directories (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/235">#235</a>)</p>
<p>Adds the ability to opt directories that the CLI excludes from manifest
<br />discovery by default (build, dist, node_modules, .venv, etc.) back into
<br />the scan, for projects that keep manifest files under those names.</p>
<p>- New --include-dirs flag (comma-separated directory names) re-includes
<br /> any of the default-excluded names in manifest discovery.
<br />- --include-module-folders now functions as documented (re-includes the
<br /> JS/TS module folders as a group); it was previously a no-op.</p>
<p>Bumps version to 2.4.10 with changelog and CLI reference updates.</p>
<p>Signed-off-by: lelia <[email protected]></p>leliatag:github.com,2008:Repository/802230750/v2.4.92026-06-12T08:22:53Zv2.4.9<p>feat: stream CLI log transcripts and run status to Socket backend (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/201">#201</a>)</p>
<p>* feat: stream CLI logs to /python-cli-runs/* lifecycle endpoints</p>
<p>Buffer the CLI's own log records and POST them in 5s batches to a new
<br />register/upload/finalize lifecycle so the admin dashboard renders what
<br />the user saw in their terminal alongside the run's terminal status.</p>
<p>New modules:
<br />- core/cli_run.py — register_cli_run / finalize_cli_run helpers
<br />- core/log_uploader.py — BatchedLogUploader (daemon-thread flusher,
<br /> chunked under the 256KB cap, swallows network errors, drains on
<br /> shutdown) and UploadingLogHandler routing log records to it
<br />- core/streaming.py — setup_streaming() wires both into the socketcli
<br /> and socketdev loggers, forces them to DEBUG so uploads capture the
<br /> full history regardless of local terminal verbosity, and returns a
<br /> teardown callable for the caller to register with atexit
<br />- set_run_status() propagates the terminal status through the teardown;
<br /> socketcli.py exception handlers call it for KeyboardInterrupt
<br /> (cancelled), uncaught Exception (failure), and any SystemExit with a
<br /> non-zero code (failure) so sys.exit() paths inside main_code surface
<br /> correctly instead of defaulting to success</p>
<p>Best-effort end-to-end: registration failures fall back to no-streaming
<br />and never block the scan. Opt out with --disable-server-log-streaming.</p>
<p>Tested against local depscan with the matching /v0/python-cli-runs/*
<br />endpoints; 173 unit tests pass.</p>
<p>* chore: drop per-batch size chunking to match upstream uploader</p>
<p>The 256 KB ceiling I added speculatively when the server cap was 256 KB
<br />no longer matches the reference implementation we're mirroring, which
<br />sends each flush as a single POST regardless of size. With the server
<br />cap now well above any plausible single-flush volume, chunking is
<br />unnecessary and divergent — drop it.</p>
<p>Removes _chunk_by_size, _MAX_BATCH_BYTES, and the four chunking tests.
<br />_flush now POSTs the entire buffered batch as one request.</p>
<p>* chore: drop integration field from cli-run register payload</p>
<p>The server-side handler now rejects unknown fields and the integration
<br />column has been removed from the schema (it was plumbed end-to-end but
<br />never displayed, filtered, or grouped on). Stop sending it.</p>
<p>Removes the integration parameter from register_cli_run and
<br />setup_streaming, drops the corresponding wiring in socketcli.py, and
<br />prunes the now-pointless test_register_cli_run_omits_integration_when_falsy
<br />case.</p>
<p>* feat: link cli-run to its full_scan via report_run_id on finalize</p>
<p>The depscan side now joins cli_run → full_scans → repositories via the
<br />report_run_id field to surface the scanned repo in the admin dashboard
<br />view of each CLI run. Wire the CLI to send the full_scan_id (== the
<br />report_run_id depscan expects) when it has one.</p>
<p>- finalize_cli_run accepts an optional report_run_id and includes it
<br /> (nullable) in the POST body.
<br />- streaming.py adds a module-level _report_run_id holder and a
<br /> set_report_run_id() setter; teardown passes it through to finalize.
<br />- socketcli.py captures diff.id at a single chokepoint after the
<br /> diff-producing branches converge, guarded against the NO_DIFF_RAN /
<br /> NO_SCAN_RAN sentinel values.</p>
<p>The field is nullable end-to-end so CLI invocations that fail before
<br />producing a diff (or are run in modes that don't create one) still
<br />finalize cleanly.</p>
<p>* chore: bump version to 2.2.87 for streaming logs feature</p>
<p>- socketsecurity/__init__.py: __version__ → 2.2.87
<br />- pyproject.toml: version → 2.2.87
<br />- CHANGELOG.md: new 2.2.87 entry describing the streaming-logs feature</p>
<p>Required by .github/workflows/version-check.yml, which fails the PR if
<br />the version isn't incremented relative to main.</p>
<p>* feat: flip streaming logs to opt-in via --upload-logs</p>
<p>The Socket backend changed its register contract so that log streaming
<br />is now opt-in rather than default-on. The CLI always calls register
<br />(cheap, lets the server force-enable for specific orgs) and gates the
<br />downstream upload/finalize lifecycle on the response.</p>
<p>Wire changes:
<br />- POST /v0/python-cli-runs body adds a required `share_logs` field.
<br />- Response: { log_streaming_enabled: bool, run_id: <uuid|null> }.
<br /> When log_streaming_enabled is false, run_id is null and the CLI
<br /> skips the upload + finalize calls entirely.</p>
<p>CLI changes:
<br />- New `--upload-logs` flag (default off). When set, the CLI sends
<br /> share_logs=true on register.
<br />- Removed `--disable-server-log-streaming` — default is off, so an
<br /> opt-out flag no longer makes sense.
<br />- register_cli_run takes a required share_logs arg and returns None
<br /> whenever log_streaming_enabled is false (whatever the reason: client
<br /> opted out, server denied, server unreachable).</p>
<p>Bumps version to 2.2.88 and updates the CHANGELOG entry to reflect
<br />the opt-in shape.</p>
<p>* chore: regenerate uv.lock for version 2.4.8</p>
<p>The version-check workflow added in main now requires uv.lock to be
<br />updated whenever pyproject.toml changes, and the SFW smoke jobs run
<br />`uv sync --locked`, which fails on an out-of-sync lockfile.</p>
<p>* feat: add --no-upload-logs to explicitly decline log upload</p>
<p>Backend now distinguishes "user wants out" from "user said nothing":
<br />- `decline_logs: true` (the new flag) overrides every other signal
<br /> including the server-side org-level override, so users with a
<br /> legal/consent reason for no upload get a guaranteed off.
<br />- `share_logs: true` (the existing --upload-logs) opts in.
<br />- Otherwise the server applies its own policy.</p>
<p>Argparse enforces that --upload-logs and --no-upload-logs are mutually
<br />exclusive (post-parse check via parser.error so dash/underscore aliases
<br />on either side still coexist with the same dests).</p>
<p>register_cli_run now sends both `share_logs` and `decline_logs` in the
<br />payload; setup_streaming forwards both. CHANGELOG 2.4.8 entry updated
<br />to call out --no-upload-logs alongside --upload-logs.</p>
<p>* chore: bump version to 2.4.9</p>
<p>2.4.8 already shipped with the full-scan retry fix; this release adds
<br />the opt-in --upload-logs streaming channel.</p>
<p>* chore: bump __version__ to 2.4.9</p>
<p>version-check reads socketsecurity/__init__.py; the previous bump
<br />only touched pyproject.toml.</p>
<p>* refactor: address PR review on streaming logs</p>
<p>- collapse upload_logs/decline_logs config fields into a single
<br /> Optional[bool] (tri-state); projection to share_logs/decline_logs
<br /> happens at the setup_streaming call site.
<br />- streaming.py: replace module-level globals + atexit teardown with a
<br /> StreamingLogs context manager. set_run_status disappears entirely —
<br /> __exit__ infers the run status from the exception that closed the
<br /> with block. set_report_run_id is now an instance method. Logger
<br /> handler wiring iterates over (cli_logger, sdk_logger) instead of
<br /> repeating itself.
<br />- log_uploader.py: drop _LEVEL_MAP, use logging.getLevelName directly.
<br /> Wire format changes WARN/ERROR-for-CRITICAL to WARNING/CRITICAL.
<br />- log_uploader.py: tidy BatchedLogUploader.stop so the final _flush
<br /> always runs and the thread shutdown only runs when there is a thread.
<br />- socketcli.py: wrap main_code body in 'with setup_streaming(...) as
<br /> streaming:'; cli()'s exception handlers no longer need to set status
<br /> before re-raising.
<br />- tests updated for the CM API and the new level strings.</p>
<p>* test(log_uploader): cover cross-thread emit during active flush</p>
<p>Adds a deterministic regression test that parks the uploader thread
<br />inside _flush() via a threading.Event, emits a real log record from
<br />the main thread while _FLUSH_GUARD.active is set on the uploader
<br />thread, and asserts the record lands in the next batch (not dropped).
<br />Documents that the thread-local guard only blocks recursive emits on
<br />the uploader thread itself.</p>
<p>* refactor(config): use store_const + mutually exclusive group for log-upload flags</p>
<p>--upload-logs and --no-upload-logs now share dest='upload_logs' via
<br />store_const (True/False) in an argparse mutually exclusive group.
<br />argparse handles the conflict natively; drop the manual mutex check
<br />and the tri-state mapping in from_args. args.upload_logs is now
<br />Optional[bool] directly.</p>
<p>The undocumented --upload_logs / --no_upload_logs snake_case aliases
<br />are dropped (introduced earlier in this same unreleased branch; no
<br />users to break).</p>
<p>* refactor: push upload_logs tri-state down to the API boundary</p>
<p>- register_cli_run now takes upload_logs: Optional[bool] directly and
<br /> projects to share_logs/decline_logs only when building the JSON
<br /> payload. The invalid (share=True, decline=True) state is now
<br /> unrepresentable above the wire boundary.
<br />- StreamingLogs.__init__ takes upload_logs instead of the two
<br /> booleans; the call site in socketcli.py just passes
<br /> config.upload_logs through.
<br />- Drop the setup_streaming alias; call sites use StreamingLogs
<br /> directly.
<br />- Drop the dead 'except SystemExit: raise' in cli() — re-raising is
<br /> the default for an unhandled exception path.
<br />- Tests updated for the new signatures.</p>
<p>* fix(cli_run): broaden register exception handling to honor 'never break the scan'</p>
<p>The earlier register_cli_run only caught APIFailure on the request and
<br />ValueError/JSONDecodeError on resp.json(). If the server returned JSON
<br />that parsed but wasn't an object (e.g. a list), body.get(...) would
<br />raise AttributeError and propagate out of StreamingLogs.__enter__,
<br />crashing the CLI before the scan even starts.</p>
<p>Collapse the request + parse + field-extraction into a single try with
<br />a broad except so any unexpected failure — known or otherwise — falls
<br />back to no-streaming, matching the module docstring's promise.</p>
<p>Add regression tests for non-dict JSON bodies and arbitrary unexpected
<br />exceptions from client.request.</p>barslevtag:github.com,2008:Repository/802230750/v2.4.82026-06-10T12:00:35Zv2.4.8<p>Retry transient full-scan upload failures (502/503/504/408, dropped c…</p>
<p>…onnections) (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/232">#232</a>)</p>
<p>* Retry transient full-scan upload failures (502/503/504/408, dropped connections)</p>
<p>A full-scan upload can fail transiently at the gateway/connection level -
<br />an HTTP 502/503/504/408, a dropped or reset connection, or a client-side
<br />timeout - without the server having created the scan. The CLI previously
<br />made exactly one attempt, so an entire run (including a completed
<br />reachability analysis) died on a single transient failure even though a
<br />retried upload almost always succeeds.</p>
<p>create_full_scan now retries the fullscans POST up to 3 total attempts with
<br />increasing waits (~10s, then ~30s, plus jitter) on transient failures only:
<br />APIBadGateway (502), APIConnectionError, APITimeout, and catch-all APIFailure
<br />whose embedded original_status_code is 408/503/504. Dedicated 4xx classes,
<br />catch-all 400s, and error payloads are never retried. In these failure modes
<br />the server never finished reading the request body, so no scan was created
<br />and a retry does not duplicate one; in the rare case where a gateway timeout
<br />races a request the server later completes, the extra scan is benign and
<br />superseded by the retry (as if the CLI had run twice).</p>
<p>The retry loop lives inside the existing try/finally so the brotli-compressed
<br />.socket.facts.json.br temp files survive until every attempt has finished;
<br />fullscans.post rebuilds its lazy file loaders from the plain paths on every
<br />call, so re-invoking it per attempt is safe.</p>
<p>Assisted-by: Claude Code:claude-opus-4-8</p>
<p>* docs: drop the 'retry almost always succeeds' claim from retry comments</p>
<p>* Move transient-error classification into the SDK; simplify retry loop</p>
<p>Address review feedback on the upload retry:</p>
<p>- The retry decision now delegates to APIFailure.is_transient_error()
<br /> (socketdev>=3.3.0, <a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-sdk-python/pull/93">SocketDev/socket-sdk-python#93</a>), which classifies
<br /> by the HTTP status code the SDK records when raising. The CLI no
<br /> longer encodes the SDK's exception hierarchy or parses status codes
<br /> out of message text, so SDK restructuring can't silently break the
<br /> classification.
<br />- The backoff schedule is now the single source of truth for the loop:
<br /> FULL_SCAN_UPLOAD_BACKOFF_SCHEDULE_SECONDS = (10.0, 30.0, None), where
<br /> each entry is the wait before the next attempt and the final None
<br /> re-raises instead of retrying. FULL_SCAN_UPLOAD_MAX_ATTEMPTS is
<br /> computed from its length.</p>
<p>Note: uv.lock is intentionally not regenerated yet - socketdev 3.3.0
<br />must be released to PyPI first (blocked on socket-sdk-python#93).</p>
<p>* Lock socketdev 3.3.0</p>
<p>socketdev 3.3.0 is now released, unblocking the >=3.3.0 floor bump.</p>mtorptag:github.com,2008:Repository/802230750/v2.4.72026-06-09T12:23:07Zv2.4.7<p>Pin @coana-tech/cli version; make reachability auto-update opt-in (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/230">#230</a>)</p>
<p>* Pin @coana-tech/cli version; make reachability auto-update opt-in</p>
<p>The Python CLI auto-updated the reachability (Coana) engine to the latest
<br />published version on every --reach run via `npm install -g @coana-tech/cli`.
<br />Automatically pulling a brand-new engine version without opting in is
<br />undesirable for environments that need to review/approve dependency updates
<br />before adopting them.</p>
<p>Run a fixed, pinned version (DEFAULT_COANA_CLI_VERSION = 15.3.22) via
<br />`npx @coana-tech/cli@<pinned>` instead, so the engine version only changes
<br />through a standard pip upgrade of this CLI. Opt into newest with
<br />`--reach-version latest`; pin an explicit version with `--reach-version <semver>`.
<br />The global `npm install -g` step is dropped entirely, so an existing global
<br />install is never auto-updated or downgraded.</p>
<p>* Disable npx caching and add npm-install + node fallback for coana</p>
<p>Mirror the Socket Node CLI's coana launcher:
<br />- Run the engine via `npx --yes --force` so the npx cache is bypassed; a
<br /> corrupt or partial cache entry can no longer wedge a reachability run.
<br />- Fall back to `npm install --no-save --prefix <tmp> @coana-tech/cli@<ver>`
<br /> + `node <bin>` when the npx launcher is missing or dies before coana starts
<br /> (spawn error / signal / exit >= 128). Small positive exit codes are treated
<br /> as real coana failures and are not retried.
<br />- Toggle with SOCKET_CLI_COANA_FORCE_NPM_INSTALL and SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK.
<br />- Strip npm_package_* env vars before spawning coana to avoid E2BIG in large monorepos.</p>
<p>Kept on version 2.4.7 (same unreleased version as the pin change).</p>
<p>* Bump pinned @coana-tech/cli to 15.3.24</p>
<p>* Address PR review: per-version fallback cache, node prereq, accurate npx wording</p>
<p>- M2: cache the npm-install fallback's resolved script path per version for the
<br /> process lifetime (mirrors the Node CLI's installedCoanaScriptPathsByVersion), so a
<br /> repeated fallback installs once instead of re-installing + leaking a temp dir each call.
<br />- M3: surface a clear error when `node` is missing in the fallback (instead of an opaque
<br /> FileNotFoundError after a costly npm install), and add `node` to the up-front prereq check.
<br />- M1: correct the overstated 'npx --force disables the cache' wording in docstrings, docs,
<br /> and CHANGELOG. The code already matches the Node CLI exactly (npx --yes --force); --force
<br /> does not force a re-download of an already-cached pinned version, so the docs now describe
<br /> what the flags actually do rather than claiming a cache bypass.</p>
<p>Adds tests for per-version caching, node-missing, and real _resolve_coana_bin /
<br />_build_coana_node_cmd parsing.</p>
<p>* Address review comments: Final annotation, atexit tmp cleanup, parametrized tests</p>
<p>- Annotate DEFAULT_COANA_CLI_VERSION with typing.Final.
<br />- Register an atexit handler to remove the npm-install fallback's temp dirs.
<br />- Trim the over-long --force explanation in _spawn_coana's docstring and drop the
<br /> inline comment that duplicated it.
<br />- Use try/finally in the cache-clearing test fixture.
<br />- Parametrize the spec-resolution, npx-version, and launcher-failure-heuristic tests.</p>
<p>* Move launch-strategy rationale from the spec resolver to _spawn_coana</p>
<p>The 'why npx, not npm install -g' explanation describes how coana is launched, not
<br />how a package spec string is built, so it belongs on _spawn_coana (per review). Leaves
<br />_resolve_coana_package_spec with a minimal docstring.</p>
<p>* docs: show the real --reach-version default (15.3.24) in the Default column</p>
<p>* docs: show real reach-flag defaults from the Coana CLI implementation</p>
<p>Fill in the Default column for the flags whose defaults come from coana, verified
<br />against the @coana-tech/cli source (coana-package-manager/packages/cli):
<br />- --reach-analysis-timeout -> 600 (cli-core.ts: defaults to 600s when unset)
<br />- --reach-analysis-memory-limit -> 8192 (index.ts --memory-limit default)
<br />- --reach-concurrency -> 1 (index.ts --concurrency default)
<br />- --reach-min-severity -> info (no coana default = analyze all; info is the effective floor)</p>mtorptag:github.com,2008:Repository/802230750/v2.4.62026-06-04T07:07:31Zv2.4.6<p>docs: correct remaining reachability reference gaps (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/228">#228</a>)</p>
<p>Reachability-reference fixes layered on current main (v2.4.5):</p>
<p>- Document the uv + Enterprise-plan prerequisites the CLI enforces before
<br /> running reachability (exit 3), and that per-ecosystem build toolchains are
<br /> the analysis engine's runtime check, not a CLI pre-check.
<br />- Correct --reach-min-severity values to info/low/moderate/high/critical.
<br />- Document --reach-enable-analysis-splitting, --reach-detailed-analysis-log-file,
<br /> --reach-lazy-mode, --reach-use-only-pregenerated-sboms.
<br />- Clarify --only-facts-file submits only the facts file when creating the full
<br /> scan (no pre-existing scan required).
<br />- Note --reach creates a tier-1 full-application scan (scan_type=socket_tier1).</p>
<p>Docs-only; the version bump + uv.lock are mandated by the sync-version hook.</p>mtorptag:github.com,2008:Repository/802230750/v2.4.52026-06-03T19:38:44Zv2.4.5<p>Harden dependency review checks across PR types (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/224">#224</a>)</p>
<p>* ci: report e2e-* checks on fork and Dependabot PRs</p>
<p>The e2e job is skipped on PRs that can't access repository secrets
<br />(forks and Dependabot). Because it's skipped via a job-level `if`, its
<br />matrix never expands, so the required e2e-* check contexts are never
<br />created and branch protection waits on them indefinitely, blocking merge.</p>
<p>Add an e2e-bypass job whose `if` is the exact negation of the e2e job's
<br />run condition. It emits the same e2e-* check names with a passing status
<br />for fork/Dependabot PRs, satisfying branch protection without running the
<br />real tests. The two jobs are mutually exclusive and exhaustive: every PR
<br />runs exactly one.</p>
<p>Signed-off-by: lelia <[email protected]></p>
<p>* ci: add dependency-review-gate aggregator check</p>
<p>The Socket Firewall enterprise smoke job is the most meaningful supply-chain
<br />check for maintainer-added dependencies, but it can't be required directly:
<br />it's conditional (per-manifest, and free-vs-enterprise per author), so on most
<br />PRs it's legitimately skipped -- and a required check whose job is skipped sits
<br />at "Expected -- Waiting for status" forever, blocking merge (the same trap
<br />that stranded Dependabot PRs on the e2e-* checks).</p>
<p>Add a dependency-review-gate job that always runs and collapses every smoke
<br />job into one pass/fail signal: it fails iff any job that ran ended in failure
<br />or was cancelled; success and skipped both pass. This is the single check
<br />intended to be marked required later -- it satisfies Dependabot/fork PRs (which
<br />run Firewall-free) and maintainer PRs (Firewall-enterprise) alike, and turns a
<br />Socket Firewall BLOCK into a merge-blocking failure instead of a non-required
<br />job nobody is forced to run.</p>
<p>Scaffolding only: the gate is not yet added to branch protection's required
<br />checks (deferred until it's merged to main and observed reporting).</p>
<p>Signed-off-by: lelia <[email protected]></p>
<p>* chore: bump CLI to 2.4.5 and require socketdev>=3.2.1</p>
<p>Follows the 2.4.4 release (SDK >=3.2.0) by picking up socketdev 3.2.1.
<br />Regenerates uv.lock to the published 3.2.1 release; no CLI logic changes.</p>
<p>Signed-off-by: lelia <[email protected]></p>
<p>---------</p>
<p>Signed-off-by: lelia <[email protected]></p>leliatag:github.com,2008:Repository/802230750/v2.4.42026-06-03T17:55:33Zv2.4.4<p>chore(deps): bump socketdev floor to >=3.2.0 (<a class="issue-link js-issue-link notranslate" href="https://linear.app/socketdev/issue/CE-225">CE-225</a>) (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/222">#222</a>)</p>
<p>Pick up socketdev 3.2.0, which adds OTHER = "other" to SocketCategory
<br />so the backend's "other" alert category no longer triggers the
<br />"Unknown SocketCategory" warning fallback (SDK PR <a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/85">#85</a>). No CLI logic
<br />changes. Bump CLI to 2.4.1 (on top of the 2.4.0 license-details fix).</p>
<p>uv.lock regenerated against socketdev 3.2.0.</p>
<p>Signed-off-by: lelia <[email protected]></p>leliatag:github.com,2008:Repository/802230750/v2.4.32026-06-03T17:23:07Zv2.4.3<p>feat(reach): add unified --exclude-paths, deprecate --reach-exclude-p…</p>
<p>…aths (<a class="issue-link js-issue-link" href="https://github.com/SocketDev/socket-python-cli/pull/227">#227</a>)</p>
<p>Add a single --exclude-paths flag (Node CLI parity) that filters BOTH SCA manifest
<br />discovery and reachability analysis:</p>
<p>- New Core matcher: anchored micromatch-style globs compiled to regex (no new deps).
<br /> Scan-root-relative POSIX paths, '*' does not cross '/', '**' does, each pattern P
<br /> expanded to [P, P/**]. Threaded into find_files via cli_config; no-op when unset.
<br />- Reach side unions --exclude-paths with the now-deprecated --reach-exclude-paths and
<br /> forwards to coana --exclude-dirs.
<br />- Validation mirrors Node's assertValidExcludePaths (rejects negation, absolute paths,
<br /> '..' traversal, degenerate match-everything; trailing slash stripped so '**/' is rejected).
<br /> Accepts comma-strings and config-file lists.
<br />- --reach-exclude-paths soft-deprecated: still works, [DEPRECATED] in help, warns at runtime.</p>
<p>Docs: document --exclude-paths under 'Path and File' (it affects every scan, not just
<br />reach), mark --reach-exclude-paths deprecated, and refresh the reachability flag table
<br />(--reach-analysis-timeout/-memory-limit primary names, --reach-debug,
<br />--reach-disable-external-tool-checks, defaults delegated to coana).</p>
<p>Adds a CHANGELOG 2.4.3 entry and tests incl. the Node parity cases, validation, and config-file paths.</p>mtorp