template: improve template metadata for discovery and clarity - #119
Merged
Conversation
The Dev Container Template specification defines `platforms` as the languages and platforms supported by the template, not the container OS. All ten templates declared `["linux"]`, which carries no signal for filtering the template list. Set each template's `platforms` to the toolchain it provides, matching upstream conventions (e.g. the upstream Go template uses `["Go"]`), and bump each template version so the metadata change is published. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XykZSuEV18wLzbS6yhkw4a
The `imageVariant` descriptions restated the value format ("Go version and
Debian version") instead of helping a user pick a value. They left three
questions unanswered: which Debian release `trixie` and `bookworm` are,
whether `proposals` is a closed list (it is not — the field is not an
`enum`), and where the published tags can be found.
- Rewrite every option description to map the Debian codenames and state
that other published tags are accepted, in one of two fixed forms
depending on whether the tag pins a toolchain version.
- Add an `Image Variants` section to each NOTES.md/README.md linking to
the base image's published tags, since the description cannot hold a URL.
- Document both conventions, along with the `platforms` rule, in AGENTS.md.
- Extend the CI description-length check to option descriptions, capped at
120 characters (the template `description` stays at 88).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XykZSuEV18wLzbS6yhkw4a
`keywords` are "strings relevant to a user that would search for this Template", but the hardening that distinguishes these templates was not searchable: no template listed a single security-related term. - Add `security`, `hardened`, and `non-root` to all ten templates. - node: add `corepack`, `pnpm`, and `yarn` — the image ships no npm, so Corepack is how a user drives package managers here. - uv: add `astral` and `ruff`, matching the bundled Ruff extension. - terraform: add `terraform-ls`, which the template configures. OpenTofu is deliberately left out since it is not shipped. - Record the convention in AGENTS.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XykZSuEV18wLzbS6yhkw4a
The uv template is listed as "Python (uv)" but generated a container named "uv", so the editor window title disagreed with the entry the user picked from the template list. Every other template already matches. Rename the container to "Python (uv)" and use the same label in the repository README's template table and its example output, then record the rule in AGENTS.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XykZSuEV18wLzbS6yhkw4a
Four descriptions filled their 88-character budget with wording every
template shares ("rebuild-friendly caches", "hardened container defaults"),
leaving nothing that identifies the template itself.
- mise: name what the cache holds — tool installs.
- node: surface Corepack, which is how package managers are driven since
the image ships no npm.
- terraform: name the plugin cache volume.
- debian: state the non-root default, matching the other templates.
The shared `Security-focused` prefix is kept: templates are compared
against other templates for the same toolchain, where the names are
identical and the hardening is the reason to choose this one. AGENTS.md
records that reasoning so the prefix is not dropped by accident.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XykZSuEV18wLzbS6yhkw4a
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five metadata fixes, all about information a user sees while searching for, browsing, applying, and then opening a template.
1.
platformsnow lists languages, not the OSThe Dev Container Template specification defines
platformsas "Languages and platforms supported by the Template" — not the container OS. All ten templates declared["linux"], so the field carried no signal for filtering the template list. Upstream templates use values like["Go"].platformsgolang["Go"]node["Node.js"]uv["Python"]rustup["Rust"]zig["Zig"]terraform["Terraform"]bun["Bun", "JavaScript", "TypeScript"]deno["Deno", "JavaScript", "TypeScript"]debian["Any"]mise["Any"]debianandmiseare not tied to a single toolchain, so they useAny. One version bump per template covers every change in this pull request.2.
imageVariantdescriptions answer "which value do I pick?"The old descriptions restated the value format ("Go version and Debian version") and left three questions unanswered: which Debian release
trixieandbookwormare, whetherproposalsis a closed list (it is not — the field is not anenum), and where the published tags can be found.Two fixed forms are used, depending on whether the tag pins a toolchain version:
<Toolchain> and Debian version (trixie = Debian 13, bookworm = Debian 12). Other published tags can be entered.—bun,deno,golang,node,terraform,zigDebian version (trixie = Debian 13, bookworm = Debian 12). Other published tags can be entered.—debian,mise,rustup,uvA description cannot hold the tag-list URL within a sane length, so each template also gains an
Image Variantssection inNOTES.md(and the generatedREADME.md) that links to the base image's published tags and repeats the codename mapping — keeping each template page self-contained.3.
keywordsoptimized as search termskeywordsare "strings relevant to a user that would search for this Template", yet the hardening that distinguishes this repository was not searchable — no template listed a single security-related term.security,hardened,non-root.node:corepack,pnpm,yarn— the image ships no npm, so Corepack is how a user drives package managers here.uv:astral,ruff— the template bundles the Ruff extension and sets it as the Python formatter.terraform:terraform-ls— configured viaterraform.languageServer.path. OpenTofu is deliberately left out since it is not shipped.4. The uv container name matches the template name
The uv template is listed as Python (uv) but generated
"name": "uv", so the editor window title disagreed with the entry the user picked from the list. Every other template already matches (golang→ Go,rustup→ Rust), so uv was the lone exception.The container is renamed to
Python (uv), and the repository README uses the same label in its template table and in the example output under What You Get.5. Descriptions spend their budget on template-specific detail
Four descriptions filled the 88-character budget with wording every template shares, leaving nothing that identifies the template itself.
The shared
Security-focusedprefix is kept deliberately. Every surface that shows a description — the VS Code template picker, the README table, the registry listing — shows the template name right next to it, so leading with the toolchain would repeat what is already on screen. The prefix earns its place in the case that actually needs a tiebreaker: a user who has already filtered by their stack and is comparing this template against another one with the same name, where the hardening is the reason to pick this one.AGENTS.mdrecords that reasoning so the prefix is not dropped by accident.Conventions and CI
AGENTS.mdgains aTemplate Metadatasection recording theplatformsrule, the two description forms, the "proposalsis a shortlist, not anenum" rule, the name-matching rule, the keyword convention, the description-prefix rationale, and the version-bump expectation.Image Variantsis added to the documentedNOTES.mdsection order.Note on the length limit
The
imageVariantwording does not fit the existing 88-character budget — the longest,terraform, is 109 characters — so option descriptions are capped at 120 while the templatedescriptionstays at 88. The two render in different places: the templatedescriptionis the one-line headline in the template list, while an option description is a table cell in the README and a prompt while applying. If you would rather have a single shared limit, the option descriptions can be tightened to fit 88 instead (roughly, by shorteningbookworm = Debian 12tobookworm = 12and the trailing sentence toother tags accepted).Verification
jqparses everydevcontainer-template.json; the length check passes locally (every template description is 83–88 characters) and fails as expected on a 121-character option description.NOTES.mdbody is still embedded verbatim in its generatedREADME.md, and theREADME.mdoptions tables and description lines carry the new text.debianpublishes only codename and date-stamped tags, so its wording differs).devcontainer.json— the Ruff extension, theterraform-lssetting, and the Corepack cache mount are all present.nameindevcontainer-template.jsonand.devcontainer/devcontainer.json.