mcoda 0.1.19 → 0.1.21
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/dist/commands/backlog/OrderTasksCommand.d.ts +2 -0
- package/dist/commands/backlog/OrderTasksCommand.d.ts.map +1 -1
- package/dist/commands/backlog/OrderTasksCommand.js +38 -2
- package/dist/commands/docs/DocsCommands.d.ts.map +1 -1
- package/dist/commands/docs/DocsCommands.js +11 -11
- package/dist/commands/estimate/EstimateCommands.d.ts.map +1 -1
- package/dist/commands/estimate/EstimateCommands.js +28 -27
- package/dist/commands/openapi/OpenapiCommands.d.ts +1 -0
- package/dist/commands/openapi/OpenapiCommands.d.ts.map +1 -1
- package/dist/commands/openapi/OpenapiCommands.js +11 -1
- package/dist/commands/planning/CreateTasksCommand.d.ts.map +1 -1
- package/dist/commands/planning/CreateTasksCommand.js +18 -12
- package/dist/commands/planning/QaTasksCommand.d.ts +14 -0
- package/dist/commands/planning/QaTasksCommand.d.ts.map +1 -1
- package/dist/commands/planning/QaTasksCommand.js +89 -7
- package/dist/commands/review/CodeReviewCommand.d.ts +14 -0
- package/dist/commands/review/CodeReviewCommand.d.ts.map +1 -1
- package/dist/commands/review/CodeReviewCommand.js +133 -4
- package/dist/commands/work/WorkOnTasksCommand.d.ts +15 -1
- package/dist/commands/work/WorkOnTasksCommand.d.ts.map +1 -1
- package/dist/commands/work/WorkOnTasksCommand.js +140 -8
- package/dist/commands/workspace/ProjectGuidanceCommand.d.ts +1 -0
- package/dist/commands/workspace/ProjectGuidanceCommand.d.ts.map +1 -1
- package/dist/commands/workspace/ProjectGuidanceCommand.js +81 -1
- package/dist/commands/workspace/SetWorkspaceCommand.d.ts.map +1 -1
- package/dist/commands/workspace/SetWorkspaceCommand.js +37 -1
- package/package.json +5 -5
|
@@ -2,12 +2,14 @@ interface ParsedArgs {
|
|
|
2
2
|
workspaceRoot?: string;
|
|
3
3
|
project?: string;
|
|
4
4
|
epic?: string;
|
|
5
|
+
story?: string;
|
|
5
6
|
status?: string[];
|
|
6
7
|
agentName?: string;
|
|
7
8
|
agentStream?: boolean;
|
|
8
9
|
rateAgents: boolean;
|
|
9
10
|
inferDeps: boolean;
|
|
10
11
|
apply: boolean;
|
|
12
|
+
planningContextPolicy: "best_effort" | "require_any" | "require_sds_or_openapi";
|
|
11
13
|
stageOrder?: string[];
|
|
12
14
|
json: boolean;
|
|
13
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/OrderTasksCommand.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"OrderTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/OrderTasksCommand.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,qBAAqB,EAAE,aAAa,GAAG,aAAa,GAAG,wBAAwB,CAAC;IAChF,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;CACf;AAuDD,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,KAAG,UA4IpD,CAAC;AAkDF,qBAAa,iBAAiB;WACf,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA+DhD"}
|
|
@@ -4,11 +4,13 @@ const usage = `mcoda order-tasks \\
|
|
|
4
4
|
[--workspace-root <PATH>] \\
|
|
5
5
|
--project <PROJECT_KEY> \\
|
|
6
6
|
[--epic <EPIC_KEY>] \\
|
|
7
|
+
[--story <STORY_KEY>] \\
|
|
7
8
|
[--status <STATUS_FILTER>] \\
|
|
8
9
|
[--agent <NAME>] \\
|
|
9
10
|
[--agent-stream <true|false>] \\
|
|
10
11
|
[--infer-deps] \\
|
|
11
|
-
[--apply] \\
|
|
12
|
+
[--apply <true|false>] \\
|
|
13
|
+
[--planning-context-policy <best_effort|require_any|require_sds_or_openapi>] \\
|
|
12
14
|
[--stage-order <foundation,backend,frontend,other>] \\
|
|
13
15
|
[--rate-agents] \\
|
|
14
16
|
[--json]`;
|
|
@@ -41,12 +43,22 @@ const parseStageOrder = (value) => {
|
|
|
41
43
|
.filter(Boolean);
|
|
42
44
|
return parts.length ? parts : undefined;
|
|
43
45
|
};
|
|
46
|
+
const normalizePlanningContextPolicy = (value) => {
|
|
47
|
+
if (!value)
|
|
48
|
+
return undefined;
|
|
49
|
+
const normalized = value.trim().toLowerCase();
|
|
50
|
+
if (normalized === "best_effort" || normalized === "require_any" || normalized === "require_sds_or_openapi") {
|
|
51
|
+
return normalized;
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
};
|
|
44
55
|
export const parseOrderTasksArgs = (argv) => {
|
|
45
56
|
const parsed = {
|
|
46
57
|
agentStream: false,
|
|
47
58
|
rateAgents: false,
|
|
48
59
|
inferDeps: false,
|
|
49
|
-
apply:
|
|
60
|
+
apply: true,
|
|
61
|
+
planningContextPolicy: "require_sds_or_openapi",
|
|
50
62
|
json: false,
|
|
51
63
|
};
|
|
52
64
|
for (let i = 0; i < argv.length; i += 1) {
|
|
@@ -75,6 +87,12 @@ export const parseOrderTasksArgs = (argv) => {
|
|
|
75
87
|
parsed.stageOrder = parseStageOrder(arg.split("=")[1]);
|
|
76
88
|
continue;
|
|
77
89
|
}
|
|
90
|
+
if (arg.startsWith("--planning-context-policy=")) {
|
|
91
|
+
const policy = normalizePlanningContextPolicy(arg.split("=")[1]);
|
|
92
|
+
if (policy)
|
|
93
|
+
parsed.planningContextPolicy = policy;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
78
96
|
switch (arg) {
|
|
79
97
|
case "--workspace-root":
|
|
80
98
|
parsed.workspaceRoot = argv[i + 1] ? path.resolve(argv[i + 1]) : undefined;
|
|
@@ -88,6 +106,10 @@ export const parseOrderTasksArgs = (argv) => {
|
|
|
88
106
|
parsed.epic = argv[i + 1];
|
|
89
107
|
i += 1;
|
|
90
108
|
break;
|
|
109
|
+
case "--story":
|
|
110
|
+
parsed.story = argv[i + 1];
|
|
111
|
+
i += 1;
|
|
112
|
+
break;
|
|
91
113
|
case "--status":
|
|
92
114
|
parsed.status = parseStatuses(argv[i + 1]);
|
|
93
115
|
i += 1;
|
|
@@ -133,6 +155,14 @@ export const parseOrderTasksArgs = (argv) => {
|
|
|
133
155
|
parsed.stageOrder = parseStageOrder(argv[i + 1]);
|
|
134
156
|
i += 1;
|
|
135
157
|
break;
|
|
158
|
+
case "--planning-context-policy": {
|
|
159
|
+
const policy = normalizePlanningContextPolicy(argv[i + 1]);
|
|
160
|
+
if (policy) {
|
|
161
|
+
parsed.planningContextPolicy = policy;
|
|
162
|
+
}
|
|
163
|
+
i += 1;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
136
166
|
case "--rate-agents": {
|
|
137
167
|
const next = argv[i + 1];
|
|
138
168
|
if (next && !next.startsWith("-")) {
|
|
@@ -160,6 +190,9 @@ export const parseOrderTasksArgs = (argv) => {
|
|
|
160
190
|
else if (arg.startsWith("--epic=")) {
|
|
161
191
|
parsed.epic = arg.split("=")[1];
|
|
162
192
|
}
|
|
193
|
+
else if (arg.startsWith("--story=")) {
|
|
194
|
+
parsed.story = arg.split("=")[1];
|
|
195
|
+
}
|
|
163
196
|
else if (arg === "--json=true") {
|
|
164
197
|
parsed.json = true;
|
|
165
198
|
}
|
|
@@ -232,11 +265,14 @@ export class OrderTasksCommand {
|
|
|
232
265
|
const result = await service.orderTasks({
|
|
233
266
|
projectKey: parsed.project,
|
|
234
267
|
epicKey: parsed.epic,
|
|
268
|
+
storyKey: parsed.story,
|
|
235
269
|
statusFilter: parsed.status,
|
|
236
270
|
agentName: parsed.agentName,
|
|
237
271
|
agentStream: parsed.agentStream,
|
|
238
272
|
rateAgents: parsed.rateAgents,
|
|
239
273
|
inferDependencies: parsed.inferDeps,
|
|
274
|
+
apply: parsed.apply,
|
|
275
|
+
planningContextPolicy: parsed.planningContextPolicy,
|
|
240
276
|
stageOrder: resolvedStageOrder,
|
|
241
277
|
});
|
|
242
278
|
if (parsed.json) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocsCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/docs/DocsCommands.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAUD,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,KAAG,
|
|
1
|
+
{"version":3,"file":"DocsCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/docs/DocsCommands.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAUD,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,KAAG,aA8N7C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,KAAG,aAoO7C,CAAC;AAoBF,qBAAa,YAAY;WACV,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA+KhD"}
|
|
@@ -23,10 +23,10 @@ export const parsePdrArgs = (argv) => {
|
|
|
23
23
|
let rateAgents = false;
|
|
24
24
|
let fast = false;
|
|
25
25
|
let iterate = false;
|
|
26
|
-
let quality;
|
|
27
|
-
let resolveOpenQuestions =
|
|
28
|
-
let noPlaceholders =
|
|
29
|
-
let noMaybes =
|
|
26
|
+
let quality = "build-ready";
|
|
27
|
+
let resolveOpenQuestions = true;
|
|
28
|
+
let noPlaceholders = true;
|
|
29
|
+
let noMaybes = true;
|
|
30
30
|
let crossAlign = true;
|
|
31
31
|
let dryRun = false;
|
|
32
32
|
let json = false;
|
|
@@ -205,9 +205,6 @@ export const parsePdrArgs = (argv) => {
|
|
|
205
205
|
case "--no-telemetry":
|
|
206
206
|
noTelemetry = true;
|
|
207
207
|
break;
|
|
208
|
-
case "--no-telemetry":
|
|
209
|
-
noTelemetry = true;
|
|
210
|
-
break;
|
|
211
208
|
case "--help":
|
|
212
209
|
case "-h":
|
|
213
210
|
// eslint-disable-next-line no-console
|
|
@@ -255,10 +252,10 @@ export const parseSdsArgs = (argv) => {
|
|
|
255
252
|
let force = false;
|
|
256
253
|
let fast = false;
|
|
257
254
|
let iterate = false;
|
|
258
|
-
let quality;
|
|
259
|
-
let resolveOpenQuestions =
|
|
260
|
-
let noPlaceholders =
|
|
261
|
-
let noMaybes =
|
|
255
|
+
let quality = "build-ready";
|
|
256
|
+
let resolveOpenQuestions = true;
|
|
257
|
+
let noPlaceholders = true;
|
|
258
|
+
let noMaybes = true;
|
|
262
259
|
let crossAlign = true;
|
|
263
260
|
let resumeJobId;
|
|
264
261
|
let dryRun = false;
|
|
@@ -439,6 +436,9 @@ export const parseSdsArgs = (argv) => {
|
|
|
439
436
|
case "--no-color":
|
|
440
437
|
noColor = true;
|
|
441
438
|
break;
|
|
439
|
+
case "--no-telemetry":
|
|
440
|
+
noTelemetry = true;
|
|
441
|
+
break;
|
|
442
442
|
case "--help":
|
|
443
443
|
case "-h":
|
|
444
444
|
// eslint-disable-next-line no-console
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EstimateCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/estimate/EstimateCommands.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,cAAc,EAGf,MAAM,aAAa,CAAC;AAErB,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AA6BD,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,KAAG,UA4HlD,CAAC;
|
|
1
|
+
{"version":3,"file":"EstimateCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/estimate/EstimateCommands.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,cAAc,EAGf,MAAM,aAAa,CAAC;AAErB,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AA6BD,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,KAAG,UA4HlD,CAAC;AAgEF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,MAwBjE,CAAC;AA6NF,qBAAa,gBAAgB;WACd,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAkEhD"}
|
|
@@ -193,11 +193,13 @@ const formatPanel = (lines) => {
|
|
|
193
193
|
const bottom = `╰${"─".repeat(width + 2)}╯`;
|
|
194
194
|
return [top, ...body, bottom].join("\n");
|
|
195
195
|
};
|
|
196
|
-
const formatBoxTable = (headers, rows) => {
|
|
196
|
+
const formatBoxTable = (headers, rows, options) => {
|
|
197
197
|
const widths = headers.map((header, idx) => Math.max(visibleLength(header), ...rows.map((row) => visibleLength(row[idx] ?? ""))));
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
const
|
|
198
|
+
const lineStyle = options?.lineStyle ?? ((value) => value);
|
|
199
|
+
const border = (left, join, right) => lineStyle(`${left}${widths.map((width) => "─".repeat(width + 2)).join(join)}${right}`);
|
|
200
|
+
const verticalLine = lineStyle("│");
|
|
201
|
+
const headerLine = `${verticalLine}${headers.map((header, idx) => ` ${padVisible(header, widths[idx])} `).join(verticalLine)}${verticalLine}`;
|
|
202
|
+
const rowLines = rows.map((row) => `${verticalLine}${row.map((cell, idx) => ` ${padVisible(cell ?? "", widths[idx])} `).join(verticalLine)}${verticalLine}`);
|
|
201
203
|
return [
|
|
202
204
|
border("╭", "┬", "╮"),
|
|
203
205
|
headerLine,
|
|
@@ -330,6 +332,7 @@ const renderProgressSection = (result, colorEnabled) => {
|
|
|
330
332
|
};
|
|
331
333
|
const renderResult = (result, options) => {
|
|
332
334
|
const { colorEnabled } = options;
|
|
335
|
+
const purpleTableLines = (value) => style.magenta(colorEnabled, value);
|
|
333
336
|
const velocity = result.effectiveVelocity;
|
|
334
337
|
const source = velocity.source;
|
|
335
338
|
const spHeader = `SP/H (${source})`;
|
|
@@ -370,15 +373,14 @@ const renderResult = (result, options) => {
|
|
|
370
373
|
],
|
|
371
374
|
];
|
|
372
375
|
// eslint-disable-next-line no-console
|
|
373
|
-
console.log(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
]));
|
|
376
|
+
console.log(style.bold(colorEnabled, style.magenta(colorEnabled, "🧮 Effort by Lane")));
|
|
377
|
+
// eslint-disable-next-line no-console
|
|
378
|
+
console.log(formatBoxTable([
|
|
379
|
+
style.bold(colorEnabled, "LANE"),
|
|
380
|
+
style.bold(colorEnabled, "STORY POINTS"),
|
|
381
|
+
style.bold(colorEnabled, spHeader.toUpperCase()),
|
|
382
|
+
style.bold(colorEnabled, "TIME LEFT"),
|
|
383
|
+
], rows, { lineStyle: purpleTableLines }));
|
|
382
384
|
const counts = result.statusCounts;
|
|
383
385
|
// eslint-disable-next-line no-console
|
|
384
386
|
console.log(formatPanel([
|
|
@@ -404,20 +406,19 @@ const renderResult = (result, options) => {
|
|
|
404
406
|
`${style.bold(colorEnabled, "Samples")}${windowLabel} : impl=${samples.implementation ?? 0}, review=${samples.review ?? 0}, qa=${samples.qa ?? 0}`,
|
|
405
407
|
]));
|
|
406
408
|
// eslint-disable-next-line no-console
|
|
407
|
-
console.log(
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
]));
|
|
409
|
+
console.log(style.bold(colorEnabled, style.magenta(colorEnabled, "⏱️ ETAs")));
|
|
410
|
+
// eslint-disable-next-line no-console
|
|
411
|
+
console.log(formatBoxTable([
|
|
412
|
+
style.bold(colorEnabled, "READY TO REVIEW"),
|
|
413
|
+
style.bold(colorEnabled, "READY TO QA"),
|
|
414
|
+
style.bold(colorEnabled, "COMPLETE"),
|
|
415
|
+
], [
|
|
416
|
+
[
|
|
417
|
+
formatEtaCell(result.etas.readyToReviewEta),
|
|
418
|
+
formatEtaCell(result.etas.readyToQaEta),
|
|
419
|
+
formatEtaCell(result.etas.completeEta),
|
|
420
|
+
],
|
|
421
|
+
], { lineStyle: purpleTableLines }));
|
|
421
422
|
// eslint-disable-next-line no-console
|
|
422
423
|
console.log(formatPanel([
|
|
423
424
|
`${style.bold(colorEnabled, "ℹ️ Assumptions")} : lane work runs in parallel; total hours uses the longest lane.`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenapiCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/openapi/OpenapiCommands.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;CACtB;AAUD,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,KAAG,
|
|
1
|
+
{"version":3,"file":"OpenapiCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/openapi/OpenapiCommands.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;CACtB;AAUD,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,KAAG,iBA6FjD,CAAC;AAcF,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,MAAM,EAiB/D,CAAC;AAEF,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA6EhD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { OpenApiJobError, OpenApiService, WorkspaceResolver } from "@mcoda/core";
|
|
4
|
-
const usage = "mcoda openapi-from-docs [--workspace-root <PATH>] [--agent <NAME>] [--agent-stream <true|false>] [--rate-agents] [--force] [--dry-run] [--validate-only] [--no-telemetry]";
|
|
4
|
+
const usage = "mcoda openapi-from-docs [--workspace-root <PATH>] [--project <PROJECT_KEY>] [--agent <NAME>] [--agent-stream <true|false>] [--rate-agents] [--force] [--dry-run] [--validate-only] [--no-telemetry]";
|
|
5
5
|
const parseBooleanFlag = (value, defaultValue) => {
|
|
6
6
|
if (value === undefined)
|
|
7
7
|
return defaultValue;
|
|
@@ -14,6 +14,7 @@ const parseBooleanFlag = (value, defaultValue) => {
|
|
|
14
14
|
};
|
|
15
15
|
export const parseOpenapiArgs = (argv) => {
|
|
16
16
|
let workspaceRoot;
|
|
17
|
+
let project;
|
|
17
18
|
let agentName;
|
|
18
19
|
let agentStream;
|
|
19
20
|
let rateAgents = false;
|
|
@@ -38,6 +39,10 @@ export const parseOpenapiArgs = (argv) => {
|
|
|
38
39
|
workspaceRoot = argv[i + 1] ? path.resolve(argv[i + 1]) : undefined;
|
|
39
40
|
i += 1;
|
|
40
41
|
break;
|
|
42
|
+
case "--project":
|
|
43
|
+
project = argv[i + 1];
|
|
44
|
+
i += 1;
|
|
45
|
+
break;
|
|
41
46
|
case "--agent":
|
|
42
47
|
agentName = argv[i + 1];
|
|
43
48
|
i += 1;
|
|
@@ -83,11 +88,15 @@ export const parseOpenapiArgs = (argv) => {
|
|
|
83
88
|
process.exit(0);
|
|
84
89
|
break;
|
|
85
90
|
default:
|
|
91
|
+
if (arg.startsWith("--project=")) {
|
|
92
|
+
project = arg.split("=")[1];
|
|
93
|
+
}
|
|
86
94
|
break;
|
|
87
95
|
}
|
|
88
96
|
}
|
|
89
97
|
return {
|
|
90
98
|
workspaceRoot,
|
|
99
|
+
project,
|
|
91
100
|
agentName,
|
|
92
101
|
agentStream: agentStream ?? false,
|
|
93
102
|
rateAgents,
|
|
@@ -141,6 +150,7 @@ export class OpenapiCommands {
|
|
|
141
150
|
const onToken = shouldStream ? (token) => process.stdout.write(token) : undefined;
|
|
142
151
|
const result = await service.generateFromDocs({
|
|
143
152
|
workspace,
|
|
153
|
+
projectKey: parsed.project,
|
|
144
154
|
agentName: parsed.agentName,
|
|
145
155
|
agentStream: parsed.agentStream,
|
|
146
156
|
rateAgents: parsed.rateAgents,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/planning/CreateTasksCommand.ts"],"names":[],"mappings":"AAKA,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AA2D5D,eAAO,MAAM,yBAAyB,GAAI,SAAS;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC,KAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"CreateTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/planning/CreateTasksCommand.ts"],"names":[],"mappings":"AAKA,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AA2D5D,eAAO,MAAM,yBAAyB,GAAI,SAAS;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC,KAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAmD3C,CAAC;AAUF,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,KAAG,UAsIrD,CAAC;AAEF,qBAAa,kBAAkB;WAChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAmEhD"}
|
|
@@ -61,26 +61,32 @@ const listTaskProjects = async (mcodaDir) => {
|
|
|
61
61
|
};
|
|
62
62
|
export const pickCreateTasksProjectKey = (options) => {
|
|
63
63
|
const warnings = [];
|
|
64
|
+
const requestedKey = options.requestedKey?.trim() || undefined;
|
|
65
|
+
const configuredKey = options.configuredKey?.trim() || undefined;
|
|
64
66
|
const derivedKey = options.derivedKey || "proj";
|
|
65
67
|
const existing = options.existing ?? [];
|
|
66
68
|
const latestExisting = existing[0]?.key;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
const existingMatchesRequested = requestedKey ? existing.some((item) => item.key === requestedKey) : false;
|
|
70
|
+
if (requestedKey) {
|
|
71
|
+
if (configuredKey && configuredKey !== requestedKey) {
|
|
72
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; overriding configured project key "${configuredKey}".`);
|
|
73
|
+
}
|
|
74
|
+
if (latestExisting && !existingMatchesRequested) {
|
|
75
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; existing task plans were found for "${latestExisting}".`);
|
|
70
76
|
}
|
|
71
77
|
if (existing.length > 1) {
|
|
72
|
-
warnings.push(`Multiple task plan folders detected (${existing.map((item) => item.key).join(", ")}); using
|
|
78
|
+
warnings.push(`Multiple task plan folders detected (${existing.map((item) => item.key).join(", ")}); using explicitly requested project key "${requestedKey}".`);
|
|
73
79
|
}
|
|
74
|
-
return { projectKey:
|
|
80
|
+
return { projectKey: requestedKey, warnings };
|
|
75
81
|
}
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
: false;
|
|
80
|
-
const selected = requestedMatches ? (options.requestedKey ?? latestExisting) : latestExisting;
|
|
81
|
-
if (options.requestedKey && !requestedMatches) {
|
|
82
|
-
warnings.push(`Found existing project key "${latestExisting}" under workspace task plans; ignoring requested "${options.requestedKey}".`);
|
|
82
|
+
if (configuredKey) {
|
|
83
|
+
if (existing.length > 1) {
|
|
84
|
+
warnings.push(`Multiple task plan folders detected (${existing.map((item) => item.key).join(", ")}); using configured project key "${configuredKey}".`);
|
|
83
85
|
}
|
|
86
|
+
return { projectKey: configuredKey, warnings };
|
|
87
|
+
}
|
|
88
|
+
if (latestExisting) {
|
|
89
|
+
const selected = latestExisting;
|
|
84
90
|
if (!options.requestedKey && selected !== derivedKey) {
|
|
85
91
|
warnings.push(`Reusing existing project key "${selected}" from workspace task plans.`);
|
|
86
92
|
}
|
|
@@ -14,6 +14,8 @@ interface ParsedArgs {
|
|
|
14
14
|
agentStream: boolean;
|
|
15
15
|
rateAgents: boolean;
|
|
16
16
|
createFollowupTasks: "auto" | "none" | "prompt";
|
|
17
|
+
dependencyPolicy: "enforce" | "ignore";
|
|
18
|
+
noChangesPolicy: "require_qa" | "skip" | "manual";
|
|
17
19
|
dryRun: boolean;
|
|
18
20
|
json: boolean;
|
|
19
21
|
debug: boolean;
|
|
@@ -26,7 +28,19 @@ interface ParsedArgs {
|
|
|
26
28
|
cleanIgnorePaths: string[];
|
|
27
29
|
quiet?: boolean;
|
|
28
30
|
}
|
|
31
|
+
type ProjectKeyCandidate = {
|
|
32
|
+
key: string;
|
|
33
|
+
createdAt?: string | null;
|
|
34
|
+
};
|
|
29
35
|
export declare const parseQaTasksArgs: (argv: string[]) => ParsedArgs;
|
|
36
|
+
export declare const pickQaTasksProjectKey: (options: {
|
|
37
|
+
requestedKey?: string;
|
|
38
|
+
configuredKey?: string;
|
|
39
|
+
existing: ProjectKeyCandidate[];
|
|
40
|
+
}) => {
|
|
41
|
+
projectKey?: string;
|
|
42
|
+
warnings: string[];
|
|
43
|
+
};
|
|
30
44
|
export declare class QaTasksCommand {
|
|
31
45
|
static run(argv: string[]): Promise<void>;
|
|
32
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QaTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/planning/QaTasksCommand.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QaTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/planning/QaTasksCommand.ts"],"names":[],"mappings":"AAKA,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,mBAAmB,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IAChD,gBAAgB,EAAE,SAAS,GAAG,QAAQ,CAAC;IACvC,eAAe,EAAE,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAYtE,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,KAAG,UAiOjD,CAAC;AAkBF,eAAO,MAAM,qBAAqB,GAAI,SAAS;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC,KAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAgC5C,CAAC;AAEF,qBAAa,cAAc;WACZ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAsJhD"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { WorkspaceRepository } from "@mcoda/db";
|
|
2
3
|
import { QaTasksApi, WorkspaceResolver } from "@mcoda/core";
|
|
3
4
|
import { PathHelper, QA_ALLOWED_STATUSES, filterTaskStatuses } from "@mcoda/shared";
|
|
4
|
-
const usage = `mcoda qa-tasks [--workspace-root <path>] --project <PROJECT_KEY> [--task <TASK_KEY> ... | --epic <EPIC_KEY> | --story <STORY_KEY>] [--status <STATUS_FILTER>] [--limit N] [--mode auto|manual] [--profile <PROFILE_NAME>] [--level unit|integration|acceptance] [--test-command "<CMD>"] [--agent <NAME>] [--agent-stream true|false] [--rate-agents] [--create-followup-tasks auto|none|prompt] [--result pass|fail] [--notes "<text>"] [--evidence-url "<url>"] [--resume <JOB_ID>] [--allow-dirty true|false] [--clean-ignore "<path[,path]...>"] [--dry-run] [--json]`;
|
|
5
|
+
const usage = `mcoda qa-tasks [--workspace-root <path>] [--project <PROJECT_KEY>] [--task <TASK_KEY> ... | --epic <EPIC_KEY> | --story <STORY_KEY>] [--status <STATUS_FILTER>] [--limit N] [--mode auto|manual] [--profile <PROFILE_NAME>] [--level unit|integration|acceptance] [--test-command "<CMD>"] [--agent <NAME>] [--agent-stream true|false] [--rate-agents] [--create-followup-tasks auto|none|prompt] [--dependency-policy enforce|ignore] [--no-changes-policy require_qa|skip|manual] [--result pass|fail] [--notes "<text>"] [--evidence-url "<url>"] [--resume <JOB_ID>] [--allow-dirty true|false] [--clean-ignore "<path[,path]...>"] [--dry-run] [--json]`;
|
|
5
6
|
const parseBooleanFlag = (value, defaultValue) => {
|
|
6
7
|
if (value === undefined)
|
|
7
8
|
return defaultValue;
|
|
@@ -28,6 +29,8 @@ export const parseQaTasksArgs = (argv) => {
|
|
|
28
29
|
let agentStream;
|
|
29
30
|
let rateAgents = false;
|
|
30
31
|
let followups = "auto";
|
|
32
|
+
let dependencyPolicy;
|
|
33
|
+
let noChangesPolicy;
|
|
31
34
|
let dryRun = false;
|
|
32
35
|
let json = false;
|
|
33
36
|
let debug = false;
|
|
@@ -126,6 +129,23 @@ export const parseQaTasksArgs = (argv) => {
|
|
|
126
129
|
followups = argv[i + 1] ?? "auto";
|
|
127
130
|
i += 1;
|
|
128
131
|
break;
|
|
132
|
+
case "--dependency-policy": {
|
|
133
|
+
const next = argv[i + 1];
|
|
134
|
+
if (next && !next.startsWith("--")) {
|
|
135
|
+
dependencyPolicy = next === "ignore" ? "ignore" : "enforce";
|
|
136
|
+
i += 1;
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case "--no-changes-policy": {
|
|
141
|
+
const next = argv[i + 1];
|
|
142
|
+
if (next && !next.startsWith("--")) {
|
|
143
|
+
noChangesPolicy =
|
|
144
|
+
next === "skip" || next === "manual" || next === "require_qa" ? next : "require_qa";
|
|
145
|
+
i += 1;
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
129
149
|
case "--dry-run":
|
|
130
150
|
dryRun = true;
|
|
131
151
|
break;
|
|
@@ -199,6 +219,8 @@ export const parseQaTasksArgs = (argv) => {
|
|
|
199
219
|
agentStream: agentStream ?? true,
|
|
200
220
|
rateAgents,
|
|
201
221
|
createFollowupTasks: followups,
|
|
222
|
+
dependencyPolicy: dependencyPolicy ?? "enforce",
|
|
223
|
+
noChangesPolicy: noChangesPolicy ?? "require_qa",
|
|
202
224
|
dryRun,
|
|
203
225
|
json,
|
|
204
226
|
debug,
|
|
@@ -212,6 +234,50 @@ export const parseQaTasksArgs = (argv) => {
|
|
|
212
234
|
quiet,
|
|
213
235
|
};
|
|
214
236
|
};
|
|
237
|
+
const listWorkspaceProjects = async (workspaceRoot) => {
|
|
238
|
+
const repo = await WorkspaceRepository.create(workspaceRoot);
|
|
239
|
+
try {
|
|
240
|
+
const rows = await repo
|
|
241
|
+
.getDb()
|
|
242
|
+
.all(`SELECT key, created_at FROM projects ORDER BY created_at ASC, key ASC`);
|
|
243
|
+
return rows
|
|
244
|
+
.map((row) => ({ key: String(row.key), createdAt: row.created_at ?? null }))
|
|
245
|
+
.filter((row) => row.key.trim().length > 0);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
await repo.close();
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
export const pickQaTasksProjectKey = (options) => {
|
|
255
|
+
const warnings = [];
|
|
256
|
+
const requestedKey = options.requestedKey?.trim() || undefined;
|
|
257
|
+
const configuredKey = options.configuredKey?.trim() || undefined;
|
|
258
|
+
const existing = options.existing ?? [];
|
|
259
|
+
const firstExisting = existing[0]?.key;
|
|
260
|
+
if (requestedKey) {
|
|
261
|
+
if (configuredKey && configuredKey !== requestedKey) {
|
|
262
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; overriding configured project key "${configuredKey}".`);
|
|
263
|
+
}
|
|
264
|
+
if (firstExisting && requestedKey !== firstExisting) {
|
|
265
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; first workspace project is "${firstExisting}".`);
|
|
266
|
+
}
|
|
267
|
+
return { projectKey: requestedKey, warnings };
|
|
268
|
+
}
|
|
269
|
+
if (configuredKey) {
|
|
270
|
+
if (firstExisting && configuredKey !== firstExisting) {
|
|
271
|
+
warnings.push(`Using configured project key "${configuredKey}" instead of first workspace project "${firstExisting}".`);
|
|
272
|
+
}
|
|
273
|
+
return { projectKey: configuredKey, warnings };
|
|
274
|
+
}
|
|
275
|
+
if (firstExisting) {
|
|
276
|
+
warnings.push(`No --project provided; defaulting to first workspace project "${firstExisting}".`);
|
|
277
|
+
return { projectKey: firstExisting, warnings };
|
|
278
|
+
}
|
|
279
|
+
return { projectKey: undefined, warnings };
|
|
280
|
+
};
|
|
215
281
|
export class QaTasksCommand {
|
|
216
282
|
static async run(argv) {
|
|
217
283
|
const parsed = parseQaTasksArgs(argv);
|
|
@@ -243,18 +309,29 @@ export class QaTasksCommand {
|
|
|
243
309
|
explicitWorkspace: parsed.workspaceRoot,
|
|
244
310
|
noRepoWrites: true,
|
|
245
311
|
});
|
|
246
|
-
const
|
|
247
|
-
const
|
|
248
|
-
|
|
312
|
+
const existingProjects = parsed.projectKey ? [] : await listWorkspaceProjects(workspace.workspaceRoot);
|
|
313
|
+
const configuredKey = typeof workspace.config?.projectKey === "string" && workspace.config.projectKey.trim().length > 0
|
|
314
|
+
? workspace.config.projectKey
|
|
315
|
+
: undefined;
|
|
316
|
+
const projectResolution = pickQaTasksProjectKey({
|
|
317
|
+
requestedKey: parsed.projectKey,
|
|
318
|
+
configuredKey,
|
|
319
|
+
existing: existingProjects,
|
|
320
|
+
});
|
|
321
|
+
if (!projectResolution.projectKey) {
|
|
249
322
|
// eslint-disable-next-line no-console
|
|
250
|
-
console.error("--project
|
|
323
|
+
console.error("qa-tasks could not resolve a project key. Provide --project <PROJECT_KEY> or create tasks for this workspace first.");
|
|
251
324
|
process.exitCode = 1;
|
|
252
325
|
return;
|
|
253
326
|
}
|
|
327
|
+
if (projectResolution.warnings.length && !parsed.json && !parsed.quiet) {
|
|
328
|
+
// eslint-disable-next-line no-console
|
|
329
|
+
console.warn(projectResolution.warnings.map((warning) => `! ${warning}`).join("\n"));
|
|
330
|
+
}
|
|
254
331
|
try {
|
|
255
332
|
const result = await QaTasksApi.runQa({
|
|
256
333
|
workspaceRoot: workspace.workspaceRoot,
|
|
257
|
-
projectKey,
|
|
334
|
+
projectKey: projectResolution.projectKey,
|
|
258
335
|
taskKeys: parsed.taskKeys,
|
|
259
336
|
epicKey: parsed.epicKey,
|
|
260
337
|
storyKey: parsed.storyKey,
|
|
@@ -270,6 +347,9 @@ export class QaTasksCommand {
|
|
|
270
347
|
agentStream: parsed.agentStream,
|
|
271
348
|
rateAgents: parsed.rateAgents,
|
|
272
349
|
createFollowupTasks: followupMode,
|
|
350
|
+
dependencyPolicy: parsed.dependencyPolicy,
|
|
351
|
+
noChangesPolicy: parsed.noChangesPolicy,
|
|
352
|
+
debug: parsed.debug,
|
|
273
353
|
dryRun: parsed.dryRun,
|
|
274
354
|
result: parsed.result,
|
|
275
355
|
notes: parsed.notes,
|
|
@@ -281,7 +361,7 @@ export class QaTasksCommand {
|
|
|
281
361
|
if (parsed.debug && !parsed.json && !parsed.quiet) {
|
|
282
362
|
// eslint-disable-next-line no-console
|
|
283
363
|
console.log("[debug] options", {
|
|
284
|
-
projectKey,
|
|
364
|
+
projectKey: projectResolution.projectKey,
|
|
285
365
|
tasks: parsed.taskKeys,
|
|
286
366
|
epicKey: parsed.epicKey,
|
|
287
367
|
storyKey: parsed.storyKey,
|
|
@@ -291,6 +371,8 @@ export class QaTasksCommand {
|
|
|
291
371
|
limit: parsed.limit,
|
|
292
372
|
testCommand: parsed.testCommand,
|
|
293
373
|
followups: followupMode,
|
|
374
|
+
dependencyPolicy: parsed.dependencyPolicy,
|
|
375
|
+
noChangesPolicy: parsed.noChangesPolicy,
|
|
294
376
|
dryRun: parsed.dryRun,
|
|
295
377
|
noTelemetry: parsed.noTelemetry,
|
|
296
378
|
});
|
|
@@ -13,9 +13,23 @@ interface ParsedArgs {
|
|
|
13
13
|
agentStream?: boolean;
|
|
14
14
|
rateAgents: boolean;
|
|
15
15
|
createFollowupTasks: boolean;
|
|
16
|
+
executionContextPolicy?: "best_effort" | "require_any" | "require_sds_or_openapi";
|
|
17
|
+
emptyDiffApprovalPolicy?: "ready_to_qa" | "complete";
|
|
16
18
|
json: boolean;
|
|
17
19
|
}
|
|
20
|
+
type ProjectKeyCandidate = {
|
|
21
|
+
key: string;
|
|
22
|
+
createdAt?: string | null;
|
|
23
|
+
};
|
|
18
24
|
export declare const parseCodeReviewArgs: (argv: string[]) => ParsedArgs;
|
|
25
|
+
export declare const pickCodeReviewProjectKey: (options: {
|
|
26
|
+
requestedKey?: string;
|
|
27
|
+
configuredKey?: string;
|
|
28
|
+
existing: ProjectKeyCandidate[];
|
|
29
|
+
}) => {
|
|
30
|
+
projectKey?: string;
|
|
31
|
+
warnings: string[];
|
|
32
|
+
};
|
|
19
33
|
export declare class CodeReviewCommand {
|
|
20
34
|
static run(argv: string[]): Promise<void>;
|
|
21
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeReviewCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/review/CodeReviewCommand.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CodeReviewCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/review/CodeReviewCommand.ts"],"names":[],"mappings":"AAKA,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,sBAAsB,CAAC,EAAE,aAAa,GAAG,aAAa,GAAG,wBAAwB,CAAC;IAClF,uBAAuB,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC;IACrD,IAAI,EAAE,OAAO,CAAC;CACf;AAED,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AA2DtE,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,KAAG,UAuMpD,CAAC;AAoBF,eAAO,MAAM,wBAAwB,GAAI,SAAS;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC,KAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAkC5C,CAAC;AAEF,qBAAa,iBAAiB;WACf,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAoHhD"}
|