cascade-ai 0.12.19 → 0.12.21

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/cli.cjs CHANGED
@@ -109,7 +109,7 @@ var __export = (target, all) => {
109
109
  var CASCADE_VERSION, CASCADE_CONFIG_FILE, CASCADE_DB_FILE, CASCADE_DASHBOARD_SECRET_FILE, GLOBAL_CONFIG_DIR, GLOBAL_DB_FILE, GLOBAL_KEYSTORE_FILE, GLOBAL_RUNTIME_DB_FILE, DEFAULT_DASHBOARD_PORT, DEFAULT_CONTEXT_LIMIT, DEFAULT_AUTO_SUMMARIZE_AT, MODELS, T1_MODEL_PRIORITY, T2_MODEL_PRIORITY, T3_MODEL_PRIORITY, VISION_MODEL_PRIORITY, COMPLEXITY_T2_COUNT, THEME_NAMES, DEFAULT_THEME, OLLAMA_BASE_URL, LM_STUDIO_BASE_URL, AZURE_BASE_URL_TEMPLATE, TOOL_NAMES, DEFAULT_APPROVAL_REQUIRED;
110
110
  var init_constants = __esm({
111
111
  "src/constants.ts"() {
112
- CASCADE_VERSION = "0.12.19";
112
+ CASCADE_VERSION = "0.12.21";
113
113
  CASCADE_CONFIG_FILE = ".cascade/config.json";
114
114
  CASCADE_DB_FILE = ".cascade/memory.db";
115
115
  CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
@@ -1216,8 +1216,7 @@ var init_gemini = __esm({
1216
1216
  }
1217
1217
  });
1218
1218
  function preferIpv4Host(url) {
1219
- if (!url) return url;
1220
- return url.replace(/^(https?:\/\/)localhost(?=[:/]|$)/i, "$1127.0.0.1");
1219
+ return url;
1221
1220
  }
1222
1221
  async function nodeHttpFetch(input, init = {}, redirectCount = 0) {
1223
1222
  const urlStr = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
@@ -1522,7 +1521,7 @@ var init_openai_compatible = __esm({
1522
1521
  init_net();
1523
1522
  OpenAICompatibleProvider = class extends OpenAIProvider {
1524
1523
  constructor(config, model) {
1525
- super(config, model);
1524
+ super({ ...config, apiKey: config.apiKey ?? "not-required" }, model);
1526
1525
  this.client = new OpenAI__default.default({
1527
1526
  apiKey: config.apiKey ?? "not-required",
1528
1527
  baseURL: preferIpv4Host(config.baseUrl),
@@ -4166,10 +4165,10 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
4166
4165
  if (availableProviders.has("ollama")) {
4167
4166
  await this.discoverOllamaModels(ollamaCfg);
4168
4167
  }
4169
- if (availableProviders.has("openai-compatible")) {
4170
- await Promise.all(
4171
- config.providers.filter((p) => p.type === "openai-compatible").map((cfg) => this.discoverOpenAICompatibleModels(cfg))
4172
- );
4168
+ const ocConfigs = config.providers.filter((p) => p.type === "openai-compatible" && p.baseUrl);
4169
+ if (ocConfigs.length > 0) {
4170
+ const results = await Promise.all(ocConfigs.map((cfg) => this.discoverOpenAICompatibleModels(cfg)));
4171
+ if (results.some(Boolean)) this.selector.markProviderAvailable("openai-compatible");
4173
4172
  }
4174
4173
  for (const tier of ["T1", "T2", "T3"]) {
4175
4174
  const override = tier === "T1" ? config.models.t1 : tier === "T2" ? config.models.t2 : config.models.t3;
@@ -4640,6 +4639,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
4640
4639
  } catch {
4641
4640
  }
4642
4641
  }
4642
+ /** Returns true when at least one real model was discovered from the endpoint. */
4643
4643
  async discoverOpenAICompatibleModels(cfg) {
4644
4644
  try {
4645
4645
  const seed = {
@@ -4659,8 +4659,10 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
4659
4659
  for (const m of models) {
4660
4660
  this.selector.addDynamicModel(m);
4661
4661
  }
4662
+ return models.length > 0;
4662
4663
  } catch (err) {
4663
4664
  console.warn("[router] OpenAI-compatible model discovery failed:", err instanceof Error ? err.message : err);
4665
+ return false;
4664
4666
  }
4665
4667
  }
4666
4668
  ensureProvider(model, configs) {
@@ -11018,135 +11020,126 @@ init_ollama();
11018
11020
  init_openai_compatible();
11019
11021
 
11020
11022
  // src/cli/themes/index.ts
11021
- var cascadeTheme = {
11022
- name: "cascade",
11023
- colors: {
11024
- primary: "#7C6AF7",
11025
- // Cascade violet
11026
- secondary: "#A78BFA",
11027
- accent: "#06B6D4",
11028
- // Cyan
11029
- success: "#10B981",
11030
- warning: "#F59E0B",
11031
- error: "#EF4444",
11032
- info: "#3B82F6",
11033
- muted: "#6B7280",
11034
- background: "#0F0F1A",
11035
- foreground: "#E2E8F0",
11036
- border: "#2D2B55",
11037
- t1Color: "#7C6AF7",
11038
- // Violet
11039
- t2Color: "#06B6D4",
11040
- // Cyan
11041
- t3Color: "#10B981"
11042
- // Green
11043
- }
11044
- };
11045
- var darkTheme = {
11046
- name: "dark",
11047
- colors: {
11048
- primary: "#60A5FA",
11049
- secondary: "#818CF8",
11050
- accent: "#34D399",
11051
- success: "#34D399",
11052
- warning: "#FBBF24",
11053
- error: "#F87171",
11054
- info: "#60A5FA",
11055
- muted: "#6B7280",
11056
- background: "#111827",
11057
- foreground: "#F9FAFB",
11058
- border: "#374151",
11059
- t1Color: "#60A5FA",
11060
- t2Color: "#818CF8",
11061
- t3Color: "#34D399"
11062
- }
11063
- };
11064
- var lightTheme = {
11065
- name: "light",
11066
- colors: {
11067
- primary: "#2563EB",
11068
- secondary: "#7C3AED",
11069
- accent: "#0891B2",
11070
- success: "#059669",
11071
- warning: "#D97706",
11072
- error: "#DC2626",
11073
- info: "#2563EB",
11074
- muted: "#6B7280",
11075
- background: "#FFFFFF",
11076
- foreground: "#111827",
11077
- border: "#E5E7EB",
11078
- t1Color: "#2563EB",
11079
- t2Color: "#7C3AED",
11080
- t3Color: "#059669"
11081
- }
11082
- };
11083
- var draculaTheme = {
11084
- name: "dracula",
11085
- colors: {
11086
- primary: "#BD93F9",
11087
- secondary: "#FF79C6",
11088
- accent: "#8BE9FD",
11089
- success: "#50FA7B",
11090
- warning: "#FFB86C",
11091
- error: "#FF5555",
11092
- info: "#8BE9FD",
11093
- muted: "#6272A4",
11094
- background: "#282A36",
11095
- foreground: "#F8F8F2",
11096
- border: "#44475A",
11097
- t1Color: "#BD93F9",
11098
- t2Color: "#FF79C6",
11099
- t3Color: "#50FA7B"
11100
- }
11101
- };
11102
- var nordTheme = {
11103
- name: "nord",
11104
- colors: {
11105
- primary: "#88C0D0",
11106
- secondary: "#81A1C1",
11107
- accent: "#A3BE8C",
11108
- success: "#A3BE8C",
11109
- warning: "#EBCB8B",
11110
- error: "#BF616A",
11111
- info: "#5E81AC",
11112
- muted: "#4C566A",
11113
- background: "#2E3440",
11114
- foreground: "#ECEFF4",
11115
- border: "#3B4252",
11116
- t1Color: "#88C0D0",
11117
- t2Color: "#81A1C1",
11118
- t3Color: "#A3BE8C"
11119
- }
11023
+ function defineTheme(name, colors) {
11024
+ return { name, colors };
11025
+ }
11026
+ var midnightTheme = defineTheme("midnight", {
11027
+ primary: "#8B7CF9",
11028
+ secondary: "#B7AEFF",
11029
+ accent: "#42D3E7",
11030
+ success: "#3DDC97",
11031
+ warning: "#F7B84B",
11032
+ error: "#FF6685",
11033
+ info: "#67A8FF",
11034
+ muted: "#7C819B",
11035
+ background: "#080A12",
11036
+ foreground: "#EDF0FA",
11037
+ border: "#292D42",
11038
+ t1Color: "#F7B84B",
11039
+ t2Color: "#A98BFF",
11040
+ t3Color: "#42D3E7"
11041
+ });
11042
+ var auroraTheme = defineTheme("aurora", {
11043
+ primary: "#6F8CFF",
11044
+ secondary: "#A78BFA",
11045
+ accent: "#45E0B8",
11046
+ success: "#45E0B8",
11047
+ warning: "#FFD166",
11048
+ error: "#FF6B8A",
11049
+ info: "#6FB7FF",
11050
+ muted: "#7890A8",
11051
+ background: "#071019",
11052
+ foreground: "#EAF7F5",
11053
+ border: "#20384A",
11054
+ t1Color: "#FFD166",
11055
+ t2Color: "#8B9CFF",
11056
+ t3Color: "#45E0B8"
11057
+ });
11058
+ var emberTheme = defineTheme("ember", {
11059
+ primary: "#FF8A5B",
11060
+ secondary: "#FFB36B",
11061
+ accent: "#F7C75B",
11062
+ success: "#72D69A",
11063
+ warning: "#F7C75B",
11064
+ error: "#FF647C",
11065
+ info: "#73B7FF",
11066
+ muted: "#9A8078",
11067
+ background: "#120C0B",
11068
+ foreground: "#FFF1E9",
11069
+ border: "#463027",
11070
+ t1Color: "#F7C75B",
11071
+ t2Color: "#FF8A5B",
11072
+ t3Color: "#72D69A"
11073
+ });
11074
+ var tideTheme = defineTheme("tide", {
11075
+ primary: "#4DA8FF",
11076
+ secondary: "#65C7F7",
11077
+ accent: "#51E1D4",
11078
+ success: "#63D9A5",
11079
+ warning: "#F2C879",
11080
+ error: "#F0718B",
11081
+ info: "#4DA8FF",
11082
+ muted: "#71899C",
11083
+ background: "#061017",
11084
+ foreground: "#E8F5FA",
11085
+ border: "#1C3947",
11086
+ t1Color: "#F2C879",
11087
+ t2Color: "#65A8F7",
11088
+ t3Color: "#51E1D4"
11089
+ });
11090
+ var bloomTheme = defineTheme("bloom", {
11091
+ primary: "#C084FC",
11092
+ secondary: "#F08BB4",
11093
+ accent: "#7DD3FC",
11094
+ success: "#6EE7B7",
11095
+ warning: "#FBCB78",
11096
+ error: "#FB7185",
11097
+ info: "#7DD3FC",
11098
+ muted: "#9B83A8",
11099
+ background: "#140D19",
11100
+ foreground: "#F8EEFC",
11101
+ border: "#412B4D",
11102
+ t1Color: "#FBCB78",
11103
+ t2Color: "#C084FC",
11104
+ t3Color: "#7DD3FC"
11105
+ });
11106
+ var daybreakTheme = defineTheme("daybreak", {
11107
+ primary: "#6857D9",
11108
+ secondary: "#826AE6",
11109
+ accent: "#087F91",
11110
+ success: "#087A55",
11111
+ warning: "#A86408",
11112
+ error: "#C83253",
11113
+ info: "#2563A8",
11114
+ muted: "#667085",
11115
+ background: "#F7F7FB",
11116
+ foreground: "#202336",
11117
+ border: "#D9DCE8",
11118
+ t1Color: "#A86408",
11119
+ t2Color: "#6857D9",
11120
+ t3Color: "#087F91"
11121
+ });
11122
+ var canonicalThemes = {
11123
+ midnight: midnightTheme,
11124
+ aurora: auroraTheme,
11125
+ ember: emberTheme,
11126
+ tide: tideTheme,
11127
+ bloom: bloomTheme,
11128
+ daybreak: daybreakTheme
11120
11129
  };
11121
- var solarizedTheme = {
11122
- name: "solarized",
11123
- colors: {
11124
- primary: "#268BD2",
11125
- secondary: "#2AA198",
11126
- accent: "#B58900",
11127
- success: "#859900",
11128
- warning: "#CB4B16",
11129
- error: "#DC322F",
11130
- info: "#268BD2",
11131
- muted: "#657B83",
11132
- background: "#002B36",
11133
- foreground: "#839496",
11134
- border: "#073642",
11135
- t1Color: "#268BD2",
11136
- t2Color: "#2AA198",
11137
- t3Color: "#859900"
11138
- }
11130
+ var THEME_ALIASES = {
11131
+ cascade: "midnight",
11132
+ dark: "aurora",
11133
+ light: "daybreak",
11134
+ dracula: "bloom",
11135
+ nord: "tide",
11136
+ solarized: "ember"
11139
11137
  };
11140
- var themes = /* @__PURE__ */ new Map([
11141
- ["cascade", cascadeTheme],
11142
- ["dark", darkTheme],
11143
- ["light", lightTheme],
11144
- ["dracula", draculaTheme],
11145
- ["nord", nordTheme],
11146
- ["solarized", solarizedTheme]
11147
- ]);
11138
+ function resolveThemeName(name) {
11139
+ return (name in canonicalThemes ? name : THEME_ALIASES[name]) || "midnight";
11140
+ }
11148
11141
  function getTheme(name) {
11149
- return themes.get(name) ?? cascadeTheme;
11142
+ return canonicalThemes[resolveThemeName(name)] ?? midnightTheme;
11150
11143
  }
11151
11144
 
11152
11145
  // src/cli/slash/index.ts
@@ -11400,6 +11393,13 @@ var FIXED_CHROME_ROWS = 1 + // StatusBar
11400
11393
  3;
11401
11394
  var STREAM_TAIL_ROWS = 9;
11402
11395
  var SLASH_PANEL_ROWS = 11;
11396
+ function computeAdaptiveLayoutMode(columns, rows) {
11397
+ const safeColumns = Number.isFinite(columns) && columns > 0 ? columns : 100;
11398
+ const safeRows = Number.isFinite(rows) && rows > 0 ? rows : 40;
11399
+ if (safeColumns < 80 || safeRows < 24) return "narrow";
11400
+ if (safeColumns < 120 || safeRows < 32) return "medium";
11401
+ return "wide";
11402
+ }
11403
11403
  var TREE_ROWS_FULL = 10;
11404
11404
  var TREE_ROWS_COMPACT = 4;
11405
11405
  var TIMELINE_ROWS = 4;
@@ -11659,7 +11659,7 @@ function formatTokens(n) {
11659
11659
  var StatusBar = React2__default.default.memo(StatusBarInternal);
11660
11660
  function HintBarInternal({ theme, isExecuting }) {
11661
11661
  if (isExecuting) return null;
11662
- return /* @__PURE__ */ jsxRuntime.jsx(ink.Box, { paddingLeft: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.accent, dimColor: true, children: "/help \xB7 /clear \xB7 /theme \xB7 /cost \xB7 /model \xB7 /export" }) });
11662
+ return /* @__PURE__ */ jsxRuntime.jsx(ink.Box, { paddingLeft: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.accent, dimColor: true, children: "/ commands \xB7 \u2191\u2193 history \xB7 Esc cancel \xB7 Ctrl+C exit" }) });
11663
11663
  }
11664
11664
  var HintBar = React2__default.default.memo(HintBarInternal);
11665
11665
  function ApprovalPrompt({ request, theme, onDecision }) {
@@ -11983,6 +11983,53 @@ function CostTracker({
11983
11983
  ] })
11984
11984
  ] });
11985
11985
  }
11986
+ function CompactStatus({ theme, activeT2Count, activeT3Count, currentAction, activeTool, isStreaming }) {
11987
+ const activeCount = activeT2Count + activeT3Count;
11988
+ const isActive = isStreaming || activeCount > 0;
11989
+ const rightHint = isActive ? /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
11990
+ "T2:",
11991
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.accent, children: activeT2Count }),
11992
+ " T3:",
11993
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.accent, children: activeT3Count })
11994
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
11995
+ "[",
11996
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.accent, bold: true, children: "tree" }),
11997
+ "]"
11998
+ ] });
11999
+ return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { paddingX: 1, borderStyle: "single", borderTop: false, borderLeft: false, borderRight: false, borderColor: theme.colors.border, children: [
12000
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Box, { flexGrow: 1, children: isActive ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12001
+ /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.accent, bold: true, children: [
12002
+ /* @__PURE__ */ jsxRuntime.jsx(Spinner__default.default, { type: "hamburger" }),
12003
+ " "
12004
+ ] }),
12005
+ activeTool ? (
12006
+ // Show active tool prominently
12007
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12008
+ /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: "yellow", bold: true, children: [
12009
+ "\u2699 ",
12010
+ activeTool
12011
+ ] }),
12012
+ currentAction && !currentAction.startsWith("Using tool:") && /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
12013
+ " \u2503 ",
12014
+ currentAction.length > 60 ? currentAction.slice(0, 57) + "..." : currentAction
12015
+ ] })
12016
+ ] })
12017
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12018
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.accent, bold: true, children: activeCount > 0 ? `WORKING: ${activeCount} AGENTS` : "ORCHESTRATING" }),
12019
+ currentAction && /* @__PURE__ */ jsxRuntime.jsxs(ink.Text, { color: theme.colors.muted, children: [
12020
+ " \u2503 ",
12021
+ currentAction.length > 80 ? currentAction.slice(0, 77) + "..." : currentAction
12022
+ ] })
12023
+ ] })
12024
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { children: [
12025
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: "\u25CF SYSTEM IDLE " }),
12026
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: "\u2503 Press " }),
12027
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.accent, bold: true, children: "/" }),
12028
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, children: " for command palette" })
12029
+ ] }) }),
12030
+ /* @__PURE__ */ jsxRuntime.jsx(ink.Box, { children: rightHint })
12031
+ ] });
12032
+ }
11986
12033
  function ChatMessage({ role, content, theme, timestamp, isStreaming }) {
11987
12034
  const { label, color, prefix } = getRoleStyle(role, theme);
11988
12035
  return /* @__PURE__ */ jsxRuntime.jsxs(ink.Box, { flexDirection: "column", marginY: 1, children: [
@@ -12287,6 +12334,19 @@ function tailLines(text, n) {
12287
12334
  const lines = text.split("\n");
12288
12335
  return lines.slice(-8);
12289
12336
  }
12337
+ function activeTierSummary(root) {
12338
+ const summary = { t2: 0, t3: 0 };
12339
+ const visit = (node) => {
12340
+ if (node.status === "ACTIVE") {
12341
+ if (node.role === "T2") summary.t2 += 1;
12342
+ if (node.role === "T3") summary.t3 += 1;
12343
+ summary.action ??= node.currentAction;
12344
+ }
12345
+ node.children?.forEach(visit);
12346
+ };
12347
+ if (root) visit(root);
12348
+ return summary;
12349
+ }
12290
12350
  function WelcomeBanner({ theme, config, workspacePath, sessionId }) {
12291
12351
  const t1 = config.models?.t1 ?? "auto";
12292
12352
  const t2 = config.models?.t2 ?? "auto";
@@ -13184,13 +13244,15 @@ ${lastUser.content}`;
13184
13244
  };
13185
13245
  }, [stdout]);
13186
13246
  const width = termSize.columns;
13247
+ const adaptiveMode = computeAdaptiveLayoutMode(termSize.columns, termSize.rows);
13187
13248
  const budgetOpts = {
13188
13249
  isTypingCommand,
13189
- showCost: state.showCost,
13190
- showDetails: state.showDetails,
13191
- showComms: state.showComms && state.peerEvents.length > 0
13250
+ showCost: state.showCost && adaptiveMode !== "narrow",
13251
+ showDetails: state.showDetails && adaptiveMode === "wide",
13252
+ showComms: state.showComms && state.peerEvents.length > 0 && adaptiveMode === "wide"
13192
13253
  };
13193
13254
  const liveBudget = computeLiveAreaBudget(termSize.rows, budgetOpts);
13255
+ const tierSummary = activeTierSummary(state.agentTree);
13194
13256
  const transcriptRows = altScreen ? computeTranscriptRows(termSize.rows, liveBudget, { ...budgetOpts, treeVisible: state.agentTree != null }) : 0;
13195
13257
  const transcriptLines = altScreen ? flattenTranscript(state.messages) : [];
13196
13258
  const transcript = altScreen ? windowTranscript(transcriptLines, historyOffset, transcriptRows) : null;
@@ -13280,10 +13342,28 @@ ${lastUser.content}`;
13280
13342
  onClose: () => setIsShowingModels(false)
13281
13343
  }
13282
13344
  ) }),
13283
- /* @__PURE__ */ jsxRuntime.jsx(AgentTree, { root: state.agentTree, theme, scrollOffset: treeScrollOffset, maxRows: liveBudget.treeMaxRows }),
13284
- state.showComms && liveBudget.commsMaxEvents > 0 && /* @__PURE__ */ jsxRuntime.jsx(PeerFeed, { events: state.peerEvents, theme, maxRows: liveBudget.commsMaxEvents }),
13285
- state.showDetails && liveBudget.showTimeline && /* @__PURE__ */ jsxRuntime.jsx(TimelinePanel, { nodes: [...treeNodesRef.current.values()], theme, currentIndex: timelineIndex, onChangeIndex: setTimelineIndex }),
13286
- state.showCost && /* @__PURE__ */ jsxRuntime.jsx(CostTracker, { theme, totalTokens: state.totalTokens, totalCostUsd: state.totalCostUsd, callsByProvider: state.callsByProvider, callsByTier: state.callsByTier, costByTier: state.costByTier, tokensByTier: state.tokensByTier, compact: liveBudget.costCompact, savedUsd: state.savedUsd, savedPct: state.savedPct }),
13345
+ adaptiveMode === "narrow" && state.agentTree ? /* @__PURE__ */ jsxRuntime.jsx(
13346
+ CompactStatus,
13347
+ {
13348
+ theme,
13349
+ activeT2Count: tierSummary.t2,
13350
+ activeT3Count: tierSummary.t3,
13351
+ currentAction: tierSummary.action ?? state.agentTree.currentAction,
13352
+ activeTool: state.activeTool,
13353
+ isStreaming: state.isStreaming
13354
+ }
13355
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
13356
+ AgentTree,
13357
+ {
13358
+ root: state.agentTree,
13359
+ theme,
13360
+ scrollOffset: treeScrollOffset,
13361
+ maxRows: adaptiveMode === "medium" ? Math.min(4, liveBudget.treeMaxRows) : liveBudget.treeMaxRows
13362
+ }
13363
+ ),
13364
+ adaptiveMode === "wide" && state.showComms && liveBudget.commsMaxEvents > 0 && /* @__PURE__ */ jsxRuntime.jsx(PeerFeed, { events: state.peerEvents, theme, maxRows: liveBudget.commsMaxEvents }),
13365
+ adaptiveMode === "wide" && state.showDetails && liveBudget.showTimeline && /* @__PURE__ */ jsxRuntime.jsx(TimelinePanel, { nodes: [...treeNodesRef.current.values()], theme, currentIndex: timelineIndex, onChangeIndex: setTimelineIndex }),
13366
+ adaptiveMode !== "narrow" && state.showCost && /* @__PURE__ */ jsxRuntime.jsx(CostTracker, { theme, totalTokens: state.totalTokens, totalCostUsd: state.totalCostUsd, callsByProvider: state.callsByProvider, callsByTier: state.callsByTier, costByTier: state.costByTier, tokensByTier: state.tokensByTier, compact: liveBudget.costCompact, savedUsd: state.savedUsd, savedPct: state.savedPct }),
13287
13367
  liveBudget.collapsed && (state.showCost || state.showDetails || state.agentTree != null) && /* @__PURE__ */ jsxRuntime.jsx(ink.Text, { color: theme.colors.muted, dimColor: true, children: " \u25B8 panels collapsed (small terminal)" }),
13288
13368
  state.approvalRequest && /* @__PURE__ */ jsxRuntime.jsx(ApprovalPrompt, { request: state.approvalRequest, theme, onDecision: (decision) => {
13289
13369
  dispatch({ type: "SET_APPROVAL", request: null });