centaurus-cli 2.0.0 → 2.0.2
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.
- package/CONFIG_GUIDE.md +100 -106
- package/README.md +68 -63
- package/dist/cli-adapter.d.ts +9 -3
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +123 -164
- package/dist/cli-adapter.js.map +1 -1
- package/dist/commands/CommandParser.d.ts +1 -1
- package/dist/commands/CommandParser.d.ts.map +1 -1
- package/dist/commands/CommandParser.js +3 -18
- package/dist/commands/CommandParser.js.map +1 -1
- package/dist/commands/view-duplication-logs.d.ts +5 -0
- package/dist/commands/view-duplication-logs.d.ts.map +1 -0
- package/dist/commands/view-duplication-logs.js +14 -0
- package/dist/commands/view-duplication-logs.js.map +1 -0
- package/dist/config/ConfigManager.d.ts +10 -7
- package/dist/config/ConfigManager.d.ts.map +1 -1
- package/dist/config/ConfigManager.js +43 -142
- package/dist/config/ConfigManager.js.map +1 -1
- package/dist/config/defaultConfig.d.ts +0 -4
- package/dist/config/defaultConfig.d.ts.map +1 -1
- package/dist/config/defaultConfig.js +1 -6
- package/dist/config/defaultConfig.js.map +1 -1
- package/dist/config/manager.d.ts +15 -13
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +52 -41
- package/dist/config/manager.js.map +1 -1
- package/dist/config/models.d.ts +31 -0
- package/dist/config/models.d.ts.map +1 -0
- package/dist/config/models.js +49 -0
- package/dist/config/models.js.map +1 -0
- package/dist/config/types.d.ts +0 -3
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +0 -1
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +27 -1
- package/dist/index.js.map +1 -1
- package/dist/prompts/system-prompt.d.ts +1 -1
- package/dist/prompts/system-prompt.d.ts.map +1 -1
- package/dist/prompts/system-prompt.js +0 -1
- package/dist/prompts/system-prompt.js.map +1 -1
- package/dist/services/ai-service-client.d.ts +82 -0
- package/dist/services/ai-service-client.d.ts.map +1 -0
- package/dist/services/ai-service-client.js +254 -0
- package/dist/services/ai-service-client.js.map +1 -0
- package/dist/services/api-client.js +3 -3
- package/dist/services/api-client.js.map +1 -1
- package/dist/tools/ToolRegistry.d.ts +14 -3
- package/dist/tools/ToolRegistry.d.ts.map +1 -1
- package/dist/tools/ToolRegistry.js +46 -34
- package/dist/tools/ToolRegistry.js.map +1 -1
- package/dist/tools/command.d.ts.map +1 -1
- package/dist/tools/command.js +17 -3
- package/dist/tools/command.js.map +1 -1
- package/dist/tools/file-ops.js +3 -3
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/web-search.js +2 -2
- package/dist/tools/web-search.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui/components/App.d.ts +3 -2
- package/dist/ui/components/App.d.ts.map +1 -1
- package/dist/ui/components/App.js +107 -16
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/CodeBlock.d.ts.map +1 -1
- package/dist/ui/components/CodeBlock.js +15 -3
- package/dist/ui/components/CodeBlock.js.map +1 -1
- package/dist/ui/components/ConfirmPrompt.d.ts.map +1 -1
- package/dist/ui/components/ConfirmPrompt.js +32 -20
- package/dist/ui/components/ConfirmPrompt.js.map +1 -1
- package/dist/ui/components/DiffViewer.d.ts.map +1 -1
- package/dist/ui/components/DiffViewer.js +16 -2
- package/dist/ui/components/DiffViewer.js.map +1 -1
- package/dist/ui/components/InputBox.d.ts.map +1 -1
- package/dist/ui/components/InputBox.js +26 -9
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/LoadingIndicator.d.ts.map +1 -1
- package/dist/ui/components/LoadingIndicator.js +6 -2
- package/dist/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/ui/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/ui/components/MarkdownRenderer.js +8 -12
- package/dist/ui/components/MarkdownRenderer.js.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.d.ts +6 -7
- package/dist/ui/components/StreamingMessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.js +69 -12
- package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
- package/dist/ui/components/ToolExecutionMessage.d.ts.map +1 -1
- package/dist/ui/components/ToolExecutionMessage.js +44 -16
- package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
- package/dist/ui/components/WelcomeBanner.d.ts.map +1 -1
- package/dist/ui/components/WelcomeBanner.js.map +1 -1
- package/dist/ui/utils/duplication-detector.d.ts +32 -0
- package/dist/ui/utils/duplication-detector.d.ts.map +1 -0
- package/dist/ui/utils/duplication-detector.js +227 -0
- package/dist/ui/utils/duplication-detector.js.map +1 -0
- package/dist/ui/utils/duplication-logger.d.ts +21 -0
- package/dist/ui/utils/duplication-logger.d.ts.map +1 -0
- package/dist/ui/utils/duplication-logger.js +85 -0
- package/dist/ui/utils/duplication-logger.js.map +1 -0
- package/dist/ui/utils/terminal-scanner.d.ts +19 -0
- package/dist/ui/utils/terminal-scanner.d.ts.map +1 -0
- package/dist/ui/utils/terminal-scanner.js +217 -0
- package/dist/ui/utils/terminal-scanner.js.map +1 -0
- package/package.json +2 -13
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duplication Detector Utility
|
|
3
|
+
*
|
|
4
|
+
* Detects when the UI has been duplicated by monitoring the terminal output
|
|
5
|
+
* for multiple instances of the InputBox component.
|
|
6
|
+
*/
|
|
7
|
+
import { useEffect, useRef } from 'react';
|
|
8
|
+
import { logDuplication } from './duplication-logger.js';
|
|
9
|
+
/**
|
|
10
|
+
* Detects UI duplication by scanning the terminal buffer for multiple input boxes
|
|
11
|
+
*/
|
|
12
|
+
export function useDuplicationDetector({ onDuplicationDetected, checkIntervalMs = 500, enabled = true }) {
|
|
13
|
+
const lastCheckRef = useRef(0);
|
|
14
|
+
const duplicationDetectedRef = useRef(false);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (!enabled)
|
|
17
|
+
return;
|
|
18
|
+
const intervalId = setInterval(() => {
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
// Throttle checks
|
|
21
|
+
if (now - lastCheckRef.current < checkIntervalMs) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
lastCheckRef.current = now;
|
|
25
|
+
// Check for duplication
|
|
26
|
+
if (detectDuplication()) {
|
|
27
|
+
if (!duplicationDetectedRef.current) {
|
|
28
|
+
duplicationDetectedRef.current = true;
|
|
29
|
+
console.error('[Duplication Detector] UI duplication detected! Triggering recovery...');
|
|
30
|
+
onDuplicationDetected();
|
|
31
|
+
// Reset flag after a delay to allow re-detection if needed
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
duplicationDetectedRef.current = false;
|
|
34
|
+
}, 2000);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}, checkIntervalMs);
|
|
38
|
+
return () => clearInterval(intervalId);
|
|
39
|
+
}, [onDuplicationDetected, checkIntervalMs, enabled]);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Detects duplication by analyzing the terminal output
|
|
43
|
+
* Returns true if duplication is detected
|
|
44
|
+
*/
|
|
45
|
+
function detectDuplication() {
|
|
46
|
+
try {
|
|
47
|
+
// Get the terminal output by reading stdout
|
|
48
|
+
// We'll look for multiple instances of the InputBox border pattern
|
|
49
|
+
const terminalOutput = getTerminalOutput();
|
|
50
|
+
if (!terminalOutput) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
// Count occurrences of the InputBox component markers
|
|
54
|
+
const inputBoxCount = countInputBoxes(terminalOutput);
|
|
55
|
+
// If we find more than 1 input box, duplication has occurred
|
|
56
|
+
if (inputBoxCount > 1) {
|
|
57
|
+
console.error(`[Duplication Detector] Found ${inputBoxCount} input boxes (expected 1)`);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error('[Duplication Detector] Error during detection:', error);
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Gets the current terminal output
|
|
69
|
+
*/
|
|
70
|
+
function getTerminalOutput() {
|
|
71
|
+
try {
|
|
72
|
+
// In Node.js, we can't directly read the terminal buffer
|
|
73
|
+
// Instead, we'll use a different approach: check if Ink is rendering multiple times
|
|
74
|
+
// by looking at the process.stdout content
|
|
75
|
+
// For now, we'll use a heuristic based on the terminal rows
|
|
76
|
+
if (process.stdout.rows && process.stdout.columns) {
|
|
77
|
+
// We can't directly read the buffer, so we'll use an alternative approach
|
|
78
|
+
// Store a marker in the component and check for duplicates
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Counts the number of InputBox components in the terminal output
|
|
89
|
+
*/
|
|
90
|
+
function countInputBoxes(output) {
|
|
91
|
+
// Look for the InputBox border pattern (round border style)
|
|
92
|
+
// The InputBox has distinctive markers:
|
|
93
|
+
// 1. "CWD:" text
|
|
94
|
+
// 2. "Model:" text
|
|
95
|
+
// 3. "AUTO-ACCEPT:" text
|
|
96
|
+
// 4. "> " prompt
|
|
97
|
+
// 5. "Ctrl+T to toggle" help text
|
|
98
|
+
const markers = [
|
|
99
|
+
/CWD:/g,
|
|
100
|
+
/Model:/g,
|
|
101
|
+
/AUTO-ACCEPT:/g,
|
|
102
|
+
/Ctrl\+T to toggle auto-accept/g
|
|
103
|
+
];
|
|
104
|
+
let maxCount = 0;
|
|
105
|
+
for (const marker of markers) {
|
|
106
|
+
const matches = output.match(marker);
|
|
107
|
+
const count = matches ? matches.length : 0;
|
|
108
|
+
maxCount = Math.max(maxCount, count);
|
|
109
|
+
}
|
|
110
|
+
return maxCount;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Alternative approach: Use a global counter to track InputBox renders
|
|
114
|
+
*/
|
|
115
|
+
let inputBoxRenderCount = 0;
|
|
116
|
+
let lastResetTime = Date.now();
|
|
117
|
+
export function registerInputBoxRender() {
|
|
118
|
+
const now = Date.now();
|
|
119
|
+
// Reset counter every 100ms (one render cycle)
|
|
120
|
+
if (now - lastResetTime > 100) {
|
|
121
|
+
inputBoxRenderCount = 0;
|
|
122
|
+
lastResetTime = now;
|
|
123
|
+
}
|
|
124
|
+
inputBoxRenderCount++;
|
|
125
|
+
}
|
|
126
|
+
export function getInputBoxRenderCount() {
|
|
127
|
+
return inputBoxRenderCount;
|
|
128
|
+
}
|
|
129
|
+
export function resetInputBoxRenderCount() {
|
|
130
|
+
inputBoxRenderCount = 0;
|
|
131
|
+
lastResetTime = Date.now();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Track WelcomeBanner renders
|
|
135
|
+
* Banner should only render once per session, so we don't reset the counter automatically
|
|
136
|
+
*/
|
|
137
|
+
let bannerRenderCount = 0;
|
|
138
|
+
let bannerRenderTimestamps = [];
|
|
139
|
+
let duplicationCallback = null;
|
|
140
|
+
export function setDuplicationCallback(callback) {
|
|
141
|
+
logDuplication('Callback registered', 'INFO');
|
|
142
|
+
duplicationCallback = callback;
|
|
143
|
+
}
|
|
144
|
+
export function registerBannerRender() {
|
|
145
|
+
const now = Date.now();
|
|
146
|
+
bannerRenderCount++;
|
|
147
|
+
bannerRenderTimestamps.push(now);
|
|
148
|
+
logDuplication(`Banner render #${bannerRenderCount} at ${now}`, 'INFO');
|
|
149
|
+
// Keep only last 10 timestamps for analysis
|
|
150
|
+
if (bannerRenderTimestamps.length > 10) {
|
|
151
|
+
bannerRenderTimestamps.shift();
|
|
152
|
+
}
|
|
153
|
+
// Immediate check: if banner count > 1, trigger duplication callback
|
|
154
|
+
if (bannerRenderCount > 1) {
|
|
155
|
+
logDuplication(`DUPLICATION! Banner render #${bannerRenderCount} detected!`, 'ERROR');
|
|
156
|
+
if (duplicationCallback) {
|
|
157
|
+
logDuplication('Triggering immediate recovery callback...', 'ERROR');
|
|
158
|
+
duplicationCallback();
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
logDuplication('WARNING: No callback registered yet!', 'WARN');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export function getBannerRenderCount() {
|
|
166
|
+
return bannerRenderCount;
|
|
167
|
+
}
|
|
168
|
+
export function resetBannerRenderCount() {
|
|
169
|
+
bannerRenderCount = 0;
|
|
170
|
+
bannerRenderTimestamps = [];
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Hook to detect duplication using render counting
|
|
174
|
+
* Checks both InputBox and Banner render counts
|
|
175
|
+
* Banner check is cumulative (never resets automatically), InputBox resets per cycle
|
|
176
|
+
*/
|
|
177
|
+
export function useRenderCountDuplicationDetector({ onDuplicationDetected, threshold = 2, checkIntervalMs = 100, enabled = true }) {
|
|
178
|
+
const duplicationDetectedRef = useRef(false);
|
|
179
|
+
const lastBannerCountRef = useRef(0);
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
if (!enabled)
|
|
182
|
+
return;
|
|
183
|
+
logDuplication('Periodic monitoring started', 'INFO');
|
|
184
|
+
const intervalId = setInterval(() => {
|
|
185
|
+
const inputBoxCount = getInputBoxRenderCount();
|
|
186
|
+
const bannerCount = getBannerRenderCount();
|
|
187
|
+
// Log current counts for debugging
|
|
188
|
+
if (inputBoxCount > 0 || bannerCount > 0) {
|
|
189
|
+
logDuplication(`Check: InputBox=${inputBoxCount}, Banner=${bannerCount}, LastBanner=${lastBannerCountRef.current}`, 'INFO');
|
|
190
|
+
}
|
|
191
|
+
// Check if InputBox has been rendered multiple times in current cycle
|
|
192
|
+
const inputBoxDuplicated = inputBoxCount > threshold;
|
|
193
|
+
// Check if banner count has increased (meaning a new banner was rendered)
|
|
194
|
+
// Banner should only render once, so any increase after initial render is duplication
|
|
195
|
+
const bannerDuplicated = bannerCount > 1 && bannerCount > lastBannerCountRef.current;
|
|
196
|
+
const isDuplicated = inputBoxDuplicated || bannerDuplicated;
|
|
197
|
+
if (isDuplicated) {
|
|
198
|
+
if (!duplicationDetectedRef.current) {
|
|
199
|
+
duplicationDetectedRef.current = true;
|
|
200
|
+
if (inputBoxDuplicated) {
|
|
201
|
+
logDuplication(`Multiple InputBox renders detected (${inputBoxCount})! Triggering recovery...`, 'ERROR');
|
|
202
|
+
}
|
|
203
|
+
if (bannerDuplicated) {
|
|
204
|
+
logDuplication(`Multiple Banner renders detected (${bannerCount}, was ${lastBannerCountRef.current})! Triggering recovery...`, 'ERROR');
|
|
205
|
+
}
|
|
206
|
+
onDuplicationDetected();
|
|
207
|
+
resetInputBoxRenderCount();
|
|
208
|
+
// Don't reset banner count here - let the recovery handler do it
|
|
209
|
+
// Reset flag after a delay
|
|
210
|
+
setTimeout(() => {
|
|
211
|
+
duplicationDetectedRef.current = false;
|
|
212
|
+
lastBannerCountRef.current = 1; // After recovery, we expect 1 banner
|
|
213
|
+
}, 1000);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
// Update last banner count for next check
|
|
218
|
+
lastBannerCountRef.current = bannerCount;
|
|
219
|
+
}
|
|
220
|
+
}, checkIntervalMs);
|
|
221
|
+
return () => {
|
|
222
|
+
logDuplication('Periodic monitoring stopped', 'INFO');
|
|
223
|
+
clearInterval(intervalId);
|
|
224
|
+
};
|
|
225
|
+
}, [onDuplicationDetected, threshold, checkIntervalMs, enabled]);
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=duplication-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplication-detector.js","sourceRoot":"","sources":["../../../src/ui/utils/duplication-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAQzD;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,qBAAqB,EACrB,eAAe,GAAG,GAAG,EACrB,OAAO,GAAG,IAAI,EACa;IAC3B,MAAM,YAAY,GAAG,MAAM,CAAS,CAAC,CAAC,CAAC;IACvC,MAAM,sBAAsB,GAAG,MAAM,CAAU,KAAK,CAAC,CAAC;IAEtD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAEvB,kBAAkB;YAClB,IAAI,GAAG,GAAG,YAAY,CAAC,OAAO,GAAG,eAAe,EAAE,CAAC;gBACjD,OAAO;YACT,CAAC;YAED,YAAY,CAAC,OAAO,GAAG,GAAG,CAAC;YAE3B,wBAAwB;YACxB,IAAI,iBAAiB,EAAE,EAAE,CAAC;gBACxB,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,CAAC;oBACpC,sBAAsB,CAAC,OAAO,GAAG,IAAI,CAAC;oBACtC,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;oBACxF,qBAAqB,EAAE,CAAC;oBAExB,2DAA2D;oBAC3D,UAAU,CAAC,GAAG,EAAE;wBACd,sBAAsB,CAAC,OAAO,GAAG,KAAK,CAAC;oBACzC,CAAC,EAAE,IAAI,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;QACH,CAAC,EAAE,eAAe,CAAC,CAAC;QAEpB,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC,EAAE,CAAC,qBAAqB,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,4CAA4C;QAC5C,mEAAmE;QACnE,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;QAE3C,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,sDAAsD;QACtD,MAAM,aAAa,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;QAEtD,6DAA6D;QAC7D,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,gCAAgC,aAAa,2BAA2B,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,KAAK,CAAC,CAAC;QACvE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,yDAAyD;QACzD,oFAAoF;QACpF,2CAA2C;QAE3C,4DAA4D;QAC5D,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClD,0EAA0E;YAC1E,2DAA2D;YAC3D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,4DAA4D;IAC5D,wCAAwC;IACxC,iBAAiB;IACjB,mBAAmB;IACnB,yBAAyB;IACzB,iBAAiB;IACjB,kCAAkC;IAElC,MAAM,OAAO,GAAG;QACd,OAAO;QACP,SAAS;QACT,eAAe;QACf,gCAAgC;KACjC,CAAC;IAEF,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,IAAI,mBAAmB,GAAG,CAAC,CAAC;AAC5B,IAAI,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAE/B,MAAM,UAAU,sBAAsB;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,+CAA+C;IAC/C,IAAI,GAAG,GAAG,aAAa,GAAG,GAAG,EAAE,CAAC;QAC9B,mBAAmB,GAAG,CAAC,CAAC;QACxB,aAAa,GAAG,GAAG,CAAC;IACtB,CAAC;IAED,mBAAmB,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,mBAAmB,GAAG,CAAC,CAAC;IACxB,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAC1B,IAAI,sBAAsB,GAAa,EAAE,CAAC;AAC1C,IAAI,mBAAmB,GAAwB,IAAI,CAAC;AAEpD,MAAM,UAAU,sBAAsB,CAAC,QAAoB;IACzD,cAAc,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAC9C,mBAAmB,GAAG,QAAQ,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,iBAAiB,EAAE,CAAC;IACpB,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEjC,cAAc,CAAC,kBAAkB,iBAAiB,OAAO,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAExE,4CAA4C;IAC5C,IAAI,sBAAsB,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACvC,sBAAsB,CAAC,KAAK,EAAE,CAAC;IACjC,CAAC;IAED,qEAAqE;IACrE,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;QAC1B,cAAc,CAAC,+BAA+B,iBAAiB,YAAY,EAAE,OAAO,CAAC,CAAC;QACtF,IAAI,mBAAmB,EAAE,CAAC;YACxB,cAAc,CAAC,2CAA2C,EAAE,OAAO,CAAC,CAAC;YACrE,mBAAmB,EAAE,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,cAAc,CAAC,sCAAsC,EAAE,MAAM,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,iBAAiB,GAAG,CAAC,CAAC;IACtB,sBAAsB,GAAG,EAAE,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAAC,EAChD,qBAAqB,EACrB,SAAS,GAAG,CAAC,EACb,eAAe,GAAG,GAAG,EACrB,OAAO,GAAG,IAAI,EACsC;IACpD,MAAM,sBAAsB,GAAG,MAAM,CAAU,KAAK,CAAC,CAAC;IACtD,MAAM,kBAAkB,GAAG,MAAM,CAAS,CAAC,CAAC,CAAC;IAE7C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,cAAc,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;QAEtD,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YAClC,MAAM,aAAa,GAAG,sBAAsB,EAAE,CAAC;YAC/C,MAAM,WAAW,GAAG,oBAAoB,EAAE,CAAC;YAE3C,mCAAmC;YACnC,IAAI,aAAa,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACzC,cAAc,CAAC,mBAAmB,aAAa,YAAY,WAAW,gBAAgB,kBAAkB,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;YAC9H,CAAC;YAED,sEAAsE;YACtE,MAAM,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAAC;YAErD,0EAA0E;YAC1E,sFAAsF;YACtF,MAAM,gBAAgB,GAAG,WAAW,GAAG,CAAC,IAAI,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC;YAErF,MAAM,YAAY,GAAG,kBAAkB,IAAI,gBAAgB,CAAC;YAE5D,IAAI,YAAY,EAAE,CAAC;gBACjB,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,CAAC;oBACpC,sBAAsB,CAAC,OAAO,GAAG,IAAI,CAAC;oBAEtC,IAAI,kBAAkB,EAAE,CAAC;wBACvB,cAAc,CAAC,uCAAuC,aAAa,2BAA2B,EAAE,OAAO,CAAC,CAAC;oBAC3G,CAAC;oBACD,IAAI,gBAAgB,EAAE,CAAC;wBACrB,cAAc,CAAC,qCAAqC,WAAW,SAAS,kBAAkB,CAAC,OAAO,2BAA2B,EAAE,OAAO,CAAC,CAAC;oBAC1I,CAAC;oBAED,qBAAqB,EAAE,CAAC;oBACxB,wBAAwB,EAAE,CAAC;oBAC3B,iEAAiE;oBAEjE,2BAA2B;oBAC3B,UAAU,CAAC,GAAG,EAAE;wBACd,sBAAsB,CAAC,OAAO,GAAG,KAAK,CAAC;wBACvC,kBAAkB,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,qCAAqC;oBACvE,CAAC,EAAE,IAAI,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,0CAA0C;gBAC1C,kBAAkB,CAAC,OAAO,GAAG,WAAW,CAAC;YAC3C,CAAC;QACH,CAAC,EAAE,eAAe,CAAC,CAAC;QAEpB,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;YACtD,aAAa,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,qBAAqB,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based logging system for duplication detection
|
|
3
|
+
* Logs to a file instead of console to avoid cluttering the terminal
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Write a log entry to the file
|
|
7
|
+
*/
|
|
8
|
+
export declare function logDuplication(message: string, level?: 'INFO' | 'WARN' | 'ERROR'): void;
|
|
9
|
+
/**
|
|
10
|
+
* Clear the log file
|
|
11
|
+
*/
|
|
12
|
+
export declare function clearDuplicationLog(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Get the log file path
|
|
15
|
+
*/
|
|
16
|
+
export declare function getLogFilePath(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Read the last N lines from the log file
|
|
19
|
+
*/
|
|
20
|
+
export declare function readLastLogLines(lines?: number): string;
|
|
21
|
+
//# sourceMappingURL=duplication-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplication-logger.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/duplication-logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,MAAM,GAAG,OAAgB,GAAG,IAAI,CAuB/F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAS1C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,MAAW,GAAG,MAAM,CAa3D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-based logging system for duplication detection
|
|
3
|
+
* Logs to a file instead of console to avoid cluttering the terminal
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
const LOG_DIR = path.join(os.tmpdir(), 'centaurus-cli-logs');
|
|
9
|
+
const LOG_FILE = path.join(LOG_DIR, 'duplication-detector.log');
|
|
10
|
+
const MAX_LOG_SIZE = 1024 * 1024; // 1MB
|
|
11
|
+
// Ensure log directory exists
|
|
12
|
+
try {
|
|
13
|
+
if (!fs.existsSync(LOG_DIR)) {
|
|
14
|
+
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
// Silently fail if we can't create log directory
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Write a log entry to the file
|
|
22
|
+
*/
|
|
23
|
+
export function logDuplication(message, level = 'INFO') {
|
|
24
|
+
try {
|
|
25
|
+
const timestamp = new Date().toISOString();
|
|
26
|
+
const logEntry = `[${timestamp}] [${level}] ${message}\n`;
|
|
27
|
+
// Check file size and rotate if needed
|
|
28
|
+
if (fs.existsSync(LOG_FILE)) {
|
|
29
|
+
const stats = fs.statSync(LOG_FILE);
|
|
30
|
+
if (stats.size > MAX_LOG_SIZE) {
|
|
31
|
+
// Rotate log file
|
|
32
|
+
const backupFile = path.join(LOG_DIR, `duplication-detector.log.old`);
|
|
33
|
+
if (fs.existsSync(backupFile)) {
|
|
34
|
+
fs.unlinkSync(backupFile);
|
|
35
|
+
}
|
|
36
|
+
fs.renameSync(LOG_FILE, backupFile);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Append to log file
|
|
40
|
+
fs.appendFileSync(LOG_FILE, logEntry);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// Silently fail if we can't write to log
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Clear the log file
|
|
48
|
+
*/
|
|
49
|
+
export function clearDuplicationLog() {
|
|
50
|
+
try {
|
|
51
|
+
if (fs.existsSync(LOG_FILE)) {
|
|
52
|
+
fs.unlinkSync(LOG_FILE);
|
|
53
|
+
}
|
|
54
|
+
logDuplication('=== Log cleared ===', 'INFO');
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
// Silently fail
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the log file path
|
|
62
|
+
*/
|
|
63
|
+
export function getLogFilePath() {
|
|
64
|
+
return LOG_FILE;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Read the last N lines from the log file
|
|
68
|
+
*/
|
|
69
|
+
export function readLastLogLines(lines = 50) {
|
|
70
|
+
try {
|
|
71
|
+
if (!fs.existsSync(LOG_FILE)) {
|
|
72
|
+
return 'No log file found';
|
|
73
|
+
}
|
|
74
|
+
const content = fs.readFileSync(LOG_FILE, 'utf-8');
|
|
75
|
+
const allLines = content.split('\n').filter(line => line.trim());
|
|
76
|
+
const lastLines = allLines.slice(-lines);
|
|
77
|
+
return lastLines.join('\n');
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
return `Error reading log: ${error}`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Initialize log on module load
|
|
84
|
+
logDuplication('=== Duplication detector initialized ===', 'INFO');
|
|
85
|
+
//# sourceMappingURL=duplication-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplication-logger.js","sourceRoot":"","sources":["../../../src/ui/utils/duplication-logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Output Scanner
|
|
3
|
+
* Detects UI duplication by analyzing the actual terminal buffer content
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Scan terminal output for duplication patterns
|
|
7
|
+
* Returns true if duplication is detected
|
|
8
|
+
*/
|
|
9
|
+
export declare function scanTerminalForDuplication(): boolean;
|
|
10
|
+
export declare function injectTerminalMarker(): void;
|
|
11
|
+
export declare function getMarkerCount(): number;
|
|
12
|
+
export declare function resetMarkerCount(): void;
|
|
13
|
+
export declare function captureInkOutput(chunk: string): void;
|
|
14
|
+
export declare function clearInkOutputBuffer(): void;
|
|
15
|
+
export declare function pauseDetection(): void;
|
|
16
|
+
export declare function resumeDetection(): void;
|
|
17
|
+
export declare function hookStdout(onDuplicationDetected: () => void): void;
|
|
18
|
+
export declare function unhookStdout(): void;
|
|
19
|
+
//# sourceMappingURL=terminal-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-scanner.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/terminal-scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAuBpD;AASD,wBAAgB,oBAAoB,IAAI,IAAI,CAK3C;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AASD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CA6BpD;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C;AASD,wBAAgB,cAAc,IAAI,IAAI,CAGrC;AAED,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AAED,wBAAgB,UAAU,CAAC,qBAAqB,EAAE,MAAM,IAAI,GAAG,IAAI,CAkIlE;AAED,wBAAgB,YAAY,IAAI,IAAI,CAanC"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Output Scanner
|
|
3
|
+
* Detects UI duplication by analyzing the actual terminal buffer content
|
|
4
|
+
*/
|
|
5
|
+
import { logDuplication } from './duplication-logger.js';
|
|
6
|
+
// Store the last known good state
|
|
7
|
+
let lastKnownLineCount = 0;
|
|
8
|
+
let consecutiveDuplicationDetections = 0;
|
|
9
|
+
/**
|
|
10
|
+
* Scan terminal output for duplication patterns
|
|
11
|
+
* Returns true if duplication is detected
|
|
12
|
+
*/
|
|
13
|
+
export function scanTerminalForDuplication() {
|
|
14
|
+
try {
|
|
15
|
+
// Get terminal dimensions
|
|
16
|
+
const rows = process.stdout.rows || 0;
|
|
17
|
+
const cols = process.stdout.columns || 0;
|
|
18
|
+
if (rows === 0 || cols === 0) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
// Try to detect duplication by checking for repeated patterns
|
|
22
|
+
// We'll use a heuristic: if we see the same distinctive text multiple times,
|
|
23
|
+
// it's likely duplicated
|
|
24
|
+
// Since we can't directly read the terminal buffer in Node.js,
|
|
25
|
+
// we'll use a different approach: track cursor position changes
|
|
26
|
+
// and detect anomalies
|
|
27
|
+
return false; // Placeholder - terminal buffer reading not available in Node.js
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
logDuplication(`Terminal scan error: ${error}`, 'WARN');
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Alternative: Use a marker-based detection system
|
|
36
|
+
* Inject invisible markers and count them
|
|
37
|
+
*/
|
|
38
|
+
let markerCount = 0;
|
|
39
|
+
const MARKER_ID = `\x1b]1337;marker=${Date.now()}\x07`;
|
|
40
|
+
export function injectTerminalMarker() {
|
|
41
|
+
// Inject an invisible marker that we can count
|
|
42
|
+
process.stdout.write(MARKER_ID);
|
|
43
|
+
markerCount++;
|
|
44
|
+
logDuplication(`Marker injected, count: ${markerCount}`, 'INFO');
|
|
45
|
+
}
|
|
46
|
+
export function getMarkerCount() {
|
|
47
|
+
return markerCount;
|
|
48
|
+
}
|
|
49
|
+
export function resetMarkerCount() {
|
|
50
|
+
markerCount = 0;
|
|
51
|
+
logDuplication('Marker count reset', 'INFO');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Better approach: Monitor Ink's render output
|
|
55
|
+
* Hook into Ink's output stream
|
|
56
|
+
*/
|
|
57
|
+
let inkOutputBuffer = [];
|
|
58
|
+
const MAX_BUFFER_SIZE = 1000;
|
|
59
|
+
export function captureInkOutput(chunk) {
|
|
60
|
+
inkOutputBuffer.push(chunk);
|
|
61
|
+
// Keep buffer size manageable
|
|
62
|
+
if (inkOutputBuffer.length > MAX_BUFFER_SIZE) {
|
|
63
|
+
inkOutputBuffer.shift();
|
|
64
|
+
}
|
|
65
|
+
// Check for duplication patterns in recent output
|
|
66
|
+
if (inkOutputBuffer.length > 10) {
|
|
67
|
+
const recentOutput = inkOutputBuffer.slice(-10).join('');
|
|
68
|
+
// Look for the banner ASCII art pattern
|
|
69
|
+
const bannerPattern = /██████╗███████╗███╗ ██╗████████╗/g;
|
|
70
|
+
const bannerMatches = recentOutput.match(bannerPattern);
|
|
71
|
+
if (bannerMatches && bannerMatches.length > 1) {
|
|
72
|
+
logDuplication(`Banner pattern found ${bannerMatches.length} times in recent output!`, 'ERROR');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Look for InputBox pattern
|
|
76
|
+
const inputBoxPattern = /CWD:.*Model:.*AUTO-ACCEPT:/g;
|
|
77
|
+
const inputBoxMatches = recentOutput.match(inputBoxPattern);
|
|
78
|
+
if (inputBoxMatches && inputBoxMatches.length > 1) {
|
|
79
|
+
logDuplication(`InputBox pattern found ${inputBoxMatches.length} times in recent output!`, 'ERROR');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export function clearInkOutputBuffer() {
|
|
84
|
+
inkOutputBuffer = [];
|
|
85
|
+
logDuplication('Ink output buffer cleared', 'INFO');
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Hook into process.stdout.write to intercept all output
|
|
89
|
+
*/
|
|
90
|
+
const originalWrite = process.stdout.write.bind(process.stdout);
|
|
91
|
+
let isHooked = false;
|
|
92
|
+
let detectionEnabled = true;
|
|
93
|
+
export function pauseDetection() {
|
|
94
|
+
detectionEnabled = false;
|
|
95
|
+
logDuplication('Detection paused', 'INFO');
|
|
96
|
+
}
|
|
97
|
+
export function resumeDetection() {
|
|
98
|
+
detectionEnabled = true;
|
|
99
|
+
logDuplication('Detection resumed', 'INFO');
|
|
100
|
+
}
|
|
101
|
+
export function hookStdout(onDuplicationDetected) {
|
|
102
|
+
if (isHooked)
|
|
103
|
+
return;
|
|
104
|
+
logDuplication('Hooking into stdout for duplication detection', 'INFO');
|
|
105
|
+
isHooked = true;
|
|
106
|
+
let outputBuffer = '';
|
|
107
|
+
let lastCheckTime = Date.now();
|
|
108
|
+
let recoveryScheduled = false;
|
|
109
|
+
let lastRecoveryTime = 0;
|
|
110
|
+
// Continuous monitoring - check buffer every 100ms
|
|
111
|
+
const monitoringInterval = setInterval(() => {
|
|
112
|
+
if (!detectionEnabled || recoveryScheduled) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const now = Date.now();
|
|
116
|
+
// Prevent recovery spam
|
|
117
|
+
if (now - lastRecoveryTime < 2000) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// Check for banner duplication
|
|
121
|
+
const bannerPattern = /██████╗███████╗███╗ ██╗████████╗ █████╗ ██╗ ██╗██████╗ ██╗ ██╗███████╗/g;
|
|
122
|
+
const bannerMatches = outputBuffer.match(bannerPattern);
|
|
123
|
+
// Log buffer state periodically for debugging
|
|
124
|
+
if (now % 5000 < 100) { // Every ~5 seconds
|
|
125
|
+
const bufferPreview = outputBuffer.slice(-500).replace(/\n/g, '\\n').substring(0, 200);
|
|
126
|
+
logDuplication(`[MONITOR] Buffer size: ${outputBuffer.length}, Banners: ${bannerMatches ? bannerMatches.length : 0}, Preview: ${bufferPreview}`, 'INFO');
|
|
127
|
+
}
|
|
128
|
+
if (bannerMatches && bannerMatches.length > 1) {
|
|
129
|
+
logDuplication(`[MONITOR] DUPLICATION DETECTED! Banner found ${bannerMatches.length} times`, 'ERROR');
|
|
130
|
+
logDuplication(`[MONITOR] Buffer content (last 1000 chars): ${outputBuffer.slice(-1000)}`, 'ERROR');
|
|
131
|
+
recoveryScheduled = true;
|
|
132
|
+
lastRecoveryTime = now;
|
|
133
|
+
outputBuffer = '';
|
|
134
|
+
pauseDetection();
|
|
135
|
+
setImmediate(() => {
|
|
136
|
+
logDuplication('[MONITOR] Executing recovery', 'ERROR');
|
|
137
|
+
onDuplicationDetected();
|
|
138
|
+
recoveryScheduled = false;
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
resumeDetection();
|
|
141
|
+
outputBuffer = '';
|
|
142
|
+
}, 800);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}, 100); // Check every 100ms
|
|
146
|
+
// Store interval ID for cleanup
|
|
147
|
+
hookStdout.monitoringInterval = monitoringInterval;
|
|
148
|
+
process.stdout.write = function (chunk, ...args) {
|
|
149
|
+
const str = chunk.toString();
|
|
150
|
+
// Always write to actual stdout first
|
|
151
|
+
const result = originalWrite(chunk, ...args);
|
|
152
|
+
// Then add to our monitoring buffer
|
|
153
|
+
outputBuffer += str;
|
|
154
|
+
// Skip detection if paused (during recovery)
|
|
155
|
+
if (!detectionEnabled) {
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
const now = Date.now();
|
|
159
|
+
// Prevent recovery spam - at least 2 seconds between recoveries
|
|
160
|
+
if (now - lastRecoveryTime < 2000) {
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
// Look for banner duplication in the buffer
|
|
164
|
+
const bannerPattern = /██████╗███████╗███╗ ██╗████████╗ █████╗ ██╗ ██╗██████╗ ██╗ ██╗███████╗/g;
|
|
165
|
+
const bannerMatches = outputBuffer.match(bannerPattern);
|
|
166
|
+
if (bannerMatches && bannerMatches.length > 1 && !recoveryScheduled) {
|
|
167
|
+
logDuplication(`DUPLICATION DETECTED! Banner found ${bannerMatches.length} times in output buffer (${outputBuffer.length} bytes)`, 'ERROR');
|
|
168
|
+
logDuplication(`Time since last recovery: ${now - lastRecoveryTime}ms`, 'ERROR');
|
|
169
|
+
logDuplication(`Buffer content (last 2000 chars): ${outputBuffer.slice(-2000)}`, 'ERROR');
|
|
170
|
+
recoveryScheduled = true;
|
|
171
|
+
lastRecoveryTime = now;
|
|
172
|
+
// IMMEDIATELY clear the output buffer
|
|
173
|
+
outputBuffer = '';
|
|
174
|
+
logDuplication('Output buffer cleared immediately', 'ERROR');
|
|
175
|
+
// Pause detection during recovery
|
|
176
|
+
pauseDetection();
|
|
177
|
+
// Use setImmediate to defer recovery until after current render completes
|
|
178
|
+
setImmediate(() => {
|
|
179
|
+
logDuplication('Executing immediate recovery', 'ERROR');
|
|
180
|
+
onDuplicationDetected();
|
|
181
|
+
consecutiveDuplicationDetections = 0;
|
|
182
|
+
recoveryScheduled = false;
|
|
183
|
+
// Resume detection after recovery completes
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
logDuplication('Resuming detection after recovery', 'INFO');
|
|
186
|
+
resumeDetection();
|
|
187
|
+
outputBuffer = ''; // Clear buffer again to start fresh
|
|
188
|
+
}, 800);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
// Reset counter if no duplication found
|
|
193
|
+
if (now - lastCheckTime > 1000) {
|
|
194
|
+
consecutiveDuplicationDetections = 0;
|
|
195
|
+
lastCheckTime = now;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Keep buffer size manageable (last 150KB to catch more duplication)
|
|
199
|
+
if (outputBuffer.length > 150000) {
|
|
200
|
+
outputBuffer = outputBuffer.slice(-150000);
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export function unhookStdout() {
|
|
206
|
+
if (!isHooked)
|
|
207
|
+
return;
|
|
208
|
+
logDuplication('Unhooking stdout', 'INFO');
|
|
209
|
+
// Clear monitoring interval
|
|
210
|
+
if (hookStdout.monitoringInterval) {
|
|
211
|
+
clearInterval(hookStdout.monitoringInterval);
|
|
212
|
+
logDuplication('Monitoring interval cleared', 'INFO');
|
|
213
|
+
}
|
|
214
|
+
process.stdout.write = originalWrite;
|
|
215
|
+
isHooked = false;
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=terminal-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-scanner.js","sourceRoot":"","sources":["../../../src/ui/utils/terminal-scanner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "centaurus-cli",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "A powerful command-line AI coding assistant with Google Gemini
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "A powerful command-line AI coding assistant with Google Gemini support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -21,26 +21,16 @@
|
|
|
21
21
|
"cli",
|
|
22
22
|
"coding-assistant",
|
|
23
23
|
"gemini",
|
|
24
|
-
"openrouter",
|
|
25
24
|
"agentic",
|
|
26
25
|
"code-editor",
|
|
27
26
|
"ai-assistant",
|
|
28
27
|
"terminal",
|
|
29
28
|
"developer-tools",
|
|
30
|
-
"chatgpt",
|
|
31
29
|
"llm",
|
|
32
30
|
"artificial-intelligence"
|
|
33
31
|
],
|
|
34
32
|
"author": "Rohan Abhilash S",
|
|
35
33
|
"license": "MIT",
|
|
36
|
-
"repository": {
|
|
37
|
-
"type": "git",
|
|
38
|
-
"url": "https://github.com/Rohan-Abhilash/centaurus-cli.git"
|
|
39
|
-
},
|
|
40
|
-
"bugs": {
|
|
41
|
-
"url": "https://github.com/Rohan-Abhilash/centaurus-cli/issues"
|
|
42
|
-
},
|
|
43
|
-
"homepage": "https://github.com/Rohan-Abhilash/centaurus-cli#readme",
|
|
44
34
|
"engines": {
|
|
45
35
|
"node": ">=18.0.0"
|
|
46
36
|
},
|
|
@@ -53,7 +43,6 @@
|
|
|
53
43
|
"AUTH_FLOW.md"
|
|
54
44
|
],
|
|
55
45
|
"dependencies": {
|
|
56
|
-
"@google/generative-ai": "^0.24.1",
|
|
57
46
|
"@types/node": "^24.7.2",
|
|
58
47
|
"@types/react": "^18.3.26",
|
|
59
48
|
"axios": "^1.12.2",
|