@vavio/cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/vavio.mjs +61 -21
  2. package/package.json +1 -1
package/dist/vavio.mjs CHANGED
@@ -10,7 +10,7 @@ import { Client, StreamableHTTPClientTransport } from "@modelcontextprotocol/cli
10
10
 
11
11
  // src/constants.ts
12
12
  var CLI_NAME = "@vavio/cli";
13
- var CLI_VERSION = "0.1.0";
13
+ var CLI_VERSION = "0.1.1";
14
14
  var CONTRACT_VERSION = 1;
15
15
  var CONTRACT_HEADER = "Vavio-Contract";
16
16
  var CONTRACT_MIN_HEADER = "Vavio-Contract-Min";
@@ -606,10 +606,14 @@ var COMMANDS = {
606
606
  summary: "Remove this computer's sign-in and revoke it on Vavio.",
607
607
  details: ["Exit code 3 means the local sign-in is removed but Vavio could not revoke it from here: next.text says what to do."]
608
608
  },
609
- whoami: { usage: "vavio whoami", summary: "Show the signed-in workspace. Same result as vavio account." },
609
+ status: {
610
+ usage: "vavio status",
611
+ summary: "Show your account: workspace, Hermes instances and their state, and open operations. Plain vavio does the same once signed in."
612
+ },
613
+ whoami: { usage: "vavio whoami", summary: "Show the signed-in workspace." },
610
614
  account: {
611
615
  usage: "vavio account",
612
- summary: "Read the account: workspace, Hermes instances, offerings, included Hermes and open operations."
616
+ summary: "Read the account: workspace, Hermes instances, offerings, included Hermes and open operations. Same as vavio status."
613
617
  },
614
618
  "instances list": { usage: "vavio instances list", summary: "List the workspace's Hermes instances with their ids and access state." },
615
619
  "instance status": {
@@ -651,6 +655,8 @@ function mainHelp() {
651
655
  "",
652
656
  "Usage: vavio <command> [options]",
653
657
  "",
658
+ "Start: vavio login, then vavio status.",
659
+ "",
654
660
  "Commands:",
655
661
  ...lines,
656
662
  "",
@@ -722,21 +728,37 @@ function table(rows) {
722
728
  return rows.map((row) => row.map((cell, i) => i === row.length - 1 ? cell : cell.padEnd(widths[i])).join(" ")).join("\n");
723
729
  }
724
730
  var str = (value) => value === null || value === void 0 ? "-" : String(value);
731
+ function priceText(price) {
732
+ if (!price) return null;
733
+ const amount = typeof price.amount === "number" ? price.amount.toFixed(2) : str(price.amount);
734
+ const currency = str(price.currency).toUpperCase();
735
+ return `${currency === "USD" ? `$${amount}` : `${amount} ${currency}`}/${str(price.interval)}`;
736
+ }
737
+ function orderText(o) {
738
+ return o.purchasable ? "available to order" : `not available to order yet${o.reason ? `: ${str(o.reason)}` : ""}`;
739
+ }
740
+ var indent = (text) => text.split("\n").map((line) => ` ${line}`).join("\n");
741
+ function accountText(v) {
742
+ const ws = v.workspace ?? {};
743
+ const instances = v.instances ?? [];
744
+ const offerings = v.offerings ?? [];
745
+ const ent = v.entitlements?.hermes ?? {};
746
+ const lines = [`Workspace ${ws.name ? `${str(ws.name)} (${str(ws.id)})` : str(ws.id)}`, `Role ${str(v.role)}`];
747
+ if (instances.length) {
748
+ lines.push(`Hermes ${instances.length === 1 ? "1 instance" : `${instances.length} instances`} (included ${str(ent.used)} of ${str(ent.granted)})`);
749
+ lines.push(indent(table([["ID", "ACCESS", "STATE", "ADDRESS"], ...instances.map((i) => [str(i.id), str(i.access), str(i.lifecycle_state), str(i.address)])])));
750
+ } else {
751
+ lines.push("Hermes none yet");
752
+ for (const o of offerings) {
753
+ const price = priceText(o.price);
754
+ lines.push(`Hosting ${str(o.title)}${price ? `, ${price}` : ""}: ${orderText(o)}`);
755
+ }
756
+ }
757
+ lines.push(`Open operations ${str(v.open_operations)}`);
758
+ return lines.join("\n");
759
+ }
725
760
  var FORMAT = {
726
- account(v) {
727
- const ws = v.workspace ?? {};
728
- const instances = v.instances ?? [];
729
- const offerings = v.offerings ?? [];
730
- const ent = v.entitlements?.hermes ?? {};
731
- return [
732
- `Workspace ${str(ws.name)} (${str(ws.id)})`,
733
- `Role ${str(v.role)}`,
734
- `Hermes ${instances.length} instance(s); included ${str(ent.used)} of ${str(ent.granted)}`,
735
- ...instances.map((i) => ` ${str(i.id)} ${str(i.access)} ${str(i.address)}`),
736
- `Offerings ${offerings.map((o) => `${str(o.title)}: ${o.purchasable ? "for sale" : "not for sale yet"}`).join("; ") || "none"}`,
737
- `Open operations ${str(v.open_operations)}`
738
- ].join("\n");
739
- },
761
+ account: accountText,
740
762
  whoami(v) {
741
763
  const ws = v.workspace ?? {};
742
764
  return `Signed in as the ${str(v.role)} of workspace ${str(ws.name)} (${str(ws.id)}).`;
@@ -768,7 +790,7 @@ Older: vavio operations list --before ${str(v.next_before)}` : "";
768
790
  offerings(v) {
769
791
  const rows = (v.offerings ?? []).map((o) => {
770
792
  const price = o.price;
771
- return [str(o.id), str(o.title), price ? `${str(price.amount)} ${str(price.currency)}/${str(price.interval)}` : "no price set", o.purchasable ? "for sale" : `not for sale${o.reason ? `: ${str(o.reason)}` : ""}`];
793
+ return [str(o.id), str(o.title), priceText(price) ?? "no price set", orderText(o)];
772
794
  });
773
795
  return rows.length ? table([["ID", "TITLE", "PRICE", "STATUS"], ...rows]) : "No offerings.";
774
796
  },
@@ -817,6 +839,18 @@ async function connect(ctx) {
817
839
  if (!await provider.signIn()) throw notSignedIn();
818
840
  return openSession({ url: ctx.url, fetchFn: ctx.fetch.fetchFn, seen: ctx.fetch.seen, era, auth: provider });
819
841
  }
842
+ async function isSignedIn(ctx) {
843
+ if (accessTokenOf(ctx)) return true;
844
+ const provider = new CliOAuthProvider({
845
+ serverUrl: ctx.key,
846
+ config: ctx.config,
847
+ store: await storeFor(ctx),
848
+ redactor: ctx.redactor,
849
+ interactive: false,
850
+ redirectUri: loopbackRedirect(registeredPort(ctx.config.server(ctx.key).client))
851
+ });
852
+ return await provider.signIn() !== null;
853
+ }
820
854
  async function withSession(ctx, work) {
821
855
  const session = await connect(ctx);
822
856
  try {
@@ -1084,6 +1118,9 @@ function route(positionals) {
1084
1118
  case "account":
1085
1119
  exact(1);
1086
1120
  return { key: "account", run: (ctx) => callAndReport(ctx, "account_overview", {}, FORMAT.account) };
1121
+ case "status":
1122
+ exact(1);
1123
+ return { key: "status", run: (ctx) => callAndReport(ctx, "account_overview", {}, FORMAT.account) };
1087
1124
  case "offerings":
1088
1125
  exact(1);
1089
1126
  return { key: "offerings", run: (ctx) => callAndReport(ctx, "list_offerings", {}, FORMAT.offerings) };
@@ -1150,13 +1187,15 @@ async function runCli(argv, io = {}) {
1150
1187
  else out().out(`${CLI_NAME} ${CLI_VERSION} (contract ${CONTRACT_VERSION})`);
1151
1188
  return EXIT.ok;
1152
1189
  }
1153
- if (flags.help || positionals.length === 0 || positionals[0] === "help") {
1190
+ const showHelp = () => {
1154
1191
  const text = helpFor(positionals);
1155
1192
  if (json) out().value({ outcome: "ok", help: text });
1156
1193
  else out().out(text);
1157
1194
  return EXIT.ok;
1158
- }
1159
- const target = route(positionals);
1195
+ };
1196
+ if (flags.help || positionals[0] === "help") return showHelp();
1197
+ const bare = positionals.length === 0;
1198
+ const target = route(bare ? ["status"] : positionals);
1160
1199
  const allowed = /* @__PURE__ */ new Set([...GLOBAL_FLAGS, ...COMMANDS[target.key].flags ?? []]);
1161
1200
  for (const name of Object.keys(flags)) {
1162
1201
  if (!allowed.has(name)) throw usage(`--${name} does not apply to vavio ${target.key}. See vavio ${target.key.split(" ")[0]} --help.`);
@@ -1178,6 +1217,7 @@ async function runCli(argv, io = {}) {
1178
1217
  platform,
1179
1218
  fetch: contractFetch(io.fetch ?? globalThis.fetch, url)
1180
1219
  };
1220
+ if (bare && !await isSignedIn(ctx)) return showHelp();
1181
1221
  return await target.run(ctx);
1182
1222
  } catch (error) {
1183
1223
  const failure = error instanceof CliError ? error : new CliError("failed", `Unexpected error: ${(error instanceof Error ? error.message : String(error)).slice(0, 200)}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vavio/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "vavio: operate your Vavio account and Hermes instances from a terminal or your own AI assistant, over Vavio's MCP server.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://vavio.ai",