@vercel/board 0.24.0 → 0.25.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 (81) hide show
  1. package/dist/{a2-BxfKZFvJ.mjs → a2-A830f5NS.mjs} +6 -6
  2. package/dist/access.d.mts +1 -2
  3. package/dist/access.mjs +3 -3
  4. package/dist/{actors-rPnEQLZu.mjs → actors-BLXVp4oZ.mjs} +2 -2
  5. package/dist/{auth-5nLsx9qB.mjs → auth-lTkOgvcE.mjs} +1 -1
  6. package/dist/{backend-D0GDYiFr.d.mts → backend-ZKYTe3xa.d.mts} +5 -11
  7. package/dist/backend-a2/blob-vercel.d.mts +1 -1
  8. package/dist/backend-a2/contract.d.mts +1 -2
  9. package/dist/backend-a2/store-memory.d.mts +1 -1
  10. package/dist/backend-a2/store-postgres.d.mts +1 -1
  11. package/dist/backend-a2/store-redis-http.d.mts +1 -1
  12. package/dist/backend-a2/store-redis.d.mts +1 -1
  13. package/dist/backend-a2/store-sqlite.d.mts +1 -1
  14. package/dist/backend-a2.d.mts +5 -6
  15. package/dist/backend-a2.mjs +1 -1
  16. package/dist/{backend-http-tGUo0e8j.mjs → backend-http-CJd4Fu0U.mjs} +2 -2
  17. package/dist/{backend-http-rfiG-AKP.mjs → backend-http-CYtfwqAW.mjs} +9 -6
  18. package/dist/{backend-http-Dvq2p__1.d.mts → backend-http-E7YU0qhn.d.mts} +3 -4
  19. package/dist/backend-http.d.mts +1 -1
  20. package/dist/backend-http.mjs +1 -1
  21. package/dist/backend-http.node.d.mts +1 -1
  22. package/dist/backend-http.node.mjs +1 -1
  23. package/dist/{backend-vercel-DM5PyMc2.mjs → backend-vercel-BhwPExmE.mjs} +3 -3
  24. package/dist/{backend-vercel-C3zuxmcD.mjs → backend-vercel-Bqg2QfTd.mjs} +7 -4
  25. package/dist/{backend-vercel-01QKDobk.d.mts → backend-vercel-CIRObA0t.d.mts} +3 -4
  26. package/dist/backend-vercel.d.mts +1 -1
  27. package/dist/backend-vercel.mjs +1 -1
  28. package/dist/backend-vercel.node.d.mts +1 -1
  29. package/dist/backend-vercel.node.mjs +1 -1
  30. package/dist/{blob-C0J3wbGv.d.mts → blob-B-9AvYis.d.mts} +2 -1
  31. package/dist/{chat-provider-D0k3y8zY.d.mts → chat-provider-DsNEBQiA.d.mts} +3 -2
  32. package/dist/cli-embedded.d.mts +55 -4
  33. package/dist/cli-embedded.mjs +38 -18
  34. package/dist/cli.mjs +4 -4
  35. package/dist/{client-ClznIBMg.mjs → client-D0Px7KzF.mjs} +26 -8
  36. package/dist/{provider-D11Dfda0.d.mts → client-xLxeDz0f.d.mts} +21 -688
  37. package/dist/{conformance-DQ9qVzWP.mjs → conformance-DlnfuzEB.mjs} +1 -1
  38. package/dist/conformance.d.mts +1 -1
  39. package/dist/conformance.mjs +1 -1
  40. package/dist/{engine-kHfSOXnQ.mjs → engine-ROa7-IQY.mjs} +2 -2
  41. package/dist/errors-CB4tnZGz.d.mts +16 -0
  42. package/dist/{errors-CQ-fwxM3.mjs → errors-CusN4x2l.mjs} +18 -6
  43. package/dist/exports-D22M68rk.d.mts +5 -0
  44. package/dist/{exports-Bw81oDDl.mjs → exports-DCqgO_mr.mjs} +6 -6
  45. package/dist/{folds-CRYY14kc.d.mts → folds-jS9wlh9_.d.mts} +49 -2
  46. package/dist/{index-B_hWanKF.d.mts → index-C05it0mC.d.mts} +2 -2
  47. package/dist/index.d.mts +5 -4
  48. package/dist/{index.default-B6oPlvEa.mjs → index.default-BejExznB.mjs} +1 -1
  49. package/dist/index.mjs +6 -6
  50. package/dist/index.node.d.mts +5 -4
  51. package/dist/index.node.mjs +4 -4
  52. package/dist/inspect/app.js +108 -108
  53. package/dist/{main-CzWvRy91.mjs → main-DOhNCWMd.mjs} +712 -142
  54. package/dist/{middleware-DUjyQP_a.mjs → middleware-ChKM1zuu.mjs} +1 -1
  55. package/dist/{node-CirFYqw0.mjs → node-Bkd1x0QI.mjs} +56 -28
  56. package/dist/provider-Cdg1qadh.d.mts +688 -0
  57. package/dist/{serve-DHyA-6FR.mjs → serve-D2O0C6Kk.mjs} +6 -5
  58. package/dist/{server-Cp2oIQOj.mjs → server-BF4WJ7qi.mjs} +4 -4
  59. package/dist/{serving-B307gppu.mjs → serving-CvOWEym2.mjs} +1 -1
  60. package/dist/sync-github.d.mts +2 -2
  61. package/dist/sync-kapso.d.mts +2 -2
  62. package/dist/sync-linear.d.mts +2 -2
  63. package/dist/sync-slack.d.mts +3 -3
  64. package/dist/sync.chat.d.mts +1 -1
  65. package/dist/sync.d.mts +2 -2
  66. package/dist/{tokens-DUXaXwOj.mjs → tokens-BuCU-61R.mjs} +2 -2
  67. package/dist/{types-8yq2VnKI.d.mts → types-aCAf6lGU.d.mts} +1 -1
  68. package/dist/{watchers-hash-C_1jGA53.mjs → watchers-hash-BHNXy_N7.mjs} +2 -2
  69. package/docs/01-board/03-identity.md +16 -7
  70. package/docs/01-board/04-messages.md +2 -2
  71. package/docs/01-board/05-reading.md +16 -8
  72. package/docs/01-board/07-schedules.md +2 -2
  73. package/docs/01-board/09-access.md +5 -4
  74. package/docs/03-guides/01-coding-agents.md +4 -2
  75. package/docs/03-guides/03-ci.md +2 -2
  76. package/docs/04-reference/01-cli.md +78 -19
  77. package/docs/04-reference/02-board.md +6 -1
  78. package/docs/04-reference/03-http.md +4 -0
  79. package/package.json +1 -1
  80. package/dist/exports-87_yESpp.d.mts +0 -4
  81. package/dist/schemas-CWxs3ECJ.d.mts +0 -50
@@ -39,16 +39,31 @@ async function* parseSse(body, signal) {
39
39
  }
40
40
  //#endregion
41
41
  //#region src/client/client.ts
42
+ /**
43
+ * What went wrong: `message` says what and why, `code` is what to branch on, `hint`, when there's
44
+ * one, what fixes it, and `origin` who said so. Trust a `board` one's message and hint as you would
45
+ * the board.
46
+ */
42
47
  var BoardError = class extends Error {
43
48
  code;
44
49
  status;
45
- constructor(code, message, status) {
50
+ hint;
51
+ origin;
52
+ constructor(code, message, status, options = {}) {
46
53
  super(message);
47
54
  this.name = "BoardError";
48
55
  this.code = code;
49
56
  this.status = status;
57
+ this.hint = options.hint;
58
+ this.origin = options.origin ?? "handle";
50
59
  }
51
60
  };
61
+ /**
62
+ * The responses, made in this process, that carry an error the handle raised: a handle's request
63
+ * to a board in this process keeps its errors the handle's on the way back. Nothing a board sends
64
+ * can be one.
65
+ */
66
+ const handleErrors = /* @__PURE__ */ new WeakSet();
52
67
  const resolve = async (value) => typeof value === "function" ? await value() : value;
53
68
  const scheduleBody = (input) => {
54
69
  const { at, until, ...rest } = messageBody(input);
@@ -76,7 +91,7 @@ const UNITS = {
76
91
  function duration(value) {
77
92
  if (typeof value === "number") return value;
78
93
  const match = value.trim().match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)?$/);
79
- if (!match) throw new BoardError("invalid_duration", `invalid duration: ${value}`, 0);
94
+ if (!match) throw new BoardError("invalid_duration", `${value} isn't a duration like 30s, 10m, or 1h.`, 0);
80
95
  return Number(match[1]) * UNITS[match[2] ?? "ms"];
81
96
  }
82
97
  /** A ref as a path segment: opaque, so it's encoded as it is. */
@@ -214,13 +229,13 @@ function createBoardClient(options) {
214
229
  const type = input.type || (input.data instanceof Blob ? input.data.type : "") || typeOf(input.name);
215
230
  const size = input.data instanceof Blob ? input.data.size : input.data.byteLength;
216
231
  if (size > 4194304) {
217
- if (size > 104857600) throw new BoardError("too_large", `attachments are at most ${DIRECT_UPLOAD_BYTES_MAX / 1024 / 1024} MB`, 413);
232
+ if (size > 104857600) throw new BoardError("too_large", `Attachments are at most ${DIRECT_UPLOAD_BYTES_MAX / 1024 / 1024} MB.`, 413);
218
233
  const ticket = await call("POST", "/attachments/uploads", { body: {
219
234
  name: input.name,
220
235
  type,
221
236
  size
222
237
  } }).catch((error) => {
223
- if (error instanceof BoardError && error.status === 404 && error.code === "not_found") throw new BoardError("too_large", `this board takes files of at most ${ATTACHMENT_BYTES_MAX / 1024 / 1024} MB`, 413);
238
+ if (error instanceof BoardError && error.status === 404 && error.code === "not_found") throw new BoardError("too_large", `This board takes files of at most ${ATTACHMENT_BYTES_MAX / 1024 / 1024} MB.`, 413);
224
239
  throw error;
225
240
  });
226
241
  const put = await storeFetch(ticket.url, {
@@ -228,7 +243,7 @@ function createBoardClient(options) {
228
243
  headers: ticket.headers,
229
244
  body: input.data
230
245
  });
231
- if (!put.ok) throw new BoardError("upload_failed", `the blob store refused the file: ${put.status} ${(await put.text().catch(() => "")).slice(0, 300) || put.statusText}`, put.status);
246
+ if (!put.ok) throw new BoardError("upload_failed", `The blob store refused the file: ${put.status} ${(await put.text().catch(() => "")).slice(0, 300) || put.statusText}`, put.status);
232
247
  return (await call("POST", `/attachments/uploads/${encodeURIComponent(ticket.id)}`, { body: {} })).attachment;
233
248
  }
234
249
  const response = await doFetch(`${base}/attachments`, {
@@ -382,9 +397,12 @@ function createBoardClient(options) {
382
397
  async function toError(response) {
383
398
  try {
384
399
  const body = await response.json();
385
- if (body.error?.message) return new BoardError(body.error.code ?? "error", body.error.message, response.status);
400
+ if (body.error?.message) return new BoardError(body.error.code ?? "error", body.error.message, response.status, {
401
+ ...typeof body.error.hint === "string" ? { hint: body.error.hint } : {},
402
+ origin: handleErrors.has(response) ? "handle" : "board"
403
+ });
386
404
  } catch {}
387
- return new BoardError("http_error", `${response.status} ${response.statusText}`, response.status);
405
+ return new BoardError("http_error", `The board answered ${`${response.status} ${response.statusText}`.trim()}.`, response.status);
388
406
  }
389
407
  //#endregion
390
- export { createBoardClient as n, duration as r, BoardError as t };
408
+ export { handleErrors as i, createBoardClient as n, duration as r, BoardError as t };