Skip to content

fix: TypeScript dependency analysis -- proper parser, .js resolution, include_paths (OPE-120)#280

Merged
DevanshuNEU merged 6 commits into
OpenCodeIntel:mainfrom
DevanshuNEU:fix/ts-dependency-analyzer
Mar 6, 2026
Merged

fix: TypeScript dependency analysis -- proper parser, .js resolution, include_paths (OPE-120)#280
DevanshuNEU merged 6 commits into
OpenCodeIntel:mainfrom
DevanshuNEU:fix/ts-dependency-analyzer

Conversation

@DevanshuNEU

@DevanshuNEU DevanshuNEU commented Mar 6, 2026

Copy link
Copy Markdown
Collaborator

Bug

Dependencies tab shows 0 dependencies for TypeScript repos (Effect-TS). Three stacked bugs.

Root causes

1. Wrong parser (line 27)

# Before: JS grammar for TS files -- has_error: True on TS code
'typescript': Parser(Language(tsjavascript.language()))

# After: proper TS grammar -- has_error: False
'typescript': Parser(Language(tstypescript.language_typescript()))
'tsx': Parser(Language(tstypescript.language_tsx()))

2. Import resolution fails on TS convention
TypeScript imports use .js extension but actual file is .ts on disk:

import { pipe } from "./Function.js"  // actual file: ./Function.ts

Resolver now strips .js/.jsx before trying .ts/.tsx extensions.

3. No include_paths support
build_dependency_graph scanned entire clone. Subset-indexed repos got wrong files. Now accepts include_paths to filter file discovery.

Changes

1 file, +18 -7 lines: backend/services/dependency_analyzer.py

Note

Existing cached dependency data needs to be cleared (re-index) to see the fix. The analysis route serves from cache -- stale 0-dependency results persist until re-index.

Closes OPE-120

Summary by CodeRabbit

  • New Features

    • TypeScript/TSX support added to dependency analysis with broader import resolution and recognition of TS-specific extensions.
    • Ability to limit dependency scans to specified subdirectories (include_paths).
    • File discovery now targets common code file types (.py, .js, .jsx, .ts, .tsx).
  • Tests

    • Comprehensive test suites added for dependency analysis, style analysis, tree-sitter extraction, and user limits.
  • Chores

    • Added TypeScript parser dependency to requirements.

…ion, include_paths (OPE-120)

Three stacked bugs causing 0 dependencies for TypeScript repos:

1. Wrong parser: used JS grammar for TS files. JS parser has errors on
   import type, generics, mapped types. Now uses tree-sitter-typescript
   (language_typescript for .ts, language_tsx for .tsx).

2. Import resolution: TS imports use .js extension but actual files are
   .ts on disk (standard with moduleResolution: nodenext). Resolver now
   strips .js/.jsx before trying .ts/.tsx extensions. Also added .d.ts.

3. No include_paths: build_dependency_graph scanned entire clone dir.
   Effect-TS subset repos got Python files mixed in. Now accepts
   include_paths parameter to filter file discovery.

Closes OPE-120
@vercel

vercel Bot commented Mar 6, 2026

Copy link
Copy Markdown

@DevanshuNEU is attempting to deploy a commit to the Dev's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Mar 6, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added TypeScript/TSX parsing and resolution to the dependency analyzer, limited file discovery to specific code extensions, introduced an optional include_paths parameter to restrict scanned directories, and extended import resolution probing to normalize JS/JSX imports and consider .d.ts during path resolution.

Changes

Cohort / File(s) Summary
Dependency analyzer core
backend/services/dependency_analyzer.py
Added TypeScript and TSX parser entries; mapped .tsx to tsx; file discovery limited to .py, .js, .jsx, .ts, .tsx; build_dependency_graph signature now accepts include_paths: List[str] = None; import resolution normalizes .js/.jsx imports for TS and probes .d.ts during path probing and resolution.
Tests — DependencyAnalyzer
backend/tests/test_dependency_analyzer.py
New comprehensive tests for parser init, language detection (typescript, tsx, javascript, python), TypeScript/TSX import extraction and counts, import resolution (JS→TS normalization, relative/module probing, .d.ts handling), include_paths filtering, and dependency graph metrics.
Tests — StyleAnalyzer
backend/tests/test_style_analyzer.py
New fixtures and tests exercising StyleAnalyzer on TypeScript and Python projects: parser exposure, language detection, file analysis, function/class counting, async detection, pattern checks, and empty/no-code-file edge cases.
Tests — TreeSitterExtractor
backend/tests/test_tree_sitter_extractor.py
New tests covering extraction of TS/TSX constructs (named/arrow functions, classes, interfaces, generics, TSX components) and Python constructs (functions, async, methods), plus edge cases (empty, syntax errors, binary, large files).
Tests — UserLimits
backend/tests/test_user_limits.py
New tests validating UserLimits across tiers, tier detection, repo-count enforcement, usage summary generation, and boundary conditions with fixtures and mocks.
Dependencies
backend/requirements.txt
Added tree-sitter-typescript>=0.23.0 to support TypeScript/TSX parsing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped through repos, whiskers all a-twitch,

found .ts and .tsx beneath a tiny stitch,
nudged .js to match and sniffed a .d.ts,
wove imports together with a joyful yes,
then thumped a happy code-map — hop, hop, hooray!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: fixing TypeScript dependency analysis by addressing the parser, .js resolution, and adding include_paths support, matching the core bug fixes described in the PR objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/services/dependency_analyzer.py (1)

246-264: ⚠️ Potential issue | 🟠 Major

Extend the absolute-import probe list as well.

These lines fix relative TS imports, but the absolute-import branch below still only checks ['.py', '.js', '.ts']. TSX or declaration files reached through baseUrl/aliased absolute imports will still be treated as external.

🛠️ Proposed follow-up
-            for ext in ['.py', '.js', '.ts']:
+            for ext in ['.py', '.js', '.ts', '.tsx', '.d.ts']:
                 test_path = module_path + ext
                 if test_path in internal_files:
                     return test_path
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/services/dependency_analyzer.py` around lines 246 - 264, The
absolute-import probe list is too narrow and misses TSX and declaration files;
update the branch that handles non-relative imports (where import_path does not
start with '.') to probe the same expanded extensions as the relative-import
branch (include '', '.ts', '.tsx', '.d.ts', '.js', '.jsx', '.py') so that
baseUrl/aliased absolute imports resolve TS/TSX/.d.ts files the same way as
relative imports; locate the absolute-import logic that currently uses ['.py',
'.js', '.ts'] and replace or extend that list accordingly (refer to symbols
import_path, source_dir, potential_base, and extensions).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/services/dependency_analyzer.py`:
- Around line 127-128: The fresh-build path is ignoring include_paths because
callers still call build_dependency_graph(repo["local_path"]) and the method's
fresh-build branch doesn't apply include_paths; update the route that invokes
build_dependency_graph to forward the include_paths argument (i.e., change the
call that currently passes repo["local_path"] to pass include_paths as well) and
update build_dependency_graph itself to apply include_paths in the
cache-miss/fresh-build code path (use the include_paths list when selecting
which files/dirs to scan before saving the graph). Ensure you reference and
update the existing build_dependency_graph function and the caller site that
uses repo["local_path"] so subset-indexed repos only scan the provided
include_paths.
- Around line 143-146: The current include_paths filtering uses string
startswith on relative (computed from file_path.relative_to(repo_path)), which
incorrectly matches prefixes like "src/app" matching "src/application"; update
the logic that filters by include_paths (the block referencing include_paths,
relative, repo_path, and file_path) to perform path-aware matching instead of
raw string prefixes: for each allowlist entry convert it to a Path/PurePath and
compare path components (e.g., check equality or that relative.parts begins with
entry.parts) or use Path.match with a proper pattern so only exact directory
boundaries are matched; ensure the condition continues to skip files that are
not under any exact allowlist path.
- Line 12: The import of tree_sitter_typescript in
backend/services/dependency_analyzer.py is not listed in dependencies; add the
package name tree-sitter-typescript to backend/requirements.txt so CI installs
it before tests; ensure the exact name "tree-sitter-typescript" is appended (or
updated) in requirements.txt and commit the change so ModuleNotFoundError for
tree_sitter_typescript is prevented.

---

Outside diff comments:
In `@backend/services/dependency_analyzer.py`:
- Around line 246-264: The absolute-import probe list is too narrow and misses
TSX and declaration files; update the branch that handles non-relative imports
(where import_path does not start with '.') to probe the same expanded
extensions as the relative-import branch (include '', '.ts', '.tsx', '.d.ts',
'.js', '.jsx', '.py') so that baseUrl/aliased absolute imports resolve
TS/TSX/.d.ts files the same way as relative imports; locate the absolute-import
logic that currently uses ['.py', '.js', '.ts'] and replace or extend that list
accordingly (refer to symbols import_path, source_dir, potential_base, and
extensions).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 93fc2026-358b-4d4a-a8f1-efcc26d20228

📥 Commits

Reviewing files that changed from the base of the PR and between c3288da and d832021.

📒 Files selected for processing (1)
  • backend/services/dependency_analyzer.py

Comment thread backend/services/dependency_analyzer.py
Comment thread backend/services/dependency_analyzer.py
Comment thread backend/services/dependency_analyzer.py
…lude_paths

Full test coverage for the three fixes in this PR:

TestParserInitialization (5): TS/TSX parsers loaded, not same as JS parser
TestLanguageDetection (6): file extension -> language mapping
TestTypeScriptImportExtraction (5): import type, export from, TSX, counts
TestImportResolution (2): .js extension resolves to .ts file on disk
TestIncludePaths (3): filters by directory, excludes unrelated files
TestGraphMetrics (3): node counts, edge validity, metric fields
TestPythonImports (2): regression -- Python imports still work

Uses tmp_path fixtures with realistic Effect-TS-style code structure.
All 26 pass in 2.09s.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/tests/test_dependency_analyzer.py (1)

160-167: Consider verifying all TSX imports.

The Button.tsx fixture imports three modules: "react", "../utils.js", and "./types.js". The test only asserts the first two. Adding an assertion for "./types.js" would provide more comprehensive coverage.

🔧 Suggested enhancement
     def test_tsx_imports(self, analyzer, tsx_repo):
         """TSX files should be parsed without errors"""
         result = analyzer.analyze_file_dependencies(
             str(tsx_repo / "src/components/Button.tsx")
         )
         imports = set(result['imports'])
         assert "react" in imports
         assert "../utils.js" in imports
+        assert "./types.js" in imports
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_dependency_analyzer.py` around lines 160 - 167, The
test_tsx_imports test is missing an assertion for one of Button.tsx's imports;
update the test in test_tsx_imports to also assert that "./types.js" is present
in the imports set returned by analyzer.analyze_file_dependencies when analyzing
the Button.tsx fixture, e.g., add an assertion checking "./types.js" in the
imports variable to ensure all three imports ("react", "../utils.js",
"./types.js") are verified.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/tests/test_dependency_analyzer.py`:
- Around line 179-191: The test_js_extension_resolves_to_ts contains an unused
local variable option_deps assigned from graph['dependencies'] but never used;
remove the unused assignment (option_deps) or replace it with an assertion that
uses dependencies if intended. Locate the test_js_extension_resolves_to_ts
function and either delete the line that sets option_deps =
deps.get('packages/effect/src/Option.ts', []) or change it to an assertion
(e.g., assert deps.get(...) is not None or assert expected entries) after
calling analyzer.build_dependency_graph to ensure the dependency data is
actually validated.

---

Nitpick comments:
In `@backend/tests/test_dependency_analyzer.py`:
- Around line 160-167: The test_tsx_imports test is missing an assertion for one
of Button.tsx's imports; update the test in test_tsx_imports to also assert that
"./types.js" is present in the imports set returned by
analyzer.analyze_file_dependencies when analyzing the Button.tsx fixture, e.g.,
add an assertion checking "./types.js" in the imports variable to ensure all
three imports ("react", "../utils.js", "./types.js") are verified.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d4a63a04-001b-4c3e-8cbd-6f5fb5841959

📥 Commits

Reviewing files that changed from the base of the PR and between d832021 and 90f1ebe.

📒 Files selected for processing (1)
  • backend/tests/test_dependency_analyzer.py

Comment thread backend/tests/test_dependency_analyzer.py
…ctor

Previously untested services now covered:

test_style_analyzer.py (12): TS/Python analysis, language detection,
  function/class counts, empty project handling
test_user_limits.py (15): tier limit values, ascending limits validation,
  tier detection, repo count enforcement, usage summary
test_tree_sitter_extractor.py (12): TS function/arrow/class extraction,
  TSX components, Effect-TS generics, Python extraction, edge cases

Total test suite: 343 + 26 (dep analyzer) + 39 = 408 tests, all passing.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (7)
backend/tests/test_style_analyzer.py (1)

1-12: Unused import: tempfile.

The tempfile module is imported but never used. The tests use pytest's tmp_path fixture instead.

Suggested fix
 """
 Tests for StyleAnalyzer -- convention detection on TypeScript and Python
 """
 import pytest
-import tempfile
 from pathlib import Path
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_style_analyzer.py` around lines 1 - 12, Remove the unused
import of tempfile from the test module: edit the top-level imports in
backend/tests/test_style_analyzer.py and delete the line importing tempfile so
only pytest, Path, and any used fixtures remain; you can locate the file by the
analyzer fixture that imports services.style_analyzer.StyleAnalyzer and ensure
no other code depends on tempfile before committing.
backend/tests/test_tree_sitter_extractor.py (4)

200-206: Consider tightening the binary content test assertion.

According to the context snippet, extract_from_code catches all exceptions and returns an empty list []. The current test allows both returning a list and raising an exception, but based on the implementation, it should always return a list. Consider removing the try/except to verify the expected behavior.

Suggested improvement
     def test_binary_file_skipped(self, extractor, tmp_path):
         # Binary content should not crash
-        try:
-            results = extractor.extract_from_code("\x00\x01\x02", 'typescript', 'binary.ts')
-            assert isinstance(results, list)
-        except Exception:
-            pass  # Acceptable to raise on binary
+        results = extractor.extract_from_code("\x00\x01\x02", 'typescript', 'binary.ts')
+        assert isinstance(results, list)
+        assert len(results) == 0  # Binary content yields no functions
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_tree_sitter_extractor.py` around lines 200 - 206, The test
test_binary_file_skipped should assert the concrete behavior of
extractor.extract_from_code when given binary input: remove the try/except block
and call extractor.extract_from_code("\x00\x01\x02", 'typescript', 'binary.ts')
directly, then assert the result is an empty list (e.g., results == [] or assert
results == []); this verifies the implementation of extract_from_code that
catches errors and returns [] rather than allowing exceptions to be swallowed by
the test.

193-198: Minor inconsistency: file content differs from passed content.

The test writes one broken syntax string to the file but passes a different broken syntax string to extract_from_code. While this doesn't affect the test outcome (both are invalid), it could cause confusion during debugging. Consider using the same content for consistency.

Suggested fix
     def test_syntax_error_file(self, extractor, tmp_path):
         f = tmp_path / "broken.ts"
-        f.write_text("export function { this is not valid TS !!!")
+        broken_code = "export function { broken !!!"
+        f.write_text(broken_code)
         # Should not crash
-        results = extractor.extract_from_code("export function { broken !!!", 'typescript', 'broken.ts')
+        results = extractor.extract_from_code(broken_code, 'typescript', str(f))
         assert isinstance(results, list)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_tree_sitter_extractor.py` around lines 193 - 198, The test
test_syntax_error_file writes one broken TypeScript string to the temporary file
but calls extractor.extract_from_code with a different broken string; make them
consistent by assigning the broken source to a local variable (e.g., broken =
"export function { this is not valid TS !!!") and use that same variable for
both f.write_text(...) and extractor.extract_from_code(broken, 'typescript',
'broken.ts') so the file content and passed content match; keep the assertions
unchanged.

93-94: Non-assertion: len(results) >= 0 is always true.

This assertion provides no test value since a list length is always non-negative. If the intent is to allow extractors that skip interfaces, consider documenting that explicitly or removing the assertion entirely.

Suggested improvement
         names = [r.name for r in results]
-        # At minimum should find the interface
-        assert len(results) >= 0  # Some extractors skip interfaces
+        # Some extractors skip interfaces; just verify no crash
+        assert isinstance(results, list)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_tree_sitter_extractor.py` around lines 93 - 94, The
assertion "assert len(results) >= 0" in the test referencing the variable
results is a no-op and should be removed; update the test in
test_tree_sitter_extractor.py to either delete that line entirely or replace it
with a meaningful check (e.g., "assert len(results) >= 1" if the extractor must
find an interface, or "assert isinstance(results, list)" if you only want to
validate the return type) and add a brief comment clarifying the expected
behavior for extractors that may skip interfaces.

75-77: Assertion at line 77 is always satisfied when line 75 passes.

The assertion assert any('getUser' in n for n in names) or len(results) >= 1 is redundant because if len(results) >= 1 (checked at line 75), the or condition is always true. Consider making the assertion more specific:

Suggested improvement
         # Extractor extracts methods, class name may not be separate
         assert len(results) >= 1
-        # Methods should also be extracted
-        assert any('getUser' in n for n in names) or len(results) >= 1
+        # Optionally verify method extraction if implementation supports it
+        # assert any('getUser' in n for n in names)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_tree_sitter_extractor.py` around lines 75 - 77, The second
assertion is redundant because len(results) >= 1 is already checked; change the
assertion to specifically verify that a method name was extracted by replacing
the current or-expression with a direct check like asserting any('getUser' in n
for n in names) (i.e., remove the "or len(results) >= 1" part) so the test
ensures the extractor returns a 'getUser' method name; locate this in the
test_tree_sitter_extractor.py assertions dealing with results and names.
backend/tests/test_user_limits.py (2)

109-114: Consider adding a test for ENTERPRISE user blocked at limit (10).

The test covers ENTERPRISE at 9 repos (allowed), but there's no corresponding test for being blocked at the limit of 10, unlike FREE and PRO tiers which both have "allowed" and "blocked at limit" tests.

Suggested addition
def test_enterprise_user_blocked_at_10(self, limiter):
    with patch.object(limiter, 'get_user_tier') as mock_tier:
        mock_tier.return_value = UserTier.ENTERPRISE
        with patch.object(limiter, 'get_user_repo_count', return_value=10):
            result = limiter.check_repo_count("user-ent")
            assert result.allowed is False
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_user_limits.py` around lines 109 - 114, Add a new unit
test mirroring test_enterprise_user_can_add_up_to_10 that asserts an ENTERPRISE
user is blocked when at the limit: patch limiter.get_user_tier to return
UserTier.ENTERPRISE and patch limiter.get_user_repo_count to return 10, call
limiter.check_repo_count("user-ent") and assert result.allowed is False; place
the test alongside the other tier tests so it validates the blocking behavior
for the ENTERPRISE tier.

19-50: Redundant imports inside test methods.

TIER_LIMITS and UserTier are already imported at the module level (line 6). The repeated imports inside each test method are unnecessary.

Suggested cleanup
     def test_free_tier_values(self):
-        from services.user_limits import TIER_LIMITS, UserTier
         free = TIER_LIMITS[UserTier.FREE]
         assert free.max_repos == 1, "Free should have 1 repo"
         # ... similar for other test methods
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_user_limits.py` around lines 19 - 50, Remove the redundant
in-function imports of TIER_LIMITS and UserTier inside each test in
test_user_limits.py and rely on the single module-level import already present;
locate occurrences of TIER_LIMITS and UserTier in functions like
test_free_tier_values, test_pro_tier_values, test_enterprise_tier_values,
test_all_tiers_have_limits, and test_tier_limits_are_ascending and delete the
inner "from services.user_limits import TIER_LIMITS, UserTier" lines so the
tests use the top-level imports only.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@backend/tests/test_style_analyzer.py`:
- Around line 1-12: Remove the unused import of tempfile from the test module:
edit the top-level imports in backend/tests/test_style_analyzer.py and delete
the line importing tempfile so only pytest, Path, and any used fixtures remain;
you can locate the file by the analyzer fixture that imports
services.style_analyzer.StyleAnalyzer and ensure no other code depends on
tempfile before committing.

In `@backend/tests/test_tree_sitter_extractor.py`:
- Around line 200-206: The test test_binary_file_skipped should assert the
concrete behavior of extractor.extract_from_code when given binary input: remove
the try/except block and call extractor.extract_from_code("\x00\x01\x02",
'typescript', 'binary.ts') directly, then assert the result is an empty list
(e.g., results == [] or assert results == []); this verifies the implementation
of extract_from_code that catches errors and returns [] rather than allowing
exceptions to be swallowed by the test.
- Around line 193-198: The test test_syntax_error_file writes one broken
TypeScript string to the temporary file but calls extractor.extract_from_code
with a different broken string; make them consistent by assigning the broken
source to a local variable (e.g., broken = "export function { this is not valid
TS !!!") and use that same variable for both f.write_text(...) and
extractor.extract_from_code(broken, 'typescript', 'broken.ts') so the file
content and passed content match; keep the assertions unchanged.
- Around line 93-94: The assertion "assert len(results) >= 0" in the test
referencing the variable results is a no-op and should be removed; update the
test in test_tree_sitter_extractor.py to either delete that line entirely or
replace it with a meaningful check (e.g., "assert len(results) >= 1" if the
extractor must find an interface, or "assert isinstance(results, list)" if you
only want to validate the return type) and add a brief comment clarifying the
expected behavior for extractors that may skip interfaces.
- Around line 75-77: The second assertion is redundant because len(results) >= 1
is already checked; change the assertion to specifically verify that a method
name was extracted by replacing the current or-expression with a direct check
like asserting any('getUser' in n for n in names) (i.e., remove the "or
len(results) >= 1" part) so the test ensures the extractor returns a 'getUser'
method name; locate this in the test_tree_sitter_extractor.py assertions dealing
with results and names.

In `@backend/tests/test_user_limits.py`:
- Around line 109-114: Add a new unit test mirroring
test_enterprise_user_can_add_up_to_10 that asserts an ENTERPRISE user is blocked
when at the limit: patch limiter.get_user_tier to return UserTier.ENTERPRISE and
patch limiter.get_user_repo_count to return 10, call
limiter.check_repo_count("user-ent") and assert result.allowed is False; place
the test alongside the other tier tests so it validates the blocking behavior
for the ENTERPRISE tier.
- Around line 19-50: Remove the redundant in-function imports of TIER_LIMITS and
UserTier inside each test in test_user_limits.py and rely on the single
module-level import already present; locate occurrences of TIER_LIMITS and
UserTier in functions like test_free_tier_values, test_pro_tier_values,
test_enterprise_tier_values, test_all_tiers_have_limits, and
test_tier_limits_are_ascending and delete the inner "from services.user_limits
import TIER_LIMITS, UserTier" lines so the tests use the top-level imports only.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6478efda-80af-4a99-a88b-0aef5936930a

📥 Commits

Reviewing files that changed from the base of the PR and between 90f1ebe and 56bea23.

📒 Files selected for processing (3)
  • backend/tests/test_style_analyzer.py
  • backend/tests/test_tree_sitter_extractor.py
  • backend/tests/test_user_limits.py

…nterprise blocked test

- Remove unused tempfile import from test_style_analyzer.py
- Remove 6 redundant in-function imports from test_user_limits.py
- Add test_enterprise_user_blocked_at_10 to user limits
- Fix test_binary_file_skipped: assert results == [] instead of try/except
- Fix test_syntax_error_file: use same broken string for file and extract call
- Fix test_extracts_interfaces: assert isinstance(results, list) not >= 0
- Fix test_extracts_classes: remove redundant or-clause in assertion
…nsions, requirements

1. include_paths: replaced string startswith with Path.parts comparison
   to prevent 'src/app' matching 'src/application' (new test added)

2. Absolute import resolver: extended extensions from [.py, .js, .ts]
   to match relative resolver ['', .ts, .tsx, .d.ts, .js, .jsx, .py]

3. Added tree-sitter-typescript to requirements.txt for CI

4. Tests: replaced unused option_deps with assertion, added ./types.js
   assertion to tsx_imports test, added prefix confusion test

Note: callers in routes/analysis.py still call build_dependency_graph
without include_paths because include_paths is not persisted to the
repositories table. Tracked as separate schema change.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
backend/tests/test_dependency_analyzer.py (2)

5-6: Remove unused imports.

tempfile and os are imported but never used. The fixtures use pytest's tmp_path fixture and pathlib.Path instead.

🧹 Suggested fix
 import pytest
-import tempfile
-import os
 from pathlib import Path
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_dependency_analyzer.py` around lines 5 - 6, Remove the
unused imports `tempfile` and `os` from the test module; the tests already use
pytest's `tmp_path` fixture and `pathlib.Path`, so delete the `import tempfile`
and `import os` lines to eliminate unused-import warnings and keep imports
minimal.

177-202: Consider adding a test for .d.ts resolution.

The _resolve_import_to_file method probes for .d.ts extensions (per backend/services/dependency_analyzer.py line 239), but no test validates this behavior. Given that .d.ts files are common in TypeScript projects for type declarations, consider adding coverage.

💡 Example test addition in TestImportResolution
def test_d_ts_files_are_discovered(self, analyzer, tmp_path):
    """Type declaration files (.d.ts) should be included in resolution"""
    src = tmp_path / "src"
    src.mkdir()
    (src / "index.ts").write_text('import { Config } from "./config.js"')
    (src / "config.d.ts").write_text('export interface Config { debug: boolean }')
    
    graph = analyzer.build_dependency_graph(str(tmp_path))
    file_paths = set(graph['dependencies'].keys())
    assert any('config.d.ts' in f for f in file_paths)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tests/test_dependency_analyzer.py` around lines 177 - 202, Add a new
test method in TestImportResolution (e.g., test_d_ts_files_are_discovered) that
uses tmp_path to create a small repo: write src/index.ts importing "./config.js"
and create src/config.d.ts with some export; call
analyzer.build_dependency_graph on the tmp path and assert that the resulting
graph includes the config.d.ts file (e.g., check graph['dependencies'] keys or
edges contain 'config.d.ts'); this verifies the _resolve_import_to_file behavior
that should probe for .d.ts files.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@backend/tests/test_dependency_analyzer.py`:
- Around line 5-6: Remove the unused imports `tempfile` and `os` from the test
module; the tests already use pytest's `tmp_path` fixture and `pathlib.Path`, so
delete the `import tempfile` and `import os` lines to eliminate unused-import
warnings and keep imports minimal.
- Around line 177-202: Add a new test method in TestImportResolution (e.g.,
test_d_ts_files_are_discovered) that uses tmp_path to create a small repo: write
src/index.ts importing "./config.js" and create src/config.d.ts with some
export; call analyzer.build_dependency_graph on the tmp path and assert that the
resulting graph includes the config.d.ts file (e.g., check graph['dependencies']
keys or edges contain 'config.d.ts'); this verifies the _resolve_import_to_file
behavior that should probe for .d.ts files.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 83828158-dc81-4259-a7ba-6bb93bb04b8d

📥 Commits

Reviewing files that changed from the base of the PR and between d3e7932 and 0fa6f6d.

📒 Files selected for processing (3)
  • backend/requirements.txt
  • backend/services/dependency_analyzer.py
  • backend/tests/test_dependency_analyzer.py
✅ Files skipped from review due to trivial changes (1)
  • backend/requirements.txt
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/services/dependency_analyzer.py

- Removed unused tempfile and os imports (tests use pytest tmp_path)
- Added test_d_ts_files_are_discovered: verifies import './config.js'
  resolves to config.d.ts when no .ts file exists
@vercel

vercel Bot commented Mar 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
opencodeintel Ignored Ignored Preview Mar 6, 2026 8:32pm

@DevanshuNEU DevanshuNEU merged commit 36a235a into OpenCodeIntel:main Mar 6, 2026
7 checks passed
DevanshuNEU added a commit to DevanshuNEU/opencodeintel-fork-new that referenced this pull request Mar 11, 2026
…t indexing

When users select specific directories via include_paths (e.g. 2 packages
out of 1767 files), the Overview and Code Style pages showed counts for
the full repo instead of the indexed subset. Root cause: dependency_analyzer
respected include_paths but style_analyzer and dna_extractor did not.

Changes:
- style_analyzer.analyze_repository_style() now accepts include_paths
- dna_extractor.extract_dna() now accepts include_paths
- dna_extractor._discover_files() now accepts include_paths
- analysis.py routes pass repo.get('include_paths') to both analyzers
- include_paths sanitization (corrupt jsonb guard) in both services
- Path.parts filtering matches dependency_analyzer pattern (PR OpenCodeIntel#280)

Closes OPE-119
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant