claude-ide-bridge 1.1.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/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/activityLog.d.ts +26 -0
- package/dist/activityLog.js +76 -0
- package/dist/activityLog.js.map +1 -0
- package/dist/bridge.d.ts +19 -0
- package/dist/bridge.js +277 -0
- package/dist/bridge.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.js +221 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/extensionClient.d.ts +193 -0
- package/dist/extensionClient.js +698 -0
- package/dist/extensionClient.js.map +1 -0
- package/dist/fileLock.d.ts +12 -0
- package/dist/fileLock.js +30 -0
- package/dist/fileLock.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/lockfile.d.ts +12 -0
- package/dist/lockfile.js +127 -0
- package/dist/lockfile.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +68 -0
- package/dist/logger.js.map +1 -0
- package/dist/probe.d.ts +22 -0
- package/dist/probe.js +45 -0
- package/dist/probe.js.map +1 -0
- package/dist/server.d.ts +25 -0
- package/dist/server.js +265 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/activityLog.d.ts +39 -0
- package/dist/tools/activityLog.js +49 -0
- package/dist/tools/activityLog.js.map +1 -0
- package/dist/tools/aiComments.d.ts +26 -0
- package/dist/tools/aiComments.js +196 -0
- package/dist/tools/aiComments.js.map +1 -0
- package/dist/tools/bridgeStatus.d.ts +21 -0
- package/dist/tools/bridgeStatus.js +41 -0
- package/dist/tools/bridgeStatus.js.map +1 -0
- package/dist/tools/checkDocumentDirty.d.ts +28 -0
- package/dist/tools/checkDocumentDirty.js +61 -0
- package/dist/tools/checkDocumentDirty.js.map +1 -0
- package/dist/tools/clipboard.d.ts +50 -0
- package/dist/tools/clipboard.js +82 -0
- package/dist/tools/clipboard.js.map +1 -0
- package/dist/tools/closeTabs.d.ts +49 -0
- package/dist/tools/closeTabs.js +77 -0
- package/dist/tools/closeTabs.js.map +1 -0
- package/dist/tools/debug.d.ts +154 -0
- package/dist/tools/debug.js +248 -0
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/decorations.d.ts +92 -0
- package/dist/tools/decorations.js +150 -0
- package/dist/tools/decorations.js.map +1 -0
- package/dist/tools/diffDebugger.d.ts +62 -0
- package/dist/tools/diffDebugger.js +245 -0
- package/dist/tools/diffDebugger.js.map +1 -0
- package/dist/tools/editText.d.ts +80 -0
- package/dist/tools/editText.js +274 -0
- package/dist/tools/editText.js.map +1 -0
- package/dist/tools/fileOperations.d.ts +111 -0
- package/dist/tools/fileOperations.js +280 -0
- package/dist/tools/fileOperations.js.map +1 -0
- package/dist/tools/fileWatcher.d.ts +54 -0
- package/dist/tools/fileWatcher.js +100 -0
- package/dist/tools/fileWatcher.js.map +1 -0
- package/dist/tools/findFiles.d.ts +31 -0
- package/dist/tools/findFiles.js +119 -0
- package/dist/tools/findFiles.js.map +1 -0
- package/dist/tools/fixAllLintErrors.d.ts +29 -0
- package/dist/tools/fixAllLintErrors.js +114 -0
- package/dist/tools/fixAllLintErrors.js.map +1 -0
- package/dist/tools/flowGuardian.d.ts +61 -0
- package/dist/tools/flowGuardian.js +311 -0
- package/dist/tools/flowGuardian.js.map +1 -0
- package/dist/tools/formatDocument.d.ts +30 -0
- package/dist/tools/formatDocument.js +132 -0
- package/dist/tools/formatDocument.js.map +1 -0
- package/dist/tools/formatFile.d.ts +28 -0
- package/dist/tools/formatFile.js +110 -0
- package/dist/tools/formatFile.js.map +1 -0
- package/dist/tools/getBufferContent.d.ts +38 -0
- package/dist/tools/getBufferContent.js +100 -0
- package/dist/tools/getBufferContent.js.map +1 -0
- package/dist/tools/getCurrentSelection.d.ts +43 -0
- package/dist/tools/getCurrentSelection.js +75 -0
- package/dist/tools/getCurrentSelection.js.map +1 -0
- package/dist/tools/getDiagnostics.d.ts +38 -0
- package/dist/tools/getDiagnostics.js +204 -0
- package/dist/tools/getDiagnostics.js.map +1 -0
- package/dist/tools/getDocumentSymbols.d.ts +27 -0
- package/dist/tools/getDocumentSymbols.js +133 -0
- package/dist/tools/getDocumentSymbols.js.map +1 -0
- package/dist/tools/getFileTree.d.ts +36 -0
- package/dist/tools/getFileTree.js +111 -0
- package/dist/tools/getFileTree.js.map +1 -0
- package/dist/tools/getGitDiff.d.ts +34 -0
- package/dist/tools/getGitDiff.js +57 -0
- package/dist/tools/getGitDiff.js.map +1 -0
- package/dist/tools/getGitLog.d.ts +30 -0
- package/dist/tools/getGitLog.js +65 -0
- package/dist/tools/getGitLog.js.map +1 -0
- package/dist/tools/getGitStatus.d.ts +26 -0
- package/dist/tools/getGitStatus.js +95 -0
- package/dist/tools/getGitStatus.js.map +1 -0
- package/dist/tools/getOpenEditors.d.ts +21 -0
- package/dist/tools/getOpenEditors.js +84 -0
- package/dist/tools/getOpenEditors.js.map +1 -0
- package/dist/tools/getProjectInfo.d.ts +20 -0
- package/dist/tools/getProjectInfo.js +315 -0
- package/dist/tools/getProjectInfo.js.map +1 -0
- package/dist/tools/getToolCapabilities.d.ts +23 -0
- package/dist/tools/getToolCapabilities.js +249 -0
- package/dist/tools/getToolCapabilities.js.map +1 -0
- package/dist/tools/getWorkspaceFolders.d.ts +21 -0
- package/dist/tools/getWorkspaceFolders.js +47 -0
- package/dist/tools/getWorkspaceFolders.js.map +1 -0
- package/dist/tools/gitHistory.d.ts +78 -0
- package/dist/tools/gitHistory.js +151 -0
- package/dist/tools/gitHistory.js.map +1 -0
- package/dist/tools/gitWrite.d.ts +335 -0
- package/dist/tools/gitWrite.js +859 -0
- package/dist/tools/gitWrite.js.map +1 -0
- package/dist/tools/github/actions.d.ts +67 -0
- package/dist/tools/github/actions.js +155 -0
- package/dist/tools/github/actions.js.map +1 -0
- package/dist/tools/github/index.d.ts +4 -0
- package/dist/tools/github/index.js +5 -0
- package/dist/tools/github/index.js.map +1 -0
- package/dist/tools/github/issues.d.ts +140 -0
- package/dist/tools/github/issues.js +279 -0
- package/dist/tools/github/issues.js.map +1 -0
- package/dist/tools/github/pr.d.ts +101 -0
- package/dist/tools/github/pr.js +215 -0
- package/dist/tools/github/pr.js.map +1 -0
- package/dist/tools/github/review.d.ts +101 -0
- package/dist/tools/github/review.js +292 -0
- package/dist/tools/github/review.js.map +1 -0
- package/dist/tools/github/shared.d.ts +4 -0
- package/dist/tools/github/shared.js +12 -0
- package/dist/tools/github/shared.js.map +1 -0
- package/dist/tools/github.d.ts +308 -0
- package/dist/tools/github.js +656 -0
- package/dist/tools/github.js.map +1 -0
- package/dist/tools/hoverAtCursor.d.ts +22 -0
- package/dist/tools/hoverAtCursor.js +51 -0
- package/dist/tools/hoverAtCursor.js.map +1 -0
- package/dist/tools/httpClient.d.ts +83 -0
- package/dist/tools/httpClient.js +335 -0
- package/dist/tools/httpClient.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.js +246 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/inlayHints.d.ts +38 -0
- package/dist/tools/inlayHints.js +56 -0
- package/dist/tools/inlayHints.js.map +1 -0
- package/dist/tools/linters/biome.d.ts +2 -0
- package/dist/tools/linters/biome.js +44 -0
- package/dist/tools/linters/biome.js.map +1 -0
- package/dist/tools/linters/cargo.d.ts +2 -0
- package/dist/tools/linters/cargo.js +45 -0
- package/dist/tools/linters/cargo.js.map +1 -0
- package/dist/tools/linters/eslint.d.ts +2 -0
- package/dist/tools/linters/eslint.js +59 -0
- package/dist/tools/linters/eslint.js.map +1 -0
- package/dist/tools/linters/govet.d.ts +2 -0
- package/dist/tools/linters/govet.js +37 -0
- package/dist/tools/linters/govet.js.map +1 -0
- package/dist/tools/linters/pyright.d.ts +2 -0
- package/dist/tools/linters/pyright.js +34 -0
- package/dist/tools/linters/pyright.js.map +1 -0
- package/dist/tools/linters/ruff.d.ts +2 -0
- package/dist/tools/linters/ruff.js +30 -0
- package/dist/tools/linters/ruff.js.map +1 -0
- package/dist/tools/linters/types.d.ts +16 -0
- package/dist/tools/linters/types.js +2 -0
- package/dist/tools/linters/types.js.map +1 -0
- package/dist/tools/linters/typescript.d.ts +2 -0
- package/dist/tools/linters/typescript.js +38 -0
- package/dist/tools/linters/typescript.js.map +1 -0
- package/dist/tools/lsp.d.ts +310 -0
- package/dist/tools/lsp.js +684 -0
- package/dist/tools/lsp.js.map +1 -0
- package/dist/tools/notebook.d.ts +95 -0
- package/dist/tools/notebook.js +144 -0
- package/dist/tools/notebook.js.map +1 -0
- package/dist/tools/openDiff.d.ts +41 -0
- package/dist/tools/openDiff.js +116 -0
- package/dist/tools/openDiff.js.map +1 -0
- package/dist/tools/openFile.d.ts +34 -0
- package/dist/tools/openFile.js +102 -0
- package/dist/tools/openFile.js.map +1 -0
- package/dist/tools/organizeImports.d.ts +29 -0
- package/dist/tools/organizeImports.js +64 -0
- package/dist/tools/organizeImports.js.map +1 -0
- package/dist/tools/planPersistence.d.ts +196 -0
- package/dist/tools/planPersistence.js +437 -0
- package/dist/tools/planPersistence.js.map +1 -0
- package/dist/tools/replaceBlock.d.ts +40 -0
- package/dist/tools/replaceBlock.js +105 -0
- package/dist/tools/replaceBlock.js.map +1 -0
- package/dist/tools/runCommand.d.ts +43 -0
- package/dist/tools/runCommand.js +141 -0
- package/dist/tools/runCommand.js.map +1 -0
- package/dist/tools/runTests.d.ts +32 -0
- package/dist/tools/runTests.js +160 -0
- package/dist/tools/runTests.js.map +1 -0
- package/dist/tools/saveDocument.d.ts +28 -0
- package/dist/tools/saveDocument.js +58 -0
- package/dist/tools/saveDocument.js.map +1 -0
- package/dist/tools/searchAndReplace.d.ts +50 -0
- package/dist/tools/searchAndReplace.js +203 -0
- package/dist/tools/searchAndReplace.js.map +1 -0
- package/dist/tools/searchWorkspace.d.ts +52 -0
- package/dist/tools/searchWorkspace.js +159 -0
- package/dist/tools/searchWorkspace.js.map +1 -0
- package/dist/tools/setActiveWorkspaceFolder.d.ts +28 -0
- package/dist/tools/setActiveWorkspaceFolder.js +32 -0
- package/dist/tools/setActiveWorkspaceFolder.js.map +1 -0
- package/dist/tools/tasks.d.ts +56 -0
- package/dist/tools/tasks.js +89 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/terminal.d.ts +241 -0
- package/dist/tools/terminal.js +539 -0
- package/dist/tools/terminal.js.map +1 -0
- package/dist/tools/testRunners/cargoTest.d.ts +2 -0
- package/dist/tools/testRunners/cargoTest.js +123 -0
- package/dist/tools/testRunners/cargoTest.js.map +1 -0
- package/dist/tools/testRunners/goTest.d.ts +2 -0
- package/dist/tools/testRunners/goTest.js +106 -0
- package/dist/tools/testRunners/goTest.js.map +1 -0
- package/dist/tools/testRunners/pytest.d.ts +2 -0
- package/dist/tools/testRunners/pytest.js +133 -0
- package/dist/tools/testRunners/pytest.js.map +1 -0
- package/dist/tools/testRunners/types.d.ts +18 -0
- package/dist/tools/testRunners/types.js +2 -0
- package/dist/tools/testRunners/types.js.map +1 -0
- package/dist/tools/testRunners/vitestJest.d.ts +3 -0
- package/dist/tools/testRunners/vitestJest.js +178 -0
- package/dist/tools/testRunners/vitestJest.js.map +1 -0
- package/dist/tools/typeHierarchy.d.ts +45 -0
- package/dist/tools/typeHierarchy.js +65 -0
- package/dist/tools/typeHierarchy.js.map +1 -0
- package/dist/tools/utils.d.ts +54 -0
- package/dist/tools/utils.js +267 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/vscodeCommands.d.ts +59 -0
- package/dist/tools/vscodeCommands.js +108 -0
- package/dist/tools/vscodeCommands.js.map +1 -0
- package/dist/tools/watchDiagnostics.d.ts +32 -0
- package/dist/tools/watchDiagnostics.js +87 -0
- package/dist/tools/watchDiagnostics.js.map +1 -0
- package/dist/tools/workspaceSettings.d.ts +67 -0
- package/dist/tools/workspaceSettings.js +102 -0
- package/dist/tools/workspaceSettings.js.map +1 -0
- package/dist/tools/workspaceSnapshots.d.ts +174 -0
- package/dist/tools/workspaceSnapshots.js +474 -0
- package/dist/tools/workspaceSnapshots.js.map +1 -0
- package/dist/transport.d.ts +57 -0
- package/dist/transport.js +417 -0
- package/dist/transport.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/wsUtils.d.ts +9 -0
- package/dist/wsUtils.js +54 -0
- package/dist/wsUtils.js.map +1 -0
- package/package.json +69 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { EventEmitter } from "node:events";
|
|
3
|
+
import http from "node:http";
|
|
4
|
+
import { WebSocket, WebSocketServer as WsServer } from "ws";
|
|
5
|
+
const ALLOWED_HOSTS = new Set(["localhost", "127.0.0.1"]);
|
|
6
|
+
function enableTcpKeepalive(ws) {
|
|
7
|
+
const rawSocket = ws
|
|
8
|
+
._socket;
|
|
9
|
+
if (rawSocket?.setKeepAlive) {
|
|
10
|
+
rawSocket.setKeepAlive(true, 60_000); // 60s TCP keepalive as defense-in-depth
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function timingSafeTokenCompare(a, b) {
|
|
14
|
+
const bA = Buffer.from(a);
|
|
15
|
+
const bB = Buffer.from(b);
|
|
16
|
+
const len = Math.max(bA.length, bB.length);
|
|
17
|
+
const padA = Buffer.alloc(len);
|
|
18
|
+
const padB = Buffer.alloc(len);
|
|
19
|
+
bA.copy(padA);
|
|
20
|
+
bB.copy(padB);
|
|
21
|
+
return crypto.timingSafeEqual(padA, padB) && bA.length === bB.length;
|
|
22
|
+
}
|
|
23
|
+
function setupPongHandler(ws) {
|
|
24
|
+
ws.on("pong", (data) => {
|
|
25
|
+
ws.isAlive = true;
|
|
26
|
+
ws.missedPongs = 0;
|
|
27
|
+
const sentAt = Number.parseInt(data.toString(), 10);
|
|
28
|
+
ws.lastPongTime = Number.isNaN(sentAt) ? Date.now() : sentAt;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const MIN_CONNECTION_INTERVAL_MS = 50; // Allow multiple agents to connect within same second
|
|
32
|
+
export class Server extends EventEmitter {
|
|
33
|
+
authToken;
|
|
34
|
+
logger;
|
|
35
|
+
httpServer;
|
|
36
|
+
wss;
|
|
37
|
+
pingInterval = null;
|
|
38
|
+
lastClaudeConnectionTime = 0;
|
|
39
|
+
lastExtensionConnectionTime = 0;
|
|
40
|
+
startTime = Date.now();
|
|
41
|
+
/** Set by bridge to provide health data */
|
|
42
|
+
healthDataFn = null;
|
|
43
|
+
/** Set by bridge to provide Prometheus metrics */
|
|
44
|
+
metricsFn = null;
|
|
45
|
+
constructor(authToken, logger) {
|
|
46
|
+
super();
|
|
47
|
+
this.authToken = authToken;
|
|
48
|
+
this.logger = logger;
|
|
49
|
+
this.httpServer = http.createServer((req, res) => {
|
|
50
|
+
if (req.url === "/metrics" && req.method === "GET") {
|
|
51
|
+
try {
|
|
52
|
+
const body = this.metricsFn?.() ?? "";
|
|
53
|
+
res.writeHead(200, {
|
|
54
|
+
"Content-Type": "text/plain; version=0.0.4; charset=utf-8",
|
|
55
|
+
});
|
|
56
|
+
res.end(body);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
60
|
+
res.end(JSON.stringify({
|
|
61
|
+
error: err instanceof Error ? err.message : String(err),
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (req.url === "/health" && req.method === "GET") {
|
|
67
|
+
try {
|
|
68
|
+
const data = {
|
|
69
|
+
status: "ok",
|
|
70
|
+
uptimeMs: Date.now() - this.startTime,
|
|
71
|
+
connections: this.wss.clients.size,
|
|
72
|
+
...(this.healthDataFn?.() ?? {}),
|
|
73
|
+
};
|
|
74
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
75
|
+
res.end(JSON.stringify(data));
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
79
|
+
res.end(JSON.stringify({
|
|
80
|
+
error: err instanceof Error ? err.message : String(err),
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
86
|
+
res.end("Not found");
|
|
87
|
+
});
|
|
88
|
+
// Do NOT pass server — we handle upgrade manually for pre-handshake auth
|
|
89
|
+
this.wss = new WsServer({
|
|
90
|
+
noServer: true,
|
|
91
|
+
maxPayload: 4 * 1024 * 1024,
|
|
92
|
+
perMessageDeflate: false,
|
|
93
|
+
});
|
|
94
|
+
// Authenticate on upgrade BEFORE completing the WebSocket handshake
|
|
95
|
+
this.httpServer.on("upgrade", (request, socket, head) => {
|
|
96
|
+
// Prevent unhandled error events on the raw socket during upgrade
|
|
97
|
+
socket.on("error", () => socket.destroy());
|
|
98
|
+
// Validate Host header to defend against DNS rebinding
|
|
99
|
+
const host = request.headers.host?.replace(/:\d+$/, "");
|
|
100
|
+
if (!host || !ALLOWED_HOSTS.has(host)) {
|
|
101
|
+
this.logger.warn(`Rejected connection with invalid Host header: ${host}`);
|
|
102
|
+
socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
|
|
103
|
+
socket.destroy();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
// Check for extension connection (distinct header)
|
|
108
|
+
const extensionToken = request.headers["x-claude-ide-extension"];
|
|
109
|
+
if (typeof extensionToken === "string" &&
|
|
110
|
+
timingSafeTokenCompare(extensionToken, this.authToken)) {
|
|
111
|
+
// Rate limit per client type to prevent connection-storm DoS
|
|
112
|
+
if (now - this.lastExtensionConnectionTime <
|
|
113
|
+
MIN_CONNECTION_INTERVAL_MS) {
|
|
114
|
+
socket.write("HTTP/1.1 429 Too Many Requests\r\n\r\n");
|
|
115
|
+
socket.destroy();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.lastExtensionConnectionTime = now;
|
|
119
|
+
this.wss.handleUpgrade(request, socket, head, (ws) => {
|
|
120
|
+
const alive = ws;
|
|
121
|
+
alive.isAlive = true;
|
|
122
|
+
alive.missedPongs = 0;
|
|
123
|
+
alive.lastPongTime = Date.now();
|
|
124
|
+
enableTcpKeepalive(ws);
|
|
125
|
+
setupPongHandler(alive);
|
|
126
|
+
this.emit("extension", ws);
|
|
127
|
+
ws.once("close", () => {
|
|
128
|
+
this.lastExtensionConnectionTime = 0;
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Check for Claude Code connection
|
|
134
|
+
const token = request.headers["x-claude-code-ide-authorization"];
|
|
135
|
+
if (typeof token !== "string" ||
|
|
136
|
+
!timingSafeTokenCompare(token, this.authToken)) {
|
|
137
|
+
this.logger.warn("Rejected unauthorized WebSocket upgrade");
|
|
138
|
+
socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
|
|
139
|
+
socket.destroy();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
// Rate limit per client type to prevent connection-storm DoS
|
|
143
|
+
if (now - this.lastClaudeConnectionTime < MIN_CONNECTION_INTERVAL_MS) {
|
|
144
|
+
socket.write("HTTP/1.1 429 Too Many Requests\r\n\r\n");
|
|
145
|
+
socket.destroy();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
this.lastClaudeConnectionTime = now;
|
|
149
|
+
this.wss.handleUpgrade(request, socket, head, (ws) => {
|
|
150
|
+
this.wss.emit("connection", ws, request);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
this.wss.on("connection", (raw) => {
|
|
154
|
+
const ws = raw;
|
|
155
|
+
this.logger.info("Claude Code connected");
|
|
156
|
+
ws.isAlive = true;
|
|
157
|
+
ws.missedPongs = 0;
|
|
158
|
+
ws.lastPongTime = Date.now();
|
|
159
|
+
enableTcpKeepalive(raw);
|
|
160
|
+
setupPongHandler(ws);
|
|
161
|
+
ws.on("error", (err) => {
|
|
162
|
+
this.logger.error(`WebSocket client error: ${err.message}`);
|
|
163
|
+
});
|
|
164
|
+
this.emit("connection", ws);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
async listen(port, bindAddress = "127.0.0.1") {
|
|
168
|
+
return new Promise((resolve, reject) => {
|
|
169
|
+
this.httpServer
|
|
170
|
+
.listen(port, bindAddress, () => {
|
|
171
|
+
const addr = this.httpServer.address();
|
|
172
|
+
if (!addr || typeof addr === "string") {
|
|
173
|
+
if (this.pingInterval) {
|
|
174
|
+
clearInterval(this.pingInterval);
|
|
175
|
+
this.pingInterval = null;
|
|
176
|
+
}
|
|
177
|
+
reject(new Error("Unexpected server address"));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// Ping clients every 30s; terminate after 3 missed pongs (90s tolerance)
|
|
181
|
+
this.pingInterval = setInterval(() => {
|
|
182
|
+
const now = Date.now();
|
|
183
|
+
for (const raw of this.wss.clients) {
|
|
184
|
+
const client = raw;
|
|
185
|
+
// Sleep/wake detection: if timer fired much later than expected,
|
|
186
|
+
// the system likely slept. Reset and probe instead of killing.
|
|
187
|
+
if (client.lastPingTime && now - client.lastPingTime > 45_000) {
|
|
188
|
+
client.missedPongs = 0;
|
|
189
|
+
client.isAlive = false;
|
|
190
|
+
client.lastPingTime = now;
|
|
191
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
192
|
+
client.ping(Buffer.from(now.toString()));
|
|
193
|
+
}
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (!client.isAlive) {
|
|
197
|
+
client.missedPongs = (client.missedPongs ?? 0) + 1;
|
|
198
|
+
if (client.missedPongs >= 3) {
|
|
199
|
+
this.logger.warn("Terminating unresponsive client (3 missed pongs)");
|
|
200
|
+
client.terminate();
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
client.isAlive = false;
|
|
205
|
+
client.lastPingTime = now;
|
|
206
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
207
|
+
client.ping(Buffer.from(now.toString()));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}, 30_000);
|
|
211
|
+
resolve(addr.port);
|
|
212
|
+
})
|
|
213
|
+
.on("error", reject);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
async findAndListen(preferredPort, bindAddress = "127.0.0.1") {
|
|
217
|
+
if (preferredPort) {
|
|
218
|
+
if (preferredPort < 1 || preferredPort > 65535) {
|
|
219
|
+
this.logger.warn(`Invalid port ${preferredPort} (must be 1-65535), falling back to OS-assigned port`);
|
|
220
|
+
preferredPort = null;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
return this.listen(preferredPort, bindAddress);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Port 0 lets the OS kernel assign a free port atomically
|
|
227
|
+
return this.listen(0, bindAddress);
|
|
228
|
+
}
|
|
229
|
+
async close() {
|
|
230
|
+
if (this.pingInterval)
|
|
231
|
+
clearInterval(this.pingInterval);
|
|
232
|
+
for (const client of this.wss.clients) {
|
|
233
|
+
client.close(1001, "Server shutting down");
|
|
234
|
+
}
|
|
235
|
+
// Wait up to 2s for graceful disconnect, then force-terminate
|
|
236
|
+
await new Promise((resolve) => {
|
|
237
|
+
const forceTimer = setTimeout(() => {
|
|
238
|
+
for (const client of this.wss.clients) {
|
|
239
|
+
client.terminate();
|
|
240
|
+
}
|
|
241
|
+
resolve();
|
|
242
|
+
}, 2000);
|
|
243
|
+
this.wss.close(() => {
|
|
244
|
+
clearTimeout(forceTimer);
|
|
245
|
+
resolve();
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
// Drain idle keep-alive HTTP connections (Node 20+ native)
|
|
249
|
+
this.httpServer.closeIdleConnections();
|
|
250
|
+
await new Promise((resolve) => {
|
|
251
|
+
// Hard failsafe: force-close any remaining HTTP connections after 10s
|
|
252
|
+
const hardTimer = setTimeout(() => {
|
|
253
|
+
this.httpServer.closeAllConnections();
|
|
254
|
+
resolve();
|
|
255
|
+
}, 10_000);
|
|
256
|
+
this.httpServer.close((err) => {
|
|
257
|
+
clearTimeout(hardTimer);
|
|
258
|
+
if (err)
|
|
259
|
+
this.logger.error(`HTTP server close error: ${err.message}`);
|
|
260
|
+
resolve();
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ActivityLog } from "../activityLog.js";
|
|
2
|
+
export declare function createGetActivityLogTool(activityLog: ActivityLog): {
|
|
3
|
+
schema: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
annotations: {
|
|
7
|
+
readOnlyHint: boolean;
|
|
8
|
+
};
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: "object";
|
|
11
|
+
properties: {
|
|
12
|
+
tool: {
|
|
13
|
+
type: "string";
|
|
14
|
+
description: string;
|
|
15
|
+
};
|
|
16
|
+
status: {
|
|
17
|
+
type: "string";
|
|
18
|
+
enum: string[];
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
last: {
|
|
22
|
+
type: "number";
|
|
23
|
+
description: string;
|
|
24
|
+
};
|
|
25
|
+
showStats: {
|
|
26
|
+
type: "boolean";
|
|
27
|
+
description: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
additionalProperties: false;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
handler: (args: Record<string, unknown>) => Promise<{
|
|
34
|
+
content: Array<{
|
|
35
|
+
type: string;
|
|
36
|
+
text: string;
|
|
37
|
+
}>;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { optionalBool, optionalInt, optionalString, success } from "./utils.js";
|
|
2
|
+
export function createGetActivityLogTool(activityLog) {
|
|
3
|
+
return {
|
|
4
|
+
schema: {
|
|
5
|
+
name: "getActivityLog",
|
|
6
|
+
description: "Query the log of recent tool calls. Shows what tools were called, their timing, and status. Useful for reviewing what actions have been taken in this session.",
|
|
7
|
+
annotations: { readOnlyHint: true },
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
tool: {
|
|
12
|
+
type: "string",
|
|
13
|
+
description: "Filter by tool name",
|
|
14
|
+
},
|
|
15
|
+
status: {
|
|
16
|
+
type: "string",
|
|
17
|
+
enum: ["success", "error"],
|
|
18
|
+
description: "Filter by status",
|
|
19
|
+
},
|
|
20
|
+
last: {
|
|
21
|
+
type: "number",
|
|
22
|
+
description: "Number of recent entries to return (default: 50, max: 200)",
|
|
23
|
+
},
|
|
24
|
+
showStats: {
|
|
25
|
+
type: "boolean",
|
|
26
|
+
description: "If true, include per-tool statistics (call count, avg duration, error count). Default: false",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
handler: async (args) => {
|
|
33
|
+
const tool = optionalString(args, "tool");
|
|
34
|
+
const status = optionalString(args, "status");
|
|
35
|
+
const last = optionalInt(args, "last", 1, 200) ?? 50;
|
|
36
|
+
const showStats = optionalBool(args, "showStats") ?? false;
|
|
37
|
+
const entries = activityLog.query({ tool, status, last });
|
|
38
|
+
const result = {
|
|
39
|
+
entries,
|
|
40
|
+
count: entries.length,
|
|
41
|
+
};
|
|
42
|
+
if (showStats) {
|
|
43
|
+
result.stats = activityLog.stats();
|
|
44
|
+
}
|
|
45
|
+
return success(result);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=activityLog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activityLog.js","sourceRoot":"","sources":["../../src/tools/activityLog.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,UAAU,wBAAwB,CAAC,WAAwB;IAC/D,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,gBAAgB;YACtB,WAAW,EACT,gKAAgK;YAClK,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;YACnC,WAAW,EAAE;gBACX,IAAI,EAAE,QAAiB;gBACvB,UAAU,EAAE;oBACV,IAAI,EAAE;wBACJ,IAAI,EAAE,QAAiB;wBACvB,WAAW,EAAE,qBAAqB;qBACnC;oBACD,MAAM,EAAE;wBACN,IAAI,EAAE,QAAiB;wBACvB,IAAI,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC;wBAC1B,WAAW,EAAE,kBAAkB;qBAChC;oBACD,IAAI,EAAE;wBACJ,IAAI,EAAE,QAAiB;wBACvB,WAAW,EACT,4DAA4D;qBAC/D;oBACD,SAAS,EAAE;wBACT,IAAI,EAAE,SAAkB;wBACxB,WAAW,EACT,8FAA8F;qBACjG;iBACF;gBACD,oBAAoB,EAAE,KAAc;aACrC;SACF;QACD,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;YAC/C,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC9C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;YACrD,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,KAAK,CAAC;YAE3D,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,MAAM,MAAM,GAA4B;gBACtC,OAAO;gBACP,KAAK,EAAE,OAAO,CAAC,MAAM;aACtB,CAAC;YACF,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,CAAC;YACrC,CAAC;YACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ExtensionClient } from "../extensionClient.js";
|
|
2
|
+
export declare function createGetAICommentsTool(workspace: string, extensionClient: ExtensionClient): {
|
|
3
|
+
schema: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
annotations: {
|
|
7
|
+
readOnlyHint: boolean;
|
|
8
|
+
};
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: "object";
|
|
11
|
+
properties: {
|
|
12
|
+
file: {
|
|
13
|
+
type: string;
|
|
14
|
+
description: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
additionalProperties: false;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
handler: (args: Record<string, unknown>, signal?: AbortSignal) => Promise<{
|
|
21
|
+
content: Array<{
|
|
22
|
+
type: string;
|
|
23
|
+
text: string;
|
|
24
|
+
}>;
|
|
25
|
+
}>;
|
|
26
|
+
};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { execSafe, optionalString, resolveFilePath, success } from "./utils.js";
|
|
3
|
+
const SEVERITY_PREFIXES = {
|
|
4
|
+
fix: "fix",
|
|
5
|
+
todo: "todo",
|
|
6
|
+
question: "question",
|
|
7
|
+
warn: "warn",
|
|
8
|
+
task: "task",
|
|
9
|
+
};
|
|
10
|
+
function parseSeverityFromComment(comment) {
|
|
11
|
+
const match = comment.match(/^(FIX|TODO|QUESTION|WARN|TASK)\s*:?\s*/i);
|
|
12
|
+
if (match) {
|
|
13
|
+
const key = match[1].toLowerCase();
|
|
14
|
+
return {
|
|
15
|
+
severity: SEVERITY_PREFIXES[key] ?? "task",
|
|
16
|
+
text: comment.slice(match[0].length).trim(),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return { severity: "task", text: comment };
|
|
20
|
+
}
|
|
21
|
+
// Grep pattern covering all supported AI comment syntaxes:
|
|
22
|
+
// // AI:, # AI:, /* AI:, <!-- AI:, -- AI:, %% AI:, ' AI:
|
|
23
|
+
const GREP_PATTERN = "(\\/\\/|#|/\\*|<!--|--|%%|')\\s*AI:\\s*";
|
|
24
|
+
const GREP_INCLUDE_GLOBS = [
|
|
25
|
+
"*.ts",
|
|
26
|
+
"*.tsx",
|
|
27
|
+
"*.js",
|
|
28
|
+
"*.jsx",
|
|
29
|
+
"*.py",
|
|
30
|
+
"*.rb",
|
|
31
|
+
"*.go",
|
|
32
|
+
"*.rs",
|
|
33
|
+
"*.java",
|
|
34
|
+
"*.kt",
|
|
35
|
+
"*.swift",
|
|
36
|
+
"*.c",
|
|
37
|
+
"*.cpp",
|
|
38
|
+
"*.h",
|
|
39
|
+
"*.cs",
|
|
40
|
+
"*.php",
|
|
41
|
+
"*.lua",
|
|
42
|
+
"*.sql",
|
|
43
|
+
"*.hs",
|
|
44
|
+
"*.erl",
|
|
45
|
+
"*.ex",
|
|
46
|
+
"*.exs",
|
|
47
|
+
"*.ml",
|
|
48
|
+
"*.vb",
|
|
49
|
+
"*.m",
|
|
50
|
+
"*.html",
|
|
51
|
+
"*.vue",
|
|
52
|
+
"*.svelte",
|
|
53
|
+
"*.css",
|
|
54
|
+
"*.scss",
|
|
55
|
+
"*.yaml",
|
|
56
|
+
"*.yml",
|
|
57
|
+
"*.toml",
|
|
58
|
+
"*.sh",
|
|
59
|
+
];
|
|
60
|
+
export function createGetAICommentsTool(workspace, extensionClient) {
|
|
61
|
+
return {
|
|
62
|
+
schema: {
|
|
63
|
+
name: "getAIComments",
|
|
64
|
+
description: "Get pending AI comment directives (// AI: ..., # AI: ..., /* AI: */, <!-- AI: -->, -- AI:, %% AI:, ' AI:) found in workspace source files. These are inline instructions from developers for Claude to act on. Supports severity prefixes: AI:FIX, AI:TODO, AI:QUESTION, AI:WARN.",
|
|
65
|
+
annotations: { readOnlyHint: true },
|
|
66
|
+
inputSchema: {
|
|
67
|
+
type: "object",
|
|
68
|
+
properties: {
|
|
69
|
+
file: {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "Optional file path to filter comments for a specific file",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
additionalProperties: false,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
handler: async (args, signal) => {
|
|
78
|
+
const rawFile = optionalString(args, "file");
|
|
79
|
+
// If extension is connected, use it
|
|
80
|
+
if (extensionClient.isConnected()) {
|
|
81
|
+
const allComments = [];
|
|
82
|
+
for (const [, comments] of extensionClient.latestAIComments) {
|
|
83
|
+
for (const c of comments) {
|
|
84
|
+
const { severity, text } = parseSeverityFromComment(c.comment);
|
|
85
|
+
allComments.push({
|
|
86
|
+
...c,
|
|
87
|
+
comment: text,
|
|
88
|
+
severity: c.severity ?? severity,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// If no cached comments, try on-demand request
|
|
93
|
+
if (allComments.length === 0) {
|
|
94
|
+
try {
|
|
95
|
+
const result = await extensionClient.getAIComments();
|
|
96
|
+
if (Array.isArray(result)) {
|
|
97
|
+
for (const c of result) {
|
|
98
|
+
const { severity, text } = parseSeverityFromComment(c.comment);
|
|
99
|
+
allComments.push({
|
|
100
|
+
file: c.file,
|
|
101
|
+
line: c.line,
|
|
102
|
+
comment: text,
|
|
103
|
+
syntax: c.syntax,
|
|
104
|
+
fullLine: c.fullLine,
|
|
105
|
+
severity: c.severity ?? severity,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Extension may not support on-demand scan yet
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
let filtered = allComments;
|
|
115
|
+
if (rawFile) {
|
|
116
|
+
const resolved = resolveFilePath(rawFile, workspace);
|
|
117
|
+
filtered = allComments.filter((c) => c.file === resolved);
|
|
118
|
+
}
|
|
119
|
+
return success({
|
|
120
|
+
available: true,
|
|
121
|
+
source: "extension",
|
|
122
|
+
comments: filtered,
|
|
123
|
+
count: filtered.length,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// Grep fallback when extension is not connected
|
|
127
|
+
const grepArgs = ["-rn", "-E", "-m", "500", GREP_PATTERN];
|
|
128
|
+
for (const glob of GREP_INCLUDE_GLOBS) {
|
|
129
|
+
grepArgs.push("--include", glob);
|
|
130
|
+
}
|
|
131
|
+
if (rawFile) {
|
|
132
|
+
grepArgs.push(resolveFilePath(rawFile, workspace));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
grepArgs.push(workspace);
|
|
136
|
+
}
|
|
137
|
+
const result = await execSafe("grep", grepArgs, {
|
|
138
|
+
cwd: workspace,
|
|
139
|
+
signal,
|
|
140
|
+
timeout: 10000,
|
|
141
|
+
});
|
|
142
|
+
const comments = [];
|
|
143
|
+
if (result.stdout) {
|
|
144
|
+
for (const line of result.stdout.split("\n")) {
|
|
145
|
+
if (!line.trim())
|
|
146
|
+
continue;
|
|
147
|
+
// Parse grep output: file:line:content
|
|
148
|
+
const match = line.match(/^(.+?):(\d+):(.+)$/);
|
|
149
|
+
if (!match)
|
|
150
|
+
continue;
|
|
151
|
+
const file = match[1];
|
|
152
|
+
const lineNum = Number.parseInt(match[2], 10);
|
|
153
|
+
const fullLine = match[3].trim();
|
|
154
|
+
// Extract AI comment text
|
|
155
|
+
const commentMatch = fullLine.match(/(?:\/\/|#|\/\*|<!--|--|%%|')\s*AI:\s*(.+)/i);
|
|
156
|
+
if (!commentMatch)
|
|
157
|
+
continue;
|
|
158
|
+
const rawComment = commentMatch[1]
|
|
159
|
+
.replace(/\s*\*\/\s*$/, "")
|
|
160
|
+
.replace(/\s*-->\s*$/, "")
|
|
161
|
+
.trim();
|
|
162
|
+
// Detect syntax
|
|
163
|
+
let syntax = "//";
|
|
164
|
+
if (fullLine.includes("/* AI:"))
|
|
165
|
+
syntax = "/*";
|
|
166
|
+
else if (fullLine.includes("<!-- AI:"))
|
|
167
|
+
syntax = "<!--";
|
|
168
|
+
else if (fullLine.includes("# AI:"))
|
|
169
|
+
syntax = "#";
|
|
170
|
+
else if (fullLine.includes("-- AI:"))
|
|
171
|
+
syntax = "--";
|
|
172
|
+
else if (fullLine.includes("%% AI:"))
|
|
173
|
+
syntax = "%%";
|
|
174
|
+
else if (fullLine.includes("' AI:"))
|
|
175
|
+
syntax = "'";
|
|
176
|
+
const { severity, text } = parseSeverityFromComment(rawComment);
|
|
177
|
+
comments.push({
|
|
178
|
+
file: path.isAbsolute(file) ? file : path.resolve(workspace, file),
|
|
179
|
+
line: lineNum,
|
|
180
|
+
comment: text,
|
|
181
|
+
syntax,
|
|
182
|
+
fullLine,
|
|
183
|
+
severity,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return success({
|
|
188
|
+
available: true,
|
|
189
|
+
source: "grep-fallback",
|
|
190
|
+
comments,
|
|
191
|
+
count: comments.length,
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=aiComments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiComments.js","sourceRoot":"","sources":["../../src/tools/aiComments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ExtensionClient } from "../extensionClient.js";
|
|
2
|
+
export declare function createBridgeStatusTool(extensionClient: ExtensionClient, sessions?: Map<string, unknown>): {
|
|
3
|
+
schema: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
annotations: {
|
|
7
|
+
readOnlyHint: boolean;
|
|
8
|
+
};
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: "object";
|
|
11
|
+
properties: {};
|
|
12
|
+
additionalProperties: false;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
handler: () => Promise<{
|
|
16
|
+
content: Array<{
|
|
17
|
+
type: string;
|
|
18
|
+
text: string;
|
|
19
|
+
}>;
|
|
20
|
+
}>;
|
|
21
|
+
};
|