AbsoluteJS

Ops CLI

@absolutejs/cliv0.1.0betaPlatform & Infra

Config-driven ops CLI for Bun apps on your own servers — secrets rotation, environment pushes, and deploy rollbacks in one binary.

The absolutejs binary is the operations CLI for running Bun apps on servers you manage — distinct from the framework CLI (the absolute binary from @absolutejs/absolute, which handles dev, start, and compile). It puts command-line verbs over @absolutejs/secrets, @absolutejs/deploy, and @absolutejs/audit: list and rotate secrets, push and diff environment files on remote stages, inspect release history, and roll back. One absolutejs.config.ts in your project root wires the secret broker and deployment targets, and remote-touching config is lazy, so local verbs never provision infrastructure by accident.

#Installation

BASH
bun add -d @absolutejs/cli

#Capabilities

Overview

Operations CLI used by the hosted AbsoluteJS.ai platform and self-hosted Bun deployments. Verbs over @absolutejs/secrets and @absolutejs/deploy:

Sibling to @absolutejs/absolute (framework CLI: dev, start, compile, etc.). They're complementary — absolute is dev/build/codegen, absolutejs is secrets/env/deploy.

Config — absolutejs.config.ts

Drop one in your project root. The CLI walks up from the cwd to find it.

The target and deployer fields are LAZY (() => …). Verbs that don't touch a remote (secrets list, secrets set) never invoke them — absolutejs secrets list won't accidentally provision a Hetzner box.

Commands

secrets

Verb — Description

list — Print every name + fingerprint from the adapter. Plaintext never appears.

Show 10 more

get [--show] — Resolve one secret. Default prints fingerprint= only; --show prints plaintext.

set <NAME>= — Put a value via the configured adapter.

rotate — Call broker.rotate(name) — generates a new value, persists, fires onRotate listeners.

env

Verb — Description

push — Resolve secretNames + extras for the stage, atomic-write the remote env file, run reload.

pull — Read the remote env file as-is.

diff [--all] — Show added/changed/removed keys between what push would write and what's currently on the remote. --all also lists unchanged keys.

deploy

Verb — Description

Composition with the rotation loop

broker.rotate fires the in-process onRotate listeners (long-lived DB clients swap creds in place); env push propagates to the remote boxes and reloads the services.

Secrets management verbs

list, get, set, and rotate against whatever secrets adapter you configure. Output shows fingerprints by default — plaintext only appears with an explicit --show.

Environment push and diff

env push resolves secrets plus extras for a stage, atomically writes the remote env file, and runs your reload command. env diff shows exactly what a push would add, change, or remove before you run it.

Release history and rollback

deploy releases, deploy status, and deploy rollback --to give per-stage release history and one-command rollback to any previous release.

Lazy remote config

Deployment target and deployer fields in the config are factories, invoked only by verbs that touch a remote — running secrets list will never spin up a cloud server.

Machine-readable output

A global --json flag switches every verb to machine-readable output for scripting and CI pipelines.

Outcomes

What you can build

Overview

Operations CLI used by the hosted AbsoluteJS.ai platform and self-hosted Bun deployments. Verbs over @absolutejs/secrets and @absolutejs/deploy:

Install

The absolutejs binary lands in node_modules/.bin/. Run via bunx absolutejs, npx absolutejs, or alias it in your shell.

Config — absolutejs.config.ts

Drop one in your project root. The CLI walks up from the cwd to find it.

Hardening checklist

Production guidance

OverviewOperations CLI used by the hosted AbsoluteJS.ai platform and self-hosted Bun deployments. Verbs over @absolutejs/secrets and @absolutejs/deploy:

Follow in order

Troubleshooting path

1
Trace from the first failed boundary
Reproduce the smallest canonical @absolutejs/cli example, confirm the supported entry point and version in the API explorer, then inspect the first boundary that did not produce its documented result.

#@absolutejs/cli quick start

Partial snippet

# @absolutejs/cli

TXT
absolutejs secrets list                  list secret names + fingerprints
absolutejs secrets rotate STRIPE_KEY     generate + persist a new value
absolutejs env push prod                 push resolved env file to a stage
absolutejs env diff prod                 see what `env push` would change
absolutejs deploy rollback prod          roll back to the previous release

#Config — absolutejs.config.ts

Partial snippet

Drop one in your project root. The CLI walks up from the cwd to find it.

TS
import { defineConfig } from "@absolutejs/cli";
import { createSecretBroker, encryptedFileAdapter } from "@absolutejs/secrets";
import { hetznerTarget } from "@absolutejs/deploy/hetzner";
import { createDeployer } from "@absolutejs/deploy";

const adapter = encryptedFileAdapter({
  path: "./.secrets.enc.json",
  key: {
    type: "passphrase",
    passphrase: process.env.SECRETS_MASTER!,
  },
});

const broker = createSecretBroker({ adapter });

const prodTarget = () =>
  hetznerTarget({
    token: process.env.HETZNER_TOKEN!,
    name: "api-prod-1",
    region: "nbg1",
    serverType: "cx22",
    image: "ubuntu-22.04",
    sshKeys: [process.env.HETZNER_KEY_FINGERPRINT!],
  });

export default defineConfig({
  secrets: broker,
  secretAdapter: adapter,
  deployments: [
    {
      name: "prod",
      target: prodTarget,
      remotePath: "/etc/api.env",
      secretNames: ["DATABASE_URL", "STRIPE_KEY"],
      extras: { NODE_ENV: "production" },
      reload: "systemctl reload api",
      deployer: async () =>
        createDeployer({
          appName: "api",
          target: await prodTarget(),
        }),
    },
  ],
});

#Composition with the rotation loop

Partial snippet

Working example for Composition with the rotation loop.

BASH
# Rotate STRIPE_KEY in the broker.
absolutejs secrets rotate STRIPE_KEY

# Push to every deployment that uses it.
absolutejs env push prod
absolutejs env push staging

#Everyday Commands

Partial snippet

The core verbs. Run via bunx absolutejs, npx absolutejs, or alias the node_modules/.bin binary in your shell.

BASH
absolutejs secrets list              # secret names + fingerprints
absolutejs secrets rotate STRIPE_KEY # generate + persist a new value
absolutejs env diff prod             # preview what env push would change
absolutejs env push prod             # push resolved env file to a stage
absolutejs deploy rollback prod      # roll back to the previous release

#Config — absolutejs.config.ts

Partial snippet

Drop absolutejs.config.ts in your project root — the CLI walks up from the cwd to find it. target and deployer are lazy factories, so local-only verbs never touch the remote.

TS
import { defineConfig } from '@absolutejs/cli';
import {
  createSecretBroker,
  encryptedFileAdapter,
} from '@absolutejs/secrets';
import { hetznerTarget } from '@absolutejs/deploy/hetzner';
import { createDeployer } from '@absolutejs/deploy';

const adapter = encryptedFileAdapter({
  path: './.secrets.enc.json',
  key: {
    type: 'passphrase',
    passphrase: process.env.SECRETS_MASTER!,
  },
});

const broker = createSecretBroker({ adapter });

const prodTarget = () =>
  hetznerTarget({
    token: process.env.HETZNER_TOKEN!,
    name: 'api-prod-1',
    region: 'nbg1',
    serverType: 'cx22',
    image: 'ubuntu-22.04',
    sshKeys: [process.env.HETZNER_KEY_FINGERPRINT!],
  });

export default defineConfig({
  secrets: broker,
  secretAdapter: adapter,
  deployments: [
    {
      name: 'prod',
      target: prodTarget,
      remotePath: '/etc/api.env',
      secretNames: ['DATABASE_URL', 'STRIPE_KEY'],
      extras: { NODE_ENV: 'production' },
      reload: 'systemctl reload api',
      deployer: async () =>
        createDeployer({
          appName: 'api',
          target: await prodTarget(),
        }),
    },
  ],
});

#Rotate and Propagate

Partial snippet

Rotation and propagation compose: rotate updates the broker and notifies live listeners, then env push carries the new value to each remote box.

BASH
# Rotate STRIPE_KEY in the broker — in-process onRotate
# listeners swap credentials in place.
absolutejs secrets rotate STRIPE_KEY

# Propagate to every stage that uses it: atomic remote
# env-file write, then the configured reload command.
absolutejs env push prod
absolutejs env push staging
Not the framework CLI
Two CLIs, two jobs: absolute (from @absolutejs/absolute) is the framework CLI for dev, build, and codegen; absolutejs (this package) is the ops CLI for secrets, env, and deploy. They're complementary and usually installed side by side.
Beta
The package is pre-1.0. Verb names and config shape are settling, but expect minor adjustments before a stable release.

#API reference

Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.

9 symbols
SecretValuetypePermalink

@absolutejs/cli — substrate CLI for the AbsoluteJS PaaS. Library entry: exports defineConfig for absolutejs.config.ts authors + the types the CLI verbs operate on. The CLI itself runs via the absolutejs binary (see bin/absolutejs.js and src/cli.ts). Composes with @absolutejs/secrets (broker, encrypted file adapter), @absolutejs/deploy (Target, Deployer, EnvDeployment), and any other substrate package that satisfies one of the narrow interfaces below.

TS
type SecretValue = {
    value: string;
    fingerprint: string;
};
Exported from @absolutejs/cli

Current package surface

What ships today

@absolutejs/cliv0.1.0 · betaDev ToolsnpmSource
1entry points9symbols

Import surface · click to copy