#
tokens: 49120/50000 18/440 files (page 5/17)
lines: off (toggle) GitHub
raw markdown copy
This is page 5 of 17. Use http://codebase.md/shashankss1205/codegraphcontext?lines=false&page={x} to view the full context.

# Directory Structure

```
├── .cgcignore
├── .dockerignore
├── .env.example
├── .github
│   ├── FUNDING.yml
│   └── workflows
│       ├── docker-publish.yml
│       ├── e2e-tests.yml
│       ├── post_discord_invite.yml
│       ├── test.yml
│       └── update-contributors.yml
├── .gitignore
├── CLI_Commands.md
├── CONTRIBUTING.md
├── contributors.md
├── deploy-production.sh
├── DEPLOYMENT_CHECKLIST.md
├── DOCKER_COMPLETE_GUIDE.md
├── DOCKER_DEPLOYMENT.md
├── DOCKER_README.md
├── docker-compose.template.yml
├── docker-quickstart.sh
├── Dockerfile
├── 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
│   │   └── watching.md
│   ├── mkdocs.yml
│   └── site
│       ├── 404.html
│       ├── architecture
│       │   └── index.html
│       ├── assets
│       │   ├── images
│       │   │   └── favicon.png
│       │   ├── javascripts
│       │   │   ├── bundle.79ae519e.min.js
│       │   │   ├── bundle.79ae519e.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.2c215733.min.js
│       │   │       └── search.2c215733.min.js.map
│       │   └── stylesheets
│       │       ├── main.484c7ddc.min.css
│       │       ├── main.484c7ddc.min.css.map
│       │       ├── palette.ab4e12ef.min.css
│       │       └── palette.ab4e12ef.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
│       └── watching
│           └── index.html
├── funding.json
├── HOSTING_COMPARISON.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
├── k8s
│   ├── configmap.yaml
│   ├── deployment.yaml
│   ├── neo4j-deployment.yaml
│   ├── pvc.yaml
│   ├── README.md
│   └── service.yaml
├── LICENSE
├── MANIFEST.in
├── organizer
│   ├── CONTRIBUTING_LANGUAGES.md
│   ├── cookbook.md
│   ├── docs.md
│   ├── language_specific_nodes.md
│   ├── Tools_Exploration.md
│   └── troubleshoot.md
├── pyproject.toml
├── README.md
├── scripts
│   ├── generate_lang_contributors.py
│   ├── post_install_fix.sh
│   ├── test_all_parsers.py
│   └── update_language_parsers.py
├── SECURITY.md
├── src
│   └── codegraphcontext
│       ├── __init__.py
│       ├── __main__.py
│       ├── cli
│       │   ├── __init__.py
│       │   ├── cli_helpers.py
│       │   ├── config_manager.py
│       │   ├── main.py
│       │   ├── setup_macos.py
│       │   └── setup_wizard.py
│       ├── core
│       │   ├── __init__.py
│       │   ├── database_falkordb.py
│       │   ├── database.py
│       │   ├── falkor_worker.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
│       │   │   ├── csharp.py
│       │   │   ├── go.py
│       │   │   ├── java.py
│       │   │   ├── javascript.py
│       │   │   ├── kotlin.py
│       │   │   ├── php.py
│       │   │   ├── python.py
│       │   │   ├── ruby.py
│       │   │   ├── rust.py
│       │   │   ├── scala.py
│       │   │   ├── swift.py
│       │   │   ├── typescript.py
│       │   │   └── typescriptjsx.py
│       │   ├── package_resolver.py
│       │   ├── query_tool_languages
│       │   │   ├── c_toolkit.py
│       │   │   ├── cpp_toolkit.py
│       │   │   ├── csharp_toolkit.py
│       │   │   ├── go_toolkit.py
│       │   │   ├── java_toolkit.py
│       │   │   ├── javascript_toolkit.py
│       │   │   ├── python_toolkit.py
│       │   │   ├── ruby_toolkit.py
│       │   │   ├── rust_toolkit.py
│       │   │   ├── scala_toolkit.py
│       │   │   ├── swift_toolkit.py
│       │   │   └── typescript_toolkit.py
│       │   └── system.py
│       └── utils
│           ├── debug_log.py
│           └── tree_sitter_manager.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_csharp
│   │   ├── README.md
│   │   └── src
│   │       └── Example.App
│   │           ├── Attributes
│   │           │   └── CustomAttributes.cs
│   │           ├── Example.App.csproj
│   │           ├── Models
│   │           │   ├── Person.cs
│   │           │   ├── Point.cs
│   │           │   ├── Role.cs
│   │           │   └── User.cs
│   │           ├── OuterClass.cs
│   │           ├── Program.cs
│   │           ├── Services
│   │           │   ├── GreetingService.cs
│   │           │   ├── IGreetingService.cs
│   │           │   └── LegacyService.cs
│   │           └── Utils
│   │               ├── CollectionHelper.cs
│   │               └── FileHelper.cs
│   ├── 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_kotlin
│   │   ├── AdvancedClasses.kt
│   │   ├── Annotations.kt
│   │   ├── Coroutines.kt
│   │   ├── EdgeCases.kt
│   │   ├── Functions.kt
│   │   ├── Main.kt
│   │   ├── Properties.kt
│   │   └── User.kt
│   ├── 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_scala
│   │   ├── Animals.scala
│   │   ├── Complex.scala
│   │   ├── Functional.scala
│   │   ├── Geometry.scala
│   │   ├── Main.scala
│   │   ├── PackageObject.scala
│   │   ├── Script.sc
│   │   ├── Services.scala
│   │   ├── Shapes.scala
│   │   ├── Utils.scala
│   │   └── Variables.scala
│   ├── sample_project_swift
│   │   ├── Generics.swift
│   │   ├── Main.swift
│   │   ├── README.md
│   │   ├── Shapes.swift
│   │   ├── User.swift
│   │   └── Vehicles.swift
│   ├── sample_project_typescript
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── sample_tsx.tsx
│   │   ├── 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_kotlin_parser.py
│   ├── test_swift_parser.py
│   ├── test_tree_sitter
│   │   ├── __init__.py
│   │   ├── class_instantiation.py
│   │   ├── complex_classes.py
│   │   └── test_file.py
│   ├── test_tree_sitter_manager.py
│   └── test_typescript_parser.py
├── visualize_graph.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
│   │   │   ├── SocialMentionsTimeline.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
└── windows_setup_guide.md
```

# Files

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

```rust
// iterators_closures.rs - Demonstrates Rust iterators and closures
use std::collections::HashMap;

// Closure examples

/// Function taking closure as parameter
pub fn apply<F>(f: F, x: i32) -> i32
where
    F: Fn(i32) -> i32,
{
    f(x)
}

/// Function returning closure
pub fn make_adder(n: i32) -> impl Fn(i32) -> i32 {
    move |x| x + n
}

/// Closure capturing environment
pub fn closure_capture() {
    let factor = 5;
    let multiply = |x| x * factor;
    println!("Result: {}", multiply(10));
}

/// Closure with move
pub fn closure_move() -> Box<dyn Fn(i32) -> i32> {
    let factor = 5;
    Box::new(move |x| x * factor)
}

/// FnOnce closure (consumes captured values)
pub fn call_once<F>(f: F)
where
    F: FnOnce(),
{
    f();
}

/// FnMut closure (mutates captured values)
pub fn call_mut<F>(mut f: F)
where
    F: FnMut(),
{
    f();
    f();
}

// Iterator examples

/// Custom iterator
pub struct Counter {
    count: u32,
    max: u32,
}

impl Counter {
    pub fn new(max: u32) -> Self {
        Self { count: 0, max }
    }
}

impl Iterator for Counter {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        if self.count < self.max {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

/// Range iterator wrapper
pub struct Range {
    start: i32,
    end: i32,
    current: i32,
}

impl Range {
    pub fn new(start: i32, end: i32) -> Self {
        Self {
            start,
            end,
            current: start,
        }
    }
}

impl Iterator for Range {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current < self.end {
            let result = self.current;
            self.current += 1;
            Some(result)
        } else {
            None
        }
    }
}

// Iterator adapter patterns

/// Map pattern
pub fn double_numbers(numbers: Vec<i32>) -> Vec<i32> {
    numbers.iter().map(|&x| x * 2).collect()
}

/// Filter pattern
pub fn filter_evens(numbers: Vec<i32>) -> Vec<i32> {
    numbers.into_iter().filter(|&x| x % 2 == 0).collect()
}

/// Filter and map combined
pub fn process_numbers(numbers: Vec<i32>) -> Vec<i32> {
    numbers
        .into_iter()
        .filter(|&x| x > 0)
        .map(|x| x * 2)
        .collect()
}

/// Fold/reduce pattern
pub fn sum_numbers(numbers: &[i32]) -> i32 {
    numbers.iter().fold(0, |acc, &x| acc + x)
}

/// Find pattern
pub fn find_first_even(numbers: &[i32]) -> Option<i32> {
    numbers.iter().find(|&&x| x % 2 == 0).copied()
}

/// Any and all
pub fn has_negative(numbers: &[i32]) -> bool {
    numbers.iter().any(|&x| x < 0)
}

pub fn all_positive(numbers: &[i32]) -> bool {
    numbers.iter().all(|&x| x > 0)
}

/// Take and skip
pub fn take_first_n(numbers: Vec<i32>, n: usize) -> Vec<i32> {
    numbers.into_iter().take(n).collect()
}

pub fn skip_first_n(numbers: Vec<i32>, n: usize) -> Vec<i32> {
    numbers.into_iter().skip(n).collect()
}

/// Chain iterators
pub fn chain_vectors(v1: Vec<i32>, v2: Vec<i32>) -> Vec<i32> {
    v1.into_iter().chain(v2.into_iter()).collect()
}

/// Zip iterators
pub fn zip_vectors(v1: Vec<i32>, v2: Vec<i32>) -> Vec<(i32, i32)> {
    v1.into_iter().zip(v2.into_iter()).collect()
}

/// Enumerate
pub fn enumerate_items(items: Vec<String>) -> Vec<(usize, String)> {
    items.into_iter().enumerate().collect()
}

/// Flat map
pub fn flat_map_example(nested: Vec<Vec<i32>>) -> Vec<i32> {
    nested.into_iter().flat_map(|v| v.into_iter()).collect()
}

/// Partition
pub fn partition_numbers(numbers: Vec<i32>) -> (Vec<i32>, Vec<i32>) {
    numbers.into_iter().partition(|&x| x % 2 == 0)
}

// Complex iterator chains

/// Multiple operations
pub fn complex_pipeline(numbers: Vec<i32>) -> i32 {
    numbers
        .into_iter()
        .filter(|&x| x > 0)
        .map(|x| x * 2)
        .filter(|&x| x < 100)
        .fold(0, |acc, x| acc + x)
}

/// Group by pattern (using HashMap)
pub fn group_by_parity(numbers: Vec<i32>) -> HashMap<bool, Vec<i32>> {
    let mut map = HashMap::new();
    for num in numbers {
        let is_even = num % 2 == 0;
        map.entry(is_even).or_insert_with(Vec::new).push(num);
    }
    map
}

/// Max and min
pub fn find_extremes(numbers: &[i32]) -> (Option<i32>, Option<i32>) {
    let max = numbers.iter().max().copied();
    let min = numbers.iter().min().copied();
    (max, min)
}

/// Collect into different types
pub fn collect_examples(numbers: Vec<i32>) -> (Vec<i32>, String) {
    let vec: Vec<i32> = numbers.iter().map(|&x| x * 2).collect();
    let string: String = numbers
        .iter()
        .map(|x| x.to_string())
        .collect::<Vec<String>>()
        .join(", ");
    (vec, string)
}

// Custom iterator adapters

pub struct StepBy {
    iter: std::vec::IntoIter<i32>,
    step: usize,
}

impl StepBy {
    pub fn new(vec: Vec<i32>, step: usize) -> Self {
        Self {
            iter: vec.into_iter(),
            step,
        }
    }
}

impl Iterator for StepBy {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        let result = self.iter.next()?;
        for _ in 0..self.step - 1 {
            self.iter.next();
        }
        Some(result)
    }
}

// Lazy evaluation demonstration

pub struct LazyMap<I, F> {
    iter: I,
    f: F,
}

impl<I, F, T, U> Iterator for LazyMap<I, F>
where
    I: Iterator<Item = T>,
    F: FnMut(T) -> U,
{
    type Item = U;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(|x| (self.f)(x))
    }
}

// Infinite iterators

pub fn fibonacci_iterator() -> impl Iterator<Item = u64> {
    let mut a = 0;
    let mut b = 1;
    std::iter::from_fn(move || {
        let result = a;
        let next = a + b;
        a = b;
        b = next;
        Some(result)
    })
}

/// Take from infinite iterator
pub fn first_n_fibonacci(n: usize) -> Vec<u64> {
    fibonacci_iterator().take(n).collect()
}

// Peekable iterator
pub fn peek_example(numbers: Vec<i32>) -> Vec<i32> {
    let mut iter = numbers.into_iter().peekable();
    let mut result = Vec::new();

    while let Some(&next) = iter.peek() {
        if next % 2 == 0 {
            result.push(iter.next().unwrap());
        } else {
            iter.next();
        }
    }

    result
}

// Cycle iterator
pub fn cycle_example(items: Vec<i32>, count: usize) -> Vec<i32> {
    items.into_iter().cycle().take(count).collect()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_counter() {
        let counter = Counter::new(5);
        let result: Vec<u32> = counter.collect();
        assert_eq!(result, vec![1, 2, 3, 4, 5]);
    }

    #[test]
    fn test_double_numbers() {
        let numbers = vec![1, 2, 3, 4, 5];
        let doubled = double_numbers(numbers);
        assert_eq!(doubled, vec![2, 4, 6, 8, 10]);
    }

    #[test]
    fn test_filter_evens() {
        let numbers = vec![1, 2, 3, 4, 5, 6];
        let evens = filter_evens(numbers);
        assert_eq!(evens, vec![2, 4, 6]);
    }

    #[test]
    fn test_sum_numbers() {
        let numbers = vec![1, 2, 3, 4, 5];
        assert_eq!(sum_numbers(&numbers), 15);
    }

    #[test]
    fn test_make_adder() {
        let add_five = make_adder(5);
        assert_eq!(add_five(10), 15);
    }

    #[test]
    fn test_fibonacci() {
        let fibs = first_n_fibonacci(10);
        assert_eq!(fibs, vec![0, 1, 1, 2, 3, 5, 8, 13, 21, 34]);
    }
}


```

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

```typescript
import * as React from "react";
import * as MenubarPrimitive from "@radix-ui/react-menubar";
import { Check, ChevronRight, Circle } from "lucide-react";

import { cn } from "@/lib/utils";

const MenubarMenu = MenubarPrimitive.Menu;

const MenubarGroup = MenubarPrimitive.Group;

const MenubarPortal = MenubarPrimitive.Portal;

const MenubarSub = MenubarPrimitive.Sub;

const MenubarRadioGroup = MenubarPrimitive.RadioGroup;

const Menubar = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.Root>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>
>(({ className, ...props }, ref) => (
  <MenubarPrimitive.Root
    ref={ref}
    className={cn("flex h-10 items-center space-x-1 rounded-md border bg-background p-1", className)}
    {...props}
  />
));
Menubar.displayName = MenubarPrimitive.Root.displayName;

const MenubarTrigger = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.Trigger>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>
>(({ className, ...props }, ref) => (
  <MenubarPrimitive.Trigger
    ref={ref}
    className={cn(
      "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",
      className,
    )}
    {...props}
  />
));
MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;

const MenubarSubTrigger = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
    inset?: boolean;
  }
>(({ className, inset, children, ...props }, ref) => (
  <MenubarPrimitive.SubTrigger
    ref={ref}
    className={cn(
      "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",
      inset && "pl-8",
      className,
    )}
    {...props}
  >
    {children}
    <ChevronRight className="ml-auto h-4 w-4" />
  </MenubarPrimitive.SubTrigger>
));
MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;

const MenubarSubContent = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.SubContent>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>
>(({ className, ...props }, ref) => (
  <MenubarPrimitive.SubContent
    ref={ref}
    className={cn(
      "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",
      className,
    )}
    {...props}
  />
));
MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;

const MenubarContent = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
>(({ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }, ref) => (
  <MenubarPrimitive.Portal>
    <MenubarPrimitive.Content
      ref={ref}
      align={align}
      alignOffset={alignOffset}
      sideOffset={sideOffset}
      className={cn(
        "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",
        className,
      )}
      {...props}
    />
  </MenubarPrimitive.Portal>
));
MenubarContent.displayName = MenubarPrimitive.Content.displayName;

const MenubarItem = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.Item>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
    inset?: boolean;
  }
>(({ className, inset, ...props }, ref) => (
  <MenubarPrimitive.Item
    ref={ref}
    className={cn(
      "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",
      inset && "pl-8",
      className,
    )}
    {...props}
  />
));
MenubarItem.displayName = MenubarPrimitive.Item.displayName;

const MenubarCheckboxItem = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>
>(({ className, children, checked, ...props }, ref) => (
  <MenubarPrimitive.CheckboxItem
    ref={ref}
    className={cn(
      "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",
      className,
    )}
    checked={checked}
    {...props}
  >
    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
      <MenubarPrimitive.ItemIndicator>
        <Check className="h-4 w-4" />
      </MenubarPrimitive.ItemIndicator>
    </span>
    {children}
  </MenubarPrimitive.CheckboxItem>
));
MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;

const MenubarRadioItem = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.RadioItem>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>
>(({ className, children, ...props }, ref) => (
  <MenubarPrimitive.RadioItem
    ref={ref}
    className={cn(
      "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",
      className,
    )}
    {...props}
  >
    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
      <MenubarPrimitive.ItemIndicator>
        <Circle className="h-2 w-2 fill-current" />
      </MenubarPrimitive.ItemIndicator>
    </span>
    {children}
  </MenubarPrimitive.RadioItem>
));
MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;

const MenubarLabel = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.Label>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
    inset?: boolean;
  }
>(({ className, inset, ...props }, ref) => (
  <MenubarPrimitive.Label
    ref={ref}
    className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
    {...props}
  />
));
MenubarLabel.displayName = MenubarPrimitive.Label.displayName;

const MenubarSeparator = React.forwardRef<
  React.ElementRef<typeof MenubarPrimitive.Separator>,
  React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>
>(({ className, ...props }, ref) => (
  <MenubarPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
));
MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;

const MenubarShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
  return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
};
MenubarShortcut.displayname = "MenubarShortcut";

export {
  Menubar,
  MenubarMenu,
  MenubarTrigger,
  MenubarContent,
  MenubarItem,
  MenubarSeparator,
  MenubarLabel,
  MenubarCheckboxItem,
  MenubarRadioGroup,
  MenubarRadioItem,
  MenubarPortal,
  MenubarSubContent,
  MenubarSubTrigger,
  MenubarGroup,
  MenubarSub,
  MenubarShortcut,
};

```

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

```rust
// concurrency.rs - Demonstrates Rust concurrency patterns
use std::sync::{Arc, Mutex, RwLock, mpsc};
use std::thread;
use std::time::Duration;

/// Simple thread spawning
pub fn spawn_simple_thread() {
    let handle = thread::spawn(|| {
        for i in 1..5 {
            println!("Thread: {}", i);
            thread::sleep(Duration::from_millis(10));
        }
    });

    handle.join().unwrap();
}

/// Thread with move closure
pub fn thread_with_ownership() {
    let data = vec![1, 2, 3, 4, 5];
    
    let handle = thread::spawn(move || {
        println!("Thread got data: {:?}", data);
        data.iter().sum::<i32>()
    });

    let result = handle.join().unwrap();
    println!("Sum: {}", result);
}

/// Multiple threads
pub fn spawn_multiple_threads(count: usize) -> Vec<i32> {
    let mut handles = vec![];

    for i in 0..count {
        let handle = thread::spawn(move || {
            thread::sleep(Duration::from_millis(10));
            i as i32 * 2
        });
        handles.push(handle);
    }

    handles.into_iter().map(|h| h.join().unwrap()).collect()
}

// Mutex for shared state

/// Shared counter with Mutex
pub fn shared_counter(thread_count: usize) -> i32 {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..thread_count {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            for _ in 0..100 {
                let mut num = counter.lock().unwrap();
                *num += 1;
            }
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    let final_count = *counter.lock().unwrap();
    final_count
}

/// Safe data structure with Mutex
#[derive(Debug)]
pub struct SafeCounter {
    count: Arc<Mutex<i32>>,
}

impl SafeCounter {
    pub fn new() -> Self {
        Self {
            count: Arc::new(Mutex::new(0)),
        }
    }

    pub fn increment(&self) {
        let mut count = self.count.lock().unwrap();
        *count += 1;
    }

    pub fn get(&self) -> i32 {
        *self.count.lock().unwrap()
    }

    pub fn clone_counter(&self) -> SafeCounter {
        SafeCounter {
            count: Arc::clone(&self.count),
        }
    }
}

// RwLock for read-heavy workloads

/// Shared data with RwLock
pub struct SharedData {
    data: Arc<RwLock<Vec<i32>>>,
}

impl SharedData {
    pub fn new() -> Self {
        Self {
            data: Arc::new(RwLock::new(Vec::new())),
        }
    }

    pub fn add(&self, value: i32) {
        let mut data = self.data.write().unwrap();
        data.push(value);
    }

    pub fn get(&self, index: usize) -> Option<i32> {
        let data = self.data.read().unwrap();
        data.get(index).copied()
    }

    pub fn len(&self) -> usize {
        let data = self.data.read().unwrap();
        data.len()
    }

    pub fn clone_data(&self) -> SharedData {
        SharedData {
            data: Arc::clone(&self.data),
        }
    }
}

// Message passing with channels

/// Simple channel communication
pub fn simple_channel() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let messages = vec!["hello", "from", "thread"];
        for msg in messages {
            tx.send(msg).unwrap();
            thread::sleep(Duration::from_millis(10));
        }
    });

    for received in rx {
        println!("Got: {}", received);
    }
}

/// Multiple producers
pub fn multiple_producers() -> Vec<String> {
    let (tx, rx) = mpsc::channel();
    let mut results = Vec::new();

    for i in 0..3 {
        let tx_clone = tx.clone();
        thread::spawn(move || {
            let message = format!("Message from thread {}", i);
            tx_clone.send(message).unwrap();
        });
    }

    drop(tx); // Drop original sender

    for received in rx {
        results.push(received);
    }

    results
}

/// Worker pool pattern
pub struct ThreadPool {
    workers: Vec<Worker>,
    sender: mpsc::Sender<Job>,
}

type Job = Box<dyn FnOnce() + Send + 'static>;

struct Worker {
    id: usize,
    thread: Option<thread::JoinHandle<()>>,
}

impl Worker {
    fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
        let thread = thread::spawn(move || loop {
            let job = receiver.lock().unwrap().recv();

            match job {
                Ok(job) => {
                    println!("Worker {} executing job", id);
                    job();
                }
                Err(_) => {
                    println!("Worker {} shutting down", id);
                    break;
                }
            }
        });

        Worker {
            id,
            thread: Some(thread),
        }
    }
}

impl ThreadPool {
    pub fn new(size: usize) -> ThreadPool {
        assert!(size > 0);

        let (sender, receiver) = mpsc::channel();
        let receiver = Arc::new(Mutex::new(receiver));
        let mut workers = Vec::with_capacity(size);

        for id in 0..size {
            workers.push(Worker::new(id, Arc::clone(&receiver)));
        }

        ThreadPool { workers, sender }
    }

    pub fn execute<F>(&self, f: F)
    where
        F: FnOnce() + Send + 'static,
    {
        let job = Box::new(f);
        self.sender.send(job).unwrap();
    }
}

impl Drop for ThreadPool {
    fn drop(&mut self) {
        for worker in &mut self.workers {
            if let Some(thread) = worker.thread.take() {
                thread.join().unwrap();
            }
        }
    }
}

// Barrier synchronization
use std::sync::Barrier;

pub fn barrier_example() {
    let barrier = Arc::new(Barrier::new(3));
    let mut handles = vec![];

    for i in 0..3 {
        let barrier = Arc::clone(&barrier);
        let handle = thread::spawn(move || {
            println!("Thread {} before barrier", i);
            barrier.wait();
            println!("Thread {} after barrier", i);
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }
}

// Atomic operations
use std::sync::atomic::{AtomicUsize, Ordering};

pub struct AtomicCounter {
    count: AtomicUsize,
}

impl AtomicCounter {
    pub fn new() -> Self {
        Self {
            count: AtomicUsize::new(0),
        }
    }

    pub fn increment(&self) {
        self.count.fetch_add(1, Ordering::SeqCst);
    }

    pub fn get(&self) -> usize {
        self.count.load(Ordering::SeqCst)
    }
}

// Once initialization
use std::sync::Once;

static mut SINGLETON: Option<String> = None;
static INIT: Once = Once::new();

pub fn get_singleton() -> &'static String {
    unsafe {
        INIT.call_once(|| {
            SINGLETON = Some(String::from("Singleton instance"));
        });
        SINGLETON.as_ref().unwrap()
    }
}

// Scoped threads (Rust 1.63+)
pub fn scoped_threads() {
    let mut data = vec![1, 2, 3, 4, 5];

    thread::scope(|s| {
        s.spawn(|| {
            println!("Thread 1 can access data: {:?}", data);
        });

        s.spawn(|| {
            println!("Thread 2 can also access data: {:?}", data);
        });
    });

    data.push(6); // Can use data after scope
    println!("Final data: {:?}", data);
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_shared_counter() {
        let result = shared_counter(5);
        assert_eq!(result, 500);
    }

    #[test]
    fn test_safe_counter() {
        let counter = SafeCounter::new();
        counter.increment();
        counter.increment();
        assert_eq!(counter.get(), 2);
    }

    #[test]
    fn test_shared_data() {
        let data = SharedData::new();
        data.add(1);
        data.add(2);
        data.add(3);
        assert_eq!(data.len(), 3);
        assert_eq!(data.get(1), Some(2));
    }

    #[test]
    fn test_atomic_counter() {
        let counter = AtomicCounter::new();
        counter.increment();
        counter.increment();
        assert_eq!(counter.get(), 2);
    }
}


```

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

```rust
// error_handling.rs - Demonstrates Rust error handling patterns
use std::error::Error;
use std::fmt;
use std::fs::File;
use std::io::{self, Read};

/// Custom error type
#[derive(Debug, Clone)]
pub struct CustomError {
    pub code: u32,
    pub message: String,
}

impl fmt::Display for CustomError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Error {}: {}", self.code, self.message)
    }
}

impl Error for CustomError {}

impl CustomError {
    pub fn new(code: u32, message: String) -> Self {
        Self { code, message }
    }
}

/// Validation error
#[derive(Debug)]
pub struct ValidationError {
    pub field: String,
    pub value: String,
    pub reason: String,
}

impl fmt::Display for ValidationError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Validation failed for field '{}' with value '{}': {}",
            self.field, self.value, self.reason
        )
    }
}

impl Error for ValidationError {}

/// Multiple error types enum
#[derive(Debug)]
pub enum AppError {
    Io(io::Error),
    Parse(std::num::ParseIntError),
    Custom(CustomError),
    Validation(ValidationError),
}

impl fmt::Display for AppError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            AppError::Io(err) => write!(f, "IO error: {}", err),
            AppError::Parse(err) => write!(f, "Parse error: {}", err),
            AppError::Custom(err) => write!(f, "Custom error: {}", err),
            AppError::Validation(err) => write!(f, "Validation error: {}", err),
        }
    }
}

impl Error for AppError {}

impl From<io::Error> for AppError {
    fn from(err: io::Error) -> Self {
        AppError::Io(err)
    }
}

impl From<std::num::ParseIntError> for AppError {
    fn from(err: std::num::ParseIntError) -> Self {
        AppError::Parse(err)
    }
}

impl From<CustomError> for AppError {
    fn from(err: CustomError) -> Self {
        AppError::Custom(err)
    }
}

// Basic Result usage

/// Simple function returning Result
pub fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("Division by zero".to_string())
    } else {
        Ok(a / b)
    }
}

/// Function with multiple error conditions
pub fn validate_age(age: i32) -> Result<i32, String> {
    if age < 0 {
        return Err("Age cannot be negative".to_string());
    }
    if age > 150 {
        return Err("Age is unrealistic".to_string());
    }
    Ok(age)
}

/// Using custom error type
pub fn validate_username(username: &str) -> Result<String, CustomError> {
    if username.is_empty() {
        return Err(CustomError::new(400, "Username cannot be empty".to_string()));
    }
    if username.len() < 3 {
        return Err(CustomError::new(400, "Username too short".to_string()));
    }
    if username.len() > 20 {
        return Err(CustomError::new(400, "Username too long".to_string()));
    }
    Ok(username.to_string())
}

/// Error propagation with ? operator
pub fn read_file_contents(filename: &str) -> Result<String, io::Error> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

/// Chaining operations with ?
pub fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
    let num: i32 = s.parse()?;
    Ok(num * 2)
}

/// Multiple error types with ?
pub fn read_and_parse(filename: &str) -> Result<i32, AppError> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    let num: i32 = contents.trim().parse()?;
    Ok(num)
}

/// Custom validation with ValidationError
pub fn validate_email(email: &str) -> Result<String, ValidationError> {
    if !email.contains('@') {
        return Err(ValidationError {
            field: "email".to_string(),
            value: email.to_string(),
            reason: "Must contain @ symbol".to_string(),
        });
    }
    if !email.contains('.') {
        return Err(ValidationError {
            field: "email".to_string(),
            value: email.to_string(),
            reason: "Must contain domain extension".to_string(),
        });
    }
    Ok(email.to_string())
}

/// Using match for error handling
pub fn process_result(result: Result<i32, String>) -> i32 {
    match result {
        Ok(value) => value,
        Err(e) => {
            println!("Error occurred: {}", e);
            0
        }
    }
}

/// Using unwrap_or
pub fn safe_divide(a: i32, b: i32) -> i32 {
    divide(a, b).unwrap_or(0)
}

/// Using unwrap_or_else
pub fn safe_divide_with_default(a: i32, b: i32, default: i32) -> i32 {
    divide(a, b).unwrap_or_else(|_| default)
}

/// Using map and and_then
pub fn parse_and_validate(s: &str) -> Result<i32, String> {
    s.parse::<i32>()
        .map_err(|e| format!("Parse error: {}", e))
        .and_then(|num| {
            if num >= 0 {
                Ok(num)
            } else {
                Err("Number must be non-negative".to_string())
            }
        })
}

/// Error recovery pattern
pub fn try_parse_or_default(s: &str, default: i32) -> i32 {
    s.parse().unwrap_or(default)
}

/// Multiple validation steps
pub fn validate_user(name: &str, age: i32, email: &str) -> Result<User, Vec<String>> {
    let mut errors = Vec::new();

    if name.is_empty() {
        errors.push("Name cannot be empty".to_string());
    }
    if age < 18 {
        errors.push("Must be 18 or older".to_string());
    }
    if !email.contains('@') {
        errors.push("Invalid email".to_string());
    }

    if errors.is_empty() {
        Ok(User {
            name: name.to_string(),
            age,
            email: email.to_string(),
        })
    } else {
        Err(errors)
    }
}

#[derive(Debug)]
pub struct User {
    name: String,
    age: i32,
    email: String,
}

/// Panic for unrecoverable errors
pub fn must_succeed(value: Option<i32>) -> i32 {
    value.expect("This should never be None")
}

/// Option to Result conversion
pub fn find_user(id: u32) -> Option<String> {
    if id > 0 {
        Some(format!("User {}", id))
    } else {
        None
    }
}

pub fn get_user_or_error(id: u32) -> Result<String, String> {
    find_user(id).ok_or_else(|| "User not found".to_string())
}

/// Combining Results
pub fn validate_and_parse(s: &str) -> Result<i32, String> {
    if s.is_empty() {
        return Err("Input is empty".to_string());
    }
    s.parse::<i32>()
        .map_err(|e| format!("Failed to parse: {}", e))
}

/// Early return pattern
pub fn process_input(input: &str) -> Result<i32, String> {
    let trimmed = input.trim();
    if trimmed.is_empty() {
        return Err("Empty input".to_string());
    }

    let num: i32 = trimmed.parse().map_err(|_| "Invalid number".to_string())?;

    if num < 0 {
        return Err("Negative number".to_string());
    }

    Ok(num * 2)
}

/// Collecting Results
pub fn parse_numbers(strings: Vec<&str>) -> Result<Vec<i32>, String> {
    strings
        .iter()
        .map(|s| s.parse::<i32>().map_err(|e| e.to_string()))
        .collect()
}

/// Result with Box<dyn Error>
pub fn flexible_error_handling(input: &str) -> Result<i32, Box<dyn Error>> {
    let num: i32 = input.parse()?;
    if num < 0 {
        return Err(Box::new(CustomError::new(400, "Negative number".to_string())));
    }
    Ok(num)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_divide_success() {
        assert_eq!(divide(10, 2), Ok(5));
    }

    #[test]
    fn test_divide_error() {
        assert!(divide(10, 0).is_err());
    }

    #[test]
    fn test_validate_age() {
        assert!(validate_age(25).is_ok());
        assert!(validate_age(-1).is_err());
        assert!(validate_age(200).is_err());
    }

    #[test]
    fn test_validate_username() {
        assert!(validate_username("john_doe").is_ok());
        assert!(validate_username("ab").is_err());
        assert!(validate_username("").is_err());
    }
}


```

--------------------------------------------------------------------------------
/DOCKER_DEPLOYMENT.md:
--------------------------------------------------------------------------------

```markdown
# Docker Deployment Guide for CodeGraphContext

This guide explains how to build, run, and deploy CodeGraphContext using Docker.

## 📦 Quick Start

### Option 1: Using Docker Compose (Recommended)

1. **Copy the template file:**
   ```bash
   cp docker-compose.template.yml docker-compose.yml
   ```

2. **Start CodeGraphContext with FalkorDB Lite (default):**
   ```bash
   docker-compose up -d codegraphcontext
   ```

3. **Access the container:**
   ```bash
   docker-compose exec codegraphcontext bash
   ```

4. **Inside the container, use cgc commands:**
   ```bash
   cgc index .
   cgc list
   cgc analyze callers my_function
   ```

### Option 2: Using Docker Directly

1. **Build the image:**
   ```bash
   docker build -t codegraphcontext:latest .
   ```

2. **Run the container:**
   ```bash
   docker run -it --rm \
     -v $(pwd):/workspace \
     -v cgc-data:/root/.codegraphcontext \
     codegraphcontext:latest bash
   ```

3. **Use cgc commands inside the container:**
   ```bash
   cgc index .
   cgc help
   ```

## 🗄️ Database Options

### FalkorDB Lite (Default - Included in Container)

FalkorDB Lite is built into the Docker image and requires no additional setup. It's perfect for:
- Development and testing
- Single-user scenarios
- Quick analysis tasks

**No additional configuration needed!** Just start the container and use `cgc` commands.

### Neo4j (Optional - For Production)

If you need a production-grade database, you can use Neo4j:

1. **Start both CodeGraphContext and Neo4j:**
   ```bash
   docker-compose --profile neo4j up -d
   ```

2. **Configure CodeGraphContext to use Neo4j:**
   ```bash
   docker-compose exec codegraphcontext bash
   cgc neo4j setup
   ```
   
   When prompted, use:
   - URI: `bolt://neo4j:7687`
   - Username: `neo4j`
   - Password: `codegraph123`

3. **Access Neo4j Browser:**
   Open http://localhost:7474 in your browser

## 📊 Volume Mounts

The Docker setup uses two types of volumes:

1. **Workspace Volume** (`./:/workspace`):
   - Mounts your current directory into the container
   - Allows CodeGraphContext to index your code
   - Changes are bidirectional

2. **Data Volume** (`cgc-data:/root/.codegraphcontext`):
   - Persists database files and configuration
   - Survives container restarts
   - Keeps your indexed data safe

## 🚀 Common Usage Patterns

### Index a Project

```bash
# Start the container
docker-compose up -d codegraphcontext

# Access the container
docker-compose exec codegraphcontext bash

# Index the current directory
cgc index .

# List indexed repositories
cgc list
```

### Run as MCP Server

```bash
# Start the container with MCP server
docker-compose run --rm -p 8080:8080 codegraphcontext cgc mcp start
```

### Watch for Changes

```bash
docker-compose exec codegraphcontext cgc watch /workspace
```

### One-off Analysis

```bash
# Run a single command without entering the container
docker-compose run --rm codegraphcontext cgc analyze complexity --threshold 10
```

## 🌐 Hosting Online

### Option 1: Cloud VM (AWS, GCP, Azure, DigitalOcean)

1. **Provision a VM** (Ubuntu 22.04 recommended):
   - Minimum: 2 vCPUs, 4GB RAM
   - Recommended: 4 vCPUs, 8GB RAM

2. **Install Docker and Docker Compose:**
   ```bash
   curl -fsSL https://get.docker.com -o get-docker.sh
   sudo sh get-docker.sh
   sudo apt-get install docker-compose-plugin
   ```

3. **Clone your repository:**
   ```bash
   git clone https://github.com/Shashankss1205/CodeGraphContext.git
   cd CodeGraphContext
   ```

4. **Start the services:**
   ```bash
   cp docker-compose.template.yml docker-compose.yml
   docker-compose --profile neo4j up -d
   ```

5. **Configure firewall:**
   ```bash
   # For Neo4j Browser
   sudo ufw allow 7474/tcp
   sudo ufw allow 7687/tcp
   ```

### Option 2: Container Platforms

#### Google Cloud Run

```bash
# Build and push to Google Container Registry
gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/codegraphcontext

# Deploy to Cloud Run
gcloud run deploy codegraphcontext \
  --image gcr.io/YOUR_PROJECT_ID/codegraphcontext \
  --platform managed \
  --region us-central1 \
  --memory 2Gi
```

#### AWS ECS/Fargate

1. **Push to ECR:**
   ```bash
   aws ecr create-repository --repository-name codegraphcontext
   docker tag codegraphcontext:latest YOUR_ACCOUNT.dkr.ecr.REGION.amazonaws.com/codegraphcontext:latest
   docker push YOUR_ACCOUNT.dkr.ecr.REGION.amazonaws.com/codegraphcontext:latest
   ```

2. **Create ECS Task Definition** and deploy using AWS Console or CLI

#### Azure Container Instances

```bash
# Create resource group
az group create --name cgc-rg --location eastus

# Create container instance
az container create \
  --resource-group cgc-rg \
  --name codegraphcontext \
  --image codegraphcontext:latest \
  --cpu 2 \
  --memory 4
```

### Option 3: Kubernetes (For Scale)

1. **Create deployment:**
   ```yaml
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: codegraphcontext
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: codegraphcontext
     template:
       metadata:
         labels:
           app: codegraphcontext
       spec:
         containers:
         - name: codegraphcontext
           image: codegraphcontext:latest
           volumeMounts:
           - name: cgc-data
             mountPath: /root/.codegraphcontext
         volumes:
         - name: cgc-data
           persistentVolumeClaim:
             claimName: cgc-pvc
   ```

2. **Apply configuration:**
   ```bash
   kubectl apply -f deployment.yaml
   ```

### Option 4: Self-Hosted with Docker Swarm

```bash
# Initialize swarm
docker swarm init

# Deploy stack
docker stack deploy -c docker-compose.yml cgc
```

## 🔒 Security Considerations

1. **Change default Neo4j password:**
   Edit `docker-compose.yml` and update `NEO4J_AUTH`

2. **Use environment variables for secrets:**
   ```bash
   docker-compose run --rm \
     -e NEO4J_PASSWORD=your_secure_password \
     codegraphcontext bash
   ```

3. **Enable HTTPS** for production deployments using reverse proxy (nginx, Traefik)

4. **Restrict network access:**
   - Use firewall rules
   - Configure security groups
   - Use VPN for sensitive codebases

## 🔧 Troubleshooting

### Container won't start
```bash
# Check logs
docker-compose logs codegraphcontext

# Rebuild image
docker-compose build --no-cache codegraphcontext
```

### Database connection issues
```bash
# Verify Neo4j is running
docker-compose ps

# Check Neo4j logs
docker-compose logs neo4j

# Test connection
docker-compose exec codegraphcontext cgc query "MATCH (n) RETURN count(n)"
```

### Out of memory
```bash
# Increase Docker memory limit in Docker Desktop settings
# Or for Neo4j, edit docker-compose.yml:
NEO4J_dbms_memory_heap_max__size=4G
```

## 📈 Performance Optimization

1. **Use volumes for large codebases:**
   ```yaml
   volumes:
     - type: volume
       source: cgc-data
       target: /root/.codegraphcontext
   ```

2. **Allocate more resources:**
   ```yaml
   deploy:
     resources:
       limits:
         cpus: '4'
         memory: 8G
   ```

3. **Use SSD storage** for database volumes in production

## 🎯 Production Checklist

- [ ] Change default passwords
- [ ] Configure persistent volumes
- [ ] Set up automated backups
- [ ] Configure monitoring and logging
- [ ] Enable HTTPS/TLS
- [ ] Set resource limits
- [ ] Configure health checks
- [ ] Set up CI/CD pipeline
- [ ] Document deployment process
- [ ] Test disaster recovery

## 📚 Additional Resources

- [Docker Documentation](https://docs.docker.com/)
- [Docker Compose Reference](https://docs.docker.com/compose/)
- [Neo4j Docker Guide](https://neo4j.com/developer/docker/)
- [CodeGraphContext Documentation](https://shashankss1205.github.io/CodeGraphContext/)

## 💡 Tips

- Use `.cgcignore` to exclude files from indexing
- Mount specific directories instead of entire filesystem
- Use Docker networks for service isolation
- Implement log rotation for long-running containers
- Consider using Docker secrets for sensitive data

```

--------------------------------------------------------------------------------
/deploy-production.sh:
--------------------------------------------------------------------------------

```bash
#!/bin/bash

# CodeGraphContext - Production Deployment Script
# This script automates the deployment of CodeGraphContext to a cloud VM

set -e

echo "🚀 CodeGraphContext Production Deployment"
echo "=========================================="
echo ""

# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Function to print colored output
print_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

print_error() {
    echo -e "${RED}❌ $1${NC}"
}

# Check if running as root
if [ "$EUID" -eq 0 ]; then 
    print_warning "Please do not run as root. Run as a regular user with sudo privileges."
    exit 1
fi

# System check
print_info "Checking system requirements..."

# Check OS
if [ -f /etc/os-release ]; then
    . /etc/os-release
    print_success "OS: $NAME $VERSION"
else
    print_error "Cannot determine OS. This script requires Ubuntu/Debian."
    exit 1
fi

# Update system
print_info "Updating system packages..."
sudo apt-get update -qq
print_success "System updated"

# Install Docker if not present
if ! command -v docker &> /dev/null; then
    print_info "Installing Docker..."
    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh
    sudo usermod -aG docker $USER
    rm get-docker.sh
    print_success "Docker installed"
else
    print_success "Docker already installed: $(docker --version)"
fi

# Install Docker Compose if not present
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
    print_info "Installing Docker Compose..."
    sudo apt-get install -y docker-compose-plugin
    print_success "Docker Compose installed"
else
    print_success "Docker Compose already installed"
fi

# Install git if not present
if ! command -v git &> /dev/null; then
    print_info "Installing Git..."
    sudo apt-get install -y git
    print_success "Git installed"
fi

# Install other useful tools
print_info "Installing additional tools..."
sudo apt-get install -y curl wget htop vim ufw -qq
print_success "Additional tools installed"

# Configure firewall
print_info "Configuring firewall..."
sudo ufw --force enable
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 7474/tcp comment 'Neo4j HTTP'
sudo ufw allow 7687/tcp comment 'Neo4j Bolt'
print_success "Firewall configured"

# Ask for deployment directory
read -p "Enter deployment directory (default: ~/codegraphcontext): " DEPLOY_DIR
DEPLOY_DIR=${DEPLOY_DIR:-~/codegraphcontext}

# Create deployment directory
mkdir -p $DEPLOY_DIR
cd $DEPLOY_DIR

# Clone or update repository
if [ -d ".git" ]; then
    print_info "Updating existing repository..."
    git pull
else
    print_info "Cloning repository..."
    git clone https://github.com/Shashankss1205/CodeGraphContext.git .
fi
print_success "Repository ready"

# Copy docker-compose template
if [ ! -f "docker-compose.yml" ]; then
    print_info "Creating docker-compose.yml..."
    cp docker-compose.template.yml docker-compose.yml
    print_success "docker-compose.yml created"
fi

# Ask for database choice
echo ""
print_info "Database Selection"
echo "1) FalkorDB Lite (default, lightweight)"
echo "2) Neo4j (production-grade)"
read -p "Choose database [1-2] (default: 1): " DB_CHOICE
DB_CHOICE=${DB_CHOICE:-1}

# Configure Neo4j password if selected
if [ "$DB_CHOICE" = "2" ]; then
    echo ""
    print_info "Neo4j Configuration"
    read -sp "Enter Neo4j password (default: codegraph123): " NEO4J_PASSWORD
    echo ""
    NEO4J_PASSWORD=${NEO4J_PASSWORD:-codegraph123}
    
    # Update docker-compose.yml with new password
    sed -i "s/NEO4J_AUTH=neo4j\/codegraph123/NEO4J_AUTH=neo4j\/$NEO4J_PASSWORD/" docker-compose.yml
    print_success "Neo4j password configured"
fi

# Build and start services
echo ""
print_info "Building Docker images..."
docker-compose build --no-cache

if [ "$DB_CHOICE" = "2" ]; then
    print_info "Starting services with Neo4j..."
    docker-compose --profile neo4j up -d
else
    print_info "Starting services with FalkorDB Lite..."
    docker-compose up -d codegraphcontext
fi

# Wait for services to start
print_info "Waiting for services to start..."
sleep 10

# Check service status
if docker-compose ps | grep -q "Up"; then
    print_success "Services started successfully!"
else
    print_error "Services failed to start. Check logs with: docker-compose logs"
    exit 1
fi

# Display service information
echo ""
echo "=========================================="
print_success "Deployment Complete!"
echo "=========================================="
echo ""
print_info "Service Information:"
echo "  - CodeGraphContext: Running"
if [ "$DB_CHOICE" = "2" ]; then
    echo "  - Neo4j Browser: http://$(curl -s ifconfig.me):7474"
    echo "  - Neo4j Bolt: bolt://$(curl -s ifconfig.me):7687"
    echo "  - Neo4j Username: neo4j"
    echo "  - Neo4j Password: $NEO4J_PASSWORD"
fi
echo ""
print_info "Useful Commands:"
echo "  - Access container: docker-compose exec codegraphcontext bash"
echo "  - View logs: docker-compose logs -f"
echo "  - Stop services: docker-compose down"
echo "  - Restart services: docker-compose restart"
echo ""
print_info "Next Steps:"
echo "  1. Access the container: docker-compose exec codegraphcontext bash"
echo "  2. Index your code: cgc index /workspace"
echo "  3. Query the graph: cgc list"
echo ""

# Create systemd service for auto-start
read -p "Create systemd service for auto-start on boot? [y/N]: " CREATE_SERVICE
if [[ $CREATE_SERVICE =~ ^[Yy]$ ]]; then
    print_info "Creating systemd service..."
    
    sudo tee /etc/systemd/system/codegraphcontext.service > /dev/null <<EOF
[Unit]
Description=CodeGraphContext Docker Compose
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=$DEPLOY_DIR
ExecStart=/usr/bin/docker-compose up -d
ExecStop=/usr/bin/docker-compose down
User=$USER

[Install]
WantedBy=multi-user.target
EOF

    sudo systemctl daemon-reload
    sudo systemctl enable codegraphcontext.service
    print_success "Systemd service created and enabled"
fi

# Setup automatic backups
read -p "Setup automatic daily backups? [y/N]: " SETUP_BACKUPS
if [[ $SETUP_BACKUPS =~ ^[Yy]$ ]]; then
    print_info "Setting up automatic backups..."
    
    # Create backup script
    cat > $DEPLOY_DIR/backup.sh <<'EOF'
#!/bin/bash
BACKUP_DIR=~/codegraphcontext-backups
mkdir -p $BACKUP_DIR
DATE=$(date +%Y%m%d-%H%M%S)
docker run --rm -v cgc-data:/data -v $BACKUP_DIR:/backup \
    alpine tar czf /backup/cgc-backup-$DATE.tar.gz /data
# Keep only last 7 backups
ls -t $BACKUP_DIR/cgc-backup-*.tar.gz | tail -n +8 | xargs -r rm
echo "Backup completed: cgc-backup-$DATE.tar.gz"
EOF
    
    chmod +x $DEPLOY_DIR/backup.sh
    
    # Add to crontab
    (crontab -l 2>/dev/null; echo "0 2 * * * $DEPLOY_DIR/backup.sh >> $DEPLOY_DIR/backup.log 2>&1") | crontab -
    
    print_success "Daily backups configured (runs at 2 AM)"
    print_info "Backup location: ~/codegraphcontext-backups"
fi

# Security recommendations
echo ""
print_warning "Security Recommendations:"
echo "  1. Change Neo4j password (if using Neo4j)"
echo "  2. Configure SSL/TLS with a reverse proxy (nginx/Traefik)"
echo "  3. Restrict firewall rules to specific IPs if possible"
echo "  4. Enable automatic security updates"
echo "  5. Regularly backup your data"
echo ""

# Monitoring setup
read -p "Install monitoring tools (htop, ctop)? [y/N]: " INSTALL_MONITORING
if [[ $INSTALL_MONITORING =~ ^[Yy]$ ]]; then
    print_info "Installing monitoring tools..."
    sudo apt-get install -y htop
    
    # Install ctop (container monitoring)
    sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.7/ctop-0.7.7-linux-amd64 \
        -O /usr/local/bin/ctop
    sudo chmod +x /usr/local/bin/ctop
    
    print_success "Monitoring tools installed"
    print_info "Use 'htop' for system monitoring and 'ctop' for container monitoring"
fi

echo ""
print_success "🎉 Production deployment complete!"
print_info "For more information, see DOCKER_DEPLOYMENT.md"
echo ""

# Ask if user wants to enter container
read -p "Enter the container now? [y/N]: " ENTER_CONTAINER
if [[ $ENTER_CONTAINER =~ ^[Yy]$ ]]; then
    docker-compose exec codegraphcontext bash
fi

```

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

```rust
// generics.rs - Demonstrates Rust generics and type parameters
use std::cmp::PartialOrd;
use std::fmt::{Debug, Display};
use std::ops::Add;

/// Generic function with single type parameter
pub fn first<T>(list: &[T]) -> Option<&T> {
    list.first()
}

/// Generic function with trait bound
pub fn largest<T: PartialOrd>(list: &[T]) -> Option<&T> {
    if list.is_empty() {
        return None;
    }

    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    Some(largest)
}

/// Generic function with multiple type parameters
pub fn pair<T, U>(first: T, second: U) -> (T, U) {
    (first, second)
}

/// Generic function with multiple trait bounds
pub fn print_pair<T: Display, U: Display>(first: T, second: U) {
    println!("First: {}, Second: {}", first, second);
}

/// Generic function with where clause
pub fn complex_function<T, U>(t: T, u: U) -> String
where
    T: Display + Clone,
    U: Display + Debug,
{
    format!("T: {}, U: {:?}", t, u)
}

// Generic structs

/// Simple generic struct
#[derive(Debug, Clone)]
pub struct Point<T> {
    pub x: T,
    pub y: T,
}

impl<T> Point<T> {
    pub fn new(x: T, y: T) -> Self {
        Self { x, y }
    }

    pub fn x(&self) -> &T {
        &self.x
    }

    pub fn y(&self) -> &T {
        &self.y
    }
}

impl<T: Add<Output = T> + Copy> Point<T> {
    pub fn add(&self, other: &Point<T>) -> Point<T> {
        Point {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

/// Generic struct with multiple type parameters
#[derive(Debug)]
pub struct Pair<T, U> {
    pub first: T,
    pub second: U,
}

impl<T, U> Pair<T, U> {
    pub fn new(first: T, second: U) -> Self {
        Self { first, second }
    }

    pub fn swap(self) -> Pair<U, T> {
        Pair {
            first: self.second,
            second: self.first,
        }
    }
}

impl<T: Clone, U: Clone> Pair<T, U> {
    pub fn clone_first(&self) -> T {
        self.first.clone()
    }

    pub fn clone_second(&self) -> U {
        self.second.clone()
    }
}

// Generic collections

/// Generic stack
#[derive(Debug)]
pub struct Stack<T> {
    items: Vec<T>,
}

impl<T> Stack<T> {
    pub fn new() -> Self {
        Self { items: Vec::new() }
    }

    pub fn push(&mut self, item: T) {
        self.items.push(item);
    }

    pub fn pop(&mut self) -> Option<T> {
        self.items.pop()
    }

    pub fn peek(&self) -> Option<&T> {
        self.items.last()
    }

    pub fn is_empty(&self) -> bool {
        self.items.is_empty()
    }

    pub fn len(&self) -> usize {
        self.items.len()
    }
}

/// Generic queue
#[derive(Debug)]
pub struct Queue<T> {
    items: Vec<T>,
}

impl<T> Queue<T> {
    pub fn new() -> Self {
        Self { items: Vec::new() }
    }

    pub fn enqueue(&mut self, item: T) {
        self.items.push(item);
    }

    pub fn dequeue(&mut self) -> Option<T> {
        if self.items.is_empty() {
            None
        } else {
            Some(self.items.remove(0))
        }
    }

    pub fn peek(&self) -> Option<&T> {
        self.items.first()
    }

    pub fn len(&self) -> usize {
        self.items.len()
    }
}

/// Generic linked list node
#[derive(Debug)]
pub struct Node<T> {
    pub value: T,
    pub next: Option<Box<Node<T>>>,
}

impl<T> Node<T> {
    pub fn new(value: T) -> Self {
        Self { value, next: None }
    }
}

/// Generic linked list
#[derive(Debug)]
pub struct LinkedList<T> {
    head: Option<Box<Node<T>>>,
    size: usize,
}

impl<T> LinkedList<T> {
    pub fn new() -> Self {
        Self {
            head: None,
            size: 0,
        }
    }

    pub fn push(&mut self, value: T) {
        let new_node = Box::new(Node {
            value,
            next: self.head.take(),
        });
        self.head = Some(new_node);
        self.size += 1;
    }

    pub fn pop(&mut self) -> Option<T> {
        self.head.take().map(|node| {
            self.head = node.next;
            self.size -= 1;
            node.value
        })
    }

    pub fn len(&self) -> usize {
        self.size
    }

    pub fn is_empty(&self) -> bool {
        self.size == 0
    }
}

// Generic enums

/// Generic Option-like enum
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Maybe<T> {
    Just(T),
    Nothing,
}

impl<T> Maybe<T> {
    pub fn is_just(&self) -> bool {
        matches!(self, Maybe::Just(_))
    }

    pub fn unwrap(self) -> T {
        match self {
            Maybe::Just(value) => value,
            Maybe::Nothing => panic!("Called unwrap on Nothing"),
        }
    }

    pub fn unwrap_or(self, default: T) -> T {
        match self {
            Maybe::Just(value) => value,
            Maybe::Nothing => default,
        }
    }

    pub fn map<U, F>(self, f: F) -> Maybe<U>
    where
        F: FnOnce(T) -> U,
    {
        match self {
            Maybe::Just(value) => Maybe::Just(f(value)),
            Maybe::Nothing => Maybe::Nothing,
        }
    }
}

/// Generic Result-like enum
#[derive(Debug, Clone, PartialEq)]
pub enum Outcome<T, E> {
    Success(T),
    Failure(E),
}

impl<T, E> Outcome<T, E> {
    pub fn is_success(&self) -> bool {
        matches!(self, Outcome::Success(_))
    }

    pub fn map<U, F>(self, f: F) -> Outcome<U, E>
    where
        F: FnOnce(T) -> U,
    {
        match self {
            Outcome::Success(value) => Outcome::Success(f(value)),
            Outcome::Failure(err) => Outcome::Failure(err),
        }
    }

    pub fn and_then<U, F>(self, f: F) -> Outcome<U, E>
    where
        F: FnOnce(T) -> Outcome<U, E>,
    {
        match self {
            Outcome::Success(value) => f(value),
            Outcome::Failure(err) => Outcome::Failure(err),
        }
    }
}

// Generic trait implementations

/// Generic wrapper type
#[derive(Debug, Clone)]
pub struct Wrapper<T> {
    value: T,
}

impl<T> Wrapper<T> {
    pub fn new(value: T) -> Self {
        Self { value }
    }

    pub fn into_inner(self) -> T {
        self.value
    }

    pub fn get(&self) -> &T {
        &self.value
    }

    pub fn get_mut(&mut self) -> &mut T {
        &mut self.value
    }
}

impl<T: Display> Display for Wrapper<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Wrapper({})", self.value)
    }
}

// Generic functions with closures

/// Map function for vectors
pub fn map<T, U, F>(vec: Vec<T>, f: F) -> Vec<U>
where
    F: Fn(T) -> U,
{
    vec.into_iter().map(f).collect()
}

/// Filter function for vectors
pub fn filter<T, F>(vec: Vec<T>, predicate: F) -> Vec<T>
where
    F: Fn(&T) -> bool,
{
    vec.into_iter().filter(|x| predicate(x)).collect()
}

/// Reduce/fold function
pub fn reduce<T, U, F>(vec: Vec<T>, initial: U, f: F) -> U
where
    F: Fn(U, T) -> U,
{
    vec.into_iter().fold(initial, f)
}

// Const generics (Rust 1.51+)

/// Array wrapper with const generic size
#[derive(Debug)]
pub struct FixedArray<T, const N: usize> {
    data: [T; N],
}

impl<T: Default + Copy, const N: usize> FixedArray<T, N> {
    pub fn new() -> Self {
        Self {
            data: [T::default(); N],
        }
    }

    pub fn get(&self, index: usize) -> Option<&T> {
        self.data.get(index)
    }

    pub fn set(&mut self, index: usize, value: T) -> Result<(), String> {
        if index < N {
            self.data[index] = value;
            Ok(())
        } else {
            Err("Index out of bounds".to_string())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_largest() {
        let numbers = vec![34, 50, 25, 100, 65];
        assert_eq!(largest(&numbers), Some(&100));
    }

    #[test]
    fn test_point_add() {
        let p1 = Point::new(1, 2);
        let p2 = Point::new(3, 4);
        let p3 = p1.add(&p2);
        assert_eq!(p3.x, 4);
        assert_eq!(p3.y, 6);
    }

    #[test]
    fn test_stack() {
        let mut stack = Stack::new();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        assert_eq!(stack.pop(), Some(3));
        assert_eq!(stack.len(), 2);
    }

    #[test]
    fn test_maybe() {
        let just = Maybe::Just(42);
        let nothing: Maybe<i32> = Maybe::Nothing;
        
        assert!(just.is_just());
        assert!(!nothing.is_just());
        assert_eq!(just.unwrap(), 42);
    }
}


```

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

```markdown
# Language Contributors

This file is auto-generated. Do not edit manually.

## C Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | [Shashank Shekhar Singh](https://github.com/Shashankss1205) | 4 | 298 | 289 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/c.py?author=Shashankss1205) |
| 2 | PrakharGoyal28 | 1 | 295 | 0 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 3 | Harsh | 1 | 260 | 256 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 4 | TanmayRanaware | 1 | 251 | 13 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 5 | Shashankss1205 | 1 | 2 | 5 | [c.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |


## Cpp Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | Paras | 7 | 376 | 69 | [cpp.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 2 | Shashankss1205 | 6 | 206 | 470 | [cpp.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 3 | Shashank Shekhar Singh | 3 | 121 | 43 | [cpp.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 4 | [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) |


## Go Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | Shashank Shekhar Singh | 3 | 49 | 31 | [go.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 2 | Shashankss1205 | 2 | 19 | 14 | [go.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 3 | Harshdhall01 | 1 | 446 | 0 | [go.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |


## Java Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | [Shashank Shekhar Singh](https://github.com/Shashankss1205) | 3 | 208 | 65 | [java.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/java.py?author=Shashankss1205) |
| 2 | Aashish Jha | 1 | 304 | 0 | [java.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 3 | Sreeja Khan | 1 | 42 | 1 | [java.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 4 | Shashankss1205 | 1 | 8 | 10 | [java.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |


## Javascript Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | [Shashank Shekhar Singh](https://github.com/Shashankss1205) | 6 | 352 | 360 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/javascript.py?author=Shashankss1205) |
| 2 | Shashankss1205 | 4 | 427 | 114 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 3 | Akshit | 3 | 55 | 5 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 4 | PrakharGoyal28 | 1 | 195 | 23 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 5 | Priyal Duggal | 1 | 175 | 113 | [javascript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |


## Python Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | Shashank Shekhar Singh | 6 | 140 | 24 | [python.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 2 | Shashankss1205 | 4 | 488 | 34 | [python.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |


## Ruby Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | Shashank Shekhar Singh | 3 | 74 | 34 | [ruby.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 2 | TanmayRanaware | 1 | 426 | 0 | [ruby.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 3 | Peter Jusko | 1 | 71 | 3 | [ruby.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 4 | Shashankss1205 | 1 | 2 | 5 | [ruby.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |


## Rust Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | Shashankss1205 | 3 | 148 | 5 | [rust.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 2 | Shashank Shekhar Singh | 3 | 129 | 74 | [rust.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 3 | Siddharth Baleja | 1 | 122 | 53 | [rust.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 4 | Syed Sohail | 1 | 28 | 8 | [rust.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |


## Typescript Contributors

| Rank | Contributor | Commits | Lines Added | Lines Deleted | Link to Contributions |
|---|---|---|---|---|---|
| 1 | [Shashank Shekhar Singh](https://github.com/Shashankss1205) | 4 | 107 | 41 | [typescript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/typescript.py?author=Shashankss1205) |
| 2 | Shashankss1205 | 2 | 71 | 35 | [typescript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |
| 3 | [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) |
| 4 | ANUKOOL | 1 | 54 | 0 | [typescript.py](https://github.com/Shashankss1205/CodeGraphContext/commits/main/src/codegraphcontext/tools/languages/[email protected]) |



```

--------------------------------------------------------------------------------
/tests/test_tree_sitter_manager.py:
--------------------------------------------------------------------------------

```python
"""
Tests for the tree-sitter manager module.

This test suite verifies:
1. Language caching works correctly
2. Parser creation is thread-safe
3. Language aliasing works
4. Error handling is appropriate
"""

import pytest
import threading
from pathlib import Path

from codegraphcontext.utils.tree_sitter_manager import (
    TreeSitterManager,
    get_tree_sitter_manager,
    get_language_safe,
    create_parser,
    LANGUAGE_ALIASES,
)


class TestTreeSitterManager:
    """Test suite for TreeSitterManager class."""
    
    def test_singleton_pattern(self):
        """Test that get_tree_sitter_manager returns the same instance."""
        manager1 = get_tree_sitter_manager()
        manager2 = get_tree_sitter_manager()
        assert manager1 is manager2
    
    def test_get_language_safe_caching(self):
        """Test that languages are cached properly."""
        manager = get_tree_sitter_manager()
        
        # First call loads the language
        lang1 = manager.get_language_safe("python")
        
        # Second call should return cached language
        lang2 = manager.get_language_safe("python")
        
        assert lang1 is lang2
    
    def test_language_aliases(self):
        """Test that language aliases work correctly."""
        manager = get_tree_sitter_manager()
        
        # Test Python aliases
        lang_python = manager.get_language_safe("python")
        lang_py = manager.get_language_safe("py")
        assert lang_python is lang_py
        
        # Test C# aliases
        lang_csharp1 = manager.get_language_safe("c_sharp")
        lang_csharp2 = manager.get_language_safe("c#")
        lang_csharp3 = manager.get_language_safe("csharp")
        lang_csharp4 = manager.get_language_safe("cs")
        assert lang_csharp1 is lang_csharp2
        assert lang_csharp2 is lang_csharp3
        assert lang_csharp3 is lang_csharp4
        
        # Test JavaScript aliases
        lang_js1 = manager.get_language_safe("javascript")
        lang_js2 = manager.get_language_safe("js")
        assert lang_js1 is lang_js2
    
    def test_invalid_language_raises_error(self):
        """Test that invalid language names raise ValueError."""
        manager = get_tree_sitter_manager()
        
        with pytest.raises(ValueError, match="Unknown language"):
            manager.get_language_safe("invalid_language_xyz")
    
    def test_create_parser_returns_new_instance(self):
        """Test that create_parser returns a new parser each time."""
        manager = get_tree_sitter_manager()
        
        parser1 = manager.create_parser("python")
        parser2 = manager.create_parser("python")
        
        # Parsers should be different instances
        assert parser1 is not parser2
        
        # But they should use the same language
        assert parser1.language is parser2.language
    
    def test_thread_safety(self):
        """Test that language loading is thread-safe."""
        manager = get_tree_sitter_manager()
        results = {}
        
        def load_language(lang_name, thread_id):
            """Load a language and store the result."""
            results[thread_id] = manager.get_language_safe(lang_name)
        
        # Create multiple threads that load the same language
        threads = []
        for i in range(10):
            thread = threading.Thread(target=load_language, args=("python", i))
            threads.append(thread)
            thread.start()
        
        # Wait for all threads to complete
        for thread in threads:
            thread.join()
        
        # All threads should have gotten the same language instance
        first_lang = results[0]
        for lang in results.values():
            assert lang is first_lang
    
    def test_is_language_available(self):
        """Test the is_language_available method."""
        manager = get_tree_sitter_manager()
        
        # Valid languages should return True
        assert manager.is_language_available("python") is True
        assert manager.is_language_available("javascript") is True
        assert manager.is_language_available("py") is True  # alias
        
        # Invalid languages should return False
        assert manager.is_language_available("invalid_xyz") is False
    
    def test_get_supported_languages(self):
        """Test that get_supported_languages returns expected languages."""
        manager = get_tree_sitter_manager()
        
        supported = manager.get_supported_languages()
        
        # Should be a sorted list
        assert isinstance(supported, list)
        assert supported == sorted(supported)
        
        # Should contain expected languages
        expected_languages = ["python", "javascript", "typescript", "c", "cpp", "java", "ruby", "rust", "go", "c_sharp"]
        for lang in expected_languages:
            assert lang in supported
    
    def test_convenience_functions(self):
        """Test the module-level convenience functions."""
        # Test get_language_safe
        lang1 = get_language_safe("python")
        lang2 = get_language_safe("python")
        assert lang1 is lang2
        
        # Test create_parser
        parser1 = create_parser("python")
        parser2 = create_parser("python")
        assert parser1 is not parser2
        assert parser1.language is parser2.language


class TestLanguageAliases:
    """Test suite for language alias mappings."""
    
    def test_all_aliases_map_to_valid_languages(self):
        """Test that all aliases in LANGUAGE_ALIASES map to valid languages."""
        manager = get_tree_sitter_manager()
        
        # Get unique target languages
        unique_targets = set(LANGUAGE_ALIASES.values())
        
        # Each target should be loadable
        for target in unique_targets:
            try:
                manager.get_language_safe(target)
            except Exception as e:
                pytest.fail(f"Language '{target}' from LANGUAGE_ALIASES is not loadable: {e}")
    
    def test_canonical_names_map_to_themselves(self):
        """Test that canonical names map to themselves in LANGUAGE_ALIASES."""
        canonical_names = ["python", "javascript", "typescript", "c", "cpp", "java", "ruby", "rust", "go", "c_sharp"]
        
        for name in canonical_names:
            assert LANGUAGE_ALIASES.get(name) == name, f"Canonical name '{name}' should map to itself"


class TestParserCreation:
    """Test suite for parser creation and usage."""
    
    def test_parser_can_parse_code(self):
        """Test that created parsers can actually parse code."""
        manager = get_tree_sitter_manager()
        parser = manager.create_parser("python")
        
        # Simple Python code
        code = b"def hello():\n    print('world')\n"
        tree = parser.parse(code)
        
        assert tree is not None
        assert tree.root_node is not None
        assert tree.root_node.type == "module"
    
    def test_multiple_parsers_independent(self):
        """Test that multiple parsers can be used independently."""
        manager = get_tree_sitter_manager()
        
        parser1 = manager.create_parser("python")
        parser2 = manager.create_parser("python")
        
        code1 = b"x = 1"
        code2 = b"y = 2"
        
        tree1 = parser1.parse(code1)
        tree2 = parser2.parse(code2)
        
        # Trees should be different
        assert tree1 is not tree2
        assert tree1.root_node.text != tree2.root_node.text


class TestErrorHandling:
    """Test suite for error handling."""
    
    def test_clear_error_for_unknown_language(self):
        """Test that unknown languages produce clear error messages."""
        manager = get_tree_sitter_manager()
        
        with pytest.raises(ValueError) as exc_info:
            manager.get_language_safe("nonexistent_language")
        
        error_message = str(exc_info.value)
        assert "Unknown language" in error_message
        assert "nonexistent_language" in error_message
    
    def test_case_insensitive_language_names(self):
        """Test that language names are case-insensitive."""
        manager = get_tree_sitter_manager()
        
        # These should all work
        lang1 = manager.get_language_safe("python")
        lang2 = manager.get_language_safe("Python")
        lang3 = manager.get_language_safe("PYTHON")
        
        assert lang1 is lang2
        assert lang2 is lang3


if __name__ == "__main__":
    pytest.main([__file__, "-v"])

```

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

```python
"""
Tests for database configuration validation and error handling.
"""

import pytest
import sys
from pathlib import Path

# Add src to path for imports (needed for direct test execution)
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

from codegraphcontext.core.database import DatabaseManager


class TestConfigValidation:
    """Tests for validate_config method"""
    
    def test_validate_config_valid_neo4j_uri(self):
        """Test validation passes for valid neo4j:// URI"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7687", "neo4j", "password123"
        )
        assert is_valid is True
        assert error is None
    
    def test_validate_config_valid_bolt_uri(self):
        """Test validation passes for valid bolt:// URI"""
        is_valid, error = DatabaseManager.validate_config(
            "bolt://localhost:7687", "neo4j", "password123"
        )
        assert is_valid is True
        assert error is None
    
    def test_validate_config_valid_secure_uri(self):
        """Test validation passes for valid neo4j+s:// URI"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j+s://localhost:7687", "neo4j", "password123"
        )
        assert is_valid is True
        assert error is None
    
    def test_validate_config_invalid_uri_no_protocol(self):
        """Test validation fails for URI without protocol"""
        is_valid, error = DatabaseManager.validate_config(
            "localhost:7687", "neo4j", "password123"
        )
        assert is_valid is False
        assert error is not None
        assert "Invalid Neo4j URI format" in error
        assert "neo4j://" in error or "bolt://" in error
    
    def test_validate_config_invalid_uri_no_port(self):
        """Test validation fails for URI without port"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost", "neo4j", "password123"
        )
        assert is_valid is False
        assert error is not None
        assert "Invalid Neo4j URI format" in error
    
    def test_validate_config_invalid_uri_wrong_protocol(self):
        """Test validation fails for invalid protocol"""
        is_valid, error = DatabaseManager.validate_config(
            "http://localhost:7687", "neo4j", "password123"
        )
        assert is_valid is False
        assert error is not None
        assert "Invalid Neo4j URI format" in error
    
    def test_validate_config_empty_username(self):
        """Test validation fails for empty username"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7687", "", "password123"
        )
        assert is_valid is False
        assert error is not None
        assert "Username cannot be empty" in error
        assert "neo4j" in error  # Should mention default username
    
    def test_validate_config_whitespace_username(self):
        """Test validation fails for whitespace-only username"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7687", "   ", "password123"
        )
        assert is_valid is False
        assert error is not None
        assert "Username cannot be empty" in error
    
    def test_validate_config_none_username(self):
        """Test validation fails for None username"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7687", None, "password123"
        )
        assert is_valid is False
        assert error is not None
        assert "Username cannot be empty" in error
    
    def test_validate_config_empty_password(self):
        """Test validation fails for empty password"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7687", "neo4j", ""
        )
        assert is_valid is False
        assert error is not None
        assert "Password cannot be empty" in error
    
    def test_validate_config_whitespace_password(self):
        """Test validation fails for whitespace-only password"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7687", "neo4j", "   "
        )
        assert is_valid is False
        assert error is not None
        assert "Password cannot be empty" in error
    
    def test_validate_config_none_password(self):
        """Test validation fails for None password"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7687", "neo4j", None
        )
        assert is_valid is False
        assert error is not None
        assert "Password cannot be empty" in error
    
    def test_validate_config_valid_with_special_chars_in_password(self):
        """Test validation passes for password with special characters"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7687", "neo4j", "p@ssw0rd!#$%"
        )
        assert is_valid is True
        assert error is None
    
    def test_validate_config_valid_custom_port(self):
        """Test validation passes for custom port"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://localhost:7688", "neo4j", "password123"
        )
        assert is_valid is True
        assert error is None
    
    def test_validate_config_valid_remote_host(self):
        """Test validation passes for remote host"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://example.com:7687", "neo4j", "password123"
        )
        assert is_valid is True
        assert error is None
    
    def test_validate_config_valid_ip_address(self):
        """Test validation passes for IP address"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j://192.168.1.100:7687", "neo4j", "password123"
        )
        assert is_valid is True
        assert error is None


class TestConnectionTest:
    """Tests for test_connection method"""
    
    def test_connection_invalid_host_unreachable(self):
        """Test connection fails gracefully for unreachable host"""
        is_connected, error = DatabaseManager.test_connection(
            "neo4j://unreachable-host-12345.invalid:7687", "neo4j", "password123"
        )
        assert is_connected is False
        assert error is not None
        assert "Cannot reach Neo4j server" in error or "Connection failed" in error
    
    def test_connection_invalid_port(self):
        """Test connection fails for invalid port"""
        is_connected, error = DatabaseManager.test_connection(
            "neo4j://localhost:9999", "neo4j", "password123"
        )
        assert is_connected is False
        assert error is not None
        # Should mention connectivity or unavailability
        assert any(keyword in error for keyword in ["reach", "unavailable", "failed", "Connection"])
    
    def test_connection_provides_troubleshooting_tips(self):
        """Test that error messages include troubleshooting tips"""
        is_connected, error = DatabaseManager.test_connection(
            "neo4j://localhost:9999", "neo4j", "password123"
        )
        assert is_connected is False
        assert error is not None
        # Should provide helpful troubleshooting
        assert any(keyword in error.lower() for keyword in ["troubleshoot", "check", "docker", "try"])


class TestValidationIntegration:
    """Integration tests for validation in real-world scenarios"""
    
    def test_validate_aura_style_uri(self):
        """Test validation works for Neo4j Aura-style URIs"""
        is_valid, error = DatabaseManager.validate_config(
            "neo4j+s://abc123.databases.neo4j.io:7687", "neo4j", "password123"
        )
        assert is_valid is True
        assert error is None
    
    def test_validate_bolt_ssc_uri(self):
        """Test validation works for bolt+ssc:// URIs"""
        is_valid, error = DatabaseManager.validate_config(
            "bolt+ssc://localhost:7687", "neo4j", "password123"
        )
        assert is_valid is True
        assert error is None
    
    def test_multiple_validation_errors_at_once(self):
        """Test validation catches the first error in priority order"""
        # URI is invalid, username empty, password empty - should catch URI first
        is_valid, error = DatabaseManager.validate_config(
            "invalid-uri", "", ""
        )
        assert is_valid is False
        assert "Invalid Neo4j URI format" in error


if __name__ == "__main__":
    pytest.main([__file__, "-v"])

```

--------------------------------------------------------------------------------
/src/codegraphcontext/utils/tree_sitter_manager.py:
--------------------------------------------------------------------------------

```python
"""
Tree-sitter language and parser management module.

This module provides thread-safe, cached access to tree-sitter languages and parsers.
It handles the migration from tree-sitter-languages to tree-sitter-language-pack.

Key design principles:
1. Cache languages, not parsers (parsers are NOT thread-safe)
2. Handle language name aliasing
3. Provide clear error messages for missing languages
4. Support optional tree-sitter dependency
"""

from typing import Dict, Optional
import threading

from tree_sitter import Language, Parser
from tree_sitter_language_pack import get_language


# Language name aliases for compatibility
LANGUAGE_ALIASES = {
    # Common aliases
    "py": "python",
    "js": "javascript",
    "ts": "typescript",
    "c++": "cpp",
    "c#": "c_sharp",
    "csharp": "c_sharp",
    "cs": "c_sharp",
    "rb": "ruby",
    "rs": "rust",
    "go": "go",
    "php": "php",
    ".php": "php",
    
    # Canonical names (map to themselves for consistency)
    "python": "python",
    "javascript": "javascript",
    "typescript": "typescript",
    "cpp": "cpp",
    "c_sharp": "c_sharp",
    "c": "c",
    "java": "java",
    "ruby": "ruby",
    "rust": "rust",
    "kt": "kotlin",
    "kotlin": "kotlin",
    "scala": "scala",
    ".scala": "scala",
    "swift": "swift",
    ".swift": "swift",
}


class TreeSitterManager:
    """
    Manages tree-sitter language loading and parser creation.
    
    This class provides:
    - Thread-safe language caching
    - Language name aliasing
    - Parser lifecycle management
    - Clear error handling
    """
    
    def __init__(self):
        """Initialize the tree-sitter manager."""
        self._language_cache: Dict[str, Language] = {}
        self._cache_lock = threading.Lock()
    
    def _normalize_language_name(self, lang: str) -> str:
        """
        Normalize a language name to its canonical form.
        
        Args:
            lang: Language name (e.g., "py", "python", "c++")
            
        Returns:
            Canonical language name (e.g., "python", "cpp")
            
        Raises:
            ValueError: If language name is not recognized
        """
        normalized = LANGUAGE_ALIASES.get(lang.lower())
        if normalized is None:
            raise ValueError(
                f"Unknown language: {lang}. "
                f"Supported languages: {', '.join(sorted(set(LANGUAGE_ALIASES.values())))}"
            )
        return normalized
    
    def get_language_safe(self, lang: str) -> Language:
        """
        Get a cached Language object for the specified language.
        
        This method is thread-safe and caches languages to avoid repeated loading.
        
        Args:
            lang: Language name (supports aliases like "py", "c++", etc.)
            
        Returns:
            Tree-sitter Language object
            
        Raises:
            ValueError: If language is not supported
            Exception: If language loading fails
        """
        # Normalize the language name
        canonical_name = self._normalize_language_name(lang)
        
        # Check cache first (fast path, no lock needed for reads)
        if canonical_name in self._language_cache:
            return self._language_cache[canonical_name]
        
        # Load language with lock (slow path)
        with self._cache_lock:
            # Double-check after acquiring lock
            if canonical_name in self._language_cache:
                return self._language_cache[canonical_name]
            
            try:
                # Special handling for C# which is available as tree_sitter_c_sharp
                if canonical_name == "c_sharp":
                    import tree_sitter_c_sharp
                    # tree_sitter_c_sharp.language() returns a PyCapsule, wrap it in Language
                    capsule = tree_sitter_c_sharp.language()
                    language = Language(capsule)
                else:
                    # Load the language from tree-sitter-language-pack
                    language = get_language(canonical_name)
                
                self._language_cache[canonical_name] = language
                return language
            except (KeyError, ModuleNotFoundError):
                raise ValueError(
                    f"Language '{canonical_name}' is not available in tree-sitter-language-pack. "
                    f"This may be due to a missing or experimental grammar."
                )
            except Exception as e:
                raise Exception(
                    f"Failed to load language '{canonical_name}': {e}"
                )
    
    def create_parser(self, lang: str) -> Parser:
        """
        Create a new Parser instance for the specified language.
        
        IMPORTANT: Parsers are NOT thread-safe and should not be shared across threads.
        Each thread should create its own parser using this method.
        
        Args:
            lang: Language name (supports aliases)
            
        Returns:
            A new Parser instance configured for the language
            
        Raises:
            ValueError: If language is not supported
            Exception: If parser creation fails
        """
        language = self.get_language_safe(lang)
        # In tree-sitter 0.25+, Parser takes language in constructor
        parser = Parser(language)
        return parser
    
    def is_language_available(self, lang: str) -> bool:
        """
        Check if a language is available without raising exceptions.
        
        Args:
            lang: Language name
            
        Returns:
            True if language is available, False otherwise
        """
        try:
            self.get_language_safe(lang)
            return True
        except (ValueError, Exception):
            return False
    
    def get_supported_languages(self) -> list[str]:
        """
        Get a list of all supported language names.
        
        Returns:
            Sorted list of canonical language names
        """
        return sorted(set(LANGUAGE_ALIASES.values()))


# Global singleton instance
_manager_instance: Optional[TreeSitterManager] = None
_instance_lock = threading.Lock()


def get_tree_sitter_manager() -> TreeSitterManager:
    """
    Get the global TreeSitterManager instance (singleton pattern).
    
    Returns:
        The global TreeSitterManager instance
    """
    global _manager_instance
    
    if _manager_instance is not None:
        return _manager_instance
    
    with _instance_lock:
        if _manager_instance is None:
            _manager_instance = TreeSitterManager()
        return _manager_instance


# Convenience functions for backward compatibility
def get_language_safe(lang: str) -> Language:
    """Get a cached Language object. Thread-safe."""
    return get_tree_sitter_manager().get_language_safe(lang)


def create_parser(lang: str) -> Parser:
    """Create a new Parser for the language. Each call returns a new parser."""
    return get_tree_sitter_manager().create_parser(lang)


def execute_query(language: Language, query_string: str, node):
    """
    Execute a tree-sitter query and return captures in backward-compatible format.
    
    This function provides compatibility with the old tree-sitter 0.20.x API where
    you could call query.captures(node). The new 0.25+ API uses QueryCursor.
    
    Args:
        language: Tree-sitter Language object
        query_string: Query string in tree-sitter query syntax
        node: Tree-sitter Node to query
        
    Returns:
        List of (node, capture_name) tuples, compatible with old API
        
    Example:
        >>> from tree_sitter_language_pack import get_language
        >>> lang = get_language('python')
        >>> parser = Parser(lang)
        >>> tree = parser.parse(b'def hello(): pass')
        >>> captures = execute_query(lang, '(function_definition) @func', tree.root_node)
        >>> for node, name in captures:
        ...     print(f'{name}: {node.type}')
    """
    from tree_sitter import Query, QueryCursor
    
    try:
        # Create query and cursor
        query = Query(language, query_string)
        cursor = QueryCursor(query)
        
        # Execute query and convert to old format
        captures = []
        
        # Use matches() which returns (pattern_index, captures_dict) tuples
        for pattern_index, captures_dict in cursor.matches(node):
            # captures_dict is {capture_name: [nodes]}
            for capture_name, nodes in captures_dict.items():
                for captured_node in nodes:
                    # Old format: (node, capture_name)
                    captures.append((captured_node, capture_name))
        
        return captures
        
    except Exception as e:
        # Provide helpful error message
        raise Exception(
            f"Failed to execute query: {e}\n"
            f"Query string: {query_string[:100]}..."
        )


```

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

```javascript
/*!
 * Lunr languages, `Finnish` language
 * https://github.com/MihaiValentin/lunr-languages
 *
 * Copyright 2014, Mihai Valentin
 * http://www.mozilla.org/MPL/
 */
/*!
 * based on
 * Snowball JavaScript Library v0.3
 * http://code.google.com/p/urim/
 * http://snowball.tartarus.org/
 *
 * Copyright 2010, Oleg Mazko
 * http://www.mozilla.org/MPL/
 */

!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
# Contributing New Language Support to CodeGraphContext

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.

## 1. Understanding the Architecture

CodeGraphContext uses a modular architecture for multi-language support:

*   **Generic `TreeSitterParser` (in `graph_builder.py`):** This acts as a wrapper, dispatching parsing tasks to language-specific implementations.
*   **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:
    *   Tree-sitter queries (`<LANG>_QUERIES`).
    *   A `<Lang>TreeSitterParser` class that encapsulates language-specific parsing logic.
    *   A `pre_scan_<lang>` function for initial symbol mapping.
*   **`GraphBuilder` (in `graph_builder.py`):** Manages the overall graph building process, including file discovery, pre-scanning, and dispatching to the correct language parser.

## 2. Steps to Add a New Language (e.g., TypeScript - `.ts`)

### Step 2.1: Create the Language Module File

1.  Create a new file: `src/codegraphcontext/tools/languages/typescript.py`.
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).
3.  Define `TS_QUERIES` (Tree-sitter queries for TypeScript).
4.  Create a `TypescriptTreeSitterParser` class.
5.  Create a `pre_scan_typescript` function.

### Step 2.2: Define Tree-sitter Queries (`TS_QUERIES`)

This is the most critical and often iterative step. You'll need to define queries for:

*   **`functions`**: Function declarations, arrow functions, methods.
*   **`classes`**: Class declarations, class expressions.
*   **`imports`**: ES6 imports (`import ... from ...`), CommonJS `require()`.
*   **`calls`**: Function calls, method calls.
*   **`variables`**: Variable declarations (`let`, `const`, `var`).
*   **`docstrings`**: (Optional) How documentation comments are identified.
*   **`lambda_assignments`**: (Optional, Python-specific) If the language has similar constructs.

**Tips for Query Writing:**
*   **Consult Tree-sitter Grammars:** Find the `node-types.json` or grammar definition for your language (e.g., `tree-sitter-typescript`).
*   **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.
*   **Start Simple:** Begin with basic queries and gradually add complexity.
*   **Test Iteratively:** After each query, test it with sample code.

### Step 2.3: Implement `<Lang>TreeSitterParser` Class

This class (e.g., `TypescriptTreeSitterParser`) will encapsulate the language-specific logic.

1.  **`__init__(self, generic_parser_wrapper)`**:
    *   Store `generic_parser_wrapper`, `language_name`, `language`, `parser` from the generic wrapper.
    *   Load `TS_QUERIES` using `self.language.query(query_str)`.
2.  **Helper Methods**:
    *   `_get_node_text(self, node)`: Extracts text from a tree-sitter node.
    *   `_get_parent_context(self, node, types=...)`: (Language-specific node types for context).
    *   `_calculate_complexity(self, node)`: (Language-specific complexity nodes).
    *   `_get_docstring(self, body_node)`: (Language-specific docstring extraction).
3.  **`parse(self, file_path: Path, is_dependency: bool = False) -> Dict`**:
    *   Reads the file, parses it with `self.parser`.
    *   Calls its own `_find_*` methods (`_find_functions`, `_find_classes`, etc.).
    *   Returns a standardized dictionary format (as seen in `python.py` and `javascript.py`).
4.  **`_find_*` Methods**:
    Implement these for each query type, extracting data from the AST and populating the standardized dictionary.

### Step 2.4: Implement `pre_scan_<lang>` Function

This function (e.g., `pre_scan_typescript`) will quickly scan files to build an initial `imports_map`.

1.  It takes `files: list[Path]` and `parser_wrapper` (an instance of `TreeSitterParser`).
2.  Uses a simplified query (e.g., for `class_declaration` and `function_declaration`) to quickly find definitions.
3.  Returns a dictionary mapping symbol names to file paths.

### Step 2.5: Integrate into `graph_builder.py`

1.  **`GraphBuilder.__init__`**:
    *   Add `'.ts': TreeSitterParser('typescript')` to `self.parsers`.
2.  **`TreeSitterParser.__init__`**:
    *   Add an `elif self.language_name == 'typescript':` block to initialize `self.language_specific_parser` with `TypescriptTreeSitterParser(self)`.
3.  **`GraphBuilder._pre_scan_for_imports`**:
    *   Add an `elif '.ts' in files_by_lang:` block to import `pre_scan_typescript` and call it.

## 3. Verification and Debugging using Neo4j

After implementing support for a new language, it's crucial to verify that the graph is being built correctly.

### Step 3.1: Prepare a Sample Project

Create a small sample project for your new language (e.g., `tests/sample_project_typescript/`) with:
*   Function declarations.
*   Class declarations (including inheritance).
*   Various import types (if applicable).
*   Function calls.
*   Variable declarations.

### Step 3.2: Index the Sample Project

1.  **Delete existing data (if any):**
    ```bash
    # Replace with your sample project path
    <tool_code>print(default_api.delete_repository(repo_path='/path/to/your/sample_project'))</tool_code>
2.  **Index the project:**
    ```bash
    # Replace with your sample project path
    <tool_code>print(default_api.add_code_to_graph(path='/path/to/your/sample_project'))</tool_code>
3.  **Monitor job status:**
    ```bash
    # Use the job_id returned by add_code_to_graph
    <tool_code>print(default_api.check_job_status(job_id='<your_job_id>'))</tool_code>

### Step 3.3: Query the Neo4j Graph

Use Cypher queries to inspect the generated graph.

*   **Check for Files and Language Tags:**
    ```cypher
    MATCH (f:File)
    WHERE f.path STARTS WITH '/path/to/your/sample_project'
    RETURN f.name, f.path, f.lang
    ```
    *Expected:* All files from your sample project should be listed with the correct `lang` tag.

*   **Check for Functions:**
    ```cypher
    MATCH (f:File)-[:CONTAINS]->(fn:Function)
    WHERE f.path STARTS WITH '/path/to/your/sample_project'
      AND fn.lang = '<your_language_name>'
    RETURN f.name AS FileName, fn.name AS FunctionName, fn.line_number AS Line
    ```
    *Expected:* All functions from your sample project should be listed.

*   **Check for Classes:**
    ```cypher
    MATCH (f:File)-[:CONTAINS]->(c:Class)
    WHERE f.path STARTS WITH '/path/to/your/sample_project'
      AND c.lang = '<your_language_name>'
    RETURN f.name AS FileName, c.name AS ClassName, c.line_number AS Line
    ```
    *Expected:* All classes from your sample project should be listed.

*   **Check for Imports (Module-level):**
    ```cypher
    MATCH (f:File)-[:IMPORTS]->(m:Module)
    WHERE f.path STARTS WITH '/path/to/your/sample_project'
      AND f.lang = '<your_language_name>'
    RETURN f.name AS FileName, m.name AS ImportedModule, m.full_import_name AS FullImportName
    ```
    *Expected:* All module-level imports should be listed.

*   **Check for Function Calls:**
    ```cypher
    MATCH (caller:Function)-[:CALLS]->(callee:Function)
    WHERE caller.file_path STARTS WITH '/path/to/your/sample_project'
      AND caller.lang = '<your_language_name>'
    RETURN caller.name AS Caller, callee.name AS Callee, caller.file_path AS CallerFile, callee.file_path AS CalleeFile
    ```
    *Expected:* All function calls should be correctly linked.

*   **Check for Class Inheritance:**
    ```cypher
    MATCH (child:Class)-[:INHERITS]->(parent:Class)
    WHERE child.file_path STARTS WITH '/path/to/your/sample_project'
      AND child.lang = '<your_language_name>'
    RETURN child.name AS ChildClass, parent.name AS ParentClass, child.file_path AS ChildFile, parent.file_path AS ParentFile
    ```
    *Expected:* All inheritance relationships should be correctly linked.

### Step 3.4: Debugging Common Issues

*   **`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.
*   **Missing Relationships (e.g., `CALLS`, `IMPORTS`)**:
    *   **Check `_find_*` methods**: Ensure your `_find_*` methods are correctly extracting the necessary data.
    *   **Check `imports_map`**: Verify that the `pre_scan_<lang>` function is correctly populating the `imports_map`.
    *   **Check `local_imports` map**: Ensure the `local_imports` map (built in `_create_function_calls` and `_create_inheritance_links`) is correctly resolving symbols.
*   **Incorrect `lang` tags**: Ensure `self.language_name` is correctly passed and stored.

By following these steps, contributors can effectively add and verify new language support.

```

--------------------------------------------------------------------------------
/organizer/CONTRIBUTING_LANGUAGES.md:
--------------------------------------------------------------------------------

```markdown
# Contributing New Language Support to CodeGraphContext

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.

## 1. Understanding the Architecture

CodeGraphContext uses a modular architecture for multi-language support:

*   **Generic `TreeSitterParser` (in `graph_builder.py`):** This acts as a wrapper, dispatching parsing tasks to language-specific implementations.
*   **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:
    *   Tree-sitter queries (`<LANG>_QUERIES`).
    *   A `<Lang>TreeSitterParser` class that encapsulates language-specific parsing logic.
    *   A `pre_scan_<lang>` function for initial symbol mapping.
*   **`GraphBuilder` (in `graph_builder.py`):** Manages the overall graph building process, including file discovery, pre-scanning, and dispatching to the correct language parser.

## 2. Steps to Add a New Language (e.g., TypeScript - `.ts`)

### Step 2.1: Create the Language Module File

1.  Create a new file: `src/codegraphcontext/tools/languages/typescript.py`.
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).
3.  Define `TS_QUERIES` (Tree-sitter queries for TypeScript).
4.  Create a `TypescriptTreeSitterParser` class.
5.  Create a `pre_scan_typescript` function.

### Step 2.2: Define Tree-sitter Queries (`TS_QUERIES`)

This is the most critical and often iterative step. You'll need to define queries for:

*   **`functions`**: Function declarations, arrow functions, methods.
*   **`classes`**: Class declarations, class expressions.
*   **`imports`**: ES6 imports (`import ... from ...`), CommonJS `require()`.
*   **`calls`**: Function calls, method calls.
*   **`variables`**: Variable declarations (`let`, `const`, `var`).
*   **`docstrings`**: (Optional) How documentation comments are identified.
*   **`lambda_assignments`**: (Optional, Python-specific) If the language has similar constructs.

**Tips for Query Writing:**
*   **Consult Tree-sitter Grammars:** Find the `node-types.json` or grammar definition for your language (e.g., `tree-sitter-typescript`).
*   **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.
*   **Start Simple:** Begin with basic queries and gradually add complexity.
*   **Test Iteratively:** After each query, test it with sample code.

### Step 2.3: Implement `<Lang>TreeSitterParser` Class

This class (e.g., `TypescriptTreeSitterParser`) will encapsulate the language-specific logic.

1.  **`__init__(self, generic_parser_wrapper)`**:
    *   Store `generic_parser_wrapper`, `language_name`, `language`, `parser` from the generic wrapper.
    *   Load `TS_QUERIES` using `self.language.query(query_str)`.
2.  **Helper Methods**:
    *   `_get_node_text(self, node)`: Extracts text from a tree-sitter node.
    *   `_get_parent_context(self, node, types=...)`: (Language-specific node types for context).
    *   `_calculate_complexity(self, node)`: (Language-specific complexity nodes).
    *   `_get_docstring(self, body_node)`: (Language-specific docstring extraction).
3.  **`parse(self, file_path: Path, is_dependency: bool = False) -> Dict`**:
    *   Reads the file, parses it with `self.parser`.
    *   Calls its own `_find_*` methods (`_find_functions`, `_find_classes`, etc.).
    *   Returns a standardized dictionary format (as seen in `python.py` and `javascript.py`).
4.  **`_find_*` Methods**:
    Implement these for each query type, extracting data from the AST and populating the standardized dictionary.

### Step 2.4: Implement `pre_scan_<lang>` Function

This function (e.g., `pre_scan_typescript`) will quickly scan files to build an initial `imports_map`.

1.  It takes `files: list[Path]` and `parser_wrapper` (an instance of `TreeSitterParser`).
2.  Uses a simplified query (e.g., for `class_declaration` and `function_declaration`) to quickly find definitions.
3.  Returns a dictionary mapping symbol names to file paths.

### Step 2.5: Integrate into `graph_builder.py`

1.  **`GraphBuilder.__init__`**:
    *   Add `'.ts': TreeSitterParser('typescript')` to `self.parsers`.
2.  **`TreeSitterParser.__init__`**:
    *   Add an `elif self.language_name == 'typescript':` block to initialize `self.language_specific_parser` with `TypescriptTreeSitterParser(self)`.
3.  **`GraphBuilder._pre_scan_for_imports`**:
    *   Add an `elif '.ts' in files_by_lang:` block to import `pre_scan_typescript` and call it.

## 3. Verification and Debugging using Neo4j

After implementing support for a new language, it's crucial to verify that the graph is being built correctly.

### Step 3.1: Prepare a Sample Project

Create a small sample project for your new language (e.g., `tests/sample_project_typescript/`) with:
*   Function declarations.
*   Class declarations (including inheritance).
*   Various import types (if applicable).
*   Function calls.
*   Variable declarations.

### Step 3.2: Index the Sample Project

1.  **Delete existing data (if any):**
    ```bash
    # Replace with your sample project path
    <tool_code>print(default_api.delete_repository(repo_path='/path/to/your/sample_project'))</tool_code>
2.  **Index the project:**
    ```bash
    # Replace with your sample project path
    <tool_code>print(default_api.add_code_to_graph(path='/path/to/your/sample_project'))</tool_code>
3.  **Monitor job status:**
    ```bash
    # Use the job_id returned by add_code_to_graph
    <tool_code>print(default_api.check_job_status(job_id='<your_job_id>'))</tool_code>

### Step 3.3: Query the Neo4j Graph

Use Cypher queries to inspect the generated graph.

*   **Check for Files and Language Tags:**
    ```cypher
    MATCH (f:File)
    WHERE f.path STARTS WITH '/path/to/your/sample_project'
    RETURN f.name, f.path, f.lang
    ```
    *Expected:* All files from your sample project should be listed with the correct `lang` tag.

*   **Check for Functions:**
    ```cypher
    MATCH (f:File)-[:CONTAINS]->(fn:Function)
    WHERE f.path STARTS WITH '/path/to/your/sample_project'
      AND fn.lang = '<your_language_name>'
    RETURN f.name AS FileName, fn.name AS FunctionName, fn.line_number AS Line
    ```
    *Expected:* All functions from your sample project should be listed.

*   **Check for Classes:**
    ```cypher
    MATCH (f:File)-[:CONTAINS]->(c:Class)
    WHERE f.path STARTS WITH '/path/to/your/sample_project'
      AND c.lang = '<your_language_name>'
    RETURN f.name AS FileName, c.name AS ClassName, c.line_number AS Line
    ```
    *Expected:* All classes from your sample project should be listed.

*   **Check for Imports (Module-level):**
    ```cypher
    MATCH (f:File)-[:IMPORTS]->(m:Module)
    WHERE f.path STARTS WITH '/path/to/your/sample_project'
      AND f.lang = '<your_language_name>'
    RETURN f.name AS FileName, m.name AS ImportedModule, m.full_import_name AS FullImportName
    ```
    *Expected:* All module-level imports should be listed.

*   **Check for Function Calls:**
    ```cypher
    MATCH (caller:Function)-[:CALLS]->(callee:Function)
    WHERE caller.file_path STARTS WITH '/path/to/your/sample_project'
      AND caller.lang = '<your_language_name>'
    RETURN caller.name AS Caller, callee.name AS Callee, caller.file_path AS CallerFile, callee.file_path AS CalleeFile
    ```
    *Expected:* All function calls should be correctly linked.

*   **Check for Class Inheritance:**
    ```cypher
    MATCH (child:Class)-[:INHERITS]->(parent:Class)
    WHERE child.file_path STARTS WITH '/path/to/your/sample_project'
      AND child.lang = '<your_language_name>'
    RETURN child.name AS ChildClass, parent.name AS ParentClass, child.file_path AS ChildFile, parent.file_path AS ParentFile
    ```
    *Expected:* All inheritance relationships should be correctly linked.

### Step 3.4: Debugging Common Issues

*   **`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.
*   **Missing Relationships (e.g., `CALLS`, `IMPORTS`)**:
    *   **Check `_find_*` methods**: Ensure your `_find_*` methods are correctly extracting the necessary data.
    *   **Check `imports_map`**: Verify that the `pre_scan_<lang>` function is correctly populating the `imports_map`.
    *   **Check `local_imports` map**: Ensure the `local_imports` map (built in `_create_function_calls` and `_create_inheritance_links`) is correctly resolving symbols.
*   **Incorrect `lang` tags**: Ensure `self.language_name` is correctly passed and stored.

By following these steps, contributors can effectively add and verify new language support.

```

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

```javascript
/*!
 * Lunr languages, `Hungarian` language
 * https://github.com/MihaiValentin/lunr-languages
 *
 * Copyright 2014, Mihai Valentin
 * http://www.mozilla.org/MPL/
 */
/*!
 * based on
 * Snowball JavaScript Library v0.3
 * http://code.google.com/p/urim/
 * http://snowball.tartarus.org/
 *
 * Copyright 2010, Oleg Mazko
 * http://www.mozilla.org/MPL/
 */

!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e<L.limit&&L.cursor++),void(d=L.cursor);if(L.cursor=e,e>=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}});
```

--------------------------------------------------------------------------------
/tests/sample_project_typescript/src/classes-inheritance.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * Classes and Inheritance
 * Demonstrates TypeScript's OOP features including classes, inheritance,
 * abstract classes, access modifiers, static members, and advanced patterns
 */

// ========== Basic Class Definition ==========
export class Person {
  // Public property (default)
  public name: string;
  
  // Private property (only accessible within this class)
  private _id: number;
  
  // Protected property (accessible in this class and subclasses)
  protected age: number;
  
  // Readonly property
  readonly birthDate: Date;
  
  // Static property
  static species: string = "Homo sapiens";
  
  // Static method
  static getSpecies(): string {
    return Person.species;
  }

  constructor(name: string, age: number, id: number) {
    this.name = name;
    this.age = age;
    this._id = id;
    this.birthDate = new Date();
  }

  // Public method
  public introduce(): string {
    return `Hello, I'm ${this.name} and I'm ${this.age} years old.`;
  }

  // Private method
  private validateAge(age: number): boolean {
    return age >= 0 && age <= 150;
  }

  // Protected method
  protected updateAge(newAge: number): void {
    if (this.validateAge(newAge)) {
      this.age = newAge;
    }
  }

  // Getter
  get id(): number {
    return this._id;
  }

  // Setter
  set id(value: number) {
    if (value > 0) {
      this._id = value;
    }
  }

  // Method with overloads
  greet(): string;
  greet(formal: boolean): string;
  greet(formal: boolean, title: string): string;
  greet(formal?: boolean, title?: string): string {
    const greeting = formal ? "Good day" : "Hi";
    const nameWithTitle = title ? `${title} ${this.name}` : this.name;
    return `${greeting}, ${nameWithTitle}!`;
  }
}

// ========== Inheritance ==========
export class Employee extends Person {
  private salary: number;
  public department: string;
  
  constructor(name: string, age: number, id: number, department: string, salary: number) {
    super(name, age, id); // Call parent constructor
    this.department = department;
    this.salary = salary;
  }

  // Override parent method
  public override introduce(): string {
    return `${super.introduce()} I work in ${this.department}.`;
  }

  // New method specific to Employee
  public work(): string {
    return `${this.name} is working in the ${this.department} department.`;
  }

  // Access protected member from parent
  public celebrateBirthday(): void {
    this.updateAge(this.age + 1);
    console.log(`Happy birthday! Now ${this.age} years old.`);
  }

  // Getter for private property
  get monthlySalary(): number {
    return this.salary;
  }

  // Setter with validation
  set monthlySalary(value: number) {
    if (value >= 0) {
      this.salary = value;
    } else {
      throw new Error("Salary cannot be negative");
    }
  }
}

// ========== Abstract Classes ==========
export abstract class Animal {
  protected name: string;
  protected age: number;
  
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  // Concrete method
  public sleep(): string {
    return `${this.name} is sleeping.`;
  }

  // Abstract method (must be implemented by subclasses)
  abstract makeSound(): string;
  
  // Abstract method with parameters
  abstract move(distance: number): string;
}

// ========== Concrete Implementation of Abstract Class ==========
export class Dog extends Animal {
  private breed: string;
  
  constructor(name: string, age: number, breed: string) {
    super(name, age);
    this.breed = breed;
  }

  // Implementation of abstract method
  public makeSound(): string {
    return `${this.name} the ${this.breed} says: Woof! Woof!`;
  }

  // Implementation of abstract method
  public move(distance: number): string {
    return `${this.name} runs ${distance} meters.`;
  }

  // Additional method specific to Dog
  public fetch(): string {
    return `${this.name} fetches the ball!`;
  }
}

export class Cat extends Animal {
  private indoor: boolean;
  
  constructor(name: string, age: number, indoor: boolean = true) {
    super(name, age);
    this.indoor = indoor;
  }

  public makeSound(): string {
    return `${this.name} says: Meow!`;
  }

  public move(distance: number): string {
    const verb = this.indoor ? "walks" : "prowls";
    return `${this.name} ${verb} ${distance} meters.`;
  }

  public climb(): string {
    return `${this.name} climbs up high.`;
  }
}

// ========== Interface Implementation ==========
interface Flyable {
  fly(height: number): string;
  land(): string;
}

interface Swimmable {
  swim(depth: number): string;
  surface(): string;
}

export class Duck extends Animal implements Flyable, Swimmable {
  constructor(name: string, age: number) {
    super(name, age);
  }

  public makeSound(): string {
    return `${this.name} says: Quack! Quack!`;
  }

  public move(distance: number): string {
    return `${this.name} waddles ${distance} meters.`;
  }

  // Implement Flyable
  public fly(height: number): string {
    return `${this.name} flies at ${height} meters high.`;
  }

  public land(): string {
    return `${this.name} lands gracefully.`;
  }

  // Implement Swimmable
  public swim(depth: number): string {
    return `${this.name} swims at ${depth} meters deep.`;
  }

  public surface(): string {
    return `${this.name} surfaces from the water.`;
  }
}

// ========== Generic Classes ==========
export class Container<T> {
  private items: T[] = [];

  public add(item: T): void {
    this.items.push(item);
  }

  public remove(item: T): boolean {
    const index = this.items.indexOf(item);
    if (index > -1) {
      this.items.splice(index, 1);
      return true;
    }
    return false;
  }

  public getAll(): readonly T[] {
    return [...this.items];
  }

  public size(): number {
    return this.items.length;
  }

  public clear(): void {
    this.items = [];
  }
}

// Generic class with constraints
export class NumberContainer<T extends number> extends Container<T> {
  public sum(): T {
    return this.getAll().reduce((sum, item) => (sum + item) as T, 0 as T);
  }

  public average(): number {
    const items = this.getAll();
    return items.length > 0 ? this.sum() / items.length : 0;
  }
}

// ========== Singleton Pattern ==========
export class Database {
  private static instance: Database;
  private connections: number = 0;

  private constructor() {
    // Private constructor prevents instantiation
  }

  public static getInstance(): Database {
    if (!Database.instance) {
      Database.instance = new Database();
    }
    return Database.instance;
  }

  public connect(): string {
    this.connections++;
    return `Connected to database. Total connections: ${this.connections}`;
  }

  public disconnect(): string {
    if (this.connections > 0) {
      this.connections--;
      return `Disconnected from database. Remaining connections: ${this.connections}`;
    }
    return "No active connections to disconnect.";
  }
}

// ========== Static Class Pattern ==========
export class MathUtils {
  // Prevent instantiation
  private constructor() {}

  public static PI: number = Math.PI;
  
  public static calculateCircleArea(radius: number): number {
    return MathUtils.PI * radius * radius;
  }

  public static calculateDistance(x1: number, y1: number, x2: number, y2: number): number {
    return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
  }

  public static clamp(value: number, min: number, max: number): number {
    return Math.min(Math.max(value, min), max);
  }
}

// ========== Mixins Pattern ==========
type Constructor<T = {}> = new (...args: any[]) => T;

// Mixin function
export function Timestamped<TBase extends Constructor>(Base: TBase) {
  return class extends Base {
    timestamp = Date.now();
    
    getTimestamp(): number {
      return this.timestamp;
    }
  };
}

export function Activatable<TBase extends Constructor>(Base: TBase) {
  return class extends Base {
    isActive = false;
    
    activate(): void {
      this.isActive = true;
    }
    
    deactivate(): void {
      this.isActive = false;
    }
  };
}

// Base class for mixins
export class BaseUser {
  constructor(public name: string) {}
}

// Apply mixins
export const TimestampedUser = Timestamped(BaseUser);
export const ActivatableUser = Activatable(BaseUser);
export const EnhancedUser = Timestamped(Activatable(BaseUser));

// ========== Usage Examples ==========
export const classExamples = {
  // Basic usage
  person: new Person("John Doe", 30, 123),
  employee: new Employee("Jane Smith", 28, 456, "Engineering", 75000),
  
  // Animals
  dog: new Dog("Buddy", 3, "Golden Retriever"),
  cat: new Cat("Whiskers", 2, true),
  duck: new Duck("Quackers", 1),
  
  // Generic containers
  stringContainer: new Container<string>(),
  numberContainer: new NumberContainer<number>(),
  
  // Singleton
  database: Database.getInstance(),
  
  // Mixins
  timestampedUser: new TimestampedUser("Alice"),
  enhancedUser: new EnhancedUser("Bob")
};

// Initialize some examples
classExamples.stringContainer.add("Hello");
classExamples.stringContainer.add("World");

classExamples.numberContainer.add(10);
classExamples.numberContainer.add(20);
classExamples.numberContainer.add(30);
```

--------------------------------------------------------------------------------
/tests/sample_project_typescript/src/functions-generics.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * Functions and Generics
 * Demonstrates TypeScript's function types, overloads, generics, constraints,
 * higher-order functions, and advanced function patterns
 */

// ========== Basic Function Types ==========
export function simpleFunction(x: number, y: number): number {
  return x + y;
}

// Optional parameters
export function greet(name: string, greeting?: string): string {
  return `${greeting || "Hello"}, ${name}!`;
}

// Default parameters
export function createUser(name: string, active: boolean = true): { name: string; active: boolean } {
  return { name, active };
}

// Rest parameters
export function sum(...numbers: number[]): number {
  return numbers.reduce((total, num) => total + num, 0);
}

// ========== Function Overloads ==========
export function parseValue(value: string): number;
export function parseValue(value: number): string;
export function parseValue(value: boolean): string;
export function parseValue(value: string | number | boolean): string | number {
  if (typeof value === "string") {
    return parseInt(value, 10);
  } else if (typeof value === "number") {
    return value.toString();
  } else {
    return value.toString();
  }
}

// Complex overloads
export function processData(data: string[]): string[];
export function processData(data: number[]): number[];
export function processData<T>(data: T[], processor: (item: T) => T): T[];
export function processData<T>(
  data: T[],
  processor?: (item: T) => T
): T[] {
  if (processor) {
    return data.map(processor);
  }
  return [...data];
}

// ========== Arrow Functions ==========
export const multiply = (x: number, y: number): number => x * y;

export const isEven = (n: number): boolean => n % 2 === 0;

// Higher-order arrow function
export const createMultiplier = (factor: number) => (value: number) => value * factor;

// ========== Generic Functions ==========
export function identity<T>(arg: T): T {
  return arg;
}

export function getFirstElement<T>(array: T[]): T | undefined {
  return array[0];
}

// Generic with multiple type parameters
export function merge<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

// Generic with default type parameter
export function createArray<T = string>(length: number, defaultValue: T): T[] {
  return Array(length).fill(defaultValue);
}

// ========== Generic Constraints ==========
// Constraint using extends
export function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

// Constraint with interface
interface Lengthwise {
  length: number;
}

export function logLength<T extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

// Constraint with conditional types
export function processItem<T extends string | number>(
  item: T
): T extends string ? string : number {
  if (typeof item === "string") {
    return item.toUpperCase() as T extends string ? string : number;
  }
  return (item * 2) as T extends string ? string : number;
}

// ========== Advanced Generic Patterns ==========
// Generic factory function
export interface Constructable<T = {}> {
  new (...args: any[]): T;
}

export function createInstance<T>(constructor: Constructable<T>, ...args: any[]): T {
  return new constructor(...args);
}

// Generic with constraint and default
export function sortBy<T, K extends keyof T = keyof T>(
  array: T[],
  key: K,
  ascending: boolean = true
): T[] {
  return array.sort((a, b) => {
    const valueA = a[key];
    const valueB = b[key];
    
    if (valueA < valueB) return ascending ? -1 : 1;
    if (valueA > valueB) return ascending ? 1 : -1;
    return 0;
  });
}

// ========== Function Types ==========
export type UnaryFunction<T, R> = (arg: T) => R;
export type BinaryFunction<T, U, R> = (arg1: T, arg2: U) => R;
export type Predicate<T> = (arg: T) => boolean;
export type Mapper<T, R> = (item: T, index: number, array: T[]) => R;

// Function that accepts function types
export function pipe<T, R1, R2>(
  input: T,
  fn1: UnaryFunction<T, R1>,
  fn2: UnaryFunction<R1, R2>
): R2 {
  return fn2(fn1(input));
}

// ========== Higher-Order Functions ==========
export function memoize<T extends (...args: any[]) => any>(fn: T): T {
  const cache = new Map();
  
  return ((...args: any[]) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key);
    }
    const result = fn(...args);
    cache.set(key, result);
    return result;
  }) as T;
}

export function debounce<T extends (...args: any[]) => any>(
  fn: T,
  delay: number
): T {
  let timeoutId: NodeJS.Timeout;
  
  return ((...args: any[]) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn(...args), delay);
  }) as T;
}

export function throttle<T extends (...args: any[]) => any>(
  fn: T,
  limit: number
): T {
  let inThrottle: boolean;
  
  return ((...args: any[]) => {
    if (!inThrottle) {
      fn(...args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  }) as T;
}

// ========== Generic Data Structures ==========
export class Stack<T> {
  private items: T[] = [];

  push(item: T): void {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }

  peek(): T | undefined {
    return this.items[this.items.length - 1];
  }

  isEmpty(): boolean {
    return this.items.length === 0;
  }

  size(): number {
    return this.items.length;
  }
}

export class Queue<T> {
  private items: T[] = [];

  enqueue(item: T): void {
    this.items.push(item);
  }

  dequeue(): T | undefined {
    return this.items.shift();
  }

  front(): T | undefined {
    return this.items[0];
  }

  isEmpty(): boolean {
    return this.items.length === 0;
  }

  size(): number {
    return this.items.length;
  }
}

// Generic with multiple constraints
export interface Comparable<T> {
  compareTo(other: T): number;
}

export class PriorityQueue<T extends Comparable<T>> {
  private items: T[] = [];

  enqueue(item: T): void {
    this.items.push(item);
    this.items.sort((a, b) => a.compareTo(b));
  }

  dequeue(): T | undefined {
    return this.items.shift();
  }

  peek(): T | undefined {
    return this.items[0];
  }

  isEmpty(): boolean {
    return this.items.length === 0;
  }
}

// ========== Utility Functions with Generics ==========
export function arrayChunk<T>(array: T[], size: number): T[][] {
  const chunks: T[][] = [];
  for (let i = 0; i < array.length; i += size) {
    chunks.push(array.slice(i, i + size));
  }
  return chunks;
}

export function arrayUnique<T>(array: T[]): T[] {
  return [...new Set(array)];
}

export function arrayGroupBy<T, K extends string | number | symbol>(
  array: T[],
  keyFn: (item: T) => K
): Record<K, T[]> {
  return array.reduce((groups, item) => {
    const key = keyFn(item);
    groups[key] = groups[key] || [];
    groups[key]!.push(item);
    return groups;
  }, {} as Record<K, T[]>);
}

// Curried functions
export const curriedAdd = (x: number) => (y: number) => x + y;
export const curriedFilter = <T>(predicate: Predicate<T>) => (array: T[]) => 
  array.filter(predicate);

// ========== Generic Utility Types Functions ==========
export function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
  const result = {} as Pick<T, K>;
  keys.forEach(key => {
    result[key] = obj[key];
  });
  return result;
}

export function omit<T, K extends keyof T>(obj: T, ...keys: K[]): Omit<T, K> {
  const result = { ...obj };
  keys.forEach(key => {
    delete result[key];
  });
  return result as Omit<T, K>;
}

export function deepClone<T>(obj: T): T {
  if (obj === null || typeof obj !== "object") {
    return obj;
  }
  
  if (obj instanceof Date) {
    return new Date(obj.getTime()) as T;
  }
  
  if (obj instanceof Array) {
    return obj.map(item => deepClone(item)) as T;
  }
  
  if (typeof obj === "object") {
    const copy = {} as T;
    Object.keys(obj).forEach(key => {
      (copy as any)[key] = deepClone((obj as any)[key]);
    });
    return copy;
  }
  
  return obj;
}

// ========== Function Composition ==========
export function compose<T, R1, R2>(
  fn1: (arg: T) => R1,
  fn2: (arg: R1) => R2
): (arg: T) => R2;
export function compose<T, R1, R2, R3>(
  fn1: (arg: T) => R1,
  fn2: (arg: R1) => R2,
  fn3: (arg: R2) => R3
): (arg: T) => R3;
export function compose(...fns: Function[]) {
  return (arg: any) => fns.reduce((result, fn) => fn(result), arg);
}

// ========== Usage Examples ==========
export const functionExamples = {
  // Basic functions
  basicSum: sum(1, 2, 3, 4, 5),
  parsedString: parseValue("123"),
  parsedNumber: parseValue(456),
  
  // Generics
  identityString: identity("hello"),
  identityNumber: identity(42),
  mergedObject: merge({ name: "John" }, { age: 30 }),
  
  // Data structures
  numberStack: new Stack<number>(),
  stringQueue: new Queue<string>(),
  
  // Higher-order functions
  double: createMultiplier(2),
  memoizedFib: memoize((n: number): number => {
    if (n <= 1) return n;
    return functionExamples.memoizedFib(n - 1) + functionExamples.memoizedFib(n - 2);
  }),
  
  // Array utilities
  chunkedArray: arrayChunk([1, 2, 3, 4, 5, 6, 7], 3),
  uniqueArray: arrayUnique([1, 2, 2, 3, 3, 3, 4]),
  groupedItems: arrayGroupBy(
    [{ type: "fruit", name: "apple" }, { type: "fruit", name: "banana" }, { type: "vegetable", name: "carrot" }],
    item => item.type
  )
};

// Initialize some examples
functionExamples.numberStack.push(1);
functionExamples.numberStack.push(2);
functionExamples.numberStack.push(3);

functionExamples.stringQueue.enqueue("first");
functionExamples.stringQueue.enqueue("second");
functionExamples.stringQueue.enqueue("third");
```

--------------------------------------------------------------------------------
/src/codegraphcontext/core/watcher.py:
--------------------------------------------------------------------------------

```python
# src/codegraphcontext/core/watcher.py
"""
This module implements the live file-watching functionality using the `watchdog` library.
It observes directories for changes and triggers updates to the code graph.
"""
import threading
from pathlib import Path
import typing
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

if typing.TYPE_CHECKING:
    from codegraphcontext.tools.graph_builder import GraphBuilder
    from codegraphcontext.core.jobs import JobManager

from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger

class RepositoryEventHandler(FileSystemEventHandler):
    """
    A dedicated event handler for a single repository being watched.
    
    This handler is stateful. It performs an initial scan of the repository
    to build a baseline and then uses this cached state to perform efficient
    updates when files are changed, created, or deleted.
    """
    def __init__(self, graph_builder: "GraphBuilder", repo_path: Path, debounce_interval=2.0, perform_initial_scan: bool = True):
        """
        Initializes the event handler.

        Args:
            graph_builder: An instance of the GraphBuilder to perform graph operations.
            repo_path: The absolute path to the repository directory to watch.
            debounce_interval: The time in seconds to wait for more changes before processing an event.
            perform_initial_scan: Whether to perform an initial scan of the repository.
        """
        super().__init__()
        self.graph_builder = graph_builder
        self.repo_path = repo_path
        self.debounce_interval = debounce_interval
        self.timers = {} # A dictionary to manage debounce timers for file paths.
        
        # Caches for the repository's state.
        self.all_file_data = []
        self.imports_map = {}
        
        # Perform the initial scan and linking when the watcher is created.
        if perform_initial_scan:
            self._initial_scan()

    def _initial_scan(self):
        """Scans the entire repository, parses all files, and builds the initial graph."""
        info_logger(f"Performing initial scan for watcher: {self.repo_path}")
        supported_extensions = self.graph_builder.parsers.keys()
        all_files = [f for f in self.repo_path.rglob("*") if f.is_file() and f.suffix in supported_extensions]
        
        # 1. Pre-scan all files to get a global map of where every symbol is defined.
        self.imports_map = self.graph_builder._pre_scan_for_imports(all_files)
        
        # 2. Parse all files in detail and cache the parsed data.
        for f in all_files:
            parsed_data = self.graph_builder.parse_file(self.repo_path, f)
            if "error" not in parsed_data:
                self.all_file_data.append(parsed_data)
        
        # 3. After all files are parsed, create the relationships (e.g., function calls) between them.
        self.graph_builder._create_all_function_calls(self.all_file_data, self.imports_map)
        self.graph_builder._create_all_inheritance_links(self.all_file_data, self.imports_map)
        info_logger(f"Initial scan and graph linking complete for: {self.repo_path}")

    def _debounce(self, event_path, action):
        """
        Schedules an action to run after a debounce interval.
        This prevents the handler from firing on every single file save event in rapid
        succession, which is common in IDEs. It waits for a quiet period before processing.
        """
        # If a timer already exists for this path, cancel it.
        if event_path in self.timers:
            self.timers[event_path].cancel()
        # Create and start a new timer.
        timer = threading.Timer(self.debounce_interval, action)
        timer.start()
        self.timers[event_path] = timer

    def _handle_modification(self, event_path_str: str):
        """
        Orchestrates the complete update cycle for a modified or created file.
        This involves re-scanning the entire repo to update cross-file relationships.
        """
        info_logger(f"File change detected, starting full repository refresh for: {event_path_str}")
        modified_path = Path(event_path_str)

        # 1. Get all supported files in the repository.
        supported_extensions = self.graph_builder.parsers.keys()
        all_files = [f for f in self.repo_path.rglob("*") if f.is_file() and f.suffix in supported_extensions]

        # 2. Re-scan all files to get a fresh, global map of all symbols.
        self.imports_map = self.graph_builder._pre_scan_for_imports(all_files)
        info_logger("Refreshed global imports map.")

        # 3. Update the specific file that changed in the graph.
        # This deletes old nodes and adds new ones for the single file.
        self.graph_builder.update_file_in_graph(
            modified_path, self.repo_path, self.imports_map
        )

        # 4. Re-parse all files to have a complete, in-memory representation for the linking pass.
        # This is necessary because a change in one file can affect relationships in others.
        self.all_file_data = []
        for f in all_files:
            parsed_data = self.graph_builder.parse_file(self.repo_path, f)
            if "error" not in parsed_data:
                self.all_file_data.append(parsed_data)
        info_logger("Refreshed in-memory cache of all file data.")

        # 5. CRITICAL: Re-link the entire graph using the fully updated cache and imports map.
        info_logger("Re-linking the entire graph for calls and inheritance...")
        self.graph_builder._create_all_function_calls(self.all_file_data, self.imports_map)
        self.graph_builder._create_all_inheritance_links(self.all_file_data, self.imports_map)
        info_logger(f"Graph refresh for change in {event_path_str} complete! ✅")

    # The following methods are called by the watchdog observer when a file event occurs.
    def on_created(self, event):
        if not event.is_directory and Path(event.src_path).suffix in self.graph_builder.parsers:
            self._debounce(event.src_path, lambda: self._handle_modification(event.src_path))

    def on_modified(self, event):
        if not event.is_directory and Path(event.src_path).suffix in self.graph_builder.parsers:
            self._debounce(event.src_path, lambda: self._handle_modification(event.src_path))

    def on_deleted(self, event):
        if not event.is_directory and Path(event.src_path).suffix in self.graph_builder.parsers:
            self._debounce(event.src_path, lambda: self._handle_modification(event.src_path))

    def on_moved(self, event):
        if not event.is_directory:
            if Path(event.src_path).suffix in self.graph_builder.parsers:
                self._debounce(event.src_path, lambda: self._handle_modification(event.src_path))
            if Path(event.dest_path).suffix in self.graph_builder.parsers:
                self._debounce(event.dest_path, lambda: self._handle_modification(event.dest_path))


class CodeWatcher:
    """
    Manages the file system observer thread. It can watch multiple directories,
    assigning a separate `RepositoryEventHandler` to each one.
    """
    def __init__(self, graph_builder: "GraphBuilder", job_manager= "JobManager"):
        self.graph_builder = graph_builder
        self.observer = Observer()
        self.watched_paths = set() # Keep track of paths already being watched.
        self.watches = {} # Store watch objects to allow unscheduling

    def watch_directory(self, path: str, perform_initial_scan: bool = True):
        """Schedules a directory to be watched for changes."""
        path_obj = Path(path).resolve()
        path_str = str(path_obj)

        if path_str in self.watched_paths:
            info_logger(f"Path already being watched: {path_str}")
            return {"message": f"Path already being watched: {path_str}"}
        
        # Create a new, dedicated event handler for this specific repository path.
        event_handler = RepositoryEventHandler(self.graph_builder, path_obj, perform_initial_scan=perform_initial_scan)
        
        watch = self.observer.schedule(event_handler, path_str, recursive=True)
        self.watches[path_str] = watch
        self.watched_paths.add(path_str)
        info_logger(f"Started watching for code changes in: {path_str}")
        
        return {"message": f"Started watching {path_str}."}
    def unwatch_directory(self, path: str):
        """Stops watching a directory for changes."""
        path_obj = Path(path).resolve()
        path_str = str(path_obj)

        if path_str not in self.watched_paths:
            warning_logger(f"Attempted to unwatch a path that is not being watched: {path_str}")
            return {"error": f"Path not currently being watched: {path_str}"}

        watch = self.watches.pop(path_str, None)
        if watch:
            self.observer.unschedule(watch)
        
        self.watched_paths.discard(path_str)
        info_logger(f"Stopped watching for code changes in: {path_str}")
        return {"message": f"Stopped watching {path_str}."}

    def list_watched_paths(self) -> list:
        """Returns a list of all currently watched directory paths."""
        return list(self.watched_paths)

    def start(self):
        """Starts the observer thread."""
        if not self.observer.is_alive():
            self.observer.start()
            info_logger("Code watcher observer thread started.")

    def stop(self):
        """Stops the observer thread gracefully."""
        if self.observer.is_alive():
            self.observer.stop()
            self.observer.join() # Wait for the thread to terminate.
            info_logger("Code watcher observer thread stopped.")

```
Page 5/17FirstPrevNextLast