@mcoda/core 0.1.18 → 0.1.20
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/estimate/EstimateService.d.ts +2 -0
- package/dist/services/estimate/EstimateService.d.ts.map +1 -1
- package/dist/services/estimate/EstimateService.js +54 -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 +4 -0
- package/dist/services/execution/WorkOnTasksService.d.ts.map +1 -1
- package/dist/services/execution/WorkOnTasksService.js +146 -22
- 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 +15 -0
- package/dist/services/planning/CreateTasksService.d.ts.map +1 -1
- package/dist/services/planning/CreateTasksService.js +592 -81
- 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;
|
|
@@ -41,6 +42,7 @@ export interface WorkOnTasksResult {
|
|
|
41
42
|
warnings: string[];
|
|
42
43
|
}
|
|
43
44
|
export type MissingTestsPolicy = "block_job" | "skip_task" | "fail_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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"}
|
|
@@ -834,6 +834,7 @@ const splitFileBlocksByExistence = (fileBlocks, cwd) => {
|
|
|
834
834
|
return { existing, remaining };
|
|
835
835
|
};
|
|
836
836
|
const DEFAULT_MISSING_TESTS_POLICY = "block_job";
|
|
837
|
+
const DEFAULT_EXECUTION_CONTEXT_POLICY = "best_effort";
|
|
837
838
|
const normalizeMissingTestsPolicy = (value) => {
|
|
838
839
|
if (typeof value !== "string")
|
|
839
840
|
return undefined;
|
|
@@ -843,6 +844,15 @@ const normalizeMissingTestsPolicy = (value) => {
|
|
|
843
844
|
}
|
|
844
845
|
return undefined;
|
|
845
846
|
};
|
|
847
|
+
const normalizeExecutionContextPolicy = (value) => {
|
|
848
|
+
if (typeof value !== "string")
|
|
849
|
+
return undefined;
|
|
850
|
+
const normalized = value.trim().toLowerCase();
|
|
851
|
+
if (normalized === "best_effort" || normalized === "require_any" || normalized === "require_sds_or_openapi") {
|
|
852
|
+
return normalized;
|
|
853
|
+
}
|
|
854
|
+
return undefined;
|
|
855
|
+
};
|
|
846
856
|
const normalizeStringArray = (value) => {
|
|
847
857
|
if (!Array.isArray(value))
|
|
848
858
|
return [];
|
|
@@ -1412,6 +1422,15 @@ const allowsTestsOnlyCompletion = (task, metadata, allowedFiles) => {
|
|
|
1412
1422
|
return false;
|
|
1413
1423
|
};
|
|
1414
1424
|
const hasProductTouchedFiles = (touchedFiles) => touchedFiles.some((file) => !isTestLikePath(file) && !isDocumentationPath(file));
|
|
1425
|
+
const classifyExecutionContextKind = (doc) => {
|
|
1426
|
+
const type = (doc.docType ?? "").toLowerCase();
|
|
1427
|
+
const label = `${doc.path ?? ""} ${doc.title ?? ""}`.toLowerCase();
|
|
1428
|
+
if (type.includes("sds") || /\bsds\b/.test(label))
|
|
1429
|
+
return "sds";
|
|
1430
|
+
if (type.includes("openapi") || type.includes("swagger") || /(openapi|swagger)/.test(label))
|
|
1431
|
+
return "openapi";
|
|
1432
|
+
return "fallback";
|
|
1433
|
+
};
|
|
1415
1434
|
const buildDocContextQuery = (task, allowedFiles) => {
|
|
1416
1435
|
const seeds = [
|
|
1417
1436
|
task.key,
|
|
@@ -2260,6 +2279,61 @@ export class WorkOnTasksService {
|
|
|
2260
2279
|
await this.logTask(taskRunId, `${phase}:${status}`, phase, payload);
|
|
2261
2280
|
await this.checkpoint(jobId, `task:${taskKey}:${phase}:${status}`, payload);
|
|
2262
2281
|
}
|
|
2282
|
+
enforceExecutionContextPolicy(policy, context) {
|
|
2283
|
+
if (policy === "best_effort")
|
|
2284
|
+
return;
|
|
2285
|
+
if (policy === "require_any") {
|
|
2286
|
+
if (!context) {
|
|
2287
|
+
throw new Error("Execution context is required but no planning documents were resolved (policy=require_any).");
|
|
2288
|
+
}
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
if (!context) {
|
|
2292
|
+
throw new Error("Execution context requires SDS/OpenAPI sources, but none were resolved (policy=require_sds_or_openapi).");
|
|
2293
|
+
}
|
|
2294
|
+
if (context.kind !== "sds" && context.kind !== "openapi") {
|
|
2295
|
+
throw new Error(`Execution context policy require_sds_or_openapi rejected source '${context.source}' (kind=${context.kind}).`);
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
async resolveExecutionPlanningContext(projectKey, warnings) {
|
|
2299
|
+
if (!projectKey)
|
|
2300
|
+
return undefined;
|
|
2301
|
+
const pickFirst = async (filter) => {
|
|
2302
|
+
const docs = await this.deps.docdex.search(filter);
|
|
2303
|
+
return docs[0];
|
|
2304
|
+
};
|
|
2305
|
+
try {
|
|
2306
|
+
const sdsDoc = await pickFirst({ projectKey, docType: "SDS", profile: "workspace-code" });
|
|
2307
|
+
if (sdsDoc) {
|
|
2308
|
+
return {
|
|
2309
|
+
source: sdsDoc.id ?? sdsDoc.path ?? sdsDoc.title ?? "sds",
|
|
2310
|
+
kind: classifyExecutionContextKind(sdsDoc),
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2313
|
+
const openapiDoc = await pickFirst({ projectKey, docType: "OPENAPI", profile: "workspace-code" });
|
|
2314
|
+
if (openapiDoc) {
|
|
2315
|
+
return {
|
|
2316
|
+
source: openapiDoc.id ?? openapiDoc.path ?? openapiDoc.title ?? "openapi",
|
|
2317
|
+
kind: classifyExecutionContextKind(openapiDoc),
|
|
2318
|
+
};
|
|
2319
|
+
}
|
|
2320
|
+
const fallbackDoc = await pickFirst({
|
|
2321
|
+
projectKey,
|
|
2322
|
+
profile: "workspace-code",
|
|
2323
|
+
query: "sds requirements architecture openapi swagger",
|
|
2324
|
+
});
|
|
2325
|
+
if (!fallbackDoc)
|
|
2326
|
+
return undefined;
|
|
2327
|
+
return {
|
|
2328
|
+
source: fallbackDoc.id ?? fallbackDoc.path ?? fallbackDoc.title ?? "workspace-code",
|
|
2329
|
+
kind: classifyExecutionContextKind(fallbackDoc),
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
catch (error) {
|
|
2333
|
+
warnings.push(`Execution context preflight failed to query docdex: ${error.message}`);
|
|
2334
|
+
return undefined;
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2263
2337
|
async gatherDocContext(task, projectKey, docLinks = [], allowedFiles = []) {
|
|
2264
2338
|
const warnings = [];
|
|
2265
2339
|
const parts = [];
|
|
@@ -2286,9 +2360,36 @@ export class WorkOnTasksService {
|
|
|
2286
2360
|
}
|
|
2287
2361
|
}
|
|
2288
2362
|
try {
|
|
2289
|
-
|
|
2363
|
+
const docs = [];
|
|
2364
|
+
const seen = new Set();
|
|
2365
|
+
const appendDocs = async (filter) => {
|
|
2366
|
+
const found = await this.deps.docdex.search(filter);
|
|
2367
|
+
for (const doc of found) {
|
|
2368
|
+
const key = String(doc.id ?? doc.path ?? doc.title ?? "");
|
|
2369
|
+
if (!key)
|
|
2370
|
+
continue;
|
|
2371
|
+
if (seen.has(key))
|
|
2372
|
+
continue;
|
|
2373
|
+
seen.add(key);
|
|
2374
|
+
docs.push(doc);
|
|
2375
|
+
}
|
|
2376
|
+
};
|
|
2377
|
+
const sdsFilter = docQuery
|
|
2378
|
+
? { projectKey, docType: "SDS", profile: "workspace-code", query: docQuery }
|
|
2379
|
+
: { projectKey, docType: "SDS", profile: "workspace-code" };
|
|
2380
|
+
const openapiFilter = docQuery
|
|
2381
|
+
? { projectKey, docType: "OPENAPI", profile: "workspace-code", query: docQuery }
|
|
2382
|
+
: { projectKey, docType: "OPENAPI", profile: "workspace-code" };
|
|
2383
|
+
await appendDocs(sdsFilter);
|
|
2384
|
+
await appendDocs(openapiFilter);
|
|
2385
|
+
if (!docs.length) {
|
|
2386
|
+
const genericFilter = docQuery
|
|
2387
|
+
? { projectKey, profile: "workspace-code", query: docQuery }
|
|
2388
|
+
: { projectKey, profile: "workspace-code" };
|
|
2389
|
+
await appendDocs(genericFilter);
|
|
2390
|
+
}
|
|
2290
2391
|
if (!docs.length && docQuery) {
|
|
2291
|
-
|
|
2392
|
+
await appendDocs({ projectKey, profile: "workspace-code" });
|
|
2292
2393
|
}
|
|
2293
2394
|
const filteredDocs = docs.filter((doc) => !isDocContextExcluded(doc.path ?? doc.title ?? doc.id, false) &&
|
|
2294
2395
|
(includeTestDocs || !isTestLikePath(doc.path ?? doc.title ?? doc.id)));
|
|
@@ -3389,12 +3490,14 @@ export class WorkOnTasksService {
|
|
|
3389
3490
|
const commentBacklogMaxFails = resolveCommentBacklogMaxFails();
|
|
3390
3491
|
const requestedMissingTestsPolicy = normalizeMissingTestsPolicy(request.missingTestsPolicy);
|
|
3391
3492
|
const missingTestsPolicy = requestedMissingTestsPolicy ?? (request.allowMissingTests ? "skip_task" : DEFAULT_MISSING_TESTS_POLICY);
|
|
3493
|
+
const requestedExecutionContextPolicy = normalizeExecutionContextPolicy(request.executionContextPolicy);
|
|
3494
|
+
const executionContextPolicy = requestedExecutionContextPolicy ?? DEFAULT_EXECUTION_CONTEXT_POLICY;
|
|
3392
3495
|
const baseCodaliEnvOverrides = codaliRequired ? buildCodaliEnvOverrides() : {};
|
|
3393
3496
|
const configuredBaseBranch = this.workspace.config?.branch;
|
|
3394
3497
|
const requestedBaseBranch = request.baseBranch;
|
|
3395
3498
|
const resolvedBaseBranch = (requestedBaseBranch ?? configuredBaseBranch ?? DEFAULT_BASE_BRANCH).trim();
|
|
3396
3499
|
const normalizedBaseBranch = resolvedBaseBranch === "dev" ? DEFAULT_BASE_BRANCH : resolvedBaseBranch;
|
|
3397
|
-
const baseBranch = DEFAULT_BASE_BRANCH;
|
|
3500
|
+
const baseBranch = normalizedBaseBranch || DEFAULT_BASE_BRANCH;
|
|
3398
3501
|
const configuredAutoMerge = this.workspace.config?.autoMerge;
|
|
3399
3502
|
const configuredAutoPush = this.workspace.config?.autoPush;
|
|
3400
3503
|
const autoMerge = request.autoMerge ?? configuredAutoMerge ?? true;
|
|
@@ -3405,7 +3508,12 @@ export class WorkOnTasksService {
|
|
|
3405
3508
|
if (request.missingTestsPolicy && !requestedMissingTestsPolicy) {
|
|
3406
3509
|
runnerWarnings.push(`Unknown missing-tests policy "${String(request.missingTestsPolicy)}"; using "${missingTestsPolicy}".`);
|
|
3407
3510
|
}
|
|
3408
|
-
|
|
3511
|
+
if (request.executionContextPolicy && !requestedExecutionContextPolicy) {
|
|
3512
|
+
runnerWarnings.push(`Unknown execution-context policy "${String(request.executionContextPolicy)}"; using "${executionContextPolicy}".`);
|
|
3513
|
+
}
|
|
3514
|
+
const explicitTaskSelection = Boolean(request.taskKeys?.length);
|
|
3515
|
+
const ignoreDependencies = request.ignoreDependencies === true || explicitTaskSelection;
|
|
3516
|
+
const ignoreStatusFilter = explicitTaskSelection || request.ignoreStatusFilter === true;
|
|
3409
3517
|
const { filtered: statusFilter, rejected } = ignoreStatusFilter
|
|
3410
3518
|
? { filtered: request.statusFilter ?? [], rejected: [] }
|
|
3411
3519
|
: filterTaskStatuses(request.statusFilter, WORK_ALLOWED_STATUSES, WORK_ALLOWED_STATUSES);
|
|
@@ -3426,9 +3534,6 @@ export class WorkOnTasksService {
|
|
|
3426
3534
|
if (codaliRequired && isPatchModeEnabled()) {
|
|
3427
3535
|
runnerWarnings.push("work-on-tasks patch mode is ignored when codali is required.");
|
|
3428
3536
|
}
|
|
3429
|
-
if (normalizedBaseBranch && normalizedBaseBranch !== DEFAULT_BASE_BRANCH) {
|
|
3430
|
-
baseBranchWarnings.push(`Base branch ${normalizedBaseBranch} ignored; work-on-tasks always uses ${DEFAULT_BASE_BRANCH}.`);
|
|
3431
|
-
}
|
|
3432
3537
|
const commandRun = await this.deps.jobService.startCommandRun(commandName, request.projectKey, {
|
|
3433
3538
|
taskIds: request.taskKeys,
|
|
3434
3539
|
});
|
|
@@ -3443,7 +3548,7 @@ export class WorkOnTasksService {
|
|
|
3443
3548
|
ignoreStatusFilter,
|
|
3444
3549
|
includeTypes,
|
|
3445
3550
|
excludeTypes,
|
|
3446
|
-
ignoreDependencies
|
|
3551
|
+
ignoreDependencies,
|
|
3447
3552
|
limit: request.limit,
|
|
3448
3553
|
parallel: request.parallel,
|
|
3449
3554
|
noCommit: request.noCommit ?? false,
|
|
@@ -3452,6 +3557,7 @@ export class WorkOnTasksService {
|
|
|
3452
3557
|
agentStream,
|
|
3453
3558
|
missingTestsPolicy,
|
|
3454
3559
|
allowMissingTests: request.allowMissingTests ?? false,
|
|
3560
|
+
executionContextPolicy,
|
|
3455
3561
|
},
|
|
3456
3562
|
});
|
|
3457
3563
|
const workspaceRoot = request.workspace.workspaceRoot;
|
|
@@ -3517,6 +3623,29 @@ export class WorkOnTasksService {
|
|
|
3517
3623
|
return message === resolveAbortReason();
|
|
3518
3624
|
};
|
|
3519
3625
|
try {
|
|
3626
|
+
const warnings = [...baseBranchWarnings, ...statusWarnings, ...runnerWarnings];
|
|
3627
|
+
try {
|
|
3628
|
+
const guidance = await ensureProjectGuidance(this.workspace.workspaceRoot, {
|
|
3629
|
+
mcodaDir: this.workspace.mcodaDir,
|
|
3630
|
+
projectKey: request.projectKey,
|
|
3631
|
+
});
|
|
3632
|
+
if (guidance.status !== "existing") {
|
|
3633
|
+
warnings.push(`project_guidance_${guidance.status}: ${guidance.path}`);
|
|
3634
|
+
}
|
|
3635
|
+
for (const warning of guidance.warnings ?? []) {
|
|
3636
|
+
warnings.push(`project_guidance_warning:${warning}`);
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3639
|
+
catch (error) {
|
|
3640
|
+
warnings.push(`project_guidance_bootstrap_failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3641
|
+
}
|
|
3642
|
+
const executionContext = await this.resolveExecutionPlanningContext(request.projectKey, warnings);
|
|
3643
|
+
this.enforceExecutionContextPolicy(executionContextPolicy, executionContext);
|
|
3644
|
+
await this.checkpoint(job.id, "execution_context_preflight", {
|
|
3645
|
+
policy: executionContextPolicy,
|
|
3646
|
+
source: executionContext?.source ?? null,
|
|
3647
|
+
kind: executionContext?.kind ?? null,
|
|
3648
|
+
});
|
|
3520
3649
|
await this.checkoutBaseBranch(baseBranch, { allowDirty: true });
|
|
3521
3650
|
selection = await this.selectionService.selectTasks({
|
|
3522
3651
|
projectKey: request.projectKey,
|
|
@@ -3527,7 +3656,8 @@ export class WorkOnTasksService {
|
|
|
3527
3656
|
ignoreStatusFilter,
|
|
3528
3657
|
includeTypes,
|
|
3529
3658
|
excludeTypes,
|
|
3530
|
-
ignoreDependencies
|
|
3659
|
+
ignoreDependencies,
|
|
3660
|
+
missingContextPolicy: request.missingContextPolicy ?? "block",
|
|
3531
3661
|
limit: request.limit,
|
|
3532
3662
|
parallel: request.parallel,
|
|
3533
3663
|
});
|
|
@@ -3542,20 +3672,9 @@ export class WorkOnTasksService {
|
|
|
3542
3672
|
totalItems: selection.ordered.length,
|
|
3543
3673
|
processedItems: 0,
|
|
3544
3674
|
});
|
|
3675
|
+
warnings.push(...selection.warnings);
|
|
3545
3676
|
const results = [];
|
|
3546
3677
|
const taskSummaries = new Map();
|
|
3547
|
-
const warnings = [...baseBranchWarnings, ...statusWarnings, ...runnerWarnings, ...selection.warnings];
|
|
3548
|
-
try {
|
|
3549
|
-
const guidance = await ensureProjectGuidance(this.workspace.workspaceRoot, {
|
|
3550
|
-
mcodaDir: this.workspace.mcodaDir,
|
|
3551
|
-
});
|
|
3552
|
-
if (guidance.status !== "existing") {
|
|
3553
|
-
warnings.push(`project_guidance_${guidance.status}: ${guidance.path}`);
|
|
3554
|
-
}
|
|
3555
|
-
}
|
|
3556
|
-
catch (error) {
|
|
3557
|
-
warnings.push(`project_guidance_bootstrap_failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3558
|
-
}
|
|
3559
3678
|
if (missingTestsPolicy === "block_job") {
|
|
3560
3679
|
const missingHarnessTasks = await this.findMissingTestHarnessTasks(selection.ordered);
|
|
3561
3680
|
if (missingHarnessTasks.length > 0) {
|
|
@@ -4461,9 +4580,14 @@ export class WorkOnTasksService {
|
|
|
4461
4580
|
continue taskLoop;
|
|
4462
4581
|
}
|
|
4463
4582
|
await endPhase("context", { docWarnings, docSummary: Boolean(docSummary) });
|
|
4464
|
-
const projectGuidance = await loadProjectGuidance(this.workspace.workspaceRoot, this.workspace.mcodaDir
|
|
4583
|
+
const projectGuidance = await loadProjectGuidance(this.workspace.workspaceRoot, this.workspace.mcodaDir, {
|
|
4584
|
+
projectKey: request.projectKey,
|
|
4585
|
+
});
|
|
4465
4586
|
if (projectGuidance) {
|
|
4466
4587
|
await this.logTask(taskRun.id, `Loaded project guidance from ${projectGuidance.source}`, "project_guidance");
|
|
4588
|
+
for (const warning of projectGuidance.warnings ?? []) {
|
|
4589
|
+
await this.logTask(taskRun.id, `Project guidance warning: ${warning}`, "project_guidance");
|
|
4590
|
+
}
|
|
4467
4591
|
}
|
|
4468
4592
|
await startPhase("prompt", { docSummary: Boolean(docSummary), agent: agent.id });
|
|
4469
4593
|
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":"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"}
|
|
@@ -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() {
|
|
@@ -58,10 +58,19 @@ export declare class CreateTasksService {
|
|
|
58
58
|
});
|
|
59
59
|
static create(workspace: WorkspaceResolution): Promise<CreateTasksService>;
|
|
60
60
|
close(): Promise<void>;
|
|
61
|
+
private storyScopeKey;
|
|
62
|
+
private taskScopeKey;
|
|
63
|
+
private scopeStory;
|
|
64
|
+
private scopeTask;
|
|
61
65
|
private seedPriorities;
|
|
62
66
|
private resolveAgent;
|
|
63
67
|
private ensureRatingService;
|
|
64
68
|
private prepareDocs;
|
|
69
|
+
private normalizeDocInputForSet;
|
|
70
|
+
private docIdentity;
|
|
71
|
+
private mergeDocs;
|
|
72
|
+
private sortDocsForPlanning;
|
|
73
|
+
private collectDocsFromInputs;
|
|
65
74
|
private resolveDefaultDocInputs;
|
|
66
75
|
private walkDocCandidates;
|
|
67
76
|
private scoreDocCandidate;
|
|
@@ -74,18 +83,24 @@ export declare class CreateTasksService {
|
|
|
74
83
|
private extractServiceMentionsFromText;
|
|
75
84
|
private resolveServiceMentionFromPhrase;
|
|
76
85
|
private collectDependencyStatements;
|
|
86
|
+
private extractStartupWaveHints;
|
|
77
87
|
private sortServicesByDependency;
|
|
78
88
|
private buildServiceDependencyGraph;
|
|
89
|
+
private buildProjectConstructionMethod;
|
|
79
90
|
private orderStoryTasksByDependencies;
|
|
80
91
|
private applyServiceDependencySequencing;
|
|
81
92
|
private shouldInjectStructureBootstrap;
|
|
82
93
|
private injectStructureBootstrapPlan;
|
|
83
94
|
private enforceStoryScopedDependencies;
|
|
95
|
+
private validatePlanLocalIdentifiers;
|
|
84
96
|
private buildQaPreflight;
|
|
85
97
|
private buildQaOverrides;
|
|
98
|
+
private isOpenApiDoc;
|
|
99
|
+
private buildOpenApiHintSummary;
|
|
86
100
|
private buildDocContext;
|
|
87
101
|
private buildPrompt;
|
|
88
102
|
private fallbackPlan;
|
|
103
|
+
private materializePlanFromSeed;
|
|
89
104
|
private invokeAgentWithRetry;
|
|
90
105
|
private parseEpics;
|
|
91
106
|
private generateStoriesForEpic;
|
|
@@ -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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"}
|