@startanaicompany/cli 1.0.0 → 1.1.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,253 @@
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** (`~/.saac/config.json`)
37
+ - Managed by the `conf` package
38
+ - Stores user credentials (email, userId, apiKey)
39
+ - Stores API URLs (wrapper API, Gitea)
40
+ - Persists across all projects
41
+
42
+ 2. **Project Config** (`.saac/config.json` in project directory)
43
+ - Manually managed via fs operations
44
+ - Stores application-specific data (applicationUuid, applicationName, subdomain, gitRepository)
45
+ - Required for deployment commands
46
+
47
+ **Important Pattern**: Commands check both configs:
48
+ - Authentication commands → global config only
49
+ - Deployment/management commands → require BOTH global config (for auth) and project config (for app UUID)
50
+
51
+ ### API Client (`src/lib/api.js`)
52
+
53
+ Creates axios instances with:
54
+ - Base URL from global config
55
+ - X-API-Key header automatically injected from global config
56
+ - 30-second timeout
57
+ - All API functions are async and return response.data
58
+
59
+ **API Wrapper Endpoints**:
60
+ - `/register` - Create new user account
61
+ - `/users/verify` - Email verification
62
+ - `/users/me` - Get current user info
63
+ - `/applications` - CRUD operations for apps
64
+ - `/applications/:uuid/deploy` - Trigger deployment
65
+ - `/applications/:uuid/logs` - Fetch logs
66
+ - `/applications/:uuid/env` - Manage environment variables
67
+ - `/applications/:uuid/domain` - Update domain settings
68
+
69
+ ### Logger (`src/lib/logger.js`)
70
+
71
+ Centralized logging utility using chalk, ora, and boxen:
72
+ - `logger.success()` - Green checkmark messages
73
+ - `logger.error()` - Red X messages
74
+ - `logger.warn()` - Yellow warning symbol
75
+ - `logger.info()` - Blue info symbol
76
+ - `logger.spinner(text)` - Returns ora spinner instance
77
+ - `logger.section(title)` - Bold cyan headers with underline
78
+ - `logger.field(key, value)` - Key-value pair display
79
+ - `logger.box(message, options)` - Boxed messages
80
+
81
+ **Pattern**: Use spinners for async operations:
82
+ ```javascript
83
+ const spin = logger.spinner('Processing...').start();
84
+ try {
85
+ await someAsyncOperation();
86
+ spin.succeed('Done!');
87
+ } catch (error) {
88
+ spin.fail('Failed');
89
+ throw error;
90
+ }
91
+ ```
92
+
93
+ ### Command Structure
94
+
95
+ All commands follow this pattern:
96
+ 1. **Validate required flags** - Show usage if missing (commands are non-interactive by default)
97
+ 2. Import required libraries (api, config, logger)
98
+ 3. Check authentication with `isAuthenticated()` (validates session token expiration)
99
+ 4. Check project config if needed with `getProjectConfig()`
100
+ 5. Execute operation with spinner feedback
101
+ 6. Handle errors and exit with appropriate code
102
+
103
+ **Important:** Commands require flags and do NOT use interactive prompts. This makes them LLM and automation-friendly.
104
+
105
+ **Examples:**
106
+ ```bash
107
+ # ✅ Correct - with flags
108
+ saac register -e user@example.com
109
+ saac login -e user@example.com -k cw_api_key
110
+
111
+ # ❌ Wrong - will show usage error
112
+ saac register
113
+ saac login
114
+ ```
115
+
116
+ **Command Files**:
117
+ - Authentication: `register.js`, `login.js`, `verify.js`, `logout.js`, `whoami.js`
118
+ - App Management: `create.js`, `init.js`, `deploy.js`, `delete.js`, `list.js`, `status.js`
119
+ - Configuration: `env.js`, `domain.js`
120
+ - Logs: `logs.js`
121
+
122
+ ### Entry Point (`bin/saac.js`)
123
+
124
+ Uses Commander.js to define:
125
+ - Commands with options and aliases
126
+ - Nested commands (e.g., `env set`, `env get`, `domain set`)
127
+ - Help text and version info
128
+ - Error handling for invalid commands
129
+
130
+ ## Important Patterns
131
+
132
+ ### Authentication Flow
133
+
134
+ **Session Token Flow (Primary):**
135
+ 1. User registers with email → API returns session token (1 year expiration)
136
+ 2. Session token stored in global config with expiration timestamp
137
+ 3. Verification code sent to MailHog (not real email)
138
+ 4. User verifies → verified flag set to true
139
+ 5. All subsequent API requests include X-Session-Token header
140
+ 6. Token expires after 1 year → user must login again
141
+
142
+ **API Key Flow (CI/CD & Scripts):**
143
+ 1. User logs in with email + API key → API returns session token
144
+ 2. Environment variable `SAAC_API_KEY` can override stored credentials
145
+ 3. Useful for automation, scripts, and CI/CD pipelines
146
+
147
+ **Authentication Priority:**
148
+ ```javascript
149
+ // In api.js createClient()
150
+ if (process.env.SAAC_API_KEY) {
151
+ headers['X-API-Key'] = SAAC_API_KEY; // 1st priority
152
+ } else if (user.sessionToken) {
153
+ headers['X-Session-Token'] = sessionToken; // 2nd priority
154
+ } else if (user.apiKey) {
155
+ headers['X-API-Key'] = apiKey; // 3rd priority (backward compat)
156
+ }
157
+ ```
158
+
159
+ ### Application Lifecycle
160
+
161
+ 1. **Create/Init** → applicationUuid saved to `.saac/config.json`
162
+ 2. **Deploy** → POST to `/applications/:uuid/deploy`
163
+ 3. **Monitor** → GET `/applications/:uuid/logs`
164
+ 4. **Update** → PATCH environment or domain
165
+ 5. **Delete** → DELETE `/applications/:uuid`
166
+
167
+ ### Error Handling Convention
168
+
169
+ All commands use try-catch with:
170
+ ```javascript
171
+ try {
172
+ // command logic
173
+ } catch (error) {
174
+ logger.error(error.response?.data?.message || error.message);
175
+ process.exit(1);
176
+ }
177
+ ```
178
+
179
+ This pattern extracts API error messages or falls back to generic error message.
180
+
181
+ ## Development Notes
182
+
183
+ ### Session Token Implementation
184
+
185
+ The CLI now uses session tokens instead of storing permanent API keys:
186
+
187
+ **Config Storage** (`~/.saac/config.json`):
188
+ ```json
189
+ {
190
+ "user": {
191
+ "email": "user@example.com",
192
+ "userId": "uuid",
193
+ "sessionToken": "st_...",
194
+ "expiresAt": "2026-01-25T12:00:00Z",
195
+ "verified": true
196
+ }
197
+ }
198
+ ```
199
+
200
+ **Token Validation Functions** (in `config.js`):
201
+ - `isAuthenticated()` - Checks if user has valid, non-expired token
202
+ - `isTokenExpired()` - Checks if session token has expired
203
+ - `isTokenExpiringSoon()` - Checks if token expires within 7 days
204
+
205
+ **Backend Requirements:**
206
+ - `POST /auth/login` - Accepts `X-API-Key` + email, returns session token
207
+ - Middleware must accept both `X-Session-Token` and `X-API-Key` headers
208
+ - Session tokens expire after 1 year
209
+
210
+ ### Incomplete Commands
211
+
212
+ Several commands are stubbed with TODO comments:
213
+ - `src/commands/create.js` - Not implemented
214
+ - `src/commands/init.js` - Not implemented
215
+ - `src/commands/env.js` - Not implemented
216
+
217
+ These need full implementation following the pattern from completed commands like `deploy.js` or `login.js`.
218
+
219
+ **Implementation Pattern for New Commands:**
220
+ 1. Require flags, no interactive prompts
221
+ 2. Show usage info if required flags missing
222
+ 3. Validate inputs before API calls
223
+ 4. Use spinners for async operations
224
+ 5. Handle errors with descriptive messages
225
+
226
+ ### MailHog Integration
227
+
228
+ The system uses MailHog for email verification in development:
229
+ - URL: https://mailhog.goryan.io
230
+ - Users must manually retrieve verification codes
231
+ - Production would use real SMTP
232
+
233
+ ### Domain Configuration
234
+
235
+ Default domain suffix: `startanaicompany.com`
236
+ Applications are accessible at: `{subdomain}.startanaicompany.com`
237
+
238
+ ### Git Repository Integration
239
+
240
+ The wrapper API expects Git repositories to be hosted on the StartAnAiCompany Gitea instance:
241
+ - Gitea URL: https://git.startanaicompany.com
242
+ - During registration, Gitea username can be auto-detected or manually provided
243
+ - Applications reference repositories in the format: `git@git.startanaicompany.com:user/repo.git`
244
+
245
+ ## Testing Considerations
246
+
247
+ When implementing new commands:
248
+ 1. Test both with flags and interactive prompts
249
+ 2. Verify error handling for missing authentication
250
+ 3. Verify error handling for missing project config
251
+ 4. Test API error responses
252
+ 5. Ensure proper exit codes (0 for success, 1 for errors)
253
+ 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`
@@ -225,7 +255,7 @@ Stored in `.saac/config.json` in your project:
225
255
 
226
256
  ```bash
227
257
  # Step 1: Register and verify
228
- saac register --email dev@company.com
258
+ saac register -e dev@company.com
229
259
  # Check MailHog for code
230
260
  saac verify 123456
231
261