@startanaicompany/cli 1.4.20 → 1.5.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 CHANGED
@@ -146,16 +146,28 @@ Uses Commander.js to define:
146
146
  5. All subsequent API requests include X-Session-Token header
147
147
  6. Token expires after 1 year → user must login again
148
148
 
149
- **API Key Flow (CI/CD & Scripts):**
150
- 1. User logs in with email + API key → API returns session token
151
- 2. Environment variable `SAAC_API_KEY` can override stored credentials
152
- 3. Useful for automation, scripts, and CI/CD pipelines
149
+ **Auto-Login Flow (CI/CD & Automation):**
150
+ 1. User sets `SAAC_USER_API_KEY` and `SAAC_USER_EMAIL` environment variables
151
+ 2. Any command checks `ensureAuthenticated()` instead of `isAuthenticated()`
152
+ 3. If not logged in, `ensureAuthenticated()` checks for env vars
153
+ 4. If both present, automatically calls login API
154
+ 5. Session token saved to config, cached for subsequent commands
155
+ 6. Subsequent commands use cached session (fast path, no API call)
153
156
 
154
157
  **Authentication Priority:**
155
158
  ```javascript
156
- // In api.js createClient()
159
+ // In commands (e.g., deploy.js, list.js, etc.)
160
+ if (!(await ensureAuthenticated())) {
161
+ // Not logged in and auto-login failed
162
+ logger.error('Not logged in');
163
+ logger.info('Run: saac login -e <email> -k <api-key>');
164
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
165
+ process.exit(1);
166
+ }
167
+
168
+ // In api.js createClient() - Header priority:
157
169
  if (process.env.SAAC_API_KEY) {
158
- headers['X-API-Key'] = SAAC_API_KEY; // 1st priority
170
+ headers['X-API-Key'] = SAAC_API_KEY; // 1st priority (legacy)
159
171
  } else if (user.sessionToken) {
160
172
  headers['X-Session-Token'] = sessionToken; // 2nd priority
161
173
  } else if (user.apiKey) {
@@ -163,6 +175,11 @@ if (process.env.SAAC_API_KEY) {
163
175
  }
164
176
  ```
165
177
 
178
+ **Environment Variables:**
179
+ - `SAAC_USER_API_KEY` - API key for auto-login (NEW)
180
+ - `SAAC_USER_EMAIL` - Email for auto-login (NEW)
181
+ - `SAAC_API_KEY` - Legacy API key (used directly in API headers, bypasses login)
182
+
166
183
  ### Application Lifecycle
167
184
 
168
185
  1. **Create/Init** → applicationUuid saved to `.saac/config.json`
@@ -205,10 +222,53 @@ The CLI now uses session tokens instead of storing permanent API keys:
205
222
  ```
206
223
 
207
224
  **Token Validation Functions** (in `config.js`):
208
- - `isAuthenticated()` - Checks if user has valid, non-expired token
225
+ - `isAuthenticated()` - Checks if user has valid, non-expired token (synchronous)
226
+ - `ensureAuthenticated()` - **NEW**: Checks authentication + auto-login via env vars (async)
209
227
  - `isTokenExpired()` - Checks if session token has expired
210
228
  - `isTokenExpiringSoon()` - Checks if token expires within 7 days
211
229
 
230
+ **ensureAuthenticated() Function:**
231
+ ```javascript
232
+ async function ensureAuthenticated() {
233
+ // Step 1: Check if already authenticated (fast path)
234
+ if (isAuthenticated()) {
235
+ return true;
236
+ }
237
+
238
+ // Step 2: Check for environment variables
239
+ const apiKey = process.env.SAAC_USER_API_KEY;
240
+ const email = process.env.SAAC_USER_EMAIL;
241
+
242
+ if (!apiKey || !email) {
243
+ return false; // No env vars - cannot auto-login
244
+ }
245
+
246
+ // Step 3: Attempt auto-login via API
247
+ try {
248
+ const api = require('./api');
249
+ const result = await api.login(email, apiKey);
250
+
251
+ // Step 4: Save session token to config
252
+ saveUser({
253
+ email: result.user.email,
254
+ userId: result.user.id,
255
+ sessionToken: result.session_token,
256
+ expiresAt: result.expires_at,
257
+ verified: result.user.verified,
258
+ });
259
+
260
+ return true; // Auto-login successful
261
+ } catch (error) {
262
+ return false; // Auto-login failed
263
+ }
264
+ }
265
+ ```
266
+
267
+ **When to use:**
268
+ - Use `ensureAuthenticated()` in ALL non-auth commands (deploy, list, create, etc.)
269
+ - Use `isAuthenticated()` only when you don't want auto-login behavior
270
+ - Commands that should NOT use `ensureAuthenticated()`: login, logout, register, verify
271
+
212
272
  **Backend Requirements:**
213
273
  - `POST /auth/login` - Accepts `X-API-Key` + email, returns session token
214
274
  - Middleware must accept both `X-Session-Token` and `X-API-Key` headers