Skip to content

chore(deps): bump esbuild and vite in /server/dashboard#37

Open
dependabot[bot] wants to merge 42 commits into
mainfrom
dependabot/npm_and_yarn/server/dashboard/multi-64f29988ee
Open

chore(deps): bump esbuild and vite in /server/dashboard#37
dependabot[bot] wants to merge 42 commits into
mainfrom
dependabot/npm_and_yarn/server/dashboard/multi-64f29988ee

Conversation

@dependabot
Copy link
Copy Markdown
Contributor

@dependabot dependabot Bot commented on behalf of github May 11, 2026

Removes esbuild. It's no longer used after updating ancestor dependency vite. These dependencies need to be updated together.

Removes esbuild

Updates vite from 5.4.21 to 8.0.12

Release notes

Sourced from vite's releases.

v8.0.12

Please refer to CHANGELOG.md for details.

v8.0.11

Please refer to CHANGELOG.md for details.

v8.0.10

Please refer to CHANGELOG.md for details.

v8.0.9

Please refer to CHANGELOG.md for details.

v8.0.8

Please refer to CHANGELOG.md for details.

v8.0.7

Please refer to CHANGELOG.md for details.

v8.0.6

Please refer to CHANGELOG.md for details.

v8.0.5

Please refer to CHANGELOG.md for details.

v8.0.4

Please refer to CHANGELOG.md for details.

create-vite@8.0.3

Please refer to CHANGELOG.md for details.

v8.0.3

Please refer to CHANGELOG.md for details.

create-vite@8.0.2

Please refer to CHANGELOG.md for details.

v8.0.2

Please refer to CHANGELOG.md for details.

create-vite@8.0.1

Please refer to CHANGELOG.md for details.

v8.0.1

Please refer to CHANGELOG.md for details.

plugin-legacy@8.0.1

Please refer to CHANGELOG.md for details.

create-vite@8.0.0

Please refer to CHANGELOG.md for details.

... (truncated)

Changelog

Sourced from vite's changelog.

8.0.12 (2026-05-11)

Features

Bug Fixes

  • deps: update all non-major dependencies (#22420) (2be6000)
  • module-runner: prevent partial-exports race on concurrent imports of in-flight invalidated re-export chains (#22369) (f5a22e6)
  • refer to rolldownOptions instead of deprecated rollupOptions in messages (#22400) (b675c7b)
  • worker: apply build.target to worker bundle (#22404) (3c93fde)
  • worker: forward define to worker bundle transform (#22408) (d4838a0)

Miscellaneous Chores

8.0.11 (2026-05-07)

Features

Bug Fixes

  • deps: update all non-major dependencies (#22334) (672c962)
  • deps: update all non-major dependencies (#22382) (5c0cfcb)
  • glob: align hmr matcher options with glob enumeration (#22306) (30028f9)
  • make separate object instance for each environment (#22276) (7c2aa3b)

Documentation

Miscellaneous Chores

  • deps: update dependency tsdown to ^0.21.10 (#22333) (3b51e05)
  • deps: update rolldown-related dependencies (#22383) (555ff36)
  • deps: update transitive packages to fix npm audit alerts (#22316) (86aee62)

Code Refactoring

Tests

... (truncated)

Commits
  • 4dce8b4 release: v8.0.12
  • b675c7b fix: refer to rolldownOptions instead of deprecated rollupOptions in mess...
  • 66b9eb3 chore(deps): update rolldown-related dependencies (#22421)
  • 2fe7bd2 chore(deps): update dependency eslint-plugin-n to v18 (#22423)
  • 2be6000 fix(deps): update all non-major dependencies (#22420)
  • d4838a0 fix(worker): forward define to worker bundle transform (#22408)
  • cf0ff41 feat: update rolldown to 1.0.0 (#22401)
  • 3c93fde fix(worker): apply build.target to worker bundle (#22404)
  • f5a22e6 fix(module-runner): prevent partial-exports race on concurrent imports of in-...
  • 66f3194 release: v8.0.11
  • Additional commits viewable in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    You can disable automated security fix PRs for this repo from the Security Alerts page.

dvcdsys and others added 30 commits April 25, 2026 10:07
- cli/cmd/config.go (CodeQL go/clear-text-logging, alert #2):
  `cix config show` previously printed `cix_abcdef123456...wxyz` for
  configured keys (masked but still leaked first 12 + last 4 chars =
  half the entropy of a 32-char hex key). CodeQL flagged this as
  clear-text logging of sensitive data.

  Replace masked rendering with length-only metadata
  ("(set, N chars)"). Users who need the actual value can read
  ~/.cix/config.yaml directly; the show command's job is to verify
  that the value is configured, not to disclose it.

- .github/workflows/ci-go.yml (CodeQL go/missing-permissions, alert #11):
  Workflow had no permissions block, so it inherited the full
  GITHUB_TOKEN scope of the repo. The job only runs vet/test/build —
  no writes, no SARIF, no publishes — so a `permissions: contents: read`
  block is sufficient. Brings ci-go.yml in line with the other
  workflows (release-cli, release-server, security) which already
  pin permissions explicitly.

The 5 Trivy alerts on server/bench/go.mod auto-closed after 36c105c
added skip-dirs: server/bench to the trivy-action config.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous fix replaced masked-key display with "(set, %d chars)". CodeQL
still flagged it because len(cfg.API.Key) is a tainted-data access from
the secret field — the taint propagates through Sprintf to the Printf
sink even though the actual bytes never reach the log.

Render binary state only — "(set)" / "(not set)". No data derived from
the key bytes (not even length) reaches the logging sink, so the
go/clear-text-logging flow analysis has no source-to-sink path to
report.
Even after switching the value to a literal "(set)"/"(not set)",
CodeQL's go/clear-text-logging kept flagging the Printf because the
local variable was still NAMED `apiKey`. The query treats any
identifier matching the sensitive-name pattern (*Key, *Secret,
*Token, *Password, *Credentials) as a taint source, regardless of
what value it holds.

Renaming the local to `keyStatus` removes the name-based source
match. Combined with the previous binary "(set)/(not set)" change,
there is now neither a data-flow path nor a name match from the
secret to the logging sink.
- CLI releases move to cli/v* tag namespace (release-cli.yml)
- Add cix version command and --version flag (root.go, version.go)
- install.sh: filter cli/* releases, version-aware skip, --force, --help
- Rename ci-go.yml -> ci-server.yml; add ci-cli.yml (ubuntu+macos matrix)
- Standardize names across all 5 workflows (CI:/Release:/Security)
- Unify action versions; collapse release-cli build into single matrix job
- README: add CI badges, document tag scheme
Default setup auto-detected and scanned 8 languages, 6 of which were
false-positives (java-kotlin, ruby, rust, javascript-typescript,
c-cpp, python from legacy/). The matrix is now tightly scoped.

Requires manual action: disable Default CodeQL setup in repo Settings →
Code security → Code scanning. Otherwise both runs will execute in
parallel.
…bash regex fallback

Three related chunker improvements:

1. Language registry expansion. defaultRegistry now ships 30 languages
   (Tier A: Go/Python/JS/TS/TSX/Java/C/C++/Ruby/PHP/Rust; Tier B: C#/Swift/
   Kotlin/Scala/Haskell/Elixir/Erlang/OCaml/Lua/Bash/HTML/CSS/SQL/YAML/JSON
   /TOML/Markdown/Dockerfile/Make). Configurable via CIX_ENABLED_LANGUAGES.
   See doc/LANGUAGES.md.

2. Tree-sitter parse-budget guard. Bash grammar exhibits catastrophic
   backtracking on real-world scripts (31s on 7KB install.sh). Added
   parseBudget=2s with twin guards: SetTimeoutMicros + SetCancellationFlag
   armed by time.AfterFunc. On budget exceeded, falls back to chunkFallback().

3. Bash regex fallback. New bashRegexChunks() recognises the three common
   bash function forms (POSIX `name() {`, keyword `function name {`, with
   or without parens) and finds each function's closing brace via a state
   machine that handles single/double strings, comments, heredocs
   (<<EOF / <<-EOF / <<'EOF' / <<\"EOF\"), and here-strings (<<<).
   Module-type chunks fill gaps so top-level commands stay indexed.
   18 tests cover all forms + edge cases (nested braces, strings/comments
   with braces, install.sh repro, malformed/unbalanced).

extractName extended with `word`, `field_identifier`, `simple_identifier`,
`constant` so tree-sitter chunks for bash/Go-method/Swift/Kotlin/Ruby pick
up the symbol name instead of falling back to nil.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…index/files

Replaces the single-JSON response of POST /index/files with an NDJSON event
stream when the client sends Accept: application/x-ndjson. Solves three
real-world pain points seen on heavy batches (e.g. 20 files = 347 chunks =
165s on a single GPU slot):

* CLI no longer hits its 600s http.Client deadline on long batches —
  per-event keepalive plus a server-side 10s heartbeat ticker keep the
  connection alive arbitrarily long. New streamingClient on the CLI uses
  Timeout: 0 with a 60s idle-watchdog instead.
* Server now detects client disconnect mid-batch via r.Context().Done()
  and immediately calls CancelIndexing() to release the per-project session
  lock. Previously the lock survived until the 1h TTL.
* Per-file progress is visible during the batch (file_started, file_chunked,
  file_embedded, file_done events). Three render modes on the CLI:
  Interactive (TTY status line with CR), LineByLine (CI / non-TTY),
  Quiet (watcher — only summaries + file_error).

Backwards compatibility is asymmetric and intentional: server still serves
old clients (no Accept header → existing single-JSON path). New CLI hard-
fails with ErrLegacyServer if it gets back Content-Type: application/json,
because the operator's deploy workflow is server-first.

Wire format and event schema documented in server/internal/indexer/progress.go
and mirrored in cli/internal/client/progress.go.

SIGINT/SIGTERM in `cix reindex` now propagates via signal.NotifyContext —
HTTP request context cancels, server frees lock automatically. Belt-and-
braces deferred CancelIndex on error paths in indexer.Run() and watcher
Stop().

Tests:
* server/internal/httpapi/indexing_streaming_test.go — streaming happy
  path, disconnect-frees-lock (direct handler invocation with custom
  flushRecorder), legacy compat negotiation
* cli/internal/client/index_streaming_test.go — NDJSON parse, callback
  ordering, ErrLegacyServer hard-fail, idle timeout, retry on 503/429,
  back-compat SendFiles wrapper
* watcher tests updated to mock NDJSON responses

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…efile target

* New `cix cancel` command frees a stuck per-project session lock without
  having to wait for the 1h TTL. Pairs with the streaming-handler ctx-
  disconnect path: in normal use the lock auto-clears, this is the manual
  escape hatch.

* `cix summary` now groups "Top symbols" by language and shows up to N per
  language instead of one mixed list. Earlier output mixed Go/Python/JS
  symbols with no indication of which file they came from, which made the
  summary nearly useless on multi-language repos.

* server/Makefile: docker-build-cuda-dev target builds + pushes :cu128-dev
  for manual prod testing before tagging a release. Floating tag, no
  pinned variant — rollback isn't a concern for a dev tag.

* root Makefile: small build-target plumbing.

* doc/benchmark-cix-vs-grep.md: numbers from the search-vs-grep comparison
  done while debugging the install.sh hang. Tracked locally — not user
  documentation, more of an internal reference.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…s symbol metadata

Two related fixes that cleaned up search/cix-def output for repos with
markdown docs and long Go/Python functions:

1. Markdown registry. tree-sitter-markdown's `section` already wraps
   the heading + its body, so listing both \`section\` and \`atx_heading\`
   in the type-nodes config emitted duplicate one-line chunks for every
   \`### foo\` heading (visible as Type: type | 1-2 line snippets in
   `cix search` output). Drop \`atx_heading\` — keep only \`section\`.

2. splitChunk. When tree-sitter emitted a function chunk larger than
   maxChunkSize (default 4500 chars), splitChunk cut it into N pieces and
   set SymbolName/SymbolSignature/ChunkType=\"function\" on every piece.
   Result: cix def run returned N hits at different line ranges of the
   same function. Now only the FIRST piece carries the symbol metadata;
   subsequent pieces become anonymous \`block\` chunks. Full content of
   the symbol stays indexed for embed/FTS search — only the symbol-index
   attribution is consolidated.

Test: TestSplitChunk_OnlyFirstKeepsSymbol — fixture is a 2000-line Python
function, asserts exactly one chunk in the result claims symbol=big_func.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…b render

Tree-sitter emits nested chunks by design — a markdown H1 wraps its H2
sub-sections, a Go class wraps its methods, a Python module wraps its
classes. A vector search that hits the inner chunk also tends to hit (a
bit weaker) the outer chunk, and the user's --limit budget gets eaten
by N near-duplicates of the same code region. Same problem with
splitChunk leftovers when a long function is cut into pieces.

This change collapses overlapping results from the same file into a
single "outer" hit with the inner matches recorded as NestedHits. Two
merge cases:

1. Strict containment — A.range ⊋ B.range and same file → absorb B.
2. Same-symbol adjacent — adjacent ranges where at least one carries a
   symbol name → absorb (catches splitChunk piece1 + piece2 leftovers).

Cross-file results are NEVER merged. Exact duplicates (same range twice)
are not merged either — those should be deduped at the vector-store
layer (already are, via dedupByLocation).

Windowed retrieval: instead of over-fetching limit×2 once, the search
handler now retries with limit×2, ×4, ×8, ×16 if mergeOverlappingHits
collapses the result set below the user's --limit. Stops early when the
vector store returns fewer rows than asked (HNSW exhausted) or when the
factor cap is hit. In practice the first window is enough; the loop
exists for repos with deeply nested markdown or many class+method
hits inside the same files.

Server changes:
- New file search_merge.go — mergeOverlappingHits, shouldMerge.
- searchResultItem gains NestedHits []nestedHit (omitempty).
- semanticSearchHandler refactored: extract fetchVectorResults +
  filterToSearchItems helpers, wrap call in factor loop, drop the early
  break-on-limit (merge needs the full filtered set to identify
  overlaps).
- 10 unit tests for mergeOverlappingHits + 1 integration test
  (TestSemanticSearch_NestedMarkdownMerge) verifying nested H1/H2
  sections collapse to a single result with NestedHits populated.

CLI changes:
- SearchResult / NestedHit struct mirrors the server response.
- cix search render shows "+ N more match(es) inside:" with
  per-hit score/range/symbol so the user sees WHY the outer chunk
  ranks well even when the actual signal came from a sub-section.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…s inside

Changes the unit of search output from "chunk" to "file". Inspired by
how grep groups hits per file but with AST-aware match boundaries and
embedding-driven ranking.

Old wire shape: a flat list of chunks. A file with three matching
chunks ate three slots out of the user's --limit budget, scattered
across the result list, often with the file appearing at positions #3
and #10 simultaneously.

New wire shape:
  results: [
    {
      file_path, language, best_score,
      matches: [
        { start_line, end_line, score, content, chunk_type, symbol_name,
          nested_hits },
        ...
      ]
    }
  ]
  total: <distinct files>

Ranking:
* Files ordered by best_score (the highest match score in the group)
  descending.
* Inside each file, matches ordered by start_line ascending — natural
  reading order top-to-bottom.
* No per-file cap on matches. The only intra-file filter is min_score.
  A file with 50 matches above threshold shows all 50.

Window loop now targets distinct files, not chunks: factor 2..16,
stops when len(file_groups) >= limit, when the vector store returns
fewer rows than asked, or when the cap is hit.

mergeOverlappingHits still runs FIRST (collapses nested H1⊋H2⊋H3 etc.
into one match with nested_hits inside), then groupByFile lifts the
survivors into file-grouped output. So a markdown file with three
nested sections still produces ONE match (not one file with three),
and a Go file with class+method overlap still produces a clean class
match with the method as a nested hit.

CLI render redesigned around the new shape:
  1. /path/to/file.go  [best 0.85]  4 matches · go
     -- [0.85] lines 61-195  (function run)
        ```go
        ...
        ```
        + 1 more match inside:
          · [0.50] line 80  (function init)
     -- [0.42] lines 250-280  (type Server)
        ```go
        ...
        ```

Tests:
* groupByFile: sort-by-best-score, sort-matches-by-line, preserves
  nested_hits, empty input.
* TestSemanticSearch_NestedMarkdownMerge updated for the new shape —
  still asserts the H1 absorbs the two H2 sub-sections (now visible
  as group.Matches[0].NestedHits).
* CLI search_test fixture updated to new wire shape.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Removes the archived Python/FastAPI backend deprecated on 2026-04-24
per the schedule in doc/MIGRATION_FROM_PYTHON.md. No Go code imports
this tree; the migration completed in server/v0.3.0.

Updated references:
* CONTRIBUTING.md: drop legacy row from repo-tree diagram
* doc/MIGRATION_FROM_PYTHON.md: past-tense, retain as historical /
  rollback recipe for the preserved :0.2-python-legacy Docker tag
* doc/DEPRECATION_POLICY.md: past-tense
* .github/workflows/codeql.yml: drop two now-stale comment fragments
* server/internal/vectorstore/store.go: rephrase docID comment to
  drop the dead path pointer; the byte-format invariant (md5[:6] →
  12 hex chars + line range + idx) stays load-bearing for existing
  prod indexes
* README: .cixignore example legacy/ -> vendor/ to avoid implying
  the dir still ships

server/bench/queries.json keeps "legacy/" in anti_paths defensively;
the rules are inert with the dir gone.

Slates the next server tag at v0.4.0 per the deletion plan in
doc/MIGRATION_FROM_PYTHON.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds `provenance: mode=max` and `sbom: true` to both build-push steps
(CPU and CUDA) in release-server.yml.

Docker Scout grade dropped from B (locally pushed images via
`make scout-cuda` / `make docker-build-cuda-dev`) to C (CI-pushed
`:cu128` / `:latest`) because the local Makefile targets pass these
flags explicitly while `docker/build-push-action@v6` defaults to
`provenance: mode=min` and `sbom: false`. Without an SBOM the
"Supply chain attestations" policy fails, dragging the grade down.

Aligning the CI flags with the Makefile should restore grade B on
the next `server/v*` release without changing image contents.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a `workflow_dispatch` trigger so an existing released version can
be rebuilt without cutting a new tag — useful for refreshing image
attestations (e.g. after this PR's SBOM change), picking up a new base
image, or re-running after a transient CI failure.

Inputs:
  - ref: git ref to check out (tag like `server/v0.4.0` or a SHA)
  - version: version string used in image tags (e.g. `v0.4.0`)
  - update_floating_tags: also push `:latest` / `:cu128` (default true)

The GitHub release step is skipped on dispatch (the release already
exists for the version being rebuilt). Tag-pushed releases keep the
exact same behavior as before.

Usage after merge:
  gh workflow run release-server.yml \
    -f ref=server/v0.4.0 \
    -f version=v0.4.0 \
    -f update_floating_tags=true

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…icit auth gating

doc/openapi.yaml describes all 18 endpoints; oapi-codegen v2 generates
typed request/response models and a chi-server ServerInterface, committed
in internal/httpapi/openapi/. Handlers were rewritten as methods on a new
Server struct that implements the generated interface — wire format is
byte-identical to the previous closure-based handlers.

NDJSON streaming on POST /index/files keeps both content-types under one
spec entry with Accept-header negotiation; the embedded spec is served at
/openapi.json (no file duplication — pulled from openapi.GetSpecJSON).

Swagger UI 5.18.2 is embedded via embed.FS and served at /docs (public,
same-origin). Makefile gains openapi-gen, openapi-check, swagger-ui-fetch
targets. CI can run openapi-check to catch drift between spec and
generated code.

Auth gating made explicit: the implicit empty-API-key bypass is removed.
config.Validate now refuses to start with CIX_API_KEY="" unless
CIX_AUTH_DISABLED=true is set. The middleware panics on empty-key
construction as a defense-in-depth check; the router wires it only when
auth is not explicitly disabled. Production Docker images are unaffected
(they always set CIX_API_KEY); local dev gets a loud WARN and a clear
opt-out flag instead of silent open auth.

Local-dev defaults for SQLitePath / ChromaPersistDir resolve to
~/.cix/data/... so make run works without editing .env. Container images
explicitly override these to /data/... — no production behaviour change.
The CPU Dockerfile gains the same ENV CIX_SQLITE_PATH / CIX_CHROMA_PERSIST_DIR
that Dockerfile.cuda already had, so both images share one data layout.

.gitignore exception added for server/internal/httpapi/docs/ so the
embedded Swagger UI bundle ships with the source tree (top-level docs/
remains gitignored per CLAUDE.md).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The CLI's defer-cleanup on early exit (Ctrl-C, network drop) calls
POST /index/cancel to free the per-project run lock. Gating cancel
behind the admin role would strand viewer-owned runs until the 1-hour
TTL elapses — worse UX than the theoretical DoS we'd be preventing.

PATCH /projects/{path} and DELETE /projects/{path} stay admin-only;
those are genuinely destructive. If we ever need owner-scoped cancel,
key off projects.indexing_run.started_by_user_id in a follow-up.

- Drop mustBeAdmin gate from IndexCancel; add comment explaining why.
- Update OpenAPI summary/description; drop 403 from cancel responses.
- Regenerate openapi.gen.go.
- Test: TestIndexCancel_AnyAuthenticatedUser pins the new policy
  (viewer cancels their own project → 200, not 403).
- Trim cancel from TestProjectMutations_AdminOnly cases.
- Doc: SECURITY_DEPLOYMENT.md "what the server does NOT do" section
  now lists PATCH/DELETE (not PATCH/DELETE/index-cancel) as admin-only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CI: Server / test was failing on `go vet` because
//go:embed all:dist in dashboard/embed.go found no matching files —
the .gitkeep marker that .gitignore promises to preserve was never
actually committable: a stray bare `dist/` rule in the Python section
matched any `dist/` directory at any depth, and Git can't re-include
a file under a broadly-excluded parent. Narrow the bare rule to
/dist/ (root only) and commit the marker so a fresh clone passes
the test suite without first building the React bundle.

CodeQL go/uncontrolled-allocation-size flagged
server.go:419 — `make([]openapi.FileResultItem, 0, limit)` where
limit derives from a user-supplied JSON field. Cap with a new
clampLimit helper at maxResultLimit = 1000 — well above any legit
dashboard / CLI page size, well below any value that would balloon
the slice or stall the SQL LIMIT clause. Apply to the four other
endpoints that derive `limit` from `body.Limit` for defense in
depth (search, files, references, definitions, symbols).

derefIntOrDefault keeps the old contract (still used for
non-capacity metadata fields like body.TotalFilesDiscovered).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nale

Two-part change in response to PR review:

1) Lengthen the random portion of issued keys from 24 → 32 bytes,
   so the on-the-wire token is now `cix_<43-char-base64url>` (47 chars
   total) instead of `cix_<32-char>` (36 chars). Matches GitHub-class
   PAT verbosity and pushes the entropy floor from 192 → 256 bits.
   Existing keys keep working — the lookup column is the hash, not
   the length.

2) Expand the comment on hashKey() to spell out why SHA-256 is the
   correct primitive for hashing a server-issued, high-entropy token
   and explicitly refute the CodeQL `go/insufficient-password-hash`
   alert. Adding a slow KDF (bcrypt/argon2/PBKDF2) would tax every
   authenticated request 25–250 ms without raising the security floor
   a single bit, because brute-forcing the hash at 256-bit pre-image
   entropy is computationally indistinguishable from brute-forcing
   the underlying random bytes. Same pattern GitHub / Stripe / AWS
   use for their machine-issued tokens.

Test asserting body length updated 32 → 43 to match the new size.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Both Dockerfile and Dockerfile.cuda have `COPY --from=openapi
openapi.yaml /spec/openapi.yaml` in the dashboard build stage (added
when the dashboard started consuming the OpenAPI spec for type
generation). The release workflow's docker/build-push-action calls were
missing the corresponding `build-contexts: openapi=doc` parameter, so
the next `server/v*` tag push (or workflow_dispatch) would fail at the
dashboard stage with "stage openapi not found".

`make docker-build-cuda-dev` works because it passes
`--build-context openapi=$(ROOT)/../doc` directly. This brings CI to
parity.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two latent bugs in the v0.5.0 CPU image surfaced during post-release
smoke testing of dvcdsys/code-index:v0.5.0 on macOS arm64:

1) Port mismatch — image baked ENV CIX_PORT=8001 (Python parallel-PoC
   carry-over) but docker-compose.yml mapped 21847:21847. A fresh
   `docker compose up -d` from the published files left the host port
   pointing at a non-listening container port; `curl` saw connection
   reset. The Python backend was archived 2026-04, so the rationale
   for 8001 is dead. CUDA image already uses 21847; CPU now matches.

2) /data ownership — distroless USER nonroot:nonroot (uid 65532) but
   the Dockerfile declared `VOLUME ["/data"]` without pre-creating the
   directory with nonroot ownership. A fresh Docker named volume
   inherited root ownership from the daemon and the runtime user got
   `mkdir /data/sqlite: permission denied` on first boot. CUDA image
   pre-creates /data via COPY --chown=1001:1001; CPU now does the
   same with --chown=65532:65532.

Changes:
- server/Dockerfile: ENV CIX_PORT=21847, EXPOSE 21847; mkdir /out/data
  in builder stage; COPY --chown=65532:65532 /out/data /data before
  VOLUME declaration.
- server/internal/config/config.go: getenvInt default 8001 → 21847.
  Doc comment rewritten — "Python parallel rollout" rationale is dead.
- server/internal/config/config_test.go: TestLoadDefaults expects 21847.
- server/README.md: stale "phase 1 / Python parallel" preamble replaced;
  port table cell updated; quick-start docker run example uses 21847
  and shows the now-required bootstrap admin envs.
- docker-compose.yml + docker-compose.cuda.yml: explicit
  CIX_PORT=${CIX_PORT:-21847} as defense in depth against future
  Dockerfile regressions or third-party forks.
- docker-compose.yml: bind-mount uid comment updated 1001 → 65532
  (the CPU image's nonroot uid; CUDA's 1001 only applies to the
  CUDA compose file).

Local verification:
- `make` build green; full Go test suite green (one fixture updated).
- `docker buildx build` of the patched CPU Dockerfile produces an arm64
  image. `docker run` with a NAMED VOLUME (no --user override) and the
  DEFAULT port (no CIX_PORT env) now boots cleanly:
    /health → 200
    /api/v1/auth/bootstrap-status → 200
    /dashboard/ → 200
    /api/v1/admin/users → 200 (admin session)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
dvcdsys and others added 12 commits May 8, 2026 10:47
Adds a server-side `versioncheck` service that polls GitHub releases
on the `server/v*` tag stream every 6h (configurable), exposes the
result via `GET /status`, and renders a dismissible banner in the
dashboard when a newer release is available.

Single poll per server regardless of open clients — the per-instance
cache avoids hammering the GitHub API and keeps the browser from
forging "latest version" claims. ETag-based revalidation keeps
unauthenticated rate-limit usage at ~4 req/day per server (vs. the
60/h GitHub limit).

Config:
  CIX_VERSION_CHECK_ENABLED   default true
  CIX_VERSION_CHECK_INTERVAL  default 6h, Go duration string
  CIX_VERSION_CHECK_REPO      default "dvcdsys/code-index"

Server-side:
  - server/internal/versioncheck/check.go — service + Snapshot type
  - server/internal/versioncheck/check_test.go — coverage including
    ETag revalidation, prerelease/draft skipping, error caching
  - GetStatus folds in update_available / latest_version /
    release_url / version_check (omitted entirely when disabled)
  - main.go wires the background poller with 60s initial delay so
    the boot path doesn't depend on GitHub reachability

Dashboard:
  - UpdateBanner component, dismissals namespaced by latest_version
    in localStorage so a fresh release re-shows the banner
  - useServerStatus types extended with the new optional fields

OpenAPI:
  - update_available, latest_version, release_url, version_check
    on the existing /status response
  - VersionCheckStatus schema for the version_check object

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…amfid

macOS Sequoia (26+) tightened the amfid (AppleMobileFileIntegrity)
policy: ad-hoc-signed binaries whose linked dylibs carry stale
signatures or a com.apple.provenance xattr from the previous bundle
get SIGKILL'd within milliseconds of execve. Symptom in the
supervisor: `signal: killed` with empty stderr (kill happens before
the child can write a single byte), followed by exhausted restart
budget and the boot path failing with "embeddings: llama-server not
ready: context deadline exceeded".

Root cause is that `cp -R $(LLAMA_DIR)/. $(BUNDLE_DIR)/llama/` in
the existing `bundle:` target creates new files macOS treats as
untrusted; whatever blessing the previous bundle had does not carry
over. So the fix has to run on every bundle, not just first install.

Wraps the strip + deep re-sign in `ifeq ($(OS),darwin)` so other
platforms are unaffected. Tested with two consecutive `make bundle`
+ direct llama-server invocation cycles — both stay alive past the
first metal_library_init log line where the previous behaviour died.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ship cix as an installable Claude Code plugin alongside the existing
manual skill, so users get one-command setup with bundled CLI, slash
commands, and behavioral hooks.

Plugin layout (plugins/cix/):
- skills/cix/SKILL.md — copy of the legacy skill with tightened
  description + when_to_use trigger phrases for reliable auto-trigger
- commands/{search,def,refs,init,status,summary}.md — 6 slash commands
  exposed as /cix:* with frontmatter + bash execution
- hooks/hooks.json — SessionStart + PreToolUse(Grep|Glob) registration
- scripts/cix-wrapper.sh — "use system cix or auto-install via the
  official install.sh" wrapper, exposed on PATH via bin/cix symlink
- scripts/session-start.sh — one-time reminder injected via
  hookSpecificOutput.additionalContext when project has .cixignore
- scripts/grep-nudge.sh — exponential-backoff nudge on Grep/Glob calls
  (fires on call #1, 2, 4, 8, 16, …; ~7 nudges per 100-Grep session)
- .claude-plugin/plugin.json — manifest, version 0.1.0

Marketplace (.claude-plugin/marketplace.json):
- Repo doubles as marketplace; one plugin entry pointing to plugins/cix/
- Compatible with `--sparse .claude-plugin plugins` so users skip the
  ~80 MB server/CLI/dashboard checkout

Docs:
- CLAUDE-CODE-PLUGIN.md (new) — full user-facing guide: prerequisites
  (server runs separately, CLI must be configured independently),
  install paths, verification, scope choice, uninstall, troubleshooting
- README.md — Claude Code section now exposes two integration paths:
  Option A "Plugin (recommended)" linking to CLAUDE-CODE-PLUGIN.md, and
  Option B "Skill (manual, legacy)" preserved verbatim for users who
  can't use the plugin system

Adoption design (4 layers, total context overhead ~8 KB per cix-heavy
session, ~400 B if cix isn't used):
1. Skill description (native, always-in-context)
2. SessionStart hook reminder (once per session)
3. PreToolUse(Grep|Glob) nudges (exponential backoff)
4. SKILL.md body lazy-loaded once via native skill mechanism

Validated with `claude plugin validate` for both plugin and marketplace
manifests; unit-tested hook scripts (backoff schedule, .cixignore
detection); installed locally via `claude plugin install` and verified
the wrapper resolves to system cix or bootstraps install.sh on demand.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…tion

Previously hooks used the presence of `.cixignore` as a proxy for
"this project is cix-indexed". That's a weak signal — a project may be
registered with the cix-server without a `.cixignore` file (it's
optional, only needed for ignore patterns), and a stale `.cixignore`
can stick around after a project is removed from the server.

Switch SessionStart to ask `cix status` directly (~17 ms on a local
server, exit 0 only if the project is registered AND the server is
reachable). Cache the decision in `/tmp/cix-aware-$SESSION_ID` so
PreToolUse(Grep|Glob) can read it in ~1 ms without re-querying on
every Grep call.

session-start.sh:
- Resolves cix binary (plugin-bundled wrapper preferred, falls back to
  PATH lookup).
- Runs `cix status -p $CLAUDE_PROJECT_DIR` with a 2-second timeout
  implemented in pure bash (no coreutils dependency — macOS lacks
  `timeout`/`gtimeout` by default).
- Writes "1" or "0" to /tmp/cix-aware-$SESSION_ID.
- Injects the same SessionStart reminder on success, stays silent on
  failure (project not indexed, server unreachable, cix CLI missing).

grep-nudge.sh:
- Reads /tmp/cix-aware-$SESSION_ID first.
- Falls back to .cixignore presence if the cache is absent (covers
  resumed sessions where SessionStart didn't fire).
- Stays silent if neither source confirms cix-aware. No cix CLI calls.

Docs (CLAUDE-CODE-PLUGIN.md, plugins/cix/README.md):
- "How it works" / "Per-project trigger threshold" / "Hooks silent in
  indexed project" troubleshooting all reflect the new logic.
- Document the cache files (cix-aware + cix-grep-count) and their
  cleanup on /tmp reboot.

End-to-end test passed: SessionStart writes cache=1 in indexed repo,
cache=0 in /tmp; grep-nudge fires on calls 1, 2, 4, 8 reading the cache
in indexed repo, stays silent in /tmp.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…UGIN_DATA

Two changes addressing review feedback:

1. Move cache from /tmp to $CLAUDE_PLUGIN_DATA
   - /tmp on macOS is cleaned daily for files older than 3 days; on
     Linux it's typically cleared on reboot. Long-running Claude Code
     sessions outlived these windows, so the cache could vanish
     mid-session and force grep-nudge into its fallback path
     (now removed — see #2).
   - $CLAUDE_PLUGIN_DATA is plugin-persistent storage managed by Claude
     Code (resolves to ~/.claude/plugins/data/cix-code-index/), is
     exported to hook subprocesses, survives plugin updates, and is
     never cleaned by the OS.
   - SessionStart opportunistically deletes its own markers older than
     30 days so the directory doesn't grow unbounded.
   - Falls back to /tmp only when run outside a plugin context (tests).

2. Strict cache contract — no .cixignore fallback
   - Per user feedback: "if SessionStart concluded the project is not
     indexed, just turn off — don't pollute the agent with reminders".
   - grep-nudge previously fell back to checking .cixignore when the
     cache file was absent. That created false positives: a stale
     .cixignore left over from a removed project would trigger nudges
     even after `cix status` confirmed not-indexed.
   - New contract: cache file present + content "1" → nudges allowed;
     anything else (file missing, "0", or unreadable) → silent for the
     entire session.
   - Trade-off documented: a session that started before the cix-server
     came up stays silent even after the server recovers. Restart
     Claude Code to re-evaluate. Better to miss a few nudge opportunities
     than to nag a developer whose server is down.

Test coverage: end-to-end script tests pass for all three states —
indexed (NUDGE on calls 1, 2, 4, 8), not-indexed (silent), and
cache-absent (silent without .cixignore fallback).

Docs (CLAUDE-CODE-PLUGIN.md, plugins/cix/README.md):
- "How it works" section explains the strict cache policy.
- "Per-project trigger threshold" documents that a server reachable at
  SessionStart is required, and how to recover (restart session).
- "Hook state cleanup" section now points at $CLAUDE_PLUGIN_DATA and
  explains the 30-day GC.
- Troubleshooting "Hooks silent in indexed project" lists the inspection
  command for the cache file.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per review feedback: $CLAUDE_PLUGIN_DATA isn't cleaned by the OS, so we
need to remove our own markers. Add a SessionEnd hook that deletes the
two per-session files when a session terminates normally.

scripts/session-end.sh:
- Reads session_id from stdin JSON.
- Removes $CLAUDE_PLUGIN_DATA/cix-aware-$SESSION_ID and
  $CLAUDE_PLUGIN_DATA/cix-grep-count-$SESSION_ID.
- Best-effort: failures silently ignored, since SessionEnd's last word
  shouldn't include error noise.

hooks/hooks.json:
- Register SessionEnd alongside the existing SessionStart and
  PreToolUse(Grep|Glob) entries.

Two-tier cleanup strategy now in place:
1. SessionEnd handles the normal exit path.
2. 30-day GC in SessionStart covers forced kills (kill -9, OOM, panic)
   where SessionEnd never runs.

End-to-end lifecycle test passed: SessionStart writes cache (1 byte),
grep-nudge increments counter (NUDGE 1, 2, 4 / silent 3), SessionEnd
removes both files leaving the cache dir empty.

Docs updated (CLAUDE-CODE-PLUGIN.md, plugins/cix/README.md): explain
the two-tier cleanup and document SessionEnd alongside the other hooks.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…cache

Two new hooks address gaps that surfaced during design review:

CwdChanged
  - When Claude changes working directory mid-session (`cd ../other`),
    the existing cache (`cix-aware-$SESSION_ID`) was stale — it held
    the verdict for the original project, not the new one. The hook
    now caches a separate verdict per (session, project_dir) so a
    multi-project flow gets correct cix-awareness in each.
  - Behavior: silent on cd (no reminder injection) — PreToolUse(Grep|Glob)
    handles the first-Grep-in-new-project nudge through its per-project
    backoff counter, which resets per directory.
  - No-op if the new directory was already evaluated in this session
    (Claude bouncing back to a known project).

PostCompact
  - Skill bodies survive auto-compaction natively (re-attached up to
    5K tokens per skill, see Claude Code skills docs). But the
    SessionStart `additionalContext` reminder — and PreToolUse nudges
    — are NOT skills; they're tool result messages and get dropped or
    summarised during compaction.
  - In long sessions (8+ hours) where the cix skill hasn't been
    invoked yet, the model can "forget" cix exists after compaction.
    PostCompact re-injects the SessionStart reminder if the current
    project's cache says "1".
  - No-op if cache is "0" or missing.

Cache key change (breaking for in-flight sessions; benign for new ones)
  - Old: $CLAUDE_PLUGIN_DATA/cix-aware-$SESSION_ID
  - New: $CLAUDE_PLUGIN_DATA/cix-aware-$SESSION_ID-$DIR_HASH
    where DIR_HASH = `shasum -a 256 <<< $PROJECT_DIR | cut -c1-8`
    (works on both macOS and Linux; falls back to a path-derived
    suffix if shasum is missing).
  - Per-project state means each directory has its own backoff counter:
    a fresh `cd` into a cix-aware project always fires a nudge on the
    first Grep, not the 32nd.

session-start.sh, grep-nudge.sh: refactored to compute DIR_HASH inline
  and use the new key. Same algorithm in both; bash sourcing avoided
  to keep each script standalone-runnable for testing.

session-end.sh: switched from `rm -f $cix-aware-$SID $cix-grep-count-$SID`
  to a glob `find -name 'cix-aware-$SID-*' -delete` so it cleans every
  per-(session, dir) marker the session created.

hooks.json: register CwdChanged and PostCompact alongside SessionStart,
  PreToolUse(Grep|Glob), and SessionEnd. Five hooks total now.

doc/TODO.md (new): document `PostToolUseFailure` for `Bash(cix *)` as a
  v0.2 deferred item. Original ask was an interactive UI prompt
  ("Disable cix plugin for this session? Yes/No"); investigation showed
  Claude Code's hook API doesn't support arbitrary user dialogs
  (`permissionDecision: "ask"` is PreToolUse-only). The functional
  equivalent — overwrite cache to "0" + inject explanation message —
  is straightforward but the underlying problem (cix-server flapping
  mid-session) is rare enough that we want real-usage data before
  shipping. ~1 day of work, queued.

Test coverage: 10-step multi-dir integration test exercises the full
lifecycle — SessionStart, Greps with backoff, CwdChanged into non-cix
dir, silent Greps there, CwdChanged back (preserves counter), more
Greps continuing the original backoff, PostCompact re-injection,
PostCompact silent for non-cix dir, 3 cache files persisted,
SessionEnd glob cleans everything.

Docs (CLAUDE-CODE-PLUGIN.md, plugins/cix/README.md): "Behavioral hooks"
sections enumerate all 5 hooks, explain the per-(session, dir) cache
key, and document the strict cache contract for each.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Address security concern: bash hook scripts run on every Claude Code
session and call `find -delete` against $CLAUDE_PLUGIN_DATA. Without
tests and without runtime guards, a misconfigured environment could in
principle wipe arbitrary files. Layered defense:

1. Path validation guards (runtime, in scripts)
   session-start.sh and session-end.sh now refuse to operate if
   $CLAUDE_PLUGIN_DATA is outside the whitelist:
     - $HOME/.claude/plugins/data/*  (official plugin-data dir)
     - /tmp or /tmp/*                 (fallback / installer scratch)
     - $TMPDIR/*                      (macOS test sandboxes)
   Anything else (e.g. /, $HOME, /etc) prints a refusal message and
   exits non-zero without touching anything.

2. Conservative find patterns (already in place, hardened)
   Every find -delete uses -maxdepth 1, -type f, and a tight -name
   filter. No rm -rf anywhere in the plugin. Subdirectories, symlinks,
   and files outside the cix-aware-* / cix-grep-count-* patterns are
   never reached.

3. bats-core test suite (plugins/cix/tests/)
   46 tests across 6 files, all passing on macOS. Covers:
     - session-start.bats — cix-status flow, cache write, GC,
       guard refusals (=, =$HOME, =/etc), guard accepts (plugin-data,
       /tmp, $TMPDIR)
     - cwd-changed.bats — first-cd evaluation, no-op on cached dir,
       multi-dir cache, silent on cd, timeout
     - grep-nudge.bats — exponential backoff (1, 2, 4, 8, 16),
       per-(session, dir) counters, no cix CLI calls (cache-only)
     - post-compact.bats — re-injection only when cache="1"
     - session-end.bats — glob deletion across dir hashes,
       SECURITY: never touches other sessions' files, never touches
       non-cix files even if they look similar, GUARD refuses on /
       and $HOME and /etc, SECURITY: shell-injection in session_id
       does not delete a /tmp canary
     - cix-wrapper.bats — system-cix passthrough, exit code propagation,
       arg propagation, self-recursion guard via symlink chain

   Mocks: tests/mocks/bin/cix is a fake CLI controlled via env vars
   (MOCK_CIX_EXIT, MOCK_CIX_DELAY, MOCK_CIX_LOG_FILE). helpers.bash
   provides setup_test_env / teardown_test_env / run_hook / make_cache /
   read_cache / read_counter / compute_hash / mock_cix_call_count.

4. GitHub Actions workflow (.github/workflows/ci-plugin.yml)
   Runs on push and PR when plugins/cix/** or .claude-plugin/** changes.
   Matrix: ubuntu-latest + macos-latest. Steps:
     - Install bats-core, jq, shellcheck (apt or brew)
     - Run bats --tap plugins/cix/tests/*.bats
     - Run shellcheck --severity=warning on all hook scripts
     - Validate JSON manifests (marketplace, plugin, hooks)
     - Verify bin/cix symlink integrity
   Fails on shellcheck warnings, not just errors — keeps scripts
   defensive about quoting, word splitting, and unsafe globs.

5. Documentation
   plugins/cix/tests/README.md — how to run locally, test matrix
   summary, mock interface, how to add new tests.
   CLAUDE-CODE-PLUGIN.md — new "Security & testing" section
   documenting the three defensive layers.

All 46 tests pass locally on macOS 14 with bats-core 1.13.0.
shellcheck --severity=warning is clean on all 6 hook scripts.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…instead

Previous commit added `case "$CACHE_DIR" in $HOME/.claude/plugins/data/*|/tmp*|...) ;;
*) refuse;;` guards to session-start.sh and session-end.sh. Per review:
the whitelist blocks legitimate non-standard layouts (corporate setups
with custom CLAUDE_PLUGIN_DATA, XDG-style layouts, alternative paths)
while providing no real safety advantage on top of the existing
file-level filters.

Real safety model: every `find -delete` already uses
  -maxdepth 1   (no recursion)
  -type f       (files only — skips dirs/symlinks)
  -name 'cix-aware-...' / -name 'cix-grep-count-...'  (exact prefix)

For session-end.sh the patterns also embed $SESSION_ID (a Claude-Code-
assigned UUID), so the patterns practically cannot match anything but
our own marker files even in unusual cache dirs. There's no path on
which a hook script could touch a file that doesn't already match the
strict name pattern.

Removed:
- session-start.sh: path whitelist case-block before GC
- session-end.sh: path whitelist case-block before find -delete
- 5 tests in session-start.bats: GUARD: refuses /, $HOME, /etc;
  GUARD: allows plugin-data; GUARD: allows /tmp
- 3 tests in session-end.bats: GUARD: refuses /, $HOME, /etc

Added:
- session-start.bats: "GC never deletes files outside the cix-aware-*
  / cix-grep-count-* prefixes — even in same dir" — populates cache
  dir with confusable names (cix-other-pattern, X-cix-aware-fake-...,
  cix alone, AWARE-MISTAKEN-CASE) all 90 days old, asserts every one
  survives GC.
- session-end.bats: "in a non-standard cache dir, only matching files
  are deleted" — uses a fresh mktemp dir under BATS_TMPDIR (NOT in
  the old whitelist), populates with secrets.json, kubeconfig.yaml,
  .env, deploy.sh + a subdirectory with a nested file, asserts only
  cix-aware-our-sess-* and cix-grep-count-our-sess-* are deleted.

Test count: 46 → 41 (5 guard tests removed, 2 positive tests added,
8 - 3 net). All 41 pass on macOS 14 + bats 1.13.0. shellcheck still
clean.

Docs (CLAUDE-CODE-PLUGIN.md, plugins/cix/tests/README.md): "Security
& testing" section now explains the file-level safety model and
explicitly documents that custom data dirs are supported.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CodeQL flagged ci-plugin.yml on the PR with: "Workflow does not contain
permissions". The workflow only reads repo contents (clones, runs
tests, validates manifests) — it never pushes commits, opens PRs,
posts comments, or touches releases. Lock GITHUB_TOKEN down to:

    permissions:
      contents: read

at the workflow level so the implicit default (which can be repo-wide
write on legacy installs) is overridden everywhere.

Also: document the pre-existing govulncheck failure on `main` in
doc/TODO.md. Two Go stdlib vulnerabilities (GO-2026-4971, GO-2026-4918)
landed in 1.25.10; server/go.mod still pins 1.25.9. Bumping the
go directive is a 5-minute fix in a separate PR — outside this
plugin's scope, so flagged for the server roadmap rather than handled
here.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
govulncheck flagged two CVEs reachable from server code:

- GO-2026-4971 — Panic in net.Dial and net.LookupPort when handling
  NUL byte on Windows. Reachable from
  internal/embeddings/client.go:240 (http.Client.Do →
  net.Dialer.DialContext) and internal/embeddings/supervisor.go:158
  (net.Listen for free-port picking).

- GO-2026-4918 — Infinite loop in HTTP/2 transport when given bad
  SETTINGS_MAX_FRAME_SIZE in golang.org/x/net/http2. Reachable from
  internal/embeddings/client.go:240 (http.Client.Do) and
  cmd/cix-server/main.go:38 (healthcheck http.Client.Get).

Both fixed in go1.25.10. Bump the `go` directive in server/go.mod;
go.sum is unchanged (no dependency-tree changes from a stdlib version
bump).

CI uses `go-version-file: server/go.mod` so this is the only change
needed — the workflow will pick up 1.25.10 on the next run.

Verified locally with GOTOOLCHAIN=go1.25.10:
  - go build ./...        — clean
  - govulncheck ./...     — "No vulnerabilities found."

Reachability:
  - GO-2026-4971 — Windows-only code path; Linux/macOS deployments
    weren't affected at runtime, but govulncheck flagged the call site.
  - GO-2026-4918 — HTTP/2 transport; real risk on any cix-server
    instance reachable by an untrusted peer. This is the one that
    actually mattered.

Removed the corresponding entry from doc/TODO.md (no longer pending).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Removes [esbuild](https://github.com/evanw/esbuild). It's no longer used after updating ancestor dependency [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). These dependencies need to be updated together.


Removes `esbuild`

Updates `vite` from 5.4.21 to 8.0.12
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.12/packages/vite)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 
  dependency-type: indirect
- dependency-name: vite
  dependency-version: 8.0.12
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels May 11, 2026
@dvcdsys dvcdsys force-pushed the dependabot/npm_and_yarn/server/dashboard/multi-64f29988ee branch from ab00182 to 4751ce1 Compare May 12, 2026 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant