@wervt/cli 0.2.11 → 0.2.12
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 +18 -1
- package/dist/index.mjs +50 -6
- package/package.json +1 -1
- package/skill/SKILL.md +2 -1
package/README.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
# @wervt/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The `wervt` command: deploy and manage apps on a [wervt](https://wervt.app) server.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
vpx @wervt/cli login --url https://api.wervt.app # approve the code in the dashboard
|
|
7
|
+
vpx @wervt/cli skill install # teach your agent wervt
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
In an app (`vp create wervt my-app` adds the CLI as a dev dependency):
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
vp exec wervt deploy # build, upload, migrate, activate
|
|
14
|
+
vp exec wervt access my-app --public # or --add friend@example.com
|
|
15
|
+
vp exec wervt logs my-app
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Without [Vite+](https://viteplus.dev), use `npx @wervt/cli` and `pnpm exec wervt`. `wervt --help`
|
|
19
|
+
lists every command: `apps`, `releases`, `rollback`, `activate`, `env`, `tokens`, `members`,
|
|
20
|
+
`tasks`, `stats`, `delete`, `whoami`, … Docs: [wervt.app](https://wervt.app/getting-started/quickstart).
|
package/dist/index.mjs
CHANGED
|
@@ -463,6 +463,45 @@ const access = defineCommand({
|
|
|
463
463
|
if (result.visibility === "private") console.log(result.allow.length ? `allowed: ${result.allow.join(", ")}` : "allowed: admins only");
|
|
464
464
|
}
|
|
465
465
|
});
|
|
466
|
+
const members = defineCommand({
|
|
467
|
+
meta: {
|
|
468
|
+
name: "members",
|
|
469
|
+
description: "Show or change who manages an app (its owner and members)"
|
|
470
|
+
},
|
|
471
|
+
args: {
|
|
472
|
+
app: {
|
|
473
|
+
type: "positional",
|
|
474
|
+
required: true,
|
|
475
|
+
description: "App name"
|
|
476
|
+
},
|
|
477
|
+
add: {
|
|
478
|
+
type: "string",
|
|
479
|
+
description: "Add members by email (comma separated)"
|
|
480
|
+
},
|
|
481
|
+
remove: {
|
|
482
|
+
type: "string",
|
|
483
|
+
description: "Remove members by email (comma separated)"
|
|
484
|
+
},
|
|
485
|
+
owner: {
|
|
486
|
+
type: "string",
|
|
487
|
+
description: "Hand the app to another owner"
|
|
488
|
+
},
|
|
489
|
+
...connection
|
|
490
|
+
},
|
|
491
|
+
async run({ args }) {
|
|
492
|
+
const change = {};
|
|
493
|
+
if (args.add) change.add = toList(args.add);
|
|
494
|
+
if (args.remove) change.remove = toList(args.remove);
|
|
495
|
+
if (args.owner) change.owner = args.owner;
|
|
496
|
+
const result = await (Object.keys(change).length ? await api(`/v1/apps/${args.app}/owners`, args, {
|
|
497
|
+
method: "PATCH",
|
|
498
|
+
headers: { "content-type": "application/json" },
|
|
499
|
+
body: JSON.stringify(change)
|
|
500
|
+
}) : await api(`/v1/apps/${args.app}/owners`, args)).json();
|
|
501
|
+
console.log(`owner: ${result.owner}`);
|
|
502
|
+
console.log(`members: ${result.members.length ? result.members.join(", ") : "none"}`);
|
|
503
|
+
}
|
|
504
|
+
});
|
|
466
505
|
const env = defineCommand({
|
|
467
506
|
meta: {
|
|
468
507
|
name: "env",
|
|
@@ -791,12 +830,16 @@ const whoami = defineCommand({
|
|
|
791
830
|
args: connection,
|
|
792
831
|
async run({ args }) {
|
|
793
832
|
const { url, token } = await resolveConfig(args);
|
|
794
|
-
const
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
role =
|
|
833
|
+
const res = await fetch(`${url}/v1/whoami`, { headers: { authorization: `Bearer ${token}` } });
|
|
834
|
+
if (res.status === 401) throw new Error(`The token is not valid for ${url}`);
|
|
835
|
+
let role;
|
|
836
|
+
if (res.ok) {
|
|
837
|
+
const me = await res.json();
|
|
838
|
+
role = me.role === "deploy" ? `deploy token for ${me.app}` : me.email ? `${me.role} (${me.email})` : me.role;
|
|
839
|
+
} else {
|
|
840
|
+
const deployApp = token.match(/^wervtd_([a-z0-9-]+)_/)?.[1];
|
|
841
|
+
const probe = deployApp ? void 0 : await fetch(`${url}/v1/databases`, { headers: { authorization: `Bearer ${token}` } });
|
|
842
|
+
role = deployApp ? `deploy token for ${deployApp}` : probe.ok ? "admin" : probe.status === 403 ? "read" : `unknown (${probe.status})`;
|
|
800
843
|
}
|
|
801
844
|
console.log(`${url}\n${role}`);
|
|
802
845
|
}
|
|
@@ -939,6 +982,7 @@ runMain(defineCommand({
|
|
|
939
982
|
rollback,
|
|
940
983
|
reprovision,
|
|
941
984
|
access,
|
|
985
|
+
members,
|
|
942
986
|
env,
|
|
943
987
|
tokens,
|
|
944
988
|
tasks,
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -63,8 +63,9 @@ existing app, work in its repository instead.
|
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
65
|
pnpm exec wervt deploy # build, upload, migrate, activate
|
|
66
|
-
pnpm exec wervt access <name> --public # new apps are private (
|
|
66
|
+
pnpm exec wervt access <name> --public # new apps are private (owner, members, admins)
|
|
67
67
|
pnpm exec wervt access <name> --add a@x.com,*@company.com # or let specific people in
|
|
68
|
+
pnpm exec wervt members <name> --add a@x.com # who may deploy and manage it (the first deploy owns it)
|
|
68
69
|
pnpm exec wervt env <name> --set KEY=value # server env vars, applied from the next request
|
|
69
70
|
```
|
|
70
71
|
|