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.
- package/dist/bin/McodaEntrypoint.d.ts.map +1 -1
- package/dist/bin/McodaEntrypoint.js +7 -1
- package/dist/commands/agents/AgentsCommands.d.ts.map +1 -1
- package/dist/commands/agents/AgentsCommands.js +17 -1
- package/dist/commands/docs/DocsCommands.d.ts +17 -0
- package/dist/commands/docs/DocsCommands.d.ts.map +1 -1
- package/dist/commands/docs/DocsCommands.js +204 -0
- package/dist/commands/planning/CreateTasksCommand.d.ts +3 -0
- package/dist/commands/planning/CreateTasksCommand.d.ts.map +1 -1
- package/dist/commands/planning/CreateTasksCommand.js +67 -12
- package/package.json +5 -5
|
@@ -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;
|
|
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
|
-
|
|
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":"
|
|
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
|
|
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":"
|
|
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;
|
|
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
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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:
|
|
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(
|
|
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.
|
|
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.
|
|
49
|
-
"@mcoda/shared": "0.1.
|
|
48
|
+
"@mcoda/core": "0.1.35",
|
|
49
|
+
"@mcoda/shared": "0.1.35"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@mcoda/db": "0.1.
|
|
53
|
-
"@mcoda/integrations": "0.1.
|
|
52
|
+
"@mcoda/db": "0.1.35",
|
|
53
|
+
"@mcoda/integrations": "0.1.35"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "tsc -p tsconfig.json",
|