Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,38 @@ project unresolved issues. Missing local paths, root-like paths, package imports
starting with `#`, and common alias forms such as `@/` and `~/` are reported as
unresolved.

## Dependency Query Graph

The `query` command builds a graph from the same parsed file metadata and module
resolver used by normal analysis. Query nodes are either project files or
exported symbols written as `<file>:<symbol>`. Edges preserve the source shape
that created the dependency: named imports, side-effect imports, string-literal
dynamic imports, `import.meta.glob`, re-exports, namespace exports, namespace
member reads, and export-definition edges from symbols back to their declaring
files.

Selectors are resolved after graph construction:

- File selectors match one project file node.
- Directory selectors match every project file node under that directory.
- Export selectors match one exported-symbol node.

`somepath` and `somepaths` run breadth-first search from the resolved source
nodes. They keep one visited bit and one parent edge per node, so dependency
cycles cannot create infinite walks. `somepath` stops after the first matched
target. `somepaths` keeps traversing and reconstructs one shortest path for each
reachable matched target.

`allpaths` intentionally does not enumerate every simple path. It computes the
set of nodes reachable forward from the sources, the set of nodes that can reach
the targets by reverse traversal, intersects those sets, and returns every edge
whose endpoints are both in that intersection. This returns the finite path
subgraph even when the dependency graph contains cycles.

Query output supports text, JSON, Mermaid, and SVG. Mermaid is the diagram IR
(`flowchart LR`), and SVG is rendered from that Mermaid source with
`mermaid-rs-renderer`.

## Reachability Algorithm

`analyze_path` seeds three mutable collections:
Expand Down
11 changes: 8 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,20 @@ The public Rust API is intentionally narrow:
- `codescythe::run_and_fix(cwd, config_path)` applies supported removals and
returns a fix report.
- `codescythe::doctor(cwd, config_path)` returns config-risk diagnostics.
- `codescythe::query(cwd, config_path, request)` returns dependency paths or a
path subgraph for `somepath`, `somepaths`, and `allpaths`.
- `codescythe::render_query_mermaid(result)` and
`codescythe::render_query_svg(result)` render query results as diagrams.

The core crate has no npm or CLI concerns. That keeps conformance tests and
future analysis work centered on one library boundary.

### Runtime Adapters

`crates/codescythe_cli` is a thin `clap` wrapper around the core crate. It
supports text and JSON output, exits with `1` when issues are found, and exits
with `2` for runtime/config errors.
`crates/codescythe_cli` is a thin `clap` wrapper around the core crate. Normal
analysis supports text and JSON output, exits with `1` when issues are found,
and exits with `2` for runtime/config errors. The `query` subcommand supports
text, JSON, Mermaid, and SVG output for dependency-path inspection.

`crates/codescythe_napi` exposes the same core behavior to Node through N-API:
`analyze`, `fix`, and `doctor` all return JSON strings from Rust, while the
Expand Down
86 changes: 79 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,85 @@ codescythe query allpaths src/main.ts src/runtime.ts:initRuntime --output svg >
```

Selectors can point at files, directories, or exported symbols written as
`<file>:<symbol>`. `somepath` returns one shortest path, `somepaths` returns one
shortest path per reachable matched target, and `allpaths` returns the subgraph
of every node and edge that lies on a path from the source selector to the target
selector. JSON output includes stable file/export nodes and typed import or
re-export edges. Mermaid output renders the same query graph as a `flowchart LR`
diagram, and SVG output renders that Mermaid source with the pure-Rust
`mermaid-rs-renderer` crate.
`<file>:<symbol>`. Relative selectors are resolved from the analysis root chosen
by `-C` or `--config`.

- `somepath` returns one shortest path from the source selector to any matched
target.
- `somepaths` returns one shortest path per reachable matched target, which is
useful for file-to-folder queries.
- `allpaths` returns the subgraph of every node and edge that lies on a path
from the source selector to the target selector.

Text output is optimized for terminal inspection. JSON output includes stable
file/export nodes and typed import or re-export edges. Mermaid output renders
the same query graph as a `flowchart LR` diagram, and SVG output renders that
Mermaid source with the pure-Rust `mermaid-rs-renderer` crate.

`somepath` and `somepaths` use breadth-first search with visited nodes, while
`allpaths` intersects forward reachability from the source with reverse
reachability from the target. That makes dependency cycles finite without
enumerating every possible walk through the graph.

Fixture-backed Mermaid examples:

```sh
codescythe query somepath -C tests/fixtures/test-file-usage --output mermaid src/main.ts src/module.ts:used
```

```mermaid
flowchart LR
n0["src/module.ts:used"]
n1["src/main.ts"]
n1 -->|"named import ./module:used"| n0
```

```sh
codescythe query somepaths -C tests/fixtures/oxc-resolution --output mermaid app/index.ts app/
```

```mermaid
flowchart LR
n0["app/aliased.ts:aliased"]
n1["app/extension.ts:extension"]
n2["app/internal.ts:internal"]
n3["app/aliased.ts"]
n4["app/extension.ts"]
n5["app/index.ts"]
n6["app/internal.ts"]
n0 -->|"defined in file aliased"| n3
n1 -->|"defined in file extension"| n4
n2 -->|"defined in file internal"| n6
n5 -->|"named import @/aliased:aliased"| n0
n5 -->|"named import ./extension.js:extension"| n1
n5 -->|"named import #internal:internal"| n2
```

```sh
codescythe query allpaths -C tests/fixtures/knip-export-basics --output mermaid index.ts my-namespace.ts:y
```

```mermaid
flowchart LR
n0["index.ts"]
n1["my-module.ts"]
n2["my-module.ts:myExport"]
n3["my-namespace.ts:y"]
n2 -->|"defined in file myExport"| n1
n0 -->|"named import ./my-module.js:myExport"| n2
n1 -->|"namespace member ./my-namespace.js:y"| n3
```

```sh
codescythe query somepath -C tests/fixtures/runfiles-fixture --output mermaid workspace/frontend/apps/client/platform/platformRuntime.ts protobuf/generated/client.ts:client
```

```mermaid
flowchart LR
n0["protobuf/generated/client.ts:client"]
n1["workspace/frontend/apps/client/platform/platformRuntime.ts"]
n1 -->|"named import #bazel_generated/client:client"| n0
```

## Contributing

Expand Down
Loading