v0.1.0 to v0.1.0

74 added, 231 removed. Audit A to A.

---
name: dotnet-inspect-private-feeds
version: 0.1.0
- description: Inspect packages from private and custom NuGet feeds safely — select and map sources, use credential providers or explicit configuration, diagnose authentication failures, and reason about source-bound caches and offline operation.
+ description: Inspect packages from private or folder NuGet feeds using explicit sources, mapping and noninteractive authentication; preserve source authority and distinguish failures from package absence.
---
- # dotnet-inspect: private NuGet feeds
-
- Use this skill when package evidence lives outside NuGet.org. Start with a
- credential-free source configuration and a NuGet credential provider; keep
- tokens out of repositories and command lines.
-
- ```bash
- dnx dotnet-inspect -y -- <command>
- ```
-
- ## Select the feed
+ # dotnet-inspect: Inspect NuGet Packages from Private and Local Feeds
- `--nugetconfig` uses exactly the named configuration. `--source` replaces the
- configured source set and can repeat; `--add-source` augments it for one run.
- Use a source-only config when a credential provider supplies authentication:
+ Use this skill when package evidence lives outside NuGet.org.
+ Run `dnx dotnet-inspect -y -- <command>`. Start with a credential-free
+ configuration and a NuGet credential provider; keep tokens out of repositories,
+ URLs and command lines.
- ```xml
- <?xml version="1.0" encoding="utf-8"?>
- <configuration>
- <packageSources>
- <clear />
- <add key="private" value="https://example.com/nuget/v3/index.json" />
- </packageSources>
- </configuration>
- ```
+ ## Select and pin the source
```bash
- dnx dotnet-inspect -y -- package MyCompany.Widget --nugetconfig ./NuGet.Config
- dnx dotnet-inspect -y -- package MyCompany.Widget --versions-with-feed \
+ dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 \
--nugetconfig ./NuGet.Config
- ```
-
- `find --packages` currently uses NuGet.org only; it rejects private-feed source
- overrides rather than silently querying the wrong authority.
-
- Version discovery combines all eligible sources and chooses the highest
- semantic version; source order is not precedence. Pin `Package@Version` when
- the exact coordinate matters.
-
- ## Share a private-feed Workspace with Inspect Web
-
- Author a credential-free format-5 URL that declares an
- authentication-required source:
-
- ```bash
- dnx dotnet-inspect -y -- workspace \
- --package Private.Package@1.2.3 \
- --tfm net10.0 \
- --nuget-source-auth-required \
- https://nuget.pkg.github.com/example/index.json \
- --share url
- ```
-
- Inspect Web prompts once per exact endpoint for a username and personal access
- token. Credentials remain in page-session memory only: activation-local copies
- are cleared after settlement, while the active realization or
- incumbent-recovery binding may retain them until replacement or disposal. They
- are not placed in the packet or URL, retained Workspace definition, browser
- storage, logs, diagnostics, or telemetry. Reloading prompts again. Cancellation
- or failure before publication preserves the prior visible Workspace; if
- recovery after cutover also fails, Inspect Web enters a blocking retry state
- rather than exposing the failed tentative Workspace. Declared anonymous
- sources activate without a prompt.
-
- ### Query versions from a folder feed
-
- Online version queries support NuGet V2/V3 folder feeds, specified as a
- path, a `file://` URI, or a mapped source in `NuGet.Config`:
-
- ```bash
- dnx dotnet-inspect -y -- package MyCompany.Widget --versions --source ./feed
- dnx dotnet-inspect -y -- package MyCompany.Widget --versions -n 5 --preview \
- --source ./feed --jsonl
- dnx dotnet-inspect -y -- package MyCompany.Widget --versions -n 1 --source ./feed
- dnx dotnet-inspect -y -- package MyCompany.Widget@latest --versions --source ./feed
- dnx dotnet-inspect -y -- package MyCompany.Widget --version 1.2.3 --source ./feed
- dnx dotnet-inspect -y -- package MyCompany.Widget@1.0.0..2.0.0 --versions \
- --source ./feed --include-unlisted
dnx dotnet-inspect -y -- package MyCompany.Widget --versions-with-feed \
- --source ./feed --add-source https://api.nuget.org/v3/index.json
- ```
-
- Local and HTTP versions are combined and sorted before the result limit.
- Use `--versions -n 1` for one newest listed version row, or
- `Package@latest --versions` to force a fresh latest-version check.
- For online single-package inspection, an unpinned ID can reuse the tool's
- prior version settlement within its jittered one-hour window. A stale prior is
- refreshed within five seconds; if refresh fails, the tool serves the prior with
- one warning naming its age. Use `Package@latest` when the inspection must make
- a fresh version check. Version-listing, range, and wildcard queries retain
- their own selection paths.
- Missing folders or invalid archives are source failures, not package absence;
- usable peer results carry an explicit partial warning on stderr. Local reads
- use bounded enumeration rather than treating filenames as version evidence.
- Latest, single-version discovery, and range selection require complete
- evidence: an unreadable peer makes them fail instead of choosing from a
- healthy subset. A pinned verification may report a coordinate observed on a
- readable feed, with peer failures disclosed. `--include-unlisted` and
- `--versions-with-feed` retain their listing and feed columns; local versions
- use the non-Gallery `listed` convention.
-
- These version queries are metadata-only and do not use `--offline`.
-
- ### Inspect a package from a folder feed
-
- Pin one coordinate to inspect its payload through the configured folder source:
-
- ```bash
- dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 --source ./feed
- dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 --source ./feed \
- --path @readme --content --raw
- dnx dotnet-inspect -y -- package MyCompany.Widget --source ./feed
- dnx dotnet-inspect -y -- package 'MyCompany.Widget@1.*' --source ./feed \
- --path @readme --content --raw
- ```
-
- Online single-package inspection also supports latest, `--preview`, and
- wildcard payload selection. It freshly queries every eligible source and
- requires complete evidence before choosing a version; a failed peer blocks
- automatic selection even when another source has a warm payload cache.
- Only sources that reported the selected version may supply its payload.
- Wildcards use a case-insensitive version prefix and may match prereleases.
-
- Caller-pinned acquisition tries local sources before HTTP sources.
- Declaration order is not precedence within a tier. One eligible source can
- supply the exact package even when an earlier peer fails; `--verbose` retains
- those diagnostics. Tool-wrapper redirects independently reapply mapping.
-
- Local payload caches are scoped to the canonical configured folder, not just
- package ID/version or producer identity. HTTP payloads currently use temporary
- authority-scoped materialization and do not reuse persistent payload caches.
- Automatic selection does not reuse legacy candidate caches. `package --versions`
- can enumerate a range, but ordinary `package` payload inspection does not
- accept a range or `--at`.
-
- ### Inspect APIs and history from a folder feed
-
- Online API commands support omitted/latest and wildcard selection, exact pins,
- and explicitly addressed ranges:
-
- ```bash
- dnx dotnet-inspect -y -- type MyCompany.Widget --package MyCompany.Widget \
- --source ./feed
- dnx dotnet-inspect -y -- type MyCompany.Widget \
- --package 'MyCompany.Widget@1.*' --source ./feed
- dnx dotnet-inspect -y -- type MyCompany.Widget --package MyCompany.Widget@1.2.3 \
+ --nugetconfig ./NuGet.Config
+ dnx dotnet-inspect -y -- package MyCompany.Widget --versions -n 1 \
--source ./feed
- dnx dotnet-inspect -y -- type MyCompany.Widget \
- --package MyCompany.Widget@1.0.0..2.0.0 --at last --source ./feed
- dnx dotnet-inspect -y -- diff --history --package MyCompany.Widget@1.0.0..2.0.0 \
- --type MyCompany.Widget --type-presence --at first --at last --source ./feed
+ dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 \
+ --source ./feed --path @readme --content --raw
```
- Omitted and `@latest` API selection chooses the highest stable listed version.
- Wildcards use the package selection contract's case-insensitive prefix
- semantics and may select a prerelease.
-
- Ranges require complete fresh discovery and acquire only from sources that
- reported each selected coordinate. Diff History retains one vector for all its
- probes. Omit `--at` for full-population evaluation, repeat it for explicit
- checkpoints, use `--max-probes` for adaptive bisection, or use
- `--major-versions` for one representative per major. API findings use the
- first stable version, with the latest prerelease fallback for preview-only
- majors; Analysis findings use the latest admitted version per major. An
- unreadable peer prevents selection.
+ `--nugetconfig` selects exactly that configuration. Repeatable `--source`
+ replaces configured sources; `--add-source` augments them for one invocation.
+ Folder feeds accept a path or `file://` URI. Source order is not version
+ precedence: discovery chooses among eligible observations. Pin `Id@version`
+ when the exact coordinate matters; `Id@latest --versions` requests a fresh
+ latest-version check, and `--preview` opts into prereleases.
- API/history vectors exclude unlisted observations, including endpoints.
- An exact pin can still inspect an unlisted coordinate. Do not copy ordinals
- from a `--include-unlisted` metadata listing into a listed-only vector.
- Diff History probe recommendations retain source/configuration and selection
- options. `match --similar` retains the reporting configured sources in its
- exact-package replay, without depending on temporary extraction paths.
+ `find --packages` is NuGet.org-only and rejects source overrides.
+ For API/history inspection, carry the same `--source`/`--nugetconfig` and TFM
+ through every probe. Load `skill compatibility` for ranges, checkpoints and
+ `--major-versions`; do not reuse ordinals from an unlisted-inclusive version
+ listing in a listed-only history vector.
- Exact API pins and range probes use the same local authority caches and HTTP
- temporary storage as package inspection. HTTP payloads are downloaded anew in
- each invocation. Multi-package and dependency commands, and offline extraction
- remain on their existing paths.
+ For detailed command admission use `--help`; for unfamiliar inspection/query
+ depth use `explain "<question>"` and follow its returned binding.
- ### Restrict package ids to feeds
+ ## Source mapping
- dotnet-inspect honors `<packageSourceMapping>` from the selected NuGet
- configuration:
+ Use normal `<packageSources>` plus `<packageSourceMapping>` in NuGet.Config.
+ Every requested package, including dependencies and tool redirects, needs an
+ eligible source. Exact-ID mapping wins over prefixes; otherwise the longest
+ prefix wins.
```xml
<packageSourceMapping>
<packageSource key="private">
<package pattern="MyCompany.*" />
</packageSource>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
</packageSourceMapping>
```
- An exact package id wins over prefixes; otherwise the longest matching prefix
- wins. Mapping is applied independently to top-level packages, dependencies,
- RID companions, platform packs, tool redirects, searches, and routing probes.
- Every package id must match an active named source. `--source` and
- `--add-source` do not disable mapping; an override must match the configured
- endpoint to retain its mapped source name.
+ An override does not disable mapping. Its endpoint must match a configured
+ source to retain that source's mapped name. Do not recover mapping failures by
+ silently switching to another authority.
- ## Azure Artifacts credential provider
+ ## Authenticate noninteractively
- Install Microsoft's provider as a global tool. dotnet-inspect discovers
- `NUGET_NETCORE_PLUGIN_PATHS`, then `NUGET_PLUGIN_PATHS`, then
- `~/.nuget/plugins/netcore/` and `nuget-plugin-*` executables on `PATH`.
+ Install Microsoft's Azure Artifacts provider:
```bash
dotnet tool install --global Microsoft.Artifacts.CredentialProvider.NuGet.Tool
```
- Credential plugins run only after a feed answers `401`. dotnet-inspect requests
- credentials noninteractively: cached and environment-supplied credentials work,
- but it never opens a sign-in prompt. `az login` alone does not supply a NuGet
- credential.
+ dotnet-inspect discovers `NUGET_NETCORE_PLUGIN_PATHS`, `NUGET_PLUGIN_PATHS`,
+ the normal `~/.nuget/plugins/netcore/` directory, and `nuget-plugin-*` tools on
+ PATH. Providers run after a `401` and are requested noninteractively: cached
+ and environment-supplied credentials work, but no sign-in prompt opens.
+ `az login` alone does not supply a NuGet credential.
- In Azure Pipelines, authenticate before restore or inspection:
+ In Azure Pipelines, run `NuGetAuthenticate@1` before inspection. Outside it,
+ use the provider's documented unattended input such as
+ `ARTIFACTS_CREDENTIALPROVIDER_EXTERNAL_FEED_ENDPOINTS`, without printing its
+ expanded secret value. For build identities, the provider also accepts
+ `ARTIFACTS_CREDENTIALPROVIDER_URI_PREFIXES` and
+ `ARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN`; certificate inputs use
+ `ARTIFACTS_CREDENTIALPROVIDER_FEED_ENDPOINTS`.
- ```yaml
- - task: NuGetAuthenticate@1
- - script: dotnet restore
- - script: dnx dotnet-inspect -y -- package MyCompany.Widget
- ```
+ If no provider serves the feed, a private config outside the repository can
+ supply both `Username` and `ClearTextPassword` under the matching
+ `packageSourceCredentials` key. Do not rely on `%VAR%` expansion, encrypted
+ `Password`, `NuGetPackageSourceCredentials_*`, or URL credentials:
+ dotnet-inspect does not consume those forms.
- Outside Azure Pipelines, provide the provider's documented unattended
- credential input. Do not print the expanded value:
+ ## Share a credential-free declaration
```bash
- export ARTIFACTS_CREDENTIALPROVIDER_EXTERNAL_FEED_ENDPOINTS='{"endpointCredentials":[{"endpoint":"https://example.com/nuget/v3/index.json","username":"unused","password":"'"$TOKEN"'"}]}'
+ dnx dotnet-inspect -y -- workspace \
+ --package Private.Package@1.2.3 --tfm net10.0 \
+ --nuget-source-auth-required \
+ https://nuget.pkg.github.com/example/index.json --share url
```
- For an Azure Pipelines-compatible build identity, the provider also accepts
- `ARTIFACTS_CREDENTIALPROVIDER_URI_PREFIXES` with
- `ARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN`. Service-principal certificate
- configuration uses `ARTIFACTS_CREDENTIALPROVIDER_FEED_ENDPOINTS`.
-
- ## Explicit credentials
-
- When no provider serves the feed, dotnet-inspect accepts both `Username` and
- `ClearTextPassword` under a matching `packageSourceCredentials` key. Keep that
- config outside the repository and select it with `--nugetconfig`.
-
- Do not rely on `%VAR%` expansion, encrypted `<Password>`,
- `NuGetPackageSourceCredentials_*`, or credentials embedded in a source URL;
- dotnet-inspect does not use those forms.
+ Inspect Web prompts per authentication-required endpoint. Credentials stay in
+ page-session memory, not the packet, URL, browser storage or telemetry.
+ Reloading prompts again. The declaration carries source requirements, not
+ credentials or proof that acquisition succeeded.
- ## Diagnose failures and caches
+ ## Diagnose failures without changing authority
- A reported `401 Unauthorized` means the source was unreadable, not that the
- package is absent. Check provider discovery, URI matching, token scope, and
- expiration before changing the package id.
+ A `401` means unreadable source, not absent package. Check provider discovery,
+ endpoint matching, token scope and expiry before changing the ID. Missing
+ folders and malformed archives are source failures too. A healthy peer does
+ not make incomplete automatic version discovery complete.
- dotnet-inspect's package payload and candidate caches retain source provenance.
- The NuGet global folder is payload-only: it can fulfill an exact resolved
- coordinate only when `.nupkg.metadata.source` names an authorized producer.
- Missing or mismatched provenance is a cache miss, and installed payloads do not
- introduce version candidates. Use `--no-nuget-cache` to exclude that layer.
- `--offline` forbids network access and does not start credential plugins, so it
- succeeds only from producer-authorized caches. Online version queries bypass
- these legacy caches. Online single-package extraction, exact API pins, and
- API/history range probes use authority-scoped
- payload storage instead: old producer-keyed entries cannot authorize it, and HTTP
- global-packages entries are not reused. A local global-packages entry must
- name the same canonical configured folder in `.nupkg.metadata.source`.
- Other unmigrated paths still skip configured folder feeds; `--verbose`
- reports the skip. Passing a local `.nupkg` file remains supported separately.
+ Payload caches do not authorize a new source or introduce version candidates.
+ Retain source provenance and warnings; a warm cache must not become an
+ unqualified cross-feed answer. `--no-nuget-cache` excludes the NuGet global
+ package-cache layer where supported.
- ```bash
- dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 \
- --source https://example.com/nuget/v3/index.json --no-nuget-cache
- dnx dotnet-inspect -y -- package MyCompany.Widget@1.2.3 \
- --nugetconfig ./NuGet.Config --offline
- ```
+ `--offline` prohibits network and credential plugins; successful inspection
+ requires already authorized local content. It is not a metadata-only online
+ version query. An offline cache miss is not evidence that the package does
+ not exist.