rackmind-cli 0.1.2
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 +179 -0
- package/bin/rackmind.js +6 -0
- package/dist/ai/client.d.ts +71 -0
- package/dist/ai/client.d.ts.map +1 -0
- package/dist/ai/client.js +198 -0
- package/dist/ai/client.js.map +1 -0
- package/dist/ai/system-prompt.d.ts +20 -0
- package/dist/ai/system-prompt.d.ts.map +1 -0
- package/dist/ai/system-prompt.js +169 -0
- package/dist/ai/system-prompt.js.map +1 -0
- package/dist/ai/tool-executor.d.ts +27 -0
- package/dist/ai/tool-executor.d.ts.map +1 -0
- package/dist/ai/tool-executor.js +184 -0
- package/dist/ai/tool-executor.js.map +1 -0
- package/dist/ai/tools.d.ts +7 -0
- package/dist/ai/tools.d.ts.map +1 -0
- package/dist/ai/tools.js +203 -0
- package/dist/ai/tools.js.map +1 -0
- package/dist/commands/config.d.ts +21 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +169 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/connect.d.ts +7 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +117 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/containers.d.ts +5 -0
- package/dist/commands/containers.d.ts.map +1 -0
- package/dist/commands/containers.js +83 -0
- package/dist/commands/containers.js.map +1 -0
- package/dist/commands/exec.d.ts +5 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +133 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/lifecycle.d.ts +7 -0
- package/dist/commands/lifecycle.d.ts.map +1 -0
- package/dist/commands/lifecycle.js +213 -0
- package/dist/commands/lifecycle.js.map +1 -0
- package/dist/commands/logs.d.ts +5 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +117 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/report.d.ts +6 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +203 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/servers.d.ts +17 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/commands/servers.js +116 -0
- package/dist/commands/servers.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +174 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/vms.d.ts +5 -0
- package/dist/commands/vms.d.ts.map +1 -0
- package/dist/commands/vms.js +83 -0
- package/dist/commands/vms.js.map +1 -0
- package/dist/config/crypto.d.ts +20 -0
- package/dist/config/crypto.d.ts.map +1 -0
- package/dist/config/crypto.js +78 -0
- package/dist/config/crypto.js.map +1 -0
- package/dist/config/index.d.ts +21 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +158 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +263 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +83 -0
- package/dist/config/types.js.map +1 -0
- package/dist/globals.d.ts +22 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +43 -0
- package/dist/globals.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +399 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive/App.d.ts +3 -0
- package/dist/interactive/App.d.ts.map +1 -0
- package/dist/interactive/App.js +103 -0
- package/dist/interactive/App.js.map +1 -0
- package/dist/interactive/components/Header.d.ts +8 -0
- package/dist/interactive/components/Header.d.ts.map +1 -0
- package/dist/interactive/components/Header.js +20 -0
- package/dist/interactive/components/Header.js.map +1 -0
- package/dist/interactive/components/InputBar.d.ts +9 -0
- package/dist/interactive/components/InputBar.d.ts.map +1 -0
- package/dist/interactive/components/InputBar.js +89 -0
- package/dist/interactive/components/InputBar.js.map +1 -0
- package/dist/interactive/components/MessageList.d.ts +9 -0
- package/dist/interactive/components/MessageList.d.ts.map +1 -0
- package/dist/interactive/components/MessageList.js +28 -0
- package/dist/interactive/components/MessageList.js.map +1 -0
- package/dist/interactive/components/Spinner.d.ts +7 -0
- package/dist/interactive/components/Spinner.d.ts.map +1 -0
- package/dist/interactive/components/Spinner.js +19 -0
- package/dist/interactive/components/Spinner.js.map +1 -0
- package/dist/interactive/components/StatusBar.d.ts +10 -0
- package/dist/interactive/components/StatusBar.d.ts.map +1 -0
- package/dist/interactive/components/StatusBar.js +7 -0
- package/dist/interactive/components/StatusBar.js.map +1 -0
- package/dist/interactive/components/StreamingMessage.d.ts +7 -0
- package/dist/interactive/components/StreamingMessage.d.ts.map +1 -0
- package/dist/interactive/components/StreamingMessage.js +9 -0
- package/dist/interactive/components/StreamingMessage.js.map +1 -0
- package/dist/interactive/components/ToolIndicator.d.ts +7 -0
- package/dist/interactive/components/ToolIndicator.d.ts.map +1 -0
- package/dist/interactive/components/ToolIndicator.js +10 -0
- package/dist/interactive/components/ToolIndicator.js.map +1 -0
- package/dist/interactive/components/ToolOutput.d.ts +8 -0
- package/dist/interactive/components/ToolOutput.d.ts.map +1 -0
- package/dist/interactive/components/ToolOutput.js +9 -0
- package/dist/interactive/components/ToolOutput.js.map +1 -0
- package/dist/interactive/components/WelcomeScreen.d.ts +9 -0
- package/dist/interactive/components/WelcomeScreen.d.ts.map +1 -0
- package/dist/interactive/components/WelcomeScreen.js +8 -0
- package/dist/interactive/components/WelcomeScreen.js.map +1 -0
- package/dist/interactive/launch.d.ts +6 -0
- package/dist/interactive/launch.d.ts.map +1 -0
- package/dist/interactive/launch.js +30 -0
- package/dist/interactive/launch.js.map +1 -0
- package/dist/interactive/slashCommands.d.ts +13 -0
- package/dist/interactive/slashCommands.d.ts.map +1 -0
- package/dist/interactive/slashCommands.js +102 -0
- package/dist/interactive/slashCommands.js.map +1 -0
- package/dist/interactive/useRackMind.d.ts +30 -0
- package/dist/interactive/useRackMind.d.ts.map +1 -0
- package/dist/interactive/useRackMind.js +241 -0
- package/dist/interactive/useRackMind.js.map +1 -0
- package/dist/oneshot/run.d.ts +2 -0
- package/dist/oneshot/run.d.ts.map +1 -0
- package/dist/oneshot/run.js +195 -0
- package/dist/oneshot/run.js.map +1 -0
- package/dist/server/client.d.ts +89 -0
- package/dist/server/client.d.ts.map +1 -0
- package/dist/server/client.js +239 -0
- package/dist/server/client.js.map +1 -0
- package/dist/server/proxmox.d.ts +160 -0
- package/dist/server/proxmox.d.ts.map +1 -0
- package/dist/server/proxmox.js +219 -0
- package/dist/server/proxmox.js.map +1 -0
- package/dist/server/ssh.d.ts +80 -0
- package/dist/server/ssh.d.ts.map +1 -0
- package/dist/server/ssh.js +262 -0
- package/dist/server/ssh.js.map +1 -0
- package/dist/utils/ascii.d.ts +3 -0
- package/dist/utils/ascii.d.ts.map +1 -0
- package/dist/utils/ascii.js +16 -0
- package/dist/utils/ascii.js.map +1 -0
- package/dist/utils/format.d.ts +7 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +20 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/history.d.ts +23 -0
- package/dist/utils/history.d.ts.map +1 -0
- package/dist/utils/history.js +107 -0
- package/dist/utils/history.js.map +1 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +51 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.d.ts +12 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +76 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/prompt.d.ts +25 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +133 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/retry.d.ts +37 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +122 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/shutdown.d.ts +22 -0
- package/dist/utils/shutdown.d.ts.map +1 -0
- package/dist/utils/shutdown.js +94 -0
- package/dist/utils/shutdown.js.map +1 -0
- package/dist/utils/table.d.ts +38 -0
- package/dist/utils/table.d.ts.map +1 -0
- package/dist/utils/table.js +150 -0
- package/dist/utils/table.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// useRackMind hook — core state management for the interactive REPL
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Manages conversation history, streaming state, server connection,
|
|
5
|
+
// and tool execution tracking. Provides a `sendMessage` function
|
|
6
|
+
// that components call when the user submits a query.
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
9
|
+
import { AIClient } from '../ai/client.js';
|
|
10
|
+
import { ServerClient } from '../server/client.js';
|
|
11
|
+
import { getAnthropicApiKey, getActiveProfile, readConfig } from '../config/index.js';
|
|
12
|
+
import { logger } from '../utils/logger.js';
|
|
13
|
+
import { onShutdown, removeShutdownHandler } from '../utils/shutdown.js';
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// ID generation
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
let messageCounter = 0;
|
|
18
|
+
function nextMessageId() {
|
|
19
|
+
messageCounter += 1;
|
|
20
|
+
return `msg-${Date.now()}-${messageCounter}`;
|
|
21
|
+
}
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Hook
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
export function useRackMind() {
|
|
26
|
+
const [messages, setMessages] = useState([]);
|
|
27
|
+
const [connection, setConnection] = useState({
|
|
28
|
+
status: 'disconnected',
|
|
29
|
+
serverAlias: null,
|
|
30
|
+
error: null,
|
|
31
|
+
});
|
|
32
|
+
const [isThinking, setIsThinking] = useState(false);
|
|
33
|
+
const [streamingText, setStreamingText] = useState('');
|
|
34
|
+
const [activeTools, setActiveTools] = useState([]);
|
|
35
|
+
const [error, setError] = useState(null);
|
|
36
|
+
const config = readConfig();
|
|
37
|
+
const model = config.preferences.model;
|
|
38
|
+
// Refs for mutable state that callbacks need
|
|
39
|
+
const serverClientRef = useRef(null);
|
|
40
|
+
const aiClientRef = useRef(null);
|
|
41
|
+
const historyRef = useRef([]);
|
|
42
|
+
const toolExecutionsRef = useRef([]);
|
|
43
|
+
// -----------------------------------------------------------------------
|
|
44
|
+
// Connect to server
|
|
45
|
+
// -----------------------------------------------------------------------
|
|
46
|
+
const connect = useCallback(async () => {
|
|
47
|
+
setConnection({
|
|
48
|
+
status: 'connecting',
|
|
49
|
+
serverAlias: null,
|
|
50
|
+
error: null,
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
const apiKey = getAnthropicApiKey();
|
|
54
|
+
if (!apiKey) {
|
|
55
|
+
setConnection({
|
|
56
|
+
status: 'error',
|
|
57
|
+
serverAlias: null,
|
|
58
|
+
error: 'No API key configured. Run: rackmind config set-api-key',
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const profile = getActiveProfile();
|
|
63
|
+
if (!profile) {
|
|
64
|
+
setConnection({
|
|
65
|
+
status: 'error',
|
|
66
|
+
serverAlias: null,
|
|
67
|
+
error: 'No active server. Run: rackmind connect <alias>',
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Create server client and connect SSH
|
|
72
|
+
const client = new ServerClient(profile);
|
|
73
|
+
await client.connectSSH();
|
|
74
|
+
serverClientRef.current = client;
|
|
75
|
+
// Create AI client
|
|
76
|
+
aiClientRef.current = new AIClient({
|
|
77
|
+
apiKey,
|
|
78
|
+
model: config.preferences.model,
|
|
79
|
+
});
|
|
80
|
+
setConnection({
|
|
81
|
+
status: 'connected',
|
|
82
|
+
serverAlias: profile.alias,
|
|
83
|
+
error: null,
|
|
84
|
+
});
|
|
85
|
+
logger.info('Interactive mode connected', { alias: profile.alias });
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
89
|
+
logger.error('Interactive mode connection failed', { error: message });
|
|
90
|
+
setConnection({
|
|
91
|
+
status: 'error',
|
|
92
|
+
serverAlias: null,
|
|
93
|
+
error: message,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}, [config.preferences.model]);
|
|
97
|
+
// -----------------------------------------------------------------------
|
|
98
|
+
// Disconnect
|
|
99
|
+
// -----------------------------------------------------------------------
|
|
100
|
+
const disconnect = useCallback(() => {
|
|
101
|
+
if (serverClientRef.current) {
|
|
102
|
+
serverClientRef.current.dispose();
|
|
103
|
+
serverClientRef.current = null;
|
|
104
|
+
}
|
|
105
|
+
aiClientRef.current = null;
|
|
106
|
+
historyRef.current = [];
|
|
107
|
+
setConnection({
|
|
108
|
+
status: 'disconnected',
|
|
109
|
+
serverAlias: null,
|
|
110
|
+
error: null,
|
|
111
|
+
});
|
|
112
|
+
}, []);
|
|
113
|
+
// Clean up on unmount + register signal handler cleanup
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
const cleanupFn = () => {
|
|
116
|
+
if (serverClientRef.current) {
|
|
117
|
+
serverClientRef.current.dispose();
|
|
118
|
+
serverClientRef.current = null;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
onShutdown(cleanupFn);
|
|
122
|
+
return () => {
|
|
123
|
+
cleanupFn();
|
|
124
|
+
removeShutdownHandler(cleanupFn);
|
|
125
|
+
};
|
|
126
|
+
}, []);
|
|
127
|
+
// -----------------------------------------------------------------------
|
|
128
|
+
// Send message
|
|
129
|
+
// -----------------------------------------------------------------------
|
|
130
|
+
const sendMessage = useCallback(async (text) => {
|
|
131
|
+
if (!aiClientRef.current || !serverClientRef.current || !connection.serverAlias) {
|
|
132
|
+
setError('Not connected to a server.');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const trimmed = text.trim();
|
|
136
|
+
if (!trimmed)
|
|
137
|
+
return;
|
|
138
|
+
// Add user message
|
|
139
|
+
const userMessage = {
|
|
140
|
+
id: nextMessageId(),
|
|
141
|
+
role: 'user',
|
|
142
|
+
content: trimmed,
|
|
143
|
+
timestamp: Date.now(),
|
|
144
|
+
};
|
|
145
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
146
|
+
setIsThinking(true);
|
|
147
|
+
setStreamingText('');
|
|
148
|
+
setError(null);
|
|
149
|
+
toolExecutionsRef.current = [];
|
|
150
|
+
let accumulatedText = '';
|
|
151
|
+
const callbacks = {
|
|
152
|
+
onText: (chunk) => {
|
|
153
|
+
accumulatedText += chunk;
|
|
154
|
+
setStreamingText(accumulatedText);
|
|
155
|
+
},
|
|
156
|
+
onToolStart: (toolName) => {
|
|
157
|
+
setActiveTools((prev) => [...prev, toolName]);
|
|
158
|
+
},
|
|
159
|
+
onToolEnd: (toolName) => {
|
|
160
|
+
setActiveTools((prev) => prev.filter((t) => t !== toolName));
|
|
161
|
+
},
|
|
162
|
+
onToolResult: (execution) => {
|
|
163
|
+
toolExecutionsRef.current.push(execution);
|
|
164
|
+
},
|
|
165
|
+
onError: (errorMsg) => {
|
|
166
|
+
setError(errorMsg);
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
try {
|
|
170
|
+
const updatedHistory = await aiClientRef.current.chatMultiTurn(trimmed, historyRef.current, serverClientRef.current, connection.serverAlias, callbacks);
|
|
171
|
+
historyRef.current = updatedHistory;
|
|
172
|
+
// Add assistant message with final text
|
|
173
|
+
const assistantMessage = {
|
|
174
|
+
id: nextMessageId(),
|
|
175
|
+
role: 'assistant',
|
|
176
|
+
content: accumulatedText,
|
|
177
|
+
timestamp: Date.now(),
|
|
178
|
+
toolExecutions: toolExecutionsRef.current.length > 0
|
|
179
|
+
? [...toolExecutionsRef.current]
|
|
180
|
+
: undefined,
|
|
181
|
+
};
|
|
182
|
+
setMessages((prev) => [...prev, assistantMessage]);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
186
|
+
logger.error('Interactive chat failed', { error: message });
|
|
187
|
+
// Provide human-readable errors
|
|
188
|
+
let userError = message;
|
|
189
|
+
if (message.includes('401') || message.includes('authentication_error')) {
|
|
190
|
+
userError = 'Anthropic API authentication failed. Check your API key.';
|
|
191
|
+
}
|
|
192
|
+
else if (message.includes('429') || message.includes('rate_limit')) {
|
|
193
|
+
userError = 'Rate limit hit. Please wait and try again.';
|
|
194
|
+
}
|
|
195
|
+
else if (message.includes('overloaded')) {
|
|
196
|
+
userError = 'Anthropic API is overloaded. Try again in a moment.';
|
|
197
|
+
}
|
|
198
|
+
else if (message.includes('ECONNREFUSED') || message.includes('ETIMEDOUT')) {
|
|
199
|
+
userError = 'Cannot connect to server. Check your configuration.';
|
|
200
|
+
}
|
|
201
|
+
const errorMessage = {
|
|
202
|
+
id: nextMessageId(),
|
|
203
|
+
role: 'system',
|
|
204
|
+
content: userError,
|
|
205
|
+
timestamp: Date.now(),
|
|
206
|
+
};
|
|
207
|
+
setMessages((prev) => [...prev, errorMessage]);
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
setIsThinking(false);
|
|
211
|
+
setStreamingText('');
|
|
212
|
+
setActiveTools([]);
|
|
213
|
+
}
|
|
214
|
+
}, [connection.serverAlias]);
|
|
215
|
+
// -----------------------------------------------------------------------
|
|
216
|
+
// Clear messages
|
|
217
|
+
// -----------------------------------------------------------------------
|
|
218
|
+
const clearMessages = useCallback(() => {
|
|
219
|
+
setMessages([]);
|
|
220
|
+
historyRef.current = [];
|
|
221
|
+
setStreamingText('');
|
|
222
|
+
setError(null);
|
|
223
|
+
}, []);
|
|
224
|
+
// -----------------------------------------------------------------------
|
|
225
|
+
// Return
|
|
226
|
+
// -----------------------------------------------------------------------
|
|
227
|
+
return {
|
|
228
|
+
messages,
|
|
229
|
+
connection,
|
|
230
|
+
isThinking,
|
|
231
|
+
streamingText,
|
|
232
|
+
activeTools,
|
|
233
|
+
model,
|
|
234
|
+
error,
|
|
235
|
+
sendMessage,
|
|
236
|
+
clearMessages,
|
|
237
|
+
connect,
|
|
238
|
+
disconnect,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=useRackMind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRackMind.js","sourceRoot":"","sources":["../../src/interactive/useRackMind.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/oneshot/run.ts"],"names":[],"mappings":"AAgGA,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8I9D"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// One-shot command execution — rackmind "query" or rackmind ask "query"
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Loads config, connects to the active server, sends the query to Claude
|
|
5
|
+
// with full server context and tools, streams the response to stdout, and
|
|
6
|
+
// exits with 0 (success) or 1 (error).
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
import { getAnthropicApiKey, getActiveProfile, readConfig, setAnthropicApiKey, } from '../config/index.js';
|
|
11
|
+
import { ServerClient } from '../server/client.js';
|
|
12
|
+
import { AIClient } from '../ai/client.js';
|
|
13
|
+
import { formatError } from '../utils/format.js';
|
|
14
|
+
import { logger } from '../utils/logger.js';
|
|
15
|
+
import { promptSecret } from '../utils/prompt.js';
|
|
16
|
+
import { renderMarkdown } from '../utils/markdown.js';
|
|
17
|
+
import { registerSignalHandlers, onShutdown } from '../utils/shutdown.js';
|
|
18
|
+
import { isQuietMode, isJsonMode } from '../globals.js';
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// API key setup
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* Ensure an Anthropic API key is available.
|
|
24
|
+
* If not configured, prompt the user to enter one (only in TTY mode).
|
|
25
|
+
* Returns the API key or null if unavailable.
|
|
26
|
+
*/
|
|
27
|
+
async function ensureApiKey() {
|
|
28
|
+
let apiKey = getAnthropicApiKey();
|
|
29
|
+
if (apiKey)
|
|
30
|
+
return apiKey;
|
|
31
|
+
// Check if we're in an interactive terminal
|
|
32
|
+
if (!process.stdin.isTTY) {
|
|
33
|
+
process.stderr.write(formatError('No Anthropic API key configured. Run `rackmind` interactively to set one up, ' +
|
|
34
|
+
'or set it with: rackmind config set-api-key') + '\n');
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
// Prompt the user
|
|
38
|
+
process.stderr.write(chalk.yellow('\nNo Anthropic API key configured.\n') +
|
|
39
|
+
chalk.dim('Get one at https://console.anthropic.com/settings/keys\n\n'));
|
|
40
|
+
apiKey = await promptSecret('Enter your Anthropic API key');
|
|
41
|
+
if (!apiKey) {
|
|
42
|
+
process.stderr.write(formatError('API key is required.') + '\n');
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
// Validate format
|
|
46
|
+
if (!apiKey.startsWith('sk-ant-')) {
|
|
47
|
+
process.stderr.write(chalk.yellow('Warning: API key does not start with "sk-ant-". Saving anyway.\n'));
|
|
48
|
+
}
|
|
49
|
+
// Save encrypted
|
|
50
|
+
setAnthropicApiKey(apiKey);
|
|
51
|
+
process.stderr.write(chalk.green('API key saved.\n\n'));
|
|
52
|
+
return apiKey;
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Active server check
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
function ensureActiveServer() {
|
|
58
|
+
const profile = getActiveProfile();
|
|
59
|
+
if (profile)
|
|
60
|
+
return { alias: profile.alias };
|
|
61
|
+
process.stderr.write(formatError('No active server configured. Run `rackmind connect <alias>` to set one up.') +
|
|
62
|
+
'\n');
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Oneshot runner
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
export async function runOneshot(prompt) {
|
|
69
|
+
let serverClient = null;
|
|
70
|
+
// Register signal handlers for graceful shutdown
|
|
71
|
+
registerSignalHandlers();
|
|
72
|
+
try {
|
|
73
|
+
// 1. Ensure API key
|
|
74
|
+
const apiKey = await ensureApiKey();
|
|
75
|
+
if (!apiKey) {
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
// 2. Ensure active server
|
|
79
|
+
const server = ensureActiveServer();
|
|
80
|
+
if (!server) {
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
// 3. Create server client and connect SSH
|
|
84
|
+
const quiet = isQuietMode();
|
|
85
|
+
const spinner = quiet
|
|
86
|
+
? null
|
|
87
|
+
: ora({
|
|
88
|
+
text: 'Connecting to server...',
|
|
89
|
+
stream: process.stderr,
|
|
90
|
+
}).start();
|
|
91
|
+
serverClient = ServerClient.fromActiveProfile();
|
|
92
|
+
// Register cleanup handler for SSH
|
|
93
|
+
onShutdown(() => {
|
|
94
|
+
serverClient?.dispose();
|
|
95
|
+
});
|
|
96
|
+
await serverClient.connectSSH();
|
|
97
|
+
if (spinner)
|
|
98
|
+
spinner.text = 'Fetching server context...';
|
|
99
|
+
// 4. Create AI client
|
|
100
|
+
const config = readConfig();
|
|
101
|
+
const aiClient = new AIClient({
|
|
102
|
+
apiKey,
|
|
103
|
+
model: config.preferences.model,
|
|
104
|
+
});
|
|
105
|
+
if (spinner)
|
|
106
|
+
spinner.succeed('Connected');
|
|
107
|
+
// 5. Set up stream callbacks — collect full response for markdown rendering
|
|
108
|
+
let fullText = '';
|
|
109
|
+
const isTTY = Boolean(process.stdout.isTTY);
|
|
110
|
+
const jsonMode = isJsonMode();
|
|
111
|
+
const callbacks = {
|
|
112
|
+
onText: (text) => {
|
|
113
|
+
fullText += text;
|
|
114
|
+
// Stream raw text to non-TTY (piped) output for scriptability
|
|
115
|
+
// Also stream raw text in JSON mode (we wrap it after)
|
|
116
|
+
if (!isTTY && !jsonMode) {
|
|
117
|
+
process.stdout.write(text);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
onToolStart: (_toolName, label) => {
|
|
121
|
+
if (!quiet) {
|
|
122
|
+
process.stderr.write(chalk.cyan(` ⚡ Executing: ${label}\n`));
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
onToolEnd: (_toolName, label, isError) => {
|
|
126
|
+
if (!quiet) {
|
|
127
|
+
if (isError) {
|
|
128
|
+
process.stderr.write(chalk.red(` ✗ ${label}\n`));
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
process.stderr.write(chalk.green(` ✓ ${label}\n`));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
onError: (error) => {
|
|
136
|
+
process.stderr.write(formatError(error) + '\n');
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
// 6. Run the AI query
|
|
140
|
+
if (!quiet) {
|
|
141
|
+
process.stderr.write(chalk.dim(`\nQuerying: "${prompt}"\n\n`));
|
|
142
|
+
}
|
|
143
|
+
await aiClient.chat(prompt, serverClient, server.alias, callbacks);
|
|
144
|
+
// Output the response
|
|
145
|
+
if (fullText) {
|
|
146
|
+
if (jsonMode) {
|
|
147
|
+
// JSON mode: wrap the response in a structured object
|
|
148
|
+
const output = {
|
|
149
|
+
model: aiClient.getModel(),
|
|
150
|
+
prompt,
|
|
151
|
+
response: fullText,
|
|
152
|
+
};
|
|
153
|
+
process.stdout.write(JSON.stringify(output, null, 2) + '\n');
|
|
154
|
+
}
|
|
155
|
+
else if (isTTY) {
|
|
156
|
+
// TTY: render with markdown formatting
|
|
157
|
+
const rendered = renderMarkdown(fullText);
|
|
158
|
+
process.stdout.write(rendered + '\n');
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Piped: raw text was already streamed, add a trailing newline
|
|
162
|
+
process.stdout.write('\n');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Clean up and exit
|
|
166
|
+
serverClient.dispose();
|
|
167
|
+
process.exit(0);
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
// Clean up on error
|
|
171
|
+
if (serverClient) {
|
|
172
|
+
serverClient.dispose();
|
|
173
|
+
}
|
|
174
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
175
|
+
logger.error('Oneshot execution failed', { error: message });
|
|
176
|
+
// Provide human-readable error messages
|
|
177
|
+
if (message.includes('401') || message.includes('authentication_error')) {
|
|
178
|
+
process.stderr.write(formatError('Anthropic API authentication failed. Check your API key.') + '\n');
|
|
179
|
+
}
|
|
180
|
+
else if (message.includes('429') || message.includes('rate_limit')) {
|
|
181
|
+
process.stderr.write(formatError('Anthropic API rate limit hit. Please wait and try again.') + '\n');
|
|
182
|
+
}
|
|
183
|
+
else if (message.includes('ECONNREFUSED') || message.includes('ETIMEDOUT')) {
|
|
184
|
+
process.stderr.write(formatError('Cannot connect to server. Check your server configuration.') + '\n');
|
|
185
|
+
}
|
|
186
|
+
else if (message.includes('overloaded')) {
|
|
187
|
+
process.stderr.write(formatError('Anthropic API is overloaded. Please try again in a moment.') + '\n');
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
process.stderr.write(formatError(message) + '\n');
|
|
191
|
+
}
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/oneshot/run.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,wEAAwE;AACxE,8EAA8E;AAC9E,yEAAyE;AACzE,0EAA0E;AAC1E,uCAAuC;AACvC,8EAA8E;AAE9E,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EACH,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,kBAAkB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAwB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAExD,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;;GAIG;AACH,KAAK,UAAU,YAAY;IACvB,IAAI,MAAM,GAAG,kBAAkB,EAAE,CAAC;IAElC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,4CAA4C;IAC5C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,WAAW,CACP,+EAA+E;YAC3E,6CAA6C,CACpD,GAAG,IAAI,CACX,CAAC;QACF,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,kBAAkB;IAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,KAAK,CAAC,MAAM,CAAC,sCAAsC,CAAC;QAChD,KAAK,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAC9E,CAAC;IAEF,MAAM,GAAG,MAAM,YAAY,CAAC,8BAA8B,CAAC,CAAC;IAE5D,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,sBAAsB,CAAC,GAAG,IAAI,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,kBAAkB;IAClB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,KAAK,CAAC,MAAM,CAAC,kEAAkE,CAAC,CACnF,CAAC;IACN,CAAC;IAED,iBAAiB;IACjB,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAExD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,SAAS,kBAAkB;IACvB,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;IAE7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,WAAW,CAAC,4EAA4E,CAAC;QACrF,IAAI,CACX,CAAC;IACF,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC3C,IAAI,YAAY,GAAwB,IAAI,CAAC;IAE7C,iDAAiD;IACjD,sBAAsB,EAAE,CAAC;IAEzB,IAAI,CAAC;QACD,oBAAoB;QACpB,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,0BAA0B;QAC1B,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,0CAA0C;QAC1C,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,KAAK;YACjB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,GAAG,CAAC;gBACA,IAAI,EAAE,yBAAyB;gBAC/B,MAAM,EAAE,OAAO,CAAC,MAAM;aACzB,CAAC,CAAC,KAAK,EAAE,CAAC;QAEjB,YAAY,GAAG,YAAY,CAAC,iBAAiB,EAAE,CAAC;QAEhD,mCAAmC;QACnC,UAAU,CAAC,GAAG,EAAE;YACZ,YAAY,EAAE,OAAO,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;QAEhC,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,GAAG,4BAA4B,CAAC;QAEzD,sBAAsB;QACtB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;YAC1B,MAAM;YACN,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK;SAClC,CAAC,CAAC;QAEH,IAAI,OAAO;YAAE,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAE1C,4EAA4E;QAC5E,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAoB;YAC/B,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACrB,QAAQ,IAAI,IAAI,CAAC;gBACjB,8DAA8D;gBAC9D,uDAAuD;gBACvD,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC/B,CAAC;YACL,CAAC;YACD,WAAW,EAAE,CAAC,SAAiB,EAAE,KAAa,EAAE,EAAE;gBAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;oBACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC;gBAClE,CAAC;YACL,CAAC;YACD,SAAS,EAAE,CAAC,SAAiB,EAAE,KAAa,EAAE,OAAgB,EAAE,EAAE;gBAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;oBACT,IAAI,OAAO,EAAE,CAAC;wBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC;oBACtD,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC;oBACxD,CAAC;gBACL,CAAC;YACL,CAAC;YACD,OAAO,EAAE,CAAC,KAAa,EAAE,EAAE;gBACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;YACpD,CAAC;SACJ,CAAC;QAEF,sBAAsB;QACtB,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,MAAM,OAAO,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAEnE,sBAAsB;QACtB,IAAI,QAAQ,EAAE,CAAC;YACX,IAAI,QAAQ,EAAE,CAAC;gBACX,sDAAsD;gBACtD,MAAM,MAAM,GAAG;oBACX,KAAK,EAAE,QAAQ,CAAC,QAAQ,EAAE;oBAC1B,MAAM;oBACN,QAAQ,EAAE,QAAQ;iBACrB,CAAC;gBACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACjE,CAAC;iBAAM,IAAI,KAAK,EAAE,CAAC;gBACf,uCAAuC;gBACvC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;gBAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACJ,+DAA+D;gBAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;QACL,CAAC;QAED,oBAAoB;QACpB,YAAY,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,oBAAoB;QACpB,IAAI,YAAY,EAAE,CAAC;YACf,YAAY,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAE7D,wCAAwC;QACxC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;YACtE,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,WAAW,CAAC,0DAA0D,CAAC,GAAG,IAAI,CACjF,CAAC;QACN,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,WAAW,CAAC,0DAA0D,CAAC,GAAG,IAAI,CACjF,CAAC;QACN,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3E,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,WAAW,CAAC,4DAA4D,CAAC,GAAG,IAAI,CACnF,CAAC;QACN,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,WAAW,CAAC,4DAA4D,CAAC,GAAG,IAAI,CACnF,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type ProxmoxNode, type ProxmoxContainer, type ProxmoxVM, type ProxmoxGuestStatus, type ProxmoxGuestConfig, type ProxmoxVersion, type ProxmoxResource } from './proxmox.js';
|
|
2
|
+
import { type SSHExecResult, type StreamCallback } from './ssh.js';
|
|
3
|
+
import type { ServerProfile } from '../config/types.js';
|
|
4
|
+
export interface ServerStatus {
|
|
5
|
+
/** Whether the Proxmox API is reachable */
|
|
6
|
+
apiConnected: boolean;
|
|
7
|
+
/** Whether SSH is connected */
|
|
8
|
+
sshConnected: boolean;
|
|
9
|
+
/** Proxmox version info (null if API unreachable) */
|
|
10
|
+
proxmoxVersion: ProxmoxVersion | null;
|
|
11
|
+
/** SSH hostname (null if SSH unreachable) */
|
|
12
|
+
sshHostname: string | null;
|
|
13
|
+
/** Active server profile alias */
|
|
14
|
+
serverAlias: string;
|
|
15
|
+
/** Base URL for the Proxmox API */
|
|
16
|
+
apiUrl: string;
|
|
17
|
+
/** Resolved node name */
|
|
18
|
+
node: string | null;
|
|
19
|
+
/** Error messages for failed connections */
|
|
20
|
+
errors: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare class ServerClient {
|
|
23
|
+
private readonly profile;
|
|
24
|
+
private readonly proxmox;
|
|
25
|
+
private readonly ssh;
|
|
26
|
+
private resolvedNode;
|
|
27
|
+
constructor(profile: ServerProfile);
|
|
28
|
+
/**
|
|
29
|
+
* Create a ServerClient from the active server profile in config.
|
|
30
|
+
* Throws if no active server is configured.
|
|
31
|
+
*/
|
|
32
|
+
static fromActiveProfile(): ServerClient;
|
|
33
|
+
/** Connect SSH (Proxmox API is stateless, no connect needed) */
|
|
34
|
+
connectSSH(): Promise<void>;
|
|
35
|
+
/** Disconnect SSH */
|
|
36
|
+
disconnectSSH(): void;
|
|
37
|
+
/** Test all connections and return status */
|
|
38
|
+
getStatus(): Promise<ServerStatus>;
|
|
39
|
+
/**
|
|
40
|
+
* Get the node name to use for API calls.
|
|
41
|
+
* Uses the profile's configured node, or auto-detects from the API.
|
|
42
|
+
*/
|
|
43
|
+
getNodeName(): Promise<string>;
|
|
44
|
+
/** List all nodes in the cluster */
|
|
45
|
+
listNodes(): Promise<ProxmoxNode[]>;
|
|
46
|
+
/** Get status of a specific node */
|
|
47
|
+
getNodeStatus(node?: string): Promise<ProxmoxNode>;
|
|
48
|
+
/** List all LXC containers on the active node */
|
|
49
|
+
listContainers(node?: string): Promise<ProxmoxContainer[]>;
|
|
50
|
+
/** Get status of an LXC container */
|
|
51
|
+
getContainerStatus(vmid: number, node?: string): Promise<ProxmoxGuestStatus>;
|
|
52
|
+
/** Get configuration of an LXC container */
|
|
53
|
+
getContainerConfig(vmid: number, node?: string): Promise<ProxmoxGuestConfig>;
|
|
54
|
+
/** Start an LXC container */
|
|
55
|
+
startContainer(vmid: number, node?: string): Promise<string>;
|
|
56
|
+
/** Stop an LXC container */
|
|
57
|
+
stopContainer(vmid: number, node?: string): Promise<string>;
|
|
58
|
+
/** Restart an LXC container */
|
|
59
|
+
restartContainer(vmid: number, node?: string): Promise<string>;
|
|
60
|
+
/** List all QEMU VMs on the active node */
|
|
61
|
+
listVMs(node?: string): Promise<ProxmoxVM[]>;
|
|
62
|
+
/** Get status of a QEMU VM */
|
|
63
|
+
getVMStatus(vmid: number, node?: string): Promise<ProxmoxGuestStatus>;
|
|
64
|
+
/** Get configuration of a QEMU VM */
|
|
65
|
+
getVMConfig(vmid: number, node?: string): Promise<ProxmoxGuestConfig>;
|
|
66
|
+
/** Start a QEMU VM */
|
|
67
|
+
startVM(vmid: number, node?: string): Promise<string>;
|
|
68
|
+
/** Stop a QEMU VM */
|
|
69
|
+
stopVM(vmid: number, node?: string): Promise<string>;
|
|
70
|
+
/** Restart a QEMU VM */
|
|
71
|
+
restartVM(vmid: number, node?: string): Promise<string>;
|
|
72
|
+
/** Get all resources across the cluster */
|
|
73
|
+
listResources(type?: string): Promise<ProxmoxResource[]>;
|
|
74
|
+
/** Execute a command on the Proxmox host via SSH (auto-reconnects) */
|
|
75
|
+
execOnHost(command: string): Promise<SSHExecResult>;
|
|
76
|
+
/** Execute a command on the Proxmox host with streaming output (auto-reconnects) */
|
|
77
|
+
execOnHostStream(command: string, onData: StreamCallback): Promise<number | null>;
|
|
78
|
+
/** Execute a command inside an LXC container via SSH + pct exec (auto-reconnects) */
|
|
79
|
+
execInContainer(vmid: number, command: string): Promise<SSHExecResult>;
|
|
80
|
+
/** Execute a command inside an LXC container with streaming output (auto-reconnects) */
|
|
81
|
+
execInContainerStream(vmid: number, command: string, onData: StreamCallback): Promise<number | null>;
|
|
82
|
+
/** Clean up all connections */
|
|
83
|
+
dispose(): void;
|
|
84
|
+
}
|
|
85
|
+
export { ProxmoxClient, ProxmoxApiError } from './proxmox.js';
|
|
86
|
+
export { SSHConnection, SSHConnectionError } from './ssh.js';
|
|
87
|
+
export type { ProxmoxNode, ProxmoxContainer, ProxmoxVM, ProxmoxGuestStatus, ProxmoxGuestConfig, ProxmoxVersion, ProxmoxResource, ProxmoxClientOptions, } from './proxmox.js';
|
|
88
|
+
export type { SSHClientOptions, SSHExecResult, StreamCallback } from './ssh.js';
|
|
89
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/server/client.ts"],"names":[],"mappings":"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"}
|