baro-ai 0.69.1 → 0.70.0

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.
package/dist/cli.mjs CHANGED
@@ -1958,12 +1958,12 @@ var require_parse_proxy_response = __commonJS({
1958
1958
  return;
1959
1959
  }
1960
1960
  const headerParts = buffered.slice(0, endOfHeaders).toString("ascii").split("\r\n");
1961
- const firstLine = headerParts.shift();
1962
- if (!firstLine) {
1961
+ const firstLine2 = headerParts.shift();
1962
+ if (!firstLine2) {
1963
1963
  socket.destroy();
1964
1964
  return reject(new Error("No header received from proxy CONNECT response"));
1965
1965
  }
1966
- const firstLineParts = firstLine.split(" ");
1966
+ const firstLineParts = firstLine2.split(" ");
1967
1967
  const statusCode = +firstLineParts[1];
1968
1968
  const statusText = firstLineParts.slice(2).join(" ");
1969
1969
  const headers = {};
@@ -1986,7 +1986,7 @@ var require_parse_proxy_response = __commonJS({
1986
1986
  headers[key] = value;
1987
1987
  }
1988
1988
  }
1989
- debug("got proxy server response: %o %o", firstLine, headers);
1989
+ debug("got proxy server response: %o %o", firstLine2, headers);
1990
1990
  cleanup();
1991
1991
  resolve4({
1992
1992
  connect: {
@@ -22697,6 +22697,7 @@ import { resolve as resolve3 } from "path";
22697
22697
 
22698
22698
  // ../baro-orchestrator/src/orchestrate.ts
22699
22699
  import { mkdirSync as mkdirSync7 } from "fs";
22700
+ import { hostname } from "os";
22700
22701
  import { dirname as dirname3, join as join7 } from "path";
22701
22702
 
22702
22703
  // ../../node_modules/openai/internal/tslib.mjs
@@ -40039,6 +40040,38 @@ async function getGitFileStats(cwd, baseSha) {
40039
40040
  return { created: 0, modified: 0 };
40040
40041
  }
40041
40042
  }
40043
+ var DIFF_LINE_CAP = 180;
40044
+ async function getDiff(cwd, fromSha, toSha = "HEAD") {
40045
+ const files = [];
40046
+ try {
40047
+ const { stdout } = await exec("git", ["diff", "--numstat", fromSha, toSha], { cwd });
40048
+ for (const line of stdout.split("\n")) {
40049
+ if (!line.trim()) continue;
40050
+ const parts = line.split(" ");
40051
+ if (parts.length < 3) continue;
40052
+ const [a, r2] = parts;
40053
+ const path6 = parts.slice(2).join(" ");
40054
+ files.push({
40055
+ path: path6,
40056
+ added: a === "-" ? 0 : parseInt(a, 10) || 0,
40057
+ removed: r2 === "-" ? 0 : parseInt(r2, 10) || 0
40058
+ });
40059
+ }
40060
+ } catch {
40061
+ }
40062
+ let diff = "";
40063
+ try {
40064
+ const { stdout } = await exec("git", ["diff", fromSha, toSha], {
40065
+ cwd,
40066
+ maxBuffer: 16 * 1024 * 1024
40067
+ });
40068
+ const lines = stdout.split("\n");
40069
+ diff = lines.length > DIFF_LINE_CAP ? lines.slice(0, DIFF_LINE_CAP).join("\n") + `
40070
+ \u2026 (${lines.length - DIFF_LINE_CAP} more lines truncated)` : stdout;
40071
+ } catch {
40072
+ }
40073
+ return { files, diff };
40074
+ }
40042
40075
  async function hasRemoteOrigin(cwd) {
40043
40076
  try {
40044
40077
  await exec("git", ["remote", "get-url", "origin"], { cwd });
@@ -43181,33 +43214,94 @@ function emit(event) {
43181
43214
  // ../baro-orchestrator/src/participants/forwarders/agent-stream.ts
43182
43215
  var AgentStreamForwarder = class extends BaseObserver {
43183
43216
  async onExternalModelMessage(source, item) {
43184
- const agentId = source.agentId;
43185
- if (typeof agentId !== "string") return;
43217
+ const agentId = agentIdOf(source);
43218
+ if (!agentId) return;
43186
43219
  const json = item.toJSON();
43187
43220
  const text = json.content?.[0]?.text ?? "";
43188
- if (!text.trim()) return;
43189
- emitMultiline(agentId, text);
43221
+ const line = firstLine(text);
43222
+ if (!line) return;
43223
+ emit({ type: "activity", id: agentId, kind: "agent_msg", text: truncate(line, 160) });
43190
43224
  }
43191
43225
  async onExternalFunctionCall(source, item) {
43192
- const agentId = source.agentId;
43193
- if (typeof agentId !== "string") return;
43194
- emitMultiline(agentId, `[tool_call] ${item.name} ${item.args}`);
43226
+ const agentId = agentIdOf(source);
43227
+ if (!agentId) return;
43228
+ const args = parseArgs(item.args);
43229
+ const tool = item.name;
43230
+ if (tool === "write_file" || tool === "edit_file") {
43231
+ const path6 = strField(args, "path", "file_path", "file") ?? "(file)";
43232
+ const op = tool === "edit_file" ? "modify" : "create";
43233
+ emit({ type: "activity", id: agentId, kind: "file_change", tool: "write", op, path: path6, text: path6 });
43234
+ return;
43235
+ }
43236
+ if (tool === "bash") {
43237
+ const cmd = firstLine(strField(args, "command", "cmd", "script") ?? "");
43238
+ emit({ type: "activity", id: agentId, kind: "tool_call", tool: "bash", text: truncate(cmd || "bash", 140) });
43239
+ return;
43240
+ }
43241
+ const target = strField(args, "path", "file_path", "pattern", "query", "file") ?? "";
43242
+ const text = target ? `${tool} ${target}` : tool;
43243
+ emit({ type: "activity", id: agentId, kind: "tool_call", tool: "read", text: truncate(text, 140) });
43195
43244
  }
43196
43245
  async onExternalFunctionCallOutput(source, item) {
43197
- const agentId = source.agentId;
43198
- if (typeof agentId !== "string") return;
43246
+ const agentId = agentIdOf(source);
43247
+ if (!agentId) return;
43199
43248
  const json = item.toJSON();
43200
- const text = json.output?.[0]?.text ?? "";
43201
- emitMultiline(agentId, `[tool_result ${json.call_id}] ${text}`);
43249
+ const out = json.output?.[0]?.text ?? "";
43250
+ if (!out.trim()) return;
43251
+ const verdict = testVerdict(out);
43252
+ if (verdict !== null) {
43253
+ emit({
43254
+ type: "activity",
43255
+ id: agentId,
43256
+ kind: "test",
43257
+ ok: verdict,
43258
+ text: truncate(firstLine(out) || (verdict ? "tests passed" : "tests failed"), 140)
43259
+ });
43260
+ return;
43261
+ }
43262
+ emit({ type: "activity", id: agentId, kind: "tool_result", text: truncate(firstLine(out), 120) });
43202
43263
  }
43203
43264
  };
43204
- function emitMultiline(agentId, text) {
43205
- if (!text) return;
43206
- const lines = text.split("\n");
43207
- for (const line of lines) {
43208
- if (line.length === 0 && lines.length === 1) continue;
43209
- emit({ type: "story_log", id: agentId, line });
43265
+ function agentIdOf(source) {
43266
+ const id = source.agentId;
43267
+ return typeof id === "string" ? id : null;
43268
+ }
43269
+ function parseArgs(raw) {
43270
+ if (raw && typeof raw === "object") return raw;
43271
+ if (typeof raw === "string") {
43272
+ try {
43273
+ const v = JSON.parse(raw);
43274
+ return v && typeof v === "object" ? v : {};
43275
+ } catch {
43276
+ return {};
43277
+ }
43210
43278
  }
43279
+ return {};
43280
+ }
43281
+ function strField(obj, ...keys) {
43282
+ for (const k of keys) {
43283
+ const v = obj[k];
43284
+ if (typeof v === "string" && v.length > 0) return v;
43285
+ }
43286
+ return void 0;
43287
+ }
43288
+ function firstLine(s2) {
43289
+ for (const l of s2.split("\n")) {
43290
+ const t2 = l.trim();
43291
+ if (t2) return t2;
43292
+ }
43293
+ return "";
43294
+ }
43295
+ function truncate(s2, max) {
43296
+ return s2.length <= max ? s2 : s2.slice(0, max - 1) + "\u2026";
43297
+ }
43298
+ function testVerdict(out) {
43299
+ const s2 = out.toLowerCase();
43300
+ const failed = /\b\d+\s+fail(ed|ing|ures?)?\b/.test(s2) || /(^|\s)fail\b/.test(s2);
43301
+ const passed = /\b(all\s+)?\d+\s+(tests?\s+)?(pass(ed|ing)?|ok)\b/.test(s2) || /\btests?\s+pass(ed)?\b/.test(s2);
43302
+ if (failed) return false;
43303
+ if (passed) return true;
43304
+ return null;
43211
43305
  }
43212
43306
 
43213
43307
  // ../baro-orchestrator/src/participants/forwarders/coordination.ts
@@ -43431,7 +43525,10 @@ var TokenUsageForwarder = class extends BaseObserver {
43431
43525
  type: "token_usage",
43432
43526
  id: item.agentId,
43433
43527
  input_tokens: inputTokens,
43434
- output_tokens: outputTokens
43528
+ output_tokens: outputTokens,
43529
+ // Claude CLI reports a per-result dollar cost; carry it so the TUI
43530
+ // can sum a per-run cost. Null for non-Claude backends.
43531
+ cost_usd: typeof item.totalCostUsd === "number" ? item.totalCostUsd : void 0
43435
43532
  });
43436
43533
  }
43437
43534
  handleCodexTurnEvent(item) {
@@ -43680,7 +43777,7 @@ function describeCall(tool, args) {
43680
43777
  if (pattern) tags.push(pattern);
43681
43778
  } else if (tool === "Bash") {
43682
43779
  const cmd = stringArg(args, "command");
43683
- summary = `Bash ${truncate(cmd ?? "", 80)}`;
43780
+ summary = `Bash ${truncate2(cmd ?? "", 80)}`;
43684
43781
  if (cmd) tags.push(cmd.split(/\s+/)[0] ?? "");
43685
43782
  } else if (tool === "WebFetch") {
43686
43783
  const url = stringArg(args, "url");
@@ -43688,7 +43785,7 @@ function describeCall(tool, args) {
43688
43785
  if (url) tags.push(url);
43689
43786
  } else if (tool === "WebSearch") {
43690
43787
  const q = stringArg(args, "query");
43691
- summary = `WebSearch '${truncate(q ?? "", 60)}'`;
43788
+ summary = `WebSearch '${truncate2(q ?? "", 60)}'`;
43692
43789
  if (q) tags.push(q);
43693
43790
  }
43694
43791
  return { tags: tags.filter((t2) => t2.length > 0), summary };
@@ -43697,7 +43794,7 @@ function stringArg(args, key) {
43697
43794
  const v = args[key];
43698
43795
  return typeof v === "string" ? v : void 0;
43699
43796
  }
43700
- function truncate(s2, n) {
43797
+ function truncate2(s2, n) {
43701
43798
  return s2.length > n ? `${s2.slice(0, n)}\u2026` : s2;
43702
43799
  }
43703
43800
  function formatEntry(k) {
@@ -44261,10 +44358,10 @@ var CodexCliParticipant = class _CodexCliParticipant extends BaseObserver {
44261
44358
  super();
44262
44359
  this.agentId = agentId;
44263
44360
  this.options = {
44264
- codexBin: "codex",
44265
- bypassSandbox: false,
44266
- skipGitRepoCheck: false,
44267
- ...opts
44361
+ ...opts,
44362
+ codexBin: opts.codexBin ?? "codex",
44363
+ bypassSandbox: opts.bypassSandbox ?? false,
44364
+ skipGitRepoCheck: opts.skipGitRepoCheck ?? false
44268
44365
  };
44269
44366
  this.ready = new Promise((res, rej) => {
44270
44367
  this.resolveReady = res;
@@ -44607,6 +44704,7 @@ var CodexStoryAgent = class extends BaseObserver {
44607
44704
  cwd: this.spec.cwd,
44608
44705
  prompt: this.spec.prompt,
44609
44706
  model: this.spec.model,
44707
+ codexBin: this.spec.codexBin,
44610
44708
  bypassSandbox: this.spec.bypassSandbox,
44611
44709
  skipGitRepoCheck: this.spec.skipGitRepoCheck
44612
44710
  });
@@ -45594,9 +45692,9 @@ var OpenCodeCliParticipant = class _OpenCodeCliParticipant extends BaseObserver
45594
45692
  super();
45595
45693
  this.agentId = agentId;
45596
45694
  this.options = {
45597
- opencodeBin: "opencode",
45598
- skipPermissions: true,
45599
- ...opts
45695
+ ...opts,
45696
+ opencodeBin: opts.opencodeBin ?? "opencode",
45697
+ skipPermissions: opts.skipPermissions ?? true
45600
45698
  };
45601
45699
  this.ready = new Promise((res, rej) => {
45602
45700
  this.resolveReady = res;
@@ -45964,6 +46062,7 @@ var OpenCodeStoryAgent = class extends BaseObserver {
45964
46062
  cwd: this.spec.cwd,
45965
46063
  prompt: this.spec.prompt,
45966
46064
  model: this.spec.model,
46065
+ opencodeBin: this.spec.opencodeBin,
45967
46066
  skipPermissions: this.spec.skipPermissions
45968
46067
  });
45969
46068
  this.currentOpenCode = opencode;
@@ -46278,8 +46377,8 @@ var PiCliParticipant = class _PiCliParticipant extends BaseObserver {
46278
46377
  super();
46279
46378
  this.agentId = agentId;
46280
46379
  this.options = {
46281
- piBin: "pi",
46282
- ...opts
46380
+ ...opts,
46381
+ piBin: opts.piBin ?? "pi"
46283
46382
  };
46284
46383
  this.ready = new Promise((res, rej) => {
46285
46384
  this.resolveReady = res;
@@ -46737,7 +46836,8 @@ var PiStoryAgent = class extends BaseObserver {
46737
46836
  cwd: this.spec.cwd,
46738
46837
  prompt: this.spec.prompt,
46739
46838
  provider: this.spec.provider,
46740
- model: this.spec.model
46839
+ model: this.spec.model,
46840
+ piBin: this.spec.piBin
46741
46841
  });
46742
46842
  this.currentPi = pi;
46743
46843
  pi.join(this.envRef);
@@ -46938,11 +47038,11 @@ var ClaudeCliParticipant = class _ClaudeCliParticipant extends BaseObserver {
46938
47038
  super();
46939
47039
  this.agentId = agentId;
46940
47040
  this.options = {
46941
- includePartialMessages: false,
46942
- replayUserMessages: true,
46943
- permissionMode: "bypassPermissions",
46944
- claudeBin: "claude",
46945
- ...opts
47041
+ ...opts,
47042
+ includePartialMessages: opts.includePartialMessages ?? false,
47043
+ replayUserMessages: opts.replayUserMessages ?? true,
47044
+ permissionMode: opts.permissionMode ?? "bypassPermissions",
47045
+ claudeBin: opts.claudeBin ?? "claude"
46946
47046
  };
46947
47047
  this.ready = new Promise((res, rej) => {
46948
47048
  this.resolveReady = res;
@@ -47344,7 +47444,8 @@ var StoryAgent = class extends BaseObserver {
47344
47444
  const claude = new ClaudeCliParticipant(this.spec.id, {
47345
47445
  cwd: this.spec.cwd,
47346
47446
  model: this.spec.model,
47347
- effort: this.spec.effort
47447
+ effort: this.spec.effort,
47448
+ claudeBin: this.spec.claudeBin
47348
47449
  });
47349
47450
  this.currentClaude = claude;
47350
47451
  claude.join(this.envRef);
@@ -48446,6 +48547,7 @@ async function orchestrate(config) {
48446
48547
  } : void 0,
48447
48548
  onStoryPassed: useGit ? async (storyId) => {
48448
48549
  const log2 = (line) => emitTui && emit({ type: "story_log", id: storyId, line });
48550
+ const beforeMerge = emitTui ? await getHeadSha(config.cwd) : null;
48449
48551
  if (worktrees) {
48450
48552
  let merged = false;
48451
48553
  try {
@@ -48458,6 +48560,17 @@ async function orchestrate(config) {
48458
48560
  return;
48459
48561
  }
48460
48562
  if (merged) {
48563
+ if (emitTui && beforeMerge) {
48564
+ const d = await getDiff(config.cwd, beforeMerge, "HEAD");
48565
+ if (d.files.length) {
48566
+ emit({
48567
+ type: "story_diff",
48568
+ id: storyId,
48569
+ files: d.files,
48570
+ diff: d.diff || void 0
48571
+ });
48572
+ }
48573
+ }
48461
48574
  await worktrees.cleanup(storyId);
48462
48575
  worktreePushNeeded = true;
48463
48576
  if (emitTui) {
@@ -48509,7 +48622,8 @@ async function orchestrate(config) {
48509
48622
  id: s2.id,
48510
48623
  title: s2.title,
48511
48624
  depends_on: s2.dependsOn
48512
- }))
48625
+ })),
48626
+ runner: hostname()
48513
48627
  });
48514
48628
  const dagLevels = buildDag(prd.userStories).map(
48515
48629
  (lvl) => lvl.storyIds.map((id) => ({ id }))
@@ -48544,6 +48658,17 @@ async function orchestrate(config) {
48544
48658
  const stats2 = await getGitFileStats(config.cwd, baseSha);
48545
48659
  filesCreated = stats2.created;
48546
48660
  filesModified = stats2.modified;
48661
+ if (emitTui) {
48662
+ const runDiff = await getDiff(config.cwd, baseSha, "HEAD");
48663
+ if (runDiff.files.length) {
48664
+ emit({
48665
+ type: "story_diff",
48666
+ id: "(run)",
48667
+ files: runDiff.files,
48668
+ diff: runDiff.diff || void 0
48669
+ });
48670
+ }
48671
+ }
48547
48672
  }
48548
48673
  if (emitTui) {
48549
48674
  emit({
@@ -48579,7 +48704,7 @@ function tokenizeForHints(text) {
48579
48704
  }
48580
48705
 
48581
48706
  // ../baro-orchestrator/scripts/cli.ts
48582
- function parseArgs(argv) {
48707
+ function parseArgs2(argv) {
48583
48708
  const args = {
48584
48709
  prd: "prd.json",
48585
48710
  cwd: ".",
@@ -48766,7 +48891,7 @@ function printHelp() {
48766
48891
  );
48767
48892
  }
48768
48893
  async function main() {
48769
- const args = parseArgs(process.argv.slice(2));
48894
+ const args = parseArgs2(process.argv.slice(2));
48770
48895
  if (args.help) {
48771
48896
  printHelp();
48772
48897
  return;