@mcoda/core 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/QaTasksApi.d.ts.map +1 -1
- package/dist/api/QaTasksApi.js +3 -0
- package/dist/prompts/PdrPrompts.d.ts.map +1 -1
- package/dist/prompts/PdrPrompts.js +22 -8
- package/dist/prompts/SdsPrompts.d.ts.map +1 -1
- package/dist/prompts/SdsPrompts.js +53 -34
- package/dist/services/backlog/BacklogService.d.ts.map +1 -1
- package/dist/services/backlog/BacklogService.js +3 -0
- package/dist/services/backlog/TaskOrderingService.d.ts +9 -0
- package/dist/services/backlog/TaskOrderingService.d.ts.map +1 -1
- package/dist/services/backlog/TaskOrderingService.js +251 -35
- package/dist/services/docs/DocsService.d.ts.map +1 -1
- package/dist/services/docs/DocsService.js +487 -71
- package/dist/services/docs/review/gates/PdrFolderTreeGate.d.ts +7 -0
- package/dist/services/docs/review/gates/PdrFolderTreeGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/PdrFolderTreeGate.js +151 -0
- package/dist/services/docs/review/gates/PdrNoUnresolvedItemsGate.d.ts +7 -0
- package/dist/services/docs/review/gates/PdrNoUnresolvedItemsGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/PdrNoUnresolvedItemsGate.js +109 -0
- package/dist/services/docs/review/gates/PdrTechStackRationaleGate.d.ts +7 -0
- package/dist/services/docs/review/gates/PdrTechStackRationaleGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/PdrTechStackRationaleGate.js +128 -0
- package/dist/services/docs/review/gates/SdsFolderTreeGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SdsFolderTreeGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SdsFolderTreeGate.js +153 -0
- package/dist/services/docs/review/gates/SdsNoUnresolvedItemsGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SdsNoUnresolvedItemsGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SdsNoUnresolvedItemsGate.js +109 -0
- package/dist/services/docs/review/gates/SdsTechStackRationaleGate.d.ts +7 -0
- package/dist/services/docs/review/gates/SdsTechStackRationaleGate.d.ts.map +1 -0
- package/dist/services/docs/review/gates/SdsTechStackRationaleGate.js +128 -0
- package/dist/services/execution/QaTasksService.d.ts +6 -0
- package/dist/services/execution/QaTasksService.d.ts.map +1 -1
- package/dist/services/execution/QaTasksService.js +278 -95
- package/dist/services/execution/TaskSelectionService.d.ts +3 -0
- package/dist/services/execution/TaskSelectionService.d.ts.map +1 -1
- package/dist/services/execution/TaskSelectionService.js +33 -0
- package/dist/services/execution/WorkOnTasksService.d.ts +5 -1
- package/dist/services/execution/WorkOnTasksService.d.ts.map +1 -1
- package/dist/services/execution/WorkOnTasksService.js +178 -34
- package/dist/services/openapi/OpenApiService.d.ts.map +1 -1
- package/dist/services/openapi/OpenApiService.js +43 -4
- package/dist/services/planning/CreateTasksService.d.ts +12 -0
- package/dist/services/planning/CreateTasksService.d.ts.map +1 -1
- package/dist/services/planning/CreateTasksService.js +585 -48
- package/dist/services/planning/RefineTasksService.d.ts +1 -0
- package/dist/services/planning/RefineTasksService.d.ts.map +1 -1
- package/dist/services/planning/RefineTasksService.js +88 -2
- package/dist/services/review/CodeReviewService.d.ts +6 -0
- package/dist/services/review/CodeReviewService.d.ts.map +1 -1
- package/dist/services/review/CodeReviewService.js +260 -41
- package/dist/services/shared/ProjectGuidance.d.ts +18 -2
- package/dist/services/shared/ProjectGuidance.d.ts.map +1 -1
- package/dist/services/shared/ProjectGuidance.js +535 -34
- package/package.json +6 -6
|
@@ -26,6 +26,7 @@ export interface WorkOnTasksRequest extends TaskSelectionFilters {
|
|
|
26
26
|
allowFileOverwrite?: boolean;
|
|
27
27
|
missingTestsPolicy?: MissingTestsPolicy;
|
|
28
28
|
allowMissingTests?: boolean;
|
|
29
|
+
executionContextPolicy?: ExecutionContextPolicy;
|
|
29
30
|
}
|
|
30
31
|
export interface TaskExecutionResult {
|
|
31
32
|
taskKey: string;
|
|
@@ -40,7 +41,8 @@ export interface WorkOnTasksResult {
|
|
|
40
41
|
results: TaskExecutionResult[];
|
|
41
42
|
warnings: string[];
|
|
42
43
|
}
|
|
43
|
-
export type MissingTestsPolicy = "block_job" | "skip_task" | "fail_task";
|
|
44
|
+
export type MissingTestsPolicy = "block_job" | "skip_task" | "fail_task" | "continue_task";
|
|
45
|
+
export type ExecutionContextPolicy = "best_effort" | "require_any" | "require_sds_or_openapi";
|
|
44
46
|
export declare class WorkOnTasksService {
|
|
45
47
|
private workspace;
|
|
46
48
|
private deps;
|
|
@@ -79,6 +81,8 @@ export declare class WorkOnTasksService {
|
|
|
79
81
|
private logTask;
|
|
80
82
|
private recordTokenUsage;
|
|
81
83
|
private updateTaskPhase;
|
|
84
|
+
private enforceExecutionContextPolicy;
|
|
85
|
+
private resolveExecutionPlanningContext;
|
|
82
86
|
private gatherDocContext;
|
|
83
87
|
private parseCommentBody;
|
|
84
88
|
private buildCommentBacklog;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkOnTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/execution/WorkOnTasksService.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAgD,MAAM,eAAe,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAuB,MAAM,WAAW,CAAC;AAEvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAiB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC1G,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAsFrE,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,SAAS,EAAE,mBAAmB,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iBAAiB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"WorkOnTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/execution/WorkOnTasksService.ts"],"names":[],"mappings":"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"}
|
|
@@ -833,12 +833,31 @@ const splitFileBlocksByExistence = (fileBlocks, cwd) => {
|
|
|
833
833
|
}
|
|
834
834
|
return { existing, remaining };
|
|
835
835
|
};
|
|
836
|
-
const DEFAULT_MISSING_TESTS_POLICY = "
|
|
836
|
+
const DEFAULT_MISSING_TESTS_POLICY = "continue_task";
|
|
837
|
+
const DEFAULT_EXECUTION_CONTEXT_POLICY = "best_effort";
|
|
837
838
|
const normalizeMissingTestsPolicy = (value) => {
|
|
838
839
|
if (typeof value !== "string")
|
|
839
840
|
return undefined;
|
|
840
841
|
const normalized = value.trim().toLowerCase().replace(/-/g, "_");
|
|
841
|
-
if (normalized === "block_job" ||
|
|
842
|
+
if (normalized === "block_job" ||
|
|
843
|
+
normalized === "skip_task" ||
|
|
844
|
+
normalized === "fail_task" ||
|
|
845
|
+
normalized === "continue_task" ||
|
|
846
|
+
normalized === "continue" ||
|
|
847
|
+
normalized === "allow" ||
|
|
848
|
+
normalized === "warn_task") {
|
|
849
|
+
if (normalized === "continue" || normalized === "allow" || normalized === "warn_task") {
|
|
850
|
+
return "continue_task";
|
|
851
|
+
}
|
|
852
|
+
return normalized;
|
|
853
|
+
}
|
|
854
|
+
return undefined;
|
|
855
|
+
};
|
|
856
|
+
const normalizeExecutionContextPolicy = (value) => {
|
|
857
|
+
if (typeof value !== "string")
|
|
858
|
+
return undefined;
|
|
859
|
+
const normalized = value.trim().toLowerCase();
|
|
860
|
+
if (normalized === "best_effort" || normalized === "require_any" || normalized === "require_sds_or_openapi") {
|
|
842
861
|
return normalized;
|
|
843
862
|
}
|
|
844
863
|
return undefined;
|
|
@@ -1412,6 +1431,15 @@ const allowsTestsOnlyCompletion = (task, metadata, allowedFiles) => {
|
|
|
1412
1431
|
return false;
|
|
1413
1432
|
};
|
|
1414
1433
|
const hasProductTouchedFiles = (touchedFiles) => touchedFiles.some((file) => !isTestLikePath(file) && !isDocumentationPath(file));
|
|
1434
|
+
const classifyExecutionContextKind = (doc) => {
|
|
1435
|
+
const type = (doc.docType ?? "").toLowerCase();
|
|
1436
|
+
const label = `${doc.path ?? ""} ${doc.title ?? ""}`.toLowerCase();
|
|
1437
|
+
if (type.includes("sds") || /\bsds\b/.test(label))
|
|
1438
|
+
return "sds";
|
|
1439
|
+
if (type.includes("openapi") || type.includes("swagger") || /(openapi|swagger)/.test(label))
|
|
1440
|
+
return "openapi";
|
|
1441
|
+
return "fallback";
|
|
1442
|
+
};
|
|
1415
1443
|
const buildDocContextQuery = (task, allowedFiles) => {
|
|
1416
1444
|
const seeds = [
|
|
1417
1445
|
task.key,
|
|
@@ -2260,6 +2288,61 @@ export class WorkOnTasksService {
|
|
|
2260
2288
|
await this.logTask(taskRunId, `${phase}:${status}`, phase, payload);
|
|
2261
2289
|
await this.checkpoint(jobId, `task:${taskKey}:${phase}:${status}`, payload);
|
|
2262
2290
|
}
|
|
2291
|
+
enforceExecutionContextPolicy(policy, context) {
|
|
2292
|
+
if (policy === "best_effort")
|
|
2293
|
+
return;
|
|
2294
|
+
if (policy === "require_any") {
|
|
2295
|
+
if (!context) {
|
|
2296
|
+
throw new Error("Execution context is required but no planning documents were resolved (policy=require_any).");
|
|
2297
|
+
}
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
2300
|
+
if (!context) {
|
|
2301
|
+
throw new Error("Execution context requires SDS/OpenAPI sources, but none were resolved (policy=require_sds_or_openapi).");
|
|
2302
|
+
}
|
|
2303
|
+
if (context.kind !== "sds" && context.kind !== "openapi") {
|
|
2304
|
+
throw new Error(`Execution context policy require_sds_or_openapi rejected source '${context.source}' (kind=${context.kind}).`);
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
async resolveExecutionPlanningContext(projectKey, warnings) {
|
|
2308
|
+
if (!projectKey)
|
|
2309
|
+
return undefined;
|
|
2310
|
+
const pickFirst = async (filter) => {
|
|
2311
|
+
const docs = await this.deps.docdex.search(filter);
|
|
2312
|
+
return docs[0];
|
|
2313
|
+
};
|
|
2314
|
+
try {
|
|
2315
|
+
const sdsDoc = await pickFirst({ projectKey, docType: "SDS", profile: "workspace-code" });
|
|
2316
|
+
if (sdsDoc) {
|
|
2317
|
+
return {
|
|
2318
|
+
source: sdsDoc.id ?? sdsDoc.path ?? sdsDoc.title ?? "sds",
|
|
2319
|
+
kind: classifyExecutionContextKind(sdsDoc),
|
|
2320
|
+
};
|
|
2321
|
+
}
|
|
2322
|
+
const openapiDoc = await pickFirst({ projectKey, docType: "OPENAPI", profile: "workspace-code" });
|
|
2323
|
+
if (openapiDoc) {
|
|
2324
|
+
return {
|
|
2325
|
+
source: openapiDoc.id ?? openapiDoc.path ?? openapiDoc.title ?? "openapi",
|
|
2326
|
+
kind: classifyExecutionContextKind(openapiDoc),
|
|
2327
|
+
};
|
|
2328
|
+
}
|
|
2329
|
+
const fallbackDoc = await pickFirst({
|
|
2330
|
+
projectKey,
|
|
2331
|
+
profile: "workspace-code",
|
|
2332
|
+
query: "sds requirements architecture openapi swagger",
|
|
2333
|
+
});
|
|
2334
|
+
if (!fallbackDoc)
|
|
2335
|
+
return undefined;
|
|
2336
|
+
return {
|
|
2337
|
+
source: fallbackDoc.id ?? fallbackDoc.path ?? fallbackDoc.title ?? "workspace-code",
|
|
2338
|
+
kind: classifyExecutionContextKind(fallbackDoc),
|
|
2339
|
+
};
|
|
2340
|
+
}
|
|
2341
|
+
catch (error) {
|
|
2342
|
+
warnings.push(`Execution context preflight failed to query docdex: ${error.message}`);
|
|
2343
|
+
return undefined;
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2263
2346
|
async gatherDocContext(task, projectKey, docLinks = [], allowedFiles = []) {
|
|
2264
2347
|
const warnings = [];
|
|
2265
2348
|
const parts = [];
|
|
@@ -2286,9 +2369,36 @@ export class WorkOnTasksService {
|
|
|
2286
2369
|
}
|
|
2287
2370
|
}
|
|
2288
2371
|
try {
|
|
2289
|
-
|
|
2372
|
+
const docs = [];
|
|
2373
|
+
const seen = new Set();
|
|
2374
|
+
const appendDocs = async (filter) => {
|
|
2375
|
+
const found = await this.deps.docdex.search(filter);
|
|
2376
|
+
for (const doc of found) {
|
|
2377
|
+
const key = String(doc.id ?? doc.path ?? doc.title ?? "");
|
|
2378
|
+
if (!key)
|
|
2379
|
+
continue;
|
|
2380
|
+
if (seen.has(key))
|
|
2381
|
+
continue;
|
|
2382
|
+
seen.add(key);
|
|
2383
|
+
docs.push(doc);
|
|
2384
|
+
}
|
|
2385
|
+
};
|
|
2386
|
+
const sdsFilter = docQuery
|
|
2387
|
+
? { projectKey, docType: "SDS", profile: "workspace-code", query: docQuery }
|
|
2388
|
+
: { projectKey, docType: "SDS", profile: "workspace-code" };
|
|
2389
|
+
const openapiFilter = docQuery
|
|
2390
|
+
? { projectKey, docType: "OPENAPI", profile: "workspace-code", query: docQuery }
|
|
2391
|
+
: { projectKey, docType: "OPENAPI", profile: "workspace-code" };
|
|
2392
|
+
await appendDocs(sdsFilter);
|
|
2393
|
+
await appendDocs(openapiFilter);
|
|
2394
|
+
if (!docs.length) {
|
|
2395
|
+
const genericFilter = docQuery
|
|
2396
|
+
? { projectKey, profile: "workspace-code", query: docQuery }
|
|
2397
|
+
: { projectKey, profile: "workspace-code" };
|
|
2398
|
+
await appendDocs(genericFilter);
|
|
2399
|
+
}
|
|
2290
2400
|
if (!docs.length && docQuery) {
|
|
2291
|
-
|
|
2401
|
+
await appendDocs({ projectKey, profile: "workspace-code" });
|
|
2292
2402
|
}
|
|
2293
2403
|
const filteredDocs = docs.filter((doc) => !isDocContextExcluded(doc.path ?? doc.title ?? doc.id, false) &&
|
|
2294
2404
|
(includeTestDocs || !isTestLikePath(doc.path ?? doc.title ?? doc.id)));
|
|
@@ -3388,13 +3498,20 @@ export class WorkOnTasksService {
|
|
|
3388
3498
|
const enforceCommentBacklog = isCommentBacklogEnforced();
|
|
3389
3499
|
const commentBacklogMaxFails = resolveCommentBacklogMaxFails();
|
|
3390
3500
|
const requestedMissingTestsPolicy = normalizeMissingTestsPolicy(request.missingTestsPolicy);
|
|
3391
|
-
const missingTestsPolicy = requestedMissingTestsPolicy ??
|
|
3501
|
+
const missingTestsPolicy = requestedMissingTestsPolicy ??
|
|
3502
|
+
(request.allowMissingTests === true
|
|
3503
|
+
? "continue_task"
|
|
3504
|
+
: request.allowMissingTests === false
|
|
3505
|
+
? "block_job"
|
|
3506
|
+
: DEFAULT_MISSING_TESTS_POLICY);
|
|
3507
|
+
const requestedExecutionContextPolicy = normalizeExecutionContextPolicy(request.executionContextPolicy);
|
|
3508
|
+
const executionContextPolicy = requestedExecutionContextPolicy ?? DEFAULT_EXECUTION_CONTEXT_POLICY;
|
|
3392
3509
|
const baseCodaliEnvOverrides = codaliRequired ? buildCodaliEnvOverrides() : {};
|
|
3393
3510
|
const configuredBaseBranch = this.workspace.config?.branch;
|
|
3394
3511
|
const requestedBaseBranch = request.baseBranch;
|
|
3395
3512
|
const resolvedBaseBranch = (requestedBaseBranch ?? configuredBaseBranch ?? DEFAULT_BASE_BRANCH).trim();
|
|
3396
3513
|
const normalizedBaseBranch = resolvedBaseBranch === "dev" ? DEFAULT_BASE_BRANCH : resolvedBaseBranch;
|
|
3397
|
-
const baseBranch = DEFAULT_BASE_BRANCH;
|
|
3514
|
+
const baseBranch = normalizedBaseBranch || DEFAULT_BASE_BRANCH;
|
|
3398
3515
|
const configuredAutoMerge = this.workspace.config?.autoMerge;
|
|
3399
3516
|
const configuredAutoPush = this.workspace.config?.autoPush;
|
|
3400
3517
|
const autoMerge = request.autoMerge ?? configuredAutoMerge ?? true;
|
|
@@ -3405,6 +3522,9 @@ export class WorkOnTasksService {
|
|
|
3405
3522
|
if (request.missingTestsPolicy && !requestedMissingTestsPolicy) {
|
|
3406
3523
|
runnerWarnings.push(`Unknown missing-tests policy "${String(request.missingTestsPolicy)}"; using "${missingTestsPolicy}".`);
|
|
3407
3524
|
}
|
|
3525
|
+
if (request.executionContextPolicy && !requestedExecutionContextPolicy) {
|
|
3526
|
+
runnerWarnings.push(`Unknown execution-context policy "${String(request.executionContextPolicy)}"; using "${executionContextPolicy}".`);
|
|
3527
|
+
}
|
|
3408
3528
|
const explicitTaskSelection = Boolean(request.taskKeys?.length);
|
|
3409
3529
|
const ignoreDependencies = request.ignoreDependencies === true || explicitTaskSelection;
|
|
3410
3530
|
const ignoreStatusFilter = explicitTaskSelection || request.ignoreStatusFilter === true;
|
|
@@ -3428,9 +3548,6 @@ export class WorkOnTasksService {
|
|
|
3428
3548
|
if (codaliRequired && isPatchModeEnabled()) {
|
|
3429
3549
|
runnerWarnings.push("work-on-tasks patch mode is ignored when codali is required.");
|
|
3430
3550
|
}
|
|
3431
|
-
if (normalizedBaseBranch && normalizedBaseBranch !== DEFAULT_BASE_BRANCH) {
|
|
3432
|
-
baseBranchWarnings.push(`Base branch ${normalizedBaseBranch} ignored; work-on-tasks always uses ${DEFAULT_BASE_BRANCH}.`);
|
|
3433
|
-
}
|
|
3434
3551
|
const commandRun = await this.deps.jobService.startCommandRun(commandName, request.projectKey, {
|
|
3435
3552
|
taskIds: request.taskKeys,
|
|
3436
3553
|
});
|
|
@@ -3454,6 +3571,7 @@ export class WorkOnTasksService {
|
|
|
3454
3571
|
agentStream,
|
|
3455
3572
|
missingTestsPolicy,
|
|
3456
3573
|
allowMissingTests: request.allowMissingTests ?? false,
|
|
3574
|
+
executionContextPolicy,
|
|
3457
3575
|
},
|
|
3458
3576
|
});
|
|
3459
3577
|
const workspaceRoot = request.workspace.workspaceRoot;
|
|
@@ -3519,6 +3637,29 @@ export class WorkOnTasksService {
|
|
|
3519
3637
|
return message === resolveAbortReason();
|
|
3520
3638
|
};
|
|
3521
3639
|
try {
|
|
3640
|
+
const warnings = [...baseBranchWarnings, ...statusWarnings, ...runnerWarnings];
|
|
3641
|
+
try {
|
|
3642
|
+
const guidance = await ensureProjectGuidance(this.workspace.workspaceRoot, {
|
|
3643
|
+
mcodaDir: this.workspace.mcodaDir,
|
|
3644
|
+
projectKey: request.projectKey,
|
|
3645
|
+
});
|
|
3646
|
+
if (guidance.status !== "existing") {
|
|
3647
|
+
warnings.push(`project_guidance_${guidance.status}: ${guidance.path}`);
|
|
3648
|
+
}
|
|
3649
|
+
for (const warning of guidance.warnings ?? []) {
|
|
3650
|
+
warnings.push(`project_guidance_warning:${warning}`);
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
catch (error) {
|
|
3654
|
+
warnings.push(`project_guidance_bootstrap_failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3655
|
+
}
|
|
3656
|
+
const executionContext = await this.resolveExecutionPlanningContext(request.projectKey, warnings);
|
|
3657
|
+
this.enforceExecutionContextPolicy(executionContextPolicy, executionContext);
|
|
3658
|
+
await this.checkpoint(job.id, "execution_context_preflight", {
|
|
3659
|
+
policy: executionContextPolicy,
|
|
3660
|
+
source: executionContext?.source ?? null,
|
|
3661
|
+
kind: executionContext?.kind ?? null,
|
|
3662
|
+
});
|
|
3522
3663
|
await this.checkoutBaseBranch(baseBranch, { allowDirty: true });
|
|
3523
3664
|
selection = await this.selectionService.selectTasks({
|
|
3524
3665
|
projectKey: request.projectKey,
|
|
@@ -3530,6 +3671,7 @@ export class WorkOnTasksService {
|
|
|
3530
3671
|
includeTypes,
|
|
3531
3672
|
excludeTypes,
|
|
3532
3673
|
ignoreDependencies,
|
|
3674
|
+
missingContextPolicy: request.missingContextPolicy ?? "block",
|
|
3533
3675
|
limit: request.limit,
|
|
3534
3676
|
parallel: request.parallel,
|
|
3535
3677
|
});
|
|
@@ -3544,20 +3686,9 @@ export class WorkOnTasksService {
|
|
|
3544
3686
|
totalItems: selection.ordered.length,
|
|
3545
3687
|
processedItems: 0,
|
|
3546
3688
|
});
|
|
3689
|
+
warnings.push(...selection.warnings);
|
|
3547
3690
|
const results = [];
|
|
3548
3691
|
const taskSummaries = new Map();
|
|
3549
|
-
const warnings = [...baseBranchWarnings, ...statusWarnings, ...runnerWarnings, ...selection.warnings];
|
|
3550
|
-
try {
|
|
3551
|
-
const guidance = await ensureProjectGuidance(this.workspace.workspaceRoot, {
|
|
3552
|
-
mcodaDir: this.workspace.mcodaDir,
|
|
3553
|
-
});
|
|
3554
|
-
if (guidance.status !== "existing") {
|
|
3555
|
-
warnings.push(`project_guidance_${guidance.status}: ${guidance.path}`);
|
|
3556
|
-
}
|
|
3557
|
-
}
|
|
3558
|
-
catch (error) {
|
|
3559
|
-
warnings.push(`project_guidance_bootstrap_failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3560
|
-
}
|
|
3561
3692
|
if (missingTestsPolicy === "block_job") {
|
|
3562
3693
|
const missingHarnessTasks = await this.findMissingTestHarnessTasks(selection.ordered);
|
|
3563
3694
|
if (missingHarnessTasks.length > 0) {
|
|
@@ -4095,18 +4226,26 @@ export class WorkOnTasksService {
|
|
|
4095
4226
|
await emitTaskEndOnce();
|
|
4096
4227
|
throw new Error(`missing_test_harness: ${task.task.key} requires tests but no runnable test commands were found`);
|
|
4097
4228
|
}
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
}
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4229
|
+
if (missingTestsPolicy === "continue_task") {
|
|
4230
|
+
const warning = `Task ${task.task.key}: tests required but no runnable test harness was found; proceeding without automated tests.` +
|
|
4231
|
+
" Add metadata.tests/testCommands or tests/all.js.";
|
|
4232
|
+
warnings.push(warning);
|
|
4233
|
+
await this.logTask(taskRun.id, "Tests required but no runnable test commands were found; continuing without automated tests due to missing-tests policy.", "tests", { testRequirements, missingTestsPolicy });
|
|
4234
|
+
}
|
|
4235
|
+
else {
|
|
4236
|
+
await this.logTask(taskRun.id, "Tests required but no runnable test commands were found; failing task.", "tests", { testRequirements, missingTestsPolicy });
|
|
4237
|
+
await this.stateService.markFailed(task.task, "tests_not_configured", statusContext);
|
|
4238
|
+
await this.deps.workspaceRepo.updateTaskRun(taskRun.id, {
|
|
4239
|
+
status: "failed",
|
|
4240
|
+
finishedAt: new Date().toISOString(),
|
|
4241
|
+
});
|
|
4242
|
+
setFailureReason("tests_not_configured");
|
|
4243
|
+
results.push({ taskKey: task.task.key, status: "failed", notes: "tests_not_configured" });
|
|
4244
|
+
taskStatus = "failed";
|
|
4245
|
+
await this.deps.jobService.updateJobStatus(job.id, "running", { processedItems: index + 1 });
|
|
4246
|
+
await emitTaskEndOnce();
|
|
4247
|
+
continue taskLoop;
|
|
4248
|
+
}
|
|
4110
4249
|
}
|
|
4111
4250
|
const shouldRunTests = !request.dryRun && (testsRequired ? hasRunnableTests : testCommands.length > 0);
|
|
4112
4251
|
let mergeConflicts = [];
|
|
@@ -4463,9 +4602,14 @@ export class WorkOnTasksService {
|
|
|
4463
4602
|
continue taskLoop;
|
|
4464
4603
|
}
|
|
4465
4604
|
await endPhase("context", { docWarnings, docSummary: Boolean(docSummary) });
|
|
4466
|
-
const projectGuidance = await loadProjectGuidance(this.workspace.workspaceRoot, this.workspace.mcodaDir
|
|
4605
|
+
const projectGuidance = await loadProjectGuidance(this.workspace.workspaceRoot, this.workspace.mcodaDir, {
|
|
4606
|
+
projectKey: request.projectKey,
|
|
4607
|
+
});
|
|
4467
4608
|
if (projectGuidance) {
|
|
4468
4609
|
await this.logTask(taskRun.id, `Loaded project guidance from ${projectGuidance.source}`, "project_guidance");
|
|
4610
|
+
for (const warning of projectGuidance.warnings ?? []) {
|
|
4611
|
+
await this.logTask(taskRun.id, `Project guidance warning: ${warning}`, "project_guidance");
|
|
4612
|
+
}
|
|
4469
4613
|
}
|
|
4470
4614
|
await startPhase("prompt", { docSummary: Boolean(docSummary), agent: agent.id });
|
|
4471
4615
|
commentContext = await this.loadCommentContext(task.task.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenApiService.d.ts","sourceRoot":"","sources":["../../../src/services/openapi/OpenApiService.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAkB,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAiC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAIrE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA6CD,qBAAa,eAAgB,SAAQ,KAAK;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEH,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAK1D;AAgBD,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,MAapD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAmBpF,CAAC;AAIF,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,EAAE,QAAQ,MAAM,KAAG,MAAM,GAAG,SAS1E,CAAC;AAMF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,wBAAwB,GAAI,KAAK,MAAM,KAAG,mBAAmB,EAwCzE,CAAC;AAEF,MAAM,WAAW,6BAA6B;IAC5C,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"OpenApiService.d.ts","sourceRoot":"","sources":["../../../src/services/openapi/OpenApiService.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAkB,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAiC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAIrE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA6CD,qBAAa,eAAgB,SAAQ,KAAK;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEH,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAK1D;AAgBD,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,MAapD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAmBpF,CAAC;AAIF,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,EAAE,QAAQ,MAAM,KAAG,MAAM,GAAG,SAS1E,CAAC;AAMF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,wBAAwB,GAAI,KAAK,MAAM,KAAG,mBAAmB,EAwCzE,CAAC;AAEF,MAAM,WAAW,6BAA6B;IAC5C,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AA6BD,eAAO,MAAM,qBAAqB,GAAI,KAAK,GAAG,KAAG,MAAM,EAkItD,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,KAAK,MAAM,KAAG,6BAoB1D,CAAC;AAyLF,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,IAAI,CAAC,CAAmB;IAChC,OAAO,CAAC,aAAa,CAAC,CAAqB;IAC3C,OAAO,CAAC,aAAa,CAAC,CAAsB;gBAG1C,SAAS,EAAE,mBAAmB,EAC9B,IAAI,EAAE;QACJ,MAAM,CAAC,EAAE,YAAY,CAAC;QACtB,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,YAAY,EAAE,YAAY,CAAC;QAC3B,cAAc,EAAE,cAAc,CAAC;QAC/B,IAAI,CAAC,EAAE,gBAAgB,CAAC;QACxB,aAAa,CAAC,EAAE,mBAAmB,CAAC;QACpC,aAAa,CAAC,EAAE,kBAAkB,CAAC;QACnC,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB;WAcU,MAAM,CAAC,SAAS,EAAE,mBAAmB,EAAE,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,cAAc,CAAC;IAe/G,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAcd,YAAY;YASZ,mBAAmB;YAoBnB,WAAW;IA8BzB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,YAAY;YAIN,mBAAmB;IAajC,OAAO,CAAC,WAAW;YAuCL,gBAAgB;YAMhB,cAAc;YAOd,eAAe;YAoBf,oBAAoB;YAWpB,oBAAoB;IAmClC,OAAO,CAAC,gBAAgB;YAKV,gBAAgB;YAahB,iBAAiB;YAMjB,cAAc;YAMd,sBAAsB;YA6CtB,sBAAsB;IAYpC,OAAO,CAAC,qBAAqB;YA2Cf,gBAAgB;IAoGxB,gBAAgB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAyiBxF"}
|
|
@@ -139,6 +139,7 @@ export const findAdminSurfaceMentions = (raw) => {
|
|
|
139
139
|
};
|
|
140
140
|
const HTTP_METHODS = ["get", "post", "put", "patch", "delete", "options", "head", "trace"];
|
|
141
141
|
const OPERATION_ID_PATTERN = /^[A-Za-z0-9_.-]+$/;
|
|
142
|
+
const TASK_HINT_STAGE_VALUES = new Set(["foundation", "backend", "frontend", "other"]);
|
|
142
143
|
const isPlainObject = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
143
144
|
const operationUsesJsonSchema = (operation) => {
|
|
144
145
|
const contentBlocks = [];
|
|
@@ -230,6 +231,43 @@ export const validateOpenApiSchema = (doc) => {
|
|
|
230
231
|
else {
|
|
231
232
|
operationIds.set(operationId, `${method.toUpperCase()} ${pathKey}`);
|
|
232
233
|
}
|
|
234
|
+
const taskHints = operation["x-mcoda-task-hints"];
|
|
235
|
+
if (taskHints !== undefined) {
|
|
236
|
+
if (!isPlainObject(taskHints)) {
|
|
237
|
+
errors.push(`Invalid x-mcoda-task-hints for ${method.toUpperCase()} ${pathKey}: must be an object.`);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
const stage = taskHints.stage;
|
|
241
|
+
if (stage !== undefined && (typeof stage !== "string" || !TASK_HINT_STAGE_VALUES.has(stage))) {
|
|
242
|
+
errors.push(`Invalid x-mcoda-task-hints.stage for ${method.toUpperCase()} ${pathKey}: expected one of foundation|backend|frontend|other.`);
|
|
243
|
+
}
|
|
244
|
+
const complexity = taskHints.complexity;
|
|
245
|
+
if (complexity !== undefined &&
|
|
246
|
+
(typeof complexity !== "number" || !Number.isFinite(complexity) || complexity < 0)) {
|
|
247
|
+
errors.push(`Invalid x-mcoda-task-hints.complexity for ${method.toUpperCase()} ${pathKey}: expected non-negative number.`);
|
|
248
|
+
}
|
|
249
|
+
const dependsOn = taskHints.depends_on_operations;
|
|
250
|
+
if (dependsOn !== undefined &&
|
|
251
|
+
(!Array.isArray(dependsOn) || dependsOn.some((entry) => typeof entry !== "string"))) {
|
|
252
|
+
errors.push(`Invalid x-mcoda-task-hints.depends_on_operations for ${method.toUpperCase()} ${pathKey}: expected string array.`);
|
|
253
|
+
}
|
|
254
|
+
const testRequirements = taskHints.test_requirements;
|
|
255
|
+
if (testRequirements !== undefined) {
|
|
256
|
+
if (!isPlainObject(testRequirements)) {
|
|
257
|
+
errors.push(`Invalid x-mcoda-task-hints.test_requirements for ${method.toUpperCase()} ${pathKey}: expected object.`);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
for (const key of ["unit", "component", "integration", "api"]) {
|
|
261
|
+
const value = testRequirements[key];
|
|
262
|
+
if (value !== undefined &&
|
|
263
|
+
(!Array.isArray(value) || value.some((entry) => typeof entry !== "string"))) {
|
|
264
|
+
errors.push(`Invalid x-mcoda-task-hints.test_requirements.${key} for ${method.toUpperCase()} ${pathKey}: expected string array.`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
233
271
|
}
|
|
234
272
|
}
|
|
235
273
|
}
|
|
@@ -400,7 +438,7 @@ class OpenapiContextAssembler {
|
|
|
400
438
|
sdsDocs = [local];
|
|
401
439
|
}
|
|
402
440
|
else {
|
|
403
|
-
|
|
441
|
+
throw new Error("openapi-from-docs requires an SDS document. Generate SDS first (mcoda docs sds generate) or add docs/sds/sds.md.");
|
|
404
442
|
}
|
|
405
443
|
}
|
|
406
444
|
else {
|
|
@@ -594,8 +632,8 @@ export class OpenApiService {
|
|
|
594
632
|
: "";
|
|
595
633
|
return [
|
|
596
634
|
"You are generating an OpenAPI 3.1 YAML for THIS workspace/project using only the provided PDR/SDS/RFP context.",
|
|
597
|
-
"Derive resources, schemas, and HTTP endpoints directly from
|
|
598
|
-
"
|
|
635
|
+
"Derive resources, schemas, and HTTP endpoints directly from SDS-grounded product requirements only.",
|
|
636
|
+
"Do not invent endpoints, workflows, or schemas that are not traceable to SDS/PDR/RFP context.",
|
|
599
637
|
"Prefer concise tags derived from domain resources (e.g., Todos). Avoid generic mcoda/system endpoints unless explicitly described in the context.",
|
|
600
638
|
`Use OpenAPI version ${OPENAPI_VERSION}, set info.title to the project name from context (fallback \"mcoda API\"), and info.version ${cliVersion}.`,
|
|
601
639
|
adminNote,
|
|
@@ -605,8 +643,9 @@ export class OpenApiService {
|
|
|
605
643
|
"- Derive endpoints, schemas, and tags from the provided PDR/SDS/RFP context only.",
|
|
606
644
|
"- Do NOT emit generic mcoda CLI/system endpoints unless explicitly described.",
|
|
607
645
|
"- Prefer concise schemas and operations that map to described APIs; omit unused boilerplate.",
|
|
646
|
+
"- For each operation, include x-mcoda-task-hints with fields: service (string), capability (string), stage (foundation|backend|frontend|other), complexity (number), depends_on_operations (string[]), test_requirements ({ unit: string[], component: string[], integration: string[], api: string[] }).",
|
|
608
647
|
"Context:",
|
|
609
|
-
contextBlocks || "
|
|
648
|
+
contextBlocks || "SDS context is required and should always be present.",
|
|
610
649
|
].join("\n\n");
|
|
611
650
|
}
|
|
612
651
|
async ensureOpenapiDir() {
|
|
@@ -66,6 +66,11 @@ export declare class CreateTasksService {
|
|
|
66
66
|
private resolveAgent;
|
|
67
67
|
private ensureRatingService;
|
|
68
68
|
private prepareDocs;
|
|
69
|
+
private normalizeDocInputForSet;
|
|
70
|
+
private docIdentity;
|
|
71
|
+
private mergeDocs;
|
|
72
|
+
private sortDocsForPlanning;
|
|
73
|
+
private collectDocsFromInputs;
|
|
69
74
|
private resolveDefaultDocInputs;
|
|
70
75
|
private walkDocCandidates;
|
|
71
76
|
private scoreDocCandidate;
|
|
@@ -78,8 +83,10 @@ export declare class CreateTasksService {
|
|
|
78
83
|
private extractServiceMentionsFromText;
|
|
79
84
|
private resolveServiceMentionFromPhrase;
|
|
80
85
|
private collectDependencyStatements;
|
|
86
|
+
private extractStartupWaveHints;
|
|
81
87
|
private sortServicesByDependency;
|
|
82
88
|
private buildServiceDependencyGraph;
|
|
89
|
+
private buildProjectConstructionMethod;
|
|
83
90
|
private orderStoryTasksByDependencies;
|
|
84
91
|
private applyServiceDependencySequencing;
|
|
85
92
|
private shouldInjectStructureBootstrap;
|
|
@@ -88,13 +95,18 @@ export declare class CreateTasksService {
|
|
|
88
95
|
private validatePlanLocalIdentifiers;
|
|
89
96
|
private buildQaPreflight;
|
|
90
97
|
private buildQaOverrides;
|
|
98
|
+
private isOpenApiDoc;
|
|
99
|
+
private buildOpenApiHintSummary;
|
|
91
100
|
private buildDocContext;
|
|
92
101
|
private buildPrompt;
|
|
93
102
|
private fallbackPlan;
|
|
103
|
+
private materializePlanFromSeed;
|
|
94
104
|
private invokeAgentWithRetry;
|
|
95
105
|
private parseEpics;
|
|
96
106
|
private generateStoriesForEpic;
|
|
97
107
|
private generateTasksForStory;
|
|
108
|
+
private buildFallbackStoryForEpic;
|
|
109
|
+
private buildFallbackTasksForStory;
|
|
98
110
|
private generatePlanFromAgent;
|
|
99
111
|
private writePlanArtifacts;
|
|
100
112
|
private persistPlanToDb;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/CreateTasksService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CreateTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/CreateTasksService.ts"],"names":[],"mappings":"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"}
|