@mcoda/core 0.1.29 → 0.1.31

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.
@@ -1 +1 @@
1
- {"version":3,"file":"WorkOnTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/execution/WorkOnTasksService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkOnTasksService.d.ts","sourceRoot":"","sources":["../../../src/services/execution/WorkOnTasksService.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,6 @@ import { RoutingService } from "../agents/RoutingService.js";
17
17
  import { GATEWAY_HANDOFF_ENV_PATH } from "../agents/GatewayHandoff.js";
18
18
  import { AgentRatingService } from "../agents/AgentRatingService.js";
19
19
  import { ensureProjectGuidance, isDocContextExcluded, loadProjectGuidance, normalizeDocType, } from "../shared/ProjectGuidance.js";
20
- import { AUTH_ERROR_REASON, isAuthErrorMessage } from "../shared/AuthErrors.js";
21
20
  import { buildDocdexUsageGuidance } from "../shared/DocdexGuidance.js";
22
21
  import { createTaskCommentSlug, formatTaskCommentBody } from "../tasks/TaskCommentFormatter.js";
23
22
  const exec = promisify(execCb);
@@ -67,6 +66,9 @@ const QA_PROMPT_MARKERS = [
67
66
  "qa plan output schema",
68
67
  ];
69
68
  const QA_ADAPTERS = new Set(["qa-cli"]);
69
+ const ANSI_WARNING_REGEX = /\x1B\[[0-?]*[ -/]*[@-~]/g;
70
+ const CONTROL_WARNING_REGEX = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
71
+ const DEPENDENCY_WARNING_REGEX = /^Skipped \d+ task\(s\) due to dependencies not ready\.$/i;
70
72
  const sanitizeNonGatewayPrompt = (value) => {
71
73
  if (!value)
72
74
  return undefined;
@@ -144,6 +146,11 @@ const mergeUnique = (values) => {
144
146
  }
145
147
  return result;
146
148
  };
149
+ const sanitizeWarningText = (value) => value
150
+ .replace(ANSI_WARNING_REGEX, "")
151
+ .replace(CONTROL_WARNING_REGEX, "")
152
+ .replace(/\s+/g, " ")
153
+ .trim();
147
154
  const buildCodaliEnvOverrides = (options = []) => {
148
155
  const resolvedOptions = Array.isArray(options) ? { preferredFiles: options } : options;
149
156
  const overrides = {};
@@ -3585,12 +3592,16 @@ export class WorkOnTasksService {
3585
3592
  dependentCount: dependentCounts.get(candidate.task.id) ?? 0,
3586
3593
  }))
3587
3594
  .sort((a, b) => {
3588
- if (a.dependentCount !== b.dependentCount)
3589
- return b.dependentCount - a.dependentCount;
3590
3595
  const priorityA = a.candidate.task.priority ?? Number.MAX_SAFE_INTEGER;
3591
3596
  const priorityB = b.candidate.task.priority ?? Number.MAX_SAFE_INTEGER;
3592
3597
  if (priorityA !== priorityB)
3593
3598
  return priorityA - priorityB;
3599
+ if (a.dependentCount !== b.dependentCount)
3600
+ return b.dependentCount - a.dependentCount;
3601
+ const storyPointsA = a.candidate.task.storyPoints ?? Number.POSITIVE_INFINITY;
3602
+ const storyPointsB = b.candidate.task.storyPoints ?? Number.POSITIVE_INFINITY;
3603
+ if (storyPointsA !== storyPointsB)
3604
+ return storyPointsA - storyPointsB;
3594
3605
  const createdA = Date.parse(a.candidate.task.createdAt) || 0;
3595
3606
  const createdB = Date.parse(b.candidate.task.createdAt) || 0;
3596
3607
  if (createdA !== createdB)
@@ -3760,13 +3771,24 @@ export class WorkOnTasksService {
3760
3771
  try {
3761
3772
  const warnings = [...baseBranchWarnings, ...statusWarnings, ...runnerWarnings];
3762
3773
  const selectionWarningSet = new Set();
3774
+ let dependencyWarningIndex = null;
3763
3775
  const pushSelectionWarnings = (entries) => {
3764
- for (const warning of entries) {
3765
- const normalized = warning.trim();
3776
+ for (const rawWarning of entries) {
3777
+ const normalized = sanitizeWarningText(rawWarning);
3766
3778
  if (!normalized || selectionWarningSet.has(normalized))
3767
3779
  continue;
3780
+ if (DEPENDENCY_WARNING_REGEX.test(normalized)) {
3781
+ if (dependencyWarningIndex === null) {
3782
+ warnings.push(normalized);
3783
+ dependencyWarningIndex = warnings.length - 1;
3784
+ }
3785
+ else {
3786
+ warnings[dependencyWarningIndex] = normalized;
3787
+ }
3788
+ continue;
3789
+ }
3768
3790
  selectionWarningSet.add(normalized);
3769
- warnings.push(warning);
3791
+ warnings.push(normalized);
3770
3792
  }
3771
3793
  };
3772
3794
  try {
@@ -3809,7 +3831,7 @@ export class WorkOnTasksService {
3809
3831
  if (selection.ordered.length === 0 && !ignoreDependencies && !explicitTaskSelection) {
3810
3832
  const dependencyBlocked = selection.warnings.some((warning) => warning.toLowerCase().includes("dependencies not ready"));
3811
3833
  if (dependencyBlocked) {
3812
- const fallbackSelection = await this.selectionService.selectTasks({
3834
+ const refreshedSelection = await this.selectionService.selectTasks({
3813
3835
  projectKey: request.projectKey,
3814
3836
  epicKey: request.epicKey,
3815
3837
  storyKey: request.storyKey,
@@ -3818,22 +3840,42 @@ export class WorkOnTasksService {
3818
3840
  ignoreStatusFilter,
3819
3841
  includeTypes,
3820
3842
  excludeTypes,
3821
- ignoreDependencies: true,
3843
+ ignoreDependencies,
3822
3844
  missingContextPolicy: request.missingContextPolicy ?? "block",
3845
+ limit: request.limit,
3823
3846
  parallel: request.parallel,
3824
3847
  });
3825
- pushSelectionWarnings(fallbackSelection.warnings);
3826
- const fallbackTask = this.selectMostDependedTask(fallbackSelection.ordered);
3827
- if (fallbackTask) {
3828
- selection = {
3829
- ...selection,
3830
- project: selection.project ?? fallbackSelection.project,
3831
- ordered: [fallbackTask],
3832
- warnings: [
3833
- ...selection.warnings,
3834
- `No dependency-ready tasks available; selected ${fallbackTask.task.key} from dependency-loop fallback.`,
3835
- ],
3836
- };
3848
+ pushSelectionWarnings(refreshedSelection.warnings);
3849
+ if (refreshedSelection.ordered.length > 0) {
3850
+ selection = refreshedSelection;
3851
+ }
3852
+ else {
3853
+ const fallbackSelection = await this.selectionService.selectTasks({
3854
+ projectKey: request.projectKey,
3855
+ epicKey: request.epicKey,
3856
+ storyKey: request.storyKey,
3857
+ taskKeys: request.taskKeys,
3858
+ statusFilter,
3859
+ ignoreStatusFilter,
3860
+ includeTypes,
3861
+ excludeTypes,
3862
+ ignoreDependencies: true,
3863
+ missingContextPolicy: request.missingContextPolicy ?? "block",
3864
+ parallel: request.parallel,
3865
+ });
3866
+ pushSelectionWarnings(fallbackSelection.warnings);
3867
+ const fallbackTask = this.selectMostDependedTask(fallbackSelection.ordered);
3868
+ if (fallbackTask) {
3869
+ selection = {
3870
+ ...selection,
3871
+ project: selection.project ?? fallbackSelection.project,
3872
+ ordered: [fallbackTask],
3873
+ warnings: [
3874
+ ...selection.warnings,
3875
+ `No dependency-ready tasks available; selected ${fallbackTask.task.key} from dependency-loop fallback.`,
3876
+ ],
3877
+ };
3878
+ }
3837
3879
  }
3838
3880
  }
3839
3881
  }
@@ -4080,6 +4122,9 @@ export class WorkOnTasksService {
4080
4122
  };
4081
4123
  const maxSelectedTasks = typeof request.limit === "number" && request.limit > 0 ? request.limit : undefined;
4082
4124
  const selectedTaskIds = new Set(selection.ordered.map((entry) => entry.task.id));
4125
+ const seenDocWarnings = new Set(warnings
4126
+ .map((warning) => sanitizeWarningText(warning))
4127
+ .filter((warning) => warning.length > 0));
4083
4128
  const refreshSelectionQueue = async (processedCount) => {
4084
4129
  if (maxSelectedTasks !== undefined && selectedTaskIds.size >= maxSelectedTasks)
4085
4130
  return;
@@ -4165,13 +4210,10 @@ export class WorkOnTasksService {
4165
4210
  processedItems: processedCount,
4166
4211
  });
4167
4212
  };
4168
- let abortRemainingReason = null;
4169
4213
  taskLoop: for (let index = 0; index < selection.ordered.length; index += 1) {
4170
4214
  const task = selection.ordered[index];
4171
4215
  if (!task)
4172
4216
  continue;
4173
- if (abortRemainingReason)
4174
- break taskLoop;
4175
4217
  abortIfSignaled();
4176
4218
  const startedAt = new Date().toISOString();
4177
4219
  const taskRun = await this.deps.workspaceRepo.createTaskRun({
@@ -4891,8 +4933,18 @@ export class WorkOnTasksService {
4891
4933
  docdexUnavailable = docContext.docdexUnavailable;
4892
4934
  }
4893
4935
  if (docWarnings.length) {
4894
- warnings.push(...docWarnings);
4895
- await this.logTask(taskRun.id, docWarnings.join("; "), "docdex");
4936
+ const uniqueDocWarnings = [];
4937
+ for (const warning of docWarnings) {
4938
+ const normalized = sanitizeWarningText(warning);
4939
+ if (!normalized || seenDocWarnings.has(normalized))
4940
+ continue;
4941
+ seenDocWarnings.add(normalized);
4942
+ uniqueDocWarnings.push(normalized);
4943
+ }
4944
+ if (uniqueDocWarnings.length > 0) {
4945
+ warnings.push(...uniqueDocWarnings);
4946
+ await this.logTask(taskRun.id, uniqueDocWarnings.join("; "), "docdex");
4947
+ }
4896
4948
  }
4897
4949
  if (docdexUnavailable) {
4898
4950
  const message = "Docdex unavailable; missing required context for this task.";
@@ -5285,13 +5337,9 @@ export class WorkOnTasksService {
5285
5337
  });
5286
5338
  const codaliReason = resolveCodaliFailureReason(message);
5287
5339
  const failureNote = codaliReason ?? message;
5340
+ await this.stateService.markFailed(task.task, failureNote, statusContext);
5288
5341
  setFailureReason(failureNote);
5289
5342
  results.push({ taskKey: task.task.key, status: "failed", notes: failureNote });
5290
- if (isAuthErrorMessage(message)) {
5291
- abortRemainingReason = message;
5292
- setFailureReason(AUTH_ERROR_REASON);
5293
- warnings.push(`Auth/rate limit error detected; stopping after ${task.task.key}. ${message}`);
5294
- }
5295
5343
  taskStatus = "failed";
5296
5344
  await this.deps.jobService.updateJobStatus(job.id, "running", { processedItems: index + 1 });
5297
5345
  continue taskLoop;
@@ -6417,7 +6465,7 @@ export class WorkOnTasksService {
6417
6465
  throw error;
6418
6466
  }
6419
6467
  finally {
6420
- if (runVcsPhase && !vcsFinalized) {
6468
+ if (runVcsPhase && !vcsFinalized && taskStatus === "succeeded") {
6421
6469
  try {
6422
6470
  await runVcsPhase({ allowResultUpdate: false, reason: "finalize" });
6423
6471
  }
@@ -6459,28 +6507,21 @@ export class WorkOnTasksService {
6459
6507
  }
6460
6508
  finally {
6461
6509
  await emitTaskEndOnce();
6462
- if (!abortRemainingReason) {
6463
- try {
6464
- await refreshSelectionQueue(index + 1);
6465
- }
6466
- catch (error) {
6467
- warnings.push(`selection_refresh_failed: ${error instanceof Error ? error.message : String(error)}`);
6468
- }
6510
+ try {
6511
+ await refreshSelectionQueue(index + 1);
6512
+ }
6513
+ catch (error) {
6514
+ warnings.push(`selection_refresh_failed: ${error instanceof Error ? error.message : String(error)}`);
6469
6515
  }
6470
6516
  }
6471
6517
  }
6472
- if (abortRemainingReason) {
6473
- warnings.push(`Stopped remaining tasks due to auth/rate limit: ${abortRemainingReason}`);
6474
- }
6475
6518
  const failureCount = results.filter((r) => r.status === "failed").length;
6476
- const state = abortRemainingReason
6477
- ? "failed"
6478
- : failureCount === 0
6479
- ? "completed"
6480
- : failureCount === results.length
6481
- ? "failed"
6482
- : "partial";
6483
- const errorSummary = abortRemainingReason ?? (failureCount ? `${failureCount} task(s) failed` : undefined);
6519
+ const state = failureCount === 0
6520
+ ? "completed"
6521
+ : failureCount === results.length
6522
+ ? "failed"
6523
+ : "partial";
6524
+ const errorSummary = failureCount ? `${failureCount} task(s) failed` : undefined;
6484
6525
  const summaryTasks = results.map((result) => {
6485
6526
  const existing = taskSummaries.get(result.taskKey);
6486
6527
  if (existing)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcoda/core",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "description": "Core services and APIs for the mcoda CLI.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,11 +32,11 @@
32
32
  "dependencies": {
33
33
  "@apidevtools/swagger-parser": "^10.1.0",
34
34
  "yaml": "^2.4.2",
35
- "@mcoda/db": "0.1.29",
36
- "@mcoda/generators": "0.1.29",
37
- "@mcoda/shared": "0.1.29",
38
- "@mcoda/agents": "0.1.29",
39
- "@mcoda/integrations": "0.1.29"
35
+ "@mcoda/shared": "0.1.31",
36
+ "@mcoda/generators": "0.1.31",
37
+ "@mcoda/db": "0.1.31",
38
+ "@mcoda/agents": "0.1.31",
39
+ "@mcoda/integrations": "0.1.31"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "tsc -p tsconfig.json",