centaurus-cli 2.3.0 → 2.5.0
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 +151 -1
- package/dist/cli-adapter.d.ts +41 -2
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +407 -79
- package/dist/cli-adapter.js.map +1 -1
- package/dist/config/types.d.ts +23 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +20 -0
- package/dist/config/types.js.map +1 -1
- package/dist/context/__tests__/command-detector.test.d.ts +14 -0
- package/dist/context/__tests__/command-detector.test.d.ts.map +1 -0
- package/dist/context/__tests__/command-detector.test.js +318 -0
- package/dist/context/__tests__/command-detector.test.js.map +1 -0
- package/dist/context/__tests__/context-manager.test.d.ts +16 -0
- package/dist/context/__tests__/context-manager.test.d.ts.map +1 -0
- package/dist/context/__tests__/context-manager.test.js +375 -0
- package/dist/context/__tests__/context-manager.test.js.map +1 -0
- package/dist/context/__tests__/error-handling.test.d.ts +15 -0
- package/dist/context/__tests__/error-handling.test.d.ts.map +1 -0
- package/dist/context/__tests__/error-handling.test.js +447 -0
- package/dist/context/__tests__/error-handling.test.js.map +1 -0
- package/dist/context/command-detector.d.ts +50 -0
- package/dist/context/command-detector.d.ts.map +1 -0
- package/dist/context/command-detector.js +72 -0
- package/dist/context/command-detector.js.map +1 -0
- package/dist/context/context-manager.d.ts +144 -0
- package/dist/context/context-manager.d.ts.map +1 -0
- package/dist/context/context-manager.js +487 -0
- package/dist/context/context-manager.js.map +1 -0
- package/dist/context/handlers/__tests__/docker-handler.test.d.ts +13 -0
- package/dist/context/handlers/__tests__/docker-handler.test.d.ts.map +1 -0
- package/dist/context/handlers/__tests__/docker-handler.test.js +285 -0
- package/dist/context/handlers/__tests__/docker-handler.test.js.map +1 -0
- package/dist/context/handlers/__tests__/ssh-handler.test.d.ts +13 -0
- package/dist/context/handlers/__tests__/ssh-handler.test.d.ts.map +1 -0
- package/dist/context/handlers/__tests__/ssh-handler.test.js +251 -0
- package/dist/context/handlers/__tests__/ssh-handler.test.js.map +1 -0
- package/dist/context/handlers/__tests__/wsl-handler.test.d.ts +7 -0
- package/dist/context/handlers/__tests__/wsl-handler.test.d.ts.map +1 -0
- package/dist/context/handlers/__tests__/wsl-handler.test.js +331 -0
- package/dist/context/handlers/__tests__/wsl-handler.test.js.map +1 -0
- package/dist/context/handlers/docker-handler.d.ts +111 -0
- package/dist/context/handlers/docker-handler.d.ts.map +1 -0
- package/dist/context/handlers/docker-handler.js +439 -0
- package/dist/context/handlers/docker-handler.js.map +1 -0
- package/dist/context/handlers/ssh-handler.d.ts +120 -0
- package/dist/context/handlers/ssh-handler.d.ts.map +1 -0
- package/dist/context/handlers/ssh-handler.js +523 -0
- package/dist/context/handlers/ssh-handler.js.map +1 -0
- package/dist/context/handlers/wsl-handler.d.ts +128 -0
- package/dist/context/handlers/wsl-handler.d.ts.map +1 -0
- package/dist/context/handlers/wsl-handler.js +590 -0
- package/dist/context/handlers/wsl-handler.js.map +1 -0
- package/dist/context/index.d.ts +8 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +7 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/subshell-handler.d.ts +130 -0
- package/dist/context/subshell-handler.d.ts.map +1 -0
- package/dist/context/subshell-handler.js +5 -0
- package/dist/context/subshell-handler.js.map +1 -0
- package/dist/context/types.d.ts +70 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +34 -0
- package/dist/context/types.js.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/services/__tests__/ai-context-injector.test.d.ts +15 -0
- package/dist/services/__tests__/ai-context-injector.test.d.ts.map +1 -0
- package/dist/services/__tests__/ai-context-injector.test.js +326 -0
- package/dist/services/__tests__/ai-context-injector.test.js.map +1 -0
- package/dist/services/ai-context-injector.d.ts +41 -0
- package/dist/services/ai-context-injector.d.ts.map +1 -0
- package/dist/services/ai-context-injector.js +97 -0
- package/dist/services/ai-context-injector.js.map +1 -0
- package/dist/services/ai-service-client.d.ts +4 -1
- package/dist/services/ai-service-client.d.ts.map +1 -1
- package/dist/services/ai-service-client.js +6 -2
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/services/api-client.js +1 -1
- package/dist/services/api-client.js.map +1 -1
- package/dist/src/context/types.js +27 -0
- package/dist/src/services/ai-context-injector.js +96 -0
- package/dist/src/services/ai-service-client.js +270 -0
- package/dist/src/services/api-client.js +349 -0
- package/dist/src/tools/types.js +1 -0
- package/dist/src/types/index.js +1 -0
- package/dist/test/context/types.js +27 -0
- package/dist/test/services/__tests__/ai-context-injector.test.js +325 -0
- package/dist/test/services/ai-context-injector.js +96 -0
- package/dist/test/services/ai-service-client.js +270 -0
- package/dist/test/services/api-client.js +349 -0
- package/dist/test/tools/types.js +1 -0
- package/dist/test/types/index.js +1 -0
- package/dist/test-ai-context-injector.js +97 -0
- package/dist/test-ssh-handler.d.ts +8 -0
- package/dist/test-ssh-handler.d.ts.map +1 -0
- package/dist/test-ssh-handler.js +198 -0
- package/dist/test-ssh-handler.js.map +1 -0
- package/dist/tools/command.d.ts.map +1 -1
- package/dist/tools/command.js +123 -46
- package/dist/tools/command.js.map +1 -1
- package/dist/tools/file-ops.d.ts.map +1 -1
- package/dist/tools/file-ops.js +115 -48
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/types.d.ts +1 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/web-search.js +2 -2
- package/dist/tools/web-search.js.map +1 -1
- package/dist/types/index.d.ts +41 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui/components/App.d.ts +3 -0
- package/dist/ui/components/App.d.ts.map +1 -1
- package/dist/ui/components/App.js +213 -46
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/Breadcrumbs.d.ts +12 -0
- package/dist/ui/components/Breadcrumbs.d.ts.map +1 -0
- package/dist/ui/components/Breadcrumbs.js +62 -0
- package/dist/ui/components/Breadcrumbs.js.map +1 -0
- package/dist/ui/components/CodeBlock.js +1 -1
- package/dist/ui/components/CodeBlock.js.map +1 -1
- package/dist/ui/components/DiffViewer.js +1 -1
- package/dist/ui/components/DiffViewer.js.map +1 -1
- package/dist/ui/components/FileViewerScreen.d.ts +14 -0
- package/dist/ui/components/FileViewerScreen.d.ts.map +1 -0
- package/dist/ui/components/FileViewerScreen.js +74 -0
- package/dist/ui/components/FileViewerScreen.js.map +1 -0
- package/dist/ui/components/InputBox.d.ts +2 -0
- package/dist/ui/components/InputBox.d.ts.map +1 -1
- package/dist/ui/components/InputBox.js +85 -41
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/MessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/MessageDisplay.js +3 -28
- package/dist/ui/components/MessageDisplay.js.map +1 -1
- package/dist/ui/components/PasswordPrompt.d.ts +9 -0
- package/dist/ui/components/PasswordPrompt.d.ts.map +1 -0
- package/dist/ui/components/PasswordPrompt.js +20 -0
- package/dist/ui/components/PasswordPrompt.js.map +1 -0
- package/dist/ui/components/StatusBar.d.ts +2 -0
- package/dist/ui/components/StatusBar.d.ts.map +1 -1
- package/dist/ui/components/StatusBar.js +36 -1
- package/dist/ui/components/StatusBar.js.map +1 -1
- package/dist/ui/components/ToolExecutionMessage.d.ts.map +1 -1
- package/dist/ui/components/ToolExecutionMessage.js +13 -24
- package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
- package/dist/ui/components/VersionUpdatePrompt.d.ts +10 -0
- package/dist/ui/components/VersionUpdatePrompt.d.ts.map +1 -0
- package/dist/ui/components/VersionUpdatePrompt.js +41 -0
- package/dist/ui/components/VersionUpdatePrompt.js.map +1 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +38 -10
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/version-checker.d.ts +14 -0
- package/dist/utils/version-checker.d.ts.map +1 -0
- package/dist/utils/version-checker.js +63 -0
- package/dist/utils/version-checker.js.map +1 -0
- package/package.json +71 -69
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker Handler for container execution
|
|
3
|
+
*/
|
|
4
|
+
import { exec } from 'child_process';
|
|
5
|
+
import { promisify } from 'util';
|
|
6
|
+
import { writeFile, unlink } from 'fs/promises';
|
|
7
|
+
import { tmpdir } from 'os';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { SubshellConnectionError, SubshellExecutionError } from '../types.js';
|
|
10
|
+
import { randomBytes } from 'crypto';
|
|
11
|
+
const execAsync = promisify(exec);
|
|
12
|
+
/**
|
|
13
|
+
* Docker Handler implementation
|
|
14
|
+
*/
|
|
15
|
+
export class DockerHandler {
|
|
16
|
+
type = 'docker';
|
|
17
|
+
detectionPatterns = [
|
|
18
|
+
/^docker\s+exec\s+/,
|
|
19
|
+
/^docker\s+exec\s+-it\s+/,
|
|
20
|
+
];
|
|
21
|
+
config = null;
|
|
22
|
+
currentWorkingDirectory = '/';
|
|
23
|
+
shellType = 'sh';
|
|
24
|
+
osType = 'linux';
|
|
25
|
+
sessionId = '';
|
|
26
|
+
/**
|
|
27
|
+
* Detect if a command should trigger this handler
|
|
28
|
+
*/
|
|
29
|
+
detect(command) {
|
|
30
|
+
return this.detectionPatterns.some(pattern => pattern.test(command));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Connect to the Docker container
|
|
34
|
+
*/
|
|
35
|
+
async connect(command, cwd) {
|
|
36
|
+
this.sessionId = randomBytes(16).toString('hex');
|
|
37
|
+
try {
|
|
38
|
+
// Parse Docker command to extract container ID
|
|
39
|
+
this.config = this.parseDockerCommand(command);
|
|
40
|
+
// Verify container exists and is running
|
|
41
|
+
await this.verifyContainer();
|
|
42
|
+
// Detect shell type and OS
|
|
43
|
+
this.shellType = await this.detectShellType();
|
|
44
|
+
this.osType = await this.detectOSType();
|
|
45
|
+
// Get initial working directory
|
|
46
|
+
this.currentWorkingDirectory = await this.getCurrentWorkingDirectory();
|
|
47
|
+
return {
|
|
48
|
+
type: 'docker',
|
|
49
|
+
handler: this,
|
|
50
|
+
metadata: {
|
|
51
|
+
workingDirectory: this.currentWorkingDirectory,
|
|
52
|
+
shell: this.shellType,
|
|
53
|
+
os: this.osType,
|
|
54
|
+
containerId: this.config.containerId,
|
|
55
|
+
},
|
|
56
|
+
connectionState: 'connected',
|
|
57
|
+
sessionId: this.sessionId,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new SubshellConnectionError('docker', error instanceof Error ? error.message : 'Unknown error', false);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Disconnect from the Docker container
|
|
66
|
+
*/
|
|
67
|
+
async disconnect() {
|
|
68
|
+
this.config = null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Execute a command in the Docker container
|
|
72
|
+
*/
|
|
73
|
+
async executeCommand(command) {
|
|
74
|
+
if (!this.config) {
|
|
75
|
+
throw new SubshellExecutionError(command, 'Not connected to Docker container');
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const dockerCommand = this.buildDockerCommand(command);
|
|
79
|
+
const { stdout, stderr } = await this.executeWithTimeout(() => execAsync(dockerCommand), 30000, 'Command execution');
|
|
80
|
+
// Extract working directory from output
|
|
81
|
+
const pwdMatch = stdout.match(/__CENTAURUS_PWD__:(.+)$/m);
|
|
82
|
+
let cleanStdout = stdout;
|
|
83
|
+
if (pwdMatch) {
|
|
84
|
+
this.currentWorkingDirectory = pwdMatch[1].trim();
|
|
85
|
+
cleanStdout = stdout.replace(/__CENTAURUS_PWD__:.+$/m, '').trim();
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
stdout: cleanStdout,
|
|
89
|
+
stderr,
|
|
90
|
+
exitCode: 0,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return {
|
|
95
|
+
stdout: '',
|
|
96
|
+
stderr: error.stderr || error.message,
|
|
97
|
+
exitCode: error.code || 1,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Read a file from the Docker container filesystem
|
|
103
|
+
*/
|
|
104
|
+
async readFile(path) {
|
|
105
|
+
if (!this.config) {
|
|
106
|
+
throw new Error('Not connected to Docker container');
|
|
107
|
+
}
|
|
108
|
+
const absolutePath = this.resolveAbsolutePath(path);
|
|
109
|
+
// Use base64 to avoid encoding issues and be binary-safe
|
|
110
|
+
const command = `docker exec ${this.config.containerId} sh -lc "base64 '${absolutePath}' 2>/dev/null || cat '${absolutePath}' | base64"`;
|
|
111
|
+
try {
|
|
112
|
+
const { stdout } = await execAsync(command);
|
|
113
|
+
const b64 = stdout.replace(/\s+/g, '');
|
|
114
|
+
return Buffer.from(b64, 'base64').toString('utf-8');
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
throw new Error(`Failed to read file ${path}: ${error.message}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Write a file to the Docker container filesystem
|
|
122
|
+
*/
|
|
123
|
+
async writeFile(path, content) {
|
|
124
|
+
if (!this.config) {
|
|
125
|
+
throw new Error('Not connected to Docker container');
|
|
126
|
+
}
|
|
127
|
+
const absolutePath = this.resolveAbsolutePath(path);
|
|
128
|
+
// Create a temporary file on the host
|
|
129
|
+
const tempFile = join(tmpdir(), `centaurus-${randomBytes(8).toString('hex')}.tmp`);
|
|
130
|
+
try {
|
|
131
|
+
// Write content to temp file
|
|
132
|
+
await writeFile(tempFile, content, 'utf8');
|
|
133
|
+
// Copy temp file to container
|
|
134
|
+
const copyCommand = `docker cp \"${tempFile}\" ${this.config.containerId}:\"${absolutePath}\"`;
|
|
135
|
+
await execAsync(copyCommand);
|
|
136
|
+
// Clean up temp file
|
|
137
|
+
await unlink(tempFile);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
// Try base64-over-exec fallback if docker cp fails
|
|
141
|
+
try {
|
|
142
|
+
// Ensure file is empty first
|
|
143
|
+
await execAsync(`docker exec ${this.config.containerId} sh -lc ": > \"${absolutePath}\""`);
|
|
144
|
+
const base64Content = Buffer.from(content, 'utf-8').toString('base64');
|
|
145
|
+
const CHUNK_SIZE = 32000;
|
|
146
|
+
for (let i = 0; i < base64Content.length; i += CHUNK_SIZE) {
|
|
147
|
+
const chunk = base64Content.slice(i, i + CHUNK_SIZE);
|
|
148
|
+
const writeCmd = `docker exec ${this.config.containerId} sh -lc 'echo "${chunk}" | base64 -d >> \"${absolutePath}\"'`;
|
|
149
|
+
await execAsync(writeCmd);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch (fbErr) {
|
|
153
|
+
// Try to clean up temp file even if fallback also failed
|
|
154
|
+
try {
|
|
155
|
+
await unlink(tempFile);
|
|
156
|
+
}
|
|
157
|
+
catch { }
|
|
158
|
+
throw new Error(`Failed to write file ${path}: ${error.message}; fallback failed: ${fbErr.message}`);
|
|
159
|
+
}
|
|
160
|
+
// Try to clean up temp file even if copy failed originally
|
|
161
|
+
try {
|
|
162
|
+
await unlink(tempFile);
|
|
163
|
+
}
|
|
164
|
+
catch { }
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* List directory contents in Docker container
|
|
169
|
+
*/
|
|
170
|
+
async listDirectory(path) {
|
|
171
|
+
if (!this.config) {
|
|
172
|
+
throw new Error('Not connected to Docker container');
|
|
173
|
+
}
|
|
174
|
+
const absolutePath = this.resolveAbsolutePath(path);
|
|
175
|
+
const command = `docker exec ${this.config.containerId} ls -la "${absolutePath}"`;
|
|
176
|
+
try {
|
|
177
|
+
const { stdout } = await execAsync(command);
|
|
178
|
+
return this.parseDirectoryListing(stdout);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
throw new Error(`Failed to list directory ${path}: ${error.message}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Search for files matching a pattern in Docker container
|
|
186
|
+
*/
|
|
187
|
+
async searchFiles(pattern, directory) {
|
|
188
|
+
if (!this.config) {
|
|
189
|
+
throw new Error('Not connected to Docker container');
|
|
190
|
+
}
|
|
191
|
+
const absolutePath = this.resolveAbsolutePath(directory);
|
|
192
|
+
const escapedPattern = pattern.replace(/'/g, "'\\''");
|
|
193
|
+
const command = `docker exec ${this.config.containerId} sh -c "grep -rn '${escapedPattern}' '${absolutePath}' 2>/dev/null || true"`;
|
|
194
|
+
try {
|
|
195
|
+
const { stdout } = await execAsync(command);
|
|
196
|
+
return this.parseSearchResults(stdout);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
// grep returns non-zero if no matches, which is not an error
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get the current working directory in the Docker container
|
|
205
|
+
*/
|
|
206
|
+
async getCurrentWorkingDirectory() {
|
|
207
|
+
if (!this.config) {
|
|
208
|
+
return '/';
|
|
209
|
+
}
|
|
210
|
+
const command = `docker exec ${this.config.containerId} pwd`;
|
|
211
|
+
try {
|
|
212
|
+
const { stdout } = await execAsync(command);
|
|
213
|
+
return stdout.trim();
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return '/';
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get the shell type
|
|
221
|
+
*/
|
|
222
|
+
async getShellType() {
|
|
223
|
+
return this.shellType;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get the operating system type
|
|
227
|
+
*/
|
|
228
|
+
async getOSType() {
|
|
229
|
+
return this.osType;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Get breadcrumb information for the UI
|
|
233
|
+
*/
|
|
234
|
+
getBreadcrumbs() {
|
|
235
|
+
if (!this.config) {
|
|
236
|
+
return [];
|
|
237
|
+
}
|
|
238
|
+
const displayName = this.config.containerName || this.config.containerId.substring(0, 12);
|
|
239
|
+
return [
|
|
240
|
+
{
|
|
241
|
+
label: 'docker',
|
|
242
|
+
color: 'blue',
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
label: displayName,
|
|
246
|
+
color: 'blue',
|
|
247
|
+
},
|
|
248
|
+
];
|
|
249
|
+
}
|
|
250
|
+
// Private helper methods
|
|
251
|
+
/**
|
|
252
|
+
* Parse Docker exec command to extract container ID
|
|
253
|
+
*/
|
|
254
|
+
parseDockerCommand(command) {
|
|
255
|
+
const parts = command.trim().split(/\s+/);
|
|
256
|
+
let containerId = '';
|
|
257
|
+
// Find the container ID (first non-flag argument after 'exec')
|
|
258
|
+
let foundExec = false;
|
|
259
|
+
for (let i = 0; i < parts.length; i++) {
|
|
260
|
+
const part = parts[i];
|
|
261
|
+
if (part === 'exec') {
|
|
262
|
+
foundExec = true;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
if (foundExec) {
|
|
266
|
+
// Skip flags
|
|
267
|
+
if (part.startsWith('-')) {
|
|
268
|
+
// Check if it's a flag with a value
|
|
269
|
+
if (part === '-e' || part === '-w' || part === '-u') {
|
|
270
|
+
i++; // Skip the next part (flag value)
|
|
271
|
+
}
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
// This should be the container ID
|
|
275
|
+
containerId = part;
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (!containerId) {
|
|
280
|
+
throw new Error('Could not parse container ID from Docker command');
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
containerId,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Verify that the container exists and is running
|
|
288
|
+
*/
|
|
289
|
+
async verifyContainer() {
|
|
290
|
+
if (!this.config) {
|
|
291
|
+
throw new Error('No container configuration');
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
// Use docker inspect to check container status
|
|
295
|
+
const command = `docker inspect --format="{{.State.Running}},{{.Name}}" ${this.config.containerId}`;
|
|
296
|
+
const { stdout } = await execAsync(command);
|
|
297
|
+
const [running, name] = stdout.trim().split(',');
|
|
298
|
+
if (running !== 'true') {
|
|
299
|
+
throw new Error(`Container ${this.config.containerId} is not running`);
|
|
300
|
+
}
|
|
301
|
+
// Store container name (remove leading /)
|
|
302
|
+
if (name) {
|
|
303
|
+
this.config.containerName = name.replace(/^\//, '');
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
if (error.message.includes('No such object')) {
|
|
308
|
+
throw new Error(`Container ${this.config.containerId} does not exist`);
|
|
309
|
+
}
|
|
310
|
+
throw error;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Detect the shell type in the Docker container
|
|
315
|
+
*/
|
|
316
|
+
async detectShellType() {
|
|
317
|
+
if (!this.config) {
|
|
318
|
+
return 'sh';
|
|
319
|
+
}
|
|
320
|
+
try {
|
|
321
|
+
// Try to detect shell
|
|
322
|
+
const command = `docker exec ${this.config.containerId} sh -c "echo \\$SHELL"`;
|
|
323
|
+
const { stdout } = await execAsync(command);
|
|
324
|
+
const shellPath = stdout.trim();
|
|
325
|
+
if (shellPath.includes('bash'))
|
|
326
|
+
return 'bash';
|
|
327
|
+
if (shellPath.includes('zsh'))
|
|
328
|
+
return 'zsh';
|
|
329
|
+
if (shellPath.includes('fish'))
|
|
330
|
+
return 'fish';
|
|
331
|
+
// Default to sh for containers
|
|
332
|
+
return 'sh';
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return 'sh';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Detect the operating system type in the Docker container
|
|
340
|
+
*/
|
|
341
|
+
async detectOSType() {
|
|
342
|
+
if (!this.config) {
|
|
343
|
+
return 'linux';
|
|
344
|
+
}
|
|
345
|
+
try {
|
|
346
|
+
const command = `docker exec ${this.config.containerId} uname -s`;
|
|
347
|
+
const { stdout } = await execAsync(command);
|
|
348
|
+
const osName = stdout.trim().toLowerCase();
|
|
349
|
+
if (osName.includes('darwin'))
|
|
350
|
+
return 'macos';
|
|
351
|
+
if (osName.includes('linux'))
|
|
352
|
+
return 'linux';
|
|
353
|
+
// Most containers are Linux
|
|
354
|
+
return 'linux';
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return 'linux';
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Build a Docker exec command with working directory context
|
|
362
|
+
*/
|
|
363
|
+
buildDockerCommand(command) {
|
|
364
|
+
if (!this.config) {
|
|
365
|
+
throw new Error('Not connected to Docker container');
|
|
366
|
+
}
|
|
367
|
+
// Add pwd tracking to command
|
|
368
|
+
const commandWithPwd = `${command}; echo "__CENTAURUS_PWD__:$(pwd)"`;
|
|
369
|
+
// Use -w flag to set working directory
|
|
370
|
+
return `docker exec -w "${this.currentWorkingDirectory}" ${this.config.containerId} sh -c "${commandWithPwd.replace(/"/g, '\\"')}"`;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Resolve a path to an absolute path
|
|
374
|
+
*/
|
|
375
|
+
resolveAbsolutePath(path) {
|
|
376
|
+
if (path.startsWith('/')) {
|
|
377
|
+
return path;
|
|
378
|
+
}
|
|
379
|
+
if (path.startsWith('~')) {
|
|
380
|
+
return path;
|
|
381
|
+
}
|
|
382
|
+
return `${this.currentWorkingDirectory}/${path}`;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Parse directory listing output
|
|
386
|
+
*/
|
|
387
|
+
parseDirectoryListing(output) {
|
|
388
|
+
const entries = [];
|
|
389
|
+
const lines = output.split('\n').filter(line => line.trim());
|
|
390
|
+
for (const line of lines) {
|
|
391
|
+
// Skip total line and current/parent directory
|
|
392
|
+
if (line.startsWith('total') || line.endsWith(' .') || line.endsWith(' ..')) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
// Parse ls -la output: permissions links owner group size date time name
|
|
396
|
+
const match = line.match(/^([drwx-]+)\s+\d+\s+\S+\s+\S+\s+(\d+)\s+\S+\s+\S+\s+\S+\s+(.+)$/);
|
|
397
|
+
if (match) {
|
|
398
|
+
const permissions = match[1];
|
|
399
|
+
const size = parseInt(match[2], 10);
|
|
400
|
+
const name = match[3];
|
|
401
|
+
entries.push({
|
|
402
|
+
name,
|
|
403
|
+
type: permissions.startsWith('d') ? 'directory' : 'file',
|
|
404
|
+
size,
|
|
405
|
+
permissions,
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return entries;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Parse search results from grep output
|
|
413
|
+
*/
|
|
414
|
+
parseSearchResults(output) {
|
|
415
|
+
const results = [];
|
|
416
|
+
const lines = output.split('\n').filter(line => line.trim());
|
|
417
|
+
for (const line of lines) {
|
|
418
|
+
const match = line.match(/^(.+?):(\d+):(.+)$/);
|
|
419
|
+
if (match) {
|
|
420
|
+
results.push({
|
|
421
|
+
file: match[1],
|
|
422
|
+
line: parseInt(match[2], 10),
|
|
423
|
+
content: match[3],
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return results;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Execute a promise with a timeout
|
|
431
|
+
*/
|
|
432
|
+
async executeWithTimeout(operation, timeoutMs, operationName) {
|
|
433
|
+
return Promise.race([
|
|
434
|
+
operation(),
|
|
435
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`${operationName} timed out after ${timeoutMs}ms`)), timeoutMs)),
|
|
436
|
+
]);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=docker-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-handler.js","sourceRoot":"","sources":["../../../src/context/handlers/docker-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Handler for remote shell connections
|
|
3
|
+
*/
|
|
4
|
+
import { SubshellHandler, BreadcrumbInfo, CommandResult, DirectoryEntry, SearchResult } from '../subshell-handler.js';
|
|
5
|
+
import { SubshellContext, OSType } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* SSH-specific configuration
|
|
8
|
+
*/
|
|
9
|
+
export interface SSHConfig {
|
|
10
|
+
host: string;
|
|
11
|
+
port: number;
|
|
12
|
+
username: string;
|
|
13
|
+
password?: string;
|
|
14
|
+
privateKey?: Buffer | string;
|
|
15
|
+
passphrase?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* SSH Handler implementation
|
|
19
|
+
*/
|
|
20
|
+
export declare class SSHHandler implements SubshellHandler {
|
|
21
|
+
readonly type = "ssh";
|
|
22
|
+
readonly detectionPatterns: RegExp[];
|
|
23
|
+
private client;
|
|
24
|
+
private sftpClient;
|
|
25
|
+
private config;
|
|
26
|
+
private currentWorkingDirectory;
|
|
27
|
+
private shellType;
|
|
28
|
+
private osType;
|
|
29
|
+
private sessionId;
|
|
30
|
+
private onPasswordRequest?;
|
|
31
|
+
/**
|
|
32
|
+
* Set password request callback
|
|
33
|
+
*/
|
|
34
|
+
setPasswordRequestCallback(callback: (message: string) => Promise<string>): void;
|
|
35
|
+
/**
|
|
36
|
+
* Detect if a command should trigger this handler
|
|
37
|
+
*/
|
|
38
|
+
detect(command: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Connect to the SSH server
|
|
41
|
+
*/
|
|
42
|
+
connect(command: string, cwd: string): Promise<SubshellContext>;
|
|
43
|
+
/**
|
|
44
|
+
* Disconnect from the SSH server
|
|
45
|
+
*/
|
|
46
|
+
disconnect(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Execute a command in the SSH session
|
|
49
|
+
*/
|
|
50
|
+
executeCommand(command: string): Promise<CommandResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Read a file from the remote filesystem
|
|
53
|
+
*/
|
|
54
|
+
readFile(path: string): Promise<string>;
|
|
55
|
+
/**
|
|
56
|
+
* Write a file to the remote filesystem
|
|
57
|
+
*/
|
|
58
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* List directory contents
|
|
61
|
+
*/
|
|
62
|
+
listDirectory(path: string): Promise<DirectoryEntry[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Search for files matching a pattern
|
|
65
|
+
*/
|
|
66
|
+
searchFiles(pattern: string, directory: string): Promise<SearchResult[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Get the current working directory
|
|
69
|
+
*/
|
|
70
|
+
getCurrentWorkingDirectory(): Promise<string>;
|
|
71
|
+
/**
|
|
72
|
+
* Get the shell type
|
|
73
|
+
*/
|
|
74
|
+
getShellType(): Promise<string>;
|
|
75
|
+
/**
|
|
76
|
+
* Get the operating system type
|
|
77
|
+
*/
|
|
78
|
+
getOSType(): Promise<OSType>;
|
|
79
|
+
/**
|
|
80
|
+
* Get breadcrumb information for the UI
|
|
81
|
+
*/
|
|
82
|
+
getBreadcrumbs(): BreadcrumbInfo[];
|
|
83
|
+
/**
|
|
84
|
+
* Parse SSH command to extract connection details
|
|
85
|
+
*/
|
|
86
|
+
private parseSSHCommand;
|
|
87
|
+
/**
|
|
88
|
+
* Establish SSH connection
|
|
89
|
+
*/
|
|
90
|
+
private establishConnection;
|
|
91
|
+
/**
|
|
92
|
+
* Initialize SFTP session
|
|
93
|
+
*/
|
|
94
|
+
private initializeSFTP;
|
|
95
|
+
/**
|
|
96
|
+
* Detect the shell type on the remote system
|
|
97
|
+
*/
|
|
98
|
+
private detectShellType;
|
|
99
|
+
/**
|
|
100
|
+
* Detect the operating system type
|
|
101
|
+
*/
|
|
102
|
+
private detectOSType;
|
|
103
|
+
/**
|
|
104
|
+
* Inject shell integration script
|
|
105
|
+
*/
|
|
106
|
+
private injectShellIntegration;
|
|
107
|
+
/**
|
|
108
|
+
* Get shell integration script based on shell type
|
|
109
|
+
*/
|
|
110
|
+
private getShellIntegrationScript;
|
|
111
|
+
/**
|
|
112
|
+
* Resolve a path to an absolute path
|
|
113
|
+
*/
|
|
114
|
+
private resolveAbsolutePath;
|
|
115
|
+
/**
|
|
116
|
+
* Parse directory listing output (ls -la)
|
|
117
|
+
*/
|
|
118
|
+
private parseDirectoryListing;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=ssh-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-handler.d.ts","sourceRoot":"","sources":["../../../src/context/handlers/ssh-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtH,OAAO,EAAE,eAAe,EAAmD,MAAM,EAAE,MAAM,aAAa,CAAC;AAGvG;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,UAAW,YAAW,eAAe;IAChD,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,iBAAiB,WAGxB;IAEF,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,uBAAuB,CAAe;IAC9C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,iBAAiB,CAAC,CAAuC;IAEjE;;OAEG;IACH,0BAA0B,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAIhF;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA6DrE;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAcjC;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAmD7D;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0B7C;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC7D;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA8B5D;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAwB9E;;OAEG;IACG,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC;IAKnD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAIrC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAIlC;;OAEG;IACH,cAAc,IAAI,cAAc,EAAE;IAmBlC;;OAEG;IACH,OAAO,CAAC,eAAe;IA4CvB;;OAEG;YACW,mBAAmB;IAmCjC;;OAEG;YACW,cAAc;IAiB5B;;OAEG;YACW,eAAe;IAe7B;;OAEG;YACW,YAAY;IAc1B;;OAEG;YACW,sBAAsB;IAUpC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAsCjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAwB9B"}
|