codeharness 0.33.0 → 0.33.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.33.0" : "0.0.0-dev";
2898
+ var HARNESS_VERSION = true ? "0.33.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-4YPX74BX.js";
19
+ } from "./chunk-537B2B6W.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-4YPX74BX.js";
43
+ } from "./chunk-537B2B6W.js";
44
44
 
45
45
  // src/index.ts
46
46
  import { Command } from "commander";
@@ -5462,8 +5462,8 @@ function App({ state, onCycleLane, onQuit }) {
5462
5462
  ] })
5463
5463
  ] }) : /* @__PURE__ */ jsxs7(Fragment, { children: [
5464
5464
  /* @__PURE__ */ jsx7(Separator, {}),
5465
- /* @__PURE__ */ jsx7(ProgressBar, { done: state.sprintInfo?.done ?? 0, total: state.sprintInfo?.total ?? 0 }),
5466
- /* @__PURE__ */ jsx7(EpicInfo, { info: state.sprintInfo }),
5465
+ /* @__PURE__ */ jsx7(ProgressBar, { done: state.sprintInfo?.done ?? 0, total: state.sprintInfo?.total ?? 0, inProgress: state.stories.filter((s) => s.status === "in-progress").length }),
5466
+ /* @__PURE__ */ jsx7(EpicInfo, { info: state.sprintInfo, stories: state.stories }),
5467
5467
  /* @__PURE__ */ jsx7(StoryContext, { entries: state.storyContext ?? [] }),
5468
5468
  /* @__PURE__ */ jsx7(Separator, {}),
5469
5469
  /* @__PURE__ */ jsx7(WorkflowGraph, { flow: state.workflowFlow, currentTask: state.currentTaskName, taskStates: state.taskStates }),
@@ -5499,22 +5499,36 @@ function Header({ info: info3, laneCount }) {
5499
5499
  /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: right })
5500
5500
  ] });
5501
5501
  }
5502
- function ProgressBar({ done, total }) {
5503
- const width = Math.max(10, (process.stdout.columns || 80) - 30);
5504
- const pct = total > 0 ? done / total : 0;
5505
- const filled = Math.round(width * pct);
5506
- const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
5507
- const pctStr = total > 0 ? `${Math.round(pct * 100)}%` : "0%";
5502
+ function ProgressBar({ done, total, inProgress }) {
5503
+ const width = Math.max(10, (process.stdout.columns || 80) - 40);
5504
+ const ip = inProgress ?? 0;
5505
+ const donePct = total > 0 ? done / total : 0;
5506
+ const ipPct = total > 0 ? ip / total : 0;
5507
+ const doneFilled = Math.round(width * donePct);
5508
+ const ipFilled = Math.round(width * ipPct);
5509
+ const empty = Math.max(0, width - doneFilled - ipFilled);
5510
+ const pctStr = total > 0 ? `${Math.round((done + ip) * 100 / total)}%` : "0%";
5511
+ const label = ip > 0 ? `${done} verified + ${ip} in progress / ${total} (${pctStr})` : `${done}/${total} stories (${pctStr})`;
5508
5512
  return /* @__PURE__ */ jsxs8(Text8, { children: [
5509
5513
  "Progress: ",
5510
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: bar }),
5511
- ` ${done}/${total} stories (${pctStr})`
5514
+ /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u2588".repeat(doneFilled) }),
5515
+ /* @__PURE__ */ jsx8(Text8, { color: "yellow", children: "\u2588".repeat(ipFilled) }),
5516
+ /* @__PURE__ */ jsx8(Text8, { children: "\u2591".repeat(empty) }),
5517
+ ` ${label}`
5512
5518
  ] });
5513
5519
  }
5514
- function EpicInfo({ info: info3 }) {
5520
+ function EpicInfo({ info: info3, stories }) {
5515
5521
  if (!info3?.epicId) return null;
5516
5522
  const title = info3.epicTitle ?? `Epic ${info3.epicId}`;
5517
- const progress = info3.epicStoriesTotal ? ` \u2014 ${info3.epicStoriesDone ?? 0}/${info3.epicStoriesTotal} stories done` : "";
5523
+ const epicPrefix2 = `${info3.epicId}-`;
5524
+ const epicStories = stories?.filter((s) => s.key.startsWith(epicPrefix2)) ?? [];
5525
+ const ipCount = epicStories.filter((s) => s.status === "in-progress").length;
5526
+ const doneCount = info3.epicStoriesDone ?? 0;
5527
+ const totalCount = info3.epicStoriesTotal ?? epicStories.length;
5528
+ const progressParts = [];
5529
+ if (doneCount > 0) progressParts.push(`${doneCount} verified`);
5530
+ if (ipCount > 0) progressParts.push(`${ipCount} implemented`);
5531
+ const progress = totalCount > 0 ? ` \u2014 ${progressParts.join(", ")} / ${totalCount} stories` : "";
5518
5532
  return /* @__PURE__ */ jsxs8(Text8, { children: [
5519
5533
  /* @__PURE__ */ jsx8(Text8, { bold: true, children: `Epic ${info3.epicId}: ${title}` }),
5520
5534
  /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: progress })
@@ -5938,18 +5952,28 @@ function startRenderer(options) {
5938
5952
  const ctx = [];
5939
5953
  const currentStory = currentKey ?? "";
5940
5954
  const currentTask = state.currentTaskName ?? "";
5941
- let foundCurrent = false;
5942
- let prevKey = null;
5943
- for (const s of updatedStories) {
5944
- if (s.key === currentStory) {
5945
- if (prevKey) ctx.push({ key: prevKey, role: "prev" });
5946
- ctx.push({ key: s.key, role: "current", task: currentTask });
5947
- foundCurrent = true;
5948
- } else if (foundCurrent && s.status === "pending") {
5949
- ctx.push({ key: s.key, role: "next" });
5950
- break;
5951
- } else if (s.status === "done") {
5952
- prevKey = s.key;
5955
+ const epicMatch = currentStory.match(/^Epic (\d+)/);
5956
+ if (epicMatch) {
5957
+ const epicPrefix2 = `${epicMatch[1]}-`;
5958
+ const epicStories = updatedStories.filter((s) => s.key.startsWith(epicPrefix2));
5959
+ const lastDone = [...epicStories].reverse().find((s) => s.status === "done" || s.status === "in-progress");
5960
+ if (lastDone) ctx.push({ key: lastDone.key, role: "prev" });
5961
+ const ipStory = epicStories.find((s) => s.status === "in-progress");
5962
+ if (ipStory) ctx.push({ key: `${epicStories.length} stories in epic`, role: "current" });
5963
+ } else {
5964
+ let foundCurrent = false;
5965
+ let prevKey = null;
5966
+ for (const s of updatedStories) {
5967
+ if (s.key === currentStory) {
5968
+ if (prevKey) ctx.push({ key: prevKey, role: "prev" });
5969
+ ctx.push({ key: s.key, role: "current" });
5970
+ foundCurrent = true;
5971
+ } else if (foundCurrent && (s.status === "pending" || s.status === "in-progress")) {
5972
+ ctx.push({ key: s.key, role: "next" });
5973
+ break;
5974
+ } else if (s.status === "done" || s.status === "in-progress") {
5975
+ prevKey = s.key;
5976
+ }
5953
5977
  }
5954
5978
  }
5955
5979
  state.storyContext = ctx;
@@ -6251,6 +6275,10 @@ function registerRunCommand(program) {
6251
6275
  renderer.updateStories([...storyEntries]);
6252
6276
  }
6253
6277
  }
6278
+ if (isEpicTask) {
6279
+ const epicStories = storyEntries.filter((s) => s.key.startsWith(`${epicId}-`));
6280
+ renderer.updateStories([...storyEntries]);
6281
+ }
6254
6282
  }
6255
6283
  if (event.type === "dispatch-end") {
6256
6284
  totalCostUsd += event.costUsd ?? 0;
@@ -11082,7 +11110,7 @@ function registerTeardownCommand(program) {
11082
11110
  } else if (otlpMode === "remote-routed") {
11083
11111
  if (!options.keepDocker) {
11084
11112
  try {
11085
- const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-Y73EO7Z4.js");
11113
+ const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-ZMY7GX5P.js");
11086
11114
  stopCollectorOnly2();
11087
11115
  result.docker.stopped = true;
11088
11116
  if (!isJson) {
@@ -11114,7 +11142,7 @@ function registerTeardownCommand(program) {
11114
11142
  info("Shared stack: kept running (other projects may use it)");
11115
11143
  }
11116
11144
  } else if (isLegacyStack) {
11117
- const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-Y73EO7Z4.js");
11145
+ const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-ZMY7GX5P.js");
11118
11146
  let stackRunning = false;
11119
11147
  try {
11120
11148
  stackRunning = isStackRunning2(composeFile);
@@ -14101,7 +14129,7 @@ function registerDriversCommand(program) {
14101
14129
  }
14102
14130
 
14103
14131
  // src/index.ts
14104
- var VERSION = true ? "0.33.0" : "0.0.0-dev";
14132
+ var VERSION = true ? "0.33.1" : "0.0.0-dev";
14105
14133
  function createProgram() {
14106
14134
  const program = new Command();
14107
14135
  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.33.0",
3
+ "version": "0.33.1",
4
4
  "type": "module",
5
5
  "description": "CLI for codeharness — makes autonomous coding agents produce software that actually works",
6
6
  "bin": {