@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 +67 -7
- package/README.md +2272 -271
- package/bin/saac.js +11 -0
- package/package.json +1 -1
- package/src/commands/create.js +5 -6
- package/src/commands/delete.js +5 -3
- package/src/commands/deploy.js +6 -4
- package/src/commands/deployments.js +5 -3
- package/src/commands/domain.js +9 -5
- package/src/commands/env.js +9 -5
- package/src/commands/exec.js +9 -5
- package/src/commands/git.js +171 -13
- package/src/commands/init.js +116 -20
- package/src/commands/keys.js +7 -3
- package/src/commands/list.js +5 -6
- package/src/commands/logs.js +5 -3
- package/src/commands/run.js +5 -3
- package/src/commands/sessions.js +4 -5
- package/src/commands/shell.js +5 -3
- package/src/commands/status.js +4 -5
- package/src/commands/update.js +5 -6
- package/src/commands/whoami.js +4 -5
- package/src/lib/api.js +30 -0
- package/src/lib/config.js +47 -0
package/src/commands/logs.js
CHANGED
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const api = require('../lib/api');
|
|
6
|
-
const { getProjectConfig,
|
|
6
|
+
const { getProjectConfig, ensureAuthenticated } = require('../lib/config');
|
|
7
7
|
const logger = require('../lib/logger');
|
|
8
8
|
|
|
9
9
|
async function logs(deploymentUuidArg, options) {
|
|
10
10
|
try {
|
|
11
11
|
// Check authentication
|
|
12
|
-
if (!
|
|
13
|
-
logger.error('Not logged in
|
|
12
|
+
if (!(await ensureAuthenticated())) {
|
|
13
|
+
logger.error('Not logged in');
|
|
14
|
+
logger.info('Run: saac login -e <email> -k <api-key>');
|
|
15
|
+
logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
|
|
14
16
|
process.exit(1);
|
|
15
17
|
}
|
|
16
18
|
|
package/src/commands/run.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const api = require('../lib/api');
|
|
6
|
-
const { getProjectConfig,
|
|
6
|
+
const { getProjectConfig, ensureAuthenticated } = require('../lib/config');
|
|
7
7
|
const logger = require('../lib/logger');
|
|
8
8
|
const { spawn } = require('child_process');
|
|
9
9
|
const fs = require('fs');
|
|
@@ -55,8 +55,10 @@ async function getEnvironmentVariables(appUuid, forceRefresh = false) {
|
|
|
55
55
|
async function run(command, options = {}) {
|
|
56
56
|
try {
|
|
57
57
|
// Check authentication
|
|
58
|
-
if (!
|
|
59
|
-
logger.error('Not logged in
|
|
58
|
+
if (!(await ensureAuthenticated())) {
|
|
59
|
+
logger.error('Not logged in');
|
|
60
|
+
logger.info('Run: saac login -e <email> -k <api-key>');
|
|
61
|
+
logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
|
|
60
62
|
process.exit(1);
|
|
61
63
|
}
|
|
62
64
|
|
package/src/commands/sessions.js
CHANGED
|
@@ -3,18 +3,17 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const api = require('../lib/api');
|
|
6
|
-
const {
|
|
6
|
+
const { ensureAuthenticated } = require('../lib/config');
|
|
7
7
|
const logger = require('../lib/logger');
|
|
8
8
|
const { table } = require('table');
|
|
9
9
|
|
|
10
10
|
async function sessions() {
|
|
11
11
|
try {
|
|
12
12
|
// Check authentication
|
|
13
|
-
if (!
|
|
13
|
+
if (!(await ensureAuthenticated())) {
|
|
14
14
|
logger.error('Not logged in');
|
|
15
|
-
logger.
|
|
16
|
-
logger.info('
|
|
17
|
-
logger.log(' saac login -e <email> -k <api-key>');
|
|
15
|
+
logger.info('Run: saac login -e <email> -k <api-key>');
|
|
16
|
+
logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
|
|
18
17
|
process.exit(1);
|
|
19
18
|
}
|
|
20
19
|
|
package/src/commands/shell.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const WebSocket = require('ws');
|
|
9
9
|
const readline = require('readline');
|
|
10
|
-
const { getProjectConfig,
|
|
10
|
+
const { getProjectConfig, ensureAuthenticated, getUser, getApiUrl } = require('../lib/config');
|
|
11
11
|
const logger = require('../lib/logger');
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -320,8 +320,10 @@ class ShellClient {
|
|
|
320
320
|
async function shell(options = {}) {
|
|
321
321
|
try {
|
|
322
322
|
// Check authentication
|
|
323
|
-
if (!
|
|
324
|
-
logger.error('Not logged in
|
|
323
|
+
if (!(await ensureAuthenticated())) {
|
|
324
|
+
logger.error('Not logged in');
|
|
325
|
+
logger.info('Run: saac login -e <email> -k <api-key>');
|
|
326
|
+
logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
|
|
325
327
|
process.exit(1);
|
|
326
328
|
}
|
|
327
329
|
|
package/src/commands/status.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const api = require('../lib/api');
|
|
6
|
-
const { getUser,
|
|
6
|
+
const { getUser, ensureAuthenticated, isTokenExpiringSoon } = require('../lib/config');
|
|
7
7
|
const logger = require('../lib/logger');
|
|
8
8
|
const { table } = require('table');
|
|
9
9
|
|
|
@@ -13,11 +13,10 @@ async function status() {
|
|
|
13
13
|
logger.newline();
|
|
14
14
|
|
|
15
15
|
// Check if logged in locally (silently)
|
|
16
|
-
if (!
|
|
16
|
+
if (!(await ensureAuthenticated())) {
|
|
17
17
|
logger.error('Not logged in');
|
|
18
|
-
logger.
|
|
19
|
-
logger.info('
|
|
20
|
-
logger.log(' saac login -e <email> -k <api-key>');
|
|
18
|
+
logger.info('Run: saac login -e <email> -k <api-key>');
|
|
19
|
+
logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
|
|
21
20
|
process.exit(1);
|
|
22
21
|
}
|
|
23
22
|
|
package/src/commands/update.js
CHANGED
|
@@ -3,17 +3,16 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const api = require('../lib/api');
|
|
6
|
-
const {
|
|
6
|
+
const { ensureAuthenticated, getProjectConfig } = require('../lib/config');
|
|
7
7
|
const logger = require('../lib/logger');
|
|
8
8
|
|
|
9
9
|
async function update(options) {
|
|
10
10
|
try {
|
|
11
|
-
// Check authentication
|
|
12
|
-
if (!
|
|
11
|
+
// Check authentication (with auto-login support)
|
|
12
|
+
if (!(await ensureAuthenticated())) {
|
|
13
13
|
logger.error('Not logged in');
|
|
14
|
-
logger.
|
|
15
|
-
logger.info('
|
|
16
|
-
logger.log(' saac login -e <email> -k <api-key>');
|
|
14
|
+
logger.info('Run: saac login -e <email> -k <api-key>');
|
|
15
|
+
logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
|
|
17
16
|
process.exit(1);
|
|
18
17
|
}
|
|
19
18
|
|
package/src/commands/whoami.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const api = require('../lib/api');
|
|
6
|
-
const {
|
|
6
|
+
const { ensureAuthenticated } = require('../lib/config');
|
|
7
7
|
const logger = require('../lib/logger');
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -12,11 +12,10 @@ const logger = require('../lib/logger');
|
|
|
12
12
|
async function whoami() {
|
|
13
13
|
try {
|
|
14
14
|
// Check authentication
|
|
15
|
-
if (!
|
|
15
|
+
if (!(await ensureAuthenticated())) {
|
|
16
16
|
logger.error('Not logged in');
|
|
17
|
-
logger.
|
|
18
|
-
logger.info('
|
|
19
|
-
logger.log(' saac login -e <email> -k <api-key>');
|
|
17
|
+
logger.info('Run: saac login -e <email> -k <api-key>');
|
|
18
|
+
logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
|
|
20
19
|
process.exit(1);
|
|
21
20
|
}
|
|
22
21
|
|
package/src/lib/api.js
CHANGED
|
@@ -290,6 +290,35 @@ async function getExecutionHistory(uuid, params = {}) {
|
|
|
290
290
|
return response.data;
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
/**
|
|
294
|
+
* List repositories from a connected Git host
|
|
295
|
+
* @param {string} gitHost - Git host domain (e.g., 'github.com', 'git.startanaicompany.com')
|
|
296
|
+
* @param {object} options - Query options
|
|
297
|
+
* @param {number} options.page - Page number for pagination (default: 1)
|
|
298
|
+
* @param {number} options.perPage - Results per page (default: 100, max: 100)
|
|
299
|
+
* @param {string} options.sort - Sort order: 'updated', 'created', 'name' (default: 'updated')
|
|
300
|
+
* @param {string} options.visibility - Filter: 'all', 'public', 'private' (default: 'all')
|
|
301
|
+
* @param {boolean} options.includeCommits - Include latest commit info (default: false)
|
|
302
|
+
* @returns {Promise<object>} - Repository listing response
|
|
303
|
+
*/
|
|
304
|
+
async function listGitRepositories(gitHost, options = {}) {
|
|
305
|
+
const client = createClient();
|
|
306
|
+
|
|
307
|
+
// Build query parameters
|
|
308
|
+
const params = {};
|
|
309
|
+
if (options.page) params.page = options.page;
|
|
310
|
+
if (options.perPage) params.per_page = options.perPage;
|
|
311
|
+
if (options.sort) params.sort = options.sort;
|
|
312
|
+
if (options.visibility) params.visibility = options.visibility;
|
|
313
|
+
if (options.includeCommits) params.include_commits = true;
|
|
314
|
+
|
|
315
|
+
// URL encode the git host
|
|
316
|
+
const encodedHost = encodeURIComponent(gitHost);
|
|
317
|
+
|
|
318
|
+
const response = await client.get(`/git/connections/${encodedHost}/repos`, { params });
|
|
319
|
+
return response.data;
|
|
320
|
+
}
|
|
321
|
+
|
|
293
322
|
module.exports = {
|
|
294
323
|
createClient,
|
|
295
324
|
login,
|
|
@@ -315,4 +344,5 @@ module.exports = {
|
|
|
315
344
|
getDeploymentLogs,
|
|
316
345
|
executeCommand,
|
|
317
346
|
getExecutionHistory,
|
|
347
|
+
listGitRepositories,
|
|
318
348
|
};
|
package/src/lib/config.js
CHANGED
|
@@ -106,6 +106,52 @@ function isTokenExpiringSoon() {
|
|
|
106
106
|
return expirationDate <= sevenDaysFromNow && !isTokenExpired();
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Ensure user is authenticated, with auto-login support via environment variables
|
|
111
|
+
* Checks for SAAC_USER_API_KEY and SAAC_USER_EMAIL environment variables
|
|
112
|
+
* If present and user is not authenticated, attempts automatic login
|
|
113
|
+
*
|
|
114
|
+
* @returns {Promise<boolean>} - True if authenticated, false otherwise
|
|
115
|
+
*/
|
|
116
|
+
async function ensureAuthenticated() {
|
|
117
|
+
// Step 1: Check if already authenticated (fast path)
|
|
118
|
+
if (isAuthenticated()) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Step 2: Check for environment variables
|
|
123
|
+
const apiKey = process.env.SAAC_USER_API_KEY;
|
|
124
|
+
const email = process.env.SAAC_USER_EMAIL;
|
|
125
|
+
|
|
126
|
+
if (!apiKey || !email) {
|
|
127
|
+
// No environment variables - cannot auto-login
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Step 3: Attempt auto-login via API
|
|
132
|
+
try {
|
|
133
|
+
// Dynamically require to avoid circular dependency
|
|
134
|
+
const api = require('./api');
|
|
135
|
+
const result = await api.login(email, apiKey);
|
|
136
|
+
|
|
137
|
+
// Step 4: Save session token to config
|
|
138
|
+
saveUser({
|
|
139
|
+
email: result.user.email,
|
|
140
|
+
userId: result.user.id,
|
|
141
|
+
sessionToken: result.session_token,
|
|
142
|
+
expiresAt: result.expires_at,
|
|
143
|
+
verified: result.user.verified,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Auto-login successful
|
|
147
|
+
return true;
|
|
148
|
+
|
|
149
|
+
} catch (error) {
|
|
150
|
+
// Auto-login failed (invalid key, network error, etc.)
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
109
155
|
/**
|
|
110
156
|
* Get user info
|
|
111
157
|
*/
|
|
@@ -146,6 +192,7 @@ module.exports = {
|
|
|
146
192
|
getProjectConfig,
|
|
147
193
|
saveProjectConfig,
|
|
148
194
|
isAuthenticated,
|
|
195
|
+
ensureAuthenticated,
|
|
149
196
|
isTokenExpired,
|
|
150
197
|
isTokenExpiringSoon,
|
|
151
198
|
getUser,
|