baro-ai 0.22.1 → 0.22.3

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
@@ -7525,6 +7525,55 @@ function extractStderr(e) {
7525
7525
  return e instanceof Error ? e.message : String(e);
7526
7526
  }
7527
7527
 
7528
+ // ../baro-orchestrator/src/dag.ts
7529
+ function buildDag(stories, options = {}) {
7530
+ const onlyIncomplete = options.onlyIncomplete ?? false;
7531
+ const completedIds = new Set(
7532
+ stories.filter((s) => s.passes === true).map((s) => s.id)
7533
+ );
7534
+ const active = onlyIncomplete ? stories.filter((s) => s.passes !== true) : stories.slice();
7535
+ const storyMap = new Map(active.map((s) => [s.id, s]));
7536
+ const inDegree = /* @__PURE__ */ new Map();
7537
+ const dependents = /* @__PURE__ */ new Map();
7538
+ for (const s of active) {
7539
+ const activeDeps = (s.dependsOn ?? []).filter(
7540
+ (d) => storyMap.has(d) && (!onlyIncomplete || !completedIds.has(d))
7541
+ );
7542
+ inDegree.set(s.id, activeDeps.length);
7543
+ for (const dep of activeDeps) {
7544
+ const list = dependents.get(dep) ?? [];
7545
+ list.push(s.id);
7546
+ dependents.set(dep, list);
7547
+ }
7548
+ }
7549
+ const levels = [];
7550
+ let queue = active.filter((s) => (inDegree.get(s.id) ?? 0) === 0);
7551
+ while (queue.length > 0) {
7552
+ queue.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
7553
+ levels.push({ storyIds: queue.map((s) => s.id) });
7554
+ const next = [];
7555
+ for (const s of queue) {
7556
+ const deps = dependents.get(s.id);
7557
+ if (!deps) continue;
7558
+ for (const dependentId of deps) {
7559
+ const remaining = (inDegree.get(dependentId) ?? 0) - 1;
7560
+ inDegree.set(dependentId, remaining);
7561
+ if (remaining === 0) {
7562
+ const story = storyMap.get(dependentId);
7563
+ if (story) next.push(story);
7564
+ }
7565
+ }
7566
+ }
7567
+ queue = next;
7568
+ }
7569
+ const placed = new Set(levels.flatMap((l) => l.storyIds));
7570
+ if (placed.size !== active.length) {
7571
+ const cycled = active.filter((s) => !placed.has(s.id)).map((s) => s.id);
7572
+ throw new Error(`Dependency cycle detected: ${cycled.join(", ")}`);
7573
+ }
7574
+ return levels;
7575
+ }
7576
+
7528
7577
  // ../baro-orchestrator/src/participants/auditor.ts
7529
7578
  import { appendFileSync, mkdirSync } from "fs";
7530
7579
  import { dirname } from "path";
@@ -7901,55 +7950,6 @@ var Auditor = class extends Participant {
7901
7950
  import { existsSync, readFileSync as readFileSync2 } from "fs";
7902
7951
  import { join } from "path";
7903
7952
 
7904
- // ../baro-orchestrator/src/dag.ts
7905
- function buildDag(stories, options = {}) {
7906
- const onlyIncomplete = options.onlyIncomplete ?? false;
7907
- const completedIds = new Set(
7908
- stories.filter((s) => s.passes === true).map((s) => s.id)
7909
- );
7910
- const active = onlyIncomplete ? stories.filter((s) => s.passes !== true) : stories.slice();
7911
- const storyMap = new Map(active.map((s) => [s.id, s]));
7912
- const inDegree = /* @__PURE__ */ new Map();
7913
- const dependents = /* @__PURE__ */ new Map();
7914
- for (const s of active) {
7915
- const activeDeps = (s.dependsOn ?? []).filter(
7916
- (d) => storyMap.has(d) && (!onlyIncomplete || !completedIds.has(d))
7917
- );
7918
- inDegree.set(s.id, activeDeps.length);
7919
- for (const dep of activeDeps) {
7920
- const list = dependents.get(dep) ?? [];
7921
- list.push(s.id);
7922
- dependents.set(dep, list);
7923
- }
7924
- }
7925
- const levels = [];
7926
- let queue = active.filter((s) => (inDegree.get(s.id) ?? 0) === 0);
7927
- while (queue.length > 0) {
7928
- queue.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
7929
- levels.push({ storyIds: queue.map((s) => s.id) });
7930
- const next = [];
7931
- for (const s of queue) {
7932
- const deps = dependents.get(s.id);
7933
- if (!deps) continue;
7934
- for (const dependentId of deps) {
7935
- const remaining = (inDegree.get(dependentId) ?? 0) - 1;
7936
- inDegree.set(dependentId, remaining);
7937
- if (remaining === 0) {
7938
- const story = storyMap.get(dependentId);
7939
- if (story) next.push(story);
7940
- }
7941
- }
7942
- }
7943
- queue = next;
7944
- }
7945
- const placed = new Set(levels.flatMap((l) => l.storyIds));
7946
- if (placed.size !== active.length) {
7947
- const cycled = active.filter((s) => !placed.has(s.id)).map((s) => s.id);
7948
- throw new Error(`Dependency cycle detected: ${cycled.join(", ")}`);
7949
- }
7950
- return levels;
7951
- }
7952
-
7953
7953
  // ../baro-orchestrator/src/prd.ts
7954
7954
  import { readFileSync, writeFileSync } from "fs";
7955
7955
  var STORY_DEFAULTS = { retries: 2 };
@@ -8396,7 +8396,13 @@ var StoryAgent = class extends Participant {
8396
8396
  retryDelayMs: 1500,
8397
8397
  quietTimeoutMs: 2e3,
8398
8398
  maxTurns: 4,
8399
- hardTimeoutSecs: 300,
8399
+ // hardTimeoutSecs <= 0 disables the absolute kill timer.
8400
+ // The previous default of 300s was killing real refactor
8401
+ // work mid-flight (e.g. "delete SEF module" touches dozens
8402
+ // of files and routinely needs >5 minutes); we'd rather
8403
+ // let the per-attempt timeoutSecs and the quiet-timer
8404
+ // close out idle agents than guillotine a productive one.
8405
+ hardTimeoutSecs: 0,
8400
8406
  ...spec
8401
8407
  };
8402
8408
  this.done = new Promise((res) => {
@@ -8457,10 +8463,10 @@ var StoryAgent = class extends Participant {
8457
8463
  let lastSummary = null;
8458
8464
  let lastError = null;
8459
8465
  let hardTimedOut = false;
8460
- const hardTimer = setTimeout(() => {
8466
+ const hardTimer = this.spec.hardTimeoutSecs > 0 ? setTimeout(() => {
8461
8467
  hardTimedOut = true;
8462
8468
  this.currentClaude?.abort();
8463
- }, this.spec.hardTimeoutSecs * 1e3);
8469
+ }, this.spec.hardTimeoutSecs * 1e3) : null;
8464
8470
  try {
8465
8471
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
8466
8472
  if (hardTimedOut) {
@@ -8503,7 +8509,7 @@ var StoryAgent = class extends Participant {
8503
8509
  }
8504
8510
  }
8505
8511
  } finally {
8506
- clearTimeout(hardTimer);
8512
+ if (hardTimer !== null) clearTimeout(hardTimer);
8507
8513
  }
8508
8514
  const durationSecs = Math.round(
8509
8515
  (Date.now() - (this.startedAt ?? Date.now())) / 1e3
@@ -9919,6 +9925,10 @@ async function orchestrate(config) {
9919
9925
  depends_on: s.dependsOn
9920
9926
  }))
9921
9927
  });
9928
+ const dagLevels = buildDag(prd.userStories).map(
9929
+ (lvl) => lvl.storyIds.map((id) => ({ id }))
9930
+ );
9931
+ emit({ type: "dag", levels: dagLevels });
9922
9932
  }
9923
9933
  env.deliverContextItem(operator, new RunStartRequestItem("orchestrate"));
9924
9934
  const summary = await conductor.done;
@@ -10286,6 +10296,18 @@ async function main() {
10286
10296
  process.exit(1);
10287
10297
  }
10288
10298
  }
10299
+ process.on("unhandledRejection", (reason) => {
10300
+ const stack = reason?.stack ?? String(reason);
10301
+ process.stderr.write(`[cli] unhandledRejection: ${stack}
10302
+ `);
10303
+ process.exit(1);
10304
+ });
10305
+ process.on("uncaughtException", (err) => {
10306
+ const stack = err?.stack ?? String(err);
10307
+ process.stderr.write(`[cli] uncaughtException: ${stack}
10308
+ `);
10309
+ process.exit(1);
10310
+ });
10289
10311
  main().catch((e) => {
10290
10312
  process.stderr.write(`[cli] unhandled: ${e?.stack ?? String(e)}
10291
10313
  `);