v0.1.0 to v0.1.0

76 added, 309 removed. Audit A to A.

---
name: dotnet-inspect-relationships
version: 0.1.0
- description: Map how code connects โ€” implementors and subclasses, extension methods, dependency graphs, reverse callers, and ecosystem integrations. Many outputs are graph-shaped (add --mermaid).
+ description: Trace .NET package and Type dependencies, implementors, subclasses, extensions, calls and callers; use scoped graph evidence to explain connections without claiming unverified coverage.
---
- # dotnet-inspect: relationships and dependency graphs
-
- Use this skill to map how code connects: what implements or extends a type, what
- it depends on, and who calls it. Dependency graphs and Member Call Graphs share
- the same graph gestures: add `--tree` for a standalone path view, `--mermaid`
- for a standalone diagram, or `--markdown --mermaid` to embed one.
-
- ```bash
- dnx dotnet-inspect -y -- <command>
- ```
-
- With a positional type, scope relationship commands with
- `--project path/to.csproj`, repeatable `--package Foo`, `--library path.dll`,
- `--platform`, `--extensions`, `--aspnetcore`, and `--tfm net9.0`. Without a
- positional type, `depends` treats repeatable `--package`, `--nuspec`,
- `--library`, and `--project` options as explicit roots; exclusive
- `--package-prefix PREFIX` admits up to 500 package roots by default and can be
- bounded explicitly with `--max-packages`.
-
- `--project` reads existing restored assets; restore/build first if dependencies
- changed.
+ # dotnet-inspect: Trace .NET Dependencies, Calls, and Type Relationships
- ## What does the root declare directly?
+ Use this skill to ask what code depends on, who calls it, or how it integrates.
+ Run `dnx dotnet-inspect -y -- <command>`. Start with the known relationship;
+ use `explain "<question>"` only when the route is unfamiliar. `-D` discovers
+ sections, `-Q` query rules, and `--help` command-specific arguments.
- `depends -S Dependencies` reports normalized direct declarations without
- requesting transitive traversal. Select `Dependencies,Failures` when a mixed
- root request should retain usable declaration rows while also reporting roots
- that could not be inspected.
+ ## Dependencies
```bash
dnx dotnet-inspect -y -- depends \
- --package Newtonsoft.Json --tfm net8.0
- dnx dotnet-inspect -y -- depends \
- --project ./src/App/App.csproj \
- --nuspec ./artifacts/App.nuspec \
- -S "Dependencies,Failures"
- dnx dotnet-inspect -y -- depends \
- --package-prefix Microsoft.Extensions --tfm net10.0 -v:n
+ --package System.Text.Json@10.0.0 --tfm net10.0
+ dnx dotnet-inspect -y -- depends JsonSerializer \
+ --package System.Text.Json@10.0.0 --tfm net10.0
+ dnx dotnet-inspect -y -- depends --project ./App.csproj \
+ --tfm net10.0 -S "Pruning,Latest Versions" --json
```
- ## Would the platform supply a direct dependency?
+ Without a positional Type, roots are package declarations, restored projects,
+ libraries or nuspecs. With a Type, the relationship is between Types; do not
+ confuse it with package dependency resolution.
- `depends -S Pruning` explicitly compares each selected direct declaration's
- source-authorized package candidate with one exact installed platform
- inventory. It requires `--tfm`; the default family is `runtime`, and
- `--platform-family aspnetcore` selects ASP.NET Core. The section does not
- traverse or remove graph edges.
+ Use `-S Dependencies` for direct declarations, `-S "Dependency Hierarchy"`
+ for rooted traversal, and `--depth 1` for direct edges. `--tree` and
+ `--mermaid` change presentation, not traversal. Shared targets can appear under
+ several parents: those are distinct relationships, not duplicate packages.
+ Library `References` is direct assembly metadata; `Reference Hierarchy`
+ traverses references.
+ `Pruning` needs the actual target framework. Use `--platform-family aspnetcore`
+ for a web project's platform comparison. `PlatformDelegation` identifies a
+ removal candidate, not an update candidate; an older platform version does not
+ authorize a downgrade. Read `Latest Versions` separately from API compatibility.
+ Load `skill project-analysis` for dependency-risk judgment.
+
+ ## A supplied Project file, without restore
+
```bash
+ dnx dotnet-inspect -y -- depends --project-document ./App.csproj --envelope
dnx dotnet-inspect -y -- depends \
- --package System.Text.Json@9.0.0 \
- --tfm net11.0 \
- -S Pruning
+ --project-document ./obj/project.assets.json --json
```
- Read `Candidate` as the selected package version and `Platform Provides` as
- separate comparison evidence. An older platform-provided version produces
- `PackageRetained`; it is not selected as a downgrade.
-
- ## What implements or extends it?
+ This reads only the named file: no MSBuild evaluation, adjacent-assets lookup,
+ restore or dependency acquisition. Authored constraints are not resolved
+ versions; imported and central values can remain unknown. Restored assets
+ provide exact target/package evidence. `--project` remains the existing
+ restored-assets locator. Preserve limitations, Failures, diagnostics and the
+ nonzero status of incomplete results, even when usable rows remain.
- `type Interface -S Implementers` finds concrete implementors;
- `type Base -S "Derived Types"` finds subclasses. `extensions Type` finds
- extension methods. Add `--reachable` (with `--depth N`) to include extensions
- on types reachable through properties and methods.
+ ## Implementors, subclasses and extensions
```bash
dnx dotnet-inspect -y -- type IDisposable \
--platform System.Private.CoreLib -S Implementers
+ dnx dotnet-inspect -y -- type Stream \
+ --platform System.Private.CoreLib -S "Derived Types"
dnx dotnet-inspect -y -- extensions HttpClient --platform --reachable
- packet=$(dnx dotnet-inspect -y -- workspace \
- --package Microsoft.Extensions.Logging.Abstractions@10.0.0 \
- --tfm net10.0 \
- --register-package-prefix Microsoft.Extensions \
- --share packet)
- dnx dotnet-inspect -y -- type Microsoft.Extensions.Logging.ILogger \
- --workspace "$packet" -S Implementers
- dnx dotnet-inspect -y -- type IEquatable \
- --project ./src/App/App.csproj -S Implementers -v:q
- dnx dotnet-inspect -y -- extensions string --project ./src/App/App.csproj -v:n
```
- ## What does it depend on?
-
- `depends Type` walks a type hierarchy inside its search scopes. Asset mode
- omits the positional type and walks explicit package manifests, restored
- projects, and library references. `--depth 1` includes direct edges only;
- omitting it follows the complete authorized graph. Shared targets remain
- distinct incoming edges and appear as revisits in tree output. `-D`, `-S`,
- `--table`, `--tsv`, `--jsonl`, `--json`, `--count`, `--rows`, and `-n` address
- the existing section and logical-row contracts. For positional type mode only,
- unprojected `--json` is now the complete camelCase
- `TypeDependencySectionResult`, not the former flattened presentation graph.
-
- ```bash
- dnx dotnet-inspect -y -- depends JsonSerializer --package System.Text.Json
- dnx dotnet-inspect -y -- depends MyType --library MyLib.dll --mermaid
- dnx dotnet-inspect -y -- depends Command --project ./src/App/App.csproj -v:q
- dnx dotnet-inspect -y -- depends Int128 --table --rows 1..10
- dnx dotnet-inspect -y -- depends -Q "Dependency Graph"
- dnx dotnet-inspect -y -- depends Int128 \
- --where "Kind=Interface" \
- --order-by "Target desc" \
- --top 5 --table
- dnx dotnet-inspect -y -- depends NpgsqlOptionsExtension \
- --package Npgsql.EntityFrameworkCore.PostgreSQL@8.0.4 \
- --tfm net8.0 \
- --envelope
- dnx dotnet-inspect -y -- depends NpgsqlOptionsExtension \
- --package Npgsql.EntityFrameworkCore.PostgreSQL@8.0.4 \
- --tfm net8.0 \
- --json
- dnx dotnet-inspect -y -- depends \
- --project ./src/App/App.csproj \
- --depth 2 \
- -S "Dependency Hierarchy,Dependencies"
- dnx dotnet-inspect -y -- depends \
- --package Microsoft.Extensions.Hosting@10.0.0 \
- --depth 1 \
- --tree
- dnx dotnet-inspect -y -- package Microsoft.Extensions.Hosting@10.0.0 \
- -S Dependencies
- dnx dotnet-inspect -y -- package Microsoft.Extensions.Hosting@10.0.0 \
- -S "Dependency Hierarchy" --depth 1 --tree
- dnx dotnet-inspect -y -- library System.Text.Json \
- -D @Dependencies --details
- dnx dotnet-inspect -y -- library System.Text.Json \
- -D "Reference Hierarchy" --details
- dnx dotnet-inspect -y -- library System.Text.Json -S References
- dnx dotnet-inspect -y -- library System.Text.Json \
- -S "Reference Hierarchy" --tree
- ```
-
- For asset roots, `Dependency Hierarchy` preserves one occurrence per
- root-relative parent relationship. Use `Dependencies` for direct declaration
- evidence; use hierarchy table or JSON output when repeated targets and their
- parent context matter. On `package`, selecting `Dependency Hierarchy` invokes
- the same Depends operation, while `--tree` only chooses its projection.
- Both entrances inherit the same Depth capability. For positional type mode,
- `-Q "Dependency Graph"` reports the Source, Target, and Kind predicates plus
- field and Traversal ordering. `--top` requires a Source, Target, or Kind field
- order; Traversal cannot rank.
- On `library`, `References` remains direct assembly metadata and
- `Reference Hierarchy` invokes that same occurrence-addressed Depends operation
- for the exact assembly; `--depth` controls traversal and `--tree` remains only
- a projection choice. Use `-D @Dependencies --details` to compare the complete
- category with its members before choosing the exact hierarchy section for tree
- or Mermaid output.
-
- `--envelope` is a presence-only service-output selector implemented only for
- positional `depends <type>`. It implies JSON and emits
- `schema_version: 1`, `result_kind: "type-dependencies"`, the same Content as
- the paired `--json` command, Share, and ordered diagnostics. The Content keeps
- the complete dependency relationships plus the selected
- `rowSelection.relationships`; dependency enums remain numeric.
- The service constructs Share for both JSON modes, but `--json` emits Content
- only; `--envelope` exposes Share.
-
- For one exact NuGet.org package version and TFM, `share.kind` is normally
- `available`; its `full_url` opens the analogous Dependencies view in Inspect
- Web and `packet` is the canonical replay state. Mixed dependency sources and
- explicit `--depth` remain valid Content requests but make Share
- `nonProjectable`, because the published browser cannot preserve them. This is
- the high-value envelope path when a dependency answer should include a
- user-drillable graph.
-
- With `--envelope`, use `--compact` for minified JSON. `--depth` remains
- traversal, and `--rows` or `-n`/`--head`/`--tail` remain semantic relationship
- selection. Do not combine it with `--json`, another format, Discover or schema
- modes, `-S`, explicit `-v`, Count, fields/columns, decoration, projections, or
- rendered-line clipping. `--verbose` and `--tips` remain on stderr;
- explicit `--share` retains the existing final-line URL/packet policy. Asset
- mode, Discover, Count, Library Diff, and `--evidence-envelope` have not adopted
- this transport.
-
- ## Who calls it? (reverse edges)
-
- `member Type -m Method:1 -S Calls` lists what a method calls; `-S Callers` lists
- the call sites that reach it. With an explicit source, widen the caller search
- with `--bin`, `--project`, or `--caller-package`. With no explicit source, the
- first `--project` is the source context; repeated `--project` values after it
- remain caller scopes.
-
- With exactly `-S Callers`, `-n`, `--tail`, and strict `--rows A..B` select
- complete deduplicated call-site rows after every authorized caller scope has
- been scanned. Markdown, table, TSV, JSONL, JSON, and Count consume that same
- selected vector. Add `--lines` only for rendered-text clipping; `@Calls`, mixed
- sections, and scope-implied Callers retain rendered-line fallback.
-
- With exactly `-S Calls`, the same selectors operate on complete direct
- call-site occurrences after the selected method and its generated evidence
- methods have been analyzed. Repeated calls remain distinct, all output formats
- consume the same selected vector, and neighboring `@Calls`, mixed-section,
- discovery, and verbosity-implied modes retain rendered-line fallback.
-
- ```bash
- dnx dotnet-inspect -y -- member Type -m Method:1 -S Calls -n 1 --tail --json
- dnx dotnet-inspect -y -- member string -m IndexOf~147d84bbd7 -S Callers --caller-package System.Text.Json@9.0.0 --tfm net9.0
- ```
-
- `Call Graph` is the bounded bidirectional view centered on one member: inbound
- callers toward entry points plus outbound calls. Its default Markdown view is
- an edge table. Select `--tree` for a standalone path-oriented view,
- `--mermaid` for a standalone diagram, or `--markdown --mermaid` for a diagram
- inside the Markdown document. For scripts, `--tsv` and `--jsonl` expose the
- same ordered edges. Machine fields `from` and `to` are always present;
- `from_group`, `to_group`, and `label` appear only when the whole graph uses
- them. A row window does not change that schema. `--count` and `--rows` address
- edge rows consistently across these views.
-
- For a type-level dependency summary, `Called Types` groups direct calls by
- target type, assembly, members, and call kinds.
-
- `Call Graph` has no `--envelope` route. Its graph, row selection, and
- completeness evidence belong to Content, so use the graph views or structured
- row formats above. A separate exact-member `--share url` projects the public
- API Overview, not the Call Graph; do not present that URL as a replay of the
- graph analysis.
-
- ```bash
- dnx dotnet-inspect -y -- member Type -m Method:1 -S "Call Graph"
- dnx dotnet-inspect -y -- member Type -m Method:1 -S "Call Graph" --tree
- dnx dotnet-inspect -y -- member Type -m Method:1 -S "Call Graph" --mermaid
- dnx dotnet-inspect -y -- member Type -m Method:1 -S "Call Graph" --markdown --mermaid
- dnx dotnet-inspect -y -- member Type -m Method:1 -S "Call Graph" --jsonl
- dnx dotnet-inspect -y -- type Type --library MyLib.dll -S "Called Types"
- ```
-
- For an integration-style explanation of calls leaving one package assembly,
- use `graph calls`. It resolves one exact member in `--root-package`,
- automatically follows that root's authorized dependency graph, and retains
- only external boundary calls plus their shortest local connectors. Root asset
- selection stays exact; dependency traversal independently uses `--tfm` or the
- product default. This is always external-focused; it does not change the
- general bidirectional `member -S "Call Graph"` view. Dependency members with
- unique ownership retain their exact package id, version, and selected
- framework. In Inspect Web, selecting such a node loads that exact package
- through the ordinary package path before opening the member; ambiguous
- ownership publishes no package coordinate.
-
- ```bash
- dnx dotnet-inspect -y -- graph calls \
- Microsoft.Extensions.DependencyInjection.ProviderBuilderServiceCollectionExtensions \
- AddOpenTelemetrySharedProviderBuilderServices~4d95928639 \
- --root-package OpenTelemetry@1.18.0 \
- --root-tfm net10.0 \
- --tfm net10.0 \
- --all
- ```
-
- Each logical edge has a typed `connector`, `boundary`, or
- `unclassified-boundary` role. Table, TSV, JSONL, and JSON retain physical call
- receipts; Markdown, Mermaid, and plaintext lower the same Markout graph. Calls
- into assemblies outside the explicit package context remain visible as
- unclassified boundaries with an incompleteness warning. `-n`, `--tail`, and
- `--rows` select complete logical edges after bounded graph construction.
- By default, the supply-chain baseline highlights third-party Package
- boundaries while keeping the root Package and registered .NET ecosystems as
- connectors. `--first-party-prefix PREFIX` adds a known first-party Package
- family to the baseline. Use `--baseline self` to keep only the root and explicit
- first-party prefixes as connectors, or `--baseline nothing` to highlight every
- known dependency Package; the latter rejects first-party prefixes. These
- choices change highlighting, not dependency traversal.
-
- For an exact pair of Libraries, `graph libraries --library ./Consumer.dll
- --library ./Provider.dll` reports physical cross-Library calls in both
- directions. Select `-S "Direct Use Clusters"` to group connected source and
- target methods with their physical call sites. Reopen one cluster with
- `--where "Cluster=N"`, then select `-S "Public Root Paths"` to see bounded
- paths from public consumer entrypoints to that cluster. Use `-Q "Call Sites"`
- to discover the cluster predicate before opening the Libraries.
+ Scope with `--package`, `--library`, a restored `--project`, or platform inputs.
+ Direct declarations and reachable applicability are different questions;
+ `--reachable` widens extension discovery through reachable types.
- ## What does it integrate with? (ecosystem)
+ ## Calls and callers
- All integrations are enabled by default. Discover and narrow the ordinary
- Integration result with canonical concept or ecosystem identities:
+ Choose a Member from `Member Index`, then retain its stable selector:
```bash
- dnx dotnet-inspect -y -- library -Q Integrations
- dnx dotnet-inspect -y -- library Aspire.Hosting.Redis@13.5.3 \
- --tfm net8.0 -S Integrations --where "ecosystem=ecosystem.aspire"
- dnx dotnet-inspect -y -- library MyLibrary.dll -S Integrations \
- --where "integration=integration.aspire" --jsonl
+ dnx dotnet-inspect -y -- member JsonSerializer \
+ --package System.Text.Json -m Serialize -S "Member Index"
+ dnx dotnet-inspect -y -- member JsonSerializer \
+ --package System.Text.Json Serialize:1 -S Calls
+ dnx dotnet-inspect -y -- member JsonSerializer \
+ --package System.Text.Json Serialize:1 -S "Call Graph" --tree
```
- Omitting `-S` with either predicate selects `Integrations`. The two facets
- intersect when combined. An empty filtered result is not absence of all
- Integration support; full-library presence and Census remain unchanged.
- Unsupported IDs and combinations fail explicitly. Do not combine either
- predicate with Performance Triage or Body Shapes queries. These options belong
- to `library`, not `package --library` or `graph`.
+ `Calls` lists outgoing physical sites; `Callers` searches incoming sites in
+ authorized scopes. Widen caller scope with `--caller-package`, `--bin`, or
+ `--project` where supported. `Call Graph` is a bounded bidirectional view;
+ use `--jsonl` or `--tsv` for edge rows. Repeated physical calls and distinct
+ graph relationships have different counts.
- `graph integrations` compares an explicit package set inside one
- binding-consistent target. Repeat `--package name[@version]`, provide the shared
- `--tfm`, and add `--relationship <id>` only when the default Integration family
- should be narrowed. This is an induced set, not a traversal: it has no direction
- or depth. Markdown is an edge table by default; `--tree`, `--mermaid`, `--json`,
- `--jsonl`, and `--count` project the same logical relationships. `-n`, bare
- `-N`, `--tail`, and strict `--rows` select complete logical edges after the
- graph is built and before those formats; use `--lines` only for explicit
- rendered-line clipping. Row selection does not reduce package acquisition or
- hide retained graph failures. `graph libraries` remains a separate
- multi-section command: its default and exact `Call Sites` views apply the same
- semantic gestures to complete physical call sites, and exact
- `Direct Use Clusters` applies them to complete deterministic cluster rows.
- Its independent summary, path, wildcard, category, and multi-section views
- retain rendered-line `-n`.
- Missing `api.extension` or `integration.observed` endpoints whose assemblies are
- absent from the explicit package set remain outside the induced graph; add the
- owning package to admit those relationships. A missing
- `integration.opportunity` target and other binding failures -- unavailable,
- ambiguous, rejected, or selected outside the active context -- remain visible
- and produce a nonzero exit.
+ Use `--all` for non-public targets. A function load or callback registration
+ does not prove execution. Missing external assemblies and bounded traversal
+ limit what an empty caller result can establish.
- ```bash
- dnx dotnet-inspect -y -- graph integrations \
- --package Microsoft.Extensions.DependencyInjection.Abstractions@10.0.0 \
- --package Microsoft.Extensions.Logging.Abstractions@10.0.0 \
- --package Microsoft.Extensions.Logging@10.0.0 \
- --package Microsoft.Extensions.Http@10.0.0 \
- --tfm net10.0 \
- --relationship integration.observed
- ```
+ ## Cross-package structure and integrations
- `-S @Integrations` on `library` or `package --library` rolls up the ecosystem
- frameworks a library plugs into โ€” DI, hosting, ASP.NET Core, AI, OpenTelemetry,
- configuration, logging, and more โ€” plus `Integration Opportunities` and
- language/runtime integration signals like C# union types.
+ | Question | Entrance |
+ | --- | --- |
+ | Which dependency boundaries does one entrypoint reach? | `graph calls TYPE MEMBER --root-package Id@version --root-tfm net10.0 --tfm net10.0` |
+ | How do two exact Libraries call each other? | `graph libraries --library Consumer.dll --library Provider.dll` |
+ | Is a dependency used through a small cluster of APIs? | `graph packages --package Consumer@version --package Provider@version --tfm net10.0` |
+ | Which frameworks does a Library integrate with? | `library MyLib.dll -S Integrations` |
+ | Which relationships exist within an explicit package set? | `graph integrations --package A@version --package B@version --tfm net10.0` |
- ```bash
- dnx dotnet-inspect -y -- package Microsoft.Extensions.AI --library -S @Integrations
- dnx dotnet-inspect -y -- library MyLibrary.dll -S "Union Types" --tsv
- dnx dotnet-inspect -y -- library --platform System.Text.Json -S "Union Types" --tsv
- ```
+ Follow `--help`, `-D`, and installed explanation for cluster drills, public
+ root paths, integration identities and baseline controls rather than guessing
+ their bindings. Integration graphs are induced over the explicit set, not an
+ automatic dependency traversal. Missing ownership is not permission to invent
+ package coordinates.
- Use `Union Types` when looking for C# union adoption in libraries. It reports
- types annotated with `System.Runtime.CompilerServices.UnionAttribute`, whether
- they implement `IUnion`, and constructor-derived case types. Current platform
- libraries may expose the runtime infrastructure before any production library
- declares union types, so an empty table is still a useful signal.
+ Keep package/version, TFM, selected Library, Type and Member identity with
+ every conclusion. Graph views and row limits do not prove complete coverage.
+ Offer a Share URL only when it preserves the actual scenario; a separate
+ Member overview URL does not preserve the Call Graph.