@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
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { GatewayAgentResult } from "./GatewayAgentService.js";
|
|
2
2
|
export declare const GATEWAY_HANDOFF_ENV_PATH = "MCODA_GATEWAY_HANDOFF_PATH";
|
|
3
|
+
export interface GatewayHandoffContext {
|
|
4
|
+
qaFailureSummary?: string;
|
|
5
|
+
learningSummary?: string;
|
|
6
|
+
}
|
|
3
7
|
export declare const buildGatewayHandoffDocdexUsage: () => string;
|
|
4
|
-
export declare const buildGatewayHandoffContent: (result: GatewayAgentResult) => string;
|
|
8
|
+
export declare const buildGatewayHandoffContent: (result: GatewayAgentResult, context?: GatewayHandoffContext) => string;
|
|
5
9
|
export declare const writeGatewayHandoffFile: (workspaceRoot: string, commandRunId: string, content: string, prefix?: string) => Promise<string>;
|
|
6
10
|
export declare const withGatewayHandoff: <T>(handoffPath: string | undefined, fn: () => Promise<T>) => Promise<T>;
|
|
7
11
|
//# sourceMappingURL=GatewayHandoff.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GatewayHandoff.d.ts","sourceRoot":"","sources":["../../../src/services/agents/GatewayHandoff.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"GatewayHandoff.d.ts","sourceRoot":"","sources":["../../../src/services/agents/GatewayHandoff.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE,eAAO,MAAM,wBAAwB,+BAA+B,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,8BAA8B,QAAO,MAMjD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,QAAQ,kBAAkB,EAC1B,UAAU,qBAAqB,KAC9B,MAiGF,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,eAAe,MAAM,EACrB,cAAc,MAAM,EACpB,SAAS,MAAM,EACf,eAAkB,KACjB,OAAO,CAAC,MAAM,CAMhB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,CAAC,EAAE,aAAa,MAAM,GAAG,SAAS,EAAE,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAc5G,CAAC"}
|
|
@@ -1,89 +1,122 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { buildDocdexUsageGuidance } from "../shared/DocdexGuidance.js";
|
|
4
|
+
import { PathHelper } from "@mcoda/shared";
|
|
3
5
|
export const GATEWAY_HANDOFF_ENV_PATH = "MCODA_GATEWAY_HANDOFF_PATH";
|
|
4
6
|
export const buildGatewayHandoffDocdexUsage = () => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
lines.push("- Memory: `docdexd memory-store` / `memory-recall` (HTTP: `/v1/memory/store`, `/v1/memory/recall`).");
|
|
11
|
-
lines.push("- Agent profile: `docdexd profile add/search` (HTTP: `/v1/profile/add`, `/v1/profile/search`, `/v1/profile/save`).");
|
|
12
|
-
lines.push("- AST/impact/snippets use daemon endpoints (`/v1/ast`, `/v1/graph/impact`, `/snippet/:doc_id`).");
|
|
13
|
-
lines.push("- Reasoning DAG: capture session_id (docdex request_id) and export with `docdexd dag view --repo <repo> <session_id> --format text|dot|json`.");
|
|
14
|
-
lines.push("- HTTP DAG export: `GET /v1/dag/export?session_id=<id>&format=json|text|dot&max_nodes=<n>`.");
|
|
15
|
-
lines.push("- Note any docdex failures/disabled memory/profile in task comments or docdexNotes.");
|
|
16
|
-
return lines.join("\n");
|
|
7
|
+
return buildDocdexUsageGuidance({
|
|
8
|
+
contextLabel: "docdexNotes or task comments",
|
|
9
|
+
includeHeading: true,
|
|
10
|
+
includeFallback: true,
|
|
11
|
+
});
|
|
17
12
|
};
|
|
18
|
-
export const buildGatewayHandoffContent = (result) => {
|
|
13
|
+
export const buildGatewayHandoffContent = (result, context) => {
|
|
19
14
|
const lines = [];
|
|
15
|
+
const analysis = result.analysis;
|
|
16
|
+
const filesLikelyTouched = analysis.filesLikelyTouched ?? [];
|
|
17
|
+
const filesToCreate = analysis.filesToCreate ?? [];
|
|
18
|
+
const dirsToCreate = analysis.dirsToCreate ?? [];
|
|
19
|
+
const assumptions = analysis.assumptions ?? [];
|
|
20
|
+
const risks = analysis.risks ?? [];
|
|
21
|
+
const docdexNotes = analysis.docdexNotes ?? [];
|
|
20
22
|
lines.push("# Gateway Handoff");
|
|
21
23
|
lines.push("");
|
|
22
24
|
lines.push(`Job: ${result.job}`);
|
|
23
25
|
lines.push(`Gateway agent: ${result.gatewayAgent.slug}`);
|
|
24
26
|
lines.push(`Chosen agent: ${result.chosenAgent.agentSlug}`);
|
|
25
27
|
lines.push("");
|
|
26
|
-
if (
|
|
28
|
+
if (analysis.reasoningSummary?.trim()) {
|
|
27
29
|
lines.push("## Reasoning Summary");
|
|
28
|
-
lines.push(
|
|
30
|
+
lines.push(analysis.reasoningSummary.trim());
|
|
31
|
+
lines.push("");
|
|
32
|
+
}
|
|
33
|
+
if (result.tasks?.length) {
|
|
34
|
+
lines.push("## Task Context");
|
|
35
|
+
result.tasks.forEach((task) => {
|
|
36
|
+
lines.push(`- ${task.key}: ${task.title}`);
|
|
37
|
+
if (task.description)
|
|
38
|
+
lines.push(` Description: ${task.description}`);
|
|
39
|
+
if (task.acceptanceCriteria?.length)
|
|
40
|
+
lines.push(` Acceptance: ${task.acceptanceCriteria.join(" | ")}`);
|
|
41
|
+
if (task.dependencies?.length)
|
|
42
|
+
lines.push(` Dependencies: ${task.dependencies.join(", ")}`);
|
|
43
|
+
});
|
|
29
44
|
lines.push("");
|
|
30
45
|
}
|
|
31
46
|
lines.push("## Summary");
|
|
32
|
-
lines.push(
|
|
47
|
+
lines.push(analysis.summary || "(none)");
|
|
33
48
|
lines.push("");
|
|
34
49
|
lines.push("## Current State");
|
|
35
|
-
lines.push(
|
|
50
|
+
lines.push(analysis.currentState || "(none)");
|
|
36
51
|
lines.push("");
|
|
37
52
|
lines.push("## Todo");
|
|
38
|
-
lines.push(
|
|
53
|
+
lines.push(analysis.todo || "(none)");
|
|
39
54
|
lines.push("");
|
|
40
55
|
lines.push("## Understanding");
|
|
41
|
-
lines.push(
|
|
56
|
+
lines.push(analysis.understanding || "(none)");
|
|
42
57
|
lines.push("");
|
|
43
58
|
lines.push("## Plan");
|
|
44
|
-
if (
|
|
45
|
-
|
|
59
|
+
if (analysis.plan.length) {
|
|
60
|
+
analysis.plan.forEach((step, idx) => lines.push(`${idx + 1}. ${step}`));
|
|
46
61
|
}
|
|
47
62
|
else {
|
|
48
63
|
lines.push("(none)");
|
|
49
64
|
}
|
|
50
65
|
lines.push("");
|
|
51
66
|
lines.push("## Files Likely Touched");
|
|
52
|
-
if (
|
|
53
|
-
|
|
67
|
+
if (filesLikelyTouched.length) {
|
|
68
|
+
filesLikelyTouched.forEach((file) => lines.push(`- ${file}`));
|
|
54
69
|
}
|
|
55
70
|
else {
|
|
56
71
|
lines.push("(none)");
|
|
57
72
|
}
|
|
58
73
|
lines.push("");
|
|
59
74
|
lines.push("## Files To Create");
|
|
60
|
-
if (
|
|
61
|
-
|
|
75
|
+
if (filesToCreate.length) {
|
|
76
|
+
filesToCreate.forEach((file) => lines.push(`- ${file}`));
|
|
62
77
|
}
|
|
63
78
|
else {
|
|
64
79
|
lines.push("(none)");
|
|
65
80
|
}
|
|
66
|
-
|
|
81
|
+
lines.push("");
|
|
82
|
+
lines.push("## Dirs To Create");
|
|
83
|
+
if (dirsToCreate.length) {
|
|
84
|
+
dirsToCreate.forEach((dir) => lines.push(`- ${dir}`));
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
lines.push("(none)");
|
|
88
|
+
}
|
|
89
|
+
if (assumptions.length) {
|
|
67
90
|
lines.push("");
|
|
68
91
|
lines.push("## Assumptions");
|
|
69
|
-
|
|
92
|
+
assumptions.forEach((item) => lines.push(`- ${item}`));
|
|
70
93
|
}
|
|
71
|
-
if (
|
|
94
|
+
if (risks.length) {
|
|
72
95
|
lines.push("");
|
|
73
96
|
lines.push("## Risks");
|
|
74
|
-
|
|
97
|
+
risks.forEach((item) => lines.push(`- ${item}`));
|
|
75
98
|
}
|
|
76
|
-
if (
|
|
99
|
+
if (docdexNotes.length) {
|
|
77
100
|
lines.push("");
|
|
78
101
|
lines.push("## Docdex Notes");
|
|
79
|
-
|
|
102
|
+
docdexNotes.forEach((item) => lines.push(`- ${item}`));
|
|
103
|
+
}
|
|
104
|
+
if (context?.qaFailureSummary?.trim()) {
|
|
105
|
+
lines.push("");
|
|
106
|
+
lines.push("## QA Failure Summary");
|
|
107
|
+
lines.push(context.qaFailureSummary.trim());
|
|
108
|
+
}
|
|
109
|
+
if (context?.learningSummary?.trim()) {
|
|
110
|
+
lines.push("");
|
|
111
|
+
lines.push("## Revert Learning");
|
|
112
|
+
lines.push(context.learningSummary.trim());
|
|
80
113
|
}
|
|
81
114
|
lines.push("");
|
|
82
115
|
lines.push(buildGatewayHandoffDocdexUsage());
|
|
83
116
|
return lines.join("\n");
|
|
84
117
|
};
|
|
85
118
|
export const writeGatewayHandoffFile = async (workspaceRoot, commandRunId, content, prefix = "gateway") => {
|
|
86
|
-
const handoffDir = path.join(workspaceRoot, "
|
|
119
|
+
const handoffDir = path.join(PathHelper.getWorkspaceDir(workspaceRoot), "handoffs");
|
|
87
120
|
await fs.mkdir(handoffDir, { recursive: true });
|
|
88
121
|
const handoffPath = path.join(handoffDir, `${prefix}-${commandRunId}.md`);
|
|
89
122
|
await fs.writeFile(handoffPath, content, "utf8");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoutingService.d.ts","sourceRoot":"","sources":["../../../src/services/agents/RoutingService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EAKlB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAyB,MAAM,iCAAiC,CAAC;AAE1F,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"RoutingService.d.ts","sourceRoot":"","sources":["../../../src/services/agents/RoutingService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EAKlB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAyB,MAAM,iCAAiC,CAAC;AAE1F,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAChD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,qBAAa,cAAc;IAEvB,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE;QACZ,UAAU,CAAC,EAAE,gBAAgB,CAAC;QAC9B,YAAY,CAAC,EAAE;YAAE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAAC,eAAe,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;SAAE,CAAC;QACjJ,UAAU,CAAC,EAAE,gBAAgB,CAAC;KAC/B;WAGU,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;IAYxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,OAAO,CAAC,oBAAoB;IAgB5B,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;YAI/B,UAAU;YAiBV,iBAAiB;IAY/B,OAAO,CAAC,gBAAgB;IAIlB,oBAAoB,CAAC,SAAS,EAAE,mBAAmB,GAAG,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;YAc/E,qBAAqB;IAoB7B,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAQ5D,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC;IAyD3G,OAAO,CAAC,mBAAmB;IAgBrB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;CA2OjF"}
|
|
@@ -26,9 +26,9 @@ export class RoutingService {
|
|
|
26
26
|
await this.deps.globalRepo.close();
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
requiredCapabilities(commandName, taskType) {
|
|
29
|
+
requiredCapabilities(commandName, taskType, extraCapabilities = []) {
|
|
30
30
|
const normalized = this.normalizeCommand(commandName);
|
|
31
|
-
const required = [...getCommandRequiredCapabilities(normalized)];
|
|
31
|
+
const required = [...getCommandRequiredCapabilities(normalized), ...extraCapabilities];
|
|
32
32
|
if (taskType) {
|
|
33
33
|
const lower = taskType.toLowerCase();
|
|
34
34
|
if (lower.includes("qa")) {
|
|
@@ -174,13 +174,13 @@ export class RoutingService {
|
|
|
174
174
|
agentOverride: params.overrideAgentSlug,
|
|
175
175
|
taskType: params.taskType,
|
|
176
176
|
projectKey: params.projectKey,
|
|
177
|
-
requiredCapabilities: this.requiredCapabilities(commandName, params.taskType),
|
|
177
|
+
requiredCapabilities: this.requiredCapabilities(commandName, params.taskType, params.requiredCapabilities),
|
|
178
178
|
};
|
|
179
179
|
}
|
|
180
180
|
async resolveAgentForCommand(params) {
|
|
181
181
|
await this.migrateLegacyDefaults(params.workspace);
|
|
182
182
|
const normalizedCommand = this.normalizeCommand(params.commandName);
|
|
183
|
-
const requiredCaps = this.requiredCapabilities(normalizedCommand, params.taskType);
|
|
183
|
+
const requiredCaps = this.requiredCapabilities(normalizedCommand, params.taskType, params.requiredCapabilities);
|
|
184
184
|
const fillHealth = async (agentId, current) => {
|
|
185
185
|
if (current && current.status)
|
|
186
186
|
return current;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WorkspaceResolution } from "../../workspace/WorkspaceManager.js";
|
|
2
|
+
type BacklogLane = "implementation" | "review" | "qa" | "done";
|
|
2
3
|
export interface BacklogTotals {
|
|
3
4
|
implementation: {
|
|
4
5
|
tasks: number;
|
|
@@ -17,6 +18,25 @@ export interface BacklogTotals {
|
|
|
17
18
|
story_points: number;
|
|
18
19
|
};
|
|
19
20
|
}
|
|
21
|
+
export interface BacklogOrderingMeta {
|
|
22
|
+
requested: boolean;
|
|
23
|
+
applied: boolean;
|
|
24
|
+
reason: string;
|
|
25
|
+
}
|
|
26
|
+
export interface BacklogCrossLaneDependency {
|
|
27
|
+
task_key: string;
|
|
28
|
+
depends_on_key: string;
|
|
29
|
+
task_lane: BacklogLane;
|
|
30
|
+
dependency_lane: BacklogLane;
|
|
31
|
+
}
|
|
32
|
+
export interface BacklogCrossLaneMeta {
|
|
33
|
+
count: number;
|
|
34
|
+
dependencies: BacklogCrossLaneDependency[];
|
|
35
|
+
}
|
|
36
|
+
export interface BacklogMeta {
|
|
37
|
+
ordering: BacklogOrderingMeta;
|
|
38
|
+
crossLaneDependencies: BacklogCrossLaneMeta;
|
|
39
|
+
}
|
|
20
40
|
export interface EpicBacklogSummary {
|
|
21
41
|
epic_id: string;
|
|
22
42
|
epic_key: string;
|
|
@@ -73,6 +93,7 @@ export interface BacklogQueryOptions {
|
|
|
73
93
|
export interface BacklogResult {
|
|
74
94
|
summary: BacklogSummary;
|
|
75
95
|
warnings: string[];
|
|
96
|
+
meta: BacklogMeta;
|
|
76
97
|
}
|
|
77
98
|
export declare class BacklogService {
|
|
78
99
|
private workspace;
|
|
@@ -94,5 +115,7 @@ export declare class BacklogService {
|
|
|
94
115
|
private orderTasks;
|
|
95
116
|
private topologicalSort;
|
|
96
117
|
private sortEpics;
|
|
118
|
+
private findCrossLaneDependencies;
|
|
97
119
|
}
|
|
120
|
+
export {};
|
|
98
121
|
//# sourceMappingURL=BacklogService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BacklogService.d.ts","sourceRoot":"","sources":["../../../src/services/backlog/BacklogService.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"BacklogService.d.ts","sourceRoot":"","sources":["../../../src/services/backlog/BacklogService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import { Connection } from "@mcoda/db";
|
|
3
|
-
import { PathHelper } from "@mcoda/shared";
|
|
3
|
+
import { PathHelper, READY_TO_CODE_REVIEW, isReadyToReviewStatus } from "@mcoda/shared";
|
|
4
4
|
import { TaskOrderingService } from "./TaskOrderingService.js";
|
|
5
|
-
const IMPLEMENTATION_STATUSES = new Set(["not_started", "in_progress"
|
|
6
|
-
const REVIEW_STATUSES = new Set(["ready_to_review"]);
|
|
5
|
+
const IMPLEMENTATION_STATUSES = new Set(["not_started", "in_progress"]);
|
|
7
6
|
const QA_STATUSES = new Set(["ready_to_qa"]);
|
|
8
7
|
const DONE_STATUSES = new Set(["completed", "cancelled"]);
|
|
9
8
|
const emptyTotals = () => ({
|
|
@@ -16,7 +15,7 @@ const bucketForStatus = (status) => {
|
|
|
16
15
|
const normalized = status?.toLowerCase() ?? "";
|
|
17
16
|
if (IMPLEMENTATION_STATUSES.has(normalized))
|
|
18
17
|
return "implementation";
|
|
19
|
-
if (
|
|
18
|
+
if (isReadyToReviewStatus(normalized))
|
|
20
19
|
return "review";
|
|
21
20
|
if (QA_STATUSES.has(normalized))
|
|
22
21
|
return "qa";
|
|
@@ -43,7 +42,7 @@ const hasTables = async (db, required) => {
|
|
|
43
42
|
return rows.length === required.length;
|
|
44
43
|
};
|
|
45
44
|
const deriveStoryStatus = (statuses) => {
|
|
46
|
-
const order = ["completed", "cancelled", "ready_to_qa",
|
|
45
|
+
const order = ["completed", "cancelled", "ready_to_qa", READY_TO_CODE_REVIEW, "changes_requested", "in_progress", "not_started"];
|
|
47
46
|
for (const status of order) {
|
|
48
47
|
if (statuses.has(status))
|
|
49
48
|
return status;
|
|
@@ -157,10 +156,20 @@ export class BacklogService {
|
|
|
157
156
|
dependency_keys: dependencies,
|
|
158
157
|
});
|
|
159
158
|
}
|
|
159
|
+
const crossLaneDependencies = this.findCrossLaneDependencies(tasksRows);
|
|
160
|
+
if (crossLaneDependencies.length > 0) {
|
|
161
|
+
this.warnings.push(`Cross-lane dependencies detected (${crossLaneDependencies.length}). Ordering by lane may be misleading.`);
|
|
162
|
+
}
|
|
160
163
|
let orderedTasks;
|
|
164
|
+
const orderingMeta = {
|
|
165
|
+
requested: options.orderByDependencies === true,
|
|
166
|
+
applied: false,
|
|
167
|
+
reason: options.orderByDependencies ? "requested" : "default_order",
|
|
168
|
+
};
|
|
161
169
|
if (options.orderByDependencies) {
|
|
162
170
|
if (!project) {
|
|
163
171
|
this.warnings.push("Dependency ordering requires a project scope; using default ordering.");
|
|
172
|
+
orderingMeta.reason = "missing_project_scope";
|
|
164
173
|
orderedTasks = this.orderTasks(tasksRows, options.verbose === true);
|
|
165
174
|
}
|
|
166
175
|
else {
|
|
@@ -172,8 +181,9 @@ export class BacklogService {
|
|
|
172
181
|
storyKey: story?.key,
|
|
173
182
|
assignee: options.assignee,
|
|
174
183
|
statusFilter: options.statuses,
|
|
175
|
-
includeBlocked: true,
|
|
176
184
|
});
|
|
185
|
+
orderingMeta.applied = true;
|
|
186
|
+
orderingMeta.reason = "dependency_graph";
|
|
177
187
|
const orderMap = new Map(ordering.ordered.map((t, idx) => [t.taskId, idx]));
|
|
178
188
|
orderedTasks = tasksRows
|
|
179
189
|
.slice()
|
|
@@ -187,9 +197,15 @@ export class BacklogService {
|
|
|
187
197
|
this.warnings.push(...ordering.warnings);
|
|
188
198
|
}
|
|
189
199
|
catch (error) {
|
|
200
|
+
const prefix = "Dependency ordering failed; falling back to heuristic ordering.";
|
|
190
201
|
if (options.verbose) {
|
|
191
|
-
this.warnings.push(
|
|
202
|
+
this.warnings.push(`${prefix} ${error.message}`);
|
|
192
203
|
}
|
|
204
|
+
else {
|
|
205
|
+
this.warnings.push(prefix);
|
|
206
|
+
}
|
|
207
|
+
orderingMeta.applied = false;
|
|
208
|
+
orderingMeta.reason = "heuristic_fallback";
|
|
193
209
|
orderedTasks = this.orderTasks(tasksRows, options.verbose === true);
|
|
194
210
|
}
|
|
195
211
|
finally {
|
|
@@ -198,6 +214,7 @@ export class BacklogService {
|
|
|
198
214
|
}
|
|
199
215
|
}
|
|
200
216
|
else {
|
|
217
|
+
orderingMeta.reason = "default_order";
|
|
201
218
|
orderedTasks = this.defaultOrder(tasksRows);
|
|
202
219
|
}
|
|
203
220
|
const epicSummaries = Array.from(epics.values()).map((e) => {
|
|
@@ -235,6 +252,13 @@ export class BacklogService {
|
|
|
235
252
|
tasks: orderedTasks,
|
|
236
253
|
},
|
|
237
254
|
warnings: this.warnings,
|
|
255
|
+
meta: {
|
|
256
|
+
ordering: orderingMeta,
|
|
257
|
+
crossLaneDependencies: {
|
|
258
|
+
count: crossLaneDependencies.length,
|
|
259
|
+
dependencies: crossLaneDependencies,
|
|
260
|
+
},
|
|
261
|
+
},
|
|
238
262
|
};
|
|
239
263
|
}
|
|
240
264
|
async getProject(projectKey) {
|
|
@@ -450,4 +474,35 @@ export class BacklogService {
|
|
|
450
474
|
}),
|
|
451
475
|
}));
|
|
452
476
|
}
|
|
477
|
+
findCrossLaneDependencies(tasks) {
|
|
478
|
+
if (tasks.length === 0)
|
|
479
|
+
return [];
|
|
480
|
+
const laneByKey = new Map();
|
|
481
|
+
for (const task of tasks) {
|
|
482
|
+
laneByKey.set(task.task_key, bucketForStatus(task.status));
|
|
483
|
+
}
|
|
484
|
+
const results = [];
|
|
485
|
+
for (const task of tasks) {
|
|
486
|
+
const taskLane = laneByKey.get(task.task_key);
|
|
487
|
+
if (!taskLane || task.dependency_keys.length === 0)
|
|
488
|
+
continue;
|
|
489
|
+
for (const depKey of task.dependency_keys) {
|
|
490
|
+
const dependencyLane = laneByKey.get(depKey);
|
|
491
|
+
if (!dependencyLane || dependencyLane === taskLane)
|
|
492
|
+
continue;
|
|
493
|
+
results.push({
|
|
494
|
+
task_key: task.task_key,
|
|
495
|
+
depends_on_key: depKey,
|
|
496
|
+
task_lane: taskLane,
|
|
497
|
+
dependency_lane: dependencyLane,
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return results.sort((a, b) => {
|
|
502
|
+
const taskCompare = a.task_key.localeCompare(b.task_key);
|
|
503
|
+
if (taskCompare !== 0)
|
|
504
|
+
return taskCompare;
|
|
505
|
+
return a.depends_on_key.localeCompare(b.depends_on_key);
|
|
506
|
+
});
|
|
507
|
+
}
|
|
453
508
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type TaskStage = "foundation" | "backend" | "frontend" | "other";
|
|
2
|
+
export interface TaskClassification {
|
|
3
|
+
stage: TaskStage;
|
|
4
|
+
foundation: boolean;
|
|
5
|
+
reasons: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare const classifyTask: (input: {
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
type?: string;
|
|
11
|
+
}) => TaskClassification;
|
|
12
|
+
//# sourceMappingURL=TaskOrderingHeuristics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskOrderingHeuristics.d.ts","sourceRoot":"","sources":["../../../src/services/backlog/TaskOrderingHeuristics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA+BD,eAAO,MAAM,YAAY,GAAI,OAAO;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,kBAgC7F,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const FOUNDATION_KEYWORDS = new Set([
|
|
2
|
+
"initialize",
|
|
3
|
+
"scaffold",
|
|
4
|
+
"setup",
|
|
5
|
+
"install",
|
|
6
|
+
"configure",
|
|
7
|
+
"express",
|
|
8
|
+
"server",
|
|
9
|
+
"openapi",
|
|
10
|
+
"spec",
|
|
11
|
+
"sds",
|
|
12
|
+
]);
|
|
13
|
+
const BACKEND_KEYWORDS = new Set(["api", "endpoint", "server", "express", "db", "database", "storage", "persistence"]);
|
|
14
|
+
const FRONTEND_KEYWORDS = new Set(["ui", "html", "css", "dom", "render", "style", "frontend"]);
|
|
15
|
+
const tokenize = (value) => {
|
|
16
|
+
if (!value)
|
|
17
|
+
return [];
|
|
18
|
+
return value
|
|
19
|
+
.toLowerCase()
|
|
20
|
+
.split(/[^a-z0-9]+/g)
|
|
21
|
+
.map((token) => token.trim())
|
|
22
|
+
.filter(Boolean);
|
|
23
|
+
};
|
|
24
|
+
const collectHits = (tokens, keywords) => tokens.filter((token) => keywords.has(token));
|
|
25
|
+
export const classifyTask = (input) => {
|
|
26
|
+
const titleTokens = tokenize(input.title);
|
|
27
|
+
const descriptionTokens = tokenize(input.description);
|
|
28
|
+
const tokens = [...titleTokens, ...descriptionTokens];
|
|
29
|
+
const backendHits = collectHits(tokens, BACKEND_KEYWORDS);
|
|
30
|
+
const frontendHits = collectHits(tokens, FRONTEND_KEYWORDS);
|
|
31
|
+
const foundationHits = collectHits(titleTokens, FOUNDATION_KEYWORDS);
|
|
32
|
+
const type = (input.type ?? "").toLowerCase();
|
|
33
|
+
const isChore = type === "chore";
|
|
34
|
+
const foundation = isChore || foundationHits.length > 0;
|
|
35
|
+
let stage = "other";
|
|
36
|
+
if (backendHits.length > 0) {
|
|
37
|
+
stage = "backend";
|
|
38
|
+
}
|
|
39
|
+
else if (frontendHits.length > 0) {
|
|
40
|
+
stage = "frontend";
|
|
41
|
+
}
|
|
42
|
+
else if (foundation) {
|
|
43
|
+
stage = "foundation";
|
|
44
|
+
}
|
|
45
|
+
const reasons = [
|
|
46
|
+
...backendHits.map((hit) => `backend:${hit}`),
|
|
47
|
+
...frontendHits.map((hit) => `frontend:${hit}`),
|
|
48
|
+
...foundationHits.map((hit) => `foundation:${hit}`),
|
|
49
|
+
isChore ? "type:chore" : undefined,
|
|
50
|
+
].filter((value) => Boolean(value));
|
|
51
|
+
return {
|
|
52
|
+
stage,
|
|
53
|
+
foundation,
|
|
54
|
+
reasons,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WorkspaceResolution } from "../../workspace/WorkspaceManager.js";
|
|
2
|
+
import { TaskStage } from "./TaskOrderingHeuristics.js";
|
|
2
3
|
interface ProjectRow {
|
|
3
4
|
id: string;
|
|
4
5
|
key: string;
|
|
@@ -26,8 +27,6 @@ export interface TaskOrderItem {
|
|
|
26
27
|
storyId: string;
|
|
27
28
|
storyKey: string;
|
|
28
29
|
storyTitle: string;
|
|
29
|
-
blocked: boolean;
|
|
30
|
-
blockedBy: string[];
|
|
31
30
|
dependencyKeys: string[];
|
|
32
31
|
dependencyImpact: DependencyImpact;
|
|
33
32
|
cycleDetected?: boolean;
|
|
@@ -37,22 +36,28 @@ export interface TaskOrderingResult {
|
|
|
37
36
|
project: ProjectRow;
|
|
38
37
|
epic?: EpicRow;
|
|
39
38
|
ordered: TaskOrderItem[];
|
|
40
|
-
blocked: TaskOrderItem[];
|
|
41
39
|
warnings: string[];
|
|
42
40
|
jobId?: string;
|
|
43
41
|
commandRunId?: string;
|
|
44
42
|
}
|
|
43
|
+
export interface InferredDependency {
|
|
44
|
+
taskKey: string;
|
|
45
|
+
dependsOnKeys: string[];
|
|
46
|
+
}
|
|
45
47
|
export interface TaskOrderingRequest {
|
|
46
48
|
projectKey: string;
|
|
47
49
|
epicKey?: string;
|
|
48
50
|
storyKey?: string;
|
|
49
51
|
assignee?: string;
|
|
50
52
|
statusFilter?: string[];
|
|
51
|
-
includeBlocked?: boolean;
|
|
52
53
|
agentName?: string;
|
|
53
54
|
agentStream?: boolean;
|
|
54
55
|
rateAgents?: boolean;
|
|
56
|
+
stageOrder?: TaskStage[];
|
|
57
|
+
injectFoundationDeps?: boolean;
|
|
58
|
+
inferDependencies?: boolean;
|
|
55
59
|
}
|
|
60
|
+
export declare const parseDependencyInferenceOutput: (output: string, validTaskKeys: Set<string>, warnings: string[]) => InferredDependency[];
|
|
56
61
|
export declare class TaskOrderingService {
|
|
57
62
|
private workspace;
|
|
58
63
|
private db;
|
|
@@ -74,13 +79,20 @@ export declare class TaskOrderingService {
|
|
|
74
79
|
private getStory;
|
|
75
80
|
private fetchTasks;
|
|
76
81
|
private fetchDependencies;
|
|
82
|
+
private loadMissingContext;
|
|
77
83
|
private dependencyImpactMap;
|
|
84
|
+
private resolveClassification;
|
|
85
|
+
private buildDependencyGraph;
|
|
86
|
+
private hasDependencyPath;
|
|
87
|
+
private injectFoundationDependencies;
|
|
88
|
+
private applyInferredDependencies;
|
|
78
89
|
private compareTasks;
|
|
79
90
|
private topologicalSort;
|
|
80
91
|
private buildNodes;
|
|
81
92
|
private resolveAgent;
|
|
82
93
|
private invokeAgent;
|
|
83
94
|
private applyAgentRanking;
|
|
95
|
+
private inferDependenciesWithAgent;
|
|
84
96
|
private persistPriorities;
|
|
85
97
|
private mapResult;
|
|
86
98
|
orderTasks(request: TaskOrderingRequest): Promise<TaskOrderingResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskOrderingService.d.ts","sourceRoot":"","sources":["../../../src/services/backlog/TaskOrderingService.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"TaskOrderingService.d.ts","sourceRoot":"","sources":["../../../src/services/backlog/TaskOrderingService.ts"],"names":[],"mappings":"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"}
|