This is page 7 of 14. Use http://codebase.md/shashankss1205/codegraphcontext?format=md&lines=false&page={x} to view the full context.

# Directory Structure

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

# Files

--------------------------------------------------------------------------------
/organizer/cookbook.md:
--------------------------------------------------------------------------------

```markdown
# MCP Tool Cookbook

This cookbook provides examples of how to use the `mcp` tool to query and understand your Python codebase. The "Tool" indicates which `mcp` tool to use, and the "JSON Arguments" are what the LLM would provide to that tool.

---

## Basic Queries

### 1. Find a specific function by name
- **Natural Language:** "Where is the function `foo` defined?"
- **Tool:** `find_code`
- **JSON Arguments:**
  ```json
  {
    "query": "foo"
  }
  ```

![Query 1](../images/1.png)

### 2. Find all calls to a specific function
- **Natural Language:** "Find all calls to the `helper` function."
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "find_callers",
    "target": "helper"
  }
  ```

![Query 2](../images/2.png)

### 3. Find what a function calls
- **Natural Language:** "What functions are called inside the `foo` function?"
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "find_callees",
    "target": "foo",
    "context": "/teamspace/studios/this_studio/demo/CodeGraphContext/tests/sample_project/module_a.py"
  }
  ```

![Query 3](../images/3.png)

### 4. Find all imports of a specific module
- **Natural Language:** "Where is the `math` module imported?"
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "find_importers",
    "target": "math"
  }
  ```

![Query 4](../images/4.png)

### 5. Find all methods of a class
- **Natural Language:** "What are the methods of the `A` class?"
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "class_hierarchy",
    "target": "A"
  }
  ```
- **Note:** The response for `class_hierarchy` includes a list of methods.

![Query 5](../images/5.png)

### 6. Find all classes that inherit from a specific class
- **Natural Language:** "Show me all classes that inherit from `Base`."
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "class_hierarchy",
    "target": "Base"
  }
  ```
- **Note:** The response for `class_hierarchy` includes a list of child classes.

![Query 6](../images/6.png)

### 7. Find all functions with a specific decorator
- **Natural Language:** "Find all functions with the `log_decorator`."
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "find_functions_by_decorator",
    "target": "log_decorator"
  }
  ```

![Query 7](../images/7.png)

### 8. Find all dataclasses
- **Natural Language:** "Find all dataclasses."
- **Tool:** `execute_cypher_query`
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (c:Class) WHERE 'dataclass' IN c.decorators RETURN c.name, c.file_path"
  }
  ```

![Query 8](../images/8.png)

---

## Code Analysis & Quality

### 9. Find the 5 most complex functions
- **Natural Language:** "Find the 5 most complex functions."
- **Tool:** `find_most_complex_functions`
- **JSON Arguments:**
  ```json
  {
    "limit": 5
  }
  ```

![Query 9](../images/9.png)

### 10. Calculate cyclomatic complexity of a function
- **Natural Language:** "What is the cyclomatic complexity of `try_except_finally`?"
- **Tool:** `calculate_cyclomatic_complexity`
- **JSON Arguments:**
  ```json
  {
    "function_name": "try_except_finally"
  }
  ```

### 11. Find unused code
- **Natural Language:** "Find unused code, but ignore API endpoints decorated with `@app.route`."
- **Tool:** `find_dead_code`
- **JSON Arguments:**
  ```json
  {
    "exclude_decorated_with": ["@app.route"]
  }
  ```

![Query 11](../images/11.png)

### 12. Find the call chain between two functions
- **Natural Language:** "What is the call chain from `wrapper` to `helper`?"
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "call_chain",
    "target": "wrapper->helper"
  }
  ```

![Query 12](../images/12.png)

### 13. Find all direct and indirect callers of a function
- **Natural Language:** "Show me all functions that eventually call the `helper` function."
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "find_all_callers",
    "target": "helper"
  }
  ```

![Query 13](../images/13.png)

### 14. Find functions by argument name
- **Natural Language:** "Find all functions that take `self` as an argument."
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "find_functions_by_argument",
    "target": "self"
  }
  ```

![Query 14](../images/14.png)

### 15. List all python package imports from a directory
- **Natural Language:** "List all python package imports from my project directory."
- **Tool:** `execute_cypher_query`
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:File)-[:IMPORTS]->(m:Module) WHERE f.path ENDS WITH '.py' RETURN DISTINCT m.name"
  }
  ```

---

## Repository Information Queries

### 16. List all indexed projects
- **Natural Language:** "List all projects I have indexed."
- **Tool:** `list_indexed_repositories`
- **JSON Arguments:**
  ```json
  {}
  ```

![Query 16](../images/16.png)

### 17. Check the status of an indexing job
- **Natural Language:** "What is the status of job `4cb9a60e-c1b1-43a7-9c94-c840771506bc`?"
- **Tool:** `check_job_status`
- **JSON Arguments:**
  ```json
  {
    "job_id": "4cb9a60e-c1b1-43a7-9c94-c840771506bc"
  }
  ```

### 18. List all background jobs
- **Natural Language:** "Show me all background jobs."
- **Tool:** `list_jobs`
- **JSON Arguments:**
  ```json
  {}
  ```

---

## Advanced Cypher Queries

These examples use the `execute_cypher_query` tool for more specific and complex questions.

### 19. Find all function definitions
- **Natural Language:** "Find all function definitions in the codebase."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (n:Function) RETURN n.name, n.file_path, n.line_number LIMIT 50"
  }
  ```

![Query 19](../images/19.png)

### 20. Find all classes
- **Natural Language:** "Show me all the classes."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (n:Class) RETURN n.name, n.file_path, n.line_number LIMIT 50"
  }
  ```

![Query 20](../images/20.png)

### 21. Find all functions in a file
- **Natural Language:** "Find all functions in `module_a.py`."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function) WHERE f.file_path ENDS WITH 'module_a.py' RETURN f.name"
  }
  ```

![Query 21](../images/21.png)

### 22. Find all classes in a file
- **Natural Language:** "Find all classes in `advanced_classes.py`."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (c:Class) WHERE c.file_path ENDS WITH 'advanced_classes.py' RETURN c.name"
  }
  ```

![Query 22](../images/22.png)

### 23. List all top-level functions and classes in a file
- **Natural Language:** "List all top-level functions and classes in `module_a.py`."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:File)-[:CONTAINS]->(n) WHERE f.name = 'module_a.py' AND (n:Function OR n:Class) AND n.context IS NULL RETURN n.name"
  }
  ```

![Query 23](../images/23.png)

### 24. Find functions in one module that call a function in another
- **Natural Language:** "Find functions in `module_a.py` that call `helper` in `module_b.py`."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (caller:Function)-[:CALLS]->(callee:Function {name: 'helper'}) WHERE caller.file_path ENDS WITH 'module_a.py' AND callee.file_path ENDS WITH 'module_b.py' RETURN caller.name"
  }
  ```

![Query 24](../images/24.png)

### 25. Find circular file imports
- **Natural Language:** "Are there any circular dependencies between files?"
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f1:File)-[:IMPORTS]->(m2:Module), (f2:File)-[:IMPORTS]->(m1:Module) WHERE f1.name = m1.name + '.py' AND f2.name = m2.name + '.py' RETURN f1.name, f2.name"
  }
  ```

### 26. Find all functions with more than 5 arguments
- **Natural Language:** "Find all functions with a large number of arguments."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function) WHERE size(f.args) > 5 RETURN f.name, f.file_path, size(f.args) as arg_count"
  }
  ```

![Query 26](../images/26.png)

### 27. Find all functions in a file that have a docstring
- **Natural Language:** "Find all functions in `module_a.py` that have a docstring."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function) WHERE f.file_path ENDS WITH 'module_a.py' AND f.docstring IS NOT NULL AND f.docstring <> '' RETURN f.name"
  }
  ```

### 28. Find all classes that have a specific method
- **Natural Language:** "Find all classes that have a `greet` method."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (c:Class)-[:CONTAINS]->(m:Function {name: 'greet'}) RETURN c.name, c.file_path"
  }
  ```

![Query 28](../images/28.png)

### 29. Find the depth of inheritance for all classes
- **Natural Language:** "How deep are the inheritance chains for all classes?"
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (c:Class) OPTIONAL MATCH path = (c)-[:INHERITS*]->(parent:Class) RETURN c.name, c.file_path, length(path) AS depth ORDER BY depth DESC"
  }
  ```

![Query 29](../images/29.png)

### 30. Find all functions that have a docstring
- **Natural Language:** "Show me all functions that are documented."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function) WHERE f.docstring IS NOT NULL AND f.docstring <> '' RETURN f.name, f.file_path LIMIT 50"
  }
  ```

![Query 30](../images/30.png)

### 31. Find all decorated methods in a class
- **Natural Language:** "Find all decorated methods in the `Child` class."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (c:Class {name: 'Child'})-[:CONTAINS]->(m:Function) WHERE m.decorators IS NOT NULL AND size(m.decorators) > 0 RETURN m.name"
  }
  ```

![Query 31](../images/31.png)

### 32. Find the number of functions in each file
- **Natural Language:** "How many functions are in each file?"
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function) RETURN f.file_path, count(f) AS function_count ORDER BY function_count DESC"
  }
  ```

![Query 32](../images/32.png)

### 33. Find all methods that override a parent method
- **Natural Language:** "Find all methods that are overridden from a parent class."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (c:Class)-[:INHERITS]->(p:Class), (c)-[:CONTAINS]->(m:Function), (p)-[:CONTAINS]->(m_parent:Function) WHERE m.name = m_parent.name RETURN m.name as method, c.name as child_class, p.name as parent_class"
  }
  ```

![Query 33](../images/33.png)

### 34. Find all functions that call `super()`
- **Natural Language:** "Find all methods that call their parent's method via `super()`."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function)-[r:CALLS]->() WHERE r.full_call_name STARTS WITH 'super(' RETURN f.name, f.file_path"
  }
  ```

![Query 34](../images/34.png)

### 35. Find all calls to a function with a specific argument
- **Natural Language:** "Find all calls to `helper` with the argument `x`."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH ()-[r:CALLS]->(f:Function {name: 'helper'}) WHERE 'x' IN r.args RETURN r.full_call_name, r.line_number, r.file_path"
  }
  ```

![Query 35](../images/35.png)

### 36. Find all functions that are not called by any other function
- **Natural Language:** "Find all dead code (functions that are never called)."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function) WHERE NOT (()-[:CALLS]->(f)) AND f.is_dependency = false RETURN f.name, f.file_path"
  }
  ```

![Query 36](../images/36.png)

### 37. Find all functions that are called with a specific argument
- **Natural Language:** "Find all calls to `print` with the argument `'hello'`."
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (c:Call) WHERE c.name = 'print' AND 'hello' IN c.args RETURN c.file, c.lineno"
  }
  ```

### 38. Find all direct and indirect callees of a function
- **Natural Language:** "Show me all functions that are eventually called by the `foo` function."
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "find_all_callees",
    "target": "foo",
    "context": "/teamspace/studios/this_studio/demo/CodeGraphContext/tests/sample_project/module_a.py"
  }
  ```

![Query 38](../images/38.png)

### 39. Find all functions that are overridden
- **Natural Language:** "Find all functions that are overridden."
- **Tool:** `analyze_code_relationships`
- **JSON Arguments:**
  ```json
  {
    "query_type": "overrides",
    "target": "foo"
  }
  ```

![Query 39](../images/39.png)

### 40. Find all modules imported by `module_a`
- **Natural Language:** "Find all modules imported by `module_a`."
- **Tool:** `execute_cypher_query`
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:File {name: 'module_a.py'})-[:IMPORTS]->(m:Module) RETURN m.name AS imported_module_name"
  }
  ```

![Query 40](../images/40.png)

### 41. Find large functions that should be refactored
- **Natural Language:** "Find functions with more than 20 lines of code that might need refactoring."
- **Tool:** `execute_cypher_query`
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function)
    WHERE f.end_line - f.line_number > 20
    RETURN f"
  }
  ```

![Query 41](../images/41.png)

### 42. Find recursive functions
- **Natural Language:** "Find all functions that call themselves (recursive functions)."
- **Tool:** `execute_cypher_query`
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH p=(f:Function)-[:CALLS]->(f2:Function)
    WHERE f.name = f2.name AND f.file_path = f2.file_path
    RETURN p"
  }
  ```
![Query 42](../images/42.png)

### 42. Find most connected functions (hub functions)
- **Natural Language:** "Find the functions that are most central to the codebase (called by many and call many others)."
- **Tool:** `execute_cypher_query`
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "MATCH (f:Function)
    OPTIONAL MATCH (f)-[:CALLS]->(callee:Function)
    OPTIONAL MATCH (caller:Function)-[:CALLS]->(f)
    WITH f, count(DISTINCT callee) AS calls_out, count(DISTINCT caller) AS calls_in
    ORDER BY (calls_out + calls_in) DESC
    LIMIT 5
    MATCH p=(f)-[*0..2]-()
    RETURN p"
  }
  ```
![Query 43](../images/43.png)

## Security & Sensitive Data Analysis

### 42. Find potential security vulnerabilities (hardcoded secrets)
- **Natural Language:** "Find potential hardcoded passwords, API keys, or secrets in the codebase."
- **Tool:** `execute_cypher_query`
- **JSON Arguments:**
  ```json
  {
    "cypher_query": "WITH ["password",  "api_key", "apikey",    "secret_token", "token", "auth", "access_key", "private_key", "client_secret", "sessionid", "jwt"] AS keywords
    MATCH (f:Function)
    WHERE ANY(word IN keywords WHERE toLower(f.source_code) CONTAINS word)
    RETURN f"
  }
  ```
```

--------------------------------------------------------------------------------
/docs/site/future_work/index.html:
--------------------------------------------------------------------------------

```html

<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
        <link rel="prev" href="../troubleshooting/">
      
      
        <link rel="next" href="../license/">
      
      
      <link rel="icon" href="../assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.21">
    
    
      
        <title>Future Work - CodeGraphContext</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/main.2a3383ac.min.css">
      
      


    
    
      
    
    
      
        
        
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
        <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
      
    
    
    <script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
    
      

    
    
    
  </head>
  
  
    <body dir="ltr">
  
    
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#ongoing-concerns-and-future-work" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
    
      

  

<header class="md-header md-header--shadow" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="Header">
    <a href=".." title="CodeGraphContext" class="md-header__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>

    </a>
    <label class="md-header__button md-icon" for="__drawer">
      
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">
            CodeGraphContext
          </span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            
              Future Work
            
          </span>
        </div>
      </div>
    </div>
    
    
      <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
    
    
    
      
      
        <label class="md-header__button md-icon" for="__search">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
        </label>
        <div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
      <label class="md-search__icon md-icon" for="__search">
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
      </label>
      <nav class="md-search__options" aria-label="Search">
        
        <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
        </button>
      </nav>
      
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list" role="presentation"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
      
    
    
  </nav>
  
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
          
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              
              <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    



<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href=".." title="CodeGraphContext" class="md-nav__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>

    </a>
    CodeGraphContext
  </label>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href=".." class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Home
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../installation/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Installation
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../use_cases/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Use Cases
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../architecture/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Architecture
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../cli/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    CLI Reference
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../server/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Server
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../core/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Core Concepts
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../tools/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Tools
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../cookbook/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Cookbook
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_10" >
        
          
          <label class="md-nav__link" for="__nav_10" id="__nav_10_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    Contributing
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_10_label" aria-expanded="false">
          <label class="md-nav__title" for="__nav_10">
            <span class="md-nav__icon md-icon"></span>
            Contributing
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../contributing/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Overview
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../contributing_languages/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Adding New Languages
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../troubleshooting/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Troubleshooting
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
    
  
  
  
    <li class="md-nav__item md-nav__item--active">
      
      <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
      
      
        
      
      
        <label class="md-nav__link md-nav__link--active" for="__toc">
          
  
  
  <span class="md-ellipsis">
    Future Work
    
  </span>
  

          <span class="md-nav__icon md-icon"></span>
        </label>
      
      <a href="./" class="md-nav__link md-nav__link--active">
        
  
  
  <span class="md-ellipsis">
    Future Work
    
  </span>
  

      </a>
      
        

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#semantic-search" class="md-nav__link">
    <span class="md-ellipsis">
      Semantic Search
    </span>
  </a>
  
</li>
      
    </ul>
  
</nav>
      
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../license/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    License
    
  </span>
  

      </a>
    </li>
  

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              
              <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#semantic-search" class="md-nav__link">
    <span class="md-ellipsis">
      Semantic Search
    </span>
  </a>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          
            <div class="md-content" data-md-component="content">
              <article class="md-content__inner md-typeset">
                
                  



<h1 id="ongoing-concerns-and-future-work">Ongoing Concerns and Future Work</h1>
<p>This page outlines some of the current limitations of CodeGraphContext and areas for future development.</p>
<h2 id="semantic-search">Semantic Search</h2>
<p>The tool is smart enough to find and analyze a function through millions of code files, but the tool is not yet smart enough to understand that a user searching for “calculate_sum” is also intending to look at the “calculate_addition” function. This level of semantic similarity needs to be researched, developed, tested and eventually implemented by our tool.</p>












                
              </article>
            </div>
          
          
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
        </div>
        
      </main>
      
        <footer class="md-footer">
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-copyright">
  
  
    Made with
    <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
      Material for MkDocs
    </a>
  
</div>
      
    </div>
  </div>
</footer>
      
    </div>
    <div class="md-dialog" data-md-component="dialog">
      <div class="md-dialog__inner md-typeset"></div>
    </div>
    
    
    
      
      <script id="__config" type="application/json">{"base": "..", "features": [], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
    
    
      <script src="../assets/javascripts/bundle.f55a23d4.min.js"></script>
      
    
  </body>
</html>
```

--------------------------------------------------------------------------------
/tests/sample_project_typescript/src/decorators-metadata.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * Decorators and Metadata
 * Demonstrates TypeScript decorators for classes, methods, properties, and parameters
 * Note: Requires experimentalDecorators and emitDecoratorMetadata in tsconfig.json
 * Also requires reflect-metadata package for metadata reflection
 */

import "reflect-metadata";

// ========== Metadata Keys ==========
export const METADATA_KEYS = {
  VALIDATION_RULES: Symbol("validation:rules"),
  ROUTE_INFO: Symbol("route:info"),
  INJECTABLE: Symbol("injectable"),
  CACHE_CONFIG: Symbol("cache:config"),
  LOG_CONFIG: Symbol("log:config"),
  REQUIRED_ROLE: Symbol("required:role"),
  SERIALIZABLE: Symbol("serializable"),
  MAPPED_PROPERTY: Symbol("mapped:property")
};

// ========== Class Decorators ==========
export function Entity(tableName?: string): ClassDecorator {
  return function <T extends Function>(constructor: T) {
    Reflect.defineMetadata("entity:table", tableName || constructor.name.toLowerCase(), constructor);
    return constructor;
  };
}

export function Injectable(): ClassDecorator {
  return function <T extends Function>(constructor: T) {
    Reflect.defineMetadata(METADATA_KEYS.INJECTABLE, true, constructor);
    return constructor;
  };
}

export function Component(config: { selector: string; template?: string }): ClassDecorator {
  return function <T extends Function>(constructor: T) {
    Reflect.defineMetadata("component:config", config, constructor);
    return constructor;
  };
}

export function Serializable(): ClassDecorator {
  return function <T extends Function>(constructor: T) {
    Reflect.defineMetadata(METADATA_KEYS.SERIALIZABLE, true, constructor);
    
    // Add serialize method to prototype if it doesn't exist
    if (!constructor.prototype.serialize) {
      constructor.prototype.serialize = function() {
        const result: any = {};
        const serializableProps = Reflect.getMetadata("serializable:properties", this.constructor) || [];
        
        for (const prop of serializableProps) {
          if (this[prop] !== undefined) {
            result[prop] = this[prop];
          }
        }
        
        return result;
      };
    }
    
    return constructor;
  };
}

// ========== Method Decorators ==========
export function Log(message?: string): MethodDecorator {
  return function (target: any, propertyName: string | symbol, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    const className = target.constructor.name;
    
    descriptor.value = function (...args: any[]) {
      console.log(`[${className}.${String(propertyName)}] ${message || 'Method called'} with args:`, args);
      const result = originalMethod.apply(this, args);
      console.log(`[${className}.${String(propertyName)}] Result:`, result);
      return result;
    };
    
    return descriptor;
  };
}

export function Validate(): MethodDecorator {
  return function (target: any, propertyName: string | symbol, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    
    descriptor.value = function (...args: any[]) {
      // Get validation rules from metadata
      const rules = Reflect.getMetadata(METADATA_KEYS.VALIDATION_RULES, target, propertyName) || [];
      
      for (const rule of rules) {
        if (!rule.validate(...args)) {
          throw new Error(rule.message);
        }
      }
      
      return originalMethod.apply(this, args);
    };
    
    return descriptor;
  };
}

export function Cache(ttl: number = 60000): MethodDecorator {
  const cache = new Map<string, { value: any; expires: number }>();
  
  return function (target: any, propertyName: string | symbol, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    
    descriptor.value = function (...args: any[]) {
      const cacheKey = `${target.constructor.name}.${String(propertyName)}:${JSON.stringify(args)}`;
      const cached = cache.get(cacheKey);
      
      if (cached && Date.now() < cached.expires) {
        console.log(`Cache hit for ${cacheKey}`);
        return cached.value;
      }
      
      const result = originalMethod.apply(this, args);
      cache.set(cacheKey, { value: result, expires: Date.now() + ttl });
      console.log(`Cache set for ${cacheKey}`);
      
      return result;
    };
    
    return descriptor;
  };
}

export function Retry(maxAttempts: number = 3, delay: number = 1000): MethodDecorator {
  return function (target: any, propertyName: string | symbol, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    
    descriptor.value = async function (...args: any[]) {
      for (let attempt = 1; attempt <= maxAttempts; attempt++) {
        try {
          return await originalMethod.apply(this, args);
        } catch (error) {
          if (attempt === maxAttempts) {
            throw error;
          }
          
          console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
          await new Promise(resolve => setTimeout(resolve, delay * attempt));
        }
      }
    };
    
    return descriptor;
  };
}

export function RequireRole(role: string): MethodDecorator {
  return function (target: any, propertyName: string | symbol, descriptor: PropertyDescriptor) {
    Reflect.defineMetadata(METADATA_KEYS.REQUIRED_ROLE, role, target, propertyName);
    
    const originalMethod = descriptor.value;
    
    descriptor.value = function (...args: any[]) {
      const userRole = (this as any).currentUserRole;
      const requiredRole = Reflect.getMetadata(METADATA_KEYS.REQUIRED_ROLE, target, propertyName);
      
      if (!userRole || userRole !== requiredRole) {
        throw new Error(`Access denied. Required role: ${requiredRole}, current role: ${userRole}`);
      }
      
      return originalMethod.apply(this, args);
    };
    
    return descriptor;
  };
}

// ========== Property Decorators ==========
export function Column(options?: { name?: string; type?: string; nullable?: boolean }): PropertyDecorator {
  return function (target: any, propertyKey: string | symbol) {
    const columns = Reflect.getMetadata("entity:columns", target.constructor) || [];
    columns.push({
      propertyKey,
      ...options
    });
    Reflect.defineMetadata("entity:columns", columns, target.constructor);
  };
}

export function Required(): PropertyDecorator {
  return function (target: any, propertyKey: string | symbol) {
    const required = Reflect.getMetadata("validation:required", target.constructor) || [];
    required.push(propertyKey);
    Reflect.defineMetadata("validation:required", required, target.constructor);
  };
}

export function MinLength(length: number): PropertyDecorator {
  return function (target: any, propertyKey: string | symbol) {
    const validations = Reflect.getMetadata("validation:rules", target.constructor) || {};
    validations[propertyKey] = validations[propertyKey] || [];
    validations[propertyKey].push({
      type: "minLength",
      value: length,
      message: `${String(propertyKey)} must be at least ${length} characters long`
    });
    Reflect.defineMetadata("validation:rules", validations, target.constructor);
  };
}

export function Max(value: number): PropertyDecorator {
  return function (target: any, propertyKey: string | symbol) {
    const validations = Reflect.getMetadata("validation:rules", target.constructor) || {};
    validations[propertyKey] = validations[propertyKey] || [];
    validations[propertyKey].push({
      type: "max",
      value: value,
      message: `${String(propertyKey)} must not exceed ${value}`
    });
    Reflect.defineMetadata("validation:rules", validations, target.constructor);
  };
}

export function SerializableProperty(alias?: string): PropertyDecorator {
  return function (target: any, propertyKey: string | symbol) {
    const serializableProps = Reflect.getMetadata("serializable:properties", target.constructor) || [];
    serializableProps.push(propertyKey);
    Reflect.defineMetadata("serializable:properties", serializableProps, target.constructor);
    
    if (alias) {
      const aliases = Reflect.getMetadata("serializable:aliases", target.constructor) || {};
      aliases[propertyKey] = alias;
      Reflect.defineMetadata("serializable:aliases", aliases, target.constructor);
    }
  };
}

export function Computed(): PropertyDecorator {
  return function (target: any, propertyKey: string | symbol) {
    const computed = Reflect.getMetadata("computed:properties", target.constructor) || [];
    computed.push(propertyKey);
    Reflect.defineMetadata("computed:properties", computed, target.constructor);
  };
}

// ========== Parameter Decorators ==========
export function Inject(token?: string): ParameterDecorator {
  return function (target: any, propertyKey: string | symbol | undefined, parameterIndex: number) {
    const existingTokens = Reflect.getMetadata("inject:tokens", target) || [];
    existingTokens[parameterIndex] = token;
    Reflect.defineMetadata("inject:tokens", existingTokens, target);
  };
}

export function ValidateParam(validator: (value: any) => boolean, message: string): ParameterDecorator {
  return function (target: any, propertyKey: string | symbol | undefined, parameterIndex: number) {
    const existingRules = Reflect.getMetadata(METADATA_KEYS.VALIDATION_RULES, target, propertyKey) || [];
    existingRules.push({
      parameterIndex,
      validate: (args: any[]) => validator(args[parameterIndex]),
      message
    });
    Reflect.defineMetadata(METADATA_KEYS.VALIDATION_RULES, existingRules, target, propertyKey);
  };
}

// ========== Accessor Decorators ==========
export function Getter(): MethodDecorator {
  return function (target: any, propertyName: string | symbol, descriptor: PropertyDescriptor) {
    Reflect.defineMetadata("accessor:type", "getter", target, propertyName);
    return descriptor;
  };
}

export function Setter(): MethodDecorator {
  return function (target: any, propertyName: string | symbol, descriptor: PropertyDescriptor) {
    Reflect.defineMetadata("accessor:type", "setter", target, propertyName);
    return descriptor;
  };
}

// ========== Utility Functions for Metadata ==========
export class MetadataReader {
  static getClassMetadata<T>(target: any, key: string | symbol): T | undefined {
    return Reflect.getMetadata(key, target);
  }

  static getMethodMetadata<T>(target: any, method: string, key: string | symbol): T | undefined {
    return Reflect.getMetadata(key, target, method);
  }

  static getPropertyMetadata<T>(target: any, property: string, key: string | symbol): T | undefined {
    return Reflect.getMetadata(key, target, property);
  }

  static getAllMethodNames(target: any): string[] {
    const methods: string[] = [];
    let current = target.prototype;
    
    while (current && current !== Object.prototype) {
      const names = Object.getOwnPropertyNames(current);
      for (const name of names) {
        if (name !== 'constructor' && typeof current[name] === 'function' && !methods.includes(name)) {
          methods.push(name);
        }
      }
      current = Object.getPrototypeOf(current);
    }
    
    return methods;
  }

  static getValidationRules(target: any): any {
    return Reflect.getMetadata("validation:rules", target) || {};
  }

  static getInjectableInfo(target: any): boolean {
    return Reflect.getMetadata(METADATA_KEYS.INJECTABLE, target) || false;
  }
}

// ========== Example Classes Using Decorators ==========
@Entity("users")
@Injectable()
@Serializable()
export class User {
  @Column({ name: "id", type: "integer" })
  @Required()
  @SerializableProperty()
  public id!: number;

  @Column({ name: "username", type: "varchar" })
  @Required()
  @MinLength(3)
  @SerializableProperty()
  public username!: string;

  @Column({ name: "email", type: "varchar" })
  @Required()
  @SerializableProperty("emailAddress")
  public email!: string;

  @Column({ name: "age", type: "integer" })
  @Max(120)
  @SerializableProperty()
  public age!: number;

  private password!: string;
  public currentUserRole?: string;

  constructor(id: number, username: string, email: string, age: number) {
    this.id = id;
    this.username = username;
    this.email = email;
    this.age = age;
  }

  @Log("Getting user info")
  @Cache(30000)
  public getInfo(): string {
    return `User: ${this.username} (${this.email})`;
  }

  @Validate()
  public updateAge(
    @ValidateParam((value: number) => value > 0 && value <= 120, "Age must be between 1 and 120")
    newAge: number
  ): void {
    this.age = newAge;
  }

  @RequireRole("admin")
  public deleteUser(): string {
    return `User ${this.username} has been deleted`;
  }

  @Retry(3, 1000)
  public async syncWithExternalService(): Promise<string> {
    // Simulate an operation that might fail
    if (Math.random() > 0.7) {
      throw new Error("External service unavailable");
    }
    return "Sync completed successfully";
  }

  @Computed()
  public get isAdult(): boolean {
    return this.age >= 18;
  }
}

@Component({ selector: "user-service", template: "<div>User Service</div>" })
export class UserService {
  constructor(
    @Inject("userRepository") private userRepo: any,
    @Inject("logger") private logger: any
  ) {}

  @Log("Finding user by ID")
  public async findById(id: number): Promise<User | null> {
    // Simulate database lookup
    await new Promise(resolve => setTimeout(resolve, 100));
    return new User(id, `user${id}`, `user${id}@example.com`, 25);
  }
}

// ========== Validation Engine ==========
export class ValidationEngine {
  static validate(instance: any): { valid: boolean; errors: string[] } {
    const errors: string[] = [];
    const constructor = instance.constructor;
    
    // Check required properties
    const required = Reflect.getMetadata("validation:required", constructor) || [];
    for (const prop of required) {
      if (instance[prop] === undefined || instance[prop] === null) {
        errors.push(`${prop} is required`);
      }
    }
    
    // Check validation rules
    const rules = Reflect.getMetadata("validation:rules", constructor) || {};
    for (const [prop, propRules] of Object.entries(rules)) {
      const value = instance[prop];
      for (const rule of (propRules as any[])) {
        if (rule.type === "minLength" && typeof value === "string" && value.length < rule.value) {
          errors.push(rule.message);
        }
        if (rule.type === "max" && typeof value === "number" && value > rule.value) {
          errors.push(rule.message);
        }
      }
    }
    
    return {
      valid: errors.length === 0,
      errors
    };
  }
}

// ========== Usage Examples ==========
export const decoratorExamples = {
  // Create a user instance
  user: new User(1, "john_doe", "john@example.com", 30),
  
  // Validation examples
  validateUser: (user: User) => ValidationEngine.validate(user),
  
  // Metadata reader examples
  getEntityInfo: (target: any) => ({
    tableName: MetadataReader.getClassMetadata(target, "entity:table"),
    columns: MetadataReader.getClassMetadata(target, "entity:columns"),
    isInjectable: MetadataReader.getInjectableInfo(target)
  }),
  
  // Service instance
  userService: new UserService("mockUserRepo", "mockLogger")
};

// Example usage of the decorated user
decoratorExamples.user.currentUserRole = "admin";

// This will use caching
console.log(decoratorExamples.user.getInfo());

// This will validate the parameter
try {
  decoratorExamples.user.updateAge(25);
} catch (error) {
  console.error("Validation error:", error);
}

// Get metadata about the User class
console.log("User metadata:", decoratorExamples.getEntityInfo(User));
```

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

```python

from pathlib import Path
from typing import Any, Dict, Optional, Tuple
from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger

CPP_QUERIES = {
    "functions": """
        (function_definition
            declarator: (function_declarator
                declarator: (identifier) @name
            )
        ) @function_node
    """,
    "classes": """
        (class_specifier
            name: (type_identifier) @name
        ) @class
    """,
    "imports": """
        (preproc_include
            path: [
                (string_literal) @path
                (system_lib_string) @path
            ]
        ) @import
    """,
    "calls": """
        (call_expression
            function: [
                (identifier) @function_name
                (field_expression
                    field: (field_identifier) @method_name
                )
            ]
        arguments: (argument_list) @args
    )
    """,
    "enums":"""
        (enum_specifier
            name: (type_identifier) @name
            body: (enumerator_list
                (enumerator
                    name: (identifier) @value
                    )*
                )? @body
        ) @enum
    """,
    "structs":"""
        (struct_specifier
            name: (type_identifier) @name
            body: (field_declaration_list)? @body
        ) @struct
    """,
    "unions": """
    (union_specifier
    name: (type_identifier)? @name
    body: (field_declaration_list
        (field_declaration
            declarator: [
                (field_identifier) @value
                (pointer_declarator (field_identifier) @value)
                (array_declarator (field_identifier) @value)
                ]
            )*
        )? @body
    ) @union
  
    """,
    "macros": """
        (preproc_def
            name: (identifier) @name
        ) @macro
    """,
    "variables": """
    (declaration
        declarator: (init_declarator
                        declarator: (identifier) @name))

    (declaration
        declarator: (init_declarator
                        declarator: (pointer_declarator
                            declarator: (identifier) @name)))
    """,
    "lambda_assignments": """
    ; Match a lambda assigned to a variable
    (declaration
        declarator: (init_declarator
            declarator: (identifier) @name
            value: (lambda_expression) @lambda_node))
    """
    
}

class CppTreeSitterParser:
    """A C++-specific parser using tree-sitter."""

    def __init__(self, generic_parser_wrapper):
        self.generic_parser_wrapper = generic_parser_wrapper
        self.language_name = "cpp"
        self.language = generic_parser_wrapper.language
        self.parser = generic_parser_wrapper.parser

        self.queries = {
            name: self.language.query(query_str)
            for name, query_str in CPP_QUERIES.items()
        }

    def _get_node_text(self, node) -> str:
        return node.text.decode('utf-8')

    def parse(self, file_path: Path, is_dependency: bool = False, **kwargs) -> Dict:
        """Parses a C++ file and returns its structure."""
        with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
            source_code = f.read()

        tree = self.parser.parse(bytes(source_code, "utf8"))
        root_node = tree.root_node

        functions = self._find_functions(root_node)
        functions.extend(self._find_lambda_assignments(root_node))
        function_calls = self._find_calls(root_node)
        classes = self._find_classes(root_node)
        imports = self._find_imports(root_node)
        structs = self._find_structs(root_node)
        enums = self._find_enums(root_node)
        unions = self._find_unions(root_node)
        macros = self._find_macros(root_node)
        variables = self._find_variables(root_node)
        
        return {
            "file_path": str(file_path),
            "functions": functions,
            "classes": classes,
            "structs": structs,
            "enums": enums,
            "unions": unions,
            "macros": macros,
            "variables": variables,  
            "declarations": [], # Placeholder
            "imports": imports,
            "function_calls": function_calls, 
            "is_dependency": is_dependency,
            "lang": self.language_name,
        }

    def _find_functions(self, root_node):
        functions = []
        query = self.queries['functions']
        for match in query.captures(root_node):
            capture_name = match[1]
            node = match[0]
            if capture_name == 'name':
                func_node = node.parent.parent.parent
                name = self._get_node_text(node)
                functions.append({
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "end_line": func_node.end_point[0] + 1,
                    "source_code": self._get_node_text(func_node),
                    "args": [], # Placeholder
                })
        return functions

    def _find_classes(self, root_node):
        classes = []
        query = self.queries['classes']
        for match in query.captures(root_node):
            capture_name = match[1]
            node = match[0]
            if capture_name == 'name':
                class_node = node.parent
                name = self._get_node_text(node)
                classes.append({
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "end_line": class_node.end_point[0] + 1,
                    "source_code": self._get_node_text(class_node),
                    "bases": [], # Placeholder
                })
        return classes

    def _find_imports(self, root_node):
        imports = []
        query = self.queries['imports']
        for match in query.captures(root_node):
            capture_name = match[1]
            node = match[0]
            if capture_name == 'path':
                path = self._get_node_text(node).strip('<>')
                imports.append({
                    "name": path,
                    "full_import_name": path,
                    "line_number": node.start_point[0] + 1,
                    "alias": None,
                })
        return imports
    
    def _find_enums(self, root_node):
        enums = []
        query = self.queries['enums']
        for node, capture_name in query.captures(root_node):
            if capture_name == 'name':
                name = self._get_node_text(node)
                enum_node = node.parent
                enums.append({
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "end_line": enum_node.end_point[0] + 1,
                    "source_code": self._get_node_text(enum_node),
                })
        return enums
 
    def _find_structs(self, root_node):
        structs = []
        query = self.queries['structs']
        for node, capture_name in query.captures(root_node):
            if capture_name == 'name':
                name = self._get_node_text(node)
                struct_node = node.parent
                structs.append({
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "end_line": struct_node.end_point[0] + 1,
                    "source_code": self._get_node_text(struct_node),
                })
        return structs

    def _find_unions(self, root_node):
        unions = []
        query = self.queries['unions']
        for node, capture_name in query.captures(root_node):
            if capture_name == 'name':
                name = self._get_node_text(node)
                union_node = node.parent
                unions.append({
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "end_line": union_node.end_point[0] + 1,
                    "source_code": self._get_node_text(union_node),
                })
        return unions

    def _find_macros(self, root_node):
        macros = []
        query = self.queries['macros']
        for match in query.captures(root_node):
            capture_name = match[1]
            node = match[0]
            if capture_name == 'name':
                macro_node = node.parent
                name = self._get_node_text(node)
                macros.append({
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "end_line": macro_node.end_point[0] + 1,
                    "source_code": self._get_node_text(macro_node),
                })
        return macros
    
    def _find_lambda_assignments(self, root_node):
        functions = []
        query = self.queries.get('lambda_assignments')
        if not query: return []

        for match in query.captures(root_node):
            capture_name = match[1]
            node = match[0]

            if capture_name == 'name':
                assignment_node = node.parent
                lambda_node = assignment_node.child_by_field_name('value')
            if lambda_node is None or lambda_node.type != 'lambda_expression':
                continue

            params_node = lambda_node.child_by_field_name('declarator')
            if params_node:
                params_node = params_node.child_by_field_name('parameters')
                name = self._get_node_text(node)
                params_node = lambda_node.child_by_field_name('parameters')
                
                context, context_type, _ = self._get_parent_context(assignment_node)
                class_context, _, _ = self._get_parent_context(assignment_node, types=('class_definition',))

                func_data = {
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "end_line": assignment_node.end_point[0] + 1,
                    "args": [p for p in [self._get_node_text(p) for p in params_node.children if p.type == 'identifier'] if p] if params_node else [],
                    "source": self._get_node_text(assignment_node),
                    "source_code": self._get_node_text(assignment_node),
                    "docstring": None,
                    "cyclomatic_complexity": 1,
                    "context": context,
                    "context_type": context_type,
                    "class_context": class_context,
                    "decorators": [],
                    "lang": self.language_name,
                    "is_dependency": False,
                }
                functions.append(func_data)
        return functions
    
    def _find_variables(self, root_node):
        variables = []
        query = self.queries['variables']
        for match in query.captures(root_node):
            capture_name = match[1]
            node = match[0]

            if capture_name == 'name':
                assignment_node = node.parent

                # Skip lambda assignments, they are handled by _find_lambda_assignments
                right_node = assignment_node.child_by_field_name('value')
                if right_node and right_node.type == 'lambda_expression':
                    continue

                name = self._get_node_text(node)
                value = self._get_node_text(right_node) if right_node else None
                
                type_node = assignment_node.child_by_field_name('type')
                type_text = self._get_node_text(type_node) if type_node else None

                context, _, _ = self._get_parent_context(node)
                class_context, _, _ = self._get_parent_context(node, types=('class_definition',))

                variable_data = {
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "value": value,
                    "type": type_text,
                    "context": context,
                    "class_context": class_context,
                    "lang": self.language_name,
                    "is_dependency": False,
                }
                variables.append(variable_data)
        return variables
    
    def _get_parent_context(self, node, types=('function_definition', 'class_definition')):
        curr = node.parent
        while curr:
            if curr.type in types:
                name_node = curr.child_by_field_name('name')
                return self._get_node_text(name_node) if name_node else None, curr.type, curr.start_point[0] + 1
            curr = curr.parent
        return None, None, None
    
    def _find_calls(self, root_node):
        calls = []
        query = self.queries['calls']
        for node, capture_name in query.captures(root_node):
            if capture_name == "function_name":
                func_name = self._get_node_text(node)
                func_node = node.parent.parent  # function_declarator -> function_definition
                full_name = self._get_full_name(func_node) or func_name

                # Find return type node (captured separately)
                return_type_node = None
                for n, cap in query.captures(func_node):
                    if cap == "return_type":
                        return_type_node = n
                        break
                return_type = self._get_node_text(return_type_node) if return_type_node else None

                # Extract parameters
                args = []
                parameters_node = func_node.child_by_field_name("declarator")
                if parameters_node:
                    param_list_node = parameters_node.child_by_field_name("parameters")
                    if param_list_node:
                        for param in param_list_node.children:
                            if param.type == "parameter_declaration":
                                type_node = param.child_by_field_name("type")
                                name_node = param.child_by_field_name("declarator")

                                param_type = self._get_node_text(type_node) if type_node else None
                                param_name = self._get_node_text(name_node) if name_node else None

                                args.append({
                                    "type": param_type,
                                    "name": param_name
                                })
                

                # Get context info (function may be inside class)
                context, _, _ = self._get_parent_context(node)
                class_context, _, _ = self._get_parent_context(node, types=("class_definition",))

                call_data = {
                    "name": func_name,
                    "full_name": full_name,
                    "line_number": node.start_point[0] + 1,
                    "args": args,
                    "inferred_obj_type": None,
                    "context": context,
                    "class_context": class_context,
                    "lang": self.language_name,
                    "is_dependency": False,
                }
                calls.append(call_data)
        return calls
    
    def _get_full_name(self, node):
        "Builds a fully qualified name for a function or call node."

        name_parts = []

        # Move upward and collect parent scopes
        curr = node
        while curr:
            if curr.type in ("function_definition", "function_declarator"):
                id_node = curr.child_by_field_name("declarator")
                if id_node and id_node.type == "identifier":
                    name_parts.insert(0, id_node.text.decode("utf8"))
            elif curr.type == "class_specifier":
                name_node = curr.child_by_field_name("name")
                if name_node:
                    name_parts.insert(0, name_node.text.decode("utf8"))
            elif curr.type == "namespace_definition":
                name_node = curr.child_by_field_name("name")
                if name_node:
                    name_parts.insert(0, name_node.text.decode("utf8"))
            curr = curr.parent

        return "::".join(name_parts) if name_parts else None


def pre_scan_cpp(files: list[Path], parser_wrapper) -> dict:
    """
    Quickly scans C++ files to build a map of top-level class, struct, and function names
    to their file paths.
    """
    imports_map = {}

    query_str = """
        (class_specifier name: (type_identifier) @name)
        (struct_specifier name: (type_identifier) @name)
        (function_definition declarator: (function_declarator declarator: (identifier) @name))
    """
    query = parser_wrapper.language.query(query_str)

    for file_path in files:
        try:
            with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                source_bytes = f.read().encode("utf-8")
                tree = parser_wrapper.parser.parse(source_bytes)

            for node, capture_name in query.captures(tree.root_node):
                if capture_name == "name":
                    name = node.text.decode("utf-8")
                    imports_map.setdefault(name, []).append(str(file_path.resolve()))
        except Exception as e:
            warning_logger(f"Tree-sitter pre-scan failed for {file_path}: {e}")

    return imports_map

```

--------------------------------------------------------------------------------
/src/codegraphcontext/tools/package_resolver.py:
--------------------------------------------------------------------------------

```python
# src/codegraphcontext/tools/package_resolver.py
import importlib
import stdlibs
from pathlib import Path
import subprocess
from typing import Optional

from ..utils.debug_log import debug_log

def _get_python_package_path(package_name: str) -> Optional[str]:
    """
    Finds the local installation path of a Python package.
    """
    try:
        debug_log(f"Getting local path for Python package: {package_name}")
        module = importlib.import_module(package_name)
        if hasattr(module, '__file__') and module.__file__:
            module_file = Path(module.__file__)
            if module_file.name == '__init__.py':
                return str(module_file.parent)
            elif package_name in stdlibs.module_names:
                return str(module_file)
            else:
                return str(module_file.parent)
        elif hasattr(module, '__path__'):
            if isinstance(module.__path__, list) and module.__path__:
                return str(Path(module.__path__[0]))
            else:
                return str(Path(str(module.__path__)))
        return None
    except ImportError:
        return None
    except Exception as e:
        debug_log(f"Error getting local path for {package_name}: {e}")
        return None

def _get_npm_package_path(package_name: str) -> Optional[str]:
    """
    Finds the local installation path of a Node.js package using `npm root`.
    """
    try:
        debug_log(f"Getting local path for npm package: {package_name}")
        local_path = Path(f"./node_modules/{package_name}")
        if local_path.exists():
            return str(local_path.resolve())

        result = subprocess.run(["npm", "root", "-g"], capture_output=True, text=True)
        if result.returncode == 0:
            global_root = result.stdout.strip()
            package_path = Path(global_root) / package_name
            if package_path.exists():
                return str(package_path.resolve())
        return None
    except Exception as e:
        debug_log(f"Error getting npm package path for {package_name}: {e}")
        return None

def _get_typescript_package_path(package_name: str) -> Optional[str]:
    """
    Finds the local installation path of a TypeScript package.
    TypeScript packages are typically npm packages, so this uses the same logic as npm.
    """
    try:
        debug_log(f"Getting local path for TypeScript package: {package_name}")
        
        # Check local node_modules first
        local_path = Path(f"./node_modules/{package_name}")
        if local_path.exists():
            return str(local_path.resolve())

        # Check global npm packages
        result = subprocess.run(["npm", "root", "-g"], capture_output=True, text=True, timeout=5)
        if result.returncode == 0:
            global_root = result.stdout.strip()
            package_path = Path(global_root) / package_name
            if package_path.exists():
                return str(package_path.resolve())
        
        return None
    except subprocess.TimeoutExpired:
        debug_log(f"npm command timed out for {package_name}")
        return None
    except Exception as e:
        debug_log(f"Error getting TypeScript package path for {package_name}: {e}")
        return None

def _get_java_package_path(package_name: str) -> Optional[str]:
    """
    Finds the local installation path of a Java package (JAR).
    Searches in Maven and Gradle cache directories.
    
    Args:
        package_name: Package name in format "groupId:artifactId" (e.g., "com.google.code.gson:gson")
                     or just "artifactId" for simple search.
    """
    try:
        debug_log(f"Getting local path for Java package: {package_name}")
        
        # Parse package name - expect format "groupId:artifactId" or just "artifactId"
        if ':' in package_name:
            group_id, artifact_id = package_name.split(':', 1)
            # Convert group_id dots to path separators (e.g., com.google.gson -> com/google/gson)
            group_path = group_id.replace('.', '/')
        else:
            # If only artifact_id provided, search for it
            artifact_id = package_name
            group_path = None
        
        search_paths = []
        
        # Maven repository (~/.m2/repository)
        maven_repo = Path.home() / ".m2" / "repository"
        if maven_repo.exists():
            if group_path:
                # Search for specific group/artifact
                package_path = maven_repo / group_path / artifact_id
                if package_path.exists():
                    # Find the latest version directory
                    version_dirs = [d for d in package_path.iterdir() if d.is_dir()]
                    if version_dirs:
                        # Sort by name (assumes semantic versioning) and get the latest
                        latest_version = sorted(version_dirs, key=lambda x: x.name)[-1]
                        return str(latest_version.resolve())
            else:
                # Search for artifact_id in the entire Maven repo
                search_paths.append(maven_repo)
        
        # Gradle cache (~/.gradle/caches/modules-2/files-2.1)
        gradle_cache = Path.home() / ".gradle" / "caches" / "modules-2" / "files-2.1"
        if gradle_cache.exists():
            if group_path:
                group_id_full = group_id if ':' in package_name else None
                if group_id_full:
                    package_path = gradle_cache / group_id_full / artifact_id
                    if package_path.exists():
                        # Find the latest version directory
                        version_dirs = [d for d in package_path.iterdir() if d.is_dir()]
                        if version_dirs:
                            latest_version = sorted(version_dirs, key=lambda x: x.name)[-1]
                            # Gradle stores files in hash subdirectories
                            hash_dirs = [d for d in latest_version.iterdir() if d.is_dir()]
                            if hash_dirs:
                                return str(hash_dirs[0].resolve())
            else:
                search_paths.append(gradle_cache)
        
        # If group_path wasn't provided or not found, search in the cache directories
        if not group_path or search_paths:
            for base_path in search_paths:
                for jar_file in base_path.rglob(f"*{artifact_id}*.jar"):
                    return str(jar_file.parent.resolve())
        
        # Check local lib directories
        local_lib_paths = [
            Path("./lib"),
            Path("./libs"),
            Path("/usr/local/lib/java"),
            Path("/opt/java/lib"),
        ]
        
        for lib_path in local_lib_paths:
            if not lib_path.exists():
                continue
            
            # Look for JAR files matching the artifact name
            for jar_file in lib_path.glob(f"*{artifact_id}*.jar"):
                return str(jar_file.resolve())
        
        return None
    except Exception as e:
        debug_log(f"Error getting Java package path for {package_name}: {e}")
def _get_c_package_path(package_name: str) -> Optional[str]:
    """
    Finds the local installation path of a C package.
    """
    try:
        debug_log(f"Getting local path for C package: {package_name}")
        
        # Try using pkg-config to find the package
        try:
            result = subprocess.run(
                ["pkg-config", "--variable=includedir", package_name],
                capture_output=True,
                text=True,
                timeout=5
            )
            if result.returncode == 0 and result.stdout.strip():
                include_dir = Path(result.stdout.strip())
                package_path = include_dir / package_name
                if package_path.exists():
                    return str(package_path.resolve())
                if include_dir.exists():
                    return str(include_dir.resolve())
        except (subprocess.TimeoutExpired, FileNotFoundError):
            debug_log(f"pkg-config not available or timed out for {package_name}")
        
        # Search in standard system include directories
        common_include_paths = [
            "/usr/include",
            "/usr/local/include",
            "/opt/homebrew/include",
            "/opt/local/include",
            Path.home() / ".local" / "include",
        ]
        
        for base_path in common_include_paths:
            base_path = Path(base_path)
            if not base_path.exists():
                continue
            
            # Check if package exists as a directory
            package_dir = base_path / package_name
            if package_dir.exists() and package_dir.is_dir():
                return str(package_dir.resolve())
            
            # Check for header files with package name
            header_file = base_path / f"{package_name}.h"
            if header_file.exists():
                return str(header_file.resolve())
        
        # Check current directory for local installations
        local_package = Path(f"./{package_name}")
        if local_package.exists():
            return str(local_package.resolve())
        
        return None
    except Exception as e:
        debug_log(f"Error getting C package path for {package_name}: {e}")
        return None
    
def _get_ruby_package_path(package_name: str) -> Optional[str]:
    """
    Finds the local installation path of a Ruby gem.
    """
    try:
        debug_log(f"Getting local path for Ruby gem: {package_name}")
        result = subprocess.run(
            ["gem", "which", package_name],
            capture_output=True,
            text=True,
            timeout=5
        )
        if result.returncode == 0 and result.stdout.strip():
            gem_path = Path(result.stdout.strip())
            if gem_path.exists():
                lib_dir = gem_path.parent if gem_path.is_file() else gem_path
                # If we are inside a gem (…/gems/foo-x.y.z/lib/foo.rb), prefer the lib/ dir:
                if (lib_dir.name == "lib") and lib_dir.is_dir():
                    return str(lib_dir.resolve())
                # Try parent/lib in case `gem which` returned .../lib/foo.rb
                if (lib_dir / "lib").is_dir():
                    return str((lib_dir / "lib").resolve())
                # Fallback: just return the directory containing the file (stdlib case like 'json')
                return str(lib_dir.resolve())
        return None
    except (subprocess.TimeoutExpired, FileNotFoundError):
        debug_log(f"gem command not available or timed out for {package_name}")
        return None
    except Exception as e:
        debug_log(f"Error getting Ruby gem path for {package_name}: {e}")
        return None

def _get_go_package_path(package_name: str) -> Optional[str]:
    """
    Finds the local installation path of a Go package using `go list`.
    Tries multiple approaches in sequence to handle different package scenarios:
      1) package dir:   go list -f '{{.Dir}}' <pkg>             (works for stdlib, GOPATH, or module subpackages)
      2) module root:   go list -m -f '{{.Dir}}' <module>       (works for full module paths)
      3) force mod:     go list -mod=mod -f '{{.Dir}}' <pkg>    (works when outside a module context)
      4) GOROOT check:  for standard library packages
      5) GOPATH check:  for packages in GOPATH
    """

    def _first_existing_dir(output: str) -> Optional[str]:
        for line in (l.strip().strip("'\"") for l in output.splitlines() if l.strip()):
            p = Path(line)
            if p.exists() and p.is_dir():
                return str(p.resolve())
        return None

    try:
        debug_log(f"Getting local path for Go package: {package_name}")
        
        # 1. Package directory (works for stdlib, GOPATH, or subpackages)
        cp = subprocess.run(
            ["go", "list", "-f", "{{.Dir}}", package_name],
            capture_output=True, text=True, timeout=15
        )
        if cp.returncode == 0:
            d = _first_existing_dir(cp.stdout)
            if d:
                return d

        # 2. Module root directory (where go.mod lives)
        cp2 = subprocess.run(
            ["go", "list", "-m", "-f", "{{.Dir}}", package_name],
            capture_output=True, text=True, timeout=15
        )
        if cp2.returncode == 0:
            d = _first_existing_dir(cp2.stdout)
            if d:
                debug_log(f"Found Go module {package_name} at {d}")
                return d

        # 3. Retry forcing module mode
        cp3 = subprocess.run(
            ["go", "list", "-mod=mod", "-f", "{{.Dir}}", package_name],
            capture_output=True, text=True, timeout=15
        )
        if cp3.returncode == 0:
            d = _first_existing_dir(cp3.stdout)
            if d:
                return d
        
        # 4. Check in GOROOT for standard library packages
        try:
            cp4 = subprocess.run(
                ["go", "env", "GOROOT"],
                capture_output=True, text=True, timeout=5
            )
            if cp4.returncode == 0:
                goroot = cp4.stdout.strip()
                if goroot:
                    std_lib_path = Path(goroot) / "src" / package_name
                    if std_lib_path.exists() and std_lib_path.is_dir():
                        return str(std_lib_path.resolve())
        except Exception as e:
            debug_log(f"Error checking GOROOT for {package_name}: {e}")
        
        # 5. Check in GOPATH as fallback
        try:
            cp5 = subprocess.run(
                ["go", "env", "GOPATH"],
                capture_output=True, text=True, timeout=5
            )
            if cp5.returncode == 0:
                gopath = cp5.stdout.strip()
                if gopath:
                    gopath_lib_path = Path(gopath) / "src" / package_name
                    if gopath_lib_path.exists() and gopath_lib_path.is_dir():
                        debug_log(f"Found Go package in GOPATH {package_name} at {gopath_lib_path}")
                        return str(gopath_lib_path.resolve())
        except Exception as e:
            debug_log(f"Error checking GOPATH for {package_name}: {e}")

        debug_log(f"Could not find Go package: {package_name}")
        return None

    except (subprocess.TimeoutExpired, FileNotFoundError):
        debug_log(f"go command not available or timed out for {package_name}")
        return None
    except Exception as e:
        debug_log(f"Error getting Go package path for {package_name}: {e}")
        return None

def _get_php_package_path(package_name: str) -> Optional[str]:
    try:
        debug_log(f"Getting local path for PHP package: {package_name}")
        
        local_vendor = Path("./vendor") / package_name
        if local_vendor.exists() and local_vendor.is_dir():
            return str(local_vendor.resolve())
        
        current_dir = Path.cwd()
        for parent in [current_dir] + list(current_dir.parents):
            vendor_path = parent / "vendor" / package_name
            if vendor_path.exists() and vendor_path.is_dir():
                return str(vendor_path.resolve())
            
            if (parent / "composer.json").exists():
                break
        
        composer_home = Path.home() / ".composer" / "vendor" / package_name
        if composer_home.exists() and composer_home.is_dir():
            return str(composer_home.resolve())
        
        composer_global = Path.home() / ".config" / "composer" / "vendor" / package_name
        if composer_global.exists() and composer_global.is_dir():
            return str(composer_global.resolve())
        
        return None
    except Exception as e:
        debug_log(f"Error getting PHP package path for {package_name}: {e}")
        return None


def get_local_package_path(package_name: str, language: str) -> Optional[str]:
    """
    Dispatches to the correct package path finder based on the language.
    """
    finders = {
        "python": _get_python_package_path,
        "javascript": _get_npm_package_path,
        "typescript": _get_typescript_package_path,
        "java": _get_java_package_path,
        "c": _get_c_package_path,
        "go": _get_go_package_path,  
        "ruby": _get_ruby_package_path,
        "php": _get_php_package_path,
        "cpp": _get_cpp_package_path,

    }
    finder = finders.get(language)
    if finder:
        return finder(package_name)
    return None

def _get_cpp_package_path(package_name: str) -> Optional[str]:
    """
    C++ package ka local path find karta hai.
    Pehle pkg-config try karta hai, fir common system paths check karta hai.
    """
    import subprocess
    import os

    # Try pkg-config
    try:
        result = subprocess.run(
            ["pkg-config", "--variable=includedir", package_name],
            capture_output=True,
            text=True,
            check=False
        )
        path = result.stdout.strip()
        if path and os.path.exists(path):
            return path
    except FileNotFoundError:
        pass

    # Common system include/lib folders
    common_paths = [
        f"/usr/include/{package_name}",
        f"/usr/local/include/{package_name}",
        f"/usr/lib/{package_name}",
        f"/usr/local/lib/{package_name}",
    ]
    for path in common_paths:
        if os.path.exists(path):
            return path

    return None


```

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

```python
from pathlib import Path
from typing import Any, Dict, Optional, Tuple
from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger


GO_QUERIES = {
    "functions": """
        (function_declaration
            name: (identifier) @name
            parameters: (parameter_list) @params
        ) @function_node
        
        (method_declaration
            receiver: (parameter_list) @receiver
            name: (field_identifier) @name
            parameters: (parameter_list) @params
        ) @function_node
    """,
    "structs": """
        (type_declaration
            (type_spec
                name: (type_identifier) @name
                type: (struct_type) @struct_body
            )
        ) @struct_node
    """,
    "interfaces": """
        (type_declaration
            (type_spec
                name: (type_identifier) @name
                type: (interface_type) @interface_body
            )
        ) @interface_node
    """,
    "imports": """
        (import_declaration
            (import_spec
                path: (interpreted_string_literal) @path
            )
        ) @import
        
        (import_declaration
            (import_spec
                name: (package_identifier) @alias
                path: (interpreted_string_literal) @path
            )
        ) @import_alias
    """,
    "calls": """
        (call_expression
            function: (identifier) @name
        )
        (call_expression
            function: (selector_expression
                field: (field_identifier) @name
            )
        )
    """,
    "variables": """
        (var_declaration
            (var_spec
                name: (identifier) @name
            )
        )
        (short_var_declaration
            left: (expression_list
                (identifier) @name
            )
        )
    """,
}

class GoTreeSitterParser:
    """A Go-specific parser using tree-sitter, encapsulating language-specific logic."""

    def __init__(self, generic_parser_wrapper):
        self.generic_parser_wrapper = generic_parser_wrapper
        self.language_name = generic_parser_wrapper.language_name
        self.language = generic_parser_wrapper.language
        self.parser = generic_parser_wrapper.parser

        self.queries = {
            name: self.language.query(query_str)
            for name, query_str in GO_QUERIES.items()
        }

    def _get_node_text(self, node) -> str:
        return node.text.decode('utf-8')

    def _get_parent_context(self, node, types=('function_declaration', 'method_declaration', 'type_declaration')):
        curr = node.parent
        while curr:
            if curr.type in types:
                if curr.type == 'type_declaration':
                    type_spec = curr.child_by_field_name('type_spec')
                    if type_spec:
                        name_node = type_spec.child_by_field_name('name')
                        return self._get_node_text(name_node) if name_node else None, curr.type, curr.start_point[0] + 1
                else:
                    name_node = curr.child_by_field_name('name')
                    return self._get_node_text(name_node) if name_node else None, curr.type, curr.start_point[0] + 1
            curr = curr.parent
        return None, None, None

    def _calculate_complexity(self, node):
        complexity_nodes = {
            "if_statement", "for_statement", "switch_statement", "case_clause",
            "expression_switch_statement", "type_switch_statement",
            "binary_expression", "call_expression"
        }
        count = 1

        def traverse(n):
            nonlocal count
            if n.type in complexity_nodes:
                count += 1
            for child in n.children:
                traverse(child)

        traverse(node)
        return count

    def _get_docstring(self, func_node):
        """Extract Go doc comment preceding the function."""
        prev_sibling = func_node.prev_sibling
        while prev_sibling and prev_sibling.type in ('comment', '\n', ' '):
            if prev_sibling.type == 'comment':
                comment_text = self._get_node_text(prev_sibling)
                if comment_text.startswith('//'):
                    return comment_text.strip()
            prev_sibling = prev_sibling.prev_sibling
        return None

    def parse(self, file_path: Path, is_dependency: bool = False) -> Dict:
        """Parses a file and returns its structure in a standardized dictionary format."""
        # This method orchestrates the parsing of a single file.
        # It calls specialized `_find_*` methods for each language construct.
        # The returned dictionary should map a specific key (e.g., 'functions', 'interfaces')
        # to a list of dictionaries, where each dictionary represents a single code construct.
        # The GraphBuilder will then use these keys to create nodes with corresponding labels.
        with open(file_path, "r", encoding="utf-8") as f:
            source_code = f.read()

        tree = self.parser.parse(bytes(source_code, "utf8"))
        root_node = tree.root_node

        functions = self._find_functions(root_node)
        structs = self._find_structs(root_node)
        interfaces = self._find_interfaces(root_node)
        imports = self._find_imports(root_node)
        function_calls = self._find_calls(root_node)
        variables = self._find_variables(root_node)

        return {
            "file_path": str(file_path),
            "functions": functions,
            "classes": structs,
            "interfaces": interfaces,
            "variables": variables,
            "imports": imports,
            "function_calls": function_calls,
            "is_dependency": is_dependency,
            "lang": self.language_name,
        }

    def _find_functions(self, root_node):
        functions = []
        query = self.queries['functions']

        captures_by_function = {}

        for node, capture_name in query.captures(root_node):
            if capture_name == 'function_node':
                func_id = id(node)
                if func_id not in captures_by_function:
                    captures_by_function[func_id] = {
                        'node': node,
                        'name': None,
                        'params': None,
                        'receiver': None
                    }
            elif capture_name == 'name':
                func_node = self._find_function_node_for_name(node)
                if func_node:
                    func_id = id(func_node)
                    if func_id not in captures_by_function:
                        captures_by_function[func_id] = {
                            'node': func_node,
                            'name': None,
                            'params': None,
                            'receiver': None
                        }
                    captures_by_function[func_id]['name'] = self._get_node_text(node)
            elif capture_name == 'params':
                func_node = self._find_function_node_for_params(node)
                if func_node:
                    func_id = id(func_node)
                    if func_id not in captures_by_function:
                        captures_by_function[func_id] = {
                            'node': func_node,
                            'name': None,
                            'params': None,
                            'receiver': None
                        }
                    captures_by_function[func_id]['params'] = node
            elif capture_name == 'receiver':
                func_node = node.parent
                if func_node and func_node.type == 'method_declaration':
                    func_id = id(func_node)
                    if func_id not in captures_by_function:
                        captures_by_function[func_id] = {
                            'node': func_node,
                            'name': None,
                            'params': None,
                            'receiver': None
                        }
                    captures_by_function[func_id]['receiver'] = node

        for func_id, data in captures_by_function.items():
            if data['name']:
                func_node = data['node']
                name = data['name']

                args = []
                if data['params']:
                    args = self._extract_parameters(data['params'])

                receiver_type = None
                if data['receiver']:
                    receiver_type = self._extract_receiver(data['receiver'])

                context, context_type, context_line = self._get_parent_context(func_node)
                class_context = receiver_type or (context if context_type == 'type_declaration' else None)

                docstring = self._get_docstring(func_node)

                func_data = {
                    "name": name,
                    "line_number": func_node.start_point[0] + 1,
                    "end_line": func_node.end_point[0] + 1,
                    "args": args,
                    "source": self._get_node_text(func_node),
                    "source_code": self._get_node_text(func_node),
                    "docstring": docstring,
                    "cyclomatic_complexity": self._calculate_complexity(func_node),
                    "context": context,
                    "context_type": context_type,
                    "class_context": class_context,
                    "decorators": [],
                    "lang": self.language_name,
                    "is_dependency": False,
                }
                functions.append(func_data)

        return functions

    def _find_function_node_for_name(self, name_node):
        current = name_node.parent
        while current:
            if current.type in ('function_declaration', 'method_declaration'):
                return current
            current = current.parent
        return None

    def _find_function_node_for_params(self, params_node):
        current = params_node.parent
        while current:
            if current.type in ('function_declaration', 'method_declaration'):
                return current
            current = current.parent
        return None

    def _extract_parameters(self, params_node):
        params = []
        if params_node.type == 'parameter_list':
            for child in params_node.children:
                if child.type == 'parameter_declaration':
                    name_node = child.child_by_field_name('name')
                    if name_node:
                        params.append(self._get_node_text(name_node))
                elif child.type == 'variadic_parameter_declaration':
                    name_node = child.child_by_field_name('name')
                    if name_node:
                        params.append(f"...{self._get_node_text(name_node)}")
        return params

    def _extract_receiver(self, receiver_node):
        if receiver_node.type == 'parameter_list' and receiver_node.named_child_count > 0:
            param = receiver_node.named_child(0)
            type_node = param.child_by_field_name('type')
            if type_node:
                type_text = self._get_node_text(type_node)
                return type_text.strip('*')
        return None

    def _find_structs(self, root_node):
        structs = []
        struct_query = self.queries['structs']
        for node, capture_name in struct_query.captures(root_node):
            if capture_name == 'name':
                struct_node = self._find_type_declaration_for_name(node)
                if struct_node:
                    name = self._get_node_text(node)
                    class_data = {
                        "name": name,
                        "line_number": struct_node.start_point[0] + 1,
                        "end_line": struct_node.end_point[0] + 1,
                        "bases": [],
                        "source": self._get_node_text(struct_node),
                        "docstring": self._get_docstring(struct_node),
                        "context": None,
                        "decorators": [],
                        "lang": self.language_name,
                        "is_dependency": False,
                    }
                    structs.append(class_data)
        return structs

    def _find_interfaces(self, root_node):
        interfaces = []
        interface_query = self.queries['interfaces']
        for node, capture_name in interface_query.captures(root_node):
            if capture_name == 'name':
                interface_node = self._find_type_declaration_for_name(node)
                if interface_node:
                    name = self._get_node_text(node)
                    class_data = {
                        "name": name,
                        "line_number": interface_node.start_point[0] + 1,
                        "end_line": interface_node.end_point[0] + 1,
                        "bases": [],
                        "source": self._get_node_text(interface_node),
                        "docstring": self._get_docstring(interface_node),
                        "context": None,
                        "decorators": [],
                        "lang": self.language_name,
                        "is_dependency": False,
                    }
                    interfaces.append(class_data)
        return interfaces

    def _find_type_declaration_for_name(self, name_node):
        current = name_node.parent
        while current:
            if current.type == 'type_declaration':
                return current
            current = current.parent
        return None

    def _find_imports(self, root_node):
        imports = []
        query = self.queries['imports']
        
        for node, capture_name in query.captures(root_node):
            line_number = node.start_point[0] + 1
            
            if capture_name == 'path':
                path_text = self._get_node_text(node).strip('"')
                package_name = path_text.split('/')[-1]
                
                alias = None
                import_spec = node.parent
                if import_spec and import_spec.type == 'import_spec':
                    alias_node = import_spec.child_by_field_name('name')
                    if alias_node:
                        alias = self._get_node_text(alias_node)
                
                imports.append({
                    'name': package_name,
                    'source': path_text,
                    'alias': alias,
                    'line_number': line_number,
                    'lang': self.language_name
                })

        return imports

    def _find_calls(self, root_node):
        calls = []
        query = self.queries['calls']
        
        for node, capture_name in query.captures(root_node):
            if capture_name == 'name':
                call_node = node.parent
                while call_node and call_node.type != 'call_expression':
                    call_node = call_node.parent
                
                if call_node:
                    name = self._get_node_text(node)
                    
                    call_data = {
                        "name": name,
                        "full_name": self._get_node_text(call_node.child_by_field_name('function')) if call_node.child_by_field_name('function') else name,
                        "line_number": node.start_point[0] + 1,
                        "args": [],
                        "inferred_obj_type": None,
                        "context": None,
                        "class_context": None,
                        "lang": self.language_name,
                        "is_dependency": False,
                    }
                    calls.append(call_data)
        
        return calls

    def _find_variables(self, root_node):
        variables = []
        query = self.queries['variables']
        
        for node, capture_name in query.captures(root_node):
            if capture_name == 'name':
                name = self._get_node_text(node)
                
                variable_data = {
                    "name": name,
                    "line_number": node.start_point[0] + 1,
                    "value": None,
                    "type": None,
                    "context": None,
                    "class_context": None,
                    "lang": self.language_name,
                    "is_dependency": False,
                }
                variables.append(variable_data)
        
        return variables

def pre_scan_go(files: list[Path], parser_wrapper) -> dict:
    """Scans Go files to create a map of function/struct names to their file paths."""
    imports_map = {}
    query_str = """
        (function_declaration name: (identifier) @name)
        (method_declaration name: (field_identifier) @name)
        (type_declaration (type_spec name: (type_identifier) @name))
    """
    query = parser_wrapper.language.query(query_str)

    for file_path in files:
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                tree = parser_wrapper.parser.parse(bytes(f.read(), "utf8"))

            for capture, _ in query.captures(tree.root_node):
                name = capture.text.decode('utf-8')
                if name not in imports_map:
                    imports_map[name] = []
                imports_map[name].append(str(file_path.resolve()))
        except Exception as e:
            warning_logger(f"Tree-sitter pre-scan failed for {file_path}: {e}")
    
    return imports_map
```

--------------------------------------------------------------------------------
/tests/sample_project_typescript/src/utilities-helpers.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * Utilities and Helpers
 * Demonstrates common utility functions, type helpers, and patterns
 * used in TypeScript projects for enhanced development experience
 */

// ========== String Utilities ==========
export const StringUtils = {
  /**
   * Capitalizes the first letter of a string
   */
  capitalize: (str: string): string => 
    str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(),

  /**
   * Converts string to camelCase
   */
  camelCase: (str: string): string =>
    str.replace(/[-_\s]+(.)?/g, (_, char) => (char ? char.toUpperCase() : '')),

  /**
   * Converts string to kebab-case
   */
  kebabCase: (str: string): string =>
    str.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`).replace(/^-/, ''),

  /**
   * Converts string to snake_case
   */
  snakeCase: (str: string): string =>
    str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`).replace(/^_/, ''),

  /**
   * Truncates a string to specified length with ellipsis
   */
  truncate: (str: string, length: number, suffix: string = '...'): string =>
    str.length <= length ? str : str.slice(0, length) + suffix,

  /**
   * Removes extra whitespace and trims
   */
  normalize: (str: string): string =>
    str.replace(/\s+/g, ' ').trim(),

  /**
   * Pluralizes a word (simple English rules)
   */
  pluralize: (word: string, count: number = 2): string => {
    if (count === 1) return word;
    if (word.endsWith('y')) return word.slice(0, -1) + 'ies';
    if (word.endsWith('s') || word.endsWith('x') || word.endsWith('ch') || word.endsWith('sh')) {
      return word + 'es';
    }
    return word + 's';
  }
};

// ========== Array Utilities ==========
export const ArrayUtils = {
  /**
   * Chunks array into smaller arrays of specified size
   */
  chunk: <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;
  },

  /**
   * Removes duplicate values from array
   */
  unique: <T>(array: T[]): T[] => [...new Set(array)],

  /**
   * Groups array items by a key function
   */
  groupBy: <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[]>);
  },

  /**
   * Flattens nested arrays by one level
   */
  flatten: <T>(array: (T | T[])[]): T[] => array.flat() as T[],

  /**
   * Deeply flattens nested arrays
   */
  flattenDeep: <T>(array: any[]): T[] => {
    return array.reduce((acc, val) => 
      Array.isArray(val) ? acc.concat(ArrayUtils.flattenDeep(val)) : acc.concat(val), []
    );
  },

  /**
   * Shuffles array elements randomly
   */
  shuffle: <T>(array: T[]): T[] => {
    const result = [...array];
    for (let i = result.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [result[i], result[j]] = [result[j]!, result[i]!];
    }
    return result;
  },

  /**
   * Returns random element from array
   */
  sample: <T>(array: T[]): T | undefined => {
    return array[Math.floor(Math.random() * array.length)];
  },

  /**
   * Returns multiple random elements from array
   */
  sampleSize: <T>(array: T[], n: number): T[] => {
    const shuffled = ArrayUtils.shuffle(array);
    return shuffled.slice(0, Math.min(n, array.length));
  }
};

// ========== Object Utilities ==========
export const ObjectUtils = {
  /**
   * Deep clones an object
   */
  deepClone: <T>(obj: T): T => {
    if (obj === null || typeof obj !== 'object') return obj;
    if (obj instanceof Date) return new Date(obj.getTime()) as unknown as T;
    if (obj instanceof Array) return obj.map(item => ObjectUtils.deepClone(item)) as unknown as T;
    if (typeof obj === 'object') {
      const copy = {} as T;
      Object.keys(obj).forEach(key => {
        (copy as any)[key] = ObjectUtils.deepClone((obj as any)[key]);
      });
      return copy;
    }
    return obj;
  },

  /**
   * Merges objects deeply
   */
  deepMerge: <T extends Record<string, any>, U extends Record<string, any>>(
    target: T,
    source: U
  ): T & U => {
    const result = { ...target } as T & U;
    
    Object.keys(source).forEach(key => {
      if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
        if (result[key as keyof (T & U)] && typeof result[key as keyof (T & U)] === 'object') {
          (result as any)[key] = ObjectUtils.deepMerge(
            result[key as keyof (T & U)] as any,
            source[key]
          );
        } else {
          (result as any)[key] = ObjectUtils.deepClone(source[key]);
        }
      } else {
        (result as any)[key] = source[key];
      }
    });
    
    return result;
  },

  /**
   * Picks specified keys from object
   */
  pick: <T extends Record<string, any>, K extends keyof T>(
    obj: T,
    keys: K[]
  ): Pick<T, K> => {
    const result = {} as Pick<T, K>;
    keys.forEach(key => {
      if (key in obj) {
        result[key] = obj[key];
      }
    });
    return result;
  },

  /**
   * Omits specified keys from object
   */
  omit: <T extends Record<string, any>, 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>;
  },

  /**
   * Gets nested value from object using dot notation
   */
  get: <T>(obj: any, path: string, defaultValue?: T): T | undefined => {
    const keys = path.split('.');
    let result = obj;
    
    for (const key of keys) {
      if (result == null || typeof result !== 'object') {
        return defaultValue;
      }
      result = result[key];
    }
    
    return result !== undefined ? result : defaultValue;
  },

  /**
   * Sets nested value in object using dot notation
   */
  set: (obj: any, path: string, value: any): void => {
    const keys = path.split('.');
    const lastKey = keys.pop()!;
    let current = obj;
    
    for (const key of keys) {
      if (!(key in current) || typeof current[key] !== 'object') {
        current[key] = {};
      }
      current = current[key];
    }
    
    current[lastKey] = value;
  },

  /**
   * Checks if object has nested property
   */
  has: (obj: any, path: string): boolean => {
    const keys = path.split('.');
    let current = obj;
    
    for (const key of keys) {
      if (current == null || typeof current !== 'object' || !(key in current)) {
        return false;
      }
      current = current[key];
    }
    
    return true;
  }
};

// ========== Function Utilities ==========
export const FunctionUtils = {
  /**
   * Debounces function execution
   */
  debounce: <T extends (...args: any[]) => any>(
    fn: T,
    delay: number
  ): ((...args: Parameters<T>) => void) => {
    let timeoutId: NodeJS.Timeout;
    return (...args: Parameters<T>) => {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => fn(...args), delay);
    };
  },

  /**
   * Throttles function execution
   */
  throttle: <T extends (...args: any[]) => any>(
    fn: T,
    limit: number
  ): ((...args: Parameters<T>) => void) => {
    let inThrottle: boolean;
    return (...args: Parameters<T>) => {
      if (!inThrottle) {
        fn(...args);
        inThrottle = true;
        setTimeout(() => (inThrottle = false), limit);
      }
    };
  },

  /**
   * Memoizes function results
   */
  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;
  },

  /**
   * Creates a curried version of function
   */
  curry: <T extends (...args: any[]) => any>(
    fn: T,
    arity: number = fn.length
  ): any => {
    return (...args: any[]) => {
      if (args.length >= arity) {
        return fn(...args);
      }
      return FunctionUtils.curry(fn.bind(null, ...args), arity - args.length);
    };
  },

  /**
   * Composes functions from right to left
   */
  compose: <T>(...fns: Function[]): (arg: T) => any => {
    return (arg: T) => fns.reduceRight((result, fn) => fn(result), arg);
  },

  /**
   * Pipes functions from left to right
   */
  pipe: <T>(...fns: Function[]): (arg: T) => any => {
    return (arg: T) => fns.reduce((result, fn) => fn(result), arg);
  }
};

// ========== Date Utilities ==========
export const DateUtils = {
  /**
   * Formats date to ISO string with timezone
   */
  toISOString: (date: Date): string => date.toISOString(),

  /**
   * Formats date to readable string
   */
  format: (date: Date, locale: string = 'en-US'): string => 
    date.toLocaleDateString(locale),

  /**
   * Gets difference between dates in various units
   */
  diff: (date1: Date, date2: Date, unit: 'days' | 'hours' | 'minutes' | 'seconds' = 'days'): number => {
    const diffMs = Math.abs(date1.getTime() - date2.getTime());
    switch (unit) {
      case 'seconds': return Math.floor(diffMs / 1000);
      case 'minutes': return Math.floor(diffMs / (1000 * 60));
      case 'hours': return Math.floor(diffMs / (1000 * 60 * 60));
      case 'days': return Math.floor(diffMs / (1000 * 60 * 60 * 24));
    }
  },

  /**
   * Adds time to date
   */
  add: (date: Date, amount: number, unit: 'days' | 'hours' | 'minutes' | 'seconds'): Date => {
    const result = new Date(date);
    switch (unit) {
      case 'seconds': result.setSeconds(result.getSeconds() + amount); break;
      case 'minutes': result.setMinutes(result.getMinutes() + amount); break;
      case 'hours': result.setHours(result.getHours() + amount); break;
      case 'days': result.setDate(result.getDate() + amount); break;
    }
    return result;
  },

  /**
   * Checks if date is between two dates
   */
  isBetween: (date: Date, start: Date, end: Date): boolean =>
    date >= start && date <= end,

  /**
   * Gets start of day
   */
  startOfDay: (date: Date): Date => {
    const result = new Date(date);
    result.setHours(0, 0, 0, 0);
    return result;
  },

  /**
   * Gets end of day
   */
  endOfDay: (date: Date): Date => {
    const result = new Date(date);
    result.setHours(23, 59, 59, 999);
    return result;
  }
};

// ========== Number Utilities ==========
export const NumberUtils = {
  /**
   * Clamps number between min and max
   */
  clamp: (value: number, min: number, max: number): number =>
    Math.min(Math.max(value, min), max),

  /**
   * Rounds to specified decimal places
   */
  round: (value: number, decimals: number = 0): number =>
    Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals),

  /**
   * Generates random number between min and max
   */
  random: (min: number, max: number): number =>
    Math.random() * (max - min) + min,

  /**
   * Generates random integer between min and max (inclusive)
   */
  randomInt: (min: number, max: number): number =>
    Math.floor(Math.random() * (max - min + 1)) + min,

  /**
   * Checks if number is in range
   */
  inRange: (value: number, min: number, max: number): boolean =>
    value >= min && value <= max,

  /**
   * Converts number to percentage string
   */
  toPercent: (value: number, decimals: number = 2): string =>
    `${NumberUtils.round(value * 100, decimals)}%`,

  /**
   * Formats number with thousands separators
   */
  format: (value: number, locale: string = 'en-US'): string =>
    value.toLocaleString(locale)
};

// ========== Type Utilities ==========
export type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

export type DeepRequired<T> = {
  [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
};

export type KeysOfType<T, U> = {
  [K in keyof T]: T[K] extends U ? K : never;
}[keyof T];

export type Writeable<T> = {
  -readonly [P in keyof T]: T[P];
};

export type OptionalExcept<T, K extends keyof T> = Partial<T> & Pick<T, K>;

export type RequiredExcept<T, K extends keyof T> = Required<Omit<T, K>> & Partial<Pick<T, K>>;

// ========== Validation Helpers ==========
export const ValidationHelpers = {
  /**
   * Email validation
   */
  isEmail: (value: string): boolean =>
    /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),

  /**
   * URL validation
   */
  isUrl: (value: string): boolean => {
    try {
      new URL(value);
      return true;
    } catch {
      return false;
    }
  },

  /**
   * UUID validation
   */
  isUuid: (value: string): boolean =>
    /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value),

  /**
   * Credit card number validation (Luhn algorithm)
   */
  isCreditCard: (value: string): boolean => {
    const num = value.replace(/\D/g, '');
    if (num.length < 13 || num.length > 19) return false;
    
    let sum = 0;
    let isEven = false;
    
    for (let i = num.length - 1; i >= 0; i--) {
      let digit = parseInt(num[i]!);
      
      if (isEven) {
        digit *= 2;
        if (digit > 9) digit -= 9;
      }
      
      sum += digit;
      isEven = !isEven;
    }
    
    return sum % 10 === 0;
  },

  /**
   * Strong password validation
   */
  isStrongPassword: (value: string): boolean => {
    const minLength = value.length >= 8;
    const hasLower = /[a-z]/.test(value);
    const hasUpper = /[A-Z]/.test(value);
    const hasNumber = /\d/.test(value);
    const hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(value);
    
    return minLength && hasLower && hasUpper && hasNumber && hasSpecial;
  }
};

// ========== Color Utilities ==========
export const ColorUtils = {
  /**
   * Converts hex to RGB
   */
  hexToRgb: (hex: string): { r: number; g: number; b: number } | null => {
    const match = hex.match(/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i);
    return match ? {
      r: parseInt(match[1]!, 16),
      g: parseInt(match[2]!, 16),
      b: parseInt(match[3]!, 16)
    } : null;
  },

  /**
   * Converts RGB to hex
   */
  rgbToHex: (r: number, g: number, b: number): string => {
    const componentToHex = (c: number) => {
      const hex = c.toString(16);
      return hex.length === 1 ? '0' + hex : hex;
    };
    return `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`;
  },

  /**
   * Lightens a color by percentage
   */
  lighten: (hex: string, percent: number): string => {
    const rgb = ColorUtils.hexToRgb(hex);
    if (!rgb) return hex;
    
    const factor = 1 + percent / 100;
    return ColorUtils.rgbToHex(
      Math.min(255, Math.round(rgb.r * factor)),
      Math.min(255, Math.round(rgb.g * factor)),
      Math.min(255, Math.round(rgb.b * factor))
    );
  }
};

// ========== Performance Utilities ==========
export const PerformanceUtils = {
  /**
   * Measures execution time of a function
   */
  measure: async <T>(fn: () => T | Promise<T>): Promise<{ result: T; duration: number }> => {
    const start = performance.now();
    const result = await fn();
    const end = performance.now();
    return { result, duration: end - start };
  },

  /**
   * Creates a performance timer
   */
  timer: () => {
    const start = performance.now();
    return {
      stop: () => performance.now() - start,
      lap: () => {
        const current = performance.now();
        return current - start;
      }
    };
  },

  /**
   * Batches synchronous operations
   */
  batch: <T, R>(
    items: T[],
    processor: (batch: T[]) => R[],
    batchSize: number = 100
  ): R[] => {
    const results: R[] = [];
    for (let i = 0; i < items.length; i += batchSize) {
      const batch = items.slice(i, i + batchSize);
      results.push(...processor(batch));
    }
    return results;
  }
};

// ========== Usage Examples ==========
export const utilityExamples = {
  // String utilities
  camelCased: StringUtils.camelCase("hello-world-example"),
  kebabCased: StringUtils.kebabCase("HelloWorldExample"),
  truncated: StringUtils.truncate("This is a very long string", 15),
  
  // Array utilities
  chunked: ArrayUtils.chunk([1, 2, 3, 4, 5, 6, 7], 3),
  unique: ArrayUtils.unique([1, 2, 2, 3, 3, 3, 4]),
  grouped: ArrayUtils.groupBy(
    [{ type: 'fruit', name: 'apple' }, { type: 'vegetable', name: 'carrot' }],
    item => item.type
  ),
  
  // Object utilities
  picked: ObjectUtils.pick({ a: 1, b: 2, c: 3 }, ['a', 'c']),
  deepValue: ObjectUtils.get({ user: { profile: { name: 'John' } } }, 'user.profile.name'),
  
  // Function utilities
  debouncedLog: FunctionUtils.debounce((message: string) => console.log(message), 1000),
  memoizedFib: FunctionUtils.memoize((n: number): number => {
    if (n <= 1) return n;
    return utilityExamples.memoizedFib(n - 1) + utilityExamples.memoizedFib(n - 2);
  }),
  
  // Date utilities
  futureDate: DateUtils.add(new Date(), 7, 'days'),
  daysDiff: DateUtils.diff(new Date('2023-12-31'), new Date('2023-01-01')),
  
  // Number utilities
  clamped: NumberUtils.clamp(150, 0, 100),
  rounded: NumberUtils.round(3.14159, 2),
  percentage: NumberUtils.toPercent(0.85),
  
  // Validation
  emailValid: ValidationHelpers.isEmail('user@example.com'),
  strongPassword: ValidationHelpers.isStrongPassword('StrongPass123!'),
  
  // Colors
  rgbColor: ColorUtils.hexToRgb('#ff0000'),
  lighterColor: ColorUtils.lighten('#ff0000', 20)
};

// Initialize some examples
console.log('Utility examples initialized:', {
  camelCased: utilityExamples.camelCased,
  chunked: utilityExamples.chunked,
  deepValue: utilityExamples.deepValue
});
```

--------------------------------------------------------------------------------
/docs/site/use_cases/index.html:
--------------------------------------------------------------------------------

```html

<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
        <link rel="prev" href="../installation/">
      
      
        <link rel="next" href="../architecture/">
      
      
      <link rel="icon" href="../assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.21">
    
    
      
        <title>Use Cases - CodeGraphContext</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/main.2a3383ac.min.css">
      
      


    
    
      
    
    
      
        
        
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
        <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
      
    
    
    <script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
    
      

    
    
    
  </head>
  
  
    <body dir="ltr">
  
    
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#real-world-use-cases" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
    
      

  

<header class="md-header md-header--shadow" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="Header">
    <a href=".." title="CodeGraphContext" class="md-header__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>

    </a>
    <label class="md-header__button md-icon" for="__drawer">
      
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">
            CodeGraphContext
          </span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            
              Use Cases
            
          </span>
        </div>
      </div>
    </div>
    
    
      <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
    
    
    
      
      
        <label class="md-header__button md-icon" for="__search">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
        </label>
        <div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
      <label class="md-search__icon md-icon" for="__search">
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
      </label>
      <nav class="md-search__options" aria-label="Search">
        
        <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
        </button>
      </nav>
      
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list" role="presentation"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
      
    
    
  </nav>
  
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
          
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              
              <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    



<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href=".." title="CodeGraphContext" class="md-nav__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>

    </a>
    CodeGraphContext
  </label>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href=".." class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Home
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../installation/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Installation
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
    
  
  
  
    <li class="md-nav__item md-nav__item--active">
      
      <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
      
      
        
      
      
      <a href="./" class="md-nav__link md-nav__link--active">
        
  
  
  <span class="md-ellipsis">
    Use Cases
    
  </span>
  

      </a>
      
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../architecture/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Architecture
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../cli/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    CLI Reference
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../server/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Server
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../core/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Core Concepts
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../tools/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Tools
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../cookbook/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Cookbook
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_10" >
        
          
          <label class="md-nav__link" for="__nav_10" id="__nav_10_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    Contributing
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_10_label" aria-expanded="false">
          <label class="md-nav__title" for="__nav_10">
            <span class="md-nav__icon md-icon"></span>
            Contributing
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../contributing/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Overview
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../contributing_languages/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Adding New Languages
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../troubleshooting/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Troubleshooting
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../future_work/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Future Work
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../license/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    License
    
  </span>
  

      </a>
    </li>
  

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              
              <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
</nav>
                  </div>
                </div>
              </div>
            
          
          
            <div class="md-content" data-md-component="content">
              <article class="md-content__inner md-typeset">
                
                  



<h1 id="real-world-use-cases">Real World Use Cases</h1>
<p>CodeGraphContext can be a powerful ally in your daily coding journey. Here are some real-world scenarios where it can significantly boost your productivity and understanding of a codebase:</p>
<ol>
<li>
<p><strong>Onboarding New Developers:</strong> A new team member can quickly get up to speed by asking questions like:</p>
<ul>
<li>"Where is the authentication logic handled?"</li>
<li>"Show me the main entry point of the application."</li>
</ul>
</li>
<li>
<p><strong>Impact Analysis:</strong> Before making a change, assess the potential ripple effects:</p>
<ul>
<li>"What other parts of the code will be affected if I change the <code>calculate_total</code> function?"</li>
</ul>
</li>
<li>
<p><strong>Code Review:</strong> Gain context on pull requests faster:</p>
<ul>
<li>"Show me the callers of this new function."</li>
<li>"Does this change introduce any new dependencies?"</li>
</ul>
</li>
<li>
<p><strong>Debugging:</strong> Trace execution flows to pinpoint the source of a bug:</p>
<ul>
<li>"Show me the call chain from <code>handle_request</code> to <code>process_payment</code>."</li>
</ul>
</li>
<li>
<p><strong>Refactoring:</strong> Identify and plan large-scale code changes:</p>
<ul>
<li>"Find all instances of the deprecated <code>OldApiClass</code>."</li>
<li>"List all functions that use the <code>urllib</code> library so I can replace them with <code>requests</code>."</li>
</ul>
</li>
<li>
<p><strong>Identifying Code Smells:</strong> Proactively find areas that need improvement:</p>
<ul>
<li>"Find the 10 most complex functions in the codebase."</li>
<li>"Show me functions with more than 5 arguments."</li>
</ul>
</li>
<li>
<p><strong>Security Audits:</strong> Search for potentially vulnerable code patterns:</p>
<ul>
<li>"Find all functions that use the <code>eval</code> function."</li>
<li>"Show me where raw SQL queries are being executed."</li>
</ul>
</li>
<li>
<p><strong>Automated Documentation:</strong> Use the tool's understanding of the code to generate documentation. (This is what this agent is doing!)</p>
</li>
<li>
<p><strong>Dependency Management:</strong> Understand how your project uses its dependencies:</p>
<ul>
<li>"Which files import the <code>requests</code> library?"</li>
<li>"Are there any circular dependencies between modules?"</li>
</ul>
</li>
<li>
<p><strong>Cleaning Up Unused Code:</strong> Keep your codebase lean and maintainable:</p>
<ul>
<li>"Is there any dead or unused code in this project?"</li>
</ul>
</li>
<li>
<p><strong>Exploring a Large Codebase:</strong> Navigate large, unfamiliar projects with ease:</p>
<ul>
<li>"List all the classes in the <code>core</code> module."</li>
<li>"What are the top-level functions in the <code>utils</code> directory?"</li>
</ul>
</li>
<li>
<p><strong>Enforcing Coding Standards:</strong> Check for adherence to team conventions:</p>
<ul>
<li>"Find all functions that are not decorated with <code>@log_execution</code>."</li>
<li>"Show me all public methods that don't have a docstring."</li>
</ul>
</li>
<li>
<p><strong>Discovering API Usage:</strong> Find examples of how to use internal or external APIs:</p>
<ul>
<li>"Show me how other parts of the code use the <code>UserService</code>."</li>
</ul>
</li>
<li>
<p><strong>Improving Test Coverage:</strong> Identify areas that may lack test coverage:</p>
<ul>
<li>"Find all functions that are not called by any test files."</li>
</ul>
</li>
<li>
<p><strong>Visualizing Code Structure:</strong> Get a bird's-eye view of your project's architecture:</p>
<ul>
<li>"Generate a graph visualization of the <code>auth</code> module and its dependencies."</li>
</ul>
</li>
<li>
<p><strong>Learning a New Framework:</strong> Understand how a new framework operates by exploring its source code.</p>
</li>
<li>
<p><strong>Code Archeology:</strong> Investigate legacy code to understand its history and purpose.</p>
</li>
<li>
<p><strong>Planning a Migration:</strong> Identify all points of contact when migrating a library or framework:</p>
<ul>
<li>"Find all the places where the <code>old_payment_gateway</code> is used."</li>
</ul>
</li>
<li>
<p><strong>Knowledge Sharing:</strong> Use the code graph as a centralized, always-up-to-date knowledge base for your team.</p>
</li>
<li>
<p><strong>Automated Code Reviews:</strong> Integrate CodeGraphContext into your CI/CD pipeline to automatically flag potential issues in pull requests.</p>
</li>
</ol>












                
              </article>
            </div>
          
          
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
        </div>
        
      </main>
      
        <footer class="md-footer">
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-copyright">
  
  
    Made with
    <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
      Material for MkDocs
    </a>
  
</div>
      
    </div>
  </div>
</footer>
      
    </div>
    <div class="md-dialog" data-md-component="dialog">
      <div class="md-dialog__inner md-typeset"></div>
    </div>
    
    
    
      
      <script id="__config" type="application/json">{"base": "..", "features": [], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
    
    
      <script src="../assets/javascripts/bundle.f55a23d4.min.js"></script>
      
    
  </body>
</html>
```

--------------------------------------------------------------------------------
/docs/site/contributing/index.html:
--------------------------------------------------------------------------------

```html

<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
        <link rel="prev" href="../cookbook/">
      
      
        <link rel="next" href="../contributing_languages/">
      
      
      <link rel="icon" href="../assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.21">
    
    
      
        <title>Overview - CodeGraphContext</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/main.2a3383ac.min.css">
      
      


    
    
      
    
    
      
        
        
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
        <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
      
    
    
    <script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
    
      

    
    
    
  </head>
  
  
    <body dir="ltr">
  
    
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#contributing-to-codegraphcontext" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
    
      

  

<header class="md-header md-header--shadow" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="Header">
    <a href=".." title="CodeGraphContext" class="md-header__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>

    </a>
    <label class="md-header__button md-icon" for="__drawer">
      
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">
            CodeGraphContext
          </span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            
              Overview
            
          </span>
        </div>
      </div>
    </div>
    
    
      <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
    
    
    
      
      
        <label class="md-header__button md-icon" for="__search">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
        </label>
        <div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
      <label class="md-search__icon md-icon" for="__search">
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
      </label>
      <nav class="md-search__options" aria-label="Search">
        
        <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
        </button>
      </nav>
      
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list" role="presentation"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
      
    
    
  </nav>
  
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
          
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              
              <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    



<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href=".." title="CodeGraphContext" class="md-nav__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>

    </a>
    CodeGraphContext
  </label>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href=".." class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Home
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../installation/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Installation
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../use_cases/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Use Cases
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../architecture/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Architecture
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../cli/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    CLI Reference
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../server/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Server
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../core/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Core Concepts
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../tools/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Tools
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../cookbook/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Cookbook
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
    
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--active md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_10" checked>
        
          
          <label class="md-nav__link" for="__nav_10" id="__nav_10_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    Contributing
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_10_label" aria-expanded="true">
          <label class="md-nav__title" for="__nav_10">
            <span class="md-nav__icon md-icon"></span>
            Contributing
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
    
  
  
  
    <li class="md-nav__item md-nav__item--active">
      
      <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
      
      
        
      
      
        <label class="md-nav__link md-nav__link--active" for="__toc">
          
  
  
  <span class="md-ellipsis">
    Overview
    
  </span>
  

          <span class="md-nav__icon md-icon"></span>
        </label>
      
      <a href="./" class="md-nav__link md-nav__link--active">
        
  
  
  <span class="md-ellipsis">
    Overview
    
  </span>
  

      </a>
      
        

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#general-guidelines" class="md-nav__link">
    <span class="md-ellipsis">
      General Guidelines
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#setting-up-your-development-environment" class="md-nav__link">
    <span class="md-ellipsis">
      Setting up Your Development Environment
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#debugging" class="md-nav__link">
    <span class="md-ellipsis">
      Debugging
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#running-tests" class="md-nav__link">
    <span class="md-ellipsis">
      Running Tests
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#submitting-changes" class="md-nav__link">
    <span class="md-ellipsis">
      Submitting Changes
    </span>
  </a>
  
</li>
      
    </ul>
  
</nav>
      
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../contributing_languages/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Adding New Languages
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../troubleshooting/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Troubleshooting
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../future_work/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Future Work
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../license/" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    License
    
  </span>
  

      </a>
    </li>
  

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              
              <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#general-guidelines" class="md-nav__link">
    <span class="md-ellipsis">
      General Guidelines
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#setting-up-your-development-environment" class="md-nav__link">
    <span class="md-ellipsis">
      Setting up Your Development Environment
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#debugging" class="md-nav__link">
    <span class="md-ellipsis">
      Debugging
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#running-tests" class="md-nav__link">
    <span class="md-ellipsis">
      Running Tests
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#submitting-changes" class="md-nav__link">
    <span class="md-ellipsis">
      Submitting Changes
    </span>
  </a>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          
            <div class="md-content" data-md-component="content">
              <article class="md-content__inner md-typeset">
                
                  



<h1 id="contributing-to-codegraphcontext">Contributing to CodeGraphContext</h1>
<p>We welcome contributions! Please follow these steps:</p>
<h2 id="general-guidelines">General Guidelines</h2>
<ul>
<li>Ensure your code adheres to the existing style and conventions of the project.</li>
<li>Write clear, concise, and well-documented code.</li>
<li>All new features or bug fixes should be accompanied by appropriate tests.</li>
<li>Keep your pull requests focused on a single feature or bug fix.</li>
</ul>
<h2 id="setting-up-your-development-environment">Setting up Your Development Environment</h2>
<ol>
<li>Fork the repository.</li>
<li>Set up your development environment: <code>pip install -e ".[dev]"</code></li>
<li>Create a new branch for your feature or bugfix (e.g., <code>git checkout -b feature/my-new-feature</code>).</li>
</ol>
<h2 id="debugging">Debugging</h2>
<p>To enable debug mode for detailed logging, locate the <code>debug_mode</code> variable in <code>src/codegraphcontext/tools/graph_builder.py</code> and set its value to <code>1</code>.</p>
<pre><code class="language-python"># src/codegraphcontext/tools/graph_builder.py
debug_mode = 1
</code></pre>
<h2 id="running-tests">Running Tests</h2>
<p>Tests are located in the <code>tests/</code> directory and are run using <code>pytest</code>.</p>
<ol>
<li>Navigate to the root of the <code>CodeGraphContext</code> directory.</li>
<li>Run all tests using the command: <code>pytest</code></li>
<li>To run specific tests, you can provide the path to the test file, for example: <code>pytest tests/test_tools.py</code></li>
<li><strong>Skipping Re-indexing:</strong> To speed up test runs, especially during development, you can set the <code>CGC_SKIP_REINDEX</code> environment variable to <code>true</code>. This will prevent the test suite from re-indexing the sample project if it's already indexed.
    <code>bash
    CGC_SKIP_REINDEX=true pytest</code></li>
</ol>
<h2 id="submitting-changes">Submitting Changes</h2>
<ol>
<li>Write your code and add corresponding tests in the <code>tests/</code> directory.</li>
<li>Ensure all tests pass and your code lints without errors.</li>
<li>Commit your changes with a descriptive commit message.</li>
<li>Submit a pull request to the <code>main</code> branch.</li>
</ol>
<!-- "Failed to check job status: 'JobManager' object has no attribute 'JobStatus'" -->












                
              </article>
            </div>
          
          
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
        </div>
        
      </main>
      
        <footer class="md-footer">
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-copyright">
  
  
    Made with
    <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
      Material for MkDocs
    </a>
  
</div>
      
    </div>
  </div>
</footer>
      
    </div>
    <div class="md-dialog" data-md-component="dialog">
      <div class="md-dialog__inner md-typeset"></div>
    </div>
    
    
    
      
      <script id="__config" type="application/json">{"base": "..", "features": [], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
    
    
      <script src="../assets/javascripts/bundle.f55a23d4.min.js"></script>
      
    
  </body>
</html>
```

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

```python
from pathlib import Path
from typing import Any, Dict, Optional, Tuple
from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger, debug_logger

RUBY_QUERIES = {
    "functions": """
        (method
            name: (identifier) @name
        ) @function_node
    """,
    "classes": """
        (class
            name: (constant) @name
        ) @class
    """,
    "modules": """
        (module
            name: (constant) @name
        ) @module_node
    """,
    "imports": """
        (call
            method: (identifier) @method_name
            arguments: (argument_list
                (string) @path
            )
        ) @import
    """,
    "calls": """
        (call
            method: (identifier) @name
        )
    """,
    "variables": """
        (assignment
            left: (identifier) @name
            right: (_) @value
        )
        (assignment
            left: (instance_variable) @name
            right: (_) @value
        )
    """,
    "comments": """
        (comment) @comment
    """,
    "module_includes": """
        (call
          method: (identifier) @method
          arguments: (argument_list (constant) @module)
        ) @include_call
    """,
}


class RubyTreeSitterParser:
    """A Ruby-specific parser using tree-sitter."""

    def __init__(self, generic_parser_wrapper: Any):
        self.generic_parser_wrapper = generic_parser_wrapper
        self.language_name = "ruby"
        self.language = generic_parser_wrapper.language
        self.parser = generic_parser_wrapper.parser

        self.queries = {
            name: self.language.query(query_str)
            for name, query_str in RUBY_QUERIES.items()
        }

    def _get_node_text(self, node: Any) -> str:
        return node.text.decode("utf-8")
    
    def _enclosing_class_name(self, node: Any) -> Optional[str]:
        name, typ, _ = self._get_parent_context(node, ('class',))
        return name
    
    def _find_modules(self, root_node: Any) -> list[Dict[str, Any]]:
        modules = []
        query = self.queries["modules"]
        # name via captures
        captures = list(query.captures(root_node))
        for node, cap in captures:
            if cap == "module_node":
                name = None
                for n, c in captures:
                    if c == "name":
                        if n.start_byte >= node.start_byte and n.end_byte <= node.end_byte:
                            name = self._get_node_text(n)
                            break
                if name:
                    modules.append({
                        "name": name,
                        "line_number": node.start_point[0] + 1,
                        "end_line": node.end_point[0] + 1,
                        "source": self._get_node_text(node),
                        "source_code": self._get_node_text(node),
                        "lang": self.language_name,
                        "is_dependency": False,
                    })
        return modules

    def _find_module_inclusions(self, root_node: Any) -> list[Dict[str, Any]]:
        includes = []
        query = self.queries["module_includes"]
        for node, cap in query.captures(root_node):
            if cap == "method":
                method_name = self._get_node_text(node)
                if method_name != "include":
                    continue
            if cap == "include_call":
                method = None
                module = None
                for n, c in query.captures(node):
                    if c == "method":
                        method = self._get_node_text(n)
                    elif c == "module":
                        module = self._get_node_text(n)
                if method == "include" and module:
                    cls = self._enclosing_class_name(node)
                    if cls:
                        includes.append({
                            "class": cls,
                            "module": module,
                            "line_number": node.start_point[0] + 1,
                            "lang": self.language_name,
                            "is_dependency": False,
                        })
        return includes


    def _get_parent_context(self, node: Any, types: Tuple[str, ...] = ('class', 'module', 'method')):
        """Find parent context for Ruby constructs."""
        curr = node.parent
        while curr:
            if curr.type in types:
                name_node = curr.child_by_field_name('name')
                if name_node:
                    return self._get_node_text(name_node), curr.type, curr.start_point[0] + 1
            curr = curr.parent
        return None, None, None

    def _calculate_complexity(self, node: Any) -> int:
        """Calculate cyclomatic complexity for Ruby constructs."""
        complexity_nodes = {
            "if", "unless", "case", "when", "while", "until", "for", "rescue", "ensure",
            "and", "or", "&&", "||", "?", "ternary"
        }
        count = 1

        def traverse(n):
            nonlocal count
            if n.type in complexity_nodes:
                count += 1
            for child in n.children:
                traverse(child)

        traverse(node)
        return count

    def _get_docstring(self, node: Any) -> Optional[str]:
        """Extract comments as docstrings for Ruby constructs."""
        # Look for comments before the node
        prev_sibling = node.prev_sibling
        while prev_sibling and prev_sibling.type in ('comment', '\n', ' '):
            if prev_sibling.type == 'comment':
                comment_text = self._get_node_text(prev_sibling)
                if comment_text.startswith('#') and not comment_text.startswith('#!'):
                    return comment_text.strip()
            prev_sibling = prev_sibling.prev_sibling
        return None

    def _parse_method_parameters(self, method_node: Any) -> list[str]:
        """Parse method parameters from a method node."""
        params = []
        # Look for parameters in the method node
        for child in method_node.children:
            if child.type == 'identifier' and child != method_node.child_by_field_name('name'):
                # This is likely a parameter
                params.append(self._get_node_text(child))
        return params

    def parse(self, file_path: Path, is_dependency: bool = False) -> Dict[str, Any]:
        """Parses a Ruby file and returns its structure."""
        with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
            source_code = f.read()

        tree = self.parser.parse(bytes(source_code, "utf8"))
        root_node = tree.root_node

        functions = self._find_functions(root_node)
        classes = self._find_classes(root_node)
        imports = self._find_imports(root_node)
        function_calls = self._find_calls(root_node)
        variables = self._find_variables(root_node)
        modules = self._find_modules(root_node)
        module_inclusions = self._find_module_inclusions(root_node)

        return {
            "file_path": str(file_path),
            "functions": functions,
            "classes": classes,
            "variables": variables,
            "imports": imports,
            "function_calls": function_calls,
            "is_dependency": is_dependency,
            "lang": self.language_name,
            "modules": modules,
            "module_inclusions": module_inclusions,
        }

    def _find_functions(self, root_node: Any) -> list[Dict[str, Any]]:
        """Find all function/method definitions."""
        functions = []
        query = self.queries["functions"]
        
        # Collect all captures first
        all_captures = list(query.captures(root_node))
        
        # Group captures by function node using a different approach
        captures_by_function = {}
        for node, capture_name in all_captures:
            if capture_name == 'function_node':
                captures_by_function[id(node)] = {'node': node, 'name': None}
        
        # Now find names for each function
        for node, capture_name in all_captures:
            if capture_name == 'name':
                # Find which function this name belongs to
                for func_id, func_data in captures_by_function.items():
                    func_node = func_data['node']
                    # Check if this name node is within the function node
                    if (node.start_byte >= func_node.start_byte and 
                        node.end_byte <= func_node.end_byte):
                        captures_by_function[func_id]['name'] = self._get_node_text(node)
                        break

        # Build function entries
        for func_data in captures_by_function.values():
            func_node = func_data['node']
            name = func_data['name']
            
            if name:
                args = self._parse_method_parameters(func_node)

                # Get context and docstring
                context, context_type, _ = self._get_parent_context(func_node)
                class_context = context if context_type in ('class', 'module') else None
                docstring = self._get_docstring(func_node)

                functions.append({
                    "name": name,
                    "line_number": func_node.start_point[0] + 1,
                    "end_line": func_node.end_point[0] + 1,
                    "args": args,
                    "source": self._get_node_text(func_node),
                    "source_code": self._get_node_text(func_node),
                    "docstring": docstring,
                    "cyclomatic_complexity": self._calculate_complexity(func_node),
                    "context": context,
                    "context_type": context_type,
                    "class_context": class_context,
                    "decorators": [],
                    "lang": self.language_name,
                    "is_dependency": False,
                })

        return functions

    def _find_classes(self, root_node: Any) -> list[Dict[str, Any]]:
        """Find all class and module definitions."""
        classes = []
        query = self.queries["classes"]
        
        # Collect all captures first
        all_captures = list(query.captures(root_node))
        
        # Group captures by class node using a different approach
        captures_by_class = {}
        for node, capture_name in all_captures:
            if capture_name == 'class':
                captures_by_class[id(node)] = {'node': node, 'name': None}
        
        # Now find names for each class
        for node, capture_name in all_captures:
            if capture_name == 'name':
                # Find which class this name belongs to
                for class_id, class_data in captures_by_class.items():
                    class_node = class_data['node']
                    # Check if this name node is within the class node
                    if (node.start_byte >= class_node.start_byte and 
                        node.end_byte <= class_node.end_byte):
                        captures_by_class[class_id]['name'] = self._get_node_text(node)
                        break

        # Build class entries
        for class_data in captures_by_class.values():
            class_node = class_data['node']
            name = class_data['name']
            
            if name:
                # Get superclass for inheritance (simplified)
                bases = []

                # Get docstring
                docstring = self._get_docstring(class_node)

                classes.append({
                    "name": name,
                    "line_number": class_node.start_point[0] + 1,
                    "end_line": class_node.end_point[0] + 1,
                    "bases": bases,
                    "source": self._get_node_text(class_node),
                    "source_code": self._get_node_text(class_node),
                    "docstring": docstring,
                    "context": None,
                    "decorators": [],
                    "lang": self.language_name,
                    "is_dependency": False,
                })

        return classes

    def _find_imports(self, root_node: Any) -> list[Dict[str, Any]]:
        """Find all require/load statements."""
        imports = []
        query = self.queries["imports"]
        
        # Collect all captures first
        all_captures = list(query.captures(root_node))
        
        # Group captures by import node using a different approach
        captures_by_import = {}
        for node, capture_name in all_captures:
            if capture_name == 'import':
                captures_by_import[id(node)] = {'node': node, 'method_name': None, 'path': None}
        
        # Now find method names and paths for each import
        for node, capture_name in all_captures:
            if capture_name == 'method_name':
                # Find which import this method name belongs to
                for import_id, import_data in captures_by_import.items():
                    import_node = import_data['node']
                    # Check if this method name node is within the import node
                    if (node.start_byte >= import_node.start_byte and 
                        node.end_byte <= import_node.end_byte):
                        captures_by_import[import_id]['method_name'] = self._get_node_text(node)
                        break
            elif capture_name == 'path':
                # Find which import this path belongs to
                for import_id, import_data in captures_by_import.items():
                    import_node = import_data['node']
                    # Check if this path node is within the import node
                    if (node.start_byte >= import_node.start_byte and 
                        node.end_byte <= import_node.end_byte):
                        captures_by_import[import_id]['path'] = self._get_node_text(node)
                        break

        # Build import entries
        for import_data in captures_by_import.values():
            import_node = import_data['node']
            method_name = import_data['method_name']
            path = import_data['path']
            
            if method_name and path:
                path = path.strip('\'"')
                
                # Only process require/load statements
                if method_name in ('require', 'require_relative', 'load'):
                    imports.append({
                        "name": path,
                        "full_import_name": f"{method_name} '{path}'",
                        "line_number": import_node.start_point[0] + 1,
                        "alias": None,
                        "lang": self.language_name,
                        "is_dependency": False,
                    })

        return imports

    def _find_calls(self, root_node: Any) -> list[Dict[str, Any]]:
        """Find all function and method calls."""
        calls = []
        query = self.queries["calls"]
        
        for node, capture_name in query.captures(root_node):
            if capture_name == 'name':
                name = self._get_node_text(node)
                full_name = name

                calls.append({
                    "name": name,
                    "full_name": full_name,
                    "line_number": node.start_point[0] + 1,
                    "args": [],  # Placeholder - could be enhanced to extract arguments
                    "inferred_obj_type": None,
                    "context": None,  # Placeholder
                    "class_context": None,  # Placeholder
                    "lang": self.language_name,
                    "is_dependency": False,
                })

        return calls

    def _find_variables(self, root_node: Any) -> list[Dict[str, Any]]:
        """Find all variable assignments."""
        variables = []
        query = self.queries["variables"]
        
        # Group captures by assignment node
        captures_by_assignment = {}
        for node, capture_name in query.captures(root_node):
            if capture_name == 'name':
                # Find the parent assignment node
                current = node.parent
                while current and current.type != 'assignment':
                    current = current.parent
                if current:
                    assignment_id = id(current)
                    if assignment_id not in captures_by_assignment:
                        captures_by_assignment[assignment_id] = {'node': current, 'name': None, 'value': None}
                    captures_by_assignment[assignment_id]['name'] = self._get_node_text(node)
            elif capture_name == 'value':
                # Find the parent assignment node
                current = node.parent
                while current and current.type != 'assignment':
                    current = current.parent
                if current:
                    assignment_id = id(current)
                    if assignment_id not in captures_by_assignment:
                        captures_by_assignment[assignment_id] = {'node': current, 'name': None, 'value': None}
                    captures_by_assignment[assignment_id]['value'] = self._get_node_text(node)

        # Build variable entries
        for var_data in captures_by_assignment.values():
            name = var_data['name']
            value = var_data['value']
            
            if name:
                # Determine variable type based on name prefix
                var_type = "local"
                if name.startswith("@"):
                    var_type = "instance"
                elif name.startswith("@@"):
                    var_type = "class"
                elif name.startswith("$"):
                    var_type = "global"

                variables.append({
                    "name": name,
                    "line_number": var_data['node'].start_point[0] + 1,
                    "value": value,
                    "type": var_type,
                    "context": None,  # Placeholder
                    "class_context": None,  # Placeholder
                    "lang": self.language_name,
                    "is_dependency": False,
                })

        return variables


def pre_scan_ruby(files: list[Path], parser_wrapper) -> dict:
    """Scans Ruby files to create a map of class/method names to their file paths."""
    imports_map = {}
    query_str = """
        (class
            name: (constant) @name
        )
        (module
            name: (constant) @name
        )
        (method
            name: (identifier) @name
        )
    """
    query = parser_wrapper.language.query(query_str)

    for file_path in files:
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                tree = parser_wrapper.parser.parse(bytes(f.read(), "utf8"))

            for capture, _ in query.captures(tree.root_node):
                name = capture.text.decode('utf-8')
                if name not in imports_map:
                    imports_map[name] = []
                imports_map[name].append(str(file_path.resolve()))
        except Exception as e:
            warning_logger(f"Tree-sitter pre-scan failed for {file_path}: {e}")
    
    return imports_map

```

