This is the second half of the InitProvider work. That issue is about answering questions we ask the user (region, subscription, env name). This one is about the bigger question we ask them, which is "what is this app and what does it need."
We already do detection and it's good. azd init --from-code runs appdetect, which parses pom.xml well enough to spot Spring Boot starters and infer that you need Redis or Postgres or Mongo. The problem is that it's a fixed list. allDetectors in internal/appdetect/appdetect.go is five entries (java, dotnet apphost, dotnet, python, javascript), the dependency and database types are closed const enums, and the whole thing lives in an internal package so nothing outside azd can even import it.
So if you're Aspire, or a company with an internal Spring Boot flavor, or Foundry trying to recognize an agent project, your only real option is to skip our detection entirely and build your own init command. Same failure mode as the defaults issue. The only way to participate in init is to replace it.
What I think we want is detection contributed through the same InitProvider capability, layered so that the more specific detector wins. MyCompanySpringBoot over SpringBoot over Java over whatever core does.
A few things that matter in the design:
- A detector should declare what it refines rather than picking a number. If you can say "I'm a more specific version of
java," the ordering falls out of the chain and nobody has to guess whether they're priority 40 or 60.
- More than one detector will match, and that's fine. The most specific one wins for anything they both claim, and the rest merges.
- Core's five detectors should become the base layer of the same mechanism instead of a special case that runs first. If we can't express our own detectors in the extension model, the extension model isn't rich enough yet.
- The closed enums have to go, or at least stop being the only vocabulary. Today a detector can only report things from a fixed set of
Dependency and DatabaseDep values. Someone else's detector needs to be able to report something we've never heard of, which probably means the result is a service or resource shape rather than an enum member.
- Whatever we do for showing inferred state has to cover this. Once detection is layered and pluggable, "azd decided you use Redis" with no way to see which detector said so is not something we should ship.
The thing I'm most worried about is two extensions both claiming the same directory with neither one refining the other. We need a defined answer for that (and probably a way for the user to pin the winner in azure.yaml so it stays pinned), otherwise which extensions you happen to have installed changes what your project is.
This is the second half of the InitProvider work. That issue is about answering questions we ask the user (region, subscription, env name). This one is about the bigger question we ask them, which is "what is this app and what does it need."
We already do detection and it's good.
azd init --from-coderunsappdetect, which parsespom.xmlwell enough to spot Spring Boot starters and infer that you need Redis or Postgres or Mongo. The problem is that it's a fixed list.allDetectorsininternal/appdetect/appdetect.gois five entries (java, dotnet apphost, dotnet, python, javascript), the dependency and database types are closed const enums, and the whole thing lives in aninternalpackage so nothing outside azd can even import it.So if you're Aspire, or a company with an internal Spring Boot flavor, or Foundry trying to recognize an agent project, your only real option is to skip our detection entirely and build your own init command. Same failure mode as the defaults issue. The only way to participate in init is to replace it.
What I think we want is detection contributed through the same InitProvider capability, layered so that the more specific detector wins.
MyCompanySpringBootoverSpringBootoverJavaover whatever core does.A few things that matter in the design:
java," the ordering falls out of the chain and nobody has to guess whether they're priority 40 or 60.DependencyandDatabaseDepvalues. Someone else's detector needs to be able to report something we've never heard of, which probably means the result is a service or resource shape rather than an enum member.The thing I'm most worried about is two extensions both claiming the same directory with neither one refining the other. We need a defined answer for that (and probably a way for the user to pin the winner in
azure.yamlso it stays pinned), otherwise which extensions you happen to have installed changes what your project is.