@kernlang/agon 0.1.4 → 0.1.5

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 (35) hide show
  1. package/dist/{chunk-O6YP55RV.js → chunk-46WNYE4R.js} +114 -69
  2. package/dist/chunk-46WNYE4R.js.map +1 -0
  3. package/dist/{chunk-FCCH7IPJ.js → chunk-4NTH3EAR.js} +39 -11
  4. package/dist/chunk-4NTH3EAR.js.map +1 -0
  5. package/dist/{chunk-4LVYSUMN.js → chunk-73ETZFDH.js} +6 -27
  6. package/dist/chunk-73ETZFDH.js.map +1 -0
  7. package/dist/{chunk-WE32YJKT.js → chunk-DGTU4UWQ.js} +2 -2
  8. package/dist/{chunk-WE32YJKT.js.map → chunk-DGTU4UWQ.js.map} +1 -1
  9. package/dist/{chunk-ATUT2BUQ.js → chunk-GPYWJO2Q.js} +24 -7
  10. package/dist/chunk-GPYWJO2Q.js.map +1 -0
  11. package/dist/{chunk-C22VTCS6.js → chunk-HAJIKZGU.js} +846 -219
  12. package/dist/chunk-HAJIKZGU.js.map +1 -0
  13. package/dist/{chunk-6ANHPXGZ.js → chunk-HSPQEDHX.js} +1 -1
  14. package/dist/{chunk-6ANHPXGZ.js.map → chunk-HSPQEDHX.js.map} +1 -1
  15. package/dist/{chunk-5QMVQPHY.js → chunk-SOUF7XTW.js} +1 -1
  16. package/dist/{chunk-5QMVQPHY.js.map → chunk-SOUF7XTW.js.map} +1 -1
  17. package/dist/{dispatch-6LQSMMGI.js → dispatch-XHLJ44TF.js} +2 -2
  18. package/dist/{forge-ES4RN7YM.js → forge-ZI7NE73F.js} +6 -6
  19. package/dist/index.js +550 -121
  20. package/dist/index.js.map +1 -1
  21. package/dist/plan-mode-KIXDKD63.js +17 -0
  22. package/dist/{src-WJGIOESS.js → src-4A5FVACG.js} +49 -3
  23. package/dist/{update-HHN4PJQI.js → update-DLPMYTF3.js} +6 -6
  24. package/package.json +4 -4
  25. package/dist/chunk-4LVYSUMN.js.map +0 -1
  26. package/dist/chunk-ATUT2BUQ.js.map +0 -1
  27. package/dist/chunk-C22VTCS6.js.map +0 -1
  28. package/dist/chunk-FCCH7IPJ.js.map +0 -1
  29. package/dist/chunk-O6YP55RV.js.map +0 -1
  30. package/dist/plan-mode-4XRC2ZC7.js +0 -17
  31. /package/dist/{dispatch-6LQSMMGI.js.map → dispatch-XHLJ44TF.js.map} +0 -0
  32. /package/dist/{forge-ES4RN7YM.js.map → forge-ZI7NE73F.js.map} +0 -0
  33. /package/dist/{plan-mode-4XRC2ZC7.js.map → plan-mode-KIXDKD63.js.map} +0 -0
  34. /package/dist/{src-WJGIOESS.js.map → src-4A5FVACG.js.map} +0 -0
  35. /package/dist/{update-HHN4PJQI.js.map → update-DLPMYTF3.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  stripReasoning,
4
4
  stripTuiChrome
5
- } from "./chunk-6ANHPXGZ.js";
5
+ } from "./chunk-HSPQEDHX.js";
6
6
  import {
7
7
  filterDefaultOrchestrationEngines,
8
8
  getSessionAllowList,
@@ -11,11 +11,13 @@ import {
11
11
  runCampfire,
12
12
  runDelegate,
13
13
  runForge,
14
- runTribunal
15
- } from "./chunk-FCCH7IPJ.js";
14
+ runTribunal,
15
+ sessionResultStore
16
+ } from "./chunk-4NTH3EAR.js";
16
17
  import {
17
- ENGINE_COLORS
18
- } from "./chunk-WE32YJKT.js";
18
+ ENGINE_COLORS,
19
+ icons
20
+ } from "./chunk-DGTU4UWQ.js";
19
21
  import {
20
22
  AgentSession,
21
23
  AgentTeam,
@@ -55,7 +57,7 @@ import {
55
57
  spawnWithTimeout,
56
58
  tracker,
57
59
  worktreeChangedDiff
58
- } from "./chunk-C22VTCS6.js";
60
+ } from "./chunk-HAJIKZGU.js";
59
61
 
60
62
  // src/generated/handlers/plan-mode.ts
61
63
  import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
@@ -641,6 +643,50 @@ ${repairBlock}`;
641
643
  const severityCounts = summarizeReviewFindings(response);
642
644
  return { response, blocking, parseFailed, unstructured, severityCounts, usage };
643
645
  }
646
+ function stripMachineBlock(response) {
647
+ const idx = response.lastIndexOf(REVIEW_SENTINEL);
648
+ if (idx < 0) return response;
649
+ return response.slice(0, idx).trimEnd();
650
+ }
651
+ function reviewOutcome(engineId, response, status, note) {
652
+ if (status !== "ok") return { engine: engineId, status, findings: [], note };
653
+ const raw = (extractReviewFindings(response) || []).filter((x) => x && typeof x === "object");
654
+ const findings = raw.map((x) => ({
655
+ engine: engineId,
656
+ severity: typeof x.severity === "string" ? x.severity : x.blocking ? "blocking" : "nit",
657
+ blocking: x.blocking,
658
+ confidence: x.confidence,
659
+ file: x.file,
660
+ lines: x.lines,
661
+ problem: x.problem,
662
+ minimalFix: x.minimalFix
663
+ }));
664
+ return { engine: engineId, status: "ok", findings };
665
+ }
666
+ function buildReviewConsensusLines(consensus) {
667
+ const fmt = (f) => ` \u2022 [${f.severity} ${f.maxConfidence.toFixed(2)} \xD7${f.engines.length}${f.pairVotes >= 2 ? " pair" : ""}] ${f.problem}${f.file ? ` (${f.file}${f.lines ? ":" + f.lines : ""})` : ""}`;
668
+ const lines = [`Consensus \u2014 ${consensus.summary}`];
669
+ if (consensus.verified.length) {
670
+ lines.push("VERIFIED (actionable):");
671
+ for (const f of consensus.verified) lines.push(fmt(f));
672
+ }
673
+ if (consensus.needsCheck.length) {
674
+ lines.push("NEEDS-CHECK (want a second opinion):");
675
+ for (const f of consensus.needsCheck) lines.push(fmt(f));
676
+ }
677
+ if (consensus.speculative.length) lines.push(`SPECULATIVE: ${consensus.speculative.length} low-confidence finding(s) \u2014 likely noise.`);
678
+ if (consensus.nits.length) lines.push(`NITS: ${consensus.nits.length}.`);
679
+ if (consensus.engineFailures.length) lines.push(`FAILED (no machine verdict): ${consensus.engineFailures.map((e) => `${e.engine} (${e.status})`).join(", ")}.`);
680
+ return lines;
681
+ }
682
+ function formatReviewCounts(c) {
683
+ if (!c || c.total === 0) return "no findings";
684
+ const parts = [];
685
+ if (c.blocking) parts.push(`${c.blocking} blocking`);
686
+ if (c.important) parts.push(`${c.important} important`);
687
+ if (c.nit) parts.push(`${c.nit} ${c.nit === 1 ? "nit" : "nits"}`);
688
+ return parts.join(", ");
689
+ }
644
690
  async function handleReview(dispatch, ctx, target, requestedEngine) {
645
691
  const abort = new AbortController();
646
692
  try {
@@ -670,15 +716,8 @@ async function handleReview(dispatch, ctx, target, requestedEngine) {
670
716
  dispatch({ type: "spinner-start", message: `${engineId} reviewing ${label}\u2026`, color });
671
717
  let response = "";
672
718
  let unstructured = false;
673
- let streaming = false;
674
719
  try {
675
- const result = await runReviewCore(diff, label, engineId, ctx, abort.signal, (chunk) => {
676
- if (!streaming) {
677
- dispatch({ type: "spinner-stop" });
678
- streaming = true;
679
- }
680
- dispatch({ type: "streaming-chunk", engineId, chunk });
681
- });
720
+ const result = await runReviewCore(diff, label, engineId, ctx, abort.signal);
682
721
  response = result.response;
683
722
  unstructured = result.unstructured;
684
723
  } catch (err) {
@@ -686,32 +725,51 @@ async function handleReview(dispatch, ctx, target, requestedEngine) {
686
725
  dispatch({ type: "error", message: `${engineId}: ${err instanceof Error ? err.message : String(err)}` });
687
726
  return;
688
727
  }
728
+ dispatch({ type: "spinner-stop" });
689
729
  if (abort.signal.aborted) {
690
- dispatch({ type: "spinner-stop" });
691
730
  return;
692
731
  }
693
- if (!streaming && response) {
694
- dispatch({ type: "engine-block", engineId, color, content: response });
695
- }
696
- if (streaming) {
697
- dispatch({ type: "streaming-end", engineId });
698
- }
699
- if (response) {
700
- appendMessage(ctx.chatSession, { role: "user", content: `[review ${label}]`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
701
- appendMessage(ctx.chatSession, { role: "engine", engineId, content: response, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
702
- tracker.record(engineId, { prompt: `[review ${label}]`, response });
703
- ctx.lastReviewResult = {
704
- engineId,
705
- target: target ?? "uncommitted",
706
- label,
707
- diff,
708
- reviewOutput: response,
709
- timestamp: Date.now()
710
- };
711
- dispatch({ type: "info", message: unstructured ? `Review complete (unstructured \u2014 findings weren't machine-parseable, but the review above is valid). Say "fix it" or "fix it with <engine>" to address it.` : `Review complete. Say "fix it" or "fix it with <engine>" to address the findings.` });
712
- } else {
732
+ if (!response) {
713
733
  dispatch({ type: "warning", message: `${engineId} returned no review output.` });
734
+ return;
714
735
  }
736
+ appendMessage(ctx.chatSession, { role: "user", content: `[review ${label}]`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
737
+ appendMessage(ctx.chatSession, { role: "engine", engineId, content: response, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
738
+ tracker.record(engineId, { prompt: `[review ${label}]`, response });
739
+ ctx.lastReviewResult = {
740
+ engineId,
741
+ target: target ?? "uncommitted",
742
+ label,
743
+ diff,
744
+ reviewOutput: response,
745
+ timestamp: Date.now()
746
+ };
747
+ const status = unstructured ? "unstructured" : "ok";
748
+ let consensusSummary;
749
+ let blocking = false;
750
+ if (status === "ok") {
751
+ const consensus = buildConsensus([reviewOutcome(engineId, response, status)]);
752
+ consensusSummary = buildReviewConsensusLines(consensus).join("\n");
753
+ blocking = consensus.autoBlock;
754
+ dispatch({ type: blocking ? "warning" : "info", message: consensusSummary });
755
+ } else {
756
+ consensusSummary = `${engineId}: unstructured review \u2014 no machine-parseable findings (the prose is valid).`;
757
+ dispatch({ type: "info", message: consensusSummary });
758
+ }
759
+ sessionResultStore.add({
760
+ type: "review",
761
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
762
+ question: label,
763
+ engines: [engineId],
764
+ winner: null,
765
+ data: {
766
+ label,
767
+ consensusSummary,
768
+ blocking,
769
+ reviews: [{ engineId, status, reviewOutput: stripMachineBlock(response) }]
770
+ }
771
+ });
772
+ dispatch({ type: "info", message: unstructured ? `Review complete (unstructured \u2014 no machine verdict, but the review is valid). Ctrl+R for the full review \xB7 say "fix it" to address it.` : `Review complete. Ctrl+R for the full review \xB7 say "fix it" or "fix it with <engine>" to address the findings.` });
715
773
  } finally {
716
774
  dispatch({ type: "spinner-stop" });
717
775
  ctx.setActiveAbort(null);
@@ -759,7 +817,6 @@ async function handleReviewMany(dispatch, ctx, target, requestedEngines) {
759
817
  timedOut = true;
760
818
  controller.abort();
761
819
  }, timeoutSec * 1e3);
762
- const color = ENGINE_COLORS[engineId] ?? 124;
763
820
  try {
764
821
  const result = await runReviewCore(diff, label, engineId, ctx, controller.signal);
765
822
  const response = (result.response ?? "").trim();
@@ -771,10 +828,11 @@ async function handleReviewMany(dispatch, ctx, target, requestedEngines) {
771
828
  dispatch({ type: "warning", message: `${engineId} returned no review output.` });
772
829
  return { engineId, reviewOutput: "", unstructured: false, status: "error", note: "no output" };
773
830
  }
774
- dispatch({ type: "engine-block", engineId, color, content: response });
831
+ const status = result.unstructured ? "unstructured" : "ok";
832
+ dispatch({ type: "info", message: result.unstructured ? `${icons().success} ${engineId}: unstructured (no machine verdict)` : `${icons().success} ${engineId}: ${formatReviewCounts(result.severityCounts)}` });
775
833
  appendMessage(ctx.chatSession, { role: "engine", engineId, content: response, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
776
834
  tracker.record(engineId, { prompt: `[review ${label}]`, response });
777
- return { engineId, reviewOutput: response, unstructured: result.unstructured, status: result.unstructured ? "parse-failed" : "ok" };
835
+ return { engineId, reviewOutput: response, unstructured: result.unstructured, status };
778
836
  } catch (err) {
779
837
  if (timedOut) {
780
838
  dispatch({ type: "warning", message: `${engineId}: timed out after ${timeoutSec}s \u2014 skipped.` });
@@ -794,36 +852,10 @@ async function handleReviewMany(dispatch, ctx, target, requestedEngines) {
794
852
  dispatch({ type: "warning", message: `No review output returned from ${engineIds.join(", ")}.` });
795
853
  return;
796
854
  }
797
- const outcomes = all.map((c) => {
798
- if (c.status !== "ok") return { engine: c.engineId, status: c.status, findings: [], note: c.note };
799
- const raw = extractReviewFindings(c.reviewOutput) || [];
800
- const findings = raw.map((x) => ({
801
- engine: c.engineId,
802
- severity: typeof x.severity === "string" ? x.severity : x.blocking ? "blocking" : "nit",
803
- blocking: x.blocking,
804
- confidence: x.confidence,
805
- file: x.file,
806
- lines: x.lines,
807
- problem: x.problem,
808
- minimalFix: x.minimalFix
809
- }));
810
- return { engine: c.engineId, status: "ok", findings };
811
- });
855
+ const outcomes = all.map((c) => reviewOutcome(c.engineId, c.reviewOutput, c.status, c.note));
812
856
  const consensus = buildConsensus(outcomes);
813
- const fmt = (f) => ` \u2022 [${f.severity} ${f.maxConfidence.toFixed(2)} \xD7${f.engines.length}${f.pairVotes >= 2 ? " pair" : ""}] ${f.problem}${f.file ? ` (${f.file}${f.lines ? ":" + f.lines : ""})` : ""}`;
814
- const lines = [`Consensus \u2014 ${consensus.summary}`];
815
- if (consensus.verified.length) {
816
- lines.push("VERIFIED (actionable):");
817
- for (const f of consensus.verified) lines.push(fmt(f));
818
- }
819
- if (consensus.needsCheck.length) {
820
- lines.push("NEEDS-CHECK (want a second opinion):");
821
- for (const f of consensus.needsCheck) lines.push(fmt(f));
822
- }
823
- if (consensus.speculative.length) lines.push(`SPECULATIVE: ${consensus.speculative.length} low-confidence finding(s) \u2014 likely noise.`);
824
- if (consensus.nits.length) lines.push(`NITS: ${consensus.nits.length}.`);
825
- if (consensus.engineFailures.length) lines.push(`FAILED (no machine verdict): ${consensus.engineFailures.map((e) => `${e.engine} (${e.status})`).join(", ")}.`);
826
- dispatch({ type: consensus.autoBlock ? "warning" : "info", message: lines.join("\n") });
857
+ const consensusSummary = buildReviewConsensusLines(consensus).join("\n");
858
+ dispatch({ type: consensus.autoBlock ? "warning" : "info", message: consensusSummary });
827
859
  const anyUnstructured = collected.some((c) => c.unstructured);
828
860
  ctx.lastReviewResult = {
829
861
  engineId: collected.map((r) => r.engineId).join(", "),
@@ -835,7 +867,20 @@ async function handleReviewMany(dispatch, ctx, target, requestedEngines) {
835
867
  ${r.reviewOutput}`).join("\n\n---\n\n"),
836
868
  timestamp: Date.now()
837
869
  };
838
- dispatch({ type: "info", message: `Multi-review complete (${collected.map((r) => r.engineId).join(", ")}).${anyUnstructured ? " Some reviews were unstructured (no machine verdict) but valid." : ""} Say "fix it" or "fix it with <engine>" to address the findings.` });
870
+ sessionResultStore.add({
871
+ type: "review",
872
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
873
+ question: label,
874
+ engines: collected.map((r) => r.engineId),
875
+ winner: null,
876
+ data: {
877
+ label,
878
+ consensusSummary,
879
+ blocking: consensus.autoBlock,
880
+ reviews: collected.map((r) => ({ engineId: r.engineId, status: r.status, reviewOutput: stripMachineBlock(r.reviewOutput) }))
881
+ }
882
+ });
883
+ dispatch({ type: "info", message: `Multi-review complete (${collected.map((r) => r.engineId).join(", ")}).${anyUnstructured ? " Some reviews were unstructured (no machine verdict) but valid." : ""} Ctrl+R for the full reviews \xB7 say "fix it" or "fix it with <engine>" to address the findings.` });
839
884
  } finally {
840
885
  ctx.setActiveAbort(null);
841
886
  }
@@ -2635,4 +2680,4 @@ export {
2635
2680
  handleExitPlanMode,
2636
2681
  buildStepExecutors
2637
2682
  };
2638
- //# sourceMappingURL=chunk-O6YP55RV.js.map
2683
+ //# sourceMappingURL=chunk-46WNYE4R.js.map