@burdenoff/vibe-agent 2.1.1 → 2.3.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/dist/app-sm6n9xst.js +1165 -0
- package/dist/app-sm6n9xst.js.map +19 -0
- package/dist/cli.js +167 -2050
- package/dist/cli.js.map +8 -30
- package/dist/index-05qfwz8r.js +122 -0
- package/dist/index-05qfwz8r.js.map +10 -0
- package/dist/index-30p492yv.js +294 -0
- package/dist/index-30p492yv.js.map +13 -0
- package/dist/index-3rjnbp97.js +268 -0
- package/dist/index-3rjnbp97.js.map +13 -0
- package/dist/index-6vry08rz.js +285 -0
- package/dist/index-6vry08rz.js.map +13 -0
- package/dist/index-88ym10cs.js +194 -0
- package/dist/index-88ym10cs.js.map +10 -0
- package/dist/index-a9g7hbj9.js +229 -0
- package/dist/index-a9g7hbj9.js.map +13 -0
- package/dist/index-atjhkm74.js +149 -0
- package/dist/index-atjhkm74.js.map +10 -0
- package/dist/index-b1eq3qvs.js +515 -0
- package/dist/index-b1eq3qvs.js.map +19 -0
- package/dist/index-c7zy3n33.js +167 -0
- package/dist/index-c7zy3n33.js.map +13 -0
- package/dist/index-fm6gqenc.js +338 -0
- package/dist/index-fm6gqenc.js.map +13 -0
- package/dist/index-hefqxwht.js +270 -0
- package/dist/index-hefqxwht.js.map +13 -0
- package/dist/index-k9hb0b93.js +280 -0
- package/dist/index-k9hb0b93.js.map +13 -0
- package/dist/index-npmvh1x9.js +385 -0
- package/dist/index-npmvh1x9.js.map +13 -0
- package/dist/index-rdm6e3rr.js +587 -0
- package/dist/index-rdm6e3rr.js.map +13 -0
- package/dist/index-s7ff1fj1.js +415 -0
- package/dist/index-s7ff1fj1.js.map +11 -0
- package/dist/index-t4qgjy5w.js +287 -0
- package/dist/index-t4qgjy5w.js.map +13 -0
- package/dist/index-wmvkjcjj.js +301 -0
- package/dist/index-wmvkjcjj.js.map +13 -0
- package/dist/{app-31chs2a1.js → index-wr0mkm57.js} +8 -3201
- package/dist/{app-31chs2a1.js.map → index-wr0mkm57.js.map} +4 -25
- package/dist/index-xmeskdnb.js +292 -0
- package/dist/index-xmeskdnb.js.map +11 -0
- package/dist/index.js +9 -6
- package/dist/index.js.map +2 -2
- package/dist/{package-hb6db316.js → package-04nkt49b.js} +5 -3
- package/dist/{package-hb6db316.js.map → package-04nkt49b.js.map} +1 -1
- package/dist/plugin-system-7r9mb1tb.js +479 -0
- package/dist/plugin-system-7r9mb1tb.js.map +10 -0
- package/package.json +3 -1
- package/dist/index-t06ktmx9.js +0 -216
- package/dist/index-t06ktmx9.js.map +0 -11
- package/dist/plugin-system-bg1pzjj9.js +0 -450
- package/dist/plugin-system-bg1pzjj9.js.map +0 -11
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
3
|
import {
|
|
4
|
-
ServiceRegistry
|
|
4
|
+
ServiceRegistry
|
|
5
|
+
} from "./index-atjhkm74.js";
|
|
6
|
+
import {
|
|
7
|
+
ServiceManager,
|
|
5
8
|
checkDependencies,
|
|
6
9
|
installDependencies
|
|
7
|
-
} from "./index-
|
|
10
|
+
} from "./index-s7ff1fj1.js";
|
|
11
|
+
import {
|
|
12
|
+
logger
|
|
13
|
+
} from "./index-88ym10cs.js";
|
|
14
|
+
import {
|
|
15
|
+
blank,
|
|
16
|
+
colors,
|
|
17
|
+
fail,
|
|
18
|
+
formatStatus,
|
|
19
|
+
formatTable,
|
|
20
|
+
header,
|
|
21
|
+
icons,
|
|
22
|
+
info,
|
|
23
|
+
kv,
|
|
24
|
+
printAgentDetails,
|
|
25
|
+
success,
|
|
26
|
+
timeAgo,
|
|
27
|
+
warn
|
|
28
|
+
} from "./index-xmeskdnb.js";
|
|
8
29
|
import {
|
|
9
30
|
__commonJS,
|
|
10
31
|
__require,
|
|
11
32
|
__toESM
|
|
12
33
|
} from "./index-g8dczzvv.js";
|
|
13
34
|
import {
|
|
14
|
-
PluginManager
|
|
15
|
-
|
|
16
|
-
} from "./plugin-system-bg1pzjj9.js";
|
|
35
|
+
PluginManager
|
|
36
|
+
} from "./plugin-system-7r9mb1tb.js";
|
|
17
37
|
|
|
18
38
|
// node_modules/commander/lib/error.js
|
|
19
39
|
var require_error = __commonJS((exports) => {
|
|
@@ -2125,548 +2145,29 @@ var {
|
|
|
2125
2145
|
} = import__.default;
|
|
2126
2146
|
|
|
2127
2147
|
// src/cli.ts
|
|
2128
|
-
import {
|
|
2129
|
-
import { join as join4, dirname as dirname2 } from "path";
|
|
2130
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2148
|
+
import { join as join3 } from "path";
|
|
2131
2149
|
|
|
2132
2150
|
// src/cli/commands/start.cmd.ts
|
|
2133
|
-
import { existsSync
|
|
2134
|
-
import { join
|
|
2135
|
-
import { homedir as homedir2 } from "os";
|
|
2136
|
-
|
|
2137
|
-
// src/cli/utils/api-client.ts
|
|
2138
|
-
var DEFAULT_AGENT_URL = "http://localhost:3005";
|
|
2139
|
-
var _apiKeyCache = new Map;
|
|
2140
|
-
function getAgentUrl(opts) {
|
|
2141
|
-
return opts?.agentUrl || process.env.AGENT_URL || DEFAULT_AGENT_URL;
|
|
2142
|
-
}
|
|
2143
|
-
async function resolveApiKey(agentUrl) {
|
|
2144
|
-
if (process.env.AGENT_API_KEY)
|
|
2145
|
-
return process.env.AGENT_API_KEY;
|
|
2146
|
-
if (_apiKeyCache.has(agentUrl))
|
|
2147
|
-
return _apiKeyCache.get(agentUrl);
|
|
2148
|
-
try {
|
|
2149
|
-
const res = await fetch(`${agentUrl}/api/agent/api-key`);
|
|
2150
|
-
if (res.ok) {
|
|
2151
|
-
const data = await res.json();
|
|
2152
|
-
if (data.apiKey) {
|
|
2153
|
-
_apiKeyCache.set(agentUrl, data.apiKey);
|
|
2154
|
-
return data.apiKey;
|
|
2155
|
-
}
|
|
2156
|
-
}
|
|
2157
|
-
} catch {}
|
|
2158
|
-
return;
|
|
2159
|
-
}
|
|
2160
|
-
async function agentFetch(agentUrl, path, options = {}) {
|
|
2161
|
-
const apiKey = await resolveApiKey(agentUrl);
|
|
2162
|
-
const headers = {
|
|
2163
|
-
...options.body ? { "Content-Type": "application/json" } : {},
|
|
2164
|
-
...apiKey ? { "x-agent-api-key": apiKey } : {},
|
|
2165
|
-
...options.headers ?? {}
|
|
2166
|
-
};
|
|
2167
|
-
const res = await fetch(`${agentUrl}${path}`, { ...options, headers });
|
|
2168
|
-
const data = await res.json().catch(() => ({}));
|
|
2169
|
-
return { ok: res.ok, status: res.status, data };
|
|
2170
|
-
}
|
|
2171
|
-
async function apiGet(agentUrl, path) {
|
|
2172
|
-
const { ok, status, data } = await agentFetch(agentUrl, path);
|
|
2173
|
-
if (!ok) {
|
|
2174
|
-
const errorMsg = data?.error || data?.message || `Agent returned ${status}`;
|
|
2175
|
-
throw new Error(String(errorMsg));
|
|
2176
|
-
}
|
|
2177
|
-
return data;
|
|
2178
|
-
}
|
|
2179
|
-
async function apiPost(agentUrl, path, body) {
|
|
2180
|
-
const { ok, status, data } = await agentFetch(agentUrl, path, {
|
|
2181
|
-
method: "POST",
|
|
2182
|
-
body: body != null ? JSON.stringify(body) : undefined
|
|
2183
|
-
});
|
|
2184
|
-
if (!ok) {
|
|
2185
|
-
const errorMsg = data?.error || data?.message || `Agent returned ${status}`;
|
|
2186
|
-
throw new Error(String(errorMsg));
|
|
2187
|
-
}
|
|
2188
|
-
return data;
|
|
2189
|
-
}
|
|
2190
|
-
async function apiPut(agentUrl, path, body) {
|
|
2191
|
-
const { ok, status, data } = await agentFetch(agentUrl, path, {
|
|
2192
|
-
method: "PUT",
|
|
2193
|
-
body: body != null ? JSON.stringify(body) : undefined
|
|
2194
|
-
});
|
|
2195
|
-
if (!ok) {
|
|
2196
|
-
const errorMsg = data?.error || data?.message || `Agent returned ${status}`;
|
|
2197
|
-
throw new Error(String(errorMsg));
|
|
2198
|
-
}
|
|
2199
|
-
return data;
|
|
2200
|
-
}
|
|
2201
|
-
async function apiDelete(agentUrl, path) {
|
|
2202
|
-
const { ok, status, data } = await agentFetch(agentUrl, path, {
|
|
2203
|
-
method: "DELETE"
|
|
2204
|
-
});
|
|
2205
|
-
if (!ok) {
|
|
2206
|
-
const errorMsg = data?.error || data?.message || `Agent returned ${status}`;
|
|
2207
|
-
throw new Error(String(errorMsg));
|
|
2208
|
-
}
|
|
2209
|
-
return data;
|
|
2210
|
-
}
|
|
2211
|
-
// src/cli/utils/format.ts
|
|
2212
|
-
var colors = {
|
|
2213
|
-
bold: (text) => `\x1B[1m${text}\x1B[22m`,
|
|
2214
|
-
dim: (text) => `\x1B[2m${text}\x1B[22m`,
|
|
2215
|
-
italic: (text) => `\x1B[3m${text}\x1B[23m`,
|
|
2216
|
-
underline: (text) => `\x1B[4m${text}\x1B[24m`,
|
|
2217
|
-
red: (text) => `\x1B[31m${text}\x1B[39m`,
|
|
2218
|
-
green: (text) => `\x1B[32m${text}\x1B[39m`,
|
|
2219
|
-
yellow: (text) => `\x1B[33m${text}\x1B[39m`,
|
|
2220
|
-
blue: (text) => `\x1B[34m${text}\x1B[39m`,
|
|
2221
|
-
magenta: (text) => `\x1B[35m${text}\x1B[39m`,
|
|
2222
|
-
cyan: (text) => `\x1B[36m${text}\x1B[39m`,
|
|
2223
|
-
white: (text) => `\x1B[37m${text}\x1B[39m`,
|
|
2224
|
-
gray: (text) => `\x1B[90m${text}\x1B[39m`,
|
|
2225
|
-
brightRed: (text) => `\x1B[91m${text}\x1B[39m`,
|
|
2226
|
-
brightGreen: (text) => `\x1B[92m${text}\x1B[39m`,
|
|
2227
|
-
brightYellow: (text) => `\x1B[93m${text}\x1B[39m`,
|
|
2228
|
-
brightBlue: (text) => `\x1B[94m${text}\x1B[39m`,
|
|
2229
|
-
reset: "\x1B[0m"
|
|
2230
|
-
};
|
|
2231
|
-
var icons = {
|
|
2232
|
-
success: colors.green("\u2713"),
|
|
2233
|
-
error: colors.red("\u2717"),
|
|
2234
|
-
warning: colors.yellow("\u26A0"),
|
|
2235
|
-
info: colors.blue("\u25CF"),
|
|
2236
|
-
running: colors.green("\u25CF"),
|
|
2237
|
-
stopped: colors.red("\u25CB"),
|
|
2238
|
-
pending: colors.yellow("\u25CC"),
|
|
2239
|
-
arrow: colors.gray("\u2192"),
|
|
2240
|
-
bullet: colors.gray("\u2022"),
|
|
2241
|
-
check: colors.green("\u2714")
|
|
2242
|
-
};
|
|
2243
|
-
function fail(msg) {
|
|
2244
|
-
console.error(`${colors.red("Error:")} ${msg}`);
|
|
2245
|
-
process.exit(1);
|
|
2246
|
-
}
|
|
2247
|
-
function success(msg) {
|
|
2248
|
-
console.log(` ${icons.success} ${msg}`);
|
|
2249
|
-
}
|
|
2250
|
-
function warn(msg) {
|
|
2251
|
-
console.log(` ${icons.warning} ${msg}`);
|
|
2252
|
-
}
|
|
2253
|
-
function info(msg) {
|
|
2254
|
-
console.log(` ${icons.info} ${msg}`);
|
|
2255
|
-
}
|
|
2256
|
-
function header(title) {
|
|
2257
|
-
console.log(`
|
|
2258
|
-
${colors.bold(`\u2500\u2500 ${title} \u2500\u2500`)}
|
|
2259
|
-
`);
|
|
2260
|
-
}
|
|
2261
|
-
function kv(key, value) {
|
|
2262
|
-
const display = value === null || value === undefined ? colors.gray("(none)") : String(value);
|
|
2263
|
-
console.log(` ${colors.bold(key.padEnd(14))} ${display}`);
|
|
2264
|
-
}
|
|
2265
|
-
function blank() {
|
|
2266
|
-
console.log();
|
|
2267
|
-
}
|
|
2268
|
-
function formatTable(rows) {
|
|
2269
|
-
if (rows.length === 0) {
|
|
2270
|
-
console.log(" (none)");
|
|
2271
|
-
return;
|
|
2272
|
-
}
|
|
2273
|
-
console.table(rows);
|
|
2274
|
-
}
|
|
2275
|
-
function timeAgo(dateStr) {
|
|
2276
|
-
const diff = Date.now() - new Date(dateStr).getTime();
|
|
2277
|
-
const s = Math.floor(diff / 1000);
|
|
2278
|
-
if (s < 0)
|
|
2279
|
-
return "just now";
|
|
2280
|
-
if (s < 60)
|
|
2281
|
-
return `${s}s ago`;
|
|
2282
|
-
const m = Math.floor(s / 60);
|
|
2283
|
-
if (m < 60)
|
|
2284
|
-
return `${m}m ago`;
|
|
2285
|
-
const h = Math.floor(m / 60);
|
|
2286
|
-
if (h < 24)
|
|
2287
|
-
return `${h}h ago`;
|
|
2288
|
-
const d = Math.floor(h / 24);
|
|
2289
|
-
if (d < 30)
|
|
2290
|
-
return `${d}d ago`;
|
|
2291
|
-
return `${Math.floor(d / 30)}mo ago`;
|
|
2292
|
-
}
|
|
2293
|
-
function formatDuration(seconds) {
|
|
2294
|
-
if (seconds < 60)
|
|
2295
|
-
return `${Math.floor(seconds)}s`;
|
|
2296
|
-
const m = Math.floor(seconds / 60);
|
|
2297
|
-
const s = Math.floor(seconds % 60);
|
|
2298
|
-
if (m < 60)
|
|
2299
|
-
return `${m}m ${s}s`;
|
|
2300
|
-
const h = Math.floor(m / 60);
|
|
2301
|
-
const rm = m % 60;
|
|
2302
|
-
return `${h}h ${rm}m`;
|
|
2303
|
-
}
|
|
2304
|
-
function formatBytes(bytes) {
|
|
2305
|
-
if (bytes < 1024)
|
|
2306
|
-
return `${bytes} B`;
|
|
2307
|
-
if (bytes < 1024 * 1024)
|
|
2308
|
-
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
2309
|
-
if (bytes < 1024 * 1024 * 1024)
|
|
2310
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2311
|
-
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
2312
|
-
}
|
|
2313
|
-
function formatStatus(status) {
|
|
2314
|
-
switch (status) {
|
|
2315
|
-
case "running":
|
|
2316
|
-
case "active":
|
|
2317
|
-
case "healthy":
|
|
2318
|
-
case "success":
|
|
2319
|
-
case "completed":
|
|
2320
|
-
return colors.green(status);
|
|
2321
|
-
case "stopped":
|
|
2322
|
-
case "inactive":
|
|
2323
|
-
case "terminated":
|
|
2324
|
-
case "failed":
|
|
2325
|
-
return colors.red(status);
|
|
2326
|
-
case "starting":
|
|
2327
|
-
case "stopping":
|
|
2328
|
-
case "pending":
|
|
2329
|
-
case "warning":
|
|
2330
|
-
return colors.yellow(status);
|
|
2331
|
-
case "error":
|
|
2332
|
-
return colors.red(status);
|
|
2333
|
-
default:
|
|
2334
|
-
return status;
|
|
2335
|
-
}
|
|
2336
|
-
}
|
|
2337
|
-
function formatNotificationType(type) {
|
|
2338
|
-
switch (type) {
|
|
2339
|
-
case "error":
|
|
2340
|
-
return colors.red("\u25CF");
|
|
2341
|
-
case "warning":
|
|
2342
|
-
return colors.yellow("\u25CF");
|
|
2343
|
-
case "success":
|
|
2344
|
-
return colors.green("\u25CF");
|
|
2345
|
-
case "info":
|
|
2346
|
-
default:
|
|
2347
|
-
return colors.blue("\u25CF");
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2350
|
-
function shortId(id, len = 10) {
|
|
2351
|
-
if (id.length <= len)
|
|
2352
|
-
return id;
|
|
2353
|
-
return id.substring(0, len) + "...";
|
|
2354
|
-
}
|
|
2355
|
-
async function printAgentDetails(agentUrl, maxWaitMs = 15000) {
|
|
2356
|
-
const startTime = Date.now();
|
|
2357
|
-
let healthy = false;
|
|
2358
|
-
while (Date.now() - startTime < maxWaitMs) {
|
|
2359
|
-
try {
|
|
2360
|
-
const res = await fetch(`${agentUrl}/health`);
|
|
2361
|
-
if (res.ok) {
|
|
2362
|
-
healthy = true;
|
|
2363
|
-
break;
|
|
2364
|
-
}
|
|
2365
|
-
} catch {}
|
|
2366
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
2367
|
-
}
|
|
2368
|
-
if (!healthy) {
|
|
2369
|
-
console.log(`
|
|
2370
|
-
${icons.warning} Agent not yet responding at ${agentUrl}. Check ${colors.bold("vibe logs")} for details.
|
|
2371
|
-
`);
|
|
2372
|
-
return;
|
|
2373
|
-
}
|
|
2374
|
-
let apiKey = "(unavailable)";
|
|
2375
|
-
try {
|
|
2376
|
-
const res = await fetch(`${agentUrl}/api/agent/api-key`);
|
|
2377
|
-
if (res.ok) {
|
|
2378
|
-
const data = await res.json();
|
|
2379
|
-
apiKey = data.apiKey;
|
|
2380
|
-
}
|
|
2381
|
-
} catch {}
|
|
2382
|
-
let tunnelUrl = "(not running)";
|
|
2383
|
-
let tunnelWaiting = false;
|
|
2384
|
-
try {
|
|
2385
|
-
const res = await fetch(`${agentUrl}/api/agent/tunnel`);
|
|
2386
|
-
if (res.ok) {
|
|
2387
|
-
const data = await res.json();
|
|
2388
|
-
if (data.tunnelUrl) {
|
|
2389
|
-
tunnelUrl = data.tunnelUrl;
|
|
2390
|
-
} else if (data.status !== "inactive") {
|
|
2391
|
-
tunnelWaiting = true;
|
|
2392
|
-
}
|
|
2393
|
-
}
|
|
2394
|
-
} catch {}
|
|
2395
|
-
if (tunnelWaiting || tunnelUrl === "(not running)") {
|
|
2396
|
-
const tunnelWaitMs = 20000;
|
|
2397
|
-
const tunnelStart = Date.now();
|
|
2398
|
-
while (Date.now() - tunnelStart < tunnelWaitMs) {
|
|
2399
|
-
try {
|
|
2400
|
-
const res = await fetch(`${agentUrl}/api/agent/tunnel`);
|
|
2401
|
-
if (res.ok) {
|
|
2402
|
-
const data = await res.json();
|
|
2403
|
-
if (data.tunnelUrl) {
|
|
2404
|
-
tunnelUrl = data.tunnelUrl;
|
|
2405
|
-
break;
|
|
2406
|
-
}
|
|
2407
|
-
}
|
|
2408
|
-
} catch {}
|
|
2409
|
-
await new Promise((r) => setTimeout(r, 1000));
|
|
2410
|
-
}
|
|
2411
|
-
}
|
|
2412
|
-
header("Agent Connection Details");
|
|
2413
|
-
kv("Agent URL:", agentUrl);
|
|
2414
|
-
kv("API Key:", apiKey);
|
|
2415
|
-
kv("Tunnel URL:", tunnelUrl === "(not running)" ? colors.yellow(tunnelUrl) : colors.green(tunnelUrl));
|
|
2416
|
-
blank();
|
|
2417
|
-
console.log(" Copy the API Key and Tunnel URL into the VibeControls UI agent configuration.");
|
|
2418
|
-
if (tunnelUrl === "(not running)") {
|
|
2419
|
-
console.log(` Start a tunnel manually: ${colors.bold(`vibe tunnel agent --start --agent-url ${agentUrl}`)}`);
|
|
2420
|
-
}
|
|
2421
|
-
blank();
|
|
2422
|
-
}
|
|
2423
|
-
// src/services/service-manager.ts
|
|
2424
|
-
import { spawn } from "child_process";
|
|
2425
|
-
import { promisify } from "util";
|
|
2426
|
-
import {
|
|
2427
|
-
existsSync,
|
|
2428
|
-
readFileSync,
|
|
2429
|
-
writeFileSync,
|
|
2430
|
-
mkdirSync,
|
|
2431
|
-
openSync,
|
|
2432
|
-
closeSync
|
|
2433
|
-
} from "fs";
|
|
2434
|
-
import { join, dirname } from "path";
|
|
2435
|
-
import { fileURLToPath } from "url";
|
|
2151
|
+
import { existsSync } from "fs";
|
|
2152
|
+
import { join } from "path";
|
|
2436
2153
|
import { homedir } from "os";
|
|
2437
|
-
import { exec } from "child_process";
|
|
2438
|
-
var execAsync = promisify(exec);
|
|
2439
|
-
var __filename2 = fileURLToPath(import.meta.url);
|
|
2440
|
-
var __dirname2 = dirname(__filename2);
|
|
2441
2154
|
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
constructor() {
|
|
2446
|
-
const configDir = join(homedir(), ".vibecontrols");
|
|
2447
|
-
this.registryPath = join(configDir, "agents.json");
|
|
2448
|
-
this.logsDir = join(configDir, "logs");
|
|
2449
|
-
mkdirSync(configDir, { recursive: true });
|
|
2450
|
-
mkdirSync(this.logsDir, { recursive: true });
|
|
2451
|
-
}
|
|
2452
|
-
async startDaemon(config) {
|
|
2453
|
-
const existing = await this.findProcessByName(config.name);
|
|
2454
|
-
if (existing && existing.status === "running") {
|
|
2455
|
-
console.log(`\u26A0\uFE0F Agent '${config.name}' is already running on port ${existing.port}`);
|
|
2456
|
-
return;
|
|
2457
|
-
}
|
|
2458
|
-
const logFile = join(this.logsDir, `${config.name}.log`);
|
|
2459
|
-
const logFd = openSync(logFile, "a");
|
|
2460
|
-
const indexPath = join(__dirname2, "..", "index.js");
|
|
2461
|
-
const child = spawn("bun", ["run", indexPath], {
|
|
2462
|
-
detached: true,
|
|
2463
|
-
stdio: ["ignore", logFd, logFd],
|
|
2464
|
-
env: {
|
|
2465
|
-
...process.env,
|
|
2466
|
-
PORT: config.port.toString(),
|
|
2467
|
-
DB_PATH: config.dbPath,
|
|
2468
|
-
NODE_ENV: "production"
|
|
2469
|
-
}
|
|
2470
|
-
});
|
|
2471
|
-
closeSync(logFd);
|
|
2472
|
-
child.unref();
|
|
2473
|
-
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
2474
|
-
const isRunning = await this.isProcessRunning(child.pid);
|
|
2475
|
-
if (!isRunning) {
|
|
2476
|
-
throw new Error(`Failed to start agent '${config.name}'`);
|
|
2477
|
-
}
|
|
2478
|
-
await this.saveProcessInfo(config.name, child.pid, config);
|
|
2479
|
-
console.log(`\uD83D\uDE80 Agent '${config.name}' started (PID: ${child.pid}, Port: ${config.port})`);
|
|
2480
|
-
}
|
|
2481
|
-
async stop(name) {
|
|
2482
|
-
const agentProcess = await this.findProcessByName(name);
|
|
2483
|
-
if (!agentProcess || agentProcess.status !== "running") {
|
|
2484
|
-
console.log(`\u26A0\uFE0F Agent '${name}' is not running`);
|
|
2485
|
-
return;
|
|
2486
|
-
}
|
|
2487
|
-
try {
|
|
2488
|
-
process.kill(agentProcess.pid, "SIGTERM");
|
|
2489
|
-
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
2490
|
-
const stillRunning = await this.isProcessRunning(agentProcess.pid);
|
|
2491
|
-
if (stillRunning) {
|
|
2492
|
-
process.kill(agentProcess.pid, "SIGKILL");
|
|
2493
|
-
}
|
|
2494
|
-
await this.updateProcessStatus(name, "stopped");
|
|
2495
|
-
console.log(`\u2705 Agent '${name}' stopped`);
|
|
2496
|
-
} catch (err) {
|
|
2497
|
-
throw new Error(`Failed to stop agent '${name}': ${err}`, { cause: err });
|
|
2498
|
-
}
|
|
2499
|
-
}
|
|
2500
|
-
async restart(name, config) {
|
|
2501
|
-
const existing = await this.findProcessByName(name);
|
|
2502
|
-
if (existing && existing.status === "running") {
|
|
2503
|
-
await this.stop(name);
|
|
2504
|
-
}
|
|
2505
|
-
await this.startDaemon(config);
|
|
2506
|
-
console.log(`\uD83D\uDD04 Agent '${name}' restarted`);
|
|
2507
|
-
}
|
|
2508
|
-
async kill(name) {
|
|
2509
|
-
const agentProcess = await this.findProcessByName(name);
|
|
2510
|
-
if (!agentProcess || agentProcess.status !== "running") {
|
|
2511
|
-
console.log(`\u26A0\uFE0F Agent '${name}' is not running`);
|
|
2512
|
-
return;
|
|
2513
|
-
}
|
|
2514
|
-
await this.killProcessTree(agentProcess.pid);
|
|
2515
|
-
await this.updateProcessStatus(name, "stopped");
|
|
2516
|
-
console.log(`\uD83D\uDC80 Agent '${name}' killed`);
|
|
2517
|
-
}
|
|
2518
|
-
async getStatus(name) {
|
|
2519
|
-
return this.findProcessByName(name);
|
|
2520
|
-
}
|
|
2521
|
-
async getStatusAll() {
|
|
2522
|
-
const registry = this.loadRegistry();
|
|
2523
|
-
const processes = [];
|
|
2524
|
-
for (const processInfo of registry) {
|
|
2525
|
-
const isRunning = await this.isProcessRunning(processInfo.pid);
|
|
2526
|
-
processes.push({
|
|
2527
|
-
...processInfo,
|
|
2528
|
-
status: isRunning ? "running" : "stopped"
|
|
2529
|
-
});
|
|
2530
|
-
}
|
|
2531
|
-
return processes;
|
|
2532
|
-
}
|
|
2533
|
-
async listInstances() {
|
|
2534
|
-
return this.getStatusAll();
|
|
2535
|
-
}
|
|
2536
|
-
async showLogs(name, options) {
|
|
2537
|
-
const logFile = join(this.logsDir, `${name}.log`);
|
|
2538
|
-
if (!existsSync(logFile)) {
|
|
2539
|
-
console.log(`No logs found for agent '${name}'`);
|
|
2540
|
-
return;
|
|
2541
|
-
}
|
|
2542
|
-
if (options.follow) {
|
|
2543
|
-
const tail = spawn("tail", [
|
|
2544
|
-
"-f",
|
|
2545
|
-
"-n",
|
|
2546
|
-
options.tail.toString(),
|
|
2547
|
-
logFile
|
|
2548
|
-
]);
|
|
2549
|
-
tail.stdout?.on("data", (data) => process.stdout.write(data));
|
|
2550
|
-
tail.stderr?.on("data", (data) => process.stderr.write(data));
|
|
2551
|
-
process.on("SIGINT", () => {
|
|
2552
|
-
tail.kill();
|
|
2553
|
-
process.exit(0);
|
|
2554
|
-
});
|
|
2555
|
-
} else {
|
|
2556
|
-
try {
|
|
2557
|
-
const { stdout } = await execAsync(`tail -n ${options.tail} "${logFile}"`);
|
|
2558
|
-
console.log(stdout);
|
|
2559
|
-
} catch (err) {
|
|
2560
|
-
console.error("Failed to read logs:", err);
|
|
2561
|
-
}
|
|
2562
|
-
}
|
|
2563
|
-
}
|
|
2564
|
-
async checkHealth(name) {
|
|
2565
|
-
const proc = await this.findProcessByName(name);
|
|
2566
|
-
if (!proc || proc.status !== "running") {
|
|
2567
|
-
return { healthy: false, details: { error: "Process not running" } };
|
|
2568
|
-
}
|
|
2155
|
+
// src/services/port-utils.ts
|
|
2156
|
+
function isPortAvailable(port, host = "0.0.0.0") {
|
|
2157
|
+
return new Promise((resolve) => {
|
|
2569
2158
|
try {
|
|
2570
|
-
const
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
healthy: false,
|
|
2576
|
-
details: {
|
|
2577
|
-
error: "Health check failed",
|
|
2578
|
-
message: err.message
|
|
2159
|
+
const server = Bun.listen({
|
|
2160
|
+
hostname: host,
|
|
2161
|
+
port,
|
|
2162
|
+
socket: {
|
|
2163
|
+
data() {}
|
|
2579
2164
|
}
|
|
2580
|
-
};
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
async setConfig(key, value) {
|
|
2584
|
-
const configFile = join(homedir(), ".vibecontrols", "config.json");
|
|
2585
|
-
let config = {};
|
|
2586
|
-
if (existsSync(configFile)) {
|
|
2587
|
-
config = JSON.parse(readFileSync(configFile, "utf8"));
|
|
2588
|
-
}
|
|
2589
|
-
config[key] = value;
|
|
2590
|
-
writeFileSync(configFile, JSON.stringify(config, null, 2));
|
|
2591
|
-
}
|
|
2592
|
-
async getConfig(key) {
|
|
2593
|
-
const configFile = join(homedir(), ".vibecontrols", "config.json");
|
|
2594
|
-
if (!existsSync(configFile))
|
|
2595
|
-
return key ? undefined : {};
|
|
2596
|
-
const config = JSON.parse(readFileSync(configFile, "utf8"));
|
|
2597
|
-
return key ? config[key] : config;
|
|
2598
|
-
}
|
|
2599
|
-
loadRegistry() {
|
|
2600
|
-
if (!existsSync(this.registryPath))
|
|
2601
|
-
return [];
|
|
2602
|
-
try {
|
|
2603
|
-
return JSON.parse(readFileSync(this.registryPath, "utf8"));
|
|
2604
|
-
} catch {
|
|
2605
|
-
return [];
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
saveRegistry(processes) {
|
|
2609
|
-
writeFileSync(this.registryPath, JSON.stringify(processes, null, 2));
|
|
2610
|
-
}
|
|
2611
|
-
async saveProcessInfo(name, pid, config) {
|
|
2612
|
-
const registry = this.loadRegistry();
|
|
2613
|
-
const filtered = registry.filter((p) => p.name !== name);
|
|
2614
|
-
filtered.push({
|
|
2615
|
-
name,
|
|
2616
|
-
pid,
|
|
2617
|
-
port: config.port,
|
|
2618
|
-
config,
|
|
2619
|
-
startTime: new Date().toISOString(),
|
|
2620
|
-
status: "running"
|
|
2621
|
-
});
|
|
2622
|
-
this.saveRegistry(filtered);
|
|
2623
|
-
}
|
|
2624
|
-
async updateProcessStatus(name, status) {
|
|
2625
|
-
const registry = this.loadRegistry();
|
|
2626
|
-
const proc = registry.find((p) => p.name === name);
|
|
2627
|
-
if (proc) {
|
|
2628
|
-
proc.status = status;
|
|
2629
|
-
this.saveRegistry(registry);
|
|
2630
|
-
}
|
|
2631
|
-
}
|
|
2632
|
-
async findProcessByName(name) {
|
|
2633
|
-
const registry = this.loadRegistry();
|
|
2634
|
-
const proc = registry.find((p) => p.name === name);
|
|
2635
|
-
if (!proc)
|
|
2636
|
-
return null;
|
|
2637
|
-
const isRunning = await this.isProcessRunning(proc.pid);
|
|
2638
|
-
proc.status = isRunning ? "running" : "stopped";
|
|
2639
|
-
return proc;
|
|
2640
|
-
}
|
|
2641
|
-
async isProcessRunning(pid) {
|
|
2642
|
-
try {
|
|
2643
|
-
process.kill(pid, 0);
|
|
2644
|
-
return true;
|
|
2645
|
-
} catch {
|
|
2646
|
-
return false;
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
async killProcessTree(pid) {
|
|
2650
|
-
try {
|
|
2651
|
-
process.kill(-pid, "SIGKILL");
|
|
2165
|
+
});
|
|
2166
|
+
server.stop(true);
|
|
2167
|
+
resolve(true);
|
|
2652
2168
|
} catch {
|
|
2653
|
-
|
|
2654
|
-
process.kill(pid, "SIGKILL");
|
|
2655
|
-
} catch {}
|
|
2169
|
+
resolve(false);
|
|
2656
2170
|
}
|
|
2657
|
-
}
|
|
2658
|
-
}
|
|
2659
|
-
|
|
2660
|
-
// src/services/port-utils.ts
|
|
2661
|
-
import { createServer } from "net";
|
|
2662
|
-
function isPortAvailable(port, host = "0.0.0.0") {
|
|
2663
|
-
return new Promise((resolve) => {
|
|
2664
|
-
const server = createServer();
|
|
2665
|
-
server.once("error", () => resolve(false));
|
|
2666
|
-
server.once("listening", () => {
|
|
2667
|
-
server.close(() => resolve(true));
|
|
2668
|
-
});
|
|
2669
|
-
server.listen(port, host);
|
|
2670
2171
|
});
|
|
2671
2172
|
}
|
|
2672
2173
|
async function findFreePortFrom(startPort, host = "0.0.0.0") {
|
|
@@ -2682,12 +2183,12 @@ async function findFreePortFrom(startPort, host = "0.0.0.0") {
|
|
|
2682
2183
|
|
|
2683
2184
|
// src/cli/commands/start.cmd.ts
|
|
2684
2185
|
function register(program2) {
|
|
2685
|
-
program2.command("start").description("Start a VibeControls agent instance").option("-p, --port <port>", "Port to listen on", "3005").option("-n, --name <name>", "Agent instance name", "default").option("-
|
|
2186
|
+
program2.command("start").description("Start a VibeControls agent instance").option("-p, --port <port>", "Port to listen on", "3005").option("-n, --name <name>", "Agent instance name", "default").option("-f, --foreground", "Run in foreground mode (default: daemon)", false).option("--db-path <path>", "Path to the SQLite database", "./vibecontrols-agent.db").option("--host <host>", "Host to bind to", "0.0.0.0").action(async (opts) => {
|
|
2686
2187
|
try {
|
|
2687
2188
|
const serviceManager = new ServiceManager;
|
|
2688
2189
|
const dbPath = opts.dbPath;
|
|
2689
|
-
const configDir =
|
|
2690
|
-
const firstRun = !
|
|
2190
|
+
const configDir = join(homedir(), ".vibecontrols");
|
|
2191
|
+
const firstRun = !existsSync(dbPath) && !existsSync(join(configDir, "agents.json"));
|
|
2691
2192
|
if (firstRun) {
|
|
2692
2193
|
info("First run detected \u2014 running setup...");
|
|
2693
2194
|
blank();
|
|
@@ -2720,47 +2221,49 @@ function register(program2) {
|
|
|
2720
2221
|
}
|
|
2721
2222
|
const host = opts.host;
|
|
2722
2223
|
const agentUrl = `http://${host === "0.0.0.0" ? "localhost" : host}:${port}`;
|
|
2723
|
-
if (opts.
|
|
2724
|
-
header("Starting agent in daemon mode");
|
|
2725
|
-
kv("Name", opts.name);
|
|
2726
|
-
kv("Port", String(port));
|
|
2727
|
-
kv("Host", host);
|
|
2728
|
-
kv("Database", dbPath);
|
|
2729
|
-
blank();
|
|
2730
|
-
await serviceManager.startDaemon({
|
|
2731
|
-
port,
|
|
2732
|
-
name: opts.name,
|
|
2733
|
-
daemon: true,
|
|
2734
|
-
dbPath,
|
|
2735
|
-
host
|
|
2736
|
-
});
|
|
2737
|
-
await printAgentDetails(agentUrl);
|
|
2738
|
-
} else {
|
|
2224
|
+
if (opts.foreground) {
|
|
2739
2225
|
header("Starting agent in foreground");
|
|
2740
2226
|
kv("Name", opts.name);
|
|
2741
2227
|
kv("Port", String(port));
|
|
2742
2228
|
kv("Host", host);
|
|
2743
2229
|
kv("Database", dbPath);
|
|
2744
2230
|
blank();
|
|
2745
|
-
const { createApp } = await import("./app-
|
|
2231
|
+
const { createApp } = await import("./app-sm6n9xst.js");
|
|
2746
2232
|
const appInstance = await createApp({
|
|
2747
2233
|
port,
|
|
2748
2234
|
host,
|
|
2749
2235
|
dbPath
|
|
2750
2236
|
});
|
|
2751
2237
|
await appInstance.start();
|
|
2238
|
+
await printAgentDetails(agentUrl);
|
|
2752
2239
|
const shutdown = async () => {
|
|
2753
2240
|
await appInstance.stop();
|
|
2754
2241
|
process.exit(0);
|
|
2755
2242
|
};
|
|
2756
2243
|
process.on("SIGTERM", shutdown);
|
|
2757
2244
|
process.on("SIGINT", shutdown);
|
|
2245
|
+
} else {
|
|
2246
|
+
header("Starting agent in daemon mode");
|
|
2247
|
+
kv("Name", opts.name);
|
|
2248
|
+
kv("Port", String(port));
|
|
2249
|
+
kv("Host", host);
|
|
2250
|
+
kv("Database", dbPath);
|
|
2251
|
+
blank();
|
|
2252
|
+
await serviceManager.startDaemon({
|
|
2253
|
+
port,
|
|
2254
|
+
name: opts.name,
|
|
2255
|
+
daemon: true,
|
|
2256
|
+
dbPath,
|
|
2257
|
+
host
|
|
2258
|
+
});
|
|
2259
|
+
await printAgentDetails(agentUrl);
|
|
2758
2260
|
}
|
|
2759
2261
|
} catch (err) {
|
|
2760
2262
|
fail(`Failed to start agent: ${err instanceof Error ? err.message : err}`);
|
|
2761
2263
|
}
|
|
2762
2264
|
});
|
|
2763
2265
|
}
|
|
2266
|
+
|
|
2764
2267
|
// src/cli/commands/stop.cmd.ts
|
|
2765
2268
|
function register2(program2) {
|
|
2766
2269
|
program2.command("stop").description("Stop a running VibeControls agent instance").option("-n, --name <name>", "Agent instance name", "default").option("--all", "Stop all running agent instances", false).action(async (opts) => {
|
|
@@ -2797,6 +2300,7 @@ function register2(program2) {
|
|
|
2797
2300
|
}
|
|
2798
2301
|
});
|
|
2799
2302
|
}
|
|
2303
|
+
|
|
2800
2304
|
// src/cli/commands/restart.cmd.ts
|
|
2801
2305
|
function register3(program2) {
|
|
2802
2306
|
program2.command("restart").description("Restart a running VibeControls agent instance").option("-n, --name <name>", "Agent instance name", "default").option("-p, --port <port>", "Port to listen on", "3005").option("--db-path <path>", "Path to the SQLite database", "./vibecontrols-agent.db").action(async (opts) => {
|
|
@@ -2838,54 +2342,49 @@ function register3(program2) {
|
|
|
2838
2342
|
}
|
|
2839
2343
|
});
|
|
2840
2344
|
}
|
|
2841
|
-
|
|
2345
|
+
|
|
2346
|
+
// src/cli/commands/kill.cmd.ts
|
|
2842
2347
|
function register4(program2) {
|
|
2843
|
-
program2.command("
|
|
2348
|
+
program2.command("kill").description("Force kill a VibeControls agent instance").option("-n, --name <name>", "Agent instance name", "default").option("--all", "Kill all agent instances", false).action(async (opts) => {
|
|
2844
2349
|
try {
|
|
2845
2350
|
const serviceManager = new ServiceManager;
|
|
2846
|
-
if (opts.
|
|
2847
|
-
header(
|
|
2351
|
+
if (opts.all) {
|
|
2352
|
+
header("Force killing all agent instances");
|
|
2848
2353
|
blank();
|
|
2849
|
-
const
|
|
2850
|
-
if (!
|
|
2851
|
-
|
|
2354
|
+
const instances = await serviceManager.listInstances();
|
|
2355
|
+
if (!instances || instances.length === 0) {
|
|
2356
|
+
info(`${icons.info} No agent instances found.`);
|
|
2852
2357
|
return;
|
|
2853
2358
|
}
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2359
|
+
let killed = 0;
|
|
2360
|
+
for (const instance of instances) {
|
|
2361
|
+
try {
|
|
2362
|
+
await serviceManager.kill(instance.name);
|
|
2363
|
+
success(`${icons.success} Killed ${colors.bold(instance.name)} (PID: ${instance.pid || "unknown"})`);
|
|
2364
|
+
killed++;
|
|
2365
|
+
} catch {
|
|
2366
|
+
warn(`${icons.warning} Could not kill ${colors.bold(instance.name)}`);
|
|
2367
|
+
}
|
|
2862
2368
|
}
|
|
2863
2369
|
blank();
|
|
2370
|
+
success(`${icons.success} Killed ${killed}/${instances.length} instance(s).`);
|
|
2864
2371
|
} else {
|
|
2865
|
-
header(
|
|
2372
|
+
header(`Force killing agent: ${opts.name}`);
|
|
2866
2373
|
blank();
|
|
2867
|
-
const
|
|
2868
|
-
if (!
|
|
2869
|
-
|
|
2870
|
-
info(`Run ${colors.bold("vibe start")} to start an agent.`);
|
|
2374
|
+
const instance = await serviceManager.getStatus(opts.name);
|
|
2375
|
+
if (!instance) {
|
|
2376
|
+
fail(`Agent instance ${colors.bold(opts.name)} not found.`);
|
|
2871
2377
|
return;
|
|
2872
2378
|
}
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
Status: formatStatus(inst.status),
|
|
2876
|
-
PID: inst.pid || "-",
|
|
2877
|
-
Port: inst.port || "-",
|
|
2878
|
-
Started: inst.startTime ? timeAgo(inst.startTime) : "-"
|
|
2879
|
-
}));
|
|
2880
|
-
formatTable(rows);
|
|
2881
|
-
blank();
|
|
2882
|
-
info(`${icons.info} ${instances.length} instance(s) found. Use ${colors.bold("vibe status -n <name>")} for details.`);
|
|
2379
|
+
await serviceManager.kill(opts.name);
|
|
2380
|
+
success(`${icons.success} Agent ${colors.bold(opts.name)} killed (PID: ${instance.pid || "unknown"}).`);
|
|
2883
2381
|
}
|
|
2884
2382
|
} catch (err) {
|
|
2885
|
-
fail(`Failed to
|
|
2383
|
+
fail(`Failed to kill agent: ${err.message}`);
|
|
2886
2384
|
}
|
|
2887
2385
|
});
|
|
2888
2386
|
}
|
|
2387
|
+
|
|
2889
2388
|
// src/cli/commands/list.cmd.ts
|
|
2890
2389
|
function register5(program2) {
|
|
2891
2390
|
program2.command("list").alias("ls").description("List all VibeControls agent instances").action(async () => {
|
|
@@ -2918,49 +2417,9 @@ function register5(program2) {
|
|
|
2918
2417
|
}
|
|
2919
2418
|
});
|
|
2920
2419
|
}
|
|
2921
|
-
|
|
2922
|
-
function register6(program2) {
|
|
2923
|
-
program2.command("kill").description("Force kill a VibeControls agent instance").option("-n, --name <name>", "Agent instance name", "default").option("--all", "Kill all agent instances", false).action(async (opts) => {
|
|
2924
|
-
try {
|
|
2925
|
-
const serviceManager = new ServiceManager;
|
|
2926
|
-
if (opts.all) {
|
|
2927
|
-
header("Force killing all agent instances");
|
|
2928
|
-
blank();
|
|
2929
|
-
const instances = await serviceManager.listInstances();
|
|
2930
|
-
if (!instances || instances.length === 0) {
|
|
2931
|
-
info(`${icons.info} No agent instances found.`);
|
|
2932
|
-
return;
|
|
2933
|
-
}
|
|
2934
|
-
let killed = 0;
|
|
2935
|
-
for (const instance of instances) {
|
|
2936
|
-
try {
|
|
2937
|
-
await serviceManager.kill(instance.name);
|
|
2938
|
-
success(`${icons.success} Killed ${colors.bold(instance.name)} (PID: ${instance.pid || "unknown"})`);
|
|
2939
|
-
killed++;
|
|
2940
|
-
} catch {
|
|
2941
|
-
warn(`${icons.warning} Could not kill ${colors.bold(instance.name)}`);
|
|
2942
|
-
}
|
|
2943
|
-
}
|
|
2944
|
-
blank();
|
|
2945
|
-
success(`${icons.success} Killed ${killed}/${instances.length} instance(s).`);
|
|
2946
|
-
} else {
|
|
2947
|
-
header(`Force killing agent: ${opts.name}`);
|
|
2948
|
-
blank();
|
|
2949
|
-
const instance = await serviceManager.getStatus(opts.name);
|
|
2950
|
-
if (!instance) {
|
|
2951
|
-
fail(`Agent instance ${colors.bold(opts.name)} not found.`);
|
|
2952
|
-
return;
|
|
2953
|
-
}
|
|
2954
|
-
await serviceManager.kill(opts.name);
|
|
2955
|
-
success(`${icons.success} Agent ${colors.bold(opts.name)} killed (PID: ${instance.pid || "unknown"}).`);
|
|
2956
|
-
}
|
|
2957
|
-
} catch (err) {
|
|
2958
|
-
fail(`Failed to kill agent: ${err.message}`);
|
|
2959
|
-
}
|
|
2960
|
-
});
|
|
2961
|
-
}
|
|
2420
|
+
|
|
2962
2421
|
// src/cli/commands/logs.cmd.ts
|
|
2963
|
-
function
|
|
2422
|
+
function register6(program2) {
|
|
2964
2423
|
program2.command("logs").description("View logs for a VibeControls agent instance").option("-n, --name <name>", "Agent instance name", "default").option("-f, --follow", "Follow log output", false).option("--tail <lines>", "Number of lines to show from the end", "100").action(async (opts) => {
|
|
2965
2424
|
try {
|
|
2966
2425
|
const serviceManager = new ServiceManager;
|
|
@@ -2989,134 +2448,13 @@ function register7(program2) {
|
|
|
2989
2448
|
}
|
|
2990
2449
|
});
|
|
2991
2450
|
}
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
function
|
|
2995
|
-
program2.command("
|
|
2451
|
+
|
|
2452
|
+
// src/cli/commands/setup.cmd.ts
|
|
2453
|
+
function register7(program2) {
|
|
2454
|
+
program2.command("setup").description("Install or verify system dependencies (tmux, ttyd, cloudflared)").option("--check", "Only check without installing", false).action(async (options) => {
|
|
2996
2455
|
try {
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
blank();
|
|
3000
|
-
const data = await apiGet(agentUrl, "/api/agent/api-key");
|
|
3001
|
-
kv("API Key", colors.bold(data.apiKey));
|
|
3002
|
-
blank();
|
|
3003
|
-
} catch (err) {
|
|
3004
|
-
fail(`Failed to get API key: ${err.message}`);
|
|
3005
|
-
}
|
|
3006
|
-
});
|
|
3007
|
-
}
|
|
3008
|
-
// src/cli/commands/health.cmd.ts
|
|
3009
|
-
var DEFAULT_AGENT_URL3 = "http://localhost:3005";
|
|
3010
|
-
function register9(program2) {
|
|
3011
|
-
program2.command("health").description("Check health of a VibeControls agent instance").option("-n, --name <name>", "Agent instance name").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL3).action(async (opts) => {
|
|
3012
|
-
try {
|
|
3013
|
-
header("Agent Health");
|
|
3014
|
-
blank();
|
|
3015
|
-
if (opts.name) {
|
|
3016
|
-
const serviceManager = new ServiceManager;
|
|
3017
|
-
const result = await serviceManager.checkHealth(opts.name);
|
|
3018
|
-
if (!result.healthy) {
|
|
3019
|
-
fail(`Agent instance ${colors.bold(opts.name)} is not responding.`);
|
|
3020
|
-
return;
|
|
3021
|
-
}
|
|
3022
|
-
const details = result.details;
|
|
3023
|
-
kv("Instance", opts.name);
|
|
3024
|
-
kv("Status", formatStatus(details.status ?? "healthy"));
|
|
3025
|
-
if (details.uptime !== undefined) {
|
|
3026
|
-
kv("Uptime", `${details.uptime}s`);
|
|
3027
|
-
}
|
|
3028
|
-
if (details.checks) {
|
|
3029
|
-
blank();
|
|
3030
|
-
info(`${icons.info} Health checks:`);
|
|
3031
|
-
for (const [name, check] of Object.entries(details.checks)) {
|
|
3032
|
-
const icon = check.status === "healthy" ? icons.success : icons.error;
|
|
3033
|
-
kv(` ${icon} ${name}`, formatStatus(check.status));
|
|
3034
|
-
}
|
|
3035
|
-
}
|
|
3036
|
-
} else {
|
|
3037
|
-
const agentUrl = getAgentUrl(opts);
|
|
3038
|
-
const data = await apiGet(agentUrl, "/health");
|
|
3039
|
-
kv("URL", agentUrl);
|
|
3040
|
-
kv("Status", formatStatus(data.status));
|
|
3041
|
-
if (data.version) {
|
|
3042
|
-
kv("Version", data.version);
|
|
3043
|
-
}
|
|
3044
|
-
if (data.uptime !== undefined) {
|
|
3045
|
-
kv("Uptime", `${data.uptime}s`);
|
|
3046
|
-
}
|
|
3047
|
-
if (data.timestamp) {
|
|
3048
|
-
kv("Timestamp", data.timestamp);
|
|
3049
|
-
}
|
|
3050
|
-
if (data.checks) {
|
|
3051
|
-
blank();
|
|
3052
|
-
info(`${icons.info} Health checks:`);
|
|
3053
|
-
for (const [name, check] of Object.entries(data.checks)) {
|
|
3054
|
-
const icon = check.status === "healthy" ? icons.success : icons.error;
|
|
3055
|
-
kv(` ${icon} ${name}`, formatStatus(check.status));
|
|
3056
|
-
}
|
|
3057
|
-
}
|
|
3058
|
-
}
|
|
3059
|
-
blank();
|
|
3060
|
-
success(`${icons.success} Agent is healthy.`);
|
|
3061
|
-
} catch (err) {
|
|
3062
|
-
fail(`Health check failed: ${err.message}`);
|
|
3063
|
-
}
|
|
3064
|
-
});
|
|
3065
|
-
}
|
|
3066
|
-
// src/cli/commands/info.cmd.ts
|
|
3067
|
-
import { platform, arch, release, hostname, cpus, totalmem } from "os";
|
|
3068
|
-
var DEFAULT_AGENT_URL4 = "http://localhost:3005";
|
|
3069
|
-
function register10(program2) {
|
|
3070
|
-
program2.command("info").description("Show local and remote VibeControls agent information").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL4).action(async (opts) => {
|
|
3071
|
-
try {
|
|
3072
|
-
header("VibeControls Agent Info");
|
|
3073
|
-
blank();
|
|
3074
|
-
info(`${icons.info} Local System`);
|
|
3075
|
-
kv("Hostname", hostname());
|
|
3076
|
-
kv("Platform", `${platform()} ${arch()}`);
|
|
3077
|
-
kv("OS Release", release());
|
|
3078
|
-
kv("CPUs", String(cpus().length));
|
|
3079
|
-
kv("Total Memory", formatBytes(totalmem()));
|
|
3080
|
-
kv("Node.js", process.version);
|
|
3081
|
-
if (process.versions.bun) {
|
|
3082
|
-
kv("Bun", process.versions.bun);
|
|
3083
|
-
}
|
|
3084
|
-
blank();
|
|
3085
|
-
const agentUrl = getAgentUrl(opts);
|
|
3086
|
-
try {
|
|
3087
|
-
const data = await apiGet(agentUrl, "/api/agent/version");
|
|
3088
|
-
info(`${icons.info} Remote Agent`);
|
|
3089
|
-
kv("URL", agentUrl);
|
|
3090
|
-
kv("Version", colors.bold(data.version));
|
|
3091
|
-
if (data.build) {
|
|
3092
|
-
kv("Build", data.build);
|
|
3093
|
-
}
|
|
3094
|
-
if (data.commit) {
|
|
3095
|
-
kv("Commit", data.commit);
|
|
3096
|
-
}
|
|
3097
|
-
if (data.nodeVersion) {
|
|
3098
|
-
kv("Node.js (remote)", data.nodeVersion);
|
|
3099
|
-
}
|
|
3100
|
-
if (data.bunVersion) {
|
|
3101
|
-
kv("Bun (remote)", data.bunVersion);
|
|
3102
|
-
}
|
|
3103
|
-
} catch {
|
|
3104
|
-
info(`${icons.info} Remote Agent`);
|
|
3105
|
-
kv("URL", agentUrl);
|
|
3106
|
-
kv("Status", colors.dim("not reachable"));
|
|
3107
|
-
}
|
|
3108
|
-
blank();
|
|
3109
|
-
} catch (err) {
|
|
3110
|
-
fail(`Failed to get info: ${err.message}`);
|
|
3111
|
-
}
|
|
3112
|
-
});
|
|
3113
|
-
}
|
|
3114
|
-
// src/cli/commands/setup.cmd.ts
|
|
3115
|
-
function register11(program2) {
|
|
3116
|
-
program2.command("setup").description("Install or verify system dependencies (tmux, ttyd, cloudflared)").option("--check", "Only check without installing", false).action(async (options) => {
|
|
3117
|
-
try {
|
|
3118
|
-
header("VibeControls Agent Setup");
|
|
3119
|
-
info("Checking dependencies...");
|
|
2456
|
+
header("VibeControls Agent Setup");
|
|
2457
|
+
info("Checking dependencies...");
|
|
3120
2458
|
blank();
|
|
3121
2459
|
const deps = checkDependencies();
|
|
3122
2460
|
const missing = [];
|
|
@@ -3154,17 +2492,17 @@ function register11(program2) {
|
|
|
3154
2492
|
}
|
|
3155
2493
|
});
|
|
3156
2494
|
}
|
|
2495
|
+
|
|
3157
2496
|
// src/cli/commands/update.cmd.ts
|
|
3158
|
-
import { execSync } from "child_process";
|
|
3159
2497
|
var PACKAGE_NAME = "vibecontrols-agent";
|
|
3160
|
-
function
|
|
2498
|
+
function register8(program2) {
|
|
3161
2499
|
program2.command("update").description("Check for and install VibeControls agent updates").option("--check", "Only check for updates without installing", false).action(async (opts) => {
|
|
3162
2500
|
try {
|
|
3163
2501
|
header("VibeControls Agent Update");
|
|
3164
2502
|
blank();
|
|
3165
2503
|
let currentVersion;
|
|
3166
2504
|
try {
|
|
3167
|
-
const pkg = await import("./package-
|
|
2505
|
+
const pkg = await import("./package-04nkt49b.js", {
|
|
3168
2506
|
with: { type: "json" }
|
|
3169
2507
|
});
|
|
3170
2508
|
currentVersion = pkg.default.version || pkg.version;
|
|
@@ -3175,9 +2513,10 @@ function register12(program2) {
|
|
|
3175
2513
|
blank();
|
|
3176
2514
|
let latestVersion;
|
|
3177
2515
|
try {
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
2516
|
+
const result = Bun.spawnSync(["npm", "view", PACKAGE_NAME, "version"], { stdout: "pipe", stderr: "pipe" });
|
|
2517
|
+
if (result.exitCode !== 0)
|
|
2518
|
+
throw new Error("npm view failed");
|
|
2519
|
+
latestVersion = result.stdout.toString().trim();
|
|
3181
2520
|
} catch {
|
|
3182
2521
|
fail(`Could not check for updates. Ensure you have internet connectivity and npm is available.`);
|
|
3183
2522
|
return;
|
|
@@ -3197,10 +2536,9 @@ function register12(program2) {
|
|
|
3197
2536
|
info(`${icons.info} Updating to ${colors.bold(latestVersion)}...`);
|
|
3198
2537
|
blank();
|
|
3199
2538
|
try {
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
});
|
|
2539
|
+
const installResult = Bun.spawnSync(["npm", "install", "-g", `${PACKAGE_NAME}@${latestVersion}`], { stdout: "inherit", stderr: "inherit" });
|
|
2540
|
+
if (installResult.exitCode !== 0)
|
|
2541
|
+
throw new Error("install failed");
|
|
3204
2542
|
} catch {
|
|
3205
2543
|
fail(`Failed to install update. Try running with sudo: ${colors.bold(`sudo npm install -g ${PACKAGE_NAME}@${latestVersion}`)}`);
|
|
3206
2544
|
return;
|
|
@@ -3213,1221 +2551,17 @@ function register12(program2) {
|
|
|
3213
2551
|
}
|
|
3214
2552
|
});
|
|
3215
2553
|
}
|
|
3216
|
-
|
|
3217
|
-
var DEFAULT_AGENT_URL5 = "http://localhost:3005";
|
|
3218
|
-
function register13(program2) {
|
|
3219
|
-
program2.command("system").description("Show system information for a running VibeControls agent").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL5).action(async (opts) => {
|
|
3220
|
-
try {
|
|
3221
|
-
const agentUrl = getAgentUrl(opts);
|
|
3222
|
-
header("Agent System Information");
|
|
3223
|
-
blank();
|
|
3224
|
-
const data = await apiGet(agentUrl, "/api/agent/system");
|
|
3225
|
-
info(`${icons.info} Agent`);
|
|
3226
|
-
kv("Version", colors.bold(data.agentVersion));
|
|
3227
|
-
if (data.bunVersion) {
|
|
3228
|
-
kv("Bun", data.bunVersion);
|
|
3229
|
-
}
|
|
3230
|
-
if (data.environment) {
|
|
3231
|
-
kv("Environment", data.environment);
|
|
3232
|
-
}
|
|
3233
|
-
kv("Uptime", formatDuration(data.uptime));
|
|
3234
|
-
blank();
|
|
3235
|
-
info(`${icons.info} Platform`);
|
|
3236
|
-
kv("OS", `${data.platform} ${data.arch}`);
|
|
3237
|
-
kv("Hostname", data.hostname);
|
|
3238
|
-
kv("Release", data.release);
|
|
3239
|
-
blank();
|
|
3240
|
-
info(`${icons.info} Resources`);
|
|
3241
|
-
kv("CPUs", String(data.cpus));
|
|
3242
|
-
kv("Total Memory", formatBytes(data.totalMemory));
|
|
3243
|
-
kv("Free Memory", formatBytes(data.freeMemory));
|
|
3244
|
-
blank();
|
|
3245
|
-
info(`${icons.info} Paths`);
|
|
3246
|
-
kv("Home", data.homeDir);
|
|
3247
|
-
kv("CWD", data.cwd);
|
|
3248
|
-
blank();
|
|
3249
|
-
} catch (err) {
|
|
3250
|
-
fail(`Failed to get system info: ${err.message}`);
|
|
3251
|
-
}
|
|
3252
|
-
});
|
|
3253
|
-
}
|
|
3254
|
-
// src/cli/commands/url.cmd.ts
|
|
3255
|
-
var DEFAULT_AGENT_URL6 = "http://localhost:3005";
|
|
3256
|
-
function register14(program2) {
|
|
3257
|
-
program2.command("url").description("Show the active URL for a running VibeControls agent").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL6).action(async (opts) => {
|
|
3258
|
-
try {
|
|
3259
|
-
const agentUrl = getAgentUrl(opts);
|
|
3260
|
-
header("Agent URL");
|
|
3261
|
-
blank();
|
|
3262
|
-
const data = await apiGet(agentUrl, "/api/agent/url");
|
|
3263
|
-
kv("Active URL", colors.bold(data.url));
|
|
3264
|
-
kv("Local URL", data.localUrl);
|
|
3265
|
-
if (data.tunnelUrl) {
|
|
3266
|
-
kv("Tunnel URL", colors.cyan(data.tunnelUrl));
|
|
3267
|
-
}
|
|
3268
|
-
kv("Mode", data.isTunnel ? `${icons.running} Tunnel active` : `${icons.info} Local only`);
|
|
3269
|
-
blank();
|
|
3270
|
-
if (data.isTunnel) {
|
|
3271
|
-
info(`${icons.info} Agent is accessible via tunnel at ${colors.bold(data.tunnelUrl)}`);
|
|
3272
|
-
} else {
|
|
3273
|
-
info(`${icons.info} Agent is running locally at ${colors.bold(data.localUrl)}`);
|
|
3274
|
-
}
|
|
3275
|
-
} catch (err) {
|
|
3276
|
-
fail(`Failed to get URL: ${err.message}`);
|
|
3277
|
-
}
|
|
3278
|
-
});
|
|
3279
|
-
}
|
|
3280
|
-
// src/cli/commands/config.cmd.ts
|
|
3281
|
-
var DEFAULT_AGENT_URL7 = "http://localhost:3005";
|
|
3282
|
-
function register15(program2) {
|
|
3283
|
-
program2.command("config").description("Manage VibeControls agent configuration").option("--set <key=value>", "Set a configuration value").option("--get <key>", "Get a configuration value").option("--delete <key>", "Delete a configuration value").option("--list", "List all configuration values", false).option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL7).action(async (opts) => {
|
|
3284
|
-
try {
|
|
3285
|
-
const agentUrl = getAgentUrl(opts);
|
|
3286
|
-
if (opts.set) {
|
|
3287
|
-
const eqIndex = opts.set.indexOf("=");
|
|
3288
|
-
if (eqIndex === -1) {
|
|
3289
|
-
fail(`Invalid format. Use ${colors.bold("--set key=value")}`);
|
|
3290
|
-
return;
|
|
3291
|
-
}
|
|
3292
|
-
const key = opts.set.slice(0, eqIndex).trim();
|
|
3293
|
-
const value = opts.set.slice(eqIndex + 1).trim();
|
|
3294
|
-
if (!key) {
|
|
3295
|
-
fail("Configuration key cannot be empty.");
|
|
3296
|
-
return;
|
|
3297
|
-
}
|
|
3298
|
-
try {
|
|
3299
|
-
await apiPut(agentUrl, `/api/config/${encodeURIComponent(key)}`, {
|
|
3300
|
-
value
|
|
3301
|
-
});
|
|
3302
|
-
} catch {
|
|
3303
|
-
await apiPost(agentUrl, "/api/config/", { key, value });
|
|
3304
|
-
}
|
|
3305
|
-
success(`${icons.success} Set ${colors.bold(key)} = ${colors.cyan(value)}`);
|
|
3306
|
-
} else if (opts.get) {
|
|
3307
|
-
header("Configuration");
|
|
3308
|
-
blank();
|
|
3309
|
-
const data = await apiGet(agentUrl, `/api/config/${encodeURIComponent(opts.get)}`);
|
|
3310
|
-
kv(data.key, colors.bold(data.value));
|
|
3311
|
-
blank();
|
|
3312
|
-
} else if (opts.delete) {
|
|
3313
|
-
await apiDelete(agentUrl, `/api/config/${encodeURIComponent(opts.delete)}`);
|
|
3314
|
-
success(`${icons.success} Deleted configuration key: ${colors.bold(opts.delete)}`);
|
|
3315
|
-
} else if (opts.list) {
|
|
3316
|
-
header("Agent Configuration");
|
|
3317
|
-
blank();
|
|
3318
|
-
const data = await apiGet(agentUrl, "/api/config/");
|
|
3319
|
-
if (!data.configs || data.configs.length === 0) {
|
|
3320
|
-
info(`${icons.info} No configuration entries found.`);
|
|
3321
|
-
return;
|
|
3322
|
-
}
|
|
3323
|
-
const rows = data.configs.map((c) => ({
|
|
3324
|
-
Key: c.key,
|
|
3325
|
-
Value: c.value
|
|
3326
|
-
}));
|
|
3327
|
-
formatTable(rows);
|
|
3328
|
-
blank();
|
|
3329
|
-
info(`${icons.info} ${data.configs.length} configuration(s) found.`);
|
|
3330
|
-
} else {
|
|
3331
|
-
info(`${icons.info} Usage:`);
|
|
3332
|
-
info(` ${colors.bold("vibe config --list")} List all config values`);
|
|
3333
|
-
info(` ${colors.bold("vibe config --get <key>")} Get a config value`);
|
|
3334
|
-
info(` ${colors.bold("vibe config --set <key=value>")} Set a config value`);
|
|
3335
|
-
info(` ${colors.bold("vibe config --delete <key>")} Delete a config value`);
|
|
3336
|
-
}
|
|
3337
|
-
} catch (err) {
|
|
3338
|
-
fail(`Config operation failed: ${err.message}`);
|
|
3339
|
-
}
|
|
3340
|
-
});
|
|
3341
|
-
}
|
|
3342
|
-
// src/cli/commands/gateway-auth.cmd.ts
|
|
3343
|
-
var DEFAULT_AGENT_URL8 = "http://localhost:3005";
|
|
3344
|
-
function register16(program2) {
|
|
3345
|
-
const gatewayAuth = program2.command("gateway-auth").description("Manage gateway authentication for VibeControls agent");
|
|
3346
|
-
gatewayAuth.command("configure").description("Configure gateway authentication credentials").requiredOption("--global-url <url>", "Global gateway URL").requiredOption("--workspace-url <url>", "Workspace gateway URL").requiredOption("--client-id <id>", "OAuth client ID").requiredOption("--client-secret <secret>", "OAuth client secret").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL8).action(async (opts) => {
|
|
3347
|
-
try {
|
|
3348
|
-
const agentUrl = getAgentUrl(opts);
|
|
3349
|
-
header("Configure Gateway Authentication");
|
|
3350
|
-
blank();
|
|
3351
|
-
info(`${icons.info} Sending gateway auth configuration...`);
|
|
3352
|
-
blank();
|
|
3353
|
-
const data = await apiPost(agentUrl, "/api/agent/gateway-auth", {
|
|
3354
|
-
globalUrl: opts.globalUrl,
|
|
3355
|
-
workspaceUrl: opts.workspaceUrl,
|
|
3356
|
-
clientId: opts.clientId,
|
|
3357
|
-
clientSecret: opts.clientSecret
|
|
3358
|
-
});
|
|
3359
|
-
if (data.success) {
|
|
3360
|
-
success(`${icons.success} Gateway authentication configured successfully.`);
|
|
3361
|
-
blank();
|
|
3362
|
-
kv("Global URL", opts.globalUrl);
|
|
3363
|
-
kv("Workspace URL", opts.workspaceUrl);
|
|
3364
|
-
kv("Client ID", opts.clientId);
|
|
3365
|
-
kv("Client Secret", colors.dim("********"));
|
|
3366
|
-
} else {
|
|
3367
|
-
fail(data.message || "Failed to configure gateway authentication.");
|
|
3368
|
-
}
|
|
3369
|
-
blank();
|
|
3370
|
-
} catch (err) {
|
|
3371
|
-
fail(`Failed to configure gateway auth: ${err.message}`);
|
|
3372
|
-
}
|
|
3373
|
-
});
|
|
3374
|
-
gatewayAuth.command("status").description("Check gateway authentication status").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL8).action(async (opts) => {
|
|
3375
|
-
try {
|
|
3376
|
-
const agentUrl = getAgentUrl(opts);
|
|
3377
|
-
header("Gateway Authentication Status");
|
|
3378
|
-
blank();
|
|
3379
|
-
const data = await apiGet(agentUrl, "/api/agent/gateway-auth");
|
|
3380
|
-
kv("Configured", data.configured ? `${icons.success} ${colors.green("Yes")}` : `${icons.error} ${colors.red("No")}`);
|
|
3381
|
-
if (data.configured) {
|
|
3382
|
-
kv("Global URL", data.globalUrl || colors.dim("n/a"));
|
|
3383
|
-
kv("Workspace URL", data.workspaceUrl || colors.dim("n/a"));
|
|
3384
|
-
kv("Client ID", data.clientId || colors.dim("n/a"));
|
|
3385
|
-
kv("Authenticated", data.authenticated ? `${icons.success} ${colors.green("Yes")}` : `${icons.error} ${colors.red("No")}`);
|
|
3386
|
-
if (data.tokenExpiresAt) {
|
|
3387
|
-
kv("Token Expires", data.tokenExpiresAt);
|
|
3388
|
-
}
|
|
3389
|
-
} else {
|
|
3390
|
-
blank();
|
|
3391
|
-
info(`${icons.info} Run ${colors.bold("vibe gateway-auth configure")} to set up gateway authentication.`);
|
|
3392
|
-
}
|
|
3393
|
-
blank();
|
|
3394
|
-
} catch (err) {
|
|
3395
|
-
fail(`Failed to get gateway auth status: ${err.message}`);
|
|
3396
|
-
}
|
|
3397
|
-
});
|
|
3398
|
-
}
|
|
3399
|
-
// src/cli/commands/session.cmd.ts
|
|
3400
|
-
var DEFAULT_AGENT_URL9 = "http://localhost:3005";
|
|
3401
|
-
function register17(program2) {
|
|
3402
|
-
const cmd = program2.command("session").description("Manage terminal sessions");
|
|
3403
|
-
cmd.command("list").description("List all sessions").option("--system", "Show system sessions instead of user sessions").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3404
|
-
try {
|
|
3405
|
-
const url = getAgentUrl(options);
|
|
3406
|
-
const endpoint = options.system ? "/api/sessions?system=true" : "/api/sessions";
|
|
3407
|
-
const sessions = await apiGet(url, endpoint);
|
|
3408
|
-
if (!sessions || sessions.length === 0) {
|
|
3409
|
-
info("No sessions found.");
|
|
3410
|
-
return;
|
|
3411
|
-
}
|
|
3412
|
-
header("Sessions");
|
|
3413
|
-
formatTable(sessions.map((s) => ({
|
|
3414
|
-
ID: shortId(s.id),
|
|
3415
|
-
Name: s.name || "-",
|
|
3416
|
-
Status: formatStatus(s.status),
|
|
3417
|
-
Port: s.port ?? "-",
|
|
3418
|
-
Project: s.project || s.projectId || "-"
|
|
3419
|
-
})));
|
|
3420
|
-
} catch (err) {
|
|
3421
|
-
fail(err.message);
|
|
3422
|
-
}
|
|
3423
|
-
});
|
|
3424
|
-
cmd.command("create").description("Create a new session").requiredOption("--name <name>", "Session name").option("--project <id>", "Project ID", "default").option("--command <cmd>", "Initial command to run").option("--cwd <dir>", "Working directory").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3425
|
-
try {
|
|
3426
|
-
const url = getAgentUrl(options);
|
|
3427
|
-
const body = {
|
|
3428
|
-
name: options.name,
|
|
3429
|
-
project: options.project
|
|
3430
|
-
};
|
|
3431
|
-
if (options.command)
|
|
3432
|
-
body.command = options.command;
|
|
3433
|
-
if (options.cwd)
|
|
3434
|
-
body.cwd = options.cwd;
|
|
3435
|
-
const result = await apiPost(url, "/api/sessions/create", body);
|
|
3436
|
-
success(`Session created: ${shortId(result.id || result.sessionId)}`);
|
|
3437
|
-
kv("Name", options.name);
|
|
3438
|
-
kv("Project", options.project);
|
|
3439
|
-
} catch (err) {
|
|
3440
|
-
fail(err.message);
|
|
3441
|
-
}
|
|
3442
|
-
});
|
|
3443
|
-
cmd.command("kill").description("Kill a session").requiredOption("-i, --id <id>", "Session ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3444
|
-
try {
|
|
3445
|
-
const url = getAgentUrl(options);
|
|
3446
|
-
await apiDelete(url, `/api/sessions/${options.id}`);
|
|
3447
|
-
success(`Session ${shortId(options.id)} killed.`);
|
|
3448
|
-
} catch (err) {
|
|
3449
|
-
fail(err.message);
|
|
3450
|
-
}
|
|
3451
|
-
});
|
|
3452
|
-
cmd.command("exec").description("Execute a command in a session").requiredOption("-i, --id <id>", "Session ID").requiredOption("-c, --command <cmd>", "Command to execute").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3453
|
-
try {
|
|
3454
|
-
const url = getAgentUrl(options);
|
|
3455
|
-
const result = await apiPost(url, `/api/sessions/${options.id}/command`, { command: options.command });
|
|
3456
|
-
success("Command executed.");
|
|
3457
|
-
if (result?.output) {
|
|
3458
|
-
blank();
|
|
3459
|
-
console.log(result.output);
|
|
3460
|
-
}
|
|
3461
|
-
} catch (err) {
|
|
3462
|
-
fail(err.message);
|
|
3463
|
-
}
|
|
3464
|
-
});
|
|
3465
|
-
cmd.command("capture").description("Capture session terminal output").requiredOption("-i, --id <id>", "Session ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3466
|
-
try {
|
|
3467
|
-
const url = getAgentUrl(options);
|
|
3468
|
-
const result = await apiGet(url, `/api/sessions/${options.id}/capture`);
|
|
3469
|
-
if (result?.content || result?.output) {
|
|
3470
|
-
console.log(result.content || result.output);
|
|
3471
|
-
} else {
|
|
3472
|
-
info("No capture data available.");
|
|
3473
|
-
}
|
|
3474
|
-
} catch (err) {
|
|
3475
|
-
fail(err.message);
|
|
3476
|
-
}
|
|
3477
|
-
});
|
|
3478
|
-
cmd.command("keys").description("Send keys to a session").requiredOption("-i, --id <id>", "Session ID").requiredOption("-k, --keys <keys>", "Keys to send").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3479
|
-
try {
|
|
3480
|
-
const url = getAgentUrl(options);
|
|
3481
|
-
await apiPost(url, `/api/sessions/${options.id}/keys`, {
|
|
3482
|
-
keys: options.keys
|
|
3483
|
-
});
|
|
3484
|
-
success("Keys sent.");
|
|
3485
|
-
} catch (err) {
|
|
3486
|
-
fail(err.message);
|
|
3487
|
-
}
|
|
3488
|
-
});
|
|
3489
|
-
cmd.command("interrupt").description("Send interrupt signal to a session").requiredOption("-i, --id <id>", "Session ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3490
|
-
try {
|
|
3491
|
-
const url = getAgentUrl(options);
|
|
3492
|
-
await apiPost(url, `/api/sessions/${options.id}/interrupt`, {});
|
|
3493
|
-
success(`Session ${shortId(options.id)} interrupted.`);
|
|
3494
|
-
} catch (err) {
|
|
3495
|
-
fail(err.message);
|
|
3496
|
-
}
|
|
3497
|
-
});
|
|
3498
|
-
cmd.command("rename").description("Rename a session").requiredOption("-i, --id <id>", "Session ID").requiredOption("--name <name>", "New session name").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3499
|
-
try {
|
|
3500
|
-
const url = getAgentUrl(options);
|
|
3501
|
-
await apiPut(url, `/api/sessions/${options.id}/rename`, {
|
|
3502
|
-
name: options.name
|
|
3503
|
-
});
|
|
3504
|
-
success(`Session ${shortId(options.id)} renamed to "${options.name}".`);
|
|
3505
|
-
} catch (err) {
|
|
3506
|
-
fail(err.message);
|
|
3507
|
-
}
|
|
3508
|
-
});
|
|
3509
|
-
cmd.command("toggle-mouse").description("Toggle mouse support in a session").requiredOption("-i, --id <id>", "Session ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3510
|
-
try {
|
|
3511
|
-
const url = getAgentUrl(options);
|
|
3512
|
-
const result = await apiPost(url, `/api/sessions/${options.id}/toggle-mouse`, {});
|
|
3513
|
-
success(`Mouse support ${result?.mouseEnabled ? "enabled" : "toggled"} for session ${shortId(options.id)}.`);
|
|
3514
|
-
} catch (err) {
|
|
3515
|
-
fail(err.message);
|
|
3516
|
-
}
|
|
3517
|
-
});
|
|
3518
|
-
cmd.command("terminal-start").description("Start terminal for a session").requiredOption("-i, --id <id>", "Session ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3519
|
-
try {
|
|
3520
|
-
const url = getAgentUrl(options);
|
|
3521
|
-
const result = await apiPost(url, `/api/sessions/${options.id}/terminal`, {});
|
|
3522
|
-
success(`Terminal started for session ${shortId(options.id)}.`);
|
|
3523
|
-
if (result?.port)
|
|
3524
|
-
kv("Port", result.port);
|
|
3525
|
-
} catch (err) {
|
|
3526
|
-
fail(err.message);
|
|
3527
|
-
}
|
|
3528
|
-
});
|
|
3529
|
-
cmd.command("terminal-stop").description("Stop terminal for a session").requiredOption("-i, --id <id>", "Session ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3530
|
-
try {
|
|
3531
|
-
const url = getAgentUrl(options);
|
|
3532
|
-
await apiPost(url, `/api/sessions/${options.id}/terminal/stop`, {});
|
|
3533
|
-
success(`Terminal stopped for session ${shortId(options.id)}.`);
|
|
3534
|
-
} catch (err) {
|
|
3535
|
-
fail(err.message);
|
|
3536
|
-
}
|
|
3537
|
-
});
|
|
3538
|
-
cmd.command("health-check").description("Run health check on all sessions").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL9).action(async (options) => {
|
|
3539
|
-
try {
|
|
3540
|
-
const url = getAgentUrl(options);
|
|
3541
|
-
const result = await apiPost(url, "/api/sessions/health-check", {});
|
|
3542
|
-
success("Health check completed.");
|
|
3543
|
-
if (result?.healthy !== undefined)
|
|
3544
|
-
kv("Healthy", result.healthy);
|
|
3545
|
-
if (result?.checked !== undefined)
|
|
3546
|
-
kv("Checked", result.checked);
|
|
3547
|
-
if (result?.fixed !== undefined)
|
|
3548
|
-
kv("Fixed", result.fixed);
|
|
3549
|
-
} catch (err) {
|
|
3550
|
-
fail(err.message);
|
|
3551
|
-
}
|
|
3552
|
-
});
|
|
3553
|
-
}
|
|
3554
|
-
// src/cli/commands/tunnel.cmd.ts
|
|
3555
|
-
var DEFAULT_AGENT_URL10 = "http://localhost:3005";
|
|
3556
|
-
function register18(program2) {
|
|
3557
|
-
const cmd = program2.command("tunnel").description("Manage tunnels for exposing local ports");
|
|
3558
|
-
cmd.command("list").description("List all tunnels").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL10).action(async (options) => {
|
|
3559
|
-
try {
|
|
3560
|
-
const url = getAgentUrl(options);
|
|
3561
|
-
const tunnels = await apiGet(url, "/api/tunnels");
|
|
3562
|
-
if (!tunnels || tunnels.length === 0) {
|
|
3563
|
-
info("No tunnels found.");
|
|
3564
|
-
return;
|
|
3565
|
-
}
|
|
3566
|
-
header("Tunnels");
|
|
3567
|
-
formatTable(tunnels.map((t) => ({
|
|
3568
|
-
ID: shortId(t.id),
|
|
3569
|
-
Port: t.port ?? "-",
|
|
3570
|
-
"Public URL": t.publicUrl || t.url || "-",
|
|
3571
|
-
Status: formatStatus(t.status),
|
|
3572
|
-
PID: t.pid ?? "-"
|
|
3573
|
-
})));
|
|
3574
|
-
} catch (err) {
|
|
3575
|
-
fail(err.message);
|
|
3576
|
-
}
|
|
3577
|
-
});
|
|
3578
|
-
cmd.command("start").description("Start a new tunnel").requiredOption("-p, --port <port>", "Local port to expose").option("-s, --subdomain <subdomain>", "Preferred subdomain").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL10).action(async (options) => {
|
|
3579
|
-
try {
|
|
3580
|
-
const url = getAgentUrl(options);
|
|
3581
|
-
const body = {
|
|
3582
|
-
port: parseInt(options.port, 10)
|
|
3583
|
-
};
|
|
3584
|
-
if (options.subdomain)
|
|
3585
|
-
body.subdomain = options.subdomain;
|
|
3586
|
-
const result = await apiPost(url, "/api/tunnels/start", body);
|
|
3587
|
-
success("Tunnel started.");
|
|
3588
|
-
if (result?.id)
|
|
3589
|
-
kv("ID", shortId(result.id));
|
|
3590
|
-
if (result?.publicUrl || result?.url)
|
|
3591
|
-
kv("Public URL", result.publicUrl || result.url);
|
|
3592
|
-
kv("Port", options.port);
|
|
3593
|
-
} catch (err) {
|
|
3594
|
-
fail(err.message);
|
|
3595
|
-
}
|
|
3596
|
-
});
|
|
3597
|
-
cmd.command("stop").description("Stop a tunnel").requiredOption("-i, --id <id>", "Tunnel ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL10).action(async (options) => {
|
|
3598
|
-
try {
|
|
3599
|
-
const url = getAgentUrl(options);
|
|
3600
|
-
await apiPost(url, `/api/tunnels/${options.id}/stop`, {});
|
|
3601
|
-
success(`Tunnel ${shortId(options.id)} stopped.`);
|
|
3602
|
-
} catch (err) {
|
|
3603
|
-
fail(err.message);
|
|
3604
|
-
}
|
|
3605
|
-
});
|
|
3606
|
-
cmd.command("delete").description("Delete a tunnel").requiredOption("-i, --id <id>", "Tunnel ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL10).action(async (options) => {
|
|
3607
|
-
try {
|
|
3608
|
-
const url = getAgentUrl(options);
|
|
3609
|
-
await apiDelete(url, `/api/tunnels/${options.id}`);
|
|
3610
|
-
success(`Tunnel ${shortId(options.id)} deleted.`);
|
|
3611
|
-
} catch (err) {
|
|
3612
|
-
fail(err.message);
|
|
3613
|
-
}
|
|
3614
|
-
});
|
|
3615
|
-
cmd.command("status").description("Show tunnel status summary").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL10).action(async (options) => {
|
|
3616
|
-
try {
|
|
3617
|
-
const url = getAgentUrl(options);
|
|
3618
|
-
const result = await apiGet(url, "/api/tunnels/status");
|
|
3619
|
-
header("Tunnel Status");
|
|
3620
|
-
kv("Total", result?.total ?? 0);
|
|
3621
|
-
kv("Active", result?.active ?? 0);
|
|
3622
|
-
kv("Inactive", result?.inactive ?? 0);
|
|
3623
|
-
kv("Errored", result?.errored ?? 0);
|
|
3624
|
-
} catch (err) {
|
|
3625
|
-
fail(err.message);
|
|
3626
|
-
}
|
|
3627
|
-
});
|
|
3628
|
-
cmd.command("agent").description("Manage agent tunnel").option("--start", "Start the agent tunnel").option("--stop", "Stop the agent tunnel").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL10).action(async (options) => {
|
|
3629
|
-
try {
|
|
3630
|
-
const url = getAgentUrl(options);
|
|
3631
|
-
if (options.start) {
|
|
3632
|
-
const result = await apiPost(url, "/api/agent/tunnel", {
|
|
3633
|
-
action: "start"
|
|
3634
|
-
});
|
|
3635
|
-
success("Agent tunnel started.");
|
|
3636
|
-
if (result?.publicUrl || result?.url)
|
|
3637
|
-
kv("Public URL", result.publicUrl || result.url);
|
|
3638
|
-
} else if (options.stop) {
|
|
3639
|
-
const result = await apiPost(url, "/api/agent/tunnel", {
|
|
3640
|
-
action: "stop"
|
|
3641
|
-
});
|
|
3642
|
-
success("Agent tunnel stopped.");
|
|
3643
|
-
} else {
|
|
3644
|
-
const result = await apiGet(url, "/api/agent/tunnel");
|
|
3645
|
-
header("Agent Tunnel");
|
|
3646
|
-
kv("Status", formatStatus(result?.status || "unknown"));
|
|
3647
|
-
if (result?.publicUrl || result?.url)
|
|
3648
|
-
kv("Public URL", result.publicUrl || result.url);
|
|
3649
|
-
if (result?.port)
|
|
3650
|
-
kv("Port", result.port);
|
|
3651
|
-
}
|
|
3652
|
-
} catch (err) {
|
|
3653
|
-
fail(err.message);
|
|
3654
|
-
}
|
|
3655
|
-
});
|
|
3656
|
-
}
|
|
3657
|
-
// src/cli/commands/task.cmd.ts
|
|
3658
|
-
var DEFAULT_AGENT_URL11 = "http://localhost:3005";
|
|
3659
|
-
function register19(program2) {
|
|
3660
|
-
const cmd = program2.command("task").description("Manage background tasks");
|
|
3661
|
-
cmd.command("list").description("List tasks").option("--status <status>", "Filter by status").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL11).action(async (options) => {
|
|
3662
|
-
try {
|
|
3663
|
-
const url = getAgentUrl(options);
|
|
3664
|
-
const query = options.status ? `/api/tasks/?status=${encodeURIComponent(options.status)}` : "/api/tasks/";
|
|
3665
|
-
const data = await apiGet(url, query);
|
|
3666
|
-
const tasks = data.tasks || [];
|
|
3667
|
-
if (!tasks || tasks.length === 0) {
|
|
3668
|
-
info("No tasks found.");
|
|
3669
|
-
return;
|
|
3670
|
-
}
|
|
3671
|
-
header("Tasks");
|
|
3672
|
-
formatTable(tasks.map((t) => ({
|
|
3673
|
-
ID: shortId(t.id),
|
|
3674
|
-
Type: t.type || "-",
|
|
3675
|
-
Status: formatStatus(t.status),
|
|
3676
|
-
Created: t.createdAt ? timeAgo(t.createdAt) : "-"
|
|
3677
|
-
})));
|
|
3678
|
-
} catch (err) {
|
|
3679
|
-
fail(err.message);
|
|
3680
|
-
}
|
|
3681
|
-
});
|
|
3682
|
-
cmd.command("run").description("Run a new task").requiredOption("-c, --command <cmd>", "Command to run").option("--cwd <dir>", "Working directory").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL11).action(async (options) => {
|
|
3683
|
-
try {
|
|
3684
|
-
const url = getAgentUrl(options);
|
|
3685
|
-
const payload = { command: options.command };
|
|
3686
|
-
if (options.cwd)
|
|
3687
|
-
payload.cwd = options.cwd;
|
|
3688
|
-
const body = {
|
|
3689
|
-
type: "command",
|
|
3690
|
-
payload: JSON.stringify(payload)
|
|
3691
|
-
};
|
|
3692
|
-
const result = await apiPost(url, "/api/tasks/", body);
|
|
3693
|
-
success(`Task created: ${shortId(result?.id || result?.taskId)}`);
|
|
3694
|
-
} catch (err) {
|
|
3695
|
-
fail(err.message);
|
|
3696
|
-
}
|
|
3697
|
-
});
|
|
3698
|
-
cmd.command("cancel").description("Cancel a running task").requiredOption("-i, --id <id>", "Task ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL11).action(async (options) => {
|
|
3699
|
-
try {
|
|
3700
|
-
const url = getAgentUrl(options);
|
|
3701
|
-
await apiPut(url, `/api/tasks/${options.id}/cancel`, {});
|
|
3702
|
-
success(`Task ${shortId(options.id)} cancelled.`);
|
|
3703
|
-
} catch (err) {
|
|
3704
|
-
fail(err.message);
|
|
3705
|
-
}
|
|
3706
|
-
});
|
|
3707
|
-
}
|
|
3708
|
-
// src/cli/commands/git.cmd.ts
|
|
3709
|
-
var DEFAULT_AGENT_URL12 = "http://localhost:3005";
|
|
3710
|
-
function register20(program2) {
|
|
3711
|
-
const cmd = program2.command("git").description("Manage git repositories");
|
|
3712
|
-
cmd.command("list").description("List discovered git repositories").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL12).action(async (options) => {
|
|
3713
|
-
try {
|
|
3714
|
-
const url = getAgentUrl(options);
|
|
3715
|
-
const data = await apiGet(url, "/api/git");
|
|
3716
|
-
const repos = data.repositories || [];
|
|
3717
|
-
if (!repos || repos.length === 0) {
|
|
3718
|
-
info("No git repositories found.");
|
|
3719
|
-
return;
|
|
3720
|
-
}
|
|
3721
|
-
header("Git Repositories");
|
|
3722
|
-
formatTable(repos.map((r) => ({
|
|
3723
|
-
ID: shortId(r.id),
|
|
3724
|
-
Name: r.name || "-",
|
|
3725
|
-
Path: r.path || "-",
|
|
3726
|
-
Type: r.type || r.projectType || "-",
|
|
3727
|
-
Submodule: r.isSubmodule ? "Yes" : "No",
|
|
3728
|
-
Scanned: r.scannedAt ? timeAgo(r.scannedAt) : "-"
|
|
3729
|
-
})));
|
|
3730
|
-
} catch (err) {
|
|
3731
|
-
fail(err.message);
|
|
3732
|
-
}
|
|
3733
|
-
});
|
|
3734
|
-
cmd.command("scan").description("Scan a directory for git repositories").requiredOption("--dir <directory>", "Directory to scan").option("--depth <depth>", "Scan depth", "3").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL12).action(async (options) => {
|
|
3735
|
-
try {
|
|
3736
|
-
const url = getAgentUrl(options);
|
|
3737
|
-
const result = await apiPost(url, "/api/git/scan", {
|
|
3738
|
-
directory: options.dir,
|
|
3739
|
-
depth: parseInt(options.depth, 10)
|
|
3740
|
-
});
|
|
3741
|
-
success("Git scan completed.");
|
|
3742
|
-
if (result?.found !== undefined)
|
|
3743
|
-
kv("Repositories found", result.found);
|
|
3744
|
-
if (result?.repositories)
|
|
3745
|
-
kv("Repositories found", result.repositories.length);
|
|
3746
|
-
} catch (err) {
|
|
3747
|
-
fail(err.message);
|
|
3748
|
-
}
|
|
3749
|
-
});
|
|
3750
|
-
cmd.command("update").description("Update a git repository entry").requiredOption("-i, --id <id>", "Repository ID").option("--vite-port <port>", "Vite dev server port").option("--project-type <type>", "Project type").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL12).action(async (options) => {
|
|
3751
|
-
try {
|
|
3752
|
-
const url = getAgentUrl(options);
|
|
3753
|
-
const body = {};
|
|
3754
|
-
if (options.vitePort)
|
|
3755
|
-
body.vitePort = parseInt(options.vitePort, 10);
|
|
3756
|
-
if (options.projectType)
|
|
3757
|
-
body.projectType = options.projectType;
|
|
3758
|
-
await apiPut(url, `/api/git/${options.id}`, body);
|
|
3759
|
-
success(`Repository ${shortId(options.id)} updated.`);
|
|
3760
|
-
} catch (err) {
|
|
3761
|
-
fail(err.message);
|
|
3762
|
-
}
|
|
3763
|
-
});
|
|
3764
|
-
cmd.command("delete").description("Delete a git repository entry").requiredOption("-i, --id <id>", "Repository ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL12).action(async (options) => {
|
|
3765
|
-
try {
|
|
3766
|
-
const url = getAgentUrl(options);
|
|
3767
|
-
await apiDelete(url, `/api/git/${options.id}`);
|
|
3768
|
-
success(`Repository ${shortId(options.id)} deleted.`);
|
|
3769
|
-
} catch (err) {
|
|
3770
|
-
fail(err.message);
|
|
3771
|
-
}
|
|
3772
|
-
});
|
|
3773
|
-
cmd.command("fix-hierarchy").description("Fix repository parent-child hierarchy").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL12).action(async (options) => {
|
|
3774
|
-
try {
|
|
3775
|
-
const url = getAgentUrl(options);
|
|
3776
|
-
const result = await apiPost(url, "/api/git/fix-hierarchy", {});
|
|
3777
|
-
success("Hierarchy fix completed.");
|
|
3778
|
-
if (result?.fixed !== undefined)
|
|
3779
|
-
kv("Fixed", result.fixed);
|
|
3780
|
-
} catch (err) {
|
|
3781
|
-
fail(err.message);
|
|
3782
|
-
}
|
|
3783
|
-
});
|
|
3784
|
-
}
|
|
3785
|
-
// src/cli/commands/file.cmd.ts
|
|
3786
|
-
var DEFAULT_AGENT_URL13 = "http://localhost:3005";
|
|
3787
|
-
function register21(program2) {
|
|
3788
|
-
const cmd = program2.command("file").description("File system operations via agent");
|
|
3789
|
-
cmd.command("read").description("Read a file").requiredOption("--path <path>", "File path to read").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL13).action(async (options) => {
|
|
3790
|
-
try {
|
|
3791
|
-
const url = getAgentUrl(options);
|
|
3792
|
-
const result = await apiPost(url, "/api/files/read", {
|
|
3793
|
-
path: options.path
|
|
3794
|
-
});
|
|
3795
|
-
if (result?.content !== undefined) {
|
|
3796
|
-
console.log(result.content);
|
|
3797
|
-
} else {
|
|
3798
|
-
info("File is empty or has no content.");
|
|
3799
|
-
}
|
|
3800
|
-
} catch (err) {
|
|
3801
|
-
fail(err.message);
|
|
3802
|
-
}
|
|
3803
|
-
});
|
|
3804
|
-
cmd.command("write").description("Write content to a file").requiredOption("--path <path>", "File path to write").requiredOption("--content <content>", "Content to write").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL13).action(async (options) => {
|
|
3805
|
-
try {
|
|
3806
|
-
const url = getAgentUrl(options);
|
|
3807
|
-
await apiPost(url, "/api/files/write", {
|
|
3808
|
-
path: options.path,
|
|
3809
|
-
content: options.content
|
|
3810
|
-
});
|
|
3811
|
-
success(`File written: ${options.path}`);
|
|
3812
|
-
} catch (err) {
|
|
3813
|
-
fail(err.message);
|
|
3814
|
-
}
|
|
3815
|
-
});
|
|
3816
|
-
cmd.command("list").description("List files in a directory").requiredOption("--path <path>", "Directory path").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL13).action(async (options) => {
|
|
3817
|
-
try {
|
|
3818
|
-
const url = getAgentUrl(options);
|
|
3819
|
-
const result = await apiPost(url, "/api/files/list", {
|
|
3820
|
-
path: options.path
|
|
3821
|
-
});
|
|
3822
|
-
const files = result?.files || result;
|
|
3823
|
-
if (!files || Array.isArray(files) && files.length === 0) {
|
|
3824
|
-
info("Directory is empty.");
|
|
3825
|
-
return;
|
|
3826
|
-
}
|
|
3827
|
-
header(`Files in ${options.path}`);
|
|
3828
|
-
formatTable((Array.isArray(files) ? files : []).map((f) => ({
|
|
3829
|
-
Name: f.name || f.filename || "-",
|
|
3830
|
-
Type: f.type || (f.isDirectory ? "directory" : "file"),
|
|
3831
|
-
Size: f.size !== undefined ? formatBytes(f.size) : "-"
|
|
3832
|
-
})));
|
|
3833
|
-
} catch (err) {
|
|
3834
|
-
fail(err.message);
|
|
3835
|
-
}
|
|
3836
|
-
});
|
|
3837
|
-
cmd.command("exists").description("Check if a file exists").requiredOption("--path <path>", "File path to check").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL13).action(async (options) => {
|
|
3838
|
-
try {
|
|
3839
|
-
const url = getAgentUrl(options);
|
|
3840
|
-
const result = await apiPost(url, "/api/files/exists", {
|
|
3841
|
-
path: options.path
|
|
3842
|
-
});
|
|
3843
|
-
if (result?.exists) {
|
|
3844
|
-
success(`File exists: ${options.path}`);
|
|
3845
|
-
} else {
|
|
3846
|
-
info(`File does not exist: ${options.path}`);
|
|
3847
|
-
}
|
|
3848
|
-
} catch (err) {
|
|
3849
|
-
fail(err.message);
|
|
3850
|
-
}
|
|
3851
|
-
});
|
|
3852
|
-
cmd.command("delete").description("Delete a file").requiredOption("--path <path>", "File path to delete").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL13).action(async (options) => {
|
|
3853
|
-
try {
|
|
3854
|
-
const url = getAgentUrl(options);
|
|
3855
|
-
await apiPost(url, "/api/files/delete", {
|
|
3856
|
-
path: options.path
|
|
3857
|
-
});
|
|
3858
|
-
success(`File deleted: ${options.path}`);
|
|
3859
|
-
} catch (err) {
|
|
3860
|
-
fail(err.message);
|
|
3861
|
-
}
|
|
3862
|
-
});
|
|
3863
|
-
cmd.command("readme").description("Read the README file from a directory").requiredOption("--path <path>", "Directory path").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL13).action(async (options) => {
|
|
3864
|
-
try {
|
|
3865
|
-
const url = getAgentUrl(options);
|
|
3866
|
-
const result = await apiPost(url, "/api/files/readme", {
|
|
3867
|
-
path: options.path
|
|
3868
|
-
});
|
|
3869
|
-
if (result?.content) {
|
|
3870
|
-
console.log(result.content);
|
|
3871
|
-
} else {
|
|
3872
|
-
info("No README found in the specified directory.");
|
|
3873
|
-
}
|
|
3874
|
-
} catch (err) {
|
|
3875
|
-
fail(err.message);
|
|
3876
|
-
}
|
|
3877
|
-
});
|
|
3878
|
-
}
|
|
3879
|
-
// src/cli/commands/bookmark.cmd.ts
|
|
3880
|
-
var DEFAULT_AGENT_URL14 = "http://localhost:3005";
|
|
3881
|
-
function register22(program2) {
|
|
3882
|
-
const cmd = program2.command("bookmark").description("Manage command bookmarks");
|
|
3883
|
-
cmd.command("list").description("List bookmarks").option("--project <id>", "Filter by project ID").option("--category <cat>", "Filter by category").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL14).action(async (options) => {
|
|
3884
|
-
try {
|
|
3885
|
-
const url = getAgentUrl(options);
|
|
3886
|
-
const params = new URLSearchParams;
|
|
3887
|
-
if (options.project)
|
|
3888
|
-
params.set("project", options.project);
|
|
3889
|
-
if (options.category)
|
|
3890
|
-
params.set("category", options.category);
|
|
3891
|
-
const query = params.toString();
|
|
3892
|
-
const endpoint = query ? `/api/bookmarks?${query}` : "/api/bookmarks";
|
|
3893
|
-
const data = await apiGet(url, endpoint);
|
|
3894
|
-
const bookmarks = data.bookmarks || [];
|
|
3895
|
-
if (!bookmarks || bookmarks.length === 0) {
|
|
3896
|
-
info("No bookmarks found.");
|
|
3897
|
-
return;
|
|
3898
|
-
}
|
|
3899
|
-
header("Bookmarks");
|
|
3900
|
-
formatTable(bookmarks.map((b) => ({
|
|
3901
|
-
ID: shortId(b.id),
|
|
3902
|
-
Command: b.command || "-",
|
|
3903
|
-
Description: b.description || "-",
|
|
3904
|
-
Category: b.category || "-",
|
|
3905
|
-
Project: b.project || b.projectId || "-"
|
|
3906
|
-
})));
|
|
3907
|
-
} catch (err) {
|
|
3908
|
-
fail(err.message);
|
|
3909
|
-
}
|
|
3910
|
-
});
|
|
3911
|
-
cmd.command("create").description("Create a new bookmark").requiredOption("-c, --command <cmd>", "Command to bookmark").option("--description <desc>", "Bookmark description").option("--category <cat>", "Category").option("--project <id>", "Project ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL14).action(async (options) => {
|
|
3912
|
-
try {
|
|
3913
|
-
const url = getAgentUrl(options);
|
|
3914
|
-
const body = { command: options.command };
|
|
3915
|
-
if (options.description)
|
|
3916
|
-
body.description = options.description;
|
|
3917
|
-
if (options.category)
|
|
3918
|
-
body.category = options.category;
|
|
3919
|
-
if (options.project)
|
|
3920
|
-
body.project = options.project;
|
|
3921
|
-
const result = await apiPost(url, "/api/bookmarks", body);
|
|
3922
|
-
success(`Bookmark created: ${shortId(result?.id)}`);
|
|
3923
|
-
} catch (err) {
|
|
3924
|
-
fail(err.message);
|
|
3925
|
-
}
|
|
3926
|
-
});
|
|
3927
|
-
cmd.command("update").description("Update a bookmark").requiredOption("-i, --id <id>", "Bookmark ID").option("-c, --command <cmd>", "New command").option("--description <desc>", "New description").option("--category <cat>", "New category").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL14).action(async (options) => {
|
|
3928
|
-
try {
|
|
3929
|
-
const url = getAgentUrl(options);
|
|
3930
|
-
const body = {};
|
|
3931
|
-
if (options.command)
|
|
3932
|
-
body.command = options.command;
|
|
3933
|
-
if (options.description)
|
|
3934
|
-
body.description = options.description;
|
|
3935
|
-
if (options.category)
|
|
3936
|
-
body.category = options.category;
|
|
3937
|
-
if (Object.keys(body).length === 0) {
|
|
3938
|
-
fail("No fields to update. Provide at least one of --command, --description, or --category.");
|
|
3939
|
-
return;
|
|
3940
|
-
}
|
|
3941
|
-
await apiPut(url, `/api/bookmarks/${options.id}`, body);
|
|
3942
|
-
success(`Bookmark ${shortId(options.id)} updated.`);
|
|
3943
|
-
} catch (err) {
|
|
3944
|
-
fail(err.message);
|
|
3945
|
-
}
|
|
3946
|
-
});
|
|
3947
|
-
cmd.command("delete").description("Delete a bookmark").requiredOption("-i, --id <id>", "Bookmark ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL14).action(async (options) => {
|
|
3948
|
-
try {
|
|
3949
|
-
const url = getAgentUrl(options);
|
|
3950
|
-
await apiDelete(url, `/api/bookmarks/${options.id}`);
|
|
3951
|
-
success(`Bookmark ${shortId(options.id)} deleted.`);
|
|
3952
|
-
} catch (err) {
|
|
3953
|
-
fail(err.message);
|
|
3954
|
-
}
|
|
3955
|
-
});
|
|
3956
|
-
cmd.command("execute").description("Execute a bookmarked command").requiredOption("-i, --id <id>", "Bookmark ID").option("--session <sessionId>", "Session ID to execute in").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL14).action(async (options) => {
|
|
3957
|
-
try {
|
|
3958
|
-
const url = getAgentUrl(options);
|
|
3959
|
-
const body = {};
|
|
3960
|
-
if (options.session)
|
|
3961
|
-
body.sessionId = options.session;
|
|
3962
|
-
const result = await apiPost(url, `/api/bookmarks/${options.id}/execute`, body);
|
|
3963
|
-
success(`Bookmark ${shortId(options.id)} executed.`);
|
|
3964
|
-
if (result?.output) {
|
|
3965
|
-
console.log(result.output);
|
|
3966
|
-
}
|
|
3967
|
-
} catch (err) {
|
|
3968
|
-
fail(err.message);
|
|
3969
|
-
}
|
|
3970
|
-
});
|
|
3971
|
-
}
|
|
3972
|
-
// src/cli/commands/notify.cmd.ts
|
|
3973
|
-
var DEFAULT_AGENT_URL15 = "http://localhost:3005";
|
|
3974
|
-
function register23(program2) {
|
|
3975
|
-
const cmd = program2.command("notify").description("Manage notifications");
|
|
3976
|
-
cmd.command("list").description("List notifications").option("--unread", "Show only unread notifications").option("--project <id>", "Filter by project ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL15).action(async (options) => {
|
|
3977
|
-
try {
|
|
3978
|
-
const url = getAgentUrl(options);
|
|
3979
|
-
const params = new URLSearchParams;
|
|
3980
|
-
if (options.unread)
|
|
3981
|
-
params.set("unread", "true");
|
|
3982
|
-
if (options.project)
|
|
3983
|
-
params.set("project", options.project);
|
|
3984
|
-
const query = params.toString();
|
|
3985
|
-
const endpoint = query ? `/api/notifications?${query}` : "/api/notifications";
|
|
3986
|
-
const data = await apiGet(url, endpoint);
|
|
3987
|
-
const notifications = data.notifications || [];
|
|
3988
|
-
if (!notifications || notifications.length === 0) {
|
|
3989
|
-
info("No notifications found.");
|
|
3990
|
-
return;
|
|
3991
|
-
}
|
|
3992
|
-
header("Notifications");
|
|
3993
|
-
blank();
|
|
3994
|
-
for (const n of notifications) {
|
|
3995
|
-
const icon = formatNotificationType(n.type);
|
|
3996
|
-
const time = n.createdAt ? colors.dim(timeAgo(n.createdAt)) : "";
|
|
3997
|
-
const title = colors.bold(n.title || "Untitled");
|
|
3998
|
-
const id = colors.dim(`[${shortId(n.id)}]`);
|
|
3999
|
-
console.log(` ${icon} ${title} ${id} ${time}`);
|
|
4000
|
-
if (n.message) {
|
|
4001
|
-
console.log(` ${n.message}`);
|
|
4002
|
-
}
|
|
4003
|
-
blank();
|
|
4004
|
-
}
|
|
4005
|
-
} catch (err) {
|
|
4006
|
-
fail(err.message);
|
|
4007
|
-
}
|
|
4008
|
-
});
|
|
4009
|
-
cmd.command("create").description("Create a notification").requiredOption("--title <title>", "Notification title").requiredOption("--message <msg>", "Notification message").option("--type <type>", "Notification type", "info").option("--project <id>", "Project ID").option("--session <name>", "Session name").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL15).action(async (options) => {
|
|
4010
|
-
try {
|
|
4011
|
-
const url = getAgentUrl(options);
|
|
4012
|
-
const body = {
|
|
4013
|
-
title: options.title,
|
|
4014
|
-
message: options.message,
|
|
4015
|
-
type: options.type
|
|
4016
|
-
};
|
|
4017
|
-
if (options.project)
|
|
4018
|
-
body.project = options.project;
|
|
4019
|
-
if (options.session)
|
|
4020
|
-
body.session = options.session;
|
|
4021
|
-
const result = await apiPost(url, "/api/notifications", body);
|
|
4022
|
-
success(`Notification created: ${shortId(result?.id)}`);
|
|
4023
|
-
} catch (err) {
|
|
4024
|
-
fail(err.message);
|
|
4025
|
-
}
|
|
4026
|
-
});
|
|
4027
|
-
cmd.command("delete").description("Delete a notification").requiredOption("-i, --id <id>", "Notification ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL15).action(async (options) => {
|
|
4028
|
-
try {
|
|
4029
|
-
const url = getAgentUrl(options);
|
|
4030
|
-
await apiDelete(url, `/api/notifications/${options.id}`);
|
|
4031
|
-
success(`Notification ${shortId(options.id)} deleted.`);
|
|
4032
|
-
} catch (err) {
|
|
4033
|
-
fail(err.message);
|
|
4034
|
-
}
|
|
4035
|
-
});
|
|
4036
|
-
cmd.command("read-all").description("Mark all notifications as read").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL15).action(async (options) => {
|
|
4037
|
-
try {
|
|
4038
|
-
const url = getAgentUrl(options);
|
|
4039
|
-
await apiPut(url, "/api/notifications/read-all", {});
|
|
4040
|
-
success("All notifications marked as read.");
|
|
4041
|
-
} catch (err) {
|
|
4042
|
-
fail(err.message);
|
|
4043
|
-
}
|
|
4044
|
-
});
|
|
4045
|
-
cmd.command("clear-old").description("Clear old notifications").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL15).action(async (options) => {
|
|
4046
|
-
try {
|
|
4047
|
-
const url = getAgentUrl(options);
|
|
4048
|
-
await apiDelete(url, "/api/notifications/clear/old");
|
|
4049
|
-
success("Old notifications cleared.");
|
|
4050
|
-
} catch (err) {
|
|
4051
|
-
fail(err.message);
|
|
4052
|
-
}
|
|
4053
|
-
});
|
|
4054
|
-
cmd.command("webhook").description("Send a webhook notification to a session").requiredOption("--session <sessionId>", "Target session ID").option("--title <title>", "Notification title").option("--message <msg>", "Notification message").option("--type <type>", "Notification type", "info").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL15).action(async (options) => {
|
|
4055
|
-
try {
|
|
4056
|
-
const url = getAgentUrl(options);
|
|
4057
|
-
const body = {};
|
|
4058
|
-
if (options.title)
|
|
4059
|
-
body.title = options.title;
|
|
4060
|
-
if (options.message)
|
|
4061
|
-
body.message = options.message;
|
|
4062
|
-
if (options.type)
|
|
4063
|
-
body.type = options.type;
|
|
4064
|
-
await apiPost(url, `/api/notifications/webhook/${options.session}`, body);
|
|
4065
|
-
success(`Webhook notification sent to session ${shortId(options.session)}.`);
|
|
4066
|
-
} catch (err) {
|
|
4067
|
-
fail(err.message);
|
|
4068
|
-
}
|
|
4069
|
-
});
|
|
4070
|
-
}
|
|
4071
|
-
// src/cli/commands/project.cmd.ts
|
|
4072
|
-
var DEFAULT_AGENT_URL16 = "http://localhost:3005";
|
|
4073
|
-
function register24(program2) {
|
|
4074
|
-
const cmd = program2.command("project").description("Manage projects");
|
|
4075
|
-
cmd.command("list").description("List all projects").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL16).action(async (options) => {
|
|
4076
|
-
try {
|
|
4077
|
-
const url = getAgentUrl(options);
|
|
4078
|
-
const data = await apiGet(url, "/api/projects");
|
|
4079
|
-
const projects = data.projects || [];
|
|
4080
|
-
if (!projects || projects.length === 0) {
|
|
4081
|
-
info("No projects found.");
|
|
4082
|
-
return;
|
|
4083
|
-
}
|
|
4084
|
-
header("Projects");
|
|
4085
|
-
formatTable(projects.map((p) => ({
|
|
4086
|
-
ID: shortId(p.id),
|
|
4087
|
-
Name: p.name || "-",
|
|
4088
|
-
Path: p.path || "-",
|
|
4089
|
-
Type: p.type || p.projectType || "-",
|
|
4090
|
-
Framework: p.framework || "-",
|
|
4091
|
-
"Git Branch": p.gitBranch || p.branch || "-"
|
|
4092
|
-
})));
|
|
4093
|
-
} catch (err) {
|
|
4094
|
-
fail(err.message);
|
|
4095
|
-
}
|
|
4096
|
-
});
|
|
4097
|
-
cmd.command("scan").description("Scan a directory for projects").requiredOption("--dir <directory>", "Directory to scan").option("--depth <depth>", "Scan depth", "3").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL16).action(async (options) => {
|
|
4098
|
-
try {
|
|
4099
|
-
const url = getAgentUrl(options);
|
|
4100
|
-
const result = await apiPost(url, "/api/projects/scan", {
|
|
4101
|
-
directory: options.dir,
|
|
4102
|
-
depth: parseInt(options.depth, 10)
|
|
4103
|
-
});
|
|
4104
|
-
success("Project scan completed.");
|
|
4105
|
-
if (result?.found !== undefined)
|
|
4106
|
-
kv("Projects found", result.found);
|
|
4107
|
-
if (result?.projects)
|
|
4108
|
-
kv("Projects found", result.projects.length);
|
|
4109
|
-
} catch (err) {
|
|
4110
|
-
fail(err.message);
|
|
4111
|
-
}
|
|
4112
|
-
});
|
|
4113
|
-
cmd.command("scan-remote").description("Scan remote workspace for projects").requiredOption("--workspace-id <id>", "Workspace ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL16).action(async (options) => {
|
|
4114
|
-
try {
|
|
4115
|
-
const url = getAgentUrl(options);
|
|
4116
|
-
const result = await apiPost(url, "/api/projects/scan-remote", {
|
|
4117
|
-
workspaceId: options.workspaceId
|
|
4118
|
-
});
|
|
4119
|
-
success("Remote project scan completed.");
|
|
4120
|
-
if (result?.found !== undefined)
|
|
4121
|
-
kv("Projects found", result.found);
|
|
4122
|
-
if (result?.projects)
|
|
4123
|
-
kv("Projects found", result.projects.length);
|
|
4124
|
-
} catch (err) {
|
|
4125
|
-
fail(err.message);
|
|
4126
|
-
}
|
|
4127
|
-
});
|
|
4128
|
-
}
|
|
4129
|
-
// src/cli/commands/plugin.cmd.ts
|
|
4130
|
-
var DEFAULT_AGENT_URL17 = "http://localhost:3005";
|
|
4131
|
-
function register25(program2) {
|
|
4132
|
-
const cmd = program2.command("plugin").description("Manage plugins");
|
|
4133
|
-
cmd.command("list").description("List installed plugins").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL17).action(async (options) => {
|
|
4134
|
-
try {
|
|
4135
|
-
const url = getAgentUrl(options);
|
|
4136
|
-
let plugins;
|
|
4137
|
-
try {
|
|
4138
|
-
const data = await apiGet(url, "/api/plugins");
|
|
4139
|
-
plugins = data.plugins || [];
|
|
4140
|
-
} catch {
|
|
4141
|
-
warn("Agent not reachable. Attempting local plugin registry...");
|
|
4142
|
-
try {
|
|
4143
|
-
const { PluginManager: PluginManager2 } = await import("./plugin-system-bg1pzjj9.js");
|
|
4144
|
-
const pm = new PluginManager2;
|
|
4145
|
-
plugins = pm.getPluginDetails() || [];
|
|
4146
|
-
} catch {
|
|
4147
|
-
fail("Could not list plugins from agent or local registry.");
|
|
4148
|
-
return;
|
|
4149
|
-
}
|
|
4150
|
-
}
|
|
4151
|
-
if (!plugins || plugins.length === 0) {
|
|
4152
|
-
info("No plugins installed.");
|
|
4153
|
-
return;
|
|
4154
|
-
}
|
|
4155
|
-
header("Installed Plugins");
|
|
4156
|
-
formatTable(plugins.map((p) => ({
|
|
4157
|
-
Name: p.name || p.package || "-",
|
|
4158
|
-
Version: p.version || "-",
|
|
4159
|
-
Status: p.status || p.enabled ? "enabled" : "disabled",
|
|
4160
|
-
Description: p.description || "-"
|
|
4161
|
-
})));
|
|
4162
|
-
} catch (err) {
|
|
4163
|
-
fail(err.message);
|
|
4164
|
-
}
|
|
4165
|
-
});
|
|
4166
|
-
cmd.command("install").description("Install a plugin").argument("<package>", "NPM package name to install").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL17).action(async (packageName, options) => {
|
|
4167
|
-
try {
|
|
4168
|
-
const url = getAgentUrl(options);
|
|
4169
|
-
try {
|
|
4170
|
-
const result = await apiPost(url, "/api/plugins/install", {
|
|
4171
|
-
package: packageName
|
|
4172
|
-
});
|
|
4173
|
-
success(`Plugin "${packageName}" installed.`);
|
|
4174
|
-
if (result?.version)
|
|
4175
|
-
kv("Version", result.version);
|
|
4176
|
-
} catch {
|
|
4177
|
-
warn("Agent not reachable. Attempting local install...");
|
|
4178
|
-
try {
|
|
4179
|
-
const { PluginManager: PluginManager2 } = await import("./plugin-system-bg1pzjj9.js");
|
|
4180
|
-
const pm = new PluginManager2;
|
|
4181
|
-
await pm.install(packageName);
|
|
4182
|
-
success(`Plugin "${packageName}" installed locally.`);
|
|
4183
|
-
} catch (localErr) {
|
|
4184
|
-
fail(`Could not install plugin via agent or locally: ${localErr.message}`);
|
|
4185
|
-
}
|
|
4186
|
-
}
|
|
4187
|
-
} catch (err) {
|
|
4188
|
-
fail(err.message);
|
|
4189
|
-
}
|
|
4190
|
-
});
|
|
4191
|
-
cmd.command("remove").description("Remove a plugin").argument("<package>", "NPM package name to remove").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL17).action(async (packageName, options) => {
|
|
4192
|
-
try {
|
|
4193
|
-
const url = getAgentUrl(options);
|
|
4194
|
-
try {
|
|
4195
|
-
await apiPost(url, "/api/plugins/remove", {
|
|
4196
|
-
package: packageName
|
|
4197
|
-
});
|
|
4198
|
-
success(`Plugin "${packageName}" removed.`);
|
|
4199
|
-
} catch {
|
|
4200
|
-
warn("Agent not reachable. Attempting local removal...");
|
|
4201
|
-
try {
|
|
4202
|
-
const { PluginManager: PluginManager2 } = await import("./plugin-system-bg1pzjj9.js");
|
|
4203
|
-
const pm = new PluginManager2;
|
|
4204
|
-
await pm.remove(packageName);
|
|
4205
|
-
success(`Plugin "${packageName}" removed locally.`);
|
|
4206
|
-
} catch (localErr) {
|
|
4207
|
-
fail(`Could not remove plugin via agent or locally: ${localErr.message}`);
|
|
4208
|
-
}
|
|
4209
|
-
}
|
|
4210
|
-
} catch (err) {
|
|
4211
|
-
fail(err.message);
|
|
4212
|
-
}
|
|
4213
|
-
});
|
|
4214
|
-
cmd.command("reload").description("Reload all plugins").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL17).action(async (options) => {
|
|
4215
|
-
try {
|
|
4216
|
-
const url = getAgentUrl(options);
|
|
4217
|
-
await apiPost(url, "/api/plugins/reload", {});
|
|
4218
|
-
success("Plugins reloaded.");
|
|
4219
|
-
} catch (err) {
|
|
4220
|
-
fail(err.message);
|
|
4221
|
-
}
|
|
4222
|
-
});
|
|
4223
|
-
cmd.command("available").description("Show available plugins").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL17).action(async (options) => {
|
|
4224
|
-
try {
|
|
4225
|
-
const url = getAgentUrl(options);
|
|
4226
|
-
const availData = await apiGet(url, "/api/plugins/available");
|
|
4227
|
-
const plugins = availData.plugins || [];
|
|
4228
|
-
if (!plugins || plugins.length === 0) {
|
|
4229
|
-
info("No available plugins found.");
|
|
4230
|
-
return;
|
|
4231
|
-
}
|
|
4232
|
-
header("Available Plugins");
|
|
4233
|
-
formatTable(plugins.map((p) => ({
|
|
4234
|
-
Name: p.name || p.package || "-",
|
|
4235
|
-
Version: p.version || p.latestVersion || "-",
|
|
4236
|
-
Description: p.description || "-"
|
|
4237
|
-
})));
|
|
4238
|
-
} catch (err) {
|
|
4239
|
-
fail(err.message);
|
|
4240
|
-
}
|
|
4241
|
-
});
|
|
4242
|
-
}
|
|
4243
|
-
// src/cli/commands/state.cmd.ts
|
|
4244
|
-
var DEFAULT_AGENT_URL18 = "http://localhost:3005";
|
|
4245
|
-
function register26(program2) {
|
|
4246
|
-
const cmd = program2.command("state").description("Manage plugin key-value state");
|
|
4247
|
-
cmd.command("list").description("List all state entries for a plugin").argument("<plugin>", "Plugin name").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL18).action(async (plugin, options) => {
|
|
4248
|
-
try {
|
|
4249
|
-
const url = getAgentUrl(options);
|
|
4250
|
-
const entries = await apiGet(url, `/api/plugin-state/${encodeURIComponent(plugin)}`);
|
|
4251
|
-
if (!entries || typeof entries === "object" && Object.keys(entries).length === 0) {
|
|
4252
|
-
info(`No state entries for plugin "${plugin}".`);
|
|
4253
|
-
return;
|
|
4254
|
-
}
|
|
4255
|
-
header(`State: ${plugin}`);
|
|
4256
|
-
blank();
|
|
4257
|
-
if (Array.isArray(entries)) {
|
|
4258
|
-
for (const entry of entries) {
|
|
4259
|
-
kv(entry.key, JSON.stringify(entry.value));
|
|
4260
|
-
}
|
|
4261
|
-
} else if (typeof entries === "object") {
|
|
4262
|
-
for (const [key, value] of Object.entries(entries)) {
|
|
4263
|
-
kv(key, JSON.stringify(value));
|
|
4264
|
-
}
|
|
4265
|
-
}
|
|
4266
|
-
} catch (err) {
|
|
4267
|
-
fail(err.message);
|
|
4268
|
-
}
|
|
4269
|
-
});
|
|
4270
|
-
cmd.command("get").description("Get a state value").argument("<plugin>", "Plugin name").argument("<key>", "State key").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL18).action(async (plugin, key, options) => {
|
|
4271
|
-
try {
|
|
4272
|
-
const url = getAgentUrl(options);
|
|
4273
|
-
const result = await apiGet(url, `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`);
|
|
4274
|
-
if (result?.value !== undefined) {
|
|
4275
|
-
header(`${plugin} / ${key}`);
|
|
4276
|
-
console.log(typeof result.value === "string" ? result.value : JSON.stringify(result.value, null, 2));
|
|
4277
|
-
} else {
|
|
4278
|
-
info(`No value found for key "${key}" in plugin "${plugin}".`);
|
|
4279
|
-
}
|
|
4280
|
-
} catch (err) {
|
|
4281
|
-
fail(err.message);
|
|
4282
|
-
}
|
|
4283
|
-
});
|
|
4284
|
-
cmd.command("set").description("Set a state value").argument("<plugin>", "Plugin name").argument("<key>", "State key").argument("<value>", "Value to set").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL18).action(async (plugin, key, value, options) => {
|
|
4285
|
-
try {
|
|
4286
|
-
const url = getAgentUrl(options);
|
|
4287
|
-
let parsedValue = value;
|
|
4288
|
-
try {
|
|
4289
|
-
parsedValue = JSON.parse(value);
|
|
4290
|
-
} catch {}
|
|
4291
|
-
await apiPut(url, `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`, { value: parsedValue });
|
|
4292
|
-
success(`State set: ${plugin}/${key}`);
|
|
4293
|
-
} catch (err) {
|
|
4294
|
-
fail(err.message);
|
|
4295
|
-
}
|
|
4296
|
-
});
|
|
4297
|
-
cmd.command("unset").description("Remove a state value").argument("<plugin>", "Plugin name").argument("<key>", "State key").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL18).action(async (plugin, key, options) => {
|
|
4298
|
-
try {
|
|
4299
|
-
const url = getAgentUrl(options);
|
|
4300
|
-
await apiDelete(url, `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`);
|
|
4301
|
-
success(`State removed: ${plugin}/${key}`);
|
|
4302
|
-
} catch (err) {
|
|
4303
|
-
fail(err.message);
|
|
4304
|
-
}
|
|
4305
|
-
});
|
|
4306
|
-
}
|
|
4307
|
-
// src/cli/commands/log.cmd.ts
|
|
4308
|
-
var DEFAULT_AGENT_URL19 = "http://localhost:3005";
|
|
4309
|
-
function register27(program2) {
|
|
4310
|
-
const cmd = program2.command("log").description("View and stream logs");
|
|
4311
|
-
cmd.command("list").description("List recent log entries").option("--level <level>", "Minimum log level", "info").option("--limit <n>", "Number of entries to show", "50").option("--source <source>", "Filter by source").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL19).action(async (options) => {
|
|
4312
|
-
try {
|
|
4313
|
-
const url = getAgentUrl(options);
|
|
4314
|
-
const params = new URLSearchParams;
|
|
4315
|
-
params.set("level", options.level);
|
|
4316
|
-
params.set("limit", options.limit);
|
|
4317
|
-
if (options.source)
|
|
4318
|
-
params.set("source", options.source);
|
|
4319
|
-
const logs = await apiGet(url, `/api/logs?${params.toString()}`);
|
|
4320
|
-
if (!logs || logs.length === 0) {
|
|
4321
|
-
info("No log entries found.");
|
|
4322
|
-
return;
|
|
4323
|
-
}
|
|
4324
|
-
header("Logs");
|
|
4325
|
-
blank();
|
|
4326
|
-
for (const entry of logs) {
|
|
4327
|
-
const level = formatLogLevel(entry.level);
|
|
4328
|
-
const time = entry.timestamp ? colors.dim(timeAgo(entry.timestamp)) : "";
|
|
4329
|
-
const source = entry.source ? colors.cyan(`[${entry.source}]`) : "";
|
|
4330
|
-
const message = entry.message || "";
|
|
4331
|
-
console.log(` ${level} ${source} ${message} ${time}`);
|
|
4332
|
-
}
|
|
4333
|
-
} catch (err) {
|
|
4334
|
-
fail(err.message);
|
|
4335
|
-
}
|
|
4336
|
-
});
|
|
4337
|
-
cmd.command("stream").description("Stream logs in real-time (SSE)").option("--level <level>", "Minimum log level", "info").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL19).action(async (options) => {
|
|
4338
|
-
try {
|
|
4339
|
-
const url = getAgentUrl(options);
|
|
4340
|
-
const params = new URLSearchParams;
|
|
4341
|
-
params.set("level", options.level);
|
|
4342
|
-
const streamUrl = `${url}/api/logs/stream?${params.toString()}`;
|
|
4343
|
-
info(`Streaming logs from ${url} (level: ${options.level})...`);
|
|
4344
|
-
info(`Press Ctrl+C to stop.
|
|
4345
|
-
`);
|
|
4346
|
-
const response = await fetch(streamUrl, {
|
|
4347
|
-
headers: { Accept: "text/event-stream" }
|
|
4348
|
-
});
|
|
4349
|
-
if (!response.ok) {
|
|
4350
|
-
fail(`Failed to connect to log stream: ${response.status} ${response.statusText}`);
|
|
4351
|
-
return;
|
|
4352
|
-
}
|
|
4353
|
-
if (!response.body) {
|
|
4354
|
-
fail("No response body for SSE stream.");
|
|
4355
|
-
return;
|
|
4356
|
-
}
|
|
4357
|
-
const decoder = new TextDecoder;
|
|
4358
|
-
const reader = response.body.getReader();
|
|
4359
|
-
const cleanup = () => {
|
|
4360
|
-
reader.cancel().catch(() => {});
|
|
4361
|
-
console.log(`
|
|
4362
|
-
Log stream ended.`);
|
|
4363
|
-
process.exit(0);
|
|
4364
|
-
};
|
|
4365
|
-
process.on("SIGINT", cleanup);
|
|
4366
|
-
process.on("SIGTERM", cleanup);
|
|
4367
|
-
let buffer = "";
|
|
4368
|
-
while (true) {
|
|
4369
|
-
const { done, value } = await reader.read();
|
|
4370
|
-
if (done)
|
|
4371
|
-
break;
|
|
4372
|
-
buffer += decoder.decode(value, { stream: true });
|
|
4373
|
-
const lines = buffer.split(`
|
|
4374
|
-
`);
|
|
4375
|
-
buffer = lines.pop() || "";
|
|
4376
|
-
for (const line of lines) {
|
|
4377
|
-
if (line.startsWith("data: ")) {
|
|
4378
|
-
const data = line.slice(6).trim();
|
|
4379
|
-
if (!data || data === "[DONE]")
|
|
4380
|
-
continue;
|
|
4381
|
-
try {
|
|
4382
|
-
const entry = JSON.parse(data);
|
|
4383
|
-
const level = formatLogLevel(entry.level);
|
|
4384
|
-
const source = entry.source ? colors.cyan(`[${entry.source}]`) : "";
|
|
4385
|
-
const message = entry.message || "";
|
|
4386
|
-
const time = entry.timestamp ? colors.dim(new Date(entry.timestamp).toLocaleTimeString()) : "";
|
|
4387
|
-
console.log(`${level} ${source} ${message} ${time}`);
|
|
4388
|
-
} catch {
|
|
4389
|
-
if (data.trim())
|
|
4390
|
-
console.log(data);
|
|
4391
|
-
}
|
|
4392
|
-
}
|
|
4393
|
-
}
|
|
4394
|
-
}
|
|
4395
|
-
} catch (err) {
|
|
4396
|
-
if (err.name === "AbortError")
|
|
4397
|
-
return;
|
|
4398
|
-
fail(err.message);
|
|
4399
|
-
}
|
|
4400
|
-
});
|
|
4401
|
-
}
|
|
4402
|
-
function formatLogLevel(level) {
|
|
4403
|
-
if (!level)
|
|
4404
|
-
return colors.dim("???");
|
|
4405
|
-
switch (level.toLowerCase()) {
|
|
4406
|
-
case "error":
|
|
4407
|
-
return colors.red(colors.bold("ERR"));
|
|
4408
|
-
case "warn":
|
|
4409
|
-
case "warning":
|
|
4410
|
-
return colors.yellow("WRN");
|
|
4411
|
-
case "info":
|
|
4412
|
-
return colors.blue("INF");
|
|
4413
|
-
case "debug":
|
|
4414
|
-
return colors.gray("DBG");
|
|
4415
|
-
case "trace":
|
|
4416
|
-
return colors.dim("TRC");
|
|
4417
|
-
default:
|
|
4418
|
-
return colors.dim(level.toUpperCase().slice(0, 3));
|
|
4419
|
-
}
|
|
4420
|
-
}
|
|
2554
|
+
|
|
4421
2555
|
// src/services/completion.service.ts
|
|
4422
2556
|
import {
|
|
4423
|
-
existsSync as
|
|
4424
|
-
mkdirSync
|
|
4425
|
-
writeFileSync
|
|
2557
|
+
existsSync as existsSync2,
|
|
2558
|
+
mkdirSync,
|
|
2559
|
+
writeFileSync,
|
|
4426
2560
|
unlinkSync,
|
|
4427
|
-
readFileSync
|
|
2561
|
+
readFileSync
|
|
4428
2562
|
} from "fs";
|
|
4429
|
-
import { join as
|
|
4430
|
-
import { homedir as
|
|
2563
|
+
import { join as join2 } from "path";
|
|
2564
|
+
import { homedir as homedir2 } from "os";
|
|
4431
2565
|
function collectCommands(cmd) {
|
|
4432
2566
|
return cmd.commands.map((sub) => ({
|
|
4433
2567
|
name: sub.name(),
|
|
@@ -4603,7 +2737,7 @@ ${MARKER_END}`;
|
|
|
4603
2737
|
return { shell: sh, path: rcFile };
|
|
4604
2738
|
}
|
|
4605
2739
|
case "zsh": {
|
|
4606
|
-
const zshrc =
|
|
2740
|
+
const zshrc = join2(homedir2(), ".zshrc");
|
|
4607
2741
|
const evalLine = `${MARKER_START}
|
|
4608
2742
|
eval "$(vibe completion zsh)"
|
|
4609
2743
|
${MARKER_END}`;
|
|
@@ -4611,11 +2745,11 @@ ${MARKER_END}`;
|
|
|
4611
2745
|
return { shell: sh, path: zshrc };
|
|
4612
2746
|
}
|
|
4613
2747
|
case "fish": {
|
|
4614
|
-
const dir =
|
|
4615
|
-
if (!
|
|
4616
|
-
|
|
4617
|
-
const target =
|
|
4618
|
-
|
|
2748
|
+
const dir = join2(process.env.XDG_CONFIG_HOME || join2(homedir2(), ".config"), "fish", "completions");
|
|
2749
|
+
if (!existsSync2(dir))
|
|
2750
|
+
mkdirSync(dir, { recursive: true });
|
|
2751
|
+
const target = join2(dir, "vibe.fish");
|
|
2752
|
+
writeFileSync(target, generateFish(cmds), "utf8");
|
|
4619
2753
|
return { shell: sh, path: target };
|
|
4620
2754
|
}
|
|
4621
2755
|
}
|
|
@@ -4629,52 +2763,52 @@ function uninstallCompletion(shell) {
|
|
|
4629
2763
|
return { shell: sh, path: rcFile };
|
|
4630
2764
|
}
|
|
4631
2765
|
case "zsh": {
|
|
4632
|
-
const zshrc =
|
|
2766
|
+
const zshrc = join2(homedir2(), ".zshrc");
|
|
4633
2767
|
removeMarkedBlock(zshrc);
|
|
4634
2768
|
return { shell: sh, path: zshrc };
|
|
4635
2769
|
}
|
|
4636
2770
|
case "fish": {
|
|
4637
|
-
const target =
|
|
4638
|
-
if (
|
|
2771
|
+
const target = join2(process.env.XDG_CONFIG_HOME || join2(homedir2(), ".config"), "fish", "completions", "vibe.fish");
|
|
2772
|
+
if (existsSync2(target))
|
|
4639
2773
|
unlinkSync(target);
|
|
4640
2774
|
return { shell: sh, path: target };
|
|
4641
2775
|
}
|
|
4642
2776
|
}
|
|
4643
2777
|
}
|
|
4644
2778
|
function bashrcPath() {
|
|
4645
|
-
const bashrc =
|
|
4646
|
-
if (
|
|
2779
|
+
const bashrc = join2(homedir2(), ".bashrc");
|
|
2780
|
+
if (existsSync2(bashrc))
|
|
4647
2781
|
return bashrc;
|
|
4648
|
-
const profile =
|
|
4649
|
-
if (
|
|
2782
|
+
const profile = join2(homedir2(), ".bash_profile");
|
|
2783
|
+
if (existsSync2(profile))
|
|
4650
2784
|
return profile;
|
|
4651
2785
|
return bashrc;
|
|
4652
2786
|
}
|
|
4653
2787
|
function appendIfMissing(file, marker, block) {
|
|
4654
2788
|
let content = "";
|
|
4655
|
-
if (
|
|
4656
|
-
content =
|
|
2789
|
+
if (existsSync2(file))
|
|
2790
|
+
content = readFileSync(file, "utf8");
|
|
4657
2791
|
if (content.includes(marker)) {
|
|
4658
2792
|
removeMarkedBlock(file);
|
|
4659
|
-
content =
|
|
2793
|
+
content = existsSync2(file) ? readFileSync(file, "utf8") : "";
|
|
4660
2794
|
}
|
|
4661
|
-
|
|
2795
|
+
writeFileSync(file, content + `
|
|
4662
2796
|
` + block + `
|
|
4663
2797
|
`, "utf8");
|
|
4664
2798
|
}
|
|
4665
2799
|
function removeMarkedBlock(file) {
|
|
4666
|
-
if (!
|
|
2800
|
+
if (!existsSync2(file))
|
|
4667
2801
|
return;
|
|
4668
|
-
const content =
|
|
2802
|
+
const content = readFileSync(file, "utf8");
|
|
4669
2803
|
const startIdx = content.indexOf(MARKER_START);
|
|
4670
2804
|
const endIdx = content.indexOf(MARKER_END);
|
|
4671
2805
|
if (startIdx === -1 || endIdx === -1)
|
|
4672
2806
|
return;
|
|
4673
|
-
|
|
2807
|
+
writeFileSync(file, content.substring(0, startIdx) + content.substring(endIdx + MARKER_END.length), "utf8");
|
|
4674
2808
|
}
|
|
4675
2809
|
|
|
4676
2810
|
// src/cli/commands/completion.cmd.ts
|
|
4677
|
-
function
|
|
2811
|
+
function register9(program2) {
|
|
4678
2812
|
const cmd = program2.command("completion").description("Generate shell completion scripts (bash, zsh, fish)");
|
|
4679
2813
|
cmd.command("bash").description("Print Bash completion script").action(() => {
|
|
4680
2814
|
const cmds = collectCommands(program2);
|
|
@@ -4712,6 +2846,7 @@ function register28(program2) {
|
|
|
4712
2846
|
}
|
|
4713
2847
|
});
|
|
4714
2848
|
}
|
|
2849
|
+
|
|
4715
2850
|
// src/cli.ts
|
|
4716
2851
|
if (typeof Bun === "undefined") {
|
|
4717
2852
|
console.error(`\x1B[31mError:\x1B[0m VibeControls Agent requires the Bun runtime.
|
|
@@ -4719,16 +2854,14 @@ if (typeof Bun === "undefined") {
|
|
|
4719
2854
|
` + " Then run: bun run vibe ...");
|
|
4720
2855
|
process.exit(1);
|
|
4721
2856
|
}
|
|
4722
|
-
var __filename3 = fileURLToPath2(import.meta.url);
|
|
4723
|
-
var __dirname3 = dirname2(__filename3);
|
|
4724
2857
|
var packageVersion = "1.0.0";
|
|
4725
2858
|
try {
|
|
4726
|
-
const packageJsonPath =
|
|
4727
|
-
const packageJson =
|
|
2859
|
+
const packageJsonPath = join3(import.meta.dir, "..", "package.json");
|
|
2860
|
+
const packageJson = await Bun.file(packageJsonPath).json();
|
|
4728
2861
|
packageVersion = packageJson.version;
|
|
4729
2862
|
} catch {}
|
|
4730
2863
|
var program2 = new Command;
|
|
4731
|
-
program2.name("vibe").description("VibeControls Agent CLI \u2014 Remote development environment management").version(packageVersion, "-v, --version");
|
|
2864
|
+
program2.name("vibe").description("VibeControls Agent CLI \u2014 Remote development environment management").version(packageVersion, "-v, --version").option("--provider <name>", "Override the default provider for tunnel/session operations");
|
|
4732
2865
|
register(program2);
|
|
4733
2866
|
register2(program2);
|
|
4734
2867
|
register3(program2);
|
|
@@ -4738,55 +2871,39 @@ register6(program2);
|
|
|
4738
2871
|
register7(program2);
|
|
4739
2872
|
register8(program2);
|
|
4740
2873
|
register9(program2);
|
|
4741
|
-
register10(program2);
|
|
4742
|
-
register11(program2);
|
|
4743
|
-
register12(program2);
|
|
4744
|
-
register13(program2);
|
|
4745
|
-
register14(program2);
|
|
4746
|
-
register15(program2);
|
|
4747
|
-
register16(program2);
|
|
4748
|
-
register17(program2);
|
|
4749
|
-
register18(program2);
|
|
4750
|
-
register19(program2);
|
|
4751
|
-
register20(program2);
|
|
4752
|
-
register21(program2);
|
|
4753
|
-
register22(program2);
|
|
4754
|
-
register23(program2);
|
|
4755
|
-
register24(program2);
|
|
4756
|
-
register25(program2);
|
|
4757
|
-
register26(program2);
|
|
4758
|
-
register27(program2);
|
|
4759
|
-
register28(program2);
|
|
4760
2874
|
async function main() {
|
|
4761
2875
|
const pluginManager = new PluginManager;
|
|
2876
|
+
try {
|
|
2877
|
+
await pluginManager.loadCorePlugins();
|
|
2878
|
+
} catch {}
|
|
4762
2879
|
try {
|
|
4763
2880
|
await pluginManager.loadAll();
|
|
4764
2881
|
} catch {}
|
|
2882
|
+
const serviceRegistry = new ServiceRegistry;
|
|
2883
|
+
const cliStorage = {
|
|
2884
|
+
async get() {
|
|
2885
|
+
return null;
|
|
2886
|
+
},
|
|
2887
|
+
async set() {},
|
|
2888
|
+
async delete() {
|
|
2889
|
+
return false;
|
|
2890
|
+
},
|
|
2891
|
+
async list() {
|
|
2892
|
+
return [];
|
|
2893
|
+
},
|
|
2894
|
+
async deleteAll() {
|
|
2895
|
+
return 0;
|
|
2896
|
+
}
|
|
2897
|
+
};
|
|
2898
|
+
const hostServices = {
|
|
2899
|
+
storage: cliStorage,
|
|
2900
|
+
logger,
|
|
2901
|
+
serviceRegistry,
|
|
2902
|
+
getProvider: (type) => serviceRegistry.getProvider(type),
|
|
2903
|
+
getAgentBaseUrl: () => process.env.AGENT_URL || "http://localhost:3005",
|
|
2904
|
+
getAgentVersion: () => packageVersion
|
|
2905
|
+
};
|
|
4765
2906
|
try {
|
|
4766
|
-
const serviceRegistry = new ServiceRegistry;
|
|
4767
|
-
const cliStorage = {
|
|
4768
|
-
async get() {
|
|
4769
|
-
return null;
|
|
4770
|
-
},
|
|
4771
|
-
async set() {},
|
|
4772
|
-
async delete() {
|
|
4773
|
-
return false;
|
|
4774
|
-
},
|
|
4775
|
-
async list() {
|
|
4776
|
-
return [];
|
|
4777
|
-
},
|
|
4778
|
-
async deleteAll() {
|
|
4779
|
-
return 0;
|
|
4780
|
-
}
|
|
4781
|
-
};
|
|
4782
|
-
const hostServices = {
|
|
4783
|
-
storage: cliStorage,
|
|
4784
|
-
logger,
|
|
4785
|
-
serviceRegistry,
|
|
4786
|
-
getProvider: (type) => serviceRegistry.getProvider(type),
|
|
4787
|
-
getAgentBaseUrl: () => process.env.AGENT_URL || "http://localhost:3005",
|
|
4788
|
-
getAgentVersion: () => packageVersion
|
|
4789
|
-
};
|
|
4790
2907
|
await pluginManager.dispatchCliSetup(program2, hostServices);
|
|
4791
2908
|
} catch {}
|
|
4792
2909
|
program2.parse();
|
|
@@ -4796,5 +2913,5 @@ main().catch((err) => {
|
|
|
4796
2913
|
process.exit(1);
|
|
4797
2914
|
});
|
|
4798
2915
|
|
|
4799
|
-
//# debugId=
|
|
2916
|
+
//# debugId=B3B10A5CB7971CB864756E2164756E21
|
|
4800
2917
|
//# sourceMappingURL=cli.js.map
|