tag:github.com,2008:https://github.com/SocketDev/socket-python-cli/releases Tags from socket-python-cli 2026-06-19T12:47:22Z tag:github.com,2008:Repository/802230750/v2.4.12 2026-06-19T12:47:55Z v2.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> mtorp tag:github.com,2008:Repository/802230750/v2.4.11 2026-06-19T07:28:27Z v2.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> mtorp tag:github.com,2008:Repository/802230750/v2.4.10 2026-06-12T21:43:50Z v2.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 &lt;[email protected]&gt;</p> lelia tag:github.com,2008:Repository/802230750/v2.4.9 2026-06-12T08:22:53Z v2.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: &lt;uuid|null&gt; }. <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> barslev tag:github.com,2008:Repository/802230750/v2.4.8 2026-06-10T12:00:35Z v2.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&gt;=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 &gt;=3.3.0 floor bump.</p> mtorp tag:github.com,2008:Repository/802230750/v2.4.7 2026-06-09T12:23:07Z v2.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@&lt;pinned&gt;` 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 &lt;semver&gt;`. <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 &lt;tmp&gt; @coana-tech/cli@&lt;ver&gt;` <br /> + `node &lt;bin&gt;` when the npx launcher is missing or dies before coana starts <br /> (spawn error / signal / exit &gt;= 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 -&gt; 600 (cli-core.ts: defaults to 600s when unset) <br />- --reach-analysis-memory-limit -&gt; 8192 (index.ts --memory-limit default) <br />- --reach-concurrency -&gt; 1 (index.ts --concurrency default) <br />- --reach-min-severity -&gt; info (no coana default = analyze all; info is the effective floor)</p> mtorp tag:github.com,2008:Repository/802230750/v2.4.6 2026-06-04T07:07:31Z v2.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> mtorp tag:github.com,2008:Repository/802230750/v2.4.5 2026-06-03T19:38:44Z v2.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 &lt;[email protected]&gt;</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 &lt;[email protected]&gt;</p> <p>* chore: bump CLI to 2.4.5 and require socketdev&gt;=3.2.1</p> <p>Follows the 2.4.4 release (SDK &gt;=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 &lt;[email protected]&gt;</p> <p>---------</p> <p>Signed-off-by: lelia &lt;[email protected]&gt;</p> lelia tag:github.com,2008:Repository/802230750/v2.4.4 2026-06-03T17:55:33Z v2.4.4 <p>chore(deps): bump socketdev floor to &gt;=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 &lt;[email protected]&gt;</p> lelia tag:github.com,2008:Repository/802230750/v2.4.3 2026-06-03T17:23:07Z v2.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