vessels 0.2.1 → 0.2.3
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/dist/index.js +83 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -37,7 +37,10 @@ async function api(path, options = {}) {
|
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
39
|
const data = await res.json();
|
|
40
|
-
if (!res.ok)
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
const hint = res.status === 401 ? ` Run: vessels login --email <email>` : "";
|
|
42
|
+
throw new Error((data.error ?? `HTTP ${res.status}`) + hint);
|
|
43
|
+
}
|
|
41
44
|
return data;
|
|
42
45
|
}
|
|
43
46
|
function prompt(question) {
|
|
@@ -108,11 +111,12 @@ async function cmdKeysList() {
|
|
|
108
111
|
console.log(`${k.prefix}\u2026 ${used}${name} [${k.id}]`);
|
|
109
112
|
}
|
|
110
113
|
}
|
|
111
|
-
async function cmdKeysCreate(
|
|
112
|
-
|
|
114
|
+
async function cmdKeysCreate(args) {
|
|
115
|
+
const flags = parseFlags(args);
|
|
116
|
+
const name = flags.name || (args[0] && !args[0].startsWith("--") ? args[0] : null) || null;
|
|
113
117
|
const data = await api("/api/v1/keys", {
|
|
114
118
|
method: "POST",
|
|
115
|
-
body: JSON.stringify({ name
|
|
119
|
+
body: JSON.stringify({ name })
|
|
116
120
|
});
|
|
117
121
|
console.log(`
|
|
118
122
|
API key created. Copy it now \u2014 it won't be shown again.
|
|
@@ -120,6 +124,7 @@ API key created. Copy it now \u2014 it won't be shown again.
|
|
|
120
124
|
console.log(` ${data.key}
|
|
121
125
|
`);
|
|
122
126
|
if (data.name) console.log(`Name: ${data.name}`);
|
|
127
|
+
console.log(`VESSELS_API_KEY=${data.key}`);
|
|
123
128
|
}
|
|
124
129
|
async function cmdKeysRevoke(id) {
|
|
125
130
|
await api(`/api/v1/keys/${id}`, { method: "DELETE" });
|
|
@@ -179,18 +184,72 @@ async function cmdWebhooksToggle(id, active) {
|
|
|
179
184
|
});
|
|
180
185
|
console.log(`Webhook ${data.endpoint.id} ${data.endpoint.active ? "enabled" : "disabled"}.`);
|
|
181
186
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
187
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
188
|
+
async function resolveVesselId(input) {
|
|
189
|
+
if (UUID_RE.test(input)) return input;
|
|
190
|
+
const data = await api("/api/v1/vessels?limit=200&archived=true");
|
|
191
|
+
const vessel = (data.vessels ?? []).find((v) => v.external_id === input);
|
|
192
|
+
if (!vessel) {
|
|
193
|
+
console.error(`Vessel not found: ${input}`);
|
|
194
|
+
process.exit(1);
|
|
186
195
|
}
|
|
196
|
+
return vessel.id;
|
|
197
|
+
}
|
|
198
|
+
async function cmdMessage(args) {
|
|
199
|
+
const flags = parseFlags(args);
|
|
200
|
+
if (!flags.vessel || !flags.message) {
|
|
201
|
+
console.error("Usage: vessels message --vessel <id> --message <text>");
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
const vesselId = await resolveVesselId(flags.vessel);
|
|
205
|
+
const since = new Date(Date.now() - 5e3).toISOString();
|
|
206
|
+
const data = await api(`/api/v1/vessels/${vesselId}/messages`, {
|
|
207
|
+
method: "POST",
|
|
208
|
+
body: JSON.stringify({ message: flags.message })
|
|
209
|
+
});
|
|
210
|
+
console.log(`
|
|
211
|
+
Sent.`);
|
|
212
|
+
console.log(` vessel_id ${vesselId}`);
|
|
213
|
+
console.log(` message_id ${data.message_id}`);
|
|
214
|
+
const logsData = await api(`/api/v1/webhooks/deliveries?since=${encodeURIComponent(since)}&limit=10`);
|
|
215
|
+
const deliveries = logsData.deliveries ?? [];
|
|
216
|
+
if (!deliveries.length) {
|
|
217
|
+
console.log("\nNo webhook deliveries \u2014 add an endpoint at vessels-two.vercel.app/settings/webhooks");
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
console.log(`
|
|
221
|
+
Webhook deliveries (${deliveries.length}):
|
|
222
|
+
`);
|
|
223
|
+
for (const d of deliveries) {
|
|
224
|
+
const ok = d.response_status !== null && d.response_status >= 200 && d.response_status < 300;
|
|
225
|
+
const icon = ok ? "\u2713" : "\u2717";
|
|
226
|
+
const status = d.response_status ?? "no response";
|
|
227
|
+
const url = d.endpoint_url ?? "(deleted endpoint)";
|
|
228
|
+
const retry = d.attempt > 1 ? ` \xB7 attempt ${d.attempt}` : "";
|
|
229
|
+
const time = new Date(d.delivered_at).toLocaleTimeString([], { timeStyle: "medium" });
|
|
230
|
+
console.log(` ${icon} ${status} ${url}`);
|
|
231
|
+
console.log(` ${d.event_type}${retry} \xB7 ${time}`);
|
|
232
|
+
if (d.response_body) {
|
|
233
|
+
const body = d.response_body.length > 300 ? d.response_body.slice(0, 300) + "\u2026" : d.response_body;
|
|
234
|
+
console.log(`
|
|
235
|
+
${body.split("\n").join("\n ")}`);
|
|
236
|
+
}
|
|
237
|
+
console.log();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function cmdPush(args) {
|
|
241
|
+
const flags = parseFlags(args);
|
|
187
242
|
const apiKey = flags.key ?? process.env.VESSELS_API_KEY;
|
|
188
243
|
if (!apiKey) {
|
|
189
244
|
console.error("Provide an API key via --key or VESSELS_API_KEY env var");
|
|
190
245
|
process.exit(1);
|
|
191
246
|
}
|
|
192
|
-
|
|
193
|
-
|
|
247
|
+
if (!flags.message) {
|
|
248
|
+
console.error("Usage: vessels push --vessel <id> --message <text> --key <api_key>");
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
const message = flags.message;
|
|
252
|
+
const vessel = flags.vessel ?? void 0;
|
|
194
253
|
const res = await fetch(`${BASE_URL}/api/v1/push`, {
|
|
195
254
|
method: "POST",
|
|
196
255
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` },
|
|
@@ -215,7 +274,7 @@ Commands:
|
|
|
215
274
|
vessels whoami
|
|
216
275
|
|
|
217
276
|
vessels keys list
|
|
218
|
-
vessels keys create [name]
|
|
277
|
+
vessels keys create [--name <name>]
|
|
219
278
|
vessels keys revoke <id>
|
|
220
279
|
|
|
221
280
|
vessels webhooks list
|
|
@@ -227,11 +286,15 @@ Commands:
|
|
|
227
286
|
vessels push --vessel <id> --message <text> --key <api_key>
|
|
228
287
|
(--key can be omitted if VESSELS_API_KEY is set)
|
|
229
288
|
|
|
289
|
+
vessels message --vessel <id> --message <text>
|
|
290
|
+
Send a message as the logged-in user and print webhook delivery logs.
|
|
291
|
+
Accepts vessel UUID or external_id (e.g. booking-123).
|
|
292
|
+
|
|
230
293
|
Agent/Claude Code setup (fully non-interactive):
|
|
231
294
|
vessels login --email me@example.com
|
|
232
295
|
# tell your agent the OTP from the email
|
|
233
296
|
vessels login --email me@example.com --otp 847293
|
|
234
|
-
vessels keys create my-project
|
|
297
|
+
vessels keys create --name my-project
|
|
235
298
|
vessels webhooks create --url https://myapp.com/hooks/vessels
|
|
236
299
|
`;
|
|
237
300
|
async function main() {
|
|
@@ -244,7 +307,7 @@ async function main() {
|
|
|
244
307
|
if (cmd === "whoami") return cmdWhoami();
|
|
245
308
|
if (cmd === "keys") {
|
|
246
309
|
if (sub === "list" || !sub) return cmdKeysList();
|
|
247
|
-
if (sub === "create") return cmdKeysCreate(rest
|
|
310
|
+
if (sub === "create") return cmdKeysCreate(rest);
|
|
248
311
|
if (sub === "revoke") {
|
|
249
312
|
if (!rest[0]) {
|
|
250
313
|
console.error("Usage: vessels keys revoke <id>");
|
|
@@ -252,6 +315,9 @@ async function main() {
|
|
|
252
315
|
}
|
|
253
316
|
return cmdKeysRevoke(rest[0]);
|
|
254
317
|
}
|
|
318
|
+
console.error(`Unknown subcommand: keys ${sub}
|
|
319
|
+
Run: vessels help`);
|
|
320
|
+
process.exit(1);
|
|
255
321
|
}
|
|
256
322
|
if (cmd === "webhooks") {
|
|
257
323
|
if (sub === "list" || !sub) return cmdWebhooksList();
|
|
@@ -277,8 +343,12 @@ async function main() {
|
|
|
277
343
|
}
|
|
278
344
|
return cmdWebhooksToggle(rest[0], false);
|
|
279
345
|
}
|
|
346
|
+
console.error(`Unknown subcommand: webhooks ${sub}
|
|
347
|
+
Run: vessels help`);
|
|
348
|
+
process.exit(1);
|
|
280
349
|
}
|
|
281
350
|
if (cmd === "push") return cmdPush([sub, ...rest].filter(Boolean));
|
|
351
|
+
if (cmd === "message") return cmdMessage([sub, ...rest].filter(Boolean));
|
|
282
352
|
console.error(`Unknown command: ${cmd}
|
|
283
353
|
Run: vessels help`);
|
|
284
354
|
process.exit(1);
|