aiexecode 1.0.66 → 1.0.68

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.

Potentially problematic release.


This version of aiexecode might be problematic. Click here for more details.

Files changed (86) hide show
  1. package/config_template/settings.json +1 -3
  2. package/index.js +46 -71
  3. package/package.json +1 -12
  4. package/payload_viewer/out/404/index.html +1 -1
  5. package/payload_viewer/out/404.html +1 -1
  6. package/payload_viewer/out/index.html +1 -1
  7. package/payload_viewer/out/index.txt +1 -1
  8. package/payload_viewer/web_server.js +0 -163
  9. package/src/ai_based/completion_judge.js +96 -5
  10. package/src/ai_based/orchestrator.js +71 -3
  11. package/src/ai_based/pip_package_installer.js +14 -12
  12. package/src/ai_based/pip_package_lookup.js +13 -10
  13. package/src/commands/apikey.js +8 -34
  14. package/src/commands/help.js +3 -4
  15. package/src/commands/model.js +17 -74
  16. package/src/commands/reasoning_effort.js +1 -1
  17. package/src/config/feature_flags.js +0 -12
  18. package/src/{ui → frontend}/App.js +23 -25
  19. package/src/frontend/README.md +81 -0
  20. package/src/{ui/components/SuggestionsDisplay.js → frontend/components/AutocompleteMenu.js} +3 -3
  21. package/src/{ui/components/HistoryItemDisplay.js → frontend/components/ConversationItem.js} +37 -89
  22. package/src/{ui → frontend}/components/CurrentModelView.js +3 -5
  23. package/src/{ui → frontend}/components/Footer.js +4 -6
  24. package/src/{ui → frontend}/components/Header.js +2 -5
  25. package/src/{ui/components/InputPrompt.js → frontend/components/Input.js} +16 -54
  26. package/src/frontend/components/ModelListView.js +106 -0
  27. package/src/{ui → frontend}/components/ModelUpdatedView.js +3 -5
  28. package/src/{ui → frontend}/components/SessionSpinner.js +3 -3
  29. package/src/{ui → frontend}/components/SetupWizard.js +8 -101
  30. package/src/{ui → frontend}/components/ToolApprovalPrompt.js +16 -14
  31. package/src/frontend/design/themeColors.js +42 -0
  32. package/src/{ui → frontend}/index.js +7 -7
  33. package/src/frontend/utils/inputBuffer.js +441 -0
  34. package/src/{ui/utils/markdownRenderer.js → frontend/utils/markdownParser.js} +3 -3
  35. package/src/{ui/utils/ConsolePatcher.js → frontend/utils/outputRedirector.js} +9 -9
  36. package/src/{ui/utils/codeColorizer.js → frontend/utils/syntaxHighlighter.js} +2 -3
  37. package/src/system/ai_request.js +145 -595
  38. package/src/system/code_executer.js +111 -16
  39. package/src/system/file_integrity.js +5 -7
  40. package/src/system/log.js +3 -3
  41. package/src/system/mcp_integration.js +15 -13
  42. package/src/system/output_helper.js +0 -20
  43. package/src/system/session.js +97 -23
  44. package/src/system/session_memory.js +2 -82
  45. package/src/system/system_info.js +1 -1
  46. package/src/system/ui_events.js +0 -43
  47. package/src/tools/code_editor.js +17 -2
  48. package/src/tools/file_reader.js +17 -2
  49. package/src/tools/glob.js +9 -1
  50. package/src/tools/response_message.js +0 -2
  51. package/src/tools/ripgrep.js +9 -1
  52. package/src/tools/web_downloader.js +9 -1
  53. package/src/util/config.js +3 -8
  54. package/src/util/debug_log.js +4 -11
  55. package/src/util/mcp_config_manager.js +3 -5
  56. package/src/util/output_formatter.js +0 -47
  57. package/src/util/prompt_loader.js +3 -4
  58. package/src/util/safe_fs.js +60 -0
  59. package/src/util/setup_wizard.js +1 -3
  60. package/src/util/text_formatter.js +0 -86
  61. package/src/config/claude_models.js +0 -195
  62. package/src/ui/README.md +0 -208
  63. package/src/ui/api.js +0 -167
  64. package/src/ui/components/AgenticProgressDisplay.js +0 -126
  65. package/src/ui/components/Composer.js +0 -55
  66. package/src/ui/components/LoadingIndicator.js +0 -54
  67. package/src/ui/components/ModelListView.js +0 -214
  68. package/src/ui/components/Notifications.js +0 -55
  69. package/src/ui/components/StreamingIndicator.js +0 -36
  70. package/src/ui/contexts/AppContext.js +0 -25
  71. package/src/ui/contexts/StreamingContext.js +0 -20
  72. package/src/ui/contexts/UIStateContext.js +0 -117
  73. package/src/ui/example-usage.js +0 -180
  74. package/src/ui/hooks/useTerminalResize.js +0 -39
  75. package/src/ui/themes/semantic-tokens.js +0 -73
  76. package/src/ui/utils/text-buffer.js +0 -975
  77. /package/payload_viewer/out/_next/static/{t0WTsjXST7ISD1Boa6ifx → Z3AZSKhutj-kS4L8VpcOl}/_buildManifest.js +0 -0
  78. /package/payload_viewer/out/_next/static/{t0WTsjXST7ISD1Boa6ifx → Z3AZSKhutj-kS4L8VpcOl}/_clientMiddlewareManifest.json +0 -0
  79. /package/payload_viewer/out/_next/static/{t0WTsjXST7ISD1Boa6ifx → Z3AZSKhutj-kS4L8VpcOl}/_ssgManifest.js +0 -0
  80. /package/src/{ui → frontend}/components/BlankLine.js +0 -0
  81. /package/src/{ui → frontend}/components/FileDiffViewer.js +0 -0
  82. /package/src/{ui → frontend}/components/HelpView.js +0 -0
  83. /package/src/{ui → frontend}/hooks/useCompletion.js +0 -0
  84. /package/src/{ui → frontend}/hooks/useKeypress.js +0 -0
  85. /package/src/{ui → frontend}/utils/diffUtils.js +0 -0
  86. /package/src/{ui → frontend}/utils/renderInkComponent.js +0 -0
package/src/ui/README.md DELETED
@@ -1,208 +0,0 @@
1
- # UI System Documentation
2
-
3
- 이 디렉토리는 Ink 기반의 터미널 UI 시스템을 포함합니다.
4
-
5
- ## 구조
6
-
7
- ```
8
- ui/
9
- ├── App.js # 메인 앱 진입점 (Context 제공)
10
- ├── index.js # UI 렌더링 진입점
11
- ├── api.js # UI 상태 업데이트 API
12
- ├── example-usage.js # API 사용 예제
13
- ├── contexts/ # React Context 시스템
14
- │ ├── AppContext.js # 전역 앱 상태
15
- │ ├── UIStateContext.js # UI 상태 관리
16
- │ └── StreamingContext.js # 스트리밍 상태
17
- ├── components/ # UI 컴포넌트
18
- │ ├── Header.js # 헤더 (로고)
19
- │ ├── Footer.js # 푸터 (상태 정보)
20
- │ ├── HistoryItemDisplay.js # 개별 히스토리 아이템
21
- │ ├── InputPrompt.js # 입력 프롬프트
22
- │ ├── Composer.js # 입력 영역 + 로딩 표시
23
- │ ├── Notifications.js # 알림/경고 표시
24
- │ ├── LoadingIndicator.js # 로딩 인디케이터
25
- │ ├── StreamingIndicator.js # 스트리밍 애니메이션
26
- │ ├── AgenticProgressDisplay.js # 에이전틱 작업 진행 표시
27
- │ └── SuggestionsDisplay.js # 자동완성 제안
28
- ├── hooks/ # Custom hooks
29
- │ ├── useKeypress.js # 키보드 이벤트
30
- │ └── useCompletion.js # 자동완성
31
- ├── themes/ # 테마 시스템
32
- │ └── semantic-tokens.js # 색상 토큰
33
- └── utils/ # 유틸리티
34
- └── text-buffer.js # 텍스트 버퍼 (멀티라인)
35
- ```
36
-
37
- ## 아키텍처
38
-
39
- ### Context 시스템
40
-
41
- **AppContext**: 전역 애플리케이션 상태
42
- - version, model, buffer, commands, callbacks
43
-
44
- **UIStateContext**: UI 상태 관리
45
- - history, pendingHistoryItems
46
- - streamingState, operations
47
- - layout dimensions (mainAreaWidth, terminalHeight)
48
-
49
- **StreamingContext**: 실시간 스트리밍 상태 전달
50
-
51
- ### 레이아웃 구조
52
-
53
- ```
54
- ┌──────────────────────────────────┐
55
- │ App (Main Layout) │
56
- │ ├─ Header (Static) │
57
- │ ├─ History (Static) │
58
- │ ├─ Pending Items (Dynamic) │
59
- │ ├─ Notifications │
60
- │ ├─ Composer │
61
- │ │ ├─ LoadingIndicator │
62
- │ │ ├─ AgenticProgressDisplay │
63
- │ │ └─ InputPrompt │
64
- │ └─ Footer │
65
- └──────────────────────────────────┘
66
- ```
67
-
68
- ### StreamingState
69
-
70
- ```javascript
71
- StreamingState = {
72
- Idle: 'idle', // 대기 중
73
- Responding: 'responding', // AI 응답 중
74
- WaitingForConfirmation: 'waiting_for_confirmation',
75
- Executing: 'executing', // 작업 실행 중
76
- Completed: 'completed', // 완료
77
- Error: 'error' // 에러
78
- }
79
- ```
80
-
81
- ## UI API 사용법
82
-
83
- ### 기본 사용
84
-
85
- ```javascript
86
- import {
87
- StreamingState,
88
- setStreamingState,
89
- setThought,
90
- addHistoryMessage
91
- } from './ui/api.js';
92
-
93
- // AI가 생각 중일 때
94
- setStreamingState(StreamingState.Responding);
95
- setThought('코드 구조를 분석하고 있습니다...');
96
-
97
- // 완료 후 메시지 추가
98
- setStreamingState(StreamingState.Completed);
99
- addHistoryMessage({
100
- type: 'assistant',
101
- text: '분석이 완료되었습니다!'
102
- });
103
- ```
104
-
105
- ### 작업 진행 표시
106
-
107
- ```javascript
108
- import { startOperation, updateOperation, completeOperation } from './ui/api.js';
109
-
110
- // 작업 시작
111
- const opId = startOperation({
112
- type: 'reading', // thinking, analyzing, reading, writing, editing, executing, etc.
113
- name: '파일 읽기',
114
- description: 'src/ 디렉토리 분석 중'
115
- });
116
-
117
- // 진행 상황 업데이트
118
- updateOperation(opId, {
119
- progress: 50,
120
- detail: 'components/ 처리 중...'
121
- });
122
-
123
- // 작업 완료
124
- completeOperation(opId);
125
- ```
126
-
127
- ### 자동 작업 관리
128
-
129
- ```javascript
130
- import { runOperation } from './ui/api.js';
131
-
132
- await runOperation({
133
- type: 'building',
134
- name: '프로젝트 빌드',
135
- description: 'npm run build'
136
- }, async (update) => {
137
- update({ progress: 25, detail: 'TypeScript 컴파일 중...' });
138
- await buildStep1();
139
-
140
- update({ progress: 75, detail: '번들링 중...' });
141
- await buildStep2();
142
-
143
- update({ progress: 100, detail: '완료!' });
144
- });
145
- ```
146
-
147
- ### 배치 업데이트
148
-
149
- ```javascript
150
- import { batchUpdate } from './ui/api.js';
151
-
152
- batchUpdate({
153
- streamingState: StreamingState.Executing,
154
- thought: '최선의 접근 방법을 고민 중...',
155
- progressMessage: '요구사항 분석 중',
156
- addHistory: {
157
- type: 'system',
158
- text: '분석 시작...'
159
- }
160
- });
161
- ```
162
-
163
- ## 작업 타입 (operation types)
164
-
165
- | Type | Icon | Description |
166
- |------|------|-------------|
167
- | `thinking` | 🤔 | 생각/추론 중 |
168
- | `analyzing` | 🔍 | 분석 중 |
169
- | `reading` | 📖 | 파일 읽기 |
170
- | `writing` | ✏️ | 파일 쓰기 |
171
- | `editing` | 📝 | 파일 편집 |
172
- | `executing` | ⚙️ | 명령 실행 |
173
- | `building` | 🔨 | 빌드 |
174
- | `testing` | 🧪 | 테스트 |
175
- | `debugging` | 🐛 | 디버깅 |
176
- | `searching` | 🔎 | 검색 |
177
- | `planning` | 📋 | 계획 수립 |
178
-
179
- ## 메시지 타입
180
-
181
- | Type | Icon | Color | Usage |
182
- |------|------|-------|-------|
183
- | `user` | `>` | Accent | 사용자 입력 |
184
- | `assistant` | `◆` | Info | AI 응답 |
185
- | `system` | `ℹ` | Secondary | 시스템 메시지 |
186
- | `error` | `✗` | Error | 에러 메시지 |
187
- | `tool` | `⚙` | Success | 도구 실행 결과 |
188
- | `thinking` | `💭` | Link | AI 사고 과정 |
189
-
190
- ## 애니메이션
191
-
192
- ### Spinner
193
- - 속도: 80ms per frame
194
- - 프레임: `['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']`
195
-
196
- ### Dots
197
- - 속도: 400ms per frame
198
- - 프레임: `['. ', '.. ', '...', ' ']`
199
-
200
- ## 성능 최적화
201
-
202
- 1. **Static 컴포넌트**: 불변 히스토리는 Static으로 렌더링하여 리렌더링 방지
203
- 2. **Dynamic 영역**: 진행 중인 작업만 동적으로 업데이트
204
- 3. **조건부 렌더링**: 필요한 컴포넌트만 표시
205
-
206
- ## 예제
207
-
208
- 자세한 사용 예제는 `example-usage.js` 파일을 참고하세요.
package/src/ui/api.js DELETED
@@ -1,167 +0,0 @@
1
- /**
2
- * UI API - Helper functions to update UI state from external code
3
- *
4
- * This module provides a simple API for the AI agent to update the UI
5
- * with progress information, operations, and streaming states.
6
- */
7
-
8
- let uiStateRef = null;
9
-
10
- /**
11
- * Initialize the UI API with the UI state reference
12
- */
13
- export function initializeUIAPI(uiState) {
14
- uiStateRef = uiState;
15
- }
16
-
17
- /**
18
- * Add a message to the history
19
- */
20
- export function addHistoryMessage(message) {
21
- if (!uiStateRef) return;
22
-
23
- uiStateRef.setHistory(prev => [...prev, {
24
- id: Date.now(),
25
- ...message
26
- }]);
27
- }
28
-
29
- /**
30
- * Add a pending history item (for streaming content)
31
- */
32
- export function addPendingMessage(message) {
33
- if (!uiStateRef) return;
34
-
35
- uiStateRef.setPendingHistoryItems(prev => [...prev, message]);
36
- }
37
-
38
- /**
39
- * Clear pending messages
40
- */
41
- export function clearPendingMessages() {
42
- if (!uiStateRef) return;
43
-
44
- uiStateRef.setPendingHistoryItems([]);
45
- }
46
-
47
- /**
48
- * Update streaming state
49
- */
50
- export function setStreamingState(state) {
51
- if (!uiStateRef) return;
52
-
53
- uiStateRef.setStreamingState(state);
54
- }
55
-
56
- /**
57
- * Set the current thought/reasoning message
58
- */
59
- export function setThought(thought) {
60
- if (!uiStateRef) return;
61
-
62
- uiStateRef.setThought(thought);
63
- }
64
-
65
- /**
66
- * Set progress message
67
- */
68
- export function setProgressMessage(message) {
69
- if (!uiStateRef) return;
70
-
71
- uiStateRef.setProgressMessage(message);
72
- }
73
-
74
- /**
75
- * Start a new operation
76
- * @param {Object} operation - { type, name, description }
77
- * @returns {number} operation ID
78
- */
79
- export function startOperation(operation) {
80
- if (!uiStateRef) return null;
81
-
82
- const id = Date.now();
83
- uiStateRef.addOperation({
84
- ...operation,
85
- id,
86
- startTime: Date.now(),
87
- status: 'running'
88
- });
89
-
90
- return id;
91
- }
92
-
93
- /**
94
- * Update an existing operation
95
- * @param {number} id - Operation ID
96
- * @param {Object} updates - { status, progress, detail }
97
- */
98
- export function updateOperation(id, updates) {
99
- if (!uiStateRef) return;
100
-
101
- uiStateRef.updateOperation(id, updates);
102
- }
103
-
104
- /**
105
- * Complete an operation
106
- * @param {number} id - Operation ID
107
- */
108
- export function completeOperation(id) {
109
- if (!uiStateRef) return;
110
-
111
- uiStateRef.completeOperation(id);
112
- }
113
-
114
- /**
115
- * Add an operation with automatic completion
116
- * Useful for simple sequential operations
117
- */
118
- export async function runOperation(operation, asyncFn) {
119
- const opId = startOperation(operation);
120
-
121
- try {
122
- const result = await asyncFn((updates) => {
123
- updateOperation(opId, updates);
124
- });
125
-
126
- completeOperation(opId);
127
- return result;
128
- } catch (error) {
129
- updateOperation(opId, {
130
- status: 'error',
131
- detail: error.message
132
- });
133
- throw error;
134
- }
135
- }
136
-
137
- /**
138
- * Clear all operations
139
- */
140
- export function clearOperations() {
141
- if (!uiStateRef) return;
142
-
143
- uiStateRef.setOperations([]);
144
- }
145
-
146
- /**
147
- * Batch update multiple UI elements at once
148
- */
149
- export function batchUpdate(updates) {
150
- if (!uiStateRef) return;
151
-
152
- if (updates.streamingState !== undefined) {
153
- setStreamingState(updates.streamingState);
154
- }
155
- if (updates.thought !== undefined) {
156
- setThought(updates.thought);
157
- }
158
- if (updates.progressMessage !== undefined) {
159
- setProgressMessage(updates.progressMessage);
160
- }
161
- if (updates.addHistory) {
162
- addHistoryMessage(updates.addHistory);
163
- }
164
- }
165
-
166
- // Export StreamingState enum for convenience
167
- export { StreamingState } from './contexts/UIStateContext.js';
@@ -1,126 +0,0 @@
1
- /**
2
- * AgenticProgressDisplay - Shows agentic coding operations with detailed progress
3
- * Isolated animation to prevent parent re-renders
4
- */
5
-
6
- import React, { useState, useEffect, memo } from 'react';
7
- import { Box, Text } from 'ink';
8
- import { theme } from '../themes/semantic-tokens.js';
9
-
10
- const OPERATION_ICONS = {
11
- thinking: '🤔',
12
- analyzing: '🔍',
13
- reading: '📖',
14
- writing: '✏️',
15
- editing: '📝',
16
- executing: '⚙️',
17
- building: '🔨',
18
- testing: '🧪',
19
- debugging: '🐛',
20
- searching: '🔎',
21
- planning: '📋',
22
- completed: '✅'
23
- };
24
-
25
- const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
26
-
27
- // operations 렌더링 활성화 여부
28
- const RENDER_OPERATIONS = false;
29
-
30
- // Isolated spinner component
31
- const SpinnerFrame = memo(function SpinnerFrame() {
32
- const [frameIndex, setFrameIndex] = useState(0);
33
-
34
- useEffect(() => {
35
- const interval = setInterval(() => {
36
- setFrameIndex(prev => (prev + 1) % SPINNER_FRAMES.length);
37
- }, 80);
38
-
39
- return () => clearInterval(interval);
40
- }, []);
41
-
42
- return React.createElement(Text, { color: theme.status.info },
43
- SPINNER_FRAMES[frameIndex] + ' '
44
- );
45
- });
46
-
47
- // Main component
48
- export const AgenticProgressDisplay = memo(function AgenticProgressDisplay({ operations = [] }) {
49
- if (!RENDER_OPERATIONS || operations.length === 0) {
50
- return null;
51
- }
52
-
53
- return React.createElement(Box, {
54
- flexDirection: "column",
55
- borderStyle: "round",
56
- borderColor: theme.border.default,
57
- paddingX: 1,
58
- marginBottom: 1
59
- },
60
- React.createElement(Box, { marginBottom: 1 },
61
- React.createElement(Text, { color: theme.text.accent, bold: true },
62
- '🤖 Agentic Operations')
63
- ),
64
- operations.map((op, index) =>
65
- React.createElement(OperationItem, {
66
- key: op.id || index,
67
- operation: op
68
- })
69
- )
70
- );
71
- });
72
-
73
- const OperationItem = memo(function OperationItem({ operation }) {
74
- const { type, name, status, progress, detail, startTime } = operation;
75
-
76
- const icon = OPERATION_ICONS[type] || '•';
77
- const statusColor = {
78
- running: theme.status.info,
79
- completed: theme.status.success,
80
- error: theme.status.error,
81
- waiting: theme.text.secondary
82
- }[status] || theme.text.secondary;
83
-
84
- const elapsed = startTime ? Math.floor((Date.now() - startTime) / 1000) : 0;
85
-
86
- return React.createElement(Box, {
87
- flexDirection: "column",
88
- marginBottom: 0
89
- },
90
- React.createElement(Box, { flexDirection: "row" },
91
- status === 'running' && React.createElement(SpinnerFrame),
92
- React.createElement(Text, null, icon + ' '),
93
- React.createElement(Text, { color: statusColor, bold: status === 'running' }, name),
94
- status === 'running' && elapsed > 0 && React.createElement(Text, {
95
- color: theme.text.secondary,
96
- dimColor: true
97
- }, ` (${elapsed}s)`)
98
- ),
99
- detail && React.createElement(Box, { marginLeft: 4 },
100
- React.createElement(Text, {
101
- color: theme.text.secondary,
102
- dimColor: true
103
- }, detail)
104
- ),
105
- progress && React.createElement(Box, { marginLeft: 4 },
106
- React.createElement(ProgressBar, { progress })
107
- )
108
- );
109
- });
110
-
111
- const ProgressBar = memo(function ProgressBar({ progress }) {
112
- const percentage = Math.min(100, Math.max(0, progress));
113
- const width = 40;
114
- const filled = Math.floor((percentage / 100) * width);
115
- const empty = width - filled;
116
-
117
- const bar = '█'.repeat(filled) + '░'.repeat(empty);
118
-
119
- return React.createElement(Box, { flexDirection: "row" },
120
- React.createElement(Text, { color: theme.status.info }, bar),
121
- React.createElement(Text, {
122
- color: theme.text.secondary,
123
- dimColor: true
124
- }, ` ${percentage.toFixed(0)}%`)
125
- );
126
- });
@@ -1,55 +0,0 @@
1
- /**
2
- * Composer - Input area with loading indicators and context display
3
- */
4
-
5
- import React from 'react';
6
- import { Box } from 'ink';
7
- import { InputPrompt } from './InputPrompt.js';
8
- import { LoadingIndicator } from './LoadingIndicator.js';
9
- import { AgenticProgressDisplay } from './AgenticProgressDisplay.js';
10
- import { SessionSpinner } from './SessionSpinner.js';
11
- import { useUIState, StreamingState } from '../contexts/UIStateContext.js';
12
- import { createDebugLogger } from '../../util/debug_log.js';
13
-
14
- const debugLog = createDebugLogger('ui_components.log', 'Composer');
15
-
16
- // 로딩/진행상황 렌더링 활성화 여부
17
- const RENDER_LOADING_PROGRESS = false;
18
-
19
- export function Composer({ onSubmit, onClearScreen, commands = [], buffer }) {
20
- debugLog('Composer rendering');
21
- const uiState = useUIState();
22
-
23
- const showLoading = uiState.streamingState === StreamingState.Responding ||
24
- uiState.streamingState === StreamingState.Executing;
25
-
26
- debugLog(`Composer - streamingState: ${uiState.streamingState}, showLoading: ${showLoading}, operations: ${uiState.operations.length}`);
27
-
28
- return React.createElement(Box, {
29
- flexDirection: "column",
30
- flexShrink: 0
31
- },
32
- RENDER_LOADING_PROGRESS && showLoading && React.createElement(LoadingIndicator, {
33
- thought: uiState.thought,
34
- currentLoadingPhrase: uiState.progressMessage,
35
- elapsedTime: uiState.elapsedTime
36
- }),
37
-
38
- RENDER_LOADING_PROGRESS && uiState.operations.length > 0 && React.createElement(AgenticProgressDisplay, {
39
- operations: uiState.operations
40
- }),
41
-
42
- React.createElement(SessionSpinner, {
43
- isRunning: uiState.isSessionRunning,
44
- message: uiState.sessionMessage
45
- }),
46
-
47
- React.createElement(InputPrompt, {
48
- buffer,
49
- onSubmit,
50
- onClearScreen,
51
- commands,
52
- focus: true
53
- })
54
- );
55
- }
@@ -1,54 +0,0 @@
1
- /**
2
- * LoadingIndicator - Shows loading state with thought/progress message
3
- * Isolated animation to prevent parent re-renders
4
- */
5
-
6
- import React, { useState, useEffect, memo } from 'react';
7
- import { Box, Text } from 'ink';
8
- import { theme } from '../themes/semantic-tokens.js';
9
-
10
- const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
11
-
12
- // Isolated spinner animation component
13
- const SpinnerFrame = memo(function SpinnerFrame() {
14
- const [frameIndex, setFrameIndex] = useState(0);
15
-
16
- useEffect(() => {
17
- const interval = setInterval(() => {
18
- setFrameIndex(prev => (prev + 1) % SPINNER_FRAMES.length);
19
- }, 80);
20
-
21
- return () => clearInterval(interval);
22
- }, []);
23
-
24
- return React.createElement(Text, { color: theme.status.info },
25
- SPINNER_FRAMES[frameIndex] + ' '
26
- );
27
- });
28
-
29
- // Main component
30
- export const LoadingIndicator = memo(function LoadingIndicator({ thought, currentLoadingPhrase, elapsedTime }) {
31
- if (!thought && !currentLoadingPhrase && !elapsedTime) {
32
- return null;
33
- }
34
-
35
- const displayTime = elapsedTime ? `${Math.floor(elapsedTime / 1000)}s` : '';
36
-
37
- return React.createElement(Box, {
38
- flexDirection: "column",
39
- marginBottom: 0
40
- },
41
- thought && React.createElement(Box, null,
42
- React.createElement(SpinnerFrame),
43
- React.createElement(Text, { color: theme.text.link, italic: true }, '💭 ' + thought)
44
- ),
45
- currentLoadingPhrase && React.createElement(Box, null,
46
- React.createElement(SpinnerFrame),
47
- React.createElement(Text, { color: theme.text.secondary }, currentLoadingPhrase),
48
- displayTime && React.createElement(Text, {
49
- color: theme.text.secondary,
50
- dimColor: true
51
- }, ` (${displayTime})`)
52
- )
53
- );
54
- });