tabby-ai-assistant 1.0.12 → 1.0.15
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/.editorconfig +18 -0
- package/README.md +113 -55
- package/dist/index.js +1 -1
- package/package.json +6 -4
- package/src/components/chat/ai-sidebar.component.scss +220 -9
- package/src/components/chat/ai-sidebar.component.ts +364 -29
- package/src/components/chat/chat-input.component.ts +36 -4
- package/src/components/chat/chat-interface.component.ts +225 -5
- package/src/components/chat/chat-message.component.ts +6 -1
- package/src/components/settings/context-settings.component.ts +91 -91
- package/src/components/terminal/ai-toolbar-button.component.ts +4 -2
- package/src/components/terminal/command-suggestion.component.ts +148 -6
- package/src/index.ts +0 -6
- package/src/providers/tabby/ai-toolbar-button.provider.ts +7 -3
- package/src/services/chat/ai-sidebar.service.ts +414 -410
- package/src/services/chat/chat-session.service.ts +36 -12
- package/src/services/context/compaction.ts +110 -134
- package/src/services/context/manager.ts +27 -7
- package/src/services/context/memory.ts +17 -33
- package/src/services/context/summary.service.ts +136 -0
- package/src/services/core/ai-assistant.service.ts +1060 -37
- package/src/services/core/ai-provider-manager.service.ts +154 -25
- package/src/services/core/checkpoint.service.ts +218 -18
- package/src/services/core/config-provider.service.ts +4 -12
- package/src/services/core/toast.service.ts +106 -106
- package/src/services/providers/anthropic-provider.service.ts +126 -202
- package/src/services/providers/base-provider.service.ts +315 -21
- package/src/services/providers/glm-provider.service.ts +151 -233
- package/src/services/providers/minimax-provider.service.ts +55 -238
- package/src/services/providers/ollama-provider.service.ts +117 -188
- package/src/services/providers/openai-compatible.service.ts +165 -177
- package/src/services/providers/openai-provider.service.ts +170 -177
- package/src/services/providers/vllm-provider.service.ts +116 -188
- package/src/services/terminal/terminal-context.service.ts +265 -5
- package/src/services/terminal/terminal-manager.service.ts +748 -748
- package/src/services/terminal/terminal-tools.service.ts +612 -441
- package/src/types/ai.types.ts +156 -3
- package/src/types/provider.types.ts +206 -75
- package/src/utils/cost.utils.ts +249 -0
- package/src/utils/validation.utils.ts +306 -2
- package/dist/index.js.LICENSE.txt +0 -18
- package/src/index.ts.backup +0 -165
- package/src/services/chat/chat-history.service.ts.backup +0 -239
- package/src/services/terminal/command-analyzer.service.ts +0 -43
- package/src/services/terminal/context-menu.service.ts +0 -45
- package/src/services/terminal/hotkey.service.ts +0 -53
- package/webpack.config.js.backup +0 -57
package/src/index.ts.backup
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { FormsModule } from '@angular/forms';
|
|
4
|
-
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
|
5
|
-
|
|
6
|
-
// Tabby modules
|
|
7
|
-
import TabbyCoreModule, { ToolbarButtonProvider, ConfigProvider, HotkeyProvider } from 'tabby-core';
|
|
8
|
-
import TabbyTerminalModule from 'tabby-terminal';
|
|
9
|
-
import { SettingsTabProvider } from 'tabby-settings';
|
|
10
|
-
|
|
11
|
-
// Core Services
|
|
12
|
-
import { AiAssistantService } from './services/core/ai-assistant.service';
|
|
13
|
-
import { AiProviderManagerService } from './services/core/ai-provider-manager.service';
|
|
14
|
-
import { ConfigProviderService } from './services/core/config-provider.service';
|
|
15
|
-
import { LoggerService } from './services/core/logger.service';
|
|
16
|
-
|
|
17
|
-
// Providers
|
|
18
|
-
import { BaseAiProvider } from './services/providers/base-provider.service';
|
|
19
|
-
import { OpenAiProviderService } from './services/providers/openai-provider.service';
|
|
20
|
-
import { AnthropicProviderService } from './services/providers/anthropic-provider.service';
|
|
21
|
-
import { MinimaxProviderService } from './services/providers/minimax-provider.service';
|
|
22
|
-
import { GlmProviderService } from './services/providers/glm-provider.service';
|
|
23
|
-
import { OpenAiCompatibleProviderService } from './services/providers/openai-compatible.service';
|
|
24
|
-
|
|
25
|
-
// Security Services
|
|
26
|
-
import { SecurityValidatorService } from './services/security/security-validator.service';
|
|
27
|
-
import { RiskAssessmentService } from './services/security/risk-assessment.service';
|
|
28
|
-
import { PasswordManagerService } from './services/security/password-manager.service';
|
|
29
|
-
import { ConsentManagerService } from './services/security/consent-manager.service';
|
|
30
|
-
|
|
31
|
-
// Chat Services
|
|
32
|
-
import { ChatSessionService } from './services/chat/chat-session.service';
|
|
33
|
-
import { ChatHistoryService } from './services/chat/chat-history.service';
|
|
34
|
-
import { CommandGeneratorService } from './services/chat/command-generator.service';
|
|
35
|
-
|
|
36
|
-
// Terminal Services
|
|
37
|
-
import { CommandAnalyzerService } from './services/terminal/command-analyzer.service';
|
|
38
|
-
import { ContextMenuService } from './services/terminal/context-menu.service';
|
|
39
|
-
import { HotkeyService } from './services/terminal/hotkey.service';
|
|
40
|
-
|
|
41
|
-
// Tabby Providers (enabled for proper integration)
|
|
42
|
-
|
|
43
|
-
// Components
|
|
44
|
-
import { ChatInterfaceComponent } from './components/chat/chat-interface.component';
|
|
45
|
-
import { ChatMessageComponent } from './components/chat/chat-message.component';
|
|
46
|
-
import { ChatInputComponent } from './components/chat/chat-input.component';
|
|
47
|
-
import { ChatSettingsComponent } from './components/chat/chat-settings.component';
|
|
48
|
-
|
|
49
|
-
import { AiSettingsTabComponent } from './components/settings/ai-settings-tab.component';
|
|
50
|
-
import { ProviderConfigComponent } from './components/settings/provider-config.component';
|
|
51
|
-
import { SecuritySettingsComponent } from './components/settings/security-settings.component';
|
|
52
|
-
import { GeneralSettingsComponent } from './components/settings/general-settings.component';
|
|
53
|
-
|
|
54
|
-
import { RiskConfirmDialogComponent } from './components/security/risk-confirm-dialog.component';
|
|
55
|
-
import { PasswordPromptComponent } from './components/security/password-prompt.component';
|
|
56
|
-
import { ConsentDialogComponent } from './components/security/consent-dialog.component';
|
|
57
|
-
|
|
58
|
-
import { CommandSuggestionComponent } from './components/terminal/command-suggestion.component';
|
|
59
|
-
import { CommandPreviewComponent } from './components/terminal/command-preview.component';
|
|
60
|
-
import { AiToolbarButtonComponent } from './components/terminal/ai-toolbar-button.component';
|
|
61
|
-
|
|
62
|
-
import { LoadingSpinnerComponent } from './components/common/loading-spinner.component';
|
|
63
|
-
import { ErrorMessageComponent } from './components/common/error-message.component';
|
|
64
|
-
|
|
65
|
-
// Tabby Integration Providers (enabled for proper integration)
|
|
66
|
-
import { AiToolbarButtonProvider } from './providers/tabby/ai-toolbar-button.provider';
|
|
67
|
-
import { AiSettingsTabProvider } from './providers/tabby/ai-settings-tab.provider';
|
|
68
|
-
import { AiConfigProvider } from './providers/tabby/ai-config.provider';
|
|
69
|
-
import { AiHotkeyProvider } from './providers/tabby/ai-hotkey.provider';
|
|
70
|
-
|
|
71
|
-
@NgModule({
|
|
72
|
-
imports: [
|
|
73
|
-
CommonModule,
|
|
74
|
-
FormsModule,
|
|
75
|
-
TabbyCoreModule, // Enabled for Tabby integration
|
|
76
|
-
TabbyTerminalModule, // Required for terminal integration
|
|
77
|
-
NgbModule
|
|
78
|
-
],
|
|
79
|
-
providers: [
|
|
80
|
-
// Core Services
|
|
81
|
-
AiAssistantService,
|
|
82
|
-
AiProviderManagerService,
|
|
83
|
-
ConfigProviderService,
|
|
84
|
-
LoggerService,
|
|
85
|
-
|
|
86
|
-
// AI Providers
|
|
87
|
-
OpenAiProviderService,
|
|
88
|
-
AnthropicProviderService,
|
|
89
|
-
MinimaxProviderService,
|
|
90
|
-
GlmProviderService,
|
|
91
|
-
OpenAiCompatibleProviderService,
|
|
92
|
-
|
|
93
|
-
// Security Services
|
|
94
|
-
SecurityValidatorService,
|
|
95
|
-
RiskAssessmentService,
|
|
96
|
-
PasswordManagerService,
|
|
97
|
-
ConsentManagerService,
|
|
98
|
-
|
|
99
|
-
// Chat Services
|
|
100
|
-
ChatSessionService,
|
|
101
|
-
ChatHistoryService,
|
|
102
|
-
CommandGeneratorService,
|
|
103
|
-
|
|
104
|
-
// Terminal Services
|
|
105
|
-
CommandAnalyzerService,
|
|
106
|
-
ContextMenuService,
|
|
107
|
-
HotkeyService,
|
|
108
|
-
|
|
109
|
-
// Tabby Integration Providers (enabled for proper integration)
|
|
110
|
-
{ provide: ToolbarButtonProvider, useClass: AiToolbarButtonProvider, multi: true },
|
|
111
|
-
{ provide: SettingsTabProvider, useClass: AiSettingsTabProvider, multi: true },
|
|
112
|
-
{ provide: ConfigProvider, useClass: AiConfigProvider, multi: true },
|
|
113
|
-
{ provide: HotkeyProvider, useClass: AiHotkeyProvider, multi: true },
|
|
114
|
-
// { provide: TabContextMenuItemProvider, useClass: AiContextMenuProvider, multi: true }
|
|
115
|
-
],
|
|
116
|
-
declarations: [
|
|
117
|
-
// Chat Components
|
|
118
|
-
ChatInterfaceComponent,
|
|
119
|
-
ChatMessageComponent,
|
|
120
|
-
ChatInputComponent,
|
|
121
|
-
ChatSettingsComponent,
|
|
122
|
-
|
|
123
|
-
// Settings Components
|
|
124
|
-
AiSettingsTabComponent,
|
|
125
|
-
ProviderConfigComponent,
|
|
126
|
-
SecuritySettingsComponent,
|
|
127
|
-
GeneralSettingsComponent,
|
|
128
|
-
|
|
129
|
-
// Security Components
|
|
130
|
-
RiskConfirmDialogComponent,
|
|
131
|
-
PasswordPromptComponent,
|
|
132
|
-
ConsentDialogComponent,
|
|
133
|
-
|
|
134
|
-
// Terminal Components
|
|
135
|
-
CommandSuggestionComponent,
|
|
136
|
-
CommandPreviewComponent,
|
|
137
|
-
AiToolbarButtonComponent,
|
|
138
|
-
|
|
139
|
-
// Common Components
|
|
140
|
-
LoadingSpinnerComponent,
|
|
141
|
-
ErrorMessageComponent
|
|
142
|
-
],
|
|
143
|
-
entryComponents: [
|
|
144
|
-
ChatInterfaceComponent,
|
|
145
|
-
RiskConfirmDialogComponent,
|
|
146
|
-
PasswordPromptComponent,
|
|
147
|
-
ConsentDialogComponent,
|
|
148
|
-
CommandSuggestionComponent,
|
|
149
|
-
CommandPreviewComponent
|
|
150
|
-
]
|
|
151
|
-
})
|
|
152
|
-
export default class AiAssistantModule {
|
|
153
|
-
constructor(
|
|
154
|
-
private app: any,
|
|
155
|
-
private aiService: AiAssistantService,
|
|
156
|
-
private config: ConfigProviderService
|
|
157
|
-
) {
|
|
158
|
-
// Wait for Tabby to be ready
|
|
159
|
-
if (this.app && this.app.ready$) {
|
|
160
|
-
this.app.ready$.subscribe(() => {
|
|
161
|
-
this.aiService.initialize();
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import { BehaviorSubject, Observable } from 'rxjs';
|
|
3
|
-
import { ChatMessage } from '../../types/ai.types';
|
|
4
|
-
import { LoggerService } from '../core/logger.service';
|
|
5
|
-
|
|
6
|
-
export interface SavedSession {
|
|
7
|
-
sessionId: string;
|
|
8
|
-
title: string;
|
|
9
|
-
messages: ChatMessage[];
|
|
10
|
-
createdAt: Date;
|
|
11
|
-
updatedAt: Date;
|
|
12
|
-
messageCount: number;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const STORAGE_KEY = 'tabby-ai-assistant-chat-history';
|
|
16
|
-
const MAX_SESSIONS = 50;
|
|
17
|
-
const MAX_MESSAGES_PER_SESSION = 1000;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 聊天历史服务
|
|
21
|
-
* 持久化存储和管理聊天会话历史
|
|
22
|
-
*/
|
|
23
|
-
@Injectable({
|
|
24
|
-
providedIn: 'root'
|
|
25
|
-
})
|
|
26
|
-
export class ChatHistoryService {
|
|
27
|
-
private sessionsSubject = new BehaviorSubject<SavedSession[]>([]);
|
|
28
|
-
public sessions$ = this.sessionsSubject.asObservable();
|
|
29
|
-
|
|
30
|
-
constructor(private logger: LoggerService) {
|
|
31
|
-
this.loadSessions();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 保存会话
|
|
36
|
-
*/
|
|
37
|
-
saveSession(sessionId: string, messages: ChatMessage[], title?: string): void {
|
|
38
|
-
try {
|
|
39
|
-
const sessions = this.sessionsSubject.value;
|
|
40
|
-
const existingIndex = sessions.findIndex(s => s.sessionId === sessionId);
|
|
41
|
-
|
|
42
|
-
const sessionTitle = title || this.generateSessionTitle(messages);
|
|
43
|
-
const now = new Date();
|
|
44
|
-
|
|
45
|
-
const session: SavedSession = {
|
|
46
|
-
sessionId,
|
|
47
|
-
title: sessionTitle,
|
|
48
|
-
messages: this.trimMessages(messages),
|
|
49
|
-
createdAt: existingIndex >= 0 ? sessions[existingIndex].createdAt : now,
|
|
50
|
-
updatedAt: now,
|
|
51
|
-
messageCount: messages.length
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
if (existingIndex >= 0) {
|
|
55
|
-
sessions[existingIndex] = session;
|
|
56
|
-
} else {
|
|
57
|
-
sessions.unshift(session);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// 限制会话数量
|
|
61
|
-
const trimmedSessions = sessions.slice(0, MAX_SESSIONS);
|
|
62
|
-
this.sessionsSubject.next(trimmedSessions);
|
|
63
|
-
this.saveToStorage(trimmedSessions);
|
|
64
|
-
|
|
65
|
-
this.logger.info('Session saved', { sessionId, title: sessionTitle });
|
|
66
|
-
|
|
67
|
-
} catch (error) {
|
|
68
|
-
this.logger.error('Failed to save session', { error, sessionId });
|
|
69
|
-
throw error;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* 加载会话
|
|
75
|
-
*/
|
|
76
|
-
loadSession(sessionId: string): SavedSession | undefined {
|
|
77
|
-
const sessions = this.sessionsSubject.value;
|
|
78
|
-
return sessions.find(s => s.sessionId === sessionId);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* 删除会话
|
|
83
|
-
*/
|
|
84
|
-
deleteSession(sessionId: string): void {
|
|
85
|
-
const sessions = this.sessionsSubject.value;
|
|
86
|
-
const filteredSessions = sessions.filter(s => s.sessionId !== sessionId);
|
|
87
|
-
this.sessionsSubject.next(filteredSessions);
|
|
88
|
-
this.saveToStorage(filteredSessions);
|
|
89
|
-
this.logger.info('Session deleted', { sessionId });
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* 清空所有历史
|
|
94
|
-
*/
|
|
95
|
-
clearAllHistory(): void {
|
|
96
|
-
this.sessionsSubject.next([]);
|
|
97
|
-
this.saveToStorage([]);
|
|
98
|
-
this.logger.info('All chat history cleared');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* 搜索会话
|
|
103
|
-
*/
|
|
104
|
-
searchSessions(query: string): SavedSession[] {
|
|
105
|
-
const sessions = this.sessionsSubject.value;
|
|
106
|
-
const lowercaseQuery = query.toLowerCase();
|
|
107
|
-
|
|
108
|
-
return sessions.filter(session =>
|
|
109
|
-
session.title.toLowerCase().includes(lowercaseQuery) ||
|
|
110
|
-
session.messages.some(msg =>
|
|
111
|
-
msg.content.toLowerCase().includes(lowercaseQuery)
|
|
112
|
-
)
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* 获取最近的会话
|
|
118
|
-
*/
|
|
119
|
-
getRecentSessions(count: number = 10): SavedSession[] {
|
|
120
|
-
const sessions = this.sessionsSubject.value;
|
|
121
|
-
return sessions.slice(0, count);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* 获取会话统计
|
|
126
|
-
*/
|
|
127
|
-
getStatistics(): {
|
|
128
|
-
totalSessions: number;
|
|
129
|
-
totalMessages: number;
|
|
130
|
-
averageMessagesPerSession: number;
|
|
131
|
-
oldestSession?: Date;
|
|
132
|
-
newestSession?: Date;
|
|
133
|
-
} {
|
|
134
|
-
const sessions = this.sessionsSubject.value;
|
|
135
|
-
const totalSessions = sessions.length;
|
|
136
|
-
const totalMessages = sessions.reduce((sum, s) => sum + s.messageCount, 0);
|
|
137
|
-
const averageMessagesPerSession = totalSessions > 0 ? totalMessages / totalSessions : 0;
|
|
138
|
-
|
|
139
|
-
const dates = sessions.map(s => s.createdAt.getTime());
|
|
140
|
-
const oldestSession = dates.length > 0 ? new Date(Math.min(...dates)) : undefined;
|
|
141
|
-
const newestSession = dates.length > 0 ? new Date(Math.max(...dates)) : undefined;
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
totalSessions,
|
|
145
|
-
totalMessages,
|
|
146
|
-
averageMessagesPerSession: Math.round(averageMessagesPerSession * 100) / 100,
|
|
147
|
-
oldestSession,
|
|
148
|
-
newestSession
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* 导出所有历史
|
|
154
|
-
*/
|
|
155
|
-
exportAllHistory(): string {
|
|
156
|
-
const sessions = this.sessionsSubject.value;
|
|
157
|
-
const exportData = {
|
|
158
|
-
exportDate: new Date().toISOString(),
|
|
159
|
-
version: '1.0',
|
|
160
|
-
sessions
|
|
161
|
-
};
|
|
162
|
-
return JSON.stringify(exportData, null, 2);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* 导入历史
|
|
167
|
-
*/
|
|
168
|
-
importHistory(data: string): void {
|
|
169
|
-
try {
|
|
170
|
-
const importData = JSON.parse(data);
|
|
171
|
-
|
|
172
|
-
if (!importData.sessions || !Array.isArray(importData.sessions)) {
|
|
173
|
-
throw new Error('Invalid history format');
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const sessions = importData.sessions.map((s: any) => ({
|
|
177
|
-
...s,
|
|
178
|
-
createdAt: new Date(s.createdAt),
|
|
179
|
-
updatedAt: new Date(s.updatedAt)
|
|
180
|
-
}));
|
|
181
|
-
|
|
182
|
-
this.sessionsSubject.next(sessions);
|
|
183
|
-
this.saveToStorage(sessions);
|
|
184
|
-
|
|
185
|
-
this.logger.info('History imported', {
|
|
186
|
-
sessionCount: sessions.length
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
} catch (error) {
|
|
190
|
-
this.logger.error('Failed to import history', error);
|
|
191
|
-
throw new Error('Invalid history file format');
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
private loadSessions(): void {
|
|
196
|
-
try {
|
|
197
|
-
const stored = localStorage.getItem(STORAGE_KEY);
|
|
198
|
-
if (stored) {
|
|
199
|
-
const sessions = JSON.parse(stored).map((s: any) => ({
|
|
200
|
-
...s,
|
|
201
|
-
createdAt: new Date(s.createdAt),
|
|
202
|
-
updatedAt: new Date(s.updatedAt)
|
|
203
|
-
}));
|
|
204
|
-
this.sessionsSubject.next(sessions);
|
|
205
|
-
this.logger.info('Loaded sessions from storage', { count: sessions.length });
|
|
206
|
-
}
|
|
207
|
-
} catch (error) {
|
|
208
|
-
this.logger.error('Failed to load sessions from storage', error);
|
|
209
|
-
this.sessionsSubject.next([]);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
private saveToStorage(sessions: SavedSession[]): void {
|
|
214
|
-
try {
|
|
215
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(sessions));
|
|
216
|
-
} catch (error) {
|
|
217
|
-
this.logger.error('Failed to save sessions to storage', error);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
private generateSessionTitle(messages: ChatMessage[]): string {
|
|
222
|
-
const firstUserMessage = messages.find(m => m.role === 'user');
|
|
223
|
-
if (!firstUserMessage) {
|
|
224
|
-
return `会话 ${new Date().toLocaleString()}`;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const content = firstUserMessage.content;
|
|
228
|
-
return content.length > 50 ? content.substring(0, 50) + '...' : content;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
private trimMessages(messages: ChatMessage[]): ChatMessage[] {
|
|
232
|
-
if (messages.length <= MAX_MESSAGES_PER_SESSION) {
|
|
233
|
-
return messages;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// 保留最近的messages
|
|
237
|
-
return messages.slice(-MAX_MESSAGES_PER_SESSION);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import { Observable, of } from 'rxjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 命令分析服务
|
|
6
|
-
* 分析终端命令并提供智能建议
|
|
7
|
-
*/
|
|
8
|
-
@Injectable({
|
|
9
|
-
providedIn: 'root'
|
|
10
|
-
})
|
|
11
|
-
export class CommandAnalyzerService {
|
|
12
|
-
constructor() {}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* 分析命令
|
|
16
|
-
*/
|
|
17
|
-
analyzeCommand(command: string): Observable<any> {
|
|
18
|
-
// TODO: 实现命令分析逻辑
|
|
19
|
-
return of({
|
|
20
|
-
type: 'unknown',
|
|
21
|
-
suggestions: [],
|
|
22
|
-
explanation: ''
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* 获取命令历史
|
|
28
|
-
*/
|
|
29
|
-
getCommandHistory(): string[] {
|
|
30
|
-
return [];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* 解析命令参数
|
|
35
|
-
*/
|
|
36
|
-
parseCommand(command: string): any {
|
|
37
|
-
const parts = command.trim().split(/\s+/);
|
|
38
|
-
return {
|
|
39
|
-
command: parts[0],
|
|
40
|
-
args: parts.slice(1)
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import { Subject } from 'rxjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 上下文菜单服务
|
|
6
|
-
* 管理终端上下文菜单
|
|
7
|
-
*/
|
|
8
|
-
@Injectable({
|
|
9
|
-
providedIn: 'root'
|
|
10
|
-
})
|
|
11
|
-
export class ContextMenuService {
|
|
12
|
-
private menuItemSelected$ = new Subject<any>();
|
|
13
|
-
|
|
14
|
-
constructor() {}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 显示上下文菜单
|
|
18
|
-
*/
|
|
19
|
-
showMenu(x: number, y: number, items: any[]): void {
|
|
20
|
-
// TODO: 实现上下文菜单显示
|
|
21
|
-
console.log('Show context menu at', x, y, items);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 隐藏上下文菜单
|
|
26
|
-
*/
|
|
27
|
-
hideMenu(): void {
|
|
28
|
-
// TODO: 实现上下文菜单隐藏
|
|
29
|
-
console.log('Hide context menu');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 订阅菜单项选择事件
|
|
34
|
-
*/
|
|
35
|
-
onMenuItemSelected(): any {
|
|
36
|
-
return this.menuItemSelected$.asObservable();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 触发菜单项选择
|
|
41
|
-
*/
|
|
42
|
-
selectMenuItem(item: any): void {
|
|
43
|
-
this.menuItemSelected$.next(item);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import { Subject } from 'rxjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 热键服务
|
|
6
|
-
* 管理全局热键注册和处理
|
|
7
|
-
*/
|
|
8
|
-
@Injectable({
|
|
9
|
-
providedIn: 'root'
|
|
10
|
-
})
|
|
11
|
-
export class HotkeyService {
|
|
12
|
-
private hotkeyPressed$ = new Subject<string>();
|
|
13
|
-
|
|
14
|
-
constructor() {}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 注册热键
|
|
18
|
-
*/
|
|
19
|
-
registerHotkey(key: string, callback: () => void): void {
|
|
20
|
-
// TODO: 实现热键注册
|
|
21
|
-
console.log('Register hotkey', key);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 取消注册热键
|
|
26
|
-
*/
|
|
27
|
-
unregisterHotkey(key: string): void {
|
|
28
|
-
// TODO: 实现热键取消注册
|
|
29
|
-
console.log('Unregister hotkey', key);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 订阅热键按下事件
|
|
34
|
-
*/
|
|
35
|
-
onHotkeyPressed(): any {
|
|
36
|
-
return this.hotkeyPressed$.asObservable();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 触发热键事件
|
|
41
|
-
*/
|
|
42
|
-
triggerHotkey(key: string): void {
|
|
43
|
-
this.hotkeyPressed$.next(key);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* 检查热键是否已注册
|
|
48
|
-
*/
|
|
49
|
-
isHotkeyRegistered(key: string): boolean {
|
|
50
|
-
// TODO: 实现热键检查
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
package/webpack.config.js.backup
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const webpack = require('webpack');
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
mode: 'production',
|
|
6
|
-
entry: './src/index.ts',
|
|
7
|
-
output: {
|
|
8
|
-
path: path.resolve(__dirname, 'dist'),
|
|
9
|
-
filename: 'index.js',
|
|
10
|
-
libraryTarget: 'umd',
|
|
11
|
-
devtoolModuleFilenameTemplate: 'webpack-tabby-ai-assistant:///[resource-path]',
|
|
12
|
-
},
|
|
13
|
-
resolve: {
|
|
14
|
-
extensions: ['.ts', '.js'],
|
|
15
|
-
alias: {
|
|
16
|
-
'@': path.resolve(__dirname, 'src')
|
|
17
|
-
},
|
|
18
|
-
fallback: {
|
|
19
|
-
'os': false,
|
|
20
|
-
'path': false,
|
|
21
|
-
'crypto': false,
|
|
22
|
-
'stream': false,
|
|
23
|
-
'util': false
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
module: {
|
|
27
|
-
rules: [
|
|
28
|
-
{
|
|
29
|
-
test: /\.ts$/,
|
|
30
|
-
use: [
|
|
31
|
-
{ loader: 'ts-loader' },
|
|
32
|
-
{ loader: 'angular2-template-loader' }
|
|
33
|
-
],
|
|
34
|
-
exclude: /node_modules/
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
test: /\.(html|css|scss)$/,
|
|
38
|
-
use: ['raw-loader']
|
|
39
|
-
}
|
|
40
|
-
]
|
|
41
|
-
},
|
|
42
|
-
externals: [
|
|
43
|
-
'tabby-core',
|
|
44
|
-
'tabby-terminal',
|
|
45
|
-
'tabby-settings',
|
|
46
|
-
'@angular/core',
|
|
47
|
-
'@angular/common',
|
|
48
|
-
'@angular/forms',
|
|
49
|
-
'@ng-bootstrap/ng-bootstrap',
|
|
50
|
-
'rxjs'
|
|
51
|
-
],
|
|
52
|
-
plugins: [
|
|
53
|
-
new webpack.DefinePlugin({
|
|
54
|
-
'process.env.NODE_ENV': JSON.stringify('production')
|
|
55
|
-
})
|
|
56
|
-
]
|
|
57
|
-
};
|