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.
- package/README.md +63 -0
- package/dist/index.js +116 -8
- 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
|
|
300
|
-
|
|
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
|
-
|
|
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>");
|