Command-line interface that starts the Auto Engineer pipeline server, loads plugins, synchronizes local files with remote sandboxes, and optionally exposes a public tunnel.
The CLI is the primary entry point for Auto Engineer. It:
- Loads an
auto.config.tsconfiguration file and registers pipeline plugins and command handlers - Starts an HTTP + WebSocket server that exposes pipeline endpoints and real-time file sync
- Watches the local
narratives/directory (configurable) and streams file changes to connected clients via Socket.IO - Discovers TypeScript type definitions for external dependencies and includes them in the sync payload
- Optionally opens an ngrok tunnel for remote access from the Auto cloud app
- Renders a terminal UI (Ink-based) that aggregates stdout/stderr from registered child services
# Global install
npm install -g @auto-engineer/cli
# Or run directly
npx @auto-engineer/cliBoth auto and auto-engineer are registered as bin commands.
# 1. Create a config file in your project root
cat > auto.config.ts << 'EOF'
import { define } from '@auto-engineer/pipeline';
export const plugins = [
'@auto-engineer/narrative',
];
export const pipeline = define('my-pipeline')
.on('SchemaExported')
.emit('GenerateServer', (e) => ({
modelPath: e.data.outputPath,
destination: e.data.directory,
}))
.build();
EOF
# 2. Start the server (launches TUI by default)
auto start
# 3. In another terminal, check status
auto status
# 4. Dispatch a command
auto dispatch GenerateServer --data '{"modelPath": "./schema.json", "destination": "."}'
# 5. Open the pipeline diagram in a browser
auto diagramauto start --no-tuiauto status --host http://remote-server:5555
auto dispatch MyCommand --host http://remote-server:5555 --data '{}'Requires a free ngrok account.
# Via CLI flag
auto start --tunnel
# Or in auto.config.ts
export const tunnel = {
enabled: true,
authtoken: 'your-ngrok-authtoken', // or set NGROK_AUTHTOKEN in .env
domain: 'my-custom.ngrok.io', // optional reserved domain
};When the tunnel is active, the CLI generates a bearer token and prints it alongside the public URL. Both are needed to connect from the Auto cloud app.
By default the file syncer watches narratives/ relative to the config file. Override it:
// auto.config.ts
export const fileSync = {
dir: './custom-sync-dir',
};The file syncer encrypts provider credentials into a JWE token and includes it in the synced auto.config.json. Set one of these in your .env:
ANTHROPIC_API_KEY=sk-...
OPENAI_API_KEY=sk-...
GEMINI_API_KEY=...
XAI_API_KEY=...
# Or a custom provider
CUSTOM_PROVIDER_NAME=my-provider
CUSTOM_PROVIDER_BASE_URL=https://api.example.com
CUSTOM_PROVIDER_API_KEY=sk-...
CUSTOM_PROVIDER_DEFAULT_MODEL=my-model
# Optional: override the default model for any provider
DEFAULT_AI_MODEL=claude-sonnet-4-20250514auto start --port 8080 --config ./ci.config.ts --no-tuiThe --no-tui flag disables the interactive terminal UI, which is required for non-interactive environments.
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--port |
-p |
number | 5555 |
Server port (auto-increments if taken, up to +100) |
--debug |
-d |
boolean | false |
Enable debug mode |
--config |
-c |
string | auto.config.ts |
Path to config file |
--host |
string | localhost |
Connect to an existing server | |
--tunnel |
boolean | false |
Enable ngrok tunnel | |
--no-tui |
boolean | false |
Disable TUI, use legacy console output | |
--version |
-v |
Print version |
Start the pipeline server. This is the default command -- running auto with no subcommand is equivalent.
Send a command to the running pipeline server.
| Option | Type | Default | Description |
|---|---|---|---|
--data |
string (JSON) | {} |
Command payload |
auto dispatch GenerateServer --data '{"modelPath": "./schema.json"}'Query the server's /health and /registry endpoints. Prints uptime, registered command count, and event handler count.
Open the pipeline diagram (/pipeline/diagram) in the default browser.
The CLI looks for auto.config.ts or auto.config.js in the current working directory.
// auto.config.ts
import { define } from '@auto-engineer/pipeline';
export const fileId = 'my-project';
export const plugins = [
'@auto-engineer/narrative',
'@auto-engineer/server-generator-apollo-emmett',
];
export const pipeline = define('my-pipeline')
.on('SchemaExported')
.emit('GenerateServer', (e) => ({
modelPath: e.data.outputPath,
destination: e.data.directory,
}))
.build();
// Optional
export const fileSync = {
dir: 'narratives', // directory to watch and sync
};
export const tunnel = {
enabled: false, // enable ngrok tunnel
authtoken: 'ngrok-token', // or use NGROK_AUTHTOKEN env var
domain: 'my.ngrok.io', // optional reserved domain
token: 'custom-bearer', // optional fixed bearer token
};
export const COMMANDS = [
{
name: 'MyCommand',
handle: async (data) => ({ type: 'MyCommandDone', data: {} }),
},
];| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check (status, uptime) |
/registry |
GET | List registered command and event handlers |
/pipeline |
GET | Pipeline state |
/pipeline/diagram |
GET | Visual pipeline diagram |
/events |
GET | SSE event stream |
/command |
POST | Dispatch a command ({ type, data }) |
/configure |
POST | Set service token and org/project IDs |
ws://.../file-sync |
Socket.IO | Bi-directional file sync |
| Export | Description |
|---|---|
@auto-engineer/cli |
startServer, getServiceRegistry, types |
@auto-engineer/cli/server |
Direct server module import |
Symptom: Server exits with No pipeline config found. Create an auto.config.ts file.
Cause: No auto.config.ts or auto.config.js exists in the current working directory.
Solution:
cat > auto.config.ts << 'EOF'
import { define } from '@auto-engineer/pipeline';
export const plugins = [];
export const pipeline = define('default').build();
EOFSymptom: Server starts on a different port than expected.
Cause: The requested port is occupied. The CLI auto-scans up to 100 ports above the requested one via get-port.
Solution: Check the actual port in the startup output, or specify a known-free port:
auto start --port 6000Symptom: Dispatching a command returns an error about missing handlers.
Cause: The plugin package is not installed, not built, or does not export a COMMANDS array.
Solution:
- Install the plugin:
pnpm add @auto-engineer/my-plugin - Build it:
pnpm --filter @auto-engineer/my-plugin build - Verify it exports
COMMANDSfrom its main entry point or has acommands/directory with.jsfiles that export handlers
Symptom: Warning Failed to start ngrok tunnel appears; server continues without tunnel.
Cause: Missing or invalid ngrok authtoken.
Solution:
# Set in .env
echo 'NGROK_AUTHTOKEN=your-token' >> .env
# Or in auto.config.ts
export const tunnel = {
enabled: true,
authtoken: 'your-token',
};Symptom: Garbled output or blank screen.
Cause: Terminal does not support the Ink rendering framework, or the process is not attached to a TTY.
Solution:
auto start --no-tui# All auto debug output
DEBUG=auto:* auto start
# File syncer only
DEBUG=auto:cli:file-syncer auto start
# Type definition resolution
DEBUG=auto-engineer:file-syncer:* auto startbin/
auto.ts # Thin shim: spawns src/index.js with forwarded args
src/
index.ts # CLI entry: Commander program, start/dispatch/status/diagram
server.ts # startServer(): config loading, plugin discovery, PipelineServer + FileSyncer
config-loader.ts # Loads auto.config.ts via jiti, resolves defaults
tunnel.ts # ngrok tunnel, bearer-token auth middleware, service-token store
tui/
index.tsx # renderTui() — Ink render entry
App.tsx # Root Ink component
Dashboard.tsx # Dashboard UI
ServiceRegistry.ts # Tracks registered child services (id, streams, process)
LogBuffer.ts # Ring buffer for service log lines
hooks/
useServiceStreams.ts # Wires Readable streams into LogBuffer
file-syncer/
index.ts # FileSyncer class: chokidar watch, Socket.IO sync, auto.config.json virtual file
types/wire.ts # WireChange, WireInitial protocol types
sync/
resolveSyncFileSet.ts # Computes the set of files to sync (narratives + .d.ts externals)
crypto/
jwe-encryptor.ts # Encrypts AI provider credentials as JWE using JWKS public key
provider-resolver.ts # Detects active AI provider from env vars
discovery/
bareImports.ts # Extracts bare import specifiers from source files
dts.ts # Probes node_modules for entry .d.ts files
utils/
hash.ts # md5, readBase64, statSize via NodeFileStore
path.ts # Wire path encoding/decoding, external path remapping
graph TD
A[bin/auto.ts] --> B[src/index.ts<br/>Commander CLI]
B --> C[src/server.ts<br/>startServer]
C --> D["@auto-engineer/pipeline<br/>PipelineServer"]
C --> E[file-syncer/index.ts<br/>FileSyncer]
C --> F[config-loader.ts]
C --> G[tui/index.tsx]
B --> H[tunnel.ts<br/>ngrok + auth]
E --> I["@auto-engineer/file-store<br/>NodeFileStore"]
E --> J["@auto-engineer/narrative<br/>getScenes"]
E --> K[crypto/jwe-encryptor.ts]
E --> L[discovery/dts.ts]
E --> M[discovery/bareImports.ts]
| Package | Role |
|---|---|
@auto-engineer/pipeline |
Pipeline server, message bus, command handler registration |
@auto-engineer/narrative |
Scene graph and file discovery for sync (getScenes) |
@auto-engineer/file-store |
NodeFileStore virtual filesystem abstraction |
| Package | Role |
|---|---|
commander |
CLI argument parsing |
socket.io |
WebSocket-based file sync transport |
chokidar |
File system watcher |
ink / @inkjs/ui |
Terminal UI rendering (React-based) |
@ngrok/ngrok |
Public tunnel for remote access |
jose |
JWE encryption of AI provider credentials |
jiti |
Runtime TypeScript config loading |
get-port |
Finds available port |
ora |
Terminal spinner |