mcoda 0.1.33 → 0.1.35

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.
@@ -1 +1 @@
1
- {"version":3,"file":"McodaEntrypoint.d.ts","sourceRoot":"","sources":["../../src/bin/McodaEntrypoint.ts"],"names":[],"mappings":";AA+BA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;CAkMxE"}
1
+ {"version":3,"file":"McodaEntrypoint.d.ts","sourceRoot":"","sources":["../../src/bin/McodaEntrypoint.ts"],"names":[],"mappings":";AA+BA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;CAuMxE"}
@@ -134,7 +134,13 @@ export class McodaEntrypoint {
134
134
  return;
135
135
  }
136
136
  if (command === "sds" || command === "mcoda:sds") {
137
- await DocsCommands.run(["sds", "generate", ...rest]);
137
+ const [subcommand, ...tail] = rest;
138
+ if (subcommand === "generate" || subcommand === "suggestions") {
139
+ await DocsCommands.run(["sds", subcommand, ...tail]);
140
+ }
141
+ else {
142
+ await DocsCommands.run(["sds", "generate", ...rest]);
143
+ }
138
144
  return;
139
145
  }
140
146
  if (command === "create-tasks") {
@@ -1 +1 @@
1
- {"version":3,"file":"AgentsCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/AgentsCommands.ts"],"names":[],"mappings":"AA0WA,qBAAa,cAAc;WACZ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAqWhD"}
1
+ {"version":3,"file":"AgentsCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/AgentsCommands.ts"],"names":[],"mappings":"AAwXA,qBAAa,cAAc;WACZ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAsWhD"}
@@ -42,6 +42,9 @@ Usage: mcoda agent <list|details|limits|add|update|delete|remove|auth|auth-statu
42
42
 
43
43
  Subcommands:
44
44
  list List agents (supports --json)
45
+ --refresh-health Force health checks before listing
46
+ --no-refresh-health Skip health checks before listing
47
+ (default: enabled for --json, disabled for table output)
45
48
  details <NAME> Show agent details (supports --json)
46
49
  limits Show tracked usage-limit windows/reset times
47
50
  --agent <NAME> Filter by agent slug/id
@@ -158,6 +161,18 @@ const parseBooleanFlag = (value, label) => {
158
161
  return false;
159
162
  throw new Error(`Invalid ${label}; expected true/false`);
160
163
  };
164
+ const resolveListRefreshHealth = (flags) => {
165
+ const refreshHealth = parseBooleanFlag(flags["refresh-health"], "--refresh-health");
166
+ const noRefreshHealth = parseBooleanFlag(flags["no-refresh-health"], "--no-refresh-health");
167
+ if (refreshHealth === true && noRefreshHealth === true) {
168
+ throw new Error("Conflicting flags: --refresh-health and --no-refresh-health");
169
+ }
170
+ if (noRefreshHealth === true)
171
+ return false;
172
+ if (refreshHealth === true)
173
+ return true;
174
+ return Boolean(flags.json);
175
+ };
161
176
  const parseCostPerMillion = (value) => {
162
177
  if (value === undefined)
163
178
  return undefined;
@@ -374,7 +389,8 @@ export class AgentsCommands {
374
389
  try {
375
390
  switch (subcommand) {
376
391
  case "list": {
377
- const agents = await api.listAgents();
392
+ const refreshHealth = resolveListRefreshHealth(parsed.flags);
393
+ const agents = await api.listAgents({ refreshHealth });
378
394
  if (parsed.flags.json) {
379
395
  const detailed = await Promise.all(agents.map((agent) => api.getAgent(agent.id ?? agent.slug)));
380
396
  // eslint-disable-next-line no-console
@@ -47,8 +47,25 @@ export interface ParsedSdsArgs {
47
47
  noColor: boolean;
48
48
  noTelemetry: boolean;
49
49
  }
50
+ export interface ParsedSdsSuggestionsArgs {
51
+ workspaceRoot?: string;
52
+ projectKey?: string;
53
+ sdsPath?: string;
54
+ reviewAgentName?: string;
55
+ fixAgentName?: string;
56
+ agentStream: boolean;
57
+ rateAgents: boolean;
58
+ maxIterations: number;
59
+ dryRun: boolean;
60
+ json: boolean;
61
+ quiet: boolean;
62
+ debug: boolean;
63
+ noColor: boolean;
64
+ noTelemetry: boolean;
65
+ }
50
66
  export declare const parsePdrArgs: (argv: string[]) => ParsedPdrArgs;
51
67
  export declare const parseSdsArgs: (argv: string[]) => ParsedSdsArgs;
68
+ export declare const parseSdsSuggestionsArgs: (argv: string[]) => ParsedSdsSuggestionsArgs;
52
69
  export declare class DocsCommands {
53
70
  static run(argv: string[]): Promise<void>;
54
71
  }
@@ -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,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"}
1
+ {"version":3,"file":"DocsCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/docs/DocsCommands.ts"],"names":[],"mappings":"AAOA,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;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,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;AAiBD,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,KAAG,aA8N7C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,KAAG,aAoO7C,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,EAAE,KAAG,wBA4HxD,CAAC;AAoBF,qBAAa,YAAY;WACV,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA0PhD"}
@@ -2,6 +2,7 @@ import path from "node:path";
2
2
  import { DocsService, WorkspaceResolver } from "@mcoda/core";
3
3
  const pdrUsage = `mcoda docs pdr generate --rfp-path <FILE> [--workspace-root <PATH>] [--project <KEY>] [--out <FILE>] [--agent <NAME>] [--agent-stream <true|false>] [--rate-agents] [--rfp-id <ID>] [--fast] [--iterate] [--quality <build-ready>] [--resolve-open-questions] [--no-placeholders] [--no-maybes] [--cross-align] [--json] [--dry-run] [--debug] [--no-color] [--quiet] [--no-telemetry]`;
4
4
  const sdsUsage = `mcoda docs sds generate [--workspace-root <PATH>] [--project <KEY>] [--out <FILE>] [--agent <NAME>] [--template <NAME>] [--agent-stream <true|false>] [--rate-agents] [--fast] [--iterate] [--quality <build-ready>] [--resolve-open-questions] [--no-placeholders] [--no-maybes] [--cross-align] [--force] [--resume <JOB_ID>] [--json] [--dry-run] [--debug] [--no-color] [--quiet] [--no-telemetry]`;
5
+ const sdsSuggestionsUsage = `mcoda docs sds suggestions [--workspace-root <PATH>] [--project <KEY>] [--sds-path <FILE>] [--review-agent <NAME>] [--fix-agent <NAME>] [--agent-stream <true|false>] [--rate-agents] [--max-iterations <N>] [--json] [--dry-run] [--debug] [--no-color] [--quiet] [--no-telemetry]`;
5
6
  const parseBooleanFlag = (value, defaultValue) => {
6
7
  if (value === undefined)
7
8
  return defaultValue;
@@ -12,6 +13,15 @@ const parseBooleanFlag = (value, defaultValue) => {
12
13
  return true;
13
14
  return defaultValue;
14
15
  };
16
+ const clampIterations = (value) => {
17
+ if (!Number.isFinite(value))
18
+ return 100;
19
+ if (value < 1)
20
+ return 1;
21
+ if (value > 100)
22
+ return 100;
23
+ return Math.floor(value);
24
+ };
15
25
  export const parsePdrArgs = (argv) => {
16
26
  let workspaceRoot;
17
27
  let projectKey;
@@ -476,6 +486,131 @@ export const parseSdsArgs = (argv) => {
476
486
  noTelemetry,
477
487
  };
478
488
  };
489
+ export const parseSdsSuggestionsArgs = (argv) => {
490
+ let workspaceRoot;
491
+ let projectKey;
492
+ let sdsPath;
493
+ let reviewAgentName;
494
+ let fixAgentName;
495
+ let agentStream;
496
+ let rateAgents = false;
497
+ let maxIterations = 100;
498
+ let dryRun = false;
499
+ let json = false;
500
+ let quiet = false;
501
+ let debug = false;
502
+ let noColor = false;
503
+ let noTelemetry = false;
504
+ for (let i = 0; i < argv.length; i += 1) {
505
+ const arg = argv[i];
506
+ if (arg.startsWith("--rate-agents=")) {
507
+ const [, raw] = arg.split("=", 2);
508
+ rateAgents = parseBooleanFlag(raw, true);
509
+ continue;
510
+ }
511
+ if (arg.startsWith("--max-iterations=")) {
512
+ const [, raw] = arg.split("=", 2);
513
+ const parsed = Number.parseInt(raw ?? "", 10);
514
+ maxIterations = clampIterations(parsed);
515
+ continue;
516
+ }
517
+ switch (arg) {
518
+ case "--workspace-root":
519
+ workspaceRoot = argv[i + 1] ? path.resolve(argv[i + 1]) : undefined;
520
+ i += 1;
521
+ break;
522
+ case "--project":
523
+ projectKey = argv[i + 1];
524
+ i += 1;
525
+ break;
526
+ case "--sds-path":
527
+ sdsPath = argv[i + 1];
528
+ i += 1;
529
+ break;
530
+ case "--agent":
531
+ case "--review-agent":
532
+ reviewAgentName = argv[i + 1];
533
+ i += 1;
534
+ break;
535
+ case "--fix-agent":
536
+ fixAgentName = argv[i + 1];
537
+ i += 1;
538
+ break;
539
+ case "--agent-stream": {
540
+ const next = argv[i + 1];
541
+ if (next && !next.startsWith("--")) {
542
+ agentStream = parseBooleanFlag(next, true);
543
+ i += 1;
544
+ }
545
+ else {
546
+ agentStream = true;
547
+ }
548
+ break;
549
+ }
550
+ case "--rate-agents": {
551
+ const next = argv[i + 1];
552
+ if (next && !next.startsWith("--")) {
553
+ rateAgents = parseBooleanFlag(next, true);
554
+ i += 1;
555
+ }
556
+ else {
557
+ rateAgents = true;
558
+ }
559
+ break;
560
+ }
561
+ case "--max-iterations": {
562
+ const next = argv[i + 1];
563
+ if (next && !next.startsWith("--")) {
564
+ const parsed = Number.parseInt(next, 10);
565
+ maxIterations = clampIterations(parsed);
566
+ i += 1;
567
+ }
568
+ break;
569
+ }
570
+ case "--json":
571
+ json = true;
572
+ break;
573
+ case "--dry-run":
574
+ dryRun = true;
575
+ break;
576
+ case "--quiet":
577
+ quiet = true;
578
+ break;
579
+ case "--debug":
580
+ debug = true;
581
+ break;
582
+ case "--no-color":
583
+ noColor = true;
584
+ break;
585
+ case "--no-telemetry":
586
+ noTelemetry = true;
587
+ break;
588
+ case "--help":
589
+ case "-h":
590
+ // eslint-disable-next-line no-console
591
+ console.log(sdsSuggestionsUsage);
592
+ process.exit(0);
593
+ default:
594
+ break;
595
+ }
596
+ }
597
+ return {
598
+ workspaceRoot,
599
+ projectKey,
600
+ sdsPath,
601
+ reviewAgentName,
602
+ fixAgentName,
603
+ agentStream: agentStream ?? false,
604
+ rateAgents,
605
+ maxIterations,
606
+ dryRun,
607
+ json,
608
+ quiet,
609
+ debug,
610
+ noColor,
611
+ noTelemetry,
612
+ };
613
+ };
479
614
  const printWarnings = (warnings) => {
480
615
  if (warnings.length === 0)
481
616
  return;
@@ -502,6 +637,75 @@ export class DocsCommands {
502
637
  let args = [...argv];
503
638
  if (args[0] === "sds") {
504
639
  args = args.slice(1);
640
+ const subcommand = args[0];
641
+ if (subcommand === "suggestions") {
642
+ args = args.slice(1);
643
+ const parsed = parseSdsSuggestionsArgs(args);
644
+ const workspace = await WorkspaceResolver.resolveWorkspace({
645
+ cwd: process.cwd(),
646
+ explicitWorkspace: parsed.workspaceRoot,
647
+ });
648
+ if (parsed.debug) {
649
+ // eslint-disable-next-line no-console
650
+ console.error(`[debug] workspace resolved: ${workspace.workspaceRoot}`);
651
+ }
652
+ service = await DocsService.create(workspace, { noTelemetry: parsed.noTelemetry });
653
+ const shouldStream = parsed.agentStream && !parsed.json && !parsed.quiet;
654
+ const onToken = shouldStream ? (token) => process.stdout.write(token) : undefined;
655
+ const result = await service.generateSdsSuggestions({
656
+ workspace,
657
+ projectKey: parsed.projectKey,
658
+ sdsPath: parsed.sdsPath,
659
+ reviewAgentName: parsed.reviewAgentName,
660
+ fixAgentName: parsed.fixAgentName,
661
+ agentStream: parsed.agentStream,
662
+ rateAgents: parsed.rateAgents,
663
+ maxIterations: parsed.maxIterations,
664
+ dryRun: parsed.dryRun,
665
+ json: parsed.json,
666
+ onToken,
667
+ });
668
+ if (parsed.json) {
669
+ // eslint-disable-next-line no-console
670
+ console.log(JSON.stringify({
671
+ jobId: result.jobId,
672
+ commandRunId: result.commandRunId,
673
+ sdsPath: result.sdsPath,
674
+ suggestionsDir: result.suggestionsDir,
675
+ suggestionFiles: result.suggestionFiles,
676
+ reviewerAgentId: result.reviewerAgentId,
677
+ fixerAgentId: result.fixerAgentId,
678
+ iterations: result.iterations,
679
+ finalStatus: result.finalStatus,
680
+ warnings: result.warnings,
681
+ }, null, 2));
682
+ return;
683
+ }
684
+ if (shouldStream) {
685
+ // eslint-disable-next-line no-console
686
+ console.log("\n");
687
+ }
688
+ // eslint-disable-next-line no-console
689
+ console.log(`SDS suggestions job ${result.jobId} completed.`);
690
+ // eslint-disable-next-line no-console
691
+ console.log(`Final status: ${result.finalStatus}`);
692
+ // eslint-disable-next-line no-console
693
+ console.log(`Iterations: ${result.iterations}`);
694
+ // eslint-disable-next-line no-console
695
+ console.log(`SDS: ${result.sdsPath}${parsed.dryRun ? " (dry run, not modified)" : ""}`);
696
+ // eslint-disable-next-line no-console
697
+ console.log(`Suggestions directory: ${result.suggestionsDir}`);
698
+ if (result.suggestionFiles.length > 0) {
699
+ // eslint-disable-next-line no-console
700
+ console.log(`Suggestions files: ${result.suggestionFiles.join(", ")}`);
701
+ }
702
+ printWarnings(result.warnings);
703
+ if (parsed.debug) {
704
+ // eslint-disable-next-line no-console
705
+ console.error("[debug] Completed docs:sds suggestions");
706
+ }
707
+ return;
708
+ }
505
709
  if (args[0] === "generate")
506
710
  args = args.slice(1);
507
711
  const parsed = parseSdsArgs(args);
@@ -13,14 +13,17 @@ interface ParsedArgs {
13
13
  qaEntryUrl?: string;
14
14
  qaStartCommand?: string;
15
15
  qaRequires?: string[];
16
+ sdsPreflightApplyToSds: boolean;
16
17
  sdsPreflightCommit: boolean;
17
18
  sdsPreflightCommitMessage?: string;
19
+ unknownEpicServicePolicy?: "auto-remediate" | "fail";
18
20
  inputs: string[];
19
21
  }
20
22
  type ProjectKeyCandidate = {
21
23
  key: string;
22
24
  mtimeMs: number;
23
25
  };
26
+ export declare const createTasksUsage: string;
24
27
  export declare const pickCreateTasksProjectKey: (options: {
25
28
  requestedKey?: string;
26
29
  configuredKey?: string;
@@ -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,kBAAkB,EAAE,OAAO,CAAC;IAC5B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,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,UA6JrD,CAAC;AAEF,qBAAa,kBAAkB;WAChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAqEhD"}
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,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,wBAAwB,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IACrD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,eAAO,MAAM,gBAAgB,QAIjB,CAAC;AAyDb,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;CAiD3C,CAAC;AAUF,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,KAAG,UAkNrD,CAAC;AAEF,qBAAa,kBAAkB;WAChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAuEhD"}
@@ -2,7 +2,11 @@ import path from "node:path";
2
2
  import { promises as fs } from "node:fs";
3
3
  import { CreateTasksService, WorkspaceResolver } from "@mcoda/core";
4
4
  import { PathHelper } from "@mcoda/shared";
5
- const usage = `mcoda create-tasks [INPUT...] [--workspace-root <path>] [--project-key <key>] [--agent <name>] [--agent-stream [true|false]] [--rate-agents] [--force] [--max-epics N] [--max-stories-per-epic N] [--max-tasks-per-story N] [--qa-profile <csv>] [--qa-entry-url <url>] [--qa-start-command <cmd>] [--qa-requires <csv>] [--sds-preflight-commit [true|false]] [--sds-preflight-commit-message <text>] [--quiet]`;
5
+ export const createTasksUsage = [
6
+ "mcoda create-tasks [INPUT...] [--workspace-root <path>] [--project-key <key>] [--agent <name>] [--agent-stream [true|false]] [--rate-agents] [--force] [--max-epics N] [--max-stories-per-epic N] [--max-tasks-per-story N] [--qa-profile <csv>] [--qa-entry-url <url>] [--qa-start-command <cmd>] [--qa-requires <csv>] [--sds-preflight-apply [true|false]] [--sds-preflight-commit [true|false]] [--sds-preflight-commit-message <text>] [--unknown-epic-service-policy <auto-remediate|fail>] [--quiet]",
7
+ "Default: SDS preflight runs in sidecar mode. Use --sds-preflight-apply to write remediations back to SDS sources.",
8
+ "Use --sds-preflight-commit only together with --sds-preflight-apply.",
9
+ ].join("\n");
6
10
  const readWorkspaceConfig = async (mcodaDir) => {
7
11
  const configPath = path.join(mcodaDir, "config.json");
8
12
  try {
@@ -85,17 +89,13 @@ export const pickCreateTasksProjectKey = (options) => {
85
89
  }
86
90
  return { projectKey: configuredKey, warnings };
87
91
  }
88
- if (latestExisting) {
89
- const selected = latestExisting;
90
- if (!options.requestedKey && selected !== derivedKey) {
91
- warnings.push(`Reusing existing project key "${selected}" from workspace task plans.`);
92
- }
93
- if (existing.length > 1) {
94
- warnings.push(`Multiple task plan folders detected (${existing.map((item) => item.key).join(", ")}); using "${selected}".`);
95
- }
96
- return { projectKey: selected, warnings };
92
+ if (latestExisting && latestExisting !== derivedKey) {
93
+ warnings.push(`Existing task plans were found for "${latestExisting}", but using derived project key "${derivedKey}" to avoid accidental cross-project reuse. Pass --project-key to reuse an existing project.`);
94
+ }
95
+ if (existing.length > 1) {
96
+ warnings.push(`Multiple task plan folders detected (${existing.map((item) => item.key).join(", ")}); using derived project key "${derivedKey}".`);
97
97
  }
98
- return { projectKey: options.requestedKey ?? derivedKey, warnings };
98
+ return { projectKey: derivedKey, warnings };
99
99
  };
100
100
  const parseBooleanFlag = (value, defaultValue) => {
101
101
  if (value === undefined)
@@ -123,8 +123,18 @@ export const parseCreateTasksArgs = (argv) => {
123
123
  let qaEntryUrl;
124
124
  let qaStartCommand;
125
125
  let qaRequires;
126
+ let sdsPreflightApplyToSds = false;
126
127
  let sdsPreflightCommit = false;
127
128
  let sdsPreflightCommitMessage;
129
+ let unknownEpicServicePolicy;
130
+ const normalizePolicy = (value) => {
131
+ if (!value)
132
+ return undefined;
133
+ const normalized = value.trim().toLowerCase();
134
+ if (normalized === "auto-remediate" || normalized === "fail")
135
+ return normalized;
136
+ return undefined;
137
+ };
128
138
  for (let i = 0; i < argv.length; i += 1) {
129
139
  const arg = argv[i];
130
140
  if (arg.startsWith("--")) {
@@ -138,6 +148,20 @@ export const parseCreateTasksArgs = (argv) => {
138
148
  sdsPreflightCommit = parseBooleanFlag(raw, true);
139
149
  continue;
140
150
  }
151
+ if (arg.startsWith("--sds-preflight-apply=")) {
152
+ const [, raw] = arg.split("=", 2);
153
+ sdsPreflightApplyToSds = parseBooleanFlag(raw, true);
154
+ continue;
155
+ }
156
+ if (arg.startsWith("--unknown-epic-service-policy=")) {
157
+ const [, raw] = arg.split("=", 2);
158
+ const normalizedPolicy = normalizePolicy(raw);
159
+ if (!normalizedPolicy) {
160
+ throw new Error(`Invalid --unknown-epic-service-policy value: ${raw}. Expected auto-remediate or fail.`);
161
+ }
162
+ unknownEpicServicePolicy = normalizedPolicy;
163
+ continue;
164
+ }
141
165
  switch (arg) {
142
166
  case "--workspace-root":
143
167
  workspaceRoot = argv[i + 1] ? path.resolve(argv[i + 1]) : undefined;
@@ -227,6 +251,27 @@ export const parseCreateTasksArgs = (argv) => {
227
251
  sdsPreflightCommitMessage = argv[i + 1];
228
252
  i += 1;
229
253
  break;
254
+ case "--sds-preflight-apply": {
255
+ const next = argv[i + 1];
256
+ if (next && !next.startsWith("--")) {
257
+ sdsPreflightApplyToSds = parseBooleanFlag(next, true);
258
+ i += 1;
259
+ }
260
+ else {
261
+ sdsPreflightApplyToSds = true;
262
+ }
263
+ break;
264
+ }
265
+ case "--unknown-epic-service-policy": {
266
+ const value = argv[i + 1];
267
+ const normalizedPolicy = normalizePolicy(value);
268
+ if (!normalizedPolicy) {
269
+ throw new Error(`Invalid --unknown-epic-service-policy value: ${value ?? "(missing)"}. Expected auto-remediate or fail.`);
270
+ }
271
+ unknownEpicServicePolicy = normalizedPolicy;
272
+ i += 1;
273
+ break;
274
+ }
230
275
  case "--quiet":
231
276
  quiet = true;
232
277
  break;
@@ -236,7 +281,7 @@ export const parseCreateTasksArgs = (argv) => {
236
281
  case "--help":
237
282
  case "-h":
238
283
  // eslint-disable-next-line no-console
239
- console.log(usage);
284
+ console.log(createTasksUsage);
240
285
  process.exit(0);
241
286
  break;
242
287
  default:
@@ -247,6 +292,12 @@ export const parseCreateTasksArgs = (argv) => {
247
292
  inputs.push(arg);
248
293
  }
249
294
  }
295
+ if (sdsPreflightCommit && !sdsPreflightApplyToSds) {
296
+ throw new Error("--sds-preflight-commit requires --sds-preflight-apply.");
297
+ }
298
+ if (sdsPreflightCommitMessage && !sdsPreflightCommit) {
299
+ throw new Error("--sds-preflight-commit-message requires --sds-preflight-commit.");
300
+ }
250
301
  return {
251
302
  workspaceRoot,
252
303
  projectKey,
@@ -262,8 +313,10 @@ export const parseCreateTasksArgs = (argv) => {
262
313
  qaEntryUrl,
263
314
  qaStartCommand,
264
315
  qaRequires,
316
+ sdsPreflightApplyToSds,
265
317
  sdsPreflightCommit,
266
318
  sdsPreflightCommitMessage,
319
+ unknownEpicServicePolicy,
267
320
  inputs,
268
321
  };
269
322
  };
@@ -312,8 +365,10 @@ export class CreateTasksCommand {
312
365
  qaEntryUrl: parsed.qaEntryUrl,
313
366
  qaStartCommand: parsed.qaStartCommand,
314
367
  qaRequires: parsed.qaRequires,
368
+ sdsPreflightApplyToSds: parsed.sdsPreflightApplyToSds,
315
369
  sdsPreflightCommit: parsed.sdsPreflightCommit,
316
370
  sdsPreflightCommitMessage: parsed.sdsPreflightCommitMessage,
371
+ unknownEpicServicePolicy: parsed.unknownEpicServicePolicy,
317
372
  });
318
373
  const dbPath = PathHelper.getWorkspaceDbPath(workspace.workspaceRoot);
319
374
  if (!parsed.quiet) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcoda",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "description": "Local-first CLI for planning, documentation, and execution workflows with agent assistance.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -45,12 +45,12 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "yaml": "^2.4.2",
48
- "@mcoda/core": "0.1.33",
49
- "@mcoda/shared": "0.1.33"
48
+ "@mcoda/core": "0.1.35",
49
+ "@mcoda/shared": "0.1.35"
50
50
  },
51
51
  "devDependencies": {
52
- "@mcoda/db": "0.1.33",
53
- "@mcoda/integrations": "0.1.33"
52
+ "@mcoda/db": "0.1.35",
53
+ "@mcoda/integrations": "0.1.35"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "tsc -p tsconfig.json",