Summary
The TypeScript/JavaScript parser currently records bare import specifiers on entities but treats every non-relative specifier as an external package. In a monorepo, that silently drops imports between local workspace packages or tsconfig path aliases.
This is especially risky because downstream recovery and quality metrics consume DependencyGraph.edges. The graph can look complete enough to produce a high score even though local package dependencies are missing.
Evidence
In src/arcade_agent/parsers/typescript.py, resolve_module() returns None for every specifier that does not start with ., with the comment # external package. The second pass then skips the import when no target module is returned.
The README currently advertises TypeScript/JavaScript as full support:
https://github.com/lemduc/arcade-agent/blob/main/README.md#L134
Minimal reproduction
With the existing parser:
a.ts:
export class A {}
b.ts:
import { A } from "./a";
export class B { make(): A { return new A(); } }
the parser emits import edges. Replacing the specifier with a local bare alias:
import { A } from "@workspace/a";
while keeping the same local a.ts entity produces:
relative_edges: [('b.B', 'a.A', 'import'), ('b.B.make', 'a.A', 'import')]
bare_edges: []
bare_imports_recorded_on_entity: ['@workspace/a']
This is not asking the analyzer to add external dependency entities. The problem is that it cannot distinguish an external package from a local workspace/path-alias import.
Metric impact
For a fixture with two intra-component relative edges and two inter-component local bare-import edges, using the same component assignment:
incomplete graph: RCI = 1.0 (2 intra / 2 observed edges)
with the missing local edges: RCI = 0.5 (2 intra / 4 total edges)
So the current result is numerically correct for the incomplete graph, but it creates false confidence about the analyzed architecture. The graph/report also has no unresolved-local import diagnostic or import coverage/confidence field that would warn consumers before interpreting the score.
Real-world monorepo example
DeepSeek Harness uses local @deepseek-ai/dsh-* workspace packages. Its tsconfig.base.json maps those package names to packages/*/src, and its generated module graph documents package manifests as the canonical dependency source:
Running the current parser against the production TypeScript sources found 1,271 source-level imports referring to local workspace packages (909 unique package pairs); those bare specifiers are not emitted as TypeScript import edges.
Suggested direction
- Read workspace
package.json manifests and tsconfig baseUrl/paths when resolving TypeScript/JavaScript imports.
- Distinguish external imports from unresolved local imports; do not silently classify a local-looking unresolved specifier as external.
- Add graph/report metadata for resolved, external, and unresolved imports, plus coverage/confidence, before computing or presenting architecture scores.
- Add a monorepo/path-alias regression fixture and assert that an incomplete graph is visibly flagged or prevents the score from being presented as a complete assessment.
If the intended contract is only relative-import analysis, this should instead be documented as a limitation and the TypeScript/JavaScript “full support” claim should be narrowed.
Summary
The TypeScript/JavaScript parser currently records bare import specifiers on entities but treats every non-relative specifier as an external package. In a monorepo, that silently drops imports between local workspace packages or
tsconfigpath aliases.This is especially risky because downstream recovery and quality metrics consume
DependencyGraph.edges. The graph can look complete enough to produce a high score even though local package dependencies are missing.Evidence
In
src/arcade_agent/parsers/typescript.py,resolve_module()returnsNonefor every specifier that does not start with., with the comment# external package. The second pass then skips the import when no target module is returned.The README currently advertises TypeScript/JavaScript as full support:
https://github.com/lemduc/arcade-agent/blob/main/README.md#L134
Minimal reproduction
With the existing parser:
the parser emits import edges. Replacing the specifier with a local bare alias:
while keeping the same local
a.tsentity produces:This is not asking the analyzer to add external dependency entities. The problem is that it cannot distinguish an external package from a local workspace/path-alias import.
Metric impact
For a fixture with two intra-component relative edges and two inter-component local bare-import edges, using the same component assignment:
So the current result is numerically correct for the incomplete graph, but it creates false confidence about the analyzed architecture. The graph/report also has no unresolved-local import diagnostic or import coverage/confidence field that would warn consumers before interpreting the score.
Real-world monorepo example
DeepSeek Harness uses local
@deepseek-ai/dsh-*workspace packages. Itstsconfig.base.jsonmaps those package names topackages/*/src, and its generated module graph documents package manifests as the canonical dependency source:Running the current parser against the production TypeScript sources found 1,271 source-level imports referring to local workspace packages (909 unique package pairs); those bare specifiers are not emitted as TypeScript import edges.
Suggested direction
package.jsonmanifests andtsconfigbaseUrl/pathswhen resolving TypeScript/JavaScript imports.If the intended contract is only relative-import analysis, this should instead be documented as a limitation and the TypeScript/JavaScript “full support” claim should be narrowed.