vellum-cli 0.3.0 → 0.3.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 (3) hide show
  1. package/README.md +25 -0
  2. package/dist/index.js +152 -305
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -71,6 +71,31 @@ vellum push artifact.html --page-id pg_123 --json
71
71
  On success it prints the new version number, the human view URL, and the raw
72
72
  URL. With `--json` it prints the server's `CreateVersionResponse` verbatim.
73
73
 
74
+ ### `vellum markup <page-id>`
75
+
76
+ Pin a comment to a passage of a published document. The `--quote` text must
77
+ appear verbatim in the document; the viewer highlights it and links your note to
78
+ the highlight. Without `--version`, the page's current version is used.
79
+
80
+ ```bash
81
+ # anchor a note to a passage
82
+ vellum markup pg_123 --quote "Q3 dashboard" --body "tighten this headline"
83
+
84
+ # pipe the note in on stdin instead of --body
85
+ echo "tighten this headline" | vellum markup pg_123 --quote "Q3 dashboard"
86
+ ```
87
+
88
+ The CLI checks the quote is anchorable before posting; pass `--force` to post
89
+ anyway, or `--json` for the raw response.
90
+
91
+ ### `vellum whoami`
92
+
93
+ Show the identity the CLI is authenticated as for a server.
94
+
95
+ ### `vellum logout`
96
+
97
+ Revoke this machine's stored token server-side and forget it locally.
98
+
74
99
  ## Development
75
100
 
76
101
  From the repo root, Bun runs the TypeScript source directly (no build):
package/dist/index.js CHANGED
@@ -61,7 +61,7 @@ async function clearToken(baseUrl) {
61
61
  return existing;
62
62
  }
63
63
 
64
- // src/commands/comments.ts
64
+ // src/commands/archive.ts
65
65
  import { parseArgs } from "node:util";
66
66
  // ../core/src/client.ts
67
67
  class VellumApiError extends Error {
@@ -119,6 +119,30 @@ class VellumClient {
119
119
  await this.fail(res);
120
120
  return await res.json();
121
121
  }
122
+ async listPages(opts = {}) {
123
+ const url = new URL(`${this.baseUrl}/v1/pages`);
124
+ if (opts.archived)
125
+ url.searchParams.set("status", "archived");
126
+ else if (opts.all)
127
+ url.searchParams.set("include", "archived");
128
+ const res = await this.fetchImpl(url, { headers: this.authHeaders() });
129
+ if (!res.ok)
130
+ await this.fail(res);
131
+ return await res.json();
132
+ }
133
+ async archivePage(pageId) {
134
+ return this.setArchived(pageId, true);
135
+ }
136
+ async unarchivePage(pageId) {
137
+ return this.setArchived(pageId, false);
138
+ }
139
+ async setArchived(pageId, archived) {
140
+ const action = archived ? "archive" : "unarchive";
141
+ const res = await this.fetchImpl(`${this.baseUrl}/v1/pages/${encodeURIComponent(pageId)}/${action}`, { method: "POST", headers: this.authHeaders() });
142
+ if (!res.ok)
143
+ await this.fail(res);
144
+ return await res.json();
145
+ }
122
146
  async createComment(pageId, opts) {
123
147
  const res = await this.fetchImpl(`${this.baseUrl}/v1/pages/${encodeURIComponent(pageId)}/comments`, {
124
148
  method: "POST",
@@ -134,21 +158,6 @@ class VellumClient {
134
158
  await this.fail(res);
135
159
  return await res.json();
136
160
  }
137
- async listComments(pageId, opts = {}) {
138
- const url = new URL(`${this.baseUrl}/v1/pages/${encodeURIComponent(pageId)}/comments`);
139
- if (opts.versionId)
140
- url.searchParams.set("version_id", opts.versionId);
141
- const res = await this.fetchImpl(url, { headers: this.authHeaders() });
142
- if (!res.ok)
143
- await this.fail(res);
144
- return await res.json();
145
- }
146
- async resolveComment(commentId) {
147
- const res = await this.fetchImpl(`${this.baseUrl}/v1/comments/${encodeURIComponent(commentId)}/resolve`, { method: "POST", headers: this.authHeaders() });
148
- if (!res.ok)
149
- await this.fail(res);
150
- return await res.json();
151
- }
152
161
  async startCliAuth() {
153
162
  const res = await this.fetchImpl(`${this.baseUrl}/v1/cli/auth/start`, {
154
163
  method: "POST",
@@ -186,143 +195,159 @@ class VellumClient {
186
195
  await this.fail(res);
187
196
  }
188
197
  }
189
- // src/commands/comments.ts
190
- var HELP = `vellum comments — list the comments on a document
198
+ // src/commands/archive.ts
199
+ function help(verb) {
200
+ const what = verb === "archive" ? "hide a page from the gallery and make it read-only" : "restore an archived page to live";
201
+ return `vellum ${verb} — ${what}
191
202
 
192
203
  Usage:
193
- vellum comments <page-id> [options]
204
+ vellum ${verb} <page-id> [options]
194
205
 
195
- Reads are public, so no login is required. Comments print as threads; replies
196
- are indented under their parent.
206
+ ${verb === "archive" ? `Archiving keeps the bytes, versions, comments, and URLs intact — new
207
+ versions and comments are paused until you unarchive. Owner/admin only.` : `Unarchiving restores the page to the gallery and re-opens it for new
208
+ versions and comments. Owner/admin only.`}
197
209
 
198
210
  Options:
199
- --open Show only unresolved threads
200
- --version <id> Only comments anchored to this version id
201
211
  --url <url> Server base URL (env: VELLUM_URL)
212
+ --api-key <key> Shared API key (env: VELLUM_API_KEY)
202
213
  --json Print the raw JSON response
203
214
  -h, --help Show this help`;
204
- var truncate = (s, n) => s.length > n ? `${s.slice(0, n - 1)}…` : s;
205
- var oneLine = (s) => s.replace(/\s+/g, " ").trim();
206
- function printComment(c, indent) {
207
- const who = c.author_email ?? c.author_name ?? "(unknown)";
208
- const state = c.resolved ? "resolved" : "open";
209
- console.log(`${indent}${c.id} [${state}] ${who}`);
210
- if (c.anchor?.exact) {
211
- console.log(`${indent} on “${truncate(oneLine(c.anchor.exact), 70)}”`);
212
- }
213
- console.log(`${indent} ${truncate(oneLine(c.body), 100)}`);
214
- for (const reply of c.replies ?? []) {
215
- printComment(reply, `${indent} `);
216
- }
217
215
  }
218
- async function commentsCommand(argv) {
216
+ async function run(verb, argv) {
219
217
  const { values, positionals } = parseArgs({
220
218
  args: argv,
221
219
  allowPositionals: true,
222
220
  options: {
223
- open: { type: "boolean", default: false },
224
- version: { type: "string" },
225
221
  url: { type: "string" },
222
+ "api-key": { type: "string" },
226
223
  json: { type: "boolean", default: false },
227
224
  help: { type: "boolean", short: "h", default: false }
228
225
  }
229
226
  });
230
227
  if (values.help) {
231
- console.log(HELP);
228
+ console.log(help(verb));
232
229
  return 0;
233
230
  }
234
231
  const pageId = positionals[0];
235
232
  if (!pageId) {
236
233
  console.error(`Error: missing <page-id>.
237
234
  `);
238
- console.error(HELP);
235
+ console.error(help(verb));
239
236
  return 1;
240
237
  }
241
- const baseUrl = resolveBaseUrl({ url: values.url });
242
- const client2 = new VellumClient({ baseUrl });
243
- let comments = await client2.listComments(pageId, {
244
- versionId: values.version
245
- });
246
- if (values.open)
247
- comments = comments.filter((c) => !c.resolved);
248
- if (values.json) {
249
- console.log(JSON.stringify(comments, null, 2));
250
- return 0;
251
- }
252
- if (comments.length === 0) {
253
- console.log(values.open ? "No open comments." : "No comments.");
238
+ const flags = { url: values.url, apiKey: values["api-key"] };
239
+ const baseUrl = resolveBaseUrl(flags);
240
+ const credential = await resolveCredential(flags, baseUrl);
241
+ const client2 = new VellumClient({ baseUrl, ...credential });
242
+ try {
243
+ const res = verb === "archive" ? await client2.archivePage(pageId) : await client2.unarchivePage(pageId);
244
+ if (values.json) {
245
+ console.log(JSON.stringify(res, null, 2));
246
+ } else {
247
+ console.log(`✓ ${verb}d ${res.id}`);
248
+ }
254
249
  return 0;
250
+ } catch (err) {
251
+ if (err instanceof VellumApiError && err.status === 401) {
252
+ console.error(`Error: ${verb} requires the owner API key. Set VELLUM_API_KEY or pass --api-key.`);
253
+ return 1;
254
+ }
255
+ if (err instanceof VellumApiError && err.status === 404) {
256
+ console.error(`Error: no page found at ${pageId}.`);
257
+ return 1;
258
+ }
259
+ throw err;
255
260
  }
256
- for (const c of comments)
257
- printComment(c, "");
258
- return 0;
261
+ }
262
+ function archiveCommand(argv) {
263
+ return run("archive", argv);
264
+ }
265
+ function unarchiveCommand(argv) {
266
+ return run("unarchive", argv);
259
267
  }
260
268
 
261
- // src/commands/get.ts
269
+ // src/commands/list.ts
262
270
  import { parseArgs as parseArgs2 } from "node:util";
263
- var HELP2 = `vellum getprint a document's raw HTML
271
+ var HELP = `vellum listlist your artifacts (owner/admin only)
264
272
 
265
273
  Usage:
266
- vellum get <page-id> [options]
274
+ vellum list [options]
267
275
 
268
- Reads are public, so no login is required. Without --version, the page's
269
- current version is printed.
276
+ By default only live pages are shown. Use --archived for archived-only, or
277
+ --all for both. Listing requires the owner API key (VELLUM_API_KEY / --api-key).
270
278
 
271
279
  Options:
272
- --version <n> Print a specific version number (default: current)
280
+ --archived Show only archived pages
281
+ --all Show both live and archived pages
273
282
  --url <url> Server base URL (env: VELLUM_URL)
283
+ --api-key <key> Shared API key (env: VELLUM_API_KEY)
284
+ --json Print the raw JSON response
274
285
  -h, --help Show this help`;
275
- function resolveVersion(page, requested) {
276
- if (requested != null) {
277
- return page.versions.find((v) => v.version_number === requested) ?? null;
278
- }
279
- const current = page.current_version_id ? page.versions.find((v) => v.id === page.current_version_id) : undefined;
280
- return current ?? page.versions[page.versions.length - 1] ?? null;
286
+ function cell(value, width) {
287
+ if (value.length > width)
288
+ return `${value.slice(0, width - 1)}…`;
289
+ return value.padEnd(width);
290
+ }
291
+ function renderTable(pages) {
292
+ const lines = [
293
+ `${cell("PAGE", 26)} ${cell("LATEST", 7)} ${cell("VERS", 5)} ${cell("COMM", 5)} TITLE`
294
+ ];
295
+ for (const p of pages) {
296
+ const id = p.archived_at ? `${p.id} *` : p.id;
297
+ const latest = p.latest_version != null ? `v${p.latest_version}` : "—";
298
+ lines.push(`${cell(id, 26)} ${cell(latest, 7)} ${cell(String(p.version_count), 5)} ` + `${cell(String(p.comment_count), 5)} ${p.title ?? ""}`.trimEnd());
299
+ }
300
+ return lines.join(`
301
+ `);
281
302
  }
282
- async function getCommand(argv) {
283
- const { values, positionals } = parseArgs2({
303
+ async function listCommand(argv) {
304
+ const { values } = parseArgs2({
284
305
  args: argv,
285
- allowPositionals: true,
306
+ allowPositionals: false,
286
307
  options: {
287
- version: { type: "string" },
308
+ archived: { type: "boolean", default: false },
309
+ all: { type: "boolean", default: false },
288
310
  url: { type: "string" },
311
+ "api-key": { type: "string" },
312
+ json: { type: "boolean", default: false },
289
313
  help: { type: "boolean", short: "h", default: false }
290
314
  }
291
315
  });
292
316
  if (values.help) {
293
- console.log(HELP2);
317
+ console.log(HELP);
294
318
  return 0;
295
319
  }
296
- const pageId = positionals[0];
297
- if (!pageId) {
298
- console.error(`Error: missing <page-id>.
299
- `);
300
- console.error(HELP2);
301
- return 1;
302
- }
303
- let version;
304
- if (values.version != null) {
305
- version = Number.parseInt(values.version, 10);
306
- if (!Number.isInteger(version) || version < 1) {
307
- console.error("Error: --version must be a positive integer.");
320
+ const flags = { url: values.url, apiKey: values["api-key"] };
321
+ const baseUrl = resolveBaseUrl(flags);
322
+ const credential = await resolveCredential(flags, baseUrl);
323
+ const client2 = new VellumClient({ baseUrl, ...credential });
324
+ try {
325
+ const { pages } = await client2.listPages({
326
+ archived: values.archived,
327
+ all: values.all
328
+ });
329
+ if (values.json) {
330
+ console.log(JSON.stringify(pages, null, 2));
331
+ return 0;
332
+ }
333
+ if (pages.length === 0) {
334
+ const scope = values.archived ? "archived " : "";
335
+ console.log(`No ${scope}pages.`);
336
+ return 0;
337
+ }
338
+ console.log(renderTable(pages));
339
+ const archivedCount = pages.filter((p) => p.archived_at).length;
340
+ const suffix = archivedCount ? ` (${archivedCount} archived, marked *)` : "";
341
+ console.log(`
342
+ ${pages.length} page${pages.length === 1 ? "" : "s"}${suffix}`);
343
+ return 0;
344
+ } catch (err) {
345
+ if (err instanceof VellumApiError && err.status === 401) {
346
+ console.error("Error: list requires the owner API key. Set VELLUM_API_KEY or pass --api-key.");
308
347
  return 1;
309
348
  }
349
+ throw err;
310
350
  }
311
- const baseUrl = resolveBaseUrl({ url: values.url });
312
- const client2 = new VellumClient({ baseUrl });
313
- const page = await client2.getPage(pageId);
314
- const target = resolveVersion(page, version);
315
- if (!target) {
316
- console.error(version != null ? `Error: page has no version ${version}.` : "Error: page has no versions.");
317
- return 1;
318
- }
319
- const res = await fetch(target.raw_url);
320
- if (!res.ok) {
321
- console.error(`Error: could not fetch raw HTML (${res.status}).`);
322
- return 1;
323
- }
324
- process.stdout.write(await res.text());
325
- return 0;
326
351
  }
327
352
 
328
353
  // src/commands/login.ts
@@ -344,7 +369,7 @@ function openBrowser(url) {
344
369
  }
345
370
 
346
371
  // src/commands/login.ts
347
- var HELP3 = `vellum login — authenticate this machine to a Vellum server
372
+ var HELP2 = `vellum login — authenticate this machine to a Vellum server
348
373
 
349
374
  Opens your browser to approve a CLI login, then stores a token under
350
375
  ~/.config/vellum/config.json so future commands authenticate as you.
@@ -367,7 +392,7 @@ async function loginCommand(argv) {
367
392
  }
368
393
  });
369
394
  if (values.help) {
370
- console.log(HELP3);
395
+ console.log(HELP2);
371
396
  return 0;
372
397
  }
373
398
  const baseUrl = resolveBaseUrl({ url: values.url });
@@ -408,7 +433,7 @@ To authorize this CLI, visit:
408
433
 
409
434
  // src/commands/logout.ts
410
435
  import { parseArgs as parseArgs4 } from "node:util";
411
- var HELP4 = `vellum logout — remove this machine's stored CLI token
436
+ var HELP3 = `vellum logout — remove this machine's stored CLI token
412
437
 
413
438
  Usage:
414
439
  vellum logout [options]
@@ -425,7 +450,7 @@ async function logoutCommand(argv) {
425
450
  }
426
451
  });
427
452
  if (values.help) {
428
- console.log(HELP4);
453
+ console.log(HELP3);
429
454
  return 0;
430
455
  }
431
456
  const baseUrl = resolveBaseUrl({ url: values.url });
@@ -443,7 +468,7 @@ async function logoutCommand(argv) {
443
468
 
444
469
  // src/commands/markup.ts
445
470
  import { parseArgs as parseArgs5 } from "node:util";
446
- var HELP5 = `vellum markup — pin a comment to a passage of a document
471
+ var HELP4 = `vellum markup — pin a comment to a passage of a document
447
472
 
448
473
  Usage:
449
474
  vellum markup <page-id> --quote "<text>" --body "<note>" [options]
@@ -468,7 +493,7 @@ async function readStdin() {
468
493
  chunks.push(chunk);
469
494
  return Buffer.concat(chunks).toString("utf8");
470
495
  }
471
- function resolveVersion2(page, requested) {
496
+ function resolveVersion(page, requested) {
472
497
  if (requested != null) {
473
498
  return page.versions.find((v) => v.version_number === requested) ?? null;
474
499
  }
@@ -499,14 +524,14 @@ async function markupCommand(argv) {
499
524
  }
500
525
  });
501
526
  if (values.help) {
502
- console.log(HELP5);
527
+ console.log(HELP4);
503
528
  return 0;
504
529
  }
505
530
  const pageId = positionals[0];
506
531
  if (!pageId) {
507
532
  console.error(`Error: missing <page-id>.
508
533
  `);
509
- console.error(HELP5);
534
+ console.error(HELP4);
510
535
  return 1;
511
536
  }
512
537
  const quote = (values.quote ?? "").trim();
@@ -532,7 +557,7 @@ async function markupCommand(argv) {
532
557
  const credential = await resolveCredential(flags, baseUrl);
533
558
  const client2 = new VellumClient({ baseUrl, ...credential });
534
559
  const page = await client2.getPage(pageId);
535
- const target = resolveVersion2(page, version);
560
+ const target = resolveVersion(page, version);
536
561
  if (!target) {
537
562
  console.error(version != null ? `Error: page has no version ${version}.` : "Error: page has no versions to mark up.");
538
563
  return 1;
@@ -561,50 +586,10 @@ async function markupCommand(argv) {
561
586
  return 0;
562
587
  }
563
588
 
564
- // src/commands/open.ts
565
- import { parseArgs as parseArgs6 } from "node:util";
566
- var HELP6 = `vellum open — print (and open) a document's view URL
567
-
568
- Usage:
569
- vellum open <page-id> [options]
570
-
571
- Options:
572
- --no-browser Just print the URL; don't open the browser
573
- --url <url> Server base URL (env: VELLUM_URL)
574
- -h, --help Show this help`;
575
- async function openCommand(argv) {
576
- const { values, positionals } = parseArgs6({
577
- args: argv,
578
- allowPositionals: true,
579
- options: {
580
- "no-browser": { type: "boolean", default: false },
581
- url: { type: "string" },
582
- help: { type: "boolean", short: "h", default: false }
583
- }
584
- });
585
- if (values.help) {
586
- console.log(HELP6);
587
- return 0;
588
- }
589
- const pageId = positionals[0];
590
- if (!pageId) {
591
- console.error(`Error: missing <page-id>.
592
- `);
593
- console.error(HELP6);
594
- return 1;
595
- }
596
- const baseUrl = resolveBaseUrl({ url: values.url });
597
- const page = await new VellumClient({ baseUrl }).getPage(pageId);
598
- console.log(page.view_url);
599
- if (!values["no-browser"])
600
- openBrowser(page.view_url);
601
- return 0;
602
- }
603
-
604
589
  // src/commands/push.ts
605
590
  import { readFile as readFile2 } from "node:fs/promises";
606
- import { parseArgs as parseArgs7 } from "node:util";
607
- var HELP7 = `vellum push — create a Vellum artifact from HTML
591
+ import { parseArgs as parseArgs6 } from "node:util";
592
+ var HELP5 = `vellum push — create a Vellum artifact from HTML
608
593
 
609
594
  Usage:
610
595
  vellum push <file.html> [options]
@@ -623,7 +608,7 @@ async function readStdin2() {
623
608
  return Buffer.concat(chunks).toString("utf8");
624
609
  }
625
610
  async function pushCommand(argv) {
626
- const { values, positionals } = parseArgs7({
611
+ const { values, positionals } = parseArgs6({
627
612
  args: argv,
628
613
  allowPositionals: true,
629
614
  options: {
@@ -635,7 +620,7 @@ async function pushCommand(argv) {
635
620
  }
636
621
  });
637
622
  if (values.help) {
638
- console.log(HELP7);
623
+ console.log(HELP5);
639
624
  return 0;
640
625
  }
641
626
  const file = positionals[0];
@@ -659,143 +644,9 @@ async function pushCommand(argv) {
659
644
  return 0;
660
645
  }
661
646
 
662
- // src/commands/reply.ts
663
- import { parseArgs as parseArgs8 } from "node:util";
664
- var HELP8 = `vellum reply — reply to a comment thread
665
-
666
- Usage:
667
- vellum reply <page-id> <comment-id> --body "<note>"
668
- echo "<note>" | vellum reply <page-id> <comment-id>
669
-
670
- The reply is threaded under <comment-id> and inherits the parent's version.
671
- Run \`vellum comments <page-id>\` to find the page and comment ids.
672
-
673
- Options:
674
- --body <note> Your reply (or pipe it via stdin)
675
- --url <url> Server base URL (env: VELLUM_URL)
676
- --api-key <key> Shared API key (env: VELLUM_API_KEY)
677
- --json Print the raw JSON response
678
- -h, --help Show this help`;
679
- async function readStdin3() {
680
- const chunks = [];
681
- for await (const chunk of process.stdin)
682
- chunks.push(chunk);
683
- return Buffer.concat(chunks).toString("utf8");
684
- }
685
- function flatten(comments) {
686
- const out = [];
687
- const walk = (c) => {
688
- out.push(c);
689
- for (const reply of c.replies ?? [])
690
- walk(reply);
691
- };
692
- for (const c of comments)
693
- walk(c);
694
- return out;
695
- }
696
- async function replyCommand(argv) {
697
- const { values, positionals } = parseArgs8({
698
- args: argv,
699
- allowPositionals: true,
700
- options: {
701
- body: { type: "string" },
702
- url: { type: "string" },
703
- "api-key": { type: "string" },
704
- json: { type: "boolean", default: false },
705
- help: { type: "boolean", short: "h", default: false }
706
- }
707
- });
708
- if (values.help) {
709
- console.log(HELP8);
710
- return 0;
711
- }
712
- const [pageId, commentId] = positionals;
713
- if (!pageId || !commentId) {
714
- console.error("Error: usage is `vellum reply <page-id> <comment-id>`.\n");
715
- console.error(HELP8);
716
- return 1;
717
- }
718
- const body = (values.body ?? await readStdin3()).trim();
719
- if (!body) {
720
- console.error("Error: no note provided (pass --body or pipe it via stdin).");
721
- return 1;
722
- }
723
- const flags = { url: values.url, apiKey: values["api-key"] };
724
- const baseUrl = resolveBaseUrl(flags);
725
- const credential = await resolveCredential(flags, baseUrl);
726
- const client2 = new VellumClient({ baseUrl, ...credential });
727
- const parent = flatten(await client2.listComments(pageId)).find((c) => c.id === commentId);
728
- if (!parent) {
729
- console.error(`Error: no comment ${commentId} on page ${pageId}.`);
730
- return 1;
731
- }
732
- if (!parent.version_id) {
733
- console.error("Error: parent comment has no version to reply on.");
734
- return 1;
735
- }
736
- const reply = await client2.createComment(pageId, {
737
- versionId: parent.version_id,
738
- body,
739
- parentId: commentId
740
- });
741
- if (values.json) {
742
- console.log(JSON.stringify(reply, null, 2));
743
- } else {
744
- console.log(`✓ replied to ${commentId}`);
745
- }
746
- return 0;
747
- }
748
-
749
- // src/commands/resolve.ts
750
- import { parseArgs as parseArgs9 } from "node:util";
751
- var HELP9 = `vellum resolve — mark a comment as resolved
752
-
753
- Usage:
754
- vellum resolve <comment-id> [options]
755
-
756
- Options:
757
- --url <url> Server base URL (env: VELLUM_URL)
758
- --api-key <key> Shared API key (env: VELLUM_API_KEY)
759
- --json Print the raw JSON response
760
- -h, --help Show this help`;
761
- async function resolveCommand(argv) {
762
- const { values, positionals } = parseArgs9({
763
- args: argv,
764
- allowPositionals: true,
765
- options: {
766
- url: { type: "string" },
767
- "api-key": { type: "string" },
768
- json: { type: "boolean", default: false },
769
- help: { type: "boolean", short: "h", default: false }
770
- }
771
- });
772
- if (values.help) {
773
- console.log(HELP9);
774
- return 0;
775
- }
776
- const commentId = positionals[0];
777
- if (!commentId) {
778
- console.error(`Error: missing <comment-id>.
779
- `);
780
- console.error(HELP9);
781
- return 1;
782
- }
783
- const flags = { url: values.url, apiKey: values["api-key"] };
784
- const baseUrl = resolveBaseUrl(flags);
785
- const credential = await resolveCredential(flags, baseUrl);
786
- const client2 = new VellumClient({ baseUrl, ...credential });
787
- const comment = await client2.resolveComment(commentId);
788
- if (values.json) {
789
- console.log(JSON.stringify(comment, null, 2));
790
- } else {
791
- console.log(`✓ resolved ${comment.id}`);
792
- }
793
- return 0;
794
- }
795
-
796
647
  // src/commands/whoami.ts
797
- import { parseArgs as parseArgs10 } from "node:util";
798
- var HELP10 = `vellum whoami — show the identity the CLI is authenticated as
648
+ import { parseArgs as parseArgs7 } from "node:util";
649
+ var HELP6 = `vellum whoami — show the identity the CLI is authenticated as
799
650
 
800
651
  Usage:
801
652
  vellum whoami [options]
@@ -805,7 +656,7 @@ Options:
805
656
  --api-key <key> Shared API key (env: VELLUM_API_KEY)
806
657
  -h, --help Show this help`;
807
658
  async function whoamiCommand(argv) {
808
- const { values } = parseArgs10({
659
+ const { values } = parseArgs7({
809
660
  args: argv,
810
661
  options: {
811
662
  url: { type: "string" },
@@ -814,7 +665,7 @@ async function whoamiCommand(argv) {
814
665
  }
815
666
  });
816
667
  if (values.help) {
817
- console.log(HELP10);
668
+ console.log(HELP6);
818
669
  return 0;
819
670
  }
820
671
  const baseUrl = resolveBaseUrl({ url: values.url });
@@ -830,7 +681,7 @@ async function whoamiCommand(argv) {
830
681
  }
831
682
 
832
683
  // src/index.ts
833
- var HELP11 = `vellum — CLI for the Vellum artifact store
684
+ var HELP7 = `vellum — CLI for the Vellum artifact store
834
685
 
835
686
  Usage:
836
687
  vellum <command> [options]
@@ -840,12 +691,10 @@ Commands:
840
691
  logout Remove this machine's stored CLI token
841
692
  whoami Show the identity the CLI is authenticated as
842
693
  push Create an artifact (page) from HTML (file or stdin)
843
- get Print a document's raw HTML
844
- open Print (and open) a document's view URL
694
+ list List your artifacts (owner/admin only)
845
695
  markup Pin a comment to a passage of a document
846
- comments List the comments on a document
847
- reply Reply to a comment thread
848
- resolve Mark a comment as resolved
696
+ archive Archive a page (read-only, hidden from the gallery)
697
+ unarchive Restore an archived page to live
849
698
 
850
699
  Run 'vellum <command> --help' for command-specific options.`;
851
700
  var commands = {
@@ -853,24 +702,22 @@ var commands = {
853
702
  logout: logoutCommand,
854
703
  whoami: whoamiCommand,
855
704
  push: pushCommand,
856
- get: getCommand,
857
- open: openCommand,
705
+ list: listCommand,
858
706
  markup: markupCommand,
859
- comments: commentsCommand,
860
- reply: replyCommand,
861
- resolve: resolveCommand
707
+ archive: archiveCommand,
708
+ unarchive: unarchiveCommand
862
709
  };
863
710
  async function main() {
864
711
  const [, , cmd, ...rest] = process.argv;
865
712
  if (!cmd || cmd === "-h" || cmd === "--help" || cmd === "help") {
866
- console.log(HELP11);
713
+ console.log(HELP7);
867
714
  return cmd ? 0 : 1;
868
715
  }
869
716
  const handler = commands[cmd];
870
717
  if (!handler) {
871
718
  console.error(`Unknown command: ${cmd}
872
719
  `);
873
- console.error(HELP11);
720
+ console.error(HELP7);
874
721
  return 1;
875
722
  }
876
723
  return handler(rest);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vellum-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "The vellum CLI — publish agent-authored HTML artifacts to a Vellum server.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,9 +28,10 @@
28
28
  "start": "bun run src/index.ts",
29
29
  "build": "bun build src/index.ts --target=node --format=esm --outfile=dist/index.js",
30
30
  "prepack": "bun run build",
31
+ "release": "bun publish --access public",
31
32
  "typecheck": "tsc -p tsconfig.json --noEmit"
32
33
  },
33
34
  "devDependencies": {
34
- "@vellum/core": "workspace:*"
35
+ "@vellum/core": "0.1.0"
35
36
  }
36
37
  }