codeharness 0.31.1 → 0.31.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.31.1" : "0.0.0-dev";
2898
+ var HARNESS_VERSION = true ? "0.31.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-INMK5DZS.js";
19
+ } from "./chunk-RC2CEPIY.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-INMK5DZS.js";
43
+ } from "./chunk-RC2CEPIY.js";
44
44
 
45
45
  // src/index.ts
46
46
  import { Command } from "commander";
@@ -5105,12 +5105,24 @@ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834"
5105
5105
  function isLoopBlock2(step) {
5106
5106
  return typeof step === "object" && step !== null && "loop" in step;
5107
5107
  }
5108
- function TaskNode({ name, status, spinnerFrame }) {
5108
+ function driverLabel(driver) {
5109
+ if (!driver) return "";
5110
+ if (driver.includes("opus")) return "opus";
5111
+ if (driver.includes("sonnet")) return "snnt";
5112
+ if (driver.includes("haiku")) return "haiku";
5113
+ if (driver === "codex" || driver === "codex-mini") return "cdx";
5114
+ if (driver === "claude-code") return "cc";
5115
+ if (driver === "opencode") return "oc";
5116
+ return driver.slice(0, 4);
5117
+ }
5118
+ function TaskNode({ name, status, spinnerFrame, driver }) {
5109
5119
  const s = status ?? "pending";
5120
+ const tag = driver ? ` [${driverLabel(driver)}]` : "";
5110
5121
  switch (s) {
5111
5122
  case "done":
5112
5123
  return /* @__PURE__ */ jsxs2(Text2, { color: "green", children: [
5113
5124
  name,
5125
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: tag }),
5114
5126
  " \u2713"
5115
5127
  ] });
5116
5128
  case "active": {
@@ -5118,17 +5130,22 @@ function TaskNode({ name, status, spinnerFrame }) {
5118
5130
  return /* @__PURE__ */ jsxs2(Text2, { color: "cyan", children: [
5119
5131
  frame,
5120
5132
  " ",
5121
- name
5133
+ name,
5134
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: tag })
5122
5135
  ] });
5123
5136
  }
5124
5137
  case "failed":
5125
5138
  return /* @__PURE__ */ jsxs2(Text2, { color: "red", children: [
5126
5139
  name,
5140
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: tag }),
5127
5141
  " \u2717"
5128
5142
  ] });
5129
5143
  case "pending":
5130
5144
  default:
5131
- return /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: name });
5145
+ return /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
5146
+ name,
5147
+ tag
5148
+ ] });
5132
5149
  }
5133
5150
  }
5134
5151
  function loopIteration(tasks, taskStates) {
@@ -5138,49 +5155,74 @@ function loopIteration(tasks, taskStates) {
5138
5155
  });
5139
5156
  return anyStarted ? 1 : 0;
5140
5157
  }
5141
- function hasMetaData(taskMeta) {
5142
- if (!taskMeta) return false;
5143
- return Object.keys(taskMeta).length > 0;
5144
- }
5145
5158
  function WorkflowGraph({ flow, currentTask, taskStates, taskMeta }) {
5146
5159
  if (flow.length === 0 || Object.keys(taskStates).length === 0) {
5147
5160
  return null;
5148
5161
  }
5149
5162
  const meta = taskMeta ?? {};
5150
- const showMeta = hasMetaData(taskMeta);
5151
5163
  const spinnerFrame = Math.floor(Date.now() / 80);
5152
- const elements = [];
5153
- for (let i = 0; i < flow.length; i++) {
5154
- const step = flow[i];
5155
- if (i > 0) {
5156
- elements.push(/* @__PURE__ */ jsx2(Text2, { children: " \u2192 " }, `arrow-${i}`));
5157
- }
5164
+ let inLoop = false;
5165
+ let loopBlock = null;
5166
+ let loopItCount = 0;
5167
+ for (const step of flow) {
5158
5168
  if (isLoopBlock2(step)) {
5159
- const iteration = loopIteration(step.loop, taskStates);
5160
- const loopNodes = [];
5161
- for (let j = 0; j < step.loop.length; j++) {
5162
- if (j > 0) {
5163
- loopNodes.push(/* @__PURE__ */ jsx2(Text2, { children: " \u2192 " }, `loop-arrow-${i}-${j}`));
5164
- }
5165
- loopNodes.push(
5166
- /* @__PURE__ */ jsx2(TaskNode, { name: step.loop[j], status: taskStates[step.loop[j]], spinnerFrame }, `loop-task-${i}-${j}`)
5169
+ loopBlock = step;
5170
+ loopItCount = loopIteration(step.loop, taskStates);
5171
+ inLoop = loopItCount > 0;
5172
+ break;
5173
+ }
5174
+ }
5175
+ if (inLoop && loopBlock) {
5176
+ const elements2 = [];
5177
+ for (const step of flow) {
5178
+ if (isLoopBlock2(step)) break;
5179
+ if (typeof step === "string") {
5180
+ if (elements2.length > 0) elements2.push(/* @__PURE__ */ jsx2(Text2, { children: " \u2192 " }, `a-${step}`));
5181
+ elements2.push(
5182
+ /* @__PURE__ */ jsx2(TaskNode, { name: step, status: taskStates[step], spinnerFrame, driver: meta[step]?.driver }, `t-${step}`)
5167
5183
  );
5168
5184
  }
5169
- elements.push(
5170
- /* @__PURE__ */ jsxs2(Text2, { children: [
5171
- /* @__PURE__ */ jsxs2(Text2, { children: [
5172
- "loop(",
5173
- iteration,
5174
- ")[ "
5175
- ] }),
5176
- loopNodes,
5177
- /* @__PURE__ */ jsx2(Text2, { children: " ]" })
5178
- ] }, `loop-${i}`)
5185
+ }
5186
+ if (elements2.length > 0) elements2.push(/* @__PURE__ */ jsx2(Text2, { children: " \u2192 " }, "loop-arrow"));
5187
+ elements2.push(/* @__PURE__ */ jsx2(Text2, { children: /* @__PURE__ */ jsx2(Text2, { bold: true, children: `Loop ${loopItCount}: ` }) }, "loop-label"));
5188
+ for (let j = 0; j < loopBlock.loop.length; j++) {
5189
+ if (j > 0) elements2.push(/* @__PURE__ */ jsx2(Text2, { children: " \u2192 " }, `la-${j}`));
5190
+ const tn = loopBlock.loop[j];
5191
+ elements2.push(
5192
+ /* @__PURE__ */ jsx2(TaskNode, { name: tn, status: taskStates[tn], spinnerFrame, driver: meta[tn]?.driver }, `lt-${j}`)
5179
5193
  );
5180
- } else {
5194
+ }
5195
+ const loopDone = loopBlock.loop.every((t) => taskStates[t] === "done");
5196
+ if (loopDone) {
5197
+ let afterLoop = false;
5198
+ for (const step of flow) {
5199
+ if (afterLoop && typeof step === "string") {
5200
+ elements2.push(/* @__PURE__ */ jsx2(Text2, { children: " \u2192 " }, `post-a-${step}`));
5201
+ elements2.push(
5202
+ /* @__PURE__ */ jsx2(TaskNode, { name: step, status: taskStates[step], spinnerFrame, driver: meta[step]?.driver }, `post-${step}`)
5203
+ );
5204
+ }
5205
+ if (isLoopBlock2(step)) afterLoop = true;
5206
+ }
5207
+ }
5208
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: /* @__PURE__ */ jsxs2(Text2, { children: [
5209
+ " ",
5210
+ elements2
5211
+ ] }) });
5212
+ }
5213
+ const elements = [];
5214
+ let passedCurrent = false;
5215
+ for (const step of flow) {
5216
+ if (isLoopBlock2(step)) break;
5217
+ if (typeof step === "string") {
5218
+ if (elements.length > 0) {
5219
+ elements.push(/* @__PURE__ */ jsx2(Text2, { children: " \u2192 " }, `a-${step}`));
5220
+ }
5181
5221
  elements.push(
5182
- /* @__PURE__ */ jsx2(TaskNode, { name: step, status: taskStates[step], spinnerFrame }, `task-${i}`)
5222
+ /* @__PURE__ */ jsx2(TaskNode, { name: step, status: taskStates[step], spinnerFrame, driver: meta[step]?.driver }, `t-${step}`)
5183
5223
  );
5224
+ if (step === currentTask) passedCurrent = true;
5225
+ if (passedCurrent && step !== currentTask) break;
5184
5226
  }
5185
5227
  }
5186
5228
  return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: /* @__PURE__ */ jsxs2(Text2, { children: [
@@ -6213,7 +6255,7 @@ function registerRunCommand(program) {
6213
6255
  const taskMeta = {};
6214
6256
  for (const [tn, task] of Object.entries(parsedWorkflow.tasks)) {
6215
6257
  taskStates[tn] = "pending";
6216
- taskMeta[tn] = { driver: task.driver ?? "claude-code" };
6258
+ taskMeta[tn] = { driver: task.model ?? task.driver ?? "claude-code" };
6217
6259
  }
6218
6260
  const storyEntries = [];
6219
6261
  for (const [key, status] of Object.entries(statuses)) {
@@ -11169,7 +11211,7 @@ function registerTeardownCommand(program) {
11169
11211
  } else if (otlpMode === "remote-routed") {
11170
11212
  if (!options.keepDocker) {
11171
11213
  try {
11172
- const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-2Z4EIH3U.js");
11214
+ const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-D5IYCSH3.js");
11173
11215
  stopCollectorOnly2();
11174
11216
  result.docker.stopped = true;
11175
11217
  if (!isJson) {
@@ -11201,7 +11243,7 @@ function registerTeardownCommand(program) {
11201
11243
  info("Shared stack: kept running (other projects may use it)");
11202
11244
  }
11203
11245
  } else if (isLegacyStack) {
11204
- const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-2Z4EIH3U.js");
11246
+ const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-D5IYCSH3.js");
11205
11247
  let stackRunning = false;
11206
11248
  try {
11207
11249
  stackRunning = isStackRunning2(composeFile);
@@ -14128,7 +14170,7 @@ function registerDriversCommand(program) {
14128
14170
  }
14129
14171
 
14130
14172
  // src/index.ts
14131
- var VERSION = true ? "0.31.1" : "0.0.0-dev";
14173
+ var VERSION = true ? "0.31.2" : "0.0.0-dev";
14132
14174
  function createProgram() {
14133
14175
  const program = new Command();
14134
14176
  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.31.1",
3
+ "version": "0.31.2",
4
4
  "type": "module",
5
5
  "description": "CLI for codeharness — makes autonomous coding agents produce software that actually works",
6
6
  "bin": {