@vybestack/llxprt-code 0.3.4 → 0.4.1-nightly.250923.fc764b9f
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/README.md +3 -0
- package/dist/package.json +7 -6
- package/dist/src/auth/anthropic-oauth-provider.d.ts +4 -0
- package/dist/src/auth/anthropic-oauth-provider.js +14 -0
- package/dist/src/auth/anthropic-oauth-provider.js.map +1 -1
- package/dist/src/auth/gemini-oauth-provider.d.ts +7 -1
- package/dist/src/auth/gemini-oauth-provider.js +48 -9
- package/dist/src/auth/gemini-oauth-provider.js.map +1 -1
- package/dist/src/auth/qwen-oauth-provider.d.ts +5 -1
- package/dist/src/auth/qwen-oauth-provider.js +6 -0
- package/dist/src/auth/qwen-oauth-provider.js.map +1 -1
- package/dist/src/commands/extensions/examples/context/LLXPRT.md +8 -0
- package/dist/src/commands/extensions/examples/context/llxprt-extension.json +5 -0
- package/dist/src/commands/extensions/examples/custom-commands/commands/fs/grep-code.toml +6 -0
- package/dist/src/commands/extensions/examples/custom-commands/llxprt-extension.json +4 -0
- package/dist/src/commands/extensions/examples/exclude-tools/llxprt-extension.json +5 -0
- package/dist/src/commands/extensions/examples/mcp-server/example.d.ts +6 -0
- package/dist/src/commands/extensions/examples/mcp-server/example.js +46 -0
- package/dist/src/commands/extensions/examples/mcp-server/example.js.map +1 -0
- package/dist/src/commands/extensions/examples/mcp-server/example.ts +60 -0
- package/dist/src/commands/extensions/examples/mcp-server/llxprt-extension.json +10 -0
- package/dist/src/commands/extensions/install.js +35 -7
- package/dist/src/commands/extensions/install.js.map +1 -1
- package/dist/src/commands/extensions/install.test.js +20 -2
- package/dist/src/commands/extensions/install.test.js.map +1 -1
- package/dist/src/commands/extensions/link.d.ts +12 -0
- package/dist/src/commands/extensions/link.js +37 -0
- package/dist/src/commands/extensions/link.js.map +1 -0
- package/dist/src/commands/extensions/new.d.ts +7 -0
- package/dist/src/commands/extensions/new.js +70 -0
- package/dist/src/commands/extensions/new.js.map +1 -0
- package/dist/src/commands/extensions/new.test.d.ts +6 -0
- package/dist/src/commands/extensions/new.test.js +50 -0
- package/dist/src/commands/extensions/new.test.js.map +1 -0
- package/dist/src/commands/extensions/update.d.ts +2 -1
- package/dist/src/commands/extensions/update.js +40 -13
- package/dist/src/commands/extensions/update.js.map +1 -1
- package/dist/src/commands/extensions.js +4 -0
- package/dist/src/commands/extensions.js.map +1 -1
- package/dist/src/commands/mcp/add.js +1 -1
- package/dist/src/commands/mcp/add.js.map +1 -1
- package/dist/src/commands/mcp/list.js +2 -2
- package/dist/src/commands/mcp/list.js.map +1 -1
- package/dist/src/commands/mcp/remove.js +1 -1
- package/dist/src/commands/mcp/remove.js.map +1 -1
- package/dist/src/config/auth.d.ts +1 -1
- package/dist/src/config/auth.js +6 -13
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/auth.test.js +13 -7
- package/dist/src/config/auth.test.js.map +1 -1
- package/dist/src/config/config.d.ts +4 -1
- package/dist/src/config/config.js +47 -23
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/extension.d.ts +8 -5
- package/dist/src/config/extension.js +76 -24
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +1 -0
- package/dist/src/config/keyBindings.js +6 -25
- package/dist/src/config/keyBindings.js.map +1 -1
- package/dist/src/config/settings.d.ts +4 -4
- package/dist/src/config/settings.js +101 -68
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +252 -3
- package/dist/src/config/settingsSchema.js +248 -3
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/trustedFolders.d.ts +14 -3
- package/dist/src/config/trustedFolders.js +63 -37
- package/dist/src/config/trustedFolders.js.map +1 -1
- package/dist/src/config/trustedFolders.test.js +84 -9
- package/dist/src/config/trustedFolders.test.js.map +1 -1
- package/dist/src/gemini.js +74 -18
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +7 -23
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/nonInteractiveCli.js +32 -2
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.d.ts +2 -1
- package/dist/src/providers/providerManagerInstance.js +27 -5
- package/dist/src/providers/providerManagerInstance.js.map +1 -1
- package/dist/src/services/FileCommandLoader.d.ts +2 -0
- package/dist/src/services/FileCommandLoader.js +7 -0
- package/dist/src/services/FileCommandLoader.js.map +1 -1
- package/dist/src/ui/App.js +104 -52
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.js +1 -1
- package/dist/src/ui/commands/directoryCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.js +1 -1
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +21 -8
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.test.js +13 -13
- package/dist/src/ui/components/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.js +5 -3
- package/dist/src/ui/components/FolderTrustDialog.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js +21 -6
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/Footer.d.ts +3 -0
- package/dist/src/ui/components/Footer.js +4 -4
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/GeminiRespondingSpinner.js +5 -3
- package/dist/src/ui/components/GeminiRespondingSpinner.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.d.ts +2 -2
- package/dist/src/ui/components/InputPrompt.js +35 -25
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/MemoryUsageDisplay.js +1 -1
- package/dist/src/ui/components/MemoryUsageDisplay.js.map +1 -1
- package/dist/src/ui/components/ProQuotaDialog.d.ts +13 -0
- package/dist/src/ui/components/ProQuotaDialog.js +22 -0
- package/dist/src/ui/components/ProQuotaDialog.js.map +1 -0
- package/dist/src/ui/components/ProQuotaDialog.test.d.ts +6 -0
- package/dist/src/ui/components/ProQuotaDialog.test.js +57 -0
- package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -0
- package/dist/src/ui/components/SettingsDialog.js +4 -6
- package/dist/src/ui/components/SettingsDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +2 -2
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js +7 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
- package/dist/src/ui/components/TodoPanel.js +75 -10
- package/dist/src/ui/components/TodoPanel.js.map +1 -1
- package/dist/src/ui/components/messages/CompressionMessage.js +1 -1
- package/dist/src/ui/components/messages/CompressionMessage.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.js +5 -1
- package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
- package/dist/src/ui/components/messages/GeminiMessage.js +1 -1
- package/dist/src/ui/components/messages/GeminiMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +0 -8
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolMessage.js +2 -1
- package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
- package/dist/src/ui/components/messages/UserMessage.js +1 -1
- package/dist/src/ui/components/messages/UserMessage.js.map +1 -1
- package/dist/src/ui/components/shared/MaxSizedBox.js.map +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.js +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js +2 -2
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.js +35 -51
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/constants.d.ts +8 -2
- package/dist/src/ui/constants.js +9 -2
- package/dist/src/ui/constants.js.map +1 -1
- package/dist/src/ui/containers/SessionController.js +1 -1
- package/dist/src/ui/containers/SessionController.js.map +1 -1
- package/dist/src/ui/containers/SessionController.test.js +1 -0
- package/dist/src/ui/containers/SessionController.test.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.js +255 -42
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +115 -1
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +3 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.js +6 -3
- package/dist/src/ui/hooks/useFolderTrust.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.d.ts +2 -1
- package/dist/src/ui/hooks/useGeminiStream.integration.test.js +1 -1
- package/dist/src/ui/hooks/useGeminiStream.integration.test.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +170 -35
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useIdeTrustListener.d.ts +15 -0
- package/dist/src/ui/hooks/useIdeTrustListener.js +37 -0
- package/dist/src/ui/hooks/useIdeTrustListener.js.map +1 -0
- package/dist/src/ui/hooks/useInputHistoryStore.d.ts +19 -0
- package/dist/src/ui/hooks/useInputHistoryStore.js +81 -0
- package/dist/src/ui/hooks/useInputHistoryStore.js.map +1 -0
- package/dist/src/ui/hooks/useInputHistoryStore.test.d.ts +6 -0
- package/dist/src/ui/hooks/useInputHistoryStore.test.js +234 -0
- package/dist/src/ui/hooks/useInputHistoryStore.test.js.map +1 -0
- package/dist/src/ui/hooks/useLoadingIndicator.d.ts +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.js +2 -2
- package/dist/src/ui/hooks/useLoadingIndicator.js.map +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.test.d.ts +6 -0
- package/dist/src/ui/hooks/useLoadingIndicator.test.js +102 -0
- package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -0
- package/dist/src/ui/hooks/usePhraseCycler.d.ts +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.js +25 -17
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.d.ts +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.js +20 -13
- package/dist/src/ui/hooks/usePrivacySettings.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.test.js +52 -105
- package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -1
- package/dist/src/ui/hooks/useTerminalSize.js +22 -8
- package/dist/src/ui/hooks/useTerminalSize.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +57 -70
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/keyMatchers.test.js +9 -0
- package/dist/src/ui/keyMatchers.test.js.map +1 -1
- package/dist/src/ui/textConstants.d.ts +9 -0
- package/dist/src/ui/textConstants.js +10 -0
- package/dist/src/ui/textConstants.js.map +1 -0
- package/dist/src/ui/utils/MarkdownDisplay.test.js +2 -2
- package/dist/src/ui/utils/MarkdownDisplay.test.js.map +1 -1
- package/dist/src/ui/utils/highlight.d.ts +10 -0
- package/dist/src/ui/utils/highlight.js +41 -0
- package/dist/src/ui/utils/highlight.js.map +1 -0
- package/dist/src/ui/utils/highlight.test.d.ts +6 -0
- package/dist/src/ui/utils/highlight.test.js +93 -0
- package/dist/src/ui/utils/highlight.test.js.map +1 -0
- package/dist/src/ui/utils/platformConstants.d.ts +24 -1
- package/dist/src/ui/utils/platformConstants.js +26 -1
- package/dist/src/ui/utils/platformConstants.js.map +1 -1
- package/dist/src/utils/envVarResolver.d.ts +39 -0
- package/dist/src/utils/envVarResolver.js +97 -0
- package/dist/src/utils/envVarResolver.js.map +1 -0
- package/dist/src/utils/envVarResolver.test.d.ts +6 -0
- package/dist/src/utils/envVarResolver.test.js +221 -0
- package/dist/src/utils/envVarResolver.test.js.map +1 -0
- package/dist/src/utils/errors.d.ts +9 -0
- package/dist/src/utils/errors.js +18 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/settingsUtils.js +5 -7
- package/dist/src/utils/settingsUtils.js.map +1 -1
- package/dist/src/utils/singleSettingSaver.d.ts +7 -0
- package/dist/src/utils/singleSettingSaver.js +45 -0
- package/dist/src/utils/singleSettingSaver.js.map +1 -0
- package/dist/src/utils/userStartupWarnings.d.ts +1 -1
- package/dist/src/utils/userStartupWarnings.js +1 -1
- package/dist/src/utils/userStartupWarnings.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +398 -398
- package/dist/src/zed-integration/zedIntegration.js +11 -7
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -6
@@ -0,0 +1,234 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Google LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { act, renderHook } from '@testing-library/react';
|
7
|
+
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
8
|
+
import { useInputHistoryStore } from './useInputHistoryStore.js';
|
9
|
+
describe('useInputHistoryStore', () => {
|
10
|
+
beforeEach(() => {
|
11
|
+
vi.clearAllMocks();
|
12
|
+
});
|
13
|
+
it('should initialize with empty input history', () => {
|
14
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
15
|
+
expect(result.current.inputHistory).toEqual([]);
|
16
|
+
});
|
17
|
+
it('should add input to history', () => {
|
18
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
19
|
+
act(() => {
|
20
|
+
result.current.addInput('test message 1');
|
21
|
+
});
|
22
|
+
expect(result.current.inputHistory).toEqual(['test message 1']);
|
23
|
+
act(() => {
|
24
|
+
result.current.addInput('test message 2');
|
25
|
+
});
|
26
|
+
expect(result.current.inputHistory).toEqual([
|
27
|
+
'test message 1',
|
28
|
+
'test message 2',
|
29
|
+
]);
|
30
|
+
});
|
31
|
+
it('should not add empty or whitespace-only inputs', () => {
|
32
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
33
|
+
act(() => {
|
34
|
+
result.current.addInput('');
|
35
|
+
});
|
36
|
+
expect(result.current.inputHistory).toEqual([]);
|
37
|
+
act(() => {
|
38
|
+
result.current.addInput(' ');
|
39
|
+
});
|
40
|
+
expect(result.current.inputHistory).toEqual([]);
|
41
|
+
});
|
42
|
+
it('should deduplicate consecutive identical messages', () => {
|
43
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
44
|
+
act(() => {
|
45
|
+
result.current.addInput('test message');
|
46
|
+
});
|
47
|
+
act(() => {
|
48
|
+
result.current.addInput('test message'); // Same as previous
|
49
|
+
});
|
50
|
+
expect(result.current.inputHistory).toEqual(['test message']);
|
51
|
+
act(() => {
|
52
|
+
result.current.addInput('different message');
|
53
|
+
});
|
54
|
+
act(() => {
|
55
|
+
result.current.addInput('test message'); // Same as first, but not consecutive
|
56
|
+
});
|
57
|
+
expect(result.current.inputHistory).toEqual([
|
58
|
+
'test message',
|
59
|
+
'different message',
|
60
|
+
'test message',
|
61
|
+
]);
|
62
|
+
});
|
63
|
+
it('should initialize from logger successfully', async () => {
|
64
|
+
const mockLogger = {
|
65
|
+
getPreviousUserMessages: vi
|
66
|
+
.fn()
|
67
|
+
.mockResolvedValue(['newest', 'middle', 'oldest']),
|
68
|
+
};
|
69
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
70
|
+
await act(async () => {
|
71
|
+
await result.current.initializeFromLogger(mockLogger);
|
72
|
+
});
|
73
|
+
// Should reverse the order to oldest first
|
74
|
+
expect(result.current.inputHistory).toEqual(['oldest', 'middle', 'newest']);
|
75
|
+
expect(mockLogger.getPreviousUserMessages).toHaveBeenCalledTimes(1);
|
76
|
+
});
|
77
|
+
it('should handle logger initialization failure gracefully', async () => {
|
78
|
+
const mockLogger = {
|
79
|
+
getPreviousUserMessages: vi
|
80
|
+
.fn()
|
81
|
+
.mockRejectedValue(new Error('Logger error')),
|
82
|
+
};
|
83
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
84
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
85
|
+
await act(async () => {
|
86
|
+
await result.current.initializeFromLogger(mockLogger);
|
87
|
+
});
|
88
|
+
expect(result.current.inputHistory).toEqual([]);
|
89
|
+
expect(consoleSpy).toHaveBeenCalledWith('Failed to initialize input history from logger:', expect.any(Error));
|
90
|
+
consoleSpy.mockRestore();
|
91
|
+
});
|
92
|
+
it('should initialize only once', async () => {
|
93
|
+
const mockLogger = {
|
94
|
+
getPreviousUserMessages: vi
|
95
|
+
.fn()
|
96
|
+
.mockResolvedValue(['message1', 'message2']),
|
97
|
+
};
|
98
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
99
|
+
// Call initializeFromLogger twice
|
100
|
+
await act(async () => {
|
101
|
+
await result.current.initializeFromLogger(mockLogger);
|
102
|
+
});
|
103
|
+
await act(async () => {
|
104
|
+
await result.current.initializeFromLogger(mockLogger);
|
105
|
+
});
|
106
|
+
// Should be called only once
|
107
|
+
expect(mockLogger.getPreviousUserMessages).toHaveBeenCalledTimes(1);
|
108
|
+
expect(result.current.inputHistory).toEqual(['message2', 'message1']);
|
109
|
+
});
|
110
|
+
it('should handle null logger gracefully', async () => {
|
111
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
112
|
+
await act(async () => {
|
113
|
+
await result.current.initializeFromLogger(null);
|
114
|
+
});
|
115
|
+
expect(result.current.inputHistory).toEqual([]);
|
116
|
+
});
|
117
|
+
it('should trim input before adding to history', () => {
|
118
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
119
|
+
act(() => {
|
120
|
+
result.current.addInput(' test message ');
|
121
|
+
});
|
122
|
+
expect(result.current.inputHistory).toEqual(['test message']);
|
123
|
+
});
|
124
|
+
describe('deduplication logic from previous implementation', () => {
|
125
|
+
it('should deduplicate consecutive messages from past sessions during initialization', async () => {
|
126
|
+
const mockLogger = {
|
127
|
+
getPreviousUserMessages: vi
|
128
|
+
.fn()
|
129
|
+
.mockResolvedValue([
|
130
|
+
'message1',
|
131
|
+
'message1',
|
132
|
+
'message2',
|
133
|
+
'message2',
|
134
|
+
'message3',
|
135
|
+
]), // newest first with duplicates
|
136
|
+
};
|
137
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
138
|
+
await act(async () => {
|
139
|
+
await result.current.initializeFromLogger(mockLogger);
|
140
|
+
});
|
141
|
+
// Should deduplicate consecutive messages and reverse to oldest first
|
142
|
+
expect(result.current.inputHistory).toEqual([
|
143
|
+
'message3',
|
144
|
+
'message2',
|
145
|
+
'message1',
|
146
|
+
]);
|
147
|
+
});
|
148
|
+
it('should deduplicate across session boundaries', async () => {
|
149
|
+
const mockLogger = {
|
150
|
+
getPreviousUserMessages: vi.fn().mockResolvedValue(['old2', 'old1']), // newest first
|
151
|
+
};
|
152
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
153
|
+
// Initialize with past session
|
154
|
+
await act(async () => {
|
155
|
+
await result.current.initializeFromLogger(mockLogger);
|
156
|
+
});
|
157
|
+
// Add current session inputs
|
158
|
+
act(() => {
|
159
|
+
result.current.addInput('old2'); // Same as last past session message
|
160
|
+
});
|
161
|
+
// Should deduplicate across session boundary
|
162
|
+
expect(result.current.inputHistory).toEqual(['old1', 'old2']);
|
163
|
+
act(() => {
|
164
|
+
result.current.addInput('new1');
|
165
|
+
});
|
166
|
+
expect(result.current.inputHistory).toEqual(['old1', 'old2', 'new1']);
|
167
|
+
});
|
168
|
+
it('should preserve non-consecutive duplicates', async () => {
|
169
|
+
const mockLogger = {
|
170
|
+
getPreviousUserMessages: vi
|
171
|
+
.fn()
|
172
|
+
.mockResolvedValue(['message2', 'message1', 'message2']), // newest first with non-consecutive duplicate
|
173
|
+
};
|
174
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
175
|
+
await act(async () => {
|
176
|
+
await result.current.initializeFromLogger(mockLogger);
|
177
|
+
});
|
178
|
+
// Non-consecutive duplicates should be preserved
|
179
|
+
expect(result.current.inputHistory).toEqual([
|
180
|
+
'message2',
|
181
|
+
'message1',
|
182
|
+
'message2',
|
183
|
+
]);
|
184
|
+
});
|
185
|
+
it('should handle complex deduplication with current session', () => {
|
186
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
187
|
+
// Add multiple messages with duplicates
|
188
|
+
act(() => {
|
189
|
+
result.current.addInput('hello');
|
190
|
+
});
|
191
|
+
act(() => {
|
192
|
+
result.current.addInput('hello'); // consecutive duplicate
|
193
|
+
});
|
194
|
+
act(() => {
|
195
|
+
result.current.addInput('world');
|
196
|
+
});
|
197
|
+
act(() => {
|
198
|
+
result.current.addInput('world'); // consecutive duplicate
|
199
|
+
});
|
200
|
+
act(() => {
|
201
|
+
result.current.addInput('hello'); // non-consecutive duplicate
|
202
|
+
});
|
203
|
+
// Should have deduplicated consecutive ones
|
204
|
+
expect(result.current.inputHistory).toEqual(['hello', 'world', 'hello']);
|
205
|
+
});
|
206
|
+
it('should maintain oldest-first order in final output', async () => {
|
207
|
+
const mockLogger = {
|
208
|
+
getPreviousUserMessages: vi
|
209
|
+
.fn()
|
210
|
+
.mockResolvedValue(['newest', 'middle', 'oldest']), // newest first
|
211
|
+
};
|
212
|
+
const { result } = renderHook(() => useInputHistoryStore());
|
213
|
+
await act(async () => {
|
214
|
+
await result.current.initializeFromLogger(mockLogger);
|
215
|
+
});
|
216
|
+
// Add current session messages
|
217
|
+
act(() => {
|
218
|
+
result.current.addInput('current1');
|
219
|
+
});
|
220
|
+
act(() => {
|
221
|
+
result.current.addInput('current2');
|
222
|
+
});
|
223
|
+
// Should maintain oldest-first order
|
224
|
+
expect(result.current.inputHistory).toEqual([
|
225
|
+
'oldest',
|
226
|
+
'middle',
|
227
|
+
'newest',
|
228
|
+
'current1',
|
229
|
+
'current2',
|
230
|
+
]);
|
231
|
+
});
|
232
|
+
});
|
233
|
+
});
|
234
|
+
//# sourceMappingURL=useInputHistoryStore.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useInputHistoryStore.test.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useInputHistoryStore.test.ts"],"names":[],"mappings":"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"}
|
@@ -4,7 +4,7 @@
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
5
5
|
*/
|
6
6
|
import { StreamingState } from '../types.js';
|
7
|
-
export declare const useLoadingIndicator: (streamingState: StreamingState) => {
|
7
|
+
export declare const useLoadingIndicator: (streamingState: StreamingState, customWittyPhrases?: string[]) => {
|
8
8
|
elapsedTime: number;
|
9
9
|
currentLoadingPhrase: string;
|
10
10
|
};
|
@@ -7,13 +7,13 @@ import { StreamingState } from '../types.js';
|
|
7
7
|
import { useTimer } from './useTimer.js';
|
8
8
|
import { usePhraseCycler } from './usePhraseCycler.js';
|
9
9
|
import { useState, useEffect, useRef } from 'react'; // Added useRef
|
10
|
-
export const useLoadingIndicator = (streamingState) => {
|
10
|
+
export const useLoadingIndicator = (streamingState, customWittyPhrases) => {
|
11
11
|
const [timerResetKey, setTimerResetKey] = useState(0);
|
12
12
|
const isTimerActive = streamingState === StreamingState.Responding;
|
13
13
|
const elapsedTimeFromTimer = useTimer(isTimerActive, timerResetKey);
|
14
14
|
const isPhraseCyclingActive = streamingState === StreamingState.Responding;
|
15
15
|
const isWaiting = streamingState === StreamingState.WaitingForConfirmation;
|
16
|
-
const currentLoadingPhrase = usePhraseCycler(isPhraseCyclingActive, isWaiting);
|
16
|
+
const currentLoadingPhrase = usePhraseCycler(isPhraseCyclingActive, isWaiting, customWittyPhrases);
|
17
17
|
const [retainedElapsedTime, setRetainedElapsedTime] = useState(0);
|
18
18
|
const prevStreamingStateRef = useRef(null);
|
19
19
|
useEffect(() => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useLoadingIndicator.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useLoadingIndicator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,eAAe;AAEpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,
|
1
|
+
{"version":3,"file":"useLoadingIndicator.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useLoadingIndicator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,eAAe;AAEpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,cAA8B,EAC9B,kBAA6B,EAC7B,EAAE;IACF,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,aAAa,GAAG,cAAc,KAAK,cAAc,CAAC,UAAU,CAAC;IAEnE,MAAM,oBAAoB,GAAG,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IAEpE,MAAM,qBAAqB,GAAG,cAAc,KAAK,cAAc,CAAC,UAAU,CAAC;IAC3E,MAAM,SAAS,GAAG,cAAc,KAAK,cAAc,CAAC,sBAAsB,CAAC;IAC3E,MAAM,oBAAoB,GAAG,eAAe,CAC1C,qBAAqB,EACrB,SAAS,EACT,kBAAkB,CACnB,CAAC;IAEF,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,qBAAqB,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IAElE,SAAS,CAAC,GAAG,EAAE;QACb,IACE,qBAAqB,CAAC,OAAO,KAAK,cAAc,CAAC,sBAAsB;YACvE,cAAc,KAAK,cAAc,CAAC,UAAU,EAC5C,CAAC;YACD,gBAAgB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YAC3C,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,oDAAoD;QACjF,CAAC;aAAM,IACL,cAAc,KAAK,cAAc,CAAC,IAAI;YACtC,qBAAqB,CAAC,OAAO,KAAK,cAAc,CAAC,UAAU,EAC3D,CAAC;YACD,gBAAgB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,iDAAiD;YAC7F,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,cAAc,KAAK,cAAc,CAAC,sBAAsB,EAAE,CAAC;YACpE,wDAAwD;YACxD,kFAAkF;YAClF,sBAAsB,CAAC,oBAAoB,CAAC,CAAC;QAC/C,CAAC;QAED,qBAAqB,CAAC,OAAO,GAAG,cAAc,CAAC;IACjD,CAAC,EAAE,CAAC,cAAc,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAE3C,OAAO;QACL,WAAW,EACT,cAAc,KAAK,cAAc,CAAC,sBAAsB;YACtD,CAAC,CAAC,mBAAmB;YACrB,CAAC,CAAC,oBAAoB;QAC1B,oBAAoB;KACrB,CAAC;AACJ,CAAC,CAAC"}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
7
|
+
import { renderHook, act } from '@testing-library/react';
|
8
|
+
import { useLoadingIndicator } from './useLoadingIndicator.js';
|
9
|
+
import { StreamingState } from '../types.js';
|
10
|
+
import { WITTY_LOADING_PHRASES, PHRASE_CHANGE_INTERVAL_MS, } from './usePhraseCycler.js';
|
11
|
+
describe('useLoadingIndicator', () => {
|
12
|
+
beforeEach(() => {
|
13
|
+
vi.useFakeTimers();
|
14
|
+
});
|
15
|
+
afterEach(() => {
|
16
|
+
vi.useRealTimers(); // Restore real timers after each test
|
17
|
+
act(() => vi.runOnlyPendingTimers);
|
18
|
+
});
|
19
|
+
it('should initialize with default values when Idle', () => {
|
20
|
+
const { result } = renderHook(() => useLoadingIndicator(StreamingState.Idle));
|
21
|
+
expect(result.current.elapsedTime).toBe(0);
|
22
|
+
expect(WITTY_LOADING_PHRASES).toContain(result.current.currentLoadingPhrase);
|
23
|
+
});
|
24
|
+
it('should reflect values when Responding', async () => {
|
25
|
+
const { result } = renderHook(() => useLoadingIndicator(StreamingState.Responding));
|
26
|
+
// Initial state before timers advance
|
27
|
+
expect(result.current.elapsedTime).toBe(0);
|
28
|
+
expect(WITTY_LOADING_PHRASES).toContain(result.current.currentLoadingPhrase);
|
29
|
+
await act(async () => {
|
30
|
+
await vi.advanceTimersByTimeAsync(PHRASE_CHANGE_INTERVAL_MS + 1);
|
31
|
+
});
|
32
|
+
// Phrase should cycle if PHRASE_CHANGE_INTERVAL_MS has passed
|
33
|
+
expect(WITTY_LOADING_PHRASES).toContain(result.current.currentLoadingPhrase);
|
34
|
+
});
|
35
|
+
it('should show waiting phrase and retain elapsedTime when WaitingForConfirmation', async () => {
|
36
|
+
const { result, rerender } = renderHook(({ streamingState }) => useLoadingIndicator(streamingState), { initialProps: { streamingState: StreamingState.Responding } });
|
37
|
+
await act(async () => {
|
38
|
+
await vi.advanceTimersByTimeAsync(60000);
|
39
|
+
});
|
40
|
+
expect(result.current.elapsedTime).toBe(60);
|
41
|
+
act(() => {
|
42
|
+
rerender({ streamingState: StreamingState.WaitingForConfirmation });
|
43
|
+
});
|
44
|
+
expect(result.current.currentLoadingPhrase).toBe('Waiting for user confirmation...');
|
45
|
+
expect(result.current.elapsedTime).toBe(60); // Elapsed time should be retained
|
46
|
+
// Timer should not advance further
|
47
|
+
await act(async () => {
|
48
|
+
await vi.advanceTimersByTimeAsync(2000);
|
49
|
+
});
|
50
|
+
expect(result.current.elapsedTime).toBe(60);
|
51
|
+
});
|
52
|
+
it('should reset elapsedTime and use a witty phrase when transitioning from WaitingForConfirmation to Responding', async () => {
|
53
|
+
const { result, rerender } = renderHook(({ streamingState }) => useLoadingIndicator(streamingState), { initialProps: { streamingState: StreamingState.Responding } });
|
54
|
+
await act(async () => {
|
55
|
+
await vi.advanceTimersByTimeAsync(5000); // 5s
|
56
|
+
});
|
57
|
+
expect(result.current.elapsedTime).toBe(5);
|
58
|
+
act(() => {
|
59
|
+
rerender({ streamingState: StreamingState.WaitingForConfirmation });
|
60
|
+
});
|
61
|
+
expect(result.current.elapsedTime).toBe(5);
|
62
|
+
expect(result.current.currentLoadingPhrase).toBe('Waiting for user confirmation...');
|
63
|
+
act(() => {
|
64
|
+
rerender({ streamingState: StreamingState.Responding });
|
65
|
+
});
|
66
|
+
expect(result.current.elapsedTime).toBe(0); // Should reset
|
67
|
+
expect(WITTY_LOADING_PHRASES).toContain(result.current.currentLoadingPhrase);
|
68
|
+
await act(async () => {
|
69
|
+
await vi.advanceTimersByTimeAsync(1000);
|
70
|
+
});
|
71
|
+
expect(result.current.elapsedTime).toBe(1);
|
72
|
+
});
|
73
|
+
it('should reset timer and phrase when streamingState changes from Responding to Idle', async () => {
|
74
|
+
const { result, rerender } = renderHook(({ streamingState }) => useLoadingIndicator(streamingState), { initialProps: { streamingState: StreamingState.Responding } });
|
75
|
+
await act(async () => {
|
76
|
+
await vi.advanceTimersByTimeAsync(10000); // 10s
|
77
|
+
});
|
78
|
+
expect(result.current.elapsedTime).toBe(10);
|
79
|
+
act(() => {
|
80
|
+
rerender({ streamingState: StreamingState.Idle });
|
81
|
+
});
|
82
|
+
expect(result.current.elapsedTime).toBe(0);
|
83
|
+
expect(WITTY_LOADING_PHRASES).toContain(result.current.currentLoadingPhrase);
|
84
|
+
// Timer should not advance
|
85
|
+
await act(async () => {
|
86
|
+
await vi.advanceTimersByTimeAsync(2000);
|
87
|
+
});
|
88
|
+
expect(result.current.elapsedTime).toBe(0);
|
89
|
+
});
|
90
|
+
it('should use custom witty phrases when provided', async () => {
|
91
|
+
const customPhrases = ['Custom phrase 1', 'Custom phrase 2'];
|
92
|
+
const { result } = renderHook(() => useLoadingIndicator(StreamingState.Responding, customPhrases));
|
93
|
+
// Should use a custom phrase
|
94
|
+
expect(customPhrases).toContain(result.current.currentLoadingPhrase);
|
95
|
+
await act(async () => {
|
96
|
+
await vi.advanceTimersByTimeAsync(PHRASE_CHANGE_INTERVAL_MS + 1);
|
97
|
+
});
|
98
|
+
// Should still be using a custom phrase after change
|
99
|
+
expect(customPhrases).toContain(result.current.currentLoadingPhrase);
|
100
|
+
});
|
101
|
+
});
|
102
|
+
//# sourceMappingURL=useLoadingIndicator.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useLoadingIndicator.test.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useLoadingIndicator.test.ts"],"names":[],"mappings":"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"}
|
@@ -11,4 +11,4 @@ export declare const PHRASE_CHANGE_INTERVAL_MS = 15000;
|
|
11
11
|
* @param isWaiting Whether to show a specific waiting phrase.
|
12
12
|
* @returns The current loading phrase.
|
13
13
|
*/
|
14
|
-
export declare const usePhraseCycler: (isActive: boolean, isWaiting: boolean) => string;
|
14
|
+
export declare const usePhraseCycler: (isActive: boolean, isWaiting: boolean, customPhrases?: string[]) => string;
|
@@ -33,6 +33,19 @@ export const WITTY_LOADING_PHRASES = [
|
|
33
33
|
"Looks like somebody's got a case of the Mondays.",
|
34
34
|
'Did you get the memo about the TPS reports?',
|
35
35
|
"It's not that I'm lazy—it's that I just don't care.",
|
36
|
+
// René Magritte quotes
|
37
|
+
'An object is not so attached to its name that we cannot find another one that would suit it better.',
|
38
|
+
'If the dream is a translation of waking life, waking life is also a translation of the dream.',
|
39
|
+
'Art evokes the mystery without which the world would not exist',
|
40
|
+
'This is not a pipe.',
|
41
|
+
'We must not fear daylight just because it almost always illuminates a miserable world.',
|
42
|
+
// More Salvador Dalí quotes
|
43
|
+
'I am not strange. I am just not normal.',
|
44
|
+
'Take me, I am the drug; take me, I am hallucinogenic',
|
45
|
+
// Marcel Duchamp quotes
|
46
|
+
'I force myself to contradict myself in order to avoid conforming to my own taste.',
|
47
|
+
// André Breton quotes
|
48
|
+
'It is living and ceasing to live that are imaginary solutions. Existence is elsewhere.',
|
36
49
|
];
|
37
50
|
export const PHRASE_CHANGE_INTERVAL_MS = 15000; // 15 seconds between phrase changes
|
38
51
|
/**
|
@@ -41,8 +54,11 @@ export const PHRASE_CHANGE_INTERVAL_MS = 15000; // 15 seconds between phrase cha
|
|
41
54
|
* @param isWaiting Whether to show a specific waiting phrase.
|
42
55
|
* @returns The current loading phrase.
|
43
56
|
*/
|
44
|
-
export const usePhraseCycler = (isActive, isWaiting) => {
|
45
|
-
const
|
57
|
+
export const usePhraseCycler = (isActive, isWaiting, customPhrases) => {
|
58
|
+
const loadingPhrases = customPhrases && customPhrases.length > 0
|
59
|
+
? customPhrases
|
60
|
+
: WITTY_LOADING_PHRASES;
|
61
|
+
const [currentLoadingPhrase, setCurrentLoadingPhrase] = useState(loadingPhrases[0]);
|
46
62
|
const phraseIntervalRef = useRef(null);
|
47
63
|
useEffect(() => {
|
48
64
|
if (isWaiting) {
|
@@ -57,20 +73,12 @@ export const usePhraseCycler = (isActive, isWaiting) => {
|
|
57
73
|
clearInterval(phraseIntervalRef.current);
|
58
74
|
}
|
59
75
|
// Select an initial random phrase
|
60
|
-
const initialRandomIndex = Math.floor(Math.random() *
|
61
|
-
setCurrentLoadingPhrase(
|
76
|
+
const initialRandomIndex = Math.floor(Math.random() * loadingPhrases.length);
|
77
|
+
setCurrentLoadingPhrase(loadingPhrases[initialRandomIndex]);
|
62
78
|
phraseIntervalRef.current = setInterval(() => {
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if (WITTY_LOADING_PHRASES.length > 1) {
|
67
|
-
do {
|
68
|
-
const randomIndex = Math.floor(Math.random() * WITTY_LOADING_PHRASES.length);
|
69
|
-
nextPhrase = WITTY_LOADING_PHRASES[randomIndex];
|
70
|
-
} while (nextPhrase === prevPhrase);
|
71
|
-
}
|
72
|
-
return nextPhrase;
|
73
|
-
});
|
79
|
+
// Select a new random phrase
|
80
|
+
const randomIndex = Math.floor(Math.random() * loadingPhrases.length);
|
81
|
+
setCurrentLoadingPhrase(loadingPhrases[randomIndex]);
|
74
82
|
}, PHRASE_CHANGE_INTERVAL_MS);
|
75
83
|
}
|
76
84
|
else {
|
@@ -80,7 +88,7 @@ export const usePhraseCycler = (isActive, isWaiting) => {
|
|
80
88
|
clearInterval(phraseIntervalRef.current);
|
81
89
|
phraseIntervalRef.current = null;
|
82
90
|
}
|
83
|
-
setCurrentLoadingPhrase(
|
91
|
+
setCurrentLoadingPhrase(loadingPhrases[0]);
|
84
92
|
}
|
85
93
|
return () => {
|
86
94
|
if (phraseIntervalRef.current) {
|
@@ -88,7 +96,7 @@ export const usePhraseCycler = (isActive, isWaiting) => {
|
|
88
96
|
phraseIntervalRef.current = null;
|
89
97
|
}
|
90
98
|
};
|
91
|
-
}, [isActive, isWaiting]);
|
99
|
+
}, [isActive, isWaiting, loadingPhrases]);
|
92
100
|
return currentLoadingPhrase;
|
93
101
|
};
|
94
102
|
//# sourceMappingURL=usePhraseCycler.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"usePhraseCycler.js","sourceRoot":"","sources":["../../../../src/ui/hooks/usePhraseCycler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAEpD,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,oBAAoB;IACpB,oEAAoE;IACpE,qEAAqE;IACrE,uEAAuE;IACvE,uCAAuC;IACvC,yDAAyD;IACzD,0GAA0G;IAC1G,6DAA6D;IAC7D,mEAAmE;IACnE,0CAA0C;IAC1C,2EAA2E;IAC3E,6CAA6C;IAE7C,uBAAuB;IACvB,yDAAyD;IACzD,+BAA+B;IAC/B,gFAAgF;IAChF,+IAA+I;IAC/I,2EAA2E;IAC3E,iHAAiH;IACjH,yJAAyJ;IACzJ,iHAAiH;IAEjH,sBAAsB;IACtB,2CAA2C;IAC3C,8DAA8D;IAC9D,mCAAmC;IACnC,kDAAkD;IAClD,6CAA6C;IAC7C,qDAAqD;
|
1
|
+
{"version":3,"file":"usePhraseCycler.js","sourceRoot":"","sources":["../../../../src/ui/hooks/usePhraseCycler.ts"],"names":[],"mappings":"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"}
|
@@ -3,7 +3,7 @@
|
|
3
3
|
* Copyright 2025 Vybestack LLC
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
5
5
|
*/
|
6
|
-
import { Config } from '@vybestack/llxprt-code-core';
|
6
|
+
import { type Config } from '@vybestack/llxprt-code-core';
|
7
7
|
export interface PrivacyState {
|
8
8
|
isLoading: boolean;
|
9
9
|
error?: string;
|
@@ -4,7 +4,19 @@
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
5
5
|
*/
|
6
6
|
import { useState, useEffect, useCallback } from 'react';
|
7
|
-
import {
|
7
|
+
import { UserTierId,
|
8
|
+
// TODO: Re-enable when getCodeAssistServer is exported from core
|
9
|
+
// getCodeAssistServer,
|
10
|
+
} from '@vybestack/llxprt-code-core';
|
11
|
+
// TODO: Remove when getCodeAssistServer is exported from core
|
12
|
+
function getCodeAssistServer(config) {
|
13
|
+
const contentGenerator = config.getGeminiClient().getContentGenerator();
|
14
|
+
// Check if it's a CodeAssistServer
|
15
|
+
if (contentGenerator && 'projectId' in contentGenerator) {
|
16
|
+
return contentGenerator;
|
17
|
+
}
|
18
|
+
return undefined;
|
19
|
+
}
|
8
20
|
export const usePrivacySettings = (config) => {
|
9
21
|
const [privacyState, setPrivacyState] = useState({
|
10
22
|
isLoading: true,
|
@@ -15,7 +27,7 @@ export const usePrivacySettings = (config) => {
|
|
15
27
|
isLoading: true,
|
16
28
|
});
|
17
29
|
try {
|
18
|
-
const server =
|
30
|
+
const server = getCodeAssistServerOrFail(config);
|
19
31
|
const tier = await getTier(server);
|
20
32
|
if (tier !== UserTierId.FREE) {
|
21
33
|
// We don't need to fetch opt-out info since non-free tier
|
@@ -44,7 +56,7 @@ export const usePrivacySettings = (config) => {
|
|
44
56
|
}, [config]);
|
45
57
|
const updateDataCollectionOptIn = useCallback(async (optIn) => {
|
46
58
|
try {
|
47
|
-
const server =
|
59
|
+
const server = getCodeAssistServerOrFail(config);
|
48
60
|
const updatedOptIn = await setRemoteDataCollectionOptIn(server, optIn);
|
49
61
|
setPrivacyState({
|
50
62
|
isLoading: false,
|
@@ -64,18 +76,13 @@ export const usePrivacySettings = (config) => {
|
|
64
76
|
updateDataCollectionOptIn,
|
65
77
|
};
|
66
78
|
};
|
67
|
-
function
|
68
|
-
|
69
|
-
|
70
|
-
if (server instanceof LoggingContentGenerator) {
|
71
|
-
server = server.getWrapped();
|
72
|
-
}
|
73
|
-
// Neither of these cases should ever happen.
|
74
|
-
if (!(server instanceof CodeAssistServer)) {
|
79
|
+
function getCodeAssistServerOrFail(config) {
|
80
|
+
const server = getCodeAssistServer(config);
|
81
|
+
if (server === undefined) {
|
75
82
|
throw new Error('Oauth not being used');
|
76
83
|
}
|
77
|
-
else if (
|
78
|
-
throw new Error('
|
84
|
+
else if (server.projectId === undefined) {
|
85
|
+
throw new Error('CodeAssist server is missing a project ID');
|
79
86
|
}
|
80
87
|
return server;
|
81
88
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"usePrivacySettings.js","sourceRoot":"","sources":["../../../../src/ui/hooks/usePrivacySettings.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,
|
1
|
+
{"version":3,"file":"usePrivacySettings.js","sourceRoot":"","sources":["../../../../src/ui/hooks/usePrivacySettings.ts"],"names":[],"mappings":"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"}
|