@lobehub/lobehub 2.0.0-next.50 → 2.0.0-next.52
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/CHANGELOG.md +50 -0
- package/apps/desktop/src/main/controllers/LocalFileCtr.ts +25 -5
- package/apps/desktop/src/main/controllers/ShellCommandCtr.ts +242 -0
- package/apps/desktop/src/main/controllers/__tests__/LocalFileCtr.test.ts +4 -1
- package/apps/desktop/src/main/controllers/__tests__/ShellCommandCtr.test.ts +499 -0
- package/apps/desktop/src/main/modules/fileSearch/__tests__/macOS.integration.test.ts +357 -0
- package/apps/desktop/src/main/modules/fileSearch/impl/macOS.ts +30 -22
- package/changelog/v1.json +18 -0
- package/locales/ar/chat.json +20 -0
- package/locales/ar/common.json +1 -0
- package/locales/ar/components.json +6 -0
- package/locales/ar/models.json +119 -126
- package/locales/ar/plugin.json +2 -1
- package/locales/bg-BG/chat.json +20 -0
- package/locales/bg-BG/common.json +1 -0
- package/locales/bg-BG/components.json +6 -0
- package/locales/bg-BG/models.json +104 -132
- package/locales/bg-BG/plugin.json +2 -1
- package/locales/de-DE/chat.json +20 -0
- package/locales/de-DE/common.json +1 -0
- package/locales/de-DE/components.json +6 -0
- package/locales/de-DE/models.json +119 -126
- package/locales/de-DE/plugin.json +2 -1
- package/locales/en-US/chat.json +20 -0
- package/locales/en-US/common.json +1 -0
- package/locales/en-US/components.json +6 -0
- package/locales/en-US/models.json +167 -126
- package/locales/en-US/plugin.json +2 -1
- package/locales/es-ES/chat.json +20 -0
- package/locales/es-ES/common.json +1 -0
- package/locales/es-ES/components.json +6 -0
- package/locales/es-ES/models.json +119 -126
- package/locales/es-ES/plugin.json +2 -1
- package/locales/fa-IR/chat.json +20 -0
- package/locales/fa-IR/common.json +1 -0
- package/locales/fa-IR/components.json +6 -0
- package/locales/fa-IR/models.json +119 -126
- package/locales/fa-IR/plugin.json +2 -1
- package/locales/fr-FR/chat.json +20 -0
- package/locales/fr-FR/common.json +1 -0
- package/locales/fr-FR/components.json +6 -0
- package/locales/fr-FR/models.json +119 -126
- package/locales/fr-FR/plugin.json +2 -1
- package/locales/it-IT/chat.json +20 -0
- package/locales/it-IT/common.json +1 -0
- package/locales/it-IT/components.json +6 -0
- package/locales/it-IT/models.json +119 -126
- package/locales/it-IT/plugin.json +2 -1
- package/locales/ja-JP/chat.json +20 -0
- package/locales/ja-JP/common.json +1 -0
- package/locales/ja-JP/components.json +6 -0
- package/locales/ja-JP/models.json +119 -126
- package/locales/ja-JP/plugin.json +2 -1
- package/locales/ko-KR/chat.json +20 -0
- package/locales/ko-KR/common.json +1 -0
- package/locales/ko-KR/components.json +6 -0
- package/locales/ko-KR/models.json +119 -126
- package/locales/ko-KR/plugin.json +2 -1
- package/locales/nl-NL/chat.json +20 -0
- package/locales/nl-NL/common.json +1 -0
- package/locales/nl-NL/components.json +6 -0
- package/locales/nl-NL/models.json +119 -126
- package/locales/nl-NL/plugin.json +2 -1
- package/locales/pl-PL/chat.json +20 -0
- package/locales/pl-PL/common.json +1 -0
- package/locales/pl-PL/components.json +6 -0
- package/locales/pl-PL/models.json +119 -126
- package/locales/pl-PL/plugin.json +2 -1
- package/locales/pt-BR/chat.json +20 -0
- package/locales/pt-BR/common.json +1 -0
- package/locales/pt-BR/components.json +6 -0
- package/locales/pt-BR/models.json +119 -126
- package/locales/pt-BR/plugin.json +2 -1
- package/locales/ru-RU/chat.json +20 -0
- package/locales/ru-RU/common.json +1 -0
- package/locales/ru-RU/components.json +6 -0
- package/locales/ru-RU/models.json +119 -126
- package/locales/ru-RU/plugin.json +2 -1
- package/locales/tr-TR/chat.json +20 -0
- package/locales/tr-TR/common.json +1 -0
- package/locales/tr-TR/components.json +6 -0
- package/locales/tr-TR/models.json +119 -126
- package/locales/tr-TR/plugin.json +2 -1
- package/locales/vi-VN/chat.json +20 -0
- package/locales/vi-VN/common.json +1 -0
- package/locales/vi-VN/components.json +6 -0
- package/locales/vi-VN/models.json +119 -126
- package/locales/vi-VN/plugin.json +2 -1
- package/locales/zh-CN/chat.json +20 -0
- package/locales/zh-CN/common.json +1 -0
- package/locales/zh-CN/components.json +6 -0
- package/locales/zh-CN/models.json +173 -80
- package/locales/zh-CN/plugin.json +2 -1
- package/locales/zh-TW/chat.json +20 -0
- package/locales/zh-TW/common.json +1 -0
- package/locales/zh-TW/components.json +6 -0
- package/locales/zh-TW/models.json +119 -126
- package/locales/zh-TW/plugin.json +2 -1
- package/package.json +1 -1
- package/packages/agent-runtime/src/core/InterventionChecker.ts +1 -1
- package/packages/agent-runtime/src/core/__tests__/InterventionChecker.test.ts +23 -23
- package/packages/agent-runtime/src/types/state.ts +7 -1
- package/packages/const/src/settings/tool.ts +1 -5
- package/packages/electron-client-ipc/src/types/localSystem.ts +26 -2
- package/packages/file-loaders/src/loaders/docx/index.ts +1 -1
- package/packages/model-bank/src/aiModels/wenxin.ts +1348 -291
- package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +58 -0
- package/packages/model-runtime/src/core/contextBuilders/openai.ts +24 -10
- package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +3 -2
- package/packages/model-runtime/src/providers/openai/index.test.ts +44 -0
- package/packages/model-runtime/src/providers/wenxin/index.ts +22 -1
- package/packages/model-runtime/src/utils/modelParse.ts +6 -0
- package/packages/types/src/tool/builtin.ts +15 -4
- package/packages/types/src/tool/intervention.ts +32 -2
- package/packages/types/src/user/settings/tool.ts +3 -27
- package/src/config/modelProviders/wenxin.ts +2 -3
- package/src/features/Conversation/MarkdownElements/remarkPlugins/__snapshots__/createRemarkSelfClosingTagPlugin.test.ts.snap +133 -0
- package/src/features/Conversation/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.test.ts +48 -0
- package/src/features/Conversation/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.ts +2 -1
- package/src/features/Conversation/Messages/Assistant/Tool/Render/LoadingPlaceholder/index.tsx +3 -3
- package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/Fallback.tsx +98 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ModeSelector.tsx +5 -6
- package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/index.tsx +40 -36
- package/src/features/Conversation/Messages/Group/Tool/Render/LoadingPlaceholder/index.tsx +3 -3
- package/src/features/Conversation/Messages/Group/Tool/Render/index.tsx +25 -18
- package/src/features/LocalFile/LocalFile.tsx +55 -5
- package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +10 -4
- package/src/features/PluginsUI/Render/BuiltinType/index.tsx +2 -2
- package/src/locales/default/components.ts +6 -0
- package/src/locales/default/plugin.ts +2 -1
- package/src/services/chat/chat.test.ts +1 -0
- package/src/services/electron/localFileService.ts +4 -0
- package/src/store/aiInfra/slices/aiProvider/__tests__/selectors.test.ts +62 -0
- package/src/store/aiInfra/slices/aiProvider/selectors.ts +1 -1
- package/src/store/chat/agents/GeneralChatAgent.ts +26 -1
- package/src/store/chat/agents/__tests__/GeneralChatAgent.test.ts +173 -0
- package/src/store/chat/slices/aiChat/actions/conversationControl.ts +8 -40
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +91 -34
- package/src/store/user/selectors.ts +1 -0
- package/src/store/user/slices/settings/action.ts +12 -0
- package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +0 -7
- package/src/store/user/slices/settings/selectors/index.ts +1 -0
- package/src/store/user/slices/settings/selectors/settings.test.ts +0 -37
- package/src/store/user/slices/settings/selectors/settings.ts +0 -5
- package/src/store/user/slices/settings/selectors/toolIntervention.ts +17 -0
- package/src/tools/code-interpreter/Render/index.tsx +1 -1
- package/src/tools/interventions.ts +32 -0
- package/src/tools/local-system/Intervention/RunCommand/index.tsx +56 -0
- package/src/tools/local-system/Placeholder/ListFiles.tsx +3 -5
- package/src/tools/local-system/Placeholder/SearchFiles.tsx +2 -5
- package/src/tools/local-system/Render/ListFiles/index.tsx +16 -21
- package/src/tools/local-system/Render/RenameLocalFile/index.tsx +15 -20
- package/src/tools/local-system/Render/RunCommand/index.tsx +103 -27
- package/src/tools/local-system/Render/SearchFiles/SearchQuery/index.tsx +0 -1
- package/src/tools/local-system/Render/SearchFiles/index.tsx +15 -20
- package/src/tools/local-system/Render/WriteFile/index.tsx +2 -8
- package/src/tools/local-system/index.ts +184 -4
- package/src/tools/local-system/systemRole.ts +62 -8
- package/src/tools/placeholders.ts +39 -8
- package/src/tools/renders.ts +56 -9
- package/src/tools/web-browsing/Placeholder/{PageContent.tsx → CrawlMultiPages.tsx} +4 -1
- package/src/tools/web-browsing/Placeholder/CrawlSinglePage.tsx +12 -0
- package/src/tools/web-browsing/Placeholder/Search.tsx +4 -4
- package/src/tools/web-browsing/Render/CrawlMultiPages.tsx +15 -0
- package/src/tools/web-browsing/Render/CrawlSinglePage.tsx +15 -0
- package/src/tools/web-browsing/Render/Search/index.tsx +39 -44
- package/packages/database/migrations/0044_add_tool_intervention.sql +0 -1
- package/src/tools/local-system/Placeholder/index.tsx +0 -25
- package/src/tools/local-system/Render/index.tsx +0 -40
- package/src/tools/web-browsing/Placeholder/index.tsx +0 -40
- package/src/tools/web-browsing/Render/index.tsx +0 -57
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.52](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.51...v2.0.0-next.52)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2025-11-13**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Filter out reasoning fields from messages in ChatCompletion API.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Filter out reasoning fields from messages in ChatCompletion API, closes [#10203](https://github.com/lobehub/lobe-chat/issues/10203) [#10193](https://github.com/lobehub/lobe-chat/issues/10193) ([5f28b2c](https://github.com/lobehub/lobe-chat/commit/5f28b2c))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.51](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.50...v2.0.0-next.51)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2025-11-13**</sup>
|
|
33
|
+
|
|
34
|
+
#### 💄 Styles
|
|
35
|
+
|
|
36
|
+
- **misc**: Update ERNIE-5.0-Thinking-Preview model.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### Styles
|
|
44
|
+
|
|
45
|
+
- **misc**: Update ERNIE-5.0-Thinking-Preview model, closes [#10196](https://github.com/lobehub/lobe-chat/issues/10196) ([89f3eed](https://github.com/lobehub/lobe-chat/commit/89f3eed))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
## [Version 2.0.0-next.50](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.49...v2.0.0-next.50)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2025-11-13**</sup>
|
|
@@ -467,15 +467,35 @@ export default class LocalFileCtr extends ControllerModule {
|
|
|
467
467
|
*/
|
|
468
468
|
@ipcClientEvent('searchLocalFiles')
|
|
469
469
|
async handleLocalFilesSearch(params: LocalSearchFilesParams): Promise<FileResult[]> {
|
|
470
|
-
logger.debug('Received file search request:', {
|
|
470
|
+
logger.debug('Received file search request:', {
|
|
471
|
+
directory: params.directory,
|
|
472
|
+
keywords: params.keywords,
|
|
473
|
+
});
|
|
471
474
|
|
|
472
|
-
|
|
473
|
-
|
|
475
|
+
// Build search options from params, mapping directory to onlyIn
|
|
476
|
+
const options: SearchOptions = {
|
|
477
|
+
contentContains: params.contentContains,
|
|
478
|
+
createdAfter: params.createdAfter ? new Date(params.createdAfter) : undefined,
|
|
479
|
+
createdBefore: params.createdBefore ? new Date(params.createdBefore) : undefined,
|
|
480
|
+
detailed: params.detailed,
|
|
481
|
+
exclude: params.exclude,
|
|
482
|
+
fileTypes: params.fileTypes,
|
|
483
|
+
keywords: params.keywords,
|
|
484
|
+
limit: params.limit || 30,
|
|
485
|
+
liveUpdate: params.liveUpdate,
|
|
486
|
+
modifiedAfter: params.modifiedAfter ? new Date(params.modifiedAfter) : undefined,
|
|
487
|
+
modifiedBefore: params.modifiedBefore ? new Date(params.modifiedBefore) : undefined,
|
|
488
|
+
onlyIn: params.directory, // Map directory param to onlyIn option
|
|
489
|
+
sortBy: params.sortBy,
|
|
490
|
+
sortDirection: params.sortDirection,
|
|
474
491
|
};
|
|
475
492
|
|
|
476
493
|
try {
|
|
477
|
-
const results = await this.searchService.search(
|
|
478
|
-
logger.debug('File search completed', {
|
|
494
|
+
const results = await this.searchService.search(options.keywords, options);
|
|
495
|
+
logger.debug('File search completed', {
|
|
496
|
+
count: results.length,
|
|
497
|
+
directory: params.directory,
|
|
498
|
+
});
|
|
479
499
|
return results;
|
|
480
500
|
} catch (error) {
|
|
481
501
|
logger.error('File search failed:', error);
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GetCommandOutputParams,
|
|
3
|
+
GetCommandOutputResult,
|
|
4
|
+
KillCommandParams,
|
|
5
|
+
KillCommandResult,
|
|
6
|
+
RunCommandParams,
|
|
7
|
+
RunCommandResult,
|
|
8
|
+
} from '@lobechat/electron-client-ipc';
|
|
9
|
+
import { ChildProcess, spawn } from 'node:child_process';
|
|
10
|
+
import { randomUUID } from 'node:crypto';
|
|
11
|
+
|
|
12
|
+
import { createLogger } from '@/utils/logger';
|
|
13
|
+
|
|
14
|
+
import { ControllerModule, ipcClientEvent } from './index';
|
|
15
|
+
|
|
16
|
+
const logger = createLogger('controllers:ShellCommandCtr');
|
|
17
|
+
|
|
18
|
+
interface ShellProcess {
|
|
19
|
+
lastReadStderr: number;
|
|
20
|
+
lastReadStdout: number;
|
|
21
|
+
process: ChildProcess;
|
|
22
|
+
stderr: string[];
|
|
23
|
+
stdout: string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default class ShellCommandCtr extends ControllerModule {
|
|
27
|
+
// Shell process management
|
|
28
|
+
private shellProcesses = new Map<string, ShellProcess>();
|
|
29
|
+
|
|
30
|
+
@ipcClientEvent('runCommand')
|
|
31
|
+
async handleRunCommand({
|
|
32
|
+
command,
|
|
33
|
+
description,
|
|
34
|
+
run_in_background,
|
|
35
|
+
timeout = 120_000,
|
|
36
|
+
}: RunCommandParams): Promise<RunCommandResult> {
|
|
37
|
+
const logPrefix = `[runCommand: ${description || command.slice(0, 50)}]`;
|
|
38
|
+
logger.debug(`${logPrefix} Starting command execution`, {
|
|
39
|
+
background: run_in_background,
|
|
40
|
+
timeout,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Validate timeout
|
|
44
|
+
const effectiveTimeout = Math.min(Math.max(timeout, 1000), 600_000);
|
|
45
|
+
|
|
46
|
+
// Cross-platform shell selection
|
|
47
|
+
const shellConfig =
|
|
48
|
+
process.platform === 'win32'
|
|
49
|
+
? { args: ['/c', command], cmd: 'cmd.exe' }
|
|
50
|
+
: { args: ['-c', command], cmd: '/bin/sh' };
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
if (run_in_background) {
|
|
54
|
+
// Background execution
|
|
55
|
+
const shellId = randomUUID();
|
|
56
|
+
const childProcess = spawn(shellConfig.cmd, shellConfig.args, {
|
|
57
|
+
env: process.env,
|
|
58
|
+
shell: false,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const shellProcess: ShellProcess = {
|
|
62
|
+
lastReadStderr: 0,
|
|
63
|
+
lastReadStdout: 0,
|
|
64
|
+
process: childProcess,
|
|
65
|
+
stderr: [],
|
|
66
|
+
stdout: [],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Capture output
|
|
70
|
+
childProcess.stdout?.on('data', (data) => {
|
|
71
|
+
shellProcess.stdout.push(data.toString());
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
childProcess.stderr?.on('data', (data) => {
|
|
75
|
+
shellProcess.stderr.push(data.toString());
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
childProcess.on('exit', (code) => {
|
|
79
|
+
logger.debug(`${logPrefix} Background process exited`, { code, shellId });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
this.shellProcesses.set(shellId, shellProcess);
|
|
83
|
+
|
|
84
|
+
logger.info(`${logPrefix} Started background execution`, { shellId });
|
|
85
|
+
return {
|
|
86
|
+
shell_id: shellId,
|
|
87
|
+
success: true,
|
|
88
|
+
};
|
|
89
|
+
} else {
|
|
90
|
+
// Synchronous execution with timeout
|
|
91
|
+
return new Promise((resolve) => {
|
|
92
|
+
const childProcess = spawn(shellConfig.cmd, shellConfig.args, {
|
|
93
|
+
env: process.env,
|
|
94
|
+
shell: false,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
let stdout = '';
|
|
98
|
+
let stderr = '';
|
|
99
|
+
let killed = false;
|
|
100
|
+
|
|
101
|
+
const timeoutHandle = setTimeout(() => {
|
|
102
|
+
killed = true;
|
|
103
|
+
childProcess.kill();
|
|
104
|
+
resolve({
|
|
105
|
+
error: `Command timed out after ${effectiveTimeout}ms`,
|
|
106
|
+
stderr,
|
|
107
|
+
stdout,
|
|
108
|
+
success: false,
|
|
109
|
+
});
|
|
110
|
+
}, effectiveTimeout);
|
|
111
|
+
|
|
112
|
+
childProcess.stdout?.on('data', (data) => {
|
|
113
|
+
stdout += data.toString();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
childProcess.stderr?.on('data', (data) => {
|
|
117
|
+
stderr += data.toString();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
childProcess.on('exit', (code) => {
|
|
121
|
+
if (!killed) {
|
|
122
|
+
clearTimeout(timeoutHandle);
|
|
123
|
+
const success = code === 0;
|
|
124
|
+
logger.info(`${logPrefix} Command completed`, { code, success });
|
|
125
|
+
resolve({
|
|
126
|
+
exit_code: code || 0,
|
|
127
|
+
output: stdout + stderr,
|
|
128
|
+
stderr,
|
|
129
|
+
stdout,
|
|
130
|
+
success,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
childProcess.on('error', (error) => {
|
|
136
|
+
clearTimeout(timeoutHandle);
|
|
137
|
+
logger.error(`${logPrefix} Command failed:`, error);
|
|
138
|
+
resolve({
|
|
139
|
+
error: error.message,
|
|
140
|
+
stderr,
|
|
141
|
+
stdout,
|
|
142
|
+
success: false,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
} catch (error) {
|
|
148
|
+
logger.error(`${logPrefix} Failed to execute command:`, error);
|
|
149
|
+
return {
|
|
150
|
+
error: (error as Error).message,
|
|
151
|
+
success: false,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@ipcClientEvent('getCommandOutput')
|
|
157
|
+
async handleGetCommandOutput({
|
|
158
|
+
filter,
|
|
159
|
+
shell_id,
|
|
160
|
+
}: GetCommandOutputParams): Promise<GetCommandOutputResult> {
|
|
161
|
+
const logPrefix = `[getCommandOutput: ${shell_id}]`;
|
|
162
|
+
logger.debug(`${logPrefix} Retrieving output`);
|
|
163
|
+
|
|
164
|
+
const shellProcess = this.shellProcesses.get(shell_id);
|
|
165
|
+
if (!shellProcess) {
|
|
166
|
+
logger.error(`${logPrefix} Shell process not found`);
|
|
167
|
+
return {
|
|
168
|
+
error: `Shell ID ${shell_id} not found`,
|
|
169
|
+
output: '',
|
|
170
|
+
running: false,
|
|
171
|
+
stderr: '',
|
|
172
|
+
stdout: '',
|
|
173
|
+
success: false,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const { lastReadStderr, lastReadStdout, process: childProcess, stderr, stdout } = shellProcess;
|
|
178
|
+
|
|
179
|
+
// Get new output since last read
|
|
180
|
+
const newStdout = stdout.slice(lastReadStdout).join('');
|
|
181
|
+
const newStderr = stderr.slice(lastReadStderr).join('');
|
|
182
|
+
let output = newStdout + newStderr;
|
|
183
|
+
|
|
184
|
+
// Apply filter if provided
|
|
185
|
+
if (filter) {
|
|
186
|
+
try {
|
|
187
|
+
const regex = new RegExp(filter, 'gm');
|
|
188
|
+
const lines = output.split('\n');
|
|
189
|
+
output = lines.filter((line) => regex.test(line)).join('\n');
|
|
190
|
+
} catch (error) {
|
|
191
|
+
logger.error(`${logPrefix} Invalid filter regex:`, error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Update last read positions separately
|
|
196
|
+
shellProcess.lastReadStdout = stdout.length;
|
|
197
|
+
shellProcess.lastReadStderr = stderr.length;
|
|
198
|
+
|
|
199
|
+
const running = childProcess.exitCode === null;
|
|
200
|
+
|
|
201
|
+
logger.debug(`${logPrefix} Output retrieved`, {
|
|
202
|
+
outputLength: output.length,
|
|
203
|
+
running,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
output,
|
|
208
|
+
running,
|
|
209
|
+
stderr: newStderr,
|
|
210
|
+
stdout: newStdout,
|
|
211
|
+
success: true,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
@ipcClientEvent('killCommand')
|
|
216
|
+
async handleKillCommand({ shell_id }: KillCommandParams): Promise<KillCommandResult> {
|
|
217
|
+
const logPrefix = `[killCommand: ${shell_id}]`;
|
|
218
|
+
logger.debug(`${logPrefix} Attempting to kill shell`);
|
|
219
|
+
|
|
220
|
+
const shellProcess = this.shellProcesses.get(shell_id);
|
|
221
|
+
if (!shellProcess) {
|
|
222
|
+
logger.error(`${logPrefix} Shell process not found`);
|
|
223
|
+
return {
|
|
224
|
+
error: `Shell ID ${shell_id} not found`,
|
|
225
|
+
success: false,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
shellProcess.process.kill();
|
|
231
|
+
this.shellProcesses.delete(shell_id);
|
|
232
|
+
logger.info(`${logPrefix} Shell killed successfully`);
|
|
233
|
+
return { success: true };
|
|
234
|
+
} catch (error) {
|
|
235
|
+
logger.error(`${logPrefix} Failed to kill shell:`, error);
|
|
236
|
+
return {
|
|
237
|
+
error: (error as Error).message,
|
|
238
|
+
success: false,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
@@ -345,7 +345,10 @@ describe('LocalFileCtr', () => {
|
|
|
345
345
|
const result = await localFileCtr.handleLocalFilesSearch({ keywords: 'test' });
|
|
346
346
|
|
|
347
347
|
expect(result).toEqual(mockResults);
|
|
348
|
-
expect(mockSearchService.search).toHaveBeenCalledWith('test', {
|
|
348
|
+
expect(mockSearchService.search).toHaveBeenCalledWith('test', {
|
|
349
|
+
keywords: 'test',
|
|
350
|
+
limit: 30,
|
|
351
|
+
});
|
|
349
352
|
});
|
|
350
353
|
|
|
351
354
|
it('should return empty array on search error', async () => {
|