GitNexus/AGENTS.md
Copilot 26ff700e37
refactor(pipeline): DAG-based phase architecture + container-logic extraction to LanguageProvider (#809)
* Initial plan

* refactor: move language-specific container node logic into LanguageProvider

- Add resolveEnclosingOwner hook to LanguageProviderConfig
- Add staticOwnerTypes to MethodExtractionConfig
- Implement Ruby resolveEnclosingOwner (singleton_class → class/module)
- Replace hardcoded STATIC_OWNER_TYPES with config.staticOwnerTypes
- Move Ruby static types to rubyMethodConfig
- Move Kotlin static types to kotlinMethodConfig
- Remove Ruby singleton_class branch from findEnclosingClassInfo
- Collapse seqFindEnclosingClassNode/seqFindRawEnclosingContainerNode
  into single provider-aware seqFindEnclosingOwnerNode
- Update worker path to pass provider.resolveEnclosingOwner

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/bc9f9d4d-f749-4872-9ff2-17fc86e08787

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* test: add regression tests for config-driven staticOwnerTypes and resolveEnclosingOwner hook

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/bc9f9d4d-f749-4872-9ff2-17fc86e08787

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* refactor: implement DAG-based pipeline architecture with phase extraction

Restructure the ingestion pipeline from a ~1800-line monolithic orchestrator
into a DAG (Directed Acyclic Graph) of named phases with explicit dependencies.

New files under pipeline-phases/:
- types.ts: PipelinePhase, PipelineContext, PhaseResult contracts
- runner.ts: DAG runner with topological sort validation
- scan.ts, structure.ts, markdown.ts, cobol.ts: early phases
- parse.ts + parse-impl.ts: chunked parse + resolve (the core)
- routes.ts, tools.ts, orm.ts: post-parse enrichment phases
- cross-file.ts + cross-file-impl.ts: cross-file binding propagation
- mro.ts, communities.ts, processes.ts: graph analysis phases
- index.ts: barrel export

pipeline.ts reduced from ~1960 lines to ~184 lines:
- DAG phase array declaration
- runPipelineFromRepo as thin orchestrator
- topologicalLevelSort retained for backward compat

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/136bf9c3-2f4f-449b-9fff-001332c8371c

* test: add DAG runner unit tests, update ARCHITECTURE.md with phase DAG docs

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/136bf9c3-2f4f-449b-9fff-001332c8371c

* fix: address code review - pass resolutionContext through parse output, fix worker URL path

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/136bf9c3-2f4f-449b-9fff-001332c8371c

* fix: declare transitive parse dependency explicitly in mro/communities/processes phases

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/136bf9c3-2f4f-449b-9fff-001332c8371c

* refactor: improve pipeline-phases clean code and folder structure

- Extract synthesizeWildcardImportBindings to wildcard-synthesis.ts
- Extract extractORMQueriesInline to orm-extraction.ts
- Create shared constants.ts for AST_CACHE_CAP
- Fix inline type import in orm.ts (use proper top-level import)
- Add comprehensive JSDoc to getPhaseOutput explaining type safety
- Move isDev to module level in cross-file.ts (consistency)
- Improve module-level documentation across files
- Organize barrel exports in index.ts with section comments

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/2bd6d4aa-6271-4009-8dd2-332ea8ec73ab

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* address review feedback: fix circular dep, allFetchCalls mutation, progress bugs, remove DAG naming, extract isDev, fix _item naming, fix O(n²) line calc

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/6cf53c9b-d55d-4c6f-bf3d-7bfb82d512b6

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* improve JSDoc on lineNumberAtOffset binary search

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/6cf53c9b-d55d-4c6f-bf3d-7bfb82d512b6

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* address review: filter deps in runner, move totalFiles to ctx, fix cycle JSDoc, centralize isDev, remove DAG naming

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/b388424f-b939-4a94-97de-3855f9465564

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* fix doc consistency in graph-sort.ts module-level and function-level JSDoc

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/b388424f-b939-4a94-97de-3855f9465564

Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>

* fix(pipeline): wrap phase errors with phase name and emit terminal error progress event

Restores phase diagnostics at CLI/MCP boundary. runPipeline now wraps
phase.execute() in try/catch and rethrows with 'Phase <name> failed: ...'
preserving the original via { cause }. Also emits a terminal
{ phase: 'error' } progress event so subscribers see the failure before
the rejection propagates. Handler errors during error reporting are
swallowed to keep the original cause authoritative.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U1)

* fix(pipeline): move bindingAccumulator dispose into crossFile try/finally; make single-use

crossFile.execute() now wraps its body in try/finally so the accumulator
is released on both the happy path and when runCrossFileBindingPropagation
throws. Dev-mode telemetry stays inside the try block before dispose (all
three counters return 0 after dispose clears internal maps).

BindingAccumulator becomes single-use: appendFile after dispose now throws
'BindingAccumulator: use after dispose' instead of silently re-animating
via the old _disposed auto-clear. Docs updated; the only production
construction site (parse-impl) always creates a fresh instance per run,
so no caller relied on the re-use contract.

Residual risk documented in crossFile module JSDoc: a future phase
inserted between parse and crossFile that throws would still leak the
accumulator. Any such phase must manage accumulator lifetime explicitly.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U2)

* docs(pipeline): explain why importCtx teardown is safe before crossFile

Investigation (plan U3) confirms: `importCtx` (ImportResolutionContext)
is a scratch workspace with no downstream consumer after parse.
`resolutionContext` (returned to crossFile) is a distinct object that
owns importMap / namedImportMap / packageMap / moduleAliasMap / model,
and never closes over importCtx. cross-file-impl consumes only that
ctx via processCalls. The two confusingly-similar "context" names
were the root of the adversarial reviewer's concern — comment locks
in the invariant so the next reader sees it.

No behavioral change.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U3)

* refactor(pipeline): remove ctx.totalFiles side-channel; promote to ParseOutput

totalFiles was a hidden mutable field on PipelineContext written by
parse and read by mro/communities/processes — five reviewers flagged
this as a violation of the immutable-context invariant. Removed from
PipelineContext, which is now fully readonly, and made the implicit
temporal dep explicit: mro/communities/processes now declare 'parse'
as a dep and read totalFiles via getPhaseOutput<ParseOutput>(...).

No behavior change. Topo-sort unchanged because parse was already a
transitive dep through crossFile.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U4)

* feat(method-extractor): runtime staticOwnerTypes guard at factory chokepoint

createMethodExtractor now rejects MethodExtractionConfigs that list
companion_object / singleton_class / object_declaration in
typeDeclarationNodes but omit the matching entry from staticOwnerTypes.
Fails loudly at provider construction time instead of producing
silent isStatic=false on the 50000th file analyzed.

Opt-out convention preserved: an explicit `new Set()` (empty Set)
signals intentional exclusion and passes the guard (memory obs #30588).

All 13 existing language configs pass the guard; the new negative test
fails without it. Test-first.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U5)

* fix(pipeline): wrap sequential-fallback in try/finally so cleanup survives throws

The sequential-fallback block in runChunkedParseAndResolve now runs
inside a try/finally that guarantees astCache.clear(), accumulator
finalize, and enrichExportedTypeMap execute even if readFileContents
or processCalls throws mid-fallback. Cleanup failures are caught
inside the finally so they can't mask the original error.

Accumulator disposal ownership remains with crossFile (U2) — U6 only
adds astCache cleanup and preserves finalize ordering on the error
path.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U6)

* test(pipeline): direct unit coverage for wildcard-synthesis and cross-file-impl

Both modules previously had zero direct unit coverage — branches were
exercised only through integration tests' happy paths.

wildcard-synthesis.test.ts covers: Go graph-IMPORTS fallback, Python
moduleAliasMap build, MAX_SYNTHETIC_BINDINGS_PER_FILE cap, dedup
against existing namedImportMap entries, and empty-exportedSymbols
early return.

cross-file-impl.test.ts covers: gapRatio below threshold no-op,
MAX_CROSS_FILE_REPROCESS cap, graph-only exportedTypeMap fallback,
and empty namedImportMap short-circuit.

Tests assert current behavior — any future regression flips them.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U7)

* test(pipeline): golden-file graph-parity regression guard on mini-repo fixture

Pins the current post-P1/P2 graph output (57 symbols, 92 relationships,
4 processes, deterministic edge digest) so future silent refactors
cannot drift behavior unnoticed. If any count changes or any edge
rewires, the test fails with a readable diff listing what changed
and a copy-pasteable UPDATE_GOLDEN=1 regen command.

Edge digest keyed by symbolic (label, name, filePath) triples rather
than raw generateId output — stays meaningful across id-encoding
refactors while still catching real semantic rewiring.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U8)

* fix(pipeline): minimal cycle reporting + resolveEnclosingOwner loop safeguards

U9: runner cycle detection now reports only the SCC members via DFS
back-edge trace ('Cycle detected: A -> B -> C -> A') rather than
everything with inDegree > 0 (which mixed cycle members with blocked
dependents). Also emits the 'error' progress event for graph-
validation failures, symmetric with U1's runtime-error path.

U16: findEnclosingClassInfo now defends against language-provider
hooks that return non-container nodes — visitedContainers Set breaks
repeat-visit loops, MAX_ENCLOSING_WALK_ITERATIONS is belt-and-braces.
Documented the hook contract invariant so future provider authors
know the walk-continues-upward expectation.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U9, U16)

* refactor(pipeline): type hygiene, dead code cleanup, shared allPathSet, graph-sort naming

Bundles plan units U10, U11, U12, U14, U15:

U10 — Type hygiene: readonly ParseOutput arrays (allExtractedRoutes,
allDecoratorRoutes, allToolDefs, allORMQueries, allPaths); removed
redundant 'as string[] | undefined' cast in routes.ts and 'as URL' in
parse-impl.ts; WorkerPool is now 'import type'. Readonly contract
propagated into processORMQueries (only iterates).

U11 — Dead code & shims: deleted constants.ts shim (AST_CACHE_CAP
inlined into its sole real consumer cross-file-impl.ts; isDev
consumers now import directly from ../utils/env.js). Removed internal
utility re-exports from pipeline-phases/index.ts (no external
consumers). Removed topologicalLevelSort re-export from pipeline.ts;
updated topological-sort.test.ts to import from the canonical
utils/graph-sort.js. Stripped 'Phase 3+4:' stale JSDoc from
parse-impl.ts.

U12 — Perf: StructureOutput now carries allPathSet (ReadonlySet<string>)
built once; cobol, markdown, and cross-file-impl consume the shared
set instead of allocating their own. Parse forwards it via
ParseOutput.allPathSet; processCobol/processMarkdown widened to
ReadonlySet<string>.

U14 — graph-sort.ts: renamed local 'inDegree' to
'pendingImportsPerFile' with expanded JSDoc explaining the reverse-
graph Kahn's formulation and warning future maintainers not to
'correct' it to standard in-degree semantics. Added self-edge test.

U15 — Unconditional worker-fallback logging: removed isDev guard on
the worker-pool-creation-failure console.warn so operators can
diagnose perf degradations in production.

No behavior change. U8 golden-file test confirms pipeline output is
byte-identical.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U10, U11, U12, U14, U15)

* docs: fix ARCHITECTURE.md table integrity; bump AGENTS.md/CLAUDE.md to 1.3.0

U13 — documentation fixes:

ARCHITECTURE.md: the prior insertion of the 'Pipeline Phase DAG'
section orphaned 7 rows from the 'Where to change what' header.
Moved those 7 rows back up under their header so the table reads
contiguously; DAG section now follows the completed table.

AGENTS.md + CLAUDE.md: bumped version 1.2.0 -> 1.3.0, updated Last
reviewed to 2026-04-13, added matching Changelog row documenting
the GitNexus index stats refresh after the DAG refactor. Stat
bumps (symbols/relationships/execution flows) that were sitting
uncommitted in the working tree are now landed under a proper
changelog entry per each file's own documented schema.

Plan: docs/plans/2026-04-13-001-fix-pipeline-dag-refactor-review-findings-plan.md (U13)

* refactor(pipeline): drop spurious parse deps, true-readonly ParseOutput.exportedTypeMap, skip redundant wildcard synth

- mro/communities/processes: switch redundant `parse` dep to `structure` —
  totalFiles originates in structure, so depending on parse for it was a
  spurious data dep that obscured the real DAG.
- ParseOutput.exportedTypeMap: typed as truly ReadonlyMap<...,ReadonlyMap>>;
  graph→exports enrichment moved into parse-impl so the snapshot is
  fully populated at parse return. crossFile builds its own local mutable
  working copy for per-file re-resolution writes — no cast at the boundary.
- parse-impl: hasSynthesized flag guards the unconditional final
  synthesizeWildcardImportBindings call when per-chunk/fallback synthesis
  already ran (graph-global + idempotent across chunks).
- cross-file-impl: documented the intentional `phase: 'parsing'` progress
  label so telemetry bucketing stays consistent with the parse phase.
- cross-file-impl test: replaced the now-moved fallback-enrichment
  assertion with a stronger one — crossFile must not mutate the
  parse-supplied map.

Addresses PR #809 review pass 5 carry-overs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>
Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>
2026-04-13 20:31:05 +01:00

12 KiB

Last reviewed: 2026-04-13

Project: GitNexus · Environment: dev · Maintainer: repository maintainers (see GitHub)

This file uses a standard agent header (version, scope, model policy, reference docs, changelog), adapted for this TypeScript/JavaScript monorepo.

Scope

Reads Repository tree as needed for the task: gitnexus/, gitnexus-web/, eval/, plugin packages, .github/, .gitnexus/ when present, and docs.
Writes Only paths required for the requested change; keep diffs minimal. Update lockfiles when dependencies change.
Executes npm, npx, node under gitnexus/ and gitnexus-web/; uv run for Python under eval/ when applicable; shell utilities for documented CI/dev workflows.
Off-limits User secrets (e.g. real .env), production deployment credentials, unrelated repositories, destructive git history operations without explicit human confirmation.

Model Configuration

  • Primary: Pin in Cursor (Settings → model). Use a named model (e.g. GPT-5.2, Claude Sonnet 4.x). Avoid relying on Auto when reproducibility or audit trail matters.
  • Fallback: As configured in Cursor or your organization (do not encode latest or wildcards in automation configs).
  • Notes: The open-source GitNexus CLI indexer does not call an LLM. Optional Nexus AI in the web UI uses end-user provider keys and models.

Execution Sequence (complex tasks)

Long sessions dilute instructions. For multi-step work, state up front:

  1. Which rules in this file and GUARDRAILS.md apply (and any relevant Signs).
  2. Current Scope boundaries (Reads / Writes / Off-limits).
  3. Which validation commands you will run (e.g. cd gitnexus && npm test, npx tsc --noEmit).

On very long threads, the human may add “Remember: apply all AGENTS.md rules” to re-weight rule tokens against context dilution.

Claude Code hooks

Hooks enforce gates that prompts cannot. In Claude Code, PreToolUse hooks can block tools such as git_commit until checks pass. Adapt to this repo: e.g. cd gitnexus && npm test before commit.

Context budget (Cursor / standards)

Generic “core standards” playbooks are often long and stack-specific. For this monorepo, commands and gotchas live under Cursor Cloud specific instructions below and in CONTRIBUTING.md. If always-on rules grow, split domain rules into .cursor/rules/*.mdc (globs). Cursor: project-wide rules live in .cursor/index.mdc (YAML frontmatter with alwaysApply: true). Claude Code: optionally load a STANDARDS.md only when needed (e.g. “When writing new code, read STANDARDS.md”) to save context.

Reference Documentation

  • This repository: ARCHITECTURE.md, CONTRIBUTING.md, GUARDRAILS.md.
  • Cursor: .cursor/index.mdc (always-on rules); optional .cursor/rules/*.mdc (glob-scoped). Legacy .cursorrules is deprecated — see .cursor/index.mdc.
  • Optional local files: NOTES.md (short vendor-neutral project snapshot). For handoffs, keep notes local (e.g., a scratch file outside the repo) rather than committing HANDOFF.md.
  • GitNexus: skills under .claude/skills/gitnexus/; machine-oriented rules in the gitnexus:startgitnexus:end block below.

Changelog

Date Version Change
2026-04-13 1.3.0 Updated GitNexus index stats after DAG refactor.
2026-03-24 1.2.0 Fixed gitnexus:start block duplication (was inlined in Reference Docs bullet).
2026-03-23 1.1.0 Updated agent instructions (sections, references, Cursor layout).
2026-03-22 1.0.0 Added structured agent header and changelog.

GitNexus — Code Intelligence

This project is indexed by GitNexus as GitNexus (4325 symbols, 10556 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.

If any GitNexus tool warns the index is stale, run npx gitnexus analyze in terminal first.

Always Do

  • MUST run impact analysis before editing any symbol. Before modifying a function, class, or method, run gitnexus_impact({target: "symbolName", direction: "upstream"}) and report the blast radius (direct callers, affected processes, risk level) to the user.
  • MUST run gitnexus_detect_changes() before committing to verify your changes only affect expected symbols and execution flows.
  • MUST warn the user if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
  • When exploring unfamiliar code, use gitnexus_query({query: "concept"}) to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
  • When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use gitnexus_context({name: "symbolName"}).

When Debugging

  1. gitnexus_query({query: "<error or symptom>"}) — find execution flows related to the issue
  2. gitnexus_context({name: "<suspect function>"}) — see all callers, callees, and process participation
  3. READ gitnexus://repo/GitNexus/process/{processName} — trace the full execution flow step by step
  4. For regressions: gitnexus_detect_changes({scope: "compare", base_ref: "main"}) — see what your branch changed

When Refactoring

  • Renaming: MUST use gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true}) first. Review the preview — graph edits are safe, text_search edits need manual review. Then run with dry_run: false.
  • Extracting/Splitting: MUST run gitnexus_context({name: "target"}) to see all incoming/outgoing refs, then gitnexus_impact({target: "target", direction: "upstream"}) to find all external callers before moving code.
  • After any refactor: run gitnexus_detect_changes({scope: "all"}) to verify only expected files changed.

Never Do

  • NEVER edit a function, class, or method without first running gitnexus_impact on it.
  • NEVER ignore HIGH or CRITICAL risk warnings from impact analysis.
  • NEVER rename symbols with find-and-replace — use gitnexus_rename which understands the call graph.
  • NEVER commit changes without running gitnexus_detect_changes() to check affected scope.

Tools Quick Reference

Tool When to use Command
query Find code by concept gitnexus_query({query: "auth validation"})
context 360-degree view of one symbol gitnexus_context({name: "validateUser"})
impact Blast radius before editing gitnexus_impact({target: "X", direction: "upstream"})
detect_changes Pre-commit scope check gitnexus_detect_changes({scope: "staged"})
rename Safe multi-file rename gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})
cypher Custom graph queries gitnexus_cypher({query: "MATCH ..."})

Impact Risk Levels

Depth Meaning Action
d=1 WILL BREAK — direct callers/importers MUST update these
d=2 LIKELY AFFECTED — indirect deps Should test
d=3 MAY NEED TESTING — transitive Test if critical path

Resources

Resource Use for
gitnexus://repo/GitNexus/context Codebase overview, check index freshness
gitnexus://repo/GitNexus/clusters All functional areas
gitnexus://repo/GitNexus/processes All execution flows
gitnexus://repo/GitNexus/process/{name} Step-by-step execution trace

Self-Check Before Finishing

Before completing any code modification task, verify:

  1. gitnexus_impact was run for all modified symbols
  2. No HIGH/CRITICAL risk warnings were ignored
  3. gitnexus_detect_changes() confirms changes match expected scope
  4. All d=1 (WILL BREAK) dependents were updated

Keeping the Index Fresh

After committing code changes, the GitNexus index becomes stale. Re-run analyze to update it:

npx gitnexus analyze

If the index previously included embeddings, preserve them by adding --embeddings:

npx gitnexus analyze --embeddings

To check whether embeddings exist, inspect .gitnexus/meta.json — the stats.embeddings field shows the count (0 means no embeddings). Running analyze without --embeddings will delete any previously generated embeddings.

Claude Code users: A PostToolUse hook handles this automatically after git commit and git merge.

CLI

Task Read this skill file
Understand architecture / "How does X work?" .claude/skills/gitnexus/gitnexus-exploring/SKILL.md
Blast radius / "What breaks if I change X?" .claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md
Trace bugs / "Why is X failing?" .claude/skills/gitnexus/gitnexus-debugging/SKILL.md
Rename / extract / split / refactor .claude/skills/gitnexus/gitnexus-refactoring/SKILL.md
Tools, resources, schema reference .claude/skills/gitnexus/gitnexus-guide/SKILL.md
Index, status, clean, wiki CLI commands .claude/skills/gitnexus/gitnexus-cli/SKILL.md

Cursor Cloud specific instructions

Repository structure

This is a monorepo with two main products and supporting config packages:

Component Path Purpose
GitNexus CLI/Core gitnexus/ Main product — TypeScript CLI, indexing pipeline, MCP server. Published to npm.
GitNexus Web UI gitnexus-web/ React/Vite browser app — graph explorer + AI chat. Runs entirely in WASM.
Claude Plugin gitnexus-claude-plugin/ Static config for Claude marketplace (no build).
Cursor Integration gitnexus-cursor-integration/ Static config for Cursor editor (no build).
SWE-bench Eval eval/ Python evaluation harness (optional; needs Docker + LLM API keys).

Running services

  • CLI/Core: cd gitnexus && npm run dev (tsx watch mode) or npm run build && node dist/cli/index.js <command>
  • Web UI: cd gitnexus-web && npm run dev (Vite on port 5173)
  • Backend mode: cd <indexed-repo> && node /workspace/gitnexus/dist/cli/index.js serve (HTTP API on port 3741 by default)

Testing

CLI / Core (gitnexus/)

  • Unit tests: cd gitnexus && npm test (vitest, ~2000 tests)
  • Integration tests: cd gitnexus && npm run test:integration (vitest, ~1850 tests). Two LadybugDB file-locking tests (lbug-core-adapter, search-core) may fail in containerized environments due to /tmp locking limitations — this is a known environment issue, not a code bug.
  • TypeScript check: cd gitnexus && npx tsc --noEmit

Web UI (gitnexus-web/)

  • Unit tests: cd gitnexus-web && npm test (vitest, ~200 tests)
  • E2E tests: cd gitnexus-web && E2E=1 npx playwright test (Playwright, 5 tests — requires gitnexus serve + npm run dev running)
  • TypeScript check: cd gitnexus-web && npx tsc -b --noEmit

No separate lint command is configured; TypeScript strict checking serves as the primary static analysis.

Gotchas

  • npm install in gitnexus/ triggers prepare (builds via tsc) and postinstall (patches tree-sitter-swift). Native tree-sitter bindings require python3, make, and g++ to be present.
  • tree-sitter-kotlin and tree-sitter-swift are optional dependencies — install warnings for these are expected and non-blocking.
  • The Web UI uses vite-plugin-wasm and requires Cross-Origin-Opener-Policy/Cross-Origin-Embedder-Policy headers for SharedArrayBuffer (handled automatically by Vite dev server).
  • There is no ESLint/Prettier configuration in this repo.