@stackonward/cli
v1.7.0
Published
StackOnward CLI for creating projects and installing reusable components and snippets
Maintainers
Readme
@stackonward/cli
@stackonward/cli 是 StackOnward 的唯一公共命令入口。它把项目模板、可安装
源、分析制品、Apple 交付和部署生命周期放在同一个可审计的命令树下;领域实现
在 src/ 中按 owner 分层,发布后只读取 npm 包内的 dist/resources。
CLI 不承载云厂商控制面、产品业务逻辑或长期运行的服务器 agent。它编排已经 声明的适配器,并以结构化 JSON、稳定退出码和 receipt 作为自动化边界。
运行要求
- Node.js 20 或更高版本(构建仓库本身使用 Node.js 22.22+)
- 生成
go-backend时需要 Go 工具链 - Apple 命令只在对应 scope 需要时要求 macOS、Xcode、Fastlane 和 App Store Connect 凭证
- 部署命令按所选 target 需要 Docker、Compose、OpenSSH、Nginx 或 OCI registry
pnpm dlx @stackonward/cli --help
pnpm add --global @stackonward/cli
stackonward --version命令树
stackonward
├── init [name]
├── add [items...]
├── list [templates|components|snippets]
├── analytics
│ ├── schema
│ └── generate
├── apple
│ ├── schema | init | import-assets
│ ├── status | export | handoff
│ ├── preflight | plan | apply | verify
│ └── ...(按 scope 的计划/执行命令)
└── deploy
├── init | validate
├── build | publish
├── release | verify | rollback | reconcile
└── provision
├── validate | plan | apply | verify | reconcilesrc/index.ts 只负责注册顶层命令;命令适配器位于 src/commands,部署状态机
位于 src/deploy,平台资源配置位于 src/provision,Apple 和 analytics 分别
拥有自己的 contracts、registry、adapter 和 receipt。不要按产品或云厂商复制一份
CLI;新增 provider 应注册 adapter,而不是改写 coordinator。
项目模板与 registry
stackonward list templates
stackonward init example-site --template nuxt --yes
stackonward init example-api --template go-backend \
--module example.com/acme/example-api --yes
stackonward list components
stackonward add button
stackonward add --snippet useAsync
stackonward add --all --component初始化只接受空目录,不会把已有产品当成升级目标。模板、隐藏规则文件、依赖
闭包和二进制资源由 registry 与 copyTemplate 共同拥有;安装后的组件和 snippet
归产品仓库所有。npm 包中不保留源码 checkout 路径。
Analytics 制品
分析配置通过 provider registry 生成可审查文件,不会自动登录或发布到第三方账号:
stackonward analytics schema --provider google-tag-manager
stackonward analytics generate \
--provider google-tag-manager \
--config analytics.google.json \
--out gtm.container.json输出文件已存在时必须显式传 --overwrite。配置和 provider 凭证不写入公共包或
生成产物。
Apple 交付
Apple 交付采用 manifest → preflight → signed plan → apply → verify。计划绑定 Bundle ID、账号指纹、scope、intent、输入摘要和观测到的远端状态;未知写入结果 只能 reconcile,不能盲目重试。
stackonward apple schema
stackonward apple init ./apple-delivery \
--bundle-id com.example.app --name "Example App"
stackonward apple preflight --manifest ./apple-delivery/app.json \
--scope metadata --offline
stackonward apple plan --manifest ./apple-delivery/app.json \
--scope metadata --account ./account.json --out ./metadata.plan.json
stackonward apple apply --manifest ./apple-delivery/app.json \
--scope metadata --account ./account.json --plan ./metadata.plan.json --yes
stackonward apple verify --manifest ./apple-delivery/app.json \
--scope metadata --account ./account.json可用 scope 为 setup、native、metadata、assets、catalog、pricing、
signing、build、upload、testflight、review 和 release;status、
export、handoff 为只读检查或交接。
部署生命周期
应用在仓库根目录提供不含密钥的 deploy.config.json。Profile 决定构建形态,
target 决定传输边界,rollout 决定切流方式,lifecycle hooks 仍由产品仓库拥有。
构建时公共环境变量按 .env、.env.<environment>、CI deployVariables[environment]
的顺序合并,后者覆盖前者。Docker registry 登录写入临时 DOCKER_CONFIG,不会改写
宿主机 credential helper。
发布顺序固定为:
validate → build → publish immutable artifact → stage
→ preflight/migrate → activate traffic → verify → retain → receipt初始化与校验
stackonward deploy init --profile nuxt-node \
--target compose-host --rollout blue-green
stackonward deploy validate \
--config deploy.config.json --environment production构建、发布与蓝绿发布
REVISION="$(git rev-parse HEAD)"
stackonward deploy build \
--config deploy.config.json --environment production \
--revision "$REVISION" --output .stackonward/build.json
stackonward deploy publish \
--config deploy.config.json --environment production \
--artifact .stackonward/build.json \
--output .stackonward/published.json
stackonward deploy release \
--config deploy.config.json --environment production \
--artifact .stackonward/published.json
stackonward deploy verify \
--config deploy.config.json --environment production \
--release <release-id>只有成功观测到新版本才会更新 current/previous。健康检查失败会进入回滚
路径;远端效果不可观测时退出码为 7,必须先执行:
stackonward deploy reconcile \
--config deploy.config.json --environment production
stackonward deploy rollback \
--config deploy.config.json --environment production \
--release <known-good-release-id>OneDev 平台资源
OneDev 是第一个 provisioning provider,资源配置、secret lease、签名计划和
receipt 由 CLI 统一管理,协议细节位于 @stackonward/onedev-provisioning:
stackonward deploy provision validate --provider onedev \
--config provision.config.json --secrets provision.secrets.json --json
stackonward deploy provision plan --intent converge --provider onedev \
--config provision.config.json --secrets provision.secrets.json \
--attestation provision.attestation.json --credential-file bootstrap.token \
--out converge.plan.json --json
stackonward deploy provision apply --plan converge.plan.json \
--config provision.config.json --secrets provision.secrets.json \
--attestation provision.attestation.json --credential-file bootstrap.token \
--yes --json
stackonward deploy provision verify --provider onedev \
--config provision.config.json --secrets provision.secrets.json \
--credential-file bootstrap.token --jsonBootstrap 凭证只能来自一个来源:STACKONWARD_PROVISION_TOKEN、
--credential-file 或 --token-stdin。计划、state、receipt、私钥和 secret
JSON 均为 owner-only 文件,不得提交;secret 不会出现在日志、诊断或子进程参数中。
退出码与机器输出
所有部署命令在 stdout 输出一个 JSON 成功结果,在 stderr 输出一个安全的 JSON 失败 结果。稳定退出码如下:
| Code | 含义 |
| ----- | ----------------------------------------------- |
| 0 | 成功并已完成声明的阶段 |
| 2 | 本地参数、路径或配置无效 |
| 3 | provider/transport 前置条件不可用 |
| 4 | 计划过期、所有权或并发冲突 |
| 5 | 已知失败效果 |
| 7 | 未知效果或 blocked 状态,只允许观测与 reconcile |
| 130 | 收到取消信号 |
“文件已写入”“镜像已推送”“进程正在运行”都不是完成证明;receipt 必须包含 不可变身份、状态转换和健康结果。
OCI 构建以 Buildx 的 containerimage.digest 作为可拉取镜像身份。发布后,CLI 用
Registry 的 Manifest digest 核对同一身份,并写入 repository@digest 引用。
containerimage.config.digest 只是镜像配置 blob 的描述,不是 pull 引用。
CLI 目录与扩展边界
packages/cli/
├── src/index.ts # 唯一入口与顶层注册
├── src/commands/ # Commander 注册与按领域拆分的薄适配层
│ └── deploy/ # operations、runtime、I/O、guard、provision adapter
├── src/analytics/ # provider artifact generator registry
├── src/apple/ # Apple contract、plan、resource、执行状态
├── src/deploy/ # profile、target、rollout、lifecycle、receipt
├── src/provision/ # provider-neutral plan/state/secret/sink 协调
├── src/utils/ # 文件、registry、项目与进程边界
├── resources/ # 发布时复制到 dist/resources 的完整资源
└── scripts/check-package.mjs # 包外 tarball 安装与运行验证一个可执行文件是稳定的产品边界:共享认证、配置、退出码、日志脱敏、锁和
receipt,避免多个 CLI 产生不同语义。只有当某个能力需要独立运行时(例如长期
驻留在服务器上的 agent、不同权限边界或独立发布周期)才建立独立包/二进制;它
必须通过明确的 protocol adapter 与本 CLI 的声明和 receipt 对接,而不是把运行时
实现复制到 src/commands。
新增功能的顺序是:先在领域 owner 定义 contract 和输入 schema,再实现 adapter、 registry 注册、command wiring、fake/real boundary 测试和 packed artifact 检查。 跨 provider 增长只新增 provider 目录与配置项,不修改已有 coordinator 的语义。
开发与发布检查
pnpm --filter @stackonward/cli typecheck
pnpm --filter @stackonward/cli test
pnpm --filter @stackonward/cli build
pnpm --filter @stackonward/cli check:packagecheck:package 会打包 npm tarball,在 workspace 外安装并执行 discovery、模板
生成、provider lifecycle 和部署资源检查。它是资源或 CLI 行为交付的必要证据;
版本与 Changeset 通过仓库发布流程管理,CLI 本身不会隐式发布 npm 包或第三方配置。
参考
- Node.js package entry points
- npm
binpackage field - Commander subcommands and async parsing
- GitHub CLI extension boundary
License
MIT
