@solidactions/cli 0.6.1 → 0.6.3

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/README.md CHANGED
@@ -31,7 +31,8 @@ solidactions deploy <project-name> <path>
31
31
  | `runs [project]` | List recent workflow runs |
32
32
  | `logs <run-id>` | View logs for a workflow run |
33
33
  | `logs:build <project>` | View build/deployment logs |
34
- | `env:create <key> <value>` | Create a global environment variable |
34
+ | `env:set <key> <value>` | Set a global variable (create or update) |
35
+ | `env:set <project> <key> <value>` | Set a project variable (create or update) |
35
36
  | `env:list [project]` | List environment variables |
36
37
  | `env:delete <key>` | Delete an environment variable |
37
38
  | `env:map <project> <key> <global-key>` | Map a global variable to a project |
@@ -26,7 +26,7 @@ async function envMap(projectName, projectKey, globalKey) {
26
26
  const globalVar = variables.find((v) => v.key === globalKey);
27
27
  if (!globalVar) {
28
28
  console.error(chalk_1.default.red(`Global variable "${globalKey}" not found.`));
29
- console.log(chalk_1.default.gray('Create it with: solidactions env:create ' + globalKey + ' <value>'));
29
+ console.log(chalk_1.default.gray('Create it with: solidactions env:set ' + globalKey + ' <value>'));
30
30
  process.exit(1);
31
31
  }
32
32
  // Create the mapping
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.envSet = envSet;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const init_1 = require("./init");
10
+ async function envSet(keyOrProject, valueOrKey, valueIfProject, options = {}) {
11
+ const config = (0, init_1.getConfig)();
12
+ if (!config?.apiKey) {
13
+ console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
14
+ process.exit(1);
15
+ }
16
+ // Detect mode based on arguments
17
+ const isProjectMode = valueIfProject !== undefined;
18
+ if (isProjectMode) {
19
+ // Project mode: solidactions env:set <project> <key> <value>
20
+ const projectName = keyOrProject;
21
+ const key = valueOrKey;
22
+ const value = valueIfProject;
23
+ const environment = options.env || 'dev';
24
+ // Build project slug
25
+ const projectSlug = environment === 'production'
26
+ ? projectName
27
+ : `${projectName}-${environment}`;
28
+ // Auto-detect secrets
29
+ const isSecret = options.secret || /secret|key|token|password|credential/i.test(key);
30
+ try {
31
+ // Use bulk endpoint for upsert
32
+ const response = await axios_1.default.post(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings/bulk`, {
33
+ variables: [{
34
+ key,
35
+ value,
36
+ is_secret: isSecret,
37
+ }]
38
+ }, {
39
+ headers: {
40
+ 'Authorization': `Bearer ${config.apiKey}`,
41
+ 'Accept': 'application/json',
42
+ 'Content-Type': 'application/json',
43
+ },
44
+ });
45
+ const { created, updated } = response.data;
46
+ const action = created > 0 ? 'created' : 'updated';
47
+ console.log(chalk_1.default.green(`Variable "${key}" ${action} in project "${projectName}" (${environment}).`));
48
+ }
49
+ catch (error) {
50
+ if (error.response) {
51
+ if (error.response.status === 401) {
52
+ console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
53
+ }
54
+ else if (error.response.status === 404) {
55
+ console.error(chalk_1.default.red(`Project "${projectSlug}" not found.`));
56
+ }
57
+ else if (error.response.status === 422) {
58
+ console.error(chalk_1.default.red('Validation error:'), error.response.data);
59
+ }
60
+ else {
61
+ console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
62
+ }
63
+ }
64
+ else {
65
+ console.error(chalk_1.default.red('Connection failed:'), error.message);
66
+ }
67
+ process.exit(1);
68
+ }
69
+ }
70
+ else {
71
+ // Global mode: solidactions env:set <key> <value>
72
+ const key = keyOrProject;
73
+ const value = valueOrKey;
74
+ const isSecret = options.secret || false;
75
+ // Build the request body with per-environment values
76
+ const body = {
77
+ key,
78
+ production_value: value,
79
+ is_secret: isSecret,
80
+ };
81
+ // Handle staging value and inheritance
82
+ if (options.stagingInherit) {
83
+ body.staging_source = 'inherit_production';
84
+ }
85
+ else if (options.stagingValue !== undefined) {
86
+ body.staging_value = options.stagingValue;
87
+ body.staging_source = 'value';
88
+ }
89
+ // Handle dev value and inheritance
90
+ if (options.devInheritStaging) {
91
+ body.dev_source = 'inherit_staging';
92
+ }
93
+ else if (options.devInherit) {
94
+ body.dev_source = 'inherit_production';
95
+ }
96
+ else if (options.devValue !== undefined) {
97
+ body.dev_value = options.devValue;
98
+ body.dev_source = 'value';
99
+ }
100
+ try {
101
+ // Check if variable already exists
102
+ const getResponse = await axios_1.default.get(`${config.host}/api/v1/variables`, {
103
+ headers: {
104
+ 'Authorization': `Bearer ${config.apiKey}`,
105
+ 'Accept': 'application/json',
106
+ },
107
+ });
108
+ const variables = getResponse.data?.data || [];
109
+ const existing = variables.find((v) => v.key === key);
110
+ let action;
111
+ if (existing) {
112
+ await axios_1.default.put(`${config.host}/api/v1/variables/${existing.id}`, body, {
113
+ headers: {
114
+ 'Authorization': `Bearer ${config.apiKey}`,
115
+ 'Accept': 'application/json',
116
+ 'Content-Type': 'application/json',
117
+ },
118
+ });
119
+ action = 'updated';
120
+ }
121
+ else {
122
+ await axios_1.default.post(`${config.host}/api/v1/variables`, body, {
123
+ headers: {
124
+ 'Authorization': `Bearer ${config.apiKey}`,
125
+ 'Accept': 'application/json',
126
+ 'Content-Type': 'application/json',
127
+ },
128
+ });
129
+ action = 'created';
130
+ }
131
+ const typeLabel = isSecret ? 'secret' : 'variable';
132
+ console.log(chalk_1.default.green(`Global ${typeLabel} "${key}" ${action} successfully.`));
133
+ // Show summary of per-environment values
134
+ if (options.stagingValue) {
135
+ console.log(chalk_1.default.gray(` Staging: ${isSecret ? '********' : options.stagingValue}`));
136
+ }
137
+ else if (options.stagingInherit) {
138
+ console.log(chalk_1.default.gray(' Staging: (inherits from production)'));
139
+ }
140
+ if (options.devValue) {
141
+ console.log(chalk_1.default.gray(` Dev: ${isSecret ? '********' : options.devValue}`));
142
+ }
143
+ else if (options.devInheritStaging) {
144
+ console.log(chalk_1.default.gray(' Dev: (inherits from staging)'));
145
+ }
146
+ else if (options.devInherit) {
147
+ console.log(chalk_1.default.gray(' Dev: (inherits from production)'));
148
+ }
149
+ }
150
+ catch (error) {
151
+ if (error.response) {
152
+ if (error.response.status === 401) {
153
+ console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
154
+ }
155
+ else if (error.response.status === 422) {
156
+ console.error(chalk_1.default.red('Validation error:'), error.response.data.message || error.response.data.errors);
157
+ }
158
+ else {
159
+ console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
160
+ }
161
+ }
162
+ else {
163
+ console.error(chalk_1.default.red('Connection failed:'), error.message);
164
+ }
165
+ process.exit(1);
166
+ }
167
+ }
168
+ }
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.steps = steps;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const init_1 = require("./init");
10
+ async function steps(runId, options) {
11
+ const config = (0, init_1.getConfig)();
12
+ if (!config?.apiKey) {
13
+ console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
14
+ process.exit(1);
15
+ }
16
+ // Flag validation: --follow and --step are incompatible
17
+ if (options.follow && options.step) {
18
+ console.error(chalk_1.default.red('Cannot use --follow with --step.'));
19
+ process.exit(1);
20
+ }
21
+ try {
22
+ const response = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}/steps`, {
23
+ headers: {
24
+ 'Authorization': `Bearer ${config.apiKey}`,
25
+ 'Accept': 'application/json',
26
+ },
27
+ });
28
+ const data = response.data;
29
+ // --json mode: output raw JSON and exit
30
+ if (options.json) {
31
+ if (options.step) {
32
+ const allSteps = flattenSteps(data.workers);
33
+ const found = allSteps.find(s => s.name === options.step);
34
+ if (!found) {
35
+ console.log(JSON.stringify({
36
+ error: 'Step not found',
37
+ available: allSteps.map(s => s.name),
38
+ }, null, 2));
39
+ process.exit(1);
40
+ }
41
+ console.log(JSON.stringify(found, null, 2));
42
+ }
43
+ else {
44
+ console.log(JSON.stringify(data, null, 2));
45
+ }
46
+ return;
47
+ }
48
+ // --step mode: show single step detail
49
+ if (options.step) {
50
+ const allSteps = flattenSteps(data.workers);
51
+ const found = allSteps.find(s => s.name === options.step);
52
+ if (!found) {
53
+ console.error(chalk_1.default.red(`Step "${options.step}" not found.`));
54
+ console.log(chalk_1.default.gray('Available steps:'));
55
+ for (const s of allSteps) {
56
+ console.log(chalk_1.default.gray(` - ${s.name}`));
57
+ }
58
+ process.exit(1);
59
+ }
60
+ displaySingleStep(found);
61
+ return;
62
+ }
63
+ // Default mode: show all steps
64
+ displayAllSteps(runId, data);
65
+ // --follow mode
66
+ if (options.follow) {
67
+ console.log(chalk_1.default.gray('\n--- Following steps (Ctrl+C to stop) ---\n'));
68
+ const pollInterval = setInterval(async () => {
69
+ try {
70
+ const refreshResponse = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}/steps`, {
71
+ headers: {
72
+ 'Authorization': `Bearer ${config.apiKey}`,
73
+ 'Accept': 'application/json',
74
+ },
75
+ });
76
+ const runStatus = await axios_1.default.get(`${config.host}/api/v1/runs/${runId}`, {
77
+ headers: {
78
+ 'Authorization': `Bearer ${config.apiKey}`,
79
+ 'Accept': 'application/json',
80
+ },
81
+ });
82
+ console.clear();
83
+ displayAllSteps(runId, refreshResponse.data);
84
+ if (['completed', 'failed', 'acknowledged'].includes(runStatus.data.status)) {
85
+ clearInterval(pollInterval);
86
+ console.log(chalk_1.default.gray(`\n--- Run ${runStatus.data.status} ---`));
87
+ process.exit(runStatus.data.status === 'completed' ? 0 : 1);
88
+ }
89
+ }
90
+ catch {
91
+ // Ignore transient errors during follow
92
+ }
93
+ }, 2000);
94
+ }
95
+ }
96
+ catch (error) {
97
+ if (error.response) {
98
+ if (error.response.status === 401) {
99
+ console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
100
+ }
101
+ else if (error.response.status === 404) {
102
+ console.error(chalk_1.default.red('Run not found.'));
103
+ }
104
+ else {
105
+ console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
106
+ }
107
+ }
108
+ else {
109
+ console.error(chalk_1.default.red('Connection failed:'), error.message);
110
+ }
111
+ process.exit(1);
112
+ }
113
+ }
114
+ function flattenSteps(workers) {
115
+ const allSteps = [];
116
+ for (const worker of workers) {
117
+ for (const step of worker.steps || []) {
118
+ allSteps.push(step);
119
+ }
120
+ }
121
+ return allSteps;
122
+ }
123
+ function displaySingleStep(step) {
124
+ const statusColor = getStatusColor(step.status);
125
+ console.log(chalk_1.default.blue(`Step: ${step.name}`));
126
+ console.log(` Status: ${statusColor(step.status)}`);
127
+ console.log(` Type: ${step.type}`);
128
+ console.log(` Duration: ${formatDuration(step.duration_ms)}`);
129
+ console.log(` Started: ${step.started_at || '-'}`);
130
+ console.log(` Completed: ${step.completed_at || '-'}`);
131
+ if (step.output !== null && step.output !== undefined) {
132
+ console.log(` Output:`);
133
+ console.log(JSON.stringify(step.output, null, 2));
134
+ }
135
+ else {
136
+ console.log(` Output: ${chalk_1.default.gray('(no output)')}`);
137
+ }
138
+ if (step.error) {
139
+ console.log(chalk_1.default.red(` Error:`));
140
+ console.log(chalk_1.default.red(JSON.stringify(step.error, null, 2)));
141
+ }
142
+ }
143
+ function displayAllSteps(runId, data) {
144
+ const workers = data.workers || [];
145
+ const signalWaits = data.signal_waits || [];
146
+ console.log(chalk_1.default.blue(`Steps for run: ${runId}`));
147
+ console.log('');
148
+ for (let i = 0; i < workers.length; i++) {
149
+ const worker = workers[i];
150
+ const workerStatus = getStatusColor(worker.status || 'unknown');
151
+ const workerDuration = calculateDuration(worker.started_at, worker.completed_at);
152
+ console.log(chalk_1.default.white.bold(`Worker ${i + 1}`) + ' ' + workerStatus(worker.status || 'unknown') + chalk_1.default.gray(` (${workerDuration})`));
153
+ for (const step of worker.steps || []) {
154
+ const statusColor = getStatusColor(step.status);
155
+ const name = (step.name || '?').padEnd(30);
156
+ const status = statusColor((step.status || '?').padEnd(10));
157
+ const type = (step.type || '?').padEnd(10);
158
+ const duration = formatDuration(step.duration_ms);
159
+ console.log(` ${name} ${status} ${type} ${chalk_1.default.gray(duration)}`);
160
+ if (step.output !== null && step.output !== undefined) {
161
+ const outputStr = JSON.stringify(step.output, null, 2);
162
+ for (const line of outputStr.split('\n')) {
163
+ console.log(chalk_1.default.gray(` ${line}`));
164
+ }
165
+ }
166
+ else {
167
+ console.log(chalk_1.default.gray(' (no output)'));
168
+ }
169
+ if (step.error) {
170
+ console.log(chalk_1.default.red(` Error: ${JSON.stringify(step.error, null, 2)}`));
171
+ }
172
+ }
173
+ // Show signal waits between workers
174
+ if (i < workers.length - 1) {
175
+ const wait = signalWaits[i];
176
+ if (wait) {
177
+ console.log(chalk_1.default.yellow(` ⏳ ${wait.signal_name} (${formatDuration(wait.duration_ms)})`));
178
+ }
179
+ }
180
+ console.log('');
181
+ }
182
+ }
183
+ function formatDuration(ms) {
184
+ if (ms === null || ms === undefined)
185
+ return '-';
186
+ if (ms < 1000)
187
+ return `${ms}ms`;
188
+ if (ms < 60000)
189
+ return `${Math.round(ms / 1000)}s`;
190
+ if (ms < 3600000)
191
+ return `${Math.round(ms / 60000)}m`;
192
+ return `${Math.round(ms / 3600000)}h`;
193
+ }
194
+ function calculateDuration(startedAt, completedAt) {
195
+ if (!startedAt)
196
+ return '-';
197
+ const start = new Date(startedAt).getTime();
198
+ const end = completedAt ? new Date(completedAt).getTime() : Date.now();
199
+ return formatDuration(end - start);
200
+ }
201
+ function getStatusColor(status) {
202
+ switch (status.toLowerCase()) {
203
+ case 'completed':
204
+ return chalk_1.default.green;
205
+ case 'running':
206
+ return chalk_1.default.blue;
207
+ case 'pending':
208
+ case 'queued':
209
+ return chalk_1.default.yellow;
210
+ case 'failed':
211
+ return chalk_1.default.red;
212
+ default:
213
+ return chalk_1.default.gray;
214
+ }
215
+ }
package/dist/index.js CHANGED
@@ -6,15 +6,16 @@ const deploy_1 = require("./commands/deploy");
6
6
  const init_1 = require("./commands/init");
7
7
  const logs_1 = require("./commands/logs");
8
8
  const logs_build_1 = require("./commands/logs-build");
9
+ const steps_1 = require("./commands/steps");
9
10
  const run_1 = require("./commands/run");
10
11
  const runs_1 = require("./commands/runs");
11
12
  const pull_1 = require("./commands/pull");
12
- const env_create_1 = require("./commands/env-create");
13
13
  const env_list_1 = require("./commands/env-list");
14
14
  const env_delete_1 = require("./commands/env-delete");
15
15
  const env_map_1 = require("./commands/env-map");
16
16
  const env_pull_1 = require("./commands/env-pull");
17
17
  const env_push_1 = require("./commands/env-push");
18
+ const env_set_1 = require("./commands/env-set");
18
19
  const schedule_set_1 = require("./commands/schedule-set");
19
20
  const schedule_list_1 = require("./commands/schedule-list");
20
21
  const schedule_delete_1 = require("./commands/schedule-delete");
@@ -122,22 +123,34 @@ program
122
123
  .action((project) => {
123
124
  (0, logs_build_1.logsBuild)(project);
124
125
  });
126
+ program
127
+ .command('steps')
128
+ .description('View step outputs and timing for a workflow run')
129
+ .argument('<run-id>', 'Run ID')
130
+ .option('-s, --step <name>', 'Show output for a specific step')
131
+ .option('--json', 'Output as JSON (for piping/redirection)')
132
+ .option('-f, --follow', 'Follow step progress for in-progress runs')
133
+ .action((runId, options) => {
134
+ (0, steps_1.steps)(runId, options);
135
+ });
125
136
  // =============================================================================
126
137
  // Environment Variables
127
138
  // =============================================================================
128
139
  program
129
- .command('env:create')
130
- .description('Create a global environment variable')
131
- .argument('<key>', 'Variable name')
132
- .argument('<value>', 'Production value')
140
+ .command('env:set')
141
+ .description('Set an environment variable (create or update, global or project)')
142
+ .argument('<key-or-project>', 'Variable key (global) or project name')
143
+ .argument('<value-or-key>', 'Variable value (global) or variable key (project)')
144
+ .argument('[value]', 'Variable value (when first arg is project)')
133
145
  .option('-s, --secret', 'Mark as encrypted secret')
134
- .option('--staging-value <value>', 'Staging environment value')
135
- .option('--dev-value <value>', 'Dev environment value')
136
- .option('--staging-inherit', 'Staging inherits from production')
137
- .option('--dev-inherit', 'Dev inherits from production')
138
- .option('--dev-inherit-staging', 'Dev inherits from staging')
139
- .action((key, value, options) => {
140
- (0, env_create_1.envCreate)(key, value, options);
146
+ .option('-e, --env <environment>', 'Target environment (production/staging/dev)', 'dev')
147
+ .option('--staging-value <value>', 'Staging environment value (global only)')
148
+ .option('--dev-value <value>', 'Dev environment value (global only)')
149
+ .option('--staging-inherit', 'Staging inherits from production (global only)')
150
+ .option('--dev-inherit', 'Dev inherits from production (global only)')
151
+ .option('--dev-inherit-staging', 'Dev inherits from staging (global only)')
152
+ .action((keyOrProject, valueOrKey, value, options) => {
153
+ (0, env_set_1.envSet)(keyOrProject, valueOrKey, value, options);
141
154
  });
142
155
  program
143
156
  .command('env:list')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidactions/cli",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "SolidActions CLI - Deploy and manage workflow automation",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -1,87 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.envCreate = envCreate;
7
- const axios_1 = __importDefault(require("axios"));
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const init_1 = require("./init");
10
- async function envCreate(key, value, options = {}) {
11
- const config = (0, init_1.getConfig)();
12
- if (!config?.apiKey) {
13
- console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
14
- process.exit(1);
15
- }
16
- console.log(chalk_1.default.blue(`Creating global variable "${key}"...`));
17
- // Build the request body with per-environment values
18
- const body = {
19
- key,
20
- production_value: value,
21
- is_secret: options.secret || false,
22
- };
23
- // Handle staging value and inheritance
24
- if (options.stagingInherit) {
25
- body.staging_source = 'inherit_production';
26
- }
27
- else if (options.stagingValue !== undefined) {
28
- body.staging_value = options.stagingValue;
29
- body.staging_source = 'value';
30
- }
31
- // Handle dev value and inheritance
32
- if (options.devInheritStaging) {
33
- body.dev_source = 'inherit_staging';
34
- }
35
- else if (options.devInherit) {
36
- body.dev_source = 'inherit_production';
37
- }
38
- else if (options.devValue !== undefined) {
39
- body.dev_value = options.devValue;
40
- body.dev_source = 'value';
41
- }
42
- try {
43
- await axios_1.default.post(`${config.host}/api/v1/variables`, body, {
44
- headers: {
45
- 'Authorization': `Bearer ${config.apiKey}`,
46
- 'Accept': 'application/json',
47
- 'Content-Type': 'application/json',
48
- },
49
- });
50
- const typeLabel = options.secret ? 'secret' : 'variable';
51
- console.log(chalk_1.default.green(`Global ${typeLabel} "${key}" created successfully!`));
52
- // Show summary of what was set
53
- console.log(chalk_1.default.gray(` Production: ${options.secret ? '********' : value}`));
54
- if (options.stagingValue) {
55
- console.log(chalk_1.default.gray(` Staging: ${options.secret ? '********' : options.stagingValue}`));
56
- }
57
- else if (options.stagingInherit) {
58
- console.log(chalk_1.default.gray(' Staging: (inherits from production)'));
59
- }
60
- if (options.devValue) {
61
- console.log(chalk_1.default.gray(` Dev: ${options.secret ? '********' : options.devValue}`));
62
- }
63
- else if (options.devInheritStaging) {
64
- console.log(chalk_1.default.gray(' Dev: (inherits from staging)'));
65
- }
66
- else if (options.devInherit) {
67
- console.log(chalk_1.default.gray(' Dev: (inherits from production)'));
68
- }
69
- }
70
- catch (error) {
71
- if (error.response) {
72
- if (error.response.status === 401) {
73
- console.error(chalk_1.default.red('Authentication failed. Run "solidactions init <api-key>" to re-configure.'));
74
- }
75
- else if (error.response.status === 422) {
76
- console.error(chalk_1.default.red('Validation error:'), error.response.data.message || error.response.data.errors);
77
- }
78
- else {
79
- console.error(chalk_1.default.red(`Failed: ${error.response.status}`), error.response.data);
80
- }
81
- }
82
- else {
83
- console.error(chalk_1.default.red('Connection failed:'), error.message);
84
- }
85
- process.exit(1);
86
- }
87
- }