@startanaicompany/cli 1.3.0 → 1.3.1
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 +33 -2
- package/README.md +13 -2
- package/package.json +1 -1
- package/src/commands/init.js +160 -4
package/CLAUDE.md
CHANGED
|
@@ -313,11 +313,42 @@ saac update --restart on-failure
|
|
|
313
313
|
- Warns if tier limits were applied (resource caps)
|
|
314
314
|
- Reminds user to redeploy for changes to take effect
|
|
315
315
|
|
|
316
|
+
### Init Command Implementation
|
|
317
|
+
|
|
318
|
+
The `init` command links an existing SAAC application to the current directory.
|
|
319
|
+
|
|
320
|
+
**Primary Use Case:** When you clone a Git repository or have an existing project and want to link it to a SAAC application for deployment.
|
|
321
|
+
|
|
322
|
+
**How It Works:**
|
|
323
|
+
1. Checks if directory is already initialized (has `.saac/config.json`)
|
|
324
|
+
2. Fetches all user applications from the API
|
|
325
|
+
3. Shows interactive list to select which application to link
|
|
326
|
+
4. Saves selected application info to `.saac/config.json`
|
|
327
|
+
|
|
328
|
+
**Usage:**
|
|
329
|
+
```bash
|
|
330
|
+
# Interactive mode - select from existing applications
|
|
331
|
+
cd my-project
|
|
332
|
+
saac init
|
|
333
|
+
# Select application from list
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Behavior:**
|
|
337
|
+
- If directory is already initialized, asks for confirmation to re-link
|
|
338
|
+
- If user has no applications, suggests using `saac create`
|
|
339
|
+
- After initialization, shows available commands (deploy, logs, status, update)
|
|
340
|
+
|
|
341
|
+
**Note:** The `init` command options (`-n, --name`, etc.) are currently not implemented. To create a new application, use `saac create` instead.
|
|
342
|
+
|
|
316
343
|
### Incomplete Commands
|
|
317
344
|
|
|
318
345
|
Several commands still need implementation:
|
|
319
|
-
- `src/commands/
|
|
320
|
-
- `src/commands/
|
|
346
|
+
- `src/commands/env.js` - Not implemented (partial stub)
|
|
347
|
+
- `src/commands/domain.js` - Not implemented (partial stub)
|
|
348
|
+
- `src/commands/logs.js` - Not implemented (partial stub)
|
|
349
|
+
- `src/commands/delete.js` - Not implemented (partial stub)
|
|
350
|
+
- `src/commands/list.js` - Not implemented (partial stub)
|
|
351
|
+
- `src/commands/whoami.js` - Not implemented (partial stub)
|
|
321
352
|
|
|
322
353
|
These need full implementation following the pattern from completed commands like `create.js` or `login.js`.
|
|
323
354
|
|
package/README.md
CHANGED
|
@@ -105,13 +105,24 @@ Shows all devices where you're currently logged in with creation date, last used
|
|
|
105
105
|
### Application Management
|
|
106
106
|
|
|
107
107
|
#### `saac init`
|
|
108
|
-
|
|
108
|
+
Link an existing SAAC application to the current directory
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
|
+
# Interactive mode - select from your applications
|
|
112
|
+
cd my-project
|
|
111
113
|
saac init
|
|
112
|
-
saac init --name myapp --subdomain myapp
|
|
113
114
|
```
|
|
114
115
|
|
|
116
|
+
**Use Case:** When you clone a Git repository or have an existing project and want to link it to a SAAC application.
|
|
117
|
+
|
|
118
|
+
**What it does:**
|
|
119
|
+
1. Shows all your SAAC applications
|
|
120
|
+
2. Let you select which one to link to this directory
|
|
121
|
+
3. Saves the link to `.saac/config.json`
|
|
122
|
+
4. Now you can use `saac deploy`, `saac logs`, etc.
|
|
123
|
+
|
|
124
|
+
**Note:** To create a new application, use `saac create` instead.
|
|
125
|
+
|
|
115
126
|
#### `saac create <name>`
|
|
116
127
|
Create a new application
|
|
117
128
|
|
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -1,4 +1,160 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Init command - Initialize SAAC project in current directory
|
|
3
|
+
*
|
|
4
|
+
* Two modes:
|
|
5
|
+
* 1. Interactive: Select from existing applications (no options provided)
|
|
6
|
+
* 2. Create: Create new application and link to directory (options provided)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const api = require('../lib/api');
|
|
10
|
+
const { isAuthenticated, saveProjectConfig, getProjectConfig } = require('../lib/config');
|
|
11
|
+
const logger = require('../lib/logger');
|
|
12
|
+
const inquirer = require('inquirer');
|
|
13
|
+
|
|
14
|
+
async function init(options) {
|
|
15
|
+
try {
|
|
16
|
+
// Check authentication
|
|
17
|
+
if (!isAuthenticated()) {
|
|
18
|
+
logger.error('Not logged in');
|
|
19
|
+
logger.newline();
|
|
20
|
+
logger.info('Run:');
|
|
21
|
+
logger.log(' saac login -e <email> -k <api-key>');
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
logger.section('Initialize SAAC Project');
|
|
26
|
+
logger.newline();
|
|
27
|
+
|
|
28
|
+
// Check if already initialized
|
|
29
|
+
const existingConfig = getProjectConfig();
|
|
30
|
+
if (existingConfig) {
|
|
31
|
+
logger.warn('This directory is already linked to an application');
|
|
32
|
+
logger.newline();
|
|
33
|
+
logger.field('Application', existingConfig.applicationName);
|
|
34
|
+
logger.field('UUID', existingConfig.applicationUuid);
|
|
35
|
+
logger.field('Domain', `${existingConfig.subdomain}.${existingConfig.domainSuffix}`);
|
|
36
|
+
logger.newline();
|
|
37
|
+
|
|
38
|
+
const { overwrite } = await inquirer.prompt([
|
|
39
|
+
{
|
|
40
|
+
type: 'confirm',
|
|
41
|
+
name: 'overwrite',
|
|
42
|
+
message: 'Do you want to re-initialize this directory?',
|
|
43
|
+
default: false,
|
|
44
|
+
},
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
if (!overwrite) {
|
|
48
|
+
logger.info('Keeping existing configuration');
|
|
49
|
+
process.exit(0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
logger.newline();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Determine mode: Create new app OR link existing app
|
|
56
|
+
const hasCreateOptions = options.name || options.subdomain || options.repository;
|
|
57
|
+
|
|
58
|
+
if (hasCreateOptions) {
|
|
59
|
+
// CREATE MODE: Create a new application
|
|
60
|
+
await createAndInitialize(options);
|
|
61
|
+
} else {
|
|
62
|
+
// INTERACTIVE MODE: Link existing application
|
|
63
|
+
await linkExistingApplication();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
} catch (error) {
|
|
67
|
+
logger.error(error.response?.data?.message || error.message);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create a new application and initialize directory
|
|
74
|
+
*/
|
|
75
|
+
async function createAndInitialize(options) {
|
|
76
|
+
logger.error('Create mode not yet implemented');
|
|
77
|
+
logger.newline();
|
|
78
|
+
logger.info('To create a new application, use:');
|
|
79
|
+
logger.log(' saac create <name> -s <subdomain> -r <repository> -t <git-token>');
|
|
80
|
+
logger.newline();
|
|
81
|
+
logger.info('To link an existing application, run:');
|
|
82
|
+
logger.log(' saac init');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
|
|
85
|
+
// TODO: Implement create-and-init flow
|
|
86
|
+
// This would call the create command functionality, then save the config
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Link an existing application to current directory (interactive)
|
|
91
|
+
*/
|
|
92
|
+
async function linkExistingApplication() {
|
|
93
|
+
|
|
94
|
+
// Fetch user's applications
|
|
95
|
+
const spin = logger.spinner('Fetching your applications...').start();
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const result = await api.listApplications();
|
|
99
|
+
const applications = Array.isArray(result) ? result : (result.applications || []);
|
|
100
|
+
|
|
101
|
+
spin.succeed(`Found ${applications.length} application(s)`);
|
|
102
|
+
|
|
103
|
+
if (applications.length === 0) {
|
|
104
|
+
logger.newline();
|
|
105
|
+
logger.warn('You have no applications yet');
|
|
106
|
+
logger.newline();
|
|
107
|
+
logger.info('Create one with:');
|
|
108
|
+
logger.log(' saac create <name> -s <subdomain> -r <repository> -t <git-token>');
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
logger.newline();
|
|
113
|
+
|
|
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
|
+
]);
|
|
128
|
+
|
|
129
|
+
logger.newline();
|
|
130
|
+
|
|
131
|
+
// Save project configuration
|
|
132
|
+
saveProjectConfig({
|
|
133
|
+
applicationUuid: selectedApp.uuid,
|
|
134
|
+
applicationName: selectedApp.name,
|
|
135
|
+
subdomain: selectedApp.subdomain,
|
|
136
|
+
domainSuffix: selectedApp.domain_suffix || 'startanaicompany.com',
|
|
137
|
+
gitRepository: selectedApp.git_repository,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
logger.success('Project initialized!');
|
|
141
|
+
logger.newline();
|
|
142
|
+
logger.field('Application', selectedApp.name);
|
|
143
|
+
logger.field('UUID', selectedApp.uuid);
|
|
144
|
+
logger.field('Domain', selectedApp.domain || `${selectedApp.subdomain}.startanaicompany.com`);
|
|
145
|
+
logger.field('Status', selectedApp.status);
|
|
146
|
+
logger.newline();
|
|
147
|
+
|
|
148
|
+
logger.info('You can now use:');
|
|
149
|
+
logger.log(' saac deploy Deploy your application');
|
|
150
|
+
logger.log(' saac logs --follow View deployment logs');
|
|
151
|
+
logger.log(' saac status Check application status');
|
|
152
|
+
logger.log(' saac update --port 8080 Update configuration');
|
|
153
|
+
|
|
154
|
+
} catch (error) {
|
|
155
|
+
spin.fail('Failed to fetch applications');
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
module.exports = init;
|