@vibecontrols/vibe-plugin-ssh 2026.416.1
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 +70 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/routes/port-forward.d.ts +190 -0
- package/dist/routes/port-forward.d.ts.map +1 -0
- package/dist/routes/port-forward.js +303 -0
- package/dist/routes/port-forward.js.map +1 -0
- package/dist/routes/remote-agent-install.d.ts +179 -0
- package/dist/routes/remote-agent-install.d.ts.map +1 -0
- package/dist/routes/remote-agent-install.js +537 -0
- package/dist/routes/remote-agent-install.js.map +1 -0
- package/dist/routes/remote-terminal.d.ts +154 -0
- package/dist/routes/remote-terminal.d.ts.map +1 -0
- package/dist/routes/remote-terminal.js +437 -0
- package/dist/routes/remote-terminal.js.map +1 -0
- package/dist/routes/ssh-config-scan.d.ts +144 -0
- package/dist/routes/ssh-config-scan.d.ts.map +1 -0
- package/dist/routes/ssh-config-scan.js +271 -0
- package/dist/routes/ssh-config-scan.js.map +1 -0
- package/dist/routes/ssh.d.ts +247 -0
- package/dist/routes/ssh.d.ts.map +1 -0
- package/dist/routes/ssh.js +295 -0
- package/dist/routes/ssh.js.map +1 -0
- package/dist/types.d.ts +171 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port-forwarding routes (Elysia + KV storage).
|
|
3
|
+
*
|
|
4
|
+
* Namespace: "ssh"
|
|
5
|
+
* Keys:
|
|
6
|
+
* "connections" → JSON array of SSHConnection objects (read-only here)
|
|
7
|
+
* "port-forwards" → JSON array of PortForward objects
|
|
8
|
+
*/
|
|
9
|
+
import { Elysia } from "elysia";
|
|
10
|
+
import { Client } from "ssh2";
|
|
11
|
+
import { createServer } from "node:net";
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// In-memory map of currently active tunnels
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const activeConnections = new Map();
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// KV helpers – connections (read-only from this module)
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
async function getConnectionById(storage, id) {
|
|
20
|
+
const raw = await storage.get("ssh", "connections");
|
|
21
|
+
if (!raw)
|
|
22
|
+
return undefined;
|
|
23
|
+
const all = JSON.parse(raw);
|
|
24
|
+
return all.find((c) => c.id === id);
|
|
25
|
+
}
|
|
26
|
+
async function getConnectionByName(storage, serverName) {
|
|
27
|
+
const raw = await storage.get("ssh", "connections");
|
|
28
|
+
if (!raw)
|
|
29
|
+
return undefined;
|
|
30
|
+
const all = JSON.parse(raw);
|
|
31
|
+
return all.find((c) => c.serverName === serverName);
|
|
32
|
+
}
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// KV helpers – port forwards
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
async function getAllPortForwards(storage) {
|
|
37
|
+
const raw = await storage.get("ssh", "port-forwards");
|
|
38
|
+
if (!raw)
|
|
39
|
+
return [];
|
|
40
|
+
return JSON.parse(raw);
|
|
41
|
+
}
|
|
42
|
+
async function getPortForwardById(storage, id) {
|
|
43
|
+
const all = await getAllPortForwards(storage);
|
|
44
|
+
return all.find((pf) => pf.id === id);
|
|
45
|
+
}
|
|
46
|
+
async function savePortForwards(storage, forwards) {
|
|
47
|
+
await storage.set("ssh", "port-forwards", JSON.stringify(forwards));
|
|
48
|
+
}
|
|
49
|
+
async function updatePortForward(storage, id, patch) {
|
|
50
|
+
const all = await getAllPortForwards(storage);
|
|
51
|
+
const idx = all.findIndex((pf) => pf.id === id);
|
|
52
|
+
if (idx !== -1) {
|
|
53
|
+
all[idx] = { ...all[idx], ...patch };
|
|
54
|
+
await savePortForwards(storage, all);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function deletePortForwardById(storage, id) {
|
|
58
|
+
const all = await getAllPortForwards(storage);
|
|
59
|
+
const filtered = all.filter((pf) => pf.id !== id);
|
|
60
|
+
await savePortForwards(storage, filtered);
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Build an ssh2 connect config from a stored connection
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
async function buildConnectConfig(conn) {
|
|
66
|
+
const cfg = {
|
|
67
|
+
host: conn.host,
|
|
68
|
+
port: conn.port,
|
|
69
|
+
username: conn.username,
|
|
70
|
+
};
|
|
71
|
+
if (conn.privateKeyPath) {
|
|
72
|
+
const file = Bun.file(conn.privateKeyPath);
|
|
73
|
+
cfg.privateKey = Buffer.from(await file.arrayBuffer());
|
|
74
|
+
}
|
|
75
|
+
else if (conn.password) {
|
|
76
|
+
cfg.password = conn.password;
|
|
77
|
+
}
|
|
78
|
+
return cfg;
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Cleanup helper — exported so onServerStop can call it too
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
export function cleanupAllTunnels() {
|
|
84
|
+
for (const [, { client, server }] of activeConnections) {
|
|
85
|
+
server.close();
|
|
86
|
+
client.end();
|
|
87
|
+
}
|
|
88
|
+
activeConnections.clear();
|
|
89
|
+
}
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// Route factory
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
export function createPortForwardRoutes(hostServices) {
|
|
94
|
+
const { storage, eventBus } = hostServices;
|
|
95
|
+
return (new Elysia({ prefix: "/api/port-forward" })
|
|
96
|
+
// -----------------------------------------------------------------------
|
|
97
|
+
// GET /api/port-forward — list all port forwards
|
|
98
|
+
// -----------------------------------------------------------------------
|
|
99
|
+
.get("/", async () => {
|
|
100
|
+
const portForwards = await getAllPortForwards(storage);
|
|
101
|
+
return { portForwards };
|
|
102
|
+
})
|
|
103
|
+
// -----------------------------------------------------------------------
|
|
104
|
+
// POST /api/port-forward — create a new port forward config
|
|
105
|
+
// -----------------------------------------------------------------------
|
|
106
|
+
.post("/", async ({ body, set }) => {
|
|
107
|
+
const { localPort, remoteHost, remotePort, connectionId } = body;
|
|
108
|
+
try {
|
|
109
|
+
const existing = (await getAllPortForwards(storage)).find((pf) => pf.localPort === localPort && pf.status === "active");
|
|
110
|
+
if (existing) {
|
|
111
|
+
set.status = 409;
|
|
112
|
+
return { error: "Local port is already in use" };
|
|
113
|
+
}
|
|
114
|
+
const connectionConfig = await getConnectionById(storage, connectionId);
|
|
115
|
+
if (!connectionConfig) {
|
|
116
|
+
set.status = 404;
|
|
117
|
+
return { error: "SSH connection not found" };
|
|
118
|
+
}
|
|
119
|
+
const newPf = {
|
|
120
|
+
id: globalThis.crypto.randomUUID(),
|
|
121
|
+
localPort,
|
|
122
|
+
remoteHost,
|
|
123
|
+
remotePort,
|
|
124
|
+
serverName: connectionConfig.serverName,
|
|
125
|
+
connectionId,
|
|
126
|
+
status: "inactive",
|
|
127
|
+
createdAt: new Date().toISOString(),
|
|
128
|
+
};
|
|
129
|
+
const all = await getAllPortForwards(storage);
|
|
130
|
+
all.push(newPf);
|
|
131
|
+
await savePortForwards(storage, all);
|
|
132
|
+
return { portForward: newPf };
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
set.status = 500;
|
|
136
|
+
return {
|
|
137
|
+
error: "Failed to create port forward",
|
|
138
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
// -----------------------------------------------------------------------
|
|
143
|
+
// POST /api/port-forward/:id/start — start the tunnel
|
|
144
|
+
// -----------------------------------------------------------------------
|
|
145
|
+
.post("/:id/start", async ({ params, set }) => {
|
|
146
|
+
const { id } = params;
|
|
147
|
+
try {
|
|
148
|
+
const portForward = await getPortForwardById(storage, id);
|
|
149
|
+
if (!portForward) {
|
|
150
|
+
set.status = 404;
|
|
151
|
+
return { error: "Port forward not found" };
|
|
152
|
+
}
|
|
153
|
+
if (portForward.status === "active") {
|
|
154
|
+
set.status = 400;
|
|
155
|
+
return { error: "Port forward is already active" };
|
|
156
|
+
}
|
|
157
|
+
// Resolve connection config (by id first, then by serverName)
|
|
158
|
+
const connectionConfig = portForward.connectionId
|
|
159
|
+
? await getConnectionById(storage, portForward.connectionId)
|
|
160
|
+
: await getConnectionByName(storage, portForward.serverName);
|
|
161
|
+
if (!connectionConfig) {
|
|
162
|
+
set.status = 404;
|
|
163
|
+
return { error: "SSH connection not found" };
|
|
164
|
+
}
|
|
165
|
+
const sshClient = new Client();
|
|
166
|
+
const connectConfig = await buildConnectConfig(connectionConfig);
|
|
167
|
+
const server = createServer((localSocket) => {
|
|
168
|
+
sshClient.forwardOut("localhost", portForward.localPort, portForward.remoteHost, portForward.remotePort, (err, stream) => {
|
|
169
|
+
if (err) {
|
|
170
|
+
localSocket.end();
|
|
171
|
+
console.error("Forward error:", err);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
localSocket.pipe(stream).pipe(localSocket);
|
|
175
|
+
localSocket.on("close", () => {
|
|
176
|
+
stream.end();
|
|
177
|
+
});
|
|
178
|
+
stream.on("close", () => {
|
|
179
|
+
localSocket.end();
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
return new Promise((resolve) => {
|
|
184
|
+
sshClient.on("ready", () => {
|
|
185
|
+
server.listen(portForward.localPort, () => {
|
|
186
|
+
activeConnections.set(id, { client: sshClient, server });
|
|
187
|
+
// Persist status change
|
|
188
|
+
void updatePortForward(storage, id, { status: "active" });
|
|
189
|
+
if (eventBus) {
|
|
190
|
+
eventBus.emit("portforward:started", {
|
|
191
|
+
id,
|
|
192
|
+
localPort: portForward.localPort,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.log(`[port-forward] Started tunnel ${id} on localhost:${portForward.localPort}`);
|
|
197
|
+
}
|
|
198
|
+
resolve({
|
|
199
|
+
success: true,
|
|
200
|
+
message: `Port forwarding started on localhost:${portForward.localPort}`,
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
server.on("error", (err) => {
|
|
204
|
+
sshClient.end();
|
|
205
|
+
set.status = 500;
|
|
206
|
+
resolve({
|
|
207
|
+
error: "Failed to start local server",
|
|
208
|
+
details: err.message,
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
sshClient.on("error", (err) => {
|
|
213
|
+
set.status = 500;
|
|
214
|
+
resolve({
|
|
215
|
+
error: "SSH connection failed",
|
|
216
|
+
details: err.message,
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
sshClient.connect(connectConfig);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
set.status = 500;
|
|
224
|
+
return {
|
|
225
|
+
error: "Failed to start port forward",
|
|
226
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
// -----------------------------------------------------------------------
|
|
231
|
+
// POST /api/port-forward/:id/stop — stop an active tunnel
|
|
232
|
+
// -----------------------------------------------------------------------
|
|
233
|
+
.post("/:id/stop", async ({ params, set }) => {
|
|
234
|
+
const { id } = params;
|
|
235
|
+
try {
|
|
236
|
+
const portForward = await getPortForwardById(storage, id);
|
|
237
|
+
if (!portForward) {
|
|
238
|
+
set.status = 404;
|
|
239
|
+
return { error: "Port forward not found" };
|
|
240
|
+
}
|
|
241
|
+
if (portForward.status !== "active") {
|
|
242
|
+
set.status = 400;
|
|
243
|
+
return { error: "Port forward is not active" };
|
|
244
|
+
}
|
|
245
|
+
const active = activeConnections.get(id);
|
|
246
|
+
if (active) {
|
|
247
|
+
active.server.close();
|
|
248
|
+
active.client.end();
|
|
249
|
+
activeConnections.delete(id);
|
|
250
|
+
}
|
|
251
|
+
await updatePortForward(storage, id, { status: "inactive" });
|
|
252
|
+
if (eventBus) {
|
|
253
|
+
eventBus.emit("portforward:stopped", {
|
|
254
|
+
id,
|
|
255
|
+
localPort: portForward.localPort,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
console.log(`[port-forward] Stopped tunnel ${id} (localhost:${portForward.localPort})`);
|
|
260
|
+
}
|
|
261
|
+
return { success: true };
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
set.status = 500;
|
|
265
|
+
return {
|
|
266
|
+
error: "Failed to stop port forward",
|
|
267
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
})
|
|
271
|
+
// -----------------------------------------------------------------------
|
|
272
|
+
// DELETE /api/port-forward/:id — delete a port forward (stops if active)
|
|
273
|
+
// -----------------------------------------------------------------------
|
|
274
|
+
.delete("/:id", async ({ params, set }) => {
|
|
275
|
+
const { id } = params;
|
|
276
|
+
try {
|
|
277
|
+
const portForward = await getPortForwardById(storage, id);
|
|
278
|
+
if (!portForward) {
|
|
279
|
+
set.status = 404;
|
|
280
|
+
return { error: "Port forward not found" };
|
|
281
|
+
}
|
|
282
|
+
// Tear down tunnel if still active
|
|
283
|
+
if (portForward.status === "active") {
|
|
284
|
+
const active = activeConnections.get(id);
|
|
285
|
+
if (active) {
|
|
286
|
+
active.server.close();
|
|
287
|
+
active.client.end();
|
|
288
|
+
activeConnections.delete(id);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
await deletePortForwardById(storage, id);
|
|
292
|
+
return { success: true };
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
set.status = 500;
|
|
296
|
+
return {
|
|
297
|
+
error: "Failed to delete port forward",
|
|
298
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
}));
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=port-forward.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-forward.js","sourceRoot":"","sources":["../../src/routes/port-forward.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote agent installation routes.
|
|
3
|
+
*
|
|
4
|
+
* Installs vibecontrols-agent on a target server via SSH. This is a
|
|
5
|
+
* long-running operation — progress is reported via WebSocket events.
|
|
6
|
+
*
|
|
7
|
+
* Registry URL resolution (for @vibecontrols packages):
|
|
8
|
+
* 1. hostServices.getPluginRegistry() — reads from agent config/env
|
|
9
|
+
* 2. Fallback: https://registry.npmjs.org
|
|
10
|
+
*/
|
|
11
|
+
import { Elysia } from "elysia";
|
|
12
|
+
import type { HostServices, RemoteAgentInstallJob } from "../types.js";
|
|
13
|
+
export declare function createRemoteAgentInstallRoutes(hostServices: HostServices): Elysia<"/api/ssh/agent-install", {
|
|
14
|
+
decorator: {};
|
|
15
|
+
store: {};
|
|
16
|
+
derive: {};
|
|
17
|
+
resolve: {};
|
|
18
|
+
}, {
|
|
19
|
+
typebox: {};
|
|
20
|
+
error: {};
|
|
21
|
+
}, {
|
|
22
|
+
schema: {};
|
|
23
|
+
standaloneSchema: {};
|
|
24
|
+
macro: {};
|
|
25
|
+
macroFn: {};
|
|
26
|
+
parser: {};
|
|
27
|
+
response: {};
|
|
28
|
+
}, {
|
|
29
|
+
api: {
|
|
30
|
+
ssh: {
|
|
31
|
+
"agent-install": {
|
|
32
|
+
jobs: {
|
|
33
|
+
get: {
|
|
34
|
+
body: unknown;
|
|
35
|
+
params: {};
|
|
36
|
+
query: unknown;
|
|
37
|
+
headers: unknown;
|
|
38
|
+
response: {
|
|
39
|
+
200: {
|
|
40
|
+
jobs: RemoteAgentInstallJob[];
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
} & {
|
|
49
|
+
api: {
|
|
50
|
+
ssh: {
|
|
51
|
+
"agent-install": {
|
|
52
|
+
jobs: {
|
|
53
|
+
":id": {
|
|
54
|
+
get: {
|
|
55
|
+
body: unknown;
|
|
56
|
+
params: {
|
|
57
|
+
id: string;
|
|
58
|
+
} & {};
|
|
59
|
+
query: unknown;
|
|
60
|
+
headers: unknown;
|
|
61
|
+
response: {
|
|
62
|
+
200: {
|
|
63
|
+
error: string;
|
|
64
|
+
job?: undefined;
|
|
65
|
+
} | {
|
|
66
|
+
job: RemoteAgentInstallJob;
|
|
67
|
+
error?: undefined;
|
|
68
|
+
};
|
|
69
|
+
422: {
|
|
70
|
+
type: "validation";
|
|
71
|
+
on: string;
|
|
72
|
+
summary?: string;
|
|
73
|
+
message?: string;
|
|
74
|
+
found?: unknown;
|
|
75
|
+
property?: string;
|
|
76
|
+
expected?: string;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
} & {
|
|
86
|
+
api: {
|
|
87
|
+
ssh: {
|
|
88
|
+
"agent-install": {
|
|
89
|
+
start: {
|
|
90
|
+
post: {
|
|
91
|
+
body: unknown;
|
|
92
|
+
params: {};
|
|
93
|
+
query: unknown;
|
|
94
|
+
headers: unknown;
|
|
95
|
+
response: {
|
|
96
|
+
200: {
|
|
97
|
+
error: string;
|
|
98
|
+
jobId?: undefined;
|
|
99
|
+
status?: undefined;
|
|
100
|
+
} | {
|
|
101
|
+
jobId: `${string}-${string}-${string}-${string}-${string}`;
|
|
102
|
+
status: string;
|
|
103
|
+
error?: undefined;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
} & {
|
|
112
|
+
api: {
|
|
113
|
+
ssh: {
|
|
114
|
+
"agent-install": {
|
|
115
|
+
"batch-start": {
|
|
116
|
+
post: {
|
|
117
|
+
body: unknown;
|
|
118
|
+
params: {};
|
|
119
|
+
query: unknown;
|
|
120
|
+
headers: unknown;
|
|
121
|
+
response: {
|
|
122
|
+
200: {
|
|
123
|
+
error: string;
|
|
124
|
+
jobs?: undefined;
|
|
125
|
+
total?: undefined;
|
|
126
|
+
} | {
|
|
127
|
+
jobs: {
|
|
128
|
+
connectionId: string;
|
|
129
|
+
jobId: string;
|
|
130
|
+
}[];
|
|
131
|
+
total: number;
|
|
132
|
+
error?: undefined;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
} & {
|
|
141
|
+
api: {
|
|
142
|
+
ssh: {
|
|
143
|
+
"agent-install": {
|
|
144
|
+
uninstall: {
|
|
145
|
+
post: {
|
|
146
|
+
body: unknown;
|
|
147
|
+
params: {};
|
|
148
|
+
query: unknown;
|
|
149
|
+
headers: unknown;
|
|
150
|
+
response: {
|
|
151
|
+
200: {
|
|
152
|
+
error: string;
|
|
153
|
+
success?: undefined;
|
|
154
|
+
message?: undefined;
|
|
155
|
+
} | {
|
|
156
|
+
success: boolean;
|
|
157
|
+
message: string;
|
|
158
|
+
error?: undefined;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
}, {
|
|
167
|
+
derive: {};
|
|
168
|
+
resolve: {};
|
|
169
|
+
schema: {};
|
|
170
|
+
standaloneSchema: {};
|
|
171
|
+
response: {};
|
|
172
|
+
}, {
|
|
173
|
+
derive: {};
|
|
174
|
+
resolve: {};
|
|
175
|
+
schema: {};
|
|
176
|
+
standaloneSchema: {};
|
|
177
|
+
response: {};
|
|
178
|
+
}>;
|
|
179
|
+
//# sourceMappingURL=remote-agent-install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-agent-install.d.ts","sourceRoot":"","sources":["../../src/routes/remote-agent-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EACV,YAAY,EAEZ,qBAAqB,EAKtB,MAAM,aAAa,CAAC;AA0kBrB,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDAmF/B,MAAM;2CAAS,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2E9D"}
|