@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 +253 -0
- package/README.md +36 -6
- package/auth_session_update.md +785 -0
- package/bin/saac.js +14 -1
- package/package.json +1 -1
- package/src/commands/login.js +38 -44
- package/src/commands/logout.js +41 -3
- package/src/commands/logoutAll.js +74 -0
- package/src/commands/register.js +46 -34
- package/src/commands/sessions.js +75 -0
- package/src/commands/verify.js +32 -4
- package/src/lib/api.js +37 -1
- package/src/lib/config.js +52 -4
- package/test-session-token.js +117 -0
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
|
|
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
|
-
|
|
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
|
|
258
|
+
saac register -e dev@company.com
|
|
229
259
|
# Check MailHog for code
|
|
230
260
|
saac verify 123456
|
|
231
261
|
|