@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/bin/saac.js CHANGED
@@ -123,6 +123,17 @@ gitCommand
123
123
  .description('Disconnect a Git account')
124
124
  .action(git.disconnect);
125
125
 
126
+ gitCommand
127
+ .command('repos <git_host>')
128
+ .description('List repositories from a connected Git host')
129
+ .option('-p, --page <number>', 'Page number', '1')
130
+ .option('-n, --per-page <number>', 'Results per page (max: 100)', '20')
131
+ .option('-s, --sort <type>', 'Sort order: updated, created, name', 'updated')
132
+ .option('-v, --visibility <type>', 'Filter: all, public, private', 'all')
133
+ .option('-c, --commits', 'Include latest commit info')
134
+ .option('--json', 'Output as JSON')
135
+ .action(git.repos);
136
+
126
137
  // Application management
127
138
  program
128
139
  .command('init')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startanaicompany/cli",
3
- "version": "1.4.20",
3
+ "version": "1.5.0",
4
4
  "description": "Official CLI for StartAnAiCompany.com - Deploy AI recruitment sites with ease",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { isAuthenticated, saveProjectConfig, getUser, getProjectConfig } = require('../lib/config');
6
+ const { ensureAuthenticated, saveProjectConfig, getUser, getProjectConfig } = require('../lib/config');
7
7
  const logger = require('../lib/logger');
8
8
  const oauth = require('../lib/oauth');
9
9
  const inquirer = require('inquirer');
@@ -12,12 +12,11 @@ const errorDisplay = require('../lib/errorDisplay');
12
12
 
13
13
  async function create(name, options) {
14
14
  try {
15
- // Check authentication
16
- if (!isAuthenticated()) {
15
+ // Check authentication (with auto-login support)
16
+ if (!(await ensureAuthenticated())) {
17
17
  logger.error('Not logged in');
18
- logger.newline();
19
- logger.info('Run:');
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
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { getProjectConfig, isAuthenticated } = require('../lib/config');
6
+ const { getProjectConfig, ensureAuthenticated } = require('../lib/config');
7
7
  const logger = require('../lib/logger');
8
8
  const inquirer = require('inquirer');
9
9
  const fs = require('fs');
@@ -16,8 +16,10 @@ const path = require('path');
16
16
  async function deleteApp(options) {
17
17
  try {
18
18
  // Check authentication
19
- if (!isAuthenticated()) {
20
- logger.error('Not logged in. Run: saac login');
19
+ if (!(await ensureAuthenticated())) {
20
+ logger.error('Not logged in');
21
+ logger.info('Run: saac login -e <email> -k <api-key>');
22
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
21
23
  process.exit(1);
22
24
  }
23
25
 
@@ -3,15 +3,17 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { getProjectConfig, isAuthenticated } = require('../lib/config');
6
+ const { getProjectConfig, ensureAuthenticated } = require('../lib/config');
7
7
  const logger = require('../lib/logger');
8
8
  const errorDisplay = require('../lib/errorDisplay');
9
9
 
10
10
  async function deploy(options) {
11
11
  try {
12
- // Check authentication
13
- if (!isAuthenticated()) {
14
- logger.error('Not logged in. Run: saac login');
12
+ // Check authentication (with auto-login support)
13
+ if (!(await ensureAuthenticated())) {
14
+ logger.error('Not logged in');
15
+ logger.info('Run: saac login -e <email> -k <api-key>');
16
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
15
17
  process.exit(1);
16
18
  }
17
19
 
@@ -3,15 +3,17 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { getProjectConfig, isAuthenticated } = require('../lib/config');
6
+ const { getProjectConfig, ensureAuthenticated } = require('../lib/config');
7
7
  const logger = require('../lib/logger');
8
8
  const { table } = require('table');
9
9
 
10
10
  async function deployments(options) {
11
11
  try {
12
12
  // Check authentication
13
- if (!isAuthenticated()) {
14
- logger.error('Not logged in. Run: saac login');
13
+ if (!(await ensureAuthenticated())) {
14
+ logger.error('Not logged in');
15
+ logger.info('Run: saac login -e <email> -k <api-key>');
16
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
15
17
  process.exit(1);
16
18
  }
17
19
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { getProjectConfig, isAuthenticated, saveProjectConfig } = require('../lib/config');
6
+ const { getProjectConfig, ensureAuthenticated, saveProjectConfig } = require('../lib/config');
7
7
  const logger = require('../lib/logger');
8
8
 
9
9
  /**
@@ -14,8 +14,10 @@ const logger = require('../lib/logger');
14
14
  async function set(subdomain, options) {
15
15
  try {
16
16
  // Check authentication
17
- if (!isAuthenticated()) {
18
- logger.error('Not logged in. Run: saac login');
17
+ if (!(await ensureAuthenticated())) {
18
+ logger.error('Not logged in');
19
+ logger.info('Run: saac login -e <email> -k <api-key>');
20
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
19
21
  process.exit(1);
20
22
  }
21
23
 
@@ -149,8 +151,10 @@ async function set(subdomain, options) {
149
151
  async function show() {
150
152
  try {
151
153
  // Check authentication
152
- if (!isAuthenticated()) {
153
- logger.error('Not logged in. Run: saac login');
154
+ if (!(await ensureAuthenticated())) {
155
+ logger.error('Not logged in');
156
+ logger.info('Run: saac login -e <email> -k <api-key>');
157
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
154
158
  process.exit(1);
155
159
  }
156
160
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { getProjectConfig, isAuthenticated } = require('../lib/config');
6
+ const { getProjectConfig, ensureAuthenticated } = require('../lib/config');
7
7
  const logger = require('../lib/logger');
8
8
  const { table } = require('table');
9
9
 
@@ -14,8 +14,10 @@ const { table } = require('table');
14
14
  async function get(key) {
15
15
  try {
16
16
  // Check authentication
17
- if (!isAuthenticated()) {
18
- logger.error('Not logged in. Run: saac login');
17
+ if (!(await ensureAuthenticated())) {
18
+ logger.error('Not logged in');
19
+ logger.info('Run: saac login -e <email> -k <api-key>');
20
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
19
21
  process.exit(1);
20
22
  }
21
23
 
@@ -108,8 +110,10 @@ async function list() {
108
110
  async function set(vars) {
109
111
  try {
110
112
  // Check authentication
111
- if (!isAuthenticated()) {
112
- logger.error('Not logged in. Run: saac login');
113
+ if (!(await ensureAuthenticated())) {
114
+ logger.error('Not logged in');
115
+ logger.info('Run: saac login -e <email> -k <api-key>');
116
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
113
117
  process.exit(1);
114
118
  }
115
119
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { getProjectConfig, isAuthenticated } = require('../lib/config');
6
+ const { getProjectConfig, ensureAuthenticated } = require('../lib/config');
7
7
  const logger = require('../lib/logger');
8
8
  const { table } = require('table');
9
9
 
@@ -15,8 +15,10 @@ const { table } = require('table');
15
15
  async function exec(command, options = {}) {
16
16
  try {
17
17
  // Check authentication
18
- if (!isAuthenticated()) {
19
- logger.error('Not logged in. Run: saac login');
18
+ if (!(await ensureAuthenticated())) {
19
+ logger.error('Not logged in');
20
+ logger.info('Run: saac login -e <email> -k <api-key>');
21
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
20
22
  process.exit(1);
21
23
  }
22
24
 
@@ -156,8 +158,10 @@ async function exec(command, options = {}) {
156
158
  async function history(options = {}) {
157
159
  try {
158
160
  // Check authentication
159
- if (!isAuthenticated()) {
160
- logger.error('Not logged in. Run: saac login');
161
+ if (!(await ensureAuthenticated())) {
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');
161
165
  process.exit(1);
162
166
  }
163
167
 
@@ -3,7 +3,8 @@
3
3
  */
4
4
 
5
5
  const oauth = require('../lib/oauth');
6
- const { isAuthenticated, getUser } = require('../lib/config');
6
+ const api = require('../lib/api');
7
+ const { ensureAuthenticated, getUser } = require('../lib/config');
7
8
  const logger = require('../lib/logger');
8
9
  const { table } = require('table');
9
10
  const inquirer = require('inquirer');
@@ -14,11 +15,10 @@ const inquirer = require('inquirer');
14
15
  async function connect(host) {
15
16
  try {
16
17
  // Check authentication
17
- if (!isAuthenticated()) {
18
+ if (!(await ensureAuthenticated())) {
18
19
  logger.error('Not logged in');
19
- logger.newline();
20
- logger.info('Run:');
21
- logger.log(' saac login -e <email> -k <api-key>');
20
+ logger.info('Run: saac login -e <email> -k <api-key>');
21
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
22
22
  process.exit(1);
23
23
  }
24
24
 
@@ -115,11 +115,10 @@ async function connect(host) {
115
115
  async function list() {
116
116
  try {
117
117
  // Check authentication
118
- if (!isAuthenticated()) {
118
+ if (!(await ensureAuthenticated())) {
119
119
  logger.error('Not logged in');
120
- logger.newline();
121
- logger.info('Run:');
122
- logger.log(' saac login -e <email> -k <api-key>');
120
+ logger.info('Run: saac login -e <email> -k <api-key>');
121
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
123
122
  process.exit(1);
124
123
  }
125
124
 
@@ -192,11 +191,10 @@ async function list() {
192
191
  async function disconnect(host) {
193
192
  try {
194
193
  // Check authentication
195
- if (!isAuthenticated()) {
194
+ if (!(await ensureAuthenticated())) {
196
195
  logger.error('Not logged in');
197
- logger.newline();
198
- logger.info('Run:');
199
- logger.log(' saac login -e <email> -k <api-key>');
196
+ logger.info('Run: saac login -e <email> -k <api-key>');
197
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
200
198
  process.exit(1);
201
199
  }
202
200
 
@@ -247,8 +245,168 @@ async function disconnect(host) {
247
245
  }
248
246
  }
249
247
 
248
+ /**
249
+ * List repositories from a connected Git host
250
+ */
251
+ async function repos(gitHost, options) {
252
+ try {
253
+ // Check authentication
254
+ if (!(await ensureAuthenticated())) {
255
+ logger.error('Not logged in');
256
+ logger.info('Run: saac login -e <email> -k <api-key>');
257
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
258
+ process.exit(1);
259
+ }
260
+
261
+ if (!gitHost) {
262
+ logger.error('Git host is required');
263
+ logger.newline();
264
+ logger.info('Usage:');
265
+ logger.log(' saac git repos <host>');
266
+ logger.newline();
267
+ logger.info('Examples:');
268
+ logger.log(' saac git repos git.startanaicompany.com');
269
+ logger.log(' saac git repos github.com');
270
+ logger.log(' saac git repos github.com --commits');
271
+ logger.log(' saac git repos github.com --visibility private');
272
+ logger.newline();
273
+ logger.info('To see connected accounts:');
274
+ logger.log(' saac git list');
275
+ process.exit(1);
276
+ }
277
+
278
+ const spin = logger.spinner(`Fetching repositories from ${gitHost}...`).start();
279
+
280
+ try {
281
+ const result = await api.listGitRepositories(gitHost, {
282
+ page: options.page ? parseInt(options.page, 10) : 1,
283
+ perPage: options.perPage ? parseInt(options.perPage, 10) : 20,
284
+ sort: options.sort || 'updated',
285
+ visibility: options.visibility || 'all',
286
+ includeCommits: options.commits || false,
287
+ });
288
+
289
+ spin.succeed(`Found ${result.count} repositories on ${result.git_host}`);
290
+
291
+ // If JSON output requested, just dump and exit
292
+ if (options.json) {
293
+ console.log(JSON.stringify(result, null, 2));
294
+ return;
295
+ }
296
+
297
+ if (result.count === 0) {
298
+ logger.newline();
299
+ logger.warn('No repositories found');
300
+ logger.newline();
301
+ logger.info('Make sure you have repositories on this Git host');
302
+ return;
303
+ }
304
+
305
+ logger.newline();
306
+ logger.section(`Repositories on ${result.git_host} (${result.username})`);
307
+ logger.newline();
308
+
309
+ if (options.commits) {
310
+ // Display with commit info
311
+ const data = [
312
+ ['NAME', 'VISIBILITY', 'LAST COMMIT'],
313
+ ];
314
+
315
+ result.repositories.forEach((repo) => {
316
+ const visibility = repo.private ? logger.chalk.yellow('private') : logger.chalk.green('public');
317
+ let commitInfo = logger.chalk.dim('No commits');
318
+
319
+ if (repo.latestCommit) {
320
+ const commit = repo.latestCommit;
321
+ const sha = commit.sha.substring(0, 7);
322
+ const message = commit.message.substring(0, 30);
323
+ const date = new Date(commit.date);
324
+ const now = new Date();
325
+ const diffMs = now - date;
326
+ const diffMins = Math.floor(diffMs / 60000);
327
+ const diffHours = Math.floor(diffMs / 3600000);
328
+ const diffDays = Math.floor(diffMs / 86400000);
329
+
330
+ let timeStr;
331
+ if (diffMins < 60) {
332
+ timeStr = `${diffMins}m ago`;
333
+ } else if (diffHours < 24) {
334
+ timeStr = `${diffHours}h ago`;
335
+ } else {
336
+ timeStr = `${diffDays}d ago`;
337
+ }
338
+
339
+ commitInfo = `${logger.chalk.dim(sha)} ${message} ${logger.chalk.dim(`(${timeStr})`)}`;
340
+ }
341
+
342
+ data.push([
343
+ repo.name,
344
+ visibility,
345
+ commitInfo,
346
+ ]);
347
+ });
348
+
349
+ console.log(table(data));
350
+ } else {
351
+ // Display without commit info
352
+ const data = [
353
+ ['NAME', 'VISIBILITY', 'UPDATED', 'BRANCH', 'LANGUAGE'],
354
+ ];
355
+
356
+ result.repositories.forEach((repo) => {
357
+ const visibility = repo.private ? logger.chalk.yellow('private') : logger.chalk.green('public');
358
+ const updated = new Date(repo.updatedAt).toLocaleString();
359
+ const language = repo.language || logger.chalk.dim('N/A');
360
+
361
+ data.push([
362
+ repo.name,
363
+ visibility,
364
+ updated,
365
+ repo.defaultBranch,
366
+ language,
367
+ ]);
368
+ });
369
+
370
+ console.log(table(data));
371
+ }
372
+
373
+ logger.info(`Showing ${result.count} repositories (page ${result.page})`);
374
+
375
+ logger.newline();
376
+ logger.info('Options:');
377
+ logger.log(' --commits Include latest commit info');
378
+ logger.log(' --visibility <type> Filter: all, public, private');
379
+ logger.log(' --page <number> Page number');
380
+ logger.log(' --per-page <number> Results per page (max: 100)');
381
+ logger.log(' --json Output as JSON');
382
+
383
+ } catch (error) {
384
+ spin.fail('Failed to fetch repositories');
385
+
386
+ if (error.response?.status === 404) {
387
+ logger.newline();
388
+ logger.error(`Not connected to ${gitHost}`);
389
+ logger.newline();
390
+ logger.info('Connect with:');
391
+ logger.log(` saac git connect ${gitHost}`);
392
+ logger.newline();
393
+ logger.info('To see connected accounts:');
394
+ logger.log(' saac git list');
395
+ } else {
396
+ throw error;
397
+ }
398
+ process.exit(1);
399
+ }
400
+
401
+ } catch (error) {
402
+ logger.error(error.response?.data?.message || error.message);
403
+ process.exit(1);
404
+ }
405
+ }
406
+
250
407
  module.exports = {
251
408
  connect,
252
409
  list,
253
410
  disconnect,
411
+ repos,
254
412
  };
@@ -7,18 +7,20 @@
7
7
  */
8
8
 
9
9
  const api = require('../lib/api');
10
- const { isAuthenticated, saveProjectConfig, getProjectConfig } = require('../lib/config');
10
+ const { ensureAuthenticated, saveProjectConfig, getProjectConfig } = require('../lib/config');
11
11
  const logger = require('../lib/logger');
12
12
  const inquirer = require('inquirer');
13
+ const { execSync } = require('child_process');
14
+ const fs = require('fs');
15
+ const path = require('path');
13
16
 
14
17
  async function init(options) {
15
18
  try {
16
- // Check authentication
17
- if (!isAuthenticated()) {
19
+ // Check authentication (with auto-login support)
20
+ if (!(await ensureAuthenticated())) {
18
21
  logger.error('Not logged in');
19
- logger.newline();
20
- logger.info('Run:');
21
- logger.log(' saac login -e <email> -k <api-key>');
22
+ logger.info('Run: saac login -e <email> -k <api-key>');
23
+ logger.info('Or set: SAAC_USER_API_KEY and SAAC_USER_EMAIL');
22
24
  process.exit(1);
23
25
  }
24
26
 
@@ -86,11 +88,58 @@ async function createAndInitialize(options) {
86
88
  // This would call the create command functionality, then save the config
87
89
  }
88
90
 
91
+ /**
92
+ * Get Git remote URL from current directory
93
+ * @returns {string|null} - Git remote URL or null if not a git repo
94
+ */
95
+ function getGitRemoteUrl() {
96
+ try {
97
+ // Check if .git directory exists
98
+ if (!fs.existsSync(path.join(process.cwd(), '.git'))) {
99
+ return null;
100
+ }
101
+
102
+ // Get remote.origin.url
103
+ const remoteUrl = execSync('git config --get remote.origin.url', {
104
+ encoding: 'utf8',
105
+ stdio: ['pipe', 'pipe', 'ignore'] // Suppress stderr
106
+ }).trim();
107
+
108
+ return remoteUrl || null;
109
+ } catch (error) {
110
+ // Not a git repo or no remote configured
111
+ return null;
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Normalize Git URLs for comparison
117
+ * Converts both SSH and HTTPS URLs to a comparable format
118
+ */
119
+ function normalizeGitUrl(url) {
120
+ if (!url) return '';
121
+
122
+ // Remove .git suffix
123
+ let normalized = url.replace(/\.git$/, '');
124
+
125
+ // Convert SSH to HTTPS-like format for comparison
126
+ // git@github.com:user/repo -> github.com/user/repo
127
+ normalized = normalized.replace(/^git@([^:]+):/, '$1/');
128
+
129
+ // Remove https:// or http://
130
+ normalized = normalized.replace(/^https?:\/\//, '');
131
+
132
+ return normalized.toLowerCase();
133
+ }
134
+
89
135
  /**
90
136
  * Link an existing application to current directory (interactive)
91
137
  */
92
138
  async function linkExistingApplication() {
93
139
 
140
+ // Try to auto-detect Git repository
141
+ const gitRemoteUrl = getGitRemoteUrl();
142
+
94
143
  // Fetch user's applications
95
144
  const spin = logger.spinner('Fetching your applications...').start();
96
145
 
@@ -111,20 +160,67 @@ async function linkExistingApplication() {
111
160
 
112
161
  logger.newline();
113
162
 
114
- // Interactive: Let user select application
115
- const choices = applications.map(app => ({
116
- name: `${app.name} - ${app.domain || `${app.subdomain}.startanaicompany.com`} (${app.status})`,
117
- value: app,
118
- }));
119
-
120
- const { selectedApp } = await inquirer.prompt([
121
- {
122
- type: 'list',
123
- name: 'selectedApp',
124
- message: 'Select application to link to this directory:',
125
- choices: choices,
126
- },
127
- ]);
163
+ let selectedApp = null;
164
+
165
+ // Try to auto-match based on Git remote URL
166
+ if (gitRemoteUrl) {
167
+ const normalizedRemote = normalizeGitUrl(gitRemoteUrl);
168
+
169
+ const matchedApp = applications.find(app => {
170
+ if (!app.git_repository) return false;
171
+ const normalizedAppRepo = normalizeGitUrl(app.git_repository);
172
+ return normalizedAppRepo === normalizedRemote;
173
+ });
174
+
175
+ if (matchedApp) {
176
+ // Found matching application!
177
+ logger.info(`Auto-detected Git repository: ${gitRemoteUrl}`);
178
+ logger.newline();
179
+ logger.field('Matched Application', matchedApp.name);
180
+ logger.field('Domain', matchedApp.domain || `${matchedApp.subdomain}.startanaicompany.com`);
181
+ logger.field('Status', matchedApp.status);
182
+ logger.newline();
183
+
184
+ const { confirm } = await inquirer.prompt([
185
+ {
186
+ type: 'confirm',
187
+ name: 'confirm',
188
+ message: 'Link this application to the current directory?',
189
+ default: true,
190
+ },
191
+ ]);
192
+
193
+ if (confirm) {
194
+ selectedApp = matchedApp;
195
+ } else {
196
+ logger.newline();
197
+ logger.info('Please select a different application:');
198
+ logger.newline();
199
+ }
200
+ } else {
201
+ logger.warn(`No application found matching Git remote: ${gitRemoteUrl}`);
202
+ logger.newline();
203
+ }
204
+ }
205
+
206
+ // If no auto-match or user declined, show interactive selection
207
+ if (!selectedApp) {
208
+ const choices = applications.map(app => ({
209
+ name: `${app.name} - ${app.domain || `${app.subdomain}.startanaicompany.com`} (${app.status})`,
210
+ value: app,
211
+ }));
212
+
213
+ const answer = await inquirer.prompt([
214
+ {
215
+ type: 'list',
216
+ name: 'selectedApp',
217
+ message: 'Select application to link to this directory:',
218
+ choices: choices,
219
+ },
220
+ ]);
221
+
222
+ selectedApp = answer.selectedApp;
223
+ }
128
224
 
129
225
  logger.newline();
130
226
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { getUser, isAuthenticated } = require('../lib/config');
6
+ const { getUser, ensureAuthenticated } = require('../lib/config');
7
7
  const logger = require('../lib/logger');
8
8
  const inquirer = require('inquirer');
9
9
 
@@ -13,7 +13,7 @@ const inquirer = require('inquirer');
13
13
  async function regenerate() {
14
14
  try {
15
15
  // Must be authenticated (via session token)
16
- if (!isAuthenticated()) {
16
+ if (!(await ensureAuthenticated())) {
17
17
  logger.error('Not logged in');
18
18
  logger.newline();
19
19
  logger.info('You must be logged in to regenerate your API key');
@@ -21,6 +21,10 @@ async function regenerate() {
21
21
  logger.info('Login using email verification:');
22
22
  logger.log(' saac login -e <email> # Request OTP');
23
23
  logger.log(' saac login -e <email> --otp <code> # Verify OTP');
24
+ logger.newline();
25
+ logger.info('Or set environment variables:');
26
+ logger.log(' export SAAC_USER_API_KEY=your_api_key');
27
+ logger.log(' export SAAC_USER_EMAIL=your_email');
24
28
  process.exit(1);
25
29
  }
26
30
 
@@ -88,7 +92,7 @@ async function regenerate() {
88
92
  */
89
93
  async function show() {
90
94
  try {
91
- if (!isAuthenticated()) {
95
+ if (!(await ensureAuthenticated())) {
92
96
  logger.error('Not logged in');
93
97
  logger.newline();
94
98
  logger.info('Login first:');
@@ -3,18 +3,17 @@
3
3
  */
4
4
 
5
5
  const api = require('../lib/api');
6
- const { isAuthenticated } = require('../lib/config');
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 list() {
11
11
  try {
12
- // Check authentication
13
- if (!isAuthenticated()) {
12
+ // Check authentication (with auto-login support)
13
+ if (!(await ensureAuthenticated())) {
14
14
  logger.error('Not logged in');
15
- logger.newline();
16
- logger.info('Run:');
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