@solidactions/cli 0.7.0 → 1.0.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/README.md CHANGED
@@ -11,39 +11,82 @@ npm install -g @solidactions/cli
11
11
  ## Quick Start
12
12
 
13
13
  ```bash
14
- # Initialize with your API key
15
- solidactions init <api-key>
16
-
17
- # Deploy a project
18
- solidactions deploy <project-name> <path>
14
+ solidactions init <api-key> # Initialize (prompts for workspace)
15
+ solidactions init <api-key> --workspace <name> # Initialize with workspace
16
+ solidactions project deploy <project> <path> # Deploy a project
17
+ solidactions run start <project> <workflow> # Trigger a workflow
18
+ solidactions run view <run-id> # Inspect a run
19
19
  ```
20
20
 
21
21
  ## Commands
22
22
 
23
+ Use `solidactions <command> --help` for full flag details on any command.
24
+
25
+ ### Top-level
26
+
23
27
  | Command | Description |
24
28
  |---------|-------------|
25
- | `init <api-key>` | Initialize CLI with your API key |
29
+ | `init <api-key>` | Initialize CLI with API key |
26
30
  | `logout` | Remove saved credentials |
27
31
  | `whoami` | Show current configuration |
28
- | `deploy <project> [path]` | Deploy a project to SolidActions |
29
- | `pull <project> [path]` | Pull project source from SolidActions |
30
- | `run <project> <workflow>` | Trigger a workflow run |
31
- | `runs [project]` | List recent workflow runs |
32
- | `logs <run-id>` | View logs for a workflow run |
33
- | `logs:build <project>` | View build/deployment logs |
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) |
36
- | `env:list [project]` | List environment variables |
37
- | `env:delete <key>` | Delete an environment variable |
38
- | `env:map <project> <key> <global-key>` | Map a global variable to a project |
39
- | `env:pull <project>` | Pull resolved env vars (including OAuth tokens) to a local file |
40
- | `env:push <project> [path]` | Push .env values to a project |
41
- | `schedule:set <project> <cron>` | Set a cron schedule for a workflow |
42
- | `schedule:list <project>` | List schedules for a project |
43
- | `schedule:delete <project> <id>` | Delete a schedule |
44
- | `webhooks <project>` | List webhook URLs for a project |
45
-
46
- See [docs/cli.md](docs/cli.md) for full documentation.
32
+ | `dev <file>` | Run a workflow locally (no deploy needed) |
33
+
34
+ ### project
35
+
36
+ | Command | Key Flags | Description |
37
+ |---------|-----------|-------------|
38
+ | `project deploy <name> [path]` | `-e`, `--create`, `--config-only` | Deploy or sync config only |
39
+ | `project pull <name> [path]` | `-y` | Pull source (warns before overwriting) |
40
+ | `project logs <name>` | | View build logs |
41
+ | `project list` | | List all projects |
42
+
43
+ ### run
44
+
45
+ | Command | Key Flags | Description |
46
+ |---------|-----------|-------------|
47
+ | `run start <project> <workflow>` | `-e`, `-i`, `-w` | Trigger a workflow run |
48
+ | `run list [project]` | `--json`, `--detailed`, `--status`, `--since`, `--workflow`, `--limit`, `--offset` | List and filter runs |
49
+ | `run view <run-id>` | `--json`, `--timeline`, `--steps`, `--logs` | Inspect a run |
50
+
51
+ ### env
52
+
53
+ | Command | Key Flags | Description |
54
+ |---------|-----------|-------------|
55
+ | `env set <key> <value>` | `-s`, `-y`, `--staging-value`, `--dev-value` | Set global variable (warns before overwriting) |
56
+ | `env set <project> <key> <value>` | `-e`, `-s`, `-y` | Set project variable (warns before overwriting) |
57
+ | `env list [project]` | `-e` | List variables |
58
+ | `env delete <key-or-project> [key]` | `-y` | Delete a variable |
59
+ | `env map <project> <key> <global-key>` | `-y` | Map global to project key (warns before overwriting) |
60
+ | `env pull <project>` | `-e`, `-o`, `-y`, `--update-oauth` | Pull resolved env vars to .env file |
61
+ | `env push <project> [path]` | `-e`, `-y`, `--new-only`, `--include-undeclared` | Push .env values to project |
62
+
63
+ ### schedule
64
+
65
+ | Command | Key Flags | Description |
66
+ |---------|-----------|-------------|
67
+ | `schedule set <project> <cron>` | `-w`, `-i`, `-y` | Set cron schedule (warns if exists) |
68
+ | `schedule list <project>` | | List schedules |
69
+ | `schedule delete <project> <id>` | `-y` | Delete a schedule |
70
+
71
+ ### webhook
72
+
73
+ | Command | Key Flags | Description |
74
+ |---------|-----------|-------------|
75
+ | `webhook list <project>` | `-e`, `--show-secrets` | List webhook URLs |
76
+
77
+ ### workspace
78
+
79
+ | Command | Description |
80
+ |---------|-------------|
81
+ | `workspace list` | List all workspaces |
82
+ | `workspace set <id>` | Set active workspace (by ID, slug, or name) |
83
+
84
+ ### ai
85
+
86
+ | Command | Key Flags | Description |
87
+ |---------|-----------|-------------|
88
+ | `ai init` | `--claude`, `--agents` | Install AI helper docs |
89
+ | `ai examples [names...]` | `--all`, `--overwrite` | Install example workflows |
47
90
 
48
91
  ## Development
49
92
 
@@ -83,7 +83,7 @@ async function aiExamples(names, options = {}) {
83
83
  // Detect AI helper file and upsert examples reference
84
84
  const aiHelperFile = (0, markers_1.findAiHelperFile)();
85
85
  if (!aiHelperFile) {
86
- console.log(chalk_1.default.yellow('No AI helper file found. Run "solidactions ai:init" first to create one.'));
86
+ console.log(chalk_1.default.yellow('No AI helper file found. Run "solidactions ai init" first to create one.'));
87
87
  }
88
88
  else {
89
89
  // List ALL installed examples (existing + newly installed)
@@ -11,8 +11,8 @@ const axios_1 = __importDefault(require("axios"));
11
11
  const form_data_1 = __importDefault(require("form-data"));
12
12
  const chalk_1 = __importDefault(require("chalk"));
13
13
  const js_yaml_1 = __importDefault(require("js-yaml"));
14
- const init_1 = require("./init");
15
14
  const env_1 = require("../utils/env");
15
+ const api_1 = require("../utils/api");
16
16
  /**
17
17
  * Validate project structure before deployment.
18
18
  * Checks for required files and SDK dependency.
@@ -89,7 +89,7 @@ function validateProject(sourceDir) {
89
89
  * Push YAML env declarations to the project.
90
90
  * This registers all YAML-declared vars and their mappings.
91
91
  */
92
- async function pushYamlDeclarations(host, apiKey, projectSlug, yamlConfig) {
92
+ async function pushYamlDeclarations(config, projectSlug, yamlConfig) {
93
93
  const parsedVars = (0, env_1.parseYamlEnvVars)(yamlConfig);
94
94
  if (parsedVars.length === 0) {
95
95
  return;
@@ -102,12 +102,8 @@ async function pushYamlDeclarations(host, apiKey, projectSlug, yamlConfig) {
102
102
  source: 'yaml',
103
103
  }));
104
104
  try {
105
- await axios_1.default.post(`${host}/api/v1/projects/${projectSlug}/variable-mappings/sync-yaml`, { declarations }, {
106
- headers: {
107
- 'Authorization': `Bearer ${apiKey}`,
108
- 'Accept': 'application/json',
109
- 'Content-Type': 'application/json',
110
- },
105
+ await axios_1.default.post(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings/sync-yaml`, { declarations }, {
106
+ headers: (0, api_1.getApiHeaders)(config, 'application/json'),
111
107
  });
112
108
  console.log(chalk_1.default.gray(`Synced ${declarations.length} YAML env declarations`));
113
109
  }
@@ -116,11 +112,7 @@ async function pushYamlDeclarations(host, apiKey, projectSlug, yamlConfig) {
116
112
  }
117
113
  }
118
114
  async function deploy(projectName, sourcePath, options = {}) {
119
- const config = (0, init_1.getConfig)();
120
- if (!config?.apiKey) {
121
- console.error(chalk_1.default.red('Not initialized. Run `solidactions init <api-key>` first.'));
122
- process.exit(1);
123
- }
115
+ const config = await (0, api_1.requireConfigWithWorkspace)();
124
116
  const sourceDir = sourcePath ? path_1.default.resolve(sourcePath) : process.cwd();
125
117
  const environment = options.env || 'dev';
126
118
  if (!fs_1.default.existsSync(sourceDir)) {
@@ -165,10 +157,7 @@ async function deploy(projectName, sourcePath, options = {}) {
165
157
  ? projectName
166
158
  : `${projectName}-${environment}`;
167
159
  const checkResponse = await axios_1.default.get(`${config.host}/api/v1/projects/${lookupSlug}`, {
168
- headers: {
169
- 'Authorization': `Bearer ${config.apiKey}`,
170
- 'Accept': 'application/json',
171
- },
160
+ headers: (0, api_1.getApiHeaders)(config),
172
161
  });
173
162
  projectSlug = checkResponse.data.slug || checkResponse.data.name;
174
163
  }
@@ -187,11 +176,7 @@ async function deploy(projectName, sourcePath, options = {}) {
187
176
  slug: projectName.toLowerCase().replace(/[^a-z0-9-]/g, '-') + (environment !== 'production' ? `-${environment}` : ''),
188
177
  environment: environment,
189
178
  }, {
190
- headers: {
191
- 'Authorization': `Bearer ${config.apiKey}`,
192
- 'Accept': 'application/json',
193
- 'Content-Type': 'application/json',
194
- },
179
+ headers: (0, api_1.getApiHeaders)(config, 'application/json'),
195
180
  });
196
181
  projectSlug = createResponse.data.slug || createResponse.data.name;
197
182
  console.log(chalk_1.default.green(`Project "${projectName}"${envLabel} created.`));
@@ -206,6 +191,16 @@ async function deploy(projectName, sourcePath, options = {}) {
206
191
  process.exit(1);
207
192
  }
208
193
  }
194
+ // --config-only: sync YAML env declarations without building
195
+ if (options.configOnly) {
196
+ if (!yamlConfig) {
197
+ console.error(chalk_1.default.red('Cannot sync config: solidactions.yaml not found or invalid.'));
198
+ process.exit(1);
199
+ }
200
+ await pushYamlDeclarations(config, projectSlug, yamlConfig);
201
+ console.log(chalk_1.default.green(`✓ Config synced for ${projectSlug}${envLabel}`));
202
+ return;
203
+ }
209
204
  const archivePath = path_1.default.join(sourceDir, '.steps-deploy.tar.gz');
210
205
  const output = fs_1.default.createWriteStream(archivePath);
211
206
  const archive = (0, archiver_1.default)('tar', { gzip: true, gzipOptions: { level: 9 } });
@@ -218,8 +213,7 @@ async function deploy(projectName, sourcePath, options = {}) {
218
213
  await axios_1.default.post(`${config.host}/api/v1/projects/${projectSlug}/deploy`, form, {
219
214
  headers: {
220
215
  ...form.getHeaders(),
221
- 'Accept': 'application/json',
222
- 'Authorization': `Bearer ${config.apiKey}`,
216
+ ...(0, api_1.getApiHeaders)(config),
223
217
  },
224
218
  maxContentLength: Infinity,
225
219
  maxBodyLength: Infinity
@@ -228,13 +222,13 @@ async function deploy(projectName, sourcePath, options = {}) {
228
222
  console.log(chalk_1.default.yellow('Waiting for build to complete...\n'));
229
223
  // Poll for completion
230
224
  let attempts = 0;
231
- const maxAttempts = 120; // 2 minutes timeout
225
+ const maxAttempts = 600; // 10 minutes of inactivity timeout
232
226
  let lastLogLength = 0;
233
227
  const poll = setInterval(async () => {
234
228
  try {
235
229
  attempts++;
236
230
  const statusRes = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}`, {
237
- headers: { 'Authorization': `Bearer ${config.apiKey}` }
231
+ headers: (0, api_1.getApiHeaders)(config),
238
232
  });
239
233
  const { status, build_log } = statusRes.data;
240
234
  // Stream new log content
@@ -245,13 +239,18 @@ async function deploy(projectName, sourcePath, options = {}) {
245
239
  process.stdout.write('\n');
246
240
  }
247
241
  lastLogLength = build_log.length;
242
+ attempts = 0; // Reset timeout — build is still progressing
243
+ }
244
+ // Periodic waiting indicator when no logs yet
245
+ if (attempts > 0 && attempts % 15 === 0 && lastLogLength === 0) {
246
+ console.log(chalk_1.default.gray('Still waiting for build to start...'));
248
247
  }
249
248
  if (status === 'deployed') {
250
249
  clearInterval(poll);
251
250
  console.log(chalk_1.default.green(`\n✓ Deployed to ${projectSlug}${envLabel}!`));
252
251
  // Always sync YAML declarations (registers env vars and their mappings)
253
252
  if (yamlConfig) {
254
- await pushYamlDeclarations(config.host, config.apiKey, projectSlug, yamlConfig);
253
+ await pushYamlDeclarations(config, projectSlug, yamlConfig);
255
254
  }
256
255
  fs_1.default.unlinkSync(archivePath);
257
256
  process.exit(0);
@@ -7,13 +7,9 @@ exports.envDelete = envDelete;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const prompts_1 = __importDefault(require("prompts"));
10
- const init_1 = require("./init");
10
+ const api_1 = require("../utils/api");
11
11
  async function envDelete(keyOrProject, keyIfProject, options = {}) {
12
- const config = (0, init_1.getConfig)();
13
- if (!config?.apiKey) {
14
- console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
15
- process.exit(1);
16
- }
12
+ const config = await (0, api_1.requireConfigWithWorkspace)();
17
13
  // Determine mode: if keyIfProject is provided, it's project mapping delete
18
14
  const isProjectMode = keyIfProject !== undefined;
19
15
  const projectName = isProjectMode ? keyOrProject : undefined;
@@ -24,10 +20,7 @@ async function envDelete(keyOrProject, keyIfProject, options = {}) {
24
20
  console.log(chalk_1.default.blue(`Deleting variable mapping "${key}" from project "${projectName}"...`));
25
21
  // First, get the mapping to find its ID
26
22
  const listResponse = await axios_1.default.get(`${config.host}/api/v1/projects/${projectName}/variable-mappings`, {
27
- headers: {
28
- 'Authorization': `Bearer ${config.apiKey}`,
29
- 'Accept': 'application/json',
30
- },
23
+ headers: (0, api_1.getApiHeaders)(config),
31
24
  });
32
25
  const mappings = listResponse.data || [];
33
26
  const mapping = mappings.find((m) => m.env_name === key);
@@ -52,10 +45,7 @@ async function envDelete(keyOrProject, keyIfProject, options = {}) {
52
45
  }
53
46
  // Delete the mapping
54
47
  await axios_1.default.delete(`${config.host}/api/v1/projects/${projectName}/variable-mappings/${mapping.id}`, {
55
- headers: {
56
- 'Authorization': `Bearer ${config.apiKey}`,
57
- 'Accept': 'application/json',
58
- },
48
+ headers: (0, api_1.getApiHeaders)(config),
59
49
  });
60
50
  if (mapping.is_yaml_declared) {
61
51
  console.log(chalk_1.default.green(`Variable mapping "${key}" cleared successfully.`));
@@ -69,10 +59,7 @@ async function envDelete(keyOrProject, keyIfProject, options = {}) {
69
59
  console.log(chalk_1.default.blue(`Deleting global variable "${key}"...`));
70
60
  // First, get the variable to find its ID
71
61
  const listResponse = await axios_1.default.get(`${config.host}/api/v1/variables`, {
72
- headers: {
73
- 'Authorization': `Bearer ${config.apiKey}`,
74
- 'Accept': 'application/json',
75
- },
62
+ headers: (0, api_1.getApiHeaders)(config),
76
63
  });
77
64
  const variables = listResponse.data?.data || [];
78
65
  const variable = variables.find((v) => v.key === key);
@@ -95,10 +82,7 @@ async function envDelete(keyOrProject, keyIfProject, options = {}) {
95
82
  }
96
83
  // Delete the variable
97
84
  await axios_1.default.delete(`${config.host}/api/v1/variables/${variable.id}`, {
98
- headers: {
99
- 'Authorization': `Bearer ${config.apiKey}`,
100
- 'Accept': 'application/json',
101
- },
85
+ headers: (0, api_1.getApiHeaders)(config),
102
86
  });
103
87
  console.log(chalk_1.default.green(`Global variable "${key}" deleted successfully.`));
104
88
  }
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.envList = envList;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
- const init_1 = require("./init");
9
+ const api_1 = require("../utils/api");
10
10
  /**
11
11
  * Format a value for display, with inherited badge if applicable.
12
12
  */
@@ -27,11 +27,7 @@ function formatEnvValue(value, source, isSecret) {
27
27
  return displayValue;
28
28
  }
29
29
  async function envList(projectName, options = {}) {
30
- const config = (0, init_1.getConfig)();
31
- if (!config?.apiKey) {
32
- console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
33
- process.exit(1);
34
- }
30
+ const config = await (0, api_1.requireConfigWithWorkspace)();
35
31
  try {
36
32
  if (projectName) {
37
33
  // List project variable mappings
@@ -41,10 +37,7 @@ async function envList(projectName, options = {}) {
41
37
  : `${projectName}-${environment}`;
42
38
  console.log(chalk_1.default.blue(`Environment variables for project "${projectName}" (${environment}):`));
43
39
  const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings`, {
44
- headers: {
45
- 'Authorization': `Bearer ${config.apiKey}`,
46
- 'Accept': 'application/json',
47
- },
40
+ headers: (0, api_1.getApiHeaders)(config),
48
41
  });
49
42
  const mappings = response.data || [];
50
43
  if (mappings.length === 0) {
@@ -99,10 +92,7 @@ async function envList(projectName, options = {}) {
99
92
  // List global variables with per-environment values
100
93
  console.log(chalk_1.default.blue('Global environment variables:'));
101
94
  const response = await axios_1.default.get(`${config.host}/api/v1/variables`, {
102
- headers: {
103
- 'Authorization': `Bearer ${config.apiKey}`,
104
- 'Accept': 'application/json',
105
- },
95
+ headers: (0, api_1.getApiHeaders)(config),
106
96
  });
107
97
  const variables = response.data?.data || [];
108
98
  if (variables.length === 0) {
@@ -6,39 +6,51 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.envMap = envMap;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
- const init_1 = require("./init");
10
- async function envMap(projectName, projectKey, globalKey) {
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
- }
9
+ const prompts_1 = __importDefault(require("prompts"));
10
+ const api_1 = require("../utils/api");
11
+ async function envMap(projectName, projectKey, globalKey, options = {}) {
12
+ const config = await (0, api_1.requireConfigWithWorkspace)();
16
13
  console.log(chalk_1.default.blue(`Mapping global variable "${globalKey}" to project key "${projectKey}" in "${projectName}"...`));
17
14
  try {
18
15
  // First, get the global variable ID by key
19
16
  const varsResponse = await axios_1.default.get(`${config.host}/api/v1/variables`, {
20
- headers: {
21
- 'Authorization': `Bearer ${config.apiKey}`,
22
- 'Accept': 'application/json',
23
- },
17
+ headers: (0, api_1.getApiHeaders)(config),
24
18
  });
25
19
  const variables = varsResponse.data.data || varsResponse.data;
26
20
  const globalVar = variables.find((v) => v.key === globalKey);
27
21
  if (!globalVar) {
28
22
  console.error(chalk_1.default.red(`Global variable "${globalKey}" not found.`));
29
- console.log(chalk_1.default.gray('Create it with: solidactions env:set ' + globalKey + ' <value>'));
23
+ console.log(chalk_1.default.gray('Create it with: solidactions env set ' + globalKey + ' <value>'));
30
24
  process.exit(1);
31
25
  }
26
+ // Check if project key already has a mapping
27
+ if (!options.yes) {
28
+ const mappingsResponse = await axios_1.default.get(`${config.host}/api/v1/projects/${projectName}/variable-mappings`, { headers: (0, api_1.getApiHeaders)(config) });
29
+ const mappings = mappingsResponse.data || [];
30
+ const existing = mappings.find((m) => m.env_name === projectKey);
31
+ if (existing && (existing.has_value || existing.global_variable_id)) {
32
+ const currentSource = existing.global_variable_id
33
+ ? `mapped to global "${existing.global_variable_key || 'unknown'}"`
34
+ : 'has a local value';
35
+ console.log(chalk_1.default.yellow(`"${projectKey}" already ${currentSource} in "${projectName}".`));
36
+ const confirm = await (0, prompts_1.default)({
37
+ type: 'confirm',
38
+ name: 'proceed',
39
+ message: 'Overwrite mapping?',
40
+ initial: false,
41
+ });
42
+ if (!confirm.proceed) {
43
+ console.log(chalk_1.default.gray('Cancelled.'));
44
+ return;
45
+ }
46
+ }
47
+ }
32
48
  // Create the mapping
33
49
  await axios_1.default.post(`${config.host}/api/v1/projects/${projectName}/variable-mappings`, {
34
50
  project_key: projectKey,
35
51
  global_variable_id: globalVar.id,
36
52
  }, {
37
- headers: {
38
- 'Authorization': `Bearer ${config.apiKey}`,
39
- 'Accept': 'application/json',
40
- 'Content-Type': 'application/json',
41
- },
53
+ headers: (0, api_1.getApiHeaders)(config, 'application/json'),
42
54
  });
43
55
  console.log(chalk_1.default.green(`Variable mapping created!`));
44
56
  console.log(chalk_1.default.gray(` ${globalKey} -> ${projectKey} (in ${projectName})`));
@@ -9,7 +9,7 @@ const path_1 = __importDefault(require("path"));
9
9
  const axios_1 = __importDefault(require("axios"));
10
10
  const chalk_1 = __importDefault(require("chalk"));
11
11
  const readline_1 = __importDefault(require("readline"));
12
- const init_1 = require("./init");
12
+ const api_1 = require("../utils/api");
13
13
  /**
14
14
  * Prompt the user for confirmation (unless --yes flag is set).
15
15
  */
@@ -26,11 +26,7 @@ async function confirm(message) {
26
26
  });
27
27
  }
28
28
  async function envPull(projectName, options = {}) {
29
- const config = (0, init_1.getConfig)();
30
- if (!config?.apiKey) {
31
- console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
32
- process.exit(1);
33
- }
29
+ const config = await (0, api_1.requireConfigWithWorkspace)();
34
30
  const environment = options.env || 'dev';
35
31
  // Build the project slug for lookup
36
32
  const projectSlug = environment === 'production'
@@ -43,10 +39,7 @@ async function envPull(projectName, options = {}) {
43
39
  try {
44
40
  // First, check if there are any secrets
45
41
  const checkResponse = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings?resolve_oauth=true`, {
46
- headers: {
47
- 'Authorization': `Bearer ${config.apiKey}`,
48
- 'Accept': 'application/json',
49
- },
42
+ headers: (0, api_1.getApiHeaders)(config),
50
43
  });
51
44
  const mappings = checkResponse.data || [];
52
45
  if (mappings.length === 0) {
@@ -65,10 +58,7 @@ async function envPull(projectName, options = {}) {
65
58
  }
66
59
  // Now fetch with reveal=true to get actual values
67
60
  const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings?reveal=true&resolve_oauth=true`, {
68
- headers: {
69
- 'Authorization': `Bearer ${config.apiKey}`,
70
- 'Accept': 'application/json',
71
- },
61
+ headers: (0, api_1.getApiHeaders)(config),
72
62
  });
73
63
  const variables = response.data || [];
74
64
  // --update-oauth: Only pull OAuth tokens and merge into existing .env
@@ -157,7 +147,7 @@ async function envPull(projectName, options = {}) {
157
147
  // Full pull: Build .env file content
158
148
  const lines = [];
159
149
  lines.push(`# Environment variables for ${projectName} (${environment})`);
160
- lines.push(`# Generated by solidactions env:pull on ${new Date().toISOString()}`);
150
+ lines.push(`# Generated by solidactions env pull on ${new Date().toISOString()}`);
161
151
  lines.push('');
162
152
  let count = 0;
163
153
  let secretCount = 0;
@@ -218,7 +208,7 @@ async function envPull(projectName, options = {}) {
218
208
  else if (error.response.status === 404) {
219
209
  console.error(chalk_1.default.red(`Project "${projectSlug}" not found.`));
220
210
  if (environment !== 'production') {
221
- console.log(chalk_1.default.gray(`Try deploying with: solidactions deploy ${projectName} --env ${environment} --create`));
211
+ console.log(chalk_1.default.gray(`Try deploying with: solidactions project deploy ${projectName} --env ${environment} --create`));
222
212
  }
223
213
  }
224
214
  else {
@@ -9,14 +9,10 @@ const path_1 = __importDefault(require("path"));
9
9
  const axios_1 = __importDefault(require("axios"));
10
10
  const chalk_1 = __importDefault(require("chalk"));
11
11
  const prompts_1 = __importDefault(require("prompts"));
12
- const init_1 = require("./init");
12
+ const api_1 = require("../utils/api");
13
13
  const env_1 = require("../utils/env");
14
14
  async function envPush(projectName, sourcePath, options = {}) {
15
- const config = (0, init_1.getConfig)();
16
- if (!config?.apiKey) {
17
- console.error(chalk_1.default.red('Not initialized. Run "solidactions init <api-key>" first.'));
18
- process.exit(1);
19
- }
15
+ const config = await (0, api_1.requireConfigWithWorkspace)();
20
16
  const sourceDir = path_1.default.resolve(sourcePath);
21
17
  const environment = options.env || 'dev';
22
18
  // Read solidactions.yaml
@@ -85,10 +81,7 @@ async function envPush(projectName, sourcePath, options = {}) {
85
81
  let serverMappings = [];
86
82
  try {
87
83
  const response = await axios_1.default.get(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings`, {
88
- headers: {
89
- 'Authorization': `Bearer ${config.apiKey}`,
90
- 'Accept': 'application/json',
91
- },
84
+ headers: (0, api_1.getApiHeaders)(config),
92
85
  });
93
86
  serverMappings = response.data || [];
94
87
  }
@@ -99,7 +92,7 @@ async function envPush(projectName, sourcePath, options = {}) {
99
92
  }
100
93
  else if (error.response?.status === 404) {
101
94
  console.error(chalk_1.default.red(`Project "${projectSlug}" not found.`));
102
- console.log(chalk_1.default.gray(`Deploy first with: solidactions deploy ${projectName} --env ${environment}` + (environment !== 'production' ? ' --create' : '')));
95
+ console.log(chalk_1.default.gray(`Deploy first with: solidactions project deploy ${projectName} --env ${environment}` + (environment !== 'production' ? ' --create' : '')));
103
96
  process.exit(1);
104
97
  }
105
98
  throw error;
@@ -191,11 +184,7 @@ async function envPush(projectName, sourcePath, options = {}) {
191
184
  }));
192
185
  try {
193
186
  const response = await axios_1.default.post(`${config.host}/api/v1/projects/${projectSlug}/variable-mappings/bulk`, { variables }, {
194
- headers: {
195
- 'Authorization': `Bearer ${config.apiKey}`,
196
- 'Accept': 'application/json',
197
- 'Content-Type': 'application/json',
198
- },
187
+ headers: (0, api_1.getApiHeaders)(config, 'application/json'),
199
188
  });
200
189
  const { created, updated } = response.data;
201
190
  console.log(chalk_1.default.green(`\n✓ Pushed ${toPush.length} variable(s) to ${projectSlug}`));