@vendian/cli 0.0.32 → 0.0.33
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/cli-wrapper.mjs +195 -105
- package/package.json +1 -1
package/cli-wrapper.mjs
CHANGED
|
@@ -1107,7 +1107,7 @@ import path8 from "node:path";
|
|
|
1107
1107
|
import readline from "node:readline";
|
|
1108
1108
|
|
|
1109
1109
|
// src/version.js
|
|
1110
|
-
var CLI_VERSION = true ? "0.0.
|
|
1110
|
+
var CLI_VERSION = true ? "0.0.33" : process.env.npm_package_version || "0.0.0-dev";
|
|
1111
1111
|
|
|
1112
1112
|
// src/npm-update.js
|
|
1113
1113
|
var NPM_CHECK_INTERVAL_MS = 30 * 60 * 1e3;
|
|
@@ -2387,6 +2387,9 @@ function setCursorVisible(visible) {
|
|
|
2387
2387
|
if (!process.stdout.isTTY) return;
|
|
2388
2388
|
process.stdout.write(visible ? "\x1B[?25h" : "\x1B[?25l");
|
|
2389
2389
|
}
|
|
2390
|
+
function clearScreen() {
|
|
2391
|
+
if (process.stdout.isTTY) process.stdout.write("\x1B[2J\x1B[H");
|
|
2392
|
+
}
|
|
2390
2393
|
function makeRl() {
|
|
2391
2394
|
return readline.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
2392
2395
|
}
|
|
@@ -2403,7 +2406,7 @@ async function ask(question, defaultValue = "") {
|
|
|
2403
2406
|
async function pressEnterToContinue({ grabActive = true } = {}) {
|
|
2404
2407
|
return new Promise((resolve) => {
|
|
2405
2408
|
const rl = makeRl();
|
|
2406
|
-
process.stdout.write("\n Press Enter to continue
|
|
2409
|
+
process.stdout.write("\n Press Enter to continue... ");
|
|
2407
2410
|
rl.once("line", () => {
|
|
2408
2411
|
rl.close();
|
|
2409
2412
|
resolve();
|
|
@@ -2411,6 +2414,82 @@ async function pressEnterToContinue({ grabActive = true } = {}) {
|
|
|
2411
2414
|
rl.once("close", resolve);
|
|
2412
2415
|
});
|
|
2413
2416
|
}
|
|
2417
|
+
async function pickMenu(items, { allowBack = true } = {}) {
|
|
2418
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
2419
|
+
return pickMenuNumeric(items, allowBack);
|
|
2420
|
+
}
|
|
2421
|
+
const backIdx = allowBack ? items.length : -1;
|
|
2422
|
+
const total = items.length + (allowBack ? 1 : 0);
|
|
2423
|
+
let sel = 0;
|
|
2424
|
+
function renderLine(i) {
|
|
2425
|
+
const isBack = allowBack && i === items.length;
|
|
2426
|
+
const label = isBack ? col.gray("Back") : items[i];
|
|
2427
|
+
const pfx = i === sel ? col.cyan("\u25BA") : " ";
|
|
2428
|
+
const num = col.gray(isBack ? "0" : String(i + 1));
|
|
2429
|
+
return ` ${pfx} ${num} ${label}\x1B[K`;
|
|
2430
|
+
}
|
|
2431
|
+
setCursorVisible(false);
|
|
2432
|
+
for (let i = 0; i < total; i++) {
|
|
2433
|
+
process.stdout.write(renderLine(i) + "\n");
|
|
2434
|
+
}
|
|
2435
|
+
return new Promise((resolve) => {
|
|
2436
|
+
readline.emitKeypressEvents(process.stdin);
|
|
2437
|
+
process.stdin.setRawMode(true);
|
|
2438
|
+
process.stdin.resume();
|
|
2439
|
+
function redraw() {
|
|
2440
|
+
process.stdout.write(`\x1B[${total}A`);
|
|
2441
|
+
for (let i = 0; i < total; i++) {
|
|
2442
|
+
process.stdout.write(renderLine(i) + "\n");
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
function done(result) {
|
|
2446
|
+
process.stdin.off("keypress", onKey);
|
|
2447
|
+
try {
|
|
2448
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
2449
|
+
} catch {
|
|
2450
|
+
}
|
|
2451
|
+
setCursorVisible(true);
|
|
2452
|
+
resolve(result);
|
|
2453
|
+
}
|
|
2454
|
+
function onKey(str, key) {
|
|
2455
|
+
if (!key) return;
|
|
2456
|
+
if (key.name === "up") {
|
|
2457
|
+
sel = (sel - 1 + total) % total;
|
|
2458
|
+
redraw();
|
|
2459
|
+
} else if (key.name === "down") {
|
|
2460
|
+
sel = (sel + 1) % total;
|
|
2461
|
+
redraw();
|
|
2462
|
+
} else if (key.name === "return") {
|
|
2463
|
+
done(sel === backIdx ? -1 : sel);
|
|
2464
|
+
} else if (key.name === "escape") {
|
|
2465
|
+
done(-1);
|
|
2466
|
+
} else if (key.ctrl && key.name === "c") {
|
|
2467
|
+
done(null);
|
|
2468
|
+
} else if (/^\d$/.test(str || "")) {
|
|
2469
|
+
const n = parseInt(str, 10);
|
|
2470
|
+
if (n === 0 && allowBack) {
|
|
2471
|
+
done(-1);
|
|
2472
|
+
return;
|
|
2473
|
+
}
|
|
2474
|
+
if (n >= 1 && n <= items.length) {
|
|
2475
|
+
done(n - 1);
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
process.stdin.on("keypress", onKey);
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
2483
|
+
async function pickMenuNumeric(items, allowBack) {
|
|
2484
|
+
items.forEach((item, i) => print(` ${col.blue(String(i + 1))} ${item}`));
|
|
2485
|
+
if (allowBack) print(` ${col.gray("0 Back")}`);
|
|
2486
|
+
print("");
|
|
2487
|
+
const ans = await ask("Choose");
|
|
2488
|
+
const n = parseInt(ans, 10);
|
|
2489
|
+
if (n === 0 && allowBack) return -1;
|
|
2490
|
+
if (n >= 1 && n <= items.length) return n - 1;
|
|
2491
|
+
return -1;
|
|
2492
|
+
}
|
|
2414
2493
|
async function withOutputMode(label, fn) {
|
|
2415
2494
|
setCursorVisible(true);
|
|
2416
2495
|
print("");
|
|
@@ -2449,20 +2528,19 @@ var HOME_ACTIONS = [
|
|
|
2449
2528
|
{ value: "exit", label: "Exit", desc: "" }
|
|
2450
2529
|
];
|
|
2451
2530
|
async function showHome({ env, platform }) {
|
|
2531
|
+
clearScreen();
|
|
2452
2532
|
print("");
|
|
2453
2533
|
printHeader({ env, platform });
|
|
2454
2534
|
print("");
|
|
2455
2535
|
print(col.bold(" What would you like to do?"));
|
|
2456
2536
|
print("");
|
|
2457
|
-
HOME_ACTIONS.
|
|
2458
|
-
const desc =
|
|
2459
|
-
|
|
2537
|
+
const items = HOME_ACTIONS.map((a) => {
|
|
2538
|
+
const desc = a.desc ? col.gray(` - ${a.desc}`) : "";
|
|
2539
|
+
return `${a.label.padEnd(22)}${desc}`;
|
|
2460
2540
|
});
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
if (!Number.isFinite(n) || n < 1 || n > HOME_ACTIONS.length) return "home";
|
|
2465
|
-
return HOME_ACTIONS[n - 1].value;
|
|
2541
|
+
const idx = await pickMenu(items, { allowBack: false });
|
|
2542
|
+
if (idx === null || idx < 0) return null;
|
|
2543
|
+
return HOME_ACTIONS[idx].value;
|
|
2466
2544
|
}
|
|
2467
2545
|
var ENDPOINTS = [
|
|
2468
2546
|
{ key: "prod", label: "Production", subtitle: "Recommended for live use" },
|
|
@@ -2472,33 +2550,27 @@ var ENDPOINTS = [
|
|
|
2472
2550
|
];
|
|
2473
2551
|
async function showConnect({ env, platform }) {
|
|
2474
2552
|
while (true) {
|
|
2553
|
+
clearScreen();
|
|
2475
2554
|
print("");
|
|
2476
2555
|
printHeader({ env, platform });
|
|
2477
2556
|
print("");
|
|
2478
2557
|
print(col.bold(" Login / Switch environment:"));
|
|
2479
2558
|
print("");
|
|
2480
2559
|
const rows = endpointRows({ env, platform });
|
|
2481
|
-
const
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
print("");
|
|
2492
|
-
const ans = await ask("Choose a number, or 0 to go back");
|
|
2493
|
-
const n = parseInt(ans, 10);
|
|
2494
|
-
if (n === 0 || isNaN(n)) return "home";
|
|
2495
|
-
if (n === items.length) return "home";
|
|
2496
|
-
if (n < 1 || n > items.length) continue;
|
|
2497
|
-
if (n === items.length - 1) {
|
|
2560
|
+
const epItems = ENDPOINTS.map((ep2) => {
|
|
2561
|
+
const row = rows.find((r) => r.key === ep2.key);
|
|
2562
|
+
const badge = row?.active ? col.green(" \u25CF active") : row?.status === "signed in" ? col.cyan(" \u25CB signed in") : col.gray(` - ${ep2.subtitle}`);
|
|
2563
|
+
return `${ep2.label.padEnd(26)}${badge}`;
|
|
2564
|
+
});
|
|
2565
|
+
const allItems = [...epItems, "Custom server URL..."];
|
|
2566
|
+
const idx = await pickMenu(allItems, { allowBack: true });
|
|
2567
|
+
if (idx === null) return null;
|
|
2568
|
+
if (idx === -1) return "home";
|
|
2569
|
+
if (idx === allItems.length - 1) {
|
|
2498
2570
|
await connectCustomUrl({ env, platform });
|
|
2499
2571
|
continue;
|
|
2500
2572
|
}
|
|
2501
|
-
const ep = ENDPOINTS[
|
|
2573
|
+
const ep = ENDPOINTS[idx];
|
|
2502
2574
|
print("");
|
|
2503
2575
|
const outcome = await connectEndpointInteractive({ backend: ep.key, label: ep.label, env, platform });
|
|
2504
2576
|
if (outcome.promptedInTui) {
|
|
@@ -2513,7 +2585,7 @@ async function connectCustomUrl({ env, platform }) {
|
|
|
2513
2585
|
const url = await ask("URL", "https://");
|
|
2514
2586
|
if (!url || url === "https://") return;
|
|
2515
2587
|
print("");
|
|
2516
|
-
print(col.gray(" Connecting
|
|
2588
|
+
print(col.gray(" Connecting..."));
|
|
2517
2589
|
const outcome = await connectEndpointInteractive({ apiUrl: url, label: url, env, platform });
|
|
2518
2590
|
if (outcome.promptedInTui) {
|
|
2519
2591
|
await pressEnterToContinue();
|
|
@@ -2540,8 +2612,9 @@ var COMMAND_GROUPS = [
|
|
|
2540
2612
|
] }
|
|
2541
2613
|
];
|
|
2542
2614
|
async function showCommands() {
|
|
2615
|
+
clearScreen();
|
|
2543
2616
|
print("");
|
|
2544
|
-
print(col.bold(` \u2191 VENDIAN v${CLI_VERSION}
|
|
2617
|
+
print(col.bold(` \u2191 VENDIAN v${CLI_VERSION} - All Commands`));
|
|
2545
2618
|
print("");
|
|
2546
2619
|
for (const g of COMMAND_GROUPS) {
|
|
2547
2620
|
print(col.blue(col.bold(` ${g.section}`)));
|
|
@@ -2555,6 +2628,7 @@ async function showCommands() {
|
|
|
2555
2628
|
}
|
|
2556
2629
|
async function pickAgentsToRun({ env, platform, candidates }) {
|
|
2557
2630
|
if (candidates.length === 0) {
|
|
2631
|
+
clearScreen();
|
|
2558
2632
|
print("");
|
|
2559
2633
|
print(col.yellow(" Couldn't find any agents. Enter your agents folder path:"));
|
|
2560
2634
|
const input = await ask("Folder", "./agents");
|
|
@@ -2569,21 +2643,18 @@ async function pickAgentsToRun({ env, platform, candidates }) {
|
|
|
2569
2643
|
return pickProject({ env, platform, candidates });
|
|
2570
2644
|
}
|
|
2571
2645
|
async function pickProject({ env, platform, candidates }) {
|
|
2572
|
-
|
|
2646
|
+
clearScreen();
|
|
2573
2647
|
printHeader({ env, platform });
|
|
2574
2648
|
print("");
|
|
2575
2649
|
print(col.bold(" Which project do you want to run?"));
|
|
2576
2650
|
print("");
|
|
2577
|
-
candidates.
|
|
2651
|
+
const items = candidates.map((candidate) => {
|
|
2578
2652
|
const name = readManifestName(candidate.absolutePath) || friendlyName(path8.basename(candidate.absolutePath) || candidate.path);
|
|
2579
|
-
|
|
2653
|
+
return `${name.padEnd(32)} ${col.gray(`${candidate.agentCount} agent${candidate.agentCount === 1 ? "" : "s"}`)}`;
|
|
2580
2654
|
});
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
const
|
|
2584
|
-
const n = parseInt(ans, 10);
|
|
2585
|
-
if (n === 0 || isNaN(n) || n > candidates.length) return null;
|
|
2586
|
-
const chosen = candidates[n - 1];
|
|
2655
|
+
const idx = await pickMenu(items, { allowBack: true });
|
|
2656
|
+
if (idx === null || idx === -1) return null;
|
|
2657
|
+
const chosen = candidates[idx];
|
|
2587
2658
|
if (chosen.agentCount <= 1) return { agentsDir: chosen.path };
|
|
2588
2659
|
return pickAgentsFromFolder({ env, platform, candidate: chosen });
|
|
2589
2660
|
}
|
|
@@ -2594,23 +2665,23 @@ async function pickAgentsFromFolder({ env, platform, candidate }) {
|
|
|
2594
2665
|
...f,
|
|
2595
2666
|
displayName: readManifestName(f.absolutePath) || friendlyName(f.name || path8.basename(f.path))
|
|
2596
2667
|
}));
|
|
2597
|
-
|
|
2668
|
+
clearScreen();
|
|
2598
2669
|
printHeader({ env, platform });
|
|
2599
2670
|
print("");
|
|
2600
2671
|
print(col.bold(" Which agents do you want to start?"));
|
|
2601
2672
|
print("");
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
const
|
|
2607
|
-
|
|
2608
|
-
if (
|
|
2609
|
-
|
|
2610
|
-
return { agentsDir: named[n - 2].path };
|
|
2673
|
+
const items = [
|
|
2674
|
+
col.bold(`Run all ${folders.length} agents`),
|
|
2675
|
+
...named.map((f) => f.displayName)
|
|
2676
|
+
];
|
|
2677
|
+
const idx = await pickMenu(items, { allowBack: true });
|
|
2678
|
+
if (idx === null || idx === -1) return null;
|
|
2679
|
+
if (idx === 0) return { agentsDir: candidate.path };
|
|
2680
|
+
return { agentsDir: named[idx - 1].path };
|
|
2611
2681
|
}
|
|
2612
2682
|
async function pickSingleAgentToRun({ env, platform, candidates }) {
|
|
2613
2683
|
if (candidates.length === 0) {
|
|
2684
|
+
clearScreen();
|
|
2614
2685
|
print("");
|
|
2615
2686
|
print(col.yellow(" Couldn't find any agents."));
|
|
2616
2687
|
const input = await ask("Agent folder", "./agents/my-agent");
|
|
@@ -2631,24 +2702,19 @@ async function pickSingleAgentToRun({ env, platform, candidates }) {
|
|
|
2631
2702
|
}];
|
|
2632
2703
|
});
|
|
2633
2704
|
if (agents.length === 1) return agents[0];
|
|
2634
|
-
|
|
2705
|
+
clearScreen();
|
|
2635
2706
|
printHeader({ env, platform });
|
|
2636
2707
|
print("");
|
|
2637
2708
|
print(col.bold(" Which agent do you want to run?"));
|
|
2638
2709
|
print("");
|
|
2639
|
-
agents.
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
print("");
|
|
2644
|
-
const ans = await ask("Choose");
|
|
2645
|
-
const n = parseInt(ans, 10);
|
|
2646
|
-
if (n === 0 || isNaN(n) || n > agents.length) return null;
|
|
2647
|
-
return agents[n - 1];
|
|
2710
|
+
const items = agents.map((a) => `${a.displayName.padEnd(32)} ${col.gray(a.path)}`);
|
|
2711
|
+
const idx = await pickMenu(items, { allowBack: true });
|
|
2712
|
+
if (idx === null || idx === -1) return null;
|
|
2713
|
+
return agents[idx];
|
|
2648
2714
|
}
|
|
2649
2715
|
async function chooseCloudWorkspace({ env, platform, loadingTitle, pickerTitle } = {}) {
|
|
2650
2716
|
print("");
|
|
2651
|
-
process.stdout.write(` ${col.gray(loadingTitle || "Loading workspaces
|
|
2717
|
+
process.stdout.write(` ${col.gray(loadingTitle || "Loading workspaces...")}
|
|
2652
2718
|
`);
|
|
2653
2719
|
let wsResult;
|
|
2654
2720
|
try {
|
|
@@ -2679,22 +2745,20 @@ async function chooseCloudWorkspace({ env, platform, loadingTitle, pickerTitle }
|
|
|
2679
2745
|
const ws2 = wsResult.workspaces[0];
|
|
2680
2746
|
return { id: ws2.id || "", label: workspaceLabel(ws2) };
|
|
2681
2747
|
}
|
|
2748
|
+
clearScreen();
|
|
2682
2749
|
print("");
|
|
2683
|
-
|
|
2750
|
+
printHeader({ env, platform });
|
|
2684
2751
|
print("");
|
|
2685
|
-
|
|
2686
|
-
print(` ${col.blue(String(i + 1))} ${workspaceLabel(ws2)}`);
|
|
2687
|
-
});
|
|
2688
|
-
print(` ${col.gray("0 Back")}`);
|
|
2752
|
+
print(col.bold(` ${pickerTitle || "Choose a workspace:"}`));
|
|
2689
2753
|
print("");
|
|
2690
|
-
const
|
|
2691
|
-
const
|
|
2692
|
-
if (
|
|
2693
|
-
const ws = wsResult.workspaces[
|
|
2754
|
+
const items = wsResult.workspaces.map((ws2) => workspaceLabel(ws2));
|
|
2755
|
+
const idx = await pickMenu(items, { allowBack: true });
|
|
2756
|
+
if (idx === null || idx === -1) return null;
|
|
2757
|
+
const ws = wsResult.workspaces[idx];
|
|
2694
2758
|
return { id: ws.id || "", label: workspaceLabel(ws) };
|
|
2695
2759
|
}
|
|
2696
2760
|
async function showCreate({ env, platform }) {
|
|
2697
|
-
|
|
2761
|
+
clearScreen();
|
|
2698
2762
|
printHeader({ env, platform });
|
|
2699
2763
|
print("");
|
|
2700
2764
|
print(col.bold(" Create a new agent"));
|
|
@@ -2715,7 +2779,7 @@ async function showRun({ env, platform }) {
|
|
|
2715
2779
|
const workspace = await chooseCloudWorkspace({
|
|
2716
2780
|
env,
|
|
2717
2781
|
platform,
|
|
2718
|
-
loadingTitle: "Getting ready to run this agent
|
|
2782
|
+
loadingTitle: "Getting ready to run this agent...",
|
|
2719
2783
|
pickerTitle: "Which project should own this run?"
|
|
2720
2784
|
});
|
|
2721
2785
|
if (!workspace) return "home";
|
|
@@ -2738,7 +2802,7 @@ async function showServe({ env, platform }) {
|
|
|
2738
2802
|
const workspace = await chooseCloudWorkspace({
|
|
2739
2803
|
env,
|
|
2740
2804
|
platform,
|
|
2741
|
-
loadingTitle: "Getting ready to run your agents
|
|
2805
|
+
loadingTitle: "Getting ready to run your agents...",
|
|
2742
2806
|
pickerTitle: "Which project do you want to run?"
|
|
2743
2807
|
});
|
|
2744
2808
|
if (!workspace) return "home";
|
|
@@ -2754,7 +2818,11 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
|
|
|
2754
2818
|
let stopTimer = null;
|
|
2755
2819
|
let dashboardClosed = false;
|
|
2756
2820
|
let logStore = null;
|
|
2821
|
+
let lastAgentOnlinePrint = 0;
|
|
2822
|
+
let agentsSeenOnline = false;
|
|
2823
|
+
let initialSetupDone = false;
|
|
2757
2824
|
const W = Math.min(process.stdout.columns || 80, 100);
|
|
2825
|
+
clearScreen();
|
|
2758
2826
|
setCursorVisible(false);
|
|
2759
2827
|
print("");
|
|
2760
2828
|
print(col.gray("\u2550".repeat(W)));
|
|
@@ -2787,23 +2855,60 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
|
|
|
2787
2855
|
if (!event) return;
|
|
2788
2856
|
const type = String(event.type || "");
|
|
2789
2857
|
const agentPath = String(event.relativePath || event.path || "");
|
|
2790
|
-
const agentName = agentPath ? friendlyName(path8.basename(agentPath)) || agentPath : "";
|
|
2858
|
+
const agentName = agentPath ? friendlyName(path8.basename(agentPath)) || agentPath : ".";
|
|
2859
|
+
if (type === "daemon_wake_received") return;
|
|
2860
|
+
if (type === "lease_claim_no_job") return;
|
|
2861
|
+
if (type === "dispatch_job_received" || type === "dispatch_job_acked") return;
|
|
2862
|
+
if (type === "inventory_synced") {
|
|
2863
|
+
const agents = Array.isArray(event.agents) ? event.agents : [];
|
|
2864
|
+
const hasProblems = agents.some((a) => a.status === "error" || a.status === "disabled");
|
|
2865
|
+
const allOnline = agents.length > 0 && agents.every((a) => a.status === "online");
|
|
2866
|
+
const now = Date.now();
|
|
2867
|
+
if (!hasProblems && allOnline && agentsSeenOnline && now - lastAgentOnlinePrint < 12e4) return;
|
|
2868
|
+
for (const a of agents) {
|
|
2869
|
+
const name = friendlyName(path8.basename(a.relativePath || ".")) || a.manifestName || a.relativePath || "?";
|
|
2870
|
+
if (a.status === "error") {
|
|
2871
|
+
printAgent(name, col.red(`\u2716 Error: ${a.errorMessage || ""}`));
|
|
2872
|
+
continue;
|
|
2873
|
+
}
|
|
2874
|
+
if (a.status === "disabled") {
|
|
2875
|
+
printAgent(name, col.yellow(`\u26A0 Disabled: ${a.disabledReason || ""}`));
|
|
2876
|
+
continue;
|
|
2877
|
+
}
|
|
2878
|
+
if (a.status === "online") {
|
|
2879
|
+
printAgent(name, col.green("\u25CF Online"));
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
if (allOnline) {
|
|
2883
|
+
lastAgentOnlinePrint = now;
|
|
2884
|
+
agentsSeenOnline = true;
|
|
2885
|
+
initialSetupDone = true;
|
|
2886
|
+
}
|
|
2887
|
+
return;
|
|
2888
|
+
}
|
|
2791
2889
|
if (type === "job_started") {
|
|
2792
|
-
|
|
2890
|
+
print("");
|
|
2891
|
+
printRun(agentName, col.blue("\u25B6"), col.bold(`Started run ${shortId2(event.runId || "")}`));
|
|
2793
2892
|
return;
|
|
2794
2893
|
}
|
|
2795
2894
|
if (type === "job_completed") {
|
|
2796
2895
|
const ok = event.success !== false;
|
|
2797
|
-
|
|
2896
|
+
const errText = ok ? "" : fmtErr(event.error) || "check serve logs for details";
|
|
2897
|
+
printRun(agentName, ok ? col.green("\u2714") : col.red("\u2716"), ok ? col.green("Completed") : col.red(`Failed: ${errText}`));
|
|
2898
|
+
print("");
|
|
2798
2899
|
return;
|
|
2799
2900
|
}
|
|
2800
2901
|
if (type === "run_log") {
|
|
2801
2902
|
const lvl = String(event.level || "info");
|
|
2802
|
-
const
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2903
|
+
const evtType = String(event.eventType || "");
|
|
2904
|
+
const msg = String(
|
|
2905
|
+
event.message || (event.data?.label ? event.data.label : null) || (event.stepId ? `${evtType === "step_event" ? "Step" : evtType}: ${event.stepId}` : null) || evtType || ""
|
|
2906
|
+
);
|
|
2907
|
+
if (!msg || msg === "heartbeat") return;
|
|
2908
|
+
if (evtType === "start" && msg === "Run started") return;
|
|
2909
|
+
const isCompletionEvent = evtType === "completion";
|
|
2910
|
+
const icon = lvl === "error" ? col.red("\u2716") : isCompletionEvent ? event.success !== false ? col.green("\u2714") : col.red("\u2716") : col.cyan("\u2502");
|
|
2911
|
+
printRun(agentName, icon, clip(msg, 90));
|
|
2807
2912
|
return;
|
|
2808
2913
|
}
|
|
2809
2914
|
if (type === "error" && agentPath) {
|
|
@@ -2811,7 +2916,7 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
|
|
|
2811
2916
|
return;
|
|
2812
2917
|
}
|
|
2813
2918
|
if (type === "agent_prepare_started") {
|
|
2814
|
-
printAgent(agentName, col.gray("Preparing
|
|
2919
|
+
printAgent(agentName, col.gray("Preparing..."));
|
|
2815
2920
|
return;
|
|
2816
2921
|
}
|
|
2817
2922
|
if (type === "agent_prepare_progress") {
|
|
@@ -2831,28 +2936,10 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
|
|
|
2831
2936
|
printAgent(agentName, col.green("\u2714 Ready"));
|
|
2832
2937
|
return;
|
|
2833
2938
|
}
|
|
2834
|
-
if (type === "inventory_synced") {
|
|
2835
|
-
const agents = Array.isArray(event.agents) ? event.agents : [];
|
|
2836
|
-
for (const a of agents) {
|
|
2837
|
-
const name = friendlyName(path8.basename(a.relativePath || ".")) || a.manifestName || a.relativePath || "?";
|
|
2838
|
-
if (a.status === "error") {
|
|
2839
|
-
printAgent(name, col.red(`\u2716 Error: ${a.errorMessage || ""}`));
|
|
2840
|
-
continue;
|
|
2841
|
-
}
|
|
2842
|
-
if (a.status === "disabled") {
|
|
2843
|
-
printAgent(name, col.yellow(`\u26A0 Disabled: ${a.disabledReason || ""}`));
|
|
2844
|
-
continue;
|
|
2845
|
-
}
|
|
2846
|
-
if (a.status === "online") {
|
|
2847
|
-
printAgent(name, col.green("\u25CF Online"));
|
|
2848
|
-
continue;
|
|
2849
|
-
}
|
|
2850
|
-
}
|
|
2851
|
-
return;
|
|
2852
|
-
}
|
|
2853
2939
|
const dbgArr = serveDebugEntries([event], 1);
|
|
2854
2940
|
if (dbgArr.length > 0) {
|
|
2855
2941
|
const dbg = dbgArr[0];
|
|
2942
|
+
if (initialSetupDone && dbg.level === "info") return;
|
|
2856
2943
|
const msg = dbg.level === "error" ? col.red(dbg.message) : dbg.level === "warn" ? col.yellow(dbg.message) : col.gray(dbg.message);
|
|
2857
2944
|
printDaemon(dbg.eventType, msg);
|
|
2858
2945
|
}
|
|
@@ -2871,7 +2958,7 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
|
|
|
2871
2958
|
platform,
|
|
2872
2959
|
onProgress: (msg) => {
|
|
2873
2960
|
if (dashboardClosed) return;
|
|
2874
|
-
process.stdout.write(`\r ${col.gray(clip(msg || "Preparing
|
|
2961
|
+
process.stdout.write(`\r ${col.gray(clip(msg || "Preparing...", 70))} `);
|
|
2875
2962
|
}
|
|
2876
2963
|
});
|
|
2877
2964
|
process.stdout.write("\r" + " ".repeat(80) + "\r");
|
|
@@ -2988,7 +3075,10 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
|
|
|
2988
3075
|
const text = String(chunk).trim();
|
|
2989
3076
|
if (!text) return;
|
|
2990
3077
|
stderrChunks.push(text);
|
|
2991
|
-
|
|
3078
|
+
const isNoise = /^\[local\]\s+(running|uploading|preparing)/i.test(text) || /^(Resolved|Audited|Using Python)\b/i.test(text);
|
|
3079
|
+
if (!isNoise) {
|
|
3080
|
+
printDaemon("stderr", col.yellow(clip(text, 120)));
|
|
3081
|
+
}
|
|
2992
3082
|
state = applyServeEvent(state, {
|
|
2993
3083
|
type: "daemon_stderr",
|
|
2994
3084
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -3016,7 +3106,7 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
|
|
|
3016
3106
|
} catch {
|
|
3017
3107
|
}
|
|
3018
3108
|
removeKeypress();
|
|
3019
|
-
process.stdout.write("\n Press Enter to return to menu
|
|
3109
|
+
process.stdout.write("\n Press Enter to return to menu... ");
|
|
3020
3110
|
const rl = makeRl();
|
|
3021
3111
|
rl.once("line", () => {
|
|
3022
3112
|
rl.close();
|
|
@@ -3128,7 +3218,7 @@ async function connectEndpointInteractive({
|
|
|
3128
3218
|
const status = cloudAuthStatus({ backend, apiUrl, env, platform });
|
|
3129
3219
|
const destination = label || envLabel(status.apiUrl);
|
|
3130
3220
|
if (status.authenticated) {
|
|
3131
|
-
print(col.gray(` Connecting to ${destination}
|
|
3221
|
+
print(col.gray(` Connecting to ${destination}...`));
|
|
3132
3222
|
try {
|
|
3133
3223
|
await switchOrLoginEndpoint({ backend, apiUrl, env, platform, setupFn, activateFn });
|
|
3134
3224
|
print(col.green(` ${fig.check} ${successLabel || `Signed in to ${destination} successfully`}`));
|
|
@@ -3213,7 +3303,7 @@ function readManifestName(absoluteFolderPath) {
|
|
|
3213
3303
|
}
|
|
3214
3304
|
function clip(value, length) {
|
|
3215
3305
|
const text = String(value || "");
|
|
3216
|
-
return text.length <= length ? text : `${text.slice(0, Math.max(0, length - 1))}
|
|
3306
|
+
return text.length <= length ? text : `${text.slice(0, Math.max(0, length - 1))}...`;
|
|
3217
3307
|
}
|
|
3218
3308
|
function errMsg(error) {
|
|
3219
3309
|
return error && typeof error.message === "string" ? error.message : String(error);
|