@vavio/cli 0.1.0 → 0.1.2
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/vavio.mjs +64 -22
- 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.
|
|
13
|
+
var CLI_VERSION = "0.1.2";
|
|
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
|
-
|
|
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
|
|
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),
|
|
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 {
|
|
@@ -934,7 +968,9 @@ async function cmdLogin(ctx) {
|
|
|
934
968
|
if (ctx.out.json) ctx.out.value(value);
|
|
935
969
|
else {
|
|
936
970
|
const where = store.kind === "file" ? "a private file" : store.kind === "keychain" ? "the macOS keychain" : "the Secret Service keyring";
|
|
937
|
-
|
|
971
|
+
const raw = typeof workspace?.name === "string" ? workspace.name.replace(/\s+/g, " ").trim() : "";
|
|
972
|
+
const name = raw && !/^workspace [0-9a-f]{8}$/i.test(raw) ? raw.slice(0, 80) : null;
|
|
973
|
+
ctx.out.out(`Signed in to Vavio${name ? ` (workspace ${name})` : ""}. Saved in ${where}.`);
|
|
938
974
|
}
|
|
939
975
|
return EXIT.ok;
|
|
940
976
|
}
|
|
@@ -1084,6 +1120,9 @@ function route(positionals) {
|
|
|
1084
1120
|
case "account":
|
|
1085
1121
|
exact(1);
|
|
1086
1122
|
return { key: "account", run: (ctx) => callAndReport(ctx, "account_overview", {}, FORMAT.account) };
|
|
1123
|
+
case "status":
|
|
1124
|
+
exact(1);
|
|
1125
|
+
return { key: "status", run: (ctx) => callAndReport(ctx, "account_overview", {}, FORMAT.account) };
|
|
1087
1126
|
case "offerings":
|
|
1088
1127
|
exact(1);
|
|
1089
1128
|
return { key: "offerings", run: (ctx) => callAndReport(ctx, "list_offerings", {}, FORMAT.offerings) };
|
|
@@ -1150,13 +1189,15 @@ async function runCli(argv, io = {}) {
|
|
|
1150
1189
|
else out().out(`${CLI_NAME} ${CLI_VERSION} (contract ${CONTRACT_VERSION})`);
|
|
1151
1190
|
return EXIT.ok;
|
|
1152
1191
|
}
|
|
1153
|
-
|
|
1192
|
+
const showHelp = () => {
|
|
1154
1193
|
const text = helpFor(positionals);
|
|
1155
1194
|
if (json) out().value({ outcome: "ok", help: text });
|
|
1156
1195
|
else out().out(text);
|
|
1157
1196
|
return EXIT.ok;
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1197
|
+
};
|
|
1198
|
+
if (flags.help || positionals[0] === "help") return showHelp();
|
|
1199
|
+
const bare = positionals.length === 0;
|
|
1200
|
+
const target = route(bare ? ["status"] : positionals);
|
|
1160
1201
|
const allowed = /* @__PURE__ */ new Set([...GLOBAL_FLAGS, ...COMMANDS[target.key].flags ?? []]);
|
|
1161
1202
|
for (const name of Object.keys(flags)) {
|
|
1162
1203
|
if (!allowed.has(name)) throw usage(`--${name} does not apply to vavio ${target.key}. See vavio ${target.key.split(" ")[0]} --help.`);
|
|
@@ -1178,6 +1219,7 @@ async function runCli(argv, io = {}) {
|
|
|
1178
1219
|
platform,
|
|
1179
1220
|
fetch: contractFetch(io.fetch ?? globalThis.fetch, url)
|
|
1180
1221
|
};
|
|
1222
|
+
if (bare && !await isSignedIn(ctx)) return showHelp();
|
|
1181
1223
|
return await target.run(ctx);
|
|
1182
1224
|
} catch (error) {
|
|
1183
1225
|
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.
|
|
3
|
+
"version": "0.1.2",
|
|
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",
|