@khalilgharbaoui/opencode-claude-code-plugin 0.57.0 → 0.57.2

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/tui.js CHANGED
@@ -497,6 +497,7 @@ var TURN_SAMPLE_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
497
497
  var MIN_TURN_SAMPLES = 3;
498
498
  var CHARS_BANDWIDTH = Math.log(4);
499
499
  var OTHER_EFFORT_WEIGHT = 0.5;
500
+ var MIN_EFFORT_RATIO_SAMPLES = 2;
500
501
  var CHARS_FLOOR = 50;
501
502
  var pathOverride2 = null;
502
503
  function turnHistoryStorePath() {
@@ -531,6 +532,9 @@ function isSample(value) {
531
532
  return false;
532
533
  }
533
534
  if (sample.effort !== void 0 && typeof sample.effort !== "string") return false;
535
+ if (sample.calls !== void 0 && (typeof sample.calls !== "number" || !Number.isFinite(sample.calls) || sample.calls < 0)) {
536
+ return false;
537
+ }
534
538
  return true;
535
539
  }
536
540
  function cleanSample(sample) {
@@ -538,6 +542,7 @@ function cleanSample(sample) {
538
542
  ms: Math.round(sample.ms),
539
543
  ...sample.chars !== void 0 ? { chars: Math.round(sample.chars) } : {},
540
544
  ...sample.effort ? { effort: sample.effort } : {},
545
+ ...sample.calls !== void 0 ? { calls: Math.round(sample.calls) } : {},
541
546
  at: sample.at
542
547
  };
543
548
  }
@@ -596,16 +601,49 @@ function charsWeight(a, b) {
596
601
  function effortWeight(a, b) {
597
602
  return a === void 0 || b === void 0 || a === b ? 1 : OTHER_EFFORT_WEIGHT;
598
603
  }
604
+ function effortScales(samples, charsWeights, effort) {
605
+ const scales = /* @__PURE__ */ new Map();
606
+ if (effort === void 0) return scales;
607
+ const groups = /* @__PURE__ */ new Map();
608
+ samples.forEach((sample, index) => {
609
+ if (sample.effort === void 0) return;
610
+ const group = groups.get(sample.effort) ?? [];
611
+ group.push(index);
612
+ groups.set(sample.effort, group);
613
+ });
614
+ const own = groups.get(effort);
615
+ if (!own || own.length < MIN_EFFORT_RATIO_SAMPLES) return scales;
616
+ const medianOf = (indices) => weightedMedian(
617
+ indices.map((index) => samples[index].ms),
618
+ indices.map((index) => charsWeights[index])
619
+ );
620
+ const ownMedian = medianOf(own);
621
+ for (const [other, indices] of groups) {
622
+ if (other === effort || indices.length < MIN_EFFORT_RATIO_SAMPLES) continue;
623
+ const otherMedian = medianOf(indices);
624
+ if (ownMedian > 0 && otherMedian > 0) scales.set(other, ownMedian / otherMedian);
625
+ }
626
+ return scales;
627
+ }
599
628
  function estimateTurn(samples, input) {
600
629
  const usable = samples.filter((sample) => Number.isFinite(sample.ms) && sample.ms >= 0);
601
630
  if (usable.length < MIN_TURN_SAMPLES) return void 0;
602
631
  const elapsed = Math.max(0, input.elapsedMs);
603
- const weights = usable.map(
604
- (sample) => charsWeight(input.chars, sample.chars) * effortWeight(input.effort, sample.effort)
632
+ const charsWeights = usable.map((sample) => charsWeight(input.chars, sample.chars));
633
+ const scales = effortScales(usable, charsWeights, input.effort);
634
+ const scaled = usable.map((sample, index) => ({
635
+ ms: sample.ms * (sample.effort !== void 0 ? scales.get(sample.effort) ?? 1 : 1),
636
+ calls: sample.calls,
637
+ weight: charsWeights[index] * effortWeight(input.effort, sample.effort)
638
+ }));
639
+ const survivors = scaled.filter(
640
+ (sample) => sample.ms > elapsed && (sample.calls === void 0 || input.calls === void 0 || sample.calls >= input.calls)
605
641
  );
606
- const survivors = usable.map((sample, index) => ({ ms: sample.ms, weight: weights[index] })).filter((sample) => sample.ms > elapsed);
607
642
  if (survivors.length === 0) {
608
- const usual = weightedMedian(usable.map((sample) => sample.ms), weights);
643
+ const usual = weightedMedian(
644
+ scaled.map((sample) => sample.ms),
645
+ scaled.map((sample) => sample.weight)
646
+ );
609
647
  return { totalMs: usual, fill: 1, over: true };
610
648
  }
611
649
  const residual = weightedMedian(
@@ -786,7 +824,7 @@ function pressingWindow(windows, now) {
786
824
  var cells2 = (value) => Array.from(value).length;
787
825
  var segmentsCells = (segments) => segments.reduce((sum, segment) => sum + cells2(segment.text), 0);
788
826
  function levelRole(state) {
789
- return state === "limited" ? "error" : state === "warning" ? "effort" : "muted";
827
+ return state === "limited" ? "error" : state === "warning" ? "effort" : "ok";
790
828
  }
791
829
  function fitSegments(segments, budget) {
792
830
  const out = [];
@@ -884,6 +922,7 @@ var TASK_TOOLS = /* @__PURE__ */ new Set(["task", "subagent"]);
884
922
  var ROLE_COLOR = {
885
923
  spinner: "spinner",
886
924
  done: "done",
925
+ ok: "ok",
887
926
  error: "error",
888
927
  agent: "text",
889
928
  description: "text",
@@ -987,7 +1026,12 @@ function createSidebar(host) {
987
1026
  if (!record?.model) return view;
988
1027
  const samples = historyMap.get(turnHistoryKey(record.agent ?? agentFallback, record.model));
989
1028
  if (!samples) return view;
990
- const estimate = estimateTurn(samples, { elapsedMs: view.elapsedMs, chars: measure.chars, effort: record.effort });
1029
+ const estimate = estimateTurn(samples, {
1030
+ elapsedMs: view.elapsedMs,
1031
+ chars: measure.chars,
1032
+ effort: record.effort,
1033
+ calls: measure.calls
1034
+ });
991
1035
  if (!estimate) return view;
992
1036
  const turn = measure.startedAt ?? 0;
993
1037
  return { ...view, estimate: { ...estimate, fill: fills.hold(sessionID, turn, estimate.fill) } };
@@ -1269,6 +1313,7 @@ function registerV1(api) {
1269
1313
  muted,
1270
1314
  spinner: theme.accent,
1271
1315
  done: mix(theme.success, muted, 0.45),
1316
+ ok: theme.success ?? theme.accent,
1272
1317
  error: mix(theme.error, muted, 0.35),
1273
1318
  effort: theme.warning ?? muted,
1274
1319
  effortFaded: mix(theme.warning ?? muted, muted, 0.45),
@@ -1387,6 +1432,7 @@ function setupV2(context) {
1387
1432
  muted,
1388
1433
  spinner: accent,
1389
1434
  done: mix(theme.text.feedback.success.muted ?? theme.text.feedback.success.base, muted, 0.45),
1435
+ ok: theme.text.feedback.success.base ?? accent,
1390
1436
  error: mix(theme.text.feedback.error.muted ?? theme.text.feedback.error.base, muted, 0.35),
1391
1437
  effort: theme.text.feedback.warning?.base ?? muted,
1392
1438
  effortFaded: mix(theme.text.feedback.warning?.base ?? muted, muted, 0.45),