@@ -11,10 +11,19 @@ import {
1111
1212const originalStderrWrite = process . stderr . write ;
1313const originalAgentDir = process . env [ ENV_AGENT_DIR ] ;
14+ const consoleLevels = [ "error" , "info" , "warn" ] as const ;
15+ const originalConsoleMethods = {
16+ error : console . error ,
17+ info : console . info ,
18+ warn : console . warn ,
19+ } ;
1420const githubFineGrainedPat = "github_pat_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" ;
1521
1622const tempDirs : string [ ] = [ ] ;
1723
24+ type ConsoleLevel = keyof typeof originalConsoleMethods ;
25+ type ConsoleMethod = ( ...data : unknown [ ] ) => void ;
26+
1827function replaceStderrWrite ( write : typeof process . stderr . write ) : void {
1928 Object . defineProperty ( process . stderr , "write" , {
2029 configurable : true ,
@@ -39,10 +48,21 @@ function createCapturingStderrWrite(capture: (text: string) => void): typeof pro
3948 } ) satisfies typeof process . stderr . write ;
4049}
4150
51+ function replaceConsoleMethod ( level : ConsoleLevel , method : ConsoleMethod ) : void {
52+ Object . defineProperty ( console , level , {
53+ configurable : true ,
54+ value : method ,
55+ writable : true ,
56+ } ) ;
57+ }
58+
4259afterEach ( ( ) => {
4360 restoreInteractiveStderr ( ) ;
4461 restoreStderr ( ) ;
4562 replaceStderrWrite ( originalStderrWrite ) ;
63+ for ( const level of consoleLevels ) {
64+ replaceConsoleMethod ( level , originalConsoleMethods [ level ] ) ;
65+ }
4666 if ( originalAgentDir === undefined ) {
4767 delete process . env [ ENV_AGENT_DIR ] ;
4868 } else {
@@ -146,4 +166,34 @@ describe("interactive stderr guard", () => {
146166 expect ( log ) . not . toContain ( githubFineGrainedPat ) ;
147167 expect ( ( statSync ( debugLogPath ) . mode & 0o777 ) . toString ( 8 ) ) . toBe ( "600" ) ;
148168 } ) ;
169+
170+ it ( "hides Bun-style console diagnostics while the TUI owns the terminal and restores them afterwards" , ( ) => {
171+ const agentDir = mkdtempSync ( join ( tmpdir ( ) , "pi-hidden-console-" ) ) ;
172+ tempDirs . push ( agentDir ) ;
173+ process . env [ ENV_AGENT_DIR ] = agentDir ;
174+ let terminalText = "" ;
175+ const bunConsoleWrite = ( ...data : unknown [ ] ) => {
176+ terminalText += `${ data . map ( String ) . join ( " " ) } \n` ;
177+ } ;
178+ for ( const level of consoleLevels ) {
179+ replaceConsoleMethod ( level , bunConsoleWrite ) ;
180+ }
181+
182+ takeOverInteractiveStderr ( ) ;
183+ console . info ( "omo-senpi start-work-continuation skipped SECRET_TOKEN=console-secret" ) ;
184+ console . warn ( "omo-senpi ulw-loop status ignored" , { reason : "non-zero-exit" } ) ;
185+ console . error ( "omo-senpi component registration failed" ) ;
186+
187+ expect ( terminalText ) . toBe ( "" ) ;
188+ restoreInteractiveStderr ( ) ;
189+ console . info ( "visible after restore" ) ;
190+ expect ( terminalText ) . toBe ( "visible after restore\n" ) ;
191+
192+ const log = readFileSync ( getDebugLogPath ( ) , "utf8" ) ;
193+ expect ( log ) . toContain ( "start-work-continuation skipped" ) ;
194+ expect ( log ) . toContain ( "ulw-loop status ignored" ) ;
195+ expect ( log ) . toContain ( "component registration failed" ) ;
196+ expect ( log ) . toContain ( "SECRET_TOKEN=[REDACTED]" ) ;
197+ expect ( log ) . not . toContain ( "console-secret" ) ;
198+ } ) ;
149199} ) ;
0 commit comments