@vendian/cli 0.0.32 → 0.0.34

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.
Files changed (2) hide show
  1. package/cli-wrapper.mjs +202 -105
  2. 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.32" : process.env.npm_package_version || "0.0.0-dev";
1110
+ var CLI_VERSION = true ? "0.0.34" : 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\u2026 ");
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.forEach((action, i) => {
2458
- const desc = action.desc ? col.gray(` \u2014 ${action.desc}`) : "";
2459
- print(` ${col.blue(String(i + 1))} ${action.label.padEnd(22)}${desc}`);
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
- print("");
2462
- const ans = await ask("Choose a number");
2463
- const n = parseInt(ans, 10);
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 items = [
2482
- ...ENDPOINTS.map((ep2) => {
2483
- const row = rows.find((r) => r.key === ep2.key);
2484
- const badge = row?.active ? col.green(" \u25CF active") : row?.status === "signed in" ? col.cyan(" \u25CB signed in") : col.gray(` \u2014 ${ep2.subtitle}`);
2485
- return `${ep2.label.padEnd(26)}${badge}`;
2486
- }),
2487
- "Custom server URL\u2026",
2488
- col.gray("Back")
2489
- ];
2490
- items.forEach((item, i) => print(` ${col.blue(String(i + 1))} ${item}`));
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[n - 1];
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\u2026"));
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();
@@ -2534,14 +2606,20 @@ var COMMAND_GROUPS = [
2534
2606
  { cmd: "vendian cloud local serve --agents-dir .", desc: "Start agents" },
2535
2607
  { cmd: "vendian login --backend staging", desc: "Sign in to staging" }
2536
2608
  ] },
2609
+ { section: "Syncing & deploying", commands: [
2610
+ { cmd: "vendian cloud local push --collection-id ID --project-id PID", desc: "Push code to project repo" },
2611
+ { cmd: "vendian cloud local push --branch feature/x --from dev", desc: "Push to a new branch" },
2612
+ { cmd: "vendian cloud local deploy --collection-id ID --project-id PID", desc: "Deploy to cloud" }
2613
+ ] },
2537
2614
  { section: "Maintenance", commands: [
2538
2615
  { cmd: "vendian doctor", desc: "Check if everything is set up" },
2539
2616
  { cmd: "vendian update", desc: "Update to the latest version" }
2540
2617
  ] }
2541
2618
  ];
2542
2619
  async function showCommands() {
2620
+ clearScreen();
2543
2621
  print("");
2544
- print(col.bold(` \u2191 VENDIAN v${CLI_VERSION} \u2014 All Commands`));
2622
+ print(col.bold(` \u2191 VENDIAN v${CLI_VERSION} - All Commands`));
2545
2623
  print("");
2546
2624
  for (const g of COMMAND_GROUPS) {
2547
2625
  print(col.blue(col.bold(` ${g.section}`)));
@@ -2555,6 +2633,7 @@ async function showCommands() {
2555
2633
  }
2556
2634
  async function pickAgentsToRun({ env, platform, candidates }) {
2557
2635
  if (candidates.length === 0) {
2636
+ clearScreen();
2558
2637
  print("");
2559
2638
  print(col.yellow(" Couldn't find any agents. Enter your agents folder path:"));
2560
2639
  const input = await ask("Folder", "./agents");
@@ -2569,21 +2648,18 @@ async function pickAgentsToRun({ env, platform, candidates }) {
2569
2648
  return pickProject({ env, platform, candidates });
2570
2649
  }
2571
2650
  async function pickProject({ env, platform, candidates }) {
2572
- print("");
2651
+ clearScreen();
2573
2652
  printHeader({ env, platform });
2574
2653
  print("");
2575
2654
  print(col.bold(" Which project do you want to run?"));
2576
2655
  print("");
2577
- candidates.forEach((candidate, i) => {
2656
+ const items = candidates.map((candidate) => {
2578
2657
  const name = readManifestName(candidate.absolutePath) || friendlyName(path8.basename(candidate.absolutePath) || candidate.path);
2579
- print(` ${col.blue(String(i + 1))} ${name.padEnd(32)} ${col.gray(`${candidate.agentCount} agent${candidate.agentCount === 1 ? "" : "s"}`)}`);
2658
+ return `${name.padEnd(32)} ${col.gray(`${candidate.agentCount} agent${candidate.agentCount === 1 ? "" : "s"}`)}`;
2580
2659
  });
2581
- print(` ${col.gray("0 Back")}`);
2582
- print("");
2583
- const ans = await ask("Choose");
2584
- const n = parseInt(ans, 10);
2585
- if (n === 0 || isNaN(n) || n > candidates.length) return null;
2586
- const chosen = candidates[n - 1];
2660
+ const idx = await pickMenu(items, { allowBack: true });
2661
+ if (idx === null || idx === -1) return null;
2662
+ const chosen = candidates[idx];
2587
2663
  if (chosen.agentCount <= 1) return { agentsDir: chosen.path };
2588
2664
  return pickAgentsFromFolder({ env, platform, candidate: chosen });
2589
2665
  }
@@ -2594,23 +2670,23 @@ async function pickAgentsFromFolder({ env, platform, candidate }) {
2594
2670
  ...f,
2595
2671
  displayName: readManifestName(f.absolutePath) || friendlyName(f.name || path8.basename(f.path))
2596
2672
  }));
2597
- print("");
2673
+ clearScreen();
2598
2674
  printHeader({ env, platform });
2599
2675
  print("");
2600
2676
  print(col.bold(" Which agents do you want to start?"));
2601
2677
  print("");
2602
- print(` ${col.blue("1")} Run all ${folders.length} agents`);
2603
- named.forEach((f, i) => print(` ${col.blue(String(i + 2))} ${f.displayName}`));
2604
- print(` ${col.gray("0 Back")}`);
2605
- print("");
2606
- const ans = await ask("Choose");
2607
- const n = parseInt(ans, 10);
2608
- if (n === 0 || isNaN(n) || n > named.length + 1) return null;
2609
- if (n === 1) return { agentsDir: candidate.path };
2610
- return { agentsDir: named[n - 2].path };
2678
+ const items = [
2679
+ col.bold(`Run all ${folders.length} agents`),
2680
+ ...named.map((f) => f.displayName)
2681
+ ];
2682
+ const idx = await pickMenu(items, { allowBack: true });
2683
+ if (idx === null || idx === -1) return null;
2684
+ if (idx === 0) return { agentsDir: candidate.path };
2685
+ return { agentsDir: named[idx - 1].path };
2611
2686
  }
2612
2687
  async function pickSingleAgentToRun({ env, platform, candidates }) {
2613
2688
  if (candidates.length === 0) {
2689
+ clearScreen();
2614
2690
  print("");
2615
2691
  print(col.yellow(" Couldn't find any agents."));
2616
2692
  const input = await ask("Agent folder", "./agents/my-agent");
@@ -2631,24 +2707,19 @@ async function pickSingleAgentToRun({ env, platform, candidates }) {
2631
2707
  }];
2632
2708
  });
2633
2709
  if (agents.length === 1) return agents[0];
2634
- print("");
2710
+ clearScreen();
2635
2711
  printHeader({ env, platform });
2636
2712
  print("");
2637
2713
  print(col.bold(" Which agent do you want to run?"));
2638
2714
  print("");
2639
- agents.forEach((agent, i) => {
2640
- print(` ${col.blue(String(i + 1))} ${agent.displayName.padEnd(32)} ${col.gray(agent.path)}`);
2641
- });
2642
- print(` ${col.gray("0 Back")}`);
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];
2715
+ const items = agents.map((a) => `${a.displayName.padEnd(32)} ${col.gray(a.path)}`);
2716
+ const idx = await pickMenu(items, { allowBack: true });
2717
+ if (idx === null || idx === -1) return null;
2718
+ return agents[idx];
2648
2719
  }
2649
2720
  async function chooseCloudWorkspace({ env, platform, loadingTitle, pickerTitle } = {}) {
2650
2721
  print("");
2651
- process.stdout.write(` ${col.gray(loadingTitle || "Loading workspaces\u2026")}
2722
+ process.stdout.write(` ${col.gray(loadingTitle || "Loading workspaces...")}
2652
2723
  `);
2653
2724
  let wsResult;
2654
2725
  try {
@@ -2679,22 +2750,20 @@ async function chooseCloudWorkspace({ env, platform, loadingTitle, pickerTitle }
2679
2750
  const ws2 = wsResult.workspaces[0];
2680
2751
  return { id: ws2.id || "", label: workspaceLabel(ws2) };
2681
2752
  }
2753
+ clearScreen();
2682
2754
  print("");
2683
- print(col.bold(` ${pickerTitle || "Choose a workspace:"}`));
2755
+ printHeader({ env, platform });
2684
2756
  print("");
2685
- wsResult.workspaces.forEach((ws2, i) => {
2686
- print(` ${col.blue(String(i + 1))} ${workspaceLabel(ws2)}`);
2687
- });
2688
- print(` ${col.gray("0 Back")}`);
2757
+ print(col.bold(` ${pickerTitle || "Choose a workspace:"}`));
2689
2758
  print("");
2690
- const ans = await ask("Choose");
2691
- const n = parseInt(ans, 10);
2692
- if (n === 0 || isNaN(n) || n > wsResult.workspaces.length) return null;
2693
- const ws = wsResult.workspaces[n - 1];
2759
+ const items = wsResult.workspaces.map((ws2) => workspaceLabel(ws2));
2760
+ const idx = await pickMenu(items, { allowBack: true });
2761
+ if (idx === null || idx === -1) return null;
2762
+ const ws = wsResult.workspaces[idx];
2694
2763
  return { id: ws.id || "", label: workspaceLabel(ws) };
2695
2764
  }
2696
2765
  async function showCreate({ env, platform }) {
2697
- print("");
2766
+ clearScreen();
2698
2767
  printHeader({ env, platform });
2699
2768
  print("");
2700
2769
  print(col.bold(" Create a new agent"));
@@ -2715,7 +2784,7 @@ async function showRun({ env, platform }) {
2715
2784
  const workspace = await chooseCloudWorkspace({
2716
2785
  env,
2717
2786
  platform,
2718
- loadingTitle: "Getting ready to run this agent\u2026",
2787
+ loadingTitle: "Getting ready to run this agent...",
2719
2788
  pickerTitle: "Which project should own this run?"
2720
2789
  });
2721
2790
  if (!workspace) return "home";
@@ -2738,7 +2807,7 @@ async function showServe({ env, platform }) {
2738
2807
  const workspace = await chooseCloudWorkspace({
2739
2808
  env,
2740
2809
  platform,
2741
- loadingTitle: "Getting ready to run your agents\u2026",
2810
+ loadingTitle: "Getting ready to run your agents...",
2742
2811
  pickerTitle: "Which project do you want to run?"
2743
2812
  });
2744
2813
  if (!workspace) return "home";
@@ -2754,7 +2823,11 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
2754
2823
  let stopTimer = null;
2755
2824
  let dashboardClosed = false;
2756
2825
  let logStore = null;
2826
+ let lastAgentOnlinePrint = 0;
2827
+ let agentsSeenOnline = false;
2828
+ let initialSetupDone = false;
2757
2829
  const W = Math.min(process.stdout.columns || 80, 100);
2830
+ clearScreen();
2758
2831
  setCursorVisible(false);
2759
2832
  print("");
2760
2833
  print(col.gray("\u2550".repeat(W)));
@@ -2787,23 +2860,60 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
2787
2860
  if (!event) return;
2788
2861
  const type = String(event.type || "");
2789
2862
  const agentPath = String(event.relativePath || event.path || "");
2790
- const agentName = agentPath ? friendlyName(path8.basename(agentPath)) || agentPath : "";
2863
+ const agentName = agentPath ? friendlyName(path8.basename(agentPath)) || agentPath : ".";
2864
+ if (type === "daemon_wake_received") return;
2865
+ if (type === "lease_claim_no_job") return;
2866
+ if (type === "dispatch_job_received" || type === "dispatch_job_acked") return;
2867
+ if (type === "inventory_synced") {
2868
+ const agents = Array.isArray(event.agents) ? event.agents : [];
2869
+ const hasProblems = agents.some((a) => a.status === "error" || a.status === "disabled");
2870
+ const allOnline = agents.length > 0 && agents.every((a) => a.status === "online");
2871
+ const now = Date.now();
2872
+ if (!hasProblems && allOnline && agentsSeenOnline && now - lastAgentOnlinePrint < 12e4) return;
2873
+ for (const a of agents) {
2874
+ const name = friendlyName(path8.basename(a.relativePath || ".")) || a.manifestName || a.relativePath || "?";
2875
+ if (a.status === "error") {
2876
+ printAgent(name, col.red(`\u2716 Error: ${a.errorMessage || ""}`));
2877
+ continue;
2878
+ }
2879
+ if (a.status === "disabled") {
2880
+ printAgent(name, col.yellow(`\u26A0 Disabled: ${a.disabledReason || ""}`));
2881
+ continue;
2882
+ }
2883
+ if (a.status === "online") {
2884
+ printAgent(name, col.green("\u25CF Online"));
2885
+ }
2886
+ }
2887
+ if (allOnline) {
2888
+ lastAgentOnlinePrint = now;
2889
+ agentsSeenOnline = true;
2890
+ initialSetupDone = true;
2891
+ }
2892
+ return;
2893
+ }
2791
2894
  if (type === "job_started") {
2792
- printRun(agentName, col.blue("\u25B6"), `Started ${event.jobType || "job"} ${shortId2(event.runId || "")}`);
2895
+ print("");
2896
+ printRun(agentName, col.blue("\u25B6"), col.bold(`Started run ${shortId2(event.runId || "")}`));
2793
2897
  return;
2794
2898
  }
2795
2899
  if (type === "job_completed") {
2796
2900
  const ok = event.success !== false;
2797
- printRun(agentName, ok ? col.green("\u2714") : col.red("\u2716"), ok ? "Completed" : `Failed: ${fmtErr(event.error)}`);
2901
+ const errText = ok ? "" : fmtErr(event.error) || "check serve logs for details";
2902
+ printRun(agentName, ok ? col.green("\u2714") : col.red("\u2716"), ok ? col.green("Completed") : col.red(`Failed: ${errText}`));
2903
+ print("");
2798
2904
  return;
2799
2905
  }
2800
2906
  if (type === "run_log") {
2801
2907
  const lvl = String(event.level || "info");
2802
- const msg = String(event.message || event.eventType || "");
2803
- if (!msg) return;
2804
- const isCompletionEvent = event.eventType === "completion";
2805
- const icon = lvl === "error" ? col.red("\u2716") : isCompletionEvent ? event.success !== false ? col.green("\u2714") : col.red("\u2716") : "\u2014";
2806
- printRun(agentName || "?", icon, clip(msg, 80));
2908
+ const evtType = String(event.eventType || "");
2909
+ const msg = String(
2910
+ event.message || (event.data?.label ? event.data.label : null) || (event.stepId ? `${evtType === "step_event" ? "Step" : evtType}: ${event.stepId}` : null) || evtType || ""
2911
+ );
2912
+ if (!msg || msg === "heartbeat") return;
2913
+ if (evtType === "start" && msg === "Run started") return;
2914
+ const isCompletionEvent = evtType === "completion";
2915
+ const icon = lvl === "error" ? col.red("\u2716") : isCompletionEvent ? event.success !== false ? col.green("\u2714") : col.red("\u2716") : col.cyan("\u2502");
2916
+ printRun(agentName, icon, clip(msg, 90));
2807
2917
  return;
2808
2918
  }
2809
2919
  if (type === "error" && agentPath) {
@@ -2811,7 +2921,7 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
2811
2921
  return;
2812
2922
  }
2813
2923
  if (type === "agent_prepare_started") {
2814
- printAgent(agentName, col.gray("Preparing\u2026"));
2924
+ printAgent(agentName, col.gray("Preparing..."));
2815
2925
  return;
2816
2926
  }
2817
2927
  if (type === "agent_prepare_progress") {
@@ -2831,28 +2941,10 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
2831
2941
  printAgent(agentName, col.green("\u2714 Ready"));
2832
2942
  return;
2833
2943
  }
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
2944
  const dbgArr = serveDebugEntries([event], 1);
2854
2945
  if (dbgArr.length > 0) {
2855
2946
  const dbg = dbgArr[0];
2947
+ if (initialSetupDone && dbg.level === "info") return;
2856
2948
  const msg = dbg.level === "error" ? col.red(dbg.message) : dbg.level === "warn" ? col.yellow(dbg.message) : col.gray(dbg.message);
2857
2949
  printDaemon(dbg.eventType, msg);
2858
2950
  }
@@ -2871,7 +2963,7 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
2871
2963
  platform,
2872
2964
  onProgress: (msg) => {
2873
2965
  if (dashboardClosed) return;
2874
- process.stdout.write(`\r ${col.gray(clip(msg || "Preparing\u2026", 70))} `);
2966
+ process.stdout.write(`\r ${col.gray(clip(msg || "Preparing...", 70))} `);
2875
2967
  }
2876
2968
  });
2877
2969
  process.stdout.write("\r" + " ".repeat(80) + "\r");
@@ -2988,7 +3080,10 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
2988
3080
  const text = String(chunk).trim();
2989
3081
  if (!text) return;
2990
3082
  stderrChunks.push(text);
2991
- printDaemon("stderr", col.yellow(clip(text, 120)));
3083
+ const isNoise = /^\[local\]\s+(running|uploading|preparing)/i.test(text) || /^(Resolved|Audited|Using Python)\b/i.test(text);
3084
+ if (!isNoise) {
3085
+ printDaemon("stderr", col.yellow(clip(text, 120)));
3086
+ }
2992
3087
  state = applyServeEvent(state, {
2993
3088
  type: "daemon_stderr",
2994
3089
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -3016,7 +3111,7 @@ async function runServeDashboard({ env, platform, agentsDir, collectionId, wsLab
3016
3111
  } catch {
3017
3112
  }
3018
3113
  removeKeypress();
3019
- process.stdout.write("\n Press Enter to return to menu\u2026 ");
3114
+ process.stdout.write("\n Press Enter to return to menu... ");
3020
3115
  const rl = makeRl();
3021
3116
  rl.once("line", () => {
3022
3117
  rl.close();
@@ -3128,7 +3223,7 @@ async function connectEndpointInteractive({
3128
3223
  const status = cloudAuthStatus({ backend, apiUrl, env, platform });
3129
3224
  const destination = label || envLabel(status.apiUrl);
3130
3225
  if (status.authenticated) {
3131
- print(col.gray(` Connecting to ${destination}\u2026`));
3226
+ print(col.gray(` Connecting to ${destination}...`));
3132
3227
  try {
3133
3228
  await switchOrLoginEndpoint({ backend, apiUrl, env, platform, setupFn, activateFn });
3134
3229
  print(col.green(` ${fig.check} ${successLabel || `Signed in to ${destination} successfully`}`));
@@ -3189,6 +3284,8 @@ function helpText() {
3189
3284
  " vendian validate ./agents/my-agent --runtime",
3190
3285
  " vendian models",
3191
3286
  " vendian cloud local serve --agents-dir ./agents",
3287
+ " vendian cloud local push --collection-id ID --project-id PID --branch dev",
3288
+ " vendian cloud local push --branch feature/x --from dev",
3192
3289
  " vendian doctor",
3193
3290
  " vendian update",
3194
3291
  "",
@@ -3213,7 +3310,7 @@ function readManifestName(absoluteFolderPath) {
3213
3310
  }
3214
3311
  function clip(value, length) {
3215
3312
  const text = String(value || "");
3216
- return text.length <= length ? text : `${text.slice(0, Math.max(0, length - 1))}\u2026`;
3313
+ return text.length <= length ? text : `${text.slice(0, Math.max(0, length - 1))}...`;
3217
3314
  }
3218
3315
  function errMsg(error) {
3219
3316
  return error && typeof error.message === "string" ? error.message : String(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vendian/cli",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "description": "Public Vendian CLI bootstrapper and launcher",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,