import { memo as _$memo } from "opentui:runtime-module:%40opentui%2Fsolid";
import { createTextNode as _$createTextNode } from "opentui:runtime-module:%40opentui%2Fsolid";
import { createComponent as _$createComponent } from "opentui:runtime-module:%40opentui%2Fsolid";
import { effect as _$effect } from "opentui:runtime-module:%40opentui%2Fsolid";
import { insertNode as _$insertNode } from "opentui:runtime-module:%40opentui%2Fsolid";
import { insert as _$insert } from "opentui:runtime-module:%40opentui%2Fsolid";
import { setProp as _$setProp } from "opentui:runtime-module:%40opentui%2Fsolid";
import { createElement as _$createElement } from "opentui:runtime-module:%40opentui%2Fsolid";
/** @jsxImportSource @opentui/solid */

import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { formatQuotaMoney } from "@cortexkit/anthropic-auth-core";
import { createEffect, createSignal, For, onCleanup, Show } from "opentui:runtime-module:solid-js";
import { createRpcClient } from "./rpc/rpc-client.js";
import { getRpcDir } from "./rpc/rpc-dir.js";
import { computeQuotaPacing, DEFAULT_SIDEBAR_STATE, FIVE_HOUR_MS, formatScopedQuotaLabel, getCollapsedQuotaSummary, getFableRecoverySummary, getSidebarState, resolveActiveAccount, SEVEN_DAY_MS } from "./sidebar-state.js";
import { openCommandDialog } from "./tui/command-dialogs.js";
import { computeEffectiveOrder, DEFAULT_SLOT_ORDER, PLUGIN_KEY, queueTuiPreferenceUpdate, readTuiPreferencesFile, resolveAnthropicAuthPrefs, watchTuiPreferences } from "./tui-preferences.js";
const RPC_POLL_MS = 500;
let rpcPollStarted = false;
const ID = 'cortexkit.anthropic-auth';

// Read package metadata from either the raw src/ entry or its generated
// src/tui-compiled/ counterpart. Avoid a JSON import because package.json sits
// outside the declaration build's rootDir.
const PLUGIN_VERSION = (() => {
  const here = dirname(fileURLToPath(import.meta.url));
  for (const packageFile of [join(here, '..', 'package.json'), join(here, '..', '..', 'package.json')]) {
    try {
      const raw = readFileSync(packageFile, 'utf8');
      const version = JSON.parse(raw).version;
      if (version) return version;
    } catch {
      // Try the path for the other TUI entry layout.
    }
  }
  return '';
})();

// biome-ignore lint/suspicious/noExplicitAny: opentui border prop not typed in plugin tui surface
const SINGLE_BORDER = {
  type: 'single'
};
// Tone -> theme token. Theme tokens only — never hardcoded colors. Fallbacks
// resolve to other theme tokens so the sidebar always tracks the active theme.
function toneColor(theme, tone) {
  switch (tone) {
    case 'ok':
      return theme.success ?? theme.accent;
    case 'warn':
      return theme.warning ?? theme.accent;
    case 'err':
      return theme.error ?? theme.accent;
    case 'muted':
      return theme.textMuted ?? theme.text;
    case 'accent':
      return theme.accent ?? theme.text;
    default:
      return theme.text;
  }
}
function usageTone(usedPct, appearance) {
  if (usedPct < appearance.warnThreshold) return 'ok';
  if (usedPct < appearance.errorThreshold) return 'warn';
  return 'err';
}
const PACE_RESERVE_CHAR = '\u2592';
const PACE_DEFICIT_CHAR = '\u2593';

// Variant C pacing bar: normal fill up to min(used, pace), then a pace
// segment covering the gap — headroom being banked (reserve, ok tone) or the
// overshoot itself (deficit, err tone) — then empty cells. Without pacing the
// bar renders as a single fill+empty pair, identical to the pre-pacing look.
// Empty text nodes still occupy a phantom cell in the opentui flex row, so
// zero-length segments are dropped from every return path (plain and pacing).
function quotaBarSegments(usedPct, appearance, pacing) {
  const width = appearance.barWidth;
  const cells = pct => Math.max(0, Math.min(Math.round(pct / 100 * width), width));
  const usedCells = cells(usedPct);
  const fillTone = usageTone(usedPct, appearance);
  const plain = [{
    text: appearance.barFilledChar.repeat(usedCells),
    tone: fillTone
  }, {
    text: appearance.barEmptyChar.repeat(width - usedCells),
    tone: fillTone
  }];
  if (!pacing) return plain.filter(segment => segment.text.length > 0);
  const paceCells = cells(pacing.pacePercent);
  const lo = Math.min(usedCells, paceCells);
  const hi = Math.max(usedCells, paceCells);
  if (hi === lo) return plain.filter(segment => segment.text.length > 0);
  const overspent = usedCells > paceCells;
  return [{
    text: appearance.barFilledChar.repeat(lo),
    tone: fillTone
  }, {
    text: (overspent ? PACE_DEFICIT_CHAR : PACE_RESERVE_CHAR).repeat(hi - lo),
    tone: overspent ? 'err' : 'ok'
  }, {
    text: appearance.barEmptyChar.repeat(width - hi),
    tone: fillTone
  }].filter(segment => segment.text.length > 0);
}
function formatResetIn(resetsAt) {
  if (!resetsAt) return '';
  const ms = new Date(resetsAt).getTime() - Date.now();
  if (ms <= 0) return 'now';
  const mins = Math.floor(ms / 60_000);
  if (mins < 60) return `${mins}m`;
  const hrs = Math.floor(mins / 60);
  if (hrs < 24) {
    const rm = mins % 60;
    return rm > 0 ? `${hrs}h${rm}m` : `${hrs}h`;
  }
  const days = Math.floor(hrs / 24);
  const rh = hrs % 24;
  return rh > 0 ? `${days}d${rh}h` : `${days}d`;
}
function formatUntil(until) {
  if (!until) return '';
  const ms = until - Date.now();
  if (ms <= 0) return 'now';
  const mins = Math.ceil(ms / 60_000);
  if (mins < 60) return `${mins}m`;
  const hrs = Math.floor(mins / 60);
  const rm = mins % 60;
  return rm > 0 ? `${hrs}h${rm}m` : `${hrs}h`;
}

// --- Reusable components (aft-style) ---------------------------------------

function SectionHeader(props) {
  return (() => {
    var _el$ = _$createElement("box"),
      _el$2 = _$createElement("text"),
      _el$3 = _$createElement("b");
    _$insertNode(_el$, _el$2);
    _$setProp(_el$, "width", '100%');
    _$insertNode(_el$2, _el$3);
    _$insert(_el$3, () => props.title);
    _$effect(_p$ => {
      var _v$ = props.marginTop ?? 1,
        _v$2 = props.theme.text;
      _v$ !== _p$.e && (_p$.e = _$setProp(_el$, "marginTop", _v$, _p$.e));
      _v$2 !== _p$.t && (_p$.t = _$setProp(_el$2, "fg", _v$2, _p$.t));
      return _p$;
    }, {
      e: undefined,
      t: undefined
    });
    return _el$;
  })();
}
function StatRow(props) {
  return (() => {
    var _el$4 = _$createElement("box"),
      _el$5 = _$createElement("text"),
      _el$6 = _$createElement("text"),
      _el$7 = _$createElement("b");
    _$insertNode(_el$4, _el$5);
    _$insertNode(_el$4, _el$6);
    _$setProp(_el$4, "width", '100%');
    _$setProp(_el$4, "flexDirection", 'row');
    _$setProp(_el$4, "justifyContent", 'space-between');
    _$insert(_el$5, () => props.label);
    _$insertNode(_el$6, _el$7);
    _$insert(_el$7, () => props.value);
    _$effect(_p$ => {
      var _v$3 = props.theme.textMuted,
        _v$4 = toneColor(props.theme, props.tone ?? 'text');
      _v$3 !== _p$.e && (_p$.e = _$setProp(_el$5, "fg", _v$3, _p$.e));
      _v$4 !== _p$.t && (_p$.t = _$setProp(_el$6, "fg", _v$4, _p$.t));
      return _p$;
    }, {
      e: undefined,
      t: undefined
    });
    return _el$4;
  })();
}

// Compact row for the collapsed view: muted label left, caller-provided value
// right. Mirrors StatRow's layout so columns line up.
function CollapsedRow(props) {
  return (() => {
    var _el$8 = _$createElement("box"),
      _el$9 = _$createElement("text");
    _$insertNode(_el$8, _el$9);
    _$setProp(_el$8, "width", '100%');
    _$setProp(_el$8, "flexDirection", 'row');
    _$setProp(_el$8, "justifyContent", 'space-between');
    _$insert(_el$9, () => props.label);
    _$insert(_el$8, () => props.children, null);
    _$effect(_$p => _$setProp(_el$9, "fg", props.theme.textMuted, _$p));
    return _el$8;
  })();
}

// Quota window row: muted label left, tone-colored bar + percentage right,
// with an optional muted reset suffix. When pacing data is present, the bar
// gains a pace segment and an off-pace window adds a muted subline with the
// reserve/deficit delta and the projected runout.
function QuotaRow(props) {
  const used = () => props.window?.usedPercent ?? 0;
  const reset = () => formatResetIn(props.window?.resetsAt);
  const paceLine = () => {
    const pacing = props.pacing;
    if (!pacing || pacing.state === 'on-pace') return null;
    const pct = Math.round(Math.abs(pacing.deltaPercent));
    if (pacing.state === 'reserve') return `reserve ${pct}% \u00b7 lasts`;
    return pacing.runsOutAt ? `deficit ${pct}% \u00b7 out in ${formatResetIn(pacing.runsOutAt)}` : `deficit ${pct}% \u00b7 lasts`;
  };
  return _$createComponent(Show, {
    get when() {
      return props.window;
    },
    get fallback() {
      return (() => {
        var _el$17 = _$createElement("box"),
          _el$18 = _$createElement("text"),
          _el$19 = _$createElement("text");
        _$insertNode(_el$17, _el$18);
        _$insertNode(_el$17, _el$19);
        _$setProp(_el$17, "width", '100%');
        _$setProp(_el$17, "flexDirection", 'row');
        _$insert(_el$18, () => props.label.padEnd(3));
        _$insertNode(_el$19, _$createTextNode(`—`));
        _$effect(_p$ => {
          var _v$9 = props.theme.textMuted,
            _v$0 = props.theme.textMuted;
          _v$9 !== _p$.e && (_p$.e = _$setProp(_el$18, "fg", _v$9, _p$.e));
          _v$0 !== _p$.t && (_p$.t = _$setProp(_el$19, "fg", _v$0, _p$.t));
          return _p$;
        }, {
          e: undefined,
          t: undefined
        });
        return _el$17;
      })();
    },
    get children() {
      return [(() => {
        var _el$0 = _$createElement("box"),
          _el$1 = _$createElement("box"),
          _el$10 = _$createElement("text"),
          _el$11 = _$createElement("text");
        _$insertNode(_el$0, _el$1);
        _$setProp(_el$0, "width", '100%');
        _$setProp(_el$0, "flexDirection", 'row');
        _$setProp(_el$0, "justifyContent", 'space-between');
        _$insertNode(_el$1, _el$10);
        _$insertNode(_el$1, _el$11);
        _$setProp(_el$1, "flexDirection", 'row');
        _$insert(_el$10, () => props.label.padEnd(3));
        _$insert(_el$1, _$createComponent(For, {
          get each() {
            return quotaBarSegments(used(), props.appearance, props.pacing);
          },
          children: segment => (() => {
            var _el$21 = _$createElement("text");
            _$insert(_el$21, () => segment.text);
            _$effect(_$p => _$setProp(_el$21, "fg", toneColor(props.theme, segment.tone), _$p));
            return _el$21;
          })()
        }), _el$11);
        _$insert(_el$11, () => ` ${String(Math.round(used())).padStart(3)}%${props.binding ? ' •' : ''}`);
        _$insert(_el$0, _$createComponent(Show, {
          get when() {
            return reset();
          },
          get children() {
            var _el$12 = _$createElement("text");
            _$insert(_el$12, reset);
            _$effect(_$p => _$setProp(_el$12, "fg", props.theme.textMuted, _$p));
            return _el$12;
          }
        }), null);
        _$effect(_p$ => {
          var _v$5 = props.theme.textMuted,
            _v$6 = toneColor(props.theme, usageTone(used(), props.appearance));
          _v$5 !== _p$.e && (_p$.e = _$setProp(_el$10, "fg", _v$5, _p$.e));
          _v$6 !== _p$.t && (_p$.t = _$setProp(_el$11, "fg", _v$6, _p$.t));
          return _p$;
        }, {
          e: undefined,
          t: undefined
        });
        return _el$0;
      })(), _$createComponent(Show, {
        get when() {
          return paceLine();
        },
        get children() {
          var _el$13 = _$createElement("box"),
            _el$14 = _$createElement("text"),
            _el$16 = _$createElement("text");
          _$insertNode(_el$13, _el$14);
          _$insertNode(_el$13, _el$16);
          _$setProp(_el$13, "width", '100%');
          _$setProp(_el$13, "flexDirection", 'row');
          _$insertNode(_el$14, _$createTextNode(`   `));
          _$insert(_el$16, paceLine);
          _$effect(_p$ => {
            var _v$7 = props.theme.textMuted,
              _v$8 = toneColor(props.theme, props.pacing?.state === 'deficit' ? 'warn' : 'muted');
            _v$7 !== _p$.e && (_p$.e = _$setProp(_el$14, "fg", _v$7, _p$.e));
            _v$8 !== _p$.t && (_p$.t = _$setProp(_el$16, "fg", _v$8, _p$.t));
            return _p$;
          }, {
            e: undefined,
            t: undefined
          });
          return _el$13;
        }
      })];
    }
  });
}

// Account block: header row (name + status word) then per-window quota rows.
// Pacing is computed here — per window, against the wall clock at render time
// (re-evaluated on every state poll) — and disabled by passing false.
function AccountBlock(props) {
  const statusWord = () => props.needsReauth ? 're-login' : props.active ? 'active' : 'idle';
  const statusTone = () => props.needsReauth ? 'err' : props.active ? 'ok' : 'muted';
  const pacingFor = (window, windowMs) => props.pacingEnabled && window ? computeQuotaPacing(window, windowMs, Date.now()) : null;
  return (() => {
    var _el$22 = _$createElement("box"),
      _el$23 = _$createElement("box"),
      _el$24 = _$createElement("text"),
      _el$25 = _$createElement("b"),
      _el$26 = _$createElement("text"),
      _el$27 = _$createElement("b");
    _$insertNode(_el$22, _el$23);
    _$setProp(_el$22, "width", '100%');
    _$setProp(_el$22, "flexDirection", 'column');
    _$insertNode(_el$23, _el$24);
    _$insertNode(_el$23, _el$26);
    _$setProp(_el$23, "width", '100%');
    _$setProp(_el$23, "flexDirection", 'row');
    _$setProp(_el$23, "justifyContent", 'space-between');
    _$insertNode(_el$24, _el$25);
    _$insert(_el$25, () => `${props.name}${props.tierLabel ? ` · ${props.tierLabel}` : ''}`);
    _$insertNode(_el$26, _el$27);
    _$insert(_el$27, statusWord);
    _$insert(_el$22, _$createComponent(Show, {
      get when() {
        return props.quota;
      },
      get fallback() {
        return (() => {
          var _el$30 = _$createElement("text");
          _$insertNode(_el$30, _$createTextNode(`checking…`));
          _$effect(_$p => _$setProp(_el$30, "fg", props.theme.textMuted, _$p));
          return _el$30;
        })();
      },
      get children() {
        return [_$createComponent(QuotaRow, {
          get theme() {
            return props.theme;
          },
          get appearance() {
            return props.appearance;
          },
          label: "5h",
          get window() {
            return props.quota?.five_hour;
          },
          get pacing() {
            return pacingFor(props.quota?.five_hour, FIVE_HOUR_MS);
          },
          get binding() {
            return props.quota?.bindingWindow === 'five_hour';
          }
        }), _$createComponent(QuotaRow, {
          get theme() {
            return props.theme;
          },
          get appearance() {
            return props.appearance;
          },
          label: "7d",
          get window() {
            return props.quota?.seven_day;
          },
          get pacing() {
            return pacingFor(props.quota?.seven_day, SEVEN_DAY_MS);
          },
          get binding() {
            return props.quota?.bindingWindow === 'seven_day';
          }
        }), _$createComponent(For, {
          get each() {
            return props.quota?.scoped ?? [];
          },
          children: window => _$createComponent(QuotaRow, {
            get theme() {
              return props.theme;
            },
            get appearance() {
              return props.appearance;
            },
            get label() {
              return formatScopedQuotaLabel(window.title);
            },
            window: window,
            get pacing() {
              return pacingFor(window, SEVEN_DAY_MS);
            },
            get binding() {
              return props.quota?.bindingWindow === window.id;
            }
          })
        }), _$createComponent(Show, {
          get when() {
            return props.quota?.extraUsage;
          },
          children: extraUsage => (() => {
            var _el$32 = _$createElement("text");
            _$insert(_el$32, () => `credits ${formatQuotaMoney(extraUsage().used)}/${formatQuotaMoney(extraUsage().limit)}${extraUsage().exhausted ? ' · exhausted' : ''}`);
            _$effect(_$p => _$setProp(_el$32, "fg", toneColor(props.theme, extraUsage().severity === 'critical' ? 'err' : extraUsage().severity === 'warning' || extraUsage().exhausted ? 'warn' : 'muted'), _$p));
            return _el$32;
          })()
        }), _$createComponent(Show, {
          get when() {
            return props.quota?.fallbackAdvised === true;
          },
          get children() {
            var _el$28 = _$createElement("text");
            _$insertNode(_el$28, _$createTextNode(`→ fallback advised`));
            _$effect(_$p => _$setProp(_el$28, "fg", props.theme.textMuted, _$p));
            return _el$28;
          }
        })];
      }
    }), null);
    _$effect(_p$ => {
      var _v$1 = props.marginTop ?? 0,
        _v$10 = props.theme.text,
        _v$11 = toneColor(props.theme, statusTone());
      _v$1 !== _p$.e && (_p$.e = _$setProp(_el$22, "marginTop", _v$1, _p$.e));
      _v$10 !== _p$.t && (_p$.t = _$setProp(_el$24, "fg", _v$10, _p$.t));
      _v$11 !== _p$.a && (_p$.a = _$setProp(_el$26, "fg", _v$11, _p$.a));
      return _p$;
    }, {
      e: undefined,
      t: undefined,
      a: undefined
    });
    return _el$22;
  })();
}
export { formatQuotaMoney };

// --- Quota dialog content ---------------------------------------------------

// Renders the same rich visualization as the sidebar (account blocks with
// quota bars + pacing) so the modal matches the sidebar look.
function QuotaDialogContent(props) {
  const prefs = props.controller.prefs;
  const [state, setState] = createSignal(DEFAULT_SIDEBAR_STATE);
  let lastUpdated = 0;
  async function refresh() {
    const next = await readStateFromFile();
    if (next.lastUpdated !== lastUpdated) {
      lastUpdated = next.lastUpdated;
      setState(next);
    }
  }
  createEffect(() => {
    const timer = setInterval(refresh, prefs().pollMs);
    onCleanup(() => clearInterval(timer));
  });
  setTimeout(refresh, 0);
  const theme = () => props.api.theme.current;
  const enabledFallbacks = () => (state().fallbacks ?? []).filter(f => f.enabled);
  return (() => {
    var _el$33 = _$createElement("box"),
      _el$34 = _$createElement("box"),
      _el$35 = _$createElement("box"),
      _el$36 = _$createElement("text"),
      _el$37 = _$createElement("b");
    _$insertNode(_el$33, _el$34);
    _$setProp(_el$33, "flexDirection", 'column');
    _$setProp(_el$33, "padding", 2);
    _$setProp(_el$33, "width", '100%');
    _$setProp(_el$33, "alignItems", 'center');
    _$insertNode(_el$34, _el$35);
    _$setProp(_el$34, "flexDirection", 'column');
    _$setProp(_el$34, "width", 58);
    _$insertNode(_el$35, _el$36);
    _$setProp(_el$35, "width", '100%');
    _$setProp(_el$35, "justifyContent", 'center');
    _$setProp(_el$35, "marginBottom", 1);
    _$insertNode(_el$36, _el$37);
    _$insertNode(_el$37, _$createTextNode(`Quota`));
    _$insert(_el$34, _$createComponent(AccountBlock, {
      get theme() {
        return theme();
      },
      get appearance() {
        return prefs().appearance;
      },
      name: "main",
      get quota() {
        return state().main?.quota;
      },
      get active() {
        return state().activeId === 'main';
      },
      get pacingEnabled() {
        return prefs().sections.pacing;
      },
      get tierLabel() {
        return state().main?.tierLabel;
      }
    }), null);
    _$insert(_el$34, _$createComponent(Show, {
      get when() {
        return prefs().sections.fallbackAccounts;
      },
      get children() {
        return _$createComponent(For, {
          get each() {
            return enabledFallbacks();
          },
          children: fb => _$createComponent(AccountBlock, {
            get theme() {
              return theme();
            },
            get appearance() {
              return prefs().appearance;
            },
            get name() {
              return fb.label ?? fb.id;
            },
            get quota() {
              return fb.quota;
            },
            get active() {
              return state().activeId === fb.id;
            },
            get pacingEnabled() {
              return prefs().sections.pacing;
            },
            get tierLabel() {
              return fb.tierLabel;
            },
            get needsReauth() {
              return fb.needsReauth;
            },
            marginTop: 1
          })
        });
      }
    }), null);
    _$effect(_$p => _$setProp(_el$36, "fg", theme().text, _$p));
    return _el$33;
  })();
}

// --- State plumbing ---------------------------------------------------------

async function readStateFromFile() {
  return getSidebarState();
}
// The TUI may unmount and remount sidebar_content when the user switches
// views (e.g. main -> subagent -> main). A remount re-runs the component
// body, so any signal created inside the component would reset to its
// seed. The controller lives in the plugin closure (process lifetime)
// and owns the durable prefs/collapse signals plus the single shared
// watcher subscription, so collapse and live pref reloads survive the
// remount. No effects or memos here — those need a Solid owner, so the
// poll-interval createEffect stays inside the component.
function createSidebarController(initialPrefs) {
  const [prefs, setPrefs] = createSignal(initialPrefs);
  const seedCollapsed = initialPrefs.rememberCollapsed && initialPrefs.collapsed != null ? initialPrefs.collapsed : initialPrefs.startCollapsed;
  const [collapsed, setCollapsed] = createSignal(seedCollapsed);
  let lastPersistedCollapsed = initialPrefs.collapsed;
  let lastApplied = JSON.stringify(initialPrefs);

  // The watcher lives for the plugin/process lifetime — it is intentionally
  // never disposed. Collapse guard mirrors the race-fix in toggleCollapsed:
  // lastPersistedCollapsed is advanced only once our own write lands, so
  // watcher echoes of the previous persisted value are rejected by the
  // `!==` check and cannot revert a user click.
  watchTuiPreferences(() => {
    void (async () => {
      const next = resolveAnthropicAuthPrefs(await readTuiPreferencesFile());
      const serialized = JSON.stringify(next);
      if (serialized === lastApplied) return;
      lastApplied = serialized;
      setPrefs(next);
      if (next.rememberCollapsed && next.collapsed != null && next.collapsed !== lastPersistedCollapsed) {
        lastPersistedCollapsed = next.collapsed;
        setCollapsed(next.collapsed);
      }
    })();
  });
  function toggleCollapsed() {
    const next = !collapsed();
    setCollapsed(next);
    if (prefs().rememberCollapsed) {
      void queueTuiPreferenceUpdate(PLUGIN_KEY, ['collapsed'], next).then(() => {
        lastPersistedCollapsed = next;
      });
    }
  }
  return {
    prefs,
    collapsed,
    toggleCollapsed
  };
}
function QuotaSidebar(props) {
  const prefs = props.controller.prefs;
  const collapsed = props.controller.collapsed;
  const [state, setState] = createSignal(DEFAULT_SIDEBAR_STATE);
  let lastUpdated = 0;
  let debounce = null;
  async function refresh() {
    const next = await readStateFromFile();
    if (next.lastUpdated !== lastUpdated) {
      lastUpdated = next.lastUpdated;
      setState(next);
    }
  }
  function scheduleRefresh() {
    if (debounce) clearTimeout(debounce);
    debounce = setTimeout(() => {
      debounce = null;
      void refresh();
    }, prefs().refreshDebounceMs);
  }

  // Background poller (server and TUI run as separate module instances, so we
  // sync through the state file) plus event-driven refreshes for low latency.
  // The interval rebuilds whenever pollMs changes.
  createEffect(() => {
    const timer = setInterval(refresh, prefs().pollMs);
    onCleanup(() => clearInterval(timer));
  });
  const unsubs = [props.api.event.on('session.updated', scheduleRefresh), props.api.event.on('message.updated', scheduleRefresh)];
  setTimeout(refresh, 300);
  onCleanup(() => {
    if (debounce) clearTimeout(debounce);
    for (const u of unsubs) u();
  });
  const theme = () => props.api.theme.current;
  const enabledFallbacks = () => (state().fallbacks ?? []).filter(f => f.enabled);
  const hasData = () => state().main?.quota != null || enabledFallbacks().length > 0;
  const headerLabel = () => {
    const name = prefs().header.label;
    return !hasData() ? name : collapsed() ? `\u25b6 ${name}` : `\u25bc ${name}`;
  };
  const activeAccount = () => resolveActiveAccount(state());
  const activeQuotaSummary = () => getCollapsedQuotaSummary(activeAccount().quota);
  const activePacingDeficit = () => {
    if (!prefs().sections.pacing) return false;
    const quota = activeAccount().quota;
    if (!quota) return false;
    const now = Date.now();
    const windows = [[quota.five_hour, FIVE_HOUR_MS], [quota.seven_day, SEVEN_DAY_MS], ...(quota.scoped ?? []).map(window => [window, SEVEN_DAY_MS])];
    return windows.some(([w, ms]) => w != null && computeQuotaPacing(w, ms, now)?.state === 'deficit');
  };
  const activeQuotaTone = () => {
    const summary = activeQuotaSummary();
    const values = [summary.fiveHourUsedPercent, summary.sevenDayUsedPercent, ...summary.scopedUsedPercents].filter(value => value != null);
    // Pacing deficit is an advisory projection, not actual quota exhaustion,
    // so it can only BUMP the usage tone up to warn at most — never soften a
    // real warn/err usage reading and never paint a true red.
    const base = values.length > 0 ? usageTone(Math.max(...values), prefs().appearance) : 'muted';
    if (!activePacingDeficit()) return base;
    return base === 'ok' || base === 'muted' ? 'warn' : base;
  };
  const quotaBackedOff = () => state().main?.quotaBackedOff === true;
  const refreshBackedOff = () => state().main?.refreshBackedOff === true;
  const needsReauth = () => enabledFallbacks().some(f => f.needsReauth);
  const degraded = () => quotaBackedOff() || refreshBackedOff() || needsReauth();
  const fableRecoverySummary = () => getFableRecoverySummary(state(), props.sessionId);
  const fableRecoveryTone = () => state().fableRecoveries?.find(recovery => recovery.sessionId === props.sessionId)?.mode === 'opus' ? 'warn' : 'ok';
  const cacheKeep = () => state().cacheKeep;
  const showCache = () => prefs().sections.cache && cacheKeep() != null && cacheKeep()?.window != null;
  const relayValue = () => {
    const r = state().relay;
    if (!r) return '\u2014';
    return `${r.transport} \u00b7 ${r.enabled ? 'on' : 'off'}`;
  };
  return (() => {
    var _el$39 = _$createElement("box"),
      _el$40 = _$createElement("box"),
      _el$41 = _$createElement("box"),
      _el$42 = _$createElement("text"),
      _el$43 = _$createElement("b");
    _$insertNode(_el$39, _el$40);
    _$setProp(_el$39, "width", '100%');
    _$setProp(_el$39, "flexDirection", 'column');
    _$setProp(_el$39, "border", SINGLE_BORDER);
    _$setProp(_el$39, "paddingTop", 1);
    _$setProp(_el$39, "paddingBottom", 1);
    _$setProp(_el$39, "paddingLeft", 1);
    _$setProp(_el$39, "paddingRight", 1);
    _$insertNode(_el$40, _el$41);
    _$setProp(_el$40, "width", '100%');
    _$setProp(_el$40, "flexDirection", 'row');
    _$setProp(_el$40, "justifyContent", 'space-between');
    _$setProp(_el$40, "alignItems", 'center');
    _$setProp(_el$40, "onMouseDown", () => {
      if (hasData()) props.controller.toggleCollapsed();
    });
    _$insertNode(_el$41, _el$42);
    _$setProp(_el$41, "paddingLeft", 1);
    _$setProp(_el$41, "paddingRight", 1);
    _$insertNode(_el$42, _el$43);
    _$insert(_el$43, headerLabel);
    _$insert(_el$40, _$createComponent(Show, {
      get when() {
        return degraded();
      },
      get fallback() {
        return _$createComponent(Show, {
          get when() {
            return prefs().header.showVersion && PLUGIN_VERSION !== '';
          },
          get children() {
            var _el$53 = _$createElement("text");
            _$insert(_el$53, `v${PLUGIN_VERSION}`);
            _$effect(_$p => _$setProp(_el$53, "fg", theme().textMuted, _$p));
            return _el$53;
          }
        });
      },
      get children() {
        var _el$44 = _$createElement("box"),
          _el$45 = _$createElement("text"),
          _el$46 = _$createElement("b");
        _$insertNode(_el$44, _el$45);
        _$setProp(_el$44, "paddingLeft", 1);
        _$setProp(_el$44, "paddingRight", 1);
        _$insertNode(_el$45, _el$46);
        _$insertNode(_el$46, _$createTextNode(`LIMITED`));
        _$effect(_p$ => {
          var _v$12 = theme().warning,
            _v$13 = theme().background;
          _v$12 !== _p$.e && (_p$.e = _$setProp(_el$44, "backgroundColor", _v$12, _p$.e));
          _v$13 !== _p$.t && (_p$.t = _$setProp(_el$45, "fg", _v$13, _p$.t));
          return _p$;
        }, {
          e: undefined,
          t: undefined
        });
        return _el$44;
      }
    }), null);
    _$insert(_el$39, _$createComponent(Show, {
      get when() {
        return _$memo(() => !!collapsed())() && hasData();
      },
      get children() {
        return [_$createComponent(CollapsedRow, {
          get theme() {
            return theme();
          },
          get label() {
            return activeAccount().name;
          },
          get children() {
            return _$createComponent(Show, {
              get when() {
                return activeQuotaSummary().text != null;
              },
              get fallback() {
                return (() => {
                  var _el$54 = _$createElement("text");
                  _$insertNode(_el$54, _$createTextNode(`—`));
                  _$effect(_$p => _$setProp(_el$54, "fg", theme().textMuted, _$p));
                  return _el$54;
                })();
              },
              get children() {
                var _el$48 = _$createElement("text"),
                  _el$49 = _$createElement("b");
                _$insertNode(_el$48, _el$49);
                _$insert(_el$49, () => activeQuotaSummary().text);
                _$effect(_$p => _$setProp(_el$48, "fg", toneColor(theme(), activeQuotaTone()), _$p));
                return _el$48;
              }
            });
          }
        }), _$createComponent(Show, {
          get when() {
            return state().fastMode;
          },
          get children() {
            return _$createComponent(CollapsedRow, {
              get theme() {
                return theme();
              },
              label: "Mode",
              get children() {
                var _el$50 = _$createElement("text"),
                  _el$51 = _$createElement("b");
                _$insertNode(_el$50, _el$51);
                _$insertNode(_el$51, _$createTextNode(`fast`));
                _$effect(_$p => _$setProp(_el$50, "fg", toneColor(theme(), 'accent'), _$p));
                return _el$50;
              }
            });
          }
        }), _$createComponent(Show, {
          get when() {
            return fableRecoverySummary();
          },
          children: summary => _$createComponent(CollapsedRow, {
            get theme() {
              return theme();
            },
            label: "Recovery",
            get children() {
              var _el$56 = _$createElement("text"),
                _el$57 = _$createElement("b");
              _$insertNode(_el$56, _el$57);
              _$insert(_el$57, summary);
              _$effect(_$p => _$setProp(_el$56, "fg", toneColor(theme(), fableRecoveryTone()), _$p));
              return _el$56;
            }
          })
        })];
      }
    }), null);
    _$insert(_el$39, _$createComponent(Show, {
      get when() {
        return !collapsed() || !hasData();
      },
      get children() {
        return [_$createComponent(Show, {
          get when() {
            return hasData();
          },
          get fallback() {
            return (() => {
              var _el$58 = _$createElement("box"),
                _el$59 = _$createElement("text");
              _$insertNode(_el$58, _el$59);
              _$setProp(_el$58, "marginTop", 1);
              _$setProp(_el$58, "width", '100%');
              _$insertNode(_el$59, _$createTextNode(`Waiting for quota…`));
              _$effect(_$p => _$setProp(_el$59, "fg", theme().textMuted, _$p));
              return _el$58;
            })();
          },
          get children() {
            return _$createComponent(Show, {
              get when() {
                return prefs().sections.quota;
              },
              get children() {
                return [_$createComponent(SectionHeader, {
                  get theme() {
                    return theme();
                  },
                  title: "Quota"
                }), _$createComponent(AccountBlock, {
                  get theme() {
                    return theme();
                  },
                  get appearance() {
                    return prefs().appearance;
                  },
                  name: "main",
                  get quota() {
                    return state().main?.quota;
                  },
                  get active() {
                    return state().activeId === 'main';
                  },
                  get pacingEnabled() {
                    return prefs().sections.pacing;
                  },
                  get tierLabel() {
                    return state().main?.tierLabel;
                  }
                }), _$createComponent(Show, {
                  get when() {
                    return prefs().sections.fallbackAccounts;
                  },
                  get children() {
                    return _$createComponent(For, {
                      get each() {
                        return enabledFallbacks();
                      },
                      children: fb => _$createComponent(AccountBlock, {
                        get theme() {
                          return theme();
                        },
                        get appearance() {
                          return prefs().appearance;
                        },
                        get name() {
                          return fb.label ?? fb.id;
                        },
                        get quota() {
                          return fb.quota;
                        },
                        get active() {
                          return state().activeId === fb.id;
                        },
                        get pacingEnabled() {
                          return prefs().sections.pacing;
                        },
                        get tierLabel() {
                          return fb.tierLabel;
                        },
                        get needsReauth() {
                          return fb.needsReauth;
                        },
                        marginTop: 1
                      })
                    });
                  }
                })];
              }
            });
          }
        }), _$createComponent(Show, {
          get when() {
            return prefs().sections.routing;
          },
          get children() {
            return [_$createComponent(SectionHeader, {
              get theme() {
                return theme();
              },
              title: "Routing"
            }), _$createComponent(StatRow, {
              get theme() {
                return theme();
              },
              label: "Route",
              get value() {
                return state().route;
              },
              tone: "accent"
            }), _$createComponent(StatRow, {
              get theme() {
                return theme();
              },
              label: "Mode",
              get value() {
                return state().fastMode ? 'fast' : 'std';
              },
              get tone() {
                return state().fastMode ? 'accent' : 'muted';
              }
            }), _$createComponent(StatRow, {
              get theme() {
                return theme();
              },
              label: "Relay",
              get value() {
                return relayValue();
              },
              get tone() {
                return state().relay?.enabled ? 'ok' : 'muted';
              }
            })];
          }
        }), _$createComponent(Show, {
          get when() {
            return fableRecoverySummary();
          },
          children: summary => _$createComponent(StatRow, {
            get theme() {
              return theme();
            },
            label: "Recovery",
            get value() {
              return summary();
            },
            get tone() {
              return fableRecoveryTone();
            }
          })
        }), _$createComponent(Show, {
          get when() {
            return showCache();
          },
          get children() {
            return [_$createComponent(SectionHeader, {
              get theme() {
                return theme();
              },
              title: "Cache"
            }), _$createComponent(StatRow, {
              get theme() {
                return theme();
              },
              label: "1h cache",
              get value() {
                return `${cacheKeep()?.window} \u00b7 ${cacheKeep()?.enabled ? 'on' : 'off'}`;
              },
              get tone() {
                return cacheKeep()?.enabled ? 'ok' : 'muted';
              }
            }), _$createComponent(Show, {
              get when() {
                return (cacheKeep()?.trackedSessions ?? 0) > 0;
              },
              get children() {
                return _$createComponent(StatRow, {
                  get theme() {
                    return theme();
                  },
                  label: "Tracked",
                  get value() {
                    return String(cacheKeep()?.trackedSessions);
                  },
                  tone: "text"
                });
              }
            })];
          }
        }), _$createComponent(Show, {
          get when() {
            return _$memo(() => !!degraded())() && prefs().sections.health;
          },
          get children() {
            return [_$createComponent(SectionHeader, {
              get theme() {
                return theme();
              },
              title: "Health"
            }), _$createComponent(Show, {
              get when() {
                return quotaBackedOff();
              },
              get children() {
                return _$createComponent(StatRow, {
                  get theme() {
                    return theme();
                  },
                  label: "Quota API",
                  get value() {
                    return `backoff ${formatUntil(state().main?.quotaBackoffUntil)}`;
                  },
                  tone: "warn"
                });
              }
            }), _$createComponent(Show, {
              get when() {
                return refreshBackedOff();
              },
              get children() {
                return _$createComponent(StatRow, {
                  get theme() {
                    return theme();
                  },
                  label: "Token refresh",
                  get value() {
                    return `backoff ${formatUntil(state().main?.refreshBackoffUntil)}`;
                  },
                  tone: "warn"
                });
              }
            })];
          }
        })];
      }
    }), null);
    _$effect(_p$ => {
      var _v$14 = theme().borderActive,
        _v$15 = theme().accent,
        _v$16 = theme().background;
      _v$14 !== _p$.e && (_p$.e = _$setProp(_el$39, "borderColor", _v$14, _p$.e));
      _v$15 !== _p$.t && (_p$.t = _$setProp(_el$41, "backgroundColor", _v$15, _p$.t));
      _v$16 !== _p$.a && (_p$.a = _$setProp(_el$42, "fg", _v$16, _p$.a));
      return _p$;
    }, {
      e: undefined,
      t: undefined,
      a: undefined
    });
    return _el$39;
  })();
}
const tui = async api => {
  const root = await readTuiPreferencesFile();
  const controller = createSidebarController(resolveAnthropicAuthPrefs(root));
  api.slots.register({
    order: computeEffectiveOrder(root, PLUGIN_KEY, DEFAULT_SLOT_ORDER),
    slots: {
      sidebar_content(_ctx, props) {
        return _$createComponent(QuotaSidebar, {
          api: api,
          controller: controller,
          get sessionId() {
            return props.session_id;
          }
        });
      }
    }
  });
  if (!rpcPollStarted) {
    rpcPollStarted = true;
    const rpcClient = createRpcClient(getRpcDir(api.state.path.directory ?? ''), process.pid);
    let lastNotificationId = 0;
    let rpcInFlight = false;
    setInterval(() => {
      if (rpcInFlight) return;
      const current = api.route.current;
      const resolved = typeof current === 'function' ? current() : current;
      const sessionId = resolved?.params?.sessionID;
      rpcInFlight = true;
      void rpcClient.pending(lastNotificationId, sessionId).then(messages => {
        for (const message of [...messages].sort((a, b) => a.id - b.id)) {
          lastNotificationId = Math.max(lastNotificationId, message.id);
          if (message.payload.command === 'claude-quota') {
            api.ui.dialog.setSize('xlarge');
            api.ui.dialog.replace(() => _$createComponent(QuotaDialogContent, {
              api: api,
              controller: controller
            }));
            continue;
          }
          openCommandDialog(api, message.payload, (command, args) => rpcClient.apply({
            command,
            arguments: args,
            sessionId
          }));
        }
      }).catch(() => {}).finally(() => {
        rpcInFlight = false;
      });
    }, RPC_POLL_MS);
  }
};
const plugin = {
  id: ID,
  tui
};
export default plugin;