Feature/dependency parser - #4530
Conversation
The dependency lens held edges and their attribute metadata, and an Edge
held only free-form attributes. Levelization and cycle detection produce
two facts that are not metrics: whether an edge takes part in a cycle,
and whether it runs against the architectural flow — plus, per node, the
level it sits on.
"dependency": {
"edges": [{ "fromId": …, "toId": …, "isCyclic": true }],
"nodes": { "<id>": { "level": 2 } }
}
The four DependaCharta edge types are a pure function of (isCyclic,
isPointingUpwards), so only the pair is stored and the type is derived
where it is consumed.
Every field is optional and falsy by default, and the DTO models the
flags and `nodes` as nullable, so a producer that sets none writes byte
for byte what it wrote before — the meta.checksum characterization test
still pins the same hash.
Five places rebuilt an Edge through the three-argument constructor and
would have silently dropped the flags. Edge gains `withEndpoints` and the
re-pathing callers route through it; DependencyLens.merge ORs the flags
rather than taking the first, the same rule the frontend uses when a
namespace collapses.
`nodes` is keyed by node id, so it needs the re-keying DomainLens already
had. That walk moves to LensRekeying so both lenses share it, and
StructureModifier and LargeMerge now re-key both.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
`FileExtension.TYPESCRIPT` listed `"cts"` without the leading dot, so no `.cts` file ever matched — every other entry in the enum carries the dot. `KOTLIN` had no `.kts`, so Kotlin script files (Gradle build scripts, `.main.kts`) were invisible to language detection. Both are consumed by `ProjectScanner.getFileExtension`, so UnifiedParser now also collects metrics for `.cts` and `.kts` files it previously skipped. The dependency parser relies on the same detection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
Ports DependaCharta's analysis into ccsh as `dependencyparser`: tree-sitter
dependency extraction for 12 languages, Tarjan/DFS cycle detection and
levelization, emitted into the `dependency` lens.
ccsh dependencyparser src/ -o project.cc.json
The domain is DependaCharta's — leaves, levels, upward-pointing feedback
edges, edge weight. The infrastructure is CodeCharta's: the CLI extends
CommonAnalyserParameters, the file walk is DomainLanguageParser's scanner
(gitignore, exclude patterns, test detection), logging goes through
`util.Logger`, progress through `ProgressTracker`, and the output is a
cc.json rather than a `.cg.json`.
Two things are deliberately not the same as upstream:
**File level, not declaration level.** DependaCharta's leaves are
declarations under a logical namespace tree; a cc.json node is a position
in the physical tree. Type resolution and cycle detection still run per
declaration, where they mean something, and the result is then folded onto
the file the declarations live in: weights sum, `isCyclic` ORs, and an edge
between two declarations in one file disappears. Levelization runs on the
folder tree, so every level keys straight onto a node the file tree
already has.
**Tests are excluded by default**, behind `--include-tests`. A test
depends on everything it exercises and nothing depends on it, so including
them moves every level and cycle; DependaCharta's numbers are calibrated
without them.
Also dropped: the `dependacharta_temp` resumability layer (CodeCharta's
incremental story is `--base-file` plus contentHash), the `.cg.json`
export DTOs, and the bundled TSX natives — TSX goes through TSE's own
`Language.TSX`. The kotlinx.serialization annotations went with them; the
two remaining config parsers (tsconfig, federation package.json) are on
Gson, which every module already has.
`GraphNode.findNodeById` is a linear search and the upward-pointing rule
needs two per edge plus an ancestor walk, so `GraphIndex` precomputes both
in one pass — quadratic on a file-level graph otherwise.
Go, PHP, Python and the Vue SFC blocks keep their raw tree-sitter queries;
their grammar bindings already arrive through TSE and are pinned here to
exactly the versions TSE resolves, so the ccsh fat jar carries one set of
natives.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
Brings over the whole regression net: 52 test files and 109 resource
files. The extraction contract suite ("cellars and centaurs" in Java, C#
and C++) is the net for the analyzers, and the algorithm tests are the
net for cycle detection and levelization — 605 tests in total.
What changed while porting:
- The contract suite runs on `ExtractionPipeline` instead of the deleted
`AnalysisPipeline`, through a small test helper. Test detection is off
there: the samples live under `src/test/resources`, and the point of
them is the production-shaped code inside.
- The two `FileReport` tests that asserted on the `.cg.json` leaf DTO are
replaced by `FileLevelAggregatorTest`, which covers the same fact — a
file edge is cyclic if any declaration edge behind it is — at the level
the parser now works at.
- `IsPointingUpwardsTest` drives `GraphIndex`, which is now the only
implementation of the rule; `GraphNode` keeps just the virtual-root
wrapper.
- The C++ namespace fixtures were renamed along with the package, so the
expectations and the sample agree again.
- `Node` gets an explicit companion. It used to have one for free from
`@Serializable`, and the test builders hang off it.
New tests cover the CodeCharta-side pieces: the scanner (test files,
minified bundles, size limits, BOM stripping), the language registry, the
file-level aggregation, the processing chain end to end over the Java
sample, the project generator, the CLI and the dialog.
`FileScannerTest` caught a real one: the byte-order-mark constant was an
empty string, so no BOM was ever stripped and TreeSitter would have
mis-tokenized the first identifier of every BOM-encoded file.
Test detection is now judged on the path inside the project rather than
the absolute one, so a project that merely lives under a directory called
`test` is not analysed as if every file in it were a test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…lden test The golden test gains `check_dependencyparser`, running the "cellars and centaurs" Java sample — the same one the contract tests use, chosen because it produces all four edge types. It asserts the output validates and really carries edges, per-node levels, both graph flags and the per-file link counts, since an empty lens would validate just as happily. Docs: a module README and a docs page covering what the lens holds, the four edge types the two booleans name, why levels sit on the folder tree, and why tests are excluded by default. `dev_docs/cc-json-2.0-format.md` gains the shape and the merge/re-key semantics of the grown lens, and the parser table and `simplecc.sh` gain their entries. The ccsh enumeration tests list the new analyser, so a future one cannot be registered in the command list and forgotten in the interactive one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…arser The parser ships the physical (file-collapsed) projection. The logical layer is not missing work — every run computes the declaration nodes, their resolved leaf-to-leaf dependencies with the usage kind, and the declaration-level cycles, then throws all of it away at aggregation. The namespace tree builder is ported and unit-tested but called only by its own test. So the plan is: stop discarding, add a place to put it, levelize a second time — emitting both projections from one run into one cc.json. `files` stays the physical identity layer so ids keep joining with the other analysers; the logical graph goes into the dependency lens as `namespaces`, `leaves` and `leafEdges`, all optional and omitted when empty so today's output stays byte-identical. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
Resolution, cycle detection and levelization already ran at declaration level; everything but the file-collapsed result was discarded. The `dependency` lens gains three optional tables, keyed by dotted logical path: `leaves` (declarations, with kind, level and the id of the file node they live in), `namespaces` (package levels) and `leafEdges` (the dependencies between declarations, with weight, graph flags and every way the source uses the target). The namespace tree is levelized with the already-ported `toGraphNodes()`, `levelize()` and `GraphIndex` — the same three calls the folder tree makes — so `--omit-graph-analysis` now skips both levelizations. Two declarations resolving to one logical path keep the first and warn. `edges`, `nodes` and the per-file metrics are byte-identical to before on a real project, and the tables are omitted when empty, so a file carrying only the physical projection is unchanged too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
The logical tables are keyed by dotted logical path, which no filter moves, so merging and re-pathing touch only what addresses a node: namespaces merge max-wins like `nodes`, leaves union first-wins, leaf edges fold by endpoint pair, and a restructuring re-points `leaves[].nodeId` at the file's new id — dropping a leaf, and the edges touching it, when its file did not survive. `edgefilter` reads `edges` only and re-paths nothing, so it carries the tables through unchanged; a test guards that. `ccsh check` now rejects a leaf whose `nodeId` resolves to no node, the rule it already applies to a dangling edge endpoint or metrics key. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
… test The golden test asserts the logical tables are present alongside the physical ones. The format spec gains the merge and re-key semantics of the three tables and why `leafEdges` is a list of its own rather than a widened `Edge`; the parser docs gain the shape, the size cost and the measured parity with DependaCharta over the three contract samples — 16/16 declarations and 6/6 cycles, differing only by a self-edge this parser drops. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
`ccsh dependencyparser` runs DependaCharta's analysis on the source itself and now emits everything the importer receives and more — declaration kinds, levels, cycles and upward flags, at both file and declaration granularity — where the importer flattens all of it into edge and node attributes. It also declares `.dc.json` while DependaCharta emits `.cg.json`, so it never matched real output. The command still works and now says so on every run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…nt known issues ktlint-gradle writes intermediates/ktLint/reporters.bin but never registers it as an output of loadKtlintReporters, so `clean` deleted the file while the task stayed UP-TO-DATE and every following ktlint task failed on the missing input. Declaring the output restores the pairing. CI never saw it because it builds fresh checkouts rather than cleaning an existing one. Also records three known issues: this flaky DialogProviderTest that asserts on the working tree rather than on fixtures, the fact that declaration usage kinds are only extracted for PHP because TSE's UsedType carries no usage kind, and the build failures that follow from keeping the checkout on a mounted filesystem. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
The earlier note said TreeSitterExcavationSite carries no usage kind and no source position, so the kinds would have to be classified from scratch. Only the first half holds: TSE's per-language UsedTypeExtractor already separates inheritance, parameter, return and object-creation types (and the cpp/extractors/usedtypes split does the same for C++), and it is the public UsedType — (name, genericTypes, namespacePrefix) — that flattens the distinction away. Carrying the position upstream would light every language up at once, with TseMappings.toType() the only place here that changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
UnifiedParser and RawTextParser carried the same determineExclusionPatterns verbatim; the dependency parser is about to be the third copy, so it moves into CommonAnalyserParameters. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
The scanner ignored -e and -ibf and never excluded build folders on its own, a single-file input scanned the file's whole directory, and the file order followed the directory listing, which decides edge order and cycle breaking. -bf and --local-changes are rejected instead of ignored: the graph needs every file. spec/specs leave the test-directory set, matching DependaCharta. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…dency parser The scanner accepted the module extensions CodeCharta's FileExtension lists, but the TypeScript and JavaScript analyzers only stripped ts/tsx and js/jsx, so every such file was keyed with its extension and no import ever resolved to it. Extensions are now taken from the file as spelled and matched case-insensitively, which also sends Foo.TSX through the TSX grammar. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…ections The file-level aggregator resolved the source file of every edge through a last-wins map while the leaf table kept the first declaration, so a C# partial class was joined to one file by the leaves and to another by the edges and metrics. Each part's dependencies now count for the file they are written in, and a dependency on the split declaration points at the first part's file, the one the leaf reports. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
A schema-valid edge or leaf edge without attributes crashed the reader; the DTOs now default it. Leaf edges fold like edges (first weight wins) so a project merged with itself keeps both projections in agreement. Re-keying drops the namespaces no surviving leaf lives in, the leaf conflict warning names the leaf, ccsh check validates dependency-lens node keys and leaf edge endpoints, the upward-pointing lookup only swallows the exception it documents, and a trailing comma in a tsconfig paths array no longer leaves a null in the target list. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
fileSettings.dependencyLevels became a required slot without an IndexedDB migration, so a session persisted before it was rehydrated without the field. Version 20 seeds it the way version 19 seeded domainWords. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
The virtual-root wrapping, the C++ header/source merge, the extraction timeout and the single-file extraction had no test after the port; the dropped self-edge had none either. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…-fix plan Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
It is scratch space (brand references, a local DependaCharta checkout); the two files that were tracked stay on disk but leave the repository. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
DomainLanguageParser and DependencyParser each carried a copy of the same gitignore-aware scanner, extension filter and test-file detector. One SourceFileScanner now lives in AnalyserInterface next to the gitignore handling, with exclude patterns, a size limit, minified-bundle skipping and path-ordered results. DomainLanguageParser gains -e and -ibf through it, which it had accepted and ignored. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…parser Wildcard re-exports resolve .mts/.cts sources and a TSX source whatever its case; the namespace prune after a re-key is linear; the pipeline tests use a managed temp directory; and the docs say what the code does about split declarations and single-file inputs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…parser output Runs both tools on one project, or takes two existing output files, and diffs declarations, declaration edges, namespace levels and file edges by key. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
A move empties its source folders and the tree prunes them, but the node-id remapping kept every node whose path did not change, so the dependency and domain lenses still carried entries for ids the output no longer had. The remapping now checks survival against the restructured tree itself. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
A used type is identified by its name alone, so a declaration that uses another in several ways still yields one dependency of weight 1 in both projections, as in DependaCharta. PHP is the one language that tells usage kinds apart, so the guard runs over a PHP sample. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…es it The weight counts declaration-level dependencies, not source references, and a pair carries the first usage kind found rather than every kind. Say so in the README, the docs page, the attribute descriptors and the changelog, and mention the declaration layer in the ccsh command summary. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
An inherited baseUrl and inherited paths are rebased onto the config that extends them instead of being read relative to the child; an extends without .json finds its parent and a missing parent is warned about; the longest matching paths prefix wins; tsconfig and bundler alias targets drop their source extension so they match the extension-less node paths. All four were inherited verbatim from DependaCharta. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
A wildcard re-export keeps the import path as written, so './user.service' finds user.service.ts instead of probing for user_service.ts. A Vue component pairing a plain script with a script setup block has both analysed. An explicit import wins over a same-package type of the same name, as Java's single-type import does. Every PHP grouped use contributes, not only the first. The federation producer lookup visits siblings in name order and prefers a federation-name match over a directory-name match. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
A file whose parse fails or times out vanished from the output with only a debug line that slf4j-simple never prints, and the empty-lens warning pointed at a --verbose flag this parser never reads. Skipped files are now collected and named in one warning after the extraction phase, a tsconfig or package.json that fails to parse is warned about once, and the analyzer factory is injectable so both the failure and the timeout path are tested. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
… large merge merge --large re-keyed only a leaf's nodeId, so two inputs declaring the same dotted path were fused in the logical projection while their files stayed apart in the physical one, and the second input's leaf edges then described the first input's file. The logical ids now gain the wrapping folder as a leading segment, the way the edge paths do. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…ument its deviations PythonUtils, Path.plus(List) and the Go transitive resolution had no caller outside their own tests. The weight comments now describe declaration-level dependencies, and the README lists where the parser deliberately deviates from DependaCharta. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
… dependency parser The ported tests labelled their sections given, when and then; the project convention is Arrange, Act and Assert. Comments only, no test changed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…entions Every test name starts with should and every test carries Arrange, Act and Assert section comments (Act & Assert where the action sits inside the assertion). Names and comments only, no test body changed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
Both tools are started with the work directory as their cwd, so the relative output directory landed one level too deep and the DependaCharta report was never found. The README notes the one remaining C++ difference, which is how DependaCharta labels a merged header/source pair. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
Copies the `v0.12.0` tag of https://github.com/MaibornWolff/TreeSitterExcavationSite into `analysis/treeSitterExcavationSite`: sources, tests, contract fixtures, the two grammar jars that are not on Maven Central, and its documentation. Package names are unchanged, so nothing else has to move. Dropped along the way is everything the analysis build already provides or does not want: the Gradle wrapper and settings, its own version catalog, detekt, the Sonar and Renovate configuration, the publishing setup and the CI workflows. The module build file keeps only what the root build does not apply anyway. The repository ignores `*.jar` and normalizes every file to LF, so the bundled grammar jars need both an ignore exception and a `binary` attribute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
…itPack
The three parsers now depend on `project(":treeSitterExcavationSite")`, and the
version catalog pins the TreeSitter core and every grammar binding the module
loads instead of the JitPack coordinate of the library. The go, javascript,
php, python and vue pins the dependency parser already had are the same entries
the module declares, so a grammar can no longer end up on the classpath twice
in two versions.
`:ccsh:jar` unpacks the resolved runtime classpath, whose files carry no task
provenance, so it has to declare the modules producing them; without that
Gradle rejects the build over the module's jar.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
The module README still explained how to consume a published library from a composite build and how to drive its own Gradle wrapper, neither of which exists any more, and its changelog gave no hint that the history continues in the analysis changelog. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
`training/` holds one deliberately non-idiomatic sample project per language, written to exercise the parsers rather than to pass a linter. Biome runs from the repository root over everything, so it reported 249 errors there and `npm run format:check` failed. The directory is now ignored for both the formatter and the JavaScript linter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
`training/` holds deliberately non-idiomatic sample projects that exist to exercise the parsers, so they must never reach a quality gate. Both scans are scoped below the repository root today — the analysis scan runs with `sonar.projectBaseDir=analysis`, the visualization one with `projectBaseDir: ./visualization` and `sonar.sources=./app` — so the directory is already out of reach. The exclusions state the intent where the scanners would look first if that scope ever widens. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
One small project per language under `training/`, all modelling the same domain with the same stress constructs, so what `dependencyparser` and `domainlanguageparser` find can be compared across languages. The projects are not meant to compile; `training/README.md` is the spec they follow. Each language folder carries its `FINDINGS.md` and the parser results the report is based on, and `training/SUMMARY.md` ranks the defects across all eighteen. The dependency parser finds 14 of 71 expected file edges in C and 60 of 62 in Vue, with the recurring gaps being import aliases, fully qualified references without an import, and types used only inside function bodies. The domain parser finds all seventeen expected words in every language it supports. Console captures and lens dumps beside the results are gitignored: they are reproducible from the documented commands and carry absolute paths. Findings only, no parser changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
|
Important Review skippedToo many files! This PR contains 1555 files, which is 1405 over the limit of 150. To get a review, reduce the PR to 150 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. Usage-priced reviews support at most 300 files. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: ⛔ Files ignored due to path filters (11)
📒 Files selected for processing (1555)
You can disable this status message by setting the |
| # tree-sitter-tsx and tree-sitter-pascal are not published to Maven Central | ||
| !analysis/treeSitterExcavationSite/libs/*.jar |
There was a problem hiding this comment.
is this fine for npm?
Splits the three functions over the cognitive-complexity limit, merges the identical delphi typeref unwrappers, replaces the unchecked map accesses in the python analyzer and the cycle detection with lookups that cannot throw, and injects the extraction dispatcher instead of hardcoding Dispatchers.IO. The php dependency cache keeps its computing function, renamed rather than turned into a property getter, so it is still computed once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017StNszeUgj2pF3hf7SNzJB
|
|
…a's cg.json Reads the dependency lens and rebuilds DependaCharta's namespace tree, so the graph ccsh produces can be opened in its Web Studio and compared there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BXkdCF4kLW963NFtaVVzo9
Comparing a whole-repo run against DependaCharta leaves 75 of 7609 declaration edges as a genuine disagreement, and every one of them is name resolution guessing between same-named declarations. Both halves of that, plus the resources/ exclusion that silently shrinks the graph, are written down. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BXkdCF4kLW963NFtaVVzo9



{Meaningful title}
Please read the CONTRIBUTING.md before opening a PR.
Closes: #
Description
Descriptive pull request text, answering:
Definition of Done
A PR is only ready for merge once all the following acceptance criteria are fulfilled:
Screenshots or gifs