Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/wiki/CLI_INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,34 @@ npm test
3. Make changes and test
4. Submit pull request

## Compatibility with cli v1.5

Admin ships in lockstep with the cli (release train P7-SHIP-06): **admin 1.5.x needs cli 1.5.x**. Admin 1.5 builds its argv with the canonical spellings of the v1.5 command canon (cli wiki: `Command-Canon.md`), which a cli 1.4 does not know.

| What admin does | Where |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Every child process gets `NSELF_JSON_LEGACY=1` (the caller can override it), so the JSON admin parses keeps the bare cli 1.4 shape instead of the v1 envelope. | `getNselfChildEnv` and `ensureLegacyJsonEnv` in `src/lib/nself-path.ts`; the process default comes from `next.config.mjs` (`next dev`, `next start`) and `ENV NSELF_JSON_LEGACY=1` in the Dockerfile (the standalone `server.js` does not evaluate `next.config.mjs`) |
| `NSELF_BIN` names the binary to run, ahead of `NSELF_CLI_PATH` and discovery, for code that resolves the binary through `src/lib/nself-path.ts`. A path that does not exist is ignored with a warning. Routes that spawn a bare `nself` use `PATH` (tracked as debt). | `getNselfBinOverride` in `src/lib/nself-path.ts` |
| Relocated commands use the canonical spelling: `service` is `config services`, `secrets` is `config secrets`, `env` is `config env`, `urls` is `status urls`, `health` is `status health`, `trust` is `config trust`, `plugin install\|remove` is `add\|remove`, other `plugin` commands are `config plugins`, `plugin test` is `plugin-dev test`. | call sites under `src/` |
| `executeNselfCommand`, `streamNselfCommand` and the routes that run a user-chosen command (`cli/execute`, `commands/run`, `nself`, `ws/terminal`) rewrite an old root to the canonical argv before the exec (`canonicalizeArgv`, `canonicalizeArgs`). The check script requires the four routes to call it. | `src/lib/nselfCanon.ts` |
| `functions` and `plugin-dev` are plugin commands; the cli installs them on first use (auto-add). | allowlist in `src/lib/nselfCanon.ts` |

### The compat check

```bash
NSELF_BIN=/path/to/nself NSELF_V15=1 bash scripts/cli-compat.sh # v1.5 mode
NSELF_BIN=/path/to/nself bash scripts/cli-compat.sh # v1.4 mode
```

`scripts/cli-compat.sh` needs bash, perl and jq. It writes the sorted argv prefixes admin builds to `scripts/cli-argv-inventory.txt` (commit the file; CI-style check: `git diff --exit-code scripts/cli-argv-inventory.txt` after a run). It then fails when

- a prefix starts with an old spelling that cli v1.5 keeps only as a deprecated shim (read from `nself help --json`), or
- the longest prefix that is a cli command exits non-zero on `--help` or prints a `moved to` warning.

A prefix whose full path is not a cli command is printed as `UNKNOWN`. That is admin calling something the cli does not have (`tenant`, `auth`, `perf`, `bench`, `ssl`, ...), or a v1.5 spelling when the binary runs in v1.4 mode. UNKNOWN is a report, not a failure. The pre-existing drift is tracked in `hq/quality/debt.yaml`.

The check never installs a plugin and never reaches the network: it runs with `NSELF_NO_AUTO_ADD=1` and an empty `HOME`.

## Support

- GitHub Issues: https://github.com/nself-org/admin/issues
Expand Down
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
FROM --platform=$BUILDPLATFORM golang:1.27-alpine AS mkcert-builder
ARG TARGETOS
ARG TARGETARCH
RUN apk add --no-cache git

Check failure on line 21 in Dockerfile

View workflow job for this annotation

GitHub Actions / hadolint

DL3018 warning: Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
RUN git clone --depth 1 --branch v1.4.4 https://github.com/FiloSottile/mkcert /src

Check failure on line 22 in Dockerfile

View workflow job for this annotation

GitHub Actions / hadolint

DL3059 info: Multiple consecutive `RUN` instructions. Consider consolidation.
WORKDIR /src
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -trimpath -ldflags "-s -w" -o /out/mkcert .
Expand All @@ -31,7 +31,7 @@

# Stage 1: Dependencies
FROM node:22-alpine AS deps
RUN apk add --no-cache libc6-compat

Check failure on line 34 in Dockerfile

View workflow job for this annotation

GitHub Actions / hadolint

DL3018 warning: Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
RUN corepack enable && corepack prepare pnpm@10.28.0 --activate
WORKDIR /app

Expand All @@ -51,7 +51,7 @@

# Stage 2: Builder
FROM node:22-alpine AS builder
RUN apk add --no-cache libc6-compat

Check failure on line 54 in Dockerfile

View workflow job for this annotation

GitHub Actions / hadolint

DL3018 warning: Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
RUN corepack enable && corepack prepare pnpm@10.28.0 --activate
WORKDIR /app

Expand Down Expand Up @@ -79,7 +79,7 @@
RUN pnpm run build

# Remove dev dependencies to reduce image size
RUN pnpm prune --prod

Check failure on line 82 in Dockerfile

View workflow job for this annotation

GitHub Actions / hadolint

DL3059 info: Multiple consecutive `RUN` instructions. Consider consolidation.

# Stage 3: Runner (minimal image)
FROM node:22-alpine AS runner
Expand All @@ -91,7 +91,7 @@
# - curl, git: Required by nself commands
# - openssl, nss-tools: For SSL certificate management
# - mkcert: For local SSL certificates (installed separately)
RUN apk add --no-cache \

Check failure on line 94 in Dockerfile

View workflow job for this annotation

GitHub Actions / hadolint

DL3018 warning: Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
bash \
curl \
git \
Expand Down Expand Up @@ -121,7 +121,7 @@

# Install nself CLI pre-built binary
ARG NSELF_VERSION=1.4.14
RUN ARCH=$(uname -m) && \

Check failure on line 124 in Dockerfile

View workflow job for this annotation

GitHub Actions / hadolint

DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
if [ "$ARCH" = "x86_64" ]; then NSELF_ARCH="amd64"; \
elif [ "$ARCH" = "aarch64" ]; then NSELF_ARCH="arm64"; \
else NSELF_ARCH="amd64"; fi && \
Expand Down Expand Up @@ -194,6 +194,10 @@
# Expose port 3021 (reserved for nself-admin, distinct from Loki on 3100)
EXPOSE 3021

# cli 1.5 prints the v1 JSON envelope by default; admin parses the bare cli 1.4 shape.
# The standalone server.js does not evaluate next.config.mjs, so set it here (P7-CANON-20).
ENV NSELF_JSON_LEGACY=1

# Use STOPSIGNAL for proper graceful shutdown
STOPSIGNAL SIGTERM

Expand Down
8 changes: 8 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import withBundleAnalyzer from '@next/bundle-analyzer'
import createNextIntlPlugin from 'next-intl/plugin'

// cli 1.5 prints the v1 JSON envelope by default; admin parses the bare cli 1.4
// shape. Set once here so `next dev` and `next start` give every route that runs
// `nself` the legacy shape, including the ones that spawn a bare `nself` and never
// call findNselfPath. The Docker image sets the same variable in the Dockerfile,
// because its standalone server.js does not evaluate this file (P7-CANON-20).
// An explicit NSELF_JSON_LEGACY in the environment wins.
process.env.NSELF_JSON_LEGACY ??= '1'

const bundleAnalyzer = withBundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
})
Expand Down
260 changes: 260 additions & 0 deletions scripts/cli-argv-inventory.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
@dynamic src/app/api/auth/roles/route.ts
@dynamic src/app/api/cli/execute/route.ts
@dynamic src/app/api/commands/registry/route.ts
@dynamic src/app/api/commands/run/route.ts
@dynamic src/app/api/control-plane/route.ts
@dynamic src/app/api/deploy/blue-green/route.ts
@dynamic src/app/api/deploy/canary/route.ts
@dynamic src/app/api/deploy/preview/route.ts
@dynamic src/app/api/deploy/production/route.ts
@dynamic src/app/api/docker/exec/route.ts
@dynamic src/app/api/frontend/[name]/deploy/route.ts
@dynamic src/app/api/frontend/[name]/route.ts
@dynamic src/app/api/frontend/route.ts
@dynamic src/app/api/health/route.ts
@dynamic src/app/api/helm/generate/route.ts
@dynamic src/app/api/helm/init/route.ts
@dynamic src/app/api/helm/repos/route.ts
@dynamic src/app/api/helm/rollback/route.ts
@dynamic src/app/api/helm/route.ts
@dynamic src/app/api/helm/status/route.ts
@dynamic src/app/api/helm/uninstall/route.ts
@dynamic src/app/api/helm/upgrade/route.ts
@dynamic src/app/api/helm/values/route.ts
@dynamic src/app/api/history/deployments/route.ts
@dynamic src/app/api/history/migrations/route.ts
@dynamic src/app/api/history/route.ts
@dynamic src/app/api/k8s/apply/route.ts
@dynamic src/app/api/k8s/clusters/connect/route.ts
@dynamic src/app/api/k8s/convert/route.ts
@dynamic src/app/api/k8s/deploy/route.ts
@dynamic src/app/api/k8s/deployments/route.ts
@dynamic src/app/api/k8s/ingresses/route.ts
@dynamic src/app/api/k8s/init/route.ts
@dynamic src/app/api/k8s/namespaces/route.ts
@dynamic src/app/api/k8s/pods/route.ts
@dynamic src/app/api/k8s/rollback/route.ts
@dynamic src/app/api/k8s/scale/route.ts
@dynamic src/app/api/k8s/services/route.ts
@dynamic src/app/api/monitor/alerts/route.ts
@dynamic src/app/api/monitor/alerts/rules/route.ts
@dynamic src/app/api/monitor/alerts/silence/route.ts
@dynamic src/app/api/monitor/metrics/route.ts
@dynamic src/app/api/nself/help/route.ts
@dynamic src/app/api/nself/route.ts
@dynamic src/app/api/nself/updates/route.ts
@dynamic src/app/api/nself/version/route.ts
@dynamic src/app/api/scale/auto/route.ts
@dynamic src/app/api/sync/config/route.ts
@dynamic src/app/api/sync/db/route.ts
@dynamic src/app/api/sync/files/route.ts
@dynamic src/app/api/sync/history/route.ts
@dynamic src/app/api/sync/route.ts
@dynamic src/app/api/ws/terminal/route.ts
@dynamic src/features/license/license.ts
@dynamic src/lib/nselfCLI.ts
@dynamic src/lib/workflows/index.ts
add
apply
audit
auth devices list
auth devices register
auth devices revoke
auth devices trust
auth mfa backup-codes
auth mfa disable
auth mfa enable
auth mfa reset
auth mfa verify
auth oauth config
auth oauth disable
auth oauth enable
auth oauth install
auth oauth list
auth oauth status
auth oauth test
auth rate-limit config
auth rate-limit reset
auth rate-limit status
auth security audit
auth security report
auth security scan
auth webhooks create
auth webhooks delete
auth webhooks list
auth webhooks logs
auth webhooks show
auth webhooks test
backup
backup create
backup list
backup restore
backup schedule
bench baseline
bench compare
bench run
bench stress
build
claw import
cloud server create
cloud server destroy
cloud server status
config
config env
config env diff
config env list
config env target
config export
config import
config plugins
config plugins disable
config plugins list
config plugins logs
config plugins status
config plugins stripe
config plugins uninstall
config plugins update
config secrets
config secrets delete
config secrets get
config secrets list
config secrets rotate
config secrets set
config services
config services admin
config services cache
config services email
config services functions
config services init
config services mlflow
config services realtime
config services scaffold
config services search
config services storage
config sync
config trust status
config validate
config vault config
config vault init
config vault status
db analyze
db backup
db backup list
db list
db migrate
db query
db reset
db restore
db seed
db stats
db status
db sync
db table-data
db tables
deploy
deploy blue-green status
deploy canary status
deploy environments
deploy environments configure
deploy environments diff
deploy preview destroy
deploy preview list
deploy production
deploy staging
deploy status
doctor
export
frontend get
frontend list
frontend remove
functions delete
functions deploy
functions invoke
functions list
functions logs
helm install
helm repos list
help
init
k8s clusters
k8s logs
k8s namespaces
k8s namespaces delete
k8s namespaces get
k8s status
logs
monitor
monitor alerts rules
perf analyze
perf profile
perf report
perf slow-queries
perf suggest
plugin-dev test transactional-email
prod status
remove
reset
restart
restore
scale
scale auto status
scale status
ssl generate
ssl letsencrypt
ssl provision
ssl renew
ssl revoke
ssl status
ssl trust
staging
staging status
start
status
status health
status urls
stop
sync status
tenant activate
tenant branding colors
tenant branding logo
tenant branding preview
tenant branding reset
tenant branding show
tenant create
tenant delete
tenant domain add
tenant domain list
tenant domain primary
tenant domain remove
tenant domain show
tenant domain verify
tenant email edit
tenant email list
tenant email show
tenant list
tenant member add
tenant member list
tenant member remove
tenant member resend-invite
tenant member show
tenant member update
tenant org create
tenant org delete
tenant org list
tenant org member
tenant org permission
tenant org role
tenant org show
tenant org team
tenant org update
tenant settings list
tenant settings set
tenant show
tenant stats
tenant suspend
tenant theme apply
tenant theme customize
tenant theme list
tenant update
update
version
Loading
Loading