erosolar-cli 1.7.161 → 1.7.162

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/security/tool-security-wrapper.js +3 -3
  2. package/dist/security/tool-security-wrapper.js.map +1 -1
  3. package/dist/shell/claudeCodeStreamHandler.d.ts +145 -0
  4. package/dist/shell/claudeCodeStreamHandler.d.ts.map +1 -0
  5. package/dist/shell/claudeCodeStreamHandler.js +312 -0
  6. package/dist/shell/claudeCodeStreamHandler.js.map +1 -0
  7. package/dist/shell/inputQueueManager.d.ts +144 -0
  8. package/dist/shell/inputQueueManager.d.ts.map +1 -0
  9. package/dist/shell/inputQueueManager.js +290 -0
  10. package/dist/shell/inputQueueManager.js.map +1 -0
  11. package/dist/shell/interactiveShell.d.ts +12 -0
  12. package/dist/shell/interactiveShell.d.ts.map +1 -1
  13. package/dist/shell/interactiveShell.js +75 -18
  14. package/dist/shell/interactiveShell.js.map +1 -1
  15. package/dist/shell/streamingOutputManager.d.ts +88 -0
  16. package/dist/shell/streamingOutputManager.d.ts.map +1 -0
  17. package/dist/shell/streamingOutputManager.js +155 -0
  18. package/dist/shell/streamingOutputManager.js.map +1 -0
  19. package/dist/shell/systemPrompt.js +2 -2
  20. package/dist/shell/systemPrompt.js.map +1 -1
  21. package/dist/shell/taskCompletionDetector.d.ts.map +1 -1
  22. package/dist/shell/taskCompletionDetector.js +1 -3
  23. package/dist/shell/taskCompletionDetector.js.map +1 -1
  24. package/dist/tools/editTools.d.ts.map +1 -1
  25. package/dist/tools/editTools.js +32 -8
  26. package/dist/tools/editTools.js.map +1 -1
  27. package/dist/tools/fileTools.d.ts.map +1 -1
  28. package/dist/tools/fileTools.js +2 -126
  29. package/dist/tools/fileTools.js.map +1 -1
  30. package/dist/ui/toolDisplay.d.ts.map +1 -1
  31. package/dist/ui/toolDisplay.js +1 -3
  32. package/dist/ui/toolDisplay.js.map +1 -1
  33. package/dist/ui/toolDisplayAdapter.d.ts.map +1 -1
  34. package/dist/ui/toolDisplayAdapter.js +0 -3
  35. package/dist/ui/toolDisplayAdapter.js.map +1 -1
  36. package/package.json +1 -1
@@ -32,7 +32,7 @@ export class ToolSecurityWrapper {
32
32
  validateToolOperation(toolName, args) {
33
33
  switch (toolName) {
34
34
  case 'read_file':
35
- case 'write_file':
35
+ case 'Edit':
36
36
  case 'list_files':
37
37
  case 'search_files':
38
38
  return this.validateFileOperation(toolName, args);
@@ -52,7 +52,7 @@ export class ToolSecurityWrapper {
52
52
  * Validate file operations
53
53
  */
54
54
  validateFileOperation(toolName, args) {
55
- const path = args['path'];
55
+ const path = (args['path'] || args['file_path']);
56
56
  if (!path) {
57
57
  return {
58
58
  allowed: false,
@@ -60,7 +60,7 @@ export class ToolSecurityWrapper {
60
60
  severity: 'medium',
61
61
  };
62
62
  }
63
- const operation = toolName === 'write_file' ? 'write' : 'read';
63
+ const operation = toolName === 'Edit' ? 'write' : 'read';
64
64
  return activeStackSecurity.validateFileOperation(path, operation);
65
65
  }
66
66
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tool-security-wrapper.js","sourceRoot":"","sources":["../../src/security/tool-security-wrapper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-security-wrapper.js","sourceRoot":"","sources":["../../src/security/tool-security-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,mBAAmB,EAAiC,MAAM,4BAA4B,CAAC;AAEhG,MAAM,OAAO,mBAAmB;IAC9B;QACE,kEAAkE;IACpE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,IAA6B;QAC/D,iDAAiD;QACjD,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,aAAa,CAAC,2BAA2B,UAAU,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC;QACtF,CAAC;QAED,0BAA0B;QAC1B,0EAA0E;QAC1E,+CAA+C;QAC/C,OAAO,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACK,qBAAqB,CAAC,QAAgB,EAAE,IAA6B;QAC3E,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,WAAW,CAAC;YACjB,KAAK,MAAM,CAAC;YACZ,KAAK,YAAY,CAAC;YAClB,KAAK,cAAc;gBACjB,OAAO,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAEpD,KAAK,cAAc,CAAC;YACpB,KAAK,qBAAqB;gBACxB,OAAO,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;YAE7C,KAAK,UAAU,CAAC;YAChB,KAAK,YAAY,CAAC;YAClB,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,wBAAwB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAEvD;gBACE,uDAAuD;gBACvD,OAAO,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,qBAAqB,CAAC,QAAgB,EAAE,IAA6B;QAC3E,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAAW,CAAC;QAC3D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,mBAAmB;gBAC3B,QAAQ,EAAE,QAAQ;aACnB,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACzD,OAAO,mBAAmB,CAAC,qBAAqB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACpE,CAAC;IAED;;OAEG;IACK,wBAAwB,CAAC,IAA6B;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAW,CAAC;QAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,iBAAiB;gBACzB,QAAQ,EAAE,QAAQ;aACnB,CAAC;QACJ,CAAC;QAED,OAAO,mBAAmB,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACK,wBAAwB,CAAC,QAAgB,EAAE,IAA6B;QAC9E,IAAI,MAA0B,CAAC;QAE/B,IAAI,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YACzD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAW,CAAC;QACjC,CAAC;aAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YACpC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAW,CAAC;QACnC,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,sBAAsB;gBAC9B,QAAQ,EAAE,QAAQ;aACnB,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAmC,CAAC;QAC9F,OAAO,mBAAmB,CAAC,wBAAwB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzE,CAAC;IAED;;OAEG;IACK,wBAAwB,CAAC,IAA6B;QAC5D,wCAAwC;QACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrD,MAAM,cAAc,GAAG,mBAAmB,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAChF,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;oBAC5B,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,MAAM,EAAE,kCAAkC,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE;wBAC1E,QAAQ,EAAE,cAAc,CAAC,QAAQ;wBACjC,OAAO,EAAE,cAAc,CAAC,OAAO;qBAChC,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,mBAAmB,CAAC,cAAc,EAAE,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,mBAAmB,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAAC,QAAgB,EAAE,IAA6B;QAC/E,gDAAgD;QAChD,sDAAsD;QACtD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjD,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtB,gBAAgB,CAA2B;IAE3D,YAAY,OAAe,EAAE,gBAA0C;QACrE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,mBAAmB,EAAE,CAAC;AACnC,CAAC"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * ClaudeCodeStreamHandler - Complete streaming I/O handler following Claude Code's approach
3
+ *
4
+ * This module combines StreamingOutputManager and InputQueueManager to provide
5
+ * the complete Claude Code streaming experience:
6
+ *
7
+ * 1. Natural Output Flow
8
+ * - Streaming output just writes to stdout normally
9
+ * - Cursor stays where it is after each write
10
+ * - Lines scroll up naturally as new content appears
11
+ * - NO scroll regions, NO save/restore cursor during streaming
12
+ *
13
+ * 2. Readline Handles Input
14
+ * - Uses Node.js readline module
15
+ * - Input prompt naturally moves up as output streams above it
16
+ * - User can type while streaming - input is queued in memory, not rendered
17
+ *
18
+ * 3. Queue-Based Approach
19
+ * User types during streaming → Input stored in queue → Processed after streaming ends
20
+ *
21
+ * 4. The Key Insight
22
+ * The cursor is NEVER moved during streaming. Output just appends at current position.
23
+ * The "input at bottom" effect comes from:
24
+ * - New output pushes older content (including the prompt) upward
25
+ * - After streaming ends, a new prompt is shown at the bottom
26
+ */
27
+ import * as readline from 'node:readline';
28
+ import { EventEmitter } from 'node:events';
29
+ import { type QueuedInput } from './inputQueueManager.js';
30
+ export interface ClaudeCodeStreamState {
31
+ isStreaming: boolean;
32
+ queuedCount: number;
33
+ charsWritten: number;
34
+ linesWritten: number;
35
+ elapsedMs: number;
36
+ }
37
+ export interface ClaudeCodeStreamEvents {
38
+ 'streaming-start': () => void;
39
+ 'streaming-end': (stats: {
40
+ duration: number;
41
+ chars: number;
42
+ lines: number;
43
+ }) => void;
44
+ 'input-queued': (input: QueuedInput) => void;
45
+ 'queue-processed': (input: QueuedInput) => void;
46
+ }
47
+ /**
48
+ * Coordinates streaming output and queued input for Claude Code style UX.
49
+ */
50
+ export declare class ClaudeCodeStreamHandler extends EventEmitter {
51
+ private readonly outputManager;
52
+ private readonly inputManager;
53
+ private readonly writeStream;
54
+ private readonly readStream;
55
+ private rl;
56
+ private keypressHandler;
57
+ private originalStdoutWrite;
58
+ private isOutputSuppressed;
59
+ constructor(writeStream?: NodeJS.WriteStream, readStream?: NodeJS.ReadStream);
60
+ /**
61
+ * Attach to an existing readline interface
62
+ * Call this after creating your readline.Interface
63
+ */
64
+ attachToReadline(rl: readline.Interface): void;
65
+ /**
66
+ * Set up keypress capturing for queued input during streaming
67
+ */
68
+ private setupKeypressCapture;
69
+ /**
70
+ * Begin streaming mode
71
+ *
72
+ * Claude Code approach:
73
+ * - Start capturing input to queue
74
+ * - Suppress readline echo (characters typed go to queue, not screen)
75
+ * - Output flows naturally to stdout
76
+ */
77
+ startStreaming(): void;
78
+ /**
79
+ * End streaming mode
80
+ *
81
+ * Claude Code approach:
82
+ * - Stop capturing (any remaining buffer is preserved)
83
+ * - Restore readline echo
84
+ * - Return streaming statistics
85
+ */
86
+ endStreaming(): {
87
+ duration: number;
88
+ chars: number;
89
+ lines: number;
90
+ queuedInputs: number;
91
+ };
92
+ /**
93
+ * Write content during streaming
94
+ * Just writes naturally to stdout - no cursor manipulation
95
+ */
96
+ write(content: string): void;
97
+ /**
98
+ * Write a complete line during streaming
99
+ */
100
+ writeLine(line?: string): void;
101
+ /**
102
+ * Check if currently streaming
103
+ */
104
+ isStreaming(): boolean;
105
+ /**
106
+ * Get current state
107
+ */
108
+ getState(): ClaudeCodeStreamState;
109
+ /**
110
+ * Check if there are queued inputs to process
111
+ */
112
+ hasQueuedInput(): boolean;
113
+ /**
114
+ * Get the next queued input
115
+ */
116
+ getNextQueuedInput(): QueuedInput | undefined;
117
+ /**
118
+ * Get all queued inputs
119
+ */
120
+ getAllQueuedInputs(): QueuedInput[];
121
+ /**
122
+ * Clear all queued inputs
123
+ */
124
+ clearQueue(): void;
125
+ /**
126
+ * Get queue summary for display
127
+ */
128
+ getQueueSummary(): string;
129
+ /**
130
+ * Suppress readline's output during streaming
131
+ * Characters typed will be captured but not displayed
132
+ */
133
+ private suppressReadlineOutput;
134
+ /**
135
+ * Restore readline's normal output
136
+ */
137
+ private restoreReadlineOutput;
138
+ /**
139
+ * Cleanup when done
140
+ */
141
+ dispose(): void;
142
+ }
143
+ export declare function getClaudeCodeStreamHandler(): ClaudeCodeStreamHandler;
144
+ export declare function resetClaudeCodeStreamHandler(): void;
145
+ //# sourceMappingURL=claudeCodeStreamHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeCodeStreamHandler.d.ts","sourceRoot":"","sources":["../../src/shell/claudeCodeStreamHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAA2C,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEnG,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,eAAe,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACrF,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACjD;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,YAAY;IACvD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAE/C,OAAO,CAAC,EAAE,CAAmC;IAC7C,OAAO,CAAC,eAAe,CAA2D;IAClF,OAAO,CAAC,mBAAmB,CAA4C;IACvE,OAAO,CAAC,kBAAkB,CAAS;gBAGjC,WAAW,GAAE,MAAM,CAAC,WAA4B,EAChD,UAAU,GAAE,MAAM,CAAC,UAA0B;IAc/C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI;IAK9C;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAwE5B;;;;;;;OAOG;IACH,cAAc,IAAI,IAAI;IAetB;;;;;;;OAOG;IACH,YAAY,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE;IAyBxF;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,SAAS,CAAC,IAAI,GAAE,MAAW,GAAG,IAAI;IAIlC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,QAAQ,IAAI,qBAAqB;IAWjC;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,kBAAkB,IAAI,WAAW,GAAG,SAAS;IAI7C;;OAEG;IACH,kBAAkB,IAAI,WAAW,EAAE;IAInC;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA2C9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,IAAI,IAAI;CAehB;AAOD,wBAAgB,0BAA0B,IAAI,uBAAuB,CAKpE;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAKnD"}
@@ -0,0 +1,312 @@
1
+ /**
2
+ * ClaudeCodeStreamHandler - Complete streaming I/O handler following Claude Code's approach
3
+ *
4
+ * This module combines StreamingOutputManager and InputQueueManager to provide
5
+ * the complete Claude Code streaming experience:
6
+ *
7
+ * 1. Natural Output Flow
8
+ * - Streaming output just writes to stdout normally
9
+ * - Cursor stays where it is after each write
10
+ * - Lines scroll up naturally as new content appears
11
+ * - NO scroll regions, NO save/restore cursor during streaming
12
+ *
13
+ * 2. Readline Handles Input
14
+ * - Uses Node.js readline module
15
+ * - Input prompt naturally moves up as output streams above it
16
+ * - User can type while streaming - input is queued in memory, not rendered
17
+ *
18
+ * 3. Queue-Based Approach
19
+ * User types during streaming → Input stored in queue → Processed after streaming ends
20
+ *
21
+ * 4. The Key Insight
22
+ * The cursor is NEVER moved during streaming. Output just appends at current position.
23
+ * The "input at bottom" effect comes from:
24
+ * - New output pushes older content (including the prompt) upward
25
+ * - After streaming ends, a new prompt is shown at the bottom
26
+ */
27
+ import * as readline from 'node:readline';
28
+ import { EventEmitter } from 'node:events';
29
+ import { getStreamingOutputManager } from './streamingOutputManager.js';
30
+ import { getInputQueueManager } from './inputQueueManager.js';
31
+ /**
32
+ * Coordinates streaming output and queued input for Claude Code style UX.
33
+ */
34
+ export class ClaudeCodeStreamHandler extends EventEmitter {
35
+ outputManager;
36
+ inputManager;
37
+ writeStream;
38
+ readStream;
39
+ rl = null;
40
+ keypressHandler = null;
41
+ originalStdoutWrite = null;
42
+ isOutputSuppressed = false;
43
+ constructor(writeStream = process.stdout, readStream = process.stdin) {
44
+ super();
45
+ this.writeStream = writeStream;
46
+ this.readStream = readStream;
47
+ this.outputManager = getStreamingOutputManager();
48
+ this.inputManager = getInputQueueManager();
49
+ // Forward events
50
+ this.inputManager.on('input-queued', (input) => {
51
+ this.emit('input-queued', input);
52
+ });
53
+ }
54
+ /**
55
+ * Attach to an existing readline interface
56
+ * Call this after creating your readline.Interface
57
+ */
58
+ attachToReadline(rl) {
59
+ this.rl = rl;
60
+ this.setupKeypressCapture();
61
+ }
62
+ /**
63
+ * Set up keypress capturing for queued input during streaming
64
+ */
65
+ setupKeypressCapture() {
66
+ if (!this.readStream || !this.readStream.isTTY) {
67
+ return;
68
+ }
69
+ // Enable keypress events if not already enabled
70
+ if (this.readStream.listenerCount('keypress') === 0 && this.rl) {
71
+ readline.emitKeypressEvents(this.readStream, this.rl);
72
+ }
73
+ // Ensure raw mode for keypress events
74
+ if (this.readStream.setRawMode && !this.readStream.isRaw) {
75
+ this.readStream.setRawMode(true);
76
+ }
77
+ this.keypressHandler = (_str, key) => {
78
+ // Only capture when streaming
79
+ if (!this.outputManager.isStreaming() || !this.inputManager.isCapturing()) {
80
+ return;
81
+ }
82
+ // Handle special keys
83
+ if (key) {
84
+ // Ctrl+C - interrupt
85
+ if (key.ctrl && key.name === 'c') {
86
+ this.inputManager.handleInterrupt();
87
+ return;
88
+ }
89
+ // Enter - submit queued input
90
+ if (key.name === 'return' || key.name === 'enter') {
91
+ this.inputManager.handleSubmit();
92
+ return;
93
+ }
94
+ // Backspace
95
+ if (key.name === 'backspace') {
96
+ this.inputManager.handleBackspace();
97
+ return;
98
+ }
99
+ // Delete
100
+ if (key.name === 'delete') {
101
+ this.inputManager.handleDelete();
102
+ return;
103
+ }
104
+ // Arrow keys
105
+ if (key.name === 'left') {
106
+ this.inputManager.handleCursorLeft();
107
+ return;
108
+ }
109
+ if (key.name === 'right') {
110
+ this.inputManager.handleCursorRight();
111
+ return;
112
+ }
113
+ // Ignore other control sequences during capture
114
+ if (key.ctrl || key.meta) {
115
+ return;
116
+ }
117
+ }
118
+ // Regular character input
119
+ if (_str && _str.length > 0 && !key?.ctrl && !key?.meta) {
120
+ this.inputManager.handleChar(_str);
121
+ }
122
+ };
123
+ this.readStream.prependListener('keypress', this.keypressHandler);
124
+ }
125
+ /**
126
+ * Begin streaming mode
127
+ *
128
+ * Claude Code approach:
129
+ * - Start capturing input to queue
130
+ * - Suppress readline echo (characters typed go to queue, not screen)
131
+ * - Output flows naturally to stdout
132
+ */
133
+ startStreaming() {
134
+ if (this.outputManager.isStreaming()) {
135
+ return;
136
+ }
137
+ // Start both managers
138
+ this.outputManager.startStream();
139
+ this.inputManager.startCapturing();
140
+ // Suppress readline's output so typed characters don't appear
141
+ this.suppressReadlineOutput();
142
+ this.emit('streaming-start');
143
+ }
144
+ /**
145
+ * End streaming mode
146
+ *
147
+ * Claude Code approach:
148
+ * - Stop capturing (any remaining buffer is preserved)
149
+ * - Restore readline echo
150
+ * - Return streaming statistics
151
+ */
152
+ endStreaming() {
153
+ // Get remaining buffer before stopping capture
154
+ const remainingBuffer = this.inputManager.stopCapturing();
155
+ // If there's unsubmitted content in buffer, preserve it for next prompt
156
+ if (remainingBuffer && remainingBuffer.trim()) {
157
+ // The remaining buffer will be shown when readline prompts again
158
+ // We could queue it, but leaving it as-is is more intuitive
159
+ }
160
+ // Restore readline output
161
+ this.restoreReadlineOutput();
162
+ // End output streaming
163
+ const stats = this.outputManager.endStream();
164
+ const result = {
165
+ ...stats,
166
+ queuedInputs: this.inputManager.getQueueLength(),
167
+ };
168
+ this.emit('streaming-end', stats);
169
+ return result;
170
+ }
171
+ /**
172
+ * Write content during streaming
173
+ * Just writes naturally to stdout - no cursor manipulation
174
+ */
175
+ write(content) {
176
+ this.outputManager.writeChunk(content);
177
+ }
178
+ /**
179
+ * Write a complete line during streaming
180
+ */
181
+ writeLine(line = '') {
182
+ this.outputManager.writeLine(line);
183
+ }
184
+ /**
185
+ * Check if currently streaming
186
+ */
187
+ isStreaming() {
188
+ return this.outputManager.isStreaming();
189
+ }
190
+ /**
191
+ * Get current state
192
+ */
193
+ getState() {
194
+ const outputStats = this.outputManager.getStats();
195
+ return {
196
+ isStreaming: this.outputManager.isStreaming(),
197
+ queuedCount: this.inputManager.getQueueLength(),
198
+ charsWritten: outputStats.chars,
199
+ linesWritten: outputStats.lines,
200
+ elapsedMs: outputStats.elapsed,
201
+ };
202
+ }
203
+ /**
204
+ * Check if there are queued inputs to process
205
+ */
206
+ hasQueuedInput() {
207
+ return this.inputManager.hasQueuedInput();
208
+ }
209
+ /**
210
+ * Get the next queued input
211
+ */
212
+ getNextQueuedInput() {
213
+ return this.inputManager.dequeue();
214
+ }
215
+ /**
216
+ * Get all queued inputs
217
+ */
218
+ getAllQueuedInputs() {
219
+ return this.inputManager.getQueue();
220
+ }
221
+ /**
222
+ * Clear all queued inputs
223
+ */
224
+ clearQueue() {
225
+ this.inputManager.clearQueue();
226
+ }
227
+ /**
228
+ * Get queue summary for display
229
+ */
230
+ getQueueSummary() {
231
+ return this.inputManager.getQueueSummary();
232
+ }
233
+ /**
234
+ * Suppress readline's output during streaming
235
+ * Characters typed will be captured but not displayed
236
+ */
237
+ suppressReadlineOutput() {
238
+ if (this.isOutputSuppressed) {
239
+ return;
240
+ }
241
+ // Save original write function
242
+ this.originalStdoutWrite = this.writeStream.write.bind(this.writeStream);
243
+ // Replace with filtered version that suppresses readline echo
244
+ const outputManager = this.outputManager;
245
+ const originalWrite = this.originalStdoutWrite;
246
+ this.writeStream.write = function (chunk, encodingOrCallback, callback) {
247
+ const text = typeof chunk === 'string' ? chunk : chunk.toString();
248
+ // During streaming, only allow output from the streaming manager
249
+ // Suppress readline's echo of typed characters (single character writes)
250
+ if (outputManager.isStreaming()) {
251
+ // Allow newlines and multi-character writes (likely streaming content)
252
+ if (text.length === 1 && !text.includes('\n') && !text.includes('\r')) {
253
+ // Single character during streaming - likely user typing, suppress it
254
+ if (typeof encodingOrCallback === 'function') {
255
+ encodingOrCallback(null);
256
+ return true;
257
+ }
258
+ if (callback) {
259
+ callback(null);
260
+ }
261
+ return true;
262
+ }
263
+ }
264
+ // Pass through everything else
265
+ return originalWrite(chunk, encodingOrCallback, callback);
266
+ };
267
+ this.isOutputSuppressed = true;
268
+ }
269
+ /**
270
+ * Restore readline's normal output
271
+ */
272
+ restoreReadlineOutput() {
273
+ if (!this.isOutputSuppressed || !this.originalStdoutWrite) {
274
+ return;
275
+ }
276
+ this.writeStream.write = this.originalStdoutWrite;
277
+ this.originalStdoutWrite = null;
278
+ this.isOutputSuppressed = false;
279
+ }
280
+ /**
281
+ * Cleanup when done
282
+ */
283
+ dispose() {
284
+ // Restore output if suppressed
285
+ this.restoreReadlineOutput();
286
+ // Remove keypress handler
287
+ if (this.keypressHandler && this.readStream) {
288
+ this.readStream.off('keypress', this.keypressHandler);
289
+ this.keypressHandler = null;
290
+ }
291
+ // Clear queue
292
+ this.inputManager.clearQueue();
293
+ this.rl = null;
294
+ }
295
+ }
296
+ /**
297
+ * Singleton instance for global use
298
+ */
299
+ let globalInstance = null;
300
+ export function getClaudeCodeStreamHandler() {
301
+ if (!globalInstance) {
302
+ globalInstance = new ClaudeCodeStreamHandler();
303
+ }
304
+ return globalInstance;
305
+ }
306
+ export function resetClaudeCodeStreamHandler() {
307
+ if (globalInstance) {
308
+ globalInstance.dispose();
309
+ }
310
+ globalInstance = null;
311
+ }
312
+ //# sourceMappingURL=claudeCodeStreamHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeCodeStreamHandler.js","sourceRoot":"","sources":["../../src/shell/claudeCodeStreamHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * InputQueueManager - Queue-based input handling for Claude Code style streaming
3
+ *
4
+ * Key principles from Claude Code:
5
+ * 1. Readline handles input - Uses Node.js readline module
6
+ * 2. User can type while streaming - Input is queued in memory, not rendered
7
+ * 3. Queue-based approach: User types → stored in queue → processed after streaming ends
8
+ *
9
+ * The key insight is that the cursor is never moved during streaming.
10
+ * Input is captured "invisibly" while streaming, then processed when streaming ends.
11
+ */
12
+ import { EventEmitter } from 'node:events';
13
+ export interface QueuedInput {
14
+ id: string;
15
+ text: string;
16
+ timestamp: number;
17
+ type: 'message' | 'command' | 'interrupt';
18
+ }
19
+ export interface InputQueueState {
20
+ isCapturing: boolean;
21
+ buffer: string;
22
+ cursorPosition: number;
23
+ queue: QueuedInput[];
24
+ }
25
+ export interface InputQueueEvents {
26
+ 'input-queued': (input: QueuedInput) => void;
27
+ 'input-processed': (input: QueuedInput) => void;
28
+ 'queue-cleared': () => void;
29
+ 'capture-start': () => void;
30
+ 'capture-end': () => void;
31
+ }
32
+ /**
33
+ * Manages input queuing during streaming output.
34
+ *
35
+ * When streaming is active:
36
+ * - Captures keystrokes into a buffer
37
+ * - On Enter, queues the input for later processing
38
+ * - Provides methods to process queue after streaming ends
39
+ */
40
+ export declare class InputQueueManager extends EventEmitter {
41
+ private state;
42
+ private inputIdCounter;
43
+ private readonly maxQueueSize;
44
+ private readonly maxBufferLength;
45
+ constructor(options?: {
46
+ maxQueueSize?: number;
47
+ maxBufferLength?: number;
48
+ });
49
+ /**
50
+ * Start capturing input (during streaming)
51
+ * Input will be buffered and queued, not immediately processed
52
+ */
53
+ startCapturing(): void;
54
+ /**
55
+ * Stop capturing input (after streaming ends)
56
+ * Returns any remaining buffer content
57
+ */
58
+ stopCapturing(): string;
59
+ /**
60
+ * Check if currently capturing input
61
+ */
62
+ isCapturing(): boolean;
63
+ /**
64
+ * Handle a character input
65
+ * During capturing, adds to buffer; otherwise ignored
66
+ */
67
+ handleChar(char: string): void;
68
+ /**
69
+ * Handle backspace
70
+ */
71
+ handleBackspace(): void;
72
+ /**
73
+ * Handle delete key
74
+ */
75
+ handleDelete(): void;
76
+ /**
77
+ * Handle cursor left
78
+ */
79
+ handleCursorLeft(): void;
80
+ /**
81
+ * Handle cursor right
82
+ */
83
+ handleCursorRight(): void;
84
+ /**
85
+ * Handle Enter - queue the current buffer
86
+ * Returns the queued input or null if buffer was empty
87
+ */
88
+ handleSubmit(): QueuedInput | null;
89
+ /**
90
+ * Handle Ctrl+C during capture - queue an interrupt
91
+ */
92
+ handleInterrupt(): QueuedInput;
93
+ /**
94
+ * Get current buffer contents (for display purposes)
95
+ */
96
+ getBuffer(): string;
97
+ /**
98
+ * Get current cursor position
99
+ */
100
+ getCursorPosition(): number;
101
+ /**
102
+ * Get the number of queued inputs
103
+ */
104
+ getQueueLength(): number;
105
+ /**
106
+ * Check if there are queued inputs
107
+ */
108
+ hasQueuedInput(): boolean;
109
+ /**
110
+ * Get the next queued input without removing it
111
+ */
112
+ peekQueue(): QueuedInput | undefined;
113
+ /**
114
+ * Get and remove the next queued input
115
+ */
116
+ dequeue(): QueuedInput | undefined;
117
+ /**
118
+ * Get all queued inputs (copy)
119
+ */
120
+ getQueue(): QueuedInput[];
121
+ /**
122
+ * Clear all queued inputs
123
+ */
124
+ clearQueue(): void;
125
+ /**
126
+ * Clear the current buffer
127
+ */
128
+ clearBuffer(): void;
129
+ /**
130
+ * Set the buffer content directly (for paste handling)
131
+ */
132
+ setBuffer(content: string, cursorPos?: number): void;
133
+ /**
134
+ * Get queue summary for display
135
+ */
136
+ getQueueSummary(): string;
137
+ /**
138
+ * Get full state (for debugging)
139
+ */
140
+ getState(): InputQueueState;
141
+ }
142
+ export declare function getInputQueueManager(): InputQueueManager;
143
+ export declare function resetInputQueueManager(): void;
144
+ //# sourceMappingURL=inputQueueManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputQueueManager.d.ts","sourceRoot":"","sources":["../../src/shell/inputQueueManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,OAAO,CAAC,KAAK,CAKX;IAEF,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAO;IAM7E;;;OAGG;IACH,cAAc,IAAI,IAAI;IAYtB;;;OAGG;IACH,aAAa,IAAI,MAAM;IAWvB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAkB9B;;OAEG;IACH,eAAe,IAAI,IAAI;IAWvB;;OAEG;IACH,YAAY,IAAI,IAAI;IAUpB;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAKxB;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAKzB;;;OAGG;IACH,YAAY,IAAI,WAAW,GAAG,IAAI;IAoClC;;OAEG;IACH,eAAe,IAAI,WAAW;IAiB9B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,SAAS,IAAI,WAAW,GAAG,SAAS;IAIpC;;OAEG;IACH,OAAO,IAAI,WAAW,GAAG,SAAS;IAQlC;;OAEG;IACH,QAAQ,IAAI,WAAW,EAAE;IAIzB;;OAEG;IACH,UAAU,IAAI,IAAI;IASlB;;OAEG;IACH,WAAW,IAAI,IAAI;IAKnB;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAKpD;;OAEG;IACH,eAAe,IAAI,MAAM;IAwBzB;;OAEG;IACH,QAAQ,IAAI,eAAe;CAG5B;AAOD,wBAAgB,oBAAoB,IAAI,iBAAiB,CAKxD;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}