@wrongstack/cli 0.319.0 → 0.319.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.
Files changed (40) hide show
  1. package/dist/{auth-KF5TAD7V.js → auth-ND7J7DTD.js} +2 -2
  2. package/dist/{chunk-H7GABTGS.js → chunk-635WW3II.js} +3 -13
  3. package/dist/{chunk-7CECQDNH.js → chunk-D3K4NYQL.js} +1 -1
  4. package/dist/{chunk-4JRIWVJ4.js → chunk-ERX4BLKP.js} +1 -1
  5. package/dist/{chunk-42JD25KU.js → chunk-HF5VQWIY.js} +2 -2
  6. package/dist/{chunk-XHIEA6LG.js → chunk-IMT6PNV5.js} +1 -1
  7. package/dist/{chunk-G7337TTK.js → chunk-IS2PPBQV.js} +1 -1
  8. package/dist/{chunk-G3IMKQRH.js → chunk-JHPXJRRI.js} +1 -1
  9. package/dist/{chunk-OZDE3OWD.js → chunk-KYDJJLJI.js} +10 -10
  10. package/dist/{chunk-VWCZL4OH.js → chunk-LIWVIEZM.js} +2 -2
  11. package/dist/{chunk-7JBKXVMK.js → chunk-TALOKMIC.js} +14 -18
  12. package/dist/{chunk-SYIBTG3X.js → chunk-VOTTENR5.js} +3 -5
  13. package/dist/chunk-WHOIR577.js +1 -0
  14. package/dist/{chunk-2ZNBRZ4W.js → chunk-WQZW3RDP.js} +2 -2
  15. package/dist/{cli-context-LH4QP4W2.js → cli-context-K73EIND5.js} +6 -6
  16. package/dist/{cli-main-72XUFUCL.js → cli-main-QXSKKANW.js} +42 -57
  17. package/dist/{diag-doctor-LFCCBPMD.js → diag-doctor-QZVKUAE5.js} +4 -5
  18. package/dist/{execution-DKJDNPYF.js → execution-7ZFY4FJY.js} +484 -458
  19. package/dist/{hq-3GWBFLON.js → hq-4QQJO2GN.js} +2 -2
  20. package/dist/hq-server/routes.d.ts +1 -1
  21. package/dist/{hq-server-OARPUSQJ.js → hq-server-CVAYICIS.js} +2 -2
  22. package/dist/index.js +3 -3
  23. package/dist/{modeldiag-5FRMT6FQ.js → modeldiag-ZL4ROTQ5.js} +1 -1
  24. package/dist/{plugin-usage-CYUORYM6.js → plugin-usage-7WCZW4NP.js} +2 -2
  25. package/dist/{plugins-RV3OBBND.js → plugins-7N3TF2QF.js} +3 -3
  26. package/dist/{project-manifest-YFTJ3D5N.js → project-manifest-RV5FXGQI.js} +2 -2
  27. package/dist/{project-picker-R5TYAE3Q.js → project-picker-CCQR3W4I.js} +3 -3
  28. package/dist/{proxy-wiring-EQB5X5YH.js → proxy-wiring-QCI7EWQC.js} +3 -3
  29. package/dist/{sdd-runtime-FLKCSTYV.js → sdd-runtime-R6FAK2G2.js} +2 -2
  30. package/dist/services/sdd-runtime.d.ts +1 -1
  31. package/dist/{short-circuit-flags-U6CJAF6J.js → short-circuit-flags-7YUCERBB.js} +2 -2
  32. package/dist/slash-commands/sdd.d.ts +1 -1
  33. package/dist/{subcommands-J4JMWC5W.js → subcommands-KE6MEQQP.js} +2 -2
  34. package/dist/{webui-server-SY4EQCKD.js → webui-server-F7MSRHOF.js} +4 -2
  35. package/dist/wiring/wrongtrace-gate.d.ts +2 -2
  36. package/dist/wiring/wrongtrace-hooks.d.ts +1 -1
  37. package/dist/{wrongtrace-gate-counters-P5BCBXQN.js → wrongtrace-gate-counters-GSVY372D.js} +2 -2
  38. package/dist/{wrongtrace-telemetry-FNLANZ5I.js → wrongtrace-telemetry-KBBM5NLQ.js} +2 -2
  39. package/package.json +28 -28
  40. package/dist/chunk-ALE5KHCA.js +0 -1
@@ -22,7 +22,7 @@ import {
22
22
  import {
23
23
  fmtTok
24
24
  } from "./chunk-TYO2OVAD.js";
25
- import "./chunk-ALE5KHCA.js";
25
+ import "./chunk-WHOIR577.js";
26
26
  import {
27
27
  advanceToNextTask,
28
28
  autoDetectTaskCompletion,
@@ -212,7 +212,7 @@ async function runWebUIDispatch(ctx) {
212
212
  const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
213
213
  agent.disableInteractiveConfirmation();
214
214
  renderer.setSilent(true);
215
- const { runWebUI } = await import("./webui-server-SY4EQCKD.js");
215
+ const { runWebUI } = await import("./webui-server-F7MSRHOF.js");
216
216
  const flagValue = (names) => {
217
217
  for (const name of names) {
218
218
  if (!Object.hasOwn(flags, name)) continue;
@@ -415,7 +415,7 @@ async function runWebUIDispatch(ctx) {
415
415
  applyLiveSettings?.({ yolo: enabled });
416
416
  },
417
417
  onWrongProxyPrefsChange: (payload) => {
418
- void import("./proxy-wiring-EQB5X5YH.js").then(
418
+ void import("./proxy-wiring-QCI7EWQC.js").then(
419
419
  ({ applyWrongProxyPrefs }) => applyWrongProxyPrefs(payload)
420
420
  );
421
421
  }
@@ -893,7 +893,7 @@ function onSwitchToSession(ctx, _sessionId, targetRoot, projectName) {
893
893
  import * as path4 from "node:path";
894
894
  import { color as color3 } from "@wrongstack/core/utils";
895
895
  async function getProjectPickerItems(ctx) {
896
- const { buildPickerItems } = await import("./project-picker-R5TYAE3Q.js");
896
+ const { buildPickerItems } = await import("./project-picker-CCQR3W4I.js");
897
897
  return buildPickerItems({
898
898
  globalConfigPath: ctx.state.wpaths.globalConfig,
899
899
  currentProjectRoot: ctx.state.projectRoot
@@ -911,7 +911,7 @@ async function onProjectSelect(ctx, slug, kind) {
911
911
  }
912
912
  return;
913
913
  }
914
- const { loadManifest, saveManifest } = await import("./project-manifest-YFTJ3D5N.js");
914
+ const { loadManifest, saveManifest } = await import("./project-manifest-RV5FXGQI.js");
915
915
  const manifest = await loadManifest(state.wpaths.globalConfig);
916
916
  const project = manifest.projects.find((p) => p.slug === slug);
917
917
  if (!project) return;
@@ -1214,7 +1214,7 @@ async function switchProjectInPlace(ctx, targetRoot, displayName) {
1214
1214
 
1215
1215
  // src/boot/tui-sdd-callback.ts
1216
1216
  async function getSDDContext() {
1217
- const { getActiveSDDContext: getActiveSDDContext2 } = await import("./sdd-runtime-FLKCSTYV.js");
1217
+ const { getActiveSDDContext: getActiveSDDContext2 } = await import("./sdd-runtime-R6FAK2G2.js");
1218
1218
  return getActiveSDDContext2();
1219
1219
  }
1220
1220
  async function onSDDOutput(output) {
@@ -1225,7 +1225,7 @@ async function onSDDOutput(output) {
1225
1225
  autoDetectTaskCompletion: autoDetectTaskCompletion2,
1226
1226
  getTaskProgress: getTaskProgress2,
1227
1227
  getActiveSDDPhase: getActiveSDDPhase2
1228
- } = await import("./sdd-runtime-FLKCSTYV.js");
1228
+ } = await import("./sdd-runtime-R6FAK2G2.js");
1229
1229
  const messages = [];
1230
1230
  const specSaved = await trySaveSpecFromAIOutput2(output);
1231
1231
  if (specSaved) messages.push("\u2713 Spec detected and saved! Use /sdd approve to continue.");
@@ -1851,7 +1851,15 @@ function coerceAgentSwarmMode(v) {
1851
1851
  if (typeof v === "string" && (v === "bottom" || v === "sidebar" || v === "off")) return v;
1852
1852
  return "bottom";
1853
1853
  }
1854
- var ANIMATION_STYLES = ["rainbow", "wave", "pulse", "dots", "breathe", "static", "cycle"];
1854
+ var ANIMATION_STYLES = [
1855
+ "rainbow",
1856
+ "wave",
1857
+ "pulse",
1858
+ "dots",
1859
+ "breathe",
1860
+ "static",
1861
+ "cycle"
1862
+ ];
1855
1863
  function normalizeAnimationStyle(raw) {
1856
1864
  return typeof raw === "string" && ANIMATION_STYLES.includes(raw) ? raw : "rainbow";
1857
1865
  }
@@ -2665,7 +2673,7 @@ async function finalizeExecutionCleanup(input) {
2665
2673
  })
2666
2674
  );
2667
2675
  } else {
2668
- const { reportWrongTraceSessionTelemetry } = await import("./wrongtrace-telemetry-FNLANZ5I.js");
2676
+ const { reportWrongTraceSessionTelemetry } = await import("./wrongtrace-telemetry-KBBM5NLQ.js");
2669
2677
  const usage = tokenCounter.total();
2670
2678
  const report = reportWrongTraceSessionTelemetry({
2671
2679
  sessionId: activeSession.id,
@@ -2693,7 +2701,7 @@ async function finalizeExecutionCleanup(input) {
2693
2701
  } catch {
2694
2702
  }
2695
2703
  try {
2696
- const { snapshotGateDecisions, persistWrongTraceGateCounters } = await import("./wrongtrace-gate-counters-P5BCBXQN.js");
2704
+ const { snapshotGateDecisions, persistWrongTraceGateCounters } = await import("./wrongtrace-gate-counters-GSVY372D.js");
2697
2705
  const projectRoot = agent.ctx.projectRoot;
2698
2706
  if (projectRoot) {
2699
2707
  await persistWrongTraceGateCounters(projectRoot, snapshotGateDecisions());
@@ -2814,7 +2822,7 @@ function resolveKanbanDispatchRoute(config, spawnOpts) {
2814
2822
  tier = resolved.tier;
2815
2823
  provider = provider ?? resolved.provider ?? config.provider;
2816
2824
  model = model ?? resolved.model;
2817
- fallbackModels = fallbackModels ?? (resolved.fallbackModels?.slice() ?? void 0);
2825
+ fallbackModels = fallbackModels ?? resolved.fallbackModels?.slice() ?? void 0;
2818
2826
  }
2819
2827
  }
2820
2828
  return { provider, model, fallbackModels, ...tier ? { tier } : {} };
@@ -3453,8 +3461,12 @@ function buildChimeraReviewTaskDescription(p) {
3453
3461
  lines.push("---");
3454
3462
  lines.push("");
3455
3463
  lines.push("**Review Instructions:**");
3456
- lines.push("- Review the diffs and new file contents carefully for real bugs, broken logic, null dereferences, and security gaps.");
3457
- lines.push("- Stay strictly within the scoped diffs. DO NOT audit unchanged files, pre-existing debt, or stylistic preferences.");
3464
+ lines.push(
3465
+ "- Review the diffs and new file contents carefully for real bugs, broken logic, null dereferences, and security gaps."
3466
+ );
3467
+ lines.push(
3468
+ "- Stay strictly within the scoped diffs. DO NOT audit unchanged files, pre-existing debt, or stylistic preferences."
3469
+ );
3458
3470
  lines.push("- Use tools only when you need surrounding lines to verify a concrete issue.");
3459
3471
  lines.push("- Once the diff is validated, output your report (findings or all-clear) promptly.");
3460
3472
  return lines.join("\n");
@@ -3651,122 +3663,126 @@ function installChimeraCascadeHandler({
3651
3663
  persistEvidence,
3652
3664
  teardownHandlers
3653
3665
  }) {
3654
- const off = events.onPattern("chimera.cascade_needed", (_event, payload) => {
3655
- const p = payload;
3656
- const dir = director;
3657
- if (!dir) return;
3658
- if (p.agents.length === 0) return;
3659
- const previousWork = getPendingWork();
3660
- const pendingWork = (async () => {
3661
- try {
3662
- await previousWork;
3663
- } catch {
3664
- }
3665
- const agentEvidence = [];
3666
- for (const agentKind of p.agents) {
3666
+ const off = events.onPattern(
3667
+ "chimera.cascade_needed",
3668
+ (_event, payload) => {
3669
+ const p = payload;
3670
+ const dir = director;
3671
+ if (!dir) return;
3672
+ if (p.agents.length === 0) return;
3673
+ const previousWork = getPendingWork();
3674
+ const pendingWork = (async () => {
3667
3675
  try {
3668
- const taskDesc = buildChimeraCascadeTaskDescription(agentKind, p);
3669
- const role = agentKind === "security-scanner" ? "security-scanner" : "bug-hunter";
3670
- const ladder = buildLadder?.() ?? INHERIT_ONLY_LADDER;
3671
- const outcome = await runSubagentModelLadder({
3672
- director: dir,
3673
- ladder,
3674
- attemptTimeoutMs: CASCADE_ATTEMPT_TIMEOUT_MS,
3675
- budgetMs: CASCADE_LADDER_BUDGET_MS,
3676
- buildConfig: (attempt, timeoutMs) => ({
3677
- name: `chimera-cascade-${agentKind}`,
3678
- role,
3679
- maxIterations: 40,
3680
- maxToolCalls: 200,
3681
- timeoutMs,
3682
- // Cascade agents are ephemeral infrastructure: like reviewers,
3683
- // they must not consume the leader's lifetime maxSpawns budget.
3684
- spawnBudgetExempt: true,
3685
- // Model-driven completion (see core coordination/subagent-finish.ts):
3686
- // a rung crossing its wall-clock budget is notified in-band
3687
- // between tool batches and finishes its own turn within the
3688
- // grace window instead of being killed. Ladder-retry semantics
3689
- // are intact: a rung that still exhausts the grace window lands
3690
- // as a `timeout` task result, which advances the ladder, and
3691
- // `buildRetryPreamble` below already warns the successor that
3692
- // the tree may hold the dead rung's partial edits.
3693
- gracefulFinish: true,
3694
- // Rung 0 stays unpinned so the role model matrix still decides;
3695
- // later rungs pin a model precisely because it just failed.
3696
- ...attempt.tier === "inherit" ? {} : {
3697
- provider: attempt.provider,
3698
- model: attempt.model,
3699
- fallbackModels: attempt.fallbackModels
3676
+ await previousWork;
3677
+ } catch {
3678
+ }
3679
+ const agentEvidence = [];
3680
+ for (const agentKind of p.agents) {
3681
+ try {
3682
+ const taskDesc = buildChimeraCascadeTaskDescription(agentKind, p);
3683
+ const role = agentKind === "security-scanner" ? "security-scanner" : "bug-hunter";
3684
+ const ladder = buildLadder?.() ?? INHERIT_ONLY_LADDER;
3685
+ const outcome = await runSubagentModelLadder({
3686
+ director: dir,
3687
+ ladder,
3688
+ attemptTimeoutMs: CASCADE_ATTEMPT_TIMEOUT_MS,
3689
+ budgetMs: CASCADE_LADDER_BUDGET_MS,
3690
+ buildConfig: (attempt, timeoutMs) => ({
3691
+ name: `chimera-cascade-${agentKind}`,
3692
+ role,
3693
+ maxIterations: 40,
3694
+ maxToolCalls: 200,
3695
+ timeoutMs,
3696
+ // Cascade agents are ephemeral infrastructure: like reviewers,
3697
+ // they must not consume the leader's lifetime maxSpawns budget.
3698
+ spawnBudgetExempt: true,
3699
+ // Model-driven completion (see core coordination/subagent-finish.ts):
3700
+ // a rung crossing its wall-clock budget is notified in-band
3701
+ // between tool batches and finishes its own turn within the
3702
+ // grace window instead of being killed. Ladder-retry semantics
3703
+ // are intact: a rung that still exhausts the grace window lands
3704
+ // as a `timeout` task result, which advances the ladder, and
3705
+ // `buildRetryPreamble` below already warns the successor that
3706
+ // the tree may hold the dead rung's partial edits.
3707
+ gracefulFinish: true,
3708
+ // Rung 0 stays unpinned so the role model matrix still decides;
3709
+ // later rungs pin a model precisely because it just failed.
3710
+ ...attempt.tier === "inherit" ? {} : {
3711
+ provider: attempt.provider,
3712
+ model: attempt.model,
3713
+ fallbackModels: attempt.fallbackModels
3714
+ }
3715
+ }),
3716
+ // Cascade agents write files, so a successor must be told the tree
3717
+ // may already hold the dead attempt's partial edits.
3718
+ buildTask: (_attempt, failures) => `${buildRetryPreamble(failures)}${taskDesc}`,
3719
+ onAttemptFailed: async (failure, next) => {
3720
+ if (!next) return;
3721
+ await session.append({
3722
+ type: "error",
3723
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
3724
+ message: `\u{1F982} Chimera cascade (${agentKind}) on ${failure.model} failed (${failure.reason}) \u2014 retrying on ${attemptLabel(next)} (${next.tier}).`,
3725
+ phase: "agent"
3726
+ });
3727
+ }
3728
+ });
3729
+ const result = outcome.result;
3730
+ if (result?.status === "success") {
3731
+ const resultText = typeof result.result === "string" ? result.result : JSON.stringify(result.result);
3732
+ const claimed = extractCascadeEvidence(resultText);
3733
+ if (claimed) {
3734
+ agentEvidence.push({ agentKind, evidence: claimed });
3700
3735
  }
3701
- }),
3702
- // Cascade agents write files, so a successor must be told the tree
3703
- // may already hold the dead attempt's partial edits.
3704
- buildTask: (_attempt, failures) => `${buildRetryPreamble(failures)}${taskDesc}`,
3705
- onAttemptFailed: async (failure, next) => {
3706
- if (!next) return;
3736
+ await session.append({
3737
+ type: "llm_response",
3738
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
3739
+ content: [
3740
+ {
3741
+ type: "text",
3742
+ text: `\u{1F982} Chimera cascade (${agentKind}) \u2014 ${resultText}`
3743
+ }
3744
+ ],
3745
+ stopReason: "end_turn",
3746
+ usage: { input: 0, output: 0 }
3747
+ });
3748
+ } else {
3749
+ const detail = outcome.lastError ? outcome.lastError instanceof Error ? outcome.lastError.message : String(outcome.lastError) : `${result?.status ?? "unknown"}: ${result?.error?.message ?? "no result"}`;
3707
3750
  await session.append({
3708
3751
  type: "error",
3709
3752
  ts: (/* @__PURE__ */ new Date()).toISOString(),
3710
- message: `\u{1F982} Chimera cascade (${agentKind}) on ${failure.model} failed (${failure.reason}) \u2014 retrying on ${attemptLabel(next)} (${next.tier}).`,
3753
+ message: `\u{1F982} Chimera cascade (${agentKind}) ${result?.status ?? "unknown"}: ${detail} \u2014 exhausted ${outcome.attemptsUsed} of ${ladder.length} model(s)`,
3711
3754
  phase: "agent"
3712
3755
  });
3713
3756
  }
3714
- });
3715
- const result = outcome.result;
3716
- if (result?.status === "success") {
3717
- const resultText = typeof result.result === "string" ? result.result : JSON.stringify(result.result);
3718
- const claimed = extractCascadeEvidence(resultText);
3719
- if (claimed) {
3720
- agentEvidence.push({ agentKind, evidence: claimed });
3721
- }
3722
- await session.append({
3723
- type: "llm_response",
3724
- ts: (/* @__PURE__ */ new Date()).toISOString(),
3725
- content: [
3726
- {
3727
- type: "text",
3728
- text: `\u{1F982} Chimera cascade (${agentKind}) \u2014 ${resultText}`
3729
- }
3730
- ],
3731
- stopReason: "end_turn",
3732
- usage: { input: 0, output: 0 }
3733
- });
3734
- } else {
3735
- const detail = outcome.lastError ? outcome.lastError instanceof Error ? outcome.lastError.message : String(outcome.lastError) : `${result?.status ?? "unknown"}: ${result?.error?.message ?? "no result"}`;
3757
+ } catch (err) {
3736
3758
  await session.append({
3737
3759
  type: "error",
3738
3760
  ts: (/* @__PURE__ */ new Date()).toISOString(),
3739
- message: `\u{1F982} Chimera cascade (${agentKind}) ${result?.status ?? "unknown"}: ${detail} \u2014 exhausted ${outcome.attemptsUsed} of ${ladder.length} model(s)`,
3761
+ message: `\u{1F982} Chimera cascade (${agentKind}) failed: ${err instanceof Error ? err.message : String(err)}`,
3740
3762
  phase: "agent"
3741
3763
  });
3742
3764
  }
3743
- } catch (err) {
3744
- await session.append({
3745
- type: "error",
3746
- ts: (/* @__PURE__ */ new Date()).toISOString(),
3747
- message: `\u{1F982} Chimera cascade (${agentKind}) failed: ${err instanceof Error ? err.message : String(err)}`,
3748
- phase: "agent"
3749
- });
3750
3765
  }
3751
- }
3752
- const accumulatedEvidence = {};
3753
- for (const { evidence } of agentEvidence) {
3754
- for (const name of ["typecheck", "lint", "tests"]) {
3755
- if (evidence[name]) accumulatedEvidence[name] = evidence[name];
3766
+ const accumulatedEvidence = {};
3767
+ for (const { evidence } of agentEvidence) {
3768
+ for (const name of ["typecheck", "lint", "tests"]) {
3769
+ if (evidence[name]) accumulatedEvidence[name] = evidence[name];
3770
+ }
3756
3771
  }
3757
- }
3758
- await maybeReReviewCascade({
3759
- events,
3760
- session,
3761
- bundle: p.bundle,
3762
- reportId: p.reportId,
3763
- claimedEvidence: accumulatedEvidence,
3764
- verifyEvidence,
3765
- persistEvidence
3766
- });
3767
- })();
3768
- trackWork(pendingWork);
3769
- }, "chimera-cascade");
3772
+ await maybeReReviewCascade({
3773
+ events,
3774
+ session,
3775
+ bundle: p.bundle,
3776
+ reportId: p.reportId,
3777
+ claimedEvidence: accumulatedEvidence,
3778
+ verifyEvidence,
3779
+ persistEvidence
3780
+ });
3781
+ })();
3782
+ trackWork(pendingWork);
3783
+ },
3784
+ "chimera-cascade"
3785
+ );
3770
3786
  if (off) teardownHandlers?.push(off);
3771
3787
  }
3772
3788
  async function maybeReReviewCascade({
@@ -3948,372 +3964,376 @@ function installChimeraReviewHandler({
3948
3964
  trackWork,
3949
3965
  teardownHandlers
3950
3966
  }) {
3951
- const off = events.onPattern("chimera.review_needed", (_event, payload) => {
3952
- const p = payload;
3953
- const reviewSessionId = agent.ctx.activeRunSessionId ?? agent.ctx.session?.id ?? session.id;
3954
- if (!areSubagentsAllowedForSession(reviewSessionId)) {
3955
- void recordCompletedReview(events, { bundle: p }).catch(() => void 0);
3956
- return;
3957
- }
3958
- const dir = director;
3959
- if (!dir) {
3960
- void recordCompletedReview(events, { bundle: p }).catch(() => void 0);
3961
- return;
3962
- }
3963
- if (p.files.length === 0) return;
3964
- const appendChimeraNotice = async (message) => {
3965
- try {
3966
- await session.append({
3967
- type: "error",
3968
- ts: (/* @__PURE__ */ new Date()).toISOString(),
3969
- message,
3970
- phase: "agent"
3971
- });
3972
- } catch (err) {
3973
- console.warn(
3974
- JSON.stringify({
3975
- level: "warn",
3976
- event: "execution.chimera_notice_append_failed",
3977
- message: err instanceof Error ? err.message : String(err),
3978
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
3979
- })
3980
- );
3967
+ const off = events.onPattern(
3968
+ "chimera.review_needed",
3969
+ (_event, payload) => {
3970
+ const p = payload;
3971
+ const reviewSessionId = agent.ctx.activeRunSessionId ?? agent.ctx.session?.id ?? session.id;
3972
+ if (!areSubagentsAllowedForSession(reviewSessionId)) {
3973
+ void recordCompletedReview(events, { bundle: p }).catch(() => void 0);
3974
+ return;
3981
3975
  }
3982
- };
3983
- const persistAndEmitCompletion = async (completion) => {
3984
- try {
3985
- await persistReview(completion, projectDir);
3986
- events.emitCustom("chimera.review_persisted", {
3987
- reportId: completion.reportId,
3988
- sessionId: completion.sessionId,
3989
- cwd: completion.cwd
3990
- });
3991
- } catch (error) {
3992
- const message = error instanceof Error ? error.message : String(error);
3993
- events.emitCustom("chimera.review_persistence_failed", {
3994
- reportId: completion.reportId,
3995
- sessionId: completion.sessionId,
3996
- cwd: completion.cwd,
3997
- error: message
3998
- });
3999
- await appendChimeraNotice(
4000
- `\u{1F982} Chimera report persistence failed: ${message}. The review remains in the session transcript and mailbox.`
4001
- );
4002
- } finally {
4003
- await recordCompletedReview(events, completion);
4004
- events.emitCustom("chimera.review_complete", completion);
3976
+ const dir = director;
3977
+ if (!dir) {
3978
+ void recordCompletedReview(events, { bundle: p }).catch(() => void 0);
3979
+ return;
4005
3980
  }
4006
- };
4007
- trackWork(
4008
- (async () => {
4009
- let subagentId;
3981
+ if (p.files.length === 0) return;
3982
+ const appendChimeraNotice = async (message) => {
4010
3983
  try {
4011
- const taskDesc = buildChimeraReviewTaskDescription(p);
4012
- const tProvider = config.provider?.trim() || void 0;
4013
- const tModel = config.model?.trim() || void 0;
4014
- const rawProvider = p.reviewFallbackModels ? p.config.provider?.trim() || void 0 : tProvider;
4015
- const rawModel = p.reviewFallbackModels ? p.config.model?.trim() || void 0 : tModel;
4016
- const baseProvider = rawProvider || tProvider || config.provider;
4017
- const baseModel = rawModel || tModel || config.model;
4018
- const configFallbacks = [...p.config.fallbackModels ?? []];
4019
- if (p.config.fallbackProfile) {
4020
- configFallbacks.push(...fallbackProfileChain2(config, p.config.fallbackProfile));
4021
- }
4022
- const baseFallbacks = p.reviewFallbackModels ? [...p.reviewFallbackModels] : resolveReviewerFallbackModels(
4023
- configFallbacks.length > 0 ? configFallbacks : void 0
4024
- );
4025
- const assigned = assignReviewerModels(
4026
- baseProvider,
4027
- baseModel,
4028
- baseFallbacks,
4029
- p.reviewModelSelection ?? "round-robin",
4030
- statusTracker
3984
+ await session.append({
3985
+ type: "error",
3986
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
3987
+ message,
3988
+ phase: "agent"
3989
+ });
3990
+ } catch (err) {
3991
+ console.warn(
3992
+ JSON.stringify({
3993
+ level: "warn",
3994
+ event: "execution.chimera_notice_append_failed",
3995
+ message: err instanceof Error ? err.message : String(err),
3996
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
3997
+ })
4031
3998
  );
4032
- const ladder = buildReviewerAttemptLadder({
4033
- assigned,
4034
- profileChain: effectiveFallbackChain(config),
4035
- session: { provider: config.provider, model: config.model }
3999
+ }
4000
+ };
4001
+ const persistAndEmitCompletion = async (completion) => {
4002
+ try {
4003
+ await persistReview(completion, projectDir);
4004
+ events.emitCustom("chimera.review_persisted", {
4005
+ reportId: completion.reportId,
4006
+ sessionId: completion.sessionId,
4007
+ cwd: completion.cwd
4036
4008
  });
4037
- const ladderRefs = ladder.map(attemptLabel);
4038
- const outcome = await runSubagentModelLadder({
4039
- director: dir,
4040
- ladder,
4041
- budgetMs: REVIEWER_LADDER_BUDGET_MS,
4042
- keepWinnerAlive: false,
4043
- buildConfig: (attempt, timeoutMs) => applyChimeraReviewerReadOnlyPolicy({
4044
- name: "chimera-review",
4045
- role: "reviewer",
4046
- systemPromptOverride: CHIMERA_REVIEW_PROMPT,
4047
- maxIterations: 50,
4048
- maxToolCalls: 250,
4049
- timeoutMs,
4050
- provider: attempt.provider,
4051
- model: attempt.model,
4052
- fallbackModels: attempt.fallbackModels,
4053
- // Reviewers are ephemeral background infrastructure: they must
4054
- // not consume the leader's lifetime maxSpawns budget.
4055
- spawnBudgetExempt: true
4056
- }),
4057
- // The reviewer is read-only, so a retry re-runs the task verbatim.
4058
- buildTask: () => taskDesc,
4059
- onAttemptFailed: async (failure, next) => {
4060
- console.warn(
4061
- JSON.stringify({
4062
- level: "warn",
4063
- event: "execution.chimera_reviewer_attempt_failed",
4064
- message: failure.reason,
4065
- model: failure.model,
4066
- tier: failure.tier,
4009
+ } catch (error) {
4010
+ const message = error instanceof Error ? error.message : String(error);
4011
+ events.emitCustom("chimera.review_persistence_failed", {
4012
+ reportId: completion.reportId,
4013
+ sessionId: completion.sessionId,
4014
+ cwd: completion.cwd,
4015
+ error: message
4016
+ });
4017
+ await appendChimeraNotice(
4018
+ `\u{1F982} Chimera report persistence failed: ${message}. The review remains in the session transcript and mailbox.`
4019
+ );
4020
+ } finally {
4021
+ await recordCompletedReview(events, completion);
4022
+ events.emitCustom("chimera.review_complete", completion);
4023
+ }
4024
+ };
4025
+ trackWork(
4026
+ (async () => {
4027
+ let subagentId;
4028
+ try {
4029
+ const taskDesc = buildChimeraReviewTaskDescription(p);
4030
+ const tProvider = config.provider?.trim() || void 0;
4031
+ const tModel = config.model?.trim() || void 0;
4032
+ const rawProvider = p.reviewFallbackModels ? p.config.provider?.trim() || void 0 : tProvider;
4033
+ const rawModel = p.reviewFallbackModels ? p.config.model?.trim() || void 0 : tModel;
4034
+ const baseProvider = rawProvider || tProvider || config.provider;
4035
+ const baseModel = rawModel || tModel || config.model;
4036
+ const configFallbacks = [...p.config.fallbackModels ?? []];
4037
+ if (p.config.fallbackProfile) {
4038
+ configFallbacks.push(...fallbackProfileChain2(config, p.config.fallbackProfile));
4039
+ }
4040
+ const baseFallbacks = p.reviewFallbackModels ? [...p.reviewFallbackModels] : resolveReviewerFallbackModels(
4041
+ configFallbacks.length > 0 ? configFallbacks : void 0
4042
+ );
4043
+ const assigned = assignReviewerModels(
4044
+ baseProvider,
4045
+ baseModel,
4046
+ baseFallbacks,
4047
+ p.reviewModelSelection ?? "round-robin",
4048
+ statusTracker
4049
+ );
4050
+ const ladder = buildReviewerAttemptLadder({
4051
+ assigned,
4052
+ profileChain: effectiveFallbackChain(config),
4053
+ session: { provider: config.provider, model: config.model }
4054
+ });
4055
+ const ladderRefs = ladder.map(attemptLabel);
4056
+ const outcome = await runSubagentModelLadder({
4057
+ director: dir,
4058
+ ladder,
4059
+ budgetMs: REVIEWER_LADDER_BUDGET_MS,
4060
+ keepWinnerAlive: false,
4061
+ buildConfig: (attempt, timeoutMs) => applyChimeraReviewerReadOnlyPolicy({
4062
+ name: "chimera-review",
4063
+ role: "reviewer",
4064
+ systemPromptOverride: CHIMERA_REVIEW_PROMPT,
4065
+ maxIterations: 50,
4066
+ maxToolCalls: 250,
4067
+ timeoutMs,
4068
+ provider: attempt.provider,
4069
+ model: attempt.model,
4070
+ fallbackModels: attempt.fallbackModels,
4071
+ // Reviewers are ephemeral background infrastructure: they must
4072
+ // not consume the leader's lifetime maxSpawns budget.
4073
+ spawnBudgetExempt: true
4074
+ }),
4075
+ // The reviewer is read-only, so a retry re-runs the task verbatim.
4076
+ buildTask: () => taskDesc,
4077
+ onAttemptFailed: async (failure, next) => {
4078
+ console.warn(
4079
+ JSON.stringify({
4080
+ level: "warn",
4081
+ event: "execution.chimera_reviewer_attempt_failed",
4082
+ message: failure.reason,
4083
+ model: failure.model,
4084
+ tier: failure.tier,
4085
+ attempt: failure.attempt,
4086
+ of: ladder.length,
4087
+ nextModel: next ? attemptLabel(next) : void 0,
4088
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4089
+ })
4090
+ );
4091
+ if (!next) return;
4092
+ events.emitCustom("chimera.reviewer_model_fallback", {
4093
+ from: failure.model,
4094
+ to: attemptLabel(next),
4095
+ tier: next.tier,
4067
4096
  attempt: failure.attempt,
4068
4097
  of: ladder.length,
4069
- nextModel: next ? attemptLabel(next) : void 0,
4070
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
4071
- })
4072
- );
4073
- if (!next) return;
4074
- events.emitCustom("chimera.reviewer_model_fallback", {
4075
- from: failure.model,
4076
- to: attemptLabel(next),
4077
- tier: next.tier,
4078
- attempt: failure.attempt,
4079
- of: ladder.length,
4080
- reason: failure.reason
4081
- });
4082
- await appendChimeraNotice(
4083
- `\u{1F982} Chimera review on ${failure.model} failed (${failure.reason}) \u2014 retrying the same review on ${attemptLabel(next)} (${next.tier}).`
4084
- );
4085
- },
4086
- onRecovered: async (attempt, failures) => {
4087
- await appendChimeraNotice(
4088
- `\u{1F982} Chimera review recovered on ${attemptLabel(attempt)} (${attempt.tier}) after ${failures.length} failed attempt(s).`
4089
- );
4090
- }
4091
- });
4092
- subagentId = outcome.subagentId;
4093
- const result = outcome.result;
4094
- if (result?.status !== "success") {
4095
- const exhaustedDetail = outcome.lastError ? outcome.lastError instanceof Error ? outcome.lastError.message : String(outcome.lastError) : `${result?.status ?? "unknown"}: ${result?.error?.message ?? "no result"}`;
4096
- try {
4097
- await session.append({
4098
- type: "error",
4099
- ts: (/* @__PURE__ */ new Date()).toISOString(),
4100
- message: `\u{1F982} Chimera review subagent ${result?.status ?? "unknown"}: ${exhaustedDetail} \u2014 exhausted ${outcome.attemptsUsed} of ${ladder.length} model(s): ${ladderRefs.join(" \u2192 ")}`,
4101
- phase: "agent"
4098
+ reason: failure.reason
4099
+ });
4100
+ await appendChimeraNotice(
4101
+ `\u{1F982} Chimera review on ${failure.model} failed (${failure.reason}) \u2014 retrying the same review on ${attemptLabel(next)} (${next.tier}).`
4102
+ );
4103
+ },
4104
+ onRecovered: async (attempt, failures) => {
4105
+ await appendChimeraNotice(
4106
+ `\u{1F982} Chimera review recovered on ${attemptLabel(attempt)} (${attempt.tier}) after ${failures.length} failed attempt(s).`
4107
+ );
4108
+ }
4109
+ });
4110
+ subagentId = outcome.subagentId;
4111
+ const result = outcome.result;
4112
+ if (result?.status !== "success") {
4113
+ const exhaustedDetail = outcome.lastError ? outcome.lastError instanceof Error ? outcome.lastError.message : String(outcome.lastError) : `${result?.status ?? "unknown"}: ${result?.error?.message ?? "no result"}`;
4114
+ try {
4115
+ await session.append({
4116
+ type: "error",
4117
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
4118
+ message: `\u{1F982} Chimera review subagent ${result?.status ?? "unknown"}: ${exhaustedDetail} \u2014 exhausted ${outcome.attemptsUsed} of ${ladder.length} model(s): ${ladderRefs.join(" \u2192 ")}`,
4119
+ phase: "agent"
4120
+ });
4121
+ } catch (err) {
4122
+ console.error(
4123
+ JSON.stringify({
4124
+ level: "error",
4125
+ event: "execution.chimera_append_failed",
4126
+ message: err instanceof Error ? err.message : String(err),
4127
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4128
+ })
4129
+ );
4130
+ }
4131
+ await persistAndEmitCompletion({
4132
+ bundle: p,
4133
+ reviewText: "",
4134
+ status: result?.status ?? "unknown",
4135
+ cwd: p.cwd,
4136
+ sessionId: reviewSessionId,
4137
+ reportId: randomUUID3()
4102
4138
  });
4103
- } catch (err) {
4104
- console.error(
4105
- JSON.stringify({
4106
- level: "error",
4107
- event: "execution.chimera_append_failed",
4108
- message: err instanceof Error ? err.message : String(err),
4109
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
4110
- })
4111
- );
4139
+ return;
4112
4140
  }
4141
+ const reviewText = typeof result.result === "string" ? result.result.trim() : JSON.stringify(result.result);
4142
+ const reportId = randomUUID3();
4143
+ const reviewSource = classifyChimeraReviewSource(p);
4144
+ const winningAttempt = outcome.wonAt ? ladder[outcome.wonAt - 1] : void 0;
4145
+ const parsedReport = parseChimeraReviewReport(reviewText, {
4146
+ sessionId: reviewSessionId,
4147
+ agentId: p.fileProvenance?.find((entry) => entry.agentId)?.agentId ?? "chimera-review",
4148
+ reviewerModel: winningAttempt ? attemptLabel(winningAttempt) : void 0,
4149
+ reviewType: reviewSource,
4150
+ reportId
4151
+ });
4152
+ const verifiedFindings = await verifyFindingsAgainstDisk(parsedReport.findings, {
4153
+ cwd: p.cwd
4154
+ });
4155
+ const verifiedParsedReport = {
4156
+ ...parsedReport,
4157
+ findings: verifiedFindings
4158
+ };
4113
4159
  await persistAndEmitCompletion({
4114
4160
  bundle: p,
4115
- reviewText: "",
4116
- status: result?.status ?? "unknown",
4161
+ reviewText,
4162
+ status: "success",
4117
4163
  cwd: p.cwd,
4118
4164
  sessionId: reviewSessionId,
4119
- reportId: randomUUID3()
4165
+ reportId,
4166
+ parsedReport: verifiedParsedReport
4120
4167
  });
4121
- return;
4122
- }
4123
- const reviewText = typeof result.result === "string" ? result.result.trim() : JSON.stringify(result.result);
4124
- const reportId = randomUUID3();
4125
- const reviewSource = classifyChimeraReviewSource(p);
4126
- const winningAttempt = outcome.wonAt ? ladder[outcome.wonAt - 1] : void 0;
4127
- const parsedReport = parseChimeraReviewReport(reviewText, {
4128
- sessionId: reviewSessionId,
4129
- agentId: p.fileProvenance?.find((entry) => entry.agentId)?.agentId ?? "chimera-review",
4130
- reviewerModel: winningAttempt ? attemptLabel(winningAttempt) : void 0,
4131
- reviewType: reviewSource,
4132
- reportId
4133
- });
4134
- const verifiedFindings = await verifyFindingsAgainstDisk(parsedReport.findings, {
4135
- cwd: p.cwd
4136
- });
4137
- const verifiedParsedReport = {
4138
- ...parsedReport,
4139
- findings: verifiedFindings
4140
- };
4141
- await persistAndEmitCompletion({
4142
- bundle: p,
4143
- reviewText,
4144
- status: "success",
4145
- cwd: p.cwd,
4146
- sessionId: reviewSessionId,
4147
- reportId,
4148
- parsedReport: verifiedParsedReport
4149
- });
4150
- if (reviewText) {
4151
- const reviewHasFindings = !isChimeraAllClearReview(reviewText);
4152
- const citedFindings = verifiedFindings.filter((finding) => finding.location);
4153
- const citedPaths = new Set(
4154
- p.files.map((file) => normalizeFileKeyForCitation(file.path, p.cwd))
4155
- );
4156
- const changedBasenameIndex = /* @__PURE__ */ new Map();
4157
- for (const file of p.files) {
4158
- const normalized = normalizeFileKeyForCitation(file.path, p.cwd);
4159
- const basename7 = path12.basename(file.path).toLowerCase();
4160
- const bucket = changedBasenameIndex.get(basename7);
4161
- if (bucket) bucket.push(normalized);
4162
- else changedBasenameIndex.set(basename7, [normalized]);
4163
- }
4164
- const inScopeCited = citedFindings.filter((finding) => {
4165
- const citedKey = normalizeFileKeyForCitation(finding.location.file, p.cwd);
4166
- if (citedPaths.has(citedKey)) return true;
4167
- const suffixMatches = [...citedPaths].filter(
4168
- (cp) => cp.endsWith(`/${citedKey}`) || cp === citedKey
4168
+ if (reviewText) {
4169
+ const reviewHasFindings = !isChimeraAllClearReview(reviewText);
4170
+ const citedFindings = verifiedFindings.filter((finding) => finding.location);
4171
+ const citedPaths = new Set(
4172
+ p.files.map((file) => normalizeFileKeyForCitation(file.path, p.cwd))
4169
4173
  );
4170
- if (suffixMatches.length === 1) return true;
4171
- const basename7 = path12.basename(finding.location.file).toLowerCase();
4172
- const bucket = changedBasenameIndex.get(basename7);
4173
- return !!(bucket && bucket.length === 1);
4174
- });
4175
- const droppedCitations = citedFindings.filter(
4176
- (finding) => !inScopeCited.includes(finding)
4177
- );
4178
- const actionableFindings = inScopeCited.filter(
4179
- (finding) => finding.verification?.status === "verified"
4180
- );
4181
- const unverifiedInScope = inScopeCited.filter(
4182
- (finding) => finding.verification?.status === "unverified"
4183
- );
4184
- const failedVerificationCount = inScopeCited.filter(
4185
- (finding) => finding.verification?.status === "failed"
4186
- ).length;
4187
- const effectiveHasFindings = reviewHasFindings && (actionableFindings.length > 0 || unverifiedInScope.length > 0);
4188
- const verifiedCount = actionableFindings.length;
4189
- const unverifiedCount = unverifiedInScope.length;
4190
- const hallucinationNote = droppedCitations.length > 0 ? `
4174
+ const changedBasenameIndex = /* @__PURE__ */ new Map();
4175
+ for (const file of p.files) {
4176
+ const normalized = normalizeFileKeyForCitation(file.path, p.cwd);
4177
+ const basename7 = path12.basename(file.path).toLowerCase();
4178
+ const bucket = changedBasenameIndex.get(basename7);
4179
+ if (bucket) bucket.push(normalized);
4180
+ else changedBasenameIndex.set(basename7, [normalized]);
4181
+ }
4182
+ const inScopeCited = citedFindings.filter((finding) => {
4183
+ const citedKey = normalizeFileKeyForCitation(finding.location.file, p.cwd);
4184
+ if (citedPaths.has(citedKey)) return true;
4185
+ const suffixMatches = [...citedPaths].filter(
4186
+ (cp) => cp.endsWith(`/${citedKey}`) || cp === citedKey
4187
+ );
4188
+ if (suffixMatches.length === 1) return true;
4189
+ const basename7 = path12.basename(finding.location.file).toLowerCase();
4190
+ const bucket = changedBasenameIndex.get(basename7);
4191
+ return !!(bucket && bucket.length === 1);
4192
+ });
4193
+ const droppedCitations = citedFindings.filter(
4194
+ (finding) => !inScopeCited.includes(finding)
4195
+ );
4196
+ const actionableFindings = inScopeCited.filter(
4197
+ (finding) => finding.verification?.status === "verified"
4198
+ );
4199
+ const unverifiedInScope = inScopeCited.filter(
4200
+ (finding) => finding.verification?.status === "unverified"
4201
+ );
4202
+ const failedVerificationCount = inScopeCited.filter(
4203
+ (finding) => finding.verification?.status === "failed"
4204
+ ).length;
4205
+ const effectiveHasFindings = reviewHasFindings && (actionableFindings.length > 0 || unverifiedInScope.length > 0);
4206
+ const verifiedCount = actionableFindings.length;
4207
+ const unverifiedCount = unverifiedInScope.length;
4208
+ const hallucinationNote = droppedCitations.length > 0 ? `
4191
4209
 
4192
4210
  \u26A0\uFE0F Citation validation: ${droppedCitations.length} finding(s) cite files outside the changed-file set and should be verified before acting.` : "";
4193
- const subject = `\u{1F982} Chimera report ready \u2014 ${p.files.length} file(s) checked`;
4194
- let reviewMailMessageId;
4195
- try {
4196
- const directive = effectiveHasFindings ? "Chimera found potential issues. This report is informational: no leader turn, fix agent, or cascade was started. Open the report and explicitly ask the leader to act if you want changes." : "Chimera completed with no actionable findings. No follow-up was started.";
4197
- const reviewBody = reviewText.length > 7500 ? truncateAtCodePointBoundary(reviewText, 7500) + "\n\n\u2026(truncated, full report is in the Chimera report store)" : reviewText;
4198
- const body = `${directive}${hallucinationNote}
4211
+ const subject = `\u{1F982} Chimera report ready \u2014 ${p.files.length} file(s) checked`;
4212
+ let reviewMailMessageId;
4213
+ try {
4214
+ const directive = effectiveHasFindings ? "Chimera found potential issues. This report is informational: no leader turn, fix agent, or cascade was started. Open the report and explicitly ask the leader to act if you want changes." : "Chimera completed with no actionable findings. No follow-up was started.";
4215
+ const reviewBody = reviewText.length > 7500 ? truncateAtCodePointBoundary(reviewText, 7500) + "\n\n\u2026(truncated, full report is in the Chimera report store)" : reviewText;
4216
+ const body = `${directive}${hallucinationNote}
4199
4217
 
4200
4218
  ${reviewBody}`;
4201
- const mailMsg = await mailbox.send({
4202
- from: "chimera-review",
4203
- to: "leader",
4204
- type: "result",
4205
- audience: "leaders",
4206
- subject,
4207
- body,
4208
- priority: "normal",
4209
- // Session-affinity stamp: the recipient's leader filter
4210
- // uses this to drop the message for any leader whose current
4211
- // session id does NOT match the originating session of the
4212
- // review (`reviewSessionId` is captured above from the
4213
- // agent's active run / session id). Without this token the
4214
- // project-wide mailbox would deliver every chimera result to
4215
- // every leader, inviting them to act on reports that belong
4216
- // to a different session.
4217
- sessionAffinity: {
4218
- sessionId: reviewSessionId,
4219
- reportId,
4220
- kind: "chimera.review"
4221
- }
4222
- });
4223
- if (!mailMsg?.id) throw new Error("mailbox.send returned no message id");
4224
- reviewMailMessageId = mailMsg.id;
4225
- events.emitCustom("chimera.mailbox_delivered", {
4226
- subject,
4227
- autoFixMode: "off",
4228
- fileCount: p.files.length,
4229
- reviewLength: reviewText.length,
4230
- messageId: reviewMailMessageId
4231
- });
4232
- if (!reviewHasFindings) {
4233
- try {
4234
- await mailbox.ack({
4235
- messageId: reviewMailMessageId,
4236
- readerId: "chimera",
4237
- completed: true,
4238
- outcome: "Review completed with no actionable findings."
4239
- });
4240
- } catch (ackError) {
4241
- console.warn(
4242
- JSON.stringify({
4243
- level: "warn",
4244
- event: "execution.chimera_mailbox_completion_failed",
4245
- message: ackError instanceof Error ? ackError.message : String(ackError),
4219
+ const mailMsg = await mailbox.send({
4220
+ from: "chimera-review",
4221
+ to: "leader",
4222
+ type: "result",
4223
+ audience: "leaders",
4224
+ subject,
4225
+ body,
4226
+ priority: "normal",
4227
+ // Session-affinity stamp: the recipient's leader filter
4228
+ // uses this to drop the message for any leader whose current
4229
+ // session id does NOT match the originating session of the
4230
+ // review (`reviewSessionId` is captured above from the
4231
+ // agent's active run / session id). Without this token the
4232
+ // project-wide mailbox would deliver every chimera result to
4233
+ // every leader, inviting them to act on reports that belong
4234
+ // to a different session.
4235
+ sessionAffinity: {
4236
+ sessionId: reviewSessionId,
4237
+ reportId,
4238
+ kind: "chimera.review"
4239
+ }
4240
+ });
4241
+ if (!mailMsg?.id) throw new Error("mailbox.send returned no message id");
4242
+ reviewMailMessageId = mailMsg.id;
4243
+ events.emitCustom("chimera.mailbox_delivered", {
4244
+ subject,
4245
+ autoFixMode: "off",
4246
+ fileCount: p.files.length,
4247
+ reviewLength: reviewText.length,
4248
+ messageId: reviewMailMessageId
4249
+ });
4250
+ if (!reviewHasFindings) {
4251
+ try {
4252
+ await mailbox.ack({
4246
4253
  messageId: reviewMailMessageId,
4247
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
4248
- })
4249
- );
4254
+ readerId: "chimera",
4255
+ completed: true,
4256
+ outcome: "Review completed with no actionable findings."
4257
+ });
4258
+ } catch (ackError) {
4259
+ console.warn(
4260
+ JSON.stringify({
4261
+ level: "warn",
4262
+ event: "execution.chimera_mailbox_completion_failed",
4263
+ message: ackError instanceof Error ? ackError.message : String(ackError),
4264
+ messageId: reviewMailMessageId,
4265
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4266
+ })
4267
+ );
4268
+ }
4250
4269
  }
4270
+ } catch (mailErr) {
4271
+ const errMsg = mailErr instanceof Error ? mailErr.message : String(mailErr);
4272
+ console.error(
4273
+ JSON.stringify({
4274
+ level: "error",
4275
+ event: "execution.chimera_mailbox_failed",
4276
+ message: errMsg,
4277
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4278
+ })
4279
+ );
4280
+ events.emitCustom("chimera.mailbox_failed", {
4281
+ subject,
4282
+ autoFixMode: "off",
4283
+ fileCount: p.files.length,
4284
+ reviewLength: reviewText.length,
4285
+ error: errMsg
4286
+ });
4287
+ await session.append({
4288
+ type: "error",
4289
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
4290
+ message: `\u{1F982} Chimera report ${reportId} is ready, but mailbox delivery failed: ${errMsg}. No follow-up was started.`,
4291
+ phase: "agent"
4292
+ });
4251
4293
  }
4252
- } catch (mailErr) {
4253
- const errMsg = mailErr instanceof Error ? mailErr.message : String(mailErr);
4254
- console.error(
4255
- JSON.stringify({
4256
- level: "error",
4257
- event: "execution.chimera_mailbox_failed",
4258
- message: errMsg,
4259
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
4260
- })
4261
- );
4262
- events.emitCustom("chimera.mailbox_failed", {
4263
- subject,
4264
- autoFixMode: "off",
4294
+ const findingCount = actionableFindings.length;
4295
+ const message = effectiveHasFindings ? `\u{1F982} Chimera report ready \u2014 ${findingCount || "unparsed"} potential finding(s) (${verifiedCount} verified against disk, ${unverifiedCount} unverified, ${failedVerificationCount} failed) across ${p.files.length} file(s). No follow-up started; open the mailbox and explicitly ask the leader to act if wanted.` : `\u{1F982} Chimera report ready \u2014 ${p.files.length} file(s) checked, no actionable findings. No follow-up started.`;
4296
+ events.emitCustom("chimera.report_available", {
4297
+ reportId,
4298
+ sessionId: reviewSessionId,
4299
+ message,
4265
4300
  fileCount: p.files.length,
4266
- reviewLength: reviewText.length,
4267
- error: errMsg
4301
+ findingCount,
4302
+ hasActionableFindings: effectiveHasFindings,
4303
+ ...reviewMailMessageId ? { messageId: reviewMailMessageId } : {}
4268
4304
  });
4305
+ }
4306
+ } catch (err) {
4307
+ try {
4269
4308
  await session.append({
4270
4309
  type: "error",
4271
4310
  ts: (/* @__PURE__ */ new Date()).toISOString(),
4272
- message: `\u{1F982} Chimera report ${reportId} is ready, but mailbox delivery failed: ${errMsg}. No follow-up was started.`,
4311
+ message: `\u{1F982} Chimera review failed: ${err instanceof Error ? err.message : String(err)}`,
4273
4312
  phase: "agent"
4274
4313
  });
4314
+ } catch (appendErr) {
4315
+ console.error(
4316
+ JSON.stringify({
4317
+ level: "error",
4318
+ event: "execution.chimera_review_append_failed",
4319
+ message: appendErr instanceof Error ? appendErr.message : String(appendErr),
4320
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4321
+ })
4322
+ );
4275
4323
  }
4276
- const findingCount = actionableFindings.length;
4277
- const message = effectiveHasFindings ? `\u{1F982} Chimera report ready \u2014 ${findingCount || "unparsed"} potential finding(s) (${verifiedCount} verified against disk, ${unverifiedCount} unverified, ${failedVerificationCount} failed) across ${p.files.length} file(s). No follow-up started; open the mailbox and explicitly ask the leader to act if wanted.` : `\u{1F982} Chimera report ready \u2014 ${p.files.length} file(s) checked, no actionable findings. No follow-up started.`;
4278
- events.emitCustom("chimera.report_available", {
4279
- reportId,
4280
- sessionId: reviewSessionId,
4281
- message,
4282
- fileCount: p.files.length,
4283
- findingCount,
4284
- hasActionableFindings: effectiveHasFindings,
4285
- ...reviewMailMessageId ? { messageId: reviewMailMessageId } : {}
4286
- });
4287
- }
4288
- } catch (err) {
4289
- try {
4290
- await session.append({
4291
- type: "error",
4292
- ts: (/* @__PURE__ */ new Date()).toISOString(),
4293
- message: `\u{1F982} Chimera review failed: ${err instanceof Error ? err.message : String(err)}`,
4294
- phase: "agent"
4295
- });
4296
- } catch (appendErr) {
4297
- console.error(
4298
- JSON.stringify({
4299
- level: "error",
4300
- event: "execution.chimera_review_append_failed",
4301
- message: appendErr instanceof Error ? appendErr.message : String(appendErr),
4302
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
4303
- })
4304
- );
4305
- }
4306
- } finally {
4307
- if (subagentId) {
4308
- try {
4309
- await dir.terminate(subagentId);
4310
- } catch {
4324
+ } finally {
4325
+ if (subagentId) {
4326
+ try {
4327
+ await dir.terminate(subagentId);
4328
+ } catch {
4329
+ }
4311
4330
  }
4312
4331
  }
4313
- }
4314
- })()
4315
- );
4316
- }, "chimera-review");
4332
+ })()
4333
+ );
4334
+ },
4335
+ "chimera-review"
4336
+ );
4317
4337
  if (off) teardownHandlers?.push(off);
4318
4338
  }
4319
4339
  async function persistChimeraReview(payload, projectDir) {
@@ -4825,9 +4845,7 @@ async function runReplEternalLoop(opts, onInterruptsReset) {
4825
4845
  if (autonomy === "eternal-parallel") {
4826
4846
  const engine = opts.getParallelEngine?.();
4827
4847
  if (!engine) {
4828
- opts.renderer.writeWarning(
4829
- "Parallel mode set but no engine wired \u2014 falling back to off."
4830
- );
4848
+ opts.renderer.writeWarning("Parallel mode set but no engine wired \u2014 falling back to off.");
4831
4849
  return false;
4832
4850
  }
4833
4851
  const beforeGoal = await loadGoalSafe(opts);
@@ -4841,10 +4859,8 @@ async function runReplEternalLoop(opts, onInterruptsReset) {
4841
4859
  ) + "\n"
4842
4860
  );
4843
4861
  }
4844
- opts.renderer.write(
4845
- color8.magenta(` \u21B3 [parallel #${beforeIter + 1}] launching fan-out\u2026
4846
- `)
4847
- );
4862
+ opts.renderer.write(color8.magenta(` \u21B3 [parallel #${beforeIter + 1}] launching fan-out\u2026
4863
+ `));
4848
4864
  onInterruptsReset();
4849
4865
  try {
4850
4866
  await engine.runOneIteration();
@@ -5691,7 +5707,11 @@ function tierMenu(store) {
5691
5707
  ],
5692
5708
  body: "A tier binds a fallback profile, a spend budget and a runtime setting under one name, then routes work to it by role or phase. While disabled, spawns resolve exactly as they did before tiers existed.",
5693
5709
  actions: [
5694
- { key: "t", label: enabled ? "turn off" : "turn on", command: `/tier ${enabled ? "off" : "on"}` }
5710
+ {
5711
+ key: "t",
5712
+ label: enabled ? "turn off" : "turn on",
5713
+ command: `/tier ${enabled ? "off" : "on"}`
5714
+ }
5695
5715
  ]
5696
5716
  },
5697
5717
  {
@@ -5725,8 +5745,14 @@ function tierMenu(store) {
5725
5745
  details: [
5726
5746
  { label: "rung", value: `${index + 1} of ${levelIds.length}` },
5727
5747
  { label: "profile", value: level?.fallbackProfile ?? "(none)" },
5728
- { label: "max cost", value: level?.maxCostUsd !== void 0 ? `$${level.maxCostUsd}` : "(role default)" },
5729
- { label: "max iterations", value: level?.maxIterations !== void 0 ? String(level.maxIterations) : "(role default)" },
5748
+ {
5749
+ label: "max cost",
5750
+ value: level?.maxCostUsd !== void 0 ? `$${level.maxCostUsd}` : "(role default)"
5751
+ },
5752
+ {
5753
+ label: "max iterations",
5754
+ value: level?.maxIterations !== void 0 ? String(level.maxIterations) : "(role default)"
5755
+ },
5730
5756
  { label: "routed by", value: routedBy.join(", ") || "(nothing)" }
5731
5757
  ],
5732
5758
  body: [
@@ -6698,4 +6724,4 @@ export {
6698
6724
  execute,
6699
6725
  resolveReviewerFallbackModels
6700
6726
  };
6701
- //# sourceMappingURL=execution-DKJDNPYF.js.map
6727
+ //# sourceMappingURL=execution-7ZFY4FJY.js.map