erosolar-cli 1.7.116 → 1.7.118

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.
@@ -1,372 +1,370 @@
1
1
  /**
2
- * EnhancedPinnedChatBox - Modified version of PinnedChatBox with persistent visibility during streaming
3
- * and enhanced paste handling
2
+ * Enhanced Pinned Chat Box - Persistent chat input during AI streaming
3
+ *
4
+ * Enhanced features:
5
+ * - Always visible at bottom during AI streaming
6
+ * - Supports typing while AI is streaming responses
7
+ * - Gracefully handles long pastes without errors
8
+ * - Only submits to AI when user hits enter key
9
+ * - Integrates with existing multiline paste handler
10
+ * - Shows paste summaries for large content
11
+ * - Input history navigation with up/down arrows
12
+ * - Visual feedback during streaming
4
13
  */
5
14
  import { theme } from './theme.js';
6
- import { ANSI } from './ansi.js';
15
+ import { processPaste, isMultilinePaste } from '../core/multilinePasteHandler.js';
7
16
  export class EnhancedPinnedChatBox {
8
17
  writeStream;
18
+ config;
9
19
  state;
10
- reservedLines = 2;
11
- _lastRenderedHeight = 0;
20
+ onSubmit;
21
+ onCancel;
22
+ isActive = false;
12
23
  inputBuffer = '';
13
24
  cursorPosition = 0;
14
- commandIdCounter = 0;
15
- onCommandQueued;
16
- onInputSubmit;
17
- renderScheduled = false;
18
- isEnabled = true;
19
- isDisposed = false;
20
- lastRenderTime = 0;
21
- renderThrottleMs = 16;
22
- maxInputLength = 10000;
23
- maxQueueSize = 100;
24
- ansiPattern = /[\u001B\u009B][[\]()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
25
- oscPattern = /\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g;
26
- maxStatusMessageLength = 200;
27
- // Scroll region management
28
- scrollRegionActive = false;
29
- // Input history
30
- inputHistory = [];
25
+ history = [];
31
26
  historyIndex = -1;
32
27
  tempCurrentInput = '';
33
- maxHistorySize = 100;
34
- // Enhanced paste tracking
35
- isPastedBlock = false;
36
- pastedFullContent = '';
37
- pasteStartTime = 0;
38
- pasteLineCount = 0;
39
- maxPasteLines = 50;
40
- outputInterceptorCleanup;
41
- constructor(writeStream, _promptText = '> ', options = {}) {
28
+ isPasteMode = false;
29
+ pasteBuffer = '';
30
+ renderScheduled = false;
31
+ lastRenderTime = 0;
32
+ renderThrottleMs = 16; // ~60fps max
33
+ constructor(writeStream, onSubmit, onCancel, config = {}) {
42
34
  this.writeStream = writeStream;
43
- this.onCommandQueued = options.onCommandQueued;
44
- this.onInputSubmit = options.onInputSubmit;
45
- this.maxInputLength = options.maxInputLength ?? this.maxInputLength;
46
- this.maxQueueSize = options.maxQueueSize ?? this.maxQueueSize;
35
+ this.onSubmit = onSubmit;
36
+ this.onCancel = onCancel;
37
+ this.config = {
38
+ enabled: true,
39
+ position: 1,
40
+ maxLines: 3,
41
+ showPasteSummaries: true,
42
+ autoScroll: true,
43
+ maxInputLength: 10000,
44
+ maxHistorySize: 100,
45
+ ...config,
46
+ };
47
47
  this.state = {
48
- isProcessing: false,
49
- queuedCommands: [],
50
- currentInput: '',
51
- contextUsage: 0,
48
+ input: '',
49
+ isStreaming: false,
50
+ isTyping: false,
51
+ isPasteMode: false,
52
+ cursorPosition: 0,
53
+ history: [],
54
+ historyIndex: -1,
52
55
  statusMessage: null,
53
- isVisible: true,
56
+ isProcessing: false,
54
57
  };
55
58
  }
56
59
  /**
57
- * Enhanced paste detection with summarization
60
+ * Handle character input
58
61
  */
59
- handlePaste(content) {
60
- if (this.isDisposed)
62
+ handleInput(char) {
63
+ if (!this.isActive)
64
+ return;
65
+ // Detect paste by checking for multiple lines or large content
66
+ if (char.includes('\n') && char.length > 100) {
67
+ this.handlePaste(char);
61
68
  return;
62
- const lines = content.split('\n');
63
- const lineCount = lines.length;
64
- const charCount = content.length;
65
- this.pasteStartTime = Date.now();
66
- this.pasteLineCount = lineCount;
67
- // For large pastes, show summary instead of full content
68
- if (lineCount > this.maxPasteLines || charCount > 2000) {
69
- this.isPastedBlock = true;
70
- this.pastedFullContent = content;
71
- const summaryLines = lines.slice(0, 5);
72
- const remainingLines = lineCount - 5;
73
- const summary = summaryLines.join('\n') +
74
- (remainingLines > 0 ? `\n... (${remainingLines} more lines)` : '');
75
- this.inputBuffer = summary;
76
- this.cursorPosition = summary.length;
77
- this.state.currentInput = summary;
78
- this.setStatusMessage(`📋 Pasted ${lineCount} lines, ${charCount} chars - hit Enter to submit`);
79
- }
80
- else {
81
- this.isPastedBlock = false;
82
- this.pastedFullContent = '';
83
- this.inputBuffer = content;
84
- this.cursorPosition = content.length;
85
- this.state.currentInput = content;
86
69
  }
87
- this.scheduleRender();
88
- }
89
- /**
90
- * Clear paste state
91
- */
92
- clearPastedBlock() {
93
- this.isPastedBlock = false;
94
- this.pastedFullContent = '';
95
- this.pasteStartTime = 0;
96
- this.pasteLineCount = 0;
70
+ // Normal character input
71
+ this.handleNormalInput(char);
97
72
  }
98
73
  /**
99
- * Handle character input with paste detection
74
+ * Handle normal character input
100
75
  */
101
- handleCharacter(char) {
102
- if (this.isDisposed)
76
+ handleNormalInput(char) {
77
+ // Respect max input length
78
+ const availableSpace = this.config.maxInputLength - this.inputBuffer.length;
79
+ if (availableSpace <= 0)
103
80
  return;
104
- const now = Date.now();
105
- if (this.pasteStartTime > 0 && now - this.pasteStartTime < 100) {
106
- // Rapid input detected - treat as paste continuation
107
- this.inputBuffer = this.inputBuffer.slice(0, this.cursorPosition) +
108
- char +
109
- this.inputBuffer.slice(this.cursorPosition);
110
- this.cursorPosition += char.length;
111
- this.state.currentInput = this.inputBuffer;
112
- this.scheduleRender();
81
+ const chunk = char.slice(0, availableSpace);
82
+ if (!chunk)
113
83
  return;
114
- }
115
- // Normal character input
116
- this.inputBuffer = this.inputBuffer.slice(0, this.cursorPosition) +
117
- char +
118
- this.inputBuffer.slice(this.cursorPosition);
119
- this.cursorPosition += char.length;
120
- this.state.currentInput = this.inputBuffer;
121
- this.clearPastedBlock();
84
+ // Insert character at cursor position
85
+ this.inputBuffer =
86
+ this.inputBuffer.slice(0, this.cursorPosition) +
87
+ chunk +
88
+ this.inputBuffer.slice(this.cursorPosition);
89
+ this.cursorPosition = Math.min(this.cursorPosition + chunk.length, this.inputBuffer.length);
90
+ this.updateState();
122
91
  this.scheduleRender();
123
92
  }
124
93
  /**
125
- * Handle Enter key - only submit when explicitly pressed
94
+ * Handle paste input
126
95
  */
127
- handleEnter() {
128
- if (this.isDisposed)
129
- return null;
130
- let input;
131
- // If we have a pasted block, use the full content
132
- if (this.isPastedBlock && this.pastedFullContent) {
133
- input = this.sanitizeCommandText(this.pastedFullContent);
96
+ handlePaste(content) {
97
+ this.isPasteMode = true;
98
+ this.pasteBuffer = content;
99
+ if (this.config.showPasteSummaries && isMultilinePaste(content)) {
100
+ const processed = processPaste(content);
101
+ this.setStatusMessage(processed.displaySummary);
134
102
  }
135
103
  else {
136
- input = this.sanitizeCommandText(this.inputBuffer);
104
+ this.setStatusMessage('📋 Paste detected - Press Enter to submit');
137
105
  }
138
- if (!input)
139
- return null;
140
- // Add to history before processing
141
- const historyEntry = this.isPastedBlock
142
- ? `[Pasted ${this.pasteLineCount} lines] ${input.slice(0, 100)}...`
143
- : input;
144
- this.addToHistory(historyEntry);
145
- // If processing, queue the command instead of submitting
146
- if (this.state.isProcessing) {
147
- const type = input.startsWith('/') ? 'slash' : 'request';
148
- const queued = this.queueCommand(input, type);
149
- if (!queued) {
150
- this.setStatusMessage(`Queue is full (${this.maxQueueSize}). Submit after current task or clear queued items.`);
151
- return null;
152
- }
153
- this.clearInput();
154
- return null;
155
- }
156
- // Clear input and paste state, then notify
157
- this.clearInput();
158
- if (this.onInputSubmit) {
159
- this.onInputSubmit(input);
160
- }
161
- return input;
106
+ this.updateState();
107
+ this.scheduleRender();
162
108
  }
163
109
  /**
164
- * Enhanced render that always shows during processing
110
+ * Submit current input
165
111
  */
166
- render() {
167
- if (!this.state.isVisible || !this.supportsRendering())
168
- return;
169
- // ALWAYS render during processing - use persistent input mode
170
- if (this.state.isProcessing) {
171
- this.renderPersistentInput();
112
+ submit() {
113
+ if (!this.isActive)
172
114
  return;
115
+ let inputToSubmit;
116
+ if (this.isPasteMode) {
117
+ // Submit paste content
118
+ inputToSubmit = this.pasteBuffer;
119
+ this.clearPasteMode();
173
120
  }
174
- // Not processing - render the standard status box
175
- this.lastRenderTime = Date.now();
176
- try {
177
- const cols = Math.max(this.writeStream.columns || 80, 40);
178
- const separatorWidth = Math.min(cols - 2, 72);
179
- // Build status message
180
- const statusParts = [];
181
- // Processing status
182
- if (this.state.statusMessage) {
183
- const maxLen = Math.max(20, cols - 30);
184
- const msg = this.state.statusMessage.length > maxLen
185
- ? `${this.state.statusMessage.slice(0, maxLen - 3)}...`
186
- : this.state.statusMessage;
187
- statusParts.push(theme.ui.muted(msg));
188
- }
189
- if (statusParts.length === 0) {
190
- // Not processing and no status - nothing to show
121
+ else {
122
+ // Submit normal input
123
+ inputToSubmit = this.inputBuffer.trim();
124
+ if (!inputToSubmit)
191
125
  return;
192
- }
193
- const statusLine = statusParts.join(' │ ');
194
- const separator = theme.ui.border('─'.repeat(separatorWidth));
195
- // Write the 3-line pinned box
196
- this.safeWrite(`\r${ANSI.CLEAR_LINE}${separator}\n`);
197
- this.safeWrite(`${ANSI.CLEAR_LINE}${statusLine}\n`);
198
- this.safeWrite(`${ANSI.CLEAR_LINE}${theme.ui.muted('>')} `);
199
- this._lastRenderedHeight = 3;
126
+ // Add to history
127
+ this.addToHistory(inputToSubmit);
128
+ }
129
+ // Clear input
130
+ this.clearInput();
131
+ // Submit to AI
132
+ this.onSubmit(inputToSubmit);
133
+ }
134
+ /**
135
+ * Cancel current input or paste
136
+ */
137
+ cancel() {
138
+ if (this.isPasteMode) {
139
+ // Cancel paste mode
140
+ this.clearPasteMode();
141
+ this.setStatusMessage('Paste cancelled');
200
142
  }
201
- catch {
202
- // Silently handle render errors
143
+ else {
144
+ // Call cancel callback
145
+ this.onCancel();
203
146
  }
204
147
  }
205
148
  /**
206
- * Render persistent input during processing
149
+ * Handle history navigation - up
207
150
  */
208
- renderPersistentInput() {
209
- if (!this.supportsRendering())
151
+ navigateHistoryUp() {
152
+ if (this.history.length === 0)
210
153
  return;
211
- const rows = this.writeStream.rows || 24;
212
- const cols = Math.max(this.writeStream.columns || 80, 40);
213
- // Save cursor position
214
- this.safeWrite(ANSI.SAVE_CURSOR);
215
- // Move to the reserved bottom area (outside scroll region)
216
- this.safeWrite(ANSI.CURSOR_TO_BOTTOM(rows - 1));
217
- // Build status line
218
- const queueCount = this.state.queuedCommands.length;
219
- let statusText = '';
220
- if (this.state.isProcessing) {
221
- const queuePart = queueCount > 0 ? ` (${queueCount} queued)` : '';
222
- statusText = `🔄 AI is streaming...${queuePart} [Enter: queue additional prompts]`;
154
+ if (this.historyIndex === -1) {
155
+ // Start navigating history, save current input
156
+ this.tempCurrentInput = this.inputBuffer;
157
+ this.historyIndex = 0;
223
158
  }
224
- else if (this.state.statusMessage) {
225
- statusText = this.state.statusMessage;
159
+ else if (this.historyIndex < this.history.length - 1) {
160
+ this.historyIndex++;
226
161
  }
227
- else if (queueCount > 0) {
228
- statusText = `${queueCount} follow-up${queueCount === 1 ? '' : 's'} queued`;
229
- }
230
- // Render separator and status on bottom lines
231
- const separatorWidth = Math.min(cols - 2, 72);
232
- const separator = theme.ui.border('─'.repeat(separatorWidth));
233
- // Line rows-1: separator
234
- this.safeWrite(ANSI.CLEAR_LINE);
235
- this.safeWrite(separator);
236
- // Line rows: input line with prompt or status
237
- this.safeWrite(`\n${ANSI.CLEAR_LINE}`);
238
- // Show actual input line during processing so user can see what they're typing
239
- const promptPrefix = theme.ui.muted('> ');
240
- const currentInput = this.inputBuffer;
241
- const maxInputDisplay = cols - 4;
242
- // Truncate input if too long, showing end of input
243
- let displayInput = currentInput;
244
- if (displayInput.length > maxInputDisplay) {
245
- displayInput = '…' + displayInput.slice(-(maxInputDisplay - 1));
162
+ const historyItem = this.history[this.historyIndex];
163
+ this.setInput(historyItem);
164
+ }
165
+ /**
166
+ * Handle history navigation - down
167
+ */
168
+ navigateHistoryDown() {
169
+ if (this.historyIndex === -1)
170
+ return;
171
+ if (this.historyIndex > 0) {
172
+ this.historyIndex--;
173
+ const historyItem = this.history[this.historyIndex];
174
+ this.setInput(historyItem);
246
175
  }
247
- // Render prompt + input
248
- this.safeWrite(promptPrefix);
249
- this.safeWrite(displayInput);
250
- // Show status hint on the right if there's room
251
- if (statusText && currentInput.length < maxInputDisplay - statusText.length - 5) {
252
- const padding = cols - 3 - currentInput.length - statusText.length - 3;
253
- if (padding > 3) {
254
- this.safeWrite(' '.repeat(padding));
255
- this.safeWrite(theme.ui.muted(statusText.slice(0, cols - currentInput.length - 6)));
256
- }
176
+ else if (this.historyIndex === 0) {
177
+ // Back to original input
178
+ this.historyIndex = -1;
179
+ this.setInput(this.tempCurrentInput);
180
+ this.tempCurrentInput = '';
257
181
  }
258
- // Restore cursor to scroll region
259
- this.safeWrite(ANSI.RESTORE_CURSOR);
260
182
  }
261
- // ... (other methods remain largely the same as PinnedChatBox)
262
- supportsRendering() {
263
- return this.isEnabled &&
264
- !this.isDisposed &&
265
- this.writeStream.writable &&
266
- this.writeStream.isTTY;
183
+ /**
184
+ * Set input text
185
+ */
186
+ setInput(text, cursorPos) {
187
+ this.inputBuffer = text.slice(0, this.config.maxInputLength);
188
+ this.cursorPosition = typeof cursorPos === 'number'
189
+ ? Math.max(0, Math.min(cursorPos, this.inputBuffer.length))
190
+ : this.inputBuffer.length;
191
+ this.updateState();
192
+ this.scheduleRender();
193
+ }
194
+ /**
195
+ * Clear input
196
+ */
197
+ clearInput() {
198
+ this.inputBuffer = '';
199
+ this.cursorPosition = 0;
200
+ this.historyIndex = -1;
201
+ this.tempCurrentInput = '';
202
+ this.updateState();
203
+ this.scheduleRender();
204
+ }
205
+ /**
206
+ * Clear paste mode
207
+ */
208
+ clearPasteMode() {
209
+ this.isPasteMode = false;
210
+ this.pasteBuffer = '';
211
+ this.clearStatusMessage();
267
212
  }
268
- safeWrite(content) {
269
- try {
270
- if (this.writeStream.writable) {
271
- this.writeStream.write(content);
213
+ /**
214
+ * Add input to history
215
+ */
216
+ addToHistory(input) {
217
+ if (input.trim() && this.history[0] !== input.trim()) {
218
+ this.history.unshift(input.trim());
219
+ if (this.history.length > this.config.maxHistorySize) {
220
+ this.history.pop();
272
221
  }
273
222
  }
274
- catch {
275
- // Swallow write errors
276
- }
277
223
  }
278
- sanitizeCommandText(text) {
279
- return text
280
- .replace(this.ansiPattern, '')
281
- .replace(this.oscPattern, '')
282
- .trim();
224
+ /**
225
+ * Set status message
226
+ */
227
+ setStatusMessage(message) {
228
+ this.state.statusMessage = message;
229
+ this.updateState();
230
+ this.scheduleRender();
283
231
  }
284
- sanitizeStatusMessage(message) {
285
- if (!message)
286
- return null;
287
- return message
288
- .replace(this.ansiPattern, '')
289
- .replace(this.oscPattern, '')
290
- .slice(0, this.maxStatusMessageLength);
232
+ /**
233
+ * Clear status message
234
+ */
235
+ clearStatusMessage() {
236
+ this.state.statusMessage = null;
237
+ this.updateState();
238
+ this.scheduleRender();
291
239
  }
292
- addToHistory(entry) {
293
- if (!entry.trim())
294
- return;
295
- const existingIndex = this.inputHistory.indexOf(entry);
296
- if (existingIndex >= 0) {
297
- this.inputHistory.splice(existingIndex, 1);
298
- }
299
- this.inputHistory.push(entry);
300
- if (this.inputHistory.length > this.maxHistorySize) {
301
- this.inputHistory = this.inputHistory.slice(-this.maxHistorySize);
302
- }
240
+ /**
241
+ * Update internal state
242
+ */
243
+ updateState() {
244
+ this.state.input = this.inputBuffer;
245
+ this.state.cursorPosition = this.cursorPosition;
246
+ this.state.isPasteMode = this.isPasteMode;
247
+ this.state.historyIndex = this.historyIndex;
303
248
  }
304
- setEnabled(enabled) {
305
- if (this.isDisposed)
306
- return;
307
- if (!enabled && this.isEnabled) {
308
- this.clear();
309
- }
310
- this.isEnabled = enabled;
311
- if (enabled) {
312
- this.scheduleRender();
313
- }
249
+ /**
250
+ * Set streaming state
251
+ */
252
+ setStreaming(isStreaming) {
253
+ this.state.isStreaming = isStreaming;
254
+ this.scheduleRender();
314
255
  }
256
+ /**
257
+ * Set processing state
258
+ */
315
259
  setProcessing(isProcessing) {
316
- if (this.isDisposed)
317
- return;
318
260
  this.state.isProcessing = isProcessing;
319
261
  this.scheduleRender();
320
262
  }
321
- setContextUsage(percentage) {
322
- if (this.isDisposed)
263
+ /**
264
+ * Activate the chat box
265
+ */
266
+ activate() {
267
+ if (this.isActive)
323
268
  return;
324
- const value = Number.isFinite(percentage) ? percentage : 0;
325
- this.state.contextUsage = Math.max(0, Math.min(100, value));
269
+ this.isActive = true;
270
+ this.clearInput();
271
+ this.setStatusMessage('Type while AI streams - Press Enter to send');
272
+ // Initial render
273
+ this.forceRender();
326
274
  }
327
- setStatusMessage(message) {
328
- if (this.isDisposed)
275
+ /**
276
+ * Deactivate the chat box
277
+ */
278
+ deactivate() {
279
+ this.isActive = false;
280
+ this.clearStatusMessage();
281
+ }
282
+ /**
283
+ * Schedule render (throttled)
284
+ */
285
+ scheduleRender() {
286
+ if (this.renderScheduled)
329
287
  return;
330
- this.state.statusMessage = this.sanitizeStatusMessage(message);
331
- this.scheduleRender();
288
+ this.renderScheduled = true;
289
+ setTimeout(() => {
290
+ this.renderScheduled = false;
291
+ this.render();
292
+ }, this.renderThrottleMs);
332
293
  }
333
- queueCommand(text, type = 'request') {
334
- if (this.isDisposed)
335
- return null;
336
- if (typeof text !== 'string')
337
- return null;
338
- const sanitizedText = this.sanitizeCommandText(text);
339
- if (!sanitizedText)
340
- return null;
341
- if (this.state.queuedCommands.length >= this.maxQueueSize) {
342
- const idx = this.state.queuedCommands.findIndex(c => c.type !== 'slash');
343
- if (idx >= 0) {
344
- this.state.queuedCommands.splice(idx, 1);
345
- }
346
- else {
347
- return null;
348
- }
294
+ /**
295
+ * Force immediate render
296
+ */
297
+ forceRender() {
298
+ this.render();
299
+ }
300
+ /**
301
+ * Render the chat box
302
+ */
303
+ render() {
304
+ if (!this.isActive)
305
+ return;
306
+ const now = Date.now();
307
+ if (now - this.lastRenderTime < this.renderThrottleMs) {
308
+ return;
349
309
  }
350
- const truncated = sanitizedText.slice(0, this.maxInputLength);
351
- const preview = truncated.length > 60 ? `${truncated.slice(0, 57)}...` : truncated;
352
- const cmd = {
353
- id: `cmd-${++this.commandIdCounter}`,
354
- text: truncated,
355
- type,
356
- timestamp: Date.now(),
357
- preview,
358
- };
359
- this.state.queuedCommands.push(cmd);
360
- this.scheduleRender();
361
- if (this.onCommandQueued) {
362
- this.onCommandQueued(cmd);
310
+ this.lastRenderTime = now;
311
+ // Clear the status area
312
+ this.writeStream.write('\x1B[s'); // Save cursor position
313
+ // Move to bottom position
314
+ this.writeStream.write(`\x1B[${this.config.position}B`);
315
+ this.writeStream.write('\x1B[2K\r'); // Clear line
316
+ // Render status message if present
317
+ if (this.state.statusMessage) {
318
+ this.writeStream.write(`${theme.info(this.state.statusMessage)}\n`);
319
+ this.writeStream.write('\x1B[2K\r'); // Clear next line
363
320
  }
364
- return cmd;
321
+ // Render input prompt
322
+ let prompt;
323
+ if (this.state.isStreaming) {
324
+ prompt = `${theme.info('◉')} ${theme.ui.muted('Type while AI streams (Enter to send)')}: `;
325
+ }
326
+ else if (this.state.isProcessing) {
327
+ prompt = `${theme.warning('◐')} ${theme.ui.muted('Processing...')}: `;
328
+ }
329
+ else {
330
+ prompt = `${theme.success('>')} `;
331
+ }
332
+ // Render input with cursor
333
+ const displayInput = this.isPasteMode
334
+ ? `${theme.accent(this.inputBuffer)}`
335
+ : this.inputBuffer;
336
+ this.writeStream.write(`${prompt}${displayInput}`);
337
+ // Position cursor
338
+ const cursorOffset = prompt.length + this.cursorPosition;
339
+ this.writeStream.write(`\x1B[${cursorOffset}G`);
340
+ // Restore cursor position
341
+ this.writeStream.write('\x1B[u');
365
342
  }
366
- clearQueue() {
367
- if (this.isDisposed)
368
- return;
369
- this.state.que;
343
+ /**
344
+ * Get current state
345
+ */
346
+ getState() {
347
+ return { ...this.state };
348
+ }
349
+ /**
350
+ * Get config
351
+ */
352
+ getConfig() {
353
+ return { ...this.config };
354
+ }
355
+ /**
356
+ * Update config
357
+ */
358
+ updateConfig(config) {
359
+ this.config = { ...this.config, ...config };
360
+ }
361
+ /**
362
+ * Dispose of resources
363
+ */
364
+ dispose() {
365
+ this.deactivate();
366
+ this.clearInput();
367
+ this.clearStatusMessage();
370
368
  }
371
369
  }
372
- //# sourceMappingURL=enhancedPinnedChatBox.js.map
370
+ //# sourceMappingURL=EnhancedPinnedChatBox.js.map