A .NET 11 CLI base built with Spectre.Console, tested with xUnit, and wired for AI-assisted QA via GitHub Copilot agents and APM-managed skills.
| Path | Purpose |
|---|---|
| src/Ptu.Cli | CLI app (Spectre.Console.Cli). Commands live in Commands/, wiring in Program.Configure. |
| tests/Ptu.Cli.Tests | xUnit tests using Spectre.Console.Cli.Testing's CommandAppTester. |
| .github/agents | Copilot custom agents: the repo-specific qa agent + test agents from dotnet/skills. |
| .agents/skills | Agent skills installed by APM (run-tests, coverage-analysis, test-gap-analysis, ...). |
| apm.yml | APM manifest declaring skill dependencies (locked in apm.lock.yaml). |
| global.json | Pins the .NET 11 preview SDK. |
- To install and run the tool: .NET 10 (LTS) or .NET 11 runtime
- To build this repo: .NET SDK
11.0.100-preview.5or later (the package multi-targetsnet10.0;net11.0) - APM CLI (only needed to manage skills)
dotnet build
dotnet test
dotnet run --project src/Ptu.Cli -f net10.0 -- availability -r swedencentral -m gpt-4.1From NuGet (package sujithq.ptu.cli, command ptu):
dotnet tool install --global sujithq.ptu.cli
ptu --version
ptu availabilityUpdate with dotnet tool update --global sujithq.ptu.cli; remove with dotnet tool uninstall --global sujithq.ptu.cli.
For a local build: dotnet pack src/Ptu.Cli -c Release then dotnet tool install --global sujithq.ptu.cli --add-source ./artifacts.
ptu availability shows provisioned-throughput availability grouped by model (one group per model, one row per region). On the very first run it asks for the availability API endpoint and stores it in the config file; the endpoint returns the full dataset, so filtering happens client-side. Data Zone PTU and PAYG Data Zone Standard are shown by default; --type adds regional/global. Pass --refresh to bypass caches for both data sources and request fresh snapshots.
The PAYG column is retrieved on each run from Microsoft's public Foundry model region availability page. The Learn geography defaults to Europe (az-europe) and can be selected with --tab az-americas, --tab az-europe, --tab az-apac, or --tab az-mea; an explicit flag overrides the preset. Because CLI model names don't select a version, yes means at least one documented Azure OpenAI model version supports PAYG Data Zone Standard in that region. If the public page cannot be retrieved or parsed, PTU results still render and PAYG values are shown as unknown.
ptu availability # active preset (factory: swedencentral,francecentral × gpt-5.4,gpt-5.4-mini,gpt-5-mini,gpt-4.1)
ptu availability --refresh # bypass caches and request fresh data
ptu availability -r swedencentral,francecentral -m gpt-4.1
ptu availability --tab az-americas -r eastus -m gpt-4.1
ptu availability --preset eu -t datazone,globalExit codes: 0 success, 1 invalid input (unknown preset/type, empty region or model list), 2 API failure.
The endpoint is stored in %APPDATA%/ptu/config.json and can be inspected or changed at any time:
ptu endpoint show
ptu endpoint set https://your-availability-api.example.com/api/availability/azure-ptuIf the availability API is secured, ptu availability fails with an authentication hint (exit code 2). Sign in to the API in your browser, copy its session cookie (DevTools → Application → Cookies), and store it as a name=value pair — it is kept in %APPDATA%/ptu/config.json and sent as a Cookie header on every request:
ptu auth set "session_cookie=eyJ0b2tlbiI6..."
ptu auth show # status, user, and expiry - never the value
ptu auth clearWhen the cookie expires the API starts rejecting requests again; repeat ptu auth set with a fresh value.
Named region/model/Learn-geography profiles stored in %APPDATA%/ptu/config.json (alongside the apiEndpoint); one is the active default used by availability.
ptu preset list # * marks the active preset
ptu preset show [name]
ptu preset set eu --regions francecentral --models gpt-4.1,gpt-5-mini --tab az-europe
ptu preset use eu # switch the active default
ptu preset remove eu # 'default' is protected
ptu preset reset [--all] # restore factory values (--all drops other presets)- Create
src/Ptu.Cli/Commands/MyCommand.csextendingCommand<TSettings>; takeIAnsiConsolein the constructor (keeps it testable). - Register it in
Program.Configure. - Add tests in
tests/Ptu.Cli.TestsviaCommandAppTester— it reusesProgram.Configure, so tests exercise the real wiring.
Releases are driven by conventional commits via Versionize (fix: → patch, feat: → minor, feat!:/BREAKING CHANGE → major):
dotnet versionize # bumps csproj version, updates CHANGELOG.md, commits, tags vX.Y.Z
git push --follow-tags origin main # tag push triggers .github/workflows/release.ymlThe release workflow tests, packs, publishes to NuGet.org (trusted publishing), and creates a GitHub release with notes generated from the conventional commits (dotnet versionize changelog).
@qaagent (.github/agents/qa.agent.md): builds, tests, checks coverage and test quality, and reviews diffs. Only ever editstests/; hands off totest-quality-auditorandcode-testing-generatorfor deep audits and test generation.- Skills: installed from dotnet/skills (plugins
dotnet,dotnet-test,dotnet11) into.agents/skills/.
Manage skills with APM:
apm install # restore from apm.yml / apm.lock.yaml
apm update # refresh to latest upstream refs
apm install dotnet/skills/plugins/<plugin> --target copilot # add another plugin