English | 中文
A lightweight CLI for scaffolding projects from remote template registries.
- Create projects from a template registry hosted on GitHub.
- Support both direct command mode and interactive TUI mode.
- Resolve template versions with simple rules:
latest->mainv*-> match an existing remote branch (for examplev1orrelease/v1).
- Support template subdirectory extraction (
path) via sparse checkout. - Support project-name replacement rules defined in
templates.yaml. - Support root
.templatefile placeholder replacement and automatic rename. - Support multi-registry aliases in user config.
- Support default GitHub token from CLI config.
- Go 1.22+ (for local build)
- Git (required at runtime for template cloning)
go build -o siiway .Single-platform build:
./scripts/build/build.shMulti-platform build:
./scripts/build/build-all.shOutput binaries are generated in bin/ by default.
Windows (PowerShell):
irm https://sh.wss.moe/cli?shell=ps1 | iexLinux / macOS:
curl -fsSL https://sh.wss.moe/cli?shell=sh | shPin a version:
curl -fsSL https://sh.wss.moe/cli | SIIWAY_VERSION=v1.0.0 shThe install script fetches binaries from GitHub Releases.
siiway newThis starts a TUI flow:
- Select template
- Input version
- Input project name
- Confirm and create
siiway new <template_name>@<version> <project_name>Example:
siiway new python-service@latest my-python-servicesiiway run <action> [args...] [-- options...]List available run actions from the effective configuration:
siiway run --list
siiway run -lThe run command loads subcommand templates from two sources:
- Global config:
~/.config/siiway/config.yaml - Project config:
.siiway.yamlin current working directory (higher priority)
You can set language in .siiway.yaml to force the current project language. When set, CLI skips auto-detection and can run non-built-in project types as long as languages.<language>.run.* is configured.
Config path: languages.<language>.run.<action>
Supported placeholders:
{args}(alias:{arguments}){options}
If placeholders are omitted in a run template, CLI appends args/options to the end automatically.
Example:
siiway run add typescript -- --cleanWith:
languages:
node:
run:
add: bun add {arguments} {options}Final command:
bun add typescript --cleansiiway version [language] <version> [-- options...]List available language version configuration:
siiway version --list
siiway version -lConfiguration path (same language-structured style):
languages.<language>.version.backendlanguages.<language>.version.use
Supported built-in backends:
uv(default template:uv python pin {version})nvm(default template:nvm install {version} && nvm use {version})
You can also provide a custom command template via languages.<language>.version.use.
Version placeholders:
{version}{options}
Example config:
language: node
languages:
python:
version:
backend: uv
node:
version:
backend: nvmExample:
siiway version 20With template replacement values:
siiway new python-service@latest my-python-service \
--pm uv \
--project-version 0.1.0 \
--project-author "Your Name" \
--project-description "My project"After project creation, the CLI scans all files ending with .template in the generated project root, replaces built-in placeholders, then renames files by removing the .template suffix.
Built-in placeholders:
{pm}{sw-version}{project-name}{project-version}{project-author}{project-description}
GitHub token priority (high to low):
--tokenflagGITHUB_TOKENenvironment variablegithub_tokenin CLI config
Example:
siiway new python-service@latest my-service --token <your_token>Show current config:
siiway config showSet value by key:
siiway config set <key_name> <value>Reset to defaults:
siiway config resettoken(alias ofgithub_token)github_tokencurrent_registryregistries.<alias>.ownerregistries.<alias>.reporegistries.<alias>.refregistries.<alias>.pathregistries.<alias>.source(format:owner/repo)
Create/update a custom registry alias named internal:
siiway config set registries.internal.source your-org/cli-templates
siiway config set registries.internal.ref main
siiway config set registries.internal.path templates.yaml
siiway config set current_registry internalSet default GitHub token:
siiway config set github_token <your_token>A minimal template entry:
- name: python-service
description: Python starter project
repo_url: https://github.com/your-org/python-template
branch: main
path: templateYou can define regex replacement rules that run after cloning.
Option A: shorthand (replace.project_name)
- name: python-service
repo_url: https://github.com/your-org/python-template
replace:
project_name: pyproject.toml:siiway-python-templateMeaning:
- File:
pyproject.toml - Regex pattern:
siiway-python-template - Replacement: new project name
Option B: explicit rules (project_name_regex_rules)
- name: python-service
repo_url: https://github.com/your-org/python-template
project_name_regex_rules:
- file: pyproject.toml
pattern: siiway-python-template
replacement: "{{project_name}}"
- file_pattern: "**/*.md"
pattern: siiway-python-template
replacement: "{{project_name}}"Rule fields:
file: target one file (relative path in generated project)file_pattern: target multiple files by globpattern: regex to matchreplacement: replacement text ({{project_name}}is supported)
GitHub Actions workflow builds binaries for:
- linux/amd64
- linux/arm64
- darwin/amd64
- darwin/arm64
- windows/amd64
- windows/arm64
Artifacts are uploaded per platform by the workflow.
GitHub Release workflow file: .github/workflows/release.yml
- Push tag
v*(for examplev1.0.0) to build all binaries and publish release assets. - You can also trigger the workflow manually with input
tag.
- If metadata fetch fails, verify registry settings:
owner,repo,ref,path
- If cloning private repositories fails:
- Provide a valid token with required repo access.
- If branch resolution for
v*fails:- Ensure matching remote branch exists.
Licensed under the MIT License. See LICENSE.