@vybestack/llxprt-code-core 0.1.13 → 0.1.14
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 +24 -0
- package/dist/src/code_assist/codeAssist.d.ts +2 -1
- package/dist/src/code_assist/codeAssist.js +4 -3
- package/dist/src/code_assist/codeAssist.js.map +1 -1
- package/dist/src/code_assist/oauth2.js +9 -2
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +94 -2
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.d.ts +5 -6
- package/dist/src/code_assist/server.js +7 -70
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/setup.d.ts +6 -1
- package/dist/src/code_assist/setup.js +4 -1
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/code_assist/setup.test.js +4 -1
- package/dist/src/code_assist/setup.test.js.map +1 -1
- package/dist/src/code_assist/types.d.ts +2 -2
- package/dist/src/config/config.d.ts +25 -3
- package/dist/src/config/config.js +47 -10
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +1 -26
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/flashFallback.test.js +1 -1
- package/dist/src/config/flashFallback.test.js.map +1 -1
- package/dist/src/core/client.d.ts +6 -2
- package/dist/src/core/client.js +41 -18
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +78 -24
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +1 -1
- package/dist/src/core/contentGenerator.js +1 -1
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/coreToolScheduler.js +14 -1
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +80 -0
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +4 -3
- package/dist/src/core/geminiChat.js +8 -11
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiRequest.js +2 -37
- package/dist/src/core/geminiRequest.js.map +1 -1
- package/dist/src/core/logger.js +6 -0
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +5 -5
- package/dist/src/core/prompts.js +42 -18
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +121 -4
- package/dist/src/core/prompts.test.js.map +1 -1
- package/dist/src/core/turn.d.ts +7 -2
- package/dist/src/core/turn.js +9 -0
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +129 -0
- package/dist/src/core/turn.test.js.map +1 -1
- package/dist/src/ide/ide-client.d.ts +28 -0
- package/dist/src/ide/ide-client.js +79 -0
- package/dist/src/ide/ide-client.js.map +1 -0
- package/dist/src/ide/ideContext.d.ts +174 -0
- package/dist/src/{services → ide}/ideContext.js +28 -25
- package/dist/src/ide/ideContext.js.map +1 -0
- package/dist/src/{services → ide}/ideContext.test.js +39 -39
- package/dist/src/ide/ideContext.test.js.map +1 -0
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +4 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/google-auth-provider.d.ts +23 -0
- package/dist/src/mcp/google-auth-provider.js +63 -0
- package/dist/src/mcp/google-auth-provider.js.map +1 -0
- package/dist/src/mcp/google-auth-provider.test.js +54 -0
- package/dist/src/mcp/google-auth-provider.test.js.map +1 -0
- package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
- package/dist/src/providers/gemini/GeminiProvider.d.ts +2 -0
- package/dist/src/providers/gemini/GeminiProvider.integration.test.js +36 -0
- package/dist/src/providers/gemini/GeminiProvider.integration.test.js.map +1 -1
- package/dist/src/providers/gemini/GeminiProvider.js +57 -10
- package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
- package/dist/src/providers/openai/OpenAIProvider.js +10 -7
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.d.ts +4 -4
- package/dist/src/services/fileDiscoveryService.js +8 -8
- package/dist/src/services/gitService.js +1 -1
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/gitService.test.js +1 -1
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/loopDetectionService.d.ts +48 -5
- package/dist/src/services/loopDetectionService.js +127 -41
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +50 -123
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +2 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +17 -2
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/constants.d.ts +16 -15
- package/dist/src/telemetry/constants.js +16 -15
- package/dist/src/telemetry/constants.js.map +1 -1
- package/dist/src/telemetry/file-exporters.d.ts +28 -0
- package/dist/src/telemetry/file-exporters.js +62 -0
- package/dist/src/telemetry/file-exporters.js.map +1 -0
- package/dist/src/telemetry/loggers.d.ts +2 -1
- package/dist/src/telemetry/loggers.js +18 -3
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/sdk.js +22 -7
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +9 -2
- package/dist/src/telemetry/types.js +13 -1
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/tools/ToolFormatter.js +19 -1
- package/dist/src/tools/ToolFormatter.js.map +1 -1
- package/dist/src/tools/edit.js +10 -4
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +12 -0
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/grep.test.js +1 -1
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/ls.d.ts +5 -2
- package/dist/src/tools/ls.js +39 -10
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +5 -1
- package/dist/src/tools/mcp-client.js +416 -29
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +46 -6
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.js +1 -1
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +34 -0
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/read-file.js +1 -1
- package/dist/src/tools/read-file.test.js +98 -69
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +5 -2
- package/dist/src/tools/read-many-files.js +61 -16
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +5 -2
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +15 -26
- package/dist/src/tools/shell.js +137 -358
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +73 -318
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +13 -1
- package/dist/src/tools/tool-registry.js +45 -1
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +3 -3
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.d.ts +2 -0
- package/dist/src/utils/bfsFileSearch.js +4 -1
- package/dist/src/utils/bfsFileSearch.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.test.js +108 -105
- package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
- package/dist/src/utils/editCorrector.js +4 -4
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editCorrector.test.js +1 -1
- package/dist/src/utils/editor.js +16 -10
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +128 -28
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/errorReporting.d.ts +1 -1
- package/dist/src/utils/errorReporting.js +2 -2
- package/dist/src/utils/errorReporting.js.map +1 -1
- package/dist/src/utils/errorReporting.test.js +44 -38
- package/dist/src/utils/errorReporting.test.js.map +1 -1
- package/dist/src/utils/fileUtils.d.ts +4 -4
- package/dist/src/utils/fileUtils.js +31 -15
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +37 -37
- package/dist/src/utils/fileUtils.test.js.map +1 -1
- package/dist/src/utils/getFolderStructure.d.ts +3 -2
- package/dist/src/utils/getFolderStructure.js +27 -28
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/getFolderStructure.test.js +169 -185
- package/dist/src/utils/getFolderStructure.test.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.js +4 -7
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.test.js +71 -62
- package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.d.ts +2 -1
- package/dist/src/utils/memoryDiscovery.js +11 -5
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +160 -371
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/partUtils.d.ts +14 -0
- package/dist/src/utils/partUtils.js +65 -0
- package/dist/src/utils/partUtils.js.map +1 -0
- package/dist/src/utils/partUtils.test.d.ts +6 -0
- package/dist/src/utils/partUtils.test.js +130 -0
- package/dist/src/utils/partUtils.test.js.map +1 -0
- package/dist/src/utils/paths.d.ts +11 -0
- package/dist/src/utils/paths.js +17 -1
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/quotaErrorDetection.js.map +1 -1
- package/dist/src/utils/retry.js +1 -1
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/schemaValidator.js +5 -2
- package/dist/src/utils/schemaValidator.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +44 -0
- package/dist/src/utils/shell-utils.js +243 -0
- package/dist/src/utils/shell-utils.js.map +1 -0
- package/dist/src/utils/shell-utils.test.d.ts +6 -0
- package/dist/src/utils/shell-utils.test.js +450 -0
- package/dist/src/utils/shell-utils.test.js.map +1 -0
- package/dist/src/utils/summarizer.js +1 -30
- package/dist/src/utils/summarizer.js.map +1 -1
- package/dist/src/utils/systemEncoding.d.ts +40 -0
- package/dist/src/utils/systemEncoding.js +149 -0
- package/dist/src/utils/systemEncoding.js.map +1 -0
- package/dist/src/utils/systemEncoding.test.d.ts +6 -0
- package/dist/src/utils/systemEncoding.test.js +368 -0
- package/dist/src/utils/systemEncoding.test.js.map +1 -0
- package/dist/src/utils/user_account.test.js +1 -1
- package/dist/src/utils/user_account.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -1
- package/dist/src/core/geminiRequest.test.js +0 -72
- package/dist/src/core/geminiRequest.test.js.map +0 -1
- package/dist/src/services/ideContext.d.ts +0 -126
- package/dist/src/services/ideContext.js.map +0 -1
- package/dist/src/services/ideContext.test.js.map +0 -1
- /package/dist/src/{services → ide}/ideContext.test.d.ts +0 -0
- /package/dist/src/{core/geminiRequest.test.d.ts → mcp/google-auth-provider.test.d.ts} +0 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { expect, describe, it, beforeEach } from 'vitest';
|
|
7
|
+
import { getCommandRoots, isCommandAllowed, stripShellWrapper, } from './shell-utils.js';
|
|
8
|
+
describe('isCommandAllowed', () => {
|
|
9
|
+
let config;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
config = {
|
|
12
|
+
getCoreTools: () => undefined,
|
|
13
|
+
getExcludeTools: () => undefined,
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
it('should allow a command if no restrictions are provided', async () => {
|
|
17
|
+
const result = isCommandAllowed('ls -l', config);
|
|
18
|
+
expect(result.allowed).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
it('should allow a command if it is in the allowed list', async () => {
|
|
21
|
+
config = {
|
|
22
|
+
getCoreTools: () => ['ShellTool(ls -l)'],
|
|
23
|
+
getExcludeTools: () => undefined,
|
|
24
|
+
};
|
|
25
|
+
const result = isCommandAllowed('ls -l', config);
|
|
26
|
+
expect(result.allowed).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
it('should block a command if it is not in the allowed list', async () => {
|
|
29
|
+
config = {
|
|
30
|
+
getCoreTools: () => ['ShellTool(ls -l)'],
|
|
31
|
+
getExcludeTools: () => undefined,
|
|
32
|
+
};
|
|
33
|
+
const result = isCommandAllowed('rm -rf /', config);
|
|
34
|
+
expect(result.allowed).toBe(false);
|
|
35
|
+
expect(result.reason).toBe("Command 'rm -rf /' is not in the allowed commands list");
|
|
36
|
+
});
|
|
37
|
+
it('should block a command if it is in the blocked list', async () => {
|
|
38
|
+
config = {
|
|
39
|
+
getCoreTools: () => undefined,
|
|
40
|
+
getExcludeTools: () => ['ShellTool(rm -rf /)'],
|
|
41
|
+
};
|
|
42
|
+
const result = isCommandAllowed('rm -rf /', config);
|
|
43
|
+
expect(result.allowed).toBe(false);
|
|
44
|
+
expect(result.reason).toBe("Command 'rm -rf /' is blocked by configuration");
|
|
45
|
+
});
|
|
46
|
+
it('should allow a command if it is not in the blocked list', async () => {
|
|
47
|
+
config = {
|
|
48
|
+
getCoreTools: () => undefined,
|
|
49
|
+
getExcludeTools: () => ['ShellTool(rm -rf /)'],
|
|
50
|
+
};
|
|
51
|
+
const result = isCommandAllowed('ls -l', config);
|
|
52
|
+
expect(result.allowed).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it('should block a command if it is in both the allowed and blocked lists', async () => {
|
|
55
|
+
config = {
|
|
56
|
+
getCoreTools: () => ['ShellTool(rm -rf /)'],
|
|
57
|
+
getExcludeTools: () => ['ShellTool(rm -rf /)'],
|
|
58
|
+
};
|
|
59
|
+
const result = isCommandAllowed('rm -rf /', config);
|
|
60
|
+
expect(result.allowed).toBe(false);
|
|
61
|
+
expect(result.reason).toBe("Command 'rm -rf /' is blocked by configuration");
|
|
62
|
+
});
|
|
63
|
+
it('should allow any command when ShellTool is in coreTools without specific commands', async () => {
|
|
64
|
+
config = {
|
|
65
|
+
getCoreTools: () => ['ShellTool'],
|
|
66
|
+
getExcludeTools: () => [],
|
|
67
|
+
};
|
|
68
|
+
const result = isCommandAllowed('any command', config);
|
|
69
|
+
expect(result.allowed).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
it('should block any command when ShellTool is in excludeTools without specific commands', async () => {
|
|
72
|
+
config = {
|
|
73
|
+
getCoreTools: () => [],
|
|
74
|
+
getExcludeTools: () => ['ShellTool'],
|
|
75
|
+
};
|
|
76
|
+
const result = isCommandAllowed('any command', config);
|
|
77
|
+
expect(result.allowed).toBe(false);
|
|
78
|
+
expect(result.reason).toBe('Shell tool is globally disabled in configuration');
|
|
79
|
+
});
|
|
80
|
+
it('should allow a command if it is in the allowed list using the public-facing name', async () => {
|
|
81
|
+
config = {
|
|
82
|
+
getCoreTools: () => ['run_shell_command(ls -l)'],
|
|
83
|
+
getExcludeTools: () => undefined,
|
|
84
|
+
};
|
|
85
|
+
const result = isCommandAllowed('ls -l', config);
|
|
86
|
+
expect(result.allowed).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
it('should block a command if it is in the blocked list using the public-facing name', async () => {
|
|
89
|
+
config = {
|
|
90
|
+
getCoreTools: () => undefined,
|
|
91
|
+
getExcludeTools: () => ['run_shell_command(rm -rf /)'],
|
|
92
|
+
};
|
|
93
|
+
const result = isCommandAllowed('rm -rf /', config);
|
|
94
|
+
expect(result.allowed).toBe(false);
|
|
95
|
+
expect(result.reason).toBe("Command 'rm -rf /' is blocked by configuration");
|
|
96
|
+
});
|
|
97
|
+
it('should block any command when ShellTool is in excludeTools using the public-facing name', async () => {
|
|
98
|
+
config = {
|
|
99
|
+
getCoreTools: () => [],
|
|
100
|
+
getExcludeTools: () => ['run_shell_command'],
|
|
101
|
+
};
|
|
102
|
+
const result = isCommandAllowed('any command', config);
|
|
103
|
+
expect(result.allowed).toBe(false);
|
|
104
|
+
expect(result.reason).toBe('Shell tool is globally disabled in configuration');
|
|
105
|
+
});
|
|
106
|
+
it('should block any command if coreTools contains an empty ShellTool command list using the public-facing name', async () => {
|
|
107
|
+
config = {
|
|
108
|
+
getCoreTools: () => ['run_shell_command()'],
|
|
109
|
+
getExcludeTools: () => [],
|
|
110
|
+
};
|
|
111
|
+
const result = isCommandAllowed('any command', config);
|
|
112
|
+
expect(result.allowed).toBe(false);
|
|
113
|
+
expect(result.reason).toBe("Command 'any command' is not in the allowed commands list");
|
|
114
|
+
});
|
|
115
|
+
it('should block any command if coreTools contains an empty ShellTool command list', async () => {
|
|
116
|
+
config = {
|
|
117
|
+
getCoreTools: () => ['ShellTool()'],
|
|
118
|
+
getExcludeTools: () => [],
|
|
119
|
+
};
|
|
120
|
+
const result = isCommandAllowed('any command', config);
|
|
121
|
+
expect(result.allowed).toBe(false);
|
|
122
|
+
expect(result.reason).toBe("Command 'any command' is not in the allowed commands list");
|
|
123
|
+
});
|
|
124
|
+
it('should block a command with extra whitespace if it is in the blocked list', async () => {
|
|
125
|
+
config = {
|
|
126
|
+
getCoreTools: () => undefined,
|
|
127
|
+
getExcludeTools: () => ['ShellTool(rm -rf /)'],
|
|
128
|
+
};
|
|
129
|
+
const result = isCommandAllowed(' rm -rf / ', config);
|
|
130
|
+
expect(result.allowed).toBe(false);
|
|
131
|
+
expect(result.reason).toBe("Command 'rm -rf /' is blocked by configuration");
|
|
132
|
+
});
|
|
133
|
+
it('should allow any command when ShellTool is in present with specific commands', async () => {
|
|
134
|
+
config = {
|
|
135
|
+
getCoreTools: () => ['ShellTool', 'ShellTool(ls)'],
|
|
136
|
+
getExcludeTools: () => [],
|
|
137
|
+
};
|
|
138
|
+
const result = isCommandAllowed('any command', config);
|
|
139
|
+
expect(result.allowed).toBe(true);
|
|
140
|
+
});
|
|
141
|
+
it('should block a command on the blocklist even with a wildcard allow', async () => {
|
|
142
|
+
config = {
|
|
143
|
+
getCoreTools: () => ['ShellTool'],
|
|
144
|
+
getExcludeTools: () => ['ShellTool(rm -rf /)'],
|
|
145
|
+
};
|
|
146
|
+
const result = isCommandAllowed('rm -rf /', config);
|
|
147
|
+
expect(result.allowed).toBe(false);
|
|
148
|
+
expect(result.reason).toBe("Command 'rm -rf /' is blocked by configuration");
|
|
149
|
+
});
|
|
150
|
+
it('should allow a command that starts with an allowed command prefix', async () => {
|
|
151
|
+
config = {
|
|
152
|
+
getCoreTools: () => ['ShellTool(gh issue edit)'],
|
|
153
|
+
getExcludeTools: () => [],
|
|
154
|
+
};
|
|
155
|
+
const result = isCommandAllowed('gh issue edit 1 --add-label "kind/feature"', config);
|
|
156
|
+
expect(result.allowed).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
it('should allow a command that starts with an allowed command prefix using the public-facing name', async () => {
|
|
159
|
+
config = {
|
|
160
|
+
getCoreTools: () => ['run_shell_command(gh issue edit)'],
|
|
161
|
+
getExcludeTools: () => [],
|
|
162
|
+
};
|
|
163
|
+
const result = isCommandAllowed('gh issue edit 1 --add-label "kind/feature"', config);
|
|
164
|
+
expect(result.allowed).toBe(true);
|
|
165
|
+
});
|
|
166
|
+
it('should not allow a command that starts with an allowed command prefix but is chained with another command', async () => {
|
|
167
|
+
config = {
|
|
168
|
+
getCoreTools: () => ['run_shell_command(gh issue edit)'],
|
|
169
|
+
getExcludeTools: () => [],
|
|
170
|
+
};
|
|
171
|
+
const result = isCommandAllowed('gh issue edit&&rm -rf /', config);
|
|
172
|
+
expect(result.allowed).toBe(false);
|
|
173
|
+
expect(result.reason).toBe("Command 'rm -rf /' is not in the allowed commands list");
|
|
174
|
+
});
|
|
175
|
+
it('should not allow a command that is a prefix of an allowed command', async () => {
|
|
176
|
+
config = {
|
|
177
|
+
getCoreTools: () => ['run_shell_command(gh issue edit)'],
|
|
178
|
+
getExcludeTools: () => [],
|
|
179
|
+
};
|
|
180
|
+
const result = isCommandAllowed('gh issue', config);
|
|
181
|
+
expect(result.allowed).toBe(false);
|
|
182
|
+
expect(result.reason).toBe("Command 'gh issue' is not in the allowed commands list");
|
|
183
|
+
});
|
|
184
|
+
it('should not allow a command that is a prefix of a blocked command', async () => {
|
|
185
|
+
config = {
|
|
186
|
+
getCoreTools: () => [],
|
|
187
|
+
getExcludeTools: () => ['run_shell_command(gh issue edit)'],
|
|
188
|
+
};
|
|
189
|
+
const result = isCommandAllowed('gh issue', config);
|
|
190
|
+
expect(result.allowed).toBe(true);
|
|
191
|
+
});
|
|
192
|
+
it('should not allow a command that is chained with a pipe', async () => {
|
|
193
|
+
config = {
|
|
194
|
+
getCoreTools: () => ['run_shell_command(gh issue list)'],
|
|
195
|
+
getExcludeTools: () => [],
|
|
196
|
+
};
|
|
197
|
+
const result = isCommandAllowed('gh issue list | rm -rf /', config);
|
|
198
|
+
expect(result.allowed).toBe(false);
|
|
199
|
+
expect(result.reason).toBe("Command 'rm -rf /' is not in the allowed commands list");
|
|
200
|
+
});
|
|
201
|
+
it('should not allow a command that is chained with a semicolon', async () => {
|
|
202
|
+
config = {
|
|
203
|
+
getCoreTools: () => ['run_shell_command(gh issue list)'],
|
|
204
|
+
getExcludeTools: () => [],
|
|
205
|
+
};
|
|
206
|
+
const result = isCommandAllowed('gh issue list; rm -rf /', config);
|
|
207
|
+
expect(result.allowed).toBe(false);
|
|
208
|
+
expect(result.reason).toBe("Command 'rm -rf /' is not in the allowed commands list");
|
|
209
|
+
});
|
|
210
|
+
it('should block a chained command if any part is blocked', async () => {
|
|
211
|
+
config = {
|
|
212
|
+
getCoreTools: () => ['run_shell_command(echo "hello")'],
|
|
213
|
+
getExcludeTools: () => ['run_shell_command(rm)'],
|
|
214
|
+
};
|
|
215
|
+
const result = isCommandAllowed('echo "hello" && rm -rf /', config);
|
|
216
|
+
expect(result.allowed).toBe(false);
|
|
217
|
+
expect(result.reason).toBe("Command 'rm -rf /' is blocked by configuration");
|
|
218
|
+
});
|
|
219
|
+
it('should block a command if its prefix is on the blocklist, even if the command itself is on the allowlist', async () => {
|
|
220
|
+
config = {
|
|
221
|
+
getCoreTools: () => ['run_shell_command(git push)'],
|
|
222
|
+
getExcludeTools: () => ['run_shell_command(git)'],
|
|
223
|
+
};
|
|
224
|
+
const result = isCommandAllowed('git push', config);
|
|
225
|
+
expect(result.allowed).toBe(false);
|
|
226
|
+
expect(result.reason).toBe("Command 'git push' is blocked by configuration");
|
|
227
|
+
});
|
|
228
|
+
it('should be case-sensitive in its matching', async () => {
|
|
229
|
+
config = {
|
|
230
|
+
getCoreTools: () => ['run_shell_command(echo)'],
|
|
231
|
+
getExcludeTools: () => [],
|
|
232
|
+
};
|
|
233
|
+
const result = isCommandAllowed('ECHO "hello"', config);
|
|
234
|
+
expect(result.allowed).toBe(false);
|
|
235
|
+
expect(result.reason).toBe('Command \'ECHO "hello"\' is not in the allowed commands list');
|
|
236
|
+
});
|
|
237
|
+
it('should correctly handle commands with extra whitespace around chaining operators', async () => {
|
|
238
|
+
config = {
|
|
239
|
+
getCoreTools: () => ['run_shell_command(ls -l)'],
|
|
240
|
+
getExcludeTools: () => ['run_shell_command(rm)'],
|
|
241
|
+
};
|
|
242
|
+
const result = isCommandAllowed('ls -l ; rm -rf /', config);
|
|
243
|
+
expect(result.allowed).toBe(false);
|
|
244
|
+
expect(result.reason).toBe("Command 'rm -rf /' is blocked by configuration");
|
|
245
|
+
});
|
|
246
|
+
it('should allow a chained command if all parts are allowed', async () => {
|
|
247
|
+
config = {
|
|
248
|
+
getCoreTools: () => [
|
|
249
|
+
'run_shell_command(echo)',
|
|
250
|
+
'run_shell_command(ls -l)',
|
|
251
|
+
],
|
|
252
|
+
getExcludeTools: () => [],
|
|
253
|
+
};
|
|
254
|
+
const result = isCommandAllowed('echo "hello" && ls -l', config);
|
|
255
|
+
expect(result.allowed).toBe(true);
|
|
256
|
+
});
|
|
257
|
+
it('should block a command with command substitution using backticks', async () => {
|
|
258
|
+
config = {
|
|
259
|
+
getCoreTools: () => ['run_shell_command(echo)'],
|
|
260
|
+
getExcludeTools: () => [],
|
|
261
|
+
};
|
|
262
|
+
const result = isCommandAllowed('echo `rm -rf /`', config);
|
|
263
|
+
expect(result.allowed).toBe(false);
|
|
264
|
+
expect(result.reason).toBe('Command substitution using $(), <(), or >() is not allowed for security reasons');
|
|
265
|
+
});
|
|
266
|
+
it('should block a command with command substitution using $()', async () => {
|
|
267
|
+
config = {
|
|
268
|
+
getCoreTools: () => ['run_shell_command(echo)'],
|
|
269
|
+
getExcludeTools: () => [],
|
|
270
|
+
};
|
|
271
|
+
const result = isCommandAllowed('echo $(rm -rf /)', config);
|
|
272
|
+
expect(result.allowed).toBe(false);
|
|
273
|
+
expect(result.reason).toBe('Command substitution using $(), <(), or >() is not allowed for security reasons');
|
|
274
|
+
});
|
|
275
|
+
it('should block a command with process substitution using <()', async () => {
|
|
276
|
+
config = {
|
|
277
|
+
getCoreTools: () => ['run_shell_command(diff)'],
|
|
278
|
+
getExcludeTools: () => [],
|
|
279
|
+
};
|
|
280
|
+
const result = isCommandAllowed('diff <(ls) <(ls -a)', config);
|
|
281
|
+
expect(result.allowed).toBe(false);
|
|
282
|
+
expect(result.reason).toBe('Command substitution using $(), <(), or >() is not allowed for security reasons');
|
|
283
|
+
});
|
|
284
|
+
it('should allow a command with I/O redirection', async () => {
|
|
285
|
+
config = {
|
|
286
|
+
getCoreTools: () => ['run_shell_command(echo)'],
|
|
287
|
+
getExcludeTools: () => [],
|
|
288
|
+
};
|
|
289
|
+
const result = isCommandAllowed('echo "hello" > file.txt', config);
|
|
290
|
+
expect(result.allowed).toBe(true);
|
|
291
|
+
});
|
|
292
|
+
it('should not allow a command that is chained with a double pipe', async () => {
|
|
293
|
+
config = {
|
|
294
|
+
getCoreTools: () => ['run_shell_command(gh issue list)'],
|
|
295
|
+
getExcludeTools: () => [],
|
|
296
|
+
};
|
|
297
|
+
const result = isCommandAllowed('gh issue list || rm -rf /', config);
|
|
298
|
+
expect(result.allowed).toBe(false);
|
|
299
|
+
expect(result.reason).toBe("Command 'rm -rf /' is not in the allowed commands list");
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
describe('getCommandRoots', () => {
|
|
303
|
+
it('should return a single command', () => {
|
|
304
|
+
const result = getCommandRoots('ls -l');
|
|
305
|
+
expect(result).toEqual(['ls']);
|
|
306
|
+
});
|
|
307
|
+
it('should return multiple commands', () => {
|
|
308
|
+
const result = getCommandRoots('ls -l | grep "test"');
|
|
309
|
+
expect(result).toEqual(['ls', 'grep']);
|
|
310
|
+
});
|
|
311
|
+
it('should handle multiple commands with &&', () => {
|
|
312
|
+
const result = getCommandRoots('npm run build && npm test');
|
|
313
|
+
expect(result).toEqual(['npm', 'npm']);
|
|
314
|
+
});
|
|
315
|
+
it('should handle multiple commands with ;', () => {
|
|
316
|
+
const result = getCommandRoots('echo "hello"; echo "world"');
|
|
317
|
+
expect(result).toEqual(['echo', 'echo']);
|
|
318
|
+
});
|
|
319
|
+
it('should handle a mix of operators', () => {
|
|
320
|
+
const result = getCommandRoots('cat package.json | grep "version" && echo "done"');
|
|
321
|
+
expect(result).toEqual(['cat', 'grep', 'echo']);
|
|
322
|
+
});
|
|
323
|
+
it('should handle commands with paths', () => {
|
|
324
|
+
const result = getCommandRoots('/usr/local/bin/node script.js');
|
|
325
|
+
expect(result).toEqual(['node']);
|
|
326
|
+
});
|
|
327
|
+
it('should return an empty array for an empty string', () => {
|
|
328
|
+
const result = getCommandRoots('');
|
|
329
|
+
expect(result).toEqual([]);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
describe('stripShellWrapper', () => {
|
|
333
|
+
it('should strip sh -c from the beginning of the command', () => {
|
|
334
|
+
const result = stripShellWrapper('sh -c "ls -l"');
|
|
335
|
+
expect(result).toEqual('ls -l');
|
|
336
|
+
});
|
|
337
|
+
it('should strip bash -c from the beginning of the command', () => {
|
|
338
|
+
const result = stripShellWrapper('bash -c "ls -l"');
|
|
339
|
+
expect(result).toEqual('ls -l');
|
|
340
|
+
});
|
|
341
|
+
it('should strip zsh -c from the beginning of the command', () => {
|
|
342
|
+
const result = stripShellWrapper('zsh -c "ls -l"');
|
|
343
|
+
expect(result).toEqual('ls -l');
|
|
344
|
+
});
|
|
345
|
+
it('should not strip anything if the command does not start with a shell wrapper', () => {
|
|
346
|
+
const result = stripShellWrapper('ls -l');
|
|
347
|
+
expect(result).toEqual('ls -l');
|
|
348
|
+
});
|
|
349
|
+
it('should handle extra whitespace', () => {
|
|
350
|
+
const result = stripShellWrapper(' sh -c "ls -l" ');
|
|
351
|
+
expect(result).toEqual('ls -l');
|
|
352
|
+
});
|
|
353
|
+
it('should handle commands without quotes', () => {
|
|
354
|
+
const result = stripShellWrapper('sh -c ls -l');
|
|
355
|
+
expect(result).toEqual('ls -l');
|
|
356
|
+
});
|
|
357
|
+
it('should strip cmd.exe /c from the beginning of the command', () => {
|
|
358
|
+
const result = stripShellWrapper('cmd.exe /c "dir"');
|
|
359
|
+
expect(result).toEqual('dir');
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
describe('getCommandRoots', () => {
|
|
363
|
+
it('should handle multiple commands with &', () => {
|
|
364
|
+
const result = getCommandRoots('echo "hello" & echo "world"');
|
|
365
|
+
expect(result).toEqual(['echo', 'echo']);
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
describe('command substitution', () => {
|
|
369
|
+
let config;
|
|
370
|
+
beforeEach(() => {
|
|
371
|
+
config = {
|
|
372
|
+
getCoreTools: () => ['run_shell_command(echo)', 'run_shell_command(gh)'],
|
|
373
|
+
getExcludeTools: () => [],
|
|
374
|
+
};
|
|
375
|
+
});
|
|
376
|
+
it('should block unquoted command substitution `$(...)`', () => {
|
|
377
|
+
const result = isCommandAllowed('echo $(pwd)', config);
|
|
378
|
+
expect(result.allowed).toBe(false);
|
|
379
|
+
});
|
|
380
|
+
it('should block unquoted command substitution `<(...)`', () => {
|
|
381
|
+
const result = isCommandAllowed('echo <(pwd)', config);
|
|
382
|
+
expect(result.allowed).toBe(false);
|
|
383
|
+
});
|
|
384
|
+
it('should allow command substitution in single quotes', () => {
|
|
385
|
+
const result = isCommandAllowed("echo '$(pwd)'", config);
|
|
386
|
+
expect(result.allowed).toBe(true);
|
|
387
|
+
});
|
|
388
|
+
it('should allow backticks in single quotes', () => {
|
|
389
|
+
const result = isCommandAllowed("echo '`rm -rf /`'", config);
|
|
390
|
+
expect(result.allowed).toBe(true);
|
|
391
|
+
});
|
|
392
|
+
it('should block command substitution in double quotes', () => {
|
|
393
|
+
const result = isCommandAllowed('echo "$(pwd)"', config);
|
|
394
|
+
expect(result.allowed).toBe(false);
|
|
395
|
+
});
|
|
396
|
+
it('should allow escaped command substitution', () => {
|
|
397
|
+
const result = isCommandAllowed('echo \\$(pwd)', config);
|
|
398
|
+
expect(result.allowed).toBe(true);
|
|
399
|
+
});
|
|
400
|
+
it('should allow complex commands with quoted substitution-like patterns', () => {
|
|
401
|
+
const command = "gh pr comment 4795 --body 'This is a test comment with $(pwd) style text'";
|
|
402
|
+
const result = isCommandAllowed(command, config);
|
|
403
|
+
expect(result.allowed).toBe(true);
|
|
404
|
+
});
|
|
405
|
+
it('should block complex commands with unquoted substitution-like patterns', () => {
|
|
406
|
+
const command = 'gh pr comment 4795 --body "This is a test comment with $(pwd) style text"';
|
|
407
|
+
const result = isCommandAllowed(command, config);
|
|
408
|
+
expect(result.allowed).toBe(false);
|
|
409
|
+
});
|
|
410
|
+
it('should allow a command with markdown content using proper quoting', () => {
|
|
411
|
+
// Simple test with safe content in single quotes
|
|
412
|
+
const result = isCommandAllowed("gh pr comment 4795 --body 'This is safe markdown content'", config);
|
|
413
|
+
expect(result.allowed).toBe(true);
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
describe('getCommandRoots with quote handling', () => {
|
|
417
|
+
it('should correctly parse a simple command', () => {
|
|
418
|
+
const result = getCommandRoots('git status');
|
|
419
|
+
expect(result).toEqual(['git']);
|
|
420
|
+
});
|
|
421
|
+
it('should correctly parse a command with a quoted argument', () => {
|
|
422
|
+
const result = getCommandRoots('git commit -m "feat: new feature"');
|
|
423
|
+
expect(result).toEqual(['git']);
|
|
424
|
+
});
|
|
425
|
+
it('should correctly parse a command with single quotes', () => {
|
|
426
|
+
const result = getCommandRoots("echo 'hello world'");
|
|
427
|
+
expect(result).toEqual(['echo']);
|
|
428
|
+
});
|
|
429
|
+
it('should correctly parse a chained command with quotes', () => {
|
|
430
|
+
const result = getCommandRoots('echo "hello" && git status');
|
|
431
|
+
expect(result).toEqual(['echo', 'git']);
|
|
432
|
+
});
|
|
433
|
+
it('should correctly parse a complex chained command', () => {
|
|
434
|
+
const result = getCommandRoots('git commit -m "feat: new feature" && echo "done"');
|
|
435
|
+
expect(result).toEqual(['git', 'echo']);
|
|
436
|
+
});
|
|
437
|
+
it('should handle escaped quotes', () => {
|
|
438
|
+
const result = getCommandRoots('echo "this is a "quote""');
|
|
439
|
+
expect(result).toEqual(['echo']);
|
|
440
|
+
});
|
|
441
|
+
it('should handle commands with no spaces', () => {
|
|
442
|
+
const result = getCommandRoots('command');
|
|
443
|
+
expect(result).toEqual(['command']);
|
|
444
|
+
});
|
|
445
|
+
it('should handle multiple separators', () => {
|
|
446
|
+
const result = getCommandRoots('a;b|c&&d||e&f');
|
|
447
|
+
expect(result).toEqual(['a', 'b', 'c', 'd', 'e', 'f']);
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
//# sourceMappingURL=shell-utils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-utils.test.js","sourceRoot":"","sources":["../../../src/utils/shell-utils.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
|
|
7
|
+
import { getResponseText, partToString } from './partUtils.js';
|
|
7
8
|
/**
|
|
8
9
|
* The default summarizer for tool results.
|
|
9
10
|
*
|
|
@@ -13,36 +14,6 @@ import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
|
|
|
13
14
|
* @returns The summary of the result.
|
|
14
15
|
*/
|
|
15
16
|
export const defaultSummarizer = (result, _geminiClient, _abortSignal) => Promise.resolve(JSON.stringify(result.llmContent));
|
|
16
|
-
// TODO: Move both these functions to utils
|
|
17
|
-
function partToString(part) {
|
|
18
|
-
if (!part) {
|
|
19
|
-
return '';
|
|
20
|
-
}
|
|
21
|
-
if (typeof part === 'string') {
|
|
22
|
-
return part;
|
|
23
|
-
}
|
|
24
|
-
if (Array.isArray(part)) {
|
|
25
|
-
return part.map(partToString).join('');
|
|
26
|
-
}
|
|
27
|
-
if ('text' in part) {
|
|
28
|
-
return part.text ?? '';
|
|
29
|
-
}
|
|
30
|
-
return '';
|
|
31
|
-
}
|
|
32
|
-
function getResponseText(response) {
|
|
33
|
-
if (response.candidates && response.candidates.length > 0) {
|
|
34
|
-
const candidate = response.candidates[0];
|
|
35
|
-
if (candidate.content &&
|
|
36
|
-
candidate.content.parts &&
|
|
37
|
-
candidate.content.parts.length > 0) {
|
|
38
|
-
return candidate.content.parts
|
|
39
|
-
.filter((part) => part.text)
|
|
40
|
-
.map((part) => part.text)
|
|
41
|
-
.join('');
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
17
|
const SUMMARIZE_TOOL_OUTPUT_PROMPT = `Summarize the following tool output to be a maximum of {maxOutputTokens} tokens. The summary should be concise and capture the main points of the tool output.
|
|
47
18
|
|
|
48
19
|
The summarization should be done based on the content that is provided. Here are the basic rules to follow:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../../src/utils/summarizer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../../src/utils/summarizer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAc/D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAe,CAC3C,MAAkB,EAClB,aAA2B,EAC3B,YAAyB,EACzB,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAExD,MAAM,4BAA4B,GAAG;;;;;;;;;;;;CAYpC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAe,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,CAC7E,mBAAmB,CACjB,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,EAC/B,YAAY,EACZ,WAAW,CACZ,CAAC;AAEJ,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,eAAuB,EACvB,YAA0B,EAC1B,WAAwB,EACxB,kBAA0B,IAAI;IAE9B,8GAA8G;IAC9G,wFAAwF;IACxF,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QACjE,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,MAAM,MAAM,GAAG,4BAA4B,CAAC,OAAO,CACjD,mBAAmB,EACnB,MAAM,CAAC,eAAe,CAAC,CACxB,CAAC,OAAO,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1E,MAAM,0BAA0B,GAA0B;QACxD,eAAe;KAChB,CAAC;IACF,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,CAAC,MAAM,YAAY,CAAC,eAAe,CACxD,QAAQ,EACR,0BAA0B,EAC1B,WAAW,EACX,0BAA0B,CAC3B,CAAuC,CAAC;QACzC,OAAO,eAAe,CAAC,cAAc,CAAC,IAAI,eAAe,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO,eAAe,CAAC;IACzB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Reset the encoding cache - useful for testing
|
|
8
|
+
*/
|
|
9
|
+
export declare function resetEncodingCache(): void;
|
|
10
|
+
/**
|
|
11
|
+
* Returns the system encoding, caching the result to avoid repeated system calls.
|
|
12
|
+
* If system encoding detection fails, falls back to detecting from the provided buffer.
|
|
13
|
+
* Note: Only the system encoding is cached - buffer-based detection runs for each buffer
|
|
14
|
+
* since different buffers may have different encodings.
|
|
15
|
+
* @param buffer A buffer to use for detecting encoding if system detection fails.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getCachedEncodingForBuffer(buffer: Buffer): string;
|
|
18
|
+
/**
|
|
19
|
+
* Detects the system encoding based on the platform.
|
|
20
|
+
* For Windows, it uses the 'chcp' command to get the current code page.
|
|
21
|
+
* For Unix-like systems, it checks environment variables like LC_ALL, LC_CTYPE, and LANG.
|
|
22
|
+
* If those are not set, it tries to run 'locale charmap' to get the encoding.
|
|
23
|
+
* If detection fails, it returns null.
|
|
24
|
+
* @returns The system encoding as a string, or null if detection fails.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getSystemEncoding(): string | null;
|
|
27
|
+
/**
|
|
28
|
+
* Converts a Windows code page number to a corresponding encoding name.
|
|
29
|
+
* @param cp The Windows code page number (e.g., 437, 850, etc.)
|
|
30
|
+
* @returns The corresponding encoding name as a string, or null if no mapping exists.
|
|
31
|
+
*/
|
|
32
|
+
export declare function windowsCodePageToEncoding(cp: number): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Attempts to detect encoding from a buffer using chardet.
|
|
35
|
+
* This is useful when system encoding detection fails.
|
|
36
|
+
* Returns the detected encoding in lowercase, or null if detection fails.
|
|
37
|
+
* @param buffer The buffer to analyze for encoding.
|
|
38
|
+
* @return The detected encoding as a lowercase string, or null if detection fails.
|
|
39
|
+
*/
|
|
40
|
+
export declare function detectEncodingFromBuffer(buffer: Buffer): string | null;
|