vessels 0.2.6 → 0.3.0

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 +63 -0
  2. package/dist/index.js +116 -8
  3. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # vessels
2
+
3
+ CLI for [Vessels](https://vessels.app) — let your agent reach you.
4
+
5
+ Vessels is the communication layer between AI agents and their human operators. This CLI handles account setup, API key management, and webhook configuration.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install -g vessels
11
+ ```
12
+
13
+ ## Setup (Claude Code and AI assistants — fully non-interactive)
14
+
15
+ Two commands. One human step (the OTP from your inbox).
16
+
17
+ ```bash
18
+ # Step 1 — send OTP to your email
19
+ vessels init --email me@example.com
20
+
21
+ # Step 2 — verify and complete setup (run with the code from your inbox)
22
+ vessels init --email me@example.com --otp 847293
23
+
24
+ # Output:
25
+ # VESSELS_API_KEY=vsl_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
26
+ # npm install vessels-sdk
27
+
28
+ # With webhook (optional — add once your server is deployed):
29
+ vessels init --email me@example.com --otp 847293 --webhook-url https://myapp.com/hooks/vessels
30
+ # Also prints: VESSELS_WEBHOOK_SECRET=whsec_xxx
31
+ ```
32
+
33
+ `vessels init` creates an account if you don't have one, then creates an API key (and optional webhook endpoint), and prints copy-ready `.env` entries. It's designed for Claude Code or any AI assistant to drive autonomously — the only human touch point is entering the 6-digit OTP.
34
+
35
+ ## All commands
36
+
37
+ ```
38
+ vessels init --email <email> [--otp <code>] [--name <key-name>] [--webhook-url <url>]
39
+ First-time setup. Run once to send OTP, re-run with --otp to complete.
40
+
41
+ vessels login [--email <email>] [--otp <code>]
42
+ vessels logout
43
+ vessels whoami
44
+
45
+ vessels keys list
46
+ vessels keys create [--name <name>]
47
+ vessels keys revoke <id>
48
+
49
+ vessels webhooks list
50
+ vessels webhooks create --url <https://...> [--events interaction.response,message.user]
51
+ vessels webhooks delete <id>
52
+ vessels webhooks enable <id>
53
+ vessels webhooks disable <id>
54
+
55
+ vessels push --vessel <id> --message <text> --key <vsl_xxx>
56
+ vessels message --vessel <id> --message <text>
57
+ ```
58
+
59
+ ## Full reference
60
+
61
+ - SDK: [vessels-sdk on npm](https://www.npmjs.com/package/vessels-sdk)
62
+ - Docs: [vessels.app/docs](https://vessels.app/docs)
63
+ - AI-readable reference: [vessels.app/llms-full.txt](https://vessels.app/llms-full.txt)
package/dist/index.js CHANGED
@@ -213,6 +213,31 @@ async function cmdWebhooksToggle(id, active) {
213
213
  });
214
214
  console.log(`Webhook ${data.endpoint.id} ${data.endpoint.active ? "enabled" : "disabled"}.`);
215
215
  }
216
+ async function cmdWebhooksUpdate(id, args) {
217
+ const flags = parseFlags(args);
218
+ const updates = {};
219
+ if (flags.url !== void 0) {
220
+ if (!flags.url.startsWith("https://")) {
221
+ console.error("URL must start with https://");
222
+ process.exit(1);
223
+ }
224
+ updates.url = flags.url;
225
+ }
226
+ if (flags.events !== void 0) {
227
+ updates.events = flags.events.split(/[,\s]+/).filter(Boolean);
228
+ }
229
+ if (!Object.keys(updates).length) {
230
+ console.error("Nothing to update. Pass --url <https://...> and/or --events <a,b>.");
231
+ process.exit(1);
232
+ }
233
+ const data = await api(`/api/v1/webhooks/${id}`, {
234
+ method: "PATCH",
235
+ body: JSON.stringify(updates)
236
+ });
237
+ console.log(`Webhook ${data.endpoint.id} updated.`);
238
+ console.log(` URL: ${data.endpoint.url}`);
239
+ console.log(` Events: ${data.endpoint.events.join(", ")}`);
240
+ }
216
241
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
217
242
  async function resolveVesselId(input) {
218
243
  if (UUID_RE.test(input)) return input;
@@ -291,14 +316,93 @@ async function cmdPush(args) {
291
316
  }
292
317
  console.log(`Message sent. vessel_id=${data.vessel_id} message_id=${data.message_id}`);
293
318
  }
319
+ async function cmdInit(args) {
320
+ const flags = parseFlags(args);
321
+ const email = flags.email || await prompt("Email: ");
322
+ if (!flags.otp) {
323
+ const res = await fetch(`${BASE_URL}/api/v1/auth/otp/send`, {
324
+ method: "POST",
325
+ headers: { "Content-Type": "application/json" },
326
+ body: JSON.stringify({ email })
327
+ });
328
+ if (!res.ok) {
329
+ const data = await res.json();
330
+ console.error("Failed to send code:", data.error);
331
+ process.exit(1);
332
+ }
333
+ console.log(`
334
+ OTP sent to ${email}.
335
+ `);
336
+ const webhookFlag = flags["webhook-url"] ? ` --webhook-url ${flags["webhook-url"]}` : "";
337
+ const nameFlag = flags.name ? ` --name ${flags.name}` : "";
338
+ console.log(`Run:
339
+
340
+ vessels init --email ${email} --otp <code>${nameFlag}${webhookFlag}
341
+ `);
342
+ return;
343
+ }
344
+ const verifyRes = await fetch(`${BASE_URL}/api/v1/auth/otp/verify`, {
345
+ method: "POST",
346
+ headers: { "Content-Type": "application/json" },
347
+ body: JSON.stringify({ email, token: flags.otp })
348
+ });
349
+ const verifyData = await verifyRes.json();
350
+ if (!verifyRes.ok) {
351
+ console.error("Invalid or expired code.");
352
+ process.exit(1);
353
+ }
354
+ writeConfig({ access_token: verifyData.access_token, refresh_token: verifyData.refresh_token, email });
355
+ await api("/api/v1/me");
356
+ const keyData = await api("/api/v1/keys", {
357
+ method: "POST",
358
+ body: JSON.stringify({ name: flags.name || "default" })
359
+ });
360
+ console.log(`
361
+ Setup complete.
362
+ `);
363
+ console.log(`Add to your .env file:
364
+ `);
365
+ console.log(` VESSELS_API_KEY=${keyData.key}`);
366
+ if (flags["webhook-url"]) {
367
+ const webhookData = await api("/api/v1/webhooks", {
368
+ method: "POST",
369
+ body: JSON.stringify({ url: flags["webhook-url"], events: ["interaction.response", "message.user"] })
370
+ });
371
+ console.log(` VESSELS_WEBHOOK_SECRET=${webhookData.endpoint.secret}`);
372
+ }
373
+ console.log(`
374
+ Install the SDK:
375
+
376
+ npm install vessels-sdk
377
+ `);
378
+ if (!flags["webhook-url"]) {
379
+ console.log(`To receive webhooks (once your server is deployed):
380
+ `);
381
+ console.log(` vessels webhooks create --url https://your-app.com/hooks/vessels
382
+ `);
383
+ }
384
+ console.log(`Full reference: https://vessels.app/llms-full.txt`);
385
+ }
294
386
  var [, , cmd, sub, ...rest] = process.argv;
295
387
  var HELP = `
296
388
  vessels \u2014 CLI for Vessels (vessels.app)
297
389
 
390
+ Quick setup (Claude Code / AI agents \u2014 fully non-interactive):
391
+
392
+ vessels init --email me@example.com
393
+ # Vessels emails you a 6-digit code. Then run:
394
+ vessels init --email me@example.com --otp 847293
395
+ # Prints VESSELS_API_KEY=vsl_xxx and npm install vessels-sdk
396
+
397
+ # With a webhook (optional, run once your server is deployed):
398
+ vessels init --email me@example.com --otp 847293 --webhook-url https://myapp.com/hooks/vessels
399
+
298
400
  Commands:
299
- vessels login [--email <email>] [--otp <code>]
300
- Log in or sign up. Run without --otp to send the code, then re-run with --otp to verify.
401
+ vessels init --email <email> [--otp <code>] [--name <key-name>] [--webhook-url <url>]
402
+ First-time setup: account + API key (+ webhook). Two-step: run once to send OTP,
403
+ re-run with --otp to complete. Prints copy-ready .env entries.
301
404
 
405
+ vessels login [--email <email>] [--otp <code>]
302
406
  vessels logout
303
407
  vessels whoami
304
408
 
@@ -308,6 +412,7 @@ Commands:
308
412
 
309
413
  vessels webhooks list
310
414
  vessels webhooks create --url <https://...> [--events interaction.response,message.user]
415
+ vessels webhooks update <id> [--url <https://...>] [--events interaction.response,message.user]
311
416
  vessels webhooks delete <id>
312
417
  vessels webhooks enable <id>
313
418
  vessels webhooks disable <id>
@@ -319,18 +424,14 @@ Commands:
319
424
  Send a message as the logged-in user and print webhook delivery logs.
320
425
  Accepts vessel UUID or external_id (e.g. booking-123).
321
426
 
322
- Agent/Claude Code setup (fully non-interactive):
323
- vessels login --email me@example.com
324
- # tell your agent the OTP from the email
325
- vessels login --email me@example.com --otp 847293
326
- vessels keys create --name my-project
327
- vessels webhooks create --url https://myapp.com/hooks/vessels
427
+ Full reference: https://vessels.app/llms-full.txt
328
428
  `;
329
429
  async function main() {
330
430
  if (!cmd || cmd === "help" || cmd === "--help" || cmd === "-h") {
331
431
  console.log(HELP);
332
432
  return;
333
433
  }
434
+ if (cmd === "init") return cmdInit([sub, ...rest].filter(Boolean));
334
435
  if (cmd === "login" || cmd === "signup") return cmdLogin([sub, ...rest].filter(Boolean));
335
436
  if (cmd === "logout") return cmdLogout();
336
437
  if (cmd === "whoami") return cmdWhoami();
@@ -351,6 +452,13 @@ Run: vessels help`);
351
452
  if (cmd === "webhooks") {
352
453
  if (sub === "list" || !sub) return cmdWebhooksList();
353
454
  if (sub === "create") return cmdWebhooksCreate(rest);
455
+ if (sub === "update") {
456
+ if (!rest[0]) {
457
+ console.error("Usage: vessels webhooks update <id> [--url <https://...>] [--events <a,b>]");
458
+ process.exit(1);
459
+ }
460
+ return cmdWebhooksUpdate(rest[0], rest.slice(1));
461
+ }
354
462
  if (sub === "delete" || sub === "remove") {
355
463
  if (!rest[0]) {
356
464
  console.error("Usage: vessels webhooks delete <id>");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vessels",
3
- "version": "0.2.6",
3
+ "version": "0.3.0",
4
4
  "description": "Vessels CLI — manage your agent communication layer from the terminal",
5
5
  "type": "module",
6
6
  "bin": {