@appforge-ci/admin-cli
v0.3.13
Published
`appforge-admin` — the platform-operator CLI for fleet management (enroll, list, drain, resume, reboot, run maintenance scripts on Mac minis). This is a **separate** tool from `appforge` (`packages/cli`), which is for AppForge's customers and has no fleet
Readme
@appforge-ci/admin-cli
appforge-admin — the platform-operator CLI for fleet management (enroll,
list, drain, resume, reboot, run maintenance scripts on Mac minis). This
is a separate tool from appforge (packages/cli), which is for
AppForge's customers and has no fleet commands at all — see
docs/self-hosting.md's "Fleet management" section for why they're kept
apart. Config lives in ~/.appforge-admin/config.json, independent of
~/.appforge/config.json.
For the full day-to-day runbook (reading fleet status, troubleshooting a
NotReady/offline mini, rotating tokens, decommissioning) once this is
installed, see docs/fleet-management.md.
Install
On a machine that already has this repo cloned (the common case —
your own laptop, or a Mac mini you git cloned onto): build it and put
it on PATH with npm link:
pnpm install # once, from the repo root
pnpm --filter @appforge-ci/admin-cli build
cd packages/admin-cli && npm link # symlinks `appforge-admin` onto PATHnpm link needs to be re-run only if the symlink itself ever gets
removed (e.g. npm uninstall -g @appforge-ci/admin-cli) — a plain
rebuild (pnpm --filter @appforge-ci/admin-cli build) is enough to pick
up code changes afterwards, since the link points at dist/ in place.
From npm, once published: .github/workflows/publish.yml publishes
this package (tag-triggered, git tag vX.Y.Z && git push origin vX.Y.Z),
but that workflow needs an NPM_TOKEN repo secret that isn't
configured yet — until it is and a version has actually been published,
npm install -g @appforge-ci/admin-cli will 404. The npm link path
above is what actually works today.
Usage
appforge-admin login --api-url <api-url> --admin-api-url <admin-api-url> # once; add --web to approve in a browser instead of typing your password here
appforge-admin agents list
appforge-admin agents add-mac --name "my-mac-mini" # run ON the mini you're enrolling — see docs/self-hosting.md
appforge-admin agents add-mac --force # re-enroll THIS Mac (rotate token / rename) — same fleet row, never a duplicate
appforge-admin agents decommission <agentId> # permanently remove a mini (retired machine, or a stale duplicate row)
appforge-admin agents drain <agentId>
appforge-admin agents resume <agentId>
appforge-admin agents reboot <agentId>
appforge-admin agents restart <agentId> # just the agent process (e.g. after a manual upgrade) — no reboot needed
appforge-admin agents cancel-build <agentId> <buildId> # kill one wedged build, other concurrent builds on the same mini untouched
appforge-admin agents allow-remote-control <agentId> --on|--off # authorize (or revoke) the VNC "Connect" button's mouse/keyboard control — off by default for every agent
appforge-admin agents allow-vpn <agentId> # approve a Mac for site-to-site VPN duty (platform admin) — off by default; also deny-vpn <agentId> to revoke
appforge-admin agents run-script <agentId> <scriptName>
appforge-admin agents commands <agentId> [--limit 20] # remote-command history + who issued each one — see docs/fleet-management.md
appforge-admin agents update <agentId> [--to <version>] # roll one mini onto a new agent build (OTA) — see docs/fleet-management.md
appforge-admin agents update --all # every enrolled mini, one at a time
appforge-admin agents bootstrap [--full] # install missing toolchains on THIS Mac
appforge-admin agents enroll # advanced: just a token, no local enrollment — see add-mac instead--api-url/--admin-api-url only need passing on that first login —
they're saved to ~/.appforge-admin/config.json and reused after that.
Only accounts listed in the admin-api Worker's PLATFORM_ADMIN_EMAILS
secret can actually log in here; see docs/self-hosting.md.
The password-based login (not --web) prompts interactively for a 2FA
code if the account has it enabled and neither --totp-code nor
--recovery-code was passed — see docs/security.md's "2FA (TOTP)"
note. login --web's device-authorization flow has no password step at
all, so it's unaffected either way.
