The AI•Pkg server is built by forking NuGetGallery, stripping everything that doesn’t translate to the AI plugin registry use case, and building the AI•Pkg-specific surface on top. The migration is structured into four phases so that core infrastructure (Phases 0–1) can be verified independently before UI (Phase 3) and CLI (Phase 4) work begins.
The existing NuGetGallery.sln (139 projects) is not converted. A new AI•Pkg.slnx is created from scratch, pulling in only the source files and projects that are being retained.
Pre-Migration: Fork Setup
Fork the repo
Fork NuGet/NuGetGallery → AI•Pkg/AIpkgGallery on GitHub.
Create dev branch
Create a dev branch from main for migration work.
Protect main
Do not push breaking changes to main until Phase 1 is complete and tested.
Add specs
Add the src/AI•Pkg.Docs/ directory to the fork (already done).
Phase 0: Clean Solution Foundation
Goal: A buildable ASP.NET Core 10 SLNX solution with SQL Server DB Project and EasyAF scaffolding, no legacy code.
Step 0.1: Create AI•Pkg.slnx
Create a new Visual Studio SLNX solution file at the repo root. Add projects incrementally as they are created.
Step 0.2: Create Core Projects
| Project | Type | Notes |
|---|
src/AI•Pkg.Core/ | .NET 10 class library | No NuGet output yet |
src/AI•Pkg.Server/ | ASP.NET Core 10 web app | Minimal APIs + Blazor |
src/AI•Pkg.Server.Db/ | SQL Server DB Project (.sqlproj) | Schema source of truth |
src/AI•Pkg.Server.Data/ | .NET 10 class library | EasyAF-generated; committed |
tests/AI•Pkg.Core.Tests/ | xUnit .NET 10 | |
tests/AI•Pkg.Server.Tests/ | xUnit .NET 10 | |
Step 0.3: Set Up SQL Server Database Project
| NuGetGallery source | AI•Pkg table | Changes |
|---|
Packages | Packages | Remove: RequiresLicenseAcceptance, DevelopmentDependency, IsSymbolsPackage. Add: Capabilities, Targets, Permissions (JSON columns) |
PackageVersions | PackageVersions | Same as above; keep download count |
PackageOwners | PackageOwners | No change |
Users | Users | Keep; remove legacy OpenID fields |
Credentials | Credentials | Keep PBKDF2 API key structure |
PackageDependencies | PackageDependencies | Add Apms column (JSON) instead of TargetFramework |
PackageTags | PackageTags | No change |
PackageHistories | PackageHistories | No change |
PackageRenames | (drop) | Not needed |
SymbolPackages | (drop) | Not applicable |
Step 0.4: EasyAF Code Generation
Run EasyAF CLI against AI•Pkg.Server.Db/ to generate:
- EF Core 10 entity classes →
AI•Pkg.Server.Data/Entities/
- Repository classes →
AI•Pkg.Server.Data/Repositories/
AIpkgDbContext.cs → AI•Pkg.Server.Data/
Generated files are committed to the repo and regenerated whenever the DB project changes.
Phase 0 Verification
Phase 1: Core Registry API + Auth + AI•Pkg.Core
Goal: Working push, download, registration, and authentication. Package round-trip: aipkg pack → aipkg push → aipkg install.
Source Files to Port
| Source file | Destination | Action |
|---|
src/NuGet.Services.Entities/Package.cs | AI•Pkg.Server.Data/Entities/Package.cs | Generated by EasyAF; use as reference for field list |
src/NuGetGallery.Core/Packaging/PackageMetadata.cs | AI•Pkg.Core/Packaging/ManifestReader.cs | Port pattern; replace XML with System.Text.Json |
src/NuGetGallery.Core/Frameworks/FrameworkCompatibilityService.cs | AI•Pkg.Core/Platform/PlatformCompatibilityService.cs | Port architecture; replace TFM logic with APM fallback graph |
src/NuGetGallery/Controllers/ApiController.cs (V3 parts) | AI•Pkg.Server/Api/V3/ | Port push/delete/autocomplete as Minimal APIs |
src/NuGet.Jobs.Catalog2Registration/Schema/EntityBuilder.cs | AI•Pkg.Server/Jobs/RegistrationBuilder.cs | Port; update JSON-LD schema for AI•Pkg fields |
src/NuGetGallery/Services/PackageService.cs | AI•Pkg.Server/Services/PackageService.cs | Port; strip symbol/V2 logic |
src/NuGetGallery/Services/UserService.cs | AI•Pkg.Server/Services/UserService.cs | Port PBKDF2 API key management |
src/NuGetGallery/Authentication/ | AI•Pkg.Server/Auth/ | Port GitHub OAuth + API key auth |
src/NuGetGallery.Core/Services/CorePackageFileService.cs | AI•Pkg.Server/Storage/PackageStorageService.cs | Port; rename .nupkg → .aipkg |
Step 1.1: AI•Pkg.Core Implementation Order
AipkgManifest model
Implement AipkgManifest model with System.Text.Json source-gen serialization.
AipkgReader
ZIP reading and manifest extraction.
PlatformCompatibilityService
APM fallback graph (hardcoded table for now).
AipkgValidator
Manifest validation + archive validation.
AipkgVersion
SemVer parsing and range checking.
Write unit tests for each in AI•Pkg.Core.Tests.
Step 1.2: Registry API Endpoints
Implement Minimal API endpoints in AI•Pkg.Server/Api/V3/:
GET /v3/index.json
GET /v3/registration/{id}/index.json
GET /v3/registration/{id}/{version}.json
GET /v3/flatcontainer/{id}/index.json
GET /v3/flatcontainer/{id}/{version}/{id}.{version}.aipkg
GET /v3/flatcontainer/{id}/{version}/{id}.{version}.aispec
PUT /v3/package
DELETE /v3/package/{id}/{version}
GET /v3/platforms
GET /v3/registration/{id}/{version}/install/{apm}
Search and autocomplete endpoints are added in Phase 2 (they depend on Azure AI Search).
Phase 1 Verification
Phase 2: Search + Catalog Pipeline
Goal: Functional search and autocomplete. Packages appear in search results after push.
Source Files to Port
| Source | Destination | Action |
|---|
src/NuGet.Services.AzureSearch/Models/BaseMetadataDocument.cs | AI•Pkg.Server.Search/AipkgSearchDocument.cs | Port structure; adapt fields |
src/NuGet.Services.AzureSearch/ (indexing pipeline) | AI•Pkg.Server.Search/ | Port; use AipkgSearchDocument |
src/Stats.* | src/AI•Pkg.Jobs/Stats/ | Port CDN stats parsing; adapt for .aipkg |
src/GitHubVulnerabilities2Db/ | src/AI•Pkg.Jobs/Vulnerabilities/ | Port; adapt package ID resolution |
Phase 2 Verification
Phase 3: Blazor Web UI
Goal: Full public-facing web UI. Users can browse, search, view packages, upload, and manage accounts via browser.
Build all Blazor components as defined in Registry UI spec. No porting of Razor views — build fresh.
Implementation order:
- Layout components (NavBar, Footer, MainLayout)
- Package detail page (most important for discoverability)
- Search / browse pages
- Home page
- Upload wizard
- Account / API key management
- Admin panel
Phase 3 Verification
Phase 4: aipkg CLI MVP
Goal: Functional install, restore, remove, list, search commands. Single-binary Native AOT release.
Add remaining CLI commands (see SDK Interface spec):
install, restore, remove, list, search, info, sources, new, login, logout
Configure Native AOT publishing pipeline in GitHub Actions. Publish to GitHub Releases.
Phase 4 Verification
What to Delete from NuGetGallery
Entire Projects / Directories
| Path | Reason |
|---|
src/NuGetGallery/ (old MVC app) | Replaced by AI•Pkg.Server/ |
src/NuGetGallery.Core/ | Replaced by AI•Pkg.Core/ + AI•Pkg.Server.* |
src/NuGet.Services.Entities/ | Replaced by EasyAF-generated entities |
src/NuGet.Services.Odata/ | V2 OData — not used |
src/NuGetGallery.WebUITests/ | Old Selenium tests — not used |
src/NuGet.Jobs.Symbols*/ | Symbol package infrastructure — not applicable |
src/NuGet.Services.Logging/ | Replace with Microsoft.Extensions.Logging directly |
tests/NuGetGallery.Core.Facts/ | Recreate in AI•Pkg.Core.Tests/ |
tests/NuGetGallery.Facts/ | Recreate in AI•Pkg.Server.Tests/ |
NuGetGallery.FunctionalTests.sln | Not migrated |
tools/ (Python tooling) | Python scripts — not used |
Files Within Retained Projects
| File/Pattern | Reason |
|---|
**/*.cshtml | All Razor views — replaced by Blazor |
**/_ViewImports.cshtml | Razor infrastructure |
**/BundleConfig.js | jQuery bundling |
**/Startup.cs (OWIN) | OWIN startup — replaced by Program.cs |
**/Global.asax* | OWIN/System.Web |
src/NuGetGallery/OData/ | V2 OData controllers |
src/NuGetGallery/Controllers/ODataV* | V2 OData controllers |
**/AutofacRegistration*.cs | Autofac modules |
**/ContainerBindings.cs | Autofac container setup |
**/packages.config | Old-style NuGet package references |
Project Rename Reference
| Original | New |
|---|
NuGetGallery | AI•Pkg.Server |
NuGetGallery.Core | AI•Pkg.Core |
NuGet.Services.Entities | AI•Pkg.Server.Data (generated) |
NuGet.Services.AzureSearch | AI•Pkg.Server.Search |
NuGetGallery.Core.Facts | AI•Pkg.Core.Tests |
NuGetGallery.Facts | AI•Pkg.Server.Tests |
Stats.* | AI•Pkg.Jobs (combined jobs project) |
GitHubVulnerabilities2Db | part of AI•Pkg.Jobs |
NuGet.Packaging (client) | AI•Pkg.Core (implements own reader/writer) |
NuGetGallery.sln | AI•Pkg.slnx |
Critical Source Files to Reference
Read these NuGetGallery files before implementing the corresponding AI•Pkg components:
| NuGetGallery source | AI•Pkg component | What to learn |
|---|
src/NuGet.Services.Entities/Package.cs | AI•Pkg.Server.Data/Entities/Package.cs | Entity field list, relationships |
src/NuGetGallery.Core/Frameworks/FrameworkCompatibilityService.cs | AI•Pkg.Core/Platform/PlatformCompatibilityService.cs | Fallback graph algorithm |
src/NuGet.Services.AzureSearch/Models/BaseMetadataDocument.cs | AI•Pkg.Server.Search/AipkgSearchDocument.cs | Search document field design |
src/NuGet.Jobs.Catalog2Registration/Schema/EntityBuilder.cs | AI•Pkg.Server/Jobs/RegistrationBuilder.cs | Registration blob construction |
src/NuGetGallery.Core/Packaging/PackageMetadata.cs | AI•Pkg.Core/Packaging/ManifestReader.cs | Manifest parsing patterns |
src/Stats.*/ | AI•Pkg.Jobs/Stats/ | CDN log parsing |
src/GitHubVulnerabilities2Db/ | AI•Pkg.Jobs/Vulnerabilities/ | Vulnerability job pattern |
Open Items / Lower Priority
| Item | Notes |
|---|
| License scanning | Evaluate porting NuGet.Jobs.Validation.PackageSigning.*; lower priority |
| Package signing | Spec defined in Code Signing spec; implement post-MVP |
| OIDC auth provider | Post-MVP; add alongside GitHub OAuth |
| TypeScript SDK | @aipkg/core etc.; post-MVP (see SDK Interface spec) |
@aipkg/claude-code npm package | Post-MVP |
| DotNetDocs.com integration | Begin after AI•Pkg.Core 1.0.0 stabilizes |
| Package verified badges | Need author verification system design |
| A/B testing framework | Post-MVP |