@kernlang/agon 0.1.3 → 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 (34) hide show
  1. package/dist/{chunk-52VTWOLH.js → chunk-46WNYE4R.js} +118 -162
  2. package/dist/chunk-46WNYE4R.js.map +1 -0
  3. package/dist/{chunk-XOJPAFCJ.js → chunk-4NTH3EAR.js} +286 -541
  4. package/dist/chunk-4NTH3EAR.js.map +1 -0
  5. package/dist/{chunk-H7KZ34VX.js → chunk-73ETZFDH.js} +8 -27
  6. package/dist/chunk-73ETZFDH.js.map +1 -0
  7. package/dist/chunk-DGTU4UWQ.js +489 -0
  8. package/dist/chunk-DGTU4UWQ.js.map +1 -0
  9. package/dist/chunk-GPYWJO2Q.js +2924 -0
  10. package/dist/chunk-GPYWJO2Q.js.map +1 -0
  11. package/dist/{chunk-PFHGKBQT.js → chunk-HAJIKZGU.js} +912 -228
  12. package/dist/chunk-HAJIKZGU.js.map +1 -0
  13. package/dist/chunk-HSPQEDHX.js +102 -0
  14. package/dist/chunk-HSPQEDHX.js.map +1 -0
  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-6NV4WCMB.js → forge-ZI7NE73F.js} +6 -5
  19. package/dist/index.js +2070 -3551
  20. package/dist/index.js.map +1 -1
  21. package/dist/plan-mode-KIXDKD63.js +17 -0
  22. package/dist/{src-4VOZ6GIN.js → src-4A5FVACG.js} +53 -3
  23. package/dist/update-DLPMYTF3.js +30 -0
  24. package/dist/update-DLPMYTF3.js.map +1 -0
  25. package/package.json +4 -4
  26. package/dist/chunk-52VTWOLH.js.map +0 -1
  27. package/dist/chunk-H7KZ34VX.js.map +0 -1
  28. package/dist/chunk-PFHGKBQT.js.map +0 -1
  29. package/dist/chunk-XOJPAFCJ.js.map +0 -1
  30. package/dist/plan-mode-OSU42TOI.js +0 -15
  31. /package/dist/{dispatch-6LQSMMGI.js.map → dispatch-XHLJ44TF.js.map} +0 -0
  32. /package/dist/{forge-6NV4WCMB.js.map → forge-ZI7NE73F.js.map} +0 -0
  33. /package/dist/{plan-mode-OSU42TOI.js.map → plan-mode-KIXDKD63.js.map} +0 -0
  34. /package/dist/{src-4VOZ6GIN.js.map → src-4A5FVACG.js.map} +0 -0
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- ENGINE_COLORS,
3
+ stripReasoning,
4
+ stripTuiChrome
5
+ } from "./chunk-HSPQEDHX.js";
6
+ import {
4
7
  filterDefaultOrchestrationEngines,
5
8
  getSessionAllowList,
6
9
  handleCesarBrain,
@@ -8,8 +11,13 @@ import {
8
11
  runCampfire,
9
12
  runDelegate,
10
13
  runForge,
11
- runTribunal
12
- } from "./chunk-XOJPAFCJ.js";
14
+ runTribunal,
15
+ sessionResultStore
16
+ } from "./chunk-4NTH3EAR.js";
17
+ import {
18
+ ENGINE_COLORS,
19
+ icons
20
+ } from "./chunk-DGTU4UWQ.js";
13
21
  import {
14
22
  AgentSession,
15
23
  AgentTeam,
@@ -49,7 +57,7 @@ import {
49
57
  spawnWithTimeout,
50
58
  tracker,
51
59
  worktreeChangedDiff
52
- } from "./chunk-PFHGKBQT.js";
60
+ } from "./chunk-HAJIKZGU.js";
53
61
 
54
62
  // src/generated/handlers/plan-mode.ts
55
63
  import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
@@ -194,98 +202,6 @@ function buildConsensus(outcomes, minVerified, minPair) {
194
202
  };
195
203
  }
196
204
 
197
- // src/generated/blocks/engine-helpers.ts
198
- function parseToolInputPayload(input) {
199
- const rawInput = String(input ?? "");
200
- let parsed = {};
201
- try {
202
- if (rawInput.trim().startsWith("{")) {
203
- parsed = JSON.parse(rawInput);
204
- }
205
- } catch (e) {
206
- parsed = {};
207
- }
208
- return { rawInput, parsed };
209
- }
210
- function extractPatchText(rawInput, parsed) {
211
- const values = [parsed?.patch, parsed?.content, parsed?.diff, parsed?.input].filter((value) => typeof value === "string" && value.trim().length > 0);
212
- const fromParsed = values.find((value) => value.includes("*** Begin Patch") || value.includes("diff --git") || value.split("\n").some((line) => line.startsWith("@@")));
213
- if (fromParsed) {
214
- return fromParsed;
215
- }
216
- if (rawInput.includes("*** Begin Patch") || rawInput.includes("diff --git") || rawInput.split("\n").some((line) => line.startsWith("@@"))) {
217
- return rawInput;
218
- }
219
- return values[0] ?? "";
220
- }
221
- function parsePatchPreview(rawInput, parsed) {
222
- const patchText = extractPatchText(rawInput, parsed);
223
- const files = [];
224
- const lines = [];
225
- let additions = 0;
226
- let deletions = 0;
227
- const addFile = (filePath) => {
228
- const clean = filePath.trim().replace(/^["']|["']$/g, "");
229
- if (clean && !files.includes(clean)) files.push(clean);
230
- };
231
- for (const line of patchText.split("\n")) {
232
- const customFile = line.match(/^\*\*\* (?:Update|Add|Delete) File: (.+)$/);
233
- if (customFile) {
234
- addFile(customFile[1]);
235
- continue;
236
- }
237
- const diffFile = line.match(/^diff --git a\/(.+?) b\/(.+)$/);
238
- if (diffFile) {
239
- addFile(diffFile[2]);
240
- continue;
241
- }
242
- if (line.startsWith("+++ b/")) {
243
- addFile(line.slice("+++ b/".length));
244
- continue;
245
- }
246
- if (line.startsWith("--- a/")) {
247
- addFile(line.slice("--- a/".length));
248
- continue;
249
- }
250
- if (line.startsWith("@@")) {
251
- lines.push(line);
252
- continue;
253
- }
254
- if (line.startsWith("+") && !line.startsWith("+++")) {
255
- additions += 1;
256
- lines.push(line);
257
- continue;
258
- }
259
- if (line.startsWith("-") && !line.startsWith("---")) {
260
- deletions += 1;
261
- lines.push(line);
262
- }
263
- }
264
- return { files, lines, additions, deletions };
265
- }
266
- function extractSummary(text, maxLen) {
267
- let s = text.replace(/<think>[\s\S]*?<\/think>\s*/gi, "");
268
- s = s.replace(/^#+\s+.+\n/gm, "");
269
- s = s.replace(/^\s*[-*]\s+/gm, "");
270
- s = s.replace(/\*\*/g, "");
271
- s = s.trim();
272
- const firstSentence = s.match(/^[^.!?\n]{10,}[.!?]/);
273
- const summary = firstSentence ? firstSentence[0] : s.slice(0, maxLen);
274
- return summary.length > maxLen ? summary.slice(0, maxLen - 1) + "\u2026" : summary;
275
- }
276
- function stripReasoning(text) {
277
- return text.replace(/<(think|thinking|reasoning)>[\s\S]*?<\/\1>\s*/gi, "").trim();
278
- }
279
- function stripTuiChrome(text) {
280
- const hadChrome = /[·✢✳✶✻✽⎿]/.test(text);
281
- let s = text.replace(/[·✢✳✴✵✶✷✸✹✺✻✼✽✾⎿]/g, "").replace(/❯/g, "");
282
- if (hadChrome) {
283
- s = s.replace(/[A-Z][^\n…]{0,40}…/g, "");
284
- s = s.replace(/^[\s\d%]+/, "");
285
- }
286
- return s.replace(/[ \t]{2,}/g, " ").replace(/\n{3,}/g, "\n\n").trim();
287
- }
288
-
289
205
  // src/generated/handlers/review.ts
290
206
  function resolveReviewTarget(target, cwd) {
291
207
  const t = (target ?? "uncommitted").trim();
@@ -727,6 +643,50 @@ ${repairBlock}`;
727
643
  const severityCounts = summarizeReviewFindings(response);
728
644
  return { response, blocking, parseFailed, unstructured, severityCounts, usage };
729
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
+ }
730
690
  async function handleReview(dispatch, ctx, target, requestedEngine) {
731
691
  const abort = new AbortController();
732
692
  try {
@@ -756,15 +716,8 @@ async function handleReview(dispatch, ctx, target, requestedEngine) {
756
716
  dispatch({ type: "spinner-start", message: `${engineId} reviewing ${label}\u2026`, color });
757
717
  let response = "";
758
718
  let unstructured = false;
759
- let streaming = false;
760
719
  try {
761
- const result = await runReviewCore(diff, label, engineId, ctx, abort.signal, (chunk) => {
762
- if (!streaming) {
763
- dispatch({ type: "spinner-stop" });
764
- streaming = true;
765
- }
766
- dispatch({ type: "streaming-chunk", engineId, chunk });
767
- });
720
+ const result = await runReviewCore(diff, label, engineId, ctx, abort.signal);
768
721
  response = result.response;
769
722
  unstructured = result.unstructured;
770
723
  } catch (err) {
@@ -772,32 +725,51 @@ async function handleReview(dispatch, ctx, target, requestedEngine) {
772
725
  dispatch({ type: "error", message: `${engineId}: ${err instanceof Error ? err.message : String(err)}` });
773
726
  return;
774
727
  }
728
+ dispatch({ type: "spinner-stop" });
775
729
  if (abort.signal.aborted) {
776
- dispatch({ type: "spinner-stop" });
777
730
  return;
778
731
  }
779
- if (!streaming && response) {
780
- dispatch({ type: "engine-block", engineId, color, content: response });
781
- }
782
- if (streaming) {
783
- dispatch({ type: "streaming-end", engineId });
784
- }
785
- if (response) {
786
- appendMessage(ctx.chatSession, { role: "user", content: `[review ${label}]`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
787
- appendMessage(ctx.chatSession, { role: "engine", engineId, content: response, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
788
- tracker.record(engineId, { prompt: `[review ${label}]`, response });
789
- ctx.lastReviewResult = {
790
- engineId,
791
- target: target ?? "uncommitted",
792
- label,
793
- diff,
794
- reviewOutput: response,
795
- timestamp: Date.now()
796
- };
797
- 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.` });
798
- } else {
732
+ if (!response) {
799
733
  dispatch({ type: "warning", message: `${engineId} returned no review output.` });
734
+ return;
800
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.` });
801
773
  } finally {
802
774
  dispatch({ type: "spinner-stop" });
803
775
  ctx.setActiveAbort(null);
@@ -845,7 +817,6 @@ async function handleReviewMany(dispatch, ctx, target, requestedEngines) {
845
817
  timedOut = true;
846
818
  controller.abort();
847
819
  }, timeoutSec * 1e3);
848
- const color = ENGINE_COLORS[engineId] ?? 124;
849
820
  try {
850
821
  const result = await runReviewCore(diff, label, engineId, ctx, controller.signal);
851
822
  const response = (result.response ?? "").trim();
@@ -857,10 +828,11 @@ async function handleReviewMany(dispatch, ctx, target, requestedEngines) {
857
828
  dispatch({ type: "warning", message: `${engineId} returned no review output.` });
858
829
  return { engineId, reviewOutput: "", unstructured: false, status: "error", note: "no output" };
859
830
  }
860
- 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)}` });
861
833
  appendMessage(ctx.chatSession, { role: "engine", engineId, content: response, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
862
834
  tracker.record(engineId, { prompt: `[review ${label}]`, response });
863
- return { engineId, reviewOutput: response, unstructured: result.unstructured, status: result.unstructured ? "parse-failed" : "ok" };
835
+ return { engineId, reviewOutput: response, unstructured: result.unstructured, status };
864
836
  } catch (err) {
865
837
  if (timedOut) {
866
838
  dispatch({ type: "warning", message: `${engineId}: timed out after ${timeoutSec}s \u2014 skipped.` });
@@ -880,36 +852,10 @@ async function handleReviewMany(dispatch, ctx, target, requestedEngines) {
880
852
  dispatch({ type: "warning", message: `No review output returned from ${engineIds.join(", ")}.` });
881
853
  return;
882
854
  }
883
- const outcomes = all.map((c) => {
884
- if (c.status !== "ok") return { engine: c.engineId, status: c.status, findings: [], note: c.note };
885
- const raw = extractReviewFindings(c.reviewOutput) || [];
886
- const findings = raw.map((x) => ({
887
- engine: c.engineId,
888
- severity: typeof x.severity === "string" ? x.severity : x.blocking ? "blocking" : "nit",
889
- blocking: x.blocking,
890
- confidence: x.confidence,
891
- file: x.file,
892
- lines: x.lines,
893
- problem: x.problem,
894
- minimalFix: x.minimalFix
895
- }));
896
- return { engine: c.engineId, status: "ok", findings };
897
- });
855
+ const outcomes = all.map((c) => reviewOutcome(c.engineId, c.reviewOutput, c.status, c.note));
898
856
  const consensus = buildConsensus(outcomes);
899
- 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 : ""})` : ""}`;
900
- const lines = [`Consensus \u2014 ${consensus.summary}`];
901
- if (consensus.verified.length) {
902
- lines.push("VERIFIED (actionable):");
903
- for (const f of consensus.verified) lines.push(fmt(f));
904
- }
905
- if (consensus.needsCheck.length) {
906
- lines.push("NEEDS-CHECK (want a second opinion):");
907
- for (const f of consensus.needsCheck) lines.push(fmt(f));
908
- }
909
- if (consensus.speculative.length) lines.push(`SPECULATIVE: ${consensus.speculative.length} low-confidence finding(s) \u2014 likely noise.`);
910
- if (consensus.nits.length) lines.push(`NITS: ${consensus.nits.length}.`);
911
- if (consensus.engineFailures.length) lines.push(`FAILED (no machine verdict): ${consensus.engineFailures.map((e) => `${e.engine} (${e.status})`).join(", ")}.`);
912
- 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 });
913
859
  const anyUnstructured = collected.some((c) => c.unstructured);
914
860
  ctx.lastReviewResult = {
915
861
  engineId: collected.map((r) => r.engineId).join(", "),
@@ -921,7 +867,20 @@ async function handleReviewMany(dispatch, ctx, target, requestedEngines) {
921
867
  ${r.reviewOutput}`).join("\n\n---\n\n"),
922
868
  timestamp: Date.now()
923
869
  };
924
- 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.` });
925
884
  } finally {
926
885
  ctx.setActiveAbort(null);
927
886
  }
@@ -2709,9 +2668,6 @@ ${tResult.summary}` },
2709
2668
 
2710
2669
  export {
2711
2670
  buildConsensus,
2712
- parseToolInputPayload,
2713
- parsePatchPreview,
2714
- extractSummary,
2715
2671
  resolveReviewTarget,
2716
2672
  selectReviewEngine,
2717
2673
  extractReviewFindings,
@@ -2724,4 +2680,4 @@ export {
2724
2680
  handleExitPlanMode,
2725
2681
  buildStepExecutors
2726
2682
  };
2727
- //# sourceMappingURL=chunk-52VTWOLH.js.map
2683
+ //# sourceMappingURL=chunk-46WNYE4R.js.map