bravecode-cli 0.1.16 → 0.1.17

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.mjs CHANGED
@@ -38043,11 +38043,12 @@ var init_task = __esm({
38043
38043
  });
38044
38044
 
38045
38045
  // src/version.ts
38046
- var APP_VERSION;
38046
+ var APP_VERSION, APP_NAME;
38047
38047
  var init_version = __esm({
38048
38048
  "src/version.ts"() {
38049
38049
  "use strict";
38050
- APP_VERSION = "0.1.16";
38050
+ APP_VERSION = "0.1.17";
38051
+ APP_NAME = "BraveCode";
38051
38052
  }
38052
38053
  });
38053
38054
 
@@ -41582,18 +41583,73 @@ import "react";
41582
41583
  import { Box, Text } from "ink";
41583
41584
  import { jsx as jsx6 } from "react/jsx-runtime";
41584
41585
  function Logo() {
41585
- return /* @__PURE__ */ jsx6(Box, { flexDirection: "column", alignItems: "center", children: /* @__PURE__ */ jsx6(Text, { bold: true, color: "#00d4ff", fontSize: 2, children: "bravecode" }) });
41586
+ return /* @__PURE__ */ jsx6(Box, { flexDirection: "column", alignItems: "center", children: ROWS.map((row, i) => /* @__PURE__ */ jsx6(
41587
+ Text,
41588
+ {
41589
+ dimColor: !row.bright,
41590
+ italic: row.italic,
41591
+ bold: row.bright,
41592
+ children: row.chars
41593
+ },
41594
+ i
41595
+ )) });
41586
41596
  }
41597
+ var ROWS;
41587
41598
  var init_logo = __esm({
41588
41599
  "src/core/tui/components/logo.tsx"() {
41589
41600
  "use strict";
41601
+ ROWS = [
41602
+ { chars: " ____ ", bright: false, italic: true },
41603
+ { chars: "| _ \\ __ _ _ __ __ _ ", bright: false, italic: true },
41604
+ { chars: "| |_) / _` | '_ \\ / _` |", bright: false, italic: true },
41605
+ { chars: "| __/ (_| | | | | (_| |", bright: true, italic: false },
41606
+ { chars: "|_| \\__,_|_| |_|\\__,_|", bright: true, italic: false }
41607
+ ];
41590
41608
  }
41591
41609
  });
41592
41610
 
41593
- // src/core/tui/components/message.tsx
41611
+ // src/core/tui/components/header-bar.tsx
41594
41612
  import "react";
41595
41613
  import { Box as Box2, Text as Text2 } from "ink";
41596
41614
  import { jsx as jsx7, jsxs } from "react/jsx-runtime";
41615
+ function HeaderBar({ title, subtitle }) {
41616
+ const { colors } = useTheme();
41617
+ const cwd = process.cwd().replace(process.env.HOME || "", "~");
41618
+ return /* @__PURE__ */ jsxs(
41619
+ Box2,
41620
+ {
41621
+ flexDirection: "row",
41622
+ justifyContent: "space-between",
41623
+ width: "100%",
41624
+ paddingX: 1,
41625
+ children: [
41626
+ /* @__PURE__ */ jsxs(Box2, { flexDirection: "column", alignItems: "center", flexGrow: 1, children: [
41627
+ /* @__PURE__ */ jsxs(Text2, { children: [
41628
+ /* @__PURE__ */ jsx7(Text2, { bold: true, color: colors.text, children: title }),
41629
+ /* @__PURE__ */ jsx7(Text2, { color: colors.textMuted, children: " \u2014 " }),
41630
+ /* @__PURE__ */ jsx7(Text2, { color: colors.textSecondary, children: subtitle })
41631
+ ] }),
41632
+ /* @__PURE__ */ jsx7(Text2, { color: colors.textMuted, children: cwd })
41633
+ ] }),
41634
+ /* @__PURE__ */ jsxs(Box2, { gap: 1, children: [
41635
+ /* @__PURE__ */ jsx7(Text2, { color: colors.textMuted, children: "\u25A6" }),
41636
+ /* @__PURE__ */ jsx7(Text2, { color: colors.textMuted, children: "\u2261" })
41637
+ ] })
41638
+ ]
41639
+ }
41640
+ );
41641
+ }
41642
+ var init_header_bar = __esm({
41643
+ "src/core/tui/components/header-bar.tsx"() {
41644
+ "use strict";
41645
+ init_theme();
41646
+ }
41647
+ });
41648
+
41649
+ // src/core/tui/components/message.tsx
41650
+ import { memo, useEffect as useEffect2, useRef, useState as useState6 } from "react";
41651
+ import { Box as Box3, Text as Text3 } from "ink";
41652
+ import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
41597
41653
  function ToolCallDisplay({ toolCall }) {
41598
41654
  const { colors } = useTheme();
41599
41655
  const statusIcon = {
@@ -41623,17 +41679,17 @@ function ToolCallDisplay({ toolCall }) {
41623
41679
  };
41624
41680
  const label = toolLabels[toolCall.name]?.past || toolCall.name;
41625
41681
  const argStr = getToolArgs(toolCall);
41626
- return /* @__PURE__ */ jsxs(Box2, { marginLeft: 2, children: [
41627
- /* @__PURE__ */ jsxs(Text2, { color: statusColor, children: [
41682
+ return /* @__PURE__ */ jsxs2(Box3, { marginLeft: 2, children: [
41683
+ /* @__PURE__ */ jsxs2(Text3, { color: statusColor, children: [
41628
41684
  statusIcon,
41629
41685
  " "
41630
41686
  ] }),
41631
- /* @__PURE__ */ jsx7(Text2, { bold: true, color: colors.text, children: label }),
41632
- argStr && /* @__PURE__ */ jsxs(Text2, { color: colors.textMuted, children: [
41687
+ /* @__PURE__ */ jsx8(Text3, { bold: true, color: colors.text, children: label }),
41688
+ argStr && /* @__PURE__ */ jsxs2(Text3, { color: colors.textMuted, children: [
41633
41689
  " ",
41634
41690
  argStr
41635
41691
  ] }),
41636
- toolCall.output && toolCall.status === "completed" && /* @__PURE__ */ jsxs(Text2, { color: colors.textMuted, children: [
41692
+ toolCall.output && toolCall.status === "completed" && /* @__PURE__ */ jsxs2(Text3, { color: colors.textMuted, children: [
41637
41693
  " \u2514 ",
41638
41694
  truncate(toolCall.output.split("\n")[0], 60)
41639
41695
  ] })
@@ -41679,14 +41735,59 @@ function formatTime(date5) {
41679
41735
  hour12: false
41680
41736
  });
41681
41737
  }
41682
- function Message({ message, showTimestamp = false }) {
41738
+ function wrapLines(text2, width) {
41739
+ const innerWidth = Math.max(10, width);
41740
+ const out = [];
41741
+ for (const line of text2.split("\n")) {
41742
+ if (line.length === 0) {
41743
+ out.push("");
41744
+ continue;
41745
+ }
41746
+ for (let i = 0; i < line.length; i += innerWidth) {
41747
+ out.push(line.slice(i, i + innerWidth));
41748
+ }
41749
+ }
41750
+ return out;
41751
+ }
41752
+ function clipContent(content, width, skipTop, skipBottom) {
41753
+ if (!skipTop && !skipBottom) return content;
41754
+ const wrapped = wrapLines(content, Math.max(10, width - 2));
41755
+ const start = Math.min(skipTop, wrapped.length);
41756
+ const end = Math.max(start, wrapped.length - skipBottom);
41757
+ return wrapped.slice(start, end).join("\n");
41758
+ }
41759
+ function MessageImpl({
41760
+ message,
41761
+ showTimestamp = false,
41762
+ clipTop = 0,
41763
+ clipBottom = 0,
41764
+ maxRenderedLines
41765
+ }) {
41683
41766
  const { colors } = useTheme();
41767
+ if (message.role === "user") {
41768
+ return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "row", marginBottom: 1, children: [
41769
+ /* @__PURE__ */ jsx8(Text3, { color: colors.primary, children: "\u2502 " }),
41770
+ /* @__PURE__ */ jsx8(Text3, { color: colors.text, children: message.content })
41771
+ ] });
41772
+ }
41773
+ const isStreaming = message.toolCalls && message.toolCalls.some((tc) => tc.status === "running");
41774
+ const [renderedContent, setRenderedContent] = useState6(() => {
41775
+ if (!maxRenderedLines) return message.content;
41776
+ const wrapped = wrapLines(message.content, 80);
41777
+ return wrapped.slice(-maxRenderedLines).join("\n");
41778
+ });
41779
+ const lastSeenContent = useRef(message.content);
41780
+ useEffect2(() => {
41781
+ if (message.content === lastSeenContent.current) return;
41782
+ lastSeenContent.current = message.content;
41783
+ if (!maxRenderedLines) {
41784
+ setRenderedContent(message.content);
41785
+ return;
41786
+ }
41787
+ const wrapped = wrapLines(message.content, 80);
41788
+ setRenderedContent(wrapped.slice(-maxRenderedLines).join("\n"));
41789
+ }, [message.content, maxRenderedLines]);
41684
41790
  const roleConfig = {
41685
- user: {
41686
- label: "You",
41687
- color: colors.primary,
41688
- prefix: "\u203A"
41689
- },
41690
41791
  assistant: {
41691
41792
  label: "Assistant",
41692
41793
  color: colors.secondary,
@@ -41699,80 +41800,185 @@ function Message({ message, showTimestamp = false }) {
41699
41800
  }
41700
41801
  };
41701
41802
  const config2 = roleConfig[message.role];
41702
- return /* @__PURE__ */ jsxs(Box2, { flexDirection: "column", marginBottom: 1, children: [
41703
- /* @__PURE__ */ jsxs(Box2, { children: [
41704
- /* @__PURE__ */ jsxs(Text2, { bold: true, color: config2.color, children: [
41803
+ const baseContent = clipTop || clipBottom ? clipContent(renderedContent, 80, clipTop, clipBottom) : renderedContent;
41804
+ return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", marginBottom: 1, children: [
41805
+ /* @__PURE__ */ jsxs2(Box3, { children: [
41806
+ /* @__PURE__ */ jsxs2(Text3, { bold: true, color: config2.color, children: [
41705
41807
  config2.prefix,
41706
41808
  " ",
41707
41809
  config2.label
41708
41810
  ] }),
41709
- message.agent && /* @__PURE__ */ jsxs(Text2, { color: colors.textMuted, children: [
41811
+ message.agent && /* @__PURE__ */ jsxs2(Text3, { color: colors.textMuted, children: [
41710
41812
  " (",
41711
41813
  message.agent,
41712
41814
  ")"
41713
41815
  ] }),
41714
- showTimestamp && /* @__PURE__ */ jsxs(Text2, { color: colors.textMuted, children: [
41816
+ showTimestamp && /* @__PURE__ */ jsxs2(Text3, { color: colors.textMuted, children: [
41715
41817
  " ",
41716
41818
  formatTime(message.timestamp)
41717
- ] })
41819
+ ] }),
41820
+ isStreaming && /* @__PURE__ */ jsx8(Text3, { color: colors.textMuted, children: " streaming\u2026" })
41718
41821
  ] }),
41719
- message.role === "user" ? /* @__PURE__ */ jsx7(Box2, { marginLeft: 2, children: /* @__PURE__ */ jsx7(Text2, { color: colors.text, children: message.content }) }) : /* @__PURE__ */ jsx7(Box2, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ jsx7(Text2, { color: colors.text, children: message.content }) }),
41720
- message.toolCalls && message.toolCalls.length > 0 && /* @__PURE__ */ jsx7(Box2, { flexDirection: "column", marginTop: 1, children: message.toolCalls.map((toolCall) => /* @__PURE__ */ jsx7(ToolCallDisplay, { toolCall }, toolCall.id)) })
41822
+ /* @__PURE__ */ jsx8(Box3, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ jsx8(Text3, { color: colors.text, children: baseContent }) }),
41823
+ message.toolCalls && message.toolCalls.length > 0 && /* @__PURE__ */ jsx8(Box3, { flexDirection: "column", marginTop: 1, children: message.toolCalls.map((toolCall) => /* @__PURE__ */ jsx8(ToolCallDisplay, { toolCall }, toolCall.id)) })
41721
41824
  ] });
41722
41825
  }
41826
+ var Message;
41723
41827
  var init_message = __esm({
41724
41828
  "src/core/tui/components/message.tsx"() {
41725
41829
  "use strict";
41726
41830
  init_theme();
41831
+ Message = memo(MessageImpl, (prev, next) => {
41832
+ return prev.message === next.message && prev.showTimestamp === next.showTimestamp && prev.clipTop === next.clipTop && prev.clipBottom === next.clipBottom && prev.maxRenderedLines === next.maxRenderedLines;
41833
+ });
41834
+ }
41835
+ });
41836
+
41837
+ // src/core/tui/hooks/use-terminal-size.ts
41838
+ import { useEffect as useEffect3, useState as useState7 } from "react";
41839
+ import { useStdout } from "ink";
41840
+ function useTerminalSize() {
41841
+ const { stdout } = useStdout();
41842
+ const [size, setSize] = useState7(() => ({
41843
+ columns: stdout?.columns ?? 80,
41844
+ rows: stdout?.rows ?? 24
41845
+ }));
41846
+ useEffect3(() => {
41847
+ if (!stdout) return;
41848
+ const update = () => {
41849
+ setSize({
41850
+ columns: stdout.columns ?? 80,
41851
+ rows: stdout.rows ?? 24
41852
+ });
41853
+ };
41854
+ stdout.on("resize", update);
41855
+ update();
41856
+ return () => {
41857
+ stdout.off("resize", update);
41858
+ };
41859
+ }, [stdout]);
41860
+ return size;
41861
+ }
41862
+ var init_use_terminal_size = __esm({
41863
+ "src/core/tui/hooks/use-terminal-size.ts"() {
41864
+ "use strict";
41727
41865
  }
41728
41866
  });
41729
41867
 
41730
41868
  // src/core/tui/components/message-container.tsx
41731
- import { useRef, useEffect as useEffect2 } from "react";
41732
- import { Box as Box3, Text as Text3 } from "ink";
41733
- import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
41869
+ import { useEffect as useEffect4, useMemo, useRef as useRef2, useState as useState8 } from "react";
41870
+ import { Box as Box4, Text as Text4, useInput } from "ink";
41871
+ import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
41872
+ function messageLineCount(content, width, extras) {
41873
+ const innerWidth = Math.max(10, width - 4);
41874
+ const lines = content.split("\n");
41875
+ let rows = 0;
41876
+ for (const line of lines) {
41877
+ rows += Math.max(1, Math.ceil((line.length || 1) / innerWidth));
41878
+ }
41879
+ rows += 1;
41880
+ rows += extras.toolCalls ?? 0;
41881
+ return rows;
41882
+ }
41734
41883
  function MessageContainer() {
41735
41884
  const { colors } = useTheme();
41736
41885
  const { messages } = useSession();
41737
- const containerRef = useRef(null);
41738
- useEffect2(() => {
41739
- if (containerRef.current) {
41886
+ const { rows, columns } = useTerminalSize();
41887
+ const viewportHeight = Math.max(5, rows - 3);
41888
+ const messageHeights = useMemo(() => {
41889
+ return messages.map(
41890
+ (m) => messageLineCount(m.content, columns, {
41891
+ role: m.role,
41892
+ toolCalls: m.toolCalls?.length
41893
+ })
41894
+ );
41895
+ }, [messages, columns]);
41896
+ const totalLines = useMemo(
41897
+ () => messageHeights.reduce((a, b) => a + b, 0),
41898
+ [messageHeights]
41899
+ );
41900
+ const [scrollOffset, setScrollOffset] = useState8(0);
41901
+ const stickToBottom = useRef2(true);
41902
+ useEffect4(() => {
41903
+ if (stickToBottom.current) {
41904
+ setScrollOffset(0);
41905
+ }
41906
+ }, [totalLines]);
41907
+ useInput((input, key) => {
41908
+ if (key.pageUp) {
41909
+ stickToBottom.current = false;
41910
+ setScrollOffset((o) => Math.min(o + Math.floor(viewportHeight * 0.9), Math.max(0, totalLines - viewportHeight)));
41911
+ } else if (key.pageDown) {
41912
+ setScrollOffset((o) => {
41913
+ const next = Math.max(0, o - Math.floor(viewportHeight * 0.9));
41914
+ if (next === 0) stickToBottom.current = true;
41915
+ return next;
41916
+ });
41917
+ } else if (input === "g" && key.shift) {
41918
+ stickToBottom.current = true;
41919
+ setScrollOffset(0);
41920
+ } else if (input === "g" && !key.shift) {
41921
+ stickToBottom.current = false;
41922
+ setScrollOffset(Math.max(0, totalLines - viewportHeight));
41923
+ } else if (key.upArrow) {
41924
+ stickToBottom.current = false;
41925
+ setScrollOffset((o) => Math.min(o + 1, Math.max(0, totalLines - viewportHeight)));
41926
+ } else if (key.downArrow) {
41927
+ setScrollOffset((o) => {
41928
+ const next = Math.max(0, o - 1);
41929
+ if (next === 0) stickToBottom.current = true;
41930
+ return next;
41931
+ });
41740
41932
  }
41741
- }, [messages.length]);
41933
+ });
41742
41934
  if (messages.length === 0) {
41743
- return /* @__PURE__ */ jsxs2(
41744
- Box3,
41745
- {
41746
- flexDirection: "column",
41747
- justifyContent: "center",
41748
- alignItems: "center",
41749
- flexGrow: 1,
41750
- children: [
41751
- /* @__PURE__ */ jsx8(Text3, { bold: true, color: colors.primary, children: "BraveCode AI" }),
41752
- /* @__PURE__ */ jsx8(Text3, { color: colors.textMuted, children: "Agentic coding assistant with free model access" }),
41753
- /* @__PURE__ */ jsx8(Text3, { color: colors.textMuted, children: " " }),
41754
- /* @__PURE__ */ jsx8(Text3, { color: colors.textMuted, children: "Type a message to start. Use /help for commands." })
41755
- ]
41756
- }
41757
- );
41935
+ return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", justifyContent: "center", alignItems: "center", flexGrow: 1, children: [
41936
+ /* @__PURE__ */ jsx9(Text4, { bold: true, color: colors.primary, children: "BraveCode AI" }),
41937
+ /* @__PURE__ */ jsx9(Text4, { color: colors.textMuted, children: "Agentic coding assistant with free model access" }),
41938
+ /* @__PURE__ */ jsx9(Text4, { color: colors.textMuted, children: " " }),
41939
+ /* @__PURE__ */ jsx9(Text4, { color: colors.textMuted, children: "Type a message to start. Use /help for commands." })
41940
+ ] });
41758
41941
  }
41759
- return /* @__PURE__ */ jsx8(
41760
- Box3,
41761
- {
41762
- ref: containerRef,
41763
- flexDirection: "column",
41764
- flexGrow: 1,
41765
- overflow: "hidden",
41766
- children: messages.map((message) => /* @__PURE__ */ jsx8(
41942
+ const windowTop = totalLines - viewportHeight - scrollOffset;
41943
+ const windowBottom = totalLines - scrollOffset;
41944
+ let cursor = 0;
41945
+ const visible = [];
41946
+ for (let i = 0; i < messages.length; i++) {
41947
+ const h = messageHeights[i];
41948
+ const msgTop = cursor;
41949
+ const msgBottom = cursor + h;
41950
+ if (msgBottom > windowTop && msgTop < windowBottom) {
41951
+ const overlapTop = Math.max(0, windowTop - msgTop);
41952
+ const overlapBottom = Math.min(h, windowBottom - msgTop);
41953
+ visible.push({ idx: i, skipTop: overlapTop, skipBottom: h - overlapBottom });
41954
+ }
41955
+ cursor += h;
41956
+ if (msgBottom >= windowBottom) break;
41957
+ }
41958
+ const STREAMING_LINE_CAP = Math.max(10, Math.floor(viewportHeight * 0.6));
41959
+ const lastIndex = messages.length - 1;
41960
+ return /* @__PURE__ */ jsxs3(Box4, { ref: () => {
41961
+ }, flexDirection: "column", flexGrow: 1, overflow: "hidden", children: [
41962
+ visible.map(({ idx, skipTop, skipBottom }) => {
41963
+ const m = messages[idx];
41964
+ if (m.role === "user") {
41965
+ return /* @__PURE__ */ jsx9(Message, { message: m }, m.id);
41966
+ }
41967
+ const isStreaming = idx === lastIndex && m.content !== "";
41968
+ return /* @__PURE__ */ jsx9(
41767
41969
  Message,
41768
41970
  {
41769
- message,
41770
- showTimestamp: true
41971
+ message: m,
41972
+ showTimestamp: true,
41973
+ clipTop: skipTop,
41974
+ clipBottom: skipBottom,
41975
+ maxRenderedLines: isStreaming ? STREAMING_LINE_CAP : void 0
41771
41976
  },
41772
- message.id
41773
- ))
41774
- }
41775
- );
41977
+ m.id
41978
+ );
41979
+ }),
41980
+ !stickToBottom.current && /* @__PURE__ */ jsx9(Box4, { children: /* @__PURE__ */ jsx9(Text4, { color: colors.textMuted, children: "\u2191\u2193 scroll \xB7 pgup/pgdn \xB7 g/G top/bottom" }) })
41981
+ ] });
41776
41982
  }
41777
41983
  var init_message_container = __esm({
41778
41984
  "src/core/tui/components/message-container.tsx"() {
@@ -41780,22 +41986,23 @@ var init_message_container = __esm({
41780
41986
  init_theme();
41781
41987
  init_session();
41782
41988
  init_message();
41989
+ init_use_terminal_size();
41783
41990
  }
41784
41991
  });
41785
41992
 
41786
41993
  // src/core/tui/components/input-editor.tsx
41787
- import { useState as useState6 } from "react";
41788
- import { Box as Box4, Text as Text4, useInput, useApp } from "ink";
41789
- import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
41994
+ import { useState as useState9 } from "react";
41995
+ import { Box as Box5, Text as Text5, useInput as useInput2, useApp } from "ink";
41996
+ import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
41790
41997
  function InputEditor({ onSubmit, placeholder = "Type a message...", disabled = false }) {
41791
41998
  const { colors } = useTheme();
41792
41999
  const { isRunning } = useAgent();
41793
42000
  const { exit } = useApp();
41794
- const [value, setValue] = useState6("");
41795
- const [cursorPos, setCursorPos] = useState6(0);
41796
- const [history, setHistory] = useState6([]);
41797
- const [historyIndex, setHistoryIndex] = useState6(-1);
41798
- useInput((input, key) => {
42001
+ const [value, setValue] = useState9("");
42002
+ const [cursorPos, setCursorPos] = useState9(0);
42003
+ const [history, setHistory] = useState9([]);
42004
+ const [historyIndex, setHistoryIndex] = useState9(-1);
42005
+ useInput2((input, key) => {
41799
42006
  if (disabled || isRunning) return;
41800
42007
  if (key.return) {
41801
42008
  if (key.shift) {
@@ -41910,22 +42117,22 @@ function InputEditor({ onSubmit, placeholder = "Type a message...", disabled = f
41910
42117
  });
41911
42118
  const renderInput = () => {
41912
42119
  if (disabled || isRunning) {
41913
- return /* @__PURE__ */ jsx9(Box4, { children: /* @__PURE__ */ jsx9(Text4, { color: colors.textMuted, children: isRunning ? "Thinking..." : "Disabled" }) });
42120
+ return /* @__PURE__ */ jsx10(Box5, { children: /* @__PURE__ */ jsx10(Text5, { color: colors.textMuted, children: isRunning ? "Thinking..." : "Disabled" }) });
41914
42121
  }
41915
42122
  if (!value) {
41916
- return /* @__PURE__ */ jsx9(Box4, { children: /* @__PURE__ */ jsx9(Text4, { color: colors.textMuted, children: placeholder }) });
42123
+ return /* @__PURE__ */ jsx10(Box5, { children: /* @__PURE__ */ jsx10(Text5, { color: colors.textMuted, children: placeholder }) });
41917
42124
  }
41918
42125
  const before = value.slice(0, cursorPos);
41919
42126
  const cursor = value[cursorPos] || " ";
41920
42127
  const after = value.slice(cursorPos + 1);
41921
- return /* @__PURE__ */ jsxs3(Box4, { children: [
41922
- /* @__PURE__ */ jsx9(Text4, { children: before }),
41923
- /* @__PURE__ */ jsx9(Text4, { inverse: true, children: cursor }),
41924
- /* @__PURE__ */ jsx9(Text4, { children: after })
42128
+ return /* @__PURE__ */ jsxs4(Box5, { children: [
42129
+ /* @__PURE__ */ jsx10(Text5, { children: before }),
42130
+ /* @__PURE__ */ jsx10(Text5, { inverse: true, children: cursor }),
42131
+ /* @__PURE__ */ jsx10(Text5, { children: after })
41925
42132
  ] });
41926
42133
  };
41927
- return /* @__PURE__ */ jsxs3(Box4, { children: [
41928
- /* @__PURE__ */ jsx9(Text4, { bold: true, color: colors.primary, children: "\u203A " }),
42134
+ return /* @__PURE__ */ jsxs4(Box5, { children: [
42135
+ /* @__PURE__ */ jsx10(Text5, { bold: true, color: colors.primary, children: "\u203A " }),
41929
42136
  renderInput()
41930
42137
  ] });
41931
42138
  }
@@ -41937,56 +42144,91 @@ var init_input_editor = __esm({
41937
42144
  }
41938
42145
  });
41939
42146
 
42147
+ // src/core/tui/components/spinner.tsx
42148
+ import { useEffect as useEffect6, useState as useState10 } from "react";
42149
+ import { Text as Text6 } from "ink";
42150
+ import { jsxs as jsxs5 } from "react/jsx-runtime";
42151
+ function Spinner({ color, suffix = "" }) {
42152
+ const [frame, setFrame] = useState10(0);
42153
+ useEffect6(() => {
42154
+ const id = setInterval(() => {
42155
+ setFrame((f) => (f + 1) % FRAMES.length);
42156
+ }, TICK_MS);
42157
+ return () => clearInterval(id);
42158
+ }, []);
42159
+ return /* @__PURE__ */ jsxs5(Text6, { color, children: [
42160
+ FRAMES[frame],
42161
+ suffix
42162
+ ] });
42163
+ }
42164
+ var FRAMES, TICK_MS;
42165
+ var init_spinner = __esm({
42166
+ "src/core/tui/components/spinner.tsx"() {
42167
+ "use strict";
42168
+ FRAMES = ["\xB7\xB7\xB7\xB7\xB7\xB7\u25A0", "\xB7\xB7\xB7\xB7\xB7\u25A0\xB7", "\xB7\xB7\xB7\xB7\u25A0\xB7\xB7", "\xB7\xB7\xB7\u25A0\xB7\xB7\xB7", "\xB7\xB7\u25A0\xB7\xB7\xB7\xB7", "\xB7\u25A0\xB7\xB7\xB7\xB7\xB7", "\u25A0\xB7\xB7\xB7\xB7\xB7\xB7", "\xB7\u25A0\xB7\xB7\xB7\xB7\xB7", "\xB7\xB7\u25A0\xB7\xB7\xB7\xB7", "\xB7\xB7\xB7\u25A0\xB7\xB7\xB7", "\xB7\xB7\xB7\xB7\u25A0\xB7\xB7", "\xB7\xB7\xB7\xB7\xB7\u25A0\xB7"];
42169
+ TICK_MS = 100;
42170
+ }
42171
+ });
42172
+
41940
42173
  // src/core/tui/components/status-bar.tsx
41941
42174
  import "react";
41942
- import { Box as Box5, Text as Text5 } from "ink";
41943
- import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
42175
+ import { Box as Box6, Text as Text7 } from "ink";
42176
+ import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
41944
42177
  function StatusBar() {
41945
42178
  const { colors } = useTheme();
41946
- const { currentAgent, isRunning } = useAgent();
41947
- const width = process.stdout.columns || 80;
41948
- const cwd = process.cwd().replace(process.env.HOME || "", "~");
41949
- return /* @__PURE__ */ jsxs4(Box5, { justifyContent: "space-between", width, children: [
41950
- /* @__PURE__ */ jsxs4(Box5, { gap: 2, children: [
41951
- /* @__PURE__ */ jsx10(Text5, { color: colors.textMuted, children: cwd }),
41952
- /* @__PURE__ */ jsx10(Text5, { color: colors.textMuted, children: "\u25CF 1 MCP" }),
41953
- /* @__PURE__ */ jsx10(Text5, { color: colors.textMuted, children: "/status" })
41954
- ] }),
41955
- /* @__PURE__ */ jsx10(Text5, { color: colors.textMuted, children: APP_VERSION })
41956
- ] });
42179
+ const { isRunning } = useAgent();
42180
+ return /* @__PURE__ */ jsxs6(
42181
+ Box6,
42182
+ {
42183
+ flexDirection: "row",
42184
+ justifyContent: "space-between",
42185
+ width: "100%",
42186
+ paddingX: 1,
42187
+ children: [
42188
+ /* @__PURE__ */ jsx11(Box6, { children: isRunning ? /* @__PURE__ */ jsx11(Spinner, { color: colors.textMuted, suffix: " esc interrupt" }) : /* @__PURE__ */ jsx11(Text7, { color: colors.textMuted, children: " " }) }),
42189
+ /* @__PURE__ */ jsxs6(Box6, { gap: 2, children: [
42190
+ /* @__PURE__ */ jsx11(Text7, { color: colors.textMuted, children: "tab agents" }),
42191
+ /* @__PURE__ */ jsx11(Text7, { color: colors.textMuted, children: "ctrl+p commands" }),
42192
+ /* @__PURE__ */ jsx11(Text7, { color: colors.textMuted, children: "\xB7" }),
42193
+ /* @__PURE__ */ jsx11(Text7, { color: colors.textMuted, children: APP_VERSION })
42194
+ ] })
42195
+ ]
42196
+ }
42197
+ );
41957
42198
  }
41958
42199
  var init_status_bar = __esm({
41959
42200
  "src/core/tui/components/status-bar.tsx"() {
41960
42201
  "use strict";
41961
42202
  init_theme();
41962
42203
  init_agent2();
42204
+ init_spinner();
41963
42205
  init_version();
41964
42206
  }
41965
42207
  });
41966
42208
 
41967
42209
  // src/core/tui/components/toast.tsx
41968
42210
  import "react";
41969
- import { Box as Box6, Text as Text6 } from "ink";
41970
- import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
42211
+ import { Box as Box7, Text as Text8 } from "ink";
42212
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
41971
42213
  function ToastContainer() {
41972
42214
  const { colors } = useTheme();
41973
42215
  const { toasts } = useToast();
41974
42216
  if (toasts.length === 0) {
41975
42217
  return null;
41976
42218
  }
41977
- return /* @__PURE__ */ jsx11(Box6, { flexDirection: "column", position: "absolute", bottom: 2, right: 2, children: toasts.map((toast) => /* @__PURE__ */ jsxs5(
41978
- Box6,
42219
+ return /* @__PURE__ */ jsx12(Box7, { flexDirection: "column", position: "absolute", bottom: 2, right: 2, children: toasts.map((toast) => /* @__PURE__ */ jsxs7(
42220
+ Box7,
41979
42221
  {
41980
42222
  borderStyle: "round",
41981
42223
  borderColor: colors[variantColors[toast.variant]],
41982
42224
  paddingX: 1,
41983
42225
  marginBottom: 1,
41984
42226
  children: [
41985
- /* @__PURE__ */ jsxs5(Text6, { color: colors[variantColors[toast.variant]], children: [
42227
+ /* @__PURE__ */ jsxs7(Text8, { color: colors[variantColors[toast.variant]], children: [
41986
42228
  variantIcons[toast.variant],
41987
42229
  " "
41988
42230
  ] }),
41989
- /* @__PURE__ */ jsx11(Text6, { children: toast.message })
42231
+ /* @__PURE__ */ jsx12(Text8, { children: toast.message })
41990
42232
  ]
41991
42233
  },
41992
42234
  toast.id
@@ -42014,16 +42256,16 @@ var init_toast2 = __esm({
42014
42256
  });
42015
42257
 
42016
42258
  // src/core/tui/components/model-selector.tsx
42017
- import { useState as useState7 } from "react";
42018
- import { Box as Box7, Text as Text7, useInput as useInput2 } from "ink";
42019
- import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
42259
+ import { useState as useState11 } from "react";
42260
+ import { Box as Box8, Text as Text9, useInput as useInput3 } from "ink";
42261
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
42020
42262
  function ModelSelector() {
42021
42263
  const { colors } = useTheme();
42022
42264
  const { currentModel, setModel } = useAgent();
42023
42265
  const { closeDialog } = useDialog();
42024
42266
  const toast = useToast();
42025
- const [selectedIndex, setSelectedIndex] = useState7(0);
42026
- const [filter3, setFilter] = useState7("");
42267
+ const [selectedIndex, setSelectedIndex] = useState11(0);
42268
+ const [filter3, setFilter] = useState11("");
42027
42269
  const models = models_default.models.map((m) => ({
42028
42270
  id: m.id,
42029
42271
  name: m.name,
@@ -42033,7 +42275,7 @@ function ModelSelector() {
42033
42275
  const filteredModels = models.filter(
42034
42276
  (m) => m.tags.includes("free") && (m.name.toLowerCase().includes(filter3.toLowerCase()) || m.id.toLowerCase().includes(filter3.toLowerCase()))
42035
42277
  );
42036
- useInput2((input, key) => {
42278
+ useInput3((input, key) => {
42037
42279
  if (key.escape) {
42038
42280
  closeDialog();
42039
42281
  return;
@@ -42067,9 +42309,9 @@ function ModelSelector() {
42067
42309
  const renderModel = (model, index) => {
42068
42310
  const isSelected = model.id === currentModel;
42069
42311
  const isHighlighted = index === selectedIndex;
42070
- return /* @__PURE__ */ jsxs6(Box7, { children: [
42071
- /* @__PURE__ */ jsxs6(
42072
- Text7,
42312
+ return /* @__PURE__ */ jsxs8(Box8, { children: [
42313
+ /* @__PURE__ */ jsxs8(
42314
+ Text9,
42073
42315
  {
42074
42316
  bold: isHighlighted,
42075
42317
  color: isSelected ? colors.primary : isHighlighted ? colors.accent : colors.text,
@@ -42079,16 +42321,16 @@ function ModelSelector() {
42079
42321
  ]
42080
42322
  }
42081
42323
  ),
42082
- /* @__PURE__ */ jsxs6(Text7, { color: colors.textMuted, children: [
42324
+ /* @__PURE__ */ jsxs8(Text9, { color: colors.textMuted, children: [
42083
42325
  " (",
42084
42326
  model.provider,
42085
42327
  ")"
42086
42328
  ] }),
42087
- model.tags.includes("free") && /* @__PURE__ */ jsx12(Text7, { color: colors.success, children: " free" })
42329
+ model.tags.includes("free") && /* @__PURE__ */ jsx13(Text9, { color: colors.success, children: " free" })
42088
42330
  ] }, model.id);
42089
42331
  };
42090
- return /* @__PURE__ */ jsxs6(
42091
- Box7,
42332
+ return /* @__PURE__ */ jsxs8(
42333
+ Box8,
42092
42334
  {
42093
42335
  flexDirection: "column",
42094
42336
  borderStyle: "double",
@@ -42098,17 +42340,17 @@ function ModelSelector() {
42098
42340
  top: "50%",
42099
42341
  left: "50%",
42100
42342
  children: [
42101
- /* @__PURE__ */ jsx12(Box7, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text7, { bold: true, color: colors.primary, children: "Select Model" }) }),
42102
- /* @__PURE__ */ jsxs6(Box7, { paddingX: 1, children: [
42103
- /* @__PURE__ */ jsx12(Text7, { color: colors.textMuted, children: "Search: " }),
42104
- /* @__PURE__ */ jsx12(Text7, { children: filter3 }),
42105
- /* @__PURE__ */ jsx12(Text7, { inverse: true, children: " " })
42343
+ /* @__PURE__ */ jsx13(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text9, { bold: true, color: colors.primary, children: "Select Model" }) }),
42344
+ /* @__PURE__ */ jsxs8(Box8, { paddingX: 1, children: [
42345
+ /* @__PURE__ */ jsx13(Text9, { color: colors.textMuted, children: "Search: " }),
42346
+ /* @__PURE__ */ jsx13(Text9, { children: filter3 }),
42347
+ /* @__PURE__ */ jsx13(Text9, { inverse: true, children: " " })
42106
42348
  ] }),
42107
- /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", paddingX: 1, maxHeight: 15, children: [
42108
- /* @__PURE__ */ jsx12(Text7, { color: colors.textMuted, children: "Available Models (free):" }),
42349
+ /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, maxHeight: 15, children: [
42350
+ /* @__PURE__ */ jsx13(Text9, { color: colors.textMuted, children: "Available Models (free):" }),
42109
42351
  filteredModels.map((model, index) => renderModel(model, index))
42110
42352
  ] }),
42111
- /* @__PURE__ */ jsx12(Box7, { paddingX: 1, children: /* @__PURE__ */ jsx12(Text7, { color: colors.textMuted, children: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc close" }) })
42353
+ /* @__PURE__ */ jsx13(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text9, { color: colors.textMuted, children: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc close" }) })
42112
42354
  ]
42113
42355
  }
42114
42356
  );
@@ -42125,13 +42367,13 @@ var init_model_selector = __esm({
42125
42367
  });
42126
42368
 
42127
42369
  // src/core/tui/hooks/use-agent.ts
42128
- import { useCallback as useCallback7, useRef as useRef3 } from "react";
42370
+ import { useCallback as useCallback7, useRef as useRef4 } from "react";
42129
42371
  function useAgent2() {
42130
42372
  const { addMessage, updateMessage, addToolCall, updateToolCall } = useSession();
42131
42373
  const { currentAgent, currentModel, setRunning } = useAgent();
42132
42374
  const toast = useToast();
42133
- const agentRef = useRef3(null);
42134
- const abortRef = useRef3(null);
42375
+ const agentRef = useRef4(null);
42376
+ const abortRef = useRef4(null);
42135
42377
  const sendMessage = useCallback7(async (content) => {
42136
42378
  const userMessage = addMessage({
42137
42379
  role: "user",
@@ -42220,9 +42462,9 @@ var init_use_agent = __esm({
42220
42462
  });
42221
42463
 
42222
42464
  // src/core/tui/app.tsx
42223
- import "react";
42224
- import { Box as Box8, Text as Text8, useInput as useInput3, useApp as useApp2 } from "ink";
42225
- import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
42465
+ import React15 from "react";
42466
+ import { Box as Box9, Text as Text10, useInput as useInput4, useApp as useApp2 } from "ink";
42467
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
42226
42468
  function App() {
42227
42469
  const { colors } = useTheme();
42228
42470
  const { messages } = useSession();
@@ -42230,11 +42472,18 @@ function App() {
42230
42472
  const { isOpen, openDialog, closeDialog, dialog } = useDialog();
42231
42473
  const { sendMessage, cancelCurrent } = useAgent2();
42232
42474
  const { exit } = useApp2();
42233
- useInput3((input, key) => {
42475
+ const { columns } = useTerminalSize();
42476
+ const [sidebarForced, setSidebarForced] = React15.useState(false);
42477
+ const sidebarVisible = sidebarForced || columns >= SIDEBAR_BREAKPOINT;
42478
+ useInput4((input, key) => {
42234
42479
  if (key.ctrl && input === "p") {
42235
42480
  openDialog("model");
42236
42481
  return;
42237
42482
  }
42483
+ if (key.ctrl && input === "b") {
42484
+ setSidebarForced((v) => !v);
42485
+ return;
42486
+ }
42238
42487
  if (key.tab) {
42239
42488
  const agents = ["build", "plan", "debug", "testing", "security"];
42240
42489
  const currentIndex = agents.indexOf(currentAgent.id);
@@ -42250,8 +42499,12 @@ function App() {
42250
42499
  }
42251
42500
  return;
42252
42501
  }
42253
- if (key.escape && isOpen) {
42254
- closeDialog();
42502
+ if (key.escape) {
42503
+ if (isRunning) {
42504
+ cancelCurrent();
42505
+ } else if (isOpen) {
42506
+ closeDialog();
42507
+ }
42255
42508
  return;
42256
42509
  }
42257
42510
  });
@@ -42284,82 +42537,121 @@ function App() {
42284
42537
  await sendMessage(value);
42285
42538
  };
42286
42539
  const hasMessages = messages.length > 0;
42287
- const cwd = process.cwd().replace(process.env.HOME || "", "~");
42288
- return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", width: "100%", height: "100%", children: [
42289
- /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", flexGrow: 1, backgroundColor: colors.background, children: [
42290
- /* @__PURE__ */ jsx13(Box8, { flexDirection: "column", flexGrow: 1, justifyContent: hasMessages ? "flex-start" : "center", children: hasMessages ? /* @__PURE__ */ jsx13(MessageContainer, {}) : (
42291
- /* Welcome screen - centered vertically */
42292
- /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", alignItems: "center", gap: 1, children: [
42293
- /* @__PURE__ */ jsx13(Logo, {}),
42294
- /* @__PURE__ */ jsx13(
42295
- Box8,
42296
- {
42297
- flexDirection: "column",
42298
- width: 60,
42299
- borderStyle: "round",
42300
- borderColor: colors.border,
42301
- paddingX: 2,
42302
- paddingY: 1,
42303
- children: /* @__PURE__ */ jsx13(
42304
- InputEditor,
42305
- {
42306
- onSubmit: handleSubmit,
42307
- placeholder: 'Ask anything... "What is the tech stack of this project?"'
42308
- }
42309
- )
42310
- }
42311
- ),
42312
- /* @__PURE__ */ jsxs7(Box8, { gap: 1, children: [
42313
- /* @__PURE__ */ jsx13(Text8, { bold: true, color: colors.primary, children: currentAgent.name }),
42314
- /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: "\xB7" }),
42315
- /* @__PURE__ */ jsx13(Text8, { color: colors.textSecondary, children: currentModel })
42316
- ] }),
42317
- /* @__PURE__ */ jsxs7(Box8, { gap: 2, children: [
42318
- /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: "tab agents" }),
42319
- /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: "ctrl+p commands" })
42540
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", width: "100%", height: "100%", children: [
42541
+ /* @__PURE__ */ jsx14(HeaderBar, { title: APP_NAME, subtitle: APP_NAME.toLowerCase() }),
42542
+ /* @__PURE__ */ jsxs9(Box9, { flexDirection: "row", flexGrow: 1, width: "100%", children: [
42543
+ /* @__PURE__ */ jsx14(Box9, { flexDirection: "column", flexGrow: 1, backgroundColor: colors.background, children: /* @__PURE__ */ jsx14(
42544
+ Box9,
42545
+ {
42546
+ flexDirection: "column",
42547
+ flexGrow: 1,
42548
+ justifyContent: hasMessages ? "flex-start" : "center",
42549
+ children: hasMessages ? /* @__PURE__ */ jsx14(MessageContainer, {}) : /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", alignItems: "center", gap: 1, children: [
42550
+ /* @__PURE__ */ jsx14(Logo, {}),
42551
+ /* @__PURE__ */ jsx14(
42552
+ Box9,
42553
+ {
42554
+ flexDirection: "column",
42555
+ width: 60,
42556
+ borderStyle: "round",
42557
+ borderColor: colors.border,
42558
+ paddingX: 2,
42559
+ paddingY: 1,
42560
+ children: /* @__PURE__ */ jsx14(
42561
+ InputEditor,
42562
+ {
42563
+ onSubmit: handleSubmit,
42564
+ placeholder: 'Ask anything... "Fix broken tests"'
42565
+ }
42566
+ )
42567
+ }
42568
+ ),
42569
+ /* @__PURE__ */ jsxs9(Box9, { gap: 1, children: [
42570
+ /* @__PURE__ */ jsx14(Text10, { bold: true, color: colors.primary, children: currentAgent.name }),
42571
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "\xB7" }),
42572
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textSecondary, children: currentModel })
42573
+ ] }),
42574
+ /* @__PURE__ */ jsxs9(Box9, { gap: 2, children: [
42575
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "tab agents" }),
42576
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "ctrl+p commands" })
42577
+ ] })
42320
42578
  ] })
42321
- ] })
42579
+ }
42322
42580
  ) }),
42323
- /* @__PURE__ */ jsx13(StatusBar, {})
42324
- ] }),
42325
- /* @__PURE__ */ jsxs7(
42326
- Box8,
42327
- {
42328
- flexDirection: "column",
42329
- width: 35,
42330
- borderStyle: "single",
42331
- borderColor: colors.border,
42332
- paddingLeft: 1,
42333
- children: [
42334
- /* @__PURE__ */ jsx13(Text8, { bold: true, color: colors.textSecondary, children: "New session" }),
42335
- /* @__PURE__ */ jsxs7(Text8, { color: colors.textMuted, children: [
42336
- (/* @__PURE__ */ new Date()).toISOString().split(".")[0],
42337
- "Z"
42338
- ] }),
42339
- /* @__PURE__ */ jsx13(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text8, { bold: true, color: colors.textSecondary, children: "Context" }) }),
42340
- /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: "0 tokens" }),
42341
- /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: "0% used" }),
42342
- /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: "$0.00 spent" }),
42343
- /* @__PURE__ */ jsx13(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text8, { bold: true, color: colors.textSecondary, children: "MCP" }) }),
42344
- /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: "\u25CF railway Connected" }),
42345
- /* @__PURE__ */ jsx13(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text8, { bold: true, color: colors.textSecondary, children: "LSP" }) }),
42346
- /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: "LSPs are disabled" }),
42347
- /* @__PURE__ */ jsx13(Box8, { flexGrow: 1 }),
42348
- /* @__PURE__ */ jsx13(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text8, { color: colors.textMuted, children: cwd }) }),
42349
- /* @__PURE__ */ jsxs7(Box8, { children: [
42350
- /* @__PURE__ */ jsx13(Text8, { color: colors.success, children: "\u25CF" }),
42351
- /* @__PURE__ */ jsxs7(Text8, { color: colors.textMuted, children: [
42352
- " ",
42353
- APP_VERSION
42581
+ sidebarVisible && /* @__PURE__ */ jsxs9(
42582
+ Box9,
42583
+ {
42584
+ flexDirection: "column",
42585
+ width: 35,
42586
+ borderStyle: "single",
42587
+ borderColor: colors.border,
42588
+ paddingLeft: 1,
42589
+ children: [
42590
+ /* @__PURE__ */ jsx14(Text10, { bold: true, color: colors.text, children: "New session" }),
42591
+ /* @__PURE__ */ jsxs9(Text10, { color: colors.textMuted, children: [
42592
+ (/* @__PURE__ */ new Date()).toISOString().split(".")[0],
42593
+ "Z"
42594
+ ] }),
42595
+ /* @__PURE__ */ jsx14(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text10, { bold: true, color: colors.text, children: "Context" }) }),
42596
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "0 tokens" }),
42597
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "0% used" }),
42598
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "$0.00 spent" }),
42599
+ /* @__PURE__ */ jsx14(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text10, { bold: true, color: colors.text, children: "MCP" }) }),
42600
+ /* @__PURE__ */ jsxs9(Box9, { children: [
42601
+ /* @__PURE__ */ jsx14(Text10, { color: colors.success, children: "\u25CF" }),
42602
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textSecondary, children: " railway " }),
42603
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "Connected" })
42604
+ ] }),
42605
+ /* @__PURE__ */ jsx14(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text10, { bold: true, color: colors.text, children: "LSP" }) }),
42606
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "LSPs are disabled" }),
42607
+ /* @__PURE__ */ jsx14(Box9, { flexGrow: 1 }),
42608
+ /* @__PURE__ */ jsx14(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: process.cwd().replace(process.env.HOME || "", "~") }) }),
42609
+ /* @__PURE__ */ jsxs9(Box9, { children: [
42610
+ /* @__PURE__ */ jsxs9(Text10, { bold: true, color: colors.text, children: [
42611
+ "\u25CF ",
42612
+ APP_NAME,
42613
+ " "
42614
+ ] }),
42615
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: APP_VERSION })
42354
42616
  ] })
42355
- ] })
42356
- ]
42357
- }
42358
- ),
42359
- isOpen && dialog.type === "model" && /* @__PURE__ */ jsx13(ModelSelector, {}),
42360
- /* @__PURE__ */ jsx13(ToastContainer, {})
42617
+ ]
42618
+ }
42619
+ ),
42620
+ !sidebarVisible && /* @__PURE__ */ jsxs9(
42621
+ Box9,
42622
+ {
42623
+ flexDirection: "column",
42624
+ width: 28,
42625
+ borderStyle: "single",
42626
+ borderColor: colors.border,
42627
+ paddingLeft: 1,
42628
+ children: [
42629
+ /* @__PURE__ */ jsx14(Text10, { bold: true, color: colors.text, children: "Info" }),
42630
+ /* @__PURE__ */ jsxs9(Box9, { marginTop: 1, children: [
42631
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "agent " }),
42632
+ /* @__PURE__ */ jsx14(Text10, { color: colors.primary, children: currentAgent.name })
42633
+ ] }),
42634
+ /* @__PURE__ */ jsxs9(Text10, { color: colors.textMuted, children: [
42635
+ "model ",
42636
+ currentModel
42637
+ ] }),
42638
+ /* @__PURE__ */ jsxs9(Box9, { marginTop: 1, children: [
42639
+ /* @__PURE__ */ jsx14(Text10, { color: colors.success, children: "\u25CF" }),
42640
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: " mcp connected" })
42641
+ ] }),
42642
+ /* @__PURE__ */ jsx14(Box9, { flexGrow: 1 }),
42643
+ /* @__PURE__ */ jsx14(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: APP_VERSION }) }),
42644
+ /* @__PURE__ */ jsx14(Text10, { color: colors.textMuted, children: "ctrl+b sidebar" })
42645
+ ]
42646
+ }
42647
+ )
42648
+ ] }),
42649
+ /* @__PURE__ */ jsx14(StatusBar, {}),
42650
+ isOpen && dialog.type === "model" && /* @__PURE__ */ jsx14(ModelSelector, {}),
42651
+ /* @__PURE__ */ jsx14(ToastContainer, {})
42361
42652
  ] });
42362
42653
  }
42654
+ var SIDEBAR_BREAKPOINT;
42363
42655
  var init_app = __esm({
42364
42656
  "src/core/tui/app.tsx"() {
42365
42657
  "use strict";
@@ -42368,13 +42660,16 @@ var init_app = __esm({
42368
42660
  init_agent2();
42369
42661
  init_dialog();
42370
42662
  init_logo();
42663
+ init_header_bar();
42371
42664
  init_message_container();
42372
42665
  init_input_editor();
42373
42666
  init_status_bar();
42374
42667
  init_toast2();
42375
42668
  init_model_selector();
42376
42669
  init_use_agent();
42670
+ init_use_terminal_size();
42377
42671
  init_version();
42672
+ SIDEBAR_BREAKPOINT = 90;
42378
42673
  }
42379
42674
  });
42380
42675
 
@@ -42385,7 +42680,7 @@ __export(tui_exports, {
42385
42680
  });
42386
42681
  import "react";
42387
42682
  import { render } from "ink";
42388
- import { jsx as jsx14 } from "react/jsx-runtime";
42683
+ import { jsx as jsx15 } from "react/jsx-runtime";
42389
42684
  var TUILauncher;
42390
42685
  var init_tui = __esm({
42391
42686
  "src/core/tui/index.tsx"() {
@@ -42404,12 +42699,12 @@ var init_tui = __esm({
42404
42699
  async start() {
42405
42700
  process.stdout.write("\x1B[2J\x1B[H");
42406
42701
  const { waitUntilExit } = render(
42407
- /* @__PURE__ */ jsx14(ThemeProvider, { children: /* @__PURE__ */ jsx14(SessionProvider, { children: /* @__PURE__ */ jsx14(
42702
+ /* @__PURE__ */ jsx15(ThemeProvider, { children: /* @__PURE__ */ jsx15(SessionProvider, { children: /* @__PURE__ */ jsx15(
42408
42703
  AgentProvider,
42409
42704
  {
42410
42705
  initialAgent: this.options.agent || "build",
42411
42706
  initialModel: this.options.model,
42412
- children: /* @__PURE__ */ jsx14(DialogProvider, { children: /* @__PURE__ */ jsx14(ToastProvider, { children: /* @__PURE__ */ jsx14(App, {}) }) })
42707
+ children: /* @__PURE__ */ jsx15(DialogProvider, { children: /* @__PURE__ */ jsx15(ToastProvider, { children: /* @__PURE__ */ jsx15(App, {}) }) })
42413
42708
  }
42414
42709
  ) }) }),
42415
42710
  {