From c809dc7989a6e6a6d8421e4d3fc41ddd0f2c64ec Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 28 Jul 2026 14:51:05 +0000 Subject: [PATCH 1/4] docs: add Cursor Cloud environment setup notes Co-authored-by: Ben Durrans --- AGENTS.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index a263bd4f56..79e96b0cc0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -310,3 +310,44 @@ extension/ - ❌ Domain logic inside the callback — extract into domain packages - ❌ Passing `InvocationContext` into domain code — pass concrete values - ❌ Deep workflow call chains — keep composition flat + +## Cursor Cloud specific instructions + +Durable, non-obvious notes for agents running in the Cursor Cloud Linux VM. The +update script already runs `npm ci` (root) and `go mod download` (`cliv2/`); the +items below are setup context and gotchas, not install steps to repeat. + +- **Node/npm come from nvm, not `/exec-daemon/node`.** `/exec-daemon/node` is + first on `PATH` but ships **no npm**, and the preinstalled nvm `v22.22.2` has a + corrupted npm. Use the clean `v22.22.3` (matches `.nvmrc`) with `npm@11.12.1` + (root `.npmrc` sets `engine-strict=true`). **Always prepend** + `PATH="$HOME/.nvm/versions/node/v22.22.3/bin:$PATH"` before any `npm`/`make build` + — nvm is not auto-sourced in non-interactive shells and `nvm use` alone does not + beat `/exec-daemon/node`. +- **Go toolchain — pin the exact patch.** `cliv2/go.mod` needs Go 1.26.x; with + `GOTOOLCHAIN=auto` Go tries the **blocked** `go.dev`. Keep + `GOTOOLCHAIN=go1.26.5` set (`go env -w GOTOOLCHAIN=go1.26.5`). +- **Build public mode.** `cliv2-private/` is inaccessible here, so build with + `make build BUILD_MODE=public`. `convco` (a build dep from the Brewfile, not on + Linux) must be on `PATH`; install the `v0.7.0` musl release from GitHub into + `/usr/local/bin`. The `library.go:101` asm warnings during build are harmless. +- **go.dev license workaround.** `make build` runs `cliv2/scripts/prepare_licenses.go`, + which (a) `go-licenses save --force` regenerates `cliv2/internal/embedded/_data/licenses/`, + then (b) downloads a few manual licenses — including `go.dev`'s, from the + **blocked** `go.dev`. Because `--force` wipes the tree first, pre-placing the + file before the build does not survive. Instead let the build run once so the + tree is generated, then place the file from the reachable GitHub mirror and + stamp the make target so the step is skipped next time: + `curl -fsSL -o cliv2/internal/embedded/_data/licenses/go.dev/LICENSE https://raw.githubusercontent.com/golang/go/master/LICENSE` + then `echo done > cliv2/_cache/prepare-3rd-party-licenses` (the target has no + prerequisites, so its mere presence makes `make` skip license prep). Both paths + are gitignored. +- **Standard commands** are in [Running Tests](#running-tests) / [Running the CLI + Locally](#running-the-cli-locally). On Linux the built binary is + `./binary-releases/snyk-linux`. Verified green here: `cd cliv2 && go test ./pkg/... ./internal/...`; + `npx jest --runInBand test/jest/unit/lib/formatters` (120 pass); + `TEST_SNYK_COMMAND=./binary-releases/snyk-linux npx jest --runInBand test/jest/acceptance/snyk-test/all-projects.spec.ts` (20 pass, fake-server). +- **Some acceptance specs hit real registries** (e.g. `basic-test-all-languages`) + and fail under restricted egress; `all-projects.spec.ts` is fake-server-only and + is a clean demo. **Reachable:** `proxy.golang.org`, `github.com`, + `raw.githubusercontent.com`, `registry.npmjs.org`. **Blocked:** `go.dev`. From 5d8b01f1296c0d9fa5322e7b00346e2b23820b50 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 28 Jul 2026 14:56:41 +0000 Subject: [PATCH 2/4] docs: note cli lint tooling gotcha for Cursor Cloud Co-authored-by: Ben Durrans --- AGENTS.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 79e96b0cc0..aa143f0dca 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -347,6 +347,14 @@ items below are setup context and gotchas, not install steps to repeat. `./binary-releases/snyk-linux`. Verified green here: `cd cliv2 && go test ./pkg/... ./internal/...`; `npx jest --runInBand test/jest/unit/lib/formatters` (120 pass); `TEST_SNYK_COMMAND=./binary-releases/snyk-linux npx jest --runInBand test/jest/acceptance/snyk-test/all-projects.spec.ts` (20 pass, fake-server). +- **Lint gotcha.** `make lint` runs `npm run lint` (TS eslint) then + `cd cliv2 && make lint`. In `cliv2`, `TOOLS_BIN` is empty, so the `make lint` + prerequisite `$(TOOLS_BIN)/golangci-lint` resolves to a missing `/golangci-lint` + and re-triggers the curl-based installer. Note `cliv2` pins golangci-lint + **v2.9.0** (the root Go repos use v2.10.1). To avoid the installer, put v2.9.0 in + `cliv2/.bin/` (`GOBIN=$(pwd)/.bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.9.0`) + and run the linters directly: `npm run lint` and `cd cliv2 && ./.bin/golangci-lint run ./...` + (both report `0 issues` here). - **Some acceptance specs hit real registries** (e.g. `basic-test-all-languages`) and fail under restricted egress; `all-projects.spec.ts` is fake-server-only and is a clean demo. **Reachable:** `proxy.golang.org`, `github.com`, From a0a45047a1ee0021a1849894726eab876008174d Mon Sep 17 00:00:00 2001 From: Ben Durrans Date: Thu, 30 Jul 2026 10:54:07 +0100 Subject: [PATCH 3/4] docs: refresh Cursor Cloud setup notes Consolidates the two duplicate cloud-setup notes into this branch, keeping the more complete account of the license-prep workaround: because go-licenses runs with --force and wipes the tree, the Go LICENSE has to be placed after a build rather than before it, then the make target stamped. Verifies the claims against the checked-in Makefile: TOOLS_BIN is never assigned in cliv2/Makefile, so the golangci-lint prerequisite re-triggers the installer, and cliv2 pins v2.9.0 while the other Go repos use v2.10.1. Replaces the fixed reachable/blocked host list with guidance to probe egress directly, since the allowlist changes between runs. Co-authored-by: Cursor --- AGENTS.md | 101 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index aa143f0dca..6fb8dc7e91 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -314,48 +314,61 @@ extension/ ## Cursor Cloud specific instructions Durable, non-obvious notes for agents running in the Cursor Cloud Linux VM. The -update script already runs `npm ci` (root) and `go mod download` (`cliv2/`); the -items below are setup context and gotchas, not install steps to repeat. - -- **Node/npm come from nvm, not `/exec-daemon/node`.** `/exec-daemon/node` is - first on `PATH` but ships **no npm**, and the preinstalled nvm `v22.22.2` has a - corrupted npm. Use the clean `v22.22.3` (matches `.nvmrc`) with `npm@11.12.1` - (root `.npmrc` sets `engine-strict=true`). **Always prepend** - `PATH="$HOME/.nvm/versions/node/v22.22.3/bin:$PATH"` before any `npm`/`make build` - — nvm is not auto-sourced in non-interactive shells and `nvm use` alone does not - beat `/exec-daemon/node`. -- **Go toolchain — pin the exact patch.** `cliv2/go.mod` needs Go 1.26.x; with - `GOTOOLCHAIN=auto` Go tries the **blocked** `go.dev`. Keep - `GOTOOLCHAIN=go1.26.5` set (`go env -w GOTOOLCHAIN=go1.26.5`). -- **Build public mode.** `cliv2-private/` is inaccessible here, so build with - `make build BUILD_MODE=public`. `convco` (a build dep from the Brewfile, not on - Linux) must be on `PATH`; install the `v0.7.0` musl release from GitHub into - `/usr/local/bin`. The `library.go:101` asm warnings during build are harmless. -- **go.dev license workaround.** `make build` runs `cliv2/scripts/prepare_licenses.go`, - which (a) `go-licenses save --force` regenerates `cliv2/internal/embedded/_data/licenses/`, - then (b) downloads a few manual licenses — including `go.dev`'s, from the - **blocked** `go.dev`. Because `--force` wipes the tree first, pre-placing the - file before the build does not survive. Instead let the build run once so the - tree is generated, then place the file from the reachable GitHub mirror and - stamp the make target so the step is skipped next time: +update script already runs `npm ci` (root) and `go mod download` (`cliv2/`), so +the items below are setup context and gotchas rather than install steps to +repeat. + +- **Node and npm come from nvm, not `/exec-daemon/node`.** `/exec-daemon/node` is + first on `PATH` but ships **no npm**. Use `v22.22.3` (the `.nvmrc` version) with + `npm@11.12.1`: the root `.npmrc` sets `engine-strict=true` against + `"npm": "^11.12.1"`, so an older npm fails `npm ci` outright. **Always prepend** + `PATH="$HOME/.nvm/versions/node/v22.22.3/bin:$PATH"` before any `npm` or + `make build` — nvm is not auto-sourced in non-interactive shells, and `nvm use` + alone does not win against `/exec-daemon/node`. +- **Pin the exact Go patch version.** `cliv2/go.mod` needs Go 1.26.x, and with + `GOTOOLCHAIN=auto` Go resolves the toolchain from `go.dev`, which is normally + outside the egress allowlist. Keep `GOTOOLCHAIN=go1.26.5` set + (`go env -w GOTOOLCHAIN=go1.26.5`) so it comes from `proxy.golang.org` instead. +- **Build in public mode.** `cliv2-private/` is inaccessible here, so use + `make build BUILD_MODE=public`. `convco` is a Brewfile dependency with no Linux + install path and the build fails at the version step without it — install the + `v0.7.0` musl release from GitHub into `/usr/local/bin`. The `library.go:101` + asm warnings during the build are harmless. On Linux the output binary is + `./binary-releases/snyk-linux`. +- **The license step re-downloads from `go.dev`, and pre-placing the file does not + survive.** `make build` runs `cliv2/scripts/prepare_licenses.go`, which first has + `go-licenses save --force` regenerate `cliv2/internal/embedded/_data/licenses/` + (wiping the tree) and only then fetches a handful of manual licenses, including + Go's own from `go.dev`. So place the file *after* a build has generated the tree, + then stamp the make target so the step is skipped next time: `curl -fsSL -o cliv2/internal/embedded/_data/licenses/go.dev/LICENSE https://raw.githubusercontent.com/golang/go/master/LICENSE` - then `echo done > cliv2/_cache/prepare-3rd-party-licenses` (the target has no - prerequisites, so its mere presence makes `make` skip license prep). Both paths - are gitignored. -- **Standard commands** are in [Running Tests](#running-tests) / [Running the CLI - Locally](#running-the-cli-locally). On Linux the built binary is - `./binary-releases/snyk-linux`. Verified green here: `cd cliv2 && go test ./pkg/... ./internal/...`; - `npx jest --runInBand test/jest/unit/lib/formatters` (120 pass); - `TEST_SNYK_COMMAND=./binary-releases/snyk-linux npx jest --runInBand test/jest/acceptance/snyk-test/all-projects.spec.ts` (20 pass, fake-server). -- **Lint gotcha.** `make lint` runs `npm run lint` (TS eslint) then - `cd cliv2 && make lint`. In `cliv2`, `TOOLS_BIN` is empty, so the `make lint` - prerequisite `$(TOOLS_BIN)/golangci-lint` resolves to a missing `/golangci-lint` - and re-triggers the curl-based installer. Note `cliv2` pins golangci-lint - **v2.9.0** (the root Go repos use v2.10.1). To avoid the installer, put v2.9.0 in - `cliv2/.bin/` (`GOBIN=$(pwd)/.bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.9.0`) - and run the linters directly: `npm run lint` and `cd cliv2 && ./.bin/golangci-lint run ./...` - (both report `0 issues` here). -- **Some acceptance specs hit real registries** (e.g. `basic-test-all-languages`) - and fail under restricted egress; `all-projects.spec.ts` is fake-server-only and - is a clean demo. **Reachable:** `proxy.golang.org`, `github.com`, - `raw.githubusercontent.com`, `registry.npmjs.org`. **Blocked:** `go.dev`. + followed by `echo done > cliv2/_cache/prepare-3rd-party-licenses`. That target + (`cliv2/Makefile`) has no prerequisites, so the file's mere presence makes `make` + skip license prep. Both paths are gitignored. +- **`make lint` re-triggers the golangci-lint installer.** `cliv2/Makefile` never + assigns `TOOLS_BIN`, so the `$(TOOLS_BIN)/golangci-lint` prerequisite resolves to + a missing `/golangci-lint` and runs the curl-based installer every time. Note + `cliv2` pins **v2.9.0** (`OVERRIDE_GOCI_LINT_V`) while the other Snyk Go repos + use v2.10.1. Install it once into the directory the Makefile uses as `GO_BIN`: + `cd cliv2 && GOBIN=$(pwd)/.bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.9.0`, + then run the linters directly — `npm run lint` and + `cd cliv2 && ./.bin/golangci-lint run ./...` (both reported `0 issues` here). +- **Verified green in this environment:** `cd cliv2 && go test ./pkg/... ./internal/...`; + `npx jest --runInBand test/jest/unit/lib/formatters` (120 pass); and + `TEST_SNYK_COMMAND=./binary-releases/snyk-linux npx jest --runInBand test/jest/acceptance/snyk-test/all-projects.spec.ts` + (20 pass). See [Running Tests](#running-tests) and [Running the CLI + Locally](#running-the-cli-locally) for the full command set. +- **Some acceptance specs reach real package registries** (e.g. + `basic-test-all-languages`) and fail under restricted egress — an environment + limit, not a regression. `all-projects.spec.ts` runs entirely against the fake + server and is the clean smoke test. +- **Probe egress instead of trusting a host list.** The allowlist changes between + runs, so treat any reachable/blocked list — including in older revisions of this + section — as stale. Matching is per hostname, and a bare entry is apex-exact + while `*.example.com` covers subdomains only, so an apex host has to be + allowlisted in its own right. A block surfaces as a TLS reset mid-handshake + rather than a DNS failure, so check a host directly before concluding anything: + `timeout 12 openssl s_client -connect go.dev:443 -servername go.dev Date: Fri, 4 Sep 2026 10:50:35 +0000 Subject: [PATCH 4/4] docs: note local-only go.mod replace for snyk-ls testing Clarify that replace directives in cliv2/go.mod are for local builds only, with an example for bundling snyk-ls when testing IDE fixes. Co-authored-by: benjamin.durrans --- AGENTS.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 0879519124..f6426b505f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -279,6 +279,16 @@ make tidy replace github.com/snyk/cli-extension-foo => ../../cli-extension-foo ``` +**Local testing only.** `replace` directives in `cliv2/go.mod` are for building and testing against local clones on your machine. Do **not** commit active `replace` lines to `main` — they are not portable across machines and are not how dependencies ship. For CI or shared branches, use a temporary commit SHA in `require` (see [Changing the Code](#changing-the-code)) or a dedicated dev branch that you do not merge. Before opening a PR, remove any `replace` lines and run `make tidy` so `go.mod`/`go.sum` reflect published module versions. + +Example for IDE work that bundles `snyk-ls` (e.g. testing an LS fix in VS Code via the CLI): + +```go +replace github.com/snyk/snyk-ls => ../../snyk-ls +``` + +Then `make build` — the CLI embeds the local LS. Point the IDE at `binary-releases/snyk-linux`, not at a standalone `snyk-ls` binary. + **TypeScript** — update `package.json`, then `npm install` and temporarily commit: ```json