@profoundlogic/coderflow-cli 0.2.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/LICENSE.txt +322 -0
- package/README.md +102 -0
- package/coder.js +202 -0
- package/lib/commands/apply.js +238 -0
- package/lib/commands/attach.js +143 -0
- package/lib/commands/config.js +226 -0
- package/lib/commands/containers.js +213 -0
- package/lib/commands/discard.js +167 -0
- package/lib/commands/interactive.js +292 -0
- package/lib/commands/jira.js +464 -0
- package/lib/commands/license.js +172 -0
- package/lib/commands/list.js +104 -0
- package/lib/commands/login.js +329 -0
- package/lib/commands/logs.js +66 -0
- package/lib/commands/profile.js +539 -0
- package/lib/commands/reject.js +53 -0
- package/lib/commands/results.js +89 -0
- package/lib/commands/run.js +237 -0
- package/lib/commands/server.js +537 -0
- package/lib/commands/status.js +39 -0
- package/lib/commands/test.js +335 -0
- package/lib/config.js +378 -0
- package/lib/help.js +444 -0
- package/lib/http-client.js +180 -0
- package/lib/oidc.js +126 -0
- package/lib/profile.js +296 -0
- package/lib/state-capture.js +336 -0
- package/lib/task-grouping.js +210 -0
- package/lib/terminal-client.js +162 -0
- package/package.json +35 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command: coder run - Create and run a task
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { request } from '../http-client.js';
|
|
6
|
+
import { getDefaultEnvironment } from '../config.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Parse command line arguments for task parameters
|
|
10
|
+
* @param {Array} args - Command line arguments
|
|
11
|
+
* @returns {Object} { taskType, environment, parameters }
|
|
12
|
+
*/
|
|
13
|
+
function parseKeyValue(pair) {
|
|
14
|
+
const [rawKey, ...rest] = pair.split('=');
|
|
15
|
+
if (!rawKey || rest.length === 0) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const key = rawKey.trim();
|
|
19
|
+
const value = rest.join('=').trim();
|
|
20
|
+
if (!key || !value) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return { key, value };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseTaskArgs(args) {
|
|
27
|
+
let taskType = null;
|
|
28
|
+
let environment = null;
|
|
29
|
+
let jiraIssueKey = null;
|
|
30
|
+
let withLocalState = false;
|
|
31
|
+
const parameters = {};
|
|
32
|
+
const envVars = {};
|
|
33
|
+
const branches = {};
|
|
34
|
+
|
|
35
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
36
|
+
const arg = args[index];
|
|
37
|
+
|
|
38
|
+
if (arg === '--branch') {
|
|
39
|
+
const next = args[index + 1];
|
|
40
|
+
if (!next) {
|
|
41
|
+
console.error('Error: --branch requires REPO=BRANCH or BRANCH');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
const parsed = parseKeyValue(next);
|
|
45
|
+
if (parsed) {
|
|
46
|
+
// Format: --branch profoundjs=feature-xyz
|
|
47
|
+
branches[parsed.key] = parsed.value;
|
|
48
|
+
} else {
|
|
49
|
+
// Format: --branch feature-xyz (will be applied to first selectable repo)
|
|
50
|
+
branches._default = next.trim();
|
|
51
|
+
}
|
|
52
|
+
index += 1; // Skip value token
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (arg.startsWith('--branch=')) {
|
|
57
|
+
const pair = arg.substring('--branch='.length);
|
|
58
|
+
const parsed = parseKeyValue(pair);
|
|
59
|
+
if (parsed) {
|
|
60
|
+
// Format: --branch=profoundjs=feature-xyz
|
|
61
|
+
branches[parsed.key] = parsed.value;
|
|
62
|
+
} else {
|
|
63
|
+
// Format: --branch=feature-xyz (will be applied to first selectable repo)
|
|
64
|
+
branches._default = pair.trim();
|
|
65
|
+
}
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (arg === '--env') {
|
|
70
|
+
const next = args[index + 1];
|
|
71
|
+
if (!next) {
|
|
72
|
+
console.error('Error: --env requires KEY=VALUE');
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
const parsed = parseKeyValue(next);
|
|
76
|
+
if (!parsed) {
|
|
77
|
+
console.error(`Error: Invalid --env value: ${next}`);
|
|
78
|
+
console.error('Expected format: --env KEY=VALUE');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
envVars[parsed.key] = parsed.value;
|
|
82
|
+
index += 1; // Skip value token
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (arg.startsWith('--env=')) {
|
|
87
|
+
const pair = arg.substring('--env='.length);
|
|
88
|
+
const parsed = parseKeyValue(pair);
|
|
89
|
+
if (!parsed) {
|
|
90
|
+
console.error(`Error: Invalid --env value: ${pair}`);
|
|
91
|
+
console.error('Expected format: --env KEY=VALUE');
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
envVars[parsed.key] = parsed.value;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (arg === '--environment') {
|
|
99
|
+
const next = args[index + 1];
|
|
100
|
+
if (!next) {
|
|
101
|
+
console.error('Error: --environment requires a value');
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
environment = next;
|
|
105
|
+
index += 1;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (arg.startsWith('--environment=')) {
|
|
110
|
+
environment = arg.substring('--environment='.length);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (arg === '--jira') {
|
|
115
|
+
const next = args[index + 1];
|
|
116
|
+
if (!next) {
|
|
117
|
+
console.error('Error: --jira requires an issue key (e.g., PROJ-123)');
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
jiraIssueKey = next.trim().toUpperCase();
|
|
121
|
+
index += 1;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (arg.startsWith('--jira=')) {
|
|
126
|
+
jiraIssueKey = arg.substring('--jira='.length).trim().toUpperCase();
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (arg === '--with-local-state') {
|
|
131
|
+
withLocalState = true;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (arg.startsWith('--')) {
|
|
136
|
+
const match = arg.match(/^--([^=]+)=(.+)$/);
|
|
137
|
+
if (match) {
|
|
138
|
+
const [, key, value] = match;
|
|
139
|
+
parameters[key] = value;
|
|
140
|
+
} else {
|
|
141
|
+
console.error(`Error: Unrecognized option: ${arg}`);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (!taskType) {
|
|
148
|
+
taskType = arg;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.error(`Error: Unexpected argument: ${arg}`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return { taskType, environment, parameters, envVars, branches, jiraIssueKey, withLocalState };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export async function runTask(args = []) {
|
|
160
|
+
const { taskType, environment, parameters, envVars, branches, jiraIssueKey, withLocalState } = parseTaskArgs(args);
|
|
161
|
+
let resolvedEnvironment = environment;
|
|
162
|
+
|
|
163
|
+
if (!resolvedEnvironment) {
|
|
164
|
+
resolvedEnvironment = await getDefaultEnvironment();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (jiraIssueKey) {
|
|
168
|
+
console.log(`Creating task from Jira issue: ${jiraIssueKey}`);
|
|
169
|
+
if (resolvedEnvironment) {
|
|
170
|
+
console.log(`Environment: ${resolvedEnvironment}`);
|
|
171
|
+
}
|
|
172
|
+
} else if (taskType) {
|
|
173
|
+
console.log(`Creating task: ${taskType}`);
|
|
174
|
+
if (resolvedEnvironment) {
|
|
175
|
+
console.log(`Environment: ${resolvedEnvironment}`);
|
|
176
|
+
}
|
|
177
|
+
if (Object.keys(parameters).length > 0) {
|
|
178
|
+
console.log(`Parameters: ${JSON.stringify(parameters, null, 2)}`);
|
|
179
|
+
}
|
|
180
|
+
if (Object.keys(envVars).length > 0) {
|
|
181
|
+
console.log(`Environment variables: ${JSON.stringify(envVars, null, 2)}`);
|
|
182
|
+
}
|
|
183
|
+
if (Object.keys(branches).length > 0) {
|
|
184
|
+
console.log(`Branches: ${JSON.stringify(branches, null, 2)}`);
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
console.log(`Creating new task...`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const requestBody = {};
|
|
191
|
+
if (taskType) {
|
|
192
|
+
requestBody.task_type = taskType;
|
|
193
|
+
}
|
|
194
|
+
if (resolvedEnvironment) {
|
|
195
|
+
requestBody.environment = resolvedEnvironment;
|
|
196
|
+
}
|
|
197
|
+
if (Object.keys(parameters).length > 0) {
|
|
198
|
+
requestBody.parameters = parameters;
|
|
199
|
+
}
|
|
200
|
+
if (Object.keys(envVars).length > 0) {
|
|
201
|
+
requestBody.env_vars = envVars;
|
|
202
|
+
}
|
|
203
|
+
if (Object.keys(branches).length > 0) {
|
|
204
|
+
requestBody.branches = branches;
|
|
205
|
+
}
|
|
206
|
+
if (jiraIssueKey) {
|
|
207
|
+
requestBody.jira_issue_key = jiraIssueKey;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Capture local repository state if requested
|
|
211
|
+
if (withLocalState) {
|
|
212
|
+
console.log('\n🔍 Capturing local repository state...');
|
|
213
|
+
requestBody.capture_local_state = true;
|
|
214
|
+
requestBody.source_path = process.cwd();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const data = await request('/tasks', {
|
|
218
|
+
method: 'POST',
|
|
219
|
+
body: JSON.stringify(requestBody)
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
console.log(`\n✓ Task created successfully`);
|
|
223
|
+
console.log(` Task ID: ${data.taskId}`);
|
|
224
|
+
console.log(` Container ID: ${data.containerId}`);
|
|
225
|
+
console.log(` Status: ${data.status}`);
|
|
226
|
+
if (data.environment) {
|
|
227
|
+
console.log(` Environment: ${data.environment}`);
|
|
228
|
+
}
|
|
229
|
+
if (data.taskType) {
|
|
230
|
+
console.log(` Task Type: ${data.taskType}`);
|
|
231
|
+
}
|
|
232
|
+
if (data.jira) {
|
|
233
|
+
console.log(` Jira Issue: ${data.jira.key} - ${data.jira.summary}`);
|
|
234
|
+
}
|
|
235
|
+
console.log(`\nUse "coder status ${data.taskId}" to check progress`);
|
|
236
|
+
console.log(`Use "coder results ${data.taskId}" to get results`);
|
|
237
|
+
}
|