@involvex/super-agent-cli 0.0.88 → 0.0.91
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/dist/index.js +173 -84
- package/dist/super-agent-cli.exe +0 -0
- package/dist/super-agent.js +5 -1
- package/eslint.config.mjs +1 -1
- package/package.json +12 -10
- package/super-agent.js +5 -1
- package/vscode-extension/.vscodeignore +1 -1
- package/vscode-extension/assets/OIG2.DOaPIFEsckNdoFMZfTst.jpeg +0 -0
- package/vscode-extension/assets/OIG2.VAWPCioTg1WMPjh6hCKf.jpeg +0 -0
- package/vscode-extension/assets/OIG2.lB.rOYX.C99.N1x8iyfe.jpeg +0 -0
- package/vscode-extension/assets/OIG2.lUJOmexttYsbAVqCtOwM.jpeg +0 -0
- package/vscode-extension/assets/OIG3.emS4s05QfD4P1jTVi3Fe.jpeg +0 -0
- package/vscode-extension/assets/icon.PNG +0 -0
- package/vscode-extension/build.js +4 -4
- package/vscode-extension/dist/chat-provider.js +262 -0
- package/vscode-extension/dist/chat-provider.js.map +1 -0
- package/vscode-extension/dist/chat.css +268 -0
- package/vscode-extension/dist/chat.js +233 -0
- package/vscode-extension/dist/cli-connector.js +296 -0
- package/vscode-extension/dist/cli-connector.js.map +1 -0
- package/vscode-extension/dist/extension.js +156 -0
- package/vscode-extension/dist/extension.js.map +1 -0
- package/vscode-extension/dist/file-context.js +230 -0
- package/vscode-extension/dist/file-context.js.map +1 -0
- package/vscode-extension/dist/node_modules/ws/LICENSE +20 -0
- package/vscode-extension/dist/node_modules/ws/README.md +548 -0
- package/vscode-extension/dist/node_modules/ws/browser.js +8 -0
- package/vscode-extension/dist/node_modules/ws/index.js +13 -0
- package/vscode-extension/dist/node_modules/ws/lib/buffer-util.js +131 -0
- package/vscode-extension/dist/node_modules/ws/lib/constants.js +19 -0
- package/vscode-extension/dist/node_modules/ws/lib/event-target.js +292 -0
- package/vscode-extension/dist/node_modules/ws/lib/extension.js +203 -0
- package/vscode-extension/dist/node_modules/ws/lib/limiter.js +55 -0
- package/vscode-extension/dist/node_modules/ws/lib/permessage-deflate.js +528 -0
- package/vscode-extension/dist/node_modules/ws/lib/receiver.js +706 -0
- package/vscode-extension/dist/node_modules/ws/lib/sender.js +602 -0
- package/vscode-extension/dist/node_modules/ws/lib/stream.js +161 -0
- package/vscode-extension/dist/node_modules/ws/lib/subprotocol.js +62 -0
- package/vscode-extension/dist/node_modules/ws/lib/validation.js +152 -0
- package/vscode-extension/dist/node_modules/ws/lib/websocket-server.js +554 -0
- package/vscode-extension/dist/node_modules/ws/lib/websocket.js +1393 -0
- package/vscode-extension/dist/node_modules/ws/package.json +69 -0
- package/vscode-extension/dist/node_modules/ws/wrapper.mjs +8 -0
- package/vscode-extension/dist/super-agent-vscode-0.0.3.vsix +0 -0
- package/vscode-extension/icon.png +0 -0
- package/vscode-extension/icon.svg +11 -0
- package/vscode-extension/package.json +11 -11
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
// Chat webview script
|
|
2
|
+
// This runs in the browser context of the webview
|
|
3
|
+
const vscode = acquireVsCodeApi();
|
|
4
|
+
|
|
5
|
+
let messages = [];
|
|
6
|
+
let isConnected = false;
|
|
7
|
+
|
|
8
|
+
// Initialize
|
|
9
|
+
window.addEventListener("load", () => {
|
|
10
|
+
const promptInput = document.getElementById("prompt");
|
|
11
|
+
const sendButton = document.getElementById("send");
|
|
12
|
+
const abortButton = document.getElementById("abort");
|
|
13
|
+
const mentionButton = document.getElementById("mentionCurrent");
|
|
14
|
+
|
|
15
|
+
// Send message on Enter
|
|
16
|
+
if (promptInput) {
|
|
17
|
+
promptInput.addEventListener("keydown", e => {
|
|
18
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
sendMessage();
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (sendButton) {
|
|
26
|
+
sendButton.addEventListener("click", sendMessage);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (abortButton) {
|
|
30
|
+
abortButton.addEventListener("click", () => {
|
|
31
|
+
vscode.postMessage({ type: "abort" });
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (mentionButton) {
|
|
36
|
+
mentionButton.addEventListener("click", () => {
|
|
37
|
+
vscode.postMessage({ type: "getFileContext" });
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Request file context on load
|
|
42
|
+
vscode.postMessage({ type: "ready" });
|
|
43
|
+
vscode.postMessage({ type: "getFileContext" });
|
|
44
|
+
vscode.postMessage({ type: "requestHistory" });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Handle messages from extension
|
|
48
|
+
window.addEventListener("message", event => {
|
|
49
|
+
const message = event.data;
|
|
50
|
+
|
|
51
|
+
switch (message.type) {
|
|
52
|
+
case "messages":
|
|
53
|
+
messages = message.messages;
|
|
54
|
+
renderMessages();
|
|
55
|
+
break;
|
|
56
|
+
|
|
57
|
+
case "connectionStatus":
|
|
58
|
+
isConnected = message.connected;
|
|
59
|
+
updateConnectionStatus();
|
|
60
|
+
break;
|
|
61
|
+
|
|
62
|
+
case "fileContext":
|
|
63
|
+
updateFileContext(message.currentFile, message.openFiles);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
function sendMessage() {
|
|
69
|
+
const promptInput = document.getElementById("prompt");
|
|
70
|
+
const content = promptInput?.value.trim();
|
|
71
|
+
|
|
72
|
+
if (content) {
|
|
73
|
+
vscode.postMessage({ type: "sendMessage", content });
|
|
74
|
+
if (promptInput) {
|
|
75
|
+
promptInput.value = "";
|
|
76
|
+
}
|
|
77
|
+
showAbortButton();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function renderMessages() {
|
|
82
|
+
const messagesContainer = document.getElementById("messages");
|
|
83
|
+
if (!messagesContainer) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
messagesContainer.innerHTML = "";
|
|
88
|
+
|
|
89
|
+
for (const message of messages) {
|
|
90
|
+
const messageDiv = document.createElement("div");
|
|
91
|
+
messageDiv.className = `message ${message.role}`;
|
|
92
|
+
|
|
93
|
+
const contentDiv = document.createElement("div");
|
|
94
|
+
contentDiv.className = "content";
|
|
95
|
+
|
|
96
|
+
if (message.role === "user") {
|
|
97
|
+
contentDiv.textContent = message.content;
|
|
98
|
+
} else {
|
|
99
|
+
contentDiv.innerHTML = formatContent(message.content);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
messageDiv.appendChild(contentDiv);
|
|
103
|
+
|
|
104
|
+
// Add file contexts if present
|
|
105
|
+
if (message.fileContexts && message.fileContexts.length > 0) {
|
|
106
|
+
const filesDiv = document.createElement("div");
|
|
107
|
+
filesDiv.className = "file-contexts";
|
|
108
|
+
|
|
109
|
+
for (const fileCtx of message.fileContexts) {
|
|
110
|
+
const fileSpan = document.createElement("span");
|
|
111
|
+
fileSpan.className = "file-mention";
|
|
112
|
+
fileSpan.textContent = `@${fileCtx.relativePath}`;
|
|
113
|
+
filesDiv.appendChild(fileSpan);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
messageDiv.appendChild(filesDiv);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
messagesContainer.appendChild(messageDiv);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Scroll to bottom
|
|
123
|
+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function formatContent(content) {
|
|
127
|
+
// First escape everything to prevent XSS
|
|
128
|
+
let formatted = escapeHtml(content);
|
|
129
|
+
|
|
130
|
+
// Now apply formatting on the escaped content
|
|
131
|
+
// Code blocks
|
|
132
|
+
formatted = formatted.replace(
|
|
133
|
+
/```(\w+)?\n([\s\S]*?)```/g,
|
|
134
|
+
(match, lang, code) => {
|
|
135
|
+
return `<pre><code class="language-${lang || "text"}">${code.trim()}</code></pre>`;
|
|
136
|
+
},
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Inline code
|
|
140
|
+
formatted = formatted.replace(
|
|
141
|
+
/`([^`]+)`/g,
|
|
142
|
+
(match, code) => `<code>${code}</code>`,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Bold
|
|
146
|
+
formatted = formatted.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
|
|
147
|
+
|
|
148
|
+
// Italic
|
|
149
|
+
formatted = formatted.replace(/\*([^*]+)\*/g, "<em>$1</em>");
|
|
150
|
+
|
|
151
|
+
// Line breaks
|
|
152
|
+
formatted = formatted.replace(/\n/g, "<br>");
|
|
153
|
+
|
|
154
|
+
return formatted;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function escapeHtml(text) {
|
|
158
|
+
const div = document.createElement("div");
|
|
159
|
+
div.textContent = text;
|
|
160
|
+
return div.innerHTML;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function updateConnectionStatus() {
|
|
164
|
+
const statusElement = document.getElementById("status");
|
|
165
|
+
if (statusElement) {
|
|
166
|
+
statusElement.textContent = isConnected ? "Connected" : "Disconnected";
|
|
167
|
+
statusElement.className =
|
|
168
|
+
"status " + (isConnected ? "connected" : "disconnected");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function updateFileContext(currentFile, openFiles) {
|
|
173
|
+
const fileContextDiv = document.getElementById("fileContext");
|
|
174
|
+
if (!fileContextDiv) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
fileContextDiv.style.display = openFiles.length > 0 ? "block" : "none";
|
|
179
|
+
|
|
180
|
+
// Clear existing buttons
|
|
181
|
+
const existingButtons = fileContextDiv.querySelectorAll("button");
|
|
182
|
+
existingButtons.forEach(btn => btn.remove());
|
|
183
|
+
|
|
184
|
+
// Add button for current file
|
|
185
|
+
if (currentFile) {
|
|
186
|
+
const button = document.createElement("button");
|
|
187
|
+
button.textContent = `@ ${currentFile.relativePath}`;
|
|
188
|
+
button.onclick = () => {
|
|
189
|
+
const promptInput = document.getElementById("prompt");
|
|
190
|
+
if (promptInput) {
|
|
191
|
+
promptInput.value = `@${currentFile.relativePath} ${promptInput.value}`;
|
|
192
|
+
promptInput.focus();
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
fileContextDiv.appendChild(button);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Add buttons for open files (limit to 5)
|
|
199
|
+
for (const file of openFiles.slice(0, 5)) {
|
|
200
|
+
if (currentFile && file.relativePath === currentFile.relativePath) {
|
|
201
|
+
continue; // Skip current file
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const button = document.createElement("button");
|
|
205
|
+
button.textContent = `@ ${file.relativePath}`;
|
|
206
|
+
button.onclick = () => {
|
|
207
|
+
const promptInput = document.getElementById("prompt");
|
|
208
|
+
if (promptInput) {
|
|
209
|
+
promptInput.value = `@${file.relativePath} ${promptInput.value}`;
|
|
210
|
+
promptInput.focus();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
fileContextDiv.appendChild(button);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function showAbortButton() {
|
|
218
|
+
const abortButton = document.getElementById("abort");
|
|
219
|
+
const sendButton = document.getElementById("send");
|
|
220
|
+
|
|
221
|
+
if (abortButton && sendButton) {
|
|
222
|
+
abortButton.style.display = "inline-block";
|
|
223
|
+
sendButton.style.display = "none";
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Hide abort button after 30 seconds (timeout)
|
|
227
|
+
setTimeout(() => {
|
|
228
|
+
if (abortButton && sendButton) {
|
|
229
|
+
abortButton.style.display = "none";
|
|
230
|
+
sendButton.style.display = "inline-block";
|
|
231
|
+
}
|
|
232
|
+
}, 30000);
|
|
233
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CLIConnector = void 0;
|
|
37
|
+
const vscode = __importStar(require("vscode"));
|
|
38
|
+
const ws_1 = require("ws");
|
|
39
|
+
class CLIConnector {
|
|
40
|
+
context;
|
|
41
|
+
ws = null;
|
|
42
|
+
isConnected = false;
|
|
43
|
+
reconnectTimer = null;
|
|
44
|
+
messageHandlers = new Map();
|
|
45
|
+
statusChangeHandlers = [];
|
|
46
|
+
hasShownConnectionError = false; // Track if we've shown the error
|
|
47
|
+
reconnectAttempts = 0;
|
|
48
|
+
maxReconnectAttempts = 10; // Stop trying after N attempts
|
|
49
|
+
constructor(context) {
|
|
50
|
+
this.context = context;
|
|
51
|
+
this.loadSettings();
|
|
52
|
+
}
|
|
53
|
+
loadSettings() {
|
|
54
|
+
const config = vscode.workspace.getConfiguration("superAgent");
|
|
55
|
+
return {
|
|
56
|
+
cliPort: config.get("cliPort", 3000),
|
|
57
|
+
cliHost: config.get("cliHost", "localhost"),
|
|
58
|
+
autoConnect: config.get("autoConnect", true),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async connect() {
|
|
62
|
+
const settings = this.loadSettings();
|
|
63
|
+
const wsUrl = `ws://${settings.cliHost}:${settings.cliPort}`;
|
|
64
|
+
console.log(`[Super Agent] Attempting to connect to ${wsUrl}...`);
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
try {
|
|
67
|
+
if (this.ws) {
|
|
68
|
+
this.ws.terminate();
|
|
69
|
+
}
|
|
70
|
+
this.ws = new ws_1.WebSocket(wsUrl);
|
|
71
|
+
const connectionTimeout = setTimeout(() => {
|
|
72
|
+
if (!this.isConnected) {
|
|
73
|
+
this.ws?.terminate();
|
|
74
|
+
reject(new Error("Connection timed out"));
|
|
75
|
+
}
|
|
76
|
+
}, 5000);
|
|
77
|
+
this.ws.on("open", () => {
|
|
78
|
+
clearTimeout(connectionTimeout);
|
|
79
|
+
console.log(`[Super Agent] Successfully connected to CLI at ${wsUrl}`);
|
|
80
|
+
this.isConnected = true;
|
|
81
|
+
this.reconnectAttempts = 0;
|
|
82
|
+
this.hasShownConnectionError = false;
|
|
83
|
+
this.notifyStatusChange(true);
|
|
84
|
+
this.clearReconnectTimer();
|
|
85
|
+
resolve(true);
|
|
86
|
+
});
|
|
87
|
+
this.ws.on("error", error => {
|
|
88
|
+
clearTimeout(connectionTimeout);
|
|
89
|
+
console.error(`[Super Agent] WebSocket error:`, error);
|
|
90
|
+
this.isConnected = false;
|
|
91
|
+
this.notifyStatusChange(false);
|
|
92
|
+
if (this.reconnectAttempts === 0 && !this.hasShownConnectionError) {
|
|
93
|
+
this.showConnectionError();
|
|
94
|
+
this.hasShownConnectionError = true;
|
|
95
|
+
}
|
|
96
|
+
this.scheduleReconnect();
|
|
97
|
+
reject(error);
|
|
98
|
+
});
|
|
99
|
+
this.ws.on("close", (code, reason) => {
|
|
100
|
+
console.log(`[Super Agent] Connection closed: ${code} ${reason}`);
|
|
101
|
+
this.isConnected = false;
|
|
102
|
+
this.notifyStatusChange(false);
|
|
103
|
+
if (code !== 1000) {
|
|
104
|
+
this.scheduleReconnect();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
this.ws.on("message", data => {
|
|
108
|
+
try {
|
|
109
|
+
const message = JSON.parse(data.toString());
|
|
110
|
+
console.log(`[Super Agent] Received message: ${message.type}`);
|
|
111
|
+
this.handleMessage(message);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.error("Failed to parse CLI message:", error);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
this.isConnected = false;
|
|
120
|
+
this.notifyStatusChange(false);
|
|
121
|
+
reject(error);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
disconnect() {
|
|
126
|
+
this.clearReconnectTimer();
|
|
127
|
+
this.reconnectAttempts = this.maxReconnectAttempts;
|
|
128
|
+
if (this.ws) {
|
|
129
|
+
this.ws.close(1000, "Normal closure");
|
|
130
|
+
this.ws = null;
|
|
131
|
+
}
|
|
132
|
+
this.isConnected = false;
|
|
133
|
+
this.notifyStatusChange(false);
|
|
134
|
+
}
|
|
135
|
+
async startCLIServer() {
|
|
136
|
+
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
|
|
137
|
+
const terminal = vscode.window.createTerminal({
|
|
138
|
+
name: "Super Agent CLI",
|
|
139
|
+
cwd: workspaceRoot,
|
|
140
|
+
});
|
|
141
|
+
terminal.show();
|
|
142
|
+
// Explicitly use PowerShell on Windows to ensure our script works
|
|
143
|
+
if (process.platform === "win32") {
|
|
144
|
+
terminal.sendText("powershell -ExecutionPolicy Bypass -Command \"if (Test-Path 'super-agent.js') { bun super-agent.js web } else { super-agent web }\"");
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
terminal.sendText("if [ -f super-agent.js ]; then bun super-agent.js web; else super-agent web; fi");
|
|
148
|
+
}
|
|
149
|
+
// Give it more time to start up
|
|
150
|
+
await vscode.window.withProgress({
|
|
151
|
+
location: vscode.ProgressLocation.Notification,
|
|
152
|
+
title: "Starting Super Agent CLI Server...",
|
|
153
|
+
cancellable: false,
|
|
154
|
+
}, async (progress) => {
|
|
155
|
+
for (let i = 0; i < 5; i++) {
|
|
156
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
157
|
+
progress.report({ increment: 20 });
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
this.resetConnectionState();
|
|
161
|
+
try {
|
|
162
|
+
await this.connect();
|
|
163
|
+
vscode.window.showInformationMessage("✓ Connected to Super Agent CLI");
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
const settings = this.loadSettings();
|
|
167
|
+
console.error(`Failed to connect to ${settings.cliHost}:${settings.cliPort} after starting server:`, e);
|
|
168
|
+
vscode.window.showErrorMessage(`Failed to connect to CLI at ${settings.cliHost}:${settings.cliPort}. Please check the terminal for errors.`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async showConnectionError() {
|
|
172
|
+
const selection = await vscode.window.showWarningMessage("Could not connect to Super Agent CLI.", "Start CLI Server", "Retry");
|
|
173
|
+
if (selection === "Start CLI Server") {
|
|
174
|
+
this.startCLIServer();
|
|
175
|
+
}
|
|
176
|
+
else if (selection === "Retry") {
|
|
177
|
+
this.connect();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
scheduleReconnect() {
|
|
181
|
+
this.clearReconnectTimer();
|
|
182
|
+
// Stop reconnecting after max attempts
|
|
183
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
184
|
+
console.log("Max reconnect attempts reached. Stopping auto-reconnect.");
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
this.reconnectAttempts++;
|
|
188
|
+
const settings = this.loadSettings();
|
|
189
|
+
if (settings.autoConnect) {
|
|
190
|
+
// Exponential backoff: 5s, 10s, 20s, 40s, max 60s
|
|
191
|
+
const delay = Math.min(5000 * Math.pow(2, this.reconnectAttempts - 1), 60000);
|
|
192
|
+
this.reconnectTimer = setTimeout(() => {
|
|
193
|
+
this.connect().catch(() => {
|
|
194
|
+
// Silently fail on reconnect
|
|
195
|
+
});
|
|
196
|
+
}, delay);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
clearReconnectTimer() {
|
|
200
|
+
if (this.reconnectTimer) {
|
|
201
|
+
clearTimeout(this.reconnectTimer);
|
|
202
|
+
this.reconnectTimer = null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
sendMessage(type, content) {
|
|
206
|
+
if (this.ws && this.isConnected && this.ws.readyState === ws_1.WebSocket.OPEN) {
|
|
207
|
+
const message = { type, content };
|
|
208
|
+
this.ws.send(JSON.stringify(message));
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
// Only show message if user explicitly tries to send
|
|
212
|
+
if (type === "chat_message" || type === "command") {
|
|
213
|
+
vscode.window.showWarningMessage("Not connected to Super Agent CLI. Please run 'super-agent web' in your project directory.");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
onMessage(type, handler) {
|
|
218
|
+
this.messageHandlers.set(type, handler);
|
|
219
|
+
return () => this.messageHandlers.delete(type);
|
|
220
|
+
}
|
|
221
|
+
handleMessage(message) {
|
|
222
|
+
const handler = this.messageHandlers.get(message.type);
|
|
223
|
+
if (handler) {
|
|
224
|
+
handler(message);
|
|
225
|
+
}
|
|
226
|
+
// Also handle wildcard handlers
|
|
227
|
+
const wildcardHandler = this.messageHandlers.get("*");
|
|
228
|
+
if (wildcardHandler) {
|
|
229
|
+
wildcardHandler(message);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
onStatusChange(handler) {
|
|
233
|
+
this.statusChangeHandlers.push(handler);
|
|
234
|
+
return () => {
|
|
235
|
+
const index = this.statusChangeHandlers.indexOf(handler);
|
|
236
|
+
if (index > -1) {
|
|
237
|
+
this.statusChangeHandlers.splice(index, 1);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
notifyStatusChange(connected) {
|
|
242
|
+
for (const handler of this.statusChangeHandlers) {
|
|
243
|
+
handler(connected);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
getConnectionStatus() {
|
|
247
|
+
return this.isConnected;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Reset connection state (call this when user manually triggers connection)
|
|
251
|
+
*/
|
|
252
|
+
resetConnectionState() {
|
|
253
|
+
this.reconnectAttempts = 0;
|
|
254
|
+
this.hasShownConnectionError = false;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Request file tree from CLI
|
|
258
|
+
*/
|
|
259
|
+
requestFileTree() {
|
|
260
|
+
this.sendMessage("get_file_tree");
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Request chat history from CLI
|
|
264
|
+
*/
|
|
265
|
+
requestChatHistory() {
|
|
266
|
+
this.sendMessage("get_chat_history");
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Send a message to the CLI
|
|
270
|
+
*/
|
|
271
|
+
sendChatMessage(message, fileContexts) {
|
|
272
|
+
// CLI expects 'prompt' type and string content
|
|
273
|
+
this.sendMessage("prompt", message);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Request file content from CLI
|
|
277
|
+
*/
|
|
278
|
+
requestFileContent(filePath) {
|
|
279
|
+
// CLI expects 'path' parameter
|
|
280
|
+
this.sendMessage("get_file_content", { path: filePath });
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Send a command to the CLI
|
|
284
|
+
*/
|
|
285
|
+
sendCommand(command) {
|
|
286
|
+
this.sendMessage("command", { command });
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Abort current operation in CLI
|
|
290
|
+
*/
|
|
291
|
+
abortOperation() {
|
|
292
|
+
this.sendMessage("abort");
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
exports.CLIConnector = CLIConnector;
|
|
296
|
+
//# sourceMappingURL=cli-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-connector.js","sourceRoot":"","sources":["../src/cli-connector.ts"],"names":[],"mappings":"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"}
|