@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.
Files changed (204) hide show
  1. package/README.md +2 -2
  2. package/dist/api/AgentsApi.d.ts +1 -0
  3. package/dist/api/AgentsApi.d.ts.map +1 -1
  4. package/dist/api/AgentsApi.js +136 -11
  5. package/dist/api/QaTasksApi.d.ts.map +1 -1
  6. package/dist/api/QaTasksApi.js +4 -0
  7. package/dist/prompts/PdrPrompts.d.ts.map +1 -1
  8. package/dist/prompts/PdrPrompts.js +6 -0
  9. package/dist/prompts/SdsPrompts.d.ts.map +1 -1
  10. package/dist/prompts/SdsPrompts.js +7 -0
  11. package/dist/services/agents/AgentRatingService.d.ts +19 -0
  12. package/dist/services/agents/AgentRatingService.d.ts.map +1 -1
  13. package/dist/services/agents/AgentRatingService.js +66 -2
  14. package/dist/services/agents/GatewayAgentService.d.ts +8 -0
  15. package/dist/services/agents/GatewayAgentService.d.ts.map +1 -1
  16. package/dist/services/agents/GatewayAgentService.js +462 -65
  17. package/dist/services/agents/GatewayHandoff.d.ts +5 -1
  18. package/dist/services/agents/GatewayHandoff.d.ts.map +1 -1
  19. package/dist/services/agents/GatewayHandoff.js +65 -32
  20. package/dist/services/agents/RoutingService.d.ts +1 -0
  21. package/dist/services/agents/RoutingService.d.ts.map +1 -1
  22. package/dist/services/agents/RoutingService.js +4 -4
  23. package/dist/services/backlog/BacklogService.d.ts +23 -0
  24. package/dist/services/backlog/BacklogService.d.ts.map +1 -1
  25. package/dist/services/backlog/BacklogService.js +62 -7
  26. package/dist/services/backlog/TaskOrderingHeuristics.d.ts +12 -0
  27. package/dist/services/backlog/TaskOrderingHeuristics.d.ts.map +1 -0
  28. package/dist/services/backlog/TaskOrderingHeuristics.js +56 -0
  29. package/dist/services/backlog/TaskOrderingService.d.ts +16 -4
  30. package/dist/services/backlog/TaskOrderingService.d.ts.map +1 -1
  31. package/dist/services/backlog/TaskOrderingService.js +529 -73
  32. package/dist/services/docs/DocInventory.d.ts +11 -0
  33. package/dist/services/docs/DocInventory.d.ts.map +1 -0
  34. package/dist/services/docs/DocInventory.js +230 -0
  35. package/dist/services/docs/DocgenRunContext.d.ts +59 -0
  36. package/dist/services/docs/DocgenRunContext.d.ts.map +1 -0
  37. package/dist/services/docs/DocgenRunContext.js +4 -0
  38. package/dist/services/docs/DocsService.d.ts +59 -2
  39. package/dist/services/docs/DocsService.d.ts.map +1 -1
  40. package/dist/services/docs/DocsService.js +1701 -48
  41. package/dist/services/docs/alignment/DocAlignmentGraph.d.ts +23 -0
  42. package/dist/services/docs/alignment/DocAlignmentGraph.d.ts.map +1 -0
  43. package/dist/services/docs/alignment/DocAlignmentGraph.js +78 -0
  44. package/dist/services/docs/alignment/DocAlignmentPatcher.d.ts +19 -0
  45. package/dist/services/docs/alignment/DocAlignmentPatcher.d.ts.map +1 -0
  46. package/dist/services/docs/alignment/DocAlignmentPatcher.js +222 -0
  47. package/dist/services/docs/patch/DocPatchEngine.d.ts +57 -0
  48. package/dist/services/docs/patch/DocPatchEngine.d.ts.map +1 -0
  49. package/dist/services/docs/patch/DocPatchEngine.js +331 -0
  50. package/dist/services/docs/review/Glossary.d.ts +16 -0
  51. package/dist/services/docs/review/Glossary.d.ts.map +1 -0
  52. package/dist/services/docs/review/Glossary.js +47 -0
  53. package/dist/services/docs/review/ReviewReportRenderer.d.ts +3 -0
  54. package/dist/services/docs/review/ReviewReportRenderer.d.ts.map +1 -0
  55. package/dist/services/docs/review/ReviewReportRenderer.js +133 -0
  56. package/dist/services/docs/review/ReviewReportSchema.d.ts +39 -0
  57. package/dist/services/docs/review/ReviewReportSchema.d.ts.map +1 -0
  58. package/dist/services/docs/review/ReviewReportSchema.js +47 -0
  59. package/dist/services/docs/review/ReviewTypes.d.ts +76 -0
  60. package/dist/services/docs/review/ReviewTypes.d.ts.map +1 -0
  61. package/dist/services/docs/review/ReviewTypes.js +94 -0
  62. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.d.ts +7 -0
  63. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.d.ts.map +1 -0
  64. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.js +93 -0
  65. package/dist/services/docs/review/gates/ApiPathConsistencyGate.d.ts +7 -0
  66. package/dist/services/docs/review/gates/ApiPathConsistencyGate.d.ts.map +1 -0
  67. package/dist/services/docs/review/gates/ApiPathConsistencyGate.js +308 -0
  68. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.d.ts +8 -0
  69. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.d.ts.map +1 -0
  70. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.js +278 -0
  71. package/dist/services/docs/review/gates/DeploymentBlueprintGate.d.ts +8 -0
  72. package/dist/services/docs/review/gates/DeploymentBlueprintGate.d.ts.map +1 -0
  73. package/dist/services/docs/review/gates/DeploymentBlueprintGate.js +487 -0
  74. package/dist/services/docs/review/gates/NoMaybesGate.d.ts +8 -0
  75. package/dist/services/docs/review/gates/NoMaybesGate.d.ts.map +1 -0
  76. package/dist/services/docs/review/gates/NoMaybesGate.js +145 -0
  77. package/dist/services/docs/review/gates/OpenApiCoverageGate.d.ts +7 -0
  78. package/dist/services/docs/review/gates/OpenApiCoverageGate.d.ts.map +1 -0
  79. package/dist/services/docs/review/gates/OpenApiCoverageGate.js +266 -0
  80. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.d.ts +7 -0
  81. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.d.ts.map +1 -0
  82. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.js +59 -0
  83. package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts +7 -0
  84. package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts.map +1 -0
  85. package/dist/services/docs/review/gates/OpenQuestionsGate.js +200 -0
  86. package/dist/services/docs/review/gates/PdrInterfacesGate.d.ts +7 -0
  87. package/dist/services/docs/review/gates/PdrInterfacesGate.d.ts.map +1 -0
  88. package/dist/services/docs/review/gates/PdrInterfacesGate.js +159 -0
  89. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.d.ts +8 -0
  90. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.d.ts.map +1 -0
  91. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.js +129 -0
  92. package/dist/services/docs/review/gates/PdrOwnershipGate.d.ts +7 -0
  93. package/dist/services/docs/review/gates/PdrOwnershipGate.d.ts.map +1 -0
  94. package/dist/services/docs/review/gates/PdrOwnershipGate.js +169 -0
  95. package/dist/services/docs/review/gates/PlaceholderArtifactGate.d.ts +10 -0
  96. package/dist/services/docs/review/gates/PlaceholderArtifactGate.d.ts.map +1 -0
  97. package/dist/services/docs/review/gates/PlaceholderArtifactGate.js +261 -0
  98. package/dist/services/docs/review/gates/RfpConsentGate.d.ts +6 -0
  99. package/dist/services/docs/review/gates/RfpConsentGate.d.ts.map +1 -0
  100. package/dist/services/docs/review/gates/RfpConsentGate.js +127 -0
  101. package/dist/services/docs/review/gates/RfpDefinitionGate.d.ts +7 -0
  102. package/dist/services/docs/review/gates/RfpDefinitionGate.d.ts.map +1 -0
  103. package/dist/services/docs/review/gates/RfpDefinitionGate.js +173 -0
  104. package/dist/services/docs/review/gates/SdsAdaptersGate.d.ts +7 -0
  105. package/dist/services/docs/review/gates/SdsAdaptersGate.d.ts.map +1 -0
  106. package/dist/services/docs/review/gates/SdsAdaptersGate.js +196 -0
  107. package/dist/services/docs/review/gates/SdsDecisionsGate.d.ts +7 -0
  108. package/dist/services/docs/review/gates/SdsDecisionsGate.d.ts.map +1 -0
  109. package/dist/services/docs/review/gates/SdsDecisionsGate.js +89 -0
  110. package/dist/services/docs/review/gates/SdsOpsGate.d.ts +7 -0
  111. package/dist/services/docs/review/gates/SdsOpsGate.d.ts.map +1 -0
  112. package/dist/services/docs/review/gates/SdsOpsGate.js +162 -0
  113. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.d.ts +7 -0
  114. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.d.ts.map +1 -0
  115. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.js +166 -0
  116. package/dist/services/docs/review/gates/SqlRequiredTablesGate.d.ts +7 -0
  117. package/dist/services/docs/review/gates/SqlRequiredTablesGate.d.ts.map +1 -0
  118. package/dist/services/docs/review/gates/SqlRequiredTablesGate.js +273 -0
  119. package/dist/services/docs/review/gates/SqlSyntaxGate.d.ts +7 -0
  120. package/dist/services/docs/review/gates/SqlSyntaxGate.d.ts.map +1 -0
  121. package/dist/services/docs/review/gates/SqlSyntaxGate.js +203 -0
  122. package/dist/services/docs/review/gates/TerminologyNormalizationGate.d.ts +9 -0
  123. package/dist/services/docs/review/gates/TerminologyNormalizationGate.d.ts.map +1 -0
  124. package/dist/services/docs/review/gates/TerminologyNormalizationGate.js +217 -0
  125. package/dist/services/docs/review/glossary.json +47 -0
  126. package/dist/services/estimate/EstimateService.d.ts +2 -0
  127. package/dist/services/estimate/EstimateService.d.ts.map +1 -1
  128. package/dist/services/estimate/EstimateService.js +66 -18
  129. package/dist/services/estimate/VelocityService.d.ts +4 -0
  130. package/dist/services/estimate/VelocityService.d.ts.map +1 -1
  131. package/dist/services/estimate/VelocityService.js +179 -36
  132. package/dist/services/estimate/types.d.ts +1 -0
  133. package/dist/services/estimate/types.d.ts.map +1 -1
  134. package/dist/services/execution/GatewayTrioService.d.ts +71 -4
  135. package/dist/services/execution/GatewayTrioService.d.ts.map +1 -1
  136. package/dist/services/execution/GatewayTrioService.js +1695 -328
  137. package/dist/services/execution/QaApiRunner.d.ts +30 -0
  138. package/dist/services/execution/QaApiRunner.d.ts.map +1 -0
  139. package/dist/services/execution/QaApiRunner.js +881 -0
  140. package/dist/services/execution/QaFollowupService.d.ts +1 -0
  141. package/dist/services/execution/QaFollowupService.d.ts.map +1 -1
  142. package/dist/services/execution/QaFollowupService.js +8 -2
  143. package/dist/services/execution/QaPlanValidator.d.ts +10 -0
  144. package/dist/services/execution/QaPlanValidator.d.ts.map +1 -0
  145. package/dist/services/execution/QaPlanValidator.js +128 -0
  146. package/dist/services/execution/QaProfileService.d.ts +21 -1
  147. package/dist/services/execution/QaProfileService.d.ts.map +1 -1
  148. package/dist/services/execution/QaProfileService.js +214 -29
  149. package/dist/services/execution/QaTasksService.d.ts +41 -1
  150. package/dist/services/execution/QaTasksService.d.ts.map +1 -1
  151. package/dist/services/execution/QaTasksService.js +2851 -500
  152. package/dist/services/execution/QaTestCommandBuilder.d.ts +51 -0
  153. package/dist/services/execution/QaTestCommandBuilder.d.ts.map +1 -0
  154. package/dist/services/execution/QaTestCommandBuilder.js +495 -0
  155. package/dist/services/execution/TaskSelectionService.d.ts +4 -2
  156. package/dist/services/execution/TaskSelectionService.d.ts.map +1 -1
  157. package/dist/services/execution/TaskSelectionService.js +144 -28
  158. package/dist/services/execution/TaskStateService.d.ts +19 -6
  159. package/dist/services/execution/TaskStateService.d.ts.map +1 -1
  160. package/dist/services/execution/TaskStateService.js +128 -13
  161. package/dist/services/execution/WorkOnTasksService.d.ts +19 -2
  162. package/dist/services/execution/WorkOnTasksService.d.ts.map +1 -1
  163. package/dist/services/execution/WorkOnTasksService.js +3913 -1225
  164. package/dist/services/jobs/JobInsightsService.d.ts +4 -0
  165. package/dist/services/jobs/JobInsightsService.d.ts.map +1 -1
  166. package/dist/services/jobs/JobInsightsService.js +51 -5
  167. package/dist/services/jobs/JobResumeService.d.ts.map +1 -1
  168. package/dist/services/jobs/JobResumeService.js +23 -10
  169. package/dist/services/jobs/JobService.d.ts +56 -4
  170. package/dist/services/jobs/JobService.d.ts.map +1 -1
  171. package/dist/services/jobs/JobService.js +232 -1
  172. package/dist/services/openapi/OpenApiService.d.ts +41 -0
  173. package/dist/services/openapi/OpenApiService.d.ts.map +1 -1
  174. package/dist/services/openapi/OpenApiService.js +889 -98
  175. package/dist/services/planning/CreateTasksService.d.ts +15 -0
  176. package/dist/services/planning/CreateTasksService.d.ts.map +1 -1
  177. package/dist/services/planning/CreateTasksService.js +311 -6
  178. package/dist/services/planning/RefineTasksService.d.ts +4 -0
  179. package/dist/services/planning/RefineTasksService.d.ts.map +1 -1
  180. package/dist/services/planning/RefineTasksService.js +225 -24
  181. package/dist/services/review/CodeReviewService.d.ts +4 -0
  182. package/dist/services/review/CodeReviewService.d.ts.map +1 -1
  183. package/dist/services/review/CodeReviewService.js +778 -232
  184. package/dist/services/review/ReviewNormalizer.d.ts +9 -0
  185. package/dist/services/review/ReviewNormalizer.d.ts.map +1 -0
  186. package/dist/services/review/ReviewNormalizer.js +147 -0
  187. package/dist/services/shared/AuthErrors.d.ts +3 -0
  188. package/dist/services/shared/AuthErrors.d.ts.map +1 -0
  189. package/dist/services/shared/AuthErrors.js +17 -0
  190. package/dist/services/shared/DocdexGuidance.d.ts +7 -0
  191. package/dist/services/shared/DocdexGuidance.d.ts.map +1 -0
  192. package/dist/services/shared/DocdexGuidance.js +12 -0
  193. package/dist/services/shared/ProjectGuidance.d.ts +12 -1
  194. package/dist/services/shared/ProjectGuidance.d.ts.map +1 -1
  195. package/dist/services/shared/ProjectGuidance.js +64 -7
  196. package/dist/services/system/ToolDenylist.d.ts +13 -0
  197. package/dist/services/system/ToolDenylist.d.ts.map +1 -0
  198. package/dist/services/system/ToolDenylist.js +85 -0
  199. package/dist/services/telemetry/TelemetryService.d.ts.map +1 -1
  200. package/dist/services/telemetry/TelemetryService.js +39 -7
  201. package/dist/workspace/WorkspaceManager.d.ts +22 -0
  202. package/dist/workspace/WorkspaceManager.d.ts.map +1 -1
  203. package/dist/workspace/WorkspaceManager.js +203 -32
  204. 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":"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"}
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: { action: `create_tasks_${action}`, ...(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.workspaceRoot, ".mcoda", "tasks", projectKey);
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.workspaceRoot, ".mcoda", "tasks", projectKey);
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;AACnD,OAAO,EAAE,gBAAgB,EAA6C,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC7G,OAAO,EAIL,kBAAkB,EAClB,iBAAiB,EAGlB,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;AAGrE,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;AAmLD,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;IAoB1E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAkBd,YAAY;IAS1B,OAAO,CAAC,mBAAmB;YAYb,WAAW;IA4KzB,OAAO,CAAC,iBAAiB;YASX,gBAAgB;IAkK9B,OAAO,CAAC,gBAAgB;YA8BV,aAAa;YAoDb,gBAAgB;YA+BhB,kBAAkB;IAkChC,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,iBAAiB;IA8EzB,OAAO,CAAC,WAAW;YA0BL,eAAe;YAoSf,WAAW;IA6FnB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAka3E"}
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"}