Recommend similar templates when an azd template repository is archived
- Dominant language
- Go
- Stars
- 569
- Forks
- 364
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 136
Description
## Context
Issue #9540 and PR #9541 introduce the first safeguard for archived GitHub template repositories: show a warning and require an explicit `[y/N]` confirmation that defaults to **No** before cloning.
A richer follow-up experience should help users replace an archived template rather than only stopping initialization. Because this requires template inspection, multiple discovery sources, GitHub metadata enrichment, ranking, and additional interactive UX, it should be implemented separately from the initial archive warning.
## Proposed user experience
When `azd init --template ` detects an archived repository, replace the yes/no confirmation with a select prompt:
1. **Help me find a similar template**
2. **Stop and cancel** — default selection and equivalent to the current No response
3. **Use the template anyway** — equivalent to the current Yes response
`--no-prompt` must preserve the safe behavior introduced by #9540: stop before cloning and return an actionable error. Recommendation discovery must not silently choose or initialize another template in non-interactive mode.
If the user requests recommendations, show at most five matching templates. Selecting a recommendation should resume the normal `azd init` flow with the selected template. If no suitable templates are found, explain that outcome and return to the archived-template choices with **Stop and cancel** selected.
## Reusable architecture
Implement recommendation discovery as reusable template functionality rather than embedding it in `azd init`. The same engine should later support a command such as:
```shell
azd template similar
```
Suggested components:
- **Template inspector** — fetches and parses a template's `azure.yaml` without cloning it.
- **Candidate providers** — independently retrieve candidates from the AI Apps search endpoint and registered azd template sources.
- **Candidate normalizer** — canonicalizes repository identities and removes duplicates.
- **Ranker** — applies deterministic compatibility and popularity rules.
- **Finder/orchestrator** — coordinates inspection, discovery, enrichment, and ranking without depending on console input.
- **Command UX adapters** — `azd init` and future `azd template` commands own prompts and rendering.
The recommendation engine should accept interfaces for remote content and repository metadata so it can be tested without live network calls.
## Phase 1: Gather template information
1. Fetch the source repository's `azure.yaml` before cloning, using the repository's default branch and the existing GitHub host/token rules.
2. Parse it with the existing `project.Parse` implementation.
3. Build a normalized template profile containing:
- unique service languages from `services.*.language`
- unique hosting targets from `services.*.host`
- canonical repository identity
4. Generalize the repository metadata lookup used by #9541 so recommendation code can obtain archive state, default branch, stars, and forks without duplicating GitHub API logic.
5. Return clear diagnostics for a missing, inaccessible, or invalid `azure.yaml`.
## Phase 2: Get similar templates
1. Construct a URL-encoded search query from the source template's languages and hosts.
2. Query the public AI Apps search endpoint:
`https://lp6qsotirqelc-function-app.azurewebsites.net/api/ai-apps-search?search={query}`
3. Parse the result array, validate repository sources, normalize repository URLs, and deduplicate results. The endpoint can return the same repository more than once.
4. If the AI Apps query returns more than five unique valid candidates, use only those candidates and skip registered azd sources.
5. If it returns five or fewer, call the existing `TemplateManager.ListTemplates` implementation used by `azd template list`, then union those templates with the AI Apps results.
6. Exclude the original repository, inaccessible repositories, and archived recommendation candidates.
7. Inspect candidate `azure.yaml` files as needed so compatibility does not depend on optional or inconsistent gallery tags.
8. Use bounded concurrency and request caching to avoid serial or duplicate GitHub requests.
Provider failures should be handled independently when possible: one unavailable source should not discard valid results from another source. Cancellation from the command context must still stop the operation.
## Phase 3: Filter, rank, and present the top five
1. Keep templates whose parsed service languages match the source template's languages.
2. Enrich surviving GitHub repositories with star and fork counts. The AI Apps response does not currently provide these values.
3. Sort deterministically by:
- stars descending
- forks descending
- canonical repository URL for ties
4. Return at most five candidates.
5. Display candidates with enough context to make a choice: template title/name, repository, languages, hosts, stars, and forks.
Multi-language matching semantics should be covered explicitly by tests. The initial implementation should require the candidate to cover the source template's language set rather than treating an unrelated single-language overlap as equivalent.
## Acceptance criteria
- [ ] Archived-template UX uses the three-option select prompt, defaulting to **Stop and cancel**.
- [ ] Existing cancel, continue, and `--no-prompt` safety behavior remains intact.
- [ ] `azure.yaml` is fetched and parsed without cloning the source template.
- [ ] Languages and hosts are extracted from all configured services.
- [ ] AI Apps results are normalized and deduplicated.
- [ ] Registered sources are included only when the AI Apps search produces five or fewer unique valid candidates.
- [ ] Registered templates are obtained through the same reusable implementation as `azd template list`.
- [ ] The original and archived repositories are excluded from recommendations.
- [ ] Candidates are filtered by language compatibility and ranked by stars and forks.
- [ ] No more than five recommendations are displayed.
- [ ] The engine is reusable by a future `azd template similar` command.
- [ ] Tests cover provider failures, cancellation, duplicate repositories, the five-result cutoff, multi-service templates, language filtering, deterministic ranking, no-result behavior, and all prompt outcomes.
- [ ] Any new telemetry fields/events are added with the required telemetry documentation, coverage tests, and privacy classification.
Contributor guide
Assessment
This issue has not been assessed yet.