AiSdlc.Cli
0.22.0
dotnet tool install --global AiSdlc.Cli --version 0.22.0
dotnet new tool-manifest
dotnet tool install --local AiSdlc.Cli --version 0.22.0
#tool dotnet:?package=AiSdlc.Cli&version=0.22.0
nuke :add-package AiSdlc.Cli --version 0.22.0
aisdlc
Structural search over .NET code + live Azure infrastructure, exposed as a single CLI tool that LLM agents (and humans) call from any terminal.
Modules under one binary:
| Module | Reads from | Purpose |
|---|---|---|
aisdlc code |
local solution (Roslyn) | symbols, endpoints, DI graph, call chains, config bindings, log call sites, message publishers |
aisdlc azure |
live Azure (ARM API) | env-aware snapshot of resources, services, RBAC, alerts, log pipes, messaging entities |
aisdlc sql |
live Azure SQL / PostgreSQL | per-env database schema (tables, columns, PKs, FK graph) — Entra or password auth |
aisdlc logs |
live Log Analytics workspaces | per-workspace table & column schema for KQL composition |
aisdlc flutter |
local Flutter/Dart project (analyzer) | screens, widgets, routes, providers, HTTP calls, models + OIDC config; bridges mobile HTTP to backend EntryPoints |
aisdlc bridge |
code-index + infra-index + sql-index | auto-links code → Azure resources / SQL tables; unresolved gaps go to an LLM worklist |
aisdlc app |
all indexes + apps.yaml |
logical applications that bridge code, infra, and observability |
aisdlc ask |
indexes + --env overlay |
unified query — structure by default, environment facts with --env |
All output is Markdown to stdout. Logs go to stderr.
Requirements
- .NET 10 SDK
- For
azure scan: Azure auth — either an SPN per env ininfra-config.yaml, oraz loginforDefaultAzureCredentialfallback. - For
code init: MSBuild (bundled with SDK). - For
sql scanagainst PostgreSQL with Entra auth: the same Azure credential source above (the scanner exchanges it for a Postgres-scoped token). For password auth no Azure login is needed — the password lives in an env var whose name is referenced insql-config.yaml. - For
flutter scan: a Dart SDK onPATH(or--dart-path /path/to/dart). First scan compiles the embedded analyzer extractor to a kernel snapshot (~3 s, one-time); warm scans run in ~1 s/project.
Install
# Install as a global tool from nuget.org
dotnet tool install -g AiSdlc.Cli
After this aisdlc is on your PATH and works from any directory.
Update
dotnet tool update -g AiSdlc.Cli
Install from a local build (no feed)
dotnet pack src/CodeParser/CodeParser.csproj -c Release -o ./artifacts
dotnet tool install -g --add-source ./artifacts AiSdlc.Cli
Uninstall
dotnet tool uninstall -g AiSdlc.Cli
Run without installing
dotnet run --project src/CodeParser -- <module> <verb> ...
Publish a new release (maintainers)
Bump the version, pack, and push to nuget.org in one step:
$env:NUGET_API_KEY = "<your-nuget-org-key>"
./scripts/publish.ps1 -Version 0.9.3
Omit -Version to publish the version already set in
src/CodeParser/CodeParser.csproj. Get an API key at nuget.org → API Keys.
Quick start
Index your .NET solution
cd /path/to/some/.net/repo
aisdlc code init # writes .aisdlc/code-index.json
aisdlc code status # is the index still fresh vs git HEAD?
Ask structural questions
aisdlc code find-symbol UserService --kind class
aisdlc code find-endpoint --route api/users --method POST
aisdlc code find-endpoint --kind minimal-api
aisdlc code find-endpoint --kind mediatr-handler
aisdlc code find-usages IUserRepository
aisdlc code explain-flow UsersController --depth 4
aisdlc code architecture
aisdlc code project-map
aisdlc code config-overview
aisdlc code config-binding --type JwtSettings
aisdlc code azure-resources --kind blob-storage
Resident daemon (faster repeat queries)
A stateless call re-parses the whole code-index.json every time — fine once, but it
dominates latency across the many calls an agent makes, and grows with the index. The
read-only code verbs above transparently forward to a resident daemon that parses the
index once and answers over a named pipe in single-digit milliseconds:
aisdlc code serve # optional: start it explicitly (else it auto-spawns)
You normally never run this — the first read-only query auto-spawns a detached daemon for
that index, and every later call is served warm (no re-parse). It reloads automatically when
the index changes (e.g. after a re-init) and self-exits after 30 min idle. Results are
identical to a cold run; the daemon only affects speed. Opt out per call with --no-daemon,
or globally with AISDLC_NO_DAEMON=1.
Register Azure environments
aisdlc azure init # creates empty .aisdlc/infra-config.yaml
aisdlc azure env add prod --subscription <guid> --rg rg-myapp-prod
aisdlc azure env add qa --subscription <guid> --rg rg-myapp-qa
aisdlc azure env add devbox --subscription <guid> --rg rg-sandbox-dev --kind sandbox
aisdlc azure env list
aisdlc azure env show prod
For non-interactive auth, add an SPN block to infra-config.yaml directly —
secrets starting with $ are read from environment variables:
- name: prod
subscriptionId: 00000000-0000-0000-0000-000000000001
resourceGroup: rg-myapp-prod
spn:
tenantId: 00000000-0000-0000-0000-0000000000ff
clientId: 00000000-0000-0000-0000-000000000101
clientSecret: $PROD_SPN_SECRET
Snapshot live Azure
aisdlc azure scan # all envs
aisdlc azure scan --env prod # just one
# writes .aisdlc/infra-index.json
aisdlc azure resources --env prod
aisdlc azure resources --env prod --type storage
aisdlc azure services --env prod
aisdlc azure rbac --env prod --principal users-api-mi
Register applications (bridge code ↔ infra)
aisdlc app add users-api --description "Public REST API for user management" \
--project Users.Api
# Attach entry points (IDs come from `code find-endpoint`)
aisdlc app attach entry-point users-api --id ep_abc123
aisdlc app attach entry-point users-api --id ep_def456
# Attach deployed service per env (names come from `azure services`)
aisdlc app attach service users-api --env prod --service users-api-prod
aisdlc app attach service users-api --env qa --service users-api-qa
aisdlc app list
aisdlc app show users-api
aisdlc app validate # check that every reference still resolves
The catalogue lives in .aisdlc/apps.yaml — commit it. It's config-as-code,
not generated state.
Register databases and snapshot schema
aisdlc sql init # creates empty .aisdlc/sql-config.yaml
# Entra-ID auth (Azure SQL or PostgreSQL):
aisdlc sql db add users-prod --env prod --kind azure-sql \
--server users-sql.database.windows.net --database users
# PostgreSQL password auth — the YAML stores only the env-var NAME, never the value:
aisdlc sql db add listening-prod --env prod --kind postgres \
--server lst-psql-west.postgres.database.azure.com --database listening \
--pg-user pgadmin --password-env LST_PG_PASSWORD
LST_PG_PASSWORD='…' aisdlc sql scan # writes .aisdlc/sql-index.json
aisdlc sql tables --db listening-prod
aisdlc sql deps public.user_answers --depth 5
Scan a Flutter project
cd /path/to/repo
aisdlc flutter scan # auto-discovers any pubspec.yaml with flutter:
aisdlc flutter screens # all top-level pages with their routes
aisdlc flutter http-calls # mobile HTTP call sites with normalised paths
aisdlc flutter auth-config # detected OAuth/OIDC config (CIAM/B2C/Auth0/…)
aisdlc flutter trace SettingsScreen
After aisdlc code init has produced a backend code-index, link mobile → backend:
aisdlc flutter bridge # writes .aisdlc/flutter-bridge.json
# high-confidence auto-matches + 'unresolved' for
# dynamic URLs. Use .aisdlc/flutter-links.yaml to
# pin runtime-built URLs to their backend route.
Live daemon while you edit:
aisdlc flutter watch # re-scan the affected project on every save
# under lib/ or pubspec.yaml; bridge rebuilds too
Build the unified code ↔ infra ↔ SQL bridge
aisdlc bridge build # joins code-index + infra-index + sql-index
aisdlc bridge show # confirmed links (auto + manual)
aisdlc bridge unresolved # gaps for human/LLM follow-up
aisdlc bridge link … # persist a manual override to .aisdlc/links.yaml
Dev Container
This repo can run directly inside a Docker-based VS Code dev container instead of
WSL. The checked-in config uses a Linux .NET 10 SDK image and installs Azure
CLI plus PowerShell inside the container.
Prerequisites:
- Docker Desktop or Docker Engine
- VS Code
Dev Containersextension - If you're on Windows, WSL integration enabled for Docker Desktop is the most practical setup
Open the repo in the container:
Ctrl+Shift+P
Dev Containers: Reopen in Container
On first start, VS Code will build the container, install the recommended extensions into the container target, and run:
dotnet restore aisdlc.sln
After attach, terminals, C# language services, builds, and debugging all run inside the container instead of the WSL distro.
The killer query
aisdlc app trace users-api --env prod
One Markdown report covering:
- App metadata (name, description)
- Entry points from
code-index(route, method, handler symbol) - 3-hop DI graph walk to find collaborators
- Code-declared Azure SDK clients touched by those collaborators
- The deployed service in
prod: kind, image, ingress URL, every env var (including Key VaultsecretRefs), RBAC pointer
Equivalent to ~15 ad-hoc tool calls from an LLM agent. One call here.
Recommended layout
your-repo/
├── .aisdlc/
│ ├── code-index.json # gitignored (regenerable)
│ ├── infra-index.json # gitignored (regenerable, may contain settings)
│ ├── infra-config.yaml # COMMIT (env definitions, no secret values)
│ └── apps.yaml # COMMIT (app catalogue)
├── src/
│ └── ...
└── ...
Add this to .gitignore:
.aisdlc/code-index.json
.aisdlc/infra-index.json
Keep .aisdlc/infra-config.yaml and .aisdlc/apps.yaml in source control —
they're as much "what is this repo" documentation as *.csproj is.
For LLM agents
Put this in your CLAUDE.md / agent system prompt:
For structural questions about this codebase, prefer `aisdlc`:
- `aisdlc code find-symbol <name>` — exact / partial symbol lookup with kind filter
- `aisdlc code find-endpoint --route <r>` — HTTP routes (MVC + Minimal API + MediatR)
- `aisdlc code explain-flow <symbol>` — DI + call graph trace
- `aisdlc code find-usages <symbol>` — Roslyn-aware relations
- `aisdlc app trace <app> --env <env>` — end-to-end view: code + infra
For free-text or regex search, use grep/ripgrep instead.
Every output starts with a freshness banner (Index @ a1b2c3d4 matches HEAD …)
so the agent knows when to trust the snapshot or fall back to grep/Read.
What's not in here yet
By design, this is Phase 1:
- No observability hooks (App Insights, Log Analytics, alerts) — Phase 2.
- No KQL log query wrapper.
- No feature-flag extraction from App Configuration.
- No auto-detect (linking entry points to apps by project name, services by image name).
- No managed Azure mutations. All
azureverbs are read-only. For mutating live infra, useaz/bicep/terraform.
Project layout
src/
├── CodeParser/ # the `aisdlc` tool (dotnet tool package)
│ ├── Cli/ # dispatcher, modules, command handlers
│ ├── Models/ # CodeIndex, EntryPoint, AzureResource, ...
│ ├── Parsers/ # Roslyn extractors (MVC, Minimal API, MediatR, Azure SDK)
│ ├── Retrieval/ # RetrievalEngine, ContextAssembler, IndexFreshness
│ └── SolutionIndexer.cs # orchestrator
├── AzureInfraScanner/ # library: live Azure scan
│ ├── Config/ # infra-config.yaml schema + load/save
│ ├── Scanners/ # ResourceCollector, ServiceExtractor, AccessExtractor
│ └── InfraScanner.cs # public entry point used by `aisdlc azure scan`
├── BicepParser/ # Bicep file analysis + cross-graph link to code-index
├── CodeParser.Tests/ # (empty — TODO)
└── ...
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.22.0 | 51 | 6/4/2026 |
| 0.21.0 | 49 | 6/4/2026 |
| 0.20.0 | 39 | 6/4/2026 |
| 0.19.1 | 68 | 6/3/2026 |
| 0.19.0 | 90 | 6/3/2026 |
| 0.18.0 | 103 | 5/31/2026 |
| 0.17.0 | 103 | 5/29/2026 |
| 0.16.20 | 110 | 5/29/2026 |
| 0.16.4 | 104 | 5/23/2026 |
| 0.16.3 | 96 | 5/23/2026 |
| 0.16.2 | 101 | 5/23/2026 |
| 0.16.1 | 87 | 5/23/2026 |
| 0.16.0 | 90 | 5/23/2026 |
| 0.15.3 | 101 | 5/21/2026 |
| 0.15.2 | 94 | 5/21/2026 |
| 0.15.1 | 100 | 5/21/2026 |
| 0.15.0 | 105 | 5/21/2026 |
| 0.14.0 | 97 | 5/21/2026 |
| 0.12.0 | 101 | 5/20/2026 |
| 0.11.0 | 86 | 5/20/2026 |