Skip to content

feat(stack): add support for container templates - #2049

Open
martin-helmich wants to merge 13 commits into
masterfrom
feat/container-templates
Open

feat(stack): add support for container templates#2049
martin-helmich wants to merge 13 commits into
masterfrom
feat/container-templates

Conversation

@martin-helmich

@martin-helmich martin-helmich commented Jul 29, 2026

Copy link
Copy Markdown
Member

Implements #2048: support for container templates in mw stack.

Commands

New

  • mw stack create — creates a stack, either empty or from a container template via --from-template <template-id>. Fetches the template, resolves its userInputs, and calls the create-stack API with templateConfig. Template inputs are supplied non-interactively with repeatable --input name=value flags; any required input without a value or default is prompted for interactively. Supports -c/--update-context to point the CLI context at the new stack.
  • mw stack template list (alias stack template ls) — lists available container templates so users can discover template IDs. Filterable with --category and --type component|standalone, which map to the corresponding query parameters (omitted from the request when unset).
  • mw stack template install <template-id> — installs a template into an existing stack via the add-template-component operation, rather than creating a new stack. Stack comes from the CLI context or --stack-id; user inputs are resolved exactly as in stack create.

Changed

  • mw stack list — now shows a Template column with the originating templateId (or "no template").
  • mw stack rm — now works for template and non-template stacks alike. A project's default stack (where the stack ID equals the project ID) still cannot be removed and is emptied instead, by declaring it without services or volumes; --with-volumes additionally removes its volumes. Any other stack is removed with a single delete-stack call, replacing the previous not implemented error.
  • mw stack deploy --from-template — deprecated in favour of mw stack create --from-template; the flag now emits a deprecation notice pointing there (it used an older, GitHub-based template mechanism).

Removal of default-stack assumptions

Now that stacks other than the project's default one are first-class, the stack, container and volume commands were swept for logic that only ever worked against the default stack. Three commands derived the stack ID directly from the project ID (const stackId = projectId) and so could not address any other stack:

  • mw container run
  • mw volume create
  • mw volume rm

All three now take an optional -s/--stack-id flag, resolved by the new withStackIdOrDefault() helper in the order: explicit flag → CLI context → the project's default stack. Existing invocations keep working unchanged.

The remaining container commands resolve the stack from the container itself (withContainerAndStackId, which looks the container up project-wide and returns its actual stackId), so they already worked for any stack.

Masked input for sensitive values

Templates mark sensitive inputs with a validation schema of format password. Prompts for those inputs are now masked — the value is not echoed while typing and shows as [secret] in the process summary instead of in clear text.

Supporting code + tests

  • src/lib/resources/stack/template-inputs.tscollectTemplateUserInputs, shared by stack create and stack template install. Value precedence: explicitly provided → template default → interactive prompt. Optional inputs without a value are omitted so the API fills them from template defaults; unknown provided inputs emit a warning. Also holds isSensitiveInput(), which reads the validationSchema described above and tolerates a missing or malformed schema.
  • src/lib/resources/stack/flags.tsoptionalStackFlags / withStackIdOrDefault() for the default-stack fallback described above.
  • Unit tests for the input-resolution logic, the masking behaviour and the sensitivity detection.

Notes

  • The new commands live under a template subtopic of stack, registered in package.json, matching the singular naming used by all other topics.
  • --with-volumes on stack rm now only has an effect on the default stack, since a regular stack's volumes are removed together with the stack; this is called out in the flag description.
  • Docs under docs/ are left to the existing re-generation workflow rather than being regenerated by hand.

🤖 Generated with Claude Code

martin-helmich and others added 13 commits July 29, 2026 09:43
Add `mw stack create`, which creates a container stack either empty or
from a container template via the create-stack API's `templateConfig`.
Template user inputs can be supplied non-interactively with repeatable
`--input name=value` flags; required inputs without a value or default
are prompted for interactively.

Also:
- add `mw stack list-templates` to discover available templates and IDs
- show the originating template in `mw stack list` (`templateId`)
- make `mw stack rm` work for any stack (template or not) by using the
  dedicated delete-stack API instead of the previous "empty the default
  stack" workaround
- deprecate `mw stack deploy --from-template` in favour of
  `mw stack create --from-template`

Closes #2048

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…filters

Rename `mw stack list-templates` to `mw stack templates list`, using a new
"templates" subtopic under "stack" (alias: `stack templates ls`).

Add `--category` and `--type` flags to filter the listing; both map to the
corresponding query parameters of the list-templates API and are omitted
from the request when unset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A project's default stack (identified by its ID matching the project ID)
cannot be removed, so it is emptied instead by declaring it without any
services or volumes; "--with-volumes" additionally removes its volumes.

Any other stack is removed with a single delete-stack call, without the
preceding declare that the previous implementation performed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… a stack

Adds a command wrapping the add-template-component API operation, which
adds a template's services and volumes to an already existing stack
instead of creating a new stack for it.

The stack is taken from the CLI context or --stack-id; template user
inputs are resolved with the same precedence as "stack create"
(provided -> template default -> interactive prompt).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All other topics use a singular name, so "stack templates list" and
"stack templates install" become "stack template list" and
"stack template install" (alias: "stack template ls").

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
"container run", "volume create" and "volume rm" derived the stack ID
from the project ID, so they could only ever address a project's default
stack. They now accept an optional --stack-id flag, resolved via the new
withStackIdOrDefault() helper: explicit flag, then the CLI context, and
only then the project's default stack. Existing invocations therefore
keep working unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Values whose name suggests a password, secret, token, API key, private
key or credential are now prompted for with a masked input, so they are
neither echoed while typing nor shown in the process summary.

The container template API does not mark user inputs as sensitive, so
this is based on a heuristic over the input name. The same heuristic is
applied to "__PROMPT__" environment variables in the compose-based
deployment path, which previously always prompted unmasked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Templates mark sensitive inputs with a validation schema of format
"password", so use that instead of guessing from the input name.

This replaces the name-based heuristic introduced in the previous commit
and reverts the unrelated change to the "__PROMPT__" environment
variable path, which has no validation schema to go by.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@martin-helmich
martin-helmich marked this pull request as ready for review July 29, 2026 09:19
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.

1 participant