mcoda 0.1.18 → 0.1.20

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.
Files changed (29) hide show
  1. package/dist/commands/backlog/BacklogCommands.d.ts.map +1 -1
  2. package/dist/commands/backlog/BacklogCommands.js +11 -7
  3. package/dist/commands/backlog/OrderTasksCommand.d.ts +2 -0
  4. package/dist/commands/backlog/OrderTasksCommand.d.ts.map +1 -1
  5. package/dist/commands/backlog/OrderTasksCommand.js +38 -2
  6. package/dist/commands/docs/DocsCommands.d.ts.map +1 -1
  7. package/dist/commands/docs/DocsCommands.js +11 -11
  8. package/dist/commands/estimate/EstimateCommands.d.ts.map +1 -1
  9. package/dist/commands/estimate/EstimateCommands.js +132 -19
  10. package/dist/commands/openapi/OpenapiCommands.d.ts +1 -0
  11. package/dist/commands/openapi/OpenapiCommands.d.ts.map +1 -1
  12. package/dist/commands/openapi/OpenapiCommands.js +11 -1
  13. package/dist/commands/planning/CreateTasksCommand.d.ts.map +1 -1
  14. package/dist/commands/planning/CreateTasksCommand.js +18 -12
  15. package/dist/commands/planning/QaTasksCommand.d.ts +14 -0
  16. package/dist/commands/planning/QaTasksCommand.d.ts.map +1 -1
  17. package/dist/commands/planning/QaTasksCommand.js +89 -7
  18. package/dist/commands/review/CodeReviewCommand.d.ts +14 -0
  19. package/dist/commands/review/CodeReviewCommand.d.ts.map +1 -1
  20. package/dist/commands/review/CodeReviewCommand.js +133 -4
  21. package/dist/commands/work/WorkOnTasksCommand.d.ts +14 -0
  22. package/dist/commands/work/WorkOnTasksCommand.d.ts.map +1 -1
  23. package/dist/commands/work/WorkOnTasksCommand.js +129 -6
  24. package/dist/commands/workspace/ProjectGuidanceCommand.d.ts +1 -0
  25. package/dist/commands/workspace/ProjectGuidanceCommand.d.ts.map +1 -1
  26. package/dist/commands/workspace/ProjectGuidanceCommand.js +81 -1
  27. package/dist/commands/workspace/SetWorkspaceCommand.d.ts.map +1 -1
  28. package/dist/commands/workspace/SetWorkspaceCommand.js +37 -1
  29. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"BacklogCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/BacklogCommands.ts"],"names":[],"mappings":"AAIA,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,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AA6BD,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,KAAG,UAuHjD,CAAC;AAgLF,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA4DhD"}
1
+ {"version":3,"file":"BacklogCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/BacklogCommands.ts"],"names":[],"mappings":"AAIA,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,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AA6BD,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,KAAG,UAuHjD,CAAC;AAqLF,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA4DhD"}
@@ -177,13 +177,17 @@ const resolveStatuses = (parsed) => {
177
177
  };
178
178
  const pad = (value, width) => value.padEnd(width, " ");
179
179
  const formatTable = (headers, rows) => {
180
- const widths = headers.map((header, idx) => {
181
- return Math.max(header.length, ...rows.map((row) => (row[idx] ?? "").length));
182
- });
183
- const headerLine = headers.map((h, idx) => pad(h, widths[idx])).join(" | ");
184
- const sepLine = widths.map((w) => "-".repeat(w)).join("-+-");
185
- const body = rows.map((row) => row.map((cell, idx) => pad(cell ?? "", widths[idx])).join(" | ")).join("\n");
186
- return [headerLine, sepLine, body].filter(Boolean).join("\n");
180
+ const widths = headers.map((header, idx) => Math.max(header.length, ...rows.map((row) => (row[idx] ?? "").length)));
181
+ const border = (left, join, right) => `${left}${widths.map((width) => "─".repeat(width + 2)).join(join)}${right}`;
182
+ const headerLine = `│${headers.map((header, idx) => ` ${pad(header, widths[idx])} `).join("│")}│`;
183
+ const rowLines = rows.map((row) => `│${row.map((cell, idx) => ` ${pad(cell ?? "", widths[idx])} `).join("")}│`);
184
+ return [
185
+ border("╭", "", ""),
186
+ headerLine,
187
+ border("├", "┼", "┤"),
188
+ ...rowLines,
189
+ border("╰", "┴", "╯"),
190
+ ].join("\n");
187
191
  };
188
192
  const truncate = (value, max = 100) => {
189
193
  if (!value)
@@ -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;AA0CD,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,KAAG,UAwHpD,CAAC;AAkDF,qBAAa,iBAAiB;WACf,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA4DhD"}
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: false,
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,aAiO7C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,KAAG,aAiO7C,CAAC;AAoBF,qBAAa,YAAY;WACV,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA+KhD"}
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 = false;
28
- let noPlaceholders = false;
29
- let noMaybes = false;
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 = false;
260
- let noPlaceholders = false;
261
- let noMaybes = false;
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;AAkBF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,MAwBjE,CAAC;AA4HF,qBAAa,gBAAgB;WACd,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAgEhD"}
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"}
@@ -168,13 +168,45 @@ export const parseEstimateArgs = (argv) => {
168
168
  }
169
169
  return parsed;
170
170
  };
171
- const pad = (value, width) => value.padEnd(width, " ");
172
- const formatTable = (headers, rows) => {
173
- const widths = headers.map((header, idx) => Math.max(header.length, ...rows.map((row) => (row[idx] ?? "").length)));
174
- const headerLine = headers.map((h, idx) => pad(h, widths[idx])).join(" | ");
175
- const sepLine = widths.map((w) => "-".repeat(w)).join("-+-");
176
- const body = rows.map((row) => row.map((cell, idx) => pad(cell ?? "", widths[idx])).join(" | ")).join("\n");
177
- return [headerLine, sepLine, body].filter(Boolean).join("\n");
171
+ const ANSI_REGEX = /\x1b\[[0-9;]*m/g;
172
+ const stripAnsi = (value) => value.replace(ANSI_REGEX, "");
173
+ const visibleLength = (value) => stripAnsi(value).length;
174
+ const padVisible = (value, width) => {
175
+ const diff = width - visibleLength(value);
176
+ return diff > 0 ? `${value}${" ".repeat(diff)}` : value;
177
+ };
178
+ const colorize = (enabled, code, value) => enabled ? `\x1b[${code}m${value}\x1b[0m` : value;
179
+ const style = {
180
+ bold: (enabled, value) => colorize(enabled, 1, value),
181
+ dim: (enabled, value) => colorize(enabled, 2, value),
182
+ blue: (enabled, value) => colorize(enabled, 34, value),
183
+ cyan: (enabled, value) => colorize(enabled, 36, value),
184
+ green: (enabled, value) => colorize(enabled, 32, value),
185
+ yellow: (enabled, value) => colorize(enabled, 33, value),
186
+ magenta: (enabled, value) => colorize(enabled, 35, value),
187
+ red: (enabled, value) => colorize(enabled, 31, value),
188
+ };
189
+ const formatPanel = (lines) => {
190
+ const width = Math.max(0, ...lines.map((line) => visibleLength(line)));
191
+ const top = `╭${"─".repeat(width + 2)}╮`;
192
+ const body = lines.map((line) => `│ ${padVisible(line, width)} │`);
193
+ const bottom = `╰${"─".repeat(width + 2)}╯`;
194
+ return [top, ...body, bottom].join("\n");
195
+ };
196
+ const formatBoxTable = (headers, rows, options) => {
197
+ const widths = headers.map((header, idx) => Math.max(visibleLength(header), ...rows.map((row) => visibleLength(row[idx] ?? ""))));
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}`);
203
+ return [
204
+ border("╭", "┬", "╮"),
205
+ headerLine,
206
+ border("├", "┼", "┤"),
207
+ ...rowLines,
208
+ border("╰", "┴", "╯"),
209
+ ].join("\n");
178
210
  };
179
211
  const fmt = (value) => {
180
212
  if (value === null || value === undefined)
@@ -249,7 +281,58 @@ const formatEtaCell = (eta) => {
249
281
  const relative = formatRelativeDuration(date.getTime(), Date.now());
250
282
  return `${eta} (local ${local}, ${relative})`;
251
283
  };
252
- const renderResult = (result) => {
284
+ const createBar = (percentValue, theme) => {
285
+ const percent = Math.max(0, Math.min(100, Number.isFinite(percentValue) ? percentValue : 0));
286
+ const rounded = Math.round(percent);
287
+ const width = 10;
288
+ if (rounded <= 0) {
289
+ return theme.empty("░".repeat(width));
290
+ }
291
+ if (rounded >= 100) {
292
+ return theme.full("█".repeat(width));
293
+ }
294
+ const fullCount = Math.min(width - 1, Math.floor((rounded / 100) * width));
295
+ const partialCount = 1;
296
+ const emptyCount = Math.max(0, width - fullCount - partialCount);
297
+ return `${theme.full("█".repeat(fullCount))}${theme.partial("▒".repeat(partialCount))}${theme.empty("░".repeat(emptyCount))}`;
298
+ };
299
+ const renderProgressSection = (result, colorEnabled) => {
300
+ const work = result.completion.workOnTasks;
301
+ const qa = result.completion.readyToQa;
302
+ const done = result.completion.done;
303
+ const labels = [
304
+ "🛠️ Work on tasks",
305
+ "🧪 Ready to qa",
306
+ "✅ Done",
307
+ ];
308
+ const maxLabel = Math.max(...labels.map((label) => visibleLength(label)));
309
+ const formatLine = (label, metric, theme) => {
310
+ const bar = createBar(metric.percent, theme);
311
+ const percent = `${Math.round(metric.percent)}%`;
312
+ return `${padVisible(label, maxLabel)} : ${bar} ${percent} (${metric.done}/${metric.total})`;
313
+ };
314
+ return formatPanel([
315
+ style.bold(colorEnabled, "📊 Completion"),
316
+ formatLine("🛠️ Work on tasks", work, {
317
+ full: (value) => style.cyan(colorEnabled, value),
318
+ partial: (value) => style.blue(colorEnabled, value),
319
+ empty: (value) => style.dim(colorEnabled, value),
320
+ }),
321
+ formatLine("🧪 Ready to qa", qa, {
322
+ full: (value) => style.yellow(colorEnabled, value),
323
+ partial: (value) => style.magenta(colorEnabled, value),
324
+ empty: (value) => style.dim(colorEnabled, value),
325
+ }),
326
+ formatLine("✅ Done", done, {
327
+ full: (value) => style.green(colorEnabled, value),
328
+ partial: (value) => style.yellow(colorEnabled, value),
329
+ empty: (value) => style.dim(colorEnabled, value),
330
+ }),
331
+ ]);
332
+ };
333
+ const renderResult = (result, options) => {
334
+ const { colorEnabled } = options;
335
+ const purpleTableLines = (value) => style.magenta(colorEnabled, value);
253
336
  const velocity = result.effectiveVelocity;
254
337
  const source = velocity.source;
255
338
  const spHeader = `SP/H (${source})`;
@@ -290,28 +373,56 @@ const renderResult = (result) => {
290
373
  ],
291
374
  ];
292
375
  // eslint-disable-next-line no-console
293
- console.log(formatTable(["LANE", "STORY_POINTS", spHeader, "TIME_LEFT"], rows));
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 }));
384
+ const counts = result.statusCounts;
385
+ // eslint-disable-next-line no-console
386
+ console.log(formatPanel([
387
+ style.bold(colorEnabled, "📌 Task Status"),
388
+ `${style.bold(colorEnabled, "Total tasks")} : ${counts.total}`,
389
+ `${style.cyan(colorEnabled, "Ready to code review")} : ${counts.readyToCodeReview}`,
390
+ `${style.yellow(colorEnabled, "Ready to qa")} : ${counts.readyToQa}`,
391
+ `${style.blue(colorEnabled, "In progress")} : ${counts.inProgress}`,
392
+ `${style.red(colorEnabled, "Failed")} : ${counts.failed}`,
393
+ `${style.green(colorEnabled, "Completed")} : ${counts.completed}`,
394
+ ]));
395
+ // eslint-disable-next-line no-console
396
+ console.log(renderProgressSection(result, colorEnabled));
294
397
  const samples = velocity.samples ?? { implementation: 0, review: 0, qa: 0 };
295
398
  const windowLabel = velocity.windowTasks ? ` (window ${velocity.windowTasks})` : "";
296
399
  const fallbackNote = velocity.requestedMode && velocity.requestedMode !== velocity.source
297
400
  ? ` (requested ${velocity.requestedMode}; no empirical samples, using config)`
298
401
  : "";
299
402
  // eslint-disable-next-line no-console
300
- console.log(`\nVelocity source: ${velocity.source}${fallbackNote}`);
301
- // eslint-disable-next-line no-console
302
- console.log(`Velocity samples${windowLabel}: impl=${samples.implementation ?? 0}, review=${samples.review ?? 0}, qa=${samples.qa ?? 0}`);
403
+ console.log(formatPanel([
404
+ style.bold(colorEnabled, "📈 Velocity"),
405
+ `${style.bold(colorEnabled, "Velocity source")} : ${velocity.source}${fallbackNote}`,
406
+ `${style.bold(colorEnabled, "Samples")}${windowLabel} : impl=${samples.implementation ?? 0}, review=${samples.review ?? 0}, qa=${samples.qa ?? 0}`,
407
+ ]));
303
408
  // eslint-disable-next-line no-console
304
- console.log("ETAs:");
409
+ console.log(style.bold(colorEnabled, style.magenta(colorEnabled, "⏱️ ETAs")));
305
410
  // eslint-disable-next-line no-console
306
- console.log(formatTable(["READY_TO_REVIEW", "READY_TO_QA", "COMPLETE"], [
411
+ console.log(formatBoxTable([
412
+ style.bold(colorEnabled, "READY TO REVIEW"),
413
+ style.bold(colorEnabled, "READY TO QA"),
414
+ style.bold(colorEnabled, "COMPLETE"),
415
+ ], [
307
416
  [
308
417
  formatEtaCell(result.etas.readyToReviewEta),
309
418
  formatEtaCell(result.etas.readyToQaEta),
310
419
  formatEtaCell(result.etas.completeEta),
311
420
  ],
312
- ]));
421
+ ], { lineStyle: purpleTableLines }));
313
422
  // eslint-disable-next-line no-console
314
- console.log("\nAssumptions: lane work runs in parallel; total hours uses the longest lane.");
423
+ console.log(formatPanel([
424
+ `${style.bold(colorEnabled, "ℹ️ Assumptions")} : lane work runs in parallel; total hours uses the longest lane.`,
425
+ ]));
315
426
  };
316
427
  export class EstimateCommands {
317
428
  static async run(argv) {
@@ -346,17 +457,19 @@ export class EstimateCommands {
346
457
  console.log(JSON.stringify(result, null, 2));
347
458
  }
348
459
  else if (!parsed.quiet) {
460
+ const colorEnabled = !parsed.noColor;
349
461
  const totalTasks = result.backlogTotals.implementation.tasks +
350
462
  result.backlogTotals.review.tasks +
351
463
  result.backlogTotals.qa.tasks +
352
464
  result.backlogTotals.done.tasks;
465
+ const scopeText = `project=${parsed.project ?? "all"}${parsed.epic ? `, epic=${parsed.epic}` : ""}${parsed.story ? `, story=${parsed.story}` : ""}${parsed.assignee ? `, assignee=${parsed.assignee}` : ""}`;
353
466
  // eslint-disable-next-line no-console
354
- console.log(`Scope: project=${parsed.project ?? "all"}${parsed.epic ? `, epic=${parsed.epic}` : ""}${parsed.story ? `, story=${parsed.story}` : ""}${parsed.assignee ? `, assignee=${parsed.assignee}` : ""}`);
467
+ console.log(formatPanel([`${style.bold(colorEnabled, "🧭 Scope")} : ${scopeText}`]));
355
468
  if (totalTasks === 0) {
356
469
  // eslint-disable-next-line no-console
357
- console.log("No tasks found in the selected scope. Showing zeroed estimate.");
470
+ console.log(formatPanel([style.yellow(colorEnabled, "No tasks found in the selected scope. Showing zeroed estimate.")]));
358
471
  }
359
- renderResult(result);
472
+ renderResult(result, { colorEnabled });
360
473
  }
361
474
  }
362
475
  catch (error) {
@@ -1,5 +1,6 @@
1
1
  export interface ParsedOpenapiArgs {
2
2
  workspaceRoot?: string;
3
+ project?: string;
3
4
  agentName?: string;
4
5
  agentStream: boolean;
5
6
  rateAgents: boolean;
@@ -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,iBAoFjD,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;CA4EhD"}
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;CA0C3C,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"}
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
- if (options.configuredKey) {
68
- if (options.requestedKey && options.requestedKey !== options.configuredKey) {
69
- warnings.push(`Using configured project key "${options.configuredKey}" from workspace config; ignoring requested "${options.requestedKey}".`);
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 configured project key "${options.configuredKey}".`);
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: options.configuredKey, warnings };
80
+ return { projectKey: requestedKey, warnings };
75
81
  }
76
- if (latestExisting) {
77
- const requestedMatches = options.requestedKey
78
- ? existing.some((item) => item.key === options.requestedKey)
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":"AAIA,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,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;AAYD,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,KAAG,UA4MjD,CAAC;AAEF,qBAAa,cAAc;WACZ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAmIhD"}
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"}