codeharness 0.35.1 → 0.35.2

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.
@@ -2895,7 +2895,7 @@ function generateDockerfileTemplate(projectDir, stackOrDetections) {
2895
2895
  }
2896
2896
 
2897
2897
  // src/modules/infra/init-project.ts
2898
- var HARNESS_VERSION = true ? "0.35.1" : "0.0.0-dev";
2898
+ var HARNESS_VERSION = true ? "0.35.2" : "0.0.0-dev";
2899
2899
  function failResult(opts, error) {
2900
2900
  return {
2901
2901
  status: "fail",
@@ -16,7 +16,7 @@ import {
16
16
  stopCollectorOnly,
17
17
  stopSharedStack,
18
18
  stopStack
19
- } from "./chunk-AIXEFZIV.js";
19
+ } from "./chunk-KJF2YA5T.js";
20
20
  export {
21
21
  checkRemoteEndpoint,
22
22
  cleanupOrphanedContainers,
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ import {
40
40
  validateDockerfile,
41
41
  warn,
42
42
  writeState
43
- } from "./chunk-AIXEFZIV.js";
43
+ } from "./chunk-KJF2YA5T.js";
44
44
 
45
45
  // src/index.ts
46
46
  import { Command } from "commander";
@@ -3609,6 +3609,14 @@ async function executeLoopBlock(loopBlock, state, config, workItems, initialCont
3609
3609
  if (loopBlock.loop.length === 0) {
3610
3610
  return { state: currentState, errors, tasksCompleted, halted: false, lastContract: lastOutputContract };
3611
3611
  }
3612
+ const lastAgentTaskInLoop = (() => {
3613
+ for (let i = loopBlock.loop.length - 1; i >= 0; i--) {
3614
+ const tn = loopBlock.loop[i];
3615
+ const t = config.workflow.tasks[tn];
3616
+ if (t && t.agent !== null) return tn;
3617
+ }
3618
+ return loopBlock.loop[loopBlock.loop.length - 1];
3619
+ })();
3612
3620
  while (true) {
3613
3621
  const nextIteration = currentState.iteration + 1;
3614
3622
  const allCurrentIterationDone = currentState.iteration > 0 && loopBlock.loop.every((tn) => {
@@ -3751,88 +3759,91 @@ async function executeLoopBlock(loopBlock, state, config, workItems, initialCont
3751
3759
  propagateVerifyFlags(taskName, dispatchResult.contract, projectDir);
3752
3760
  accumulatedCostUsd += dispatchResult.contract?.cost_usd ?? 0;
3753
3761
  tasksCompleted++;
3754
- let verdict = null;
3755
- try {
3756
- verdict = parseVerdict(dispatchResult.output);
3757
- } catch (parseErr) {
3758
- if (parseErr instanceof VerdictParseError && parseErr.retryable) {
3759
- warn(`workflow-engine: verdict parse failed, retrying evaluator for ${taskName}`);
3760
- try {
3761
- const retryResult = await dispatchTaskWithResult(
3762
- task,
3763
- taskName,
3764
- PER_RUN_SENTINEL,
3765
- definition,
3766
- currentState,
3767
- config,
3768
- void 0,
3769
- lastOutputContract ?? void 0
3770
- );
3771
- currentState = retryResult.updatedState;
3772
- lastOutputContract = retryResult.contract;
3773
- propagateVerifyFlags(taskName, retryResult.contract, projectDir);
3774
- tasksCompleted++;
3775
- verdict = parseVerdict(retryResult.output);
3776
- } catch {
3777
- verdict = buildAllUnknownVerdict(
3778
- workItems,
3779
- "Evaluator failed to produce valid JSON after retry"
3780
- );
3762
+ const isLastTaskInLoop = taskName === lastAgentTaskInLoop;
3763
+ if (isLastTaskInLoop) {
3764
+ let verdict = null;
3765
+ try {
3766
+ verdict = parseVerdict(dispatchResult.output);
3767
+ } catch (parseErr) {
3768
+ if (parseErr instanceof VerdictParseError && parseErr.retryable) {
3769
+ warn(`workflow-engine: verdict parse failed, retrying evaluator for ${taskName}`);
3770
+ try {
3771
+ const retryResult = await dispatchTaskWithResult(
3772
+ task,
3773
+ taskName,
3774
+ PER_RUN_SENTINEL,
3775
+ definition,
3776
+ currentState,
3777
+ config,
3778
+ void 0,
3779
+ lastOutputContract ?? void 0
3780
+ );
3781
+ currentState = retryResult.updatedState;
3782
+ lastOutputContract = retryResult.contract;
3783
+ propagateVerifyFlags(taskName, retryResult.contract, projectDir);
3784
+ tasksCompleted++;
3785
+ verdict = parseVerdict(retryResult.output);
3786
+ } catch {
3787
+ verdict = buildAllUnknownVerdict(
3788
+ workItems,
3789
+ "Evaluator failed to produce valid JSON after retry"
3790
+ );
3791
+ }
3781
3792
  }
3782
3793
  }
3783
- }
3784
- if (!verdict) {
3785
- const tagged = parseVerdictTag(dispatchResult.output);
3786
- if (tagged) {
3787
- verdict = {
3788
- verdict: tagged.verdict,
3789
- score: { passed: tagged.verdict === "pass" ? 1 : 0, failed: tagged.verdict === "fail" ? 1 : 0, unknown: 0, total: 1 },
3790
- findings: []
3794
+ if (!verdict) {
3795
+ const tagged = parseVerdictTag(dispatchResult.output);
3796
+ if (tagged) {
3797
+ verdict = {
3798
+ verdict: tagged.verdict,
3799
+ score: { passed: tagged.verdict === "pass" ? 1 : 0, failed: tagged.verdict === "fail" ? 1 : 0, unknown: 0, total: 1 },
3800
+ findings: []
3801
+ };
3802
+ }
3803
+ }
3804
+ lastVerdict = verdict;
3805
+ if (verdict) {
3806
+ const score = {
3807
+ iteration: currentState.iteration,
3808
+ passed: verdict.score.passed,
3809
+ failed: verdict.score.failed,
3810
+ unknown: verdict.score.unknown,
3811
+ total: verdict.score.total,
3812
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
3813
+ };
3814
+ currentState = {
3815
+ ...currentState,
3816
+ evaluator_scores: [...currentState.evaluator_scores, score]
3817
+ };
3818
+ } else {
3819
+ const totalItems = workItems.length;
3820
+ const score = {
3821
+ iteration: currentState.iteration,
3822
+ passed: 0,
3823
+ failed: 0,
3824
+ unknown: totalItems,
3825
+ total: totalItems,
3826
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
3827
+ };
3828
+ currentState = {
3829
+ ...currentState,
3830
+ evaluator_scores: [...currentState.evaluator_scores, score]
3791
3831
  };
3792
3832
  }
3793
- }
3794
- lastVerdict = verdict;
3795
- if (verdict) {
3796
- const score = {
3797
- iteration: currentState.iteration,
3798
- passed: verdict.score.passed,
3799
- failed: verdict.score.failed,
3800
- unknown: verdict.score.unknown,
3801
- total: verdict.score.total,
3802
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
3803
- };
3804
- currentState = {
3805
- ...currentState,
3806
- evaluator_scores: [...currentState.evaluator_scores, score]
3807
- };
3808
- } else {
3809
- const totalItems = workItems.length;
3810
- const score = {
3811
- iteration: currentState.iteration,
3812
- passed: 0,
3813
- failed: 0,
3814
- unknown: totalItems,
3815
- total: totalItems,
3816
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
3817
- };
3818
- currentState = {
3819
- ...currentState,
3820
- evaluator_scores: [...currentState.evaluator_scores, score]
3821
- };
3833
+ const cbDecision = evaluateProgress(currentState.evaluator_scores);
3834
+ if (cbDecision.halt) {
3835
+ currentState = {
3836
+ ...currentState,
3837
+ circuit_breaker: {
3838
+ triggered: true,
3839
+ reason: cbDecision.reason,
3840
+ score_history: cbDecision.scoreHistory
3841
+ }
3842
+ };
3843
+ writeWorkflowState(currentState, projectDir);
3844
+ }
3822
3845
  }
3823
3846
  writeWorkflowState(currentState, projectDir);
3824
- const cbDecision = evaluateProgress(currentState.evaluator_scores);
3825
- if (cbDecision.halt) {
3826
- currentState = {
3827
- ...currentState,
3828
- circuit_breaker: {
3829
- triggered: true,
3830
- reason: cbDecision.reason,
3831
- score_history: cbDecision.scoreHistory
3832
- }
3833
- };
3834
- writeWorkflowState(currentState, projectDir);
3835
- }
3836
3847
  } catch (err) {
3837
3848
  const engineError = handleDispatchError(err, taskName, PER_RUN_SENTINEL);
3838
3849
  errors.push(engineError);
@@ -11188,7 +11199,7 @@ function registerTeardownCommand(program) {
11188
11199
  } else if (otlpMode === "remote-routed") {
11189
11200
  if (!options.keepDocker) {
11190
11201
  try {
11191
- const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-GYFYNCLQ.js");
11202
+ const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-EIWOFRFK.js");
11192
11203
  stopCollectorOnly2();
11193
11204
  result.docker.stopped = true;
11194
11205
  if (!isJson) {
@@ -11220,7 +11231,7 @@ function registerTeardownCommand(program) {
11220
11231
  info("Shared stack: kept running (other projects may use it)");
11221
11232
  }
11222
11233
  } else if (isLegacyStack) {
11223
- const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-GYFYNCLQ.js");
11234
+ const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-EIWOFRFK.js");
11224
11235
  let stackRunning = false;
11225
11236
  try {
11226
11237
  stackRunning = isStackRunning2(composeFile);
@@ -14207,7 +14218,7 @@ function registerDriversCommand(program) {
14207
14218
  }
14208
14219
 
14209
14220
  // src/index.ts
14210
- var VERSION = true ? "0.35.1" : "0.0.0-dev";
14221
+ var VERSION = true ? "0.35.2" : "0.0.0-dev";
14211
14222
  function createProgram() {
14212
14223
  const program = new Command();
14213
14224
  program.name("codeharness").description("Makes autonomous coding agents produce software that actually works").version(VERSION).option("--json", "Output in machine-readable JSON format");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeharness",
3
- "version": "0.35.1",
3
+ "version": "0.35.2",
4
4
  "type": "module",
5
5
  "description": "CLI for codeharness — makes autonomous coding agents produce software that actually works",
6
6
  "bin": {