@rlarua/agentteams-cli 0.0.10 → 0.0.12
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 +117 -2
- package/dist/api/comment.d.ts +11 -0
- package/dist/api/comment.d.ts.map +1 -0
- package/dist/api/comment.js +33 -0
- package/dist/api/comment.js.map +1 -0
- package/dist/api/plan.d.ts +13 -0
- package/dist/api/plan.d.ts.map +1 -0
- package/dist/api/plan.js +43 -0
- package/dist/api/plan.js.map +1 -0
- package/dist/api/postmortem.d.ts +6 -0
- package/dist/api/postmortem.d.ts.map +1 -0
- package/dist/api/postmortem.js +33 -0
- package/dist/api/postmortem.js.map +1 -0
- package/dist/api/report.d.ts +6 -0
- package/dist/api/report.d.ts.map +1 -0
- package/dist/api/report.js +33 -0
- package/dist/api/report.js.map +1 -0
- package/dist/api/status.d.ts +12 -0
- package/dist/api/status.d.ts.map +1 -0
- package/dist/api/status.js +33 -0
- package/dist/api/status.js.map +1 -0
- package/dist/commands/agentConfig.d.ts.map +1 -1
- package/dist/commands/agentConfig.js +10 -3
- package/dist/commands/agentConfig.js.map +1 -1
- package/dist/commands/agentConfigCommand.d.ts +2 -0
- package/dist/commands/agentConfigCommand.d.ts.map +1 -0
- package/dist/commands/agentConfigCommand.js +20 -0
- package/dist/commands/agentConfigCommand.js.map +1 -0
- package/dist/commands/comment.d.ts +2 -0
- package/dist/commands/comment.d.ts.map +1 -0
- package/dist/commands/comment.js +55 -0
- package/dist/commands/comment.js.map +1 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +30 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/convention.d.ts +25 -0
- package/dist/commands/convention.d.ts.map +1 -1
- package/dist/commands/convention.js +459 -17
- package/dist/commands/convention.js.map +1 -1
- package/dist/commands/conventionRouter.d.ts +3 -0
- package/dist/commands/conventionRouter.d.ts.map +1 -0
- package/dist/commands/conventionRouter.js +46 -0
- package/dist/commands/conventionRouter.js.map +1 -0
- package/dist/commands/dependency.d.ts.map +1 -1
- package/dist/commands/dependency.js +2 -1
- package/dist/commands/dependency.js.map +1 -1
- package/dist/commands/dependencyCommand.d.ts +2 -0
- package/dist/commands/dependencyCommand.d.ts.map +1 -0
- package/dist/commands/dependencyCommand.js +27 -0
- package/dist/commands/dependencyCommand.js.map +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +14 -592
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/plan.d.ts +11 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +370 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/postmortem.d.ts +2 -0
- package/dist/commands/postmortem.d.ts.map +1 -0
- package/dist/commands/postmortem.js +114 -0
- package/dist/commands/postmortem.js.map +1 -0
- package/dist/commands/report.d.ts +2 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +224 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +60 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.js +212 -34
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +11 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +60 -6
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/formatter.js +11 -1
- package/dist/utils/formatter.js.map +1 -1
- package/dist/utils/git.d.ts +19 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +41 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/httpHeaders.d.ts +3 -0
- package/dist/utils/httpHeaders.d.ts.map +1 -0
- package/dist/utils/httpHeaders.js +11 -0
- package/dist/utils/httpHeaders.js.map +1 -0
- package/dist/utils/initOutput.d.ts +3 -0
- package/dist/utils/initOutput.d.ts.map +1 -0
- package/dist/utils/initOutput.js +34 -0
- package/dist/utils/initOutput.js.map +1 -0
- package/dist/utils/legacyCompat.d.ts +3 -0
- package/dist/utils/legacyCompat.d.ts.map +1 -0
- package/dist/utils/legacyCompat.js +20 -0
- package/dist/utils/legacyCompat.js.map +1 -0
- package/dist/utils/outputPolicy.d.ts +12 -0
- package/dist/utils/outputPolicy.d.ts.map +1 -0
- package/dist/utils/outputPolicy.js +132 -0
- package/dist/utils/outputPolicy.js.map +1 -0
- package/dist/utils/parsers.d.ts +7 -0
- package/dist/utils/parsers.d.ts.map +1 -0
- package/dist/utils/parsers.js +52 -0
- package/dist/utils/parsers.js.map +1 -0
- package/dist/utils/planFormat.d.ts +17 -0
- package/dist/utils/planFormat.d.ts.map +1 -0
- package/dist/utils/planFormat.js +80 -0
- package/dist/utils/planFormat.js.map +1 -0
- package/package.json +4 -1
package/dist/commands/index.js
CHANGED
|
@@ -1,25 +1,14 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import { existsSync, mkdirSync, writeFileSync, rmSync, readdirSync, readFileSync } from 'node:fs';
|
|
3
|
-
import { join, resolve } from 'node:path';
|
|
4
1
|
import { executeInitCommand } from './init.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
function toSafeFileName(input) {
|
|
17
|
-
return input
|
|
18
|
-
.toLowerCase()
|
|
19
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
20
|
-
.replace(/^-+|-+$/g, '')
|
|
21
|
-
.slice(0, 60);
|
|
22
|
-
}
|
|
2
|
+
import { executeAgentConfigCommand } from './agentConfigCommand.js';
|
|
3
|
+
import { executeConfigCommand } from './config.js';
|
|
4
|
+
import { executeConventionCommand, executeSyncCommand } from './conventionRouter.js';
|
|
5
|
+
import { executeDependencyCommand } from './dependencyCommand.js';
|
|
6
|
+
import { executeCommentCommand } from './comment.js';
|
|
7
|
+
import { executePlanCommand } from './plan.js';
|
|
8
|
+
import { executePostMortemCommand } from './postmortem.js';
|
|
9
|
+
import { executeReportCommand } from './report.js';
|
|
10
|
+
import { executeStatusCommand } from './status.js';
|
|
11
|
+
import { loadConfig } from '../utils/config.js';
|
|
23
12
|
export async function executeCommand(resource, action, options) {
|
|
24
13
|
switch (resource) {
|
|
25
14
|
case 'init':
|
|
@@ -45,7 +34,10 @@ export async function executeCommand(resource, action, options) {
|
|
|
45
34
|
return executeStatusCommand(apiUrl, config.projectId, headers, action, options);
|
|
46
35
|
}
|
|
47
36
|
if (resource === 'plan') {
|
|
48
|
-
return executePlanCommand(apiUrl, config.projectId, headers, action,
|
|
37
|
+
return executePlanCommand(apiUrl, config.projectId, headers, action, {
|
|
38
|
+
...options,
|
|
39
|
+
defaultCreatedBy: config.agentName,
|
|
40
|
+
});
|
|
49
41
|
}
|
|
50
42
|
if (resource === 'comment') {
|
|
51
43
|
return executeCommentCommand(apiUrl, config.projectId, headers, action, options);
|
|
@@ -108,574 +100,4 @@ export async function executeCommand(resource, action, options) {
|
|
|
108
100
|
throw new Error(`Unknown resource: ${resource}`);
|
|
109
101
|
}
|
|
110
102
|
}
|
|
111
|
-
async function executeStatusCommand(apiUrl, projectId, headers, action, options) {
|
|
112
|
-
const baseUrl = `${apiUrl}/api/projects/${projectId}/agent-statuses`;
|
|
113
|
-
switch (action) {
|
|
114
|
-
case 'report': {
|
|
115
|
-
if (!options.status)
|
|
116
|
-
throw new Error('--status is required for status report');
|
|
117
|
-
if (!options.task)
|
|
118
|
-
throw new Error('--task is required for status report');
|
|
119
|
-
if (options.issues === undefined)
|
|
120
|
-
throw new Error('--issues is required for status report');
|
|
121
|
-
if (options.remaining === undefined)
|
|
122
|
-
throw new Error('--remaining is required for status report');
|
|
123
|
-
const response = await axios.post(baseUrl, {
|
|
124
|
-
agent: options.agent,
|
|
125
|
-
status: options.status,
|
|
126
|
-
task: options.task,
|
|
127
|
-
issues: splitCsv(options.issues),
|
|
128
|
-
remaining: splitCsv(options.remaining),
|
|
129
|
-
}, { headers });
|
|
130
|
-
return response.data;
|
|
131
|
-
}
|
|
132
|
-
case 'list': {
|
|
133
|
-
const params = {};
|
|
134
|
-
const page = toPositiveInteger(options.page);
|
|
135
|
-
const pageSize = toPositiveInteger(options.pageSize);
|
|
136
|
-
if (page !== undefined)
|
|
137
|
-
params.page = page;
|
|
138
|
-
if (pageSize !== undefined)
|
|
139
|
-
params.pageSize = pageSize;
|
|
140
|
-
const requestConfig = Object.keys(params).length > 0
|
|
141
|
-
? { headers, params }
|
|
142
|
-
: { headers };
|
|
143
|
-
const response = await axios.get(baseUrl, requestConfig);
|
|
144
|
-
return response.data;
|
|
145
|
-
}
|
|
146
|
-
case 'get': {
|
|
147
|
-
if (!options.id)
|
|
148
|
-
throw new Error('--id is required for status get');
|
|
149
|
-
const response = await axios.get(`${baseUrl}/${options.id}`, { headers });
|
|
150
|
-
return response.data;
|
|
151
|
-
}
|
|
152
|
-
case 'update': {
|
|
153
|
-
if (!options.id)
|
|
154
|
-
throw new Error('--id is required for status update');
|
|
155
|
-
const body = {};
|
|
156
|
-
if (options.status !== undefined)
|
|
157
|
-
body.status = options.status;
|
|
158
|
-
if (options.task !== undefined)
|
|
159
|
-
body.task = options.task;
|
|
160
|
-
if (options.issues !== undefined)
|
|
161
|
-
body.issues = splitCsv(options.issues);
|
|
162
|
-
if (options.remaining !== undefined)
|
|
163
|
-
body.remaining = splitCsv(options.remaining);
|
|
164
|
-
const response = await axios.put(`${baseUrl}/${options.id}`, body, { headers });
|
|
165
|
-
return response.data;
|
|
166
|
-
}
|
|
167
|
-
case 'delete': {
|
|
168
|
-
if (!options.id)
|
|
169
|
-
throw new Error('--id is required for status delete');
|
|
170
|
-
const response = await axios.delete(`${baseUrl}/${options.id}`, { headers });
|
|
171
|
-
return response.data;
|
|
172
|
-
}
|
|
173
|
-
default:
|
|
174
|
-
throw new Error(`Unknown action: ${action}`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
async function executePlanCommand(apiUrl, projectId, headers, action, options) {
|
|
178
|
-
const baseUrl = `${apiUrl}/api/projects/${projectId}/plans`;
|
|
179
|
-
switch (action) {
|
|
180
|
-
case 'list': {
|
|
181
|
-
const params = {};
|
|
182
|
-
if (options.title)
|
|
183
|
-
params.title = options.title;
|
|
184
|
-
if (options.search)
|
|
185
|
-
params.search = options.search;
|
|
186
|
-
if (options.status)
|
|
187
|
-
params.status = options.status;
|
|
188
|
-
if (options.assignedTo)
|
|
189
|
-
params.assignedTo = options.assignedTo;
|
|
190
|
-
const page = toPositiveInteger(options.page);
|
|
191
|
-
const pageSize = toPositiveInteger(options.pageSize);
|
|
192
|
-
if (page !== undefined)
|
|
193
|
-
params.page = page;
|
|
194
|
-
if (pageSize !== undefined)
|
|
195
|
-
params.pageSize = pageSize;
|
|
196
|
-
const requestConfig = Object.keys(params).length > 0
|
|
197
|
-
? { headers, params }
|
|
198
|
-
: { headers };
|
|
199
|
-
const response = await axios.get(baseUrl, requestConfig);
|
|
200
|
-
return response.data;
|
|
201
|
-
}
|
|
202
|
-
case 'get': {
|
|
203
|
-
if (!options.id)
|
|
204
|
-
throw new Error('--id is required for plan get');
|
|
205
|
-
const response = await axios.get(`${baseUrl}/${options.id}`, {
|
|
206
|
-
headers,
|
|
207
|
-
});
|
|
208
|
-
return response.data;
|
|
209
|
-
}
|
|
210
|
-
case 'create': {
|
|
211
|
-
if (!options.title)
|
|
212
|
-
throw new Error('--title is required for plan create');
|
|
213
|
-
let content = options.content;
|
|
214
|
-
if (options.file) {
|
|
215
|
-
const filePath = resolve(options.file);
|
|
216
|
-
if (!existsSync(filePath)) {
|
|
217
|
-
throw new Error(`File not found: ${options.file}`);
|
|
218
|
-
}
|
|
219
|
-
content = readFileSync(filePath, 'utf-8');
|
|
220
|
-
printFileInfo(options.file, content);
|
|
221
|
-
}
|
|
222
|
-
if (!content || content.trim().length === 0) {
|
|
223
|
-
throw new Error('--content or --file is required for plan create');
|
|
224
|
-
}
|
|
225
|
-
const response = await withSpinner('Creating plan...', () => axios.post(baseUrl, {
|
|
226
|
-
title: options.title,
|
|
227
|
-
content,
|
|
228
|
-
priority: options.priority ?? 'MEDIUM',
|
|
229
|
-
status: options.status,
|
|
230
|
-
}, { headers }), 'Plan created');
|
|
231
|
-
return response.data;
|
|
232
|
-
}
|
|
233
|
-
case 'update': {
|
|
234
|
-
if (!options.id)
|
|
235
|
-
throw new Error('--id is required for plan update');
|
|
236
|
-
const body = {};
|
|
237
|
-
if (options.title)
|
|
238
|
-
body.title = options.title;
|
|
239
|
-
if (options.file) {
|
|
240
|
-
const filePath = resolve(options.file);
|
|
241
|
-
if (!existsSync(filePath)) {
|
|
242
|
-
throw new Error(`File not found: ${options.file}`);
|
|
243
|
-
}
|
|
244
|
-
body.content = readFileSync(filePath, 'utf-8');
|
|
245
|
-
printFileInfo(options.file, body.content);
|
|
246
|
-
}
|
|
247
|
-
else if (options.content) {
|
|
248
|
-
body.content = options.content;
|
|
249
|
-
}
|
|
250
|
-
if (options.status)
|
|
251
|
-
body.status = options.status;
|
|
252
|
-
if (options.priority)
|
|
253
|
-
body.priority = options.priority;
|
|
254
|
-
const response = await withSpinner('Updating plan...', () => axios.put(`${baseUrl}/${options.id}`, body, { headers }), 'Plan updated');
|
|
255
|
-
return response.data;
|
|
256
|
-
}
|
|
257
|
-
case 'delete': {
|
|
258
|
-
if (!options.id)
|
|
259
|
-
throw new Error('--id is required for plan delete');
|
|
260
|
-
await axios.delete(`${baseUrl}/${options.id}`, { headers });
|
|
261
|
-
return { message: `Plan ${options.id} deleted successfully` };
|
|
262
|
-
}
|
|
263
|
-
case 'assign': {
|
|
264
|
-
if (!options.id)
|
|
265
|
-
throw new Error('--id is required for plan assign');
|
|
266
|
-
if (!options.agent)
|
|
267
|
-
throw new Error('--agent is required for plan assign');
|
|
268
|
-
const response = await axios.post(`${baseUrl}/${options.id}/assign`, { assignedTo: options.agent }, { headers });
|
|
269
|
-
return response.data;
|
|
270
|
-
}
|
|
271
|
-
case 'download': {
|
|
272
|
-
if (!options.id)
|
|
273
|
-
throw new Error('--id is required for plan download');
|
|
274
|
-
const result = await withSpinner('Downloading plan...', async () => {
|
|
275
|
-
const response = await axios.get(`${baseUrl}/${options.id}`, { headers });
|
|
276
|
-
const plan = response.data.data;
|
|
277
|
-
const projectRoot = findProjectRoot();
|
|
278
|
-
if (!projectRoot) {
|
|
279
|
-
throw new Error("Project root not found. Run 'agentteams init' first.");
|
|
280
|
-
}
|
|
281
|
-
const activePlanDir = join(projectRoot, '.agentteams', 'active-plan');
|
|
282
|
-
if (!existsSync(activePlanDir)) {
|
|
283
|
-
mkdirSync(activePlanDir, { recursive: true });
|
|
284
|
-
}
|
|
285
|
-
const safeName = toSafeFileName(plan.title) || 'plan';
|
|
286
|
-
const fileName = `${safeName}.md`;
|
|
287
|
-
const filePath = join(activePlanDir, fileName);
|
|
288
|
-
const frontmatter = [
|
|
289
|
-
'---',
|
|
290
|
-
`planId: ${plan.id}`,
|
|
291
|
-
`title: ${plan.title}`,
|
|
292
|
-
`status: ${plan.status}`,
|
|
293
|
-
`priority: ${plan.priority}`,
|
|
294
|
-
`downloadedAt: ${new Date().toISOString()}`,
|
|
295
|
-
'---',
|
|
296
|
-
].join('\n');
|
|
297
|
-
const markdown = plan.contentMarkdown ?? '';
|
|
298
|
-
writeFileSync(filePath, `${frontmatter}\n\n${markdown}`, 'utf-8');
|
|
299
|
-
return {
|
|
300
|
-
message: `Plan downloaded to ${fileName}`,
|
|
301
|
-
filePath: `.agentteams/active-plan/${fileName}`,
|
|
302
|
-
};
|
|
303
|
-
}, 'Plan downloaded');
|
|
304
|
-
return result;
|
|
305
|
-
}
|
|
306
|
-
case 'cleanup': {
|
|
307
|
-
const projectRoot = findProjectRoot();
|
|
308
|
-
if (!projectRoot) {
|
|
309
|
-
throw new Error("Project root not found. Run 'agentteams init' first.");
|
|
310
|
-
}
|
|
311
|
-
const activePlanDir = join(projectRoot, '.agentteams', 'active-plan');
|
|
312
|
-
if (!existsSync(activePlanDir)) {
|
|
313
|
-
return { message: 'No active-plan directory found.', deletedFiles: [] };
|
|
314
|
-
}
|
|
315
|
-
const deletedFiles = await withSpinner('Cleaning up plan files...', async () => {
|
|
316
|
-
const allFiles = readdirSync(activePlanDir).filter((f) => f.endsWith('.md'));
|
|
317
|
-
const deleted = [];
|
|
318
|
-
if (options.id) {
|
|
319
|
-
for (const file of allFiles) {
|
|
320
|
-
const content = readFileSync(join(activePlanDir, file), 'utf-8');
|
|
321
|
-
const match = content.match(/^planId:\s*(.+)$/m);
|
|
322
|
-
if (match && match[1].trim() === options.id) {
|
|
323
|
-
rmSync(join(activePlanDir, file));
|
|
324
|
-
deleted.push(file);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
329
|
-
for (const file of allFiles) {
|
|
330
|
-
rmSync(join(activePlanDir, file));
|
|
331
|
-
deleted.push(file);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
return deleted;
|
|
335
|
-
}, `Cleaned up plan files`);
|
|
336
|
-
return {
|
|
337
|
-
message: deletedFiles.length > 0
|
|
338
|
-
? `Deleted ${deletedFiles.length} file(s).`
|
|
339
|
-
: 'No matching files found.',
|
|
340
|
-
deletedFiles,
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
default:
|
|
344
|
-
throw new Error(`Unknown action: ${action}`);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
async function executeCommentCommand(apiUrl, projectId, headers, action, options) {
|
|
348
|
-
const planBaseUrl = `${apiUrl}/api/projects/${projectId}/plans`;
|
|
349
|
-
const commentBaseUrl = `${apiUrl}/api/projects/${projectId}/comments`;
|
|
350
|
-
switch (action) {
|
|
351
|
-
case 'list': {
|
|
352
|
-
if (!options.planId)
|
|
353
|
-
throw new Error('--plan-id is required for comment list');
|
|
354
|
-
const params = {};
|
|
355
|
-
if (options.type)
|
|
356
|
-
params.type = options.type;
|
|
357
|
-
const page = toPositiveInteger(options.page);
|
|
358
|
-
const pageSize = toPositiveInteger(options.pageSize);
|
|
359
|
-
if (page !== undefined)
|
|
360
|
-
params.page = page;
|
|
361
|
-
if (pageSize !== undefined)
|
|
362
|
-
params.pageSize = pageSize;
|
|
363
|
-
const requestConfig = Object.keys(params).length > 0
|
|
364
|
-
? { headers, params }
|
|
365
|
-
: { headers };
|
|
366
|
-
const response = await axios.get(`${planBaseUrl}/${options.planId}/comments`, requestConfig);
|
|
367
|
-
return response.data;
|
|
368
|
-
}
|
|
369
|
-
case 'get': {
|
|
370
|
-
if (!options.id)
|
|
371
|
-
throw new Error('--id is required for comment get');
|
|
372
|
-
const response = await axios.get(`${commentBaseUrl}/${options.id}`, { headers });
|
|
373
|
-
return response.data;
|
|
374
|
-
}
|
|
375
|
-
case 'create': {
|
|
376
|
-
if (!options.planId)
|
|
377
|
-
throw new Error('--plan-id is required for comment create');
|
|
378
|
-
if (!options.type)
|
|
379
|
-
throw new Error('--type is required for comment create');
|
|
380
|
-
if (!options.content)
|
|
381
|
-
throw new Error('--content is required for comment create');
|
|
382
|
-
const response = await axios.post(`${planBaseUrl}/${options.planId}/comments`, {
|
|
383
|
-
type: options.type,
|
|
384
|
-
content: options.content,
|
|
385
|
-
}, { headers });
|
|
386
|
-
return response.data;
|
|
387
|
-
}
|
|
388
|
-
case 'update': {
|
|
389
|
-
if (!options.id)
|
|
390
|
-
throw new Error('--id is required for comment update');
|
|
391
|
-
if (!options.content)
|
|
392
|
-
throw new Error('--content is required for comment update');
|
|
393
|
-
const response = await axios.put(`${commentBaseUrl}/${options.id}`, { content: options.content }, { headers });
|
|
394
|
-
return response.data;
|
|
395
|
-
}
|
|
396
|
-
case 'delete': {
|
|
397
|
-
if (!options.id)
|
|
398
|
-
throw new Error('--id is required for comment delete');
|
|
399
|
-
await axios.delete(`${commentBaseUrl}/${options.id}`, { headers });
|
|
400
|
-
return { message: `Comment ${options.id} deleted successfully` };
|
|
401
|
-
}
|
|
402
|
-
default:
|
|
403
|
-
throw new Error(`Unknown action: ${action}`);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
async function executeReportCommand(apiUrl, headers, action, options) {
|
|
407
|
-
if (!options.projectId || typeof options.projectId !== 'string') {
|
|
408
|
-
throw new Error('--project-id is required (or configure AGENTTEAMS_PROJECT_ID / .agentteams/config.json)');
|
|
409
|
-
}
|
|
410
|
-
const baseUrl = `${apiUrl}/api/projects/${options.projectId}/completion-reports`;
|
|
411
|
-
switch (action) {
|
|
412
|
-
case 'list': {
|
|
413
|
-
const params = {};
|
|
414
|
-
if (options.planId)
|
|
415
|
-
params.planId = options.planId;
|
|
416
|
-
if (options.reportType)
|
|
417
|
-
params.reportType = options.reportType;
|
|
418
|
-
if (options.status)
|
|
419
|
-
params.status = options.status;
|
|
420
|
-
if (options.createdBy)
|
|
421
|
-
params.createdBy = options.createdBy;
|
|
422
|
-
const page = toPositiveInteger(options.page);
|
|
423
|
-
const pageSize = toPositiveInteger(options.pageSize);
|
|
424
|
-
if (page !== undefined)
|
|
425
|
-
params.page = page;
|
|
426
|
-
if (pageSize !== undefined)
|
|
427
|
-
params.pageSize = pageSize;
|
|
428
|
-
const requestConfig = Object.keys(params).length > 0
|
|
429
|
-
? { headers, params }
|
|
430
|
-
: { headers };
|
|
431
|
-
const response = await axios.get(baseUrl, requestConfig);
|
|
432
|
-
return response.data;
|
|
433
|
-
}
|
|
434
|
-
case 'get': {
|
|
435
|
-
if (!options.id)
|
|
436
|
-
throw new Error('--id is required for report get');
|
|
437
|
-
const response = await axios.get(`${baseUrl}/${options.id}`, { headers });
|
|
438
|
-
return response.data;
|
|
439
|
-
}
|
|
440
|
-
case 'create': {
|
|
441
|
-
const title = (options.title ?? options.summary);
|
|
442
|
-
if (!title || title.trim().length === 0) {
|
|
443
|
-
throw new Error('--title is required for report create (or use --summary)');
|
|
444
|
-
}
|
|
445
|
-
const rawContent = options.content;
|
|
446
|
-
const content = rawContent ?? toDetailsAsMarkdown(options.details);
|
|
447
|
-
if (!content || content.trim().length === 0) {
|
|
448
|
-
throw new Error('--content is required for report create (or use --details)');
|
|
449
|
-
}
|
|
450
|
-
const reportType = options.reportType ?? 'IMPL_PLAN';
|
|
451
|
-
const status = options.status ?? 'COMPLETED';
|
|
452
|
-
const createdBy = options.createdBy
|
|
453
|
-
?? options.defaultCreatedBy
|
|
454
|
-
?? '__cli__';
|
|
455
|
-
const response = await withSpinner('Creating report...', () => axios.post(baseUrl, {
|
|
456
|
-
planId: options.planId,
|
|
457
|
-
title,
|
|
458
|
-
content,
|
|
459
|
-
reportType,
|
|
460
|
-
status,
|
|
461
|
-
createdBy
|
|
462
|
-
}, { headers }), 'Report created');
|
|
463
|
-
return response.data;
|
|
464
|
-
}
|
|
465
|
-
case 'update': {
|
|
466
|
-
if (!options.id)
|
|
467
|
-
throw new Error('--id is required for report update');
|
|
468
|
-
const body = {};
|
|
469
|
-
if (options.title ?? options.summary)
|
|
470
|
-
body.title = options.title ?? options.summary;
|
|
471
|
-
if (options.content)
|
|
472
|
-
body.content = options.content;
|
|
473
|
-
if (options.reportType)
|
|
474
|
-
body.reportType = options.reportType;
|
|
475
|
-
if (options.status)
|
|
476
|
-
body.status = options.status;
|
|
477
|
-
if (options.qualityScore !== undefined)
|
|
478
|
-
body.qualityScore = options.qualityScore;
|
|
479
|
-
const response = await axios.put(`${baseUrl}/${options.id}`, body, { headers });
|
|
480
|
-
return response.data;
|
|
481
|
-
}
|
|
482
|
-
case 'delete': {
|
|
483
|
-
if (!options.id)
|
|
484
|
-
throw new Error('--id is required for report delete');
|
|
485
|
-
await axios.delete(`${baseUrl}/${options.id}`, { headers });
|
|
486
|
-
return { message: `Report ${options.id} deleted successfully` };
|
|
487
|
-
}
|
|
488
|
-
default:
|
|
489
|
-
throw new Error(`Unknown action: ${action}`);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
async function executePostMortemCommand(apiUrl, headers, action, options) {
|
|
493
|
-
if (!options.projectId || typeof options.projectId !== 'string') {
|
|
494
|
-
throw new Error('--project-id is required (or configure AGENTTEAMS_PROJECT_ID / .agentteams/config.json)');
|
|
495
|
-
}
|
|
496
|
-
const baseUrl = `${apiUrl}/api/projects/${options.projectId}/post-mortems`;
|
|
497
|
-
switch (action) {
|
|
498
|
-
case 'list': {
|
|
499
|
-
const params = {};
|
|
500
|
-
if (options.planId)
|
|
501
|
-
params.planId = options.planId;
|
|
502
|
-
if (options.status)
|
|
503
|
-
params.status = options.status;
|
|
504
|
-
if (options.createdBy)
|
|
505
|
-
params.createdBy = options.createdBy;
|
|
506
|
-
const page = toPositiveInteger(options.page);
|
|
507
|
-
const pageSize = toPositiveInteger(options.pageSize);
|
|
508
|
-
if (page !== undefined)
|
|
509
|
-
params.page = page;
|
|
510
|
-
if (pageSize !== undefined)
|
|
511
|
-
params.pageSize = pageSize;
|
|
512
|
-
const requestConfig = Object.keys(params).length > 0
|
|
513
|
-
? { headers, params }
|
|
514
|
-
: { headers };
|
|
515
|
-
const response = await axios.get(baseUrl, requestConfig);
|
|
516
|
-
return response.data;
|
|
517
|
-
}
|
|
518
|
-
case 'get': {
|
|
519
|
-
if (!options.id)
|
|
520
|
-
throw new Error('--id is required for postmortem get');
|
|
521
|
-
const response = await axios.get(`${baseUrl}/${options.id}`, { headers });
|
|
522
|
-
return response.data;
|
|
523
|
-
}
|
|
524
|
-
case 'create': {
|
|
525
|
-
if (!options.title)
|
|
526
|
-
throw new Error('--title is required for postmortem create');
|
|
527
|
-
if (!options.content)
|
|
528
|
-
throw new Error('--content is required for postmortem create');
|
|
529
|
-
if (options.actionItems === undefined)
|
|
530
|
-
throw new Error('--action-items is required for postmortem create');
|
|
531
|
-
const response = await withSpinner('Creating post-mortem...', () => axios.post(baseUrl, {
|
|
532
|
-
planId: options.planId,
|
|
533
|
-
title: options.title,
|
|
534
|
-
content: options.content,
|
|
535
|
-
actionItems: splitCsv(options.actionItems),
|
|
536
|
-
status: options.status,
|
|
537
|
-
createdBy: options.createdBy
|
|
538
|
-
?? options.defaultCreatedBy
|
|
539
|
-
?? '__cli__'
|
|
540
|
-
}, { headers }), 'Post-mortem created');
|
|
541
|
-
return response.data;
|
|
542
|
-
}
|
|
543
|
-
case 'update': {
|
|
544
|
-
if (!options.id)
|
|
545
|
-
throw new Error('--id is required for postmortem update');
|
|
546
|
-
const body = {};
|
|
547
|
-
if (Object.prototype.hasOwnProperty.call(options, 'planId')) {
|
|
548
|
-
body.planId = options.planId;
|
|
549
|
-
}
|
|
550
|
-
if (options.title)
|
|
551
|
-
body.title = options.title;
|
|
552
|
-
if (options.content)
|
|
553
|
-
body.content = options.content;
|
|
554
|
-
if (options.actionItems !== undefined)
|
|
555
|
-
body.actionItems = splitCsv(options.actionItems);
|
|
556
|
-
if (options.status)
|
|
557
|
-
body.status = options.status;
|
|
558
|
-
const response = await axios.put(`${baseUrl}/${options.id}`, body, { headers });
|
|
559
|
-
return response.data;
|
|
560
|
-
}
|
|
561
|
-
case 'delete': {
|
|
562
|
-
if (!options.id)
|
|
563
|
-
throw new Error('--id is required for postmortem delete');
|
|
564
|
-
await axios.delete(`${baseUrl}/${options.id}`, { headers });
|
|
565
|
-
return { message: `PostMortem ${options.id} deleted successfully` };
|
|
566
|
-
}
|
|
567
|
-
default:
|
|
568
|
-
throw new Error(`Unknown action: ${action}`);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
function toDetailsAsMarkdown(details) {
|
|
572
|
-
if (typeof details !== 'string' || details.trim().length === 0) {
|
|
573
|
-
return undefined;
|
|
574
|
-
}
|
|
575
|
-
try {
|
|
576
|
-
const parsed = JSON.parse(details);
|
|
577
|
-
return `\n\n## Details\n\n\`\`\`json\n${JSON.stringify(parsed, null, 2)}\n\`\`\`\n`;
|
|
578
|
-
}
|
|
579
|
-
catch {
|
|
580
|
-
return `\n\n## Details\n\n${details}\n`;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
async function executeConventionCommand(action, options) {
|
|
584
|
-
switch (action) {
|
|
585
|
-
case 'list':
|
|
586
|
-
return conventionList();
|
|
587
|
-
case 'show':
|
|
588
|
-
return conventionShow();
|
|
589
|
-
case 'download':
|
|
590
|
-
return conventionDownload({ cwd: options?.cwd });
|
|
591
|
-
default:
|
|
592
|
-
throw new Error(`Unknown convention action: ${action}. Use list, show, or download.`);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
async function executeSyncCommand(action, options) {
|
|
596
|
-
switch (action) {
|
|
597
|
-
case 'download':
|
|
598
|
-
return conventionDownload({ cwd: options?.cwd });
|
|
599
|
-
default:
|
|
600
|
-
throw new Error(`Unknown sync action: ${action}. Use download.`);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
async function executeAgentConfigCommand(action, options) {
|
|
604
|
-
switch (action) {
|
|
605
|
-
case 'list':
|
|
606
|
-
return agentConfigList();
|
|
607
|
-
case 'get': {
|
|
608
|
-
if (!options.id)
|
|
609
|
-
throw new Error('--id is required for agent-config get');
|
|
610
|
-
return agentConfigGet(options.id);
|
|
611
|
-
}
|
|
612
|
-
case 'delete': {
|
|
613
|
-
if (!options.id)
|
|
614
|
-
throw new Error('--id is required for agent-config delete');
|
|
615
|
-
return agentConfigDelete(options.id);
|
|
616
|
-
}
|
|
617
|
-
default:
|
|
618
|
-
throw new Error(`Unknown agent-config action: ${action}. Use list, get, or delete.`);
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
async function executeDependencyCommand(action, options) {
|
|
622
|
-
switch (action) {
|
|
623
|
-
case 'list': {
|
|
624
|
-
if (!options.planId)
|
|
625
|
-
throw new Error('--plan-id is required for dependency list');
|
|
626
|
-
return dependencyList(options.planId);
|
|
627
|
-
}
|
|
628
|
-
case 'create': {
|
|
629
|
-
if (!options.planId)
|
|
630
|
-
throw new Error('--plan-id is required for dependency create');
|
|
631
|
-
if (!options.blockingPlanId)
|
|
632
|
-
throw new Error('--blocking-plan-id is required for dependency create');
|
|
633
|
-
return dependencyCreate(options.planId, options.blockingPlanId);
|
|
634
|
-
}
|
|
635
|
-
case 'delete': {
|
|
636
|
-
if (!options.planId)
|
|
637
|
-
throw new Error('--plan-id is required for dependency delete');
|
|
638
|
-
if (!options.depId)
|
|
639
|
-
throw new Error('--dep-id is required for dependency delete');
|
|
640
|
-
return dependencyDelete(options.planId, options.depId);
|
|
641
|
-
}
|
|
642
|
-
default:
|
|
643
|
-
throw new Error(`Unknown dependency action: ${action}. Use list, create, or delete.`);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
function splitCsv(value) {
|
|
647
|
-
if (typeof value !== 'string') {
|
|
648
|
-
return [];
|
|
649
|
-
}
|
|
650
|
-
const trimmed = value.trim();
|
|
651
|
-
if (trimmed.length === 0) {
|
|
652
|
-
return [];
|
|
653
|
-
}
|
|
654
|
-
return trimmed
|
|
655
|
-
.split(',')
|
|
656
|
-
.map((item) => item.trim())
|
|
657
|
-
.filter((item) => item.length > 0);
|
|
658
|
-
}
|
|
659
|
-
function toPositiveInteger(value) {
|
|
660
|
-
if (typeof value === 'number' && Number.isInteger(value) && value > 0) {
|
|
661
|
-
return value;
|
|
662
|
-
}
|
|
663
|
-
if (typeof value === 'string' && /^\d+$/.test(value)) {
|
|
664
|
-
const parsed = Number.parseInt(value, 10);
|
|
665
|
-
return parsed > 0 ? parsed : undefined;
|
|
666
|
-
}
|
|
667
|
-
return undefined;
|
|
668
|
-
}
|
|
669
|
-
async function executeConfigCommand(action) {
|
|
670
|
-
switch (action) {
|
|
671
|
-
case 'whoami': {
|
|
672
|
-
return {
|
|
673
|
-
apiKey: process.env.AGENTTEAMS_API_KEY,
|
|
674
|
-
apiUrl: process.env.AGENTTEAMS_API_URL,
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
default:
|
|
678
|
-
throw new Error(`Unknown action: ${action}`);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
103
|
//# sourceMappingURL=index.js.map
|