@startanaicompany/cli 1.0.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md ADDED
@@ -0,0 +1,358 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ SAAC CLI is the official command-line interface for StartAnAiCompany.com, enabling users to deploy AI recruitment sites through a wrapper API that interfaces with Coolify. The CLI is built with Node.js and uses the Commander.js framework for command structure.
8
+
9
+ ## Key Commands
10
+
11
+ ### Development
12
+ ```bash
13
+ # Run CLI locally during development
14
+ npm run dev
15
+
16
+ # Lint code
17
+ npm run lint
18
+
19
+ # Link for local testing
20
+ npm link
21
+ ```
22
+
23
+ ### After linking, test with:
24
+ ```bash
25
+ saac --help
26
+ saac register
27
+ saac login
28
+ ```
29
+
30
+ ## Architecture
31
+
32
+ ### Configuration System (Dual-Level)
33
+
34
+ The CLI maintains two separate configuration files:
35
+
36
+ 1. **Global Config** (`~/.config/startanaicompany/config.json`)
37
+ - Managed by the `conf` package with custom cwd path
38
+ - Stores user credentials (email, userId, sessionToken, expiresAt)
39
+ - Stores API URLs (wrapper API, Git server)
40
+ - Persists across all projects
41
+ - Note: Uses explicit path to avoid `-nodejs` suffix that Conf adds by default
42
+
43
+ 2. **Project Config** (`.saac/config.json` in project directory)
44
+ - Manually managed via fs operations
45
+ - Stores application-specific data (applicationUuid, applicationName, subdomain, gitRepository)
46
+ - Required for deployment commands
47
+
48
+ **Important Pattern**: Commands check both configs:
49
+ - Authentication commands → global config only
50
+ - Deployment/management commands → require BOTH global config (for auth) and project config (for app UUID)
51
+
52
+ ### API Client (`src/lib/api.js`)
53
+
54
+ Creates axios instances with:
55
+ - Base URL from global config
56
+ - X-API-Key header automatically injected from global config
57
+ - 30-second timeout
58
+ - All API functions are async and return response.data
59
+
60
+ **API Wrapper Endpoints**:
61
+ - `/register` - Create new user account
62
+ - `/users/verify` - Email verification
63
+ - `/users/me` - Get current user info
64
+ - `/applications` - CRUD operations for apps
65
+ - `/applications/:uuid/deploy` - Trigger deployment
66
+ - `/applications/:uuid/logs` - Fetch logs
67
+ - `/applications/:uuid/env` - Manage environment variables
68
+ - `/applications/:uuid/domain` - Update domain settings
69
+
70
+ ### Logger (`src/lib/logger.js`)
71
+
72
+ Centralized logging utility using chalk, ora, and boxen:
73
+ - `logger.success()` - Green checkmark messages
74
+ - `logger.error()` - Red X messages
75
+ - `logger.warn()` - Yellow warning symbol
76
+ - `logger.info()` - Blue info symbol
77
+ - `logger.spinner(text)` - Returns ora spinner instance
78
+ - `logger.section(title)` - Bold cyan headers with underline
79
+ - `logger.field(key, value)` - Key-value pair display
80
+ - `logger.box(message, options)` - Boxed messages
81
+
82
+ **Pattern**: Use spinners for async operations:
83
+ ```javascript
84
+ const spin = logger.spinner('Processing...').start();
85
+ try {
86
+ await someAsyncOperation();
87
+ spin.succeed('Done!');
88
+ } catch (error) {
89
+ spin.fail('Failed');
90
+ throw error;
91
+ }
92
+ ```
93
+
94
+ ### Command Structure
95
+
96
+ All commands follow this pattern:
97
+ 1. **Validate required flags** - Show usage if missing (commands are non-interactive by default)
98
+ 2. Import required libraries (api, config, logger)
99
+ 3. Check authentication with `isAuthenticated()` (validates session token expiration)
100
+ 4. Check project config if needed with `getProjectConfig()`
101
+ 5. Execute operation with spinner feedback
102
+ 6. Handle errors and exit with appropriate code
103
+
104
+ **Important:** Commands require flags and do NOT use interactive prompts. This makes them LLM and automation-friendly.
105
+
106
+ **Examples:**
107
+ ```bash
108
+ # ✅ Correct - with flags
109
+ saac register -e user@example.com
110
+ saac login -e user@example.com -k cw_api_key
111
+
112
+ # ❌ Wrong - will show usage error
113
+ saac register
114
+ saac login
115
+ ```
116
+
117
+ **Command Files**:
118
+ - Authentication: `register.js`, `login.js`, `verify.js`, `logout.js`, `whoami.js`
119
+ - App Management: `create.js`, `init.js`, `deploy.js`, `delete.js`, `list.js`, `status.js`
120
+ - Configuration: `env.js`, `domain.js`
121
+ - Logs: `logs.js`
122
+
123
+ ### Entry Point (`bin/saac.js`)
124
+
125
+ Uses Commander.js to define:
126
+ - Commands with options and aliases
127
+ - Nested commands (e.g., `env set`, `env get`, `domain set`)
128
+ - Help text and version info
129
+ - Error handling for invalid commands
130
+
131
+ ## Important Patterns
132
+
133
+ ### Authentication Flow
134
+
135
+ **Session Token Flow (Primary):**
136
+ 1. User registers with email → API returns session token (1 year expiration)
137
+ 2. Session token stored in global config with expiration timestamp
138
+ 3. Verification code sent to MailHog (not real email)
139
+ 4. User verifies → verified flag set to true
140
+ 5. All subsequent API requests include X-Session-Token header
141
+ 6. Token expires after 1 year → user must login again
142
+
143
+ **API Key Flow (CI/CD & Scripts):**
144
+ 1. User logs in with email + API key → API returns session token
145
+ 2. Environment variable `SAAC_API_KEY` can override stored credentials
146
+ 3. Useful for automation, scripts, and CI/CD pipelines
147
+
148
+ **Authentication Priority:**
149
+ ```javascript
150
+ // In api.js createClient()
151
+ if (process.env.SAAC_API_KEY) {
152
+ headers['X-API-Key'] = SAAC_API_KEY; // 1st priority
153
+ } else if (user.sessionToken) {
154
+ headers['X-Session-Token'] = sessionToken; // 2nd priority
155
+ } else if (user.apiKey) {
156
+ headers['X-API-Key'] = apiKey; // 3rd priority (backward compat)
157
+ }
158
+ ```
159
+
160
+ ### Application Lifecycle
161
+
162
+ 1. **Create/Init** → applicationUuid saved to `.saac/config.json`
163
+ 2. **Deploy** → POST to `/applications/:uuid/deploy`
164
+ 3. **Monitor** → GET `/applications/:uuid/logs`
165
+ 4. **Update** → PATCH environment or domain
166
+ 5. **Delete** → DELETE `/applications/:uuid`
167
+
168
+ ### Error Handling Convention
169
+
170
+ All commands use try-catch with:
171
+ ```javascript
172
+ try {
173
+ // command logic
174
+ } catch (error) {
175
+ logger.error(error.response?.data?.message || error.message);
176
+ process.exit(1);
177
+ }
178
+ ```
179
+
180
+ This pattern extracts API error messages or falls back to generic error message.
181
+
182
+ ## Development Notes
183
+
184
+ ### Session Token Implementation
185
+
186
+ The CLI now uses session tokens instead of storing permanent API keys:
187
+
188
+ **Config Storage** (`~/.saac/config.json`):
189
+ ```json
190
+ {
191
+ "user": {
192
+ "email": "user@example.com",
193
+ "userId": "uuid",
194
+ "sessionToken": "st_...",
195
+ "expiresAt": "2026-01-25T12:00:00Z",
196
+ "verified": true
197
+ }
198
+ }
199
+ ```
200
+
201
+ **Token Validation Functions** (in `config.js`):
202
+ - `isAuthenticated()` - Checks if user has valid, non-expired token
203
+ - `isTokenExpired()` - Checks if session token has expired
204
+ - `isTokenExpiringSoon()` - Checks if token expires within 7 days
205
+
206
+ **Backend Requirements:**
207
+ - `POST /auth/login` - Accepts `X-API-Key` + email, returns session token
208
+ - Middleware must accept both `X-Session-Token` and `X-API-Key` headers
209
+ - Session tokens expire after 1 year
210
+
211
+ ### Create Command Implementation
212
+
213
+ The `create` command is fully implemented with ALL backend features:
214
+
215
+ **Required Options:**
216
+ - `-s, --subdomain` - Subdomain for the application
217
+ - `-r, --repository` - Git repository URL (SSH format)
218
+ - `-t, --git-token` - Git API token for repository access
219
+
220
+ **Optional Basic Configuration:**
221
+ - `-b, --branch` - Git branch (default: master)
222
+ - `-d, --domain-suffix` - Domain suffix (default: startanaicompany.com)
223
+ - `-p, --port` - Port to expose (default: 3000)
224
+
225
+ **Build Pack Options:**
226
+ - `--build-pack` - Build system: dockercompose, nixpacks, dockerfile, static
227
+ - `--install-cmd` - Custom install command (e.g., "pnpm install")
228
+ - `--build-cmd` - Custom build command (e.g., "npm run build")
229
+ - `--start-cmd` - Custom start command (e.g., "node server.js")
230
+ - `--pre-deploy-cmd` - Pre-deployment hook (e.g., "npm run migrate")
231
+ - `--post-deploy-cmd` - Post-deployment hook (e.g., "npm run seed")
232
+
233
+ **Resource Limits:**
234
+ - `--cpu-limit` - CPU limit (e.g., "1", "2.5")
235
+ - `--memory-limit` - Memory limit (e.g., "512M", "2G")
236
+ - Note: Free tier limited to 1 vCPU, 1024M RAM
237
+
238
+ **Health Checks:**
239
+ - `--health-check` - Enable health checks
240
+ - `--health-path` - Health check endpoint (default: /health)
241
+ - `--health-interval` - Check interval in seconds
242
+ - `--health-timeout` - Check timeout in seconds
243
+ - `--health-retries` - Number of retries (1-10)
244
+
245
+ **Environment Variables:**
246
+ - `--env KEY=VALUE` - Can be used multiple times (max 50 variables)
247
+
248
+ **Examples:**
249
+ ```bash
250
+ # Basic application
251
+ saac create my-app -s myapp -r git@git.startanaicompany.com:user/repo.git -t abc123
252
+
253
+ # With build pack and custom port
254
+ saac create api -s api -r git@git... -t abc123 --build-pack nixpacks --port 8080
255
+
256
+ # With health checks and pre-deployment migration
257
+ saac create web -s web -r git@git... -t abc123 \
258
+ --health-check \
259
+ --pre-deploy-cmd "npm run migrate" \
260
+ --env NODE_ENV=production \
261
+ --env LOG_LEVEL=info
262
+ ```
263
+
264
+ **Implementation Details:**
265
+ - Validates all required fields before API call
266
+ - Shows configuration summary before creation
267
+ - Handles tier-based quota errors (403)
268
+ - Handles validation errors (400) with field-specific messages
269
+ - Saves project config to `.saac/config.json` after successful creation
270
+ - Displays next steps and useful commands
271
+
272
+ ### Update Command Implementation
273
+
274
+ The `update` command allows modifying application configuration after deployment using `PATCH /api/v1/applications/:uuid`.
275
+
276
+ **All Configuration Fields Can Be Updated:**
277
+ - Basic: name, branch, port
278
+ - Build pack and custom commands
279
+ - Resource limits (CPU, memory) - capped at tier limits
280
+ - Health checks (enable/disable, path, interval, timeout, retries)
281
+ - Restart policy (always, on-failure, unless-stopped, no)
282
+ - Environment variables
283
+
284
+ **Important Notes:**
285
+ - Only fields you specify will be updated (partial updates)
286
+ - Resource limits are enforced by user tier (free: 1 vCPU, 1GB RAM)
287
+ - Changes require redeployment to take effect: `saac deploy`
288
+ - Requires project config (`.saac/config.json`)
289
+
290
+ **Examples:**
291
+ ```bash
292
+ # Update port and enable health checks
293
+ saac update --port 8080 --health-check --health-path /api/health
294
+
295
+ # Switch to Nixpacks and update resource limits
296
+ saac update --build-pack nixpacks --cpu-limit 2 --memory-limit 2G
297
+
298
+ # Update custom commands
299
+ saac update --pre-deploy-cmd "npm run migrate" --start-cmd "node dist/server.js"
300
+
301
+ # Disable health checks
302
+ saac update --no-health-check
303
+
304
+ # Update environment variables
305
+ saac update --env NODE_ENV=production --env LOG_LEVEL=debug
306
+
307
+ # Change restart policy
308
+ saac update --restart on-failure
309
+ ```
310
+
311
+ **Response Behavior:**
312
+ - Shows which fields were updated
313
+ - Warns if tier limits were applied (resource caps)
314
+ - Reminds user to redeploy for changes to take effect
315
+
316
+ ### Incomplete Commands
317
+
318
+ Several commands still need implementation:
319
+ - `src/commands/init.js` - Not implemented
320
+ - `src/commands/env.js` - Not implemented
321
+
322
+ These need full implementation following the pattern from completed commands like `create.js` or `login.js`.
323
+
324
+ **Implementation Pattern for New Commands:**
325
+ 1. Require flags, no interactive prompts
326
+ 2. Show usage info if required flags missing
327
+ 3. Validate inputs before API calls
328
+ 4. Use spinners for async operations
329
+ 5. Handle errors with descriptive messages
330
+
331
+ ### MailHog Integration
332
+
333
+ The system uses MailHog for email verification in development:
334
+ - URL: https://mailhog.goryan.io
335
+ - Users must manually retrieve verification codes
336
+ - Production would use real SMTP
337
+
338
+ ### Domain Configuration
339
+
340
+ Default domain suffix: `startanaicompany.com`
341
+ Applications are accessible at: `{subdomain}.startanaicompany.com`
342
+
343
+ ### Git Repository Integration
344
+
345
+ The wrapper API expects Git repositories to be hosted on the StartAnAiCompany Gitea instance:
346
+ - Gitea URL: https://git.startanaicompany.com
347
+ - During registration, Gitea username can be auto-detected or manually provided
348
+ - Applications reference repositories in the format: `git@git.startanaicompany.com:user/repo.git`
349
+
350
+ ## Testing Considerations
351
+
352
+ When implementing new commands:
353
+ 1. Test both with flags and interactive prompts
354
+ 2. Verify error handling for missing authentication
355
+ 3. Verify error handling for missing project config
356
+ 4. Test API error responses
357
+ 5. Ensure proper exit codes (0 for success, 1 for errors)
358
+ 6. Check that spinners succeed/fail appropriately
package/README.md CHANGED
@@ -24,10 +24,10 @@ npm install -g @startanaicompany/cli
24
24
 
25
25
  ```bash
26
26
  # 1. Register for an account
27
- saac register
27
+ saac register --email user@example.com
28
28
 
29
29
  # 2. Verify your email (check MailHog)
30
- saac verify <code>
30
+ saac verify 123456
31
31
 
32
32
  # 3. Create a new application
33
33
  saac create my-recruitment-site
@@ -44,18 +44,28 @@ saac deploy
44
44
  Register for a new account
45
45
 
46
46
  ```bash
47
- saac register
48
47
  saac register --email user@example.com
48
+ saac register -e user@example.com --gitea-username myuser
49
49
  ```
50
50
 
51
+ **Required:**
52
+ - `-e, --email <email>` - Your email address
53
+
54
+ **Optional:**
55
+ - `--gitea-username <username>` - Your Gitea username (auto-detected if not provided)
56
+
51
57
  #### `saac login`
52
58
  Login with existing credentials
53
59
 
54
60
  ```bash
55
- saac login
56
61
  saac login --email user@example.com --api-key cw_...
62
+ saac login -e user@example.com -k cw_...
57
63
  ```
58
64
 
65
+ **Required:**
66
+ - `-e, --email <email>` - Your email address
67
+ - `-k, --api-key <key>` - Your API key
68
+
59
69
  #### `saac verify <code>`
60
70
  Verify your email address
61
71
 
@@ -66,12 +76,32 @@ saac verify 123456
66
76
  **Note:** Check MailHog at https://mailhog.goryan.io for verification codes
67
77
 
68
78
  #### `saac logout`
69
- Clear saved credentials
79
+ Logout from current device (revokes session token)
70
80
 
71
81
  ```bash
72
82
  saac logout
73
83
  ```
74
84
 
85
+ #### `saac logout-all`
86
+ Logout from all devices (revokes all session tokens)
87
+
88
+ ```bash
89
+ saac logout-all
90
+ saac logout-all --yes # Skip confirmation
91
+ ```
92
+
93
+ **Options:**
94
+ - `-y, --yes` - Skip confirmation prompt
95
+
96
+ #### `saac sessions`
97
+ List all active sessions
98
+
99
+ ```bash
100
+ saac sessions
101
+ ```
102
+
103
+ Shows all devices where you're currently logged in with creation date, last used time, IP address, and expiration date.
104
+
75
105
  ### Application Management
76
106
 
77
107
  #### `saac init`
@@ -82,19 +112,73 @@ saac init
82
112
  saac init --name myapp --subdomain myapp
83
113
  ```
84
114
 
85
- #### `saac create [name]`
115
+ #### `saac create <name>`
86
116
  Create a new application
87
117
 
88
118
  ```bash
89
- saac create
90
- saac create my-site --subdomain mysite
119
+ # Basic application
120
+ saac create my-app -s myapp -r git@git.startanaicompany.com:user/repo.git -t abc123
121
+
122
+ # Advanced with health checks and migration
123
+ saac create api -s api -r git@git... -t abc123 \
124
+ --build-pack nixpacks \
125
+ --port 8080 \
126
+ --pre-deploy-cmd "npm run migrate" \
127
+ --health-check \
128
+ --health-path /api/health \
129
+ --env NODE_ENV=production
91
130
  ```
92
131
 
93
- Options:
94
- - `-s, --subdomain <subdomain>` - Subdomain for your site
95
- - `-d, --domain-suffix <suffix>` - Domain suffix (default: startanaicompany.com)
96
- - `-r, --repository <url>` - Git repository URL
132
+ **Required:**
133
+ - `<name>` - Application name
134
+ - `-s, --subdomain <subdomain>` - Subdomain for your app
135
+ - `-r, --repository <url>` - Git repository URL (SSH format)
136
+ - `-t, --git-token <token>` - Git API token
137
+
138
+ **Optional:**
97
139
  - `-b, --branch <branch>` - Git branch (default: master)
140
+ - `-d, --domain-suffix <suffix>` - Domain suffix (default: startanaicompany.com)
141
+ - `-p, --port <port>` - Port to expose (default: 3000)
142
+ - `--build-pack <pack>` - Build pack: dockercompose, nixpacks, dockerfile, static
143
+ - `--install-cmd <command>` - Install command
144
+ - `--build-cmd <command>` - Build command
145
+ - `--start-cmd <command>` - Start command
146
+ - `--pre-deploy-cmd <command>` - Pre-deployment command (e.g., migrations)
147
+ - `--post-deploy-cmd <command>` - Post-deployment command (e.g., seeding)
148
+ - `--cpu-limit <limit>` - CPU limit (e.g., "1", "2.5")
149
+ - `--memory-limit <limit>` - Memory limit (e.g., "512M", "2G")
150
+ - `--health-check` - Enable health checks
151
+ - `--health-path <path>` - Health check path (default: /health)
152
+ - `--health-interval <seconds>` - Health check interval in seconds
153
+ - `--health-timeout <seconds>` - Health check timeout in seconds
154
+ - `--health-retries <count>` - Health check retries (1-10)
155
+ - `--env <KEY=VALUE>` - Environment variable (can be used multiple times)
156
+
157
+ **Note:** Free tier limited to 1 vCPU, 1024M RAM
158
+
159
+ #### `saac update`
160
+ Update application configuration
161
+
162
+ ```bash
163
+ # Update port and enable health checks
164
+ saac update --port 8080 --health-check --health-path /api/health
165
+
166
+ # Switch to Nixpacks and update resource limits
167
+ saac update --build-pack nixpacks --cpu-limit 2 --memory-limit 2G
168
+
169
+ # Update custom commands
170
+ saac update --pre-deploy-cmd "npm run migrate"
171
+
172
+ # Disable health checks
173
+ saac update --no-health-check
174
+ ```
175
+
176
+ **Options:** All options from `create` command can be updated individually
177
+
178
+ **Important:** Configuration changes require redeployment to take effect:
179
+ ```bash
180
+ saac deploy
181
+ ```
98
182
 
99
183
  #### `saac deploy`
100
184
  Deploy your application
@@ -193,7 +277,7 @@ saac rm # Alias
193
277
 
194
278
  ### Global Configuration
195
279
 
196
- Stored in `~/.saac/config.json`:
280
+ Stored in `~/.config/startanaicompany/config.json`:
197
281
 
198
282
  ```json
199
283
  {
@@ -225,7 +309,7 @@ Stored in `.saac/config.json` in your project:
225
309
 
226
310
  ```bash
227
311
  # Step 1: Register and verify
228
- saac register --email dev@company.com
312
+ saac register -e dev@company.com
229
313
  # Check MailHog for code
230
314
  saac verify 123456
231
315