feat(stack): add support for container templates - #2049
Open
martin-helmich wants to merge 13 commits into
Open
Conversation
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
marked this pull request as ready for review
July 29, 2026 09:19
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.
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 itsuserInputs, and calls the create-stack API withtemplateConfig. Template inputs are supplied non-interactively with repeatable--input name=valueflags; any required input without a value or default is prompted for interactively. Supports-c/--update-contextto point the CLI context at the new stack.mw stack template list(aliasstack template ls) — lists available container templates so users can discover template IDs. Filterable with--categoryand--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 instack create.Changed
mw stack list— now shows aTemplatecolumn with the originatingtemplateId(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-volumesadditionally removes its volumes. Any other stack is removed with a single delete-stack call, replacing the previousnot implementederror.mw stack deploy --from-template— deprecated in favour ofmw 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,containerandvolumecommands 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 runmw volume createmw volume rmAll three now take an optional
-s/--stack-idflag, resolved by the newwithStackIdOrDefault()helper in the order: explicit flag → CLI context → the project's default stack. Existing invocations keep working unchanged.The remaining
containercommands resolve the stack from the container itself (withContainerAndStackId, which looks the container up project-wide and returns its actualstackId), 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.ts—collectTemplateUserInputs, shared bystack createandstack 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 holdsisSensitiveInput(), which reads thevalidationSchemadescribed above and tolerates a missing or malformed schema.src/lib/resources/stack/flags.ts—optionalStackFlags/withStackIdOrDefault()for the default-stack fallback described above.Notes
templatesubtopic ofstack, registered inpackage.json, matching the singular naming used by all other topics.--with-volumesonstack rmnow 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/are left to the existing re-generation workflow rather than being regenerated by hand.🤖 Generated with Claude Code