Skip to content

template: improve template metadata for discovery and clarity - #119

Merged
nozaq merged 5 commits into
mainfrom
claude/platforms-field-spec-fix-9hhpdm
Aug 1, 2026
Merged

template: improve template metadata for discovery and clarity#119
nozaq merged 5 commits into
mainfrom
claude/platforms-field-spec-fix-9hhpdm

Conversation

@nozaq

@nozaq nozaq commented Aug 1, 2026

Copy link
Copy Markdown
Member

Summary

Five metadata fixes, all about information a user sees while searching for, browsing, applying, and then opening a template.

1. platforms now lists languages, not the OS

The Dev Container Template specification defines platforms as "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"].

Template platforms Version
golang ["Go"] 1.2.6 → 1.2.7
node ["Node.js"] 1.1.1 → 1.1.2
uv ["Python"] 1.0.6 → 1.0.7
rustup ["Rust"] 1.4.1 → 1.4.2
zig ["Zig"] 1.2.6 → 1.2.7
terraform ["Terraform"] 1.2.5 → 1.2.6
bun ["Bun", "JavaScript", "TypeScript"] 1.0.5 → 1.0.6
deno ["Deno", "JavaScript", "TypeScript"] 1.0.1 → 1.0.2
debian ["Any"] 1.2.6 → 1.2.7
mise ["Any"] 1.3.2 → 1.3.3

debian and mise are not tied to a single toolchain, so they use Any. One version bump per template covers every change in this pull request.

2. imageVariant descriptions 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 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.

-"description": "Go version and Debian version",
+"description": "Go and Debian version (trixie = Debian 13, bookworm = Debian 12). Other published tags can be entered.",

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, zig
  • Debian version (trixie = Debian 13, bookworm = Debian 12). Other published tags can be entered.debian, mise, rustup, uv

A description cannot hold the tag-list URL within a sane length, so each template also gains an Image Variants section in NOTES.md (and the generated README.md) that links to the base image's published tags and repeats the codename mapping — keeping each template page self-contained.

3. keywords optimized as search terms

keywords are "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.

  • All ten templates gain 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 via terraform.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.

-Security-focused mise dev container for multiple runtimes, with rebuild-friendly caches.
+Security-focused mise dev container for multiple runtimes, with cached tool installs.
-Security-focused Node.js dev container for JS/TS with hardened, non-root defaults.
+Security-focused Node.js dev container for JS/TS with non-root defaults and Corepack.
-Security-focused Terraform dev container with terraform-ls and rebuild-friendly caching.
+Security-focused Terraform dev container with terraform-ls and a plugin cache volume.
-Security-focused minimal Debian base for any stack, with hardened container defaults.
+Security-focused minimal Debian base for any stack, with hardened, non-root defaults.

The shared Security-focused prefix 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.md records that reasoning so the prefix is not dropped by accident.

Conventions and CI

  • AGENTS.md gains a Template Metadata section recording the platforms rule, the two description forms, the "proposals is a shortlist, not an enum" rule, the name-matching rule, the keyword convention, the description-prefix rationale, and the version-bump expectation. Image Variants is added to the documented NOTES.md section order.
  • The CI description-length job now checks option descriptions as well.

Note on the length limit

The imageVariant wording does not fit the existing 88-character budget — the longest, terraform, is 109 characters — so option descriptions are capped at 120 while the template description stays at 88. The two render in different places: the template description is 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 shortening bookworm = Debian 12 to bookworm = 12 and the trailing sentence to other tags accepted).

Verification

  • jq parses every devcontainer-template.json; the length check passes locally (every template description is 83–88 characters) and fails as expected on a 121-character option description.
  • Every NOTES.md body is still embedded verbatim in its generated README.md, and the README.md options tables and description lines carry the new text.
  • Published tag links were checked against GHCR; the per-template examples of "narrower tags" match what each image actually publishes (debian publishes only codename and date-stamped tags, so its wording differs).
  • Each added keyword was checked against the template's own devcontainer.json — the Ruff extension, the terraform-ls setting, and the Corepack cache mount are all present.
  • All ten templates now report an identical name in devcontainer-template.json and .devcontainer/devcontainer.json.

claude added 2 commits August 1, 2026 13:21
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
@nozaq nozaq changed the title template: declare supported languages in the platforms field template: fix the platforms field and make imageVariant descriptions decision-ready Aug 1, 2026
`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
@nozaq nozaq changed the title template: fix the platforms field and make imageVariant descriptions decision-ready template: fix platforms, imageVariant descriptions, and keywords Aug 1, 2026
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
@nozaq nozaq changed the title template: fix platforms, imageVariant descriptions, and keywords template: fix platforms, imageVariant descriptions, keywords, and the uv container name Aug 1, 2026
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
@nozaq nozaq changed the title template: fix platforms, imageVariant descriptions, keywords, and the uv container name template: improve template metadata for discovery and clarity Aug 1, 2026
@nozaq
nozaq merged commit 457ba15 into main Aug 1, 2026
60 checks passed
@nozaq
nozaq deleted the claude/platforms-field-spec-fix-9hhpdm branch August 1, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants