@vendian/cli 0.0.27 → 0.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,7 @@ vendian
8
8
  vendian login
9
9
  vendian init --output-dir ./agents
10
10
  vendian create "My Agent" --output-dir ./agents
11
+ vendian cloud local run --collection-id YOUR_COLLECTION --path ./agents/my-agent --input-json '{}'
11
12
  vendian cloud local serve --agents-dir ./agents
12
13
  ```
13
14
 
@@ -23,11 +24,13 @@ vendian create "My Agent" --output-dir ./agents
23
24
  vendian validate ./agents/my-agent --runtime
24
25
  vendian test ./agents/my-agent --dry-run --mock-credentials
25
26
  vendian models
27
+ vendian cloud local run --collection-id YOUR_COLLECTION --path ./agents/my-agent --input-json '{}'
26
28
  vendian cloud local serve --agents-dir ./agents
27
29
  ```
28
30
 
29
31
  Run `vendian` with no arguments to open the interactive menu. It shows your
30
- current endpoint connections and guides common local workflows.
32
+ current endpoint connections and guides common local workflows, including
33
+ running one local agent immediately or starting the long-lived local daemon.
31
34
 
32
35
  `vendian login` opens a browser sign-in, prepares the local runtime, and stores
33
36
  the credentials needed by the CLI for the selected endpoint. `vendian setup` is
package/cli-wrapper.mjs CHANGED
@@ -1107,7 +1107,7 @@ import path8 from "node:path";
1107
1107
  import readlinePromises from "node:readline/promises";
1108
1108
 
1109
1109
  // src/version.js
1110
- var CLI_VERSION = true ? "0.0.27" : process.env.npm_package_version || "0.0.0-dev";
1110
+ var CLI_VERSION = true ? "0.0.28" : 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;
@@ -2412,12 +2412,12 @@ async function runTui({
2412
2412
  await refreshInteractiveManagedRuntime({ env, platform, output });
2413
2413
  await loadTerm();
2414
2414
  term.fullscreen(true);
2415
- term.hideCursor();
2415
+ setCursorVisible(false);
2416
2416
  term.grabInput({ mouse: "motion" });
2417
2417
  const cleanup = () => {
2418
2418
  try {
2419
2419
  term.grabInput(false);
2420
- term.showCursor();
2420
+ setCursorVisible(true);
2421
2421
  term.fullscreen(false);
2422
2422
  } catch {
2423
2423
  }
@@ -2451,6 +2451,9 @@ async function mainLoop({ env, platform }) {
2451
2451
  while (true) {
2452
2452
  let next;
2453
2453
  switch (screen) {
2454
+ case "run":
2455
+ next = await showRun({ env, platform });
2456
+ break;
2454
2457
  case "home":
2455
2458
  next = await showHome({ env, platform });
2456
2459
  break;
@@ -2532,6 +2535,7 @@ var HOME_ACTIONS = [
2532
2535
  { value: "connect", label: "Sign in", desc: "Connect to a different account or environment" },
2533
2536
  { value: "create", label: "Create Agent", desc: "Build a new agent from a template" },
2534
2537
  { value: "commands", label: "Commands", desc: "Show all available CLI commands" },
2538
+ { value: "run", label: "Run once", desc: "Execute one local agent immediately" },
2535
2539
  { value: "exit", label: "Exit", desc: "" }
2536
2540
  ];
2537
2541
  async function showHome({ env, platform }) {
@@ -2628,6 +2632,41 @@ async function showCreate({ env, platform }) {
2628
2632
  );
2629
2633
  return "home";
2630
2634
  }
2635
+ async function showRun({ env, platform }) {
2636
+ const candidates = findAgentDirectoryCandidates();
2637
+ const picked = await pickSingleAgentToRun({ env, platform, candidates });
2638
+ if (!picked) return "home";
2639
+ const workspace = await chooseCloudWorkspace({
2640
+ env,
2641
+ platform,
2642
+ loadingTitle: " Getting ready to run this agent\u2026",
2643
+ pickerTitle: " Which project should own this run?\n\n"
2644
+ });
2645
+ if (!workspace) return "home";
2646
+ term.clear();
2647
+ drawHeader({ env, platform });
2648
+ term("\n");
2649
+ term.bold(` Run ${picked.displayName}
2650
+
2651
+ `);
2652
+ term.gray(` Agent: ${picked.path}
2653
+ `);
2654
+ term.gray(` Project: ${workspace.label}
2655
+
2656
+ `);
2657
+ term.gray(" Input JSON: ");
2658
+ const inputJson = await term.inputField({ cancelable: true, style: term.cyan, default: "{}" }).promise;
2659
+ if (inputJson === null) return "home";
2660
+ await withOutputMode(
2661
+ `Running ${picked.displayName}`,
2662
+ () => forwardToPythonVendian(buildLocalRunArgs({
2663
+ agentPath: picked.path,
2664
+ collectionId: workspace.id,
2665
+ inputJson: inputJson || "{}"
2666
+ }), { env, platform })
2667
+ );
2668
+ return "home";
2669
+ }
2631
2670
  var COMMAND_GROUPS = [
2632
2671
  { section: "Getting started", commands: [
2633
2672
  { cmd: "vendian login", desc: "Sign in and set up your computer" },
@@ -2640,6 +2679,7 @@ var COMMAND_GROUPS = [
2640
2679
  { cmd: "vendian models", desc: "List available AI models" }
2641
2680
  ] },
2642
2681
  { section: "Running agents", commands: [
2682
+ { cmd: "vendian cloud local run --collection-id ID --path . --input-json '{}'", desc: "Run one local agent once" },
2643
2683
  { cmd: "vendian cloud local serve --agents-dir .", desc: "Start agents (advanced mode)" },
2644
2684
  { cmd: "vendian login --backend staging", desc: "Sign in to staging environment" }
2645
2685
  ] },
@@ -2680,57 +2720,14 @@ async function showServe({ env, platform }) {
2680
2720
  const picked = await pickAgentsToRun({ env, platform, candidates });
2681
2721
  if (!picked) return "home";
2682
2722
  const { agentsDir } = picked;
2683
- term.clear();
2684
- drawHeader({ env, platform });
2685
- term("\n");
2686
- term.bold(` Getting ready to run your agents\u2026
2687
-
2688
- `);
2689
- let wsResult;
2690
- try {
2691
- wsResult = await listCloudWorkspaces({
2692
- env,
2693
- platform,
2694
- onProgress: (msg) => {
2695
- term.moveTo(1, HEADER_ROWS_BASE + 3);
2696
- term.eraseLine();
2697
- term.gray(` ${clip(msg, 60)}
2698
- `);
2699
- }
2700
- });
2701
- } catch (error) {
2702
- term.red(`
2703
- Couldn't connect to the server: ${errMsg(error)}
2704
- `);
2705
- term.gray(" Make sure you are signed in (choose Sign in from the main menu).\n");
2706
- await pressEnterToContinue({ grabActive: false });
2707
- return "home";
2708
- }
2709
- if (!wsResult.ok) {
2710
- term.red(`
2711
- ${fig.cross} ${wsResult.error}
2712
- `);
2713
- await pressEnterToContinue({ grabActive: false });
2714
- return "home";
2715
- }
2716
- let collectionId = wsResult.workspaces[0]?.id || "";
2717
- if (wsResult.workspaces.length > 1) {
2718
- term.clear();
2719
- drawHeader({ env, platform });
2720
- term("\n");
2721
- term.bold(" Which project do you want to run?\n\n");
2722
- const wsItems = [...wsResult.workspaces.map((w) => workspaceLabel(w)), "\u2190 Back"];
2723
- const wsResp = await term.singleColumnMenu(wsItems, {
2724
- cancelable: true,
2725
- style: term.gray,
2726
- selectedStyle: term.bgCyan.black.bold,
2727
- leftPadding: " ",
2728
- selectedLeftPadding: " \u203A "
2729
- }).promise;
2730
- if (wsResp.canceled || wsResp.selectedIndex === wsItems.length - 1) return "home";
2731
- collectionId = wsResult.workspaces[wsResp.selectedIndex]?.id || "";
2732
- }
2733
- return await runServeDashboard({ env, platform, agentsDir, collectionId });
2723
+ const workspace = await chooseCloudWorkspace({
2724
+ env,
2725
+ platform,
2726
+ loadingTitle: " Getting ready to run your agents\u2026",
2727
+ pickerTitle: " Which project do you want to run?\n\n"
2728
+ });
2729
+ if (!workspace) return "home";
2730
+ return await runServeDashboard({ env, platform, agentsDir, collectionId: workspace.id });
2734
2731
  }
2735
2732
  async function pickAgentsToRun({ env, platform, candidates }) {
2736
2733
  if (candidates.length === 0) {
@@ -2804,6 +2801,107 @@ async function pickAgentsFromFolder({ env, platform, candidate }) {
2804
2801
  if (resp.selectedIndex === 0) return { agentsDir: candidate.path };
2805
2802
  return { agentsDir: named[resp.selectedIndex - 1].path };
2806
2803
  }
2804
+ async function pickSingleAgentToRun({ env, platform, candidates }) {
2805
+ if (candidates.length === 0) {
2806
+ term.clear();
2807
+ drawHeader({ env, platform });
2808
+ term("\n");
2809
+ term.bold(" I couldn't find any agents on your computer.\n\n");
2810
+ term.gray(" Enter the path to one agent folder:\n\n");
2811
+ term.gray(" Folder: ");
2812
+ const input = await term.inputField({ cancelable: true, style: term.cyan, default: "./agents/my-agent" }).promise;
2813
+ if (input === null) return null;
2814
+ const agentPath = input || "./agents/my-agent";
2815
+ return { path: agentPath, displayName: friendlyName(path8.basename(agentPath) || "Agent") };
2816
+ }
2817
+ const agents = candidates.flatMap((candidate) => {
2818
+ const folders = findAgentFolders(candidate.absolutePath);
2819
+ if (folders.length > 0) {
2820
+ return folders.map((folder) => ({
2821
+ path: folder.path,
2822
+ displayName: readManifestName(folder.absolutePath) || friendlyName(folder.name || path8.basename(folder.path))
2823
+ }));
2824
+ }
2825
+ return [{
2826
+ path: candidate.path,
2827
+ displayName: readManifestName(candidate.absolutePath) || friendlyName(path8.basename(candidate.absolutePath) || candidate.path)
2828
+ }];
2829
+ });
2830
+ if (agents.length === 1) return agents[0];
2831
+ term.clear();
2832
+ drawHeader({ env, platform });
2833
+ term("\n");
2834
+ term.bold(" Which agent do you want to run now?\n\n");
2835
+ const items = [...agents.map((agent) => `${agent.displayName.padEnd(32)} ${agent.path}`), "\u2190 Back"];
2836
+ const resp = await term.singleColumnMenu(items, {
2837
+ cancelable: true,
2838
+ style: term.gray,
2839
+ selectedStyle: term.bgCyan.black.bold,
2840
+ leftPadding: " ",
2841
+ selectedLeftPadding: " \u203A "
2842
+ }).promise;
2843
+ if (resp.canceled || resp.selectedIndex === items.length - 1) return null;
2844
+ return agents[resp.selectedIndex];
2845
+ }
2846
+ async function chooseCloudWorkspace({
2847
+ env,
2848
+ platform,
2849
+ loadingTitle,
2850
+ pickerTitle
2851
+ } = {}) {
2852
+ term.clear();
2853
+ drawHeader({ env, platform });
2854
+ term("\n");
2855
+ term.bold(`${loadingTitle}
2856
+
2857
+ `);
2858
+ let wsResult;
2859
+ try {
2860
+ wsResult = await listCloudWorkspaces({
2861
+ env,
2862
+ platform,
2863
+ onProgress: (msg) => {
2864
+ term.moveTo(1, HEADER_ROWS_BASE + 3);
2865
+ term.eraseLine();
2866
+ term.gray(` ${clip(msg, 60)}
2867
+ `);
2868
+ }
2869
+ });
2870
+ } catch (error) {
2871
+ term.red(`
2872
+ Couldn't connect to the server: ${errMsg(error)}
2873
+ `);
2874
+ term.gray(" Make sure you are signed in (choose Sign in from the main menu).\n");
2875
+ await pressEnterToContinue({ grabActive: false });
2876
+ return null;
2877
+ }
2878
+ if (!wsResult.ok) {
2879
+ term.red(`
2880
+ ${fig.cross} ${wsResult.error}
2881
+ `);
2882
+ await pressEnterToContinue({ grabActive: false });
2883
+ return null;
2884
+ }
2885
+ if (wsResult.workspaces.length <= 1) {
2886
+ const workspace2 = wsResult.workspaces[0];
2887
+ return workspace2 ? { id: workspace2.id || "", label: workspaceLabel(workspace2) } : null;
2888
+ }
2889
+ term.clear();
2890
+ drawHeader({ env, platform });
2891
+ term("\n");
2892
+ term.bold(pickerTitle);
2893
+ const wsItems = [...wsResult.workspaces.map((w) => workspaceLabel(w)), "\u2190 Back"];
2894
+ const wsResp = await term.singleColumnMenu(wsItems, {
2895
+ cancelable: true,
2896
+ style: term.gray,
2897
+ selectedStyle: term.bgCyan.black.bold,
2898
+ leftPadding: " ",
2899
+ selectedLeftPadding: " \u203A "
2900
+ }).promise;
2901
+ if (wsResp.canceled || wsResp.selectedIndex === wsItems.length - 1) return null;
2902
+ const workspace = wsResult.workspaces[wsResp.selectedIndex];
2903
+ return { id: workspace?.id || "", label: workspaceLabel(workspace) };
2904
+ }
2807
2905
  async function runServeDashboard({ env, platform, agentsDir, collectionId }) {
2808
2906
  let state = initialServeState();
2809
2907
  let child = null;
@@ -3350,7 +3448,7 @@ function attachServeChild(child, onUpdate, onExit, logStore = null) {
3350
3448
  }
3351
3449
  async function withOutputMode(label, fn) {
3352
3450
  term.fullscreen(false);
3353
- term.showCursor();
3451
+ setCursorVisible(true);
3354
3452
  term.grabInput(false);
3355
3453
  process.stdout.write(`
3356
3454
  ${label}
@@ -3366,7 +3464,7 @@ async function withOutputMode(label, fn) {
3366
3464
  }
3367
3465
  await pressEnterToContinue({ grabActive: false });
3368
3466
  term.fullscreen(true);
3369
- term.hideCursor();
3467
+ setCursorVisible(false);
3370
3468
  term.grabInput({ mouse: "motion" });
3371
3469
  }
3372
3470
  function waitForKey(keys = null) {
@@ -3380,6 +3478,19 @@ function waitForKey(keys = null) {
3380
3478
  term.on("key", handler);
3381
3479
  });
3382
3480
  }
3481
+ function setCursorVisible(visible) {
3482
+ if (typeof term?.hideCursor === "function") {
3483
+ term.hideCursor(!visible);
3484
+ return;
3485
+ }
3486
+ if (visible && typeof term?.showCursor === "function") {
3487
+ term.showCursor();
3488
+ return;
3489
+ }
3490
+ if (!visible && typeof term?.hideCursor === "function") {
3491
+ term.hideCursor();
3492
+ }
3493
+ }
3383
3494
  async function pressEnterToContinue({ grabActive = true } = {}) {
3384
3495
  if (grabActive) {
3385
3496
  term("\n Press any key to continue\u2026");
@@ -3499,6 +3610,23 @@ function endpointErrorStatus(error) {
3499
3610
  const message = error && typeof error.message === "string" ? error.message : String(error || "Connection failed");
3500
3611
  return `${fig.cross} ${message}`;
3501
3612
  }
3613
+ function buildLocalRunArgs({
3614
+ agentPath = ".",
3615
+ collectionId = "",
3616
+ inputJson = "{}"
3617
+ } = {}) {
3618
+ return [
3619
+ "cloud",
3620
+ "local",
3621
+ "run",
3622
+ "--collection-id",
3623
+ collectionId,
3624
+ "--path",
3625
+ agentPath || ".",
3626
+ "--input-json",
3627
+ inputJson || "{}"
3628
+ ];
3629
+ }
3502
3630
  function runtimeSummary({ env = process.env, platform = process.platform, now = Date.now() } = {}) {
3503
3631
  const config = loadConfig(env, platform);
3504
3632
  const venvPath = managedVenvPath(env, platform);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vendian/cli",
3
- "version": "0.0.27",
3
+ "version": "0.0.28",
4
4
  "description": "Public Vendian CLI bootstrapper and launcher",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,