vellum-cli 0.3.3 → 0.3.5
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 +31 -12
- package/dist/index.js +26 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,14 +8,16 @@ Vellum server.
|
|
|
8
8
|
```bash
|
|
9
9
|
# one-off, no install
|
|
10
10
|
npx vellum-cli push --help
|
|
11
|
+
bunx vellum-cli push --help # or with Bun
|
|
11
12
|
|
|
12
13
|
# or install the `vellum` command globally
|
|
13
|
-
npm i -g vellum-cli
|
|
14
|
+
npm i -g vellum-cli # npm
|
|
15
|
+
bun add -g vellum-cli # Bun
|
|
14
16
|
vellum push --help
|
|
15
17
|
```
|
|
16
18
|
|
|
17
|
-
Requires Node 18
|
|
18
|
-
so it has no runtime dependencies.
|
|
19
|
+
Requires Node 18+ (or Bun). The package is self-contained (`@vellum/core` is
|
|
20
|
+
bundled in), so it has no runtime dependencies.
|
|
19
21
|
|
|
20
22
|
## Authentication
|
|
21
23
|
|
|
@@ -39,11 +41,9 @@ env vars:
|
|
|
39
41
|
| Flag | Env var | Description |
|
|
40
42
|
| ------------ | ---------------- | -------------------------------------------- |
|
|
41
43
|
| `--url` | `VELLUM_URL` | Server base URL (default `https://vellumai.app`) |
|
|
42
|
-
| `--api-key` | `VELLUM_API_KEY` | Shared owner/agent key (`X-Api-Key`) |
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
`vellum login` token is used.
|
|
45
|
+
The CLI always uses the stored `vellum login` token. Commands are scoped to
|
|
46
|
+
the logged-in page owner; the CLI does not accept the shared server API key.
|
|
47
47
|
|
|
48
48
|
## Commands
|
|
49
49
|
|
|
@@ -55,7 +55,7 @@ then stores the token. `--no-browser` just prints the URL to open manually.
|
|
|
55
55
|
### `vellum push [file]`
|
|
56
56
|
|
|
57
57
|
Create an artifact from HTML. Reads from `<file>` if given, otherwise from
|
|
58
|
-
stdin. Pass `--page-id <
|
|
58
|
+
stdin. Pass `--page-id <PAGE_ID>` to append a new version to an existing page.
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
61
|
# new page from a file
|
|
@@ -65,11 +65,19 @@ vellum push artifact.html
|
|
|
65
65
|
echo '<!doctype html><h1>Hello</h1>' | vellum push
|
|
66
66
|
|
|
67
67
|
# add a version to an existing page, print raw JSON
|
|
68
|
-
vellum push artifact.html --page-id
|
|
68
|
+
vellum push artifact.html --page-id <PAGE_ID> --json
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
On success it prints the new version number, the human view URL, and the raw
|
|
72
|
-
URL. With `--json` it prints the server's `CreateVersionResponse` verbatim
|
|
72
|
+
URL. With `--json` it prints the server's `CreateVersionResponse` verbatim;
|
|
73
|
+
that response's `id` is the version id. The page id is the `pg_...` value in
|
|
74
|
+
the view URL (`/p/<PAGE_ID>`) or from `vellum list`.
|
|
75
|
+
|
|
76
|
+
### `vellum list`
|
|
77
|
+
|
|
78
|
+
List the artifacts owned by your logged-in identity. By default only live pages
|
|
79
|
+
are shown; pass `--archived` for archived-only or `--all` for both (archived
|
|
80
|
+
pages are marked `*`). `--json` prints the raw response.
|
|
73
81
|
|
|
74
82
|
### `vellum markup <page-id>`
|
|
75
83
|
|
|
@@ -79,15 +87,22 @@ the highlight. Without `--version`, the page's current version is used.
|
|
|
79
87
|
|
|
80
88
|
```bash
|
|
81
89
|
# anchor a note to a passage
|
|
82
|
-
vellum markup
|
|
90
|
+
vellum markup <PAGE_ID> --quote "Q3 dashboard" --body "tighten this headline"
|
|
83
91
|
|
|
84
92
|
# pipe the note in on stdin instead of --body
|
|
85
|
-
echo "tighten this headline" | vellum markup
|
|
93
|
+
echo "tighten this headline" | vellum markup <PAGE_ID> --quote "Q3 dashboard"
|
|
86
94
|
```
|
|
87
95
|
|
|
88
96
|
The CLI checks the quote is anchorable before posting; pass `--force` to post
|
|
89
97
|
anyway, or `--json` for the raw response.
|
|
90
98
|
|
|
99
|
+
### `vellum archive <page-id>` / `vellum unarchive <page-id>`
|
|
100
|
+
|
|
101
|
+
Archive hides a page from the gallery and makes it read-only; the bytes,
|
|
102
|
+
versions, comments, and URLs stay intact, but new versions and comments are
|
|
103
|
+
paused until you unarchive. Unarchive restores it to live. Page owner only.
|
|
104
|
+
`--json` prints the raw response.
|
|
105
|
+
|
|
91
106
|
### `vellum whoami`
|
|
92
107
|
|
|
93
108
|
Show the identity the CLI is authenticated as for a server.
|
|
@@ -96,6 +111,10 @@ Show the identity the CLI is authenticated as for a server.
|
|
|
96
111
|
|
|
97
112
|
Revoke this machine's stored token server-side and forget it locally.
|
|
98
113
|
|
|
114
|
+
### `vellum version`
|
|
115
|
+
|
|
116
|
+
Print the installed CLI version.
|
|
117
|
+
|
|
99
118
|
## Development
|
|
100
119
|
|
|
101
120
|
From the repo root, Bun runs the TypeScript source directly (no build):
|
package/dist/index.js
CHANGED
|
@@ -15,13 +15,10 @@ function resolveBaseUrl(flags) {
|
|
|
15
15
|
return normalizeUrl(flags.url ?? process.env.VELLUM_URL ?? DEFAULT_URL);
|
|
16
16
|
}
|
|
17
17
|
async function resolveCredential(flags, baseUrl) {
|
|
18
|
-
const apiKey = flags.apiKey ?? process.env.VELLUM_API_KEY;
|
|
19
|
-
if (apiKey)
|
|
20
|
-
return { apiKey };
|
|
21
18
|
const token = await loadToken(baseUrl);
|
|
22
19
|
if (token)
|
|
23
20
|
return { token };
|
|
24
|
-
throw new ConfigError(`Not logged in to ${baseUrl}. Run \`vellum login
|
|
21
|
+
throw new ConfigError(`Not logged in to ${baseUrl}. Run \`vellum login\`.`);
|
|
25
22
|
}
|
|
26
23
|
function storePath() {
|
|
27
24
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
@@ -111,7 +108,8 @@ class VellumClient {
|
|
|
111
108
|
});
|
|
112
109
|
if (!res.ok)
|
|
113
110
|
await this.fail(res);
|
|
114
|
-
|
|
111
|
+
const body = await res.json();
|
|
112
|
+
return { ...body, created: res.status === 201 };
|
|
115
113
|
}
|
|
116
114
|
async getPage(pageId) {
|
|
117
115
|
const res = await this.fetchImpl(`${this.baseUrl}/v1/pages/${encodeURIComponent(pageId)}`, { headers: this.authHeaders() });
|
|
@@ -204,12 +202,11 @@ Usage:
|
|
|
204
202
|
vellum ${verb} <page-id> [options]
|
|
205
203
|
|
|
206
204
|
${verb === "archive" ? `Archiving keeps the bytes, versions, comments, and URLs intact — new
|
|
207
|
-
versions and comments are paused until you unarchive.
|
|
208
|
-
versions and comments.
|
|
205
|
+
versions and comments are paused until you unarchive. Page owner only.` : `Unarchiving restores the page to the gallery and re-opens it for new
|
|
206
|
+
versions and comments. Page owner only.`}
|
|
209
207
|
|
|
210
208
|
Options:
|
|
211
209
|
--url <url> Server base URL (env: VELLUM_URL)
|
|
212
|
-
--api-key <key> Shared API key (env: VELLUM_API_KEY)
|
|
213
210
|
--json Print the raw JSON response
|
|
214
211
|
-h, --help Show this help`;
|
|
215
212
|
}
|
|
@@ -219,7 +216,6 @@ async function run(verb, argv) {
|
|
|
219
216
|
allowPositionals: true,
|
|
220
217
|
options: {
|
|
221
218
|
url: { type: "string" },
|
|
222
|
-
"api-key": { type: "string" },
|
|
223
219
|
json: { type: "boolean", default: false },
|
|
224
220
|
help: { type: "boolean", short: "h", default: false }
|
|
225
221
|
}
|
|
@@ -235,7 +231,7 @@ async function run(verb, argv) {
|
|
|
235
231
|
console.error(help(verb));
|
|
236
232
|
return 1;
|
|
237
233
|
}
|
|
238
|
-
const flags = { url: values.url
|
|
234
|
+
const flags = { url: values.url };
|
|
239
235
|
const baseUrl = resolveBaseUrl(flags);
|
|
240
236
|
const credential = await resolveCredential(flags, baseUrl);
|
|
241
237
|
const client2 = new VellumClient({ baseUrl, ...credential });
|
|
@@ -249,7 +245,11 @@ async function run(verb, argv) {
|
|
|
249
245
|
return 0;
|
|
250
246
|
} catch (err) {
|
|
251
247
|
if (err instanceof VellumApiError && err.status === 401) {
|
|
252
|
-
console.error(`Error:
|
|
248
|
+
console.error(`Error: not logged in. Run \`vellum login\` as the page owner.`);
|
|
249
|
+
return 1;
|
|
250
|
+
}
|
|
251
|
+
if (err instanceof VellumApiError && err.status === 403) {
|
|
252
|
+
console.error(`Error: you don't own ${pageId}, so you can't ${verb} it.`);
|
|
253
253
|
return 1;
|
|
254
254
|
}
|
|
255
255
|
if (err instanceof VellumApiError && err.status === 404) {
|
|
@@ -273,15 +273,13 @@ var HELP = `vellum list — list your artifacts
|
|
|
273
273
|
Usage:
|
|
274
274
|
vellum list [options]
|
|
275
275
|
|
|
276
|
-
Lists the pages you own (log in with \`vellum login\`).
|
|
277
|
-
|
|
278
|
-
shown; use --archived for archived-only, or --all for both.
|
|
276
|
+
Lists the pages you own (log in with \`vellum login\`). By default only live
|
|
277
|
+
pages are shown; use --archived for archived-only, or --all for both.
|
|
279
278
|
|
|
280
279
|
Options:
|
|
281
280
|
--archived Show only archived pages
|
|
282
281
|
--all Show both live and archived pages
|
|
283
282
|
--url <url> Server base URL (env: VELLUM_URL)
|
|
284
|
-
--api-key <key> Shared API key (env: VELLUM_API_KEY)
|
|
285
283
|
--json Print the raw JSON response
|
|
286
284
|
-h, --help Show this help`;
|
|
287
285
|
function cell(value, width) {
|
|
@@ -309,7 +307,6 @@ async function listCommand(argv) {
|
|
|
309
307
|
archived: { type: "boolean", default: false },
|
|
310
308
|
all: { type: "boolean", default: false },
|
|
311
309
|
url: { type: "string" },
|
|
312
|
-
"api-key": { type: "string" },
|
|
313
310
|
json: { type: "boolean", default: false },
|
|
314
311
|
help: { type: "boolean", short: "h", default: false }
|
|
315
312
|
}
|
|
@@ -318,7 +315,7 @@ async function listCommand(argv) {
|
|
|
318
315
|
console.log(HELP);
|
|
319
316
|
return 0;
|
|
320
317
|
}
|
|
321
|
-
const flags = { url: values.url
|
|
318
|
+
const flags = { url: values.url };
|
|
322
319
|
const baseUrl = resolveBaseUrl(flags);
|
|
323
320
|
const credential = await resolveCredential(flags, baseUrl);
|
|
324
321
|
const client2 = new VellumClient({ baseUrl, ...credential });
|
|
@@ -344,7 +341,7 @@ ${pages.length} page${pages.length === 1 ? "" : "s"}${suffix}`);
|
|
|
344
341
|
return 0;
|
|
345
342
|
} catch (err) {
|
|
346
343
|
if (err instanceof VellumApiError && err.status === 401) {
|
|
347
|
-
console.error("Error: not authenticated. Run `vellum login`
|
|
344
|
+
console.error("Error: not authenticated. Run `vellum login` as the page owner.");
|
|
348
345
|
return 1;
|
|
349
346
|
}
|
|
350
347
|
throw err;
|
|
@@ -485,7 +482,6 @@ Options:
|
|
|
485
482
|
--version <n> Pin to a specific version number (default: current)
|
|
486
483
|
--force Post even if the quote isn't found in the version
|
|
487
484
|
--url <url> Server base URL (env: VELLUM_URL)
|
|
488
|
-
--api-key <key> Shared API key (env: VELLUM_API_KEY)
|
|
489
485
|
--json Print the raw JSON response
|
|
490
486
|
-h, --help Show this help`;
|
|
491
487
|
async function readStdin() {
|
|
@@ -519,7 +515,6 @@ async function markupCommand(argv) {
|
|
|
519
515
|
version: { type: "string" },
|
|
520
516
|
force: { type: "boolean", default: false },
|
|
521
517
|
url: { type: "string" },
|
|
522
|
-
"api-key": { type: "string" },
|
|
523
518
|
json: { type: "boolean", default: false },
|
|
524
519
|
help: { type: "boolean", short: "h", default: false }
|
|
525
520
|
}
|
|
@@ -553,7 +548,7 @@ async function markupCommand(argv) {
|
|
|
553
548
|
return 1;
|
|
554
549
|
}
|
|
555
550
|
}
|
|
556
|
-
const flags = { url: values.url
|
|
551
|
+
const flags = { url: values.url };
|
|
557
552
|
const baseUrl = resolveBaseUrl(flags);
|
|
558
553
|
const credential = await resolveCredential(flags, baseUrl);
|
|
559
554
|
const client2 = new VellumClient({ baseUrl, ...credential });
|
|
@@ -590,6 +585,10 @@ async function markupCommand(argv) {
|
|
|
590
585
|
// src/commands/push.ts
|
|
591
586
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
592
587
|
import { parseArgs as parseArgs6 } from "node:util";
|
|
588
|
+
function formatPush(res) {
|
|
589
|
+
const head = res.created ? `✓ v${res.version_number} created` : `↺ identical to v${res.version_number} — no new version`;
|
|
590
|
+
return [head, ` view: ${res.view_url}`, ` raw: ${res.raw_url}`];
|
|
591
|
+
}
|
|
593
592
|
var HELP5 = `vellum push — create a Vellum artifact from HTML
|
|
594
593
|
|
|
595
594
|
Usage:
|
|
@@ -599,7 +598,6 @@ Usage:
|
|
|
599
598
|
Options:
|
|
600
599
|
--page-id <id> Append a new version to an existing page
|
|
601
600
|
--url <url> Server base URL (env: VELLUM_URL)
|
|
602
|
-
--api-key <key> Shared API key (env: VELLUM_API_KEY)
|
|
603
601
|
--json Print the raw JSON response
|
|
604
602
|
-h, --help Show this help`;
|
|
605
603
|
async function readStdin2() {
|
|
@@ -615,7 +613,6 @@ async function pushCommand(argv) {
|
|
|
615
613
|
options: {
|
|
616
614
|
"page-id": { type: "string" },
|
|
617
615
|
url: { type: "string" },
|
|
618
|
-
"api-key": { type: "string" },
|
|
619
616
|
json: { type: "boolean", default: false },
|
|
620
617
|
help: { type: "boolean", short: "h", default: false }
|
|
621
618
|
}
|
|
@@ -630,7 +627,7 @@ async function pushCommand(argv) {
|
|
|
630
627
|
console.error("Error: no HTML provided (empty file or stdin).");
|
|
631
628
|
return 1;
|
|
632
629
|
}
|
|
633
|
-
const flags = { url: values.url
|
|
630
|
+
const flags = { url: values.url };
|
|
634
631
|
const baseUrl = resolveBaseUrl(flags);
|
|
635
632
|
const credential = await resolveCredential(flags, baseUrl);
|
|
636
633
|
const client2 = new VellumClient({ baseUrl, ...credential });
|
|
@@ -638,16 +635,15 @@ async function pushCommand(argv) {
|
|
|
638
635
|
if (values.json) {
|
|
639
636
|
console.log(JSON.stringify(res, null, 2));
|
|
640
637
|
} else {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
console.log(` raw: ${res.raw_url}`);
|
|
638
|
+
for (const line of formatPush(res))
|
|
639
|
+
console.log(line);
|
|
644
640
|
}
|
|
645
641
|
return 0;
|
|
646
642
|
}
|
|
647
643
|
// package.json
|
|
648
644
|
var package_default = {
|
|
649
645
|
name: "vellum-cli",
|
|
650
|
-
version: "0.3.
|
|
646
|
+
version: "0.3.5",
|
|
651
647
|
description: "The vellum CLI — publish agent-authored HTML artifacts to a Vellum server.",
|
|
652
648
|
type: "module",
|
|
653
649
|
license: "MIT",
|
|
@@ -701,14 +697,12 @@ Usage:
|
|
|
701
697
|
|
|
702
698
|
Options:
|
|
703
699
|
--url <url> Server base URL (env: VELLUM_URL)
|
|
704
|
-
--api-key <key> Shared API key (env: VELLUM_API_KEY)
|
|
705
700
|
-h, --help Show this help`;
|
|
706
701
|
async function whoamiCommand(argv) {
|
|
707
702
|
const { values } = parseArgs7({
|
|
708
703
|
args: argv,
|
|
709
704
|
options: {
|
|
710
705
|
url: { type: "string" },
|
|
711
|
-
"api-key": { type: "string" },
|
|
712
706
|
help: { type: "boolean", short: "h", default: false }
|
|
713
707
|
}
|
|
714
708
|
});
|
|
@@ -717,11 +711,7 @@ async function whoamiCommand(argv) {
|
|
|
717
711
|
return 0;
|
|
718
712
|
}
|
|
719
713
|
const baseUrl = resolveBaseUrl({ url: values.url });
|
|
720
|
-
const credential = await resolveCredential({ url: values.url
|
|
721
|
-
if ("apiKey" in credential) {
|
|
722
|
-
console.log(`Authenticated to ${baseUrl} with a shared API key (owner).`);
|
|
723
|
-
return 0;
|
|
724
|
-
}
|
|
714
|
+
const credential = await resolveCredential({ url: values.url }, baseUrl);
|
|
725
715
|
const client2 = new VellumClient({ baseUrl, token: credential.token });
|
|
726
716
|
const { email } = await client2.whoami();
|
|
727
717
|
console.log(`${email ?? "(no email on record)"} — ${baseUrl}`);
|
|
@@ -739,7 +729,7 @@ Commands:
|
|
|
739
729
|
logout Remove this machine's stored CLI token
|
|
740
730
|
whoami Show the identity the CLI is authenticated as
|
|
741
731
|
push Create an artifact (page) from HTML (file or stdin)
|
|
742
|
-
list List your
|
|
732
|
+
list List artifacts owned by your logged-in identity
|
|
743
733
|
markup Pin a comment to a passage of a document
|
|
744
734
|
archive Archive a page (read-only, hidden from the gallery)
|
|
745
735
|
unarchive Restore an archived page to live
|