@@ -40,11 +40,11 @@ let tempMcpConfigPath: string | undefined
40
40
let appConfig : AppConfig | undefined
41
41
let yolo : boolean | undefined
42
42
let confirmationPatternTriggers : string [ ] = [ ]
43
- let pipedInputPath : string | undefined
43
+ let positionalArgContentPath : string | undefined
44
44
45
45
const debugLog = util . debuglog ( 'claude-composer' )
46
46
47
- export { appConfig , pipedInputPath }
47
+ export { appConfig , positionalArgContentPath }
48
48
49
49
async function initializePatterns ( ) : Promise < boolean > {
50
50
let patternsToUse = patterns
@@ -110,9 +110,9 @@ function cleanup() {
110
110
} catch ( e ) { }
111
111
}
112
112
113
- if ( pipedInputPath && fs . existsSync ( pipedInputPath ) ) {
113
+ if ( positionalArgContentPath && fs . existsSync ( positionalArgContentPath ) ) {
114
114
try {
115
- fs . unlinkSync ( pipedInputPath )
115
+ fs . unlinkSync ( positionalArgContentPath )
116
116
} catch ( e ) { }
117
117
}
118
118
@@ -261,6 +261,47 @@ function handleStdinData(data: Buffer): void {
261
261
}
262
262
263
263
export async function main ( ) {
264
+ // Check for piped input and exit immediately
265
+ if ( ! process . stdin . isTTY ) {
266
+ console . error (
267
+ '\x1b[31m╔══════════════════════════════════════════════════════╗\x1b[0m' ,
268
+ )
269
+ console . error (
270
+ '\x1b[31m║ PIPED INPUT NOT SUPPORTED ║\x1b[0m' ,
271
+ )
272
+ console . error (
273
+ '\x1b[31m╠══════════════════════════════════════════════════════╣\x1b[0m' ,
274
+ )
275
+ console . error (
276
+ "\x1b[31m║ Claude Composer doesn't support piped input. ║\x1b[0m" ,
277
+ )
278
+ console . error (
279
+ '\x1b[31m║ ║\x1b[0m' ,
280
+ )
281
+ console . error (
282
+ '\x1b[31m║ Instead, pass your content as a positional argument: ║\x1b[0m' ,
283
+ )
284
+ console . error (
285
+ '\x1b[31m║ ║\x1b[0m' ,
286
+ )
287
+ console . error (
288
+ '\x1b[31m║ claude "your content here" ║\x1b[0m' ,
289
+ )
290
+ console . error (
291
+ '\x1b[31m║ ║\x1b[0m' ,
292
+ )
293
+ console . error (
294
+ '\x1b[31m║ Example: ║\x1b[0m' ,
295
+ )
296
+ console . error (
297
+ '\x1b[31m║ claude "explain this error: ..." ║\x1b[0m' ,
298
+ )
299
+ console . error (
300
+ '\x1b[31m╚══════════════════════════════════════════════════════╝\x1b[0m' ,
301
+ )
302
+ process . exit ( 1 )
303
+ }
304
+
264
305
if ( process . argv [ 2 ] === 'cc-init' ) {
265
306
const { handleCcInit } = await import ( './cli/cc-init.js' )
266
307
await handleCcInit ( process . argv . slice ( 3 ) )
@@ -448,10 +489,13 @@ export async function main() {
448
489
// Save the positional argument to a file
449
490
const tmpDir = os . tmpdir ( )
450
491
const timestamp = new Date ( ) . toISOString ( ) . replace ( / [: .] / g, '-' )
451
- pipedInputPath = path . join ( tmpDir , `claude-composer-piped-${ timestamp } .txt` )
492
+ positionalArgContentPath = path . join (
493
+ tmpDir ,
494
+ `claude-composer-positional-${ timestamp } .txt` ,
495
+ )
452
496
453
497
// Write the first positional argument to the file
454
- fs . writeFileSync ( pipedInputPath , childArgs [ 0 ] )
498
+ fs . writeFileSync ( positionalArgContentPath , childArgs [ 0 ] )
455
499
456
500
// Remove the argument from childArgs
457
501
childArgs . splice ( 0 , 1 )
@@ -476,11 +520,11 @@ export async function main() {
476
520
process . exit ( code )
477
521
} )
478
522
479
- // Add app ready pattern if in plan mode, if there's piped input, or if we saved positional args
523
+ // Add app ready pattern if in plan mode or if we saved positional args
480
524
// IMPORTANT: This must be done AFTER terminal manager is initialized so response queue has targets
481
- if ( appConfig ?. mode === 'plan' || ! process . stdin . isTTY || pipedInputPath ) {
525
+ if ( appConfig ?. mode === 'plan' || positionalArgContentPath ) {
482
526
const appStartedPattern = createAppReadyPattern ( ( ) => ( {
483
- pipedInputPath ,
527
+ positionalArgContentPath ,
484
528
mode : appConfig ?. mode ,
485
529
} ) )
486
530
try {
@@ -491,57 +535,13 @@ export async function main() {
491
535
}
492
536
}
493
537
494
- if ( process . stdin . isTTY ) {
495
- process . stdin . on ( 'data' , handleStdinData )
496
- } else {
497
- const fs = await import ( 'fs' )
498
- const os = await import ( 'os' )
499
- const path = await import ( 'path' )
500
-
501
- const tmpDir = os . tmpdir ( )
502
- const timestamp = new Date ( ) . toISOString ( ) . replace ( / [: .] / g, '-' )
503
- pipedInputPath = path . join ( tmpDir , `claude-composer-piped-${ timestamp } .txt` )
504
- const writeStream = fs . createWriteStream ( pipedInputPath )
505
-
506
- process . stdin . on ( 'data' , chunk => {
507
- writeStream . write ( chunk )
508
- } )
509
-
510
- process . stdin . on ( 'end' , ( ) => {
511
- writeStream . end ( )
512
- } )
513
-
514
- process . stdin . resume ( )
515
-
516
- const tty = await import ( 'tty' )
517
- if ( os . platform ( ) !== 'win32' ) {
518
- try {
519
- const ttyFd = fs . openSync ( '/dev/tty' , 'r' )
520
- const ttyStream = new tty . ReadStream ( ttyFd )
521
-
522
- ttyStream . setRawMode ( true )
523
-
524
- ttyStream . on ( 'data' , handleStdinData )
525
- ; ( global as any ) . __ttyStream = ttyStream
538
+ process . stdin . on ( 'data' , handleStdinData )
526
539
527
- process . stdout . on ( 'resize' , ( ) => {
528
- const newCols = process . stdout . columns || 80
529
- const newRows = process . stdout . rows || 30
530
- terminalManager . resize ( newCols , newRows )
531
- } )
532
- } catch ( error ) {
533
- // Silently fail - don't output to console after child process starts
534
- }
535
- }
536
- }
537
-
538
- if ( process . stdin . isTTY ) {
539
- process . stdout . on ( 'resize' , ( ) => {
540
- const newCols = process . stdout . columns || 80
541
- const newRows = process . stdout . rows || 30
542
- terminalManager . resize ( newCols , newRows )
543
- } )
544
- }
540
+ process . stdout . on ( 'resize' , ( ) => {
541
+ const newCols = process . stdout . columns || 80
542
+ const newRows = process . stdout . rows || 30
543
+ terminalManager . resize ( newCols , newRows )
544
+ } )
545
545
}
546
546
547
547
main ( ) . catch ( error => {
0 commit comments