@@ -4,10 +4,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
44 * Real-time streaming, thinking animation, tool progress, slash commands.
55 */
66import { useState , useEffect , useCallback } from 'react' ;
7- import { render , Box , Text , useApp , useInput } from 'ink' ;
7+ import { render , Box , Text , useApp , useInput , useStdout } from 'ink' ;
88import Spinner from 'ink-spinner' ;
99import TextInput from 'ink-text-input' ;
1010import { resolveModel } from './model-picker.js' ;
11+ // ─── Full-width input box ──────────────────────────────────────────────────
12+ function InputBox ( { input, setInput, onSubmit, model, balance } ) {
13+ const { stdout } = useStdout ( ) ;
14+ const cols = stdout ?. columns ?? 80 ;
15+ const innerWidth = Math . max ( 40 , cols - 4 ) ; // 4 = borders + padding
16+ return ( _jsxs ( Box , { flexDirection : "column" , marginTop : 1 , children : [ _jsx ( Text , { dimColor : true , children : '╭' + '─' . repeat ( cols - 2 ) + '╮' } ) , _jsxs ( Box , { children : [ _jsx ( Text , { dimColor : true , children : "\u2502 " } ) , _jsx ( Box , { width : innerWidth , children : _jsx ( TextInput , { value : input , onChange : setInput , onSubmit : onSubmit , placeholder : "Ask anything... (/model to switch, /help for commands)" } ) } ) , _jsxs ( Text , { dimColor : true , children : [ ' ' . repeat ( Math . max ( 0 , cols - innerWidth - 4 ) ) , "\u2502" ] } ) ] } ) , _jsx ( Text , { dimColor : true , children : '╰' + '─' . repeat ( cols - 2 ) + '╯' } ) , _jsx ( Box , { marginLeft : 1 , children : _jsxs ( Text , { dimColor : true , children : [ model , " \u00B7 " , balance , " \u00B7 esc to quit" ] } ) } ) ] } ) ) ;
17+ }
1118// ─── Model picker data ─────────────────────────────────────────────────────
1219const PICKER_MODELS = [
1320 { id : 'anthropic/claude-sonnet-4.6' , shortcut : 'sonnet' , label : 'Claude Sonnet 4.6' , price : '$3/$15' } ,
@@ -195,7 +202,7 @@ function RunCodeApp({ initialModel, workDir, walletAddress, walletBalance, chain
195202 // ── Normal Mode ──
196203 return ( _jsxs ( Box , { flexDirection : "column" , children : [ statusMsg && ( _jsx ( Box , { marginLeft : 2 , children : _jsx ( Text , { color : "green" , children : statusMsg } ) } ) ) , showHelp && ( _jsxs ( Box , { flexDirection : "column" , marginLeft : 2 , marginTop : 1 , marginBottom : 1 , children : [ _jsx ( Text , { bold : true , children : "Commands" } ) , _jsx ( Text , { children : " " } ) , _jsxs ( Text , { children : [ " " , _jsx ( Text , { color : "cyan" , children : "/model" } ) , " [name] Switch model (picker if no name)" ] } ) , _jsxs ( Text , { children : [ " " , _jsx ( Text , { color : "cyan" , children : "/wallet" } ) , " Show wallet address & balance" ] } ) , _jsxs ( Text , { children : [ " " , _jsx ( Text , { color : "cyan" , children : "/cost" } ) , " Session cost" ] } ) , _jsxs ( Text , { children : [ " " , _jsx ( Text , { color : "cyan" , children : "/help" } ) , " This help" ] } ) , _jsxs ( Text , { children : [ " " , _jsx ( Text , { color : "cyan" , children : "/exit" } ) , " Quit" ] } ) , _jsx ( Text , { children : " " } ) , _jsx ( Text , { dimColor : true , children : " Shortcuts: sonnet, opus, gpt, gemini, deepseek, flash, free, r1, o4, nano, mini, haiku" } ) ] } ) ) , showWallet && ( _jsxs ( Box , { flexDirection : "column" , marginLeft : 2 , marginTop : 1 , marginBottom : 1 , children : [ _jsx ( Text , { bold : true , children : "Wallet" } ) , _jsx ( Text , { children : " " } ) , _jsxs ( Text , { children : [ " Chain: " , _jsx ( Text , { color : "magenta" , children : chain } ) ] } ) , _jsxs ( Text , { children : [ " Address: " , _jsx ( Text , { color : "cyan" , children : walletAddress } ) ] } ) , _jsxs ( Text , { children : [ " Balance: " , _jsx ( Text , { color : "green" , children : walletBalance } ) ] } ) ] } ) ) , Array . from ( tools . values ( ) ) . map ( ( tool , i ) => ( _jsx ( Box , { marginLeft : 1 , children : tool . done ? ( tool . error
197204 ? _jsxs ( Text , { color : "red" , children : [ " \u2717 " , tool . name , " " , _jsxs ( Text , { dimColor : true , children : [ tool . elapsed , "ms" ] } ) ] } )
198- : _jsxs ( Text , { color : "green" , children : [ " \u2713 " , tool . name , " " , _jsxs ( Text , { dimColor : true , children : [ tool . elapsed , "ms \u2014 " , tool . preview . slice ( 0 , 60 ) , tool . preview . length > 60 ? '...' : '' ] } ) ] } ) ) : ( _jsxs ( Text , { color : "cyan" , children : [ " " , _jsx ( Spinner , { type : "dots" } ) , " " , tool . name , "..." ] } ) ) } , i ) ) ) , thinking && ( _jsx ( Box , { marginLeft : 1 , children : _jsxs ( Text , { color : "magenta" , children : [ " " , _jsx ( Spinner , { type : "dots" } ) , " thinking..." ] } ) } ) ) , waiting && ! thinking && tools . size === 0 && ( _jsx ( Box , { marginLeft : 1 , children : _jsxs ( Text , { color : "yellow" , children : [ " " , _jsx ( Spinner , { type : "dots" } ) , " " , _jsx ( Text , { dimColor : true , children : currentModel } ) ] } ) } ) ) , streamText && ( _jsx ( Box , { marginTop : 0 , marginBottom : 0 , children : _jsx ( Text , { children : streamText } ) } ) ) , ready && ( turnTokens . input > 0 || turnTokens . output > 0 ) && streamText && ( _jsx ( Box , { marginLeft : 1 , marginTop : 0 , children : _jsxs ( Text , { dimColor : true , children : [ turnTokens . input . toLocaleString ( ) , " in / " , turnTokens . output . toLocaleString ( ) , " out" ] } ) } ) ) , ready && ( _jsxs ( Box , { flexDirection : "column" , marginTop : streamText ? 1 : 0 , children : [ _jsxs ( Box , { children : [ _jsx ( Text , { dimColor : true , children : "\u256D\u2500" } ) , _jsx ( Text , { dimColor : true , children : '─' . repeat ( 58 ) } ) , _jsx ( Text , { dimColor : true , children : "\u256E" } ) ] } ) , _jsxs ( Box , { children : [ _jsx ( Text , { dimColor : true , children : "\u2502 " } ) , _jsx ( Box , { width : 58 , children : input ? ( _jsx ( TextInput , { value : input , onChange : setInput , onSubmit : handleSubmit } ) ) : ( _jsx ( TextInput , { value : input , onChange : setInput , onSubmit : handleSubmit , placeholder : "Ask anything... (/model to switch, /help for commands)" } ) ) } ) , _jsx ( Text , { dimColor : true , children : " \u2502" } ) ] } ) , _jsxs ( Box , { children : [ _jsx ( Text , { dimColor : true , children : "\u2570\u2500" } ) , _jsx ( Text , { dimColor : true , children : '─' . repeat ( 58 ) } ) , _jsx ( Text , { dimColor : true , children : "\u256F" } ) ] } ) , _jsxs ( Box , { marginLeft : 2 , children : [ _jsx ( Text , { dimColor : true , children : currentModel } ) , _jsx ( Text , { dimColor : true , children : " \u00B7 " } ) , _jsx ( Text , { dimColor : true , children : walletBalance } ) , _jsx ( Text , { dimColor : true , children : " \u00B7 " } ) , _jsx ( Text , { dimColor : true , children : "esc to quit" } ) ] } ) ] } ) ) ] } ) ) ;
205+ : _jsxs ( Text , { color : "green" , children : [ " \u2713 " , tool . name , " " , _jsxs ( Text , { dimColor : true , children : [ tool . elapsed , "ms \u2014 " , tool . preview . slice ( 0 , 60 ) , tool . preview . length > 60 ? '...' : '' ] } ) ] } ) ) : ( _jsxs ( Text , { color : "cyan" , children : [ " " , _jsx ( Spinner , { type : "dots" } ) , " " , tool . name , "..." ] } ) ) } , i ) ) ) , thinking && ( _jsx ( Box , { marginLeft : 1 , children : _jsxs ( Text , { color : "magenta" , children : [ " " , _jsx ( Spinner , { type : "dots" } ) , " thinking..." ] } ) } ) ) , waiting && ! thinking && tools . size === 0 && ( _jsx ( Box , { marginLeft : 1 , children : _jsxs ( Text , { color : "yellow" , children : [ " " , _jsx ( Spinner , { type : "dots" } ) , " " , _jsx ( Text , { dimColor : true , children : currentModel } ) ] } ) } ) ) , streamText && ( _jsx ( Box , { marginTop : 0 , marginBottom : 0 , children : _jsx ( Text , { children : streamText } ) } ) ) , ready && ( turnTokens . input > 0 || turnTokens . output > 0 ) && streamText && ( _jsx ( Box , { marginLeft : 1 , marginTop : 0 , children : _jsxs ( Text , { dimColor : true , children : [ turnTokens . input . toLocaleString ( ) , " in / " , turnTokens . output . toLocaleString ( ) , " out" ] } ) } ) ) , ready && ( _jsx ( InputBox , { input : input , setInput : setInput , onSubmit : handleSubmit , model : currentModel , balance : walletBalance } ) ) ] } ) ) ;
199206}
200207export function launchInkUI ( opts ) {
201208 let resolveInput = null ;
0 commit comments