codeharness 0.30.0 → 0.30.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.30.0" : "0.0.0-dev";
2898
+ var HARNESS_VERSION = true ? "0.30.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-S3RKDJMC.js";
19
+ } from "./chunk-QLY7NJIB.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-S3RKDJMC.js";
43
+ } from "./chunk-QLY7NJIB.js";
44
44
 
45
45
  // src/index.ts
46
46
  import { Command } from "commander";
@@ -5046,15 +5046,29 @@ function CompletedTool({ entry }) {
5046
5046
  entry.driver && /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` (${entry.driver})` })
5047
5047
  ] });
5048
5048
  }
5049
- var VISIBLE_COMPLETED_TOOLS = 5;
5050
- function CompletedTools({ tools }) {
5051
- const visible = tools.slice(-VISIBLE_COMPLETED_TOOLS);
5049
+ var DEFAULT_VISIBLE_TOOLS = 5;
5050
+ function CompletedTools({ tools, maxVisible }) {
5051
+ const limit = maxVisible ?? DEFAULT_VISIBLE_TOOLS;
5052
+ const visible = tools.slice(-limit);
5052
5053
  const hidden = tools.length - visible.length;
5053
5054
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
5054
5055
  hidden > 0 && /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2026 ${hidden} earlier tools` }),
5055
5056
  visible.map((entry, i) => /* @__PURE__ */ jsx(CompletedTool, { entry }, i))
5056
5057
  ] });
5057
5058
  }
5059
+ function ActivitySection({ completedTools, activeTool, activeDriverName, lastThought, retryInfo, availableHeight }) {
5060
+ let reserved = 0;
5061
+ if (activeTool) reserved++;
5062
+ if (lastThought) reserved++;
5063
+ if (retryInfo) reserved++;
5064
+ const toolsHeight = Math.max(1, availableHeight - reserved - 1);
5065
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [
5066
+ /* @__PURE__ */ jsx(CompletedTools, { tools: completedTools, maxVisible: toolsHeight }),
5067
+ activeTool && /* @__PURE__ */ jsx(ActiveTool, { name: activeTool.name, driverName: activeDriverName }),
5068
+ lastThought && /* @__PURE__ */ jsx(LastThought, { text: lastThought }),
5069
+ retryInfo && /* @__PURE__ */ jsx(RetryNotice, { info: retryInfo })
5070
+ ] });
5071
+ }
5058
5072
  function ActiveTool({ name, driverName }) {
5059
5073
  return /* @__PURE__ */ jsxs(Box, { children: [
5060
5074
  /* @__PURE__ */ jsx(Text, { color: "yellow", children: "\u26A1 " }),
@@ -5080,13 +5094,6 @@ function RetryNotice({ info: info3 }) {
5080
5094
  "ms)"
5081
5095
  ] });
5082
5096
  }
5083
- function DriverCostSummary({ driverCosts }) {
5084
- if (!driverCosts) return null;
5085
- const entries = Object.entries(driverCosts).sort(([a], [b]) => a.localeCompare(b));
5086
- if (entries.length === 0) return null;
5087
- const parts = entries.map(([driver, cost]) => `${driver} $${cost.toFixed(2)}`).join(", ");
5088
- return /* @__PURE__ */ jsx(Text, { dimColor: true, children: `Cost: ${parts}` });
5089
- }
5090
5097
 
5091
5098
  // src/lib/ink-app.tsx
5092
5099
  import { Box as Box7, Static, Text as Text7, useInput } from "ink";
@@ -5559,29 +5566,36 @@ function App({ state, onCycleLane, onQuit }) {
5559
5566
  }
5560
5567
  }, { isActive: typeof process.stdin.setRawMode === "function" });
5561
5568
  const activeLaneCount = state.laneCount ?? 0;
5569
+ const termRows = process.stdout.rows || 24;
5570
+ const fixedHeight = 10;
5571
+ const availableHeight = Math.max(3, termRows - fixedHeight);
5562
5572
  return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
5563
5573
  /* @__PURE__ */ jsx7(Static, { items: state.messages, children: (msg, i) => /* @__PURE__ */ jsx7(StoryMessageLine, { msg }, i) }),
5564
5574
  /* @__PURE__ */ jsx7(Header, { info: state.sprintInfo, laneCount: laneCount > 1 ? laneCount : void 0 }),
5565
- laneCount > 1 ? /* @__PURE__ */ jsx7(LaneContainer, { lanes, terminalWidth }) : /* @__PURE__ */ jsxs7(Fragment, { children: [
5566
- /* @__PURE__ */ jsx7(WorkflowGraph, { flow: state.workflowFlow, currentTask: state.currentTaskName, taskStates: state.taskStates, taskMeta: state.taskMeta }),
5567
- /* @__PURE__ */ jsx7(StoryBreakdown, { stories: state.stories, sprintInfo: state.sprintInfo }),
5568
- /* @__PURE__ */ jsx7(DriverCostSummary, { driverCosts: state.driverCosts })
5569
- ] }),
5570
- laneCount > 1 && state.summaryBar && /* @__PURE__ */ jsxs7(Fragment, { children: [
5575
+ laneCount > 1 ? /* @__PURE__ */ jsxs7(Fragment, { children: [
5576
+ /* @__PURE__ */ jsx7(LaneContainer, { lanes, terminalWidth }),
5577
+ state.summaryBar && /* @__PURE__ */ jsxs7(Fragment, { children: [
5578
+ /* @__PURE__ */ jsx7(Separator, {}),
5579
+ /* @__PURE__ */ jsx7(SummaryBar, { ...state.summaryBar })
5580
+ ] }),
5581
+ state.mergeState && /* @__PURE__ */ jsxs7(Fragment, { children: [
5582
+ /* @__PURE__ */ jsx7(Separator, {}),
5583
+ /* @__PURE__ */ jsx7(MergeStatus, { mergeState: state.mergeState })
5584
+ ] }),
5571
5585
  /* @__PURE__ */ jsx7(Separator, {}),
5572
- /* @__PURE__ */ jsx7(SummaryBar, { ...state.summaryBar })
5573
- ] }),
5574
- laneCount > 1 && state.mergeState && /* @__PURE__ */ jsxs7(Fragment, { children: [
5586
+ /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingLeft: 1, children: [
5587
+ /* @__PURE__ */ jsx7(LaneActivityHeader, { activeLaneId: state.activeLaneId ?? null, laneCount: activeLaneCount }),
5588
+ /* @__PURE__ */ jsx7(ActivitySection, { completedTools: state.completedTools, activeTool: state.activeTool, activeDriverName: state.activeDriverName, lastThought: state.lastThought, retryInfo: state.retryInfo, availableHeight })
5589
+ ] })
5590
+ ] }) : /* @__PURE__ */ jsxs7(Fragment, { children: [
5575
5591
  /* @__PURE__ */ jsx7(Separator, {}),
5576
- /* @__PURE__ */ jsx7(MergeStatus, { mergeState: state.mergeState })
5577
- ] }),
5578
- (state.stories.length > 0 || laneCount > 1 && (state.summaryBar || state.mergeState)) && /* @__PURE__ */ jsx7(Separator, {}),
5579
- /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingLeft: 1, children: [
5580
- /* @__PURE__ */ jsx7(LaneActivityHeader, { activeLaneId: state.activeLaneId ?? null, laneCount: activeLaneCount }),
5581
- /* @__PURE__ */ jsx7(CompletedTools, { tools: state.completedTools }),
5582
- state.activeTool && /* @__PURE__ */ jsx7(ActiveTool, { name: state.activeTool.name, driverName: state.activeDriverName }),
5583
- state.lastThought && /* @__PURE__ */ jsx7(LastThought, { text: state.lastThought }),
5584
- state.retryInfo && /* @__PURE__ */ jsx7(RetryNotice, { info: state.retryInfo })
5592
+ /* @__PURE__ */ jsx7(ProgressBar, { done: state.sprintInfo?.done ?? 0, total: state.sprintInfo?.total ?? 0 }),
5593
+ /* @__PURE__ */ jsx7(EpicInfo, { info: state.sprintInfo }),
5594
+ /* @__PURE__ */ jsx7(StoryContext, { entries: state.storyContext ?? [] }),
5595
+ /* @__PURE__ */ jsx7(Separator, {}),
5596
+ /* @__PURE__ */ jsx7(WorkflowGraph, { flow: state.workflowFlow, currentTask: state.currentTaskName, taskStates: state.taskStates }),
5597
+ /* @__PURE__ */ jsx7(Separator, {}),
5598
+ /* @__PURE__ */ jsx7(ActivitySection, { completedTools: state.completedTools, activeTool: state.activeTool, activeDriverName: state.activeDriverName, lastThought: state.lastThought, retryInfo: state.retryInfo, availableHeight })
5585
5599
  ] })
5586
5600
  ] });
5587
5601
  }
@@ -5602,133 +5616,48 @@ function formatCost3(cost) {
5602
5616
  function Header({ info: info3, laneCount }) {
5603
5617
  if (!info3) return null;
5604
5618
  const parts = ["codeharness run"];
5605
- if (laneCount != null && laneCount > 1) {
5606
- parts.push(`${laneCount} lanes`);
5607
- }
5608
- if (info3.iterationCount != null) {
5609
- parts.push(`iteration ${info3.iterationCount}`);
5610
- }
5611
- if (info3.elapsed) {
5612
- parts.push(`${info3.elapsed} elapsed`);
5613
- }
5619
+ if (laneCount != null && laneCount > 1) parts.push(`${laneCount} lanes`);
5620
+ if (info3.elapsed) parts.push(`${info3.elapsed} elapsed`);
5614
5621
  const displayCost = laneCount != null && laneCount > 1 && info3.laneTotalCost != null ? info3.laneTotalCost : info3.totalCost;
5615
- if (displayCost != null) {
5616
- parts.push(`${formatCost3(displayCost)} spent`);
5617
- }
5618
- const headerLine = parts.join(" | ");
5619
- let phaseLine = "";
5620
- if (info3.phase) {
5621
- phaseLine = `Phase: ${info3.phase}`;
5622
- if (info3.acProgress) {
5623
- phaseLine += ` \u2192 AC ${info3.acProgress}`;
5624
- }
5625
- if (info3.currentCommand) {
5626
- phaseLine += ` (${info3.currentCommand})`;
5627
- }
5628
- }
5629
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
5630
- /* @__PURE__ */ jsx8(Text8, { children: headerLine }),
5631
- /* @__PURE__ */ jsx8(Separator, {}),
5632
- /* @__PURE__ */ jsx8(Text8, { children: `Story: ${info3.storyKey || "(waiting)"}` }),
5633
- phaseLine && /* @__PURE__ */ jsx8(Text8, { children: phaseLine })
5622
+ if (displayCost != null) parts.push(`${formatCost3(displayCost)} spent`);
5623
+ const left = parts.join(" | ");
5624
+ const right = "[q to quit]";
5625
+ const width = process.stdout.columns || 80;
5626
+ const pad = Math.max(0, width - left.length - right.length);
5627
+ return /* @__PURE__ */ jsxs8(Text8, { children: [
5628
+ left,
5629
+ " ".repeat(pad),
5630
+ /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: right })
5634
5631
  ] });
5635
5632
  }
5636
- function StoryBreakdown({ stories, sprintInfo }) {
5637
- if (stories.length === 0) return null;
5638
- const done = [];
5639
- const inProgress = [];
5640
- const pending = [];
5641
- const failed = [];
5642
- const blocked = [];
5643
- for (const s of stories) {
5644
- switch (s.status) {
5645
- case "done":
5646
- done.push(s);
5647
- break;
5648
- case "in-progress":
5649
- inProgress.push(s);
5650
- break;
5651
- case "pending":
5652
- pending.push(s);
5653
- break;
5654
- case "failed":
5655
- failed.push(s);
5656
- break;
5657
- case "blocked":
5658
- blocked.push(s);
5659
- break;
5660
- }
5661
- }
5662
- const lines = [];
5663
- if (done.length > 0) {
5664
- const doneItems = done.map((s) => {
5665
- let item = `${shortKey(s.key)} \u2713`;
5666
- if (s.costByDriver && Object.keys(s.costByDriver).length > 0) {
5667
- const costParts = Object.keys(s.costByDriver).sort().map(
5668
- (driver) => `${driver} ${formatCost3(s.costByDriver[driver])}`
5669
- );
5670
- item += ` ${costParts.join(", ")}`;
5671
- }
5672
- return item;
5673
- }).join(" ");
5674
- lines.push(
5675
- /* @__PURE__ */ jsxs8(Text8, { children: [
5676
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: "Done: " }),
5677
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: doneItems })
5678
- ] }, "done")
5679
- );
5680
- }
5681
- if (inProgress.length > 0) {
5682
- for (const s of inProgress) {
5683
- let thisText = `${shortKey(s.key)} \u25C6`;
5684
- if (sprintInfo && sprintInfo.storyKey && shortKey(s.key) === shortKey(sprintInfo.storyKey)) {
5685
- if (sprintInfo.phase) thisText += ` ${sprintInfo.phase}`;
5686
- if (sprintInfo.acProgress) thisText += ` (${sprintInfo.acProgress} ACs)`;
5687
- }
5688
- lines.push(
5689
- /* @__PURE__ */ jsxs8(Text8, { children: [
5690
- /* @__PURE__ */ jsx8(Text8, { color: "cyan", children: "This: " }),
5691
- /* @__PURE__ */ jsx8(Text8, { color: "cyan", children: thisText })
5692
- ] }, `this-${s.key}`)
5693
- );
5694
- }
5695
- }
5696
- if (pending.length > 0) {
5697
- lines.push(
5698
- /* @__PURE__ */ jsxs8(Text8, { children: [
5699
- /* @__PURE__ */ jsx8(Text8, { children: "Next: " }),
5700
- /* @__PURE__ */ jsx8(Text8, { children: shortKey(pending[0].key) }),
5701
- pending.length > 1 && /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: ` (+${pending.length - 1} more)` })
5702
- ] }, "next")
5703
- );
5704
- }
5705
- if (blocked.length > 0) {
5706
- const blockedItems = blocked.map((s) => {
5707
- let item = `${shortKey(s.key)} \u2715`;
5708
- if (s.retryCount != null && s.maxRetries != null) item += ` (${s.retryCount}/${s.maxRetries})`;
5709
- return item;
5710
- }).join(" ");
5711
- lines.push(
5712
- /* @__PURE__ */ jsxs8(Text8, { children: [
5713
- /* @__PURE__ */ jsx8(Text8, { color: "yellow", children: "Blocked: " }),
5714
- /* @__PURE__ */ jsx8(Text8, { color: "yellow", children: blockedItems })
5715
- ] }, "blocked")
5716
- );
5717
- }
5718
- if (failed.length > 0) {
5719
- const failedItems = failed.map((s) => {
5720
- let item = `${shortKey(s.key)} \u2717`;
5721
- if (s.retryCount != null && s.maxRetries != null) item += ` (${s.retryCount}/${s.maxRetries})`;
5722
- return item;
5723
- }).join(" ");
5724
- lines.push(
5725
- /* @__PURE__ */ jsxs8(Text8, { children: [
5726
- /* @__PURE__ */ jsx8(Text8, { color: "red", children: "Failed: " }),
5727
- /* @__PURE__ */ jsx8(Text8, { color: "red", children: failedItems })
5728
- ] }, "failed")
5729
- );
5730
- }
5731
- return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", children: lines });
5633
+ function ProgressBar({ done, total }) {
5634
+ const width = Math.max(10, (process.stdout.columns || 80) - 30);
5635
+ const pct = total > 0 ? done / total : 0;
5636
+ const filled = Math.round(width * pct);
5637
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
5638
+ const pctStr = total > 0 ? `${Math.round(pct * 100)}%` : "0%";
5639
+ return /* @__PURE__ */ jsxs8(Text8, { children: [
5640
+ "Progress: ",
5641
+ /* @__PURE__ */ jsx8(Text8, { color: "green", children: bar }),
5642
+ ` ${done}/${total} stories (${pctStr})`
5643
+ ] });
5644
+ }
5645
+ function EpicInfo({ info: info3 }) {
5646
+ if (!info3?.epicId) return null;
5647
+ const title = info3.epicTitle ?? `Epic ${info3.epicId}`;
5648
+ const progress = info3.epicStoriesTotal ? ` \u2014 ${info3.epicStoriesDone ?? 0}/${info3.epicStoriesTotal} stories done` : "";
5649
+ return /* @__PURE__ */ jsxs8(Text8, { children: [
5650
+ /* @__PURE__ */ jsx8(Text8, { bold: true, children: `Epic ${info3.epicId}: ${title}` }),
5651
+ /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: progress })
5652
+ ] });
5653
+ }
5654
+ function StoryContext({ entries }) {
5655
+ if (entries.length === 0) return null;
5656
+ return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", children: entries.map((e, i) => {
5657
+ if (e.role === "prev") return /* @__PURE__ */ jsx8(Text8, { children: /* @__PURE__ */ jsx8(Text8, { color: "green", children: ` Prev: ${shortKey(e.key)} \u2713` }) }, i);
5658
+ if (e.role === "current") return /* @__PURE__ */ jsx8(Text8, { children: /* @__PURE__ */ jsx8(Text8, { color: "cyan", children: ` This: ${shortKey(e.key)} \u25C6 ${e.task ?? ""}` }) }, i);
5659
+ return /* @__PURE__ */ jsx8(Text8, { children: /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: ` Next: ${shortKey(e.key)}` }) }, i);
5660
+ }) });
5732
5661
  }
5733
5662
 
5734
5663
  // src/lib/ink-renderer.tsx
@@ -5771,6 +5700,7 @@ function startRenderer(options) {
5771
5700
  taskMeta: {},
5772
5701
  activeDriverName: null,
5773
5702
  driverCosts: {},
5703
+ storyContext: [],
5774
5704
  activeLaneId: null,
5775
5705
  laneCount: 0
5776
5706
  };
@@ -6125,6 +6055,24 @@ function startRenderer(options) {
6125
6055
  lastStoryKey = currentKey;
6126
6056
  }
6127
6057
  state.stories = updatedStories;
6058
+ const ctx = [];
6059
+ const currentStory = currentKey ?? "";
6060
+ const currentTask = state.currentTaskName ?? "";
6061
+ let foundCurrent = false;
6062
+ let prevKey = null;
6063
+ for (const s of updatedStories) {
6064
+ if (s.key === currentStory) {
6065
+ if (prevKey) ctx.push({ key: prevKey, role: "prev" });
6066
+ ctx.push({ key: s.key, role: "current", task: currentTask });
6067
+ foundCurrent = true;
6068
+ } else if (foundCurrent && s.status === "pending") {
6069
+ ctx.push({ key: s.key, role: "next" });
6070
+ break;
6071
+ } else if (s.status === "done") {
6072
+ prevKey = s.key;
6073
+ }
6074
+ }
6075
+ state.storyContext = ctx;
6128
6076
  rerender();
6129
6077
  }
6130
6078
  function addMessage(msg) {
@@ -6326,15 +6274,28 @@ function registerRunCommand(program) {
6326
6274
  let currentTaskName = "";
6327
6275
  const headerRefresh = setInterval(() => {
6328
6276
  if (interrupted) return;
6277
+ const epicId = currentStoryKey ? extractEpicId2(currentStoryKey) : "";
6278
+ const epic = epicId ? epicData[epicId] : void 0;
6329
6279
  renderer.updateSprintState({
6330
6280
  storyKey: currentStoryKey,
6331
6281
  phase: currentTaskName,
6332
6282
  done: storiesDone,
6333
6283
  total: counts.total,
6334
6284
  totalCost: totalCostUsd,
6335
- elapsed: formatElapsed(Date.now() - sessionStartMs)
6285
+ elapsed: formatElapsed(Date.now() - sessionStartMs),
6286
+ epicId: epicId || void 0,
6287
+ epicStoriesDone: epic?.storiesDone,
6288
+ epicStoriesTotal: epic?.storiesTotal
6336
6289
  });
6337
6290
  }, 2e3);
6291
+ const epicData = {};
6292
+ const sprintStateResult = getSprintState2();
6293
+ if (sprintStateResult.success) {
6294
+ for (const [epicKey, epic] of Object.entries(sprintStateResult.data.epics ?? {})) {
6295
+ const epicId = epicKey.replace("epic-", "");
6296
+ epicData[epicId] = { storiesDone: epic.storiesDone ?? 0, storiesTotal: epic.storiesTotal ?? 0 };
6297
+ }
6298
+ }
6338
6299
  const taskStates = {};
6339
6300
  const taskMeta = {};
6340
6301
  for (const [tn, task] of Object.entries(parsedWorkflow.tasks)) {
@@ -6357,13 +6318,18 @@ function registerRunCommand(program) {
6357
6318
  if (event.type === "dispatch-start") {
6358
6319
  currentStoryKey = event.storyKey;
6359
6320
  currentTaskName = event.taskName;
6321
+ const epicId = extractEpicId2(event.storyKey);
6322
+ const epic = epicData[epicId];
6360
6323
  renderer.updateSprintState({
6361
6324
  storyKey: event.storyKey,
6362
6325
  phase: event.taskName,
6363
6326
  done: storiesDone,
6364
6327
  total: counts.total,
6365
6328
  totalCost: totalCostUsd,
6366
- elapsed: formatElapsed(Date.now() - sessionStartMs)
6329
+ elapsed: formatElapsed(Date.now() - sessionStartMs),
6330
+ epicId,
6331
+ epicStoriesDone: epic?.storiesDone ?? 0,
6332
+ epicStoriesTotal: epic?.storiesTotal ?? 0
6367
6333
  });
6368
6334
  taskStates[event.taskName] = "active";
6369
6335
  renderer.updateWorkflowState(parsedWorkflow.flow, event.taskName, { ...taskStates }, { ...taskMeta });
@@ -11290,7 +11256,7 @@ function registerTeardownCommand(program) {
11290
11256
  } else if (otlpMode === "remote-routed") {
11291
11257
  if (!options.keepDocker) {
11292
11258
  try {
11293
- const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-7QONH2B5.js");
11259
+ const { stopCollectorOnly: stopCollectorOnly2 } = await import("./docker-P65B7Z3S.js");
11294
11260
  stopCollectorOnly2();
11295
11261
  result.docker.stopped = true;
11296
11262
  if (!isJson) {
@@ -11322,7 +11288,7 @@ function registerTeardownCommand(program) {
11322
11288
  info("Shared stack: kept running (other projects may use it)");
11323
11289
  }
11324
11290
  } else if (isLegacyStack) {
11325
- const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-7QONH2B5.js");
11291
+ const { isStackRunning: isStackRunning2, stopStack } = await import("./docker-P65B7Z3S.js");
11326
11292
  let stackRunning = false;
11327
11293
  try {
11328
11294
  stackRunning = isStackRunning2(composeFile);
@@ -14218,7 +14184,7 @@ function registerDriversCommand(program) {
14218
14184
  }
14219
14185
 
14220
14186
  // src/index.ts
14221
- var VERSION = true ? "0.30.0" : "0.0.0-dev";
14187
+ var VERSION = true ? "0.30.1" : "0.0.0-dev";
14222
14188
  function createProgram() {
14223
14189
  const program = new Command();
14224
14190
  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.30.0",
3
+ "version": "0.30.1",
4
4
  "type": "module",
5
5
  "description": "CLI for codeharness — makes autonomous coding agents produce software that actually works",
6
6
  "bin": {