@@ -14,20 +14,13 @@ async function main() {
1414 // node-pty is not supported in bun, so we use node.js to run this script
1515}
1616
17- export default async function yesClaude ( { exitOnIdle, claudeArgs = [ ] } : { exitOnIdle ?: boolean | number , claudeArgs ?: string [ ] } = { } ) {
17+ export default async function yesClaude ( { continueOnCrash , exitOnIdle, claudeArgs = [ ] } : { continueOnCrash ?: boolean , exitOnIdle ?: boolean | number , claudeArgs ?: string [ ] } = { } ) {
1818 const defaultTimeout = 5e3 ; // 5 seconds idle timeout
1919 const idleTimeout = typeof exitOnIdle === 'number' ? exitOnIdle : defaultTimeout ;
2020
2121 console . log ( '⭐ Starting claude, automatically responding to yes/no prompts...' ) ;
2222 console . log ( '⚠️ Important Security Warning: Only run this on trusted repositories. This tool automatically responds to prompts and can execute commands without user confirmation. Be aware of potential prompt injection attacks where malicious code or instructions could be embedded in files or user inputs to manipulate the automated responses.' ) ;
2323
24- // if (!process.stdin.isTTY) {
25- // console.error('Error: This script requires a TTY (terminal) input. Please run it in a terminal.');
26- // console.error('If you want to use prompts, try run:')
27- // console.error(' yes-claude "your prompt here"');
28- // return;
29- // }
30-
3124 process . stdin . setRawMode ?.( true ) //must be called any stdout/stdin usage
3225 const prefix = '' // "YESC|"
3326 const PREFIXLENGTH = prefix . length ;
@@ -38,12 +31,11 @@ export default async function yesClaude({ exitOnIdle, claudeArgs = [] }: { exitO
3831 // 2. spawn a 'claude --continue'
3932 // 3. when new process it's ready, re-attach the into new process (in shellStdio, pipe new process stdin/stdout to )
4033 // 4. if it crashes again, exit the process
41- const continueOnCrashFlag = "--continue-on-crash" ;
4234
4335 const shellOutputStream = new TransformStream < string , string > ( )
4436 const outputWriter = shellOutputStream . writable . getWriter ( )
4537
46- const shell = pty . spawn ( 'claude' , claudeArgs , {
38+ let shell = pty . spawn ( 'claude' , claudeArgs , {
4739 cols : process . stdout . columns - PREFIXLENGTH ,
4840 rows : process . stdout . rows ,
4941 cwd : process . cwd ( ) ,
@@ -52,14 +44,28 @@ export default async function yesClaude({ exitOnIdle, claudeArgs = [] }: { exitO
5244 // TODO handle error if claude is not installed, show msg:
5345 // npm install -g @anthropic-ai/claude-code
5446
55- // when claude process exits, exit the main process with the same exit code
56- shell . onExit ( ( { exitCode } ) => {
57- void process . exit ( exitCode )
58- } )
59- shell . onData ( async ( data ) => {
47+ async function onData ( data : string ) {
6048 // append data to the buffer, so we can process it later
6149 await outputWriter . write ( data ) ;
62- } )
50+ }
51+ shell . onData ( onData )
52+ // when claude process exits, exit the main process with the same exit code
53+ shell . onExit ( function onExit ( { exitCode } ) {
54+ if ( continueOnCrash ) {
55+ if ( exitCode !== 0 ) {
56+ console . log ( 'Claude crashed, restarting...' ) ;
57+ shell = pty . spawn ( 'claude' , [ 'continue' , '--continue' ] , {
58+ cols : process . stdout . columns - PREFIXLENGTH ,
59+ rows : process . stdout . rows ,
60+ cwd : process . cwd ( ) ,
61+ env : process . env ,
62+ } ) ;
63+ shell . onData ( onData )
64+ shell . onExit ( onExit ) ;
65+ }
66+ }
67+ void process . exit ( exitCode ) ;
68+ } ) ;
6369
6470 const exitClaudeCode = async ( ) => {
6571 // send exit command to the shell, must sleep a bit to avoid claude treat it as pasted input
@@ -123,7 +129,7 @@ export default async function yesClaude({ exitOnIdle, claudeArgs = [] }: { exitO
123129 )
124130 . replaceAll ( / .* (?: \r \n ? | \r ? \n ) / g, ( line ) => prefix + line ) // add prefix
125131 . forEach ( ( ) => idleWatcher . ping ( ) ) // ping the idle watcher on output for last active time to keep track of claude status
126- // .map(e => !process.stdout.isTTY ? removeControlCharacters(e) : (e)) // remove control characters if output is not a TTY
132+ . map ( e => ! process . stdout . isTTY ? removeControlCharacters ( e ) : ( e ) ) // remove control characters if output is not a TTY
127133 . to ( fromWritable ( process . stdout ) ) ;
128134}
129135
0 commit comments