@pidgeon-ai/cli 1.0.1 → 1.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PCN Labs OÜ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  COMMANDS,
4
4
  __export
5
- } from "./chunk-75GJTRBD.js";
5
+ } from "./chunk-K5E2QAJE.js";
6
6
 
7
7
  // ../sdk/dist/index.js
8
8
  var dist_exports = {};
@@ -49,6 +49,7 @@ __export(dist_exports, {
49
49
  draftsUpdate: () => draftsUpdate,
50
50
  eventsGet: () => eventsGet,
51
51
  eventsList: () => eventsList,
52
+ eventsStream: () => eventsStream,
52
53
  identitiesAccessCreate: () => identitiesAccessCreate,
53
54
  identitiesAccessDelete: () => identitiesAccessDelete,
54
55
  identitiesAccessGet: () => identitiesAccessGet,
@@ -77,6 +78,7 @@ __export(dist_exports, {
77
78
  mailboxesEmptyTrash: () => mailboxesEmptyTrash,
78
79
  mailboxesList: () => mailboxesList,
79
80
  mailboxesListFolder: () => mailboxesListFolder,
81
+ meGet: () => meGet,
80
82
  messagesAct: () => messagesAct,
81
83
  messagesForward: () => messagesForward,
82
84
  messagesGet: () => messagesGet,
@@ -94,6 +96,7 @@ __export(dist_exports, {
94
96
  routingDelete: () => routingDelete,
95
97
  routingList: () => routingList,
96
98
  routingUpdate: () => routingUpdate,
99
+ streamEvents: () => streamEvents,
97
100
  threadsGet: () => threadsGet,
98
101
  threadsLabelsCreate: () => threadsLabelsCreate,
99
102
  threadsLabelsDelete: () => threadsLabelsDelete,
@@ -155,7 +158,7 @@ function createSseClient({
155
158
  ...options
156
159
  }) {
157
160
  let lastEventId;
158
- const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
161
+ const sleep2 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
159
162
  const createStream = async function* () {
160
163
  let retryDelay = sseDefaultRetryDelay ?? 3e3;
161
164
  let attempt = 0;
@@ -259,7 +262,7 @@ function createSseClient({
259
262
  break;
260
263
  }
261
264
  const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
262
- await sleep(backoff);
265
+ await sleep2(backoff);
263
266
  }
264
267
  }
265
268
  };
@@ -1085,7 +1088,7 @@ var messagesSend = (options) => (options.client ?? client).post({
1085
1088
  ...options.headers
1086
1089
  }
1087
1090
  });
1088
- var messagesSearch = (options) => (options.client ?? client).get({
1091
+ var messagesSearch = (options) => (options?.client ?? client).get({
1089
1092
  security: [{ scheme: "bearer", type: "http" }],
1090
1093
  url: "/messages/search",
1091
1094
  ...options
@@ -1321,6 +1324,11 @@ var appPasswordsRevoke = (options) => (options.client ?? client).delete({
1321
1324
  url: "/app-passwords/{id}",
1322
1325
  ...options
1323
1326
  });
1327
+ var meGet = (options) => (options?.client ?? client).get({
1328
+ security: [{ scheme: "bearer", type: "http" }],
1329
+ url: "/me",
1330
+ ...options
1331
+ });
1324
1332
  var workspaceGet = (options) => (options?.client ?? client).get({
1325
1333
  security: [{ scheme: "bearer", type: "http" }],
1326
1334
  url: "/workspace",
@@ -1336,6 +1344,11 @@ var eventsList = (options) => (options?.client ?? client).get({
1336
1344
  url: "/events",
1337
1345
  ...options
1338
1346
  });
1347
+ var eventsStream = (options) => (options?.client ?? client).sse.get({
1348
+ security: [{ scheme: "bearer", type: "http" }],
1349
+ url: "/events/stream",
1350
+ ...options
1351
+ });
1339
1352
  var eventsGet = (options) => (options.client ?? client).get({
1340
1353
  security: [{ scheme: "bearer", type: "http" }],
1341
1354
  url: "/events/{id}",
@@ -1555,7 +1568,16 @@ var attachmentsDownloadUrl = (options) => (options.client ?? client).get({
1555
1568
  var SIGNATURE_HEADER = "x-pidgeon-signature";
1556
1569
  var TIMESTAMP_HEADER = "x-pidgeon-timestamp";
1557
1570
  async function verifyWebhook(input) {
1558
- const get = (name) => input.headers instanceof Headers ? input.headers.get(name) ?? void 0 : input.headers[name] ?? input.headers[name.toLowerCase()];
1571
+ const get = (name) => {
1572
+ if (input.headers instanceof Headers) return input.headers.get(name) ?? void 0;
1573
+ const direct = input.headers[name];
1574
+ if (direct !== void 0) return direct;
1575
+ const wanted = name.toLowerCase();
1576
+ for (const [key2, value] of Object.entries(input.headers)) {
1577
+ if (key2.toLowerCase() === wanted) return value;
1578
+ }
1579
+ return void 0;
1580
+ };
1559
1581
  const timestamp = get(TIMESTAMP_HEADER);
1560
1582
  const signature = get(SIGNATURE_HEADER);
1561
1583
  if (!timestamp || !signature) throw new Error("This request is not signed.");
@@ -1592,6 +1614,103 @@ function constantTimeEqual(a, b) {
1592
1614
  }
1593
1615
  return difference === 0;
1594
1616
  }
1617
+ async function* streamEvents(options) {
1618
+ const base = (options.baseUrl ?? "https://pidgeon.ai/api/v1").replace(/\/$/, "");
1619
+ let lastEventId;
1620
+ let backoffMs = 1e3;
1621
+ while (!options.signal?.aborted) {
1622
+ const url = new URL(`${base}/events/stream`);
1623
+ if (options.identityId) url.searchParams.set("identity_id", options.identityId);
1624
+ if (options.type) url.searchParams.set("type", options.type);
1625
+ if (options.after && !lastEventId) url.searchParams.set("after", options.after);
1626
+ let response;
1627
+ try {
1628
+ response = await fetch(url, {
1629
+ headers: {
1630
+ authorization: `Bearer ${options.apiKey}`,
1631
+ accept: "text/event-stream",
1632
+ ...lastEventId ? { "last-event-id": lastEventId } : {}
1633
+ },
1634
+ signal: options.signal
1635
+ });
1636
+ } catch {
1637
+ if (options.signal?.aborted) return;
1638
+ await sleep(backoffMs, options.signal);
1639
+ backoffMs = Math.min(backoffMs * 2, 3e4);
1640
+ continue;
1641
+ }
1642
+ if (response.status === 401 || response.status === 403 || response.status === 404) {
1643
+ throw new Error(
1644
+ `Pidgeon refused the stream: ${response.status} ${await response.text().catch(() => "")}`.trim()
1645
+ );
1646
+ }
1647
+ if (!response.ok || !response.body) {
1648
+ await sleep(backoffMs, options.signal);
1649
+ backoffMs = Math.min(backoffMs * 2, 3e4);
1650
+ continue;
1651
+ }
1652
+ backoffMs = 1e3;
1653
+ for await (const frame of frames(response.body, options.signal)) {
1654
+ if (frame.id) lastEventId = frame.id;
1655
+ if (!frame.data) continue;
1656
+ if (frame.event === "error") continue;
1657
+ let parsed;
1658
+ try {
1659
+ parsed = JSON.parse(frame.data);
1660
+ } catch {
1661
+ continue;
1662
+ }
1663
+ yield parsed;
1664
+ }
1665
+ }
1666
+ }
1667
+ async function* frames(body, signal) {
1668
+ const reader = body.getReader();
1669
+ const decoder = new TextDecoder();
1670
+ let buffer = "";
1671
+ try {
1672
+ while (!signal?.aborted) {
1673
+ const { done, value } = await reader.read();
1674
+ if (done) return;
1675
+ buffer += decoder.decode(value, { stream: true });
1676
+ let boundary = buffer.indexOf("\n\n");
1677
+ while (boundary !== -1) {
1678
+ const block = buffer.slice(0, boundary);
1679
+ buffer = buffer.slice(boundary + 2);
1680
+ boundary = buffer.indexOf("\n\n");
1681
+ const frame = {};
1682
+ const data = [];
1683
+ for (const line of block.split("\n")) {
1684
+ if (line.startsWith(":")) continue;
1685
+ const colon = line.indexOf(":");
1686
+ if (colon === -1) continue;
1687
+ const field = line.slice(0, colon);
1688
+ const value2 = line.slice(colon + 1).replace(/^ /, "");
1689
+ if (field === "id") frame.id = value2;
1690
+ else if (field === "event") frame.event = value2;
1691
+ else if (field === "data") data.push(value2);
1692
+ }
1693
+ if (data.length > 0) frame.data = data.join("\n");
1694
+ if (frame.id || frame.data) yield frame;
1695
+ }
1696
+ }
1697
+ } finally {
1698
+ await reader.cancel().catch(() => void 0);
1699
+ }
1700
+ }
1701
+ function sleep(ms, signal) {
1702
+ return new Promise((resolve) => {
1703
+ const timer = setTimeout(resolve, ms);
1704
+ signal?.addEventListener(
1705
+ "abort",
1706
+ () => {
1707
+ clearTimeout(timer);
1708
+ resolve();
1709
+ },
1710
+ { once: true }
1711
+ );
1712
+ });
1713
+ }
1595
1714
 
1596
1715
  // src/index.ts
1597
1716
  var DEFAULT_BASE_URL = "https://pidgeon.ai/api/v1";
@@ -1726,4 +1845,4 @@ export {
1726
1845
  find,
1727
1846
  run
1728
1847
  };
1729
- //# sourceMappingURL=chunk-VCNNUD25.js.map
1848
+ //# sourceMappingURL=chunk-IU5VSUXX.js.map