GitNexus/CHANGELOG.md
Minidoracat 0054496323
Some checks failed
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Gitleaks / gitleaks (push) Waiting to run
Publish / Classify release event (push) Waiting to run
Publish / RC guard (marker + release-PR skip) (push) Blocked by required conditions
Publish / ci (push) Blocked by required conditions
Publish / Publish to npm (push) Blocked by required conditions
Publish / Build & Push RC Docker images (push) Blocked by required conditions
Scorecard / Scorecard analysis (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-web) (push) Waiting to run
Devcontainer Smoke / Config-transform unit tests (push) Has been cancelled
Devcontainer Smoke / Build devcontainer image (push) Has been cancelled
fix(hooks): wrap the augment CLI child in the orphan guard (#2163) (#2169)
* fix(hooks): wrap the augment CLI child in the orphan guard (#2163)

Follow-up invited by the maintainer on #2165: the augment child
(7s local / 12s npx) was the longest-lived unwrapped subprocess, exposed
to the same SIGKILL-orphan mechanism fixed for lsof/ps.

- Export resolveUnixGuardTimeout from the probe module (both copies,
  byte-identical); adapters share the same module instance, so the memo
  and lazy self-test still run at most once per hook process.
- Wrap every CLI-executing branch of runGitNexusCli in the three
  probe-equipped adapters with the guard: budget ceil(inner/1000)+1
  seconds with -k 1, strictly above each branch's inner spawnSync
  timeout, so the supervised path is unchanged and the wrapper only
  matters once the hook itself is SIGKILLed. Windows and no-guard hosts
  keep byte-identical argv. The plugin adapter's PATH-direct gitnexus
  branch (its most common production path) is wrapped too; the cheap
  which/where probe is not.
- Cursor integration: debug-gated 'augment skipped: hook slots
  saturated' on the slot-starved early return. Its augment child stays
  unwrapped for now — that integration does not install the probe
  sibling (the 'cursor probe' item on the #2163 follow-up list).
- Reaping tests get a guard-availability precheck with an explicit
  failure message (assertion, not skipIf, so a coreutils-less Linux
  host fails diagnosably instead of going silently green).
- Tests: orphaned-augment reaping (CJS + Plugin, red without the wrap,
  ~9.1s reap measured), disabled-sentinel degradation equivalence,
  source pinning for all three adapters (exact per-branch budget-formula
  counts) + probe export + cursor debug line.

Note: pre-commit typecheck skipped; remaining tsc errors are
pre-existing on main (none in files touched here).

* fix(hooks): group-SIGKILL the npx arm, prove guard exit propagation (#2169 review)

Addresses the tri-review findings on #2169:

- [P2] npx-arm containment: the CLI is the guard's grandchild there —
  at budget expiry coreutils timeout TERMs the group, npx (the obedient
  direct child) dies, timeout returns, and -k never fires, so a
  SIGTERM-immune grandchild escaped unbounded. The npx arm's wrapper now
  uses -s KILL: an unignorable group SIGKILL at budget that reaps the
  grandchild (kept -k 1 as a harmless belt; direct-exec arms keep
  TERM-first). CHANGELOG, adapter docblocks, and the test comment now
  state the per-arm semantics honestly. New behavioral test: a staged
  hook with a PATH-injected fake npx spawning a SIGTERM-immune
  grandchild is SIGKILLed; the grandchild must be reaped (red without
  -s KILL), with a route self-proof marker pinning the npx arm.
- [P3] guard self-test now proves exit-status propagation
  (sh -c 'exit 42' must yield status 42), so an always-exit-0 stub like
  /bin/true is rejected and resolution falls through to the built-in
  candidates instead of silently killing the augment feature. New test:
  stub guard rejected, augment still emits context.
- [P3] cleanup SIGKILLs in the reaping tests re-check the
  /proc/<pid>/cmdline identity immediately before firing (PID-reuse
  guard), applied consistently to the two pre-existing #2165 spots and
  both new tests.
- Review notes: source pins now constrain wrapper argv order and exact
  per-arm counts; adapters degrade to unwrapped on probe version skew
  (typeof check) instead of a swallowed TypeError; export JSDoc wording
  fixed for relative env paths; debug-gated diagnostic when no guard is
  available (e.g. macOS without coreutils), with the CHANGELOG entry
  qualified accordingly.

Note: pre-commit typecheck skipped; remaining tsc errors are
pre-existing on main (none in files touched here).

---------

Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-06-12 15:17:30 +01:00

11 KiB

Changelog

All notable changes to GitNexus will be documented in this file.

[Unreleased]

Fixed

  • Hook db-lock probe no longer strands unkillable lsof/ps orphans — the probe's lsof/ps subprocesses are now wrapped in a self-tested coreutils timeout/gtimeout (timeout -k 1 …), so a hook SIGKILLed by the runner's 10s timeout can no longer leave lsof running forever (orphan lifetime bounded at ~3s); acquireHookSlot now also gates the probe itself, capping concurrent probes at 3 per repo. Opt out with GITNEXUS_HOOK_TIMEOUT_PATH=disabled. (#2163)
  • Hook augment CLI no longer strands orphans eitherrunGitNexusCli in the Claude, plugin, and Antigravity hook adapters now wraps the gitnexus augment subprocess (the longest-lived hook child: 7s local / 12s npx inner budgets) in the same self-tested coreutils timeout guard as the probe's lsof/ps, with a budget of ceil(inner/1000)+1 seconds — strictly above the inner spawnSync timeout, so on the supervised path Node's SIGTERM still fires first and observable behavior is unchanged. Once the hook itself has been SIGKILLed the guard takes over, with per-branch semantics: on the direct-exec branches (the CLI is the guard's child) it SIGTERMs at budget and -k 1 SIGKILLs 1s later; on the npx branches (the CLI is a grandchild behind npx) it uses -s KILL, SIGKILLing the whole process group at budget — a TERM-first guard there would only kill the obedient npx parent and exit before its -k escalation fires, stranding a SIGTERM-immune CLI. Two npx-branch caveats remain (both no worse than the pre-fix behavior, where the grandchild received no signal at all): the group-wide KILL is coreutils semantics, so a busybox timeout — which passes the self-test — still signals only its direct child and cannot reach the grandchild; and on the supervised path (hook alive, inner spawnSync timeout SIGTERMs the guard) coreutils forwards TERM rather than KILL, so a SIGTERM-immune CLI grandchild is still not reaped there. The guard self-test now also requires exit-status propagation (sh -c 'exit 42' must yield 42), so an always-exit-0 stub at GITNEXUS_HOOK_TIMEOUT_PATH can no longer be adopted and silently swallow the probe and augment. Windows, GITNEXUS_HOOK_TIMEOUT_PATH=disabled, and Unix hosts with no usable coreutils timeout/gtimeout at all (e.g. macOS without Homebrew coreutils) keep the exact pre-wrap unguarded invocation — every guard-less Unix run, whatever the reason (disabled, nothing usable, probe version skew), is now diagnosed once per hook run under GITNEXUS_DEBUG. The Cursor hook is not wrapped yet (it does not install the probe helper) but now reports its slot-saturated skip under GITNEXUS_DEBUG. (#2163 follow-up)

Changed

  • Migrated from KuzuDB to LadybugDB v0.15 (@ladybugdb/core, @ladybugdb/wasm-core)
  • Renamed all internal paths from kuzu to lbug (storage: .gitnexus/kuzu.gitnexus/lbug)
  • Added automatic cleanup of stale KuzuDB index files
  • LadybugDB v0.15 requires explicit VECTOR extension loading for semantic search

[1.5.3] - 2026-04-01

Added

  • TypeScript/JavaScript MethodExtractor config — shared extraction config covering abstract methods, visibility modifiers, async/override keywords, decorators, rest/optional/destructured parameters, and return types (#588) — @compound-ai

Fixed

  • Azure OpenAI compatibility — use max_completion_tokens instead of deprecated max_tokens (newer models reject max_tokens); skip temperature for Azure provider (some models reject non-default values) (#618)
  • Simplified Azure interactive setup — 3 prompts (endpoint, deployment, key) instead of 7 (#618)
  • Wiki HTML viewer script injection — escape </script> in embedded JSON so LLM-generated markdown no longer breaks the viewer (#618)
  • Ensure import rewrites survive npm publish lifecycle

[1.4.0] - 2026-03-13

Added

  • Language-aware symbol resolution engine with 3-tier resolver: exact FQN → scope-walk → guarded fuzzy fallback that refuses ambiguous matches (#238) — @magyargergo
  • Method Resolution Order (MRO) with 5 language-specific strategies: C++ leftmost-base, C#/Java class-over-interface, Python C3 linearization, Rust qualified syntax, default BFS (#238) — @magyargergo
  • Constructor & struct literal resolution across all languages — new Foo(), User{...}, C# primary constructors, target-typed new (#238) — @magyargergo
  • Receiver-constrained resolution using per-file TypeEnv — disambiguates user.save() vs repo.save() via ownerId matching (#238) — @magyargergo
  • Heritage & ownership edges — HAS_METHOD, OVERRIDES, Go struct embedding, Swift extension heritage, method signatures (parameterCount, returnType) (#238) — @magyargergo
  • Language-specific resolver directory (resolvers/) — extracted JVM, Go, C#, PHP, Rust resolvers from monolithic import-processor (#238) — @magyargergo
  • Type extractor directory (type-extractors/) — per-language type binding extraction with Record<SupportedLanguages, Handler> + satisfies dispatch (#238) — @magyargergo
  • Export detection dispatch table — compile-time exhaustive Record + satisfies pattern replacing switch/if chains (#238) — @magyargergo
  • Language config module (language-config.ts) — centralized tsconfig, go.mod, composer.json, .csproj, Swift package config loaders (#238) — @magyargergo
  • Optional skill generation via npx gitnexus analyze --skills — generates AI agent skills from KuzuDB knowledge graph (#171) — @zander-raycraft
  • First-class C# support — sibling-based modifier scanning, record/delegate/property/field/event declaration types (#163, #170, #178 via #237) — @Alice523, @benny-yamagata, @jnMetaCode
  • C/C++ support fixes.h → C++ mapping, static-linkage export detection, qualified/parenthesized declarators, 48 entry point patterns (#163, #227 via #237) — @Alice523, @bitgineer
  • Rust support fixes — sibling-based visibility_modifier scanning for pub detection (#227 via #237) — @bitgineer
  • Adaptive tree-sitter buffer sizingMath.min(Math.max(contentLength * 2, 512KB), 32MB) (#216 via #237) — @JasonOA888
  • Call expression matching in tree-sitter queries (#234 via #237) — @ex-nihilo-jg
  • DeepSeek model configurations (#217) — @JasonOA888
  • 282+ new unit tests, 178 integration resolver tests across 9 languages, 53 test files, 1146 total tests passing

Fixed

  • Skip unavailable native Swift parsers in sequential ingestion (#188) — @Gujiassh
  • Heritage heuristic language-gated — no longer applies class/interface rules to wrong languages (#238) — @magyargergo
  • C# base_list distinguishes EXTENDS vs IMPLEMENTS via symbol table + I[A-Z] heuristic (#238) — @magyargergo
  • Go qualified_type (models.User) correctly unwrapped in TypeEnv (#238) — @magyargergo
  • Global tier no longer blocks resolution when kind/arity filtering can narrow to 1 candidate (#238) — @magyargergo

Changed

  • import-processor.ts reduced from 1412 → 711 lines (50% reduction) via resolver and config extraction (#238) — @magyargergo
  • type-env.ts reduced from 635 → ~125 lines via type-extractor extraction (#238) — @magyargergo
  • CI/CD workflows hardened with security fixes and fork PR support (#222, #225) — @magyargergo

[1.3.11] - 2026-03-08

Security

  • Fix FTS Cypher injection by escaping backslashes in search queries (#209) — @magyargergo

Added

  • Auto-reindex hook that runs gitnexus analyze after commits and merges, with automatic embeddings preservation (#205) — @L1nusB
  • 968 integration tests (up from ~840) covering unhappy paths across search, enrichment, CLI, pipeline, worker pool, and KuzuDB (#209) — @magyargergo
  • Coverage auto-ratcheting so thresholds bump automatically on CI (#209) — @magyargergo
  • Rich CI PR report with coverage bars, test counts, and threshold tracking (#209) — @magyargergo
  • Modular CI workflow architecture with separate unit-test, integration-test, and orchestrator jobs (#209) — @magyargergo

Fixed

  • KuzuDB native addon crashes on Linux/macOS by running integration tests in isolated vitest processes with --pool=forks (#209) — @magyargergo
  • Worker pool MODULE_NOT_FOUND crash when script path is invalid (#209) — @magyargergo

Changed

  • Added macOS to the cross-platform CI test matrix (#208) — @magyargergo

[1.3.10] - 2026-03-07

Security

  • MCP transport buffer cap: Added 10 MB MAX_BUFFER_SIZE limit to prevent out-of-memory attacks via oversized Content-Length headers or unbounded newline-delimited input
  • Content-Length validation: Reject Content-Length values exceeding the buffer cap before allocating memory
  • Stack overflow prevention: Replaced recursive readNewlineMessage with iterative loop to prevent stack overflow from consecutive empty lines
  • Ambiguous prefix hardening: Tightened looksLikeContentLength to require 14+ bytes before matching, preventing false framing detection on short input
  • Closed transport guard: send() now rejects with a clear error when called after close(), with proper write-error propagation

Added

  • Dual-framing MCP transport (CompatibleStdioServerTransport): Auto-detects Content-Length (Codex/OpenCode) and newline-delimited JSON (Cursor/Claude Code) framing on the first message, responds in the same format (#207)
  • Lazy CLI module loading: All CLI subcommands now use createLazyAction() to defer heavy imports (tree-sitter, ONNX, KuzuDB) until invocation, significantly improving gitnexus mcp startup time (#207)
  • Type-safe lazy actions: createLazyAction uses constrained generics to validate export names against module types at compile time
  • Regression test suite: 13 unit tests covering transport framing, security hardening, buffer limits, and lazy action loading

Fixed

  • CALLS edge sourceId alignment: findEnclosingFunctionId now generates IDs with :startLine suffix matching node creation format, fixing process detector finding 0 entry points (#194)
  • LRU cache zero maxSize crash: Guard createASTCache against maxSize=0 when repos have no parseable files (#144)

Changed

  • Transport constructor accepts NodeJS.ReadableStream / NodeJS.WritableStream (widened from concrete ReadStream/WriteStream)
  • processReadBuffer simplified to break on first error instead of stale-buffer retry loop

[1.3.9] - 2026-03-06

Fixed

  • Aligned CALLS edge sourceId with node ID format in parse worker (#194)

[1.3.8] - 2026-03-05

Fixed

  • Force-exit after analyze to prevent KuzuDB native cleanup hang (#192)