This is page 14 of 22. Use http://codebase.md/shashankss1205/codegraphcontext?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .cgcignore
├── .github
│ ├── FUNDING.yml
│ └── workflows
│ ├── e2e-tests.yml
│ ├── post_discord_invite.yml
│ ├── test.yml
│ └── update-contributors.yml
├── .gitignore
├── CLI_Commands.md
├── 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
│ │ └── watching.md
│ ├── mkdocs.yml
│ └── site
│ ├── 404.html
│ ├── architecture
│ │ └── index.html
│ ├── assets
│ │ ├── images
│ │ │ └── favicon.png
│ │ ├── javascripts
│ │ │ ├── bundle.79ae519e.min.js
│ │ │ ├── bundle.79ae519e.min.js.map
│ │ │ ├── lunr
│ │ │ │ ├── min
│ │ │ │ │ ├── lunr.ar.min.js
│ │ │ │ │ ├── lunr.da.min.js
│ │ │ │ │ ├── lunr.de.min.js
│ │ │ │ │ ├── lunr.du.min.js
│ │ │ │ │ ├── lunr.el.min.js
│ │ │ │ │ ├── lunr.es.min.js
│ │ │ │ │ ├── lunr.fi.min.js
│ │ │ │ │ ├── lunr.fr.min.js
│ │ │ │ │ ├── lunr.he.min.js
│ │ │ │ │ ├── lunr.hi.min.js
│ │ │ │ │ ├── lunr.hu.min.js
│ │ │ │ │ ├── lunr.hy.min.js
│ │ │ │ │ ├── lunr.it.min.js
│ │ │ │ │ ├── lunr.ja.min.js
│ │ │ │ │ ├── lunr.jp.min.js
│ │ │ │ │ ├── lunr.kn.min.js
│ │ │ │ │ ├── lunr.ko.min.js
│ │ │ │ │ ├── lunr.multi.min.js
│ │ │ │ │ ├── lunr.nl.min.js
│ │ │ │ │ ├── lunr.no.min.js
│ │ │ │ │ ├── lunr.pt.min.js
│ │ │ │ │ ├── lunr.ro.min.js
│ │ │ │ │ ├── lunr.ru.min.js
│ │ │ │ │ ├── lunr.sa.min.js
│ │ │ │ │ ├── lunr.stemmer.support.min.js
│ │ │ │ │ ├── lunr.sv.min.js
│ │ │ │ │ ├── lunr.ta.min.js
│ │ │ │ │ ├── lunr.te.min.js
│ │ │ │ │ ├── lunr.th.min.js
│ │ │ │ │ ├── lunr.tr.min.js
│ │ │ │ │ ├── lunr.vi.min.js
│ │ │ │ │ └── lunr.zh.min.js
│ │ │ │ ├── tinyseg.js
│ │ │ │ └── wordcut.js
│ │ │ └── workers
│ │ │ ├── search.2c215733.min.js
│ │ │ └── search.2c215733.min.js.map
│ │ └── stylesheets
│ │ ├── main.484c7ddc.min.css
│ │ ├── main.484c7ddc.min.css.map
│ │ ├── palette.ab4e12ef.min.css
│ │ └── palette.ab4e12ef.min.css.map
│ ├── cli
│ │ └── index.html
│ ├── contributing
│ │ └── index.html
│ ├── contributing_languages
│ │ └── index.html
│ ├── cookbook
│ │ └── index.html
│ ├── core
│ │ └── index.html
│ ├── future_work
│ │ └── index.html
│ ├── images
│ │ ├── 1.png
│ │ ├── 11.png
│ │ ├── 12.png
│ │ ├── 13.png
│ │ ├── 14.png
│ │ ├── 16.png
│ │ ├── 19.png
│ │ ├── 2.png
│ │ ├── 20.png
│ │ ├── 21.png
│ │ ├── 22.png
│ │ ├── 23.png
│ │ ├── 24.png
│ │ ├── 26.png
│ │ ├── 28.png
│ │ ├── 29.png
│ │ ├── 3.png
│ │ ├── 30.png
│ │ ├── 31.png
│ │ ├── 32.png
│ │ ├── 33.png
│ │ ├── 34.png
│ │ ├── 35.png
│ │ ├── 36.png
│ │ ├── 38.png
│ │ ├── 39.png
│ │ ├── 4.png
│ │ ├── 40.png
│ │ ├── 41.png
│ │ ├── 42.png
│ │ ├── 43.png
│ │ ├── 44.png
│ │ ├── 5.png
│ │ ├── 6.png
│ │ ├── 7.png
│ │ ├── 8.png
│ │ ├── 9.png
│ │ ├── Indexing.gif
│ │ ├── tool_images
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ └── 3.png
│ │ └── Usecase.gif
│ ├── index.html
│ ├── installation
│ │ └── index.html
│ ├── license
│ │ └── index.html
│ ├── search
│ │ └── search_index.json
│ ├── server
│ │ └── index.html
│ ├── sitemap.xml
│ ├── sitemap.xml.gz
│ ├── tools
│ │ └── index.html
│ ├── troubleshooting
│ │ └── index.html
│ ├── use_cases
│ │ └── index.html
│ └── watching
│ └── index.html
├── funding.json
├── 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
├── pyproject.toml
├── README.md
├── scripts
│ ├── generate_lang_contributors.py
│ ├── post_install_fix.sh
│ ├── test_all_parsers.py
│ └── update_language_parsers.py
├── SECURITY.md
├── src
│ └── codegraphcontext
│ ├── __init__.py
│ ├── __main__.py
│ ├── cli
│ │ ├── __init__.py
│ │ ├── cli_helpers.py
│ │ ├── config_manager.py
│ │ ├── main.py
│ │ ├── setup_macos.py
│ │ └── setup_wizard.py
│ ├── core
│ │ ├── __init__.py
│ │ ├── database_falkordb.py
│ │ ├── database.py
│ │ ├── falkor_worker.py
│ │ ├── jobs.py
│ │ └── watcher.py
│ ├── prompts.py
│ ├── server.py
│ ├── tools
│ │ ├── __init__.py
│ │ ├── advanced_language_query_tool.py
│ │ ├── code_finder.py
│ │ ├── graph_builder.py
│ │ ├── languages
│ │ │ ├── c.py
│ │ │ ├── cpp.py
│ │ │ ├── csharp.py
│ │ │ ├── go.py
│ │ │ ├── java.py
│ │ │ ├── javascript.py
│ │ │ ├── kotlin.py
│ │ │ ├── php.py
│ │ │ ├── python.py
│ │ │ ├── ruby.py
│ │ │ ├── rust.py
│ │ │ ├── scala.py
│ │ │ ├── swift.py
│ │ │ ├── typescript.py
│ │ │ └── typescriptjsx.py
│ │ ├── package_resolver.py
│ │ ├── query_tool_languages
│ │ │ ├── c_toolkit.py
│ │ │ ├── cpp_toolkit.py
│ │ │ ├── csharp_toolkit.py
│ │ │ ├── go_toolkit.py
│ │ │ ├── java_toolkit.py
│ │ │ ├── javascript_toolkit.py
│ │ │ ├── python_toolkit.py
│ │ │ ├── ruby_toolkit.py
│ │ │ ├── rust_toolkit.py
│ │ │ ├── scala_toolkit.py
│ │ │ ├── swift_toolkit.py
│ │ │ └── typescript_toolkit.py
│ │ └── system.py
│ └── utils
│ ├── debug_log.py
│ └── tree_sitter_manager.py
├── tests
│ ├── __init__.py
│ ├── conftest.py
│ ├── sample_project
│ │ ├── advanced_calls.py
│ │ ├── advanced_classes.py
│ │ ├── advanced_classes2.py
│ │ ├── advanced_functions.py
│ │ ├── advanced_imports.py
│ │ ├── async_features.py
│ │ ├── callbacks_decorators.py
│ │ ├── circular1.py
│ │ ├── circular2.py
│ │ ├── class_instantiation.py
│ │ ├── cli_and_dunder.py
│ │ ├── complex_classes.py
│ │ ├── comprehensions_generators.py
│ │ ├── context_managers.py
│ │ ├── control_flow.py
│ │ ├── datatypes.py
│ │ ├── dynamic_dispatch.py
│ │ ├── dynamic_imports.py
│ │ ├── edge_cases
│ │ │ ├── comments_only.py
│ │ │ ├── docstring_only.py
│ │ │ ├── empty.py
│ │ │ ├── hardcoded_secrets.py
│ │ │ ├── long_functions.py
│ │ │ └── syntax_error.py
│ │ ├── function_chains.py
│ │ ├── generators.py
│ │ ├── import_reexports.py
│ │ ├── mapping_calls.py
│ │ ├── module_a.py
│ │ ├── module_b.py
│ │ ├── module_c
│ │ │ ├── __init__.py
│ │ │ ├── submodule1.py
│ │ │ └── submodule2.py
│ │ ├── namespace_pkg
│ │ │ └── ns_module.py
│ │ ├── pattern_matching.py
│ │ └── typing_examples.py
│ ├── sample_project_c
│ │ ├── cgc_sample
│ │ ├── include
│ │ │ ├── config.h
│ │ │ ├── math
│ │ │ │ └── vec.h
│ │ │ ├── module.h
│ │ │ ├── platform.h
│ │ │ └── util.h
│ │ ├── Makefile
│ │ ├── README.md
│ │ └── src
│ │ ├── main.c
│ │ ├── math
│ │ │ └── vec.c
│ │ ├── module.c
│ │ └── util.c
│ ├── sample_project_cpp
│ │ ├── class_features.cpp
│ │ ├── classes.cpp
│ │ ├── control_flow.cpp
│ │ ├── edge_cases.cpp
│ │ ├── enum_struct_union.cpp
│ │ ├── exceptions.cpp
│ │ ├── file_io.cpp
│ │ ├── function_chain.cpp
│ │ ├── function_chain.h
│ │ ├── function_types.cpp
│ │ ├── main.cpp
│ │ ├── main.exe
│ │ ├── namespaces.cpp
│ │ ├── raii_example.cpp
│ │ ├── README.md
│ │ ├── sample_project.exe
│ │ ├── stl_usage.cpp
│ │ ├── templates.cpp
│ │ └── types_variable_assignments.cpp
│ ├── sample_project_csharp
│ │ ├── README.md
│ │ └── src
│ │ └── Example.App
│ │ ├── Attributes
│ │ │ └── CustomAttributes.cs
│ │ ├── Example.App.csproj
│ │ ├── Models
│ │ │ ├── Person.cs
│ │ │ ├── Point.cs
│ │ │ ├── Role.cs
│ │ │ └── User.cs
│ │ ├── OuterClass.cs
│ │ ├── Program.cs
│ │ ├── Services
│ │ │ ├── GreetingService.cs
│ │ │ ├── IGreetingService.cs
│ │ │ └── LegacyService.cs
│ │ └── Utils
│ │ ├── CollectionHelper.cs
│ │ └── FileHelper.cs
│ ├── sample_project_go
│ │ ├── advanced_types.go
│ │ ├── basic_functions.go
│ │ ├── embedded_composition.go
│ │ ├── error_handling.go
│ │ ├── generics.go
│ │ ├── go.mod
│ │ ├── goroutines_channels.go
│ │ ├── interfaces.go
│ │ ├── packages_imports.go
│ │ ├── README.md
│ │ ├── structs_methods.go
│ │ └── util
│ │ └── helpers.go
│ ├── sample_project_java
│ │ ├── out
│ │ │ └── com
│ │ │ └── example
│ │ │ └── app
│ │ │ ├── annotations
│ │ │ │ └── Logged.class
│ │ │ ├── Main.class
│ │ │ ├── misc
│ │ │ │ ├── Outer.class
│ │ │ │ └── Outer$Inner.class
│ │ │ ├── model
│ │ │ │ ├── Role.class
│ │ │ │ └── User.class
│ │ │ ├── service
│ │ │ │ ├── AbstractGreeter.class
│ │ │ │ ├── GreetingService.class
│ │ │ │ └── impl
│ │ │ │ └── GreetingServiceImpl.class
│ │ │ └── util
│ │ │ ├── CollectionUtils.class
│ │ │ └── IOHelper.class
│ │ ├── README.md
│ │ ├── sources.txt
│ │ └── src
│ │ └── com
│ │ └── example
│ │ └── app
│ │ ├── annotations
│ │ │ └── Logged.java
│ │ ├── Main.java
│ │ ├── misc
│ │ │ └── Outer.java
│ │ ├── model
│ │ │ ├── Role.java
│ │ │ └── User.java
│ │ ├── service
│ │ │ ├── AbstractGreeter.java
│ │ │ ├── GreetingService.java
│ │ │ └── impl
│ │ │ └── GreetingServiceImpl.java
│ │ └── util
│ │ ├── CollectionUtils.java
│ │ └── IOHelper.java
│ ├── sample_project_javascript
│ │ ├── arrays.js
│ │ ├── asyncAwait.js
│ │ ├── classes.js
│ │ ├── dom.js
│ │ ├── errorHandling.js
│ │ ├── events.js
│ │ ├── exporter.js
│ │ ├── fetchAPI.js
│ │ ├── fixtures
│ │ │ └── js
│ │ │ └── accessors.js
│ │ ├── functions.js
│ │ ├── importer.js
│ │ ├── objects.js
│ │ ├── promises.js
│ │ ├── README.md
│ │ └── variables.js
│ ├── sample_project_kotlin
│ │ ├── AdvancedClasses.kt
│ │ ├── Annotations.kt
│ │ ├── Coroutines.kt
│ │ ├── EdgeCases.kt
│ │ ├── Functions.kt
│ │ ├── Main.kt
│ │ ├── Properties.kt
│ │ └── User.kt
│ ├── sample_project_misc
│ │ ├── index.html
│ │ ├── README.md
│ │ ├── styles.css
│ │ ├── tables.css
│ │ └── tables.html
│ ├── sample_project_php
│ │ ├── classes_objects.php
│ │ ├── database.php
│ │ ├── edgecases.php
│ │ ├── error_handling.php
│ │ ├── file_handling.php
│ │ ├── functions.php
│ │ ├── generators_iterators.php
│ │ ├── globals_superglobals.php
│ │ ├── Inheritance.php
│ │ ├── interface_traits.php
│ │ └── README.md
│ ├── sample_project_ruby
│ │ ├── class_example.rb
│ │ ├── enumerables.rb
│ │ ├── error_handling.rb
│ │ ├── file_io.rb
│ │ ├── inheritance_example.rb
│ │ ├── main.rb
│ │ ├── metaprogramming.rb
│ │ ├── mixins_example.rb
│ │ ├── module_example.rb
│ │ └── tests
│ │ ├── test_mixins.py
│ │ └── test_sample.rb
│ ├── sample_project_rust
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ └── src
│ │ ├── basic_functions.rs
│ │ ├── concurrency.rs
│ │ ├── error_handling.rs
│ │ ├── generics.rs
│ │ ├── iterators_closures.rs
│ │ ├── lib.rs
│ │ ├── lifetimes_references.rs
│ │ ├── modules.rs
│ │ ├── smart_pointers.rs
│ │ ├── structs_enums.rs
│ │ └── traits.rs
│ ├── sample_project_scala
│ │ ├── Animals.scala
│ │ ├── Complex.scala
│ │ ├── Functional.scala
│ │ ├── Geometry.scala
│ │ ├── Main.scala
│ │ ├── PackageObject.scala
│ │ ├── Script.sc
│ │ ├── Services.scala
│ │ ├── Shapes.scala
│ │ ├── Utils.scala
│ │ └── Variables.scala
│ ├── sample_project_swift
│ │ ├── Generics.swift
│ │ ├── Main.swift
│ │ ├── README.md
│ │ ├── Shapes.swift
│ │ ├── User.swift
│ │ └── Vehicles.swift
│ ├── sample_project_typescript
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── sample_tsx.tsx
│ │ ├── src
│ │ │ ├── advanced-types.ts
│ │ │ ├── async-promises.ts
│ │ │ ├── classes-inheritance.ts
│ │ │ ├── decorators-metadata.ts
│ │ │ ├── error-validation.ts
│ │ │ ├── functions-generics.ts
│ │ │ ├── index.ts
│ │ │ ├── modules-namespaces.ts
│ │ │ ├── types-interfaces.ts
│ │ │ └── utilities-helpers.ts
│ │ └── tsconfig.json
│ ├── test_cpp_parser.py
│ ├── test_database_validation.py
│ ├── test_end_to_end.py
│ ├── test_graph_indexing_js.py
│ ├── test_graph_indexing.py
│ ├── test_kotlin_parser.py
│ ├── test_swift_parser.py
│ ├── test_tree_sitter
│ │ ├── __init__.py
│ │ ├── class_instantiation.py
│ │ ├── complex_classes.py
│ │ └── test_file.py
│ ├── test_tree_sitter_manager.py
│ └── test_typescript_parser.py
├── visualize_graph.py
├── website
│ ├── .example.env
│ ├── .gitignore
│ ├── api
│ │ └── pypi.ts
│ ├── bun.lockb
│ ├── components.json
│ ├── eslint.config.js
│ ├── index.html
│ ├── package-lock.json
│ ├── package.json
│ ├── postcss.config.js
│ ├── public
│ │ ├── favicon.ico
│ │ ├── placeholder.svg
│ │ └── robots.txt
│ ├── README.md
│ ├── src
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── assets
│ │ │ ├── function-calls.png
│ │ │ ├── graph-total.png
│ │ │ ├── hero-graph.jpg
│ │ │ └── hierarchy.png
│ │ ├── components
│ │ │ ├── ComparisonTable.tsx
│ │ │ ├── CookbookSection.tsx
│ │ │ ├── DemoSection.tsx
│ │ │ ├── ExamplesSection.tsx
│ │ │ ├── FeaturesSection.tsx
│ │ │ ├── Footer.tsx
│ │ │ ├── HeroSection.tsx
│ │ │ ├── InstallationSection.tsx
│ │ │ ├── MoveToTop.tsx
│ │ │ ├── ShowDownloads.tsx
│ │ │ ├── ShowStarGraph.tsx
│ │ │ ├── SocialMentionsTimeline.tsx
│ │ │ ├── TestimonialSection.tsx
│ │ │ ├── ThemeProvider.tsx
│ │ │ ├── ThemeToggle.tsx
│ │ │ └── ui
│ │ │ ├── accordion.tsx
│ │ │ ├── alert-dialog.tsx
│ │ │ ├── alert.tsx
│ │ │ ├── aspect-ratio.tsx
│ │ │ ├── avatar.tsx
│ │ │ ├── badge.tsx
│ │ │ ├── breadcrumb.tsx
│ │ │ ├── button.tsx
│ │ │ ├── calendar.tsx
│ │ │ ├── card.tsx
│ │ │ ├── carousel.tsx
│ │ │ ├── chart.tsx
│ │ │ ├── checkbox.tsx
│ │ │ ├── collapsible.tsx
│ │ │ ├── command.tsx
│ │ │ ├── context-menu.tsx
│ │ │ ├── dialog.tsx
│ │ │ ├── drawer.tsx
│ │ │ ├── dropdown-menu.tsx
│ │ │ ├── form.tsx
│ │ │ ├── hover-card.tsx
│ │ │ ├── input-otp.tsx
│ │ │ ├── input.tsx
│ │ │ ├── label.tsx
│ │ │ ├── menubar.tsx
│ │ │ ├── navigation-menu.tsx
│ │ │ ├── orbiting-circles.tsx
│ │ │ ├── pagination.tsx
│ │ │ ├── popover.tsx
│ │ │ ├── progress.tsx
│ │ │ ├── radio-group.tsx
│ │ │ ├── resizable.tsx
│ │ │ ├── scroll-area.tsx
│ │ │ ├── select.tsx
│ │ │ ├── separator.tsx
│ │ │ ├── sheet.tsx
│ │ │ ├── sidebar.tsx
│ │ │ ├── skeleton.tsx
│ │ │ ├── slider.tsx
│ │ │ ├── sonner.tsx
│ │ │ ├── switch.tsx
│ │ │ ├── table.tsx
│ │ │ ├── tabs.tsx
│ │ │ ├── textarea.tsx
│ │ │ ├── toast.tsx
│ │ │ ├── toaster.tsx
│ │ │ ├── toggle-group.tsx
│ │ │ ├── toggle.tsx
│ │ │ ├── tooltip.tsx
│ │ │ └── use-toast.ts
│ │ ├── hooks
│ │ │ ├── use-mobile.tsx
│ │ │ └── use-toast.ts
│ │ ├── index.css
│ │ ├── lib
│ │ │ └── utils.ts
│ │ ├── main.tsx
│ │ ├── pages
│ │ │ ├── Index.tsx
│ │ │ └── NotFound.tsx
│ │ └── vite-env.d.ts
│ ├── tailwind.config.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ ├── vercel.json
│ └── vite.config.ts
└── windows_setup_guide.md
```
# Files
--------------------------------------------------------------------------------
/src/codegraphcontext/tools/languages/typescript.py:
--------------------------------------------------------------------------------
```python
1 | from pathlib import Path
2 | from typing import Dict
3 | from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger, debug_logger
4 | from codegraphcontext.utils.tree_sitter_manager import execute_query
5 |
6 | TS_QUERIES = {
7 | "functions": """
8 | (function_declaration
9 | name: (identifier) @name
10 | parameters: (formal_parameters) @params
11 | ) @function_node
12 |
13 | (variable_declarator
14 | name: (identifier) @name
15 | value: (function_expression
16 | parameters: (formal_parameters) @params
17 | ) @function_node
18 | )
19 |
20 | (variable_declarator
21 | name: (identifier) @name
22 | value: (arrow_function
23 | parameters: (formal_parameters) @params
24 | ) @function_node
25 | )
26 |
27 | (variable_declarator
28 | name: (identifier) @name
29 | value: (arrow_function
30 | parameter: (identifier) @single_param
31 | ) @function_node
32 | )
33 |
34 | (method_definition
35 | name: (property_identifier) @name
36 | parameters: (formal_parameters) @params
37 | ) @function_node
38 |
39 | (assignment_expression
40 | left: (member_expression
41 | property: (property_identifier) @name
42 | )
43 | right: (function_expression
44 | parameters: (formal_parameters) @params
45 | ) @function_node
46 | )
47 |
48 | (assignment_expression
49 | left: (member_expression
50 | property: (property_identifier) @name
51 | )
52 | right: (arrow_function
53 | parameters: (formal_parameters) @params
54 | ) @function_node
55 | )
56 | """,
57 | "classes": """
58 | (class_declaration) @class
59 | (abstract_class_declaration) @class
60 | (class) @class
61 | """,
62 | "interfaces": """
63 | (interface_declaration
64 | name: (type_identifier) @name
65 | ) @interface_node
66 | """,
67 | "type_aliases": """
68 | (type_alias_declaration
69 | name: (type_identifier) @name
70 | ) @type_alias_node
71 | """,
72 | "imports": """
73 | (import_statement) @import
74 | (call_expression
75 | function: (identifier) @require_call (#eq? @require_call "require")
76 | ) @import
77 | """,
78 | "calls": """
79 | (call_expression function: (identifier) @name)
80 | (call_expression function: (member_expression property: (property_identifier) @name))
81 | (new_expression constructor: (identifier) @name)
82 | (new_expression constructor: (member_expression property: (property_identifier) @name))
83 | """,
84 | "variables": """
85 | (variable_declarator name: (identifier) @name)
86 | """,
87 | "docstrings": """
88 | (comment) @docstring_comment
89 | """,
90 | }
91 |
92 | def is_typescript_file(file_path: Path) -> bool:
93 | return file_path.suffix in {".ts", ".tsx"}
94 |
95 | class TypescriptTreeSitterParser:
96 | """A TypeScript-specific parser using tree-sitter, encapsulating language-specific logic."""
97 |
98 | def __init__(self, generic_parser_wrapper):
99 | self.generic_parser_wrapper = generic_parser_wrapper
100 | self.language_name = generic_parser_wrapper.language_name
101 | self.language = generic_parser_wrapper.language
102 | self.parser = generic_parser_wrapper.parser
103 |
104 | def _get_node_text(self, node) -> str:
105 | return node.text.decode('utf-8')
106 |
107 | def _get_parent_context(self, node, types=('function_declaration', 'class_declaration', 'method_definition', 'function_expression', 'arrow_function')):
108 | curr = node.parent
109 | while curr:
110 | if curr.type in types:
111 | name_node = curr.child_by_field_name('name')
112 | if not name_node and curr.type in ('function_expression', 'arrow_function'):
113 | # Try to find name from variable declaration
114 | if curr.parent and curr.parent.type == 'variable_declarator':
115 | name_node = curr.parent.child_by_field_name('name')
116 | elif curr.parent and curr.parent.type == 'assignment_expression':
117 | name_node = curr.parent.child_by_field_name('left')
118 | elif curr.parent and curr.parent.type == 'pair': # property: function
119 | name_node = curr.parent.child_by_field_name('key')
120 |
121 | return self._get_node_text(name_node) if name_node else None, curr.type, curr.start_point[0] + 1
122 | curr = curr.parent
123 | return None, None, None
124 |
125 | def _calculate_complexity(self, node):
126 | complexity_nodes = {
127 | "if_statement", "for_statement", "while_statement", "do_statement",
128 | "switch_statement", "case_statement", "conditional_expression",
129 | "logical_expression", "binary_expression", "catch_clause"
130 | }
131 | count = 1
132 | def traverse(n):
133 | nonlocal count
134 | if n.type in complexity_nodes:
135 | count += 1
136 | for child in n.children:
137 | traverse(child)
138 | traverse(node)
139 | return count
140 |
141 | def _get_docstring(self, body_node):
142 | return None
143 |
144 | def parse(self, file_path: Path, is_dependency: bool = False) -> Dict:
145 | with open(file_path, "r", encoding="utf-8") as f:
146 | source_code = f.read()
147 | tree = self.parser.parse(bytes(source_code, "utf8"))
148 | root_node = tree.root_node
149 |
150 | functions = self._find_functions(root_node)
151 | classes = self._find_classes(root_node)
152 | interfaces = self._find_interfaces(root_node)
153 | type_aliases = self._find_type_aliases(root_node)
154 | imports = self._find_imports(root_node)
155 | function_calls = self._find_calls(root_node)
156 | variables = self._find_variables(root_node)
157 |
158 | return {
159 | "file_path": str(file_path),
160 | "functions": functions,
161 | "classes": classes,
162 | "interfaces": interfaces,
163 | "type_aliases": type_aliases,
164 | "variables": variables,
165 | "imports": imports,
166 | "function_calls": function_calls,
167 | "is_dependency": is_dependency,
168 | "lang": self.language_name,
169 | }
170 |
171 |
172 | def _find_functions(self, root_node):
173 | functions = []
174 | query_str = TS_QUERIES['functions']
175 | def _fn_for_name(name_node):
176 | current = name_node.parent
177 | while current:
178 | if current.type in ('function_declaration', 'function', 'arrow_function', 'method_definition'):
179 | return current
180 | elif current.type in ('variable_declarator', 'assignment_expression'):
181 | for child in current.children:
182 | if child.type in ('function', 'arrow_function'):
183 | return child
184 | current = current.parent
185 | return None
186 | def _fn_for_params(params_node):
187 | current = params_node.parent
188 | while current:
189 | if current.type in ('function_declaration', 'function', 'arrow_function', 'method_definition'):
190 | return current
191 | current = current.parent
192 | return None
193 | def _key(n):
194 | return (n.start_byte, n.end_byte, n.type)
195 | captures_by_function = {}
196 | def _bucket_for(node):
197 | fid = _key(node)
198 | return captures_by_function.setdefault(fid, {
199 | 'node': node, 'name': None, 'params': None, 'single_param': None
200 | })
201 | for node, capture_name in execute_query(self.language, query_str, root_node):
202 | if capture_name == 'function_node':
203 | _bucket_for(node)
204 | elif capture_name == 'name':
205 | fn = _fn_for_name(node)
206 | if fn:
207 | b = _bucket_for(fn)
208 | b['name'] = self._get_node_text(node)
209 | elif capture_name == 'params':
210 | fn = _fn_for_params(node)
211 | if fn:
212 | b = _bucket_for(fn)
213 | b['params'] = node
214 | elif capture_name == 'single_param':
215 | fn = _fn_for_params(node)
216 | if fn:
217 | b = _bucket_for(fn)
218 | b['single_param'] = node
219 | for _, data in captures_by_function.items():
220 | func_node = data['node']
221 | name = data.get('name')
222 | if not name and func_node.type == 'method_definition':
223 | nm = func_node.child_by_field_name('name')
224 | if nm:
225 | name = self._get_node_text(nm)
226 | if not name:
227 | continue
228 | args = []
229 | if data.get('params'):
230 | args = self._extract_parameters(data['params'])
231 | elif data.get('single_param'):
232 | args = [self._get_node_text(data['single_param'])]
233 | context, context_type, _ = self._get_parent_context(func_node)
234 | class_context = context if context_type == 'class_declaration' else None
235 | docstring = None
236 | func_data = {
237 | "name": name,
238 | "line_number": func_node.start_point[0] + 1,
239 | "end_line": func_node.end_point[0] + 1,
240 | "args": args,
241 | "source": self._get_node_text(func_node),
242 |
243 | "docstring": docstring,
244 | "cyclomatic_complexity": self._calculate_complexity(func_node),
245 | "context": context,
246 | "context_type": context_type,
247 | "class_context": class_context,
248 | "decorators": [],
249 | "lang": self.language_name,
250 | "is_dependency": False,
251 | }
252 | functions.append(func_data)
253 | return functions
254 |
255 | def _extract_parameters(self, params_node):
256 | params = []
257 | if params_node.type == 'formal_parameters':
258 | for child in params_node.children:
259 | if child.type == 'identifier':
260 | params.append(self._get_node_text(child))
261 | elif child.type == 'required_parameter':
262 | # required_parameter -> pattern (identifier) + type_annotation
263 | pattern = child.child_by_field_name('pattern')
264 | if pattern:
265 | params.append(self._get_node_text(pattern))
266 | else:
267 | # Fallback: first child that is an identifier or pattern
268 | for sub in child.children:
269 | if sub.type in ('identifier', 'object_pattern', 'array_pattern'):
270 | params.append(self._get_node_text(sub))
271 | break
272 | elif child.type == 'optional_parameter':
273 | pattern = child.child_by_field_name('pattern')
274 | if pattern:
275 | params.append(self._get_node_text(pattern))
276 | elif child.type == 'assignment_pattern':
277 | left_child = child.child_by_field_name('left')
278 | if left_child and left_child.type == 'identifier':
279 | params.append(self._get_node_text(left_child))
280 | elif child.type == 'rest_pattern':
281 | argument = child.child_by_field_name('argument')
282 | if argument and argument.type == 'identifier':
283 | params.append(f"...{self._get_node_text(argument)}")
284 | return params
285 |
286 | def _find_classes(self, root_node):
287 | classes = []
288 | query_str = TS_QUERIES['classes']
289 | for class_node, capture_name in execute_query(self.language, query_str, root_node):
290 | if capture_name == 'class':
291 | name_node = class_node.child_by_field_name('name')
292 | if not name_node: continue
293 | name = self._get_node_text(name_node)
294 | bases = []
295 | heritage_node = next((child for child in class_node.children if child.type == 'class_heritage'), None)
296 | if heritage_node:
297 | for child in heritage_node.children:
298 | if child.type == 'extends_clause':
299 | # extends_clause -> extends identifier
300 | for sub in child.children:
301 | if sub.type in ('identifier', 'type_identifier', 'member_expression'):
302 | bases.append(self._get_node_text(sub))
303 | elif child.type == 'implements_clause':
304 | # implements_clause -> implements identifier, identifier...
305 | for sub in child.children:
306 | if sub.type in ('identifier', 'type_identifier', 'member_expression'):
307 | bases.append(self._get_node_text(sub))
308 | class_data = {
309 | "name": name,
310 | "line_number": class_node.start_point[0] + 1,
311 | "end_line": class_node.end_point[0] + 1,
312 | "bases": bases,
313 | "source": self._get_node_text(class_node),
314 | "docstring": self._get_docstring(class_node),
315 | "context": None,
316 | "decorators": [],
317 | "lang": self.language_name,
318 | "is_dependency": False,
319 | }
320 | classes.append(class_data)
321 | return classes
322 |
323 | def _find_interfaces(self, root_node):
324 | interfaces = []
325 | query_str = TS_QUERIES['interfaces']
326 | for node, capture_name in execute_query(self.language, query_str, root_node):
327 | if capture_name == 'interface_node':
328 | name_node = node.child_by_field_name('name')
329 | if not name_node: continue
330 |
331 | name = self._get_node_text(name_node)
332 | interface_data = {
333 | "name": name,
334 | "line_number": node.start_point[0] + 1,
335 | "end_line": node.end_point[0] + 1,
336 | "source": self._get_node_text(node),
337 | }
338 | interfaces.append(interface_data)
339 | return interfaces
340 |
341 | def _find_type_aliases(self, root_node):
342 | type_aliases = []
343 | query_str = TS_QUERIES['type_aliases']
344 | for node, capture_name in execute_query(self.language, query_str, root_node):
345 | if capture_name == 'type_alias_node':
346 | name_node = node.child_by_field_name('name')
347 | if not name_node: continue
348 |
349 | name = self._get_node_text(name_node)
350 | type_alias_data = {
351 | "name": name,
352 | "line_number": node.start_point[0] + 1,
353 | "end_line": node.end_point[0] + 1,
354 | "source": self._get_node_text(node),
355 | }
356 | type_aliases.append(type_alias_data)
357 | return type_aliases
358 |
359 | def _find_imports(self, root_node):
360 | imports = []
361 | query_str = TS_QUERIES['imports']
362 | for node, capture_name in execute_query(self.language, query_str, root_node):
363 | if capture_name != 'import':
364 | continue
365 | line_number = node.start_point[0] + 1
366 | if node.type == 'import_statement':
367 | source = self._get_node_text(node.child_by_field_name('source')).strip('\'"')
368 | import_clause = node.child_by_field_name('import')
369 | if not import_clause:
370 | imports.append({'name': source, 'source': source, 'alias': None, 'line_number': line_number,
371 | 'lang': self.language_name})
372 | continue
373 | if import_clause.type == 'identifier':
374 | alias = self._get_node_text(import_clause)
375 | imports.append({'name': 'default', 'source': source, 'alias': alias, 'line_number': line_number,
376 | 'lang': self.language_name})
377 | elif import_clause.type == 'namespace_import':
378 | alias_node = import_clause.child_by_field_name('alias')
379 | if alias_node:
380 | alias = self._get_node_text(alias_node)
381 | imports.append({'name': '*', 'source': source, 'alias': alias, 'line_number': line_number,
382 | 'lang': self.language_name})
383 | elif import_clause.type == 'named_imports':
384 | for specifier in import_clause.children:
385 | if specifier.type == 'import_specifier':
386 | name_node = specifier.child_by_field_name('name')
387 | alias_node = specifier.child_by_field_name('alias')
388 | original_name = self._get_node_text(name_node)
389 | alias = self._get_node_text(alias_node) if alias_node else None
390 | imports.append(
391 | {'name': original_name, 'source': source, 'alias': alias, 'line_number': line_number,
392 | 'lang': self.language_name})
393 | elif node.type == 'call_expression':
394 | args = node.child_by_field_name('arguments')
395 | if not args or args.named_child_count == 0: continue
396 | source_node = args.named_child(0)
397 | if not source_node or source_node.type != 'string': continue
398 | source = self._get_node_text(source_node).strip('\'"')
399 | alias = None
400 | if node.parent.type == 'variable_declarator':
401 | alias_node = node.parent.child_by_field_name('name')
402 | if alias_node:
403 | alias = self._get_node_text(alias_node)
404 | imports.append({'name': source, 'source': source, 'alias': alias, 'line_number': line_number,
405 | 'lang': self.language_name})
406 | return imports
407 |
408 | def _find_calls(self, root_node):
409 | calls = []
410 | query_str = TS_QUERIES['calls']
411 | for node, capture_name in execute_query(self.language, query_str, root_node):
412 | if capture_name == 'name':
413 | # Traverse up to find the call/new expression
414 | call_node = node.parent
415 | while call_node and call_node.type not in ('call_expression', 'new_expression') and call_node.type != 'program':
416 | call_node = call_node.parent
417 |
418 | name = self._get_node_text(node)
419 |
420 | # Improved args extraction
421 | args = []
422 | arguments_node = None
423 | if call_node and call_node.type in ('call_expression', 'new_expression'):
424 | arguments_node = call_node.child_by_field_name('arguments')
425 |
426 | if arguments_node:
427 | for arg in arguments_node.children:
428 | if arg.type not in ('(', ')', ','):
429 | args.append(self._get_node_text(arg))
430 |
431 | call_data = {
432 | "name": name,
433 | "full_name": self._get_node_text(call_node) if call_node else name,
434 | "line_number": node.start_point[0] + 1,
435 | "args": args,
436 | "inferred_obj_type": None,
437 | "context": self._get_parent_context(node),
438 | "class_context": self._get_parent_context(node, types=('class_declaration', 'abstract_class_declaration')),
439 | "lang": self.language_name,
440 | "is_dependency": False,
441 | }
442 | calls.append(call_data)
443 | return calls
444 |
445 | def _find_variables(self, root_node):
446 | variables = []
447 | query_str = TS_QUERIES['variables']
448 | for match in execute_query(self.language, query_str, root_node):
449 | capture_name = match[1]
450 | node = match[0]
451 | if capture_name == 'name':
452 | var_node = node.parent
453 | name = self._get_node_text(node)
454 | value = None
455 | type_text = None
456 |
457 | # Detect if variable assigned to a function
458 | value_node = var_node.child_by_field_name("value") if var_node else None
459 |
460 | if value_node:
461 | value_type = value_node.type
462 |
463 | # --- Skip variables that are assigned a function ---
464 | if value_type in ("function_expression", "arrow_function"):
465 | continue
466 |
467 | if "function" in value_type or "arrow" in value_type:
468 | continue
469 |
470 | # --- Handle various assignment types ---
471 | if value_type == "call_expression":
472 | func_node = value_node.child_by_field_name("function")
473 | value = self._get_node_text(func_node) if func_node else name
474 | else:
475 | value = self._get_node_text(value_node)
476 |
477 | context, context_type, context_line = self._get_parent_context(node)
478 | class_context = context if context_type == 'class_declaration' else None
479 |
480 | variable_data = {
481 | "name": name,
482 | "line_number": node.start_point[0] + 1,
483 | "value": value,
484 | "type": type_text,
485 | "context": context,
486 | "class_context": class_context,
487 | "lang": self.language_name,
488 | "is_dependency": False,
489 | }
490 | variables.append(variable_data)
491 | return variables
492 |
493 | def pre_scan_typescript(files: list[Path], parser_wrapper) -> dict:
494 | """Scans TypeScript files to create a map of class/function names to their file paths."""
495 | imports_map = {}
496 |
497 | # Simplified queries that capture the parent nodes, then extract names manually
498 | query_strings = [
499 | "(class_declaration) @class",
500 | "(function_declaration) @function",
501 | "(variable_declarator) @var_decl",
502 | "(method_definition) @method",
503 | "(interface_declaration) @interface",
504 | "(type_alias_declaration) @type_alias",
505 | ]
506 |
507 | for file_path in files:
508 | try:
509 | with open(file_path, "r", encoding="utf-8") as f:
510 | source_code = f.read()
511 | tree = parser_wrapper.parser.parse(bytes(source_code, "utf8"))
512 |
513 | # Run each query separately
514 | for query_str in query_strings:
515 | try:
516 |
517 | for node, capture_name in execute_query(parser_wrapper.language, query_str, tree.root_node):
518 | name = None
519 |
520 | # Extract name based on node type
521 | if capture_name == 'class':
522 | name_node = node.child_by_field_name('name')
523 | if name_node:
524 | name = name_node.text.decode('utf-8')
525 |
526 | elif capture_name == 'function':
527 | name_node = node.child_by_field_name('name')
528 | if name_node:
529 | name = name_node.text.decode('utf-8')
530 |
531 | elif capture_name == 'var_decl':
532 | # Check if it's a function or arrow function
533 | name_node = node.child_by_field_name('name')
534 | value_node = node.child_by_field_name('value')
535 | if name_node and value_node:
536 | if value_node.type in ('function', 'arrow_function'):
537 | name = name_node.text.decode('utf-8')
538 |
539 | elif capture_name == 'method':
540 | name_node = node.child_by_field_name('name')
541 | if name_node:
542 | name = name_node.text.decode('utf-8')
543 |
544 | elif capture_name == 'interface':
545 | name_node = node.child_by_field_name('name')
546 | if name_node:
547 | name = name_node.text.decode('utf-8')
548 |
549 | elif capture_name == 'type_alias':
550 | name_node = node.child_by_field_name('name')
551 | if name_node:
552 | name = name_node.text.decode('utf-8')
553 |
554 | # Add to imports map if we found a name
555 | if name:
556 | if name not in imports_map:
557 | imports_map[name] = []
558 | file_path_str = str(file_path.resolve())
559 | if file_path_str not in imports_map[name]:
560 | imports_map[name].append(file_path_str)
561 |
562 | except Exception as query_error:
563 | warning_logger(f"Query failed for pattern '{query_str}': {query_error}")
564 |
565 | except Exception as e:
566 | warning_logger(f"Tree-sitter pre-scan failed for {file_path}: {e}")
567 |
568 | return imports_map
```
--------------------------------------------------------------------------------
/src/codegraphcontext/tools/languages/kotlin.py:
--------------------------------------------------------------------------------
```python
1 | from pathlib import Path
2 | from typing import Any, Dict, Optional, Tuple
3 | import re
4 | from codegraphcontext.utils.debug_log import debug_log, info_logger, error_logger, warning_logger
5 | from codegraphcontext.utils.tree_sitter_manager import execute_query
6 |
7 | KOTLIN_QUERIES = {
8 | "functions": """
9 | (function_declaration
10 | (simple_identifier) @name
11 | (function_value_parameters) @params
12 | ) @function_node
13 | """,
14 | "classes": """
15 | [
16 | (class_declaration (type_identifier) @name)
17 | (object_declaration (type_identifier) @name)
18 | (companion_object (type_identifier)? @name)
19 | ] @class
20 | """,
21 | "imports": """
22 | (import_header) @import
23 | """,
24 | "calls": """
25 | (call_expression) @call_node
26 | """,
27 | "variables": """
28 | (property_declaration
29 | (variable_declaration
30 | (simple_identifier) @name
31 | )
32 | ) @variable
33 | """,
34 | }
35 |
36 | class KotlinTreeSitterParser:
37 | def __init__(self, generic_parser_wrapper: Any):
38 | self.generic_parser_wrapper = generic_parser_wrapper
39 | self.language_name = "kotlin"
40 | self.language = generic_parser_wrapper.language
41 | self.parser = generic_parser_wrapper.parser
42 |
43 | def parse(self, file_path: Path, is_dependency: bool = False) -> Dict[str, Any]:
44 | try:
45 | with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
46 | source_code = f.read()
47 |
48 | if not source_code.strip():
49 | warning_logger(f"Empty or whitespace-only file: {file_path}")
50 | return {
51 | "file_path": str(file_path),
52 | "functions": [],
53 | "classes": [],
54 | "variables": [],
55 | "imports": [],
56 | "function_calls": [],
57 | "is_dependency": is_dependency,
58 | "lang": self.language_name,
59 | }
60 |
61 | tree = self.parser.parse(bytes(source_code, "utf8"))
62 |
63 | parsed_functions = []
64 | parsed_classes = []
65 | parsed_variables = []
66 | parsed_imports = []
67 | parsed_calls = []
68 |
69 | # Parse Variables first to populate for inference
70 | if 'variables' in KOTLIN_QUERIES:
71 | results = execute_query(self.language, KOTLIN_QUERIES['variables'], tree.root_node)
72 | parsed_variables = self._parse_variables(results, source_code, file_path)
73 |
74 | for capture_name, query in KOTLIN_QUERIES.items():
75 | if capture_name == 'variables': continue # Already done
76 | results = execute_query(self.language, query, tree.root_node)
77 |
78 | if capture_name == "functions":
79 | parsed_functions.extend(self._parse_functions(results, source_code, file_path))
80 | elif capture_name == "classes":
81 | parsed_classes.extend(self._parse_classes(results, source_code, file_path))
82 | elif capture_name == "imports":
83 | parsed_imports.extend(self._parse_imports(results, source_code))
84 | elif capture_name == "calls":
85 | parsed_calls.extend(self._parse_calls(results, source_code, file_path, parsed_variables))
86 |
87 | return {
88 | "file_path": str(file_path),
89 | "functions": parsed_functions,
90 | "classes": parsed_classes,
91 | "variables": parsed_variables,
92 | "imports": parsed_imports,
93 | "function_calls": parsed_calls,
94 | "is_dependency": is_dependency,
95 | "lang": self.language_name,
96 | }
97 |
98 | except Exception as e:
99 | error_logger(f"Error parsing Kotlin file {file_path}: {e}")
100 | return {
101 | "file_path": str(file_path),
102 | "functions": [],
103 | "classes": [],
104 | "variables": [],
105 | "imports": [],
106 | "function_calls": [],
107 | "is_dependency": is_dependency,
108 | "lang": self.language_name,
109 | }
110 |
111 | def _get_parent_context(self, node: Any) -> Tuple[Optional[str], Optional[str], Optional[int]]:
112 | curr = node.parent
113 | while curr:
114 | if curr.type in ("function_declaration",):
115 | name_node = None
116 | for child in curr.children:
117 | if child.type == "simple_identifier":
118 | name_node = child
119 | break
120 | return (
121 | self._get_node_text(name_node) if name_node else None,
122 | curr.type,
123 | curr.start_point[0] + 1,
124 | )
125 | if curr.type in ("class_declaration", "object_declaration"):
126 | for child in curr.children:
127 | if child.type in ("simple_identifier", "type_identifier"):
128 | return (
129 | self._get_node_text(child),
130 | curr.type,
131 | curr.start_point[0] + 1,
132 | )
133 | # Check for secondary constructors
134 | if curr.type == "secondary_constructor":
135 | return (
136 | "constructor",
137 | curr.type,
138 | curr.start_point[0] + 1
139 | )
140 |
141 | if curr.type == "companion_object":
142 | name = "Companion"
143 | for child in curr.children:
144 | if child.type in ("simple_identifier", "type_identifier"):
145 | name = self._get_node_text(child)
146 | break
147 | return (
148 | name,
149 | curr.type,
150 | curr.start_point[0] + 1,
151 | )
152 |
153 | # Handle anonymous objects (object_literal)
154 | if curr.type == "object_literal":
155 | # checking if it is assigned to a variable to get a name?
156 | # or simply "AnonymousObject"
157 | # It's usually hard to name them without variable context.
158 | # We can check if parent is property/variable declaration
159 | name = "AnonymousObject"
160 | return (
161 | name,
162 | curr.type,
163 | curr.start_point[0] + 1
164 | )
165 |
166 | curr = curr.parent
167 | return None, None, None
168 |
169 | def _get_node_text(self, node: Any) -> str:
170 | if not node: return ""
171 | return node.text.decode("utf-8")
172 |
173 | def _parse_functions(self, captures: list, source_code: str, file_path: Path) -> list[Dict[str, Any]]:
174 | functions = []
175 | seen_nodes = set()
176 |
177 | for node, capture_name in captures:
178 | if capture_name == "function_node":
179 | node_id = (node.start_byte, node.end_byte, node.type)
180 | if node_id in seen_nodes:
181 | continue
182 | seen_nodes.add(node_id)
183 |
184 | try:
185 | start_line = node.start_point[0] + 1
186 | end_line = node.end_point[0] + 1
187 |
188 | # Manual child lookup
189 | name_node = None
190 | for child in node.children:
191 | if child.type == "simple_identifier":
192 | name_node = child
193 | break
194 |
195 | if name_node:
196 | func_name = self._get_node_text(name_node)
197 |
198 | params_node = None
199 | for child in node.children:
200 | if child.type == "function_value_parameters":
201 | params_node = child
202 | break
203 |
204 | parameters = []
205 | if params_node:
206 | params_text = self._get_node_text(params_node)
207 | parameters = self._extract_parameter_names(params_text)
208 |
209 | source_text = self._get_node_text(node)
210 |
211 | context_name, context_type, context_line = self._get_parent_context(node)
212 |
213 | functions.append({
214 | "name": func_name,
215 | "args": parameters,
216 | "line_number": start_line,
217 | "end_line": end_line,
218 | "source": source_text,
219 | "file_path": str(file_path),
220 | "lang": self.language_name,
221 | "context": context_name,
222 | "class_context": context_name if context_type and ("class" in context_type or "object" in context_type) else None
223 | })
224 |
225 | except Exception as e:
226 | error_logger(f"Error parsing function in {file_path}: {e}")
227 | continue
228 |
229 | return functions
230 |
231 | def _parse_classes(self, captures: list, source_code: str, file_path: Path) -> list[Dict[str, Any]]:
232 | classes = []
233 | seen_nodes = set()
234 |
235 | for node, capture_name in captures:
236 | if capture_name == "class":
237 | node_id = (node.start_byte, node.end_byte, node.type)
238 | if node_id in seen_nodes:
239 | continue
240 | seen_nodes.add(node_id)
241 |
242 | try:
243 | start_line = node.start_point[0] + 1
244 | end_line = node.end_point[0] + 1
245 |
246 | # Find name child (type_identifier or simple_identifier)
247 | class_name = "Anonymous"
248 | if node.type == "companion_object":
249 | class_name = "Companion" # Default name
250 |
251 | for child in node.children:
252 | if child.type in ("type_identifier", "simple_identifier"):
253 | class_name = self._get_node_text(child)
254 | break
255 |
256 | source_text = self._get_node_text(node)
257 |
258 | bases = []
259 | # Check for delegation specifiers
260 | # class_declaration -> delegation_specifier
261 |
262 | for child in node.children:
263 | if child.type == "delegation_specifier":
264 | # children: constructor_invocation or user_type
265 | for specifier in child.children:
266 | # constructor_invocation -> user_type -> type_identifier
267 | # user_type -> type_identifier
268 |
269 | # We want the text of the type
270 | if specifier.type == "constructor_invocation":
271 | # child 0 is typically user_type
272 | for sub in specifier.children:
273 | if sub.type == "user_type":
274 | bases.append(self._get_node_text(sub))
275 | break
276 | elif specifier.type == "user_type":
277 | bases.append(self._get_node_text(specifier))
278 | elif specifier.type == "explicit_delegation":
279 | # Not handling simple yet, uses 'by'
280 | pass
281 |
282 |
283 | classes.append({
284 | "name": class_name,
285 | "line_number": start_line,
286 | "end_line": end_line,
287 | "bases": bases,
288 | "source": source_text,
289 | "file_path": str(file_path),
290 | "lang": self.language_name,
291 | })
292 |
293 | except Exception as e:
294 | error_logger(f"Error parsing class in {file_path}: {e}")
295 | continue
296 |
297 | return classes
298 |
299 | def _parse_variables(self, captures: list, source_code: str, file_path: Path) -> list[Dict[str, Any]]:
300 | variables = []
301 | seen_vars = set()
302 |
303 | for node, capture_name in captures:
304 | if capture_name == "variable":
305 | try:
306 | start_line = node.start_point[0] + 1
307 | ctx_name, ctx_type, ctx_line = self._get_parent_context(node)
308 |
309 | # Destructuring declaration
310 | if "destructuring" in node.type:
311 | pass
312 |
313 | # Regular property/variable
314 | var_name = "unknown"
315 | var_type = "Unknown"
316 |
317 | var_decl = None
318 | for child in node.children:
319 | if child.type == "variable_declaration":
320 | var_decl = child
321 | break
322 |
323 | if var_decl:
324 | # Check for name and type in variable_declaration
325 | for child in var_decl.children:
326 | if child.type == "simple_identifier":
327 | var_name = self._get_node_text(child)
328 |
329 | if child.type == "user_type":
330 | var_type = self._get_node_text(child)
331 |
332 | # Attempt inference from initializer if type is unknown
333 | if var_type == "Unknown":
334 | # property_declaration -> expression (e.g. call_expression)
335 | for child in node.children:
336 | if child.type == "call_expression":
337 | # call_expression -> simple_identifier (constructor)
338 | for sub in child.children:
339 | if sub.type == "simple_identifier":
340 | var_type = self._get_node_text(sub)
341 | break
342 | if var_type != "Unknown": break
343 |
344 | if var_name != "unknown":
345 | variables.append({
346 | "name": var_name,
347 | "type": var_type,
348 | "line_number": start_line,
349 | "file_path": str(file_path),
350 | "lang": self.language_name,
351 | "context": ctx_name,
352 | "class_context": ctx_name if ctx_type and ("class" in ctx_type or "object" in ctx_type) else None
353 | })
354 | except Exception as e:
355 | continue
356 |
357 | return variables
358 |
359 | def _parse_imports(self, captures: list, source_code: str) -> list[dict]:
360 | imports = []
361 |
362 | for node, capture_name in captures:
363 | if capture_name == "import":
364 | try:
365 | # import_header -> "import" identifier (import_alias)?
366 | text = self._get_node_text(node)
367 | # remove 'import '
368 | path = text.replace('import ', '').strip().split(' as ')[0].strip()
369 | alias = None
370 | if ' as ' in text:
371 | alias = text.split(' as ')[1].strip()
372 |
373 | imports.append({
374 | "name": path,
375 | "full_import_name": path,
376 | "line_number": node.start_point[0] + 1,
377 | "alias": alias,
378 | "context": (None, None),
379 | "lang": self.language_name,
380 | "is_dependency": False,
381 | })
382 | except Exception as e:
383 | continue
384 |
385 | return imports
386 |
387 | def _parse_calls(self, captures: list, source_code: str, file_path: Path, variables: list[Dict[str, Any]] = []) -> list[Dict[str, Any]]:
388 | calls = []
389 | seen_calls = set()
390 |
391 | # Index variables for fast lookup: (name, context) -> type
392 | var_map = {}
393 | for v in variables:
394 | key = (v['name'], v['context'])
395 | var_map[key] = v['type']
396 | # Fallback for null context or partial match could be added
397 | # For class props: (name, class_context) might work if local lookup fails?
398 |
399 | for node, capture_name in captures:
400 | if capture_name == "call_node":
401 | try:
402 | # navigation_expression check
403 |
404 | start_line = node.start_point[0] + 1
405 |
406 | call_name = "unknown"
407 | base_obj = None
408 |
409 | # call_expression usually has children:
410 | # simple_identifier (func name)
411 | # or navigation_expression (obj.method)
412 |
413 | # Heuristic for base object:
414 | # If navigation_expression -> child[0] is base, child[1] is suffix (method)
415 |
416 | # We need to look deeper into the call_expression structure.
417 | # call_expression -> (simple_identifier)
418 | # OR call_expression -> (navigation_expression (simple_identifier) (navigation_suffix (simple_identifier) ...))
419 | # OR call_expression -> (navigation_expression (call_expression) ...) (chained)
420 |
421 | # Simplified traversal to find the "function name" and "receiver"
422 |
423 | # If it's a direct call: foo()
424 | # If it's a method call: x.foo()
425 |
426 | # Tree-sitter struct:
427 | # (call_expression (simple_identifier) (call_suffix ...)) -> name = simple_identifier
428 | # (call_expression (navigation_expression (simple_identifier) (navigation_suffix (simple_identifier))) (call_suffix))
429 | # -> name = 2nd simple_identifier, base = 1st simple_identifier
430 |
431 | # Let's verify children
432 | children = node.children
433 | first_child = children[0]
434 |
435 | if first_child.type == "simple_identifier":
436 | call_name = self._get_node_text(first_child)
437 | # No explicit base object
438 | elif first_child.type == "navigation_expression":
439 | # x.foo
440 | # children: operand (x), operator (.), suffix (foo)
441 | # Usually 3 children?
442 | # Let's inspect nav expression children
443 | nav_children = first_child.children
444 | if len(nav_children) >= 2:
445 | # operand is 0
446 | operand = nav_children[0]
447 | # last one is suffix?
448 | suffix = nav_children[-1]
449 |
450 | # Suffix usually contains the method name in a navigation_suffix node or directly?
451 | # Suffix is (navigation_suffix (simple_identifier)) usually.
452 |
453 | if suffix.type == "navigation_suffix":
454 | # (navigation_suffix (simple_identifier))
455 | for c in suffix.children:
456 | if c.type == "simple_identifier":
457 | call_name = self._get_node_text(c)
458 | break
459 | elif suffix.type == "simple_identifier":
460 | call_name = self._get_node_text(suffix)
461 |
462 | # Base object
463 | base_obj = self._get_node_text(operand)
464 |
465 | if call_name == "unknown":
466 | continue
467 |
468 | full_name = f"{base_obj}.{call_name}" if base_obj else call_name
469 |
470 | ctx_name, ctx_type, ctx_line = self._get_parent_context(node)
471 |
472 | # Inference
473 | inferred_type = None
474 | if base_obj:
475 | # Lookup base_obj in variables
476 | # Try exact context
477 | inferred_type = var_map.get((base_obj, ctx_name))
478 | if not inferred_type:
479 | # Try class context if we are in a method
480 | # This logic is approximate.
481 | # If we are in method 'foo' of 'ClassA', and 'base_obj' refers to a property of 'ClassA',
482 | # var_map entry would have context 'ClassA'.
483 | # But our 'variables' parsing puts context as 'ClassA' for props.
484 | # But 'ctx_name' here is 'foo'.
485 | # We need to know 'foo' is in 'ClassA'.
486 | # 'get_parent_context' returns immediate parent.
487 | pass
488 | # Fallback: check global/file scope (context=None)
489 | if not inferred_type:
490 | inferred_type = var_map.get((base_obj, None))
491 |
492 | # Fallback: check if any variable named base_obj exists (loose match)
493 | if not inferred_type:
494 | for (vname, vctx), vtype in var_map.items():
495 | if vname == base_obj:
496 | inferred_type = vtype
497 | break
498 |
499 |
500 | calls.append({
501 | "name": call_name,
502 | "full_name": full_name,
503 | "line_number": start_line,
504 | "args": [], # Simplified
505 | "inferred_obj_type": inferred_type,
506 | "context": [None, ctx_type, ctx_line], # Keeping format compatible
507 | "class_context": [None, None],
508 | "lang": self.language_name,
509 | "is_dependency": False
510 | })
511 | except Exception as e:
512 | continue
513 | return calls
514 |
515 | def _extract_parameter_names(self, params_text: str) -> list[str]:
516 | """
517 | Extracts parameter names from a Kotlin parameter list string.
518 | Handles nested generics like Map<String, Int>.
519 |
520 | Args:
521 | params_text (str): The text content of function_value_parameters node, e.g. "(a: Int, b: Map<String, Int>)"
522 |
523 | Returns:
524 | list[str]: List of parameter names.
525 | """
526 | params = []
527 | if not params_text: return params
528 |
529 | # Remove outer parentheses
530 | clean = params_text.strip()
531 | if clean.startswith('(') and clean.endswith(')'):
532 | clean = clean[1:-1]
533 |
534 | if not clean.strip(): return params
535 |
536 | # Robust splitting by comma, respecting brackets <>, (), [], {}
537 | current_param = []
538 | depth_angle = 0 # < >
539 | depth_round = 0 # ( )
540 | depth_square = 0 # [ ]
541 | depth_curly = 0 # { }
542 |
543 | raw_params = []
544 |
545 | for char in clean:
546 | if char == '<': depth_angle += 1
547 | elif char == '>': depth_angle -= 1
548 | elif char == '(': depth_round += 1
549 | elif char == ')': depth_round -= 1
550 | elif char == '[': depth_square += 1
551 | elif char == ']': depth_square -= 1
552 | elif char == '{': depth_curly += 1
553 | elif char == '}': depth_curly -= 1
554 |
555 | if char == ',' and depth_angle == 0 and depth_round == 0 and depth_square == 0 and depth_curly == 0:
556 | raw_params.append("".join(current_param).strip())
557 | current_param = []
558 | else:
559 | current_param.append(char)
560 |
561 | if current_param:
562 | raw_params.append("".join(current_param).strip())
563 |
564 | # Process each raw parameter string to extract name
565 | # Format: "val x: Int", "override var y: String", "@Ann z: Int", "a: Int = 5"
566 | for p in raw_params:
567 | if not p: continue
568 |
569 | # Remove default value if present
570 | # Be careful with '=' inside strings or generic defaults, but usually param defaults are at top level
571 | # A simple split by '=' might be risky if default value has '=', but for name extraction it's usually safe
572 | # as the name is on the LHS.
573 | # But wait, "val x: Type = ..." -> name is before ':'
574 |
575 | # Split by ':' to separate name/modifiers from Type
576 | # Using the first ':' usually works, assuming name doesn't contain ':'
577 | colon_index = p.find(':')
578 | if colon_index != -1:
579 | lhs = p[:colon_index].strip()
580 | else:
581 | # Could be a parameter without type? (not common in Kotlin unless lambda destructuring)
582 | # Or "var x = 5" (unlikely in func params)
583 | # Just take the whole string if no colon?
584 | lhs = p.strip()
585 |
586 | # LHS contains keywords (val, var), annotations (@Foo), modifiers (crossinline, noinline, vararg)
587 | # and the parameter name. The parameter name is usually the LAST identifier.
588 |
589 | if not lhs: continue
590 |
591 | tokens = lhs.split()
592 | if tokens:
593 | # The name is the last token
594 | params.append(tokens[-1])
595 |
596 | return params
597 |
598 | def pre_scan_kotlin(files: list[Path], parser_wrapper) -> dict:
599 | name_to_files = {}
600 | for file_path in files:
601 | try:
602 | with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
603 | content = f.read()
604 |
605 | # 1. Extract package
606 | # package com.example.project
607 | package_name = ""
608 | pkg_match = re.search(r'^\s*package\s+([\w\.]+)', content, re.MULTILINE)
609 | if pkg_match:
610 | package_name = pkg_match.group(1)
611 |
612 | # 2. Extract classes/objects/interfaces/typealiases
613 | matches = re.finditer(r'\b(class|interface|object|typealias)\s+(\w+)', content)
614 |
615 | for match in matches:
616 | name = match.group(2)
617 | # Map simple name
618 | if name not in name_to_files:
619 | name_to_files[name] = []
620 | name_to_files[name].append(str(file_path))
621 |
622 | # If package exists, map FQN
623 | if package_name:
624 | fqn = f"{package_name}.{name}"
625 | if fqn not in name_to_files:
626 | name_to_files[fqn] = []
627 | name_to_files[fqn].append(str(file_path))
628 |
629 | except Exception:
630 | pass
631 | return name_to_files
632 |
```
--------------------------------------------------------------------------------
/docs/site/cli/index.html:
--------------------------------------------------------------------------------
```html
1 |
2 | <!doctype html>
3 | <html lang="en" class="no-js">
4 | <head>
5 |
6 | <meta charset="utf-8">
7 | <meta name="viewport" content="width=device-width,initial-scale=1">
8 |
9 |
10 |
11 |
12 | <link rel="prev" href="../architecture/">
13 |
14 |
15 | <link rel="next" href="../watching/">
16 |
17 |
18 |
19 |
20 |
21 | <link rel="icon" href="../assets/images/favicon.png">
22 | <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
23 |
24 |
25 |
26 | <title>CLI Reference - CodeGraphContext</title>
27 |
28 |
29 |
30 | <link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
44 | <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">
45 | <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
46 |
47 |
48 |
49 | <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>
50 |
51 |
52 |
53 |
54 |
55 | </head>
56 |
57 |
58 | <body dir="ltr">
59 |
60 |
61 | <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
62 | <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
63 | <label class="md-overlay" for="__drawer"></label>
64 | <div data-md-component="skip">
65 |
66 |
67 | <a href="#cli-reference" class="md-skip">
68 | Skip to content
69 | </a>
70 |
71 | </div>
72 | <div data-md-component="announce">
73 |
74 | </div>
75 |
76 |
77 |
78 |
79 |
80 |
81 | <header class="md-header md-header--shadow" data-md-component="header">
82 | <nav class="md-header__inner md-grid" aria-label="Header">
83 | <a href=".." title="CodeGraphContext" class="md-header__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
84 |
85 |
86 | <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>
87 |
88 | </a>
89 | <label class="md-header__button md-icon" for="__drawer">
90 |
91 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
92 | </label>
93 | <div class="md-header__title" data-md-component="header-title">
94 | <div class="md-header__ellipsis">
95 | <div class="md-header__topic">
96 | <span class="md-ellipsis">
97 | CodeGraphContext
98 | </span>
99 | </div>
100 | <div class="md-header__topic" data-md-component="header-topic">
101 | <span class="md-ellipsis">
102 |
103 | CLI Reference
104 |
105 | </span>
106 | </div>
107 | </div>
108 | </div>
109 |
110 |
111 | <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>
112 |
113 |
114 |
115 |
116 |
117 | <label class="md-header__button md-icon" for="__search">
118 |
119 | <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>
120 | </label>
121 | <div class="md-search" data-md-component="search" role="dialog">
122 | <label class="md-search__overlay" for="__search"></label>
123 | <div class="md-search__inner" role="search">
124 | <form class="md-search__form" name="search">
125 | <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>
126 | <label class="md-search__icon md-icon" for="__search">
127 |
128 | <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>
129 |
130 | <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>
131 | </label>
132 | <nav class="md-search__options" aria-label="Search">
133 |
134 | <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
135 |
136 | <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>
137 | </button>
138 | </nav>
139 |
140 | </form>
141 | <div class="md-search__output">
142 | <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
143 | <div class="md-search-result" data-md-component="search-result">
144 | <div class="md-search-result__meta">
145 | Initializing search
146 | </div>
147 | <ol class="md-search-result__list" role="presentation"></ol>
148 | </div>
149 | </div>
150 | </div>
151 | </div>
152 | </div>
153 |
154 |
155 |
156 | </nav>
157 |
158 | </header>
159 |
160 | <div class="md-container" data-md-component="container">
161 |
162 |
163 |
164 |
165 |
166 |
167 | <main class="md-main" data-md-component="main">
168 | <div class="md-main__inner md-grid">
169 |
170 |
171 |
172 | <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
173 | <div class="md-sidebar__scrollwrap">
174 | <div class="md-sidebar__inner">
175 |
176 |
177 |
178 |
179 | <nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
180 | <label class="md-nav__title" for="__drawer">
181 | <a href=".." title="CodeGraphContext" class="md-nav__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
182 |
183 |
184 | <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>
185 |
186 | </a>
187 | CodeGraphContext
188 | </label>
189 |
190 | <ul class="md-nav__list" data-md-scrollfix>
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | <li class="md-nav__item">
199 | <a href=".." class="md-nav__link">
200 |
201 |
202 |
203 | <span class="md-ellipsis">
204 |
205 |
206 | Home
207 |
208 |
209 |
210 | </span>
211 |
212 |
213 |
214 | </a>
215 | </li>
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 | <li class="md-nav__item">
226 | <a href="../installation/" class="md-nav__link">
227 |
228 |
229 |
230 | <span class="md-ellipsis">
231 |
232 |
233 | Installation
234 |
235 |
236 |
237 | </span>
238 |
239 |
240 |
241 | </a>
242 | </li>
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 | <li class="md-nav__item">
253 | <a href="../use_cases/" class="md-nav__link">
254 |
255 |
256 |
257 | <span class="md-ellipsis">
258 |
259 |
260 | Use Cases
261 |
262 |
263 |
264 | </span>
265 |
266 |
267 |
268 | </a>
269 | </li>
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 | <li class="md-nav__item">
280 | <a href="../architecture/" class="md-nav__link">
281 |
282 |
283 |
284 | <span class="md-ellipsis">
285 |
286 |
287 | Architecture
288 |
289 |
290 |
291 | </span>
292 |
293 |
294 |
295 | </a>
296 | </li>
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 | <li class="md-nav__item md-nav__item--active">
309 |
310 | <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
311 |
312 |
313 |
314 |
315 |
316 | <label class="md-nav__link md-nav__link--active" for="__toc">
317 |
318 |
319 |
320 | <span class="md-ellipsis">
321 |
322 |
323 | CLI Reference
324 |
325 |
326 |
327 | </span>
328 |
329 |
330 |
331 | <span class="md-nav__icon md-icon"></span>
332 | </label>
333 |
334 | <a href="./" class="md-nav__link md-nav__link--active">
335 |
336 |
337 |
338 | <span class="md-ellipsis">
339 |
340 |
341 | CLI Reference
342 |
343 |
344 |
345 | </span>
346 |
347 |
348 |
349 | </a>
350 |
351 |
352 |
353 | <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
354 |
355 |
356 |
357 |
358 |
359 |
360 | <label class="md-nav__title" for="__toc">
361 | <span class="md-nav__icon md-icon"></span>
362 | Table of contents
363 | </label>
364 | <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
365 |
366 | <li class="md-nav__item">
367 | <a href="#1-project-management" class="md-nav__link">
368 | <span class="md-ellipsis">
369 |
370 | 1. Project Management
371 |
372 | </span>
373 | </a>
374 |
375 | </li>
376 |
377 | <li class="md-nav__item">
378 | <a href="#2-watching-monitoring" class="md-nav__link">
379 | <span class="md-ellipsis">
380 |
381 | 2. Watching & Monitoring
382 |
383 | </span>
384 | </a>
385 |
386 | </li>
387 |
388 | <li class="md-nav__item">
389 | <a href="#3-code-analysis" class="md-nav__link">
390 | <span class="md-ellipsis">
391 |
392 | 3. Code Analysis
393 |
394 | </span>
395 | </a>
396 |
397 | </li>
398 |
399 | <li class="md-nav__item">
400 | <a href="#4-discovery-search" class="md-nav__link">
401 | <span class="md-ellipsis">
402 |
403 | 4. Discovery & Search
404 |
405 | </span>
406 | </a>
407 |
408 | </li>
409 |
410 | <li class="md-nav__item">
411 | <a href="#5-configuration-setup" class="md-nav__link">
412 | <span class="md-ellipsis">
413 |
414 | 5. Configuration & Setup
415 |
416 | </span>
417 | </a>
418 |
419 | </li>
420 |
421 | <li class="md-nav__item">
422 | <a href="#6-utilities-runtime" class="md-nav__link">
423 | <span class="md-ellipsis">
424 |
425 | 6. Utilities & Runtime
426 |
427 | </span>
428 | </a>
429 |
430 | </li>
431 |
432 | </ul>
433 |
434 | </nav>
435 |
436 | </li>
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 | <li class="md-nav__item">
447 | <a href="../watching/" class="md-nav__link">
448 |
449 |
450 |
451 | <span class="md-ellipsis">
452 |
453 |
454 | Live Watching
455 |
456 |
457 |
458 | </span>
459 |
460 |
461 |
462 | </a>
463 | </li>
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 | <li class="md-nav__item">
474 | <a href="../server/" class="md-nav__link">
475 |
476 |
477 |
478 | <span class="md-ellipsis">
479 |
480 |
481 | Server
482 |
483 |
484 |
485 | </span>
486 |
487 |
488 |
489 | </a>
490 | </li>
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 | <li class="md-nav__item">
501 | <a href="../core/" class="md-nav__link">
502 |
503 |
504 |
505 | <span class="md-ellipsis">
506 |
507 |
508 | Core Concepts
509 |
510 |
511 |
512 | </span>
513 |
514 |
515 |
516 | </a>
517 | </li>
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 | <li class="md-nav__item">
528 | <a href="../tools/" class="md-nav__link">
529 |
530 |
531 |
532 | <span class="md-ellipsis">
533 |
534 |
535 | Tools
536 |
537 |
538 |
539 | </span>
540 |
541 |
542 |
543 | </a>
544 | </li>
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 | <li class="md-nav__item">
555 | <a href="../cookbook/" class="md-nav__link">
556 |
557 |
558 |
559 | <span class="md-ellipsis">
560 |
561 |
562 | Cookbook
563 |
564 |
565 |
566 | </span>
567 |
568 |
569 |
570 | </a>
571 | </li>
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 | <li class="md-nav__item md-nav__item--nested">
587 |
588 |
589 |
590 | <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_11" >
591 |
592 |
593 | <label class="md-nav__link" for="__nav_11" id="__nav_11_label" tabindex="0">
594 |
595 |
596 |
597 | <span class="md-ellipsis">
598 |
599 |
600 | Contributing
601 |
602 |
603 |
604 | </span>
605 |
606 |
607 |
608 | <span class="md-nav__icon md-icon"></span>
609 | </label>
610 |
611 | <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_11_label" aria-expanded="false">
612 | <label class="md-nav__title" for="__nav_11">
613 | <span class="md-nav__icon md-icon"></span>
614 |
615 |
616 | Contributing
617 |
618 |
619 | </label>
620 | <ul class="md-nav__list" data-md-scrollfix>
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 | <li class="md-nav__item">
629 | <a href="../contributing/" class="md-nav__link">
630 |
631 |
632 |
633 | <span class="md-ellipsis">
634 |
635 |
636 | Overview
637 |
638 |
639 |
640 | </span>
641 |
642 |
643 |
644 | </a>
645 | </li>
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 | <li class="md-nav__item">
657 | <a href="../contributing_languages/" class="md-nav__link">
658 |
659 |
660 |
661 | <span class="md-ellipsis">
662 |
663 |
664 | Adding New Languages
665 |
666 |
667 |
668 | </span>
669 |
670 |
671 |
672 | </a>
673 | </li>
674 |
675 |
676 |
677 |
678 | </ul>
679 | </nav>
680 |
681 | </li>
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 | <li class="md-nav__item">
692 | <a href="../troubleshooting/" class="md-nav__link">
693 |
694 |
695 |
696 | <span class="md-ellipsis">
697 |
698 |
699 | Troubleshooting
700 |
701 |
702 |
703 | </span>
704 |
705 |
706 |
707 | </a>
708 | </li>
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 | <li class="md-nav__item">
719 | <a href="../future_work/" class="md-nav__link">
720 |
721 |
722 |
723 | <span class="md-ellipsis">
724 |
725 |
726 | Future Work
727 |
728 |
729 |
730 | </span>
731 |
732 |
733 |
734 | </a>
735 | </li>
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 | <li class="md-nav__item">
746 | <a href="../license/" class="md-nav__link">
747 |
748 |
749 |
750 | <span class="md-ellipsis">
751 |
752 |
753 | License
754 |
755 |
756 |
757 | </span>
758 |
759 |
760 |
761 | </a>
762 | </li>
763 |
764 |
765 |
766 | </ul>
767 | </nav>
768 | </div>
769 | </div>
770 | </div>
771 |
772 |
773 |
774 | <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
775 | <div class="md-sidebar__scrollwrap">
776 | <div class="md-sidebar__inner">
777 |
778 |
779 | <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
780 |
781 |
782 |
783 |
784 |
785 |
786 | <label class="md-nav__title" for="__toc">
787 | <span class="md-nav__icon md-icon"></span>
788 | Table of contents
789 | </label>
790 | <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
791 |
792 | <li class="md-nav__item">
793 | <a href="#1-project-management" class="md-nav__link">
794 | <span class="md-ellipsis">
795 |
796 | 1. Project Management
797 |
798 | </span>
799 | </a>
800 |
801 | </li>
802 |
803 | <li class="md-nav__item">
804 | <a href="#2-watching-monitoring" class="md-nav__link">
805 | <span class="md-ellipsis">
806 |
807 | 2. Watching & Monitoring
808 |
809 | </span>
810 | </a>
811 |
812 | </li>
813 |
814 | <li class="md-nav__item">
815 | <a href="#3-code-analysis" class="md-nav__link">
816 | <span class="md-ellipsis">
817 |
818 | 3. Code Analysis
819 |
820 | </span>
821 | </a>
822 |
823 | </li>
824 |
825 | <li class="md-nav__item">
826 | <a href="#4-discovery-search" class="md-nav__link">
827 | <span class="md-ellipsis">
828 |
829 | 4. Discovery & Search
830 |
831 | </span>
832 | </a>
833 |
834 | </li>
835 |
836 | <li class="md-nav__item">
837 | <a href="#5-configuration-setup" class="md-nav__link">
838 | <span class="md-ellipsis">
839 |
840 | 5. Configuration & Setup
841 |
842 | </span>
843 | </a>
844 |
845 | </li>
846 |
847 | <li class="md-nav__item">
848 | <a href="#6-utilities-runtime" class="md-nav__link">
849 | <span class="md-ellipsis">
850 |
851 | 6. Utilities & Runtime
852 |
853 | </span>
854 | </a>
855 |
856 | </li>
857 |
858 | </ul>
859 |
860 | </nav>
861 | </div>
862 | </div>
863 | </div>
864 |
865 |
866 |
867 | <div class="md-content" data-md-component="content">
868 |
869 | <article class="md-content__inner md-typeset">
870 |
871 |
872 |
873 |
874 |
875 | <h1 id="cli-reference">CLI Reference</h1>
876 | <p>The CodeGraphContext CLI provides a comprehensive command-line interface to manage the server, index your code, search, analyzing and interact with the code graph.</p>
877 | <h2 id="1-project-management">1. Project Management</h2>
878 | <p>Use these commands to manage the repositories in your code graph.</p>
879 | <table>
880 | <thead>
881 | <tr>
882 | <th style="text-align: left;">Command</th>
883 | <th style="text-align: left;">Arguments</th>
884 | <th style="text-align: left;">Description</th>
885 | </tr>
886 | </thead>
887 | <tbody>
888 | <tr>
889 | <td style="text-align: left;"><strong><code>cgc index</code></strong></td>
890 | <td style="text-align: left;"><code>[path]</code> <br> <code>--force</code></td>
891 | <td style="text-align: left;">Adds a repository to the graph. Default path is current directory. Use <code>--force</code> to re-index from scratch. <br> <em>(Alias: <code>cgc i</code>)</em></td>
892 | </tr>
893 | <tr>
894 | <td style="text-align: left;"><strong><code>cgc list</code></strong></td>
895 | <td style="text-align: left;">None</td>
896 | <td style="text-align: left;">Lists all repositories currently indexed in the database. <br> <em>(Alias: <code>cgc ls</code>)</em></td>
897 | </tr>
898 | <tr>
899 | <td style="text-align: left;"><strong><code>cgc delete</code></strong></td>
900 | <td style="text-align: left;"><code>[path]</code> <br> <code>--all</code></td>
901 | <td style="text-align: left;">Removes a repository from the graph. Use <code>--all</code> to wipe everything. <br> <em>(Alias: <code>cgc rm</code>)</em></td>
902 | </tr>
903 | <tr>
904 | <td style="text-align: left;"><strong><code>cgc stats</code></strong></td>
905 | <td style="text-align: left;"><code>[path]</code></td>
906 | <td style="text-align: left;">Shows indexing statistics (node counts) for the DB or a specific repo.</td>
907 | </tr>
908 | <tr>
909 | <td style="text-align: left;"><strong><code>cgc clean</code></strong></td>
910 | <td style="text-align: left;">None</td>
911 | <td style="text-align: left;">Removes orphaned nodes and cleans up the database.</td>
912 | </tr>
913 | <tr>
914 | <td style="text-align: left;"><strong><code>cgc add-package</code></strong></td>
915 | <td style="text-align: left;"><code><name> <lang></code></td>
916 | <td style="text-align: left;">Manually adds an external package node (e.g., <code>cgc add-package requests python</code>).</td>
917 | </tr>
918 | </tbody>
919 | </table>
920 | <h2 id="2-watching-monitoring">2. Watching & Monitoring</h2>
921 | <p>Automatically track changes and keep your code graph up-to-date.</p>
922 | <table>
923 | <thead>
924 | <tr>
925 | <th style="text-align: left;">Command</th>
926 | <th style="text-align: left;">Arguments</th>
927 | <th style="text-align: left;">Description</th>
928 | </tr>
929 | </thead>
930 | <tbody>
931 | <tr>
932 | <td style="text-align: left;"><strong><code>cgc watch</code></strong></td>
933 | <td style="text-align: left;"><code>[path]</code></td>
934 | <td style="text-align: left;">Watches a directory for file changes and automatically re-indexes. Runs in foreground. Default path is current directory. <br> <em>(Alias: <code>cgc w</code>)</em></td>
935 | </tr>
936 | <tr>
937 | <td style="text-align: left;"><strong><code>cgc unwatch</code></strong></td>
938 | <td style="text-align: left;"><code><path></code></td>
939 | <td style="text-align: left;">Stops watching a previously watched directory. (Primarily for MCP mode)</td>
940 | </tr>
941 | <tr>
942 | <td style="text-align: left;"><strong><code>cgc watching</code></strong></td>
943 | <td style="text-align: left;">None</td>
944 | <td style="text-align: left;">Lists all directories currently being watched for changes. (Primarily for MCP mode)</td>
945 | </tr>
946 | </tbody>
947 | </table>
948 | <h2 id="3-code-analysis">3. Code Analysis</h2>
949 | <p>Understand the structure, quality, and relationships of your code.</p>
950 | <table>
951 | <thead>
952 | <tr>
953 | <th style="text-align: left;">Command</th>
954 | <th style="text-align: left;">Arguments</th>
955 | <th style="text-align: left;">Description</th>
956 | </tr>
957 | </thead>
958 | <tbody>
959 | <tr>
960 | <td style="text-align: left;"><strong><code>cgc analyze calls</code></strong></td>
961 | <td style="text-align: left;"><code><func_name></code> <br> <code>--file</code></td>
962 | <td style="text-align: left;">Shows <strong>outgoing</strong> calls: what functions does this function call?</td>
963 | </tr>
964 | <tr>
965 | <td style="text-align: left;"><strong><code>cgc analyze callers</code></strong></td>
966 | <td style="text-align: left;"><code><func_name></code> <br> <code>--file</code></td>
967 | <td style="text-align: left;">Shows <strong>incoming</strong> calls: who calls this function?</td>
968 | </tr>
969 | <tr>
970 | <td style="text-align: left;"><strong><code>cgc analyze chain</code></strong></td>
971 | <td style="text-align: left;"><code><start> <end></code> <br> <code>--depth</code></td>
972 | <td style="text-align: left;">Finds the call path between two functions. Default depth is 5.</td>
973 | </tr>
974 | <tr>
975 | <td style="text-align: left;"><strong><code>cgc analyze deps</code></strong></td>
976 | <td style="text-align: left;"><code><module></code> <br> <code>--no-external</code></td>
977 | <td style="text-align: left;">Inspects dependencies (imports and importers) for a module.</td>
978 | </tr>
979 | <tr>
980 | <td style="text-align: left;"><strong><code>cgc analyze tree</code></strong></td>
981 | <td style="text-align: left;"><code><class_name></code> <br> <code>--file</code></td>
982 | <td style="text-align: left;">Visualizes the Class Inheritance hierarchy for a given class.</td>
983 | </tr>
984 | <tr>
985 | <td style="text-align: left;"><strong><code>cgc analyze complexity</code></strong></td>
986 | <td style="text-align: left;"><code>[path]</code> <br> <code>--threshold</code> <br> <code>--limit</code></td>
987 | <td style="text-align: left;">Lists functions with high Cyclomatic Complexity. Default threshold: 10.</td>
988 | </tr>
989 | <tr>
990 | <td style="text-align: left;"><strong><code>cgc analyze dead-code</code></strong></td>
991 | <td style="text-align: left;"><code>--exclude</code></td>
992 | <td style="text-align: left;">Finds potentially unused functions (0 callers). Use <code>--exclude</code> for decorators.</td>
993 | </tr>
994 | </tbody>
995 | </table>
996 | <h2 id="4-discovery-search">4. Discovery & Search</h2>
997 | <p>Find code elements when you don't know the exact structure.</p>
998 | <table>
999 | <thead>
1000 | <tr>
1001 | <th style="text-align: left;">Command</th>
1002 | <th style="text-align: left;">Arguments</th>
1003 | <th style="text-align: left;">Description</th>
1004 | </tr>
1005 | </thead>
1006 | <tbody>
1007 | <tr>
1008 | <td style="text-align: left;"><strong><code>cgc find name</code></strong></td>
1009 | <td style="text-align: left;"><code><name></code> <br> <code>--type</code></td>
1010 | <td style="text-align: left;">Finds code elements (Class, Function) by their <strong>exact</strong> name.</td>
1011 | </tr>
1012 | <tr>
1013 | <td style="text-align: left;"><strong><code>cgc find pattern</code></strong></td>
1014 | <td style="text-align: left;"><code><pattern></code> <br> <code>--case-sensitive</code></td>
1015 | <td style="text-align: left;">Finds elements using fuzzy substring matching (e.g. "User" finds "UserHelper").</td>
1016 | </tr>
1017 | <tr>
1018 | <td style="text-align: left;"><strong><code>cgc find type</code></strong></td>
1019 | <td style="text-align: left;"><code><type></code> <br> <code>--limit</code></td>
1020 | <td style="text-align: left;">Lists all nodes of a specific type (e.g. <code>function</code>, <code>class</code>, <code>module</code>).</td>
1021 | </tr>
1022 | </tbody>
1023 | </table>
1024 | <h2 id="5-configuration-setup">5. Configuration & Setup</h2>
1025 | <p>Manage your environment and database connections.</p>
1026 | <table>
1027 | <thead>
1028 | <tr>
1029 | <th style="text-align: left;">Command</th>
1030 | <th style="text-align: left;">Arguments</th>
1031 | <th style="text-align: left;">Description</th>
1032 | </tr>
1033 | </thead>
1034 | <tbody>
1035 | <tr>
1036 | <td style="text-align: left;"><strong><code>cgc mcp setup</code></strong></td>
1037 | <td style="text-align: left;">None</td>
1038 | <td style="text-align: left;">Configures your IDE/MCP Client. Creates <code>mcp.json</code>. <br> <em>(Alias: <code>cgc m</code>)</em></td>
1039 | </tr>
1040 | <tr>
1041 | <td style="text-align: left;"><strong><code>cgc neo4j setup</code></strong></td>
1042 | <td style="text-align: left;">None</td>
1043 | <td style="text-align: left;">Wizard to configure a Neo4j connection. <br> <em>(Alias: <code>cgc n</code>)</em></td>
1044 | </tr>
1045 | <tr>
1046 | <td style="text-align: left;"><strong><code>cgc config show</code></strong></td>
1047 | <td style="text-align: left;">None</td>
1048 | <td style="text-align: left;">Displays current configuration values.</td>
1049 | </tr>
1050 | <tr>
1051 | <td style="text-align: left;"><strong><code>cgc config set</code></strong></td>
1052 | <td style="text-align: left;"><code><key> <value></code></td>
1053 | <td style="text-align: left;">Sets a config value (e.g. <code>DEFAULT_DATABASE</code>).</td>
1054 | </tr>
1055 | <tr>
1056 | <td style="text-align: left;"><strong><code>cgc config reset</code></strong></td>
1057 | <td style="text-align: left;">None</td>
1058 | <td style="text-align: left;">Resets configuration to defaults.</td>
1059 | </tr>
1060 | <tr>
1061 | <td style="text-align: left;"><strong><code>cgc config db</code></strong></td>
1062 | <td style="text-align: left;"><code><backend></code></td>
1063 | <td style="text-align: left;">Quick switch between <code>neo4j</code> and <code>falkordb</code>.</td>
1064 | </tr>
1065 | </tbody>
1066 | </table>
1067 | <h2 id="6-utilities-runtime">6. Utilities & Runtime</h2>
1068 | <p>Helper commands for developers and the MCP server.</p>
1069 | <table>
1070 | <thead>
1071 | <tr>
1072 | <th style="text-align: left;">Command</th>
1073 | <th style="text-align: left;">Arguments</th>
1074 | <th style="text-align: left;">Description</th>
1075 | </tr>
1076 | </thead>
1077 | <tbody>
1078 | <tr>
1079 | <td style="text-align: left;"><strong><code>cgc doctor</code></strong></td>
1080 | <td style="text-align: left;">None</td>
1081 | <td style="text-align: left;">Runs system diagnostics (DB connection, dependencies, permissions).</td>
1082 | </tr>
1083 | <tr>
1084 | <td style="text-align: left;"><strong><code>cgc visualize</code></strong></td>
1085 | <td style="text-align: left;"><code>[query]</code></td>
1086 | <td style="text-align: left;">Generates a link to open the Neo4j Browser. <br> <em>(Alias: <code>cgc v</code>)</em></td>
1087 | </tr>
1088 | <tr>
1089 | <td style="text-align: left;"><strong><code>cgc query</code></strong></td>
1090 | <td style="text-align: left;"><code><query></code></td>
1091 | <td style="text-align: left;">Executes a raw Cypher query directly against the DB.</td>
1092 | </tr>
1093 | <tr>
1094 | <td style="text-align: left;"><strong><code>cgc mcp start</code></strong></td>
1095 | <td style="text-align: left;">None</td>
1096 | <td style="text-align: left;">Starts the MCP Server (used by IDEs).</td>
1097 | </tr>
1098 | <tr>
1099 | <td style="text-align: left;"><strong><code>cgc mcp tools</code></strong></td>
1100 | <td style="text-align: left;">None</td>
1101 | <td style="text-align: left;">Lists all available MCP tools supported by the server.</td>
1102 | </tr>
1103 | <tr>
1104 | <td style="text-align: left;"><strong><code>cgc start</code></strong></td>
1105 | <td style="text-align: left;">None</td>
1106 | <td style="text-align: left;"><strong>Deprecated</strong>. Use <code>cgc mcp start</code> instead.</td>
1107 | </tr>
1108 | </tbody>
1109 | </table>
1110 |
1111 |
1112 |
1113 |
1114 |
1115 |
1116 |
1117 |
1118 |
1119 |
1120 |
1121 |
1122 |
1123 | </article>
1124 | </div>
1125 |
1126 |
1127 | <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
1128 | </div>
1129 |
1130 | </main>
1131 |
1132 | <footer class="md-footer">
1133 |
1134 | <div class="md-footer-meta md-typeset">
1135 | <div class="md-footer-meta__inner md-grid">
1136 | <div class="md-copyright">
1137 |
1138 |
1139 | Made with
1140 | <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
1141 | Material for MkDocs
1142 | </a>
1143 |
1144 | </div>
1145 |
1146 | </div>
1147 | </div>
1148 | </footer>
1149 |
1150 | </div>
1151 | <div class="md-dialog" data-md-component="dialog">
1152 | <div class="md-dialog__inner md-typeset"></div>
1153 | </div>
1154 |
1155 |
1156 |
1157 |
1158 |
1159 | <script id="__config" type="application/json">{"annotate": null, "base": "..", "features": [], "search": "../assets/javascripts/workers/search.2c215733.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>
1160 |
1161 |
1162 | <script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
1163 |
1164 |
1165 | </body>
1166 | </html>
```
--------------------------------------------------------------------------------
/docs/site/server/index.html:
--------------------------------------------------------------------------------
```html
1 |
2 | <!doctype html>
3 | <html lang="en" class="no-js">
4 | <head>
5 |
6 | <meta charset="utf-8">
7 | <meta name="viewport" content="width=device-width,initial-scale=1">
8 |
9 |
10 |
11 |
12 | <link rel="prev" href="../watching/">
13 |
14 |
15 | <link rel="next" href="../core/">
16 |
17 |
18 |
19 |
20 |
21 | <link rel="icon" href="../assets/images/favicon.png">
22 | <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
23 |
24 |
25 |
26 | <title>Server - CodeGraphContext</title>
27 |
28 |
29 |
30 | <link rel="stylesheet" href="../assets/stylesheets/main.484c7ddc.min.css">
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
44 | <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">
45 | <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
46 |
47 |
48 |
49 | <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>
50 |
51 |
52 |
53 |
54 |
55 | </head>
56 |
57 |
58 | <body dir="ltr">
59 |
60 |
61 | <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
62 | <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
63 | <label class="md-overlay" for="__drawer"></label>
64 | <div data-md-component="skip">
65 |
66 |
67 | <a href="#mcpserver" class="md-skip">
68 | Skip to content
69 | </a>
70 |
71 | </div>
72 | <div data-md-component="announce">
73 |
74 | </div>
75 |
76 |
77 |
78 |
79 |
80 |
81 | <header class="md-header md-header--shadow" data-md-component="header">
82 | <nav class="md-header__inner md-grid" aria-label="Header">
83 | <a href=".." title="CodeGraphContext" class="md-header__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
84 |
85 |
86 | <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>
87 |
88 | </a>
89 | <label class="md-header__button md-icon" for="__drawer">
90 |
91 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
92 | </label>
93 | <div class="md-header__title" data-md-component="header-title">
94 | <div class="md-header__ellipsis">
95 | <div class="md-header__topic">
96 | <span class="md-ellipsis">
97 | CodeGraphContext
98 | </span>
99 | </div>
100 | <div class="md-header__topic" data-md-component="header-topic">
101 | <span class="md-ellipsis">
102 |
103 | Server
104 |
105 | </span>
106 | </div>
107 | </div>
108 | </div>
109 |
110 |
111 | <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>
112 |
113 |
114 |
115 |
116 |
117 | <label class="md-header__button md-icon" for="__search">
118 |
119 | <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>
120 | </label>
121 | <div class="md-search" data-md-component="search" role="dialog">
122 | <label class="md-search__overlay" for="__search"></label>
123 | <div class="md-search__inner" role="search">
124 | <form class="md-search__form" name="search">
125 | <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>
126 | <label class="md-search__icon md-icon" for="__search">
127 |
128 | <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>
129 |
130 | <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>
131 | </label>
132 | <nav class="md-search__options" aria-label="Search">
133 |
134 | <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
135 |
136 | <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>
137 | </button>
138 | </nav>
139 |
140 | </form>
141 | <div class="md-search__output">
142 | <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
143 | <div class="md-search-result" data-md-component="search-result">
144 | <div class="md-search-result__meta">
145 | Initializing search
146 | </div>
147 | <ol class="md-search-result__list" role="presentation"></ol>
148 | </div>
149 | </div>
150 | </div>
151 | </div>
152 | </div>
153 |
154 |
155 |
156 | </nav>
157 |
158 | </header>
159 |
160 | <div class="md-container" data-md-component="container">
161 |
162 |
163 |
164 |
165 |
166 |
167 | <main class="md-main" data-md-component="main">
168 | <div class="md-main__inner md-grid">
169 |
170 |
171 |
172 | <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
173 | <div class="md-sidebar__scrollwrap">
174 | <div class="md-sidebar__inner">
175 |
176 |
177 |
178 |
179 | <nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
180 | <label class="md-nav__title" for="__drawer">
181 | <a href=".." title="CodeGraphContext" class="md-nav__button md-logo" aria-label="CodeGraphContext" data-md-component="logo">
182 |
183 |
184 | <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>
185 |
186 | </a>
187 | CodeGraphContext
188 | </label>
189 |
190 | <ul class="md-nav__list" data-md-scrollfix>
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | <li class="md-nav__item">
199 | <a href=".." class="md-nav__link">
200 |
201 |
202 |
203 | <span class="md-ellipsis">
204 |
205 |
206 | Home
207 |
208 |
209 |
210 | </span>
211 |
212 |
213 |
214 | </a>
215 | </li>
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 | <li class="md-nav__item">
226 | <a href="../installation/" class="md-nav__link">
227 |
228 |
229 |
230 | <span class="md-ellipsis">
231 |
232 |
233 | Installation
234 |
235 |
236 |
237 | </span>
238 |
239 |
240 |
241 | </a>
242 | </li>
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 | <li class="md-nav__item">
253 | <a href="../use_cases/" class="md-nav__link">
254 |
255 |
256 |
257 | <span class="md-ellipsis">
258 |
259 |
260 | Use Cases
261 |
262 |
263 |
264 | </span>
265 |
266 |
267 |
268 | </a>
269 | </li>
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 | <li class="md-nav__item">
280 | <a href="../architecture/" class="md-nav__link">
281 |
282 |
283 |
284 | <span class="md-ellipsis">
285 |
286 |
287 | Architecture
288 |
289 |
290 |
291 | </span>
292 |
293 |
294 |
295 | </a>
296 | </li>
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 | <li class="md-nav__item">
307 | <a href="../cli/" class="md-nav__link">
308 |
309 |
310 |
311 | <span class="md-ellipsis">
312 |
313 |
314 | CLI Reference
315 |
316 |
317 |
318 | </span>
319 |
320 |
321 |
322 | </a>
323 | </li>
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 | <li class="md-nav__item">
334 | <a href="../watching/" class="md-nav__link">
335 |
336 |
337 |
338 | <span class="md-ellipsis">
339 |
340 |
341 | Live Watching
342 |
343 |
344 |
345 | </span>
346 |
347 |
348 |
349 | </a>
350 | </li>
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 | <li class="md-nav__item md-nav__item--active">
363 |
364 | <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
365 |
366 |
367 |
368 |
369 |
370 | <label class="md-nav__link md-nav__link--active" for="__toc">
371 |
372 |
373 |
374 | <span class="md-ellipsis">
375 |
376 |
377 | Server
378 |
379 |
380 |
381 | </span>
382 |
383 |
384 |
385 | <span class="md-nav__icon md-icon"></span>
386 | </label>
387 |
388 | <a href="./" class="md-nav__link md-nav__link--active">
389 |
390 |
391 |
392 | <span class="md-ellipsis">
393 |
394 |
395 | Server
396 |
397 |
398 |
399 | </span>
400 |
401 |
402 |
403 | </a>
404 |
405 |
406 |
407 | <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
408 |
409 |
410 |
411 |
412 |
413 |
414 | <label class="md-nav__title" for="__toc">
415 | <span class="md-nav__icon md-icon"></span>
416 | Table of contents
417 | </label>
418 | <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
419 |
420 | <li class="md-nav__item">
421 | <a href="#initialization" class="md-nav__link">
422 | <span class="md-ellipsis">
423 |
424 | Initialization
425 |
426 | </span>
427 | </a>
428 |
429 | </li>
430 |
431 | <li class="md-nav__item">
432 | <a href="#tool-manifest" class="md-nav__link">
433 | <span class="md-ellipsis">
434 |
435 | Tool Manifest
436 |
437 | </span>
438 | </a>
439 |
440 | <nav class="md-nav" aria-label="Tool Manifest">
441 | <ul class="md-nav__list">
442 |
443 | <li class="md-nav__item">
444 | <a href="#add_code_to_graph" class="md-nav__link">
445 | <span class="md-ellipsis">
446 |
447 | add_code_to_graph
448 |
449 | </span>
450 | </a>
451 |
452 | </li>
453 |
454 | <li class="md-nav__item">
455 | <a href="#check_job_status" class="md-nav__link">
456 | <span class="md-ellipsis">
457 |
458 | check_job_status
459 |
460 | </span>
461 | </a>
462 |
463 | </li>
464 |
465 | <li class="md-nav__item">
466 | <a href="#list_jobs" class="md-nav__link">
467 | <span class="md-ellipsis">
468 |
469 | list_jobs
470 |
471 | </span>
472 | </a>
473 |
474 | </li>
475 |
476 | <li class="md-nav__item">
477 | <a href="#find_code" class="md-nav__link">
478 | <span class="md-ellipsis">
479 |
480 | find_code
481 |
482 | </span>
483 | </a>
484 |
485 | </li>
486 |
487 | <li class="md-nav__item">
488 | <a href="#analyze_code_relationships" class="md-nav__link">
489 | <span class="md-ellipsis">
490 |
491 | analyze_code_relationships
492 |
493 | </span>
494 | </a>
495 |
496 | </li>
497 |
498 | <li class="md-nav__item">
499 | <a href="#watch_directory" class="md-nav__link">
500 | <span class="md-ellipsis">
501 |
502 | watch_directory
503 |
504 | </span>
505 | </a>
506 |
507 | </li>
508 |
509 | <li class="md-nav__item">
510 | <a href="#execute_cypher_query" class="md-nav__link">
511 | <span class="md-ellipsis">
512 |
513 | execute_cypher_query
514 |
515 | </span>
516 | </a>
517 |
518 | </li>
519 |
520 | <li class="md-nav__item">
521 | <a href="#add_package_to_graph" class="md-nav__link">
522 | <span class="md-ellipsis">
523 |
524 | add_package_to_graph
525 |
526 | </span>
527 | </a>
528 |
529 | </li>
530 |
531 | <li class="md-nav__item">
532 | <a href="#find_dead_code" class="md-nav__link">
533 | <span class="md-ellipsis">
534 |
535 | find_dead_code
536 |
537 | </span>
538 | </a>
539 |
540 | </li>
541 |
542 | <li class="md-nav__item">
543 | <a href="#calculate_cyclomatic_complexity" class="md-nav__link">
544 | <span class="md-ellipsis">
545 |
546 | calculate_cyclomatic_complexity
547 |
548 | </span>
549 | </a>
550 |
551 | </li>
552 |
553 | <li class="md-nav__item">
554 | <a href="#find_most_complex_functions" class="md-nav__link">
555 | <span class="md-ellipsis">
556 |
557 | find_most_complex_functions
558 |
559 | </span>
560 | </a>
561 |
562 | </li>
563 |
564 | <li class="md-nav__item">
565 | <a href="#list_indexed_repositories" class="md-nav__link">
566 | <span class="md-ellipsis">
567 |
568 | list_indexed_repositories
569 |
570 | </span>
571 | </a>
572 |
573 | </li>
574 |
575 | <li class="md-nav__item">
576 | <a href="#delete_repository" class="md-nav__link">
577 | <span class="md-ellipsis">
578 |
579 | delete_repository
580 |
581 | </span>
582 | </a>
583 |
584 | </li>
585 |
586 | <li class="md-nav__item">
587 | <a href="#visualize_graph_query" class="md-nav__link">
588 | <span class="md-ellipsis">
589 |
590 | visualize_graph_query
591 |
592 | </span>
593 | </a>
594 |
595 | </li>
596 |
597 | <li class="md-nav__item">
598 | <a href="#list_watched_paths" class="md-nav__link">
599 | <span class="md-ellipsis">
600 |
601 | list_watched_paths
602 |
603 | </span>
604 | </a>
605 |
606 | </li>
607 |
608 | <li class="md-nav__item">
609 | <a href="#unwatch_directory" class="md-nav__link">
610 | <span class="md-ellipsis">
611 |
612 | unwatch_directory
613 |
614 | </span>
615 | </a>
616 |
617 | </li>
618 |
619 | </ul>
620 | </nav>
621 |
622 | </li>
623 |
624 | <li class="md-nav__item">
625 | <a href="#other-methods" class="md-nav__link">
626 | <span class="md-ellipsis">
627 |
628 | Other Methods
629 |
630 | </span>
631 | </a>
632 |
633 | </li>
634 |
635 | </ul>
636 |
637 | </nav>
638 |
639 | </li>
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 | <li class="md-nav__item">
650 | <a href="../core/" class="md-nav__link">
651 |
652 |
653 |
654 | <span class="md-ellipsis">
655 |
656 |
657 | Core Concepts
658 |
659 |
660 |
661 | </span>
662 |
663 |
664 |
665 | </a>
666 | </li>
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 | <li class="md-nav__item">
677 | <a href="../tools/" class="md-nav__link">
678 |
679 |
680 |
681 | <span class="md-ellipsis">
682 |
683 |
684 | Tools
685 |
686 |
687 |
688 | </span>
689 |
690 |
691 |
692 | </a>
693 | </li>
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 | <li class="md-nav__item">
704 | <a href="../cookbook/" class="md-nav__link">
705 |
706 |
707 |
708 | <span class="md-ellipsis">
709 |
710 |
711 | Cookbook
712 |
713 |
714 |
715 | </span>
716 |
717 |
718 |
719 | </a>
720 | </li>
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 | <li class="md-nav__item md-nav__item--nested">
736 |
737 |
738 |
739 | <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_11" >
740 |
741 |
742 | <label class="md-nav__link" for="__nav_11" id="__nav_11_label" tabindex="0">
743 |
744 |
745 |
746 | <span class="md-ellipsis">
747 |
748 |
749 | Contributing
750 |
751 |
752 |
753 | </span>
754 |
755 |
756 |
757 | <span class="md-nav__icon md-icon"></span>
758 | </label>
759 |
760 | <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_11_label" aria-expanded="false">
761 | <label class="md-nav__title" for="__nav_11">
762 | <span class="md-nav__icon md-icon"></span>
763 |
764 |
765 | Contributing
766 |
767 |
768 | </label>
769 | <ul class="md-nav__list" data-md-scrollfix>
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 | <li class="md-nav__item">
778 | <a href="../contributing/" class="md-nav__link">
779 |
780 |
781 |
782 | <span class="md-ellipsis">
783 |
784 |
785 | Overview
786 |
787 |
788 |
789 | </span>
790 |
791 |
792 |
793 | </a>
794 | </li>
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 | <li class="md-nav__item">
806 | <a href="../contributing_languages/" class="md-nav__link">
807 |
808 |
809 |
810 | <span class="md-ellipsis">
811 |
812 |
813 | Adding New Languages
814 |
815 |
816 |
817 | </span>
818 |
819 |
820 |
821 | </a>
822 | </li>
823 |
824 |
825 |
826 |
827 | </ul>
828 | </nav>
829 |
830 | </li>
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 | <li class="md-nav__item">
841 | <a href="../troubleshooting/" class="md-nav__link">
842 |
843 |
844 |
845 | <span class="md-ellipsis">
846 |
847 |
848 | Troubleshooting
849 |
850 |
851 |
852 | </span>
853 |
854 |
855 |
856 | </a>
857 | </li>
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 | <li class="md-nav__item">
868 | <a href="../future_work/" class="md-nav__link">
869 |
870 |
871 |
872 | <span class="md-ellipsis">
873 |
874 |
875 | Future Work
876 |
877 |
878 |
879 | </span>
880 |
881 |
882 |
883 | </a>
884 | </li>
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 | <li class="md-nav__item">
895 | <a href="../license/" class="md-nav__link">
896 |
897 |
898 |
899 | <span class="md-ellipsis">
900 |
901 |
902 | License
903 |
904 |
905 |
906 | </span>
907 |
908 |
909 |
910 | </a>
911 | </li>
912 |
913 |
914 |
915 | </ul>
916 | </nav>
917 | </div>
918 | </div>
919 | </div>
920 |
921 |
922 |
923 | <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
924 | <div class="md-sidebar__scrollwrap">
925 | <div class="md-sidebar__inner">
926 |
927 |
928 | <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
929 |
930 |
931 |
932 |
933 |
934 |
935 | <label class="md-nav__title" for="__toc">
936 | <span class="md-nav__icon md-icon"></span>
937 | Table of contents
938 | </label>
939 | <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
940 |
941 | <li class="md-nav__item">
942 | <a href="#initialization" class="md-nav__link">
943 | <span class="md-ellipsis">
944 |
945 | Initialization
946 |
947 | </span>
948 | </a>
949 |
950 | </li>
951 |
952 | <li class="md-nav__item">
953 | <a href="#tool-manifest" class="md-nav__link">
954 | <span class="md-ellipsis">
955 |
956 | Tool Manifest
957 |
958 | </span>
959 | </a>
960 |
961 | <nav class="md-nav" aria-label="Tool Manifest">
962 | <ul class="md-nav__list">
963 |
964 | <li class="md-nav__item">
965 | <a href="#add_code_to_graph" class="md-nav__link">
966 | <span class="md-ellipsis">
967 |
968 | add_code_to_graph
969 |
970 | </span>
971 | </a>
972 |
973 | </li>
974 |
975 | <li class="md-nav__item">
976 | <a href="#check_job_status" class="md-nav__link">
977 | <span class="md-ellipsis">
978 |
979 | check_job_status
980 |
981 | </span>
982 | </a>
983 |
984 | </li>
985 |
986 | <li class="md-nav__item">
987 | <a href="#list_jobs" class="md-nav__link">
988 | <span class="md-ellipsis">
989 |
990 | list_jobs
991 |
992 | </span>
993 | </a>
994 |
995 | </li>
996 |
997 | <li class="md-nav__item">
998 | <a href="#find_code" class="md-nav__link">
999 | <span class="md-ellipsis">
1000 |
1001 | find_code
1002 |
1003 | </span>
1004 | </a>
1005 |
1006 | </li>
1007 |
1008 | <li class="md-nav__item">
1009 | <a href="#analyze_code_relationships" class="md-nav__link">
1010 | <span class="md-ellipsis">
1011 |
1012 | analyze_code_relationships
1013 |
1014 | </span>
1015 | </a>
1016 |
1017 | </li>
1018 |
1019 | <li class="md-nav__item">
1020 | <a href="#watch_directory" class="md-nav__link">
1021 | <span class="md-ellipsis">
1022 |
1023 | watch_directory
1024 |
1025 | </span>
1026 | </a>
1027 |
1028 | </li>
1029 |
1030 | <li class="md-nav__item">
1031 | <a href="#execute_cypher_query" class="md-nav__link">
1032 | <span class="md-ellipsis">
1033 |
1034 | execute_cypher_query
1035 |
1036 | </span>
1037 | </a>
1038 |
1039 | </li>
1040 |
1041 | <li class="md-nav__item">
1042 | <a href="#add_package_to_graph" class="md-nav__link">
1043 | <span class="md-ellipsis">
1044 |
1045 | add_package_to_graph
1046 |
1047 | </span>
1048 | </a>
1049 |
1050 | </li>
1051 |
1052 | <li class="md-nav__item">
1053 | <a href="#find_dead_code" class="md-nav__link">
1054 | <span class="md-ellipsis">
1055 |
1056 | find_dead_code
1057 |
1058 | </span>
1059 | </a>
1060 |
1061 | </li>
1062 |
1063 | <li class="md-nav__item">
1064 | <a href="#calculate_cyclomatic_complexity" class="md-nav__link">
1065 | <span class="md-ellipsis">
1066 |
1067 | calculate_cyclomatic_complexity
1068 |
1069 | </span>
1070 | </a>
1071 |
1072 | </li>
1073 |
1074 | <li class="md-nav__item">
1075 | <a href="#find_most_complex_functions" class="md-nav__link">
1076 | <span class="md-ellipsis">
1077 |
1078 | find_most_complex_functions
1079 |
1080 | </span>
1081 | </a>
1082 |
1083 | </li>
1084 |
1085 | <li class="md-nav__item">
1086 | <a href="#list_indexed_repositories" class="md-nav__link">
1087 | <span class="md-ellipsis">
1088 |
1089 | list_indexed_repositories
1090 |
1091 | </span>
1092 | </a>
1093 |
1094 | </li>
1095 |
1096 | <li class="md-nav__item">
1097 | <a href="#delete_repository" class="md-nav__link">
1098 | <span class="md-ellipsis">
1099 |
1100 | delete_repository
1101 |
1102 | </span>
1103 | </a>
1104 |
1105 | </li>
1106 |
1107 | <li class="md-nav__item">
1108 | <a href="#visualize_graph_query" class="md-nav__link">
1109 | <span class="md-ellipsis">
1110 |
1111 | visualize_graph_query
1112 |
1113 | </span>
1114 | </a>
1115 |
1116 | </li>
1117 |
1118 | <li class="md-nav__item">
1119 | <a href="#list_watched_paths" class="md-nav__link">
1120 | <span class="md-ellipsis">
1121 |
1122 | list_watched_paths
1123 |
1124 | </span>
1125 | </a>
1126 |
1127 | </li>
1128 |
1129 | <li class="md-nav__item">
1130 | <a href="#unwatch_directory" class="md-nav__link">
1131 | <span class="md-ellipsis">
1132 |
1133 | unwatch_directory
1134 |
1135 | </span>
1136 | </a>
1137 |
1138 | </li>
1139 |
1140 | </ul>
1141 | </nav>
1142 |
1143 | </li>
1144 |
1145 | <li class="md-nav__item">
1146 | <a href="#other-methods" class="md-nav__link">
1147 | <span class="md-ellipsis">
1148 |
1149 | Other Methods
1150 |
1151 | </span>
1152 | </a>
1153 |
1154 | </li>
1155 |
1156 | </ul>
1157 |
1158 | </nav>
1159 | </div>
1160 | </div>
1161 | </div>
1162 |
1163 |
1164 |
1165 | <div class="md-content" data-md-component="content">
1166 |
1167 | <article class="md-content__inner md-typeset">
1168 |
1169 |
1170 |
1171 |
1172 |
1173 | <h1 id="mcpserver">MCPServer</h1>
1174 | <p>The <code>MCPServer</code> class is the core of the CodeGraphContext application. It orchestrates all the major components, including database management, background job tracking, file system watching, and tool handling.</p>
1175 | <h2 id="initialization">Initialization</h2>
1176 | <p>The server is initialized with an asyncio event loop. Upon initialization, it sets up the following components:</p>
1177 | <ul>
1178 | <li><code>DatabaseManager</code>: Manages the connection to the Neo4j database.</li>
1179 | <li><code>JobManager</code>: Tracks the status of background jobs, such as code indexing.</li>
1180 | <li><code>CodeWatcher</code>: Monitors the file system for changes to keep the code graph up-to-date.</li>
1181 | <li><code>GraphBuilder</code>: Builds the code graph from the source code.</li>
1182 | <li><code>CodeFinder</code>: Provides tools for searching and analyzing the code graph.</li>
1183 | </ul>
1184 | <h2 id="tool-manifest">Tool Manifest</h2>
1185 | <p>The <code>MCPServer</code> exposes a set of tools to the AI assistant. These tools are defined in the <code>_init_tools</code> method. Here is a list of available tools:</p>
1186 | <h3 id="add_code_to_graph"><code>add_code_to_graph</code></h3>
1187 | <p>Performs a one-time scan of a local folder to add its code to the graph. Ideal for indexing libraries, dependencies, or projects not being actively modified. Returns a job ID for background processing.</p>
1188 | <h3 id="check_job_status"><code>check_job_status</code></h3>
1189 | <p>Check the status and progress of a background job.</p>
1190 | <h3 id="list_jobs"><code>list_jobs</code></h3>
1191 | <p>List all background jobs and their current status.</p>
1192 | <h3 id="find_code"><code>find_code</code></h3>
1193 | <p>Find relevant code snippets related to a keyword (e.g., function name, class name, or content).</p>
1194 | <h3 id="analyze_code_relationships"><code>analyze_code_relationships</code></h3>
1195 | <p>Analyze code relationships like 'who calls this function' or 'class hierarchy'. Supported query types include: find_callers, find_callees, find_all_callers, find_all_callees, find_importers, who_modifies, class_hierarchy, overrides, dead_code, call_chain, module_deps, variable_scope, find_complexity, find_functions_by_argument, find_functions_by_decorator.</p>
1196 | <h3 id="watch_directory"><code>watch_directory</code></h3>
1197 | <p>Performs an initial scan of a directory and then continuously monitors it for changes, automatically keeping the graph up-to-date. Ideal for projects under active development. Returns a job ID for the initial scan.</p>
1198 | <h3 id="execute_cypher_query"><code>execute_cypher_query</code></h3>
1199 | <p>This is an advanced tool for directly querying the underlying Neo4j graph using a read-only Cypher query. It should be used as a fallback when other tools cannot answer very specific or complex questions about the code graph.</p>
1200 | <p><strong>Schema Overview:</strong></p>
1201 | <p>The code graph has the following structure:</p>
1202 | <ul>
1203 | <li><strong>Nodes:</strong><ul>
1204 | <li><code>Repository</code>: Represents a project repository.</li>
1205 | <li><code>File</code>: Represents a single source code file.</li>
1206 | <li><code>Module</code>: Represents a package or a module.</li>
1207 | <li><code>Class</code>: Represents a class definition.</li>
1208 | <li><code>Function</code>: Represents a function or method definition.</li>
1209 | </ul>
1210 | </li>
1211 | <li><strong>Properties:</strong><ul>
1212 | <li>Nodes have properties like <code>name</code>, <code>path</code>, <code>cyclomatic_complexity</code> (for functions), and <code>code</code>.</li>
1213 | </ul>
1214 | </li>
1215 | <li><strong>Relationships:</strong><ul>
1216 | <li><code>CONTAINS</code>: e.g., <code>(:File)-[:CONTAINS]->(:Function)</code></li>
1217 | <li><code>CALLS</code>: e.g., <code>(:Function)-[:CALLS]->(:Function)</code></li>
1218 | <li><code>IMPORTS</code>: e.g., <code>(:File)-[:IMPORTS]->(:Module)</code></li>
1219 | <li><code>INHERITS</code>: e.g., <code>(:Class)-[:INHERITS]->(:Class)</code></li>
1220 | </ul>
1221 | </li>
1222 | </ul>
1223 | <h3 id="add_package_to_graph"><code>add_package_to_graph</code></h3>
1224 | <p>Add a Python package to Neo4j graph by discovering its location. Returns immediately with job ID.</p>
1225 | <h3 id="find_dead_code"><code>find_dead_code</code></h3>
1226 | <p>Find potentially unused functions (dead code) across the entire indexed codebase, optionally excluding functions with specific decorators.</p>
1227 | <h3 id="calculate_cyclomatic_complexity"><code>calculate_cyclomatic_complexity</code></h3>
1228 | <p>Calculate the cyclomatic complexity of a specific function to measure its complexity.</p>
1229 | <h3 id="find_most_complex_functions"><code>find_most_complex_functions</code></h3>
1230 | <p>Find the most complex functions in the codebase based on cyclomatic complexity.</p>
1231 | <h3 id="list_indexed_repositories"><code>list_indexed_repositories</code></h3>
1232 | <p>List all indexed repositories.</p>
1233 | <h3 id="delete_repository"><code>delete_repository</code></h3>
1234 | <p>Delete an indexed repository from the graph.</p>
1235 | <h3 id="visualize_graph_query"><code>visualize_graph_query</code></h3>
1236 | <p>Generates a URL to visualize the results of a Cypher query in the Neo4j Browser. The user can open this URL in their web browser to see the graph visualization.</p>
1237 | <h3 id="list_watched_paths"><code>list_watched_paths</code></h3>
1238 | <p>Lists all directories currently being watched for live file changes.</p>
1239 | <h3 id="unwatch_directory"><code>unwatch_directory</code></h3>
1240 | <p>Stops watching a directory for live file changes.</p>
1241 | <h2 id="other-methods">Other Methods</h2>
1242 | <ul>
1243 | <li><code>get_database_status()</code>: Returns the current connection status of the Neo4j database.</li>
1244 | <li><code>get_local_package_path(package_name)</code>: Finds the local installation path of a Python package.</li>
1245 | <li><code>run()</code>: Runs the main server loop, listening for JSON-RPC requests from stdin.</li>
1246 | <li><code>shutdown()</code>: Gracefully shuts down the server and its components.</li>
1247 | </ul>
1248 |
1249 |
1250 |
1251 |
1252 |
1253 |
1254 |
1255 |
1256 |
1257 |
1258 |
1259 |
1260 |
1261 | </article>
1262 | </div>
1263 |
1264 |
1265 | <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
1266 | </div>
1267 |
1268 | </main>
1269 |
1270 | <footer class="md-footer">
1271 |
1272 | <div class="md-footer-meta md-typeset">
1273 | <div class="md-footer-meta__inner md-grid">
1274 | <div class="md-copyright">
1275 |
1276 |
1277 | Made with
1278 | <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
1279 | Material for MkDocs
1280 | </a>
1281 |
1282 | </div>
1283 |
1284 | </div>
1285 | </div>
1286 | </footer>
1287 |
1288 | </div>
1289 | <div class="md-dialog" data-md-component="dialog">
1290 | <div class="md-dialog__inner md-typeset"></div>
1291 | </div>
1292 |
1293 |
1294 |
1295 |
1296 |
1297 | <script id="__config" type="application/json">{"annotate": null, "base": "..", "features": [], "search": "../assets/javascripts/workers/search.2c215733.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>
1298 |
1299 |
1300 | <script src="../assets/javascripts/bundle.79ae519e.min.js"></script>
1301 |
1302 |
1303 | </body>
1304 | </html>
```