codeharness 0.34.0 → 0.34.1

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.34.0" : "0.0.0-dev";
2898
+ var HARNESS_VERSION = true ? "0.34.1" : "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-QMWMRFGH.js";
19
+ } from "./chunk-G2RR744K.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-QMWMRFGH.js";
43
+ } from "./chunk-G2RR744K.js";
44
44
 
45
45
  // src/index.ts
46
46
  import { Command } from "commander";
@@ -3068,11 +3068,15 @@ function parseVerdict(output) {
3068
3068
  return verdict;
3069
3069
  }
3070
3070
  function parseSimpleVerdict(output) {
3071
- const jsonPattern = /\{[^{}]*"verdict"\s*:\s*"(pass|fail)"[^{}]*\}/;
3072
- const match = jsonPattern.exec(output);
3073
- if (!match) return null;
3071
+ const jsonPattern = /\{[^{}]*"verdict"\s*:\s*"(pass|fail)"[^{}]*\}/g;
3072
+ let lastMatch = null;
3073
+ let m;
3074
+ while ((m = jsonPattern.exec(output)) !== null) {
3075
+ lastMatch = m;
3076
+ }
3077
+ if (!lastMatch) return null;
3074
3078
  try {
3075
- const parsed = JSON.parse(match[0]);
3079
+ const parsed = JSON.parse(lastMatch[0]);
3076
3080
  if (parsed.verdict === "pass" || parsed.verdict === "fail") {
3077
3081
  return { verdict: parsed.verdict };
3078
3082
  }
@@ -3384,8 +3388,8 @@ async function dispatchTaskWithResult(task, taskName, storyKey, definition, stat
3384
3388
  }
3385
3389
  const isEpicSentinel = storyKey.startsWith("__epic_") || storyKey === PER_RUN_SENTINEL;
3386
3390
  const TASK_PROMPTS = {
3387
- "create-story": (key) => `Create the story spec for ${key}. Read the epic definitions and architecture docs, then write a complete story file with acceptance criteria, tasks, and dev notes.`,
3388
- "negotiate-acs": (key) => `Review the ACs in story ${key} for testability. Can each AC be verified by a blind QA agent with only Docker access and user documentation? Output a verdict JSON.`,
3391
+ "create-story": (key) => `Create or revise the story spec for ${key}. Read the epic definitions and architecture docs. If previous feedback is provided (from AC negotiation or review), revise the story to address that feedback. Write a complete story file with acceptance criteria, tasks, and dev notes.`,
3392
+ "negotiate-acs": (key) => `Review the ACs in story ${key} for testability. Can each AC be verified by a blind QA agent with only Docker access and user documentation? Your response MUST end with exactly one JSON line: {"verdict": "pass"} or {"verdict": "fail", "issues": ["..."]}`,
3389
3393
  "implement": (key) => `Implement story ${key}`,
3390
3394
  "check": (key) => `Run automated checks for story ${key}. Execute the project's test suite, linter, and coverage tool. Report pass/fail results.`,
3391
3395
  "review": (key) => `Review the implementation of story ${key}. Check for correctness, security issues, architecture violations, and AC coverage. Output a verdict JSON at the end.`,
@@ -11185,7 +11189,7 @@ function registerTeardownCommand(program) {
11185
11189
  } else if (otlpMode === "remote-routed") {
11186
11190
  if (!options.keepDocker) {
11187
11191
  try {
11188
- const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-QYSLNCQ2.js");
11192
+ const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-MEPWHG4P.js");
11189
11193
  stopCollectorOnly2();
11190
11194
  result.docker.stopped = true;
11191
11195
  if (!isJson) {
@@ -11217,7 +11221,7 @@ function registerTeardownCommand(program) {
11217
11221
  info("Shared stack: kept running (other projects may use it)");
11218
11222
  }
11219
11223
  } else if (isLegacyStack) {
11220
- const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-QYSLNCQ2.js");
11224
+ const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-MEPWHG4P.js");
11221
11225
  let stackRunning = false;
11222
11226
  try {
11223
11227
  stackRunning = isStackRunning2(composeFile);
@@ -14204,7 +14208,7 @@ function registerDriversCommand(program) {
14204
14208
  }
14205
14209
 
14206
14210
  // src/index.ts
14207
- var VERSION = true ? "0.34.0" : "0.0.0-dev";
14211
+ var VERSION = true ? "0.34.1" : "0.0.0-dev";
14208
14212
  function createProgram() {
14209
14213
  const program = new Command();
14210
14214
  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.34.0",
3
+ "version": "0.34.1",
4
4
  "type": "module",
5
5
  "description": "CLI for codeharness — makes autonomous coding agents produce software that actually works",
6
6
  "bin": {
@@ -29,16 +29,14 @@ prompt_template: |
29
29
  - Observable output (logs, responses, behavior)
30
30
  3. If an AC requires reading source code, inspecting file contents, or understanding implementation details to verify — it FAILS testability
31
31
 
32
- ## Output
32
+ ## Output — MANDATORY FORMAT
33
33
 
34
- If ALL ACs are testable, output:
35
- ```json
34
+ Your response MUST end with EXACTLY one of these two JSON lines (no code block, no markdown, just raw JSON as the LAST line of your output):
35
+
36
+ If ALL ACs are testable:
36
37
  {"verdict": "pass"}
37
- ```
38
38
 
39
- If ANY AC fails testability, output:
40
- ```json
41
- {"verdict": "fail", "issues": ["AC N: [reason it's untestable]. Suggested rewrite: [specific rewrite]"]}
42
- ```
39
+ If ANY AC fails testability:
40
+ {"verdict": "fail", "issues": ["AC 1: reason and suggested rewrite", "AC 3: reason and suggested rewrite"]}
43
41
 
44
- Be specific. Don't just say "untestable" explain WHY and provide a concrete rewrite.
42
+ You may include analysis BEFORE the verdict line, but the LAST line of your response MUST be the raw JSON verdict. This is machine-parsed — the loop cannot exit without it.