@mcoda/core 0.1.9 → 0.1.12
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 +2 -2
- package/dist/api/AgentsApi.d.ts +1 -0
- package/dist/api/AgentsApi.d.ts.map +1 -1
- package/dist/api/AgentsApi.js +136 -11
- package/dist/api/QaTasksApi.d.ts.map +1 -1
- package/dist/api/QaTasksApi.js +4 -0
- package/dist/prompts/PdrPrompts.d.ts.map +1 -1
- package/dist/prompts/PdrPrompts.js +6 -0
- package/dist/prompts/SdsPrompts.d.ts.map +1 -1
- package/dist/prompts/SdsPrompts.js +7 -0
- package/dist/services/agents/AgentRatingService.d.ts +19 -0
- package/dist/services/agents/AgentRatingService.d.ts.map +1 -1
- package/dist/services/agents/AgentRatingService.js +66 -2
- package/dist/services/agents/GatewayAgentService.d.ts +8 -0
- package/dist/services/agents/GatewayAgentService.d.ts.map +1 -1
- package/dist/services/agents/GatewayAgentService.js +462 -65
- package/dist/services/agents/GatewayHandoff.d.ts +5 -1
- package/dist/services/agents/GatewayHandoff.d.ts.map +1 -1
- package/dist/services/agents/GatewayHandoff.js +65 -32
- package/dist/services/agents/RoutingService.d.ts +1 -0
- package/dist/services/agents/RoutingService.d.ts.map +1 -1
- package/dist/services/agents/RoutingService.js +4 -4
- package/dist/services/backlog/BacklogService.d.ts +23 -0
- package/dist/services/backlog/BacklogService.d.ts.map +1 -1
- package/dist/services/backlog/BacklogService.js +62 -7
- package/dist/services/backlog/TaskOrderingHeuristics.d.ts +12 -0
- package/dist/services/backlog/TaskOrderingHeuristics.d.ts.map +1 -0
- package/dist/services/backlog/TaskOrderingHeuristics.js +56 -0
- package/dist/services/backlog/TaskOrderingService.d.ts +16 -4
- package/dist/services/backlog/TaskOrderingService.d.ts.map +1 -1
- package/dist/services/backlog/TaskOrderingService.js +529 -73
- package/dist/services/docs/DocInventory.d.ts +11 -0
- package/dist/services/docs/DocInventory.d.ts.map +1 -0
- package/dist/services/docs/DocInventory.js +230 -0
- package/dist/services/docs/DocgenRunContext.d.ts +59 -0
- package/dist/services/docs/DocgenRunContext.d.ts.map +1 -0
- package/dist/services/docs/DocgenRunContext.js +4 -0
- package/dist/services/docs/DocsService.d.ts +59 -2
- package/dist/services/docs/DocsService.d.ts.map +1 -1
- package/dist/services/docs/DocsService.js +1701 -48
- package/dist/services/docs/alignment/DocAlignmentGraph.d.ts +23 -0
- package/dist/services/docs/alignment/DocAlignmentGraph.d.ts.map +1 -0
- package/dist/services/docs/alignment/DocAlignmentGraph.js +78 -0
- package/dist/services/docs/alignment/DocAlignmentPatcher.d.ts +19 -0
- package/dist/services/docs/alignment/DocAlignmentPatcher.d.ts.map +1 -0
- package/dist/services/docs/alignment/DocAlignmentPatcher.js +222 -0
- package/dist/services/docs/patch/DocPatchEngine.d.ts +57 -0
- package/dist/services/docs/patch/DocPatchEngine.d.ts.map +1 -0
- package/dist/services/docs/patch/DocPatchEngine.js +331 -0
- package/dist/services/docs/review/Glossary.d.ts +16 -0
- package/dist/services/docs/review/Glossary.d.ts.map +1 -0
- package/dist/services/docs/review/Glossary.js +47 -0
- package/dist/services/docs/review/ReviewReportRenderer.d.ts +3 -0
- package/dist/services/docs/review/ReviewReportRenderer.d.ts.map +1 -0
- package/dist/services/docs/review/ReviewReportRenderer.js +133 -0
- package/dist/services/docs/review/ReviewReportSchema.d.ts +39 -0
- package/dist/services/docs/review/ReviewReportSchema.d.ts.map +1 -0
- package/dist/services/docs/review/ReviewReportSchema.js +47 -0
- package/dist/services/docs/review/ReviewTypes.d.ts +76 -0
- package/dist/services/docs/review/ReviewTypes.d.ts.map +1 -0
- package/dist/services/docs/review/ReviewTypes.js +94 -0
- package/dist/services/docs/review/gates/AdminOpenApiSpecGate.d.ts +7 -0
- package/dist/services/docs/review/gates/AdminOpenApiSpecGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/AdminOpenApiSpecGate.js +93 -0
- package/dist/services/docs/review/gates/ApiPathConsistencyGate.d.ts +7 -0
- package/dist/services/docs/review/gates/ApiPathConsistencyGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/ApiPathConsistencyGate.js +308 -0
- package/dist/services/docs/review/gates/BuildReadyCompletenessGate.d.ts +8 -0
- package/dist/services/docs/review/gates/BuildReadyCompletenessGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/BuildReadyCompletenessGate.js +278 -0
- package/dist/services/docs/review/gates/DeploymentBlueprintGate.d.ts +8 -0
- package/dist/services/docs/review/gates/DeploymentBlueprintGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/DeploymentBlueprintGate.js +487 -0
- package/dist/services/docs/review/gates/NoMaybesGate.d.ts +8 -0
- package/dist/services/docs/review/gates/NoMaybesGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/NoMaybesGate.js +145 -0
- package/dist/services/docs/review/gates/OpenApiCoverageGate.d.ts +7 -0
- package/dist/services/docs/review/gates/OpenApiCoverageGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/OpenApiCoverageGate.js +266 -0
- package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.d.ts +7 -0
- package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.js +59 -0
- package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts +7 -0
- package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/OpenQuestionsGate.js +200 -0
- package/dist/services/docs/review/gates/PdrInterfacesGate.d.ts +7 -0
- package/dist/services/docs/review/gates/PdrInterfacesGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/PdrInterfacesGate.js +159 -0
- package/dist/services/docs/review/gates/PdrOpenQuestionsGate.d.ts +8 -0
- package/dist/services/docs/review/gates/PdrOpenQuestionsGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/PdrOpenQuestionsGate.js +129 -0
- package/dist/services/docs/review/gates/PdrOwnershipGate.d.ts +7 -0
- package/dist/services/docs/review/gates/PdrOwnershipGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/PdrOwnershipGate.js +169 -0
- package/dist/services/docs/review/gates/PlaceholderArtifactGate.d.ts +10 -0
- package/dist/services/docs/review/gates/PlaceholderArtifactGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/PlaceholderArtifactGate.js +261 -0
- package/dist/services/docs/review/gates/RfpConsentGate.d.ts +6 -0
- package/dist/services/docs/review/gates/RfpConsentGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/RfpConsentGate.js +127 -0
- package/dist/services/docs/review/gates/RfpDefinitionGate.d.ts +7 -0
- package/dist/services/docs/review/gates/RfpDefinitionGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/RfpDefinitionGate.js +173 -0
- package/dist/services/docs/review/gates/SdsAdaptersGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SdsAdaptersGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SdsAdaptersGate.js +196 -0
- package/dist/services/docs/review/gates/SdsDecisionsGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SdsDecisionsGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SdsDecisionsGate.js +89 -0
- package/dist/services/docs/review/gates/SdsOpsGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SdsOpsGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SdsOpsGate.js +162 -0
- package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.js +166 -0
- package/dist/services/docs/review/gates/SqlRequiredTablesGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SqlRequiredTablesGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SqlRequiredTablesGate.js +273 -0
- package/dist/services/docs/review/gates/SqlSyntaxGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SqlSyntaxGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SqlSyntaxGate.js +203 -0
- package/dist/services/docs/review/gates/TerminologyNormalizationGate.d.ts +9 -0
- package/dist/services/docs/review/gates/TerminologyNormalizationGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/TerminologyNormalizationGate.js +217 -0
- package/dist/services/docs/review/glossary.json +47 -0
- package/dist/services/estimate/EstimateService.d.ts +2 -0
- package/dist/services/estimate/EstimateService.d.ts.map +1 -1
- package/dist/services/estimate/EstimateService.js +66 -18
- package/dist/services/estimate/VelocityService.d.ts +4 -0
- package/dist/services/estimate/VelocityService.d.ts.map +1 -1
- package/dist/services/estimate/VelocityService.js +179 -36
- package/dist/services/estimate/types.d.ts +1 -0
- package/dist/services/estimate/types.d.ts.map +1 -1
- package/dist/services/execution/GatewayTrioService.d.ts +71 -4
- package/dist/services/execution/GatewayTrioService.d.ts.map +1 -1
- package/dist/services/execution/GatewayTrioService.js +1695 -328
- package/dist/services/execution/QaApiRunner.d.ts +30 -0
- package/dist/services/execution/QaApiRunner.d.ts.map +1 -0
- package/dist/services/execution/QaApiRunner.js +881 -0
- package/dist/services/execution/QaFollowupService.d.ts +1 -0
- package/dist/services/execution/QaFollowupService.d.ts.map +1 -1
- package/dist/services/execution/QaFollowupService.js +8 -2
- package/dist/services/execution/QaPlanValidator.d.ts +10 -0
- package/dist/services/execution/QaPlanValidator.d.ts.map +1 -0
- package/dist/services/execution/QaPlanValidator.js +128 -0
- package/dist/services/execution/QaProfileService.d.ts +21 -1
- package/dist/services/execution/QaProfileService.d.ts.map +1 -1
- package/dist/services/execution/QaProfileService.js +214 -29
- package/dist/services/execution/QaTasksService.d.ts +41 -1
- package/dist/services/execution/QaTasksService.d.ts.map +1 -1
- package/dist/services/execution/QaTasksService.js +2851 -500
- package/dist/services/execution/QaTestCommandBuilder.d.ts +51 -0
- package/dist/services/execution/QaTestCommandBuilder.d.ts.map +1 -0
- package/dist/services/execution/QaTestCommandBuilder.js +495 -0
- package/dist/services/execution/TaskSelectionService.d.ts +4 -2
- package/dist/services/execution/TaskSelectionService.d.ts.map +1 -1
- package/dist/services/execution/TaskSelectionService.js +144 -28
- package/dist/services/execution/TaskStateService.d.ts +19 -6
- package/dist/services/execution/TaskStateService.d.ts.map +1 -1
- package/dist/services/execution/TaskStateService.js +128 -13
- package/dist/services/execution/WorkOnTasksService.d.ts +19 -2
- package/dist/services/execution/WorkOnTasksService.d.ts.map +1 -1
- package/dist/services/execution/WorkOnTasksService.js +3913 -1225
- package/dist/services/jobs/JobInsightsService.d.ts +4 -0
- package/dist/services/jobs/JobInsightsService.d.ts.map +1 -1
- package/dist/services/jobs/JobInsightsService.js +51 -5
- package/dist/services/jobs/JobResumeService.d.ts.map +1 -1
- package/dist/services/jobs/JobResumeService.js +23 -10
- package/dist/services/jobs/JobService.d.ts +56 -4
- package/dist/services/jobs/JobService.d.ts.map +1 -1
- package/dist/services/jobs/JobService.js +232 -1
- package/dist/services/openapi/OpenApiService.d.ts +41 -0
- package/dist/services/openapi/OpenApiService.d.ts.map +1 -1
- package/dist/services/openapi/OpenApiService.js +889 -98
- package/dist/services/planning/CreateTasksService.d.ts +15 -0
- package/dist/services/planning/CreateTasksService.d.ts.map +1 -1
- package/dist/services/planning/CreateTasksService.js +311 -6
- package/dist/services/planning/RefineTasksService.d.ts +4 -0
- package/dist/services/planning/RefineTasksService.d.ts.map +1 -1
- package/dist/services/planning/RefineTasksService.js +225 -24
- package/dist/services/review/CodeReviewService.d.ts +4 -0
- package/dist/services/review/CodeReviewService.d.ts.map +1 -1
- package/dist/services/review/CodeReviewService.js +778 -232
- package/dist/services/review/ReviewNormalizer.d.ts +9 -0
- package/dist/services/review/ReviewNormalizer.d.ts.map +1 -0
- package/dist/services/review/ReviewNormalizer.js +147 -0
- package/dist/services/shared/AuthErrors.d.ts +3 -0
- package/dist/services/shared/AuthErrors.d.ts.map +1 -0
- package/dist/services/shared/AuthErrors.js +17 -0
- package/dist/services/shared/DocdexGuidance.d.ts +7 -0
- package/dist/services/shared/DocdexGuidance.d.ts.map +1 -0
- package/dist/services/shared/DocdexGuidance.js +12 -0
- package/dist/services/shared/ProjectGuidance.d.ts +12 -1
- package/dist/services/shared/ProjectGuidance.d.ts.map +1 -1
- package/dist/services/shared/ProjectGuidance.js +64 -7
- package/dist/services/system/ToolDenylist.d.ts +13 -0
- package/dist/services/system/ToolDenylist.d.ts.map +1 -0
- package/dist/services/system/ToolDenylist.js +85 -0
- package/dist/services/telemetry/TelemetryService.d.ts.map +1 -1
- package/dist/services/telemetry/TelemetryService.js +39 -7
- package/dist/workspace/WorkspaceManager.d.ts +22 -0
- package/dist/workspace/WorkspaceManager.d.ts.map +1 -1
- package/dist/workspace/WorkspaceManager.js +203 -32
- package/package.json +6 -5
|
@@ -5,6 +5,7 @@ import { WorkspaceResolution } from "../../workspace/WorkspaceManager.js";
|
|
|
5
5
|
import { JobService } from "../jobs/JobService.js";
|
|
6
6
|
import { RoutingService } from "../agents/RoutingService.js";
|
|
7
7
|
import { AgentRatingService } from "../agents/AgentRatingService.js";
|
|
8
|
+
import { TaskOrderingService } from "../backlog/TaskOrderingService.js";
|
|
8
9
|
export interface CreateTasksOptions {
|
|
9
10
|
workspace: WorkspaceResolution;
|
|
10
11
|
projectKey: string;
|
|
@@ -16,6 +17,10 @@ export interface CreateTasksOptions {
|
|
|
16
17
|
maxStoriesPerEpic?: number;
|
|
17
18
|
maxTasksPerStory?: number;
|
|
18
19
|
force?: boolean;
|
|
20
|
+
qaProfiles?: string[];
|
|
21
|
+
qaEntryUrl?: string;
|
|
22
|
+
qaStartCommand?: string;
|
|
23
|
+
qaRequires?: string[];
|
|
19
24
|
}
|
|
20
25
|
export interface CreateTasksResult {
|
|
21
26
|
jobId: string;
|
|
@@ -25,6 +30,10 @@ export interface CreateTasksResult {
|
|
|
25
30
|
tasks: TaskRow[];
|
|
26
31
|
dependencies: TaskDependencyRow[];
|
|
27
32
|
}
|
|
33
|
+
type TaskOrderingClient = Pick<TaskOrderingService, "orderTasks" | "close">;
|
|
34
|
+
type TaskOrderingFactory = (workspace: WorkspaceResolution, options?: {
|
|
35
|
+
recordTelemetry?: boolean;
|
|
36
|
+
}) => Promise<TaskOrderingClient>;
|
|
28
37
|
export declare class CreateTasksService {
|
|
29
38
|
private static readonly MAX_BUSY_RETRIES;
|
|
30
39
|
private static readonly BUSY_BACKOFF_MS;
|
|
@@ -36,6 +45,7 @@ export declare class CreateTasksService {
|
|
|
36
45
|
private routingService;
|
|
37
46
|
private workspace;
|
|
38
47
|
private ratingService?;
|
|
48
|
+
private taskOrderingFactory;
|
|
39
49
|
constructor(workspace: WorkspaceResolution, deps: {
|
|
40
50
|
docdex: DocdexClient;
|
|
41
51
|
jobService: JobService;
|
|
@@ -44,13 +54,17 @@ export declare class CreateTasksService {
|
|
|
44
54
|
workspaceRepo: WorkspaceRepository;
|
|
45
55
|
routingService: RoutingService;
|
|
46
56
|
ratingService?: AgentRatingService;
|
|
57
|
+
taskOrderingFactory?: TaskOrderingFactory;
|
|
47
58
|
});
|
|
48
59
|
static create(workspace: WorkspaceResolution): Promise<CreateTasksService>;
|
|
49
60
|
close(): Promise<void>;
|
|
61
|
+
private seedPriorities;
|
|
50
62
|
private resolveAgent;
|
|
51
63
|
private ensureRatingService;
|
|
52
64
|
private prepareDocs;
|
|
53
65
|
private resolveDefaultDocInputs;
|
|
66
|
+
private buildQaPreflight;
|
|
67
|
+
private buildQaOverrides;
|
|
54
68
|
private buildDocContext;
|
|
55
69
|
private buildPrompt;
|
|
56
70
|
private fallbackPlan;
|
|
@@ -71,4 +85,5 @@ export declare class CreateTasksService {
|
|
|
71
85
|
refinePlansDir?: string;
|
|
72
86
|
}): Promise<CreateTasksResult>;
|
|
73
87
|
}
|
|
88
|
+
export {};
|
|
74
89
|
//# sourceMappingURL=CreateTasksService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/CreateTasksService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAEL,OAAO,EACP,gBAAgB,EAEhB,QAAQ,EAER,iBAAiB,EAEjB,OAAO,EACP,mBAAmB,EACpB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,YAAY,EAAkB,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"CreateTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/CreateTasksService.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,18 +7,124 @@ import { DocdexClient } from "@mcoda/integrations";
|
|
|
7
7
|
import { JobService } from "../jobs/JobService.js";
|
|
8
8
|
import { RoutingService } from "../agents/RoutingService.js";
|
|
9
9
|
import { AgentRatingService } from "../agents/AgentRatingService.js";
|
|
10
|
+
import { classifyTask } from "../backlog/TaskOrderingHeuristics.js";
|
|
11
|
+
import { TaskOrderingService } from "../backlog/TaskOrderingService.js";
|
|
10
12
|
import { createEpicKeyGenerator, createStoryKeyGenerator, createTaskKeyGenerator, } from "./KeyHelpers.js";
|
|
11
13
|
const formatBullets = (items, fallback) => {
|
|
12
14
|
if (!items || items.length === 0)
|
|
13
15
|
return `- ${fallback}`;
|
|
14
16
|
return items.map((item) => `- ${item}`).join("\n");
|
|
15
17
|
};
|
|
18
|
+
const normalizeStringArray = (value) => {
|
|
19
|
+
if (!Array.isArray(value))
|
|
20
|
+
return [];
|
|
21
|
+
return value
|
|
22
|
+
.filter((item) => typeof item === "string")
|
|
23
|
+
.map((item) => item.trim())
|
|
24
|
+
.filter(Boolean);
|
|
25
|
+
};
|
|
26
|
+
const normalizeEntrypoints = (value) => {
|
|
27
|
+
if (!Array.isArray(value))
|
|
28
|
+
return [];
|
|
29
|
+
return value
|
|
30
|
+
.map((entry) => {
|
|
31
|
+
if (!entry || typeof entry !== "object")
|
|
32
|
+
return null;
|
|
33
|
+
const record = entry;
|
|
34
|
+
const kind = record.kind;
|
|
35
|
+
if (kind !== "web" && kind !== "api" && kind !== "cli")
|
|
36
|
+
return null;
|
|
37
|
+
return {
|
|
38
|
+
kind,
|
|
39
|
+
base_url: typeof record.base_url === "string" ? record.base_url : undefined,
|
|
40
|
+
command: typeof record.command === "string" ? record.command : undefined,
|
|
41
|
+
};
|
|
42
|
+
})
|
|
43
|
+
.filter((entry) => Boolean(entry));
|
|
44
|
+
};
|
|
45
|
+
const normalizeQaReadiness = (value) => {
|
|
46
|
+
if (!value || typeof value !== "object")
|
|
47
|
+
return undefined;
|
|
48
|
+
const record = value;
|
|
49
|
+
const qa = {
|
|
50
|
+
profiles_expected: normalizeStringArray(record.profiles_expected),
|
|
51
|
+
requires: normalizeStringArray(record.requires),
|
|
52
|
+
entrypoints: normalizeEntrypoints(record.entrypoints),
|
|
53
|
+
data_setup: normalizeStringArray(record.data_setup),
|
|
54
|
+
blockers: normalizeStringArray(record.blockers),
|
|
55
|
+
notes: typeof record.notes === "string" ? record.notes : undefined,
|
|
56
|
+
};
|
|
57
|
+
const hasValues = (qa.profiles_expected?.length ?? 0) > 0 ||
|
|
58
|
+
(qa.requires?.length ?? 0) > 0 ||
|
|
59
|
+
(qa.entrypoints?.length ?? 0) > 0 ||
|
|
60
|
+
(qa.data_setup?.length ?? 0) > 0 ||
|
|
61
|
+
(qa.blockers?.length ?? 0) > 0 ||
|
|
62
|
+
(qa.notes?.length ?? 0) > 0;
|
|
63
|
+
return hasValues ? qa : undefined;
|
|
64
|
+
};
|
|
65
|
+
const uniqueStrings = (items) => Array.from(new Set(items));
|
|
66
|
+
const uniqueEntrypoints = (items) => {
|
|
67
|
+
const seen = new Set();
|
|
68
|
+
const result = [];
|
|
69
|
+
for (const entry of items) {
|
|
70
|
+
const key = `${entry.kind}|${entry.base_url ?? ""}|${entry.command ?? ""}`;
|
|
71
|
+
if (seen.has(key))
|
|
72
|
+
continue;
|
|
73
|
+
seen.add(key);
|
|
74
|
+
result.push(entry);
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
};
|
|
78
|
+
const buildQaReadiness = (params) => {
|
|
79
|
+
const derivedProfiles = ["cli"];
|
|
80
|
+
if (params.classification.stage === "frontend")
|
|
81
|
+
derivedProfiles.push("chromium");
|
|
82
|
+
if (params.classification.stage === "backend")
|
|
83
|
+
derivedProfiles.push("api");
|
|
84
|
+
const profilesExpected = uniqueStrings([
|
|
85
|
+
...derivedProfiles,
|
|
86
|
+
...(params.overrides?.profiles_expected ?? []),
|
|
87
|
+
...(params.planQa?.profiles_expected ?? []),
|
|
88
|
+
]);
|
|
89
|
+
const entrypoints = uniqueEntrypoints([
|
|
90
|
+
...(params.overrides?.entrypoints ?? []),
|
|
91
|
+
...(params.planQa?.entrypoints ?? []),
|
|
92
|
+
...(params.classification.stage === "frontend" ? params.preflight?.entrypoints ?? [] : []),
|
|
93
|
+
]);
|
|
94
|
+
const blockers = uniqueStrings([
|
|
95
|
+
...(params.overrides?.blockers ?? []),
|
|
96
|
+
...(params.planQa?.blockers ?? []),
|
|
97
|
+
...(params.preflight?.blockers ?? []),
|
|
98
|
+
]);
|
|
99
|
+
if (params.classification.stage === "frontend" && entrypoints.length === 0) {
|
|
100
|
+
blockers.push("Missing UI entrypoint (dev/start script).");
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
profiles_expected: profilesExpected,
|
|
104
|
+
requires: uniqueStrings([...(params.overrides?.requires ?? []), ...(params.planQa?.requires ?? [])]),
|
|
105
|
+
entrypoints: entrypoints.length ? entrypoints : undefined,
|
|
106
|
+
data_setup: uniqueStrings([...(params.overrides?.data_setup ?? []), ...(params.planQa?.data_setup ?? [])]),
|
|
107
|
+
blockers: blockers.length ? blockers : undefined,
|
|
108
|
+
notes: params.overrides?.notes ?? params.planQa?.notes,
|
|
109
|
+
};
|
|
110
|
+
};
|
|
16
111
|
const formatTestList = (items) => {
|
|
17
112
|
if (!items || items.length === 0)
|
|
18
113
|
return "Not applicable";
|
|
19
114
|
return items.join("; ");
|
|
20
115
|
};
|
|
21
116
|
const ensureNonEmpty = (value, fallback) => value && value.trim().length > 0 ? value.trim() : fallback;
|
|
117
|
+
const extractScriptPort = (script) => {
|
|
118
|
+
const matches = [script.match(/(?:--port|-p)\s*(\d{2,5})/), script.match(/PORT\s*=\s*(\d{2,5})/)];
|
|
119
|
+
for (const match of matches) {
|
|
120
|
+
if (!match)
|
|
121
|
+
continue;
|
|
122
|
+
const parsed = Number.parseInt(match[1] ?? "", 10);
|
|
123
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
124
|
+
return parsed;
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
};
|
|
22
128
|
const estimateTokens = (text) => Math.max(1, Math.ceil(text.length / 4));
|
|
23
129
|
const DOC_CONTEXT_BUDGET = 8000;
|
|
24
130
|
const DOCDEX_HANDLE = /^docdex:/i;
|
|
@@ -214,7 +320,17 @@ const buildStoryDescription = (storyKey, title, userStory, description, acceptan
|
|
|
214
320
|
formatBullets(relatedDocs, "Docdex handles, OpenAPI endpoints, code modules."),
|
|
215
321
|
].join("\n");
|
|
216
322
|
};
|
|
217
|
-
const buildTaskDescription = (taskKey, title, description, storyKey, epicKey, relatedDocs, dependencies, tests) => {
|
|
323
|
+
const buildTaskDescription = (taskKey, title, description, storyKey, epicKey, relatedDocs, dependencies, tests, qa) => {
|
|
324
|
+
const formatEntrypoints = (entrypoints) => {
|
|
325
|
+
if (!entrypoints || entrypoints.length === 0)
|
|
326
|
+
return "- Not specified";
|
|
327
|
+
return entrypoints
|
|
328
|
+
.map((entry) => {
|
|
329
|
+
const target = entry.base_url ?? entry.command ?? "TBD";
|
|
330
|
+
return `- ${entry.kind}: ${target}`;
|
|
331
|
+
})
|
|
332
|
+
.join("\n");
|
|
333
|
+
};
|
|
218
334
|
return [
|
|
219
335
|
`* **Task Key**: ${taskKey}`,
|
|
220
336
|
"* **Objective**",
|
|
@@ -235,6 +351,14 @@ const buildTaskDescription = (taskKey, title, description, storyKey, epicKey, re
|
|
|
235
351
|
`- Component tests: ${formatTestList(tests.componentTests)}`,
|
|
236
352
|
`- Integration tests: ${formatTestList(tests.integrationTests)}`,
|
|
237
353
|
`- API tests: ${formatTestList(tests.apiTests)}`,
|
|
354
|
+
"* **QA Readiness**",
|
|
355
|
+
`- Profiles: ${qa?.profiles_expected?.length ? qa.profiles_expected.join(", ") : "TBD"}`,
|
|
356
|
+
`- Requires: ${qa?.requires?.length ? qa.requires.join("; ") : "None specified"}`,
|
|
357
|
+
`- Data setup: ${qa?.data_setup?.length ? qa.data_setup.join("; ") : "None specified"}`,
|
|
358
|
+
"* **QA Entry Points**",
|
|
359
|
+
formatEntrypoints(qa?.entrypoints),
|
|
360
|
+
"* **QA Blockers**",
|
|
361
|
+
formatBullets(qa?.blockers, "None known."),
|
|
238
362
|
"* **Dependencies**",
|
|
239
363
|
formatBullets(dependencies, "Enumerate prerequisite tasks by key."),
|
|
240
364
|
"* **Risks & Gotchas**",
|
|
@@ -302,7 +426,14 @@ const TASK_SCHEMA_SNIPPET = `{
|
|
|
302
426
|
"unitTests": ["unit test description"],
|
|
303
427
|
"componentTests": ["component test description"],
|
|
304
428
|
"integrationTests": ["integration test description"],
|
|
305
|
-
"apiTests": ["api test description"]
|
|
429
|
+
"apiTests": ["api test description"],
|
|
430
|
+
"qa": {
|
|
431
|
+
"profiles_expected": ["cli", "api", "chromium"],
|
|
432
|
+
"requires": ["dev server", "seed data"],
|
|
433
|
+
"entrypoints": [{ "kind": "web", "base_url": "http://localhost:<PORT>", "command": "npm run dev" }],
|
|
434
|
+
"data_setup": ["seed sample data"],
|
|
435
|
+
"notes": "optional QA notes"
|
|
436
|
+
}
|
|
306
437
|
}
|
|
307
438
|
]
|
|
308
439
|
}`;
|
|
@@ -316,14 +447,17 @@ export class CreateTasksService {
|
|
|
316
447
|
this.workspaceRepo = deps.workspaceRepo;
|
|
317
448
|
this.routingService = deps.routingService;
|
|
318
449
|
this.ratingService = deps.ratingService;
|
|
450
|
+
this.taskOrderingFactory = deps.taskOrderingFactory ?? TaskOrderingService.create;
|
|
319
451
|
}
|
|
320
452
|
static async create(workspace) {
|
|
321
453
|
const repo = await GlobalRepository.create();
|
|
322
454
|
const agentService = new AgentService(repo);
|
|
323
455
|
const routingService = await RoutingService.create();
|
|
456
|
+
const docdexRepoId = workspace.config?.docdexRepoId ?? process.env.MCODA_DOCDEX_REPO_ID ?? process.env.DOCDEX_REPO_ID;
|
|
324
457
|
const docdex = new DocdexClient({
|
|
325
458
|
workspaceRoot: workspace.workspaceRoot,
|
|
326
459
|
baseUrl: workspace.config?.docdexUrl ?? process.env.MCODA_DOCDEX_URL,
|
|
460
|
+
repoId: docdexRepoId,
|
|
327
461
|
});
|
|
328
462
|
const jobService = new JobService(workspace);
|
|
329
463
|
const workspaceRepo = await WorkspaceRepository.create(workspace.workspaceRoot);
|
|
@@ -354,6 +488,17 @@ export class CreateTasksService {
|
|
|
354
488
|
const docdex = this.docdex;
|
|
355
489
|
await swallow(docdex?.close?.bind(docdex));
|
|
356
490
|
}
|
|
491
|
+
async seedPriorities(projectKey) {
|
|
492
|
+
const ordering = await this.taskOrderingFactory(this.workspace, { recordTelemetry: false });
|
|
493
|
+
try {
|
|
494
|
+
await ordering.orderTasks({
|
|
495
|
+
projectKey,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
finally {
|
|
499
|
+
await ordering.close();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
357
502
|
async resolveAgent(agentName) {
|
|
358
503
|
const resolved = await this.routingService.resolveAgentForCommand({
|
|
359
504
|
workspace: this.workspace,
|
|
@@ -440,6 +585,106 @@ export class CreateTasksService {
|
|
|
440
585
|
}
|
|
441
586
|
return existing;
|
|
442
587
|
}
|
|
588
|
+
async buildQaPreflight() {
|
|
589
|
+
const preflight = {
|
|
590
|
+
scripts: {},
|
|
591
|
+
entrypoints: [],
|
|
592
|
+
blockers: [],
|
|
593
|
+
};
|
|
594
|
+
const packagePath = path.join(this.workspace.workspaceRoot, "package.json");
|
|
595
|
+
let pkg = null;
|
|
596
|
+
try {
|
|
597
|
+
const raw = await fs.readFile(packagePath, "utf8");
|
|
598
|
+
pkg = JSON.parse(raw);
|
|
599
|
+
}
|
|
600
|
+
catch {
|
|
601
|
+
return preflight;
|
|
602
|
+
}
|
|
603
|
+
const scripts = pkg?.scripts;
|
|
604
|
+
if (scripts && typeof scripts === "object") {
|
|
605
|
+
for (const [name, value] of Object.entries(scripts)) {
|
|
606
|
+
if (typeof value === "string") {
|
|
607
|
+
preflight.scripts[name] = value;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
const dependencies = {
|
|
612
|
+
...(pkg?.dependencies && typeof pkg.dependencies === "object" ? pkg.dependencies : {}),
|
|
613
|
+
...(pkg?.devDependencies && typeof pkg.devDependencies === "object"
|
|
614
|
+
? pkg.devDependencies
|
|
615
|
+
: {}),
|
|
616
|
+
};
|
|
617
|
+
const hasDev = typeof preflight.scripts.dev === "string";
|
|
618
|
+
const hasStart = typeof preflight.scripts.start === "string";
|
|
619
|
+
const devPort = hasDev ? extractScriptPort(preflight.scripts.dev) : undefined;
|
|
620
|
+
const startPort = hasStart ? extractScriptPort(preflight.scripts.start) : undefined;
|
|
621
|
+
if (hasDev) {
|
|
622
|
+
preflight.entrypoints.push({
|
|
623
|
+
kind: "web",
|
|
624
|
+
base_url: devPort ? `http://localhost:${devPort}` : undefined,
|
|
625
|
+
command: "npm run dev",
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
else if (hasStart) {
|
|
629
|
+
preflight.entrypoints.push({
|
|
630
|
+
kind: "web",
|
|
631
|
+
base_url: startPort ? `http://localhost:${startPort}` : undefined,
|
|
632
|
+
command: "npm start",
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
const testDirs = [
|
|
636
|
+
path.join(this.workspace.workspaceRoot, "tests"),
|
|
637
|
+
path.join(this.workspace.workspaceRoot, "__tests__"),
|
|
638
|
+
];
|
|
639
|
+
const testFiles = [];
|
|
640
|
+
for (const dir of testDirs) {
|
|
641
|
+
try {
|
|
642
|
+
const stat = await fs.stat(dir);
|
|
643
|
+
if (!stat.isDirectory())
|
|
644
|
+
continue;
|
|
645
|
+
testFiles.push(...(await collectFilesRecursively(dir)));
|
|
646
|
+
}
|
|
647
|
+
catch {
|
|
648
|
+
// ignore missing test dirs
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
const testCandidates = testFiles.filter((file) => /\b(test|spec)\b/i.test(path.basename(file)));
|
|
652
|
+
const hasSupertest = typeof dependencies.supertest === "string";
|
|
653
|
+
if (!hasSupertest && testCandidates.length > 0) {
|
|
654
|
+
for (const file of testCandidates) {
|
|
655
|
+
try {
|
|
656
|
+
const content = await fs.readFile(file, "utf8");
|
|
657
|
+
if (content.includes("supertest")) {
|
|
658
|
+
preflight.blockers.push("Missing devDependency: supertest (required by test files).");
|
|
659
|
+
break;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
catch {
|
|
663
|
+
// ignore read errors
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return preflight;
|
|
668
|
+
}
|
|
669
|
+
buildQaOverrides(options) {
|
|
670
|
+
const profiles = options.qaProfiles?.filter(Boolean);
|
|
671
|
+
const requires = options.qaRequires?.filter(Boolean);
|
|
672
|
+
const entrypoints = [];
|
|
673
|
+
if (options.qaEntryUrl || options.qaStartCommand) {
|
|
674
|
+
entrypoints.push({
|
|
675
|
+
kind: "web",
|
|
676
|
+
base_url: options.qaEntryUrl,
|
|
677
|
+
command: options.qaStartCommand,
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
if (!profiles?.length && !requires?.length && entrypoints.length === 0)
|
|
681
|
+
return undefined;
|
|
682
|
+
return {
|
|
683
|
+
profiles_expected: profiles,
|
|
684
|
+
requires,
|
|
685
|
+
entrypoints: entrypoints.length ? entrypoints : undefined,
|
|
686
|
+
};
|
|
687
|
+
}
|
|
443
688
|
buildDocContext(docs) {
|
|
444
689
|
const warnings = [];
|
|
445
690
|
const blocks = [];
|
|
@@ -583,6 +828,7 @@ export class CreateTasksService {
|
|
|
583
828
|
}
|
|
584
829
|
let parsed = extractJson(output);
|
|
585
830
|
if (!parsed) {
|
|
831
|
+
const attempt = 2;
|
|
586
832
|
const fixPrompt = [
|
|
587
833
|
"Rewrite the previous response into valid JSON matching the expected schema.",
|
|
588
834
|
`Schema hint:\n${action === "epics" ? EPIC_SCHEMA_SNIPPET : action === "stories" ? STORY_SCHEMA_SNIPPET : TASK_SCHEMA_SNIPPET}`,
|
|
@@ -593,6 +839,32 @@ export class CreateTasksService {
|
|
|
593
839
|
const fix = await this.agentService.invoke(agent.id, { input: fixPrompt });
|
|
594
840
|
output = fix.output ?? "";
|
|
595
841
|
parsed = extractJson(output);
|
|
842
|
+
if (parsed) {
|
|
843
|
+
const promptTokens = estimateTokens(prompt);
|
|
844
|
+
const completionTokens = estimateTokens(output);
|
|
845
|
+
const durationSeconds = (Date.now() - startedAt) / 1000;
|
|
846
|
+
await this.jobService.recordTokenUsage({
|
|
847
|
+
timestamp: new Date().toISOString(),
|
|
848
|
+
workspaceId: this.workspace.workspaceId,
|
|
849
|
+
jobId,
|
|
850
|
+
commandRunId,
|
|
851
|
+
agentId: agent.id,
|
|
852
|
+
modelName: agent.defaultModel,
|
|
853
|
+
promptTokens,
|
|
854
|
+
completionTokens,
|
|
855
|
+
tokensPrompt: promptTokens,
|
|
856
|
+
tokensCompletion: completionTokens,
|
|
857
|
+
tokensTotal: promptTokens + completionTokens,
|
|
858
|
+
durationSeconds,
|
|
859
|
+
metadata: {
|
|
860
|
+
action: `create_tasks_${action}`,
|
|
861
|
+
phase: `create_tasks_${action}`,
|
|
862
|
+
attempt,
|
|
863
|
+
...(metadata ?? {}),
|
|
864
|
+
},
|
|
865
|
+
});
|
|
866
|
+
return { output, promptTokens, completionTokens };
|
|
867
|
+
}
|
|
596
868
|
}
|
|
597
869
|
catch (error) {
|
|
598
870
|
throw new Error(`Agent retry failed (${action}): ${error.message}`);
|
|
@@ -617,7 +889,12 @@ export class CreateTasksService {
|
|
|
617
889
|
tokensCompletion: completionTokens,
|
|
618
890
|
tokensTotal: promptTokens + completionTokens,
|
|
619
891
|
durationSeconds,
|
|
620
|
-
metadata: {
|
|
892
|
+
metadata: {
|
|
893
|
+
action: `create_tasks_${action}`,
|
|
894
|
+
phase: `create_tasks_${action}`,
|
|
895
|
+
attempt: 1,
|
|
896
|
+
...(metadata ?? {}),
|
|
897
|
+
},
|
|
621
898
|
});
|
|
622
899
|
return { output, promptTokens, completionTokens };
|
|
623
900
|
}
|
|
@@ -692,6 +969,8 @@ export class CreateTasksService {
|
|
|
692
969
|
"- Include test arrays: unitTests, componentTests, integrationTests, apiTests. Use [] when not applicable.",
|
|
693
970
|
"- Only include tests that are relevant to the task's scope.",
|
|
694
971
|
"- If the task involves code or configuration changes, include at least one relevant test; do not leave all test arrays empty unless it's purely documentation or research.",
|
|
972
|
+
"- When known, include qa object with profiles_expected/requires/entrypoints/data_setup to guide QA.",
|
|
973
|
+
"- Do not hardcode ports. For QA entrypoints, use http://localhost:<PORT> placeholders or omit base_url when unknown.",
|
|
695
974
|
"- dependsOnKeys must reference localIds in this story.",
|
|
696
975
|
"- Use docdex handles when citing docs.",
|
|
697
976
|
`Story context (key=${story.key ?? story.localId ?? "TBD"}):`,
|
|
@@ -720,6 +999,7 @@ export class CreateTasksService {
|
|
|
720
999
|
if (!hasTests && !docOnly) {
|
|
721
1000
|
unitTests.push(`Add tests for ${title} (unit/component/integration/api as applicable)`);
|
|
722
1001
|
}
|
|
1002
|
+
const qa = normalizeQaReadiness(task.qa);
|
|
723
1003
|
return {
|
|
724
1004
|
localId: task.localId ?? `t${idx + 1}`,
|
|
725
1005
|
title,
|
|
@@ -733,6 +1013,7 @@ export class CreateTasksService {
|
|
|
733
1013
|
componentTests,
|
|
734
1014
|
integrationTests,
|
|
735
1015
|
apiTests,
|
|
1016
|
+
qa,
|
|
736
1017
|
};
|
|
737
1018
|
})
|
|
738
1019
|
.filter((t) => t.title);
|
|
@@ -770,7 +1051,7 @@ export class CreateTasksService {
|
|
|
770
1051
|
return { epics: planEpics, stories: planStories, tasks: planTasks };
|
|
771
1052
|
}
|
|
772
1053
|
async writePlanArtifacts(projectKey, plan, docSummary) {
|
|
773
|
-
const baseDir = path.join(this.workspace.
|
|
1054
|
+
const baseDir = path.join(this.workspace.mcodaDir, "tasks", projectKey);
|
|
774
1055
|
await fs.mkdir(baseDir, { recursive: true });
|
|
775
1056
|
const write = async (file, data) => {
|
|
776
1057
|
const target = path.join(baseDir, file);
|
|
@@ -863,6 +1144,17 @@ export class CreateTasksService {
|
|
|
863
1144
|
const epicId = epicIdByKey.get(task.epicKey);
|
|
864
1145
|
if (!storyId || !epicId)
|
|
865
1146
|
continue;
|
|
1147
|
+
const classification = classifyTask({
|
|
1148
|
+
title: task.plan.title ?? `Task ${task.key}`,
|
|
1149
|
+
description: task.plan.description,
|
|
1150
|
+
type: task.plan.type,
|
|
1151
|
+
});
|
|
1152
|
+
const qaReadiness = buildQaReadiness({
|
|
1153
|
+
classification,
|
|
1154
|
+
planQa: task.plan.qa,
|
|
1155
|
+
preflight: options?.qaPreflight,
|
|
1156
|
+
overrides: options?.qaOverrides,
|
|
1157
|
+
});
|
|
866
1158
|
const depSlugs = (task.plan.dependsOnKeys ?? [])
|
|
867
1159
|
.map((dep) => localToKey.get(dep))
|
|
868
1160
|
.filter((value) => Boolean(value));
|
|
@@ -877,7 +1169,7 @@ export class CreateTasksService {
|
|
|
877
1169
|
componentTests: task.plan.componentTests,
|
|
878
1170
|
integrationTests: task.plan.integrationTests,
|
|
879
1171
|
apiTests: task.plan.apiTests,
|
|
880
|
-
}),
|
|
1172
|
+
}, qaReadiness),
|
|
881
1173
|
type: task.plan.type ?? "feature",
|
|
882
1174
|
status: "not_started",
|
|
883
1175
|
storyPoints: task.plan.estimatedStoryPoints ?? null,
|
|
@@ -890,6 +1182,9 @@ export class CreateTasksService {
|
|
|
890
1182
|
integration: task.plan.integrationTests ?? [],
|
|
891
1183
|
api: task.plan.apiTests ?? [],
|
|
892
1184
|
},
|
|
1185
|
+
stage: classification.stage,
|
|
1186
|
+
foundation: classification.foundation,
|
|
1187
|
+
qa: qaReadiness,
|
|
893
1188
|
},
|
|
894
1189
|
});
|
|
895
1190
|
}
|
|
@@ -983,11 +1278,18 @@ export class CreateTasksService {
|
|
|
983
1278
|
const docs = await this.prepareDocs(options.inputs);
|
|
984
1279
|
const { docSummary, warnings: docWarnings } = this.buildDocContext(docs);
|
|
985
1280
|
const { prompt } = this.buildPrompt(options.projectKey, docs, options);
|
|
1281
|
+
const qaPreflight = await this.buildQaPreflight();
|
|
1282
|
+
const qaOverrides = this.buildQaOverrides(options);
|
|
986
1283
|
await this.jobService.writeCheckpoint(job.id, {
|
|
987
1284
|
stage: "docs_indexed",
|
|
988
1285
|
timestamp: new Date().toISOString(),
|
|
989
1286
|
details: { count: docs.length, warnings: docWarnings },
|
|
990
1287
|
});
|
|
1288
|
+
await this.jobService.writeCheckpoint(job.id, {
|
|
1289
|
+
stage: "qa_preflight",
|
|
1290
|
+
timestamp: new Date().toISOString(),
|
|
1291
|
+
details: qaPreflight,
|
|
1292
|
+
});
|
|
991
1293
|
const agent = await this.resolveAgent(options.agentName);
|
|
992
1294
|
const { output: epicOutput } = await this.invokeAgentWithRetry(agent, prompt, "epics", agentStream, job.id, commandRun.id, { docWarnings });
|
|
993
1295
|
const epics = this.parseEpics(epicOutput, docs, options.projectKey).slice(0, options.maxEpics ?? Number.MAX_SAFE_INTEGER);
|
|
@@ -1022,7 +1324,10 @@ export class CreateTasksService {
|
|
|
1022
1324
|
const { epics: epicRows, stories: storyRows, tasks: taskRows, dependencies: dependencyRows } = await this.persistPlanToDb(project.id, options.projectKey, plan, job.id, commandRun.id, {
|
|
1023
1325
|
force: options.force,
|
|
1024
1326
|
resetKeys: options.force,
|
|
1327
|
+
qaPreflight,
|
|
1328
|
+
qaOverrides,
|
|
1025
1329
|
});
|
|
1330
|
+
await this.seedPriorities(options.projectKey);
|
|
1026
1331
|
await this.jobService.updateJobStatus(job.id, "completed", {
|
|
1027
1332
|
payload: {
|
|
1028
1333
|
epicsCreated: epicRows.length,
|
|
@@ -1093,7 +1398,7 @@ export class CreateTasksService {
|
|
|
1093
1398
|
commandName: "migrate-tasks",
|
|
1094
1399
|
payload: { projectKey, planDir: options.planDir },
|
|
1095
1400
|
});
|
|
1096
|
-
const planDir = options.planDir ?? path.join(this.workspace.
|
|
1401
|
+
const planDir = options.planDir ?? path.join(this.workspace.mcodaDir, "tasks", projectKey);
|
|
1097
1402
|
try {
|
|
1098
1403
|
const planPath = path.join(planDir, "plan.json");
|
|
1099
1404
|
const loadJson = async (file) => {
|
|
@@ -41,7 +41,9 @@ export declare class RefineTasksService {
|
|
|
41
41
|
});
|
|
42
42
|
static create(workspace: WorkspaceResolution): Promise<RefineTasksService>;
|
|
43
43
|
close(): Promise<void>;
|
|
44
|
+
private seedPriorities;
|
|
44
45
|
private resolveAgent;
|
|
46
|
+
private selectFallbackAgent;
|
|
45
47
|
private ensureRatingService;
|
|
46
48
|
private selectTasks;
|
|
47
49
|
private parseTaskKeyParts;
|
|
@@ -51,8 +53,10 @@ export declare class RefineTasksService {
|
|
|
51
53
|
private summarizeHistory;
|
|
52
54
|
private logWarningsToTasks;
|
|
53
55
|
private mergeMetadata;
|
|
56
|
+
private applyStageMetadata;
|
|
54
57
|
private validateOperation;
|
|
55
58
|
private detectCycle;
|
|
59
|
+
private hasDependencyPath;
|
|
56
60
|
private applyOperations;
|
|
57
61
|
private invokeAgent;
|
|
58
62
|
refineTasks(options: RefineTasksOptions): Promise<RefineTasksResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RefineTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/RefineTasksService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"RefineTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/RefineTasksService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAA6C,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC7G,OAAO,EAIL,kBAAkB,EAClB,iBAAiB,EAKlB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAKrE,UAAU,kBAAmB,SAAQ,kBAAkB;IACrD,SAAS,EAAE,mBAAmB,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAuLD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,aAAa,CAAC,CAAqB;gBAGzC,SAAS,EAAE,mBAAmB,EAC9B,IAAI,EAAE;QACJ,MAAM,EAAE,YAAY,CAAC;QACrB,UAAU,EAAE,UAAU,CAAC;QACvB,YAAY,EAAE,YAAY,CAAC;QAC3B,IAAI,EAAE,gBAAgB,CAAC;QACvB,aAAa,EAAE,mBAAmB,CAAC;QACnC,cAAc,EAAE,cAAc,CAAC;QAC/B,aAAa,CAAC,EAAE,kBAAkB,CAAC;KACpC;WAYU,MAAM,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuB1E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAkBd,cAAc;YAWd,YAAY;YAwBZ,mBAAmB;IA4CjC,OAAO,CAAC,mBAAmB;YAYb,WAAW;IA4KzB,OAAO,CAAC,iBAAiB;YASX,gBAAgB;IAmK9B,OAAO,CAAC,gBAAgB;YA8BV,aAAa;YAoDb,gBAAgB;YA+BhB,kBAAkB;IAkChC,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,iBAAiB;IA8EzB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,iBAAiB;YAkBX,eAAe;YAqYf,WAAW;IAmGnB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAma3E"}
|