#
tokens: 48393/50000 16/367 files (page 5/18)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 5 of 18. Use http://codebase.md/shashankss1205/codegraphcontext?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .github
│   └── workflows
│       ├── e2e-tests.yml
│       ├── post_discord_invite.yml
│       ├── test.yml
│       └── update-contributors.yml
├── .gitignore
├── CONTRIBUTING.md
├── contributors.md
├── docs
│   ├── docs
│   │   ├── architecture.md
│   │   ├── cli.md
│   │   ├── contributing_languages.md
│   │   ├── contributing.md
│   │   ├── cookbook.md
│   │   ├── core.md
│   │   ├── future_work.md
│   │   ├── images
│   │   │   ├── 1.png
│   │   │   ├── 11.png
│   │   │   ├── 12.png
│   │   │   ├── 13.png
│   │   │   ├── 14.png
│   │   │   ├── 16.png
│   │   │   ├── 19.png
│   │   │   ├── 2.png
│   │   │   ├── 20.png
│   │   │   ├── 21.png
│   │   │   ├── 22.png
│   │   │   ├── 23.png
│   │   │   ├── 24.png
│   │   │   ├── 26.png
│   │   │   ├── 28.png
│   │   │   ├── 29.png
│   │   │   ├── 3.png
│   │   │   ├── 30.png
│   │   │   ├── 31.png
│   │   │   ├── 32.png
│   │   │   ├── 33.png
│   │   │   ├── 34.png
│   │   │   ├── 35.png
│   │   │   ├── 36.png
│   │   │   ├── 38.png
│   │   │   ├── 39.png
│   │   │   ├── 4.png
│   │   │   ├── 40.png
│   │   │   ├── 41.png
│   │   │   ├── 42.png
│   │   │   ├── 43.png
│   │   │   ├── 44.png
│   │   │   ├── 5.png
│   │   │   ├── 6.png
│   │   │   ├── 7.png
│   │   │   ├── 8.png
│   │   │   ├── 9.png
│   │   │   ├── Indexing.gif
│   │   │   ├── tool_images
│   │   │   │   ├── 1.png
│   │   │   │   ├── 2.png
│   │   │   │   └── 3.png
│   │   │   └── Usecase.gif
│   │   ├── index.md
│   │   ├── installation.md
│   │   ├── license.md
│   │   ├── server.md
│   │   ├── tools.md
│   │   ├── troubleshooting.md
│   │   └── use_cases.md
│   ├── mkdocs.yml
│   └── site
│       ├── 404.html
│       ├── architecture
│       │   └── index.html
│       ├── assets
│       │   ├── images
│       │   │   └── favicon.png
│       │   ├── javascripts
│       │   │   ├── bundle.f55a23d4.min.js
│       │   │   ├── bundle.f55a23d4.min.js.map
│       │   │   ├── lunr
│       │   │   │   ├── min
│       │   │   │   │   ├── lunr.ar.min.js
│       │   │   │   │   ├── lunr.da.min.js
│       │   │   │   │   ├── lunr.de.min.js
│       │   │   │   │   ├── lunr.du.min.js
│       │   │   │   │   ├── lunr.el.min.js
│       │   │   │   │   ├── lunr.es.min.js
│       │   │   │   │   ├── lunr.fi.min.js
│       │   │   │   │   ├── lunr.fr.min.js
│       │   │   │   │   ├── lunr.he.min.js
│       │   │   │   │   ├── lunr.hi.min.js
│       │   │   │   │   ├── lunr.hu.min.js
│       │   │   │   │   ├── lunr.hy.min.js
│       │   │   │   │   ├── lunr.it.min.js
│       │   │   │   │   ├── lunr.ja.min.js
│       │   │   │   │   ├── lunr.jp.min.js
│       │   │   │   │   ├── lunr.kn.min.js
│       │   │   │   │   ├── lunr.ko.min.js
│       │   │   │   │   ├── lunr.multi.min.js
│       │   │   │   │   ├── lunr.nl.min.js
│       │   │   │   │   ├── lunr.no.min.js
│       │   │   │   │   ├── lunr.pt.min.js
│       │   │   │   │   ├── lunr.ro.min.js
│       │   │   │   │   ├── lunr.ru.min.js
│       │   │   │   │   ├── lunr.sa.min.js
│       │   │   │   │   ├── lunr.stemmer.support.min.js
│       │   │   │   │   ├── lunr.sv.min.js
│       │   │   │   │   ├── lunr.ta.min.js
│       │   │   │   │   ├── lunr.te.min.js
│       │   │   │   │   ├── lunr.th.min.js
│       │   │   │   │   ├── lunr.tr.min.js
│       │   │   │   │   ├── lunr.vi.min.js
│       │   │   │   │   └── lunr.zh.min.js
│       │   │   │   ├── tinyseg.js
│       │   │   │   └── wordcut.js
│       │   │   └── workers
│       │   │       ├── search.973d3a69.min.js
│       │   │       └── search.973d3a69.min.js.map
│       │   └── stylesheets
│       │       ├── main.2a3383ac.min.css
│       │       ├── main.2a3383ac.min.css.map
│       │       ├── palette.06af60db.min.css
│       │       └── palette.06af60db.min.css.map
│       ├── cli
│       │   └── index.html
│       ├── contributing
│       │   └── index.html
│       ├── contributing_languages
│       │   └── index.html
│       ├── cookbook
│       │   └── index.html
│       ├── core
│       │   └── index.html
│       ├── future_work
│       │   └── index.html
│       ├── images
│       │   ├── 1.png
│       │   ├── 11.png
│       │   ├── 12.png
│       │   ├── 13.png
│       │   ├── 14.png
│       │   ├── 16.png
│       │   ├── 19.png
│       │   ├── 2.png
│       │   ├── 20.png
│       │   ├── 21.png
│       │   ├── 22.png
│       │   ├── 23.png
│       │   ├── 24.png
│       │   ├── 26.png
│       │   ├── 28.png
│       │   ├── 29.png
│       │   ├── 3.png
│       │   ├── 30.png
│       │   ├── 31.png
│       │   ├── 32.png
│       │   ├── 33.png
│       │   ├── 34.png
│       │   ├── 35.png
│       │   ├── 36.png
│       │   ├── 38.png
│       │   ├── 39.png
│       │   ├── 4.png
│       │   ├── 40.png
│       │   ├── 41.png
│       │   ├── 42.png
│       │   ├── 43.png
│       │   ├── 44.png
│       │   ├── 5.png
│       │   ├── 6.png
│       │   ├── 7.png
│       │   ├── 8.png
│       │   ├── 9.png
│       │   ├── Indexing.gif
│       │   ├── tool_images
│       │   │   ├── 1.png
│       │   │   ├── 2.png
│       │   │   └── 3.png
│       │   └── Usecase.gif
│       ├── index.html
│       ├── installation
│       │   └── index.html
│       ├── license
│       │   └── index.html
│       ├── search
│       │   └── search_index.json
│       ├── server
│       │   └── index.html
│       ├── sitemap.xml
│       ├── sitemap.xml.gz
│       ├── tools
│       │   └── index.html
│       ├── troubleshooting
│       │   └── index.html
│       └── use_cases
│           └── index.html
├── images
│   ├── 1.png
│   ├── 11.png
│   ├── 12.png
│   ├── 13.png
│   ├── 14.png
│   ├── 16.png
│   ├── 19.png
│   ├── 2.png
│   ├── 20.png
│   ├── 21.png
│   ├── 22.png
│   ├── 23.png
│   ├── 24.png
│   ├── 26.png
│   ├── 28.png
│   ├── 29.png
│   ├── 3.png
│   ├── 30.png
│   ├── 31.png
│   ├── 32.png
│   ├── 33.png
│   ├── 34.png
│   ├── 35.png
│   ├── 36.png
│   ├── 38.png
│   ├── 39.png
│   ├── 4.png
│   ├── 40.png
│   ├── 41.png
│   ├── 42.png
│   ├── 43.png
│   ├── 44.png
│   ├── 5.png
│   ├── 6.png
│   ├── 7.png
│   ├── 8.png
│   ├── 9.png
│   ├── Indexing.gif
│   ├── tool_images
│   │   ├── 1.png
│   │   ├── 2.png
│   │   └── 3.png
│   └── Usecase.gif
├── LICENSE
├── MANIFEST.in
├── organizer
│   ├── CONTRIBUTING_LANGUAGES.md
│   ├── cookbook.md
│   ├── docs.md
│   ├── language_specific_nodes.md
│   ├── Tools_Exploration.md
│   └── troubleshoot.md
├── package-lock.json
├── pyproject.toml
├── README.md
├── scripts
│   ├── generate_lang_contributors.py
│   └── post_install_fix.sh
├── SECURITY.md
├── src
│   └── codegraphcontext
│       ├── __init__.py
│       ├── __main__.py
│       ├── cli
│       │   ├── __init__.py
│       │   ├── cli_helpers.py
│       │   ├── main.py
│       │   ├── setup_macos.py
│       │   └── setup_wizard.py
│       ├── core
│       │   ├── __init__.py
│       │   ├── database.py
│       │   ├── jobs.py
│       │   └── watcher.py
│       ├── prompts.py
│       ├── server.py
│       ├── tools
│       │   ├── __init__.py
│       │   ├── advanced_language_query_tool.py
│       │   ├── code_finder.py
│       │   ├── graph_builder.py
│       │   ├── languages
│       │   │   ├── c.py
│       │   │   ├── cpp.py
│       │   │   ├── go.py
│       │   │   ├── java.py
│       │   │   ├── javascript.py
│       │   │   ├── python.py
│       │   │   ├── ruby.py
│       │   │   ├── rust.py
│       │   │   └── typescript.py
│       │   ├── package_resolver.py
│       │   ├── query_tool_languages
│       │   │   ├── c_toolkit.py
│       │   │   ├── cpp_toolkit.py
│       │   │   ├── go_toolkit.py
│       │   │   ├── java_toolkit.py
│       │   │   ├── javascript_toolkit.py
│       │   │   ├── python_toolkit.py
│       │   │   ├── ruby_toolkit.py
│       │   │   ├── rust_toolkit.py
│       │   │   └── typescript_toolkit.py
│       │   └── system.py
│       └── utils
│           └── debug_log.py
├── tests
│   ├── __init__.py
│   ├── conftest.py
│   ├── sample_project
│   │   ├── advanced_calls.py
│   │   ├── advanced_classes.py
│   │   ├── advanced_classes2.py
│   │   ├── advanced_functions.py
│   │   ├── advanced_imports.py
│   │   ├── async_features.py
│   │   ├── callbacks_decorators.py
│   │   ├── circular1.py
│   │   ├── circular2.py
│   │   ├── class_instantiation.py
│   │   ├── cli_and_dunder.py
│   │   ├── complex_classes.py
│   │   ├── comprehensions_generators.py
│   │   ├── context_managers.py
│   │   ├── control_flow.py
│   │   ├── datatypes.py
│   │   ├── dynamic_dispatch.py
│   │   ├── dynamic_imports.py
│   │   ├── edge_cases
│   │   │   ├── comments_only.py
│   │   │   ├── docstring_only.py
│   │   │   ├── empty.py
│   │   │   ├── hardcoded_secrets.py
│   │   │   ├── long_functions.py
│   │   │   └── syntax_error.py
│   │   ├── function_chains.py
│   │   ├── generators.py
│   │   ├── import_reexports.py
│   │   ├── mapping_calls.py
│   │   ├── module_a.py
│   │   ├── module_b.py
│   │   ├── module_c
│   │   │   ├── __init__.py
│   │   │   ├── submodule1.py
│   │   │   └── submodule2.py
│   │   ├── namespace_pkg
│   │   │   └── ns_module.py
│   │   ├── pattern_matching.py
│   │   └── typing_examples.py
│   ├── sample_project_c
│   │   ├── cgc_sample
│   │   ├── include
│   │   │   ├── config.h
│   │   │   ├── math
│   │   │   │   └── vec.h
│   │   │   ├── module.h
│   │   │   ├── platform.h
│   │   │   └── util.h
│   │   ├── Makefile
│   │   ├── README.md
│   │   └── src
│   │       ├── main.c
│   │       ├── math
│   │       │   └── vec.c
│   │       ├── module.c
│   │       └── util.c
│   ├── sample_project_cpp
│   │   ├── class_features.cpp
│   │   ├── classes.cpp
│   │   ├── control_flow.cpp
│   │   ├── edge_cases.cpp
│   │   ├── enum_struct_union.cpp
│   │   ├── exceptions.cpp
│   │   ├── file_io.cpp
│   │   ├── function_chain.cpp
│   │   ├── function_chain.h
│   │   ├── function_types.cpp
│   │   ├── main.cpp
│   │   ├── main.exe
│   │   ├── namespaces.cpp
│   │   ├── raii_example.cpp
│   │   ├── README.md
│   │   ├── sample_project.exe
│   │   ├── stl_usage.cpp
│   │   ├── templates.cpp
│   │   └── types_variable_assignments.cpp
│   ├── sample_project_go
│   │   ├── advanced_types.go
│   │   ├── basic_functions.go
│   │   ├── embedded_composition.go
│   │   ├── error_handling.go
│   │   ├── generics.go
│   │   ├── go.mod
│   │   ├── goroutines_channels.go
│   │   ├── interfaces.go
│   │   ├── packages_imports.go
│   │   ├── README.md
│   │   ├── structs_methods.go
│   │   └── util
│   │       └── helpers.go
│   ├── sample_project_java
│   │   ├── out
│   │   │   └── com
│   │   │       └── example
│   │   │           └── app
│   │   │               ├── annotations
│   │   │               │   └── Logged.class
│   │   │               ├── Main.class
│   │   │               ├── misc
│   │   │               │   ├── Outer.class
│   │   │               │   └── Outer$Inner.class
│   │   │               ├── model
│   │   │               │   ├── Role.class
│   │   │               │   └── User.class
│   │   │               ├── service
│   │   │               │   ├── AbstractGreeter.class
│   │   │               │   ├── GreetingService.class
│   │   │               │   └── impl
│   │   │               │       └── GreetingServiceImpl.class
│   │   │               └── util
│   │   │                   ├── CollectionUtils.class
│   │   │                   └── IOHelper.class
│   │   ├── README.md
│   │   ├── sources.txt
│   │   └── src
│   │       └── com
│   │           └── example
│   │               └── app
│   │                   ├── annotations
│   │                   │   └── Logged.java
│   │                   ├── Main.java
│   │                   ├── misc
│   │                   │   └── Outer.java
│   │                   ├── model
│   │                   │   ├── Role.java
│   │                   │   └── User.java
│   │                   ├── service
│   │                   │   ├── AbstractGreeter.java
│   │                   │   ├── GreetingService.java
│   │                   │   └── impl
│   │                   │       └── GreetingServiceImpl.java
│   │                   └── util
│   │                       ├── CollectionUtils.java
│   │                       └── IOHelper.java
│   ├── sample_project_javascript
│   │   ├── arrays.js
│   │   ├── asyncAwait.js
│   │   ├── classes.js
│   │   ├── dom.js
│   │   ├── errorHandling.js
│   │   ├── events.js
│   │   ├── exporter.js
│   │   ├── fetchAPI.js
│   │   ├── fixtures
│   │   │   └── js
│   │   │       └── accessors.js
│   │   ├── functions.js
│   │   ├── importer.js
│   │   ├── objects.js
│   │   ├── promises.js
│   │   ├── README.md
│   │   └── variables.js
│   ├── sample_project_misc
│   │   ├── index.html
│   │   ├── README.md
│   │   ├── styles.css
│   │   ├── tables.css
│   │   └── tables.html
│   ├── sample_project_php
│   │   ├── classes_objects.php
│   │   ├── database.php
│   │   ├── edgecases.php
│   │   ├── error_handling.php
│   │   ├── file_handling.php
│   │   ├── functions.php
│   │   ├── generators_iterators.php
│   │   ├── globals_superglobals.php
│   │   ├── Inheritance.php
│   │   ├── interface_traits.php
│   │   └── README.md
│   ├── sample_project_ruby
│   │   ├── class_example.rb
│   │   ├── enumerables.rb
│   │   ├── error_handling.rb
│   │   ├── file_io.rb
│   │   ├── inheritance_example.rb
│   │   ├── main.rb
│   │   ├── metaprogramming.rb
│   │   ├── mixins_example.rb
│   │   ├── module_example.rb
│   │   └── tests
│   │       ├── test_mixins.py
│   │       └── test_sample.rb
│   ├── sample_project_rust
│   │   ├── Cargo.toml
│   │   ├── README.md
│   │   └── src
│   │       ├── basic_functions.rs
│   │       ├── concurrency.rs
│   │       ├── error_handling.rs
│   │       ├── generics.rs
│   │       ├── iterators_closures.rs
│   │       ├── lib.rs
│   │       ├── lifetimes_references.rs
│   │       ├── modules.rs
│   │       ├── smart_pointers.rs
│   │       ├── structs_enums.rs
│   │       └── traits.rs
│   ├── sample_project_typescript
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── advanced-types.ts
│   │   │   ├── async-promises.ts
│   │   │   ├── classes-inheritance.ts
│   │   │   ├── decorators-metadata.ts
│   │   │   ├── error-validation.ts
│   │   │   ├── functions-generics.ts
│   │   │   ├── index.ts
│   │   │   ├── modules-namespaces.ts
│   │   │   ├── types-interfaces.ts
│   │   │   └── utilities-helpers.ts
│   │   └── tsconfig.json
│   ├── test_cpp_parser.py
│   ├── test_database_validation.py
│   ├── test_end_to_end.py
│   ├── test_graph_indexing_js.py
│   ├── test_graph_indexing.py
│   ├── test_tree_sitter
│   │   ├── __init__.py
│   │   ├── class_instantiation.py
│   │   ├── complex_classes.py
│   │   └── test_file.py
│   └── test_typescript_parser.py
└── website
    ├── .example.env
    ├── .gitignore
    ├── api
    │   └── pypi.ts
    ├── bun.lockb
    ├── components.json
    ├── eslint.config.js
    ├── index.html
    ├── package-lock.json
    ├── package.json
    ├── postcss.config.js
    ├── public
    │   ├── favicon.ico
    │   ├── placeholder.svg
    │   └── robots.txt
    ├── README.md
    ├── src
    │   ├── App.css
    │   ├── App.tsx
    │   ├── assets
    │   │   ├── function-calls.png
    │   │   ├── graph-total.png
    │   │   ├── hero-graph.jpg
    │   │   └── hierarchy.png
    │   ├── components
    │   │   ├── ComparisonTable.tsx
    │   │   ├── CookbookSection.tsx
    │   │   ├── DemoSection.tsx
    │   │   ├── ExamplesSection.tsx
    │   │   ├── FeaturesSection.tsx
    │   │   ├── Footer.tsx
    │   │   ├── HeroSection.tsx
    │   │   ├── InstallationSection.tsx
    │   │   ├── MoveToTop.tsx
    │   │   ├── ShowDownloads.tsx
    │   │   ├── ShowStarGraph.tsx
    │   │   ├── TestimonialSection.tsx
    │   │   ├── ThemeProvider.tsx
    │   │   ├── ThemeToggle.tsx
    │   │   └── ui
    │   │       ├── accordion.tsx
    │   │       ├── alert-dialog.tsx
    │   │       ├── alert.tsx
    │   │       ├── aspect-ratio.tsx
    │   │       ├── avatar.tsx
    │   │       ├── badge.tsx
    │   │       ├── breadcrumb.tsx
    │   │       ├── button.tsx
    │   │       ├── calendar.tsx
    │   │       ├── card.tsx
    │   │       ├── carousel.tsx
    │   │       ├── chart.tsx
    │   │       ├── checkbox.tsx
    │   │       ├── collapsible.tsx
    │   │       ├── command.tsx
    │   │       ├── context-menu.tsx
    │   │       ├── dialog.tsx
    │   │       ├── drawer.tsx
    │   │       ├── dropdown-menu.tsx
    │   │       ├── form.tsx
    │   │       ├── hover-card.tsx
    │   │       ├── input-otp.tsx
    │   │       ├── input.tsx
    │   │       ├── label.tsx
    │   │       ├── menubar.tsx
    │   │       ├── navigation-menu.tsx
    │   │       ├── orbiting-circles.tsx
    │   │       ├── pagination.tsx
    │   │       ├── popover.tsx
    │   │       ├── progress.tsx
    │   │       ├── radio-group.tsx
    │   │       ├── resizable.tsx
    │   │       ├── scroll-area.tsx
    │   │       ├── select.tsx
    │   │       ├── separator.tsx
    │   │       ├── sheet.tsx
    │   │       ├── sidebar.tsx
    │   │       ├── skeleton.tsx
    │   │       ├── slider.tsx
    │   │       ├── sonner.tsx
    │   │       ├── switch.tsx
    │   │       ├── table.tsx
    │   │       ├── tabs.tsx
    │   │       ├── textarea.tsx
    │   │       ├── toast.tsx
    │   │       ├── toaster.tsx
    │   │       ├── toggle-group.tsx
    │   │       ├── toggle.tsx
    │   │       ├── tooltip.tsx
    │   │       └── use-toast.ts
    │   ├── hooks
    │   │   ├── use-mobile.tsx
    │   │   └── use-toast.ts
    │   ├── index.css
    │   ├── lib
    │   │   └── utils.ts
    │   ├── main.tsx
    │   ├── pages
    │   │   ├── Index.tsx
    │   │   └── NotFound.tsx
    │   └── vite-env.d.ts
    ├── tailwind.config.ts
    ├── tsconfig.app.json
    ├── tsconfig.json
    ├── tsconfig.node.json
    ├── vercel.json
    └── vite.config.ts
```

# Files

--------------------------------------------------------------------------------
/src/codegraphcontext/cli/cli_helpers.py:
--------------------------------------------------------------------------------

```python
  1 | # src/codegraphcontext/cli/cli_helpers.py
  2 | import asyncio
  3 | import json
  4 | import urllib.parse
  5 | from pathlib import Path
  6 | import time
  7 | from rich.console import Console
  8 | from rich.table import Table
  9 | 
 10 | from ..core.database import DatabaseManager
 11 | from ..core.jobs import JobManager
 12 | from ..tools.code_finder import CodeFinder
 13 | from ..tools.graph_builder import GraphBuilder
 14 | from ..tools.package_resolver import get_local_package_path
 15 | 
 16 | console = Console()
 17 | 
 18 | 
 19 | def _initialize_services():
 20 |     """Initializes and returns core service managers."""
 21 |     console.print("[dim]Initializing services and database connection...[/dim]")
 22 |     db_manager = DatabaseManager()
 23 |     try:
 24 |         db_manager.get_driver()
 25 |     except ValueError as e:
 26 |         console.print(f"[bold red]Database Connection Error:[/bold red] {e}")
 27 |         console.print("Please ensure your Neo4j credentials are correct and the database is running.")
 28 |         return None, None, None
 29 |     
 30 |     # The GraphBuilder requires an event loop, even for synchronous-style execution
 31 |     try:
 32 |         loop = asyncio.get_running_loop()
 33 |     except RuntimeError:
 34 |         loop = asyncio.new_event_loop()
 35 |         asyncio.set_event_loop(loop)
 36 | 
 37 |     graph_builder = GraphBuilder(db_manager, JobManager(), loop)
 38 |     code_finder = CodeFinder(db_manager)
 39 |     console.print("[dim]Services initialized.[/dim]")
 40 |     return db_manager, graph_builder, code_finder
 41 | 
 42 | 
 43 | def index_helper(path: str):
 44 |     """Synchronously indexes a repository."""
 45 |     time_start = time.time()
 46 |     services = _initialize_services()
 47 |     if not all(services):
 48 |         return
 49 | 
 50 |     db_manager, graph_builder, code_finder = services
 51 |     path_obj = Path(path).resolve()
 52 | 
 53 |     if not path_obj.exists():
 54 |         console.print(f"[red]Error: Path does not exist: {path_obj}[/red]")
 55 |         db_manager.close_driver()
 56 |         return
 57 | 
 58 |     indexed_repos = code_finder.list_indexed_repositories()
 59 |     if any(Path(repo["path"]).resolve() == path_obj for repo in indexed_repos):
 60 |         console.print(f"[yellow]Repository '{path}' is already indexed. Skipping.[/yellow]")
 61 |         db_manager.close_driver()
 62 |         return
 63 | 
 64 |     console.print(f"Starting indexing for: {path_obj}")
 65 |     console.print("[yellow]This may take a few minutes for large repositories...[/yellow]")
 66 | 
 67 |     async def do_index():
 68 |         await graph_builder.build_graph_from_path_async(path_obj, is_dependency=False)
 69 | 
 70 |     try:
 71 |         asyncio.run(do_index())
 72 |         time_end = time.time()
 73 |         elapsed = time_end - time_start
 74 |         console.print(f"[green]Successfully finished indexing: {path} in {elapsed:.2f} seconds[/green]")
 75 |     except Exception as e:
 76 |         console.print(f"[bold red]An error occurred during indexing:[/bold red] {e}")
 77 |     finally:
 78 |         db_manager.close_driver()
 79 | 
 80 | 
 81 | def add_package_helper(package_name: str, language: str):
 82 |     """Synchronously indexes a package."""
 83 |     services = _initialize_services()
 84 |     if not all(services):
 85 |         return
 86 | 
 87 |     db_manager, graph_builder, code_finder = services
 88 | 
 89 |     package_path_str = get_local_package_path(package_name, language)
 90 |     if not package_path_str:
 91 |         console.print(f"[red]Error: Could not find package '{package_name}' for language '{language}'.[/red]")
 92 |         db_manager.close_driver()
 93 |         return
 94 | 
 95 |     package_path = Path(package_path_str)
 96 |     
 97 |     indexed_repos = code_finder.list_indexed_repositories()
 98 |     if any(repo.get("name") == package_name for repo in indexed_repos if repo.get("is_dependency")):
 99 |         console.print(f"[yellow]Package '{package_name}' is already indexed. Skipping.[/yellow]")
100 |         db_manager.close_driver()
101 |         return
102 | 
103 |     console.print(f"Starting indexing for package '{package_name}' at: {package_path}")
104 |     console.print("[yellow]This may take a few minutes...[/yellow]")
105 | 
106 |     async def do_index():
107 |         await graph_builder.build_graph_from_path_async(package_path, is_dependency=True)
108 | 
109 |     try:
110 |         asyncio.run(do_index())
111 |         console.print(f"[green]Successfully finished indexing package: {package_name}[/green]")
112 |     except Exception as e:
113 |         console.print(f"[bold red]An error occurred during package indexing:[/bold red] {e}")
114 |     finally:
115 |         db_manager.close_driver()
116 | 
117 | 
118 | def list_repos_helper():
119 |     """Lists all indexed repositories."""
120 |     services = _initialize_services()
121 |     if not all(services):
122 |         return
123 |     
124 |     db_manager, _, code_finder = services
125 |     
126 |     try:
127 |         repos = code_finder.list_indexed_repositories()
128 |         if not repos:
129 |             console.print("[yellow]No repositories indexed yet.[/yellow]")
130 |             return
131 | 
132 |         table = Table(show_header=True, header_style="bold magenta")
133 |         table.add_column("Name", style="dim")
134 |         table.add_column("Path")
135 |         table.add_column("Type")
136 | 
137 |         for repo in repos:
138 |             repo_type = "Dependency" if repo.get("is_dependency") else "Project"
139 |             table.add_row(repo["name"], repo["path"], repo_type)
140 |         
141 |         console.print(table)
142 |     except Exception as e:
143 |         console.print(f"[bold red]An error occurred:[/bold red] {e}")
144 |     finally:
145 |         db_manager.close_driver()
146 | 
147 | 
148 | def delete_helper(repo_path: str):
149 |     """Deletes a repository from the graph."""
150 |     services = _initialize_services()
151 |     if not all(services):
152 |         return
153 | 
154 |     db_manager, graph_builder, _ = services
155 |     
156 |     try:
157 |         graph_builder.delete_repository_from_graph(repo_path)
158 |         console.print(f"[green]Successfully deleted repository: {repo_path}[/green]")
159 |     except Exception as e:
160 |         console.print(f"[bold red]An error occurred:[/bold red] {e}")
161 |     finally:
162 |         db_manager.close_driver()
163 | 
164 | 
165 | def cypher_helper(query: str):
166 |     """Executes a read-only Cypher query."""
167 |     services = _initialize_services()
168 |     if not all(services):
169 |         return
170 | 
171 |     db_manager, _, _ = services
172 |     
173 |     # Replicating safety checks from MCPServer
174 |     forbidden_keywords = ['CREATE', 'MERGE', 'DELETE', 'SET', 'REMOVE', 'DROP', 'CALL apoc']
175 |     if any(keyword in query.upper() for keyword in forbidden_keywords):
176 |         console.print("[bold red]Error: This command only supports read-only queries.[/bold red]")
177 |         db_manager.close_driver()
178 |         return
179 | 
180 |     try:
181 |         with db_manager.get_driver().session() as session:
182 |             result = session.run(query)
183 |             records = [record.data() for record in result]
184 |             console.print(json.dumps(records, indent=2))
185 |     except Exception as e:
186 |         console.print(f"[bold red]An error occurred while executing query:[/bold red] {e}")
187 |     finally:
188 |         db_manager.close_driver()
189 | 
190 | 
191 | def visualize_helper(query: str):
192 |     """Generates a URL to visualize a Cypher query."""
193 |     try:
194 |         encoded_query = urllib.parse.quote(query)
195 |         visualization_url = f"http://localhost:7474/browser/?cmd=edit&arg={encoded_query}"
196 |         console.print("[green]Graph visualization URL:[/green]")
197 |         console.print(visualization_url)
198 |         console.print("Open the URL in your browser to see the graph.")
199 |     except Exception as e:
200 |         console.print(f"[bold red]An error occurred while generating URL:[/bold red] {e}")
201 | 
202 | 
```

--------------------------------------------------------------------------------
/website/src/components/ShowStarGraph.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
  2 | import { Badge } from "@/components/ui/badge";
  3 | import { Button } from "@/components/ui/button";
  4 | import { ExternalLink, Star, TrendingUp, RefreshCw } from "lucide-react";
  5 | import { useState, useCallback, useEffect } from "react";
  6 | 
  7 | export default function ShowStarGraph() {
  8 |   const [imageLoaded, setImageLoaded] = useState(false);
  9 |   const [imageError, setImageError] = useState(false);
 10 |   const [refreshKey, setRefreshKey] = useState(0);
 11 |   const [isRefreshing, setIsRefreshing] = useState(false);
 12 | 
 13 |   const baseStarHistoryImageUrl =
 14 |     "https://api.star-history.com/svg?repos=Shashankss1205/CodeGraphContext&type=Date";
 15 | 
 16 |   // Add cache busting parameter to force updates
 17 |   const starHistoryImageUrl = `${baseStarHistoryImageUrl}&t=${refreshKey}`;
 18 |   const starHistoryDarkImageUrl = `${baseStarHistoryImageUrl}&theme=dark&t=${refreshKey}`;
 19 | 
 20 |   const githubRepoUrl = "https://github.com/Shashankss1205/CodeGraphContext";
 21 |   const starHistoryUrl =
 22 |     "https://star-history.com/#Shashankss1205/CodeGraphContext&Date";
 23 | 
 24 |   const handleImageLoad = () => {
 25 |     setImageLoaded(true);
 26 |     setImageError(false);
 27 |     setIsRefreshing(false);
 28 |   };
 29 | 
 30 |   const handleImageError = () => {
 31 |     setImageError(true);
 32 |     setImageLoaded(false);
 33 |     setIsRefreshing(false);
 34 |   };
 35 | 
 36 |   const handleRefresh = useCallback(() => {
 37 |     setIsRefreshing(true);
 38 |     setImageLoaded(false);
 39 |     setImageError(false);
 40 |     setRefreshKey((prev) => prev + 1);
 41 |   }, []);
 42 | 
 43 |   //Refreshed the graph everyday
 44 |    useEffect(() => {
 45 |     const today = new Date().toDateString();
 46 |     const lastUpdated = localStorage.getItem("starHistoryLastUpdate");
 47 | 
 48 |     if (lastUpdated !== today) {
 49 |       handleRefresh();
 50 |       localStorage.setItem("starHistoryLastUpdate", today);
 51 |     }
 52 |   }, [handleRefresh]);
 53 | 
 54 |   return (
 55 |     <>
 56 |       <section className="px-4 bg-gradient-to-b from-secondary/10 to-background" data-aos="fade-up">
 57 |         <div className="container mx-auto max-w-6xl">
 58 |           <div className="text-center mb-12" data-aos="fade-down">
 59 |             <div className="flex items-center justify-center gap-2 mb-4">
 60 |               <Star className="h-6 w-6 text-yellow-500 fill-yellow-500" />
 61 | 
 62 |               <h2 className="text-4xl md:text-5xl font-bold bg-gradient-to-r from-primary via-primary to-accent bg-clip-text text-transparent py-2">
 63 |                 Star History
 64 |               </h2>
 65 |               <TrendingUp className="h-6 w-6 text-green-500" />
 66 |             </div>
 67 |             <p className="text-xl text-muted-foreground max-w-3xl mx-auto">
 68 |               Track the growth and popularity of CodeGraphContext over time
 69 |             </p>
 70 |           </div>
 71 | 
 72 |           <Card className="w-full shadow-2xl border-border/50 bg-card/50 backdrop-blur-sm" data-aos="zoom-in-up">
 73 |             <CardHeader className="text-center">
 74 |               <CardTitle className="flex items-center justify-center gap-2 text-2xl">
 75 |                 <Star className="h-5 w-5 text-yellow-500 fill-yellow-500" />
 76 |                 Repository Growth
 77 |                 <Badge variant="outline" className="ml-2">
 78 |                   Updated Daily
 79 |                 </Badge>
 80 |               </CardTitle>
 81 |             </CardHeader>
 82 |             <CardContent className="p-6">
 83 |               <div className="relative">
 84 |                 {(!imageLoaded && !imageError) ||
 85 |                   (isRefreshing && (
 86 |                     <div className="w-full h-64 bg-muted rounded-lg flex items-center justify-center">
 87 |                       <div className="text-center">
 88 |                         <div className="animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full mx-auto mb-2"></div>
 89 |                         <p className="text-muted-foreground">
 90 |                           {isRefreshing
 91 |                             ? "Refreshing star history..."
 92 |                             : "Loading star history..."}
 93 |                         </p>
 94 |                       </div>
 95 |                     </div>
 96 |                   ))}
 97 | 
 98 |                 {imageError && (
 99 |                   <div className="w-full h-64 bg-muted rounded-lg flex items-center justify-center border-2 border-dashed border-border">
100 |                     <div className="text-center">
101 |                       <Star className="h-12 w-12 text-muted-foreground mx-auto mb-2" />
102 |                       <p className="text-muted-foreground mb-2">
103 |                         Unable to load star history
104 |                       </p>
105 |                       <Button
106 |                         variant="outline"
107 |                         onClick={() => window.open(starHistoryUrl, "_blank")}
108 |                       >
109 |                         <ExternalLink className="h-4 w-4 mr-2" />
110 |                         View on Star History
111 |                       </Button>
112 |                     </div>
113 |                   </div>
114 |                 )}
115 | 
116 |                 <div key={refreshKey}>
117 |                   <img
118 |                     src={starHistoryImageUrl}
119 |                     alt="CodeGraphContext Star History"
120 |                     className={`w-full h-auto rounded-lg transition-opacity duration-300 dark:hidden ${
121 |                       imageLoaded && !isRefreshing
122 |                         ? "opacity-100"
123 |                         : "opacity-0 absolute inset-0"
124 |                     } ${imageError ? "hidden" : "block"}`}
125 |                     onLoad={handleImageLoad}
126 |                     onError={handleImageError}
127 |                   />
128 |                   <img
129 |                     src={starHistoryDarkImageUrl}
130 |                     alt="CodeGraphContext Star History"
131 |                     className={`w-full h-auto rounded-lg transition-opacity duration-300 hidden dark:block ${
132 |                       imageLoaded && !isRefreshing
133 |                         ? "opacity-100"
134 |                         : "opacity-0 absolute inset-0"
135 |                     } ${imageError ? "hidden" : "block"}`}
136 |                     onLoad={handleImageLoad}
137 |                     onError={handleImageError}
138 |                   />
139 |                 </div>
140 |               </div>
141 | 
142 |               {imageLoaded && !isRefreshing && (
143 |                 <div className="mt-6 flex flex-col sm:flex-row gap-4 justify-center items-center" data-aos="fade-up" data-aos-delay="200">
144 |                   <Button
145 |                     variant="outline"
146 |                     onClick={() => window.open(githubRepoUrl, "_blank")}
147 |                     className="flex items-center gap-2"
148 |                   >
149 |                     <Star className="h-4 w-4" />
150 |                     Star on GitHub
151 |                     <ExternalLink className="h-4 w-4" />
152 |                   </Button>
153 | 
154 |                   <Button
155 |                     variant="ghost"
156 |                     onClick={() => window.open(starHistoryUrl, "_blank")}
157 |                     className="flex items-center gap-2"
158 |                   >
159 |                     <TrendingUp className="h-4 w-4" />
160 |                     View Full History
161 |                     <ExternalLink className="h-4 w-4" />
162 |                   </Button>
163 | 
164 |                 </div>
165 |               )}
166 |             </CardContent>
167 |           </Card>
168 | 
169 |         </div>
170 |       </section>
171 |       <br />
172 |       <br />
173 |     </>
174 |   );
175 | }
176 | 
177 | 
```

--------------------------------------------------------------------------------
/website/src/components/ui/context-menu.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import * as React from "react";
  2 | import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
  3 | import { Check, ChevronRight, Circle } from "lucide-react";
  4 | 
  5 | import { cn } from "@/lib/utils";
  6 | 
  7 | const ContextMenu = ContextMenuPrimitive.Root;
  8 | 
  9 | const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
 10 | 
 11 | const ContextMenuGroup = ContextMenuPrimitive.Group;
 12 | 
 13 | const ContextMenuPortal = ContextMenuPrimitive.Portal;
 14 | 
 15 | const ContextMenuSub = ContextMenuPrimitive.Sub;
 16 | 
 17 | const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
 18 | 
 19 | const ContextMenuSubTrigger = React.forwardRef<
 20 |   React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
 21 |   React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
 22 |     inset?: boolean;
 23 |   }
 24 | >(({ className, inset, children, ...props }, ref) => (
 25 |   <ContextMenuPrimitive.SubTrigger
 26 |     ref={ref}
 27 |     className={cn(
 28 |       "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
 29 |       inset && "pl-8",
 30 |       className,
 31 |     )}
 32 |     {...props}
 33 |   >
 34 |     {children}
 35 |     <ChevronRight className="ml-auto h-4 w-4" />
 36 |   </ContextMenuPrimitive.SubTrigger>
 37 | ));
 38 | ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
 39 | 
 40 | const ContextMenuSubContent = React.forwardRef<
 41 |   React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
 42 |   React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
 43 | >(({ className, ...props }, ref) => (
 44 |   <ContextMenuPrimitive.SubContent
 45 |     ref={ref}
 46 |     className={cn(
 47 |       "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 48 |       className,
 49 |     )}
 50 |     {...props}
 51 |   />
 52 | ));
 53 | ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
 54 | 
 55 | const ContextMenuContent = React.forwardRef<
 56 |   React.ElementRef<typeof ContextMenuPrimitive.Content>,
 57 |   React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
 58 | >(({ className, ...props }, ref) => (
 59 |   <ContextMenuPrimitive.Portal>
 60 |     <ContextMenuPrimitive.Content
 61 |       ref={ref}
 62 |       className={cn(
 63 |         "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 64 |         className,
 65 |       )}
 66 |       {...props}
 67 |     />
 68 |   </ContextMenuPrimitive.Portal>
 69 | ));
 70 | ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
 71 | 
 72 | const ContextMenuItem = React.forwardRef<
 73 |   React.ElementRef<typeof ContextMenuPrimitive.Item>,
 74 |   React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
 75 |     inset?: boolean;
 76 |   }
 77 | >(({ className, inset, ...props }, ref) => (
 78 |   <ContextMenuPrimitive.Item
 79 |     ref={ref}
 80 |     className={cn(
 81 |       "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
 82 |       inset && "pl-8",
 83 |       className,
 84 |     )}
 85 |     {...props}
 86 |   />
 87 | ));
 88 | ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
 89 | 
 90 | const ContextMenuCheckboxItem = React.forwardRef<
 91 |   React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
 92 |   React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
 93 | >(({ className, children, checked, ...props }, ref) => (
 94 |   <ContextMenuPrimitive.CheckboxItem
 95 |     ref={ref}
 96 |     className={cn(
 97 |       "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
 98 |       className,
 99 |     )}
100 |     checked={checked}
101 |     {...props}
102 |   >
103 |     <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
104 |       <ContextMenuPrimitive.ItemIndicator>
105 |         <Check className="h-4 w-4" />
106 |       </ContextMenuPrimitive.ItemIndicator>
107 |     </span>
108 |     {children}
109 |   </ContextMenuPrimitive.CheckboxItem>
110 | ));
111 | ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName;
112 | 
113 | const ContextMenuRadioItem = React.forwardRef<
114 |   React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
115 |   React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
116 | >(({ className, children, ...props }, ref) => (
117 |   <ContextMenuPrimitive.RadioItem
118 |     ref={ref}
119 |     className={cn(
120 |       "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
121 |       className,
122 |     )}
123 |     {...props}
124 |   >
125 |     <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
126 |       <ContextMenuPrimitive.ItemIndicator>
127 |         <Circle className="h-2 w-2 fill-current" />
128 |       </ContextMenuPrimitive.ItemIndicator>
129 |     </span>
130 |     {children}
131 |   </ContextMenuPrimitive.RadioItem>
132 | ));
133 | ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
134 | 
135 | const ContextMenuLabel = React.forwardRef<
136 |   React.ElementRef<typeof ContextMenuPrimitive.Label>,
137 |   React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
138 |     inset?: boolean;
139 |   }
140 | >(({ className, inset, ...props }, ref) => (
141 |   <ContextMenuPrimitive.Label
142 |     ref={ref}
143 |     className={cn("px-2 py-1.5 text-sm font-semibold text-foreground", inset && "pl-8", className)}
144 |     {...props}
145 |   />
146 | ));
147 | ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
148 | 
149 | const ContextMenuSeparator = React.forwardRef<
150 |   React.ElementRef<typeof ContextMenuPrimitive.Separator>,
151 |   React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
152 | >(({ className, ...props }, ref) => (
153 |   <ContextMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-border", className)} {...props} />
154 | ));
155 | ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
156 | 
157 | const ContextMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
158 |   return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
159 | };
160 | ContextMenuShortcut.displayName = "ContextMenuShortcut";
161 | 
162 | export {
163 |   ContextMenu,
164 |   ContextMenuTrigger,
165 |   ContextMenuContent,
166 |   ContextMenuItem,
167 |   ContextMenuCheckboxItem,
168 |   ContextMenuRadioItem,
169 |   ContextMenuLabel,
170 |   ContextMenuSeparator,
171 |   ContextMenuShortcut,
172 |   ContextMenuGroup,
173 |   ContextMenuPortal,
174 |   ContextMenuSub,
175 |   ContextMenuSubContent,
176 |   ContextMenuSubTrigger,
177 |   ContextMenuRadioGroup,
178 | };
179 | 
```

--------------------------------------------------------------------------------
/website/src/components/ui/dropdown-menu.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import * as React from "react";
  2 | import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
  3 | import { Check, ChevronRight, Circle } from "lucide-react";
  4 | 
  5 | import { cn } from "@/lib/utils";
  6 | 
  7 | const DropdownMenu = DropdownMenuPrimitive.Root;
  8 | 
  9 | const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
 10 | 
 11 | const DropdownMenuGroup = DropdownMenuPrimitive.Group;
 12 | 
 13 | const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
 14 | 
 15 | const DropdownMenuSub = DropdownMenuPrimitive.Sub;
 16 | 
 17 | const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
 18 | 
 19 | const DropdownMenuSubTrigger = React.forwardRef<
 20 |   React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
 21 |   React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
 22 |     inset?: boolean;
 23 |   }
 24 | >(({ className, inset, children, ...props }, ref) => (
 25 |   <DropdownMenuPrimitive.SubTrigger
 26 |     ref={ref}
 27 |     className={cn(
 28 |       "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent focus:bg-accent",
 29 |       inset && "pl-8",
 30 |       className,
 31 |     )}
 32 |     {...props}
 33 |   >
 34 |     {children}
 35 |     <ChevronRight className="ml-auto h-4 w-4" />
 36 |   </DropdownMenuPrimitive.SubTrigger>
 37 | ));
 38 | DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
 39 | 
 40 | const DropdownMenuSubContent = React.forwardRef<
 41 |   React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
 42 |   React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
 43 | >(({ className, ...props }, ref) => (
 44 |   <DropdownMenuPrimitive.SubContent
 45 |     ref={ref}
 46 |     className={cn(
 47 |       "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 48 |       className,
 49 |     )}
 50 |     {...props}
 51 |   />
 52 | ));
 53 | DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
 54 | 
 55 | const DropdownMenuContent = React.forwardRef<
 56 |   React.ElementRef<typeof DropdownMenuPrimitive.Content>,
 57 |   React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
 58 | >(({ className, sideOffset = 4, ...props }, ref) => (
 59 |   <DropdownMenuPrimitive.Portal>
 60 |     <DropdownMenuPrimitive.Content
 61 |       ref={ref}
 62 |       sideOffset={sideOffset}
 63 |       className={cn(
 64 |         "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 65 |         className,
 66 |       )}
 67 |       {...props}
 68 |     />
 69 |   </DropdownMenuPrimitive.Portal>
 70 | ));
 71 | DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
 72 | 
 73 | const DropdownMenuItem = React.forwardRef<
 74 |   React.ElementRef<typeof DropdownMenuPrimitive.Item>,
 75 |   React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
 76 |     inset?: boolean;
 77 |   }
 78 | >(({ className, inset, ...props }, ref) => (
 79 |   <DropdownMenuPrimitive.Item
 80 |     ref={ref}
 81 |     className={cn(
 82 |       "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
 83 |       inset && "pl-8",
 84 |       className,
 85 |     )}
 86 |     {...props}
 87 |   />
 88 | ));
 89 | DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
 90 | 
 91 | const DropdownMenuCheckboxItem = React.forwardRef<
 92 |   React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
 93 |   React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
 94 | >(({ className, children, checked, ...props }, ref) => (
 95 |   <DropdownMenuPrimitive.CheckboxItem
 96 |     ref={ref}
 97 |     className={cn(
 98 |       "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
 99 |       className,
100 |     )}
101 |     checked={checked}
102 |     {...props}
103 |   >
104 |     <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
105 |       <DropdownMenuPrimitive.ItemIndicator>
106 |         <Check className="h-4 w-4" />
107 |       </DropdownMenuPrimitive.ItemIndicator>
108 |     </span>
109 |     {children}
110 |   </DropdownMenuPrimitive.CheckboxItem>
111 | ));
112 | DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
113 | 
114 | const DropdownMenuRadioItem = React.forwardRef<
115 |   React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
116 |   React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
117 | >(({ className, children, ...props }, ref) => (
118 |   <DropdownMenuPrimitive.RadioItem
119 |     ref={ref}
120 |     className={cn(
121 |       "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
122 |       className,
123 |     )}
124 |     {...props}
125 |   >
126 |     <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
127 |       <DropdownMenuPrimitive.ItemIndicator>
128 |         <Circle className="h-2 w-2 fill-current" />
129 |       </DropdownMenuPrimitive.ItemIndicator>
130 |     </span>
131 |     {children}
132 |   </DropdownMenuPrimitive.RadioItem>
133 | ));
134 | DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
135 | 
136 | const DropdownMenuLabel = React.forwardRef<
137 |   React.ElementRef<typeof DropdownMenuPrimitive.Label>,
138 |   React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
139 |     inset?: boolean;
140 |   }
141 | >(({ className, inset, ...props }, ref) => (
142 |   <DropdownMenuPrimitive.Label
143 |     ref={ref}
144 |     className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
145 |     {...props}
146 |   />
147 | ));
148 | DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
149 | 
150 | const DropdownMenuSeparator = React.forwardRef<
151 |   React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
152 |   React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
153 | >(({ className, ...props }, ref) => (
154 |   <DropdownMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
155 | ));
156 | DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
157 | 
158 | const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
159 |   return <span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />;
160 | };
161 | DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
162 | 
163 | export {
164 |   DropdownMenu,
165 |   DropdownMenuTrigger,
166 |   DropdownMenuContent,
167 |   DropdownMenuItem,
168 |   DropdownMenuCheckboxItem,
169 |   DropdownMenuRadioItem,
170 |   DropdownMenuLabel,
171 |   DropdownMenuSeparator,
172 |   DropdownMenuShortcut,
173 |   DropdownMenuGroup,
174 |   DropdownMenuPortal,
175 |   DropdownMenuSub,
176 |   DropdownMenuSubContent,
177 |   DropdownMenuSubTrigger,
178 |   DropdownMenuRadioGroup,
179 | };
180 | 
```

--------------------------------------------------------------------------------
/organizer/language_specific_nodes.md:
--------------------------------------------------------------------------------

```markdown
  1 | # How to Add Language-Specific Features
  2 | 
  3 | This document outlines the standard pattern for extending the CodeGraphContext tool to support new, language-specific code constructs (like Go interfaces, Rust traits, C++ macros, etc.).
  4 | 
  5 | ## Core Philosophy
  6 | 
  7 | The system is designed with a clear separation of concerns:
  8 | 1.  **Language-Specific Parsers:** Located in `src/codegraphcontext/tools/languages/`, these are responsible for understanding the syntax of a single language and extracting its constructs into a standardized Python dictionary.
  9 | 2.  **Generic Graph Builder:** The `GraphBuilder` in `src/codegraphcontext/tools/graph_builder.py` consumes these dictionaries and is responsible for creating nodes and relationships in the Neo4j database. It is language-agnostic.
 10 | 
 11 | Adding a new feature always involves these two steps: **(1) Specialize the Parser** and **(2) Generalize the Builder**.
 12 | 
 13 | ---
 14 | 
 15 | ## Step-by-Step Guide: Adding a New Node Type
 16 | 
 17 | We will walk through two examples:
 18 | 1.  Adding support for Go `interface` nodes.
 19 | 2.  Adding support for C/C++ `macro` nodes.
 20 | 
 21 | ### Part 1: Modify the Language Parser
 22 | 
 23 | Your first goal is to teach the correct language parser to identify the new construct and return it under a unique key.
 24 | 
 25 | #### Example: Go Interfaces
 26 | 
 27 | **File to Edit:** `src/codegraphcontext/tools/languages/go.py`
 28 | 
 29 | **1. Add a Tree-sitter Query:**
 30 | Ensure a query exists in the `GO_QUERIES` dictionary to find the construct.
 31 | 
 32 | ```python
 33 | GO_QUERIES = {
 34 |     # ... existing queries
 35 |     "interfaces": """
 36 |         (type_declaration
 37 |             (type_spec
 38 |                 name: (type_identifier) @name
 39 |                 type: (interface_type) @interface_body
 40 |             )
 41 |         ) @interface_node
 42 |     """,
 43 | }
 44 | ```
 45 | 
 46 | **2. Create a Dedicated Parsing Method:**
 47 | Create a new method in the `GoTreeSitterParser` class to handle the results from your new query.
 48 | 
 49 | ```python
 50 | # In GoTreeSitterParser class
 51 | def _find_interfaces(self, root_node):
 52 |     interfaces = []
 53 |     interface_query = self.queries['interfaces']
 54 |     for node, capture_name in interface_query.captures(root_node):
 55 |         if capture_name == 'name':
 56 |             interface_node = self._find_type_declaration_for_name(node)
 57 |             if interface_node:
 58 |                 name = self._get_node_text(node)
 59 |                 interfaces.append({
 60 |                     "name": name,
 61 |                     "line_number": interface_node.start_point[0] + 1,
 62 |                     "end_line": interface_node.end_point[0] + 1,
 63 |                     "source": self._get_node_text(interface_node),
 64 |                 })
 65 |     return interfaces
 66 | ```
 67 | 
 68 | **3. Update the Main `parse` Method:**
 69 | In the parser's main `parse` method, call your new function and add its results to the dictionary that gets returned. **The key you use here (e.g., `"interfaces"`) is what the Graph Builder will use.**
 70 | 
 71 | ```python
 72 | # In GoTreeSitterParser.parse()
 73 | def parse(self, file_path: Path, is_dependency: bool = False) -> Dict:
 74 |     # This comment explains the pattern for future developers.
 75 |     # This method orchestrates the parsing of a single file.
 76 |     # It calls specialized `_find_*` methods for each language construct.
 77 |     # The returned dictionary should map a specific key (e.g., 'functions', 'interfaces')
 78 |     # to a list of dictionaries, where each dictionary represents a single code construct.
 79 |     # The GraphBuilder will then use these keys to create nodes with corresponding labels.
 80 |     with open(file_path, "r", encoding="utf-8") as f:
 81 |         source_code = f.read()
 82 | 
 83 |     tree = self.parser.parse(bytes(source_code, "utf8"))
 84 |     root_node = tree.root_node
 85 | 
 86 |     functions = self._find_functions(root_node)
 87 |     structs = self._find_structs(root_node)
 88 |     interfaces = self._find_interfaces(root_node) # Call the new method
 89 |     # ... find other constructs
 90 | 
 91 |     return {
 92 |         "file_path": str(file_path),
 93 |         "functions": functions,
 94 |         "classes": structs,      # Structs are mapped to the generic :Class label
 95 |         "interfaces": interfaces, # The new key-value pair
 96 |         "variables": variables,
 97 |         "imports": imports,
 98 |         "function_calls": function_calls,
 99 |         "is_dependency": is_dependency,
100 |         "lang": self.language_name,
101 |     }
102 | ```
103 | 
104 | ---
105 | 
106 | ### Part 2: Update the Generic Graph Builder
107 | 
108 | Now, teach the `GraphBuilder` how to handle the new key (e.g., `"interfaces"`) produced by the parser.
109 | 
110 | **File to Edit:** `src/codegraphcontext/tools/graph_builder.py`
111 | 
112 | **1. Add a Schema Constraint:**
113 | In the `create_schema` method, add a uniqueness constraint for the new Neo4j node label you are introducing (e.g., `:Interface`, `:Macro`). This is crucial for data integrity.
114 | 
115 | ```python
116 | # In GraphBuilder.create_schema()
117 | def create_schema(self):
118 |     """Create constraints and indexes in Neo4j."""
119 |     # When adding a new node type with a unique key, add its constraint here.
120 |     with self.driver.session() as session:
121 |         try:
122 |             # ... existing constraints
123 |             session.run("CREATE CONSTRAINT class_unique IF NOT EXISTS FOR (c:Class) REQUIRE (c.name, c.file_path, c.line_number) IS UNIQUE")
124 |             
125 |             # Add constraints for the new types
126 |             session.run("CREATE CONSTRAINT interface_unique IF NOT EXISTS FOR (i:Interface) REQUIRE (i.name, i.file_path, i.line_number) IS UNIQUE")
127 |             session.run("CREATE CONSTRAINT macro_unique IF NOT EXISTS FOR (m:Macro) REQUIRE (m.name, m.file_path, m.line_number) IS UNIQUE")
128 |             
129 |             # ... other schema items
130 | ```
131 | 
132 | **2. Update the Node Creation Loop:**
133 | In the `add_file_to_graph` method, there is a list called `item_mappings`. Add your new construct to this list. The builder will handle the rest automatically.
134 | 
135 | ```python
136 | # In GraphBuilder.add_file_to_graph()
137 | 
138 | # To add a new language-specific node type (e.g., 'Trait' for Rust):
139 | # 1. Ensure your language-specific parser returns a list under a unique key (e.g., 'traits': [...] ).
140 | # 2. Add a new constraint for the new label in the `create_schema` method.
141 | # 3. Add a new entry to the `item_mappings` list below (e.g., (file_data.get('traits', []), 'Trait') ).
142 | item_mappings = [
143 |     (file_data.get('functions', []), 'Function'),
144 |     (file_data.get('classes', []), 'Class'),
145 |     (file_data.get('variables', []), 'Variable'),
146 |     (file_data.get('interfaces', []), 'Interface'), # Added for Go
147 |     (file_data.get('macros', []), 'Macro')         # Added for C/C++
148 | ]
149 | for item_data, label in item_mappings:
150 |     for item in item_data:
151 |         # ... generic node creation logic
152 | ```
153 | Using `file_data.get('macros', [])` ensures that the builder doesn't fail if a language parser (like Python's) doesn't produce a `macros` key.
154 | 
155 | ---
156 | 
157 | ## Advanced Topic: Scaling with Multi-Labeling
158 | 
159 | A valid concern is the proliferation of node labels. A more advanced pattern is to use multiple labels to capture both specific and general concepts.
160 | 
161 | For example:
162 | - A Go interface node could have the labels: `[:Interface, :Contract, :Go]`
163 | - A Rust trait node could have the labels: `[:Trait, :Contract, :Rust]`
164 | 
165 | This allows for powerful, cross-language queries (e.g., `MATCH (c:Contract)`) while retaining language-specific details.
166 | 
167 | This can be implemented in `add_file_to_graph` by dynamically constructing the label string based on the data provided by the parser, which already includes a `lang` key.
168 | 
```

--------------------------------------------------------------------------------
/tests/sample_project_go/advanced_types.go:
--------------------------------------------------------------------------------

```go
  1 | // advanced_types.go - Demonstrates advanced Go types
  2 | package main
  3 | 
  4 | import (
  5 | 	"fmt"
  6 | 	"sort"
  7 | )
  8 | 
  9 | // CustomString is a custom type based on string
 10 | type CustomString string
 11 | 
 12 | // Length returns the length of the custom string
 13 | func (cs CustomString) Length() int {
 14 | 	return len(cs)
 15 | }
 16 | 
 17 | // ToUpper converts to uppercase
 18 | func (cs CustomString) ToUpper() CustomString {
 19 | 	return CustomString(fmt.Sprintf("%s", cs))
 20 | }
 21 | 
 22 | // CustomInt is a custom numeric type
 23 | type CustomInt int
 24 | 
 25 | // IsEven checks if the number is even
 26 | func (ci CustomInt) IsEven() bool {
 27 | 	return ci%2 == 0
 28 | }
 29 | 
 30 | // Double doubles the value
 31 | func (ci CustomInt) Double() CustomInt {
 32 | 	return ci * 2
 33 | }
 34 | 
 35 | // Status is an enum-like type
 36 | type Status int
 37 | 
 38 | const (
 39 | 	StatusPending Status = iota
 40 | 	StatusActive
 41 | 	StatusInactive
 42 | 	StatusDeleted
 43 | )
 44 | 
 45 | // String implements Stringer interface for Status
 46 | func (s Status) String() string {
 47 | 	return [...]string{"Pending", "Active", "Inactive", "Deleted"}[s]
 48 | }
 49 | 
 50 | // IsValid checks if status is valid
 51 | func (s Status) IsValid() bool {
 52 | 	return s >= StatusPending && s <= StatusDeleted
 53 | }
 54 | 
 55 | // Priority represents priority levels
 56 | type Priority string
 57 | 
 58 | const (
 59 | 	PriorityLow    Priority = "low"
 60 | 	PriorityMedium Priority = "medium"
 61 | 	PriorityHigh   Priority = "high"
 62 | )
 63 | 
 64 | // MapOperations demonstrates map operations
 65 | func MapOperations() map[string]int {
 66 | 	// Initialize map
 67 | 	scores := make(map[string]int)
 68 | 	
 69 | 	// Add elements
 70 | 	scores["Alice"] = 95
 71 | 	scores["Bob"] = 87
 72 | 	scores["Charlie"] = 92
 73 | 	
 74 | 	// Check existence
 75 | 	if val, ok := scores["Alice"]; ok {
 76 | 		fmt.Printf("Alice's score: %d\n", val)
 77 | 	}
 78 | 	
 79 | 	// Delete element
 80 | 	delete(scores, "Bob")
 81 | 	
 82 | 	return scores
 83 | }
 84 | 
 85 | // NestedMap demonstrates nested maps
 86 | func NestedMap() map[string]map[string]int {
 87 | 	users := make(map[string]map[string]int)
 88 | 	
 89 | 	users["user1"] = make(map[string]int)
 90 | 	users["user1"]["age"] = 25
 91 | 	users["user1"]["score"] = 100
 92 | 	
 93 | 	users["user2"] = map[string]int{
 94 | 		"age":   30,
 95 | 		"score": 95,
 96 | 	}
 97 | 	
 98 | 	return users
 99 | }
100 | 
101 | // SliceOperations demonstrates slice operations
102 | func SliceOperations() []int {
103 | 	// Create slice
104 | 	nums := []int{1, 2, 3, 4, 5}
105 | 	
106 | 	// Append
107 | 	nums = append(nums, 6, 7, 8)
108 | 	
109 | 	// Slice operations
110 | 	subset := nums[2:5]
111 | 	fmt.Println(subset)
112 | 	
113 | 	// Copy
114 | 	copied := make([]int, len(nums))
115 | 	copy(copied, nums)
116 | 	
117 | 	return copied
118 | }
119 | 
120 | // SliceOfSlices demonstrates 2D slices
121 | func SliceOfSlices() [][]int {
122 | 	matrix := [][]int{
123 | 		{1, 2, 3},
124 | 		{4, 5, 6},
125 | 		{7, 8, 9},
126 | 	}
127 | 	
128 | 	return matrix
129 | }
130 | 
131 | // ArrayOperations demonstrates array operations
132 | func ArrayOperations() [5]int {
133 | 	var arr [5]int
134 | 	arr[0] = 10
135 | 	arr[1] = 20
136 | 	
137 | 	// Array initialization
138 | 	arr2 := [5]int{1, 2, 3, 4, 5}
139 | 	
140 | 	return arr2
141 | }
142 | 
143 | // StructWithTags demonstrates struct tags
144 | type User struct {
145 | 	ID        int    `json:"id" db:"user_id"`
146 | 	Username  string `json:"username" db:"username" validate:"required"`
147 | 	Email     string `json:"email" db:"email" validate:"email"`
148 | 	Age       int    `json:"age,omitempty" db:"age"`
149 | 	IsActive  bool   `json:"is_active" db:"is_active"`
150 | 	Role      string `json:"role" db:"role" default:"user"`
151 | }
152 | 
153 | // AnonymousStruct demonstrates anonymous structs
154 | func AnonymousStruct() {
155 | 	person := struct {
156 | 		Name string
157 | 		Age  int
158 | 	}{
159 | 		Name: "John",
160 | 		Age:  30,
161 | 	}
162 | 	
163 | 	fmt.Printf("%+v\n", person)
164 | }
165 | 
166 | // FunctionType is a function type
167 | type FunctionType func(int, int) int
168 | 
169 | // ApplyOperation applies a function operation
170 | func ApplyOperation(a, b int, op FunctionType) int {
171 | 	return op(a, b)
172 | }
173 | 
174 | // MathOperations demonstrates function types
175 | func MathOperations() {
176 | 	add := func(a, b int) int { return a + b }
177 | 	multiply := func(a, b int) int { return a * b }
178 | 	
179 | 	fmt.Println(ApplyOperation(5, 3, add))
180 | 	fmt.Println(ApplyOperation(5, 3, multiply))
181 | }
182 | 
183 | // ChannelTypes demonstrates different channel types
184 | func ChannelTypes() {
185 | 	// Unbuffered channel
186 | 	ch1 := make(chan int)
187 | 	
188 | 	// Buffered channel
189 | 	ch2 := make(chan string, 5)
190 | 	
191 | 	// Send-only channel (in function signature)
192 | 	go func(ch chan<- int) {
193 | 		ch <- 42
194 | 	}(ch1)
195 | 	
196 | 	// Receive-only channel (in function signature)
197 | 	go func(ch <-chan string) {
198 | 		<-ch
199 | 	}(ch2)
200 | }
201 | 
202 | // SortableInts demonstrates custom sorting
203 | type SortableInts []int
204 | 
205 | func (s SortableInts) Len() int           { return len(s) }
206 | func (s SortableInts) Less(i, j int) bool { return s[i] < s[j] }
207 | func (s SortableInts) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
208 | 
209 | // SortIntegers sorts integers using custom type
210 | func SortIntegers(nums []int) []int {
211 | 	sortable := SortableInts(nums)
212 | 	sort.Sort(sortable)
213 | 	return nums
214 | }
215 | 
216 | // ByAge implements sort for Person by age
217 | type ByAge []Person
218 | 
219 | func (a ByAge) Len() int           { return len(a) }
220 | func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
221 | func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
222 | 
223 | // SortPeople sorts people by age
224 | func SortPeople(people []Person) []Person {
225 | 	sort.Sort(ByAge(people))
226 | 	return people
227 | }
228 | 
229 | // Result is a generic result type
230 | type Result struct {
231 | 	Success bool
232 | 	Data    interface{}
233 | 	Error   error
234 | }
235 | 
236 | // NewSuccessResult creates a success result
237 | func NewSuccessResult(data interface{}) Result {
238 | 	return Result{
239 | 		Success: true,
240 | 		Data:    data,
241 | 		Error:   nil,
242 | 	}
243 | }
244 | 
245 | // NewErrorResult creates an error result
246 | func NewErrorResult(err error) Result {
247 | 	return Result{
248 | 		Success: false,
249 | 		Data:    nil,
250 | 		Error:   err,
251 | 	}
252 | }
253 | 
254 | // PointerTypes demonstrates pointer operations
255 | func PointerTypes() {
256 | 	x := 10
257 | 	ptr := &x
258 | 	
259 | 	fmt.Printf("Value: %d, Pointer: %p, Dereferenced: %d\n", x, ptr, *ptr)
260 | 	
261 | 	*ptr = 20
262 | 	fmt.Printf("Modified value: %d\n", x)
263 | }
264 | 
265 | // PointerToStruct demonstrates pointer to struct
266 | func PointerToStruct() *User {
267 | 	user := &User{
268 | 		ID:       1,
269 | 		Username: "john_doe",
270 | 		Email:    "[email protected]",
271 | 		Age:      30,
272 | 		IsActive: true,
273 | 	}
274 | 	
275 | 	return user
276 | }
277 | 
278 | // TypeAlias demonstrates type aliasing
279 | type UserID = int
280 | type Username = string
281 | type EmailAddress = string
282 | 
283 | // CreateUserWithAliases uses type aliases
284 | func CreateUserWithAliases(id UserID, name Username, email EmailAddress) User {
285 | 	return User{
286 | 		ID:       id,
287 | 		Username: name,
288 | 		Email:    email,
289 | 	}
290 | }
291 | 
292 | // InterfaceType demonstrates interface{} (any)
293 | func InterfaceType(data interface{}) string {
294 | 	switch v := data.(type) {
295 | 	case int:
296 | 		return fmt.Sprintf("Integer: %d", v)
297 | 	case string:
298 | 		return fmt.Sprintf("String: %s", v)
299 | 	case []int:
300 | 		return fmt.Sprintf("Slice of ints: %v", v)
301 | 	case User:
302 | 		return fmt.Sprintf("User: %s", v.Username)
303 | 	default:
304 | 		return fmt.Sprintf("Unknown type: %T", v)
305 | 	}
306 | }
307 | 
308 | // BitFlags demonstrates bit flags
309 | type Permission uint8
310 | 
311 | const (
312 | 	PermissionRead Permission = 1 << iota
313 | 	PermissionWrite
314 | 	PermissionExecute
315 | 	PermissionDelete
316 | )
317 | 
318 | // HasPermission checks if a permission is set
319 | func HasPermission(perms Permission, perm Permission) bool {
320 | 	return perms&perm != 0
321 | }
322 | 
323 | // AddPermission adds a permission
324 | func AddPermission(perms Permission, perm Permission) Permission {
325 | 	return perms | perm
326 | }
327 | 
328 | // RemovePermission removes a permission
329 | func RemovePermission(perms Permission, perm Permission) Permission {
330 | 	return perms &^ perm
331 | }
332 | 
333 | func demonstrateAdvancedTypes() {
334 | 	// Custom types
335 | 	cs := CustomString("hello")
336 | 	fmt.Println(cs.Length())
337 | 	
338 | 	ci := CustomInt(10)
339 | 	fmt.Println(ci.IsEven())
340 | 	
341 | 	// Enums
342 | 	status := StatusActive
343 | 	fmt.Println(status.String())
344 | 	
345 | 	// Maps
346 | 	scores := MapOperations()
347 | 	fmt.Println(scores)
348 | 	
349 | 	// Slices
350 | 	nums := SliceOperations()
351 | 	fmt.Println(nums)
352 | 	
353 | 	// Sorting
354 | 	sorted := SortIntegers([]int{5, 2, 8, 1, 9})
355 | 	fmt.Println(sorted)
356 | }
357 | 
358 | 
```

--------------------------------------------------------------------------------
/contributors.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Language Contributors
 2 | 
 3 | This file is auto-generated. Do not edit manually.
 4 | 
 5 | ## C Contributors
 6 | 
 7 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
 8 | |---|---|---|---|---|---|
 9 | | 1 | PrakharGoyal28 | 1 | 295 | 0 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
10 | | 2 | Harsh | 1 | 260 | 256 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
11 | | 3 | [Shashank Shekhar Singh](https://github.com/Shashankss1205) | 1 | 256 | 260 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/c.py?author=Shashankss1205) |
12 | | 4 | TanmayRanaware | 1 | 251 | 13 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
13 | | 5 | Shashankss1205 | 1 | 2 | 5 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
14 | 
15 | 
16 | ## Cpp Contributors
17 | 
18 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
19 | |---|---|---|---|---|---|
20 | | 1 | Paras | 7 | 376 | 69 | [cpp.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
21 | | 2 | Shashankss1205 | 6 | 206 | 470 | [cpp.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
22 | | 3 | [TheSaturnian](https://github.com/GnautSpace) | 1 | 430 | 16 | [cpp.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/cpp.py?author=GnautSpace) |
23 | 
24 | 
25 | ## Go Contributors
26 | 
27 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
28 | |---|---|---|---|---|---|
29 | | 1 | Shashankss1205 | 2 | 19 | 14 | [go.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
30 | | 2 | Harshdhall01 | 1 | 446 | 0 | [go.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
31 | 
32 | 
33 | ## Java Contributors
34 | 
35 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
36 | |---|---|---|---|---|---|
37 | | 1 | Aashish Jha | 1 | 304 | 0 | [java.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
38 | | 2 | Sreeja Khan | 1 | 42 | 1 | [java.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
39 | | 3 | Shashankss1205 | 1 | 8 | 10 | [java.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
40 | | 4 | [Shashank Shekhar Singh](https://github.com/Shashankss1205) | 1 | 0 | 7 | [java.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/java.py?author=Shashankss1205) |
41 | 
42 | 
43 | ## Javascript Contributors
44 | 
45 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
46 | |---|---|---|---|---|---|
47 | | 1 | Shashankss1205 | 4 | 427 | 114 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
48 | | 2 | [Shashank Shekhar Singh](https://github.com/Shashankss1205) | 3 | 289 | 315 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/javascript.py?author=Shashankss1205) |
49 | | 3 | Akshit | 3 | 55 | 5 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
50 | | 4 | PrakharGoyal28 | 1 | 195 | 23 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
51 | | 5 | Priyal Duggal | 1 | 175 | 113 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
52 | 
53 | 
54 | ## Python Contributors
55 | 
56 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
57 | |---|---|---|---|---|---|
58 | | 1 | Shashankss1205 | 4 | 488 | 34 | [python.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
59 | 
60 | 
61 | ## Ruby Contributors
62 | 
63 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
64 | |---|---|---|---|---|---|
65 | | 1 | TanmayRanaware | 1 | 426 | 0 | [ruby.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
66 | | 2 | Peter Jusko | 1 | 71 | 3 | [ruby.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
67 | | 3 | Shashankss1205 | 1 | 2 | 5 | [ruby.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
68 | 
69 | 
70 | ## Rust Contributors
71 | 
72 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
73 | |---|---|---|---|---|---|
74 | | 1 | Shashankss1205 | 3 | 148 | 5 | [rust.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
75 | | 2 | Siddharth Baleja | 1 | 122 | 53 | [rust.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
76 | | 3 | Syed Sohail | 1 | 28 | 8 | [rust.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
77 | 
78 | 
79 | ## Typescript Contributors
80 | 
81 | | Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
82 | |---|---|---|---|---|---|
83 | | 1 | Shashankss1205 | 2 | 71 | 35 | [typescript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
84 | | 2 | [Vasiliy Kiryanov](https://github.com/vasiliyk) | 1 | 412 | 0 | [typescript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/typescript.py?author=vasiliyk) |
85 | | 3 | ANUKOOL | 1 | 54 | 0 | [typescript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
86 | | 4 | [Shashank Shekhar Singh](https://github.com/Shashankss1205) | 1 | 1 | 2 | [typescript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/typescript.py?author=Shashankss1205) |
87 | 
88 | 
89 | 
```

--------------------------------------------------------------------------------
/tests/sample_project_rust/src/iterators_closures.rs:
--------------------------------------------------------------------------------

```rust
  1 | // iterators_closures.rs - Demonstrates Rust iterators and closures
  2 | use std::collections::HashMap;
  3 | 
  4 | // Closure examples
  5 | 
  6 | /// Function taking closure as parameter
  7 | pub fn apply<F>(f: F, x: i32) -> i32
  8 | where
  9 |     F: Fn(i32) -> i32,
 10 | {
 11 |     f(x)
 12 | }
 13 | 
 14 | /// Function returning closure
 15 | pub fn make_adder(n: i32) -> impl Fn(i32) -> i32 {
 16 |     move |x| x + n
 17 | }
 18 | 
 19 | /// Closure capturing environment
 20 | pub fn closure_capture() {
 21 |     let factor = 5;
 22 |     let multiply = |x| x * factor;
 23 |     println!("Result: {}", multiply(10));
 24 | }
 25 | 
 26 | /// Closure with move
 27 | pub fn closure_move() -> Box<dyn Fn(i32) -> i32> {
 28 |     let factor = 5;
 29 |     Box::new(move |x| x * factor)
 30 | }
 31 | 
 32 | /// FnOnce closure (consumes captured values)
 33 | pub fn call_once<F>(f: F)
 34 | where
 35 |     F: FnOnce(),
 36 | {
 37 |     f();
 38 | }
 39 | 
 40 | /// FnMut closure (mutates captured values)
 41 | pub fn call_mut<F>(mut f: F)
 42 | where
 43 |     F: FnMut(),
 44 | {
 45 |     f();
 46 |     f();
 47 | }
 48 | 
 49 | // Iterator examples
 50 | 
 51 | /// Custom iterator
 52 | pub struct Counter {
 53 |     count: u32,
 54 |     max: u32,
 55 | }
 56 | 
 57 | impl Counter {
 58 |     pub fn new(max: u32) -> Self {
 59 |         Self { count: 0, max }
 60 |     }
 61 | }
 62 | 
 63 | impl Iterator for Counter {
 64 |     type Item = u32;
 65 | 
 66 |     fn next(&mut self) -> Option<Self::Item> {
 67 |         if self.count < self.max {
 68 |             self.count += 1;
 69 |             Some(self.count)
 70 |         } else {
 71 |             None
 72 |         }
 73 |     }
 74 | }
 75 | 
 76 | /// Range iterator wrapper
 77 | pub struct Range {
 78 |     start: i32,
 79 |     end: i32,
 80 |     current: i32,
 81 | }
 82 | 
 83 | impl Range {
 84 |     pub fn new(start: i32, end: i32) -> Self {
 85 |         Self {
 86 |             start,
 87 |             end,
 88 |             current: start,
 89 |         }
 90 |     }
 91 | }
 92 | 
 93 | impl Iterator for Range {
 94 |     type Item = i32;
 95 | 
 96 |     fn next(&mut self) -> Option<Self::Item> {
 97 |         if self.current < self.end {
 98 |             let result = self.current;
 99 |             self.current += 1;
100 |             Some(result)
101 |         } else {
102 |             None
103 |         }
104 |     }
105 | }
106 | 
107 | // Iterator adapter patterns
108 | 
109 | /// Map pattern
110 | pub fn double_numbers(numbers: Vec<i32>) -> Vec<i32> {
111 |     numbers.iter().map(|&x| x * 2).collect()
112 | }
113 | 
114 | /// Filter pattern
115 | pub fn filter_evens(numbers: Vec<i32>) -> Vec<i32> {
116 |     numbers.into_iter().filter(|&x| x % 2 == 0).collect()
117 | }
118 | 
119 | /// Filter and map combined
120 | pub fn process_numbers(numbers: Vec<i32>) -> Vec<i32> {
121 |     numbers
122 |         .into_iter()
123 |         .filter(|&x| x > 0)
124 |         .map(|x| x * 2)
125 |         .collect()
126 | }
127 | 
128 | /// Fold/reduce pattern
129 | pub fn sum_numbers(numbers: &[i32]) -> i32 {
130 |     numbers.iter().fold(0, |acc, &x| acc + x)
131 | }
132 | 
133 | /// Find pattern
134 | pub fn find_first_even(numbers: &[i32]) -> Option<i32> {
135 |     numbers.iter().find(|&&x| x % 2 == 0).copied()
136 | }
137 | 
138 | /// Any and all
139 | pub fn has_negative(numbers: &[i32]) -> bool {
140 |     numbers.iter().any(|&x| x < 0)
141 | }
142 | 
143 | pub fn all_positive(numbers: &[i32]) -> bool {
144 |     numbers.iter().all(|&x| x > 0)
145 | }
146 | 
147 | /// Take and skip
148 | pub fn take_first_n(numbers: Vec<i32>, n: usize) -> Vec<i32> {
149 |     numbers.into_iter().take(n).collect()
150 | }
151 | 
152 | pub fn skip_first_n(numbers: Vec<i32>, n: usize) -> Vec<i32> {
153 |     numbers.into_iter().skip(n).collect()
154 | }
155 | 
156 | /// Chain iterators
157 | pub fn chain_vectors(v1: Vec<i32>, v2: Vec<i32>) -> Vec<i32> {
158 |     v1.into_iter().chain(v2.into_iter()).collect()
159 | }
160 | 
161 | /// Zip iterators
162 | pub fn zip_vectors(v1: Vec<i32>, v2: Vec<i32>) -> Vec<(i32, i32)> {
163 |     v1.into_iter().zip(v2.into_iter()).collect()
164 | }
165 | 
166 | /// Enumerate
167 | pub fn enumerate_items(items: Vec<String>) -> Vec<(usize, String)> {
168 |     items.into_iter().enumerate().collect()
169 | }
170 | 
171 | /// Flat map
172 | pub fn flat_map_example(nested: Vec<Vec<i32>>) -> Vec<i32> {
173 |     nested.into_iter().flat_map(|v| v.into_iter()).collect()
174 | }
175 | 
176 | /// Partition
177 | pub fn partition_numbers(numbers: Vec<i32>) -> (Vec<i32>, Vec<i32>) {
178 |     numbers.into_iter().partition(|&x| x % 2 == 0)
179 | }
180 | 
181 | // Complex iterator chains
182 | 
183 | /// Multiple operations
184 | pub fn complex_pipeline(numbers: Vec<i32>) -> i32 {
185 |     numbers
186 |         .into_iter()
187 |         .filter(|&x| x > 0)
188 |         .map(|x| x * 2)
189 |         .filter(|&x| x < 100)
190 |         .fold(0, |acc, x| acc + x)
191 | }
192 | 
193 | /// Group by pattern (using HashMap)
194 | pub fn group_by_parity(numbers: Vec<i32>) -> HashMap<bool, Vec<i32>> {
195 |     let mut map = HashMap::new();
196 |     for num in numbers {
197 |         let is_even = num % 2 == 0;
198 |         map.entry(is_even).or_insert_with(Vec::new).push(num);
199 |     }
200 |     map
201 | }
202 | 
203 | /// Max and min
204 | pub fn find_extremes(numbers: &[i32]) -> (Option<i32>, Option<i32>) {
205 |     let max = numbers.iter().max().copied();
206 |     let min = numbers.iter().min().copied();
207 |     (max, min)
208 | }
209 | 
210 | /// Collect into different types
211 | pub fn collect_examples(numbers: Vec<i32>) -> (Vec<i32>, String) {
212 |     let vec: Vec<i32> = numbers.iter().map(|&x| x * 2).collect();
213 |     let string: String = numbers
214 |         .iter()
215 |         .map(|x| x.to_string())
216 |         .collect::<Vec<String>>()
217 |         .join(", ");
218 |     (vec, string)
219 | }
220 | 
221 | // Custom iterator adapters
222 | 
223 | pub struct StepBy {
224 |     iter: std::vec::IntoIter<i32>,
225 |     step: usize,
226 | }
227 | 
228 | impl StepBy {
229 |     pub fn new(vec: Vec<i32>, step: usize) -> Self {
230 |         Self {
231 |             iter: vec.into_iter(),
232 |             step,
233 |         }
234 |     }
235 | }
236 | 
237 | impl Iterator for StepBy {
238 |     type Item = i32;
239 | 
240 |     fn next(&mut self) -> Option<Self::Item> {
241 |         let result = self.iter.next()?;
242 |         for _ in 0..self.step - 1 {
243 |             self.iter.next();
244 |         }
245 |         Some(result)
246 |     }
247 | }
248 | 
249 | // Lazy evaluation demonstration
250 | 
251 | pub struct LazyMap<I, F> {
252 |     iter: I,
253 |     f: F,
254 | }
255 | 
256 | impl<I, F, T, U> Iterator for LazyMap<I, F>
257 | where
258 |     I: Iterator<Item = T>,
259 |     F: FnMut(T) -> U,
260 | {
261 |     type Item = U;
262 | 
263 |     fn next(&mut self) -> Option<Self::Item> {
264 |         self.iter.next().map(|x| (self.f)(x))
265 |     }
266 | }
267 | 
268 | // Infinite iterators
269 | 
270 | pub fn fibonacci_iterator() -> impl Iterator<Item = u64> {
271 |     let mut a = 0;
272 |     let mut b = 1;
273 |     std::iter::from_fn(move || {
274 |         let result = a;
275 |         let next = a + b;
276 |         a = b;
277 |         b = next;
278 |         Some(result)
279 |     })
280 | }
281 | 
282 | /// Take from infinite iterator
283 | pub fn first_n_fibonacci(n: usize) -> Vec<u64> {
284 |     fibonacci_iterator().take(n).collect()
285 | }
286 | 
287 | // Peekable iterator
288 | pub fn peek_example(numbers: Vec<i32>) -> Vec<i32> {
289 |     let mut iter = numbers.into_iter().peekable();
290 |     let mut result = Vec::new();
291 | 
292 |     while let Some(&next) = iter.peek() {
293 |         if next % 2 == 0 {
294 |             result.push(iter.next().unwrap());
295 |         } else {
296 |             iter.next();
297 |         }
298 |     }
299 | 
300 |     result
301 | }
302 | 
303 | // Cycle iterator
304 | pub fn cycle_example(items: Vec<i32>, count: usize) -> Vec<i32> {
305 |     items.into_iter().cycle().take(count).collect()
306 | }
307 | 
308 | #[cfg(test)]
309 | mod tests {
310 |     use super::*;
311 | 
312 |     #[test]
313 |     fn test_counter() {
314 |         let counter = Counter::new(5);
315 |         let result: Vec<u32> = counter.collect();
316 |         assert_eq!(result, vec![1, 2, 3, 4, 5]);
317 |     }
318 | 
319 |     #[test]
320 |     fn test_double_numbers() {
321 |         let numbers = vec![1, 2, 3, 4, 5];
322 |         let doubled = double_numbers(numbers);
323 |         assert_eq!(doubled, vec![2, 4, 6, 8, 10]);
324 |     }
325 | 
326 |     #[test]
327 |     fn test_filter_evens() {
328 |         let numbers = vec![1, 2, 3, 4, 5, 6];
329 |         let evens = filter_evens(numbers);
330 |         assert_eq!(evens, vec![2, 4, 6]);
331 |     }
332 | 
333 |     #[test]
334 |     fn test_sum_numbers() {
335 |         let numbers = vec![1, 2, 3, 4, 5];
336 |         assert_eq!(sum_numbers(&numbers), 15);
337 |     }
338 | 
339 |     #[test]
340 |     fn test_make_adder() {
341 |         let add_five = make_adder(5);
342 |         assert_eq!(add_five(10), 15);
343 |     }
344 | 
345 |     #[test]
346 |     fn test_fibonacci() {
347 |         let fibs = first_n_fibonacci(10);
348 |         assert_eq!(fibs, vec![0, 1, 1, 2, 3, 5, 8, 13, 21, 34]);
349 |     }
350 | }
351 | 
352 | 
```

--------------------------------------------------------------------------------
/website/src/components/ui/menubar.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import * as React from "react";
  2 | import * as MenubarPrimitive from "@radix-ui/react-menubar";
  3 | import { Check, ChevronRight, Circle } from "lucide-react";
  4 | 
  5 | import { cn } from "@/lib/utils";
  6 | 
  7 | const MenubarMenu = MenubarPrimitive.Menu;
  8 | 
  9 | const MenubarGroup = MenubarPrimitive.Group;
 10 | 
 11 | const MenubarPortal = MenubarPrimitive.Portal;
 12 | 
 13 | const MenubarSub = MenubarPrimitive.Sub;
 14 | 
 15 | const MenubarRadioGroup = MenubarPrimitive.RadioGroup;
 16 | 
 17 | const Menubar = React.forwardRef<
 18 |   React.ElementRef<typeof MenubarPrimitive.Root>,
 19 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>
 20 | >(({ className, ...props }, ref) => (
 21 |   <MenubarPrimitive.Root
 22 |     ref={ref}
 23 |     className={cn("flex h-10 items-center space-x-1 rounded-md border bg-background p-1", className)}
 24 |     {...props}
 25 |   />
 26 | ));
 27 | Menubar.displayName = MenubarPrimitive.Root.displayName;
 28 | 
 29 | const MenubarTrigger = React.forwardRef<
 30 |   React.ElementRef<typeof MenubarPrimitive.Trigger>,
 31 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>
 32 | >(({ className, ...props }, ref) => (
 33 |   <MenubarPrimitive.Trigger
 34 |     ref={ref}
 35 |     className={cn(
 36 |       "flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
 37 |       className,
 38 |     )}
 39 |     {...props}
 40 |   />
 41 | ));
 42 | MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;
 43 | 
 44 | const MenubarSubTrigger = React.forwardRef<
 45 |   React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
 46 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
 47 |     inset?: boolean;
 48 |   }
 49 | >(({ className, inset, children, ...props }, ref) => (
 50 |   <MenubarPrimitive.SubTrigger
 51 |     ref={ref}
 52 |     className={cn(
 53 |       "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
 54 |       inset && "pl-8",
 55 |       className,
 56 |     )}
 57 |     {...props}
 58 |   >
 59 |     {children}
 60 |     <ChevronRight className="ml-auto h-4 w-4" />
 61 |   </MenubarPrimitive.SubTrigger>
 62 | ));
 63 | MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
 64 | 
 65 | const MenubarSubContent = React.forwardRef<
 66 |   React.ElementRef<typeof MenubarPrimitive.SubContent>,
 67 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>
 68 | >(({ className, ...props }, ref) => (
 69 |   <MenubarPrimitive.SubContent
 70 |     ref={ref}
 71 |     className={cn(
 72 |       "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 73 |       className,
 74 |     )}
 75 |     {...props}
 76 |   />
 77 | ));
 78 | MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;
 79 | 
 80 | const MenubarContent = React.forwardRef<
 81 |   React.ElementRef<typeof MenubarPrimitive.Content>,
 82 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
 83 | >(({ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }, ref) => (
 84 |   <MenubarPrimitive.Portal>
 85 |     <MenubarPrimitive.Content
 86 |       ref={ref}
 87 |       align={align}
 88 |       alignOffset={alignOffset}
 89 |       sideOffset={sideOffset}
 90 |       className={cn(
 91 |         "z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 92 |         className,
 93 |       )}
 94 |       {...props}
 95 |     />
 96 |   </MenubarPrimitive.Portal>
 97 | ));
 98 | MenubarContent.displayName = MenubarPrimitive.Content.displayName;
 99 | 
100 | const MenubarItem = React.forwardRef<
101 |   React.ElementRef<typeof MenubarPrimitive.Item>,
102 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
103 |     inset?: boolean;
104 |   }
105 | >(({ className, inset, ...props }, ref) => (
106 |   <MenubarPrimitive.Item
107 |     ref={ref}
108 |     className={cn(
109 |       "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
110 |       inset && "pl-8",
111 |       className,
112 |     )}
113 |     {...props}
114 |   />
115 | ));
116 | MenubarItem.displayName = MenubarPrimitive.Item.displayName;
117 | 
118 | const MenubarCheckboxItem = React.forwardRef<
119 |   React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
120 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>
121 | >(({ className, children, checked, ...props }, ref) => (
122 |   <MenubarPrimitive.CheckboxItem
123 |     ref={ref}
124 |     className={cn(
125 |       "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
126 |       className,
127 |     )}
128 |     checked={checked}
129 |     {...props}
130 |   >
131 |     <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
132 |       <MenubarPrimitive.ItemIndicator>
133 |         <Check className="h-4 w-4" />
134 |       </MenubarPrimitive.ItemIndicator>
135 |     </span>
136 |     {children}
137 |   </MenubarPrimitive.CheckboxItem>
138 | ));
139 | MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;
140 | 
141 | const MenubarRadioItem = React.forwardRef<
142 |   React.ElementRef<typeof MenubarPrimitive.RadioItem>,
143 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>
144 | >(({ className, children, ...props }, ref) => (
145 |   <MenubarPrimitive.RadioItem
146 |     ref={ref}
147 |     className={cn(
148 |       "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
149 |       className,
150 |     )}
151 |     {...props}
152 |   >
153 |     <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
154 |       <MenubarPrimitive.ItemIndicator>
155 |         <Circle className="h-2 w-2 fill-current" />
156 |       </MenubarPrimitive.ItemIndicator>
157 |     </span>
158 |     {children}
159 |   </MenubarPrimitive.RadioItem>
160 | ));
161 | MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;
162 | 
163 | const MenubarLabel = React.forwardRef<
164 |   React.ElementRef<typeof MenubarPrimitive.Label>,
165 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
166 |     inset?: boolean;
167 |   }
168 | >(({ className, inset, ...props }, ref) => (
169 |   <MenubarPrimitive.Label
170 |     ref={ref}
171 |     className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
172 |     {...props}
173 |   />
174 | ));
175 | MenubarLabel.displayName = MenubarPrimitive.Label.displayName;
176 | 
177 | const MenubarSeparator = React.forwardRef<
178 |   React.ElementRef<typeof MenubarPrimitive.Separator>,
179 |   React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>
180 | >(({ className, ...props }, ref) => (
181 |   <MenubarPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
182 | ));
183 | MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;
184 | 
185 | const MenubarShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
186 |   return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
187 | };
188 | MenubarShortcut.displayname = "MenubarShortcut";
189 | 
190 | export {
191 |   Menubar,
192 |   MenubarMenu,
193 |   MenubarTrigger,
194 |   MenubarContent,
195 |   MenubarItem,
196 |   MenubarSeparator,
197 |   MenubarLabel,
198 |   MenubarCheckboxItem,
199 |   MenubarRadioGroup,
200 |   MenubarRadioItem,
201 |   MenubarPortal,
202 |   MenubarSubContent,
203 |   MenubarSubTrigger,
204 |   MenubarGroup,
205 |   MenubarSub,
206 |   MenubarShortcut,
207 | };
208 | 
```

--------------------------------------------------------------------------------
/tests/sample_project_rust/src/concurrency.rs:
--------------------------------------------------------------------------------

```rust
  1 | // concurrency.rs - Demonstrates Rust concurrency patterns
  2 | use std::sync::{Arc, Mutex, RwLock, mpsc};
  3 | use std::thread;
  4 | use std::time::Duration;
  5 | 
  6 | /// Simple thread spawning
  7 | pub fn spawn_simple_thread() {
  8 |     let handle = thread::spawn(|| {
  9 |         for i in 1..5 {
 10 |             println!("Thread: {}", i);
 11 |             thread::sleep(Duration::from_millis(10));
 12 |         }
 13 |     });
 14 | 
 15 |     handle.join().unwrap();
 16 | }
 17 | 
 18 | /// Thread with move closure
 19 | pub fn thread_with_ownership() {
 20 |     let data = vec![1, 2, 3, 4, 5];
 21 |     
 22 |     let handle = thread::spawn(move || {
 23 |         println!("Thread got data: {:?}", data);
 24 |         data.iter().sum::<i32>()
 25 |     });
 26 | 
 27 |     let result = handle.join().unwrap();
 28 |     println!("Sum: {}", result);
 29 | }
 30 | 
 31 | /// Multiple threads
 32 | pub fn spawn_multiple_threads(count: usize) -> Vec<i32> {
 33 |     let mut handles = vec![];
 34 | 
 35 |     for i in 0..count {
 36 |         let handle = thread::spawn(move || {
 37 |             thread::sleep(Duration::from_millis(10));
 38 |             i as i32 * 2
 39 |         });
 40 |         handles.push(handle);
 41 |     }
 42 | 
 43 |     handles.into_iter().map(|h| h.join().unwrap()).collect()
 44 | }
 45 | 
 46 | // Mutex for shared state
 47 | 
 48 | /// Shared counter with Mutex
 49 | pub fn shared_counter(thread_count: usize) -> i32 {
 50 |     let counter = Arc::new(Mutex::new(0));
 51 |     let mut handles = vec![];
 52 | 
 53 |     for _ in 0..thread_count {
 54 |         let counter = Arc::clone(&counter);
 55 |         let handle = thread::spawn(move || {
 56 |             for _ in 0..100 {
 57 |                 let mut num = counter.lock().unwrap();
 58 |                 *num += 1;
 59 |             }
 60 |         });
 61 |         handles.push(handle);
 62 |     }
 63 | 
 64 |     for handle in handles {
 65 |         handle.join().unwrap();
 66 |     }
 67 | 
 68 |     let final_count = *counter.lock().unwrap();
 69 |     final_count
 70 | }
 71 | 
 72 | /// Safe data structure with Mutex
 73 | #[derive(Debug)]
 74 | pub struct SafeCounter {
 75 |     count: Arc<Mutex<i32>>,
 76 | }
 77 | 
 78 | impl SafeCounter {
 79 |     pub fn new() -> Self {
 80 |         Self {
 81 |             count: Arc::new(Mutex::new(0)),
 82 |         }
 83 |     }
 84 | 
 85 |     pub fn increment(&self) {
 86 |         let mut count = self.count.lock().unwrap();
 87 |         *count += 1;
 88 |     }
 89 | 
 90 |     pub fn get(&self) -> i32 {
 91 |         *self.count.lock().unwrap()
 92 |     }
 93 | 
 94 |     pub fn clone_counter(&self) -> SafeCounter {
 95 |         SafeCounter {
 96 |             count: Arc::clone(&self.count),
 97 |         }
 98 |     }
 99 | }
100 | 
101 | // RwLock for read-heavy workloads
102 | 
103 | /// Shared data with RwLock
104 | pub struct SharedData {
105 |     data: Arc<RwLock<Vec<i32>>>,
106 | }
107 | 
108 | impl SharedData {
109 |     pub fn new() -> Self {
110 |         Self {
111 |             data: Arc::new(RwLock::new(Vec::new())),
112 |         }
113 |     }
114 | 
115 |     pub fn add(&self, value: i32) {
116 |         let mut data = self.data.write().unwrap();
117 |         data.push(value);
118 |     }
119 | 
120 |     pub fn get(&self, index: usize) -> Option<i32> {
121 |         let data = self.data.read().unwrap();
122 |         data.get(index).copied()
123 |     }
124 | 
125 |     pub fn len(&self) -> usize {
126 |         let data = self.data.read().unwrap();
127 |         data.len()
128 |     }
129 | 
130 |     pub fn clone_data(&self) -> SharedData {
131 |         SharedData {
132 |             data: Arc::clone(&self.data),
133 |         }
134 |     }
135 | }
136 | 
137 | // Message passing with channels
138 | 
139 | /// Simple channel communication
140 | pub fn simple_channel() {
141 |     let (tx, rx) = mpsc::channel();
142 | 
143 |     thread::spawn(move || {
144 |         let messages = vec!["hello", "from", "thread"];
145 |         for msg in messages {
146 |             tx.send(msg).unwrap();
147 |             thread::sleep(Duration::from_millis(10));
148 |         }
149 |     });
150 | 
151 |     for received in rx {
152 |         println!("Got: {}", received);
153 |     }
154 | }
155 | 
156 | /// Multiple producers
157 | pub fn multiple_producers() -> Vec<String> {
158 |     let (tx, rx) = mpsc::channel();
159 |     let mut results = Vec::new();
160 | 
161 |     for i in 0..3 {
162 |         let tx_clone = tx.clone();
163 |         thread::spawn(move || {
164 |             let message = format!("Message from thread {}", i);
165 |             tx_clone.send(message).unwrap();
166 |         });
167 |     }
168 | 
169 |     drop(tx); // Drop original sender
170 | 
171 |     for received in rx {
172 |         results.push(received);
173 |     }
174 | 
175 |     results
176 | }
177 | 
178 | /// Worker pool pattern
179 | pub struct ThreadPool {
180 |     workers: Vec<Worker>,
181 |     sender: mpsc::Sender<Job>,
182 | }
183 | 
184 | type Job = Box<dyn FnOnce() + Send + 'static>;
185 | 
186 | struct Worker {
187 |     id: usize,
188 |     thread: Option<thread::JoinHandle<()>>,
189 | }
190 | 
191 | impl Worker {
192 |     fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
193 |         let thread = thread::spawn(move || loop {
194 |             let job = receiver.lock().unwrap().recv();
195 | 
196 |             match job {
197 |                 Ok(job) => {
198 |                     println!("Worker {} executing job", id);
199 |                     job();
200 |                 }
201 |                 Err(_) => {
202 |                     println!("Worker {} shutting down", id);
203 |                     break;
204 |                 }
205 |             }
206 |         });
207 | 
208 |         Worker {
209 |             id,
210 |             thread: Some(thread),
211 |         }
212 |     }
213 | }
214 | 
215 | impl ThreadPool {
216 |     pub fn new(size: usize) -> ThreadPool {
217 |         assert!(size > 0);
218 | 
219 |         let (sender, receiver) = mpsc::channel();
220 |         let receiver = Arc::new(Mutex::new(receiver));
221 |         let mut workers = Vec::with_capacity(size);
222 | 
223 |         for id in 0..size {
224 |             workers.push(Worker::new(id, Arc::clone(&receiver)));
225 |         }
226 | 
227 |         ThreadPool { workers, sender }
228 |     }
229 | 
230 |     pub fn execute<F>(&self, f: F)
231 |     where
232 |         F: FnOnce() + Send + 'static,
233 |     {
234 |         let job = Box::new(f);
235 |         self.sender.send(job).unwrap();
236 |     }
237 | }
238 | 
239 | impl Drop for ThreadPool {
240 |     fn drop(&mut self) {
241 |         for worker in &mut self.workers {
242 |             if let Some(thread) = worker.thread.take() {
243 |                 thread.join().unwrap();
244 |             }
245 |         }
246 |     }
247 | }
248 | 
249 | // Barrier synchronization
250 | use std::sync::Barrier;
251 | 
252 | pub fn barrier_example() {
253 |     let barrier = Arc::new(Barrier::new(3));
254 |     let mut handles = vec![];
255 | 
256 |     for i in 0..3 {
257 |         let barrier = Arc::clone(&barrier);
258 |         let handle = thread::spawn(move || {
259 |             println!("Thread {} before barrier", i);
260 |             barrier.wait();
261 |             println!("Thread {} after barrier", i);
262 |         });
263 |         handles.push(handle);
264 |     }
265 | 
266 |     for handle in handles {
267 |         handle.join().unwrap();
268 |     }
269 | }
270 | 
271 | // Atomic operations
272 | use std::sync::atomic::{AtomicUsize, Ordering};
273 | 
274 | pub struct AtomicCounter {
275 |     count: AtomicUsize,
276 | }
277 | 
278 | impl AtomicCounter {
279 |     pub fn new() -> Self {
280 |         Self {
281 |             count: AtomicUsize::new(0),
282 |         }
283 |     }
284 | 
285 |     pub fn increment(&self) {
286 |         self.count.fetch_add(1, Ordering::SeqCst);
287 |     }
288 | 
289 |     pub fn get(&self) -> usize {
290 |         self.count.load(Ordering::SeqCst)
291 |     }
292 | }
293 | 
294 | // Once initialization
295 | use std::sync::Once;
296 | 
297 | static mut SINGLETON: Option<String> = None;
298 | static INIT: Once = Once::new();
299 | 
300 | pub fn get_singleton() -> &'static String {
301 |     unsafe {
302 |         INIT.call_once(|| {
303 |             SINGLETON = Some(String::from("Singleton instance"));
304 |         });
305 |         SINGLETON.as_ref().unwrap()
306 |     }
307 | }
308 | 
309 | // Scoped threads (Rust 1.63+)
310 | pub fn scoped_threads() {
311 |     let mut data = vec![1, 2, 3, 4, 5];
312 | 
313 |     thread::scope(|s| {
314 |         s.spawn(|| {
315 |             println!("Thread 1 can access data: {:?}", data);
316 |         });
317 | 
318 |         s.spawn(|| {
319 |             println!("Thread 2 can also access data: {:?}", data);
320 |         });
321 |     });
322 | 
323 |     data.push(6); // Can use data after scope
324 |     println!("Final data: {:?}", data);
325 | }
326 | 
327 | #[cfg(test)]
328 | mod tests {
329 |     use super::*;
330 | 
331 |     #[test]
332 |     fn test_shared_counter() {
333 |         let result = shared_counter(5);
334 |         assert_eq!(result, 500);
335 |     }
336 | 
337 |     #[test]
338 |     fn test_safe_counter() {
339 |         let counter = SafeCounter::new();
340 |         counter.increment();
341 |         counter.increment();
342 |         assert_eq!(counter.get(), 2);
343 |     }
344 | 
345 |     #[test]
346 |     fn test_shared_data() {
347 |         let data = SharedData::new();
348 |         data.add(1);
349 |         data.add(2);
350 |         data.add(3);
351 |         assert_eq!(data.len(), 3);
352 |         assert_eq!(data.get(1), Some(2));
353 |     }
354 | 
355 |     #[test]
356 |     fn test_atomic_counter() {
357 |         let counter = AtomicCounter::new();
358 |         counter.increment();
359 |         counter.increment();
360 |         assert_eq!(counter.get(), 2);
361 |     }
362 | }
363 | 
364 | 
```

--------------------------------------------------------------------------------
/tests/sample_project_rust/src/error_handling.rs:
--------------------------------------------------------------------------------

```rust
  1 | // error_handling.rs - Demonstrates Rust error handling patterns
  2 | use std::error::Error;
  3 | use std::fmt;
  4 | use std::fs::File;
  5 | use std::io::{self, Read};
  6 | 
  7 | /// Custom error type
  8 | #[derive(Debug, Clone)]
  9 | pub struct CustomError {
 10 |     pub code: u32,
 11 |     pub message: String,
 12 | }
 13 | 
 14 | impl fmt::Display for CustomError {
 15 |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 16 |         write!(f, "Error {}: {}", self.code, self.message)
 17 |     }
 18 | }
 19 | 
 20 | impl Error for CustomError {}
 21 | 
 22 | impl CustomError {
 23 |     pub fn new(code: u32, message: String) -> Self {
 24 |         Self { code, message }
 25 |     }
 26 | }
 27 | 
 28 | /// Validation error
 29 | #[derive(Debug)]
 30 | pub struct ValidationError {
 31 |     pub field: String,
 32 |     pub value: String,
 33 |     pub reason: String,
 34 | }
 35 | 
 36 | impl fmt::Display for ValidationError {
 37 |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 38 |         write!(
 39 |             f,
 40 |             "Validation failed for field '{}' with value '{}': {}",
 41 |             self.field, self.value, self.reason
 42 |         )
 43 |     }
 44 | }
 45 | 
 46 | impl Error for ValidationError {}
 47 | 
 48 | /// Multiple error types enum
 49 | #[derive(Debug)]
 50 | pub enum AppError {
 51 |     Io(io::Error),
 52 |     Parse(std::num::ParseIntError),
 53 |     Custom(CustomError),
 54 |     Validation(ValidationError),
 55 | }
 56 | 
 57 | impl fmt::Display for AppError {
 58 |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 59 |         match self {
 60 |             AppError::Io(err) => write!(f, "IO error: {}", err),
 61 |             AppError::Parse(err) => write!(f, "Parse error: {}", err),
 62 |             AppError::Custom(err) => write!(f, "Custom error: {}", err),
 63 |             AppError::Validation(err) => write!(f, "Validation error: {}", err),
 64 |         }
 65 |     }
 66 | }
 67 | 
 68 | impl Error for AppError {}
 69 | 
 70 | impl From<io::Error> for AppError {
 71 |     fn from(err: io::Error) -> Self {
 72 |         AppError::Io(err)
 73 |     }
 74 | }
 75 | 
 76 | impl From<std::num::ParseIntError> for AppError {
 77 |     fn from(err: std::num::ParseIntError) -> Self {
 78 |         AppError::Parse(err)
 79 |     }
 80 | }
 81 | 
 82 | impl From<CustomError> for AppError {
 83 |     fn from(err: CustomError) -> Self {
 84 |         AppError::Custom(err)
 85 |     }
 86 | }
 87 | 
 88 | // Basic Result usage
 89 | 
 90 | /// Simple function returning Result
 91 | pub fn divide(a: i32, b: i32) -> Result<i32, String> {
 92 |     if b == 0 {
 93 |         Err("Division by zero".to_string())
 94 |     } else {
 95 |         Ok(a / b)
 96 |     }
 97 | }
 98 | 
 99 | /// Function with multiple error conditions
100 | pub fn validate_age(age: i32) -> Result<i32, String> {
101 |     if age < 0 {
102 |         return Err("Age cannot be negative".to_string());
103 |     }
104 |     if age > 150 {
105 |         return Err("Age is unrealistic".to_string());
106 |     }
107 |     Ok(age)
108 | }
109 | 
110 | /// Using custom error type
111 | pub fn validate_username(username: &str) -> Result<String, CustomError> {
112 |     if username.is_empty() {
113 |         return Err(CustomError::new(400, "Username cannot be empty".to_string()));
114 |     }
115 |     if username.len() < 3 {
116 |         return Err(CustomError::new(400, "Username too short".to_string()));
117 |     }
118 |     if username.len() > 20 {
119 |         return Err(CustomError::new(400, "Username too long".to_string()));
120 |     }
121 |     Ok(username.to_string())
122 | }
123 | 
124 | /// Error propagation with ? operator
125 | pub fn read_file_contents(filename: &str) -> Result<String, io::Error> {
126 |     let mut file = File::open(filename)?;
127 |     let mut contents = String::new();
128 |     file.read_to_string(&mut contents)?;
129 |     Ok(contents)
130 | }
131 | 
132 | /// Chaining operations with ?
133 | pub fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
134 |     let num: i32 = s.parse()?;
135 |     Ok(num * 2)
136 | }
137 | 
138 | /// Multiple error types with ?
139 | pub fn read_and_parse(filename: &str) -> Result<i32, AppError> {
140 |     let mut file = File::open(filename)?;
141 |     let mut contents = String::new();
142 |     file.read_to_string(&mut contents)?;
143 |     let num: i32 = contents.trim().parse()?;
144 |     Ok(num)
145 | }
146 | 
147 | /// Custom validation with ValidationError
148 | pub fn validate_email(email: &str) -> Result<String, ValidationError> {
149 |     if !email.contains('@') {
150 |         return Err(ValidationError {
151 |             field: "email".to_string(),
152 |             value: email.to_string(),
153 |             reason: "Must contain @ symbol".to_string(),
154 |         });
155 |     }
156 |     if !email.contains('.') {
157 |         return Err(ValidationError {
158 |             field: "email".to_string(),
159 |             value: email.to_string(),
160 |             reason: "Must contain domain extension".to_string(),
161 |         });
162 |     }
163 |     Ok(email.to_string())
164 | }
165 | 
166 | /// Using match for error handling
167 | pub fn process_result(result: Result<i32, String>) -> i32 {
168 |     match result {
169 |         Ok(value) => value,
170 |         Err(e) => {
171 |             println!("Error occurred: {}", e);
172 |             0
173 |         }
174 |     }
175 | }
176 | 
177 | /// Using unwrap_or
178 | pub fn safe_divide(a: i32, b: i32) -> i32 {
179 |     divide(a, b).unwrap_or(0)
180 | }
181 | 
182 | /// Using unwrap_or_else
183 | pub fn safe_divide_with_default(a: i32, b: i32, default: i32) -> i32 {
184 |     divide(a, b).unwrap_or_else(|_| default)
185 | }
186 | 
187 | /// Using map and and_then
188 | pub fn parse_and_validate(s: &str) -> Result<i32, String> {
189 |     s.parse::<i32>()
190 |         .map_err(|e| format!("Parse error: {}", e))
191 |         .and_then(|num| {
192 |             if num >= 0 {
193 |                 Ok(num)
194 |             } else {
195 |                 Err("Number must be non-negative".to_string())
196 |             }
197 |         })
198 | }
199 | 
200 | /// Error recovery pattern
201 | pub fn try_parse_or_default(s: &str, default: i32) -> i32 {
202 |     s.parse().unwrap_or(default)
203 | }
204 | 
205 | /// Multiple validation steps
206 | pub fn validate_user(name: &str, age: i32, email: &str) -> Result<User, Vec<String>> {
207 |     let mut errors = Vec::new();
208 | 
209 |     if name.is_empty() {
210 |         errors.push("Name cannot be empty".to_string());
211 |     }
212 |     if age < 18 {
213 |         errors.push("Must be 18 or older".to_string());
214 |     }
215 |     if !email.contains('@') {
216 |         errors.push("Invalid email".to_string());
217 |     }
218 | 
219 |     if errors.is_empty() {
220 |         Ok(User {
221 |             name: name.to_string(),
222 |             age,
223 |             email: email.to_string(),
224 |         })
225 |     } else {
226 |         Err(errors)
227 |     }
228 | }
229 | 
230 | #[derive(Debug)]
231 | pub struct User {
232 |     name: String,
233 |     age: i32,
234 |     email: String,
235 | }
236 | 
237 | /// Panic for unrecoverable errors
238 | pub fn must_succeed(value: Option<i32>) -> i32 {
239 |     value.expect("This should never be None")
240 | }
241 | 
242 | /// Option to Result conversion
243 | pub fn find_user(id: u32) -> Option<String> {
244 |     if id > 0 {
245 |         Some(format!("User {}", id))
246 |     } else {
247 |         None
248 |     }
249 | }
250 | 
251 | pub fn get_user_or_error(id: u32) -> Result<String, String> {
252 |     find_user(id).ok_or_else(|| "User not found".to_string())
253 | }
254 | 
255 | /// Combining Results
256 | pub fn validate_and_parse(s: &str) -> Result<i32, String> {
257 |     if s.is_empty() {
258 |         return Err("Input is empty".to_string());
259 |     }
260 |     s.parse::<i32>()
261 |         .map_err(|e| format!("Failed to parse: {}", e))
262 | }
263 | 
264 | /// Early return pattern
265 | pub fn process_input(input: &str) -> Result<i32, String> {
266 |     let trimmed = input.trim();
267 |     if trimmed.is_empty() {
268 |         return Err("Empty input".to_string());
269 |     }
270 | 
271 |     let num: i32 = trimmed.parse().map_err(|_| "Invalid number".to_string())?;
272 | 
273 |     if num < 0 {
274 |         return Err("Negative number".to_string());
275 |     }
276 | 
277 |     Ok(num * 2)
278 | }
279 | 
280 | /// Collecting Results
281 | pub fn parse_numbers(strings: Vec<&str>) -> Result<Vec<i32>, String> {
282 |     strings
283 |         .iter()
284 |         .map(|s| s.parse::<i32>().map_err(|e| e.to_string()))
285 |         .collect()
286 | }
287 | 
288 | /// Result with Box<dyn Error>
289 | pub fn flexible_error_handling(input: &str) -> Result<i32, Box<dyn Error>> {
290 |     let num: i32 = input.parse()?;
291 |     if num < 0 {
292 |         return Err(Box::new(CustomError::new(400, "Negative number".to_string())));
293 |     }
294 |     Ok(num)
295 | }
296 | 
297 | #[cfg(test)]
298 | mod tests {
299 |     use super::*;
300 | 
301 |     #[test]
302 |     fn test_divide_success() {
303 |         assert_eq!(divide(10, 2), Ok(5));
304 |     }
305 | 
306 |     #[test]
307 |     fn test_divide_error() {
308 |         assert!(divide(10, 0).is_err());
309 |     }
310 | 
311 |     #[test]
312 |     fn test_validate_age() {
313 |         assert!(validate_age(25).is_ok());
314 |         assert!(validate_age(-1).is_err());
315 |         assert!(validate_age(200).is_err());
316 |     }
317 | 
318 |     #[test]
319 |     fn test_validate_username() {
320 |         assert!(validate_username("john_doe").is_ok());
321 |         assert!(validate_username("ab").is_err());
322 |         assert!(validate_username("").is_err());
323 |     }
324 | }
325 | 
326 | 
```

--------------------------------------------------------------------------------
/tests/sample_project_rust/src/generics.rs:
--------------------------------------------------------------------------------

```rust
  1 | // generics.rs - Demonstrates Rust generics and type parameters
  2 | use std::cmp::PartialOrd;
  3 | use std::fmt::{Debug, Display};
  4 | use std::ops::Add;
  5 | 
  6 | /// Generic function with single type parameter
  7 | pub fn first<T>(list: &[T]) -> Option<&T> {
  8 |     list.first()
  9 | }
 10 | 
 11 | /// Generic function with trait bound
 12 | pub fn largest<T: PartialOrd>(list: &[T]) -> Option<&T> {
 13 |     if list.is_empty() {
 14 |         return None;
 15 |     }
 16 | 
 17 |     let mut largest = &list[0];
 18 |     for item in list {
 19 |         if item > largest {
 20 |             largest = item;
 21 |         }
 22 |     }
 23 |     Some(largest)
 24 | }
 25 | 
 26 | /// Generic function with multiple type parameters
 27 | pub fn pair<T, U>(first: T, second: U) -> (T, U) {
 28 |     (first, second)
 29 | }
 30 | 
 31 | /// Generic function with multiple trait bounds
 32 | pub fn print_pair<T: Display, U: Display>(first: T, second: U) {
 33 |     println!("First: {}, Second: {}", first, second);
 34 | }
 35 | 
 36 | /// Generic function with where clause
 37 | pub fn complex_function<T, U>(t: T, u: U) -> String
 38 | where
 39 |     T: Display + Clone,
 40 |     U: Display + Debug,
 41 | {
 42 |     format!("T: {}, U: {:?}", t, u)
 43 | }
 44 | 
 45 | // Generic structs
 46 | 
 47 | /// Simple generic struct
 48 | #[derive(Debug, Clone)]
 49 | pub struct Point<T> {
 50 |     pub x: T,
 51 |     pub y: T,
 52 | }
 53 | 
 54 | impl<T> Point<T> {
 55 |     pub fn new(x: T, y: T) -> Self {
 56 |         Self { x, y }
 57 |     }
 58 | 
 59 |     pub fn x(&self) -> &T {
 60 |         &self.x
 61 |     }
 62 | 
 63 |     pub fn y(&self) -> &T {
 64 |         &self.y
 65 |     }
 66 | }
 67 | 
 68 | impl<T: Add<Output = T> + Copy> Point<T> {
 69 |     pub fn add(&self, other: &Point<T>) -> Point<T> {
 70 |         Point {
 71 |             x: self.x + other.x,
 72 |             y: self.y + other.y,
 73 |         }
 74 |     }
 75 | }
 76 | 
 77 | /// Generic struct with multiple type parameters
 78 | #[derive(Debug)]
 79 | pub struct Pair<T, U> {
 80 |     pub first: T,
 81 |     pub second: U,
 82 | }
 83 | 
 84 | impl<T, U> Pair<T, U> {
 85 |     pub fn new(first: T, second: U) -> Self {
 86 |         Self { first, second }
 87 |     }
 88 | 
 89 |     pub fn swap(self) -> Pair<U, T> {
 90 |         Pair {
 91 |             first: self.second,
 92 |             second: self.first,
 93 |         }
 94 |     }
 95 | }
 96 | 
 97 | impl<T: Clone, U: Clone> Pair<T, U> {
 98 |     pub fn clone_first(&self) -> T {
 99 |         self.first.clone()
100 |     }
101 | 
102 |     pub fn clone_second(&self) -> U {
103 |         self.second.clone()
104 |     }
105 | }
106 | 
107 | // Generic collections
108 | 
109 | /// Generic stack
110 | #[derive(Debug)]
111 | pub struct Stack<T> {
112 |     items: Vec<T>,
113 | }
114 | 
115 | impl<T> Stack<T> {
116 |     pub fn new() -> Self {
117 |         Self { items: Vec::new() }
118 |     }
119 | 
120 |     pub fn push(&mut self, item: T) {
121 |         self.items.push(item);
122 |     }
123 | 
124 |     pub fn pop(&mut self) -> Option<T> {
125 |         self.items.pop()
126 |     }
127 | 
128 |     pub fn peek(&self) -> Option<&T> {
129 |         self.items.last()
130 |     }
131 | 
132 |     pub fn is_empty(&self) -> bool {
133 |         self.items.is_empty()
134 |     }
135 | 
136 |     pub fn len(&self) -> usize {
137 |         self.items.len()
138 |     }
139 | }
140 | 
141 | /// Generic queue
142 | #[derive(Debug)]
143 | pub struct Queue<T> {
144 |     items: Vec<T>,
145 | }
146 | 
147 | impl<T> Queue<T> {
148 |     pub fn new() -> Self {
149 |         Self { items: Vec::new() }
150 |     }
151 | 
152 |     pub fn enqueue(&mut self, item: T) {
153 |         self.items.push(item);
154 |     }
155 | 
156 |     pub fn dequeue(&mut self) -> Option<T> {
157 |         if self.items.is_empty() {
158 |             None
159 |         } else {
160 |             Some(self.items.remove(0))
161 |         }
162 |     }
163 | 
164 |     pub fn peek(&self) -> Option<&T> {
165 |         self.items.first()
166 |     }
167 | 
168 |     pub fn len(&self) -> usize {
169 |         self.items.len()
170 |     }
171 | }
172 | 
173 | /// Generic linked list node
174 | #[derive(Debug)]
175 | pub struct Node<T> {
176 |     pub value: T,
177 |     pub next: Option<Box<Node<T>>>,
178 | }
179 | 
180 | impl<T> Node<T> {
181 |     pub fn new(value: T) -> Self {
182 |         Self { value, next: None }
183 |     }
184 | }
185 | 
186 | /// Generic linked list
187 | #[derive(Debug)]
188 | pub struct LinkedList<T> {
189 |     head: Option<Box<Node<T>>>,
190 |     size: usize,
191 | }
192 | 
193 | impl<T> LinkedList<T> {
194 |     pub fn new() -> Self {
195 |         Self {
196 |             head: None,
197 |             size: 0,
198 |         }
199 |     }
200 | 
201 |     pub fn push(&mut self, value: T) {
202 |         let new_node = Box::new(Node {
203 |             value,
204 |             next: self.head.take(),
205 |         });
206 |         self.head = Some(new_node);
207 |         self.size += 1;
208 |     }
209 | 
210 |     pub fn pop(&mut self) -> Option<T> {
211 |         self.head.take().map(|node| {
212 |             self.head = node.next;
213 |             self.size -= 1;
214 |             node.value
215 |         })
216 |     }
217 | 
218 |     pub fn len(&self) -> usize {
219 |         self.size
220 |     }
221 | 
222 |     pub fn is_empty(&self) -> bool {
223 |         self.size == 0
224 |     }
225 | }
226 | 
227 | // Generic enums
228 | 
229 | /// Generic Option-like enum
230 | #[derive(Debug, Clone, Copy, PartialEq)]
231 | pub enum Maybe<T> {
232 |     Just(T),
233 |     Nothing,
234 | }
235 | 
236 | impl<T> Maybe<T> {
237 |     pub fn is_just(&self) -> bool {
238 |         matches!(self, Maybe::Just(_))
239 |     }
240 | 
241 |     pub fn unwrap(self) -> T {
242 |         match self {
243 |             Maybe::Just(value) => value,
244 |             Maybe::Nothing => panic!("Called unwrap on Nothing"),
245 |         }
246 |     }
247 | 
248 |     pub fn unwrap_or(self, default: T) -> T {
249 |         match self {
250 |             Maybe::Just(value) => value,
251 |             Maybe::Nothing => default,
252 |         }
253 |     }
254 | 
255 |     pub fn map<U, F>(self, f: F) -> Maybe<U>
256 |     where
257 |         F: FnOnce(T) -> U,
258 |     {
259 |         match self {
260 |             Maybe::Just(value) => Maybe::Just(f(value)),
261 |             Maybe::Nothing => Maybe::Nothing,
262 |         }
263 |     }
264 | }
265 | 
266 | /// Generic Result-like enum
267 | #[derive(Debug, Clone, PartialEq)]
268 | pub enum Outcome<T, E> {
269 |     Success(T),
270 |     Failure(E),
271 | }
272 | 
273 | impl<T, E> Outcome<T, E> {
274 |     pub fn is_success(&self) -> bool {
275 |         matches!(self, Outcome::Success(_))
276 |     }
277 | 
278 |     pub fn map<U, F>(self, f: F) -> Outcome<U, E>
279 |     where
280 |         F: FnOnce(T) -> U,
281 |     {
282 |         match self {
283 |             Outcome::Success(value) => Outcome::Success(f(value)),
284 |             Outcome::Failure(err) => Outcome::Failure(err),
285 |         }
286 |     }
287 | 
288 |     pub fn and_then<U, F>(self, f: F) -> Outcome<U, E>
289 |     where
290 |         F: FnOnce(T) -> Outcome<U, E>,
291 |     {
292 |         match self {
293 |             Outcome::Success(value) => f(value),
294 |             Outcome::Failure(err) => Outcome::Failure(err),
295 |         }
296 |     }
297 | }
298 | 
299 | // Generic trait implementations
300 | 
301 | /// Generic wrapper type
302 | #[derive(Debug, Clone)]
303 | pub struct Wrapper<T> {
304 |     value: T,
305 | }
306 | 
307 | impl<T> Wrapper<T> {
308 |     pub fn new(value: T) -> Self {
309 |         Self { value }
310 |     }
311 | 
312 |     pub fn into_inner(self) -> T {
313 |         self.value
314 |     }
315 | 
316 |     pub fn get(&self) -> &T {
317 |         &self.value
318 |     }
319 | 
320 |     pub fn get_mut(&mut self) -> &mut T {
321 |         &mut self.value
322 |     }
323 | }
324 | 
325 | impl<T: Display> Display for Wrapper<T> {
326 |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
327 |         write!(f, "Wrapper({})", self.value)
328 |     }
329 | }
330 | 
331 | // Generic functions with closures
332 | 
333 | /// Map function for vectors
334 | pub fn map<T, U, F>(vec: Vec<T>, f: F) -> Vec<U>
335 | where
336 |     F: Fn(T) -> U,
337 | {
338 |     vec.into_iter().map(f).collect()
339 | }
340 | 
341 | /// Filter function for vectors
342 | pub fn filter<T, F>(vec: Vec<T>, predicate: F) -> Vec<T>
343 | where
344 |     F: Fn(&T) -> bool,
345 | {
346 |     vec.into_iter().filter(|x| predicate(x)).collect()
347 | }
348 | 
349 | /// Reduce/fold function
350 | pub fn reduce<T, U, F>(vec: Vec<T>, initial: U, f: F) -> U
351 | where
352 |     F: Fn(U, T) -> U,
353 | {
354 |     vec.into_iter().fold(initial, f)
355 | }
356 | 
357 | // Const generics (Rust 1.51+)
358 | 
359 | /// Array wrapper with const generic size
360 | #[derive(Debug)]
361 | pub struct FixedArray<T, const N: usize> {
362 |     data: [T; N],
363 | }
364 | 
365 | impl<T: Default + Copy, const N: usize> FixedArray<T, N> {
366 |     pub fn new() -> Self {
367 |         Self {
368 |             data: [T::default(); N],
369 |         }
370 |     }
371 | 
372 |     pub fn get(&self, index: usize) -> Option<&T> {
373 |         self.data.get(index)
374 |     }
375 | 
376 |     pub fn set(&mut self, index: usize, value: T) -> Result<(), String> {
377 |         if index < N {
378 |             self.data[index] = value;
379 |             Ok(())
380 |         } else {
381 |             Err("Index out of bounds".to_string())
382 |         }
383 |     }
384 | }
385 | 
386 | #[cfg(test)]
387 | mod tests {
388 |     use super::*;
389 | 
390 |     #[test]
391 |     fn test_largest() {
392 |         let numbers = vec![34, 50, 25, 100, 65];
393 |         assert_eq!(largest(&numbers), Some(&100));
394 |     }
395 | 
396 |     #[test]
397 |     fn test_point_add() {
398 |         let p1 = Point::new(1, 2);
399 |         let p2 = Point::new(3, 4);
400 |         let p3 = p1.add(&p2);
401 |         assert_eq!(p3.x, 4);
402 |         assert_eq!(p3.y, 6);
403 |     }
404 | 
405 |     #[test]
406 |     fn test_stack() {
407 |         let mut stack = Stack::new();
408 |         stack.push(1);
409 |         stack.push(2);
410 |         stack.push(3);
411 |         assert_eq!(stack.pop(), Some(3));
412 |         assert_eq!(stack.len(), 2);
413 |     }
414 | 
415 |     #[test]
416 |     fn test_maybe() {
417 |         let just = Maybe::Just(42);
418 |         let nothing: Maybe<i32> = Maybe::Nothing;
419 |         
420 |         assert!(just.is_just());
421 |         assert!(!nothing.is_just());
422 |         assert_eq!(just.unwrap(), 42);
423 |     }
424 | }
425 | 
426 | 
```

--------------------------------------------------------------------------------
/tests/test_database_validation.py:
--------------------------------------------------------------------------------

```python
  1 | """
  2 | Tests for database configuration validation and error handling.
  3 | """
  4 | 
  5 | import pytest
  6 | import sys
  7 | from pathlib import Path
  8 | 
  9 | # Add src to path for imports (needed for direct test execution)
 10 | sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
 11 | 
 12 | from codegraphcontext.core.database import DatabaseManager
 13 | 
 14 | 
 15 | class TestConfigValidation:
 16 |     """Tests for validate_config method"""
 17 |     
 18 |     def test_validate_config_valid_neo4j_uri(self):
 19 |         """Test validation passes for valid neo4j:// URI"""
 20 |         is_valid, error = DatabaseManager.validate_config(
 21 |             "neo4j://localhost:7687", "neo4j", "password123"
 22 |         )
 23 |         assert is_valid is True
 24 |         assert error is None
 25 |     
 26 |     def test_validate_config_valid_bolt_uri(self):
 27 |         """Test validation passes for valid bolt:// URI"""
 28 |         is_valid, error = DatabaseManager.validate_config(
 29 |             "bolt://localhost:7687", "neo4j", "password123"
 30 |         )
 31 |         assert is_valid is True
 32 |         assert error is None
 33 |     
 34 |     def test_validate_config_valid_secure_uri(self):
 35 |         """Test validation passes for valid neo4j+s:// URI"""
 36 |         is_valid, error = DatabaseManager.validate_config(
 37 |             "neo4j+s://localhost:7687", "neo4j", "password123"
 38 |         )
 39 |         assert is_valid is True
 40 |         assert error is None
 41 |     
 42 |     def test_validate_config_invalid_uri_no_protocol(self):
 43 |         """Test validation fails for URI without protocol"""
 44 |         is_valid, error = DatabaseManager.validate_config(
 45 |             "localhost:7687", "neo4j", "password123"
 46 |         )
 47 |         assert is_valid is False
 48 |         assert error is not None
 49 |         assert "Invalid Neo4j URI format" in error
 50 |         assert "neo4j://" in error or "bolt://" in error
 51 |     
 52 |     def test_validate_config_invalid_uri_no_port(self):
 53 |         """Test validation fails for URI without port"""
 54 |         is_valid, error = DatabaseManager.validate_config(
 55 |             "neo4j://localhost", "neo4j", "password123"
 56 |         )
 57 |         assert is_valid is False
 58 |         assert error is not None
 59 |         assert "Invalid Neo4j URI format" in error
 60 |     
 61 |     def test_validate_config_invalid_uri_wrong_protocol(self):
 62 |         """Test validation fails for invalid protocol"""
 63 |         is_valid, error = DatabaseManager.validate_config(
 64 |             "http://localhost:7687", "neo4j", "password123"
 65 |         )
 66 |         assert is_valid is False
 67 |         assert error is not None
 68 |         assert "Invalid Neo4j URI format" in error
 69 |     
 70 |     def test_validate_config_empty_username(self):
 71 |         """Test validation fails for empty username"""
 72 |         is_valid, error = DatabaseManager.validate_config(
 73 |             "neo4j://localhost:7687", "", "password123"
 74 |         )
 75 |         assert is_valid is False
 76 |         assert error is not None
 77 |         assert "Username cannot be empty" in error
 78 |         assert "neo4j" in error  # Should mention default username
 79 |     
 80 |     def test_validate_config_whitespace_username(self):
 81 |         """Test validation fails for whitespace-only username"""
 82 |         is_valid, error = DatabaseManager.validate_config(
 83 |             "neo4j://localhost:7687", "   ", "password123"
 84 |         )
 85 |         assert is_valid is False
 86 |         assert error is not None
 87 |         assert "Username cannot be empty" in error
 88 |     
 89 |     def test_validate_config_none_username(self):
 90 |         """Test validation fails for None username"""
 91 |         is_valid, error = DatabaseManager.validate_config(
 92 |             "neo4j://localhost:7687", None, "password123"
 93 |         )
 94 |         assert is_valid is False
 95 |         assert error is not None
 96 |         assert "Username cannot be empty" in error
 97 |     
 98 |     def test_validate_config_empty_password(self):
 99 |         """Test validation fails for empty password"""
100 |         is_valid, error = DatabaseManager.validate_config(
101 |             "neo4j://localhost:7687", "neo4j", ""
102 |         )
103 |         assert is_valid is False
104 |         assert error is not None
105 |         assert "Password cannot be empty" in error
106 |     
107 |     def test_validate_config_whitespace_password(self):
108 |         """Test validation fails for whitespace-only password"""
109 |         is_valid, error = DatabaseManager.validate_config(
110 |             "neo4j://localhost:7687", "neo4j", "   "
111 |         )
112 |         assert is_valid is False
113 |         assert error is not None
114 |         assert "Password cannot be empty" in error
115 |     
116 |     def test_validate_config_none_password(self):
117 |         """Test validation fails for None password"""
118 |         is_valid, error = DatabaseManager.validate_config(
119 |             "neo4j://localhost:7687", "neo4j", None
120 |         )
121 |         assert is_valid is False
122 |         assert error is not None
123 |         assert "Password cannot be empty" in error
124 |     
125 |     def test_validate_config_valid_with_special_chars_in_password(self):
126 |         """Test validation passes for password with special characters"""
127 |         is_valid, error = DatabaseManager.validate_config(
128 |             "neo4j://localhost:7687", "neo4j", "p@ssw0rd!#$%"
129 |         )
130 |         assert is_valid is True
131 |         assert error is None
132 |     
133 |     def test_validate_config_valid_custom_port(self):
134 |         """Test validation passes for custom port"""
135 |         is_valid, error = DatabaseManager.validate_config(
136 |             "neo4j://localhost:7688", "neo4j", "password123"
137 |         )
138 |         assert is_valid is True
139 |         assert error is None
140 |     
141 |     def test_validate_config_valid_remote_host(self):
142 |         """Test validation passes for remote host"""
143 |         is_valid, error = DatabaseManager.validate_config(
144 |             "neo4j://example.com:7687", "neo4j", "password123"
145 |         )
146 |         assert is_valid is True
147 |         assert error is None
148 |     
149 |     def test_validate_config_valid_ip_address(self):
150 |         """Test validation passes for IP address"""
151 |         is_valid, error = DatabaseManager.validate_config(
152 |             "neo4j://192.168.1.100:7687", "neo4j", "password123"
153 |         )
154 |         assert is_valid is True
155 |         assert error is None
156 | 
157 | 
158 | class TestConnectionTest:
159 |     """Tests for test_connection method"""
160 |     
161 |     def test_connection_invalid_host_unreachable(self):
162 |         """Test connection fails gracefully for unreachable host"""
163 |         is_connected, error = DatabaseManager.test_connection(
164 |             "neo4j://unreachable-host-12345.invalid:7687", "neo4j", "password123"
165 |         )
166 |         assert is_connected is False
167 |         assert error is not None
168 |         assert "Cannot reach Neo4j server" in error or "Connection failed" in error
169 |     
170 |     def test_connection_invalid_port(self):
171 |         """Test connection fails for invalid port"""
172 |         is_connected, error = DatabaseManager.test_connection(
173 |             "neo4j://localhost:9999", "neo4j", "password123"
174 |         )
175 |         assert is_connected is False
176 |         assert error is not None
177 |         # Should mention connectivity or unavailability
178 |         assert any(keyword in error for keyword in ["reach", "unavailable", "failed", "Connection"])
179 |     
180 |     def test_connection_provides_troubleshooting_tips(self):
181 |         """Test that error messages include troubleshooting tips"""
182 |         is_connected, error = DatabaseManager.test_connection(
183 |             "neo4j://localhost:9999", "neo4j", "password123"
184 |         )
185 |         assert is_connected is False
186 |         assert error is not None
187 |         # Should provide helpful troubleshooting
188 |         assert any(keyword in error.lower() for keyword in ["troubleshoot", "check", "docker", "try"])
189 | 
190 | 
191 | class TestValidationIntegration:
192 |     """Integration tests for validation in real-world scenarios"""
193 |     
194 |     def test_validate_aura_style_uri(self):
195 |         """Test validation works for Neo4j Aura-style URIs"""
196 |         is_valid, error = DatabaseManager.validate_config(
197 |             "neo4j+s://abc123.databases.neo4j.io:7687", "neo4j", "password123"
198 |         )
199 |         assert is_valid is True
200 |         assert error is None
201 |     
202 |     def test_validate_bolt_ssc_uri(self):
203 |         """Test validation works for bolt+ssc:// URIs"""
204 |         is_valid, error = DatabaseManager.validate_config(
205 |             "bolt+ssc://localhost:7687", "neo4j", "password123"
206 |         )
207 |         assert is_valid is True
208 |         assert error is None
209 |     
210 |     def test_multiple_validation_errors_at_once(self):
211 |         """Test validation catches the first error in priority order"""
212 |         # URI is invalid, username empty, password empty - should catch URI first
213 |         is_valid, error = DatabaseManager.validate_config(
214 |             "invalid-uri", "", ""
215 |         )
216 |         assert is_valid is False
217 |         assert "Invalid Neo4j URI format" in error
218 | 
219 | 
220 | if __name__ == "__main__":
221 |     pytest.main([__file__, "-v"])
222 | 
```

--------------------------------------------------------------------------------
/src/codegraphcontext/tools/languages/rust.py:
--------------------------------------------------------------------------------

```python
  1 | from pathlib import Path
  2 | from typing import Any, Dict, Optional, Tuple
  3 | import re
  4 | from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger, debug_logger
  5 | 
  6 | RUST_QUERIES = {
  7 |     "functions": """
  8 |         (function_item
  9 |             name: (identifier) @name
 10 |             parameters: (parameters) @params
 11 |         ) @function_node
 12 |     """,
 13 |     "classes": """
 14 |         [
 15 |             (struct_item name: (type_identifier) @name)
 16 |             (enum_item name: (type_identifier) @name)
 17 |             (trait_item name: (type_identifier) @name)
 18 |         ] @class
 19 |     """,
 20 |     "imports": """
 21 |         (use_declaration) @import
 22 |     """,
 23 |     "calls": """
 24 |         (call_expression
 25 |             function: [
 26 |                 (identifier) @name
 27 |                 (field_expression field: (field_identifier) @name)
 28 |                 (scoped_identifier name: (identifier) @name)
 29 |             ]
 30 |         )
 31 |     """,
 32 |     "traits": """
 33 |         (trait_item name: (type_identifier) @name) @trait_node
 34 |     """,  # <-- Added trait query
 35 | }
 36 | 
 37 | class RustTreeSitterParser:
 38 |     """A Rust-specific parser using tree-sitter."""
 39 | 
 40 |     def __init__(self, generic_parser_wrapper: Any):
 41 |         self.generic_parser_wrapper = generic_parser_wrapper
 42 |         self.language_name = "rust"
 43 |         self.language = generic_parser_wrapper.language
 44 |         self.parser = generic_parser_wrapper.parser
 45 | 
 46 |         self.queries = {
 47 |             name: self.language.query(query_str)
 48 |             for name, query_str in RUST_QUERIES.items()
 49 |         }
 50 | 
 51 |     def _get_node_text(self, node: Any) -> str:
 52 |         return node.text.decode("utf-8")
 53 | 
 54 |     def parse(self, file_path: Path, is_dependency: bool = False) -> Dict[str, Any]:
 55 |         """Parses a Rust file and returns its structure."""
 56 |         with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
 57 |             source_code = f.read()
 58 | 
 59 |         tree = self.parser.parse(bytes(source_code, "utf8"))
 60 |         root_node = tree.root_node
 61 | 
 62 |         functions = self._find_functions(root_node)
 63 |         classes = self._find_structs(root_node)
 64 |         imports = self._find_imports(root_node)
 65 |         function_calls = self._find_calls(root_node)
 66 |         traits = self._find_traits(root_node)  # <-- Added trait detection
 67 | 
 68 |         return {
 69 |             "file_path": str(file_path),
 70 |             "functions": functions,
 71 |             "classes": classes,
 72 |             "traits": traits,  # <-- Result for traits
 73 |             "variables": [],
 74 |             "imports": imports,
 75 |             "function_calls": function_calls,
 76 |             "is_dependency": is_dependency,
 77 |             "lang": self.language_name,
 78 |         }
 79 | 
 80 |     def _parse_function_args(self, params_node: Any) -> list[Dict[str, Any]]:
 81 |         """Helper to parse function arguments from a (parameters) node."""
 82 |         args = []
 83 |         for param in params_node.named_children:
 84 |             arg_info: Dict[str, Any] = {"name": "", "type": None}
 85 |             if param.type == "parameter":
 86 |                 pattern_node = param.child_by_field_name("pattern")
 87 |                 type_node = param.child_by_field_name("type")
 88 |                 if pattern_node:
 89 |                     arg_info["name"] = self._get_node_text(pattern_node)
 90 |                 if type_node:
 91 |                     arg_info["type"] = self._get_node_text(type_node)
 92 |                 args.append(arg_info)
 93 |             elif param.type == "self_parameter":
 94 |                 arg_info["name"] = self._get_node_text(param)
 95 |                 arg_info["type"] = "self"
 96 |                 args.append(arg_info)
 97 |         return args
 98 | 
 99 |     def _find_functions(self, root_node: Any) -> list[Dict[str, Any]]:
100 |         functions = []
101 |         query = self.queries["functions"]
102 |         for match in query.matches(root_node):
103 |             captures = {name: node for node, name in match.captures}
104 | 
105 |             func_node = captures.get("function_node")
106 |             name_node = captures.get("name")
107 |             params_node = captures.get("params")
108 | 
109 |             if func_node and name_node:
110 |                 name = self._get_node_text(name_node)
111 |                 args = self._parse_function_args(params_node) if params_node else []
112 | 
113 |                 functions.append(
114 |                     {
115 |                         "name": name,
116 |                         "line_number": name_node.start_point[0] + 1,
117 |                         "end_line": func_node.end_point[0] + 1,
118 |                         "source_code": self._get_node_text(func_node),
119 |                         "args": args,
120 |                     }
121 |                 )
122 |         return functions
123 | 
124 |     def _find_structs(self, root_node: Any) -> list[Dict[str, Any]]:
125 |         structs = []
126 |         query = self.queries["classes"]
127 |         for match in query.matches(root_node):
128 |             captures = {name: node for node, name in match.captures}
129 |             class_node = captures.get("class")
130 |             name_node = captures.get("name")
131 | 
132 |             if class_node and name_node:
133 |                 name = self._get_node_text(name_node)
134 |                 structs.append(
135 |                     {
136 |                         "name": name,
137 |                         "line_number": name_node.start_point[0] + 1,
138 |                         "end_line": class_node.end_point[0] + 1,
139 |                         "source_code": self._get_node_text(class_node),
140 |                         "bases": [],
141 |                     }
142 |                 )
143 |         return structs
144 | 
145 |     def _find_traits(self, root_node: Any) -> list[Dict[str, Any]]:
146 |         traits = []
147 |         query = self.queries["traits"]
148 |         for match in query.matches(root_node):
149 |             captures = {name: node for node, name in match.captures}
150 |             trait_node = captures.get("trait_node")
151 |             name_node = captures.get("name")
152 |             if trait_node and name_node:
153 |                 name = self._get_node_text(name_node)
154 |                 traits.append(
155 |                     {
156 |                         "name": name,
157 |                         "line_number": name_node.start_point[0] + 1,
158 |                         "end_line": trait_node.end_point[0] + 1,
159 |                         "source_code": self._get_node_text(trait_node),
160 |                     }
161 |                 )
162 |         return traits
163 | 
164 |     def _find_imports(self, root_node: Any) -> list[Dict[str, Any]]:
165 |         imports = []
166 |         query = self.queries["imports"]
167 |         for node, _ in query.captures(root_node):
168 |             full_import_name = self._get_node_text(node)
169 |             alias = None
170 | 
171 |             alias_match = re.search(r"as\s+(\w+)\s*;?$", full_import_name)
172 |             if alias_match:
173 |                 alias = alias_match.group(1)
174 |                 name = alias
175 |             else:
176 |                 cleaned_path = re.sub(r";$", "", full_import_name).strip()
177 |                 last_part = cleaned_path.split("::")[-1]
178 |                 if last_part.strip() == "*":
179 |                     name = "*"
180 |                 else:
181 |                     name_match = re.findall(r"(\w+)", last_part)
182 |                     name = name_match[-1] if name_match else last_part
183 | 
184 |             imports.append(
185 |                 {
186 |                     "name": name,
187 |                     "full_import_name": full_import_name,
188 |                     "line_number": node.start_point[0] + 1,
189 |                     "alias": alias,
190 |                 }
191 |             )
192 |         return imports
193 | 
194 |     def _find_calls(self, root_node: Any) -> list[Dict[str, Any]]:
195 |         """Finds all function and method calls."""
196 |         calls = []
197 |         query = self.queries["calls"]
198 |         for node, capture_name in query.captures(root_node):
199 |             if capture_name == "name":
200 |                 call_name = self._get_node_text(node)
201 |                 calls.append(
202 |                     {
203 |                         "name": call_name,
204 |                         "line_number": node.start_point[0] + 1,
205 |                     }
206 |                 )
207 |         return calls
208 | 
209 | def pre_scan_rust(files: list[Path], parser_wrapper) -> dict:
210 |     """Scans Rust files to create a map of function/struct/enum/trait names to their file paths."""
211 |     imports_map = {}
212 |     query_str = """
213 |         (function_item name: (identifier) @name)
214 |         (struct_item name: (type_identifier) @name)
215 |         (enum_item name: (type_identifier) @name)
216 |         (trait_item name: (type_identifier) @name)
217 |     """
218 |     query = parser_wrapper.language.query(query_str)
219 | 
220 |     for file_path in files:
221 |         try:
222 |             with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
223 |                 tree = parser_wrapper.parser.parse(bytes(f.read(), "utf8"))
224 | 
225 |             for capture, _ in query.captures(tree.root_node):
226 |                 name = capture.text.decode('utf-8')
227 |                 if name not in imports_map:
228 |                     imports_map[name] = []
229 |                 imports_map[name].append(str(file_path.resolve()))
230 |         except Exception as e:
231 |             warning_logger(f"Tree-sitter pre-scan failed for {file_path}: {e}")
232 |     return imports_map
233 | 
```

--------------------------------------------------------------------------------
/docs/site/assets/javascripts/lunr/min/lunr.fi.min.js:
--------------------------------------------------------------------------------

```javascript
 1 | /*!
 2 |  * Lunr languages, `Finnish` language
 3 |  * https://github.com/MihaiValentin/lunr-languages
 4 |  *
 5 |  * Copyright 2014, Mihai Valentin
 6 |  * http://www.mozilla.org/MPL/
 7 |  */
 8 | /*!
 9 |  * based on
10 |  * Snowball JavaScript Library v0.3
11 |  * http://code.google.com/p/urim/
12 |  * http://snowball.tartarus.org/
13 |  *
14 |  * Copyright 2010, Oleg Mazko
15 |  * http://www.mozilla.org/MPL/
16 |  */
17 | 
18 | !function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}});
```

--------------------------------------------------------------------------------
/docs/docs/contributing_languages.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Contributing New Language Support to CodeGraphContext
  2 | 
  3 | This document outlines the steps and best practices for adding support for a new programming language to CodeGraphContext. By following this guide, contributors can efficiently integrate new languages and leverage the Neo4j graph for verification.
  4 | 
  5 | ## 1. Understanding the Architecture
  6 | 
  7 | CodeGraphContext uses a modular architecture for multi-language support:
  8 | 
  9 | *   **Generic `TreeSitterParser` (in `graph_builder.py`):** This acts as a wrapper, dispatching parsing tasks to language-specific implementations.
 10 | *   **Language-Specific Parser Modules (in `src/codegraphcontext/tools/languages/`):** Each language (e.g., Python, JavaScript) has its own module (e.g., `python.py`, `javascript.py`) containing:
 11 |     *   Tree-sitter queries (`<LANG>_QUERIES`).
 12 |     *   A `<Lang>TreeSitterParser` class that encapsulates language-specific parsing logic.
 13 |     *   A `pre_scan_<lang>` function for initial symbol mapping.
 14 | *   **`GraphBuilder` (in `graph_builder.py`):** Manages the overall graph building process, including file discovery, pre-scanning, and dispatching to the correct language parser.
 15 | 
 16 | ## 2. Steps to Add a New Language (e.g., TypeScript - `.ts`)
 17 | 
 18 | ### Step 2.1: Create the Language Module File
 19 | 
 20 | 1.  Create a new file: `src/codegraphcontext/tools/languages/typescript.py`.
 21 | 2.  Add the necessary imports: `from pathlib import Path`, `from typing import Any, Dict, Optional, Tuple`, `import logging`, `import ast` (if needed for AST manipulation).
 22 | 3.  Define `TS_QUERIES` (Tree-sitter queries for TypeScript).
 23 | 4.  Create a `TypescriptTreeSitterParser` class.
 24 | 5.  Create a `pre_scan_typescript` function.
 25 | 
 26 | ### Step 2.2: Define Tree-sitter Queries (`TS_QUERIES`)
 27 | 
 28 | This is the most critical and often iterative step. You'll need to define queries for:
 29 | 
 30 | *   **`functions`**: Function declarations, arrow functions, methods.
 31 | *   **`classes`**: Class declarations, class expressions.
 32 | *   **`imports`**: ES6 imports (`import ... from ...`), CommonJS `require()`.
 33 | *   **`calls`**: Function calls, method calls.
 34 | *   **`variables`**: Variable declarations (`let`, `const`, `var`).
 35 | *   **`docstrings`**: (Optional) How documentation comments are identified.
 36 | *   **`lambda_assignments`**: (Optional, Python-specific) If the language has similar constructs.
 37 | 
 38 | **Tips for Query Writing:**
 39 | *   **Consult Tree-sitter Grammars:** Find the `node-types.json` or grammar definition for your language (e.g., `tree-sitter-typescript`).
 40 | *   **Use `tree-sitter parse`:** Use the `tree-sitter parse` command-line tool to inspect the AST of sample code snippets. This is invaluable for identifying correct node types and field names.
 41 | *   **Start Simple:** Begin with basic queries and gradually add complexity.
 42 | *   **Test Iteratively:** After each query, test it with sample code.
 43 | 
 44 | ### Step 2.3: Implement `<Lang>TreeSitterParser` Class
 45 | 
 46 | This class (e.g., `TypescriptTreeSitterParser`) will encapsulate the language-specific logic.
 47 | 
 48 | 1.  **`__init__(self, generic_parser_wrapper)`**:
 49 |     *   Store `generic_parser_wrapper`, `language_name`, `language`, `parser` from the generic wrapper.
 50 |     *   Load `TS_QUERIES` using `self.language.query(query_str)`.
 51 | 2.  **Helper Methods**:
 52 |     *   `_get_node_text(self, node)`: Extracts text from a tree-sitter node.
 53 |     *   `_get_parent_context(self, node, types=...)`: (Language-specific node types for context).
 54 |     *   `_calculate_complexity(self, node)`: (Language-specific complexity nodes).
 55 |     *   `_get_docstring(self, body_node)`: (Language-specific docstring extraction).
 56 | 3.  **`parse(self, file_path: Path, is_dependency: bool = False) -> Dict`**:
 57 |     *   Reads the file, parses it with `self.parser`.
 58 |     *   Calls its own `_find_*` methods (`_find_functions`, `_find_classes`, etc.).
 59 |     *   Returns a standardized dictionary format (as seen in `python.py` and `javascript.py`).
 60 | 4.  **`_find_*` Methods**:
 61 |     Implement these for each query type, extracting data from the AST and populating the standardized dictionary.
 62 | 
 63 | ### Step 2.4: Implement `pre_scan_<lang>` Function
 64 | 
 65 | This function (e.g., `pre_scan_typescript`) will quickly scan files to build an initial `imports_map`.
 66 | 
 67 | 1.  It takes `files: list[Path]` and `parser_wrapper` (an instance of `TreeSitterParser`).
 68 | 2.  Uses a simplified query (e.g., for `class_declaration` and `function_declaration`) to quickly find definitions.
 69 | 3.  Returns a dictionary mapping symbol names to file paths.
 70 | 
 71 | ### Step 2.5: Integrate into `graph_builder.py`
 72 | 
 73 | 1.  **`GraphBuilder.__init__`**:
 74 |     *   Add `'.ts': TreeSitterParser('typescript')` to `self.parsers`.
 75 | 2.  **`TreeSitterParser.__init__`**:
 76 |     *   Add an `elif self.language_name == 'typescript':` block to initialize `self.language_specific_parser` with `TypescriptTreeSitterParser(self)`.
 77 | 3.  **`GraphBuilder._pre_scan_for_imports`**:
 78 |     *   Add an `elif '.ts' in files_by_lang:` block to import `pre_scan_typescript` and call it.
 79 | 
 80 | ## 3. Verification and Debugging using Neo4j
 81 | 
 82 | After implementing support for a new language, it's crucial to verify that the graph is being built correctly.
 83 | 
 84 | ### Step 3.1: Prepare a Sample Project
 85 | 
 86 | Create a small sample project for your new language (e.g., `tests/sample_project_typescript/`) with:
 87 | *   Function declarations.
 88 | *   Class declarations (including inheritance).
 89 | *   Various import types (if applicable).
 90 | *   Function calls.
 91 | *   Variable declarations.
 92 | 
 93 | ### Step 3.2: Index the Sample Project
 94 | 
 95 | 1.  **Delete existing data (if any):**
 96 |     ```bash
 97 |     # Replace with your sample project path
 98 |     <tool_code>print(default_api.delete_repository(repo_path='/path/to/your/sample_project'))</tool_code>
 99 | 2.  **Index the project:**
100 |     ```bash
101 |     # Replace with your sample project path
102 |     <tool_code>print(default_api.add_code_to_graph(path='/path/to/your/sample_project'))</tool_code>
103 | 3.  **Monitor job status:**
104 |     ```bash
105 |     # Use the job_id returned by add_code_to_graph
106 |     <tool_code>print(default_api.check_job_status(job_id='<your_job_id>'))</tool_code>
107 | 
108 | ### Step 3.3: Query the Neo4j Graph
109 | 
110 | Use Cypher queries to inspect the generated graph.
111 | 
112 | *   **Check for Files and Language Tags:**
113 |     ```cypher
114 |     MATCH (f:File)
115 |     WHERE f.path STARTS WITH '/path/to/your/sample_project'
116 |     RETURN f.name, f.path, f.lang
117 |     ```
118 |     *Expected:* All files from your sample project should be listed with the correct `lang` tag.
119 | 
120 | *   **Check for Functions:**
121 |     ```cypher
122 |     MATCH (f:File)-[:CONTAINS]->(fn:Function)
123 |     WHERE f.path STARTS WITH '/path/to/your/sample_project'
124 |       AND fn.lang = '<your_language_name>'
125 |     RETURN f.name AS FileName, fn.name AS FunctionName, fn.line_number AS Line
126 |     ```
127 |     *Expected:* All functions from your sample project should be listed.
128 | 
129 | *   **Check for Classes:**
130 |     ```cypher
131 |     MATCH (f:File)-[:CONTAINS]->(c:Class)
132 |     WHERE f.path STARTS WITH '/path/to/your/sample_project'
133 |       AND c.lang = '<your_language_name>'
134 |     RETURN f.name AS FileName, c.name AS ClassName, c.line_number AS Line
135 |     ```
136 |     *Expected:* All classes from your sample project should be listed.
137 | 
138 | *   **Check for Imports (Module-level):**
139 |     ```cypher
140 |     MATCH (f:File)-[:IMPORTS]->(m:Module)
141 |     WHERE f.path STARTS WITH '/path/to/your/sample_project'
142 |       AND f.lang = '<your_language_name>'
143 |     RETURN f.name AS FileName, m.name AS ImportedModule, m.full_import_name AS FullImportName
144 |     ```
145 |     *Expected:* All module-level imports should be listed.
146 | 
147 | *   **Check for Function Calls:**
148 |     ```cypher
149 |     MATCH (caller:Function)-[:CALLS]->(callee:Function)
150 |     WHERE caller.file_path STARTS WITH '/path/to/your/sample_project'
151 |       AND caller.lang = '<your_language_name>'
152 |     RETURN caller.name AS Caller, callee.name AS Callee, caller.file_path AS CallerFile, callee.file_path AS CalleeFile
153 |     ```
154 |     *Expected:* All function calls should be correctly linked.
155 | 
156 | *   **Check for Class Inheritance:**
157 |     ```cypher
158 |     MATCH (child:Class)-[:INHERITS]->(parent:Class)
159 |     WHERE child.file_path STARTS WITH '/path/to/your/sample_project'
160 |       AND child.lang = '<your_language_name>'
161 |     RETURN child.name AS ChildClass, parent.name AS ParentClass, child.file_path AS ChildFile, parent.file_path AS ParentFile
162 |     ```
163 |     *Expected:* All inheritance relationships should be correctly linked.
164 | 
165 | ### Step 3.4: Debugging Common Issues
166 | 
167 | *   **`NameError: Invalid node type ...`**: Your tree-sitter query is using a node type that doesn't exist in the language's grammar. Use `tree-sitter parse` to inspect the AST.
168 | *   **Missing Relationships (e.g., `CALLS`, `IMPORTS`)**:
169 |     *   **Check `_find_*` methods**: Ensure your `_find_*` methods are correctly extracting the necessary data.
170 |     *   **Check `imports_map`**: Verify that the `pre_scan_<lang>` function is correctly populating the `imports_map`.
171 |     *   **Check `local_imports` map**: Ensure the `local_imports` map (built in `_create_function_calls` and `_create_inheritance_links`) is correctly resolving symbols.
172 | *   **Incorrect `lang` tags**: Ensure `self.language_name` is correctly passed and stored.
173 | 
174 | By following these steps, contributors can effectively add and verify new language support.
175 | 
```
Page 5/18FirstPrevNextLast