@@ -575,7 +575,7 @@ function printCliHelp(): void {
575575
576576Usage:
577577 bun run chat Interactive launcher (pick or create).
578- bun run chat --new [--name <alias>] Create a new thread and enter REPL .
578+ bun run chat --new [--name <alias>] Create a new thread; prints its ID .
579579 bun run chat --thread <id|alias> [prompt...] Continue a thread; REPL if no prompt.
580580 bun run chat --list List all threads.
581581 bun run chat --rm <id|alias> Delete a thread mapping.
@@ -686,7 +686,11 @@ async function interactiveStart(provider: string, model: string, thinking: strin
686686 console . log ( " • Type q (or Ctrl-C) to quit." ) ;
687687 console . log ( "" ) ;
688688
689- const rl = createInterface ( { input : process . stdin , output : process . stdout , terminal : true } ) ;
689+ const rl = createInterface ( {
690+ input : process . stdin ,
691+ output : process . stdout ,
692+ terminal : Boolean ( process . stdin . isTTY && process . stdout . isTTY ) ,
693+ } ) ;
690694 const ask = makeAsk ( rl ) ;
691695 try {
692696 while ( true ) {
@@ -1166,7 +1170,11 @@ async function repl(initial: Thread, rt: RuntimeState): Promise<void> {
11661170 console . log ( " " + c . dim ( "─────────────────────────────────────────────────────────────────────" ) ) ;
11671171 console . log ( "" ) ;
11681172
1169- const rl = createInterface ( { input : process . stdin , output : process . stdout , terminal : true } ) ;
1173+ const rl = createInterface ( {
1174+ input : process . stdin ,
1175+ output : process . stdout ,
1176+ terminal : Boolean ( process . stdin . isTTY && process . stdout . isTTY ) ,
1177+ } ) ;
11701178 // EOF-safe question wrapper: resolves null on Ctrl-D / closed stdin so the
11711179 // REPL exits cleanly instead of hanging on an unanswerable question.
11721180 const ask = makeAsk ( rl ) ;
@@ -1641,7 +1649,11 @@ type RuntimeCfg = { provider: string; model: string; thinking: string | undefine
16411649 * throwing, so callers can treat it as "user backed out".
16421650 */
16431651async function promptLine ( question : string ) : Promise < string > {
1644- const rl = createInterface ( { input : process . stdin , output : process . stdout , terminal : true } ) ;
1652+ const rl = createInterface ( {
1653+ input : process . stdin ,
1654+ output : process . stdout ,
1655+ terminal : Boolean ( process . stdin . isTTY && process . stdout . isTTY ) ,
1656+ } ) ;
16451657 try {
16461658 // makeAsk resolves null on EOF (Ctrl-D / closed stdin); map that to ""
16471659 // so callers can treat it as "user backed out".
@@ -1883,19 +1895,6 @@ async function main(): Promise<void> {
18831895 }
18841896 }
18851897
1886- // ── Locate pi binary; guide the user if it's missing ────────────────────
1887- let piBin : string ;
1888- try {
1889- piBin = locatePiBin ( ) ;
1890- } catch ( err ) {
1891- // Extract the candidate list out of the throw message for the guide.
1892- const msg = ( err as Error ) . message ;
1893- const m = msg . match ( / n o t f o u n d i n a n y o f : ( [ ^ \n ] + ) / ) ;
1894- const candidates = m ? m [ 1 ] . split ( ", " ) : [ ] ;
1895- guidePiNotInstalled ( candidates ) ;
1896- return ;
1897- }
1898-
18991898 // ── Resolve / create the active thread ──────────────────────────────────
19001899 let activeThread : Thread | null = null ;
19011900 if ( args . newThread ) {
@@ -1924,6 +1923,20 @@ async function main(): Promise<void> {
19241923 }
19251924 }
19261925
1926+ // ── Locate pi binary; guide the user if it's missing ────────────────────
1927+ // Allocation-only --new returns above and does not need runtime dependencies.
1928+ let piBin : string ;
1929+ try {
1930+ piBin = locatePiBin ( ) ;
1931+ } catch ( err ) {
1932+ // Extract the candidate list out of the throw message for the guide.
1933+ const msg = ( err as Error ) . message ;
1934+ const m = msg . match ( / n o t f o u n d i n a n y o f : ( [ ^ \n ] + ) / ) ;
1935+ const candidates = m ? m [ 1 ] . split ( ", " ) : [ ] ;
1936+ guidePiNotInstalled ( candidates ) ;
1937+ return ;
1938+ }
1939+
19271940 // Auto-retry default: on for local providers (flaky/slow), off for cloud
19281941 // (failures are usually configuration errors, not transient).
19291942 const rt : RuntimeState = {
@@ -1947,6 +1960,7 @@ async function main(): Promise<void> {
19471960 console . log ( renderMarkdown ( reply || "(no text reply produced)" ) ) ;
19481961 } catch ( err ) {
19491962 say . error ( "Turn failed" , ( err as Error ) . message ) ;
1963+ process . exitCode = 1 ;
19501964 }
19511965 return ;
19521966 }
0 commit comments