@vybestack/llxprt-code 0.1.19-alpha → 0.1.19-gamma
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 +49 -2
- package/dist/package.json +3 -3
- package/dist/src/auth/anthropic-oauth-provider.d.ts +33 -0
- package/dist/src/auth/anthropic-oauth-provider.js +129 -0
- package/dist/src/auth/anthropic-oauth-provider.js.map +1 -0
- package/dist/src/auth/gemini-oauth-provider.d.ts +15 -0
- package/dist/src/auth/gemini-oauth-provider.js +33 -0
- package/dist/src/auth/gemini-oauth-provider.js.map +1 -0
- package/dist/src/auth/oauth-manager.d.ts +109 -0
- package/dist/src/auth/oauth-manager.js +334 -0
- package/dist/src/auth/oauth-manager.js.map +1 -0
- package/dist/src/auth/oauth-manager.spec.d.ts +6 -0
- package/dist/src/auth/oauth-manager.spec.js +523 -0
- package/dist/src/auth/oauth-manager.spec.js.map +1 -0
- package/dist/src/auth/qwen-oauth-provider.d.ts +14 -0
- package/dist/src/auth/qwen-oauth-provider.js +75 -0
- package/dist/src/auth/qwen-oauth-provider.js.map +1 -0
- package/dist/src/auth/types.d.ts +7 -0
- package/dist/src/auth/types.js +7 -0
- package/dist/src/auth/types.js.map +1 -0
- package/dist/src/config/auth.js +11 -0
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/config.js +52 -30
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +66 -0
- package/dist/src/config/keyBindings.js +136 -0
- package/dist/src/config/keyBindings.js.map +1 -0
- package/dist/src/config/settings.d.ts +3 -61
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +587 -0
- package/dist/src/config/settingsSchema.js +565 -0
- package/dist/src/config/settingsSchema.js.map +1 -0
- package/dist/src/gemini.js +9 -2
- package/dist/src/gemini.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/providers/logging/git-stats-service-impl.d.ts +19 -0
- package/dist/src/providers/logging/git-stats-service-impl.js +25 -0
- package/dist/src/providers/logging/git-stats-service-impl.js.map +1 -0
- package/dist/src/providers/logging/git-stats.d.ts +43 -0
- package/dist/src/providers/logging/git-stats.js +137 -0
- package/dist/src/providers/logging/git-stats.js.map +1 -0
- package/dist/src/providers/providerManagerInstance.d.ts +2 -0
- package/dist/src/providers/providerManagerInstance.js +49 -5
- package/dist/src/providers/providerManagerInstance.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +4 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/todo-continuation/todoContinuationService.d.ts +172 -0
- package/dist/src/services/todo-continuation/todoContinuationService.js +387 -0
- package/dist/src/services/todo-continuation/todoContinuationService.js.map +1 -0
- package/dist/src/services/todo-continuation/todoContinuationService.spec.d.ts +6 -0
- package/dist/src/services/todo-continuation/todoContinuationService.spec.js +385 -0
- package/dist/src/services/todo-continuation/todoContinuationService.spec.js.map +1 -0
- package/dist/src/ui/App.js +153 -36
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/colors.d.ts +5 -0
- package/dist/src/ui/colors.js +51 -0
- package/dist/src/ui/colors.js.map +1 -1
- package/dist/src/ui/commands/authCommand.d.ts +11 -1
- package/dist/src/ui/commands/authCommand.js +145 -48
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +16 -0
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/diagnosticsCommand.js +94 -10
- package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +67 -31
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.js +32 -2
- package/dist/src/ui/commands/keyCommand.js.map +1 -1
- package/dist/src/ui/commands/keyfileCommand.js +15 -12
- package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
- package/dist/src/ui/commands/loggingCommand.d.ts +15 -0
- package/dist/src/ui/commands/loggingCommand.js +421 -0
- package/dist/src/ui/commands/loggingCommand.js.map +1 -0
- package/dist/src/ui/commands/modelCommand.js +21 -3
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/privacyCommand.d.ts +3 -0
- package/dist/src/ui/commands/privacyCommand.js +6 -3
- package/dist/src/ui/commands/privacyCommand.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +52 -14
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.js +17 -1
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/settingsCommand.d.ts +7 -0
- package/dist/src/ui/commands/settingsCommand.js +16 -0
- package/dist/src/ui/commands/settingsCommand.js.map +1 -0
- package/dist/src/ui/commands/toolformatCommand.js +79 -23
- package/dist/src/ui/commands/toolformatCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +14 -2
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.js +15 -54
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/ContextUsageDisplay.js +14 -2
- package/dist/src/ui/components/ContextUsageDisplay.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.d.ts +16 -0
- package/dist/src/ui/components/FolderTrustDialog.js +38 -0
- package/dist/src/ui/components/FolderTrustDialog.js.map +1 -0
- package/dist/src/ui/components/Footer.js +136 -16
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.d.ts +1 -0
- package/dist/src/ui/components/InputPrompt.js +87 -31
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/LoggingDialog.d.ts +37 -0
- package/dist/src/ui/components/LoggingDialog.js +155 -0
- package/dist/src/ui/components/LoggingDialog.js.map +1 -0
- package/dist/src/ui/components/MemoryUsageDisplay.js +6 -4
- package/dist/src/ui/components/MemoryUsageDisplay.js.map +1 -1
- package/dist/src/ui/components/OAuthCodeDialog.d.ts +13 -0
- package/dist/src/ui/components/OAuthCodeDialog.js +54 -0
- package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -0
- package/dist/src/ui/components/ProviderDialog.js +100 -26
- package/dist/src/ui/components/ProviderDialog.js.map +1 -1
- package/dist/src/ui/components/ProviderModelDialog.js +99 -27
- package/dist/src/ui/components/ProviderModelDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.d.ts +14 -0
- package/dist/src/ui/components/SettingsDialog.js +247 -0
- package/dist/src/ui/components/SettingsDialog.js.map +1 -0
- package/dist/src/ui/components/ThemeDialog.js +4 -15
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/TodoPanel.js +93 -18
- package/dist/src/ui/components/TodoPanel.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +85 -7
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/contexts/SettingsContext.d.ts +9 -0
- package/dist/src/ui/contexts/SettingsContext.js +15 -0
- package/dist/src/ui/contexts/SettingsContext.js.map +1 -0
- package/dist/src/ui/hooks/atCommandProcessor.js +21 -0
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +6 -2
- package/dist/src/ui/hooks/slashCommandProcessor.js +142 -113
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.js +48 -2
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.js +7 -0
- package/dist/src/ui/hooks/useConsoleMessages.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.d.ts +11 -0
- package/dist/src/ui/hooks/useFolderTrust.js +22 -0
- package/dist/src/ui/hooks/useFolderTrust.js.map +1 -0
- package/dist/src/ui/hooks/useGeminiStream.d.ts +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +35 -10
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useResponsive.d.ts +14 -0
- package/dist/src/ui/hooks/useResponsive.js +19 -0
- package/dist/src/ui/hooks/useResponsive.js.map +1 -0
- package/dist/src/ui/hooks/useSettingsCommand.d.ts +10 -0
- package/dist/src/ui/hooks/useSettingsCommand.js +21 -0
- package/dist/src/ui/hooks/useSettingsCommand.js.map +1 -0
- package/dist/src/ui/hooks/useTodoContinuation.d.ts +31 -0
- package/dist/src/ui/hooks/useTodoContinuation.js +148 -0
- package/dist/src/ui/hooks/useTodoContinuation.js.map +1 -0
- package/dist/src/ui/hooks/useTodoContinuation.spec.d.ts +6 -0
- package/dist/src/ui/hooks/useTodoContinuation.spec.js +378 -0
- package/dist/src/ui/hooks/useTodoContinuation.spec.js.map +1 -0
- package/dist/src/ui/keyMatchers.d.ts +26 -0
- package/dist/src/ui/keyMatchers.js +68 -0
- package/dist/src/ui/keyMatchers.js.map +1 -0
- package/dist/src/ui/privacy/PrivacyNotice.js +10 -4
- package/dist/src/ui/privacy/PrivacyNotice.js.map +1 -1
- package/dist/src/ui/reducers/appReducer.d.ts +3 -2
- package/dist/src/ui/reducers/appReducer.js +1 -0
- package/dist/src/ui/reducers/appReducer.js.map +1 -1
- package/dist/src/ui/themes/semantic-resolver.d.ts +12 -0
- package/dist/src/ui/themes/semantic-resolver.js +32 -0
- package/dist/src/ui/themes/semantic-resolver.js.map +1 -0
- package/dist/src/ui/themes/semantic-tokens.d.ts +52 -0
- package/dist/src/ui/themes/semantic-tokens.js +7 -0
- package/dist/src/ui/themes/semantic-tokens.js.map +1 -0
- package/dist/src/ui/themes/theme-compat.d.ts +34 -0
- package/dist/src/ui/themes/theme-compat.js +65 -0
- package/dist/src/ui/themes/theme-compat.js.map +1 -0
- package/dist/src/ui/themes/theme-manager.d.ts +8 -0
- package/dist/src/ui/themes/theme-manager.js +18 -0
- package/dist/src/ui/themes/theme-manager.js.map +1 -1
- package/dist/src/ui/utils/CodeColorizer.d.ts +2 -1
- package/dist/src/ui/utils/CodeColorizer.js +4 -3
- package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.js +4 -2
- package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
- package/dist/src/ui/utils/responsive.d.ts +16 -0
- package/dist/src/ui/utils/responsive.js +111 -0
- package/dist/src/ui/utils/responsive.js.map +1 -0
- package/dist/src/utils/cleanup.d.ts +2 -2
- package/dist/src/utils/cleanup.js +2 -2
- package/dist/src/utils/cleanup.js.map +1 -1
- package/dist/src/utils/dialogScopeUtils.d.ts +31 -0
- package/dist/src/utils/dialogScopeUtils.js +48 -0
- package/dist/src/utils/dialogScopeUtils.js.map +1 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.d.ts +75 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.js +412 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.js.map +1 -0
- package/dist/src/utils/privacy/PrivacyManager.d.ts +58 -0
- package/dist/src/utils/privacy/PrivacyManager.js +133 -0
- package/dist/src/utils/privacy/PrivacyManager.js.map +1 -0
- package/dist/src/utils/sandbox.js +10 -0
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/settingsUtils.d.ts +126 -0
- package/dist/src/utils/settingsUtils.js +327 -0
- package/dist/src/utils/settingsUtils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/src/ui/components/IDEContextDetailDisplay.d.ts +0 -12
- package/dist/src/ui/components/IDEContextDetailDisplay.js +0 -30
- package/dist/src/ui/components/IDEContextDetailDisplay.js.map +0 -1
@@ -0,0 +1,378 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { describe, it, expect, vi, beforeEach, } from 'vitest';
|
7
|
+
import { renderHook, act } from '@testing-library/react';
|
8
|
+
import { useTodoContinuation } from './useTodoContinuation.js';
|
9
|
+
import { useTodoContext } from '../contexts/TodoContext.js';
|
10
|
+
import { Config, GeminiClient, ApprovalMode, } from '@vybestack/llxprt-code-core';
|
11
|
+
// Mock dependencies
|
12
|
+
vi.mock('../contexts/TodoContext.js');
|
13
|
+
vi.mock('@vybestack/llxprt-code-core', async () => {
|
14
|
+
const actual = (await vi.importActual('@vybestack/llxprt-code-core'));
|
15
|
+
return {
|
16
|
+
...actual,
|
17
|
+
Config: vi.fn(),
|
18
|
+
GeminiClient: vi.fn(),
|
19
|
+
};
|
20
|
+
});
|
21
|
+
describe('useTodoContinuation - Behavioral Tests', () => {
|
22
|
+
let mockConfig;
|
23
|
+
let mockGeminiClient;
|
24
|
+
let mockTodoContext;
|
25
|
+
let mockOnDebugMessage;
|
26
|
+
const createTodo = (id, content, status = 'pending') => ({
|
27
|
+
id,
|
28
|
+
content,
|
29
|
+
status,
|
30
|
+
priority: 'medium',
|
31
|
+
});
|
32
|
+
beforeEach(() => {
|
33
|
+
vi.resetAllMocks();
|
34
|
+
// Mock Config
|
35
|
+
mockConfig = {
|
36
|
+
getEphemeralSettings: vi.fn().mockReturnValue({}),
|
37
|
+
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
|
38
|
+
};
|
39
|
+
Config.mockImplementation(() => mockConfig);
|
40
|
+
// Mock GeminiClient
|
41
|
+
mockGeminiClient = {
|
42
|
+
sendMessageStream: vi.fn().mockResolvedValue(undefined),
|
43
|
+
};
|
44
|
+
GeminiClient.mockImplementation(() => mockGeminiClient);
|
45
|
+
// Mock TodoContext
|
46
|
+
mockTodoContext = {
|
47
|
+
todos: [],
|
48
|
+
updateTodos: vi.fn(),
|
49
|
+
refreshTodos: vi.fn(),
|
50
|
+
};
|
51
|
+
useTodoContext.mockReturnValue(mockTodoContext);
|
52
|
+
// Mock debug message handler
|
53
|
+
mockOnDebugMessage = vi.fn();
|
54
|
+
});
|
55
|
+
describe('Stream Completion Detection', () => {
|
56
|
+
it('@requirement REQ-001.1 should trigger continuation when stream completes without tool calls and has active todos', () => {
|
57
|
+
// Given: Active todos exist and todo-continuation is enabled
|
58
|
+
mockTodoContext.todos = [
|
59
|
+
createTodo('1', 'Complete feature implementation', 'in_progress'),
|
60
|
+
createTodo('2', 'Write tests', 'pending'),
|
61
|
+
];
|
62
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
63
|
+
'todo-continuation': true,
|
64
|
+
});
|
65
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, // not responding
|
66
|
+
mockOnDebugMessage));
|
67
|
+
// When: Stream completes without tool calls
|
68
|
+
act(() => {
|
69
|
+
result.current.handleStreamCompleted(false);
|
70
|
+
});
|
71
|
+
// Then: Continuation should be triggered
|
72
|
+
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(expect.stringContaining('Complete feature implementation'), { ephemeral: true });
|
73
|
+
});
|
74
|
+
it('@requirement REQ-001.2 should NOT trigger when no active todos exist', () => {
|
75
|
+
// Given: No active todos
|
76
|
+
mockTodoContext.todos = [createTodo('1', 'Completed task', 'completed')];
|
77
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
78
|
+
'todo-continuation': true,
|
79
|
+
});
|
80
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
81
|
+
// When: Stream completes without tool calls
|
82
|
+
act(() => {
|
83
|
+
result.current.handleStreamCompleted(false);
|
84
|
+
});
|
85
|
+
// Then: No continuation should be triggered
|
86
|
+
expect(mockGeminiClient.sendMessageStream).not.toHaveBeenCalled();
|
87
|
+
});
|
88
|
+
it('@requirement REQ-001.2 should NOT trigger when tool calls were present', () => {
|
89
|
+
// Given: Active todos exist and continuation is enabled
|
90
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
91
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
92
|
+
'todo-continuation': true,
|
93
|
+
});
|
94
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
95
|
+
// When: Stream completes WITH tool calls
|
96
|
+
act(() => {
|
97
|
+
result.current.handleStreamCompleted(true);
|
98
|
+
});
|
99
|
+
// Then: No continuation should be triggered
|
100
|
+
expect(mockGeminiClient.sendMessageStream).not.toHaveBeenCalled();
|
101
|
+
});
|
102
|
+
it('@requirement REQ-001.4 should NOT trigger when todo-continuation setting is disabled', () => {
|
103
|
+
// Given: Active todos exist but continuation is disabled
|
104
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
105
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
106
|
+
'todo-continuation': false,
|
107
|
+
});
|
108
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
109
|
+
// When: Stream completes without tool calls
|
110
|
+
act(() => {
|
111
|
+
result.current.handleStreamCompleted(false);
|
112
|
+
});
|
113
|
+
// Then: No continuation should be triggered
|
114
|
+
expect(mockGeminiClient.sendMessageStream).not.toHaveBeenCalled();
|
115
|
+
});
|
116
|
+
it('@requirement REQ-001.3 should NOT trigger when AI is currently responding', () => {
|
117
|
+
// Given: Active todos and continuation enabled
|
118
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
119
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
120
|
+
'todo-continuation': true,
|
121
|
+
});
|
122
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, true, // currently responding
|
123
|
+
mockOnDebugMessage));
|
124
|
+
// When: Stream completes without tool calls
|
125
|
+
act(() => {
|
126
|
+
result.current.handleStreamCompleted(false);
|
127
|
+
});
|
128
|
+
// Then: No continuation should be triggered
|
129
|
+
expect(mockGeminiClient.sendMessageStream).not.toHaveBeenCalled();
|
130
|
+
});
|
131
|
+
});
|
132
|
+
describe('Prompt Generation', () => {
|
133
|
+
it('@requirement REQ-002.1 should send ephemeral prompt with most relevant active task', () => {
|
134
|
+
// Given: Multiple active todos with priorities
|
135
|
+
mockTodoContext.todos = [
|
136
|
+
createTodo('1', 'Fix critical bug', 'in_progress'),
|
137
|
+
createTodo('2', 'Update documentation', 'pending'),
|
138
|
+
createTodo('3', 'Add new feature', 'pending'),
|
139
|
+
];
|
140
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
141
|
+
'todo-continuation': true,
|
142
|
+
});
|
143
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
144
|
+
// When: Stream completes without tool calls
|
145
|
+
act(() => {
|
146
|
+
result.current.handleStreamCompleted(false);
|
147
|
+
});
|
148
|
+
// Then: Should send prompt with in_progress task (most relevant)
|
149
|
+
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(expect.stringContaining('Fix critical bug'), { ephemeral: true });
|
150
|
+
});
|
151
|
+
it('@requirement REQ-002.2 should use different prompt for YOLO mode', () => {
|
152
|
+
// Given: YOLO mode is active
|
153
|
+
mockTodoContext.todos = [
|
154
|
+
createTodo('1', 'Complete implementation', 'in_progress'),
|
155
|
+
];
|
156
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
157
|
+
'todo-continuation': true,
|
158
|
+
});
|
159
|
+
mockConfig.getApprovalMode.mockReturnValue(ApprovalMode.YOLO);
|
160
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
161
|
+
// When: Stream completes without tool calls
|
162
|
+
act(() => {
|
163
|
+
result.current.handleStreamCompleted(false);
|
164
|
+
});
|
165
|
+
// Then: Should use YOLO-specific prompt
|
166
|
+
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(expect.stringMatching(/(continue|proceed).*without.*confirmation/i), { ephemeral: true });
|
167
|
+
});
|
168
|
+
it('@requirement REQ-002.1 should NOT store prompt in conversation history', () => {
|
169
|
+
// Given: Active todos and continuation enabled
|
170
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
171
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
172
|
+
'todo-continuation': true,
|
173
|
+
});
|
174
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
175
|
+
// When: Stream completes without tool calls
|
176
|
+
act(() => {
|
177
|
+
result.current.handleStreamCompleted(false);
|
178
|
+
});
|
179
|
+
// Then: Should send with ephemeral flag
|
180
|
+
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(expect.any(String), { ephemeral: true });
|
181
|
+
});
|
182
|
+
});
|
183
|
+
describe('Integration with TodoContext', () => {
|
184
|
+
it('@requirement REQ-003.1 should respond to todo state changes', () => {
|
185
|
+
const { result, rerender } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
186
|
+
// Given: Initially no todos
|
187
|
+
mockTodoContext.todos = [];
|
188
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
189
|
+
'todo-continuation': true,
|
190
|
+
});
|
191
|
+
// When: Stream completes (should not trigger)
|
192
|
+
act(() => {
|
193
|
+
result.current.handleStreamCompleted(false);
|
194
|
+
});
|
195
|
+
expect(mockGeminiClient.sendMessageStream).not.toHaveBeenCalled();
|
196
|
+
// When: Todos are updated with active task
|
197
|
+
mockTodoContext.todos = [
|
198
|
+
createTodo('1', 'New active task', 'in_progress'),
|
199
|
+
];
|
200
|
+
rerender();
|
201
|
+
// Then: Next completion should trigger continuation
|
202
|
+
act(() => {
|
203
|
+
result.current.handleStreamCompleted(false);
|
204
|
+
});
|
205
|
+
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(expect.stringContaining('New active task'), { ephemeral: true });
|
206
|
+
});
|
207
|
+
it('@requirement REQ-003.2 should handle todo_pause events', () => {
|
208
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
209
|
+
// When: Todo pause is requested
|
210
|
+
const pauseResult = result.current.handleTodoPause('User requested pause');
|
211
|
+
// Then: Should return pause event structure
|
212
|
+
expect(pauseResult).toEqual({
|
213
|
+
type: 'pause',
|
214
|
+
reason: 'User requested pause',
|
215
|
+
message: expect.stringContaining('paused'),
|
216
|
+
});
|
217
|
+
});
|
218
|
+
});
|
219
|
+
describe('State Management', () => {
|
220
|
+
it('@requirement REQ-004.1 should track continuation state', () => {
|
221
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
222
|
+
// Initially not active
|
223
|
+
expect(result.current.continuationState.isActive).toBe(false);
|
224
|
+
expect(result.current.continuationState.attemptCount).toBe(0);
|
225
|
+
// Given: Active todos and continuation enabled
|
226
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
227
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
228
|
+
'todo-continuation': true,
|
229
|
+
});
|
230
|
+
// When: Continuation is triggered
|
231
|
+
act(() => {
|
232
|
+
result.current.handleStreamCompleted(false);
|
233
|
+
});
|
234
|
+
// Then: State should be updated
|
235
|
+
expect(result.current.continuationState.taskDescription).toContain('Active task');
|
236
|
+
});
|
237
|
+
it('@requirement REQ-004.2 should reset state appropriately', () => {
|
238
|
+
// Given: Active continuation state
|
239
|
+
mockTodoContext.todos = [createTodo('1', 'Task 1', 'in_progress')];
|
240
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
241
|
+
'todo-continuation': true,
|
242
|
+
});
|
243
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
244
|
+
// Trigger continuation
|
245
|
+
act(() => {
|
246
|
+
result.current.handleStreamCompleted(false);
|
247
|
+
});
|
248
|
+
// When: Stream completes with tool calls (should reset)
|
249
|
+
act(() => {
|
250
|
+
result.current.handleStreamCompleted(true);
|
251
|
+
});
|
252
|
+
// Then: State should be reset
|
253
|
+
expect(result.current.continuationState.isActive).toBe(false);
|
254
|
+
});
|
255
|
+
});
|
256
|
+
describe('Edge Cases', () => {
|
257
|
+
it('@requirement REQ-005.1 should handle multiple rapid completions', () => {
|
258
|
+
// Given: Continuation enabled with active todo
|
259
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
260
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
261
|
+
'todo-continuation': true,
|
262
|
+
});
|
263
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
264
|
+
// When: Multiple rapid completions occur
|
265
|
+
act(() => {
|
266
|
+
result.current.handleStreamCompleted(false);
|
267
|
+
result.current.handleStreamCompleted(false);
|
268
|
+
result.current.handleStreamCompleted(false);
|
269
|
+
});
|
270
|
+
// Then: Should not trigger multiple continuations simultaneously
|
271
|
+
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(1);
|
272
|
+
});
|
273
|
+
it('@requirement REQ-005.2 should handle changing settings mid-stream', () => {
|
274
|
+
// Given: Initially enabled
|
275
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
276
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
277
|
+
'todo-continuation': true,
|
278
|
+
});
|
279
|
+
const { result, rerender } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
280
|
+
// When: Setting is changed during hook lifecycle
|
281
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
282
|
+
'todo-continuation': false,
|
283
|
+
});
|
284
|
+
rerender();
|
285
|
+
// Then: Should respect new setting
|
286
|
+
act(() => {
|
287
|
+
result.current.handleStreamCompleted(false);
|
288
|
+
});
|
289
|
+
expect(mockGeminiClient.sendMessageStream).not.toHaveBeenCalled();
|
290
|
+
});
|
291
|
+
it('@requirement REQ-005.3 should handle malformed todos gracefully', () => {
|
292
|
+
// Given: Malformed todos (missing required fields)
|
293
|
+
mockTodoContext.todos = [
|
294
|
+
{
|
295
|
+
id: '1',
|
296
|
+
content: '',
|
297
|
+
status: 'in_progress',
|
298
|
+
priority: 'medium',
|
299
|
+
},
|
300
|
+
// @ts-expect-error Testing malformed data
|
301
|
+
{
|
302
|
+
id: '2',
|
303
|
+
status: 'pending',
|
304
|
+
priority: 'high',
|
305
|
+
},
|
306
|
+
];
|
307
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
308
|
+
'todo-continuation': true,
|
309
|
+
});
|
310
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
311
|
+
// When: Stream completes
|
312
|
+
act(() => {
|
313
|
+
result.current.handleStreamCompleted(false);
|
314
|
+
});
|
315
|
+
// Then: Should handle gracefully without crashing
|
316
|
+
expect(() => {
|
317
|
+
result.current.handleStreamCompleted(false);
|
318
|
+
}).not.toThrow();
|
319
|
+
// Should either skip malformed todos or handle them safely
|
320
|
+
if (mockGeminiClient.sendMessageStream.mock.calls.length > 0) {
|
321
|
+
const callArgs = mockGeminiClient.sendMessageStream.mock.calls[0];
|
322
|
+
expect(callArgs[0]).toBeTypeOf('string');
|
323
|
+
expect(callArgs[1]).toEqual({ ephemeral: true });
|
324
|
+
}
|
325
|
+
});
|
326
|
+
it('@requirement REQ-005.4 should prevent continuation loops', () => {
|
327
|
+
// Given: Continuation enabled
|
328
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
329
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
330
|
+
'todo-continuation': true,
|
331
|
+
});
|
332
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
333
|
+
// When: Continuation is triggered multiple times in sequence
|
334
|
+
act(() => {
|
335
|
+
result.current.handleStreamCompleted(false);
|
336
|
+
});
|
337
|
+
const firstCallCount = mockGeminiClient.sendMessageStream.mock.calls.length;
|
338
|
+
act(() => {
|
339
|
+
result.current.handleStreamCompleted(false);
|
340
|
+
});
|
341
|
+
// Then: Should not trigger additional continuations if already active
|
342
|
+
expect(mockGeminiClient.sendMessageStream.mock.calls.length).toBe(firstCallCount);
|
343
|
+
});
|
344
|
+
});
|
345
|
+
describe('Configuration Integration', () => {
|
346
|
+
it('@requirement REQ-006.1 should respect default settings when todo-continuation is undefined', () => {
|
347
|
+
// Given: Settings don't specify todo-continuation
|
348
|
+
mockTodoContext.todos = [createTodo('1', 'Active task', 'in_progress')];
|
349
|
+
mockConfig.getEphemeralSettings.mockReturnValue({});
|
350
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
351
|
+
// When: Stream completes without tool calls
|
352
|
+
act(() => {
|
353
|
+
result.current.handleStreamCompleted(false);
|
354
|
+
});
|
355
|
+
// Then: Should use default behavior (disabled)
|
356
|
+
expect(mockGeminiClient.sendMessageStream).not.toHaveBeenCalled();
|
357
|
+
});
|
358
|
+
it('@requirement REQ-006.2 should prioritize in_progress todos over pending ones', () => {
|
359
|
+
// Given: Mix of pending and in_progress todos
|
360
|
+
mockTodoContext.todos = [
|
361
|
+
createTodo('1', 'Pending task', 'pending'),
|
362
|
+
createTodo('2', 'Active task', 'in_progress'),
|
363
|
+
createTodo('3', 'Another pending', 'pending'),
|
364
|
+
];
|
365
|
+
mockConfig.getEphemeralSettings.mockReturnValue({
|
366
|
+
'todo-continuation': true,
|
367
|
+
});
|
368
|
+
const { result } = renderHook(() => useTodoContinuation(mockGeminiClient, mockConfig, false, mockOnDebugMessage));
|
369
|
+
// When: Stream completes
|
370
|
+
act(() => {
|
371
|
+
result.current.handleStreamCompleted(false);
|
372
|
+
});
|
373
|
+
// Then: Should select in_progress task
|
374
|
+
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(expect.stringContaining('Active task'), { ephemeral: true });
|
375
|
+
});
|
376
|
+
});
|
377
|
+
});
|
378
|
+
//# sourceMappingURL=useTodoContinuation.spec.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useTodoContinuation.spec.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useTodoContinuation.spec.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Google LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import type { Key } from './hooks/useKeypress.js';
|
7
|
+
import { Command, KeyBindingConfig } from '../config/keyBindings.js';
|
8
|
+
/**
|
9
|
+
* Key matcher function type
|
10
|
+
*/
|
11
|
+
type KeyMatcher = (key: Key) => boolean;
|
12
|
+
/**
|
13
|
+
* Type for key matchers mapped to Command enum
|
14
|
+
*/
|
15
|
+
export type KeyMatchers = {
|
16
|
+
readonly [C in Command]: KeyMatcher;
|
17
|
+
};
|
18
|
+
/**
|
19
|
+
* Creates key matchers from a key binding configuration
|
20
|
+
*/
|
21
|
+
export declare function createKeyMatchers(config?: KeyBindingConfig): KeyMatchers;
|
22
|
+
/**
|
23
|
+
* Default key binding matchers using the default configuration
|
24
|
+
*/
|
25
|
+
export declare const keyMatchers: KeyMatchers;
|
26
|
+
export { Command };
|
@@ -0,0 +1,68 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Google LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { Command, defaultKeyBindings, } from '../config/keyBindings.js';
|
7
|
+
/**
|
8
|
+
* Matches a KeyBinding against an actual Key press
|
9
|
+
* Pure data-driven matching logic
|
10
|
+
*/
|
11
|
+
function matchKeyBinding(keyBinding, key) {
|
12
|
+
// Either key name or sequence must match (but not both should be defined)
|
13
|
+
let keyMatches = false;
|
14
|
+
if (keyBinding.key !== undefined) {
|
15
|
+
keyMatches = keyBinding.key === key.name;
|
16
|
+
}
|
17
|
+
else if (keyBinding.sequence !== undefined) {
|
18
|
+
keyMatches = keyBinding.sequence === key.sequence;
|
19
|
+
}
|
20
|
+
else {
|
21
|
+
// Neither key nor sequence defined - invalid binding
|
22
|
+
return false;
|
23
|
+
}
|
24
|
+
if (!keyMatches) {
|
25
|
+
return false;
|
26
|
+
}
|
27
|
+
// Check modifiers - follow original logic:
|
28
|
+
// undefined = ignore this modifier (original behavior)
|
29
|
+
// true = modifier must be pressed
|
30
|
+
// false = modifier must NOT be pressed
|
31
|
+
if (keyBinding.ctrl !== undefined && key.ctrl !== keyBinding.ctrl) {
|
32
|
+
return false;
|
33
|
+
}
|
34
|
+
if (keyBinding.shift !== undefined && key.shift !== keyBinding.shift) {
|
35
|
+
return false;
|
36
|
+
}
|
37
|
+
if (keyBinding.command !== undefined && key.meta !== keyBinding.command) {
|
38
|
+
return false;
|
39
|
+
}
|
40
|
+
if (keyBinding.paste !== undefined && key.paste !== keyBinding.paste) {
|
41
|
+
return false;
|
42
|
+
}
|
43
|
+
return true;
|
44
|
+
}
|
45
|
+
/**
|
46
|
+
* Checks if a key matches any of the bindings for a command
|
47
|
+
*/
|
48
|
+
function matchCommand(command, key, config = defaultKeyBindings) {
|
49
|
+
const bindings = config[command];
|
50
|
+
return bindings.some((binding) => matchKeyBinding(binding, key));
|
51
|
+
}
|
52
|
+
/**
|
53
|
+
* Creates key matchers from a key binding configuration
|
54
|
+
*/
|
55
|
+
export function createKeyMatchers(config = defaultKeyBindings) {
|
56
|
+
const matchers = {};
|
57
|
+
for (const command of Object.values(Command)) {
|
58
|
+
matchers[command] = (key) => matchCommand(command, key, config);
|
59
|
+
}
|
60
|
+
return matchers;
|
61
|
+
}
|
62
|
+
/**
|
63
|
+
* Default key binding matchers using the default configuration
|
64
|
+
*/
|
65
|
+
export const keyMatchers = createKeyMatchers(defaultKeyBindings);
|
66
|
+
// Re-export Command for convenience
|
67
|
+
export { Command };
|
68
|
+
//# sourceMappingURL=keyMatchers.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keyMatchers.js","sourceRoot":"","sources":["../../../src/ui/keyMatchers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,OAAO,EAGP,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAElC;;;GAGG;AACH,SAAS,eAAe,CAAC,UAAsB,EAAE,GAAQ;IACvD,0EAA0E;IAC1E,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QACjC,UAAU,GAAG,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC;IAC3C,CAAC;SAAM,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC7C,UAAU,GAAG,UAAU,CAAC,QAAQ,KAAK,GAAG,CAAC,QAAQ,CAAC;IACpD,CAAC;SAAM,CAAC;QACN,qDAAqD;QACrD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2CAA2C;IAC3C,uDAAuD;IACvD,kCAAkC;IAClC,uCAAuC;IAEvC,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC;QAClE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU,CAAC,OAAO,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;QACxE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CACnB,OAAgB,EAChB,GAAQ,EACR,SAA2B,kBAAkB;IAE7C,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;AACnE,CAAC;AAcD;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAA2B,kBAAkB;IAE7C,MAAM,QAAQ,GAAG,EAAoC,CAAC;IAEtD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,QAAuB,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAgB,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;AAE9E,oCAAoC;AACpC,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
@@ -17,13 +17,19 @@ const NonGeminiProviderNotice = ({ providerName, onExit, }) => {
|
|
17
17
|
};
|
18
18
|
const PrivacyNoticeText = ({ config, onExit, }) => {
|
19
19
|
const authType = config.getContentGeneratorConfig()?.authType;
|
20
|
-
// Check if we're using a non-Gemini provider
|
20
|
+
// Check if we're using a non-Gemini provider or llxprt multi-provider
|
21
21
|
const providerManager = config.getProviderManager?.();
|
22
22
|
const activeProvider = providerManager?.getActiveProvider?.();
|
23
23
|
const isNonGeminiProvider = activeProvider && activeProvider.name !== 'gemini';
|
24
|
-
//
|
25
|
-
|
26
|
-
|
24
|
+
// For llxprt multi-provider or when content generator is not initialized,
|
25
|
+
// show the basic Gemini privacy notice
|
26
|
+
if (!authType || authType === AuthType.USE_PROVIDER || isNonGeminiProvider) {
|
27
|
+
// If we have a specific non-Gemini provider, show its notice
|
28
|
+
if (isNonGeminiProvider) {
|
29
|
+
return (_jsx(NonGeminiProviderNotice, { providerName: activeProvider.name, onExit: onExit }));
|
30
|
+
}
|
31
|
+
// Otherwise show basic Gemini API terms
|
32
|
+
return _jsx(GeminiPrivacyNotice, { onExit: onExit });
|
27
33
|
}
|
28
34
|
switch (authType) {
|
29
35
|
case AuthType.USE_GEMINI:
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"PrivacyNotice.js","sourceRoot":"","sources":["../../../../src/ui/privacy/PrivacyNotice.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAe,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAOrE,MAAM,uBAAuB,GAAG,CAAC,EAC/B,YAAY,EACZ,MAAM,GAIP,EAAE,EAAE;IACH,QAAQ,CAAC,GAAG,EAAE;QACZ,MAAM,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aACpC,MAAC,IAAI,yBAAQ,YAAY,kBAAkB,EAC3C,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,2CAAkC,IAChD,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,EACzB,MAAM,EACN,MAAM,GAIP,EAAE,EAAE;IACH,MAAM,QAAQ,GAAG,MAAM,CAAC,yBAAyB,EAAE,EAAE,QAAQ,CAAC;IAE9D,
|
1
|
+
{"version":3,"file":"PrivacyNotice.js","sourceRoot":"","sources":["../../../../src/ui/privacy/PrivacyNotice.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAe,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAOrE,MAAM,uBAAuB,GAAG,CAAC,EAC/B,YAAY,EACZ,MAAM,GAIP,EAAE,EAAE;IACH,QAAQ,CAAC,GAAG,EAAE;QACZ,MAAM,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aACpC,MAAC,IAAI,yBAAQ,YAAY,kBAAkB,EAC3C,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,2CAAkC,IAChD,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,EACzB,MAAM,EACN,MAAM,GAIP,EAAE,EAAE;IACH,MAAM,QAAQ,GAAG,MAAM,CAAC,yBAAyB,EAAE,EAAE,QAAQ,CAAC;IAE9D,sEAAsE;IACtE,MAAM,eAAe,GAAG,MAAM,CAAC,kBAAkB,EAAE,EAAE,CAAC;IACtD,MAAM,cAAc,GAAG,eAAe,EAAE,iBAAiB,EAAE,EAAE,CAAC;IAC9D,MAAM,mBAAmB,GACvB,cAAc,IAAI,cAAc,CAAC,IAAI,KAAK,QAAQ,CAAC;IAErD,0EAA0E;IAC1E,uCAAuC;IACvC,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,QAAQ,CAAC,YAAY,IAAI,mBAAmB,EAAE,CAAC;QAC3E,6DAA6D;QAC7D,IAAI,mBAAmB,EAAE,CAAC;YACxB,OAAO,CACL,KAAC,uBAAuB,IACtB,YAAY,EAAE,cAAc,CAAC,IAAI,EACjC,MAAM,EAAE,MAAM,GACd,CACH,CAAC;QACJ,CAAC;QACD,wCAAwC;QACxC,OAAO,KAAC,mBAAmB,IAAC,MAAM,EAAE,MAAM,GAAI,CAAC;IACjD,CAAC;IAED,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ,CAAC,UAAU;YACtB,OAAO,KAAC,mBAAmB,IAAC,MAAM,EAAE,MAAM,GAAI,CAAC;QACjD,KAAK,QAAQ,CAAC,aAAa;YACzB,OAAO,KAAC,sBAAsB,IAAC,MAAM,EAAE,MAAM,GAAI,CAAC;QACpD,KAAK,QAAQ,CAAC,iBAAiB,CAAC;QAChC;YACE,OAAO,KAAC,sBAAsB,IAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAI,CAAC;IACtE,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAsB,EAAE,EAAE,CAAC,CACvE,KAAC,GAAG,IAAC,WAAW,EAAC,OAAO,EAAC,OAAO,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,YACzD,KAAC,iBAAiB,IAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAI,GACjD,CACP,CAAC"}
|
@@ -12,10 +12,10 @@ export type AppAction = {
|
|
12
12
|
};
|
13
13
|
} | {
|
14
14
|
type: 'OPEN_DIALOG';
|
15
|
-
payload: 'theme' | 'auth' | 'editor' | 'providerModel' | 'provider' | 'privacy' | 'loadProfile' | 'tools';
|
15
|
+
payload: 'theme' | 'auth' | 'editor' | 'providerModel' | 'provider' | 'privacy' | 'loadProfile' | 'tools' | 'oauthCode';
|
16
16
|
} | {
|
17
17
|
type: 'CLOSE_DIALOG';
|
18
|
-
payload: 'theme' | 'auth' | 'editor' | 'providerModel' | 'provider' | 'privacy' | 'loadProfile' | 'tools';
|
18
|
+
payload: 'theme' | 'auth' | 'editor' | 'providerModel' | 'provider' | 'privacy' | 'loadProfile' | 'tools' | 'oauthCode';
|
19
19
|
} | {
|
20
20
|
type: 'SET_WARNING';
|
21
21
|
payload: {
|
@@ -45,6 +45,7 @@ export interface AppState {
|
|
45
45
|
privacy: boolean;
|
46
46
|
loadProfile: boolean;
|
47
47
|
tools: boolean;
|
48
|
+
oauthCode: boolean;
|
48
49
|
};
|
49
50
|
warnings: Map<string, string>;
|
50
51
|
errors: {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"appReducer.js","sourceRoot":"","sources":["../../../../src/ui/reducers/appReducer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
1
|
+
{"version":3,"file":"appReducer.js","sourceRoot":"","sources":["../../../../src/ui/reducers/appReducer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiEH,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,WAAW,EAAE;QACX,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,KAAK;QACb,aAAa,EAAE,KAAK;QACpB,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,KAAK;QAClB,KAAK,EAAE,KAAK;QACZ,SAAS,EAAE,KAAK;KACjB;IACD,QAAQ,EAAE,IAAI,GAAG,EAAE;IACnB,MAAM,EAAE;QACN,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,IAAI;KACb;IACD,iBAAiB,EAAE,IAAI;CACxB,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,KAAe,EAAE,MAAiB;IAC3D,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,UAAU;YACb,0DAA0D;YAC1D,OAAO;gBACL,GAAG,KAAK;gBACR,iBAAiB,EAAE,MAAM,CAAC,OAAO;aAClC,CAAC;QAEJ,KAAK,aAAa;YAChB,OAAO;gBACL,GAAG,KAAK;gBACR,WAAW,EAAE;oBACX,GAAG,KAAK,CAAC,WAAW;oBACpB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI;iBACvB;aACF,CAAC;QAEJ,KAAK,cAAc;YACjB,OAAO;gBACL,GAAG,KAAK;gBACR,WAAW,EAAE;oBACX,GAAG,KAAK,CAAC,WAAW;oBACpB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK;iBACxB;aACF,CAAC;QAEJ,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC5C,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC5D,OAAO;gBACL,GAAG,KAAK;gBACR,QAAQ,EAAE,WAAW;aACtB,CAAC;QACJ,CAAC;QAED,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC5C,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnC,OAAO;gBACL,GAAG,KAAK;gBACR,QAAQ,EAAE,WAAW;aACtB,CAAC;QACJ,CAAC;QAED,KAAK,iBAAiB;YACpB,OAAO;gBACL,GAAG,KAAK;gBACR,MAAM,EAAE;oBACN,GAAG,KAAK,CAAC,MAAM;oBACf,KAAK,EAAE,MAAM,CAAC,OAAO;iBACtB;aACF,CAAC;QAEJ,KAAK,gBAAgB;YACnB,OAAO;gBACL,GAAG,KAAK;gBACR,MAAM,EAAE;oBACN,GAAG,KAAK,CAAC,MAAM;oBACf,IAAI,EAAE,MAAM,CAAC,OAAO;iBACrB;aACF,CAAC;QAEJ,KAAK,kBAAkB;YACrB,OAAO;gBACL,GAAG,KAAK;gBACR,MAAM,EAAE;oBACN,GAAG,KAAK,CAAC,MAAM;oBACf,MAAM,EAAE,MAAM,CAAC,OAAO;iBACvB;aACF,CAAC;QAEJ;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Google LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { ColorsTheme } from './theme.js';
|
7
|
+
import { SemanticColors } from './semantic-tokens.js';
|
8
|
+
/**
|
9
|
+
* Resolves a theme's colors to semantic color tokens.
|
10
|
+
* Maps theme-specific colors to meaningful semantic purposes.
|
11
|
+
*/
|
12
|
+
export declare function resolveSemanticColors(theme: ColorsTheme): SemanticColors;
|
@@ -0,0 +1,32 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Google LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
/**
|
7
|
+
* Resolves a theme's colors to semantic color tokens.
|
8
|
+
* Maps theme-specific colors to meaningful semantic purposes.
|
9
|
+
*/
|
10
|
+
export function resolveSemanticColors(theme) {
|
11
|
+
return {
|
12
|
+
text: {
|
13
|
+
primary: theme.Foreground,
|
14
|
+
secondary: theme.Gray,
|
15
|
+
accent: theme.AccentBlue,
|
16
|
+
},
|
17
|
+
status: {
|
18
|
+
success: theme.AccentGreen,
|
19
|
+
warning: theme.AccentYellow,
|
20
|
+
error: theme.AccentRed,
|
21
|
+
},
|
22
|
+
background: {
|
23
|
+
primary: theme.Background,
|
24
|
+
secondary: theme.DiffAdded ?? theme.AccentGreen,
|
25
|
+
},
|
26
|
+
border: {
|
27
|
+
default: theme.Gray,
|
28
|
+
focused: theme.AccentBlue,
|
29
|
+
},
|
30
|
+
};
|
31
|
+
}
|
32
|
+
//# sourceMappingURL=semantic-resolver.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"semantic-resolver.js","sourceRoot":"","sources":["../../../../src/ui/themes/semantic-resolver.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAkB;IACtD,OAAO;QACL,IAAI,EAAE;YACJ,OAAO,EAAE,KAAK,CAAC,UAAU;YACzB,SAAS,EAAE,KAAK,CAAC,IAAI;YACrB,MAAM,EAAE,KAAK,CAAC,UAAU;SACzB;QACD,MAAM,EAAE;YACN,OAAO,EAAE,KAAK,CAAC,WAAW;YAC1B,OAAO,EAAE,KAAK,CAAC,YAAY;YAC3B,KAAK,EAAE,KAAK,CAAC,SAAS;SACvB;QACD,UAAU,EAAE;YACV,OAAO,EAAE,KAAK,CAAC,UAAU;YACzB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,WAAW;SAChD;QACD,MAAM,EAAE;YACN,OAAO,EAAE,KAAK,CAAC,IAAI;YACnB,OAAO,EAAE,KAAK,CAAC,UAAU;SAC1B;KACF,CAAC;AACJ,CAAC"}
|