@startanaicompany/cli
v1.10.0
Published
Official CLI for StartAnAiCompany.com - Deploy AI recruitment sites with ease
Readme
@startanaicompany/cli
Official CLI for StartAnAiCompany.com - Deploy AI recruitment sites with ease
Features
- ✨ Simple & Intuitive - Deploy with a single command
- 🔐 Secure - Session token + OAuth-based authentication
- 🚀 Fast - Optimized for quick deployments
- 📦 Zero Configuration - Works out of the box
- 🎨 Beautiful CLI - Color-coded output and progress indicators
- 🔄 Auto-healing - Automatically fixes common deployment issues
- 🖥️ Remote Shell - Access your container via WebSocket (Project Aurora)
- 🔧 Remote Execution - Run commands inside your container
- 🗄️ Database Management - Direct access to PostgreSQL and Redis
- 📊 Real-time Logs - View runtime and deployment logs
Installation
npm install -g @startanaicompany/cliApplication Structure
SAAC applications require a standardized Docker Compose setup with three services: app, postgres, and redis.
Required docker-compose.yml
Your application must include these services for saac db commands to work:
📄 Reference: https://git.startanaicompany.com/StartAnAiCompanyTemplates/template_001/src/branch/master/docker-compose.yml
Required services:
app- Your Node.js application (exposes port 3000)postgres- PostgreSQL 16 databaseredis- Redis 7 cache
Key requirements:
- Service names must be exactly:
app,postgres,redis - App must include environment variables:
POSTGRES_HOST=postgres,REDIS_HOST=redis - All services must have health checks
- App must depend on postgres and redis being healthy
Example docker-compose.yml
services:
app:
build: .
environment:
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
expose:
- "3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 3s
retries: 2
postgres:
image: postgres:16-alpine
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 3
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
retries: 3
volumes:
postgres-data:
redis-data:Full configuration: https://git.startanaicompany.com/StartAnAiCompanyTemplates/template_001/src/branch/master/docker-compose.yml
Why These Services?
When you run saac db sql or saac db redis, the CLI connects to these containers within your application's Docker network. The standardized naming (postgres, redis) allows SAAC to automatically discover and manage your databases.
Quick Start
# 1. Register for an account
saac register -e [email protected]
# 2. Verify your email (check MailHog at https://mailhog.goryan.io)
saac verify 123456
# 3. Login with your API key (shown after verification)
saac login -e [email protected] -k cw_your_api_key_here
# 4. Connect your Git account (OAuth - required!)
saac git connect
# 5. Create a new application (requires docker-compose.yml with postgres + redis)
# Template: https://git.startanaicompany.com/StartAnAiCompanyTemplates/template_001/src/branch/master/docker-compose.yml
saac create my-app -s myapp -r [email protected]:user/repo.git
# 6. Deploy!
saac deploy
# 7. View logs
saac logs
# 8. Query your database
saac db sql "SELECT NOW()"
saac db redis PING
# 9. Access your container shell
saac shellTable of Contents
- Authentication
- Git OAuth
- Application Management
- Environment Variables
- Remote Access
- Database Management
- Logs & Monitoring
- Domain Management
- Complete Workflows
- Troubleshooting
Authentication
Register & Login
SAAC uses a session token-based authentication system for security and ease of use.
saac register -e <email>
Register for a new account. Your Git username will be auto-detected from your email.
# Register with email
saac register -e [email protected]
# With custom Git username (optional)
saac register -e [email protected] --git-username myusernameWhat happens:
- Account created in database
- Verification code sent to email
- You're prompted to verify your email
Required:
-e, --email <email>- Your email address
Optional:
--git-username <username>- Git username (auto-detected from email if not provided)
saac verify <code>
Verify your email address with the 6-digit code from your email.
saac verify 123456Important: The verification response shows your API key (starts with cw_). Save this immediately - it's only shown once!
✓ Email verified successfully!
Your API Key (save this now!):
cw_kgzfNByNNrtrDsAW07h6ORwTtP3POK6O98klH9Rm8jTt9ByHojeH7zDmGwaF
⚠️ This API key is shown only once. Store it securely!Where to check for codes: https://mailhog.goryan.io (development environment)
saac login -e <email> -k <api-key>
Login with your email and API key. This exchanges your permanent API key for a temporary session token (valid for 1 year).
saac login -e [email protected] -k cw_your_api_key_hereWhat happens:
- API key verified with backend
- Session token generated (valid for 1 year)
- Session token stored locally in
~/.config/startanaicompany/config.json - All future commands use session token automatically
Required:
-e, --email <email>- Your email address-k, --api-key <key>- Your API key (from verification step)
Alternative: OTP Login (Optional)
You can also login with a one-time password sent to your email:
saac login -e [email protected] --otp 123456Session Management
saac sessions
List all active sessions across all devices.
saac sessionsShows:
- Device/location
- Session creation date
- Last used timestamp
- IP address
- Expiration date
Example output:
Active Sessions
───────────────
Session 1
Created: Jan 26, 2026, 10:00 AM
Last Used: Jan 29, 2026, 9:00 AM
IP: 192.168.1.100
Expires: Jan 26, 2027
Session 2
Created: Jan 20, 2026, 2:00 PM
Last Used: Jan 28, 2026, 5:00 PM
IP: 10.0.0.50
Expires: Jan 20, 2027
Total: 2 active sessionssaac logout
Logout from current device (revokes current session token only).
saac logoutWhat happens:
- Current session token revoked on server
- Local config cleared
- Other devices remain logged in
saac logout-all [-y]
Logout from all devices (revokes all session tokens).
# With confirmation prompt
saac logout-all
# Skip confirmation
saac logout-all --yes
saac logout-all -yWhat happens:
- ALL session tokens revoked on server
- Local config cleared
- All devices logged out
- You'll need to login again on all devices
Use case: Security - if you suspect your session was compromised.
API Keys
saac keys show
Show your API key information (masked for security).
saac keys show
saac keys info # AliasShows:
- API key (masked)
- Creation date
- Last used timestamp
saac keys regenerate
Generate a new API key (invalidates the old one).
saac keys regenerate⚠️ Warning: Your old API key will stop working immediately! Save the new key securely.
What happens:
- Old API key invalidated
- New API key generated
- New key displayed (only shown once)
- You'll need to update any scripts/automation using the old key
saac whoami
Show current user information.
saac whoamiShows:
- User ID
- Verification status
- Member since date
- Connected Git accounts
- Application quotas
- Available commands
Environment Variables for CI/CD
The SAAC CLI supports automatic authentication via environment variables, perfect for CI/CD pipelines, Docker containers, and automation scripts.
How It Works
When you run any SAAC command:
- CLI checks if you're already logged in (session token exists)
- If not logged in, checks for
SAAC_USER_API_KEYandSAAC_USER_EMAILenvironment variables - If both are present, automatically logs in via API
- Session token is cached for subsequent commands (same performance as manual login)
Required Environment Variables
SAAC_USER_API_KEY- Your API key (format:cw_...)SAAC_USER_EMAIL- Your email address
Both variables must be set for auto-login to work.
Usage Examples
GitHub Actions
name: Deploy to SAAC
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install SAAC CLI
run: npm install -g @startanaicompany/cli
- name: Deploy Application
env:
SAAC_USER_API_KEY: ${{ secrets.SAAC_API_KEY }}
SAAC_USER_EMAIL: ${{ secrets.SAAC_EMAIL }}
run: |
saac deploy
saac logs --deploymentSetup:
- Go to your repo → Settings → Secrets → Actions
- Add
SAAC_API_KEYwith your API key - Add
SAAC_EMAILwith your email address
GitLab CI/CD
deploy:
stage: deploy
image: node:18
variables:
SAAC_USER_API_KEY: $CI_SAAC_API_KEY
SAAC_USER_EMAIL: $CI_SAAC_EMAIL
script:
- npm install -g @startanaicompany/cli
- saac deploy
- saac logs --deployment
only:
- mainSetup:
- Go to your project → Settings → CI/CD → Variables
- Add
CI_SAAC_API_KEY(protected, masked) - Add
CI_SAAC_EMAIL
Docker
FROM node:18
# Install SAAC CLI
RUN npm install -g @startanaicompany/cli
# Set environment variables (use build args for security)
ARG SAAC_API_KEY
ARG SAAC_EMAIL
ENV SAAC_USER_API_KEY=$SAAC_API_KEY
ENV SAAC_USER_EMAIL=$SAAC_EMAIL
# Your application code
WORKDIR /app
COPY . .
# Deploy on container startup
CMD ["sh", "-c", "saac deploy && npm start"]Build with secrets:
docker build \
--build-arg SAAC_API_KEY=cw_your_key \
--build-arg [email protected] \
-t my-app .Local Shell Script
#!/bin/bash
set -e
# Set environment variables
export SAAC_USER_API_KEY=cw_your_api_key_here
export [email protected]
# Run SAAC commands
saac deploy
saac logs --deployment
saac status
echo "Deployment complete!"With .env File (Local Development)
Create .env file (add to .gitignore!):
SAAC_USER_API_KEY=cw_your_api_key_here
[email protected]Use with a script:
#!/bin/bash
# Load .env file
set -a
source .env
set +a
# Run SAAC commands
saac list
saac statusSecurity Best Practices
✅ DO:
- Store API keys in secrets management (GitHub Secrets, GitLab Variables, AWS Secrets Manager, etc.)
- Use environment variables for automation
- Add
.envfiles to.gitignore - Rotate API keys periodically with
saac keys regenerate - Use different API keys for different environments (dev, staging, prod)
- Set secrets as "protected" and "masked" in CI/CD systems
❌ DON'T:
- Commit API keys to version control
- Share API keys in plain text (Slack, email, etc.)
- Hardcode API keys in scripts or Dockerfiles
- Use the same API key across multiple teams/projects
- Log API keys in CI/CD output
How It Differs from Manual Login
| Feature | Manual Login | Auto-Login (Env Vars) | |---------|--------------|----------------------| | Session token created | ✅ Yes | ✅ Yes | | Session cached locally | ✅ Yes | ✅ Yes | | Session expires | ✅ 1 year | ✅ 1 year | | Requires user interaction | ❌ No (after first login) | ✅ Fully automated | | Perfect for CI/CD | ⚠️ Requires manual setup | ✅ Native support | | Performance | ⚡ Fast (cached) | ⚡ Fast (cached after first auto-login) |
Troubleshooting
"Not logged in" despite setting environment variables:
- Verify both
SAAC_USER_API_KEYandSAAC_USER_EMAILare set:echo $SAAC_USER_API_KEY echo $SAAC_USER_EMAIL - Ensure API key is valid (not revoked or expired)
- Check API key format starts with
cw_ - Try logging in manually to verify credentials work:
saac login -e $SAAC_USER_EMAIL -k $SAAC_USER_API_KEY
Environment variables not being read:
- Make sure variables are exported:
export SAAC_USER_API_KEY=... - Check for typos in variable names (must be exact)
- In Docker, ensure ENV is set or use build args correctly
- In CI/CD, verify secrets are configured correctly
Security concerns:
- Never print environment variables in logs:
echo $SAAC_USER_API_KEY❌ - Use masked/protected secrets in CI/CD systems
- Regenerate API key if accidentally exposed:
saac keys regenerate - Monitor active sessions:
saac sessions
Example: Complete CI/CD Workflow
name: Full Deployment Workflow
on:
push:
branches: [main, staging]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install Dependencies
run: npm install
- name: Run Tests
run: npm test
- name: Install SAAC CLI
run: npm install -g @startanaicompany/cli
- name: Deploy to SAAC
env:
SAAC_USER_API_KEY: ${{ secrets.SAAC_API_KEY }}
SAAC_USER_EMAIL: ${{ secrets.SAAC_EMAIL }}
run: |
# Auto-login happens automatically!
saac deploy
# Wait for deployment to complete (built-in timeout)
echo "Deployment finished!"
- name: Check Application Status
env:
SAAC_USER_API_KEY: ${{ secrets.SAAC_API_KEY }}
SAAC_USER_EMAIL: ${{ secrets.SAAC_EMAIL }}
run: |
saac status
saac logs --deployment | tail -20
- name: Notify on Failure
if: failure()
run: |
echo "Deployment failed! Check logs with: saac logs --deployment"Git OAuth
SAAC CLI uses OAuth-only authentication for Git access. You must connect your Git account before creating applications.
Why OAuth?
Benefits:
- ✅ Connect once, deploy unlimited apps
- ✅ No need to remember or manually provide tokens
- ✅ Tokens stored encrypted on server (AES-256-GCM)
- ✅ Auto-refresh for expired tokens
- ✅ Supports multiple Git providers (Gitea, GitHub, GitLab)
- 🔒 More secure than manual token management
saac git connect [host]
Connect a Git account via OAuth.
# Interactive mode - select from providers
saac git connect
# Connect to specific host
saac git connect git.startanaicompany.com
# Connect from repository URL
saac git connect [email protected]:user/repo.gitWhat happens:
- Browser opens to OAuth authorization page
- You authorize on the Git provider
- CLI polls for completion (every 2 seconds, max 5 minutes)
- Connection saved encrypted on server
- Future app creations use this connection automatically
Example output:
Git OAuth Connection
────────────────────
ℹ Opening browser for OAuth authorization...
ℹ Authorize the application in your browser
⏳ Waiting for authorization... (0s)
✓ Git account connected successfully!
Provider: gitea
Host: git.startanaicompany.com
Username: ryan.gogo
Expires: Never (auto-refreshed)
ℹ You can now create applications without providing Git tokens:
saac create my-app -s myapp -r [email protected]:user/repo.gitsaac git list
List all connected Git accounts.
saac git list
saac git ls # AliasShows:
- Git host
- Username
- Provider (gitea/github/gitlab)
- Connection date
- Expiration (if applicable)
- Last used timestamp
Example output:
Connected Git Accounts
──────────────────────
┌─────────────────────────────┬────────────┬──────────┬──────────────┐
│ Host │ Username │ Provider │ Connected │
├─────────────────────────────┼────────────┼──────────┼──────────────┤
│ git.startanaicompany.com │ ryan.gogo │ gitea │ Jan 26, 2026 │
└─────────────────────────────┴────────────┴──────────┴──────────────┘
Total: 1 connection(s)saac git disconnect <host>
Disconnect (revoke) a Git account connection.
saac git disconnect git.startanaicompany.comWhat happens:
- OAuth token revoked on server
- Connection removed
- Existing applications continue to work
- New applications will require reconnection
saac git repos <host>
List repositories from a connected Git host.
# Basic usage
saac git repos git.startanaicompany.com
saac git repos github.com
# Include latest commit information
saac git repos github.com --commits
# Filter by visibility
saac git repos github.com --visibility private
saac git repos github.com --visibility public
# With pagination
saac git repos github.com --page 2 --per-page 10
# Sort repositories
saac git repos github.com --sort created
saac git repos github.com --sort name
# JSON output for scripting
saac git repos github.com --json
# Combine options
saac git repos github.com --commits --visibility private --per-page 20Options:
-p, --page <number>- Page number for pagination (default: 1)-n, --per-page <number>- Results per page, max 100 (default: 20)-s, --sort <type>- Sort order:updated,created,name(default:updated)-v, --visibility <type>- Filter:all,public,private(default:all)-c, --commits- Include latest commit info for each repository--json- Output as JSON for scripting
Shows:
- Repository name
- Visibility (public/private)
- Last updated timestamp
- Default branch
- Primary language
- Latest commit (with
--commitsflag)
Example output (without commits):
Repositories on git.startanaicompany.com (ryan.gogo)
────────────────────────────────────────────────────
NAME VISIBILITY UPDATED BRANCH LANGUAGE
mysimpleflowershop private 1/27/2026, 12:52:18 AM master JavaScript
api-server private 1/26/2026, 8:30:00 PM main TypeScript
landing-page public 1/25/2026, 3:15:00 PM master HTML
Showing 3 repositories (page 1)Example output (with --commits):
Repositories on git.startanaicompany.com (ryan.gogo)
────────────────────────────────────────────────────
NAME VISIBILITY LAST COMMIT
mysimpleflowershop private 4b2c63f Initial commit - Simple Flower (3d ago)
api-server private a90373d Add user authentication (1d ago)
landing-page public f1e2d3c Update homepage design (5h ago)
Showing 3 repositories (page 1)JSON output:
$ saac git repos github.com --json
{
"success": true,
"git_host": "github.com",
"username": "johndoe",
"provider_type": "github",
"repositories": [
{
"name": "my-app",
"fullName": "johndoe/my-app",
"description": "A cool application",
"private": false,
"sshUrl": "[email protected]:johndoe/my-app.git",
"cloneUrl": "https://github.com/johndoe/my-app.git",
"htmlUrl": "https://github.com/johndoe/my-app",
"defaultBranch": "main",
"updatedAt": "2026-01-30T12:00:00Z",
"language": "JavaScript",
"latestCommit": {
"sha": "abc1234",
"message": "Fix authentication bug",
"author": "John Doe",
"date": "2026-01-30T11:30:00Z"
}
}
],
"count": 1,
"page": 1,
"per_page": 100
}Use Cases:
- Browse available repositories before creating an application
- Find repository SSH URLs for
saac createcommand - Check latest commits without visiting Git provider
- Script repository discovery and automation
- Filter personal vs organization repositories
Performance Notes:
- Without
--commits: Fast (single API call) - With
--commits: Slower (fetches commit info for each repo in parallel) - Use
--commitsonly when you need commit information
Example Workflow:
# 1. Connect to Git host
saac git connect github.com
# 2. List your repositories
saac git repos github.com
# 3. Find the repository you want to deploy
saac git repos github.com --visibility private
# 4. Copy the SSH URL from the output
# 5. Create application with that repository
saac create my-app -s myapp -r [email protected]:username/my-app.gitApplication Management
saac init
Link an existing SAAC application to the current directory.
cd my-project
saac initUse case: When you:
- Clone a Git repository
- Have an existing project
- Want to manage an application from a different directory
Smart Auto-Detection (NEW!):
If you're in a Git repository, saac init automatically detects the remote URL and matches it to your applications:
$ cd mysimpleflowershop
$ saac init
Initialize SAAC Project
───────────────────────
✓ Found 3 application(s)
ℹ Auto-detected Git repository: [email protected]:ryan.gogo/mysimpleflowershop.git
Matched Application: mysimpleflowershop
Domain: mysimpleflowershop.startanaicompany.com
Status: running:healthy
? Link this application to the current directory? (Y/n) Yes
✓ Project initialized!
Application: mysimpleflowershop
UUID: abc123-def456...
Domain: mysimpleflowershop.startanaicompany.com
Status: running:healthy
You can now use:
saac deploy Deploy your application
saac logs --follow View deployment logs
saac status Check application status
saac update --port 8080 Update configurationHow Auto-Detection Works:
- Reads Git remote URL from
.git/config - Normalizes both Git remote and application repositories
- Matches against your applications automatically
- Asks for confirmation (defaults to Yes)
- Falls back to manual selection if no match found or if you decline
Supports:
- SSH URLs:
[email protected]:user/repo.git - HTTPS URLs:
https://github.com/user/repo.git - With or without
.gitsuffix - Case-insensitive matching
Manual Selection (fallback):
If not in a Git repository or no match found, shows interactive list:
$ saac init
? Select application to link to this directory:
❯ mysimpleflowershop - mysimpleflowershop.startanaicompany.com (running:healthy)
api-server - api.startanaicompany.com (running:healthy)
landing-page - landing.startanaicompany.com (stopped)What it saves:
Creates .saac/config.json in current directory:
{
"applicationUuid": "abc123-def456...",
"applicationName": "mysimpleflowershop",
"subdomain": "mysimpleflowershop",
"domainSuffix": "startanaicompany.com",
"gitRepository": "[email protected]:ryan.gogo/mysimpleflowershop.git"
}saac create <name>
Create a new application with full configuration options.
# Basic application (OAuth required!)
saac create my-app -s myapp -r [email protected]:user/repo.git
# Advanced with health checks and migrations
saac create api \
-s api \
-r [email protected]:user/api-server.git \
--build-pack nixpacks \
--port 8080 \
--pre-deploy-cmd "npm run migrate" \
--post-deploy-cmd "npm run seed" \
--health-check \
--health-path /api/health \
--health-interval 30 \
--health-timeout 10 \
--health-retries 3 \
--cpu-limit 2 \
--memory-limit 2G \
--env NODE_ENV=production \
--env LOG_LEVEL=debug \
--env DATABASE_URL=postgresql://...Prerequisites:
- ✅ You must be logged in:
saac login - ✅ You must connect Git account:
saac git connect
Required:
<name>- Application name (alphanumeric, hyphens allowed)-s, --subdomain <subdomain>- Subdomain (e.g.,myapp→myapp.startanaicompany.com)-r, --repository <url>- Git repository URL in SSH format
Basic Options:
-b, --branch <branch>- Git branch (default:master)-d, --domain-suffix <suffix>- Domain suffix (default:startanaicompany.com)-p, --port <port>- Port to expose (default:3000)
Build Pack Options:
--build-pack <pack>- Build system to use:nixpacks(default) - Auto-detects language and buildsdockerfile- Uses Dockerfile in repositorydockercompose- Uses docker-compose.ymlstatic- Static site hosting
Custom Commands:
--install-cmd <command>- Install command (e.g.,pnpm install)--build-cmd <command>- Build command (e.g.,npm run build)--start-cmd <command>- Start command (e.g.,node dist/server.js)--pre-deploy-cmd <command>- Pre-deployment hook (e.g.,npm run migrate)--post-deploy-cmd <command>- Post-deployment hook (e.g.,npm run seed)
Resource Limits:
--cpu-limit <limit>- CPU limit (e.g.,1,2.5)--memory-limit <limit>- Memory limit (e.g.,512M,1G,2G)
Note: Free tier limited to 1 vCPU, 1024M RAM. Upgrades required for higher limits.
Health Checks:
--health-check- Enable health checks--health-path <path>- Health check endpoint (default:/health)--health-interval <seconds>- Check interval (default: 30s)--health-timeout <seconds>- Check timeout (default: 10s)--health-retries <count>- Number of retries before marking unhealthy (1-10)
Environment Variables:
--env <KEY=VALUE>- Set environment variable (can be used multiple times)- Maximum 50 variables per application
Example with all features:
saac create production-api \
-s api \
-r [email protected]:company/api.git \
-b main \
--build-pack nixpacks \
--port 8080 \
--pre-deploy-cmd "npm run db:migrate" \
--start-cmd "node dist/index.js" \
--cpu-limit 2 \
--memory-limit 2G \
--health-check \
--health-path /api/health \
--health-interval 30 \
--health-timeout 10 \
--health-retries 3 \
--env NODE_ENV=production \
--env LOG_LEVEL=info \
--env DATABASE_URL=postgresql://user:pass@host/db \
--env REDIS_URL=redis://redis:6379What happens:
- Validates all inputs
- Checks Git OAuth connection
- Creates application on Coolify via wrapper API
- Saves configuration to
.saac/config.json - Shows next steps (deploy, logs, status)
saac update
Update application configuration after creation.
# Update port and enable health checks
saac update --port 8080 --health-check --health-path /api/health
# Switch to Nixpacks and update resource limits
saac update --build-pack nixpacks --cpu-limit 2 --memory-limit 2G
# Update custom commands
saac update --pre-deploy-cmd "npm run migrate" --start-cmd "npm start"
# Disable health checks
saac update --no-health-check
# Update environment variables
saac update --env NODE_ENV=production --env DEBUG=true
# Change restart policy
saac update --restart on-failureOptions: All options from create command can be updated individually.
Important: Configuration changes require redeployment to take effect:
saac deploySupported Updates:
- Basic: name, branch, port
- Build pack and custom commands
- Resource limits (subject to tier limits)
- Health checks (enable/disable and all parameters)
- Restart policy:
always,on-failure,unless-stopped,no - Environment variables
Note: Only the fields you specify will be updated (partial updates).
saac deploy [-f]
Trigger deployment of your application.
# Normal deployment
saac deploy
# Force deployment (rebuild from scratch)
saac deploy --force
saac deploy -fWhat happens:
- Validates authentication and project config
- Triggers deployment on Coolify via wrapper API
- Shows deployment ID and status
- Provides command to follow logs
Options:
-f, --force- Force rebuild (ignore cache)
Example output:
Deploying Application
─────────────────────
ℹ Application: mysimpleflowershop
ℹ Repository: [email protected]:user/repo.git
ℹ Branch: master
⏳ Triggering deployment...
✓ Deployment triggered successfully!
Status: queued
Deployment ID: dp_abc123def456
Domain: mysimpleflowershop.startanaicompany.com
ℹ Follow deployment logs:
saac logs --deploymentsaac deployments
View deployment history for your application.
# List recent deployments (default: 20)
saac deployments
saac deploys # Alias
# Show more deployments
saac deployments --limit 50
# Pagination
saac deployments --limit 20 --offset 20Options:
-l, --limit <number>- Number of deployments to show (default: 20)-o, --offset <number>- Offset for pagination (default: 0)
Shows:
- Deployment ID
- Status (finished, failed, running, queued)
- Started/finished timestamps
- Duration
- Commit hash and message
- Branch
Example output:
Deployment History: mysimpleflowershop
─────────────────────────────────────
┌──────────────────┬──────────┬─────────────┬──────────┬──────────────┐
│ ID │ Status │ Started │ Duration │ Commit │
├──────────────────┼──────────┼─────────────┼──────────┼──────────────┤
│ dp_abc123... │ finished │ 10:30 AM │ 45s │ a1b2c3d Fix │
│ dp_def456... │ failed │ 9:15 AM │ 12s │ e4f5g6h Add │
│ dp_ghi789... │ finished │ Yesterday │ 52s │ i7j8k9l Upd │
└──────────────────┴──────────┴─────────────┴──────────┴──────────────┘
Total: 3 deploymentssaac list
List all your applications.
saac list
saac ls # AliasShows:
- Application name
- Domain
- Status (running, stopped, error, etc.)
- Git branch
- Creation date
Example output:
Your Applications (3)
─────────────────────
┌──────────────────────┬──────────────────────────────────┬─────────────┬────────┬──────────────┐
│ Name │ Domain │ Status │ Branch │ Created │
├──────────────────────┼──────────────────────────────────┼─────────────┼────────┼──────────────┤
│ mysimpleflowershop │ shop.startanaicompany.com │ Running ✓ │ master │ Jan 26, 2026 │
│ api-server │ api.startanaicompany.com │ Running ✓ │ main │ Jan 20, 2026 │
│ landing-page │ landing.startanaicompany.com │ Stopped │ master │ Jan 15, 2026 │
└──────────────────────┴──────────────────────────────────┴─────────────┴────────┴──────────────┘
Total: 3 applicationssaac status
Show current application status and configuration.
saac statusShows:
- Application details (name, UUID, domain)
- Git repository and branch
- Current status (running/stopped/error)
- Resource usage (CPU, memory)
- Health check status
- Environment variables count
- Recent deployments
Example output:
Application Status
──────────────────
Name: mysimpleflowershop
UUID: abc123def456
Domain: shop.startanaicompany.com
Status: Running ✓
Branch: master
Repository: [email protected]:user/repo.git
Resources
─────────
CPU: 0.5 / 1.0 vCPU
Memory: 256M / 1024M
Health: Healthy ✓
Configuration
─────────────
Build Pack: nixpacks
Port: 3000
Env Variables: 5 / 50
Recent Deployments
──────────────────
Last Deploy: Jan 29, 2026, 10:30 AM (finished)
Duration: 45 seconds
Commit: a1b2c3d Fix bug in authsaac delete
Delete current application.
# With confirmation prompt
saac delete
# Skip confirmation
saac delete --yes
saac delete -y
# Alias
saac rm⚠️ Warning: This action is irreversible! All data will be deleted.
What gets deleted:
- Application container
- Environment variables
- Deployment history
- Logs
- Domain configuration
What stays:
- Git repository (not affected)
- Local
.saac/config.json(you can delete manually)
saac manual
Display full documentation from GitHub README.
saac manualFetches and displays the latest README.md from the GitHub repository.
Environment Variables
Manage environment variables for your application. Changes require redeployment to take effect.
saac env set <vars...>
Set or update environment variables.
# Set single variable
saac env set NODE_ENV=production
# Set multiple variables
saac env set NODE_ENV=production LOG_LEVEL=debug API_URL=https://api.example.com
# Set variable with special characters
saac env set DATABASE_URL="postgresql://user:p@ss!word@host:5432/db"
# Set variable with spaces (must quote the entire KEY=VALUE)
saac env set "WELCOME_MESSAGE=Hello World"Rules:
- Key format:
^[A-Z_][A-Z0-9_]*$(uppercase, alphanumeric, underscores) - Valid keys:
NODE_ENV,DATABASE_URL,API_KEY,LOG_LEVEL - Invalid keys:
node-env(hyphen),2KEY(starts with number),key!(special char) - Value length: 0-10,000 characters
- Maximum variables: 50 per application
Example output:
Updating Environment Variables
──────────────────────────────
ℹ Variables to set:
NODE_ENV: production
DATABASE_URL: postgresql://use***@32/db
API_KEY: sk_t***123
⏳ Updating environment variables...
✔ Environment variables updated successfully!
✓ Set 3 variable(s)
⚠ Changes require redeployment to take effect
ℹ Run:
saac deployImportant: Environment variable values with sensitive patterns are automatically masked in output:
PASSWORD,SECRET,KEY,TOKENDATABASE_URL,DB_URL,PRIVATE,AUTH
saac env get [key]
Get environment variable(s).
# Get all variables
saac env get
# Get specific variable
saac env get NODE_ENVExample output (all variables):
Environment Variables: mysimpleflowershop
┌───────────────────┬─────────────────────────────────────┐
│ Key │ Value │
├───────────────────┼─────────────────────────────────────┤
│ NODE_ENV │ production │
│ LOG_LEVEL │ debug │
│ DATABASE_URL │ post***@32/db │
│ API_KEY │ sk_t***123 │
│ PORT │ 3000 │
└───────────────────┴─────────────────────────────────────┘
Total: 5 / 50 variablesExample output (specific variable):
Environment Variable: NODE_ENV
Key: NODE_ENV
Value: productionsaac env list
List all environment variables (alias for saac env get).
saac env list
saac env ls # AliasNote: This is exactly the same as saac env get with no arguments.
Environment Variables Workflow
# 1. Set your environment variables
saac env set NODE_ENV=production \
DATABASE_URL=postgresql://user:pass@host:5432/db \
API_KEY=sk_test_123 \
LOG_LEVEL=info
# 2. Verify what you set
saac env list
# 3. Deploy to apply changes
saac deploy
# 4. Check if application started correctly
saac logs
# 5. Verify specific variable (if needed)
saac env get DATABASE_URLCommon Variables:
# Node.js applications
saac env set NODE_ENV=production \
PORT=3000 \
LOG_LEVEL=info
# Database connections
saac env set DATABASE_URL=postgresql://user:[email protected]:5432/myapp \
REDIS_URL=redis://redis:6379
# API keys and secrets
saac env set API_KEY=sk_live_... \
JWT_SECRET=your-secret-key \
STRIPE_SECRET_KEY=sk_live_...
# Application-specific
saac env set COMPANY_NAME="Acme Corp" \
PRIMARY_COLOR="#2563EB" \
[email protected]Remote Access
Access and execute commands inside your deployed container.
Remote Shell
Project Aurora - TRUE remote shell access via WebSocket.
saac shell
Open an interactive remote shell session inside your container.
saac shellWhat happens:
- Connects to container via WebSocket
- Creates or attaches to tmux session
- Gives you a bash prompt inside the container
- Session persists even if you disconnect
Features:
- ✅ Real bash prompt from container
- ✅ Working directory changes persist
- ✅ Access to all remote files and tools
- ✅ All environment variables available
- ✅ Interactive tools work (vim, nano, htop, etc.)
- ✅ Session persistence (up to 1 hour idle)
- ✅ Auto-reconnection on network interruption
Example session:
$ saac shell
═══════════════════════════════════════════════════════════════
Remote Shell: mysimpleflowershop
═══════════════════════════════════════════════════════════════
ℹ Connecting to container...
ℹ This may take up to 30 seconds for container creation.
✓ Connected to remote container
✓ Container is ready!
ℹ Type commands below. Press Ctrl+D or type "exit" to quit.
root@container-abc123:/app# ls -la
total 128
drwxr-xr-x 8 root root 4096 Jan 29 09:00 .
drwxr-xr-x 18 root root 4096 Jan 29 09:00 ..
-rw-r--r-- 1 root root 1245 Jan 29 09:00 package.json
drwxr-xr-x 2 root root 4096 Jan 29 09:00 node_modules
-rw-r--r-- 1 root root 543 Jan 29 09:00 server.js
root@container-abc123:/app# npm run test
> [email protected] test
> jest
PASS tests/auth.test.js
PASS tests/api.test.js
Test Suites: 2 passed, 2 total
Tests: 15 passed, 15 total
root@container-abc123:/app# echo $NODE_ENV
production
root@container-abc123:/app# exit
ℹ Disconnecting from remote shell...Exit shell:
- Type
exitorquit - Press
Ctrl+D
Session Persistence: If you close your terminal and reconnect within 1 hour, you'll resume the same session:
# Terminal 1 (close after cd command)
$ saac shell
root@container:/app# cd src
root@container:/app/src# [close terminal]
# Terminal 2 (5 minutes later, same machine)
$ saac shell
root@container:/app/src# pwd
/app/src ← Same session, same directory!Use Cases:
- Debug production issues
- Run database migrations manually
- Check file contents
- Install packages temporarily
- Monitor processes
- Test commands before adding to build scripts
Remote Execution
Run one-off commands inside your container without opening an interactive shell.
saac exec <command>
Execute a single command in the remote container.
# Run npm commands
saac exec "npm run db:migrate"
saac exec "npm test"
saac exec "npm run build"
# Check versions
saac exec "node --version"
saac exec "npm --version"
# File operations
saac exec "ls -la"
saac exec "cat package.json"
saac exec "pwd"
# Custom working directory
saac exec "npm test" --workdir /app/src
# Set timeout
saac exec "npm run build" --timeout 300Options:
--workdir <path>- Working directory (default:/app)--timeout <seconds>- Timeout in seconds (default: 30, max: 300)
Security & Command Allowlist:
For security, only specific commands are allowed. Commands are executed via the SSE command channel with ~500ms response time.
Allowed Commands:
- Node.js: npm, node, npx, yarn, pnpm
- Python: python, python3, pip, pip3, poetry
- Ruby: bundle, rake, rails, ruby
- Shell: sh, bash, echo, cat, ls, pwd, env
- Database: psql, mysql, mongosh
- Build: go, cargo, make, cmake
Blocked for Security:
- System commands:
whoami,ps,top,kill - Destructive operations:
rm,chmod,chown - Advanced shell features: pipes (
|), redirects (>), command substitution
Rate Limit: 60 commands per 5 minutes per user
If you try a blocked command, you'll see a clear error message:
✖ Command not allowed
✗ This command is blocked for security reasons
⚠ Command 'whoami' is not in allowlist. Allowed commands: ...Example output:
$ saac exec "npm run db:migrate"
Executing Command: npm run db:migrate
─────────────────────────────────────
⏳ Executing remotely...
Output:
───────
> [email protected] db:migrate
> knex migrate:latest
Batch 1 run: 3 migrations
✓ create_users_table
✓ create_posts_table
✓ create_comments_table
✓ Command executed successfully
Exit Code: 0
Duration: 2.5s
Workdir: /appsaac exec --history
View execution history.
# View recent executions
saac exec --history
# Show more history
saac exec --history --limit 50
# Pagination
saac exec --history --limit 20 --offset 20Options:
--limit <number>- Limit for history (default: 20, max: 100)--offset <number>- Offset for pagination (default: 0)
Shows:
- Command executed
- Exit code (success/failure)
- Duration
- Timestamp
- Working directory
Local Development
Run local commands with remote environment variables.
saac run <command>
Execute a command locally with environment variables from your remote application.
# Run local dev server with remote env vars
saac run npm run dev
# Run tests with remote database
saac run npm test
# Run migrations locally
saac run npm run migrate
# Force refresh env vars (skip cache)
saac run npm start --sync
# Quiet mode (suppress warnings)
saac run "node script.js" --quietWhat happens:
- Fetches environment variables from remote application
- Caches them locally for 1 hour
- Spawns your command with those env vars
- Command runs on your local machine (not in container)
Options:
--sync- Force refresh environment variables (skip cache)-q, --quiet- Quiet mode (suppress warnings)
Use Cases:
- Local development with production database
- Running migrations before deployment
- Testing with production API keys
- Debugging with real environment
Example:
$ saac run "node -e 'console.log(process.env.DATABASE_URL)'"
🚀 Running command with remote environment variables
Application: mysimpleflowershop
Variables: 5 loaded
Cache: Fresh (expires in 58m)
──────────────────────────────────────────────────────────────
postgresql://user:[email protected]:5432/myapp
✓ Command completed successfully⚠️ Security Warning: Remote secrets are exposed on your local machine. Only use this on trusted machines.
Database Management
Prerequisites: Your application must follow the SAAC docker-compose.yml structure with postgres and redis services.
👉 Required configuration: https://git.startanaicompany.com/StartAnAiCompanyTemplates/template_001/src/branch/master/docker-compose.yml
The saac db commands connect to these standardized service names in your Docker network.
Manage and query your application's databases directly from the CLI.
List Containers
saac db list
List all database containers for your application.
saac db list
saac db ls # AliasShows:
- Container name
- Type (postgres, redis, app)
- Status (running, healthy, stopped)
- Docker image
Example output:
Database Containers for my-app
───────────────────────────────
┌─────────────────────────────┬──────────┬────────────┬──────────────────┐
│ Container Name │ Type │ Status │ Image │
├─────────────────────────────┼──────────┼────────────┼──────────────────┤
│ postgres-abc123-456def │ postgres │ healthy │ postgres:15 │
│ redis-abc123-456def │ redis │ healthy │ redis:7 │
│ app-abc123-456def │ app │ running │ node:18 │
└─────────────────────────────┴──────────┴────────────┴──────────────────┘SQL Queries
saac db sql <query>
Execute SQL queries on your PostgreSQL database.
# Simple SELECT query
saac db sql "SELECT NOW()"
# Query your data
saac db sql "SELECT * FROM users LIMIT 10"
# Count records
saac db sql "SELECT COUNT(*) FROM posts"
# Specify database name (optional)
saac db sql "SELECT version()" --db my_database
# Write operations (CREATE, INSERT, UPDATE, DELETE)
saac db sql "INSERT INTO users (name, email) VALUES ('John', '[email protected]')" --write
saac db sql "UPDATE users SET active = true WHERE id = 123" --write
saac db sql "DELETE FROM sessions WHERE expires_at < NOW()" --writeOptions:
--db <name>- Database name (default: from environment variables)--write- Allow write operations (INSERT, UPDATE, DELETE, CREATE, DROP)
Security:
- Read-only by default (SELECT, SHOW, DESCRIBE, EXPLAIN)
- Write operations require
--writeflag - Dangerous operations (DROP, TRUNCATE) require
--writeflag - Rate limit: 60 queries per 5 minutes
Example output:
$ saac db sql "SELECT * FROM users LIMIT 3"
Executing SQL Query on my-app
──────────────────────────────
┌────┬─────────────┬──────────────────┬────────────────────┐
│ id │ name │ email │ created_at │
├────┼─────────────┼──────────────────┼────────────────────┤
│ 1 │ Alice │ [email protected]│ 2026-02-15 10:00:00│
│ 2 │ Bob │ [email protected] │ 2026-02-15 11:30:00│
│ 3 │ Charlie │ [email protected] │ 2026-02-16 09:15:00│
└────┴─────────────┴──────────────────┴────────────────────┘
Rows returned: 3Redis Commands
saac db redis <command>
Execute Redis commands.
# Test connection
saac db redis PING
# Get a key
saac db redis GET mykey
# Set a key
saac db redis SET mykey "hello world"
# Hash operations
saac db redis HSET user:123 name "John"
saac db redis HGETALL user:123
# List operations
saac db redis LPUSH mylist "item1"
saac db redis LRANGE mylist 0 -1
# Check key existence
saac db redis EXISTS mykey
# Get key type
saac db redis TYPE mykeySupported Commands:
- String: GET, SET, APPEND, INCR, DECR
- Hash: HGET, HSET, HGETALL, HDEL
- List: LPUSH, RPUSH, LRANGE, LLEN
- Set: SADD, SMEMBERS, SISMEMBER
- Sorted Set: ZADD, ZRANGE, ZSCORE
- Key: EXISTS, DEL, TYPE, EXPIRE, TTL
- Info: PING, INFO, DBSIZE
Blocked Commands (for safety):
- FLUSHDB, FLUSHALL (data loss)
- CONFIG (security)
- SHUTDOWN (availability)
Example output:
$ saac db redis GET user:session:abc123
Executing Redis Command on my-app
──────────────────────────────────
Command: GET user:session:abc123
✓ Result:
{"userId":"123","expires":"2026-02-20T10:00:00Z"}Connection Info
saac db info
Show database connection information.
saac db infoShows:
- PostgreSQL host, port, database name
- Redis host, port
- Internal network addresses
Example output:
Database Connection Info for my-app
────────────────────────────────────
✓ PostgreSQL:
Host: postgres.internal
Port: 5432
Database: myapp_db
✓ Redis:
Host: redis.internal
Port: 6379
ℹ Note: These are internal network addresses
(only accessible within the application network)Database Management Workflows
Create table and insert data:
# 1. Create table
saac db sql "CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(100), email VARCHAR(100))" --write
# 2. Insert data
saac db sql "INSERT INTO users (name, email) VALUES ('Alice', '[email protected]')" --write
# 3. Query data
saac db sql "SELECT * FROM users"Redis caching workflow:
# 1. Set cache value
saac db redis SET cache:users:123 "{\"name\":\"Alice\",\"email\":\"[email protected]\"}"
# 2. Get cache value
saac db redis GET cache:users:123
# 3. Set expiration
saac db redis EXPIRE cache:users:123 3600
# 4. Check TTL
saac db redis TTL cache:users:123Check database health:
# List all containers
saac db list
# Check PostgreSQL version
saac db sql "SELECT version()"
# Test Redis connection
saac db redis PING
# View connection details
saac db infoLogs & Monitoring
View runtime logs and deployment logs for your application.
saac logs
View runtime logs (container stdout/stderr).
# View recent logs
saac logs
# Show more lines
saac logs --tail 200
# Follow logs in real-time (not yet implemented)
saac logs --follow
# Show logs since timestamp
saac logs --since "2026-01-29T10:00:00Z"Options:
-t, --tail <lines>- Number of lines to show (default: 100)-f, --follow- Follow log output (live streaming - not yet implemented)--since <time>- Show logs since timestamp
Example output:
Runtime Logs: mysimpleflowershop
───────────────────────────────
> [email protected] start
> node server.js
Server running on port 3000
[2026-01-29T10:30:00.000Z] INFO: Database connected
[2026-01-29T10:30:01.123Z] INFO: Application started successfully
[2026-01-29T10:30:15.456Z] INFO: GET /api/users 200 25ms
[2026-01-29T10:30:16.789Z] INFO: GET /api/posts 200 15ms
[2026-01-29T10:31:00.000Z] WARN: Slow query detected (1.2s)saac logs --deployment [uuid]
View deployment logs (build logs).
# View latest deployment logs
saac logs --deployment
# View specific deployment logs
saac logs --deployment dp_abc123def456
# Raw log format (no coloring)
saac logs --deployment --raw
# Include hidden lines (debug output)
saac logs --deployment --include-hidden
# Short form
saac logs -d
saac logs -d dp_abc123def456Options:
-d, --deployment [uuid]- View deployment logs (if UUID omitted, shows latest)--raw- Show raw log output (deployment logs only)--include-hidden- Include hidden log lines (deployment logs only)
Example output:
Deployment Logs: mysimpleflowershop
───────────────────────────────────
Deployment UUID: dp_abc123def456
Application: mysimpleflowershop
Status: finished
Commit: a1b2c3d
Message: Fix authentication bug
Started: Jan 29, 2026, 10:30:00 AM
Finished: Jan 29, 2026, 10:30:45 AM
Duration: 45s
Log Output (234 lines):
────────────────────────────────────────────────────────────
[00:00:01] Cloning repository...
[00:00:03] Checking out branch: master
[00:00:05] Detecting language: Node.js
[00:00:06] Installing dependencies...
[00:00:15] Running npm install...
[00:00:25] Building application...
[00:00:30] Running npm run build...
[00:00:40] Build completed successfully
[00:00:42] Creating container image...
[00:00:44] Pushing image to registry...
[00:00:45] ✓ Deployment completedLog Monitoring Workflow
# 1. Deploy application
saac deploy
# 2. Watch deployment progress
saac logs --deployment
# 3. If deployment succeeds, check runtime logs
saac logs --tail 100
# 4. Monitor for errors
saac logs | grep ERROR
# 5. Follow logs (when implemented)
saac logs --followDomain Management
Manage your application's domain and subdomain.
saac domain show
Show current domain configuration.
saac domain showShows:
- Current domain
- Subdomain
- Domain suffix
- SSL status (if applicable)
Example output:
Domain Configuration
────────────────────
Domain: mysimpleflowershop.startanaicompany.com
Subdomain: mysimpleflowershop
Suffix: startanaicompany.com
SSL: Enabled ✓saac domain set <subdomain>
Change your application's subdomain.
# Change subdomain
saac domain set newsubdomain
# With custom domain suffix
saac domain set myapp --domain-suffix customdomain.com
saac domain set myapp -d customdomain.comOptions:
-d, --domain-suffix <suffix>- Domain suffix (default: startanaicompany.com)
What happens:
- Updates domain configuration
- Reconfigures routing
- Issues new SSL certificate (if applicable)
- Old domain redirects to new domain
Important: You may need to redeploy for changes to take full effect:
saac deployComplete Workflows
First-Time Setup (From Scratch)
# 1. Register account
saac register -e [email protected]
# 2. Check email for verification code
# Visit: https://mailhog.goryan.io
# 3. Verify email (save API key shown after verification!)
saac verify 123456
# 4. Login with API key
saac login -e [email protected] -k cw_abc123...
# 5. Connect Git account (required for creating apps)
saac git connect git.startanaicompany.com
# 6. Clone or create your project
git clone [email protected]:company/myapp.git
cd myapp
# 7. Create SAAC application
saac create myapp \
-s myapp \
-r [email protected]:company/myapp.git \
-b main \
--env NODE_ENV=production
# 8. Deploy
saac deploy
# 9. View logs
saac logs --deployment
# 10. Check application
saac status
# 11. Access shell if needed
saac shellExisting Application (Link to Directory)
# 1. Login (if not already logged in)
saac login -e [email protected] -k cw_abc123...
# 2. Clone the repository
git clone [email protected]:company/existing-app.git
cd existing-app
# 3. Link to existing SAAC application
saac init
# Select "existing-app" from the list
# 4. Now you can manage it
saac deploy
saac logs
saac statusEnvironment Variables Management
# 1. View current environment variables
saac env list
# 2. Set new variables
saac env set NODE_ENV=production \
DATABASE_URL=postgresql://user:pass@host:5432/db \
API_KEY=sk_live_123 \
LOG_LEVEL=info
# 3. Verify they were set
saac env list
# 4. Deploy to apply changes
saac deploy
# 5. Check if application started correctly
saac logs
# 6. Test specific variable (if needed)
saac env get DATABASE_URLDebugging Production Issues
# 1. Check application status
saac status
# 2. View runtime logs
saac logs --tail 200
# 3. Look for errors
saac logs | grep ERROR
# 4. Access container shell
saac shell
# Inside container:
root@container:/app# ps aux
root@container:/app# df -h
root@container:/app# cat /app/logs/error.log
root@container:/app# npm run db:status
root@container:/app# exit
# 5. Run one-off diagnostic command
saac exec "node scripts/health-check.js"
# 6. Check environment variables
saac env list
# 7. View recent deployments
saac deployments
# 8. Check specific deployment logs
saac logs --deployment dp_abc123Local Development with Remote Env
# 1. Ensure you're in project directory
cd ~/myapp
# 2. Link to SAAC application (if not already)
saac init
# 3. Run local development server with remote env vars
saac run npm run dev
# 4. Run tests with remote database
saac run npm test
# 5. Run migrations locally (against remote database)
saac run npm run migrate
# 6. Run custom scripts
saac run "node scripts/seed-data.js"Multi-Environment Setup
# Development environment
saac create myapp-dev \
-s myapp-dev \
-r [email protected]:company/myapp.git \
-b develop \
--env NODE_ENV=development \
--env LOG_LEVEL=debug
# Staging environment
saac create myapp-staging \
-s myapp-staging \
-r [email protected]:company/myapp.git \
-b staging \
--env NODE_ENV=staging \
--env LOG_LEVEL=info
# Production environment
saac create myapp-prod \
-s myapp \
-r [email protected]:company/myapp.git \
-b main \
--env NODE_ENV=production \
--env LOG_LEVEL=warn \
--health-check \
--health-path /api/health \
--cpu-limit 2 \
--memory-limit 2G
# Switch between environments using different directories
mkdir -p ~/projects/myapp-dev ~/projects/myapp-staging ~/projects/myapp-prod
cd ~/projects/myapp-dev
saac init # Select myapp-dev
saac deploy
cd ~/projects/myapp-staging
saac init # Select myapp-staging
saac deploy
cd ~/projects/myapp-prod
saac init # Select myapp-prod
saac deployTroubleshooting
Authentication Issues
"Not logged in"
Problem: Session token expired or not found.
Solution:
saac login -e [email protected] -k cw_your_api_keyIf you lost your API key:
# You need to have a valid session first (via OTP)
# Contact support or check MailHog for OTP login
# Then regenerate API key
saac keys regenerate"Invalid or expired session token"
Problem: Session token expired (valid for 1 year).
Solution:
saac logout
saac login -e [email protected] -k cw_your_api_key"Email not verified"
Problem: You registered but didn't verify your email.
Solution:
# Check MailHog for verification code
# Visit: https://mailhog.goryan.io
# Verify with code
saac verify 123456Git OAuth Issues
"Git account not connected"
Problem: You must connect your Git account before creating applications.
Solution:
saac git connect
# Or specify host directly
saac git connect git.startanaicompany.com"OAuth authorization failed"
Problem: Browser OAuth flow was cancelled or failed.
Solution:
# Try again with specific host
saac git connect git.startanaicompany.com
# If browser doesn't open automatically, copy the URL from the terminal"OAuth connection expired"
Problem: OAuth token expired or was revoked.
Solution:
# Disconnect and reconnect
saac git disconnect git.startanaicompany.com
saac git connect git.startanaicompany.comApplication Issues
"No application found in current directory"
Problem: No .saac/config.json file in current directory.
Solution:
# Link to existing application
saac init
# Or create new application
saac create myapp -s myapp -r git@git..."Application not found" (404)
Problem: Application UUID is incorrect or application was deleted.
Solution:
# List all your applications
saac list
# Re-initialize with correct application
saac initDeployment Issues
Deployment fails
Problem: Various reasons - check logs.
Solution:
# View deployment logs to see what went wrong
saac logs --deployment
# Common issues:
# - Build errors: Check your package.json, Dockerfile, etc.
# - Missing dependencies: Ensure all dependencies are in package.json
# - Port conflicts: Check --port setting
# - Resource limits: Free tier is limited to 1 vCPU, 1GB RAM
# Try force deploy (rebuild from scratch)
saac deploy --force"Health check failed"
Problem: Health check endpoint not responding or returning errors.
Solution:
# 1. Check if health endpoint exists
saac shell
root@container:/app# curl localhost:3000/health
# 2. View logs for errors
saac logs
# 3. Temporarily disable health checks
saac update --no-health-check
saac deploy
# 4. Fix your health endpoint, re-enable health checks
saac update --health-check --health-path /api/health
saac deployEnvironment Variables Issues
"Failed to fetch environment variables" (500 error)
Problem: Backend database schema issue (known bug as of Jan 29, 2026).
Reported to backend team: Column name mismatch in database query.
Workaround: Setting variables works fine:
# Setting works
saac env set KEY=value
# Listing fails (backend issue)
saac env list # Returns 500
# Wait for backend team to fix database schemaChanges not taking effect
Problem: Environment variable changes require redeployment.
Solution:
# After setting env vars, always redeploy
saac env set NODE_ENV=production
saac deployLogs Issues
"No logs available"
Problem: Application not deployed yet or container not running.
Solution:
# Check application status
saac status
# Deploy if not deployed
saac deploy
# Wait a moment for container to start
sleep 10
# Try logs again
saac logs"result.logs.forEach is not a function"
Problem: Fixed in version 1.4.20. Update your CLI.
Solution:
npm update -g @startanaicompany/cliShell Issues
"Connection timeout"
Problem: Container taking too long to start or network issues.
Solution:
# Check application status
saac status
# Ensure application is running
saac deploy
# Wait for deployment to complete
saac logs --deployment
# Try shell again
saac shell"WebSocket connection failed"
Problem: Backend WebSocket server not available (Project Aurora not deployed yet).
Status: As of Jan 29, 2026, Project Aurora WebSocket infrastructure awaiting backend deployment.
Workaround: Use saac exec for one-off commands:
saac exec "npm run migrate"
saac exec "node --version"
saac exec "ls -la"General Debugging
# Check CLI version
saac --version
# Show help
saac --help
# Check what command does
saac logs --help
saac deploy --help
# View user information
saac whoami
# List all applications
saac list
# Check application status
saac status
# View session information
saac sessions
# Test API connectivity (manual command from GitHub)
saac manualConfiguration Files
Global Configuration
Location: ~/.config/startanaicompany/config.json
Contains:
- API URL
- User credentials (email, userId, sessionToken)
- Session expiration timestamp
- Verification status
Example:
{
"apiUrl": "https://apps.startanaicompany.com/api/v1",
"user": {
"email": "[email protected]",
"userId": "a2c37076-1b0e-4b9a-80f8-31ef39766096",
"sessionToken": "st_kgzfNByNNrtrDsAW07h6ORwTtP3POK6O98klH9Rm8jTt9ByHojeH7zDmGwaF",
"expiresAt": "2027-01-29T09:00:00.000Z",
"verified": true
}
}Note: Managed by the CLI. Do not edit manually unless troubleshooting.
Project Configuration
Location: .saac/config.json (in your project directory)
Contains:
- Application UUID
- Application name
- Subdomain
- Domain suffix
- Git repository
Example:
{
"applicationUuid": "h884go4s4080kwk4808sw0wc",
"applicationName": "mysimpleflowershop",
"subdomain": "shop",
"domainSuffix": "startanaicompany.com",
"gitRepository": "[email protected]:company/myapp.git"
}Note: Created automatically by saac create or saac init.
.gitignore
Add to your .gitignore:
# SAAC CLI config (can be project-specific, commit if shared)
.saac/config.json
# Or keep it if your team shares the same SAAC application
# .saac/config.jsonFor LLMs: How to Use This Tool
Quick Reference
Authentication Flow:
saac register -e [email protected]→ Register- Check email for code → Get verification code
saac verify 123456→ Verify (save API key!)saac login -e [email protected] -k cw_...→ Login (gets session token)
Git OAuth (Required for App Creation):
saac git connect→ Connect Git account- Browser opens → Authorize
- Now you can create apps
Application Management:
saac create name -s subdomain -r git@git...→ Createsaac deploy→ Deploysaac logs→ View logssaac shell→ Access container
Environment Variables:
saac env set KEY=value KEY2=value2→ Setsaac env list→ Listsaac deploy→ Deploy to apply changes
Common Commands:
saac list→ List all applicationssaac status→ Show application statussaac logs→ Runtime logssaac logs --deployment→ Build logssaac shell→ Interactive shell in containersaac exec "command"→ Run command in containersaac run npm start→ Run local command with remote env vars
Key Concepts for LLMs
Session Tokens: Login with API key to get session token (valid 1 year). CLI handles this automatically.
Git OAuth Required: You MUST connect Git account (
saac git connect) before creating applications.Project Context: Most commands require
.saac/config.jsonin current directory (created bycreateorinit).Environment Variables: Changes require redeployment (
saac deploy) to take effect.Two Types of Logs:
- Runtime logs:
saac logs(container stdout/stderr) - Deployment logs:
saac logs --deployment(build output)
- Runtime logs:
Remote Access:
saac shell- Interactive shell (like SSH)saac exec- One-off command executionsaac run- Local command with remote env vars
Project Aurora: WebSocket-based remote shell providing TRUE container access (not local shell with env vars).
Common Patterns
Create and Deploy:
saac create myapp -s myapp -r [email protected]:user/repo.git --env NODE_ENV=production
saac deploy
saac logs --deployment
saac logsUpdate Configuration:
saac update --port 8080 --health-check
saac deployDebug Issues:
saac status
saac logs