package-walter-green

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

A remote development machine, with Walter

基于Walter的远程开发机器

Use this skill to initialize or operate a walter project in the user's current directory. Walter provisions one machine, records it in
~/.ssh/config
so
ssh <profile>
reaches it, and powers it off and on.
使用本技能可在用户当前目录中初始化或操作walter项目。Walter会置备一台机器,将其记录到
~/.ssh/config
中,以便通过
ssh <profile>
连接,并可对机器进行开关机操作。

Requirements

要求

Babashka runs the launcher.
create
and
delete
also need OpenTofu and Ansible.
stop
and
start
need the
oci
CLI and a live session. With
github-account
set, a real
create
also needs
gh
on the workstation — it runs GitHub's device flow as its first action. Provider credentials use
COLORS_PAR_*
variables, except OCI, which uses the profile named in
~/.oci/config
, and S3, which uses OpenTofu's ambient AWS credential chain.
Babashka运行启动器。
create
delete
操作还需要OpenTofu和Ansible。
stop
start
操作需要
oci
CLI以及有效会话。若设置了
github-account
,实际执行
create
时还需要工作站上安装
gh
——它会首先运行GitHub的设备流。提供商凭证使用
COLORS_PAR_*
变量,OCI除外,它使用
~/.oci/config
中指定的配置文件,S3则使用OpenTofu的环境AWS凭证链。

Non-negotiable safety rules

不可妥协的安全规则

  • Never ask the user to paste a secret into chat.
  • Never put API tokens, passwords, private keys or access keys in
    colors.yml
    , in the
    green
    launcher, in shell history, or in generated examples. Every credential arrives through a
    COLORS_PAR_*
    environment variable named after the key it fills. Suggest a gitignored
    .envrc.private
    , never an inline export a shell history records.
  • Public SSH keys are not secrets; private ones are.
    oci-ssh-authorized-keys
    holds the path to a public-key file that OpenTofu reads at plan time — record the path, never inline the contents, and never read a private key. With
    compute-keygen: true
    walter generates and manages
    ~/.ssh/<profile>
    itself; never read or move that file either.
  • With
    github-account
    set, a real
    create
    starts by printing a one-time code and waiting — up to about fifteen minutes — for the user to approve it at https://github.com/login/device. That is the design, not a hang: the workflow is interactive at the beginning only. Relay the code and URL to the user and wait; never try to acquire, read, or echo the token itself.
  • Never set
    COLORS_PAR_PROFILE
    .
    Walter refuses to run when it is set, and suggesting it as a workaround defeats the guard. The profile identifies the project, and the project is the directory. If the user wants a different profile, edit
    colors.yml
    .
  • Do not overwrite an existing
    green
    launcher or
    colors.yml
    without explicit approval. If a project is already valid, operate it rather than regenerating it.
  • Default to
    build
    and
    create --dry-run
    . Run a real
    create
    or
    delete
    only after the user confirms that exact operation.
  • build
    and
    create --dry-run
    are credential-free by design and check no
    COLORS_PAR_*
    at all. A clean dry-run says nothing about whether real provisioning would authenticate; never report it as credential validation.
  • Before
    delete
    , remind the user that a development machine holds uncommitted work and that the boot volume goes with it.
    compute-prevent-destroy
    defaults to
    true
    ; authorize an intentional delete with
    COLORS_PAR_COMPUTE_PREVENT_DESTROY=false
    rather than editing desired state.
  • Never edit anything under
    .colors/
    — it is generated output.
Read references/configuration.md before generating or changing desired state, and before any real
create
or
delete
.
  • 切勿要求用户在聊天中粘贴机密信息。
  • 切勿将API令牌、密码、私钥或访问密钥放入
    colors.yml
    green
    启动器、shell历史记录或生成的示例中。所有凭证都通过与填充密钥对应的
    COLORS_PAR_*
    环境变量传入。建议使用被git忽略的
    .envrc.private
    ,切勿使用会被shell历史记录保存的内联export命令。
  • 公钥不是机密;私钥是。
    oci-ssh-authorized-keys
    存储的是OpenTofu在计划阶段读取的公钥文件的路径——仅记录路径,切勿内联内容,也切勿读取私钥。若设置
    compute-keygen: true
    ,Walter会自行生成并管理
    ~/.ssh/<profile>
    ;同样切勿读取或移动该文件。
  • 若设置了
    github-account
    ,实际执行
    create
    时会先打印一次性代码,然后等待(最多约15分钟)用户在https://github.com/login/device上完成授权。这是设计流程,而非卡顿:仅在开始阶段需要交互。将代码和URL告知用户并等待;切勿尝试获取、读取或回显令牌本身。
  • 切勿设置
    COLORS_PAR_PROFILE
    。当该变量被设置时,Walter会拒绝运行,建议将其作为解决方案会绕过防护机制。配置文件(profile)用于标识项目,而项目对应目录。若用户需要不同的配置文件,请编辑
    colors.yml
  • 未经明确许可,切勿覆盖现有的
    green
    启动器或
    colors.yml
    。若项目已有效,应直接操作而非重新生成。
  • 默认使用
    build
    create --dry-run
    。仅在用户确认具体操作后,才执行实际的
    create
    delete
  • build
    create --dry-run
    设计为无需凭证,完全不检查任何
    COLORS_PAR_*
    变量。成功的试运行并不代表实际置备会通过身份验证;切勿将其报告为凭证验证通过。
  • 执行
    delete
    前,提醒用户开发机器上可能包含未提交的工作,且启动卷会随机器一同销毁。
    compute-prevent-destroy
    默认设为
    true
    ;若要执行有意的删除操作,需设置
    COLORS_PAR_COMPUTE_PREVENT_DESTROY=false
    ,而非编辑预期状态。
  • 切勿编辑
    .colors/
    下的任何内容——这是生成的输出文件。
在生成或修改预期状态,以及执行任何实际的
create
delete
操作前,请阅读references/configuration.md

Commands

命令

sh
./green build              # render .colors/<profile>/ only; contacts nothing
./green create --dry-run   # print the graph; touches nothing
./green create             # provision, and write the ssh config block
./green stop               # power off
./green start              # power on, and refresh the ssh config block
./green delete             # destroy, dropping the ssh block first
-f/--file
overrides the
colors.yml
found by walking up from the working directory.
sh
./green build              # 仅渲染.colors/<profile>/;不连接任何外部服务
./green create --dry-run   # 打印执行图;不修改任何内容
./green create             # 置备机器,并写入ssh配置块
./green stop               # 关机
./green start              # 开机,并刷新ssh配置块
./green delete             # 销毁机器,先移除ssh配置块
-f/--file
参数可覆盖从工作目录向上遍历找到的
colors.yml

Initialize in the current directory

在当前目录初始化

  1. Copy the
    green
    payload beside this file into the project root and
    chmod +x
    it.
  2. Write
    colors.yml
    . Ask for the provider first, then only the keys that provider needs —
    references/configuration.md
    lists them.
  3. Choose a
    profile
    unique to this project
    , conventionally the directory name. It names the work directory, the OpenTofu state keys and the ssh alias. Two projects sharing a profile and a state bucket address the same state, which is how a development machine ends up managing a production server.
  4. Ask whether the machine should have the user's GitHub identity. If so, set
    github-account
    to their login and
    git-email
    to their commit email, and tell them a real
    create
    will start with a one-time device-flow code to approve from a browser. This is required before offering
    emacs-config-repo
    ,
    clone-orgs
    or
    dotfiles-checkout
    — their clones authenticate through it.
  5. Ask whether walter should generate the machine-access ssh keypair (
    compute-keygen: true
    ) or whether the user supplies a provider key as before.
  6. Ask whether the user wants their Emacs configuration on the machine. If so, set
    emacs-config-repo
    to its https git URL (
    git@
    /
    ssh://
    forms are refused) and
    emacs-config-dest
    to where it must live — the default is
    ~/.config/emacs
    , and a configuration expecting another path needs
    --init-directory
    to reach it. Leave both out otherwise; the rendered playbook then does not mention Emacs.
  7. Run
    ./green build
    and show the user what was rendered.
  1. 将本文件旁的
    green
    代码复制到项目根目录,并执行
    chmod +x
    赋予执行权限。
  2. 编写
    colors.yml
    。先询问提供商,再仅询问该提供商所需的密钥——
    references/configuration.md
    中列出了这些密钥。
  3. 选择一个对该项目唯一的
    profile
    ,通常使用目录名称。它会作为工作目录、OpenTofu状态密钥以及ssh别名的名称。两个项目若共享同一个profile和状态存储桶,会指向相同的状态,这可能导致开发机器意外管理生产服务器。
  4. 询问用户是否希望机器使用其GitHub身份。若是,将
    github-account
    设为其登录名,
    git-email
    设为其提交邮箱,并告知用户实际执行
    create
    时会先显示一次性设备流代码,需通过浏览器完成授权。这是提供
    emacs-config-repo
    clone-orgs
    dotfiles-checkout
    的前提——这些克隆操作会通过该身份验证。
  5. 询问用户是否希望Walter生成机器访问用的ssh密钥对(
    compute-keygen: true
    ),还是由用户自行提供提供商密钥。
  6. 询问用户是否希望在机器上安装其Emacs配置。若是,将
    emacs-config-repo
    设为其https格式的git URL(拒绝
    git@
    /
    ssh://
    格式),
    emacs-config-dest
    设为配置文件的目标路径——默认是
    ~/.config/emacs
    ,若配置文件期望其他路径,需使用
    --init-directory
    指定。否则留空这两个配置项;此时渲染的playbook不会提及Emacs。
  7. 运行
    ./green build
    并向用户展示渲染结果。

What create puts on the machine

create操作会在机器上部署的内容

Every machine gets nix, a Ghostty terminfo entry, and kernel networking settings for unprivileged
cloudflared
, unconditionally. The sysctls allow the login user's primary group to use ping sockets and raise QUIC's receive/send buffer ceilings, so a tunnel should run without sudo or those warnings. Tell the user about nix rather than proposing walter changes for other tooling: once it is there, anything else is
nix profile install
and needs nothing from walter.
The terminfo is why
Terminal type xterm-ghostty is not defined
does not happen. If a user reports that error — from
vim
,
top
,
less
or Emacs — on a machine created before this existed, the fix is to re-run
create
, not to change
TERM
. For a terminal walter does not cover, the one-liner is:
sh
infocmp -x "$TERM" | ssh <alias> -- tic -x -
With
github-account
set,
create
also logs the machine's own gh in with the token the device flow minted, makes it git's https credential helper, and configures the commit identity — every clone below authenticates through it, and nothing of the workstation's (no key, no agent) is involved. A machine already logged in skips the interactive step entirely, so re-creates stay unattended.
With
emacs-config-repo
set,
create
also installs Emacs (a full build from a pinned nixpkgs) and clones the configuration over https with the machine's own token — no private key is written to the machine, and the checkout can push back. The clone happens once; a later
create
leaves an existing one alone, so work done on the machine is never discarded. Offer
git pull
on the machine rather than a re-run when the user wants the config refreshed.
Emacs packages are not pre-fetched. The first
emacs
launch fetches from ELPA/MELPA, native-compiles and clones tree-sitter grammars, which takes minutes and is expected. Do not report it as a provisioning failure.
nix
and
emacs
reach
PATH
via
/etc/profile.d/nix.sh
, a login shell mechanism:
ssh walter-oci
sees them,
ssh walter-oci emacs …
as a one-shot command does not.
每台机器都会无条件安装nixGhostty terminfo条目,以及用于无特权运行
cloudflared
的内核网络设置。这些sysctl配置允许登录用户的主组使用ping套接字,并提高QUIC的接收/发送缓冲区上限,因此隧道无需sudo即可运行,也不会出现相关警告。向用户介绍nix即可,无需为其他工具修改Walter:一旦安装了nix,其他工具都可通过
nix profile install
安装,无需Walter参与。
terminfo条目可避免出现“Terminal type xterm-ghostty is not defined”错误。若用户报告在本功能推出前创建的机器上出现该错误(来自
vim
top
less
或Emacs),修复方法是重新运行
create
,而非修改
TERM
。对于Walter未覆盖的终端,可使用以下单行命令:
sh
infocmp -x "$TERM" | ssh <alias> -- tic -x -
若设置了
github-account
create
还会使用设备流生成的令牌在机器上完成gh登录,将其设为git的https凭证助手,并配置提交身份——后续所有克隆操作都会通过该身份验证,与工作站的任何内容(无密钥、无代理)无关。已登录的机器会完全跳过交互步骤,因此重新执行
create
时无需人工干预。
若设置了
emacs-config-repo
create
还会安装Emacs(基于固定版本nixpkgs的完整构建),并通过机器自身的令牌以https方式克隆配置文件——不会向机器写入私钥,且克隆后的仓库可推送代码。克隆操作仅执行一次;后续执行
create
时会保留已有的克隆内容,因此机器上的工作不会被丢弃。当用户希望刷新配置时,建议在机器上执行
git pull
,而非重新运行
create
Emacs包不会预先获取。首次启动
emacs
时会从ELPA/MELPA获取包、进行原生编译并克隆tree-sitter语法,这需要几分钟时间,属于正常情况。切勿将其报告为置备失败。
nix
emacs
通过
/etc/profile.d/nix.sh
加入
PATH
,这是登录shell机制:
ssh walter-oci
可看到它们,但
ssh walter-oci emacs …
这类一次性命令则无法看到。

Stopping and starting

开关机操作

stop
and
start
never reach OpenTofu. No template declares a power state, so powering the machine off out of band causes no drift — there is nothing for OpenTofu to reconcile.
Consequences worth telling the user about:
  • Only OCI can be power cycled today. Everywhere else
    stop
    reports that and exits 0. That is deliberate, not a bug. Do not present it as a failure.
  • create
    will not restart a stopped machine.
    With no power state in the configuration there is no diff, so an apply leaves it stopped.
    start
    is the only way up.
  • Stopping stops the compute meter, not the storage one. The boot volume bills whether the machine runs or not.
  • stop
    and
    start
    need the
    oci
    CLI to authenticate
    , which OpenTofu does not. Session tokens last 60 minutes. When walter reports an expired session it names the command that fixes it; run that, then retry.
stop
start
操作永远不会调用OpenTofu。模板中未声明电源状态,因此通过外部方式关机不会导致配置漂移——OpenTofu无需协调任何内容。
需要告知用户的相关后果:
  • 目前仅OCI支持电源循环。在其他环境下,
    stop
    会报告此情况并以0状态码退出。这是有意设计,而非bug。切勿将其视为失败。
  • create
    不会重启已关机的机器
    。由于配置中无电源状态,因此执行apply时不会产生差异,机器会保持关机状态。只有
    start
    操作可开机。
  • 关机仅停止计算计费,存储计费仍会继续。无论机器是否运行,启动卷都会产生费用。
  • stop
    start
    需要
    oci
    CLI完成身份验证
    ,这与OpenTofu的验证方式不同。会话令牌有效期为60分钟。当Walter报告会话过期时,会给出修复命令;执行该命令后重试即可。

When something fails

故障排查

  • COLORS_PAR_PROFILE is set
    — the user has it exported, probably from another project's
    .envrc
    . Unset it; do not work around it.
  • required credential is not set: COLORS_PAR_X
    — name the variable and let the user export it themselves.
  • no instance id
    — walter could not read the compute stage's
    instance_id
    output and desired state carries none. Either the machine was never created, or the state backend is unreachable.
    oci-instance-id
    in
    colors.yml
    is the documented escape hatch.
  • gh auth login failed
    gh
    is missing on the workstation, or the one-time code expired unapproved. Install gh or re-run
    create
    and approve the code; there is no token to paste anywhere.
  • A create failed after the code was approved — just re-run it. The minted token survives under
    ~/.local/state/walter/github-token-<profile>
    for exactly this, so the retry does not prompt again; it is removed once a create seeds the machine.
  • the login approved the code as X but colors.yml names github-account Y — the user approved from the wrong GitHub account. Re-run
    create
    and approve from the account the machine is meant to act as, or fix
    github-account
    .
  • A contract mismatch — the pinned commit is older than this launcher. Re-copy
    green
    from an updated skill; nothing inside the project fixes it.
  • COLORS_PAR_PROFILE is set
    ——用户已导出该变量,可能来自其他项目的
    .envrc
    。取消设置该变量;切勿寻找变通方法。
  • required credential is not set: COLORS_PAR_X
    ——告知用户对应的变量名称,让用户自行导出。
  • no instance id
    ——Walter无法读取计算阶段的
    instance_id
    输出,且预期状态中也未包含该值。可能是机器从未被创建,或状态后端无法访问。
    colors.yml
    中的
    oci-instance-id
    是文档中说明的解决方法。
  • gh auth login failed
    ——工作站上未安装
    gh
    ,或一次性代码未被授权已过期。安装gh或重新运行
    create
    并完成授权;无需粘贴任何令牌。
  • 授权代码后create操作失败——只需重新运行即可。生成的令牌会保存在
    ~/.local/state/walter/github-token-<profile>
    下,专为这种情况设计,因此重试时不会再次提示;当create操作完成机器置备后,该令牌会被删除。
  • 登录时使用账户X授权,但colors.yml中github-account为Y——用户使用了错误的GitHub账户授权。重新运行
    create
    并使用机器预期的账户授权,或修改
    github-account
    配置。
  • A contract mismatch——固定的提交版本早于当前启动器。从更新后的技能中重新复制
    green
    ;项目内部的任何修改都无法解决此问题。