mcoda 0.1.23 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/bin/McodaEntrypoint.d.ts.map +1 -1
- package/dist/bin/McodaEntrypoint.js +6 -1
- package/dist/commands/backlog/OrderTasksCommand.d.ts +12 -0
- package/dist/commands/backlog/OrderTasksCommand.d.ts.map +1 -1
- package/dist/commands/backlog/OrderTasksCommand.js +63 -7
- package/dist/commands/planning/RefineTasksCommand.d.ts +12 -0
- package/dist/commands/planning/RefineTasksCommand.d.ts.map +1 -1
- package/dist/commands/planning/RefineTasksCommand.js +70 -10
- package/dist/commands/planning/TaskSufficiencyAuditCommand.d.ts +28 -0
- package/dist/commands/planning/TaskSufficiencyAuditCommand.d.ts.map +1 -0
- package/dist/commands/planning/TaskSufficiencyAuditCommand.js +209 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ mcoda docs pdr generate --workspace-root . --project WEB --rfp-path docs/rfp/web
|
|
|
27
27
|
## Common commands
|
|
28
28
|
- Docs: `mcoda docs pdr generate`, `mcoda docs sds generate`
|
|
29
29
|
- Specs: `mcoda openapi-from-docs`
|
|
30
|
-
- Planning: `mcoda create-tasks`, `mcoda refine-tasks`, `mcoda order-tasks`
|
|
30
|
+
- Planning: `mcoda create-tasks`, `mcoda task-sufficiency-audit`, `mcoda refine-tasks`, `mcoda order-tasks`
|
|
31
31
|
- Execution: `mcoda add-tests`, `mcoda work-on-tasks`, `mcoda code-review`, `mcoda qa-tasks`
|
|
32
32
|
- Backlog: `mcoda backlog`, `mcoda task`
|
|
33
33
|
- Jobs/telemetry: `mcoda jobs`, `mcoda tokens`, `mcoda telemetry`
|
|
@@ -35,6 +35,8 @@ mcoda docs pdr generate --workspace-root . --project WEB --rfp-path docs/rfp/web
|
|
|
35
35
|
- Updates: `mcoda update --check`
|
|
36
36
|
|
|
37
37
|
`mcoda work-on-tasks` auto-runs the same test-harness bootstrap logic as `mcoda add-tests` when selected tasks require tests but no runnable harness exists.
|
|
38
|
+
`mcoda create-tasks` auto-runs a sufficiency pass (same engine as `mcoda task-sufficiency-audit`) to compare SDS coverage against generated backlog items and fill obvious planning gaps.
|
|
39
|
+
If that sufficiency pass errors, create-tasks continues (fail-open) and records audit failure details in job checkpoints/logs.
|
|
38
40
|
|
|
39
41
|
## Configuration
|
|
40
42
|
Environment variables are optional overrides for workspace settings:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McodaEntrypoint.d.ts","sourceRoot":"","sources":["../../src/bin/McodaEntrypoint.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"McodaEntrypoint.d.ts","sourceRoot":"","sources":["../../src/bin/McodaEntrypoint.ts"],"names":[],"mappings":";AA8BA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;CA8LxE"}
|
|
@@ -9,6 +9,7 @@ import { JobsCommands } from "../commands/jobs/JobsCommands.js";
|
|
|
9
9
|
import { OpenapiCommands } from "../commands/openapi/OpenapiCommands.js";
|
|
10
10
|
import { CreateTasksCommand } from "../commands/planning/CreateTasksCommand.js";
|
|
11
11
|
import { RefineTasksCommand } from "../commands/planning/RefineTasksCommand.js";
|
|
12
|
+
import { TaskSufficiencyAuditCommand } from "../commands/planning/TaskSufficiencyAuditCommand.js";
|
|
12
13
|
import { BacklogCommands } from "../commands/backlog/BacklogCommands.js";
|
|
13
14
|
import { TaskShowCommands } from "../commands/backlog/TaskShowCommands.js";
|
|
14
15
|
import { OrderTasksCommand } from "../commands/backlog/OrderTasksCommand.js";
|
|
@@ -81,7 +82,7 @@ export class McodaEntrypoint {
|
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
84
|
if (!command) {
|
|
84
|
-
throw new Error("Usage: mcoda <agent|gateway-agent|test-agent|agent-run|routing|docs|openapi|job|jobs|tokens|telemetry|create-tasks|migrate-tasks|refine-tasks|order-tasks|tasks|add-tests|work-on-tasks|gateway-trio|code-review|qa-tasks|backlog|task|task-detail|estimate|update|set-workspace|project-guidance|pdr|sds> [...args]\n" +
|
|
85
|
+
throw new Error("Usage: mcoda <agent|gateway-agent|test-agent|agent-run|routing|docs|openapi|job|jobs|tokens|telemetry|create-tasks|migrate-tasks|refine-tasks|task-sufficiency-audit|order-tasks|tasks|add-tests|work-on-tasks|gateway-trio|code-review|qa-tasks|backlog|task|task-detail|estimate|update|set-workspace|project-guidance|pdr|sds> [...args]\n" +
|
|
85
86
|
"Routing: use `mcoda routing defaults` to view/update workspace/global defaults, `mcoda routing preview|explain` to inspect agent selection/provenance (override → workspace_default → global_default).\n" +
|
|
86
87
|
"Aliases: `tasks order-by-deps` forwards to `order-tasks` (dependency-aware ordering), `task`/`task-detail` show a single task.\n" +
|
|
87
88
|
"Job commands (mcoda job --help for details): list|status|watch|logs|inspect|resume|cancel|tokens\n" +
|
|
@@ -147,6 +148,10 @@ export class McodaEntrypoint {
|
|
|
147
148
|
await RefineTasksCommand.run(rest);
|
|
148
149
|
return;
|
|
149
150
|
}
|
|
151
|
+
if (command === "task-sufficiency-audit") {
|
|
152
|
+
await TaskSufficiencyAuditCommand.run(rest);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
150
155
|
if (command === "qa-tasks") {
|
|
151
156
|
if (rest.includes("--help") || rest.includes("-h")) {
|
|
152
157
|
// eslint-disable-next-line no-console
|
|
@@ -13,6 +13,18 @@ interface ParsedArgs {
|
|
|
13
13
|
stageOrder?: string[];
|
|
14
14
|
json: boolean;
|
|
15
15
|
}
|
|
16
|
+
type ProjectKeyCandidate = {
|
|
17
|
+
key: string;
|
|
18
|
+
createdAt?: string | null;
|
|
19
|
+
};
|
|
20
|
+
export declare const pickOrderTasksProjectKey: (options: {
|
|
21
|
+
requestedKey?: string;
|
|
22
|
+
configuredKey?: string;
|
|
23
|
+
existing: ProjectKeyCandidate[];
|
|
24
|
+
}) => {
|
|
25
|
+
projectKey?: string;
|
|
26
|
+
warnings: string[];
|
|
27
|
+
};
|
|
16
28
|
export declare const parseOrderTasksArgs: (argv: string[]) => ParsedArgs;
|
|
17
29
|
export declare class OrderTasksCommand {
|
|
18
30
|
static run(argv: string[]): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/OrderTasksCommand.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OrderTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/OrderTasksCommand.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,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;AAED,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAmCtE,eAAO,MAAM,wBAAwB,GAAI,SAAS;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC,KAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAkC5C,CAAC;AAwCF,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;CA6EhD"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { WorkspaceRepository } from "@mcoda/db";
|
|
2
3
|
import { TaskOrderingService, WorkspaceResolver } from "@mcoda/core";
|
|
3
4
|
const usage = `mcoda order-tasks \\
|
|
4
5
|
[--workspace-root <PATH>] \\
|
|
5
|
-
--project <PROJECT_KEY> \\
|
|
6
|
+
[--project <PROJECT_KEY>] \\
|
|
6
7
|
[--epic <EPIC_KEY>] \\
|
|
7
8
|
[--story <STORY_KEY>] \\
|
|
8
9
|
[--status <STATUS_FILTER>] \\
|
|
@@ -14,6 +15,50 @@ const usage = `mcoda order-tasks \\
|
|
|
14
15
|
[--stage-order <foundation,backend,frontend,other>] \\
|
|
15
16
|
[--rate-agents] \\
|
|
16
17
|
[--json]`;
|
|
18
|
+
const listWorkspaceProjects = async (workspaceRoot) => {
|
|
19
|
+
const repo = await WorkspaceRepository.create(workspaceRoot);
|
|
20
|
+
try {
|
|
21
|
+
const rows = await repo
|
|
22
|
+
.getDb()
|
|
23
|
+
.all(`SELECT key, created_at FROM projects ORDER BY created_at ASC, key ASC`);
|
|
24
|
+
return rows
|
|
25
|
+
.map((row) => ({ key: String(row.key), createdAt: row.created_at ?? null }))
|
|
26
|
+
.filter((row) => row.key.trim().length > 0);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await repo.close();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
export const pickOrderTasksProjectKey = (options) => {
|
|
36
|
+
const warnings = [];
|
|
37
|
+
const requestedKey = options.requestedKey?.trim() || undefined;
|
|
38
|
+
const configuredKey = options.configuredKey?.trim() || undefined;
|
|
39
|
+
const existing = options.existing ?? [];
|
|
40
|
+
const firstExisting = existing[0]?.key;
|
|
41
|
+
if (requestedKey) {
|
|
42
|
+
if (configuredKey && configuredKey !== requestedKey) {
|
|
43
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; overriding configured project key "${configuredKey}".`);
|
|
44
|
+
}
|
|
45
|
+
if (firstExisting && requestedKey !== firstExisting) {
|
|
46
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; first workspace project is "${firstExisting}".`);
|
|
47
|
+
}
|
|
48
|
+
return { projectKey: requestedKey, warnings };
|
|
49
|
+
}
|
|
50
|
+
if (configuredKey) {
|
|
51
|
+
if (firstExisting && configuredKey !== firstExisting) {
|
|
52
|
+
warnings.push(`Using configured project key "${configuredKey}" instead of first workspace project "${firstExisting}".`);
|
|
53
|
+
}
|
|
54
|
+
return { projectKey: configuredKey, warnings };
|
|
55
|
+
}
|
|
56
|
+
if (firstExisting) {
|
|
57
|
+
warnings.push(`No --project provided; defaulting to first workspace project "${firstExisting}".`);
|
|
58
|
+
return { projectKey: firstExisting, warnings };
|
|
59
|
+
}
|
|
60
|
+
return { projectKey: undefined, warnings };
|
|
61
|
+
};
|
|
17
62
|
const parseBooleanFlag = (value, defaultValue) => {
|
|
18
63
|
if (value === undefined)
|
|
19
64
|
return defaultValue;
|
|
@@ -243,9 +288,19 @@ export class OrderTasksCommand {
|
|
|
243
288
|
cwd: process.cwd(),
|
|
244
289
|
explicitWorkspace: parsed.workspaceRoot,
|
|
245
290
|
});
|
|
246
|
-
|
|
291
|
+
const existingProjects = parsed.project ? [] : await listWorkspaceProjects(workspace.workspaceRoot);
|
|
292
|
+
const configuredKey = typeof workspace.config?.projectKey === "string" && workspace.config.projectKey.trim().length > 0
|
|
293
|
+
? workspace.config.projectKey
|
|
294
|
+
: undefined;
|
|
295
|
+
const projectResolution = pickOrderTasksProjectKey({
|
|
296
|
+
requestedKey: parsed.project,
|
|
297
|
+
configuredKey,
|
|
298
|
+
existing: existingProjects,
|
|
299
|
+
});
|
|
300
|
+
const commandWarnings = [...projectResolution.warnings];
|
|
301
|
+
if (!projectResolution.projectKey) {
|
|
247
302
|
// eslint-disable-next-line no-console
|
|
248
|
-
console.error("order-tasks
|
|
303
|
+
console.error("order-tasks could not resolve a project key. Provide --project <PROJECT_KEY> or create tasks for this workspace first.");
|
|
249
304
|
process.exitCode = 1;
|
|
250
305
|
return;
|
|
251
306
|
}
|
|
@@ -263,7 +318,7 @@ export class OrderTasksCommand {
|
|
|
263
318
|
const service = await TaskOrderingService.create(workspace);
|
|
264
319
|
try {
|
|
265
320
|
const result = await service.orderTasks({
|
|
266
|
-
projectKey:
|
|
321
|
+
projectKey: projectResolution.projectKey,
|
|
267
322
|
epicKey: parsed.epic,
|
|
268
323
|
storyKey: parsed.story,
|
|
269
324
|
statusFilter: parsed.status,
|
|
@@ -275,18 +330,19 @@ export class OrderTasksCommand {
|
|
|
275
330
|
planningContextPolicy: parsed.planningContextPolicy,
|
|
276
331
|
stageOrder: resolvedStageOrder,
|
|
277
332
|
});
|
|
333
|
+
const warnings = [...commandWarnings, ...result.warnings];
|
|
278
334
|
if (parsed.json) {
|
|
279
335
|
const payload = {
|
|
280
336
|
order: result.ordered,
|
|
281
337
|
};
|
|
282
|
-
if (
|
|
283
|
-
payload.warnings =
|
|
338
|
+
if (warnings.length > 0) {
|
|
339
|
+
payload.warnings = warnings;
|
|
284
340
|
}
|
|
285
341
|
// eslint-disable-next-line no-console
|
|
286
342
|
console.log(JSON.stringify(payload, null, 2));
|
|
287
343
|
return;
|
|
288
344
|
}
|
|
289
|
-
renderOrder(result.ordered,
|
|
345
|
+
renderOrder(result.ordered, warnings);
|
|
290
346
|
}
|
|
291
347
|
catch (error) {
|
|
292
348
|
// eslint-disable-next-line no-console
|
|
@@ -23,6 +23,18 @@ interface ParsedRefineArgs {
|
|
|
23
23
|
planOut?: string;
|
|
24
24
|
jobId?: string;
|
|
25
25
|
}
|
|
26
|
+
type ProjectKeyCandidate = {
|
|
27
|
+
key: string;
|
|
28
|
+
createdAt?: string | null;
|
|
29
|
+
};
|
|
30
|
+
export declare const pickRefineTasksProjectKey: (options: {
|
|
31
|
+
requestedKey?: string;
|
|
32
|
+
configuredKey?: string;
|
|
33
|
+
existing: ProjectKeyCandidate[];
|
|
34
|
+
}) => {
|
|
35
|
+
projectKey?: string;
|
|
36
|
+
warnings: string[];
|
|
37
|
+
};
|
|
26
38
|
export declare const parseRefineTasksArgs: (argv: string[]) => ParsedRefineArgs;
|
|
27
39
|
export declare class RefineTasksCommand {
|
|
28
40
|
static run(argv: string[]): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RefineTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/planning/RefineTasksCommand.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RefineTasksCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/planning/RefineTasksCommand.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,UAAU,gBAAgB;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAsBtE,eAAO,MAAM,yBAAyB,GAAI,SAAS;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC,KAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAkC5C,CAAC;AA4BF,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,KAAG,gBAyNrD,CAAC;AAEF,qBAAa,kBAAkB;WAChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAkLhD"}
|
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { WorkspaceRepository } from "@mcoda/db";
|
|
2
3
|
import { RefineTasksService, WorkspaceResolver } from "@mcoda/core";
|
|
3
|
-
const usage = `mcoda refine-tasks --project <PROJECT_KEY> [--workspace-root <PATH>] [--epic <EPIC_KEY>] [--story <STORY_KEY>] [--task <TASK_KEY> ...] [--status <STATUS>] [--max-tasks N] [--strategy split|merge|enrich|estimate|auto] [--agent <NAME>] [--agent-stream [true|false]] [--rate-agents] [--from-db [true|false]] [--dry-run] [--apply] [--resume|--skip-refined] [--run-all] [--batch-size N] [--max-batches N] [--plan-in <PATH>] [--plan-out <PATH>] [--json]`;
|
|
4
|
+
const usage = `mcoda refine-tasks [--project <PROJECT_KEY>] [--workspace-root <PATH>] [--epic <EPIC_KEY>] [--story <STORY_KEY>] [--task <TASK_KEY> ...] [--status <STATUS>] [--max-tasks N] [--strategy split|merge|enrich|estimate|auto] [--agent <NAME>] [--agent-stream [true|false]] [--rate-agents] [--from-db [true|false]] [--dry-run] [--apply] [--resume|--skip-refined] [--run-all] [--batch-size N] [--max-batches N] [--plan-in <PATH>] [--plan-out <PATH>] [--json]`;
|
|
5
|
+
const listWorkspaceProjects = async (workspaceRoot) => {
|
|
6
|
+
const repo = await WorkspaceRepository.create(workspaceRoot);
|
|
7
|
+
try {
|
|
8
|
+
const rows = await repo
|
|
9
|
+
.getDb()
|
|
10
|
+
.all(`SELECT key, created_at FROM projects ORDER BY created_at ASC, key ASC`);
|
|
11
|
+
return rows
|
|
12
|
+
.map((row) => ({ key: String(row.key), createdAt: row.created_at ?? null }))
|
|
13
|
+
.filter((row) => row.key.trim().length > 0);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
await repo.close();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export const pickRefineTasksProjectKey = (options) => {
|
|
23
|
+
const warnings = [];
|
|
24
|
+
const requestedKey = options.requestedKey?.trim() || undefined;
|
|
25
|
+
const configuredKey = options.configuredKey?.trim() || undefined;
|
|
26
|
+
const existing = options.existing ?? [];
|
|
27
|
+
const firstExisting = existing[0]?.key;
|
|
28
|
+
if (requestedKey) {
|
|
29
|
+
if (configuredKey && configuredKey !== requestedKey) {
|
|
30
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; overriding configured project key "${configuredKey}".`);
|
|
31
|
+
}
|
|
32
|
+
if (firstExisting && requestedKey !== firstExisting) {
|
|
33
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; first workspace project is "${firstExisting}".`);
|
|
34
|
+
}
|
|
35
|
+
return { projectKey: requestedKey, warnings };
|
|
36
|
+
}
|
|
37
|
+
if (configuredKey) {
|
|
38
|
+
if (firstExisting && configuredKey !== firstExisting) {
|
|
39
|
+
warnings.push(`Using configured project key "${configuredKey}" instead of first workspace project "${firstExisting}".`);
|
|
40
|
+
}
|
|
41
|
+
return { projectKey: configuredKey, warnings };
|
|
42
|
+
}
|
|
43
|
+
if (firstExisting) {
|
|
44
|
+
warnings.push(`No --project provided; defaulting to first workspace project "${firstExisting}".`);
|
|
45
|
+
return { projectKey: firstExisting, warnings };
|
|
46
|
+
}
|
|
47
|
+
return { projectKey: undefined, warnings };
|
|
48
|
+
};
|
|
4
49
|
const parseBooleanFlag = (value, defaultValue) => {
|
|
5
50
|
if (value === undefined)
|
|
6
51
|
return defaultValue;
|
|
@@ -251,12 +296,6 @@ export const parseRefineTasksArgs = (argv) => {
|
|
|
251
296
|
export class RefineTasksCommand {
|
|
252
297
|
static async run(argv) {
|
|
253
298
|
const parsed = parseRefineTasksArgs(argv);
|
|
254
|
-
if (!parsed.projectKey) {
|
|
255
|
-
// eslint-disable-next-line no-console
|
|
256
|
-
console.error("refine-tasks requires --project <PROJECT_KEY>");
|
|
257
|
-
process.exitCode = 1;
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
299
|
if (parsed.apply && parsed.dryRun) {
|
|
261
300
|
// eslint-disable-next-line no-console
|
|
262
301
|
console.error("refine-tasks: --apply cannot be used with --dry-run");
|
|
@@ -273,11 +312,31 @@ export class RefineTasksCommand {
|
|
|
273
312
|
cwd: process.cwd(),
|
|
274
313
|
explicitWorkspace: parsed.workspaceRoot,
|
|
275
314
|
});
|
|
315
|
+
const existingProjects = parsed.projectKey ? [] : await listWorkspaceProjects(workspace.workspaceRoot);
|
|
316
|
+
const configuredKey = typeof workspace.config?.projectKey === "string" && workspace.config.projectKey.trim().length > 0
|
|
317
|
+
? workspace.config.projectKey
|
|
318
|
+
: undefined;
|
|
319
|
+
const projectResolution = pickRefineTasksProjectKey({
|
|
320
|
+
requestedKey: parsed.projectKey,
|
|
321
|
+
configuredKey,
|
|
322
|
+
existing: existingProjects,
|
|
323
|
+
});
|
|
324
|
+
const commandWarnings = [...projectResolution.warnings];
|
|
325
|
+
if (!projectResolution.projectKey) {
|
|
326
|
+
// eslint-disable-next-line no-console
|
|
327
|
+
console.error("refine-tasks could not resolve a project key. Provide --project <PROJECT_KEY> or create tasks for this workspace first.");
|
|
328
|
+
process.exitCode = 1;
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (commandWarnings.length > 0 && !parsed.json) {
|
|
332
|
+
// eslint-disable-next-line no-console
|
|
333
|
+
console.warn(commandWarnings.map((warning) => `! ${warning}`).join("\n"));
|
|
334
|
+
}
|
|
276
335
|
const service = await RefineTasksService.create(workspace);
|
|
277
336
|
try {
|
|
278
337
|
const baseRequest = {
|
|
279
338
|
workspace,
|
|
280
|
-
projectKey:
|
|
339
|
+
projectKey: projectResolution.projectKey,
|
|
281
340
|
epicKey: parsed.epicKey,
|
|
282
341
|
storyKey: parsed.storyKey,
|
|
283
342
|
taskKeys: parsed.taskKeys.length ? parsed.taskKeys : undefined,
|
|
@@ -329,7 +388,7 @@ export class RefineTasksCommand {
|
|
|
329
388
|
}
|
|
330
389
|
if (parsed.json) {
|
|
331
390
|
// eslint-disable-next-line no-console
|
|
332
|
-
console.log(JSON.stringify({ status: "completed", totalProcessed, totalAffected, batches }, null, 2));
|
|
391
|
+
console.log(JSON.stringify({ status: "completed", totalProcessed, totalAffected, batches, warnings: commandWarnings }, null, 2));
|
|
333
392
|
}
|
|
334
393
|
else {
|
|
335
394
|
// eslint-disable-next-line no-console
|
|
@@ -342,12 +401,13 @@ export class RefineTasksCommand {
|
|
|
342
401
|
maxTasks: parsed.maxTasks,
|
|
343
402
|
});
|
|
344
403
|
if (parsed.json) {
|
|
404
|
+
const warnings = [...commandWarnings, ...(result.plan.warnings ?? [])];
|
|
345
405
|
// eslint-disable-next-line no-console
|
|
346
406
|
console.log(JSON.stringify({
|
|
347
407
|
status: result.applied ? "applied" : "dry_run",
|
|
348
408
|
summary: result.summary,
|
|
349
409
|
plan: result.plan,
|
|
350
|
-
warnings
|
|
410
|
+
warnings,
|
|
351
411
|
}, null, 2));
|
|
352
412
|
}
|
|
353
413
|
else {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface ParsedTaskSufficiencyArgs {
|
|
2
|
+
workspaceRoot?: string;
|
|
3
|
+
projectKey?: string;
|
|
4
|
+
maxIterations?: number;
|
|
5
|
+
maxTasksPerIteration?: number;
|
|
6
|
+
minCoverageRatio?: number;
|
|
7
|
+
dryRun: boolean;
|
|
8
|
+
json: boolean;
|
|
9
|
+
quiet: boolean;
|
|
10
|
+
}
|
|
11
|
+
type ProjectKeyCandidate = {
|
|
12
|
+
key: string;
|
|
13
|
+
createdAt?: string | null;
|
|
14
|
+
};
|
|
15
|
+
export declare const pickTaskSufficiencyProjectKey: (options: {
|
|
16
|
+
requestedKey?: string;
|
|
17
|
+
configuredKey?: string;
|
|
18
|
+
existing: ProjectKeyCandidate[];
|
|
19
|
+
}) => {
|
|
20
|
+
projectKey?: string;
|
|
21
|
+
warnings: string[];
|
|
22
|
+
};
|
|
23
|
+
export declare const parseTaskSufficiencyAuditArgs: (argv: string[]) => ParsedTaskSufficiencyArgs;
|
|
24
|
+
export declare class TaskSufficiencyAuditCommand {
|
|
25
|
+
static run(argv: string[]): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=TaskSufficiencyAuditCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskSufficiencyAuditCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/planning/TaskSufficiencyAuditCommand.ts"],"names":[],"mappings":"AAIA,UAAU,yBAAyB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,KAAK,mBAAmB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAsBtE,eAAO,MAAM,6BAA6B,GAAI,SAAS;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC,KAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAkC5C,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,MAAM,MAAM,EAAE,KAAG,yBAmE9D,CAAC;AAEF,qBAAa,2BAA2B;WACzB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA0GhD"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { WorkspaceRepository } from "@mcoda/db";
|
|
3
|
+
import { TaskSufficiencyService, WorkspaceResolver } from "@mcoda/core";
|
|
4
|
+
const usage = `mcoda task-sufficiency-audit [--workspace-root <path>] [--project <PROJECT_KEY>] [--max-iterations N] [--max-tasks-per-iteration N] [--min-coverage-ratio 0..1] [--dry-run] [--json] [--quiet]`;
|
|
5
|
+
const listWorkspaceProjects = async (workspaceRoot) => {
|
|
6
|
+
const repo = await WorkspaceRepository.create(workspaceRoot);
|
|
7
|
+
try {
|
|
8
|
+
const rows = await repo
|
|
9
|
+
.getDb()
|
|
10
|
+
.all(`SELECT key, created_at FROM projects ORDER BY created_at ASC, key ASC`);
|
|
11
|
+
return rows
|
|
12
|
+
.map((row) => ({ key: String(row.key), createdAt: row.created_at ?? null }))
|
|
13
|
+
.filter((row) => row.key.trim().length > 0);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
await repo.close();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export const pickTaskSufficiencyProjectKey = (options) => {
|
|
23
|
+
const warnings = [];
|
|
24
|
+
const requestedKey = options.requestedKey?.trim() || undefined;
|
|
25
|
+
const configuredKey = options.configuredKey?.trim() || undefined;
|
|
26
|
+
const existing = options.existing ?? [];
|
|
27
|
+
const firstExisting = existing[0]?.key;
|
|
28
|
+
if (requestedKey) {
|
|
29
|
+
if (configuredKey && configuredKey !== requestedKey) {
|
|
30
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; overriding configured project key "${configuredKey}".`);
|
|
31
|
+
}
|
|
32
|
+
if (firstExisting && requestedKey !== firstExisting) {
|
|
33
|
+
warnings.push(`Using explicitly requested project key "${requestedKey}"; first workspace project is "${firstExisting}".`);
|
|
34
|
+
}
|
|
35
|
+
return { projectKey: requestedKey, warnings };
|
|
36
|
+
}
|
|
37
|
+
if (configuredKey) {
|
|
38
|
+
if (firstExisting && configuredKey !== firstExisting) {
|
|
39
|
+
warnings.push(`Using configured project key "${configuredKey}" instead of first workspace project "${firstExisting}".`);
|
|
40
|
+
}
|
|
41
|
+
return { projectKey: configuredKey, warnings };
|
|
42
|
+
}
|
|
43
|
+
if (firstExisting) {
|
|
44
|
+
warnings.push(`No --project provided; defaulting to first workspace project "${firstExisting}".`);
|
|
45
|
+
return { projectKey: firstExisting, warnings };
|
|
46
|
+
}
|
|
47
|
+
return { projectKey: undefined, warnings };
|
|
48
|
+
};
|
|
49
|
+
export const parseTaskSufficiencyAuditArgs = (argv) => {
|
|
50
|
+
let workspaceRoot;
|
|
51
|
+
let projectKey;
|
|
52
|
+
let maxIterations;
|
|
53
|
+
let maxTasksPerIteration;
|
|
54
|
+
let minCoverageRatio;
|
|
55
|
+
let dryRun = false;
|
|
56
|
+
let json = false;
|
|
57
|
+
let quiet = false;
|
|
58
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
59
|
+
const arg = argv[i];
|
|
60
|
+
switch (arg) {
|
|
61
|
+
case "--workspace-root":
|
|
62
|
+
case "--workspace":
|
|
63
|
+
workspaceRoot = argv[i + 1] ? path.resolve(argv[i + 1]) : undefined;
|
|
64
|
+
i += 1;
|
|
65
|
+
break;
|
|
66
|
+
case "--project":
|
|
67
|
+
case "--project-key":
|
|
68
|
+
projectKey = argv[i + 1];
|
|
69
|
+
i += 1;
|
|
70
|
+
break;
|
|
71
|
+
case "--max-iterations":
|
|
72
|
+
maxIterations = Number(argv[i + 1]);
|
|
73
|
+
i += 1;
|
|
74
|
+
break;
|
|
75
|
+
case "--max-tasks-per-iteration":
|
|
76
|
+
case "--max-new-tasks":
|
|
77
|
+
maxTasksPerIteration = Number(argv[i + 1]);
|
|
78
|
+
i += 1;
|
|
79
|
+
break;
|
|
80
|
+
case "--min-coverage-ratio":
|
|
81
|
+
case "--min-coverage":
|
|
82
|
+
minCoverageRatio = Number(argv[i + 1]);
|
|
83
|
+
i += 1;
|
|
84
|
+
break;
|
|
85
|
+
case "--dry-run":
|
|
86
|
+
dryRun = true;
|
|
87
|
+
break;
|
|
88
|
+
case "--json":
|
|
89
|
+
json = true;
|
|
90
|
+
break;
|
|
91
|
+
case "--quiet":
|
|
92
|
+
quiet = true;
|
|
93
|
+
break;
|
|
94
|
+
case "--help":
|
|
95
|
+
case "-h":
|
|
96
|
+
// eslint-disable-next-line no-console
|
|
97
|
+
console.log(usage);
|
|
98
|
+
process.exit(0);
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
workspaceRoot,
|
|
106
|
+
projectKey,
|
|
107
|
+
maxIterations: Number.isFinite(maxIterations) ? maxIterations : undefined,
|
|
108
|
+
maxTasksPerIteration: Number.isFinite(maxTasksPerIteration) ? maxTasksPerIteration : undefined,
|
|
109
|
+
minCoverageRatio: Number.isFinite(minCoverageRatio) ? minCoverageRatio : undefined,
|
|
110
|
+
dryRun,
|
|
111
|
+
json,
|
|
112
|
+
quiet,
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
export class TaskSufficiencyAuditCommand {
|
|
116
|
+
static async run(argv) {
|
|
117
|
+
const parsed = parseTaskSufficiencyAuditArgs(argv);
|
|
118
|
+
const workspace = await WorkspaceResolver.resolveWorkspace({
|
|
119
|
+
cwd: process.cwd(),
|
|
120
|
+
explicitWorkspace: parsed.workspaceRoot,
|
|
121
|
+
});
|
|
122
|
+
const existingProjects = parsed.projectKey ? [] : await listWorkspaceProjects(workspace.workspaceRoot);
|
|
123
|
+
const configuredKey = typeof workspace.config?.projectKey === "string" && workspace.config.projectKey.trim().length > 0
|
|
124
|
+
? workspace.config.projectKey
|
|
125
|
+
: undefined;
|
|
126
|
+
const projectResolution = pickTaskSufficiencyProjectKey({
|
|
127
|
+
requestedKey: parsed.projectKey,
|
|
128
|
+
configuredKey,
|
|
129
|
+
existing: existingProjects,
|
|
130
|
+
});
|
|
131
|
+
if (!projectResolution.projectKey) {
|
|
132
|
+
// eslint-disable-next-line no-console
|
|
133
|
+
console.error("task-sufficiency-audit could not resolve a project key. Provide --project <PROJECT_KEY> or run create-tasks first.");
|
|
134
|
+
process.exitCode = 1;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (projectResolution.warnings.length > 0 && !parsed.json && !parsed.quiet) {
|
|
138
|
+
// eslint-disable-next-line no-console
|
|
139
|
+
console.warn(projectResolution.warnings.map((warning) => `! ${warning}`).join("\n"));
|
|
140
|
+
}
|
|
141
|
+
const service = await TaskSufficiencyService.create(workspace);
|
|
142
|
+
try {
|
|
143
|
+
const result = await service.runAudit({
|
|
144
|
+
workspace,
|
|
145
|
+
projectKey: projectResolution.projectKey,
|
|
146
|
+
dryRun: parsed.dryRun,
|
|
147
|
+
maxIterations: parsed.maxIterations,
|
|
148
|
+
maxTasksPerIteration: parsed.maxTasksPerIteration,
|
|
149
|
+
minCoverageRatio: parsed.minCoverageRatio,
|
|
150
|
+
});
|
|
151
|
+
const warnings = [...projectResolution.warnings, ...result.warnings];
|
|
152
|
+
if (parsed.json) {
|
|
153
|
+
// eslint-disable-next-line no-console
|
|
154
|
+
console.log(JSON.stringify({
|
|
155
|
+
projectKey: result.projectKey,
|
|
156
|
+
jobId: result.jobId,
|
|
157
|
+
commandRunId: result.commandRunId,
|
|
158
|
+
sourceCommand: result.sourceCommand ?? null,
|
|
159
|
+
satisfied: result.satisfied,
|
|
160
|
+
dryRun: result.dryRun,
|
|
161
|
+
maxIterations: result.maxIterations,
|
|
162
|
+
minCoverageRatio: result.minCoverageRatio,
|
|
163
|
+
totalTasksAdded: result.totalTasksAdded,
|
|
164
|
+
totalTasksUpdated: result.totalTasksUpdated,
|
|
165
|
+
finalCoverageRatio: result.finalCoverageRatio,
|
|
166
|
+
remainingSectionHeadings: result.remainingSectionHeadings,
|
|
167
|
+
remainingFolderEntries: result.remainingFolderEntries,
|
|
168
|
+
remainingGaps: result.remainingGaps,
|
|
169
|
+
iterations: result.iterations,
|
|
170
|
+
reportPath: result.reportPath,
|
|
171
|
+
reportHistoryPath: result.reportHistoryPath ?? null,
|
|
172
|
+
warnings,
|
|
173
|
+
}, null, 2));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (!parsed.quiet) {
|
|
177
|
+
const lines = [
|
|
178
|
+
`task-sufficiency-audit project=${result.projectKey}`,
|
|
179
|
+
`Job: ${result.jobId}, Command Run: ${result.commandRunId}`,
|
|
180
|
+
`Satisfied: ${result.satisfied ? "yes" : "no"}`,
|
|
181
|
+
`Dry run: ${result.dryRun ? "yes" : "no"}`,
|
|
182
|
+
`Coverage: ${result.finalCoverageRatio} (target ${result.minCoverageRatio})`,
|
|
183
|
+
`Tasks added: ${result.totalTasksAdded}`,
|
|
184
|
+
`Tasks updated: ${result.totalTasksUpdated}`,
|
|
185
|
+
`Remaining section gaps: ${result.remainingSectionHeadings.length}`,
|
|
186
|
+
`Remaining folder gaps: ${result.remainingFolderEntries.length}`,
|
|
187
|
+
`Remaining total gaps: ${result.remainingGaps.total}`,
|
|
188
|
+
`Report: ${result.reportPath}`,
|
|
189
|
+
result.reportHistoryPath ? `History snapshot: ${result.reportHistoryPath}` : undefined,
|
|
190
|
+
].filter(Boolean);
|
|
191
|
+
// eslint-disable-next-line no-console
|
|
192
|
+
console.log(lines.join("\n"));
|
|
193
|
+
}
|
|
194
|
+
if (warnings.length > 0) {
|
|
195
|
+
// eslint-disable-next-line no-console
|
|
196
|
+
console.warn(warnings.map((warning) => `! ${warning}`).join("\n"));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
201
|
+
// eslint-disable-next-line no-console
|
|
202
|
+
console.error(`task-sufficiency-audit failed: ${message}`);
|
|
203
|
+
process.exitCode = 1;
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
await service.close();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./commands/backlog/OrderTasksCommand.js";
|
|
|
10
10
|
export * from "./commands/estimate/EstimateCommands.js";
|
|
11
11
|
export * from "./commands/telemetry/TelemetryCommands.js";
|
|
12
12
|
export * from "./commands/planning/RefineTasksCommand.js";
|
|
13
|
+
export * from "./commands/planning/TaskSufficiencyAuditCommand.js";
|
|
13
14
|
export * from "./commands/work/WorkOnTasksCommand.js";
|
|
14
15
|
export * from "./commands/work/GatewayTrioCommand.js";
|
|
15
16
|
export * from "./commands/review/CodeReviewCommand.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,gDAAgD,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,gDAAgD,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./commands/backlog/OrderTasksCommand.js";
|
|
|
10
10
|
export * from "./commands/estimate/EstimateCommands.js";
|
|
11
11
|
export * from "./commands/telemetry/TelemetryCommands.js";
|
|
12
12
|
export * from "./commands/planning/RefineTasksCommand.js";
|
|
13
|
+
export * from "./commands/planning/TaskSufficiencyAuditCommand.js";
|
|
13
14
|
export * from "./commands/work/WorkOnTasksCommand.js";
|
|
14
15
|
export * from "./commands/work/GatewayTrioCommand.js";
|
|
15
16
|
export * from "./commands/review/CodeReviewCommand.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcoda",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.26",
|
|
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.26",
|
|
49
|
+
"@mcoda/shared": "0.1.26"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@mcoda/db": "0.1.
|
|
53
|
-
"@mcoda/integrations": "0.1.
|
|
52
|
+
"@mcoda/db": "0.1.26",
|
|
53
|
+
"@mcoda/integrations": "0.1.26"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "tsc -p tsconfig.json",
|