@vercel/board 0.25.1 → 0.26.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 (42) hide show
  1. package/dist/{a2-A830f5NS.mjs → a2-C4A4vr0M.mjs} +4 -4
  2. package/dist/{attempts-CLG840Oj.mjs → attempts-HXcskN1w.mjs} +1 -11
  3. package/dist/backend-a2.mjs +1 -1
  4. package/dist/{backend-http-CYtfwqAW.mjs → backend-http-3IxGe13a.mjs} +18 -4
  5. package/dist/{backend-http-CJd4Fu0U.mjs → backend-http-CQWTNzym.mjs} +2 -2
  6. package/dist/backend-http.mjs +1 -1
  7. package/dist/backend-http.node.mjs +1 -1
  8. package/dist/{backend-vercel-Bqg2QfTd.mjs → backend-vercel-BPyPi8Cv.mjs} +24 -6
  9. package/dist/{backend-vercel-BhwPExmE.mjs → backend-vercel-l5465vyw.mjs} +3 -3
  10. package/dist/backend-vercel.mjs +1 -1
  11. package/dist/backend-vercel.node.d.mts +5 -0
  12. package/dist/backend-vercel.node.mjs +2 -2
  13. package/dist/cli-commands.d.mts +1 -1
  14. package/dist/cli-commands.mjs +1 -1
  15. package/dist/cli-embedded.d.mts +5 -1
  16. package/dist/cli-embedded.mjs +8 -4
  17. package/dist/cli.mjs +4 -4
  18. package/dist/{commands-D0wXq6CY.d.mts → commands-D6gvrOh3.d.mts} +4 -4
  19. package/dist/{commands-BtL4jFq8.mjs → commands-nEG47RM_.mjs} +7 -7
  20. package/dist/{engine-ROa7-IQY.mjs → engine-Bfe6pcXb.mjs} +2 -2
  21. package/dist/{exports-DCqgO_mr.mjs → exports-B-AeCbYw.mjs} +2 -2
  22. package/dist/{index.default-BejExznB.mjs → index.default-CfAjbQrU.mjs} +1 -1
  23. package/dist/index.mjs +3 -3
  24. package/dist/index.node.mjs +1 -1
  25. package/dist/inspect/app.js +29 -29
  26. package/dist/inspect/engine.js +5 -5
  27. package/dist/{main-DOhNCWMd.mjs → main-DGyQ4gje.mjs} +24 -9
  28. package/dist/{node-Bkd1x0QI.mjs → node-Ybi9E6bO.mjs} +67 -37
  29. package/dist/{serve-D2O0C6Kk.mjs → serve-BDLJebk7.mjs} +3 -3
  30. package/dist/{server-BF4WJ7qi.mjs → server-BSXTDTOp.mjs} +3 -3
  31. package/dist/{ids-C6AYo1bu.mjs → wait-until-Dw4XrIDQ.mjs} +12 -1
  32. package/dist/{watchers-hash-BHNXy_N7.mjs → watchers-hash-BTF_bMIN.mjs} +4 -4
  33. package/docs/01-board/04-messages.md +1 -1
  34. package/docs/01-board/05-reading.md +2 -2
  35. package/docs/01-board/06-watchers.md +7 -5
  36. package/docs/02-sync/01-overview.md +2 -2
  37. package/docs/03-guides/03-ci.md +2 -2
  38. package/docs/03-guides/04-triage.md +5 -5
  39. package/docs/04-reference/01-cli.md +10 -4
  40. package/docs/04-reference/03-http.md +1 -1
  41. package/docs/index.md +2 -2
  42. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
1
  import { n as DIRECT_UPLOAD_BYTES_MAX, r as IMPORT_BYTES_MAX, t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
2
2
  import { _ as RemoteWatcherId, b as actorKind, i as Attachment, x as platformAvatar } from "./schemas-Be08nyfW.mjs";
3
3
  import "./external-BV_cUncs.mjs";
4
- import { a as METHODS, d as VERSION, f as SYNC, n as compileWatcher, r as hasCriteria, t as canonicalWatchers } from "./watchers-hash-BHNXy_N7.mjs";
4
+ import { a as METHODS, d as VERSION, f as SYNC, n as compileWatcher, r as hasCriteria, t as canonicalWatchers } from "./watchers-hash-BTF_bMIN.mjs";
5
5
  import { r as duration, t as BoardError } from "./client-D0Px7KzF.mjs";
6
- import { n as derivedId, r as isKeyIdOf } from "./ids-C6AYo1bu.mjs";
6
+ import { i as isKeyIdOf, r as derivedId, t as waitUntil } from "./wait-until-Dw4XrIDQ.mjs";
7
7
  import { a as forbidden, c as toErrorResponse, i as duplicateId, r as badRequest, s as notFound, t as HttpError } from "./errors-CusN4x2l.mjs";
8
8
  import { t as own } from "./own-OwgPWdmh.mjs";
9
9
  import { n as replaceMentions } from "./mentions-CB6ShY4R.mjs";
@@ -18,7 +18,7 @@ import { n as createServer, t as consumer } from "./server-DtFrWxi3-Boa6gdWO.mjs
18
18
  import { a as linkedTo, i as iso, n as foldMessages, o as personOf, t as foldActors } from "./folds-Dyjput8M.mjs";
19
19
  import { t as concernedMessageId } from "./project-DMDST9kl.mjs";
20
20
  import { t as TABLES_CONSUMER } from "./sql-U9WTxrwJ.mjs";
21
- import { n as waitUntil, t as afterRetry } from "./attempts-CLG840Oj.mjs";
21
+ import { t as afterRetry } from "./attempts-HXcskN1w.mjs";
22
22
  import { createHash, randomBytes } from "node:crypto";
23
23
  import { mkdir, readFile, writeFile } from "node:fs/promises";
24
24
  import { dirname, join } from "node:path";
@@ -2467,7 +2467,7 @@ function scheduleAt(value) {
2467
2467
  return index;
2468
2468
  }
2469
2469
  new AbortController().signal;
2470
- /** A wake-up only has to arrive: the board it wakes runs what it pulls before it answers. */
2470
+ /** A wake-up only has to arrive: the board it wakes answers once what it pulls has run, or after 2 seconds while it keeps going. */
2471
2471
  const WAKE_TIMEOUT_MS = 5e3;
2472
2472
  /**
2473
2473
  * `idempotentId`'s shape, a UUIDv8: the IDs the board derives for its own writes (schedule
@@ -1,13 +1,3 @@
1
- //#region src/server/wait-until.ts
2
- /**
3
- * Keeps `task` running after the response, where the platform offers it: Vercel's request context, as A2
4
- * reads it too. Elsewhere it runs on in the process.
5
- */
6
- function waitUntil(task) {
7
- try {
8
- Reflect.get(globalThis, Symbol.for("@vercel/request-context"))?.get?.()?.waitUntil?.(task);
9
- } catch {}
10
- }
11
1
  /**
12
2
  * Whether a run comes after a retry from a dead letter. A2 keeps counting
13
3
  * `ctx.attempt` across one, and no earlier run sees an attempt past A2_TRIES:
@@ -17,4 +7,4 @@ function waitUntil(task) {
17
7
  */
18
8
  const afterRetry = (attempt) => attempt > 10;
19
9
  //#endregion
20
- export { waitUntil as n, afterRetry as t };
10
+ export { afterRetry as t };
@@ -1,2 +1,2 @@
1
- import { n as fsBlob, r as memoryBlob, t as a2 } from "./a2-A830f5NS.mjs";
1
+ import { n as fsBlob, r as memoryBlob, t as a2 } from "./a2-C4A4vr0M.mjs";
2
2
  export { a2, fsBlob, memoryBlob };
@@ -1,14 +1,16 @@
1
1
  import "./files-SniSmeEr.mjs";
2
2
  import "./schemas-Be08nyfW.mjs";
3
- import { K as routes, O as RegisterBody, a as METHODS, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-BHNXy_N7.mjs";
3
+ import { K as routes, O as RegisterBody, a as METHODS, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-BTF_bMIN.mjs";
4
4
  import { n as createBoardClient, t as BoardError } from "./client-D0Px7KzF.mjs";
5
- import { a as sha256, i as keyId, n as derivedId, t as DERIVED_ID } from "./ids-C6AYo1bu.mjs";
5
+ import { a as keyId, n as DERIVED_ID, o as sha256, r as derivedId, t as waitUntil } from "./wait-until-Dw4XrIDQ.mjs";
6
6
  import { a as forbidden, o as json, t as HttpError } from "./errors-CusN4x2l.mjs";
7
7
  //#region src/server/registrant.ts
8
8
  /** Registering again this soon after the same registration only repeats it. */
9
9
  const REGISTER_EVERY_MS = 1e4;
10
10
  /** How long one wake-up runs matches before it leaves the rest to the next. */
11
11
  const DRAIN_MS = 24e4;
12
+ /** How long a wake-up waits for what it pulled to run before it answers: under the 3 seconds Vercel's API gives it. */
13
+ const WAKE_ANSWER_MS = 2e3;
12
14
  /** A pull with nothing to hand out holds this long, when the board pulls on its own. */
13
15
  const POLL_WAIT_S = 25;
14
16
  const describe$1 = (error) => ((error instanceof Error ? error.message : String(error)) || "unknown error").slice(0, 500);
@@ -142,8 +144,20 @@ function registrant(options) {
142
144
  path: "/wake",
143
145
  async handle(request) {
144
146
  started ??= Promise.resolve();
145
- if (request.headers.get("x-board-watchers") !== await options.hash()) await register(wakeable(bound().url())).catch(rethrow);
146
- return json({ ran: await drain().catch(rethrow) });
147
+ const stale = request.headers.get("x-board-watchers") !== await options.hash();
148
+ const running = (async () => {
149
+ if (stale) await register(wakeable(bound().url()));
150
+ return drain();
151
+ })();
152
+ waitUntil(running.catch((error) => console.error(`[board] couldn't run what woke it:`, describe$1(error))));
153
+ let timer;
154
+ const waited = new Promise((resolve) => timer = setTimeout(() => resolve(null), WAKE_ANSWER_MS));
155
+ try {
156
+ const ran = await Promise.race([running.catch(rethrow), waited]);
157
+ return ran === null ? new Response(null, { status: 202 }) : json({ ran });
158
+ } finally {
159
+ clearTimeout(timer);
160
+ }
147
161
  }
148
162
  }, {
149
163
  method: "POST",
@@ -1,5 +1,5 @@
1
- import { r as createHttp } from "./backend-http-CYtfwqAW.mjs";
2
- import { n as connect, r as environmentProfile, t as boardUrl } from "./node-Bkd1x0QI.mjs";
1
+ import { r as createHttp } from "./backend-http-3IxGe13a.mjs";
2
+ import { n as connect, r as environmentProfile, t as boardUrl } from "./node-Ybi9E6bO.mjs";
3
3
  //#region src/backend-http/index.ts
4
4
  const environment = {
5
5
  url: boardUrl,
@@ -1,2 +1,2 @@
1
- import { t as http } from "./index.default-BejExznB.mjs";
1
+ import { t as http } from "./index.default-CfAjbQrU.mjs";
2
2
  export { http };
@@ -1,2 +1,2 @@
1
- import { t as http } from "./backend-http-CJd4Fu0U.mjs";
1
+ import { t as http } from "./backend-http-CQWTNzym.mjs";
2
2
  export { http };
@@ -1,6 +1,6 @@
1
1
  import { t as HttpError } from "./errors-CusN4x2l.mjs";
2
- import { o as vercelLogin, r as environmentProfile, s as vercelProjectFile } from "./node-Bkd1x0QI.mjs";
3
- import { t as createVercel } from "./backend-vercel-BhwPExmE.mjs";
2
+ import { c as vercelLogin, l as vercelProjectFile, o as loginHanded, r as environmentProfile } from "./node-Ybi9E6bO.mjs";
3
+ import { t as createVercel } from "./backend-vercel-l5465vyw.mjs";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import { decodeJwt } from "jose";
6
6
  import { getVercelOidcToken } from "@vercel/oidc";
@@ -9,7 +9,7 @@ import { getVercelOidcToken } from "@vercel/oidc";
9
9
  const deployed = () => process.env.VERCEL === "1" || !!process.env.VERCEL_OIDC_TOKEN;
10
10
  /**
11
11
  * A token Vercel's API takes: `VERCEL_TOKEN`, this deployment's OIDC token, or your Vercel login,
12
- * the one the Vercel CLI hands a CLI it runs (`VERCEL_AUTH_TOKEN`) or your `vercel login`.
12
+ * the one the CLI that runs board's hands it (`vercel board`'s) or your `vercel login`.
13
13
  */
14
14
  async function token() {
15
15
  if (process.env.VERCEL_TOKEN) return process.env.VERCEL_TOKEN;
@@ -25,10 +25,28 @@ async function token() {
25
25
  function credentialSource() {
26
26
  if (process.env.VERCEL_TOKEN) return "VERCEL_TOKEN";
27
27
  if (deployed()) return "Vercel OIDC";
28
- return process.env.VERCEL_AUTH_TOKEN ? "the Vercel CLI" : "vercel login";
28
+ return loginHanded() ? "the Vercel CLI" : "vercel login";
29
29
  }
30
- /** The team: `VERCEL_ORG_ID`, the one the deployment's OIDC token names, or the linked project's (the nearest `.vercel/project.json`). */
30
+ /** The team a CLI that runs board's resolves itself (`vercel board`'s), while one does. */
31
+ let handed = null;
32
+ /**
33
+ * Hands board the team to use when nothing names one (`--scope` still wins), resolved as the app
34
+ * resolves its own and asked for only when a request needs it. Null takes it back.
35
+ */
36
+ function handTeam(resolve) {
37
+ handed = resolve;
38
+ }
39
+ /**
40
+ * The team: the one a CLI that runs board's hands it, `VERCEL_ORG_ID`, the one the deployment's OIDC
41
+ * token names, or the linked project's (the nearest `.vercel/project.json`). A handed one that
42
+ * throws fails the request with what it threw: the app's own words, not an internal error.
43
+ */
31
44
  async function team() {
45
+ if (handed) try {
46
+ return await handed();
47
+ } catch (error) {
48
+ throw new HttpError(502, "no_team", error instanceof Error ? error.message : String(error), { origin: "handle" });
49
+ }
32
50
  if (process.env.VERCEL_ORG_ID) return process.env.VERCEL_ORG_ID;
33
51
  if (!process.env.VERCEL_TOKEN && deployed()) try {
34
52
  const owner = decodeJwt(await getVercelOidcToken()).owner_id;
@@ -63,4 +81,4 @@ function vercel(options = {}) {
63
81
  return createVercel(options, environment);
64
82
  }
65
83
  //#endregion
66
- export { vercel as n, credentialSource as t };
84
+ export { handTeam as n, vercel as r, credentialSource as t };
@@ -1,8 +1,8 @@
1
1
  import { _ as RemoteWatcherId } from "./schemas-Be08nyfW.mjs";
2
- import { O as RegisterBody, a as METHODS, d as VERSION, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-BHNXy_N7.mjs";
3
- import { a as sha256, n as derivedId } from "./ids-C6AYo1bu.mjs";
2
+ import { O as RegisterBody, a as METHODS, d as VERSION, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-BTF_bMIN.mjs";
3
+ import { o as sha256, r as derivedId } from "./wait-until-Dw4XrIDQ.mjs";
4
4
  import { a as forbidden, o as json, s as notFound, t as HttpError } from "./errors-CusN4x2l.mjs";
5
- import { a as wakePath, i as registrant, n as callerProfile, t as PROJECTS_OWN } from "./backend-http-CYtfwqAW.mjs";
5
+ import { a as wakePath, i as registrant, n as callerProfile, t as PROJECTS_OWN } from "./backend-http-3IxGe13a.mjs";
6
6
  //#region src/server/backend-vercel.ts
7
7
  const PROFILE = /^[A-Za-z][A-Za-z0-9-]{0,31}$/;
8
8
  const SESSION = /^[A-Za-z0-9_.:-]{1,128}$/;
@@ -1,4 +1,4 @@
1
- import { t as createVercel } from "./backend-vercel-BhwPExmE.mjs";
1
+ import { t as createVercel } from "./backend-vercel-l5465vyw.mjs";
2
2
  //#region src/backend-vercel/index.default.ts
3
3
  /**
4
4
  * Your team's board, in Vercel's API. Outside Node there's no environment to find credentials or
@@ -2,6 +2,11 @@ import { n as VercelOptions, t as VercelBackend } from "./backend-vercel-CIRObA0
2
2
  //#region src/backend-vercel/index.d.ts
3
3
  /** Where `token` comes from, in words: what `vb whoami` says. */
4
4
  export declare function credentialSource(): string;
5
+ /**
6
+ * Hands board the team to use when nothing names one (`--scope` still wins), resolved as the app
7
+ * resolves its own and asked for only when a request needs it. Null takes it back.
8
+ */
9
+ export declare function handTeam(resolve: (() => Promise<string | null>) | null): void;
5
10
  /**
6
11
  * Your team's board, in Vercel's API: this board keeps nothing, and reads and writes that one as
7
12
  * this deployment's project, or as you. Without `board`, the team's board; without `fetch`, it
@@ -1,2 +1,2 @@
1
- import { n as vercel, t as credentialSource } from "./backend-vercel-Bqg2QfTd.mjs";
2
- export { credentialSource, vercel };
1
+ import { n as handTeam, r as vercel, t as credentialSource } from "./backend-vercel-BPyPi8Cv.mjs";
2
+ export { credentialSource, handTeam, vercel };
@@ -1,2 +1,2 @@
1
- import { a as OptionName, c as globalOptions, d as options, f as usage, i as CliOption, l as groups, n as CliCommand, o as commands, r as CliExample, s as filters, t as CliArgument, u as option } from "./commands-D0wXq6CY.mjs";
1
+ import { a as OptionName, c as globalOptions, d as options, f as usage, i as CliOption, l as groups, n as CliCommand, o as commands, r as CliExample, s as filters, t as CliArgument, u as option } from "./commands-D6gvrOh3.mjs";
2
2
  export { CliArgument, CliCommand, CliExample, CliOption, OptionName, commands, filters, globalOptions, groups, option, options, usage };
@@ -1,2 +1,2 @@
1
- import { a as option, i as groups, n as filters, o as options, r as globalOptions, s as usage, t as commands } from "./commands-BtL4jFq8.mjs";
1
+ import { a as option, i as groups, n as filters, o as options, r as globalOptions, s as usage, t as commands } from "./commands-nEG47RM_.mjs";
2
2
  export { commands, filters, globalOptions, groups, option, options, usage };
@@ -60,7 +60,9 @@ export declare function commandWord(argv: string[]): string | undefined;
60
60
  *
61
61
  * A failure goes to `onError`, with whether the run asked for `--json`, to show as the app shows
62
62
  * its own, and a warning to `onWarning` (with `--json`, it's in the result). Without them, the CLI
63
- * prints its own on stderr.
63
+ * prints its own on stderr. `login` is the app's Vercel login and `team` the team it resolves
64
+ * (`--scope` still wins): board asks for each only when a request needs it, so help, a typo, or
65
+ * misuse never refreshes a login or looks a team up.
64
66
  */
65
67
  export declare function createApp(options: {
66
68
  appName: string;
@@ -68,6 +70,8 @@ export declare function createApp(options: {
68
70
  json: boolean;
69
71
  }) => void;
70
72
  onWarning?: (warning: Warning) => void;
73
+ login?: () => Promise<string>;
74
+ team?: () => Promise<string | null>;
71
75
  }): {
72
76
  run(args: string[]): Promise<number>;
73
77
  };
@@ -1,4 +1,4 @@
1
- import { a as commandLine, c as failureLines, i as mainWith, l as formatFailure, n as commandWord, o as exitCode, r as main, s as failureDocument, t as Failed } from "./main-DOhNCWMd.mjs";
1
+ import { a as commandLine, c as failureLines, i as mainWith, l as formatFailure, n as commandWord, o as exitCode, r as main, s as failureDocument, t as Failed } from "./main-DGyQ4gje.mjs";
2
2
  //#region src/cli/embedded.ts
3
3
  /**
4
4
  * Board's CLI as `appName` names it in help, usage, and errors (`vercel board`). With no board
@@ -9,16 +9,20 @@ import { a as commandLine, c as failureLines, i as mainWith, l as formatFailure,
9
9
  *
10
10
  * A failure goes to `onError`, with whether the run asked for `--json`, to show as the app shows
11
11
  * its own, and a warning to `onWarning` (with `--json`, it's in the result). Without them, the CLI
12
- * prints its own on stderr.
12
+ * prints its own on stderr. `login` is the app's Vercel login and `team` the team it resolves
13
+ * (`--scope` still wins): board asks for each only when a request needs it, so help, a typo, or
14
+ * misuse never refreshes a login or looks a team up.
13
15
  */
14
16
  function createApp(options) {
15
- const { appName, onError, onWarning } = options;
17
+ const { appName, onError, onWarning, login, team } = options;
16
18
  return { run: (args) => main(args, {
17
19
  name: appName,
18
20
  commands: {},
19
21
  teamBoard: true,
20
22
  ...onError ? { onError } : {},
21
- ...onWarning ? { onWarning } : {}
23
+ ...onWarning ? { onWarning } : {},
24
+ ...login ? { login } : {},
25
+ ...team ? { team } : {}
22
26
  }) };
23
27
  }
24
28
  const lacking = (what, option) => async () => {
package/dist/cli.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
3
3
  import "./schemas-Be08nyfW.mjs";
4
- import { a as option } from "./commands-BtL4jFq8.mjs";
5
- import { a as projectDir } from "./node-Bkd1x0QI.mjs";
6
- import { r as main, u as who } from "./main-DOhNCWMd.mjs";
4
+ import { a as option } from "./commands-nEG47RM_.mjs";
5
+ import { s as projectDir } from "./node-Ybi9E6bO.mjs";
6
+ import { r as main, u as who } from "./main-DGyQ4gje.mjs";
7
7
  import { randomBytes, timingSafeEqual } from "node:crypto";
8
8
  import { appendFile, readFile } from "node:fs/promises";
9
9
  import { join } from "node:path";
@@ -661,7 +661,7 @@ const local = {
661
661
  if (args.length > 0) throw usage("serve takes no arguments: pass its port with --port, and its directory with --dir.");
662
662
  const port = portFlag();
663
663
  const root = projectDir();
664
- const { localHandle, serveLocal } = await import("./serve-D2O0C6Kk.mjs");
664
+ const { localHandle, serveLocal } = await import("./serve-BDLJebk7.mjs");
665
665
  const handle = flags.handle ?? process.env.BOARD_HANDLE;
666
666
  const local = await serveLocal({
667
667
  dir: flags.dir ?? join(root, ".board"),
@@ -69,7 +69,7 @@ declare const options: {
69
69
  readonly value: 'k[=v|w]';
70
70
  readonly description: "with a label on the message or its thread's root";
71
71
  };
72
- readonly from: {
72
+ readonly source: {
73
73
  readonly type: 'string';
74
74
  readonly value: 'source';
75
75
  readonly description: 'from a source: a sync key such as slack, or board';
@@ -121,7 +121,7 @@ declare const options: {
121
121
  };
122
122
  readonly json: {
123
123
  readonly type: 'boolean';
124
- readonly description: 'one JSON object per line, for programs';
124
+ readonly description: 'JSON, for programs';
125
125
  };
126
126
  readonly help: {
127
127
  readonly type: 'boolean';
@@ -139,10 +139,10 @@ declare const options: {
139
139
  readonly value: 'N';
140
140
  readonly description: 'how many';
141
141
  };
142
- readonly id: {
142
+ readonly 'idempotency-key': {
143
143
  readonly type: 'string';
144
144
  readonly value: 'key';
145
- readonly description: 'a client ID: sending the same one again posts once';
145
+ readonly description: 'sending the same one again posts once';
146
146
  };
147
147
  readonly sync: {
148
148
  readonly type: 'string';
@@ -23,7 +23,7 @@ const options = {
23
23
  value: "k[=v|w]",
24
24
  description: "with a label on the message or its thread's root"
25
25
  },
26
- from: {
26
+ source: {
27
27
  type: "string",
28
28
  value: "source",
29
29
  description: "from a source: a sync key such as slack, or board"
@@ -75,7 +75,7 @@ const options = {
75
75
  },
76
76
  json: {
77
77
  type: "boolean",
78
- description: "one JSON object per line, for programs"
78
+ description: "JSON, for programs"
79
79
  },
80
80
  help: {
81
81
  type: "boolean",
@@ -93,10 +93,10 @@ const options = {
93
93
  value: "N",
94
94
  description: "how many"
95
95
  },
96
- id: {
96
+ "idempotency-key": {
97
97
  type: "string",
98
98
  value: "key",
99
- description: "a client ID: sending the same one again posts once"
99
+ description: "sending the same one again posts once"
100
100
  },
101
101
  sync: {
102
102
  type: "string",
@@ -214,7 +214,7 @@ const option = (name, description, value) => ({
214
214
  const filters = [
215
215
  "re",
216
216
  "by",
217
- "from",
217
+ "source",
218
218
  "label",
219
219
  "text",
220
220
  "mentions",
@@ -369,7 +369,7 @@ const commands = [
369
369
  option("attach"),
370
370
  option("sync"),
371
371
  option("no-sync"),
372
- option("id")
372
+ option("idempotency-key")
373
373
  ],
374
374
  examples: [{
375
375
  name: "start a thread",
@@ -386,7 +386,7 @@ const commands = [
386
386
  arguments: [id("the ID of a message in the thread"), text()],
387
387
  options: [
388
388
  option("attach"),
389
- option("id"),
389
+ option("idempotency-key"),
390
390
  option("no-sync")
391
391
  ],
392
392
  examples: [{
@@ -2,11 +2,11 @@ import { a as typeOf, i as fileSize, r as IMPORT_BYTES_MAX, t as ATTACHMENT_BYTE
2
2
  import { C as toStorable, c as ChannelPath, m as MESSAGE_TEXT_MAX } from "./schemas-Be08nyfW.mjs";
3
3
  import { c as externalMessageKey, l as isThreadTarget, s as channelOf } from "./external-BV_cUncs.mjs";
4
4
  import { t as canonicalEmoji } from "./emoji-CTLpvH-A.mjs";
5
- import { n as derivedId } from "./ids-C6AYo1bu.mjs";
5
+ import { r as derivedId, t as waitUntil } from "./wait-until-Dw4XrIDQ.mjs";
6
6
  import { r as badRequest, s as notFound, t as HttpError } from "./errors-CusN4x2l.mjs";
7
7
  import { n as replaceMentions } from "./mentions-CB6ShY4R.mjs";
8
8
  import { t as DroppedError } from "./middleware-ChKM1zuu.mjs";
9
- import { n as waitUntil, t as afterRetry } from "./attempts-CLG840Oj.mjs";
9
+ import { t as afterRetry } from "./attempts-HXcskN1w.mjs";
10
10
  import { a as channelMissing, i as UnreadableError, n as ResolvedTarget, o as routesFor, t as ReceivedEvent } from "./provider-poIkXapd.mjs";
11
11
  import { a as immutable, n as SyncOverrides } from "./events-CewD4kw7.mjs";
12
12
  import { t as displayText } from "./bots-CGkO76qH.mjs";
@@ -1,8 +1,8 @@
1
1
  import { t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
2
2
  import "./schemas-Be08nyfW.mjs";
3
- import { A as SchedulesQuery, B as SyncReceiptBody, C as MatchesQuery, D as Ref, E as ReactBody, F as SyncBody, G as UploadStartBody, H as SyncUnlinkBody, I as SyncCodeBody, L as SyncCopiesQuery, M as SourceJoinBody, N as SourceReadQuery, O as RegisterBody, P as SyncAccountBody, R as SyncFindQuery, S as LinkedQuery, T as PostBody, U as ThreadsQuery, V as SyncRootsQuery, W as TypingBody, _ as InboxAckBody, a as METHODS, b as InboxQuery, c as queryObject, d as VERSION, f as SYNC, g as IdentityUnlinkBody, h as EventsQuery, j as SignInQuery, k as ScheduleBody, l as readCapped, m as EditBody, o as createRouter, p as AckBody, s as openapi, u as readJson, v as InboxNextQuery, w as MessagesQuery, x as LabelBody, y as InboxPushBody, z as SyncImportBody } from "./watchers-hash-BHNXy_N7.mjs";
3
+ import { A as SchedulesQuery, B as SyncReceiptBody, C as MatchesQuery, D as Ref, E as ReactBody, F as SyncBody, G as UploadStartBody, H as SyncUnlinkBody, I as SyncCodeBody, L as SyncCopiesQuery, M as SourceJoinBody, N as SourceReadQuery, O as RegisterBody, P as SyncAccountBody, R as SyncFindQuery, S as LinkedQuery, T as PostBody, U as ThreadsQuery, V as SyncRootsQuery, W as TypingBody, _ as InboxAckBody, a as METHODS, b as InboxQuery, c as queryObject, d as VERSION, f as SYNC, g as IdentityUnlinkBody, h as EventsQuery, j as SignInQuery, k as ScheduleBody, l as readCapped, m as EditBody, o as createRouter, p as AckBody, s as openapi, u as readJson, v as InboxNextQuery, w as MessagesQuery, x as LabelBody, y as InboxPushBody, z as SyncImportBody } from "./watchers-hash-BTF_bMIN.mjs";
4
4
  import { n as createBoardClient, t as BoardError } from "./client-D0Px7KzF.mjs";
5
- import { n as derivedId } from "./ids-C6AYo1bu.mjs";
5
+ import { r as derivedId } from "./wait-until-Dw4XrIDQ.mjs";
6
6
  import { a as forbidden, c as toErrorResponse, l as unauthorized, n as RejectedError, o as json, r as badRequest, s as notFound, t as HttpError } from "./errors-CusN4x2l.mjs";
7
7
  import { d as issuersOf, g as verifiesTokens, l as hostPrincipal, o as createAuthority, s as fromTokens } from "./auth-lTkOgvcE.mjs";
8
8
  import { i as resolveActor, r as claimsOf, t as KNOWN_AGENTS } from "./actors-BLXVp4oZ.mjs";
@@ -1,4 +1,4 @@
1
- import { r as createHttp } from "./backend-http-CYtfwqAW.mjs";
1
+ import { r as createHttp } from "./backend-http-3IxGe13a.mjs";
2
2
  //#region src/backend-http/index.default.ts
3
3
  /**
4
4
  * The board at `url`, which keeps the log. Outside Node there's no environment to find it or a
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { r as duration, t as BoardError } from "./client-D0Px7KzF.mjs";
2
2
  import { t as HttpError } from "./errors-CusN4x2l.mjs";
3
- import { t as http } from "./index.default-BejExznB.mjs";
4
- import { t as createBoard } from "./exports-DCqgO_mr.mjs";
3
+ import { t as http } from "./index.default-CfAjbQrU.mjs";
4
+ import { t as createBoard } from "./exports-B-AeCbYw.mjs";
5
5
  import { t as DroppedError } from "./middleware-ChKM1zuu.mjs";
6
6
  //#region src/server/index.default.ts
7
7
  /**
@@ -11,7 +11,7 @@ import { t as DroppedError } from "./middleware-ChKM1zuu.mjs";
11
11
  function board(options = {}) {
12
12
  return createBoard(options, {
13
13
  http: () => http(),
14
- sync: () => import("./engine-ROa7-IQY.mjs"),
14
+ sync: () => import("./engine-Bfe6pcXb.mjs"),
15
15
  serving: null
16
16
  });
17
17
  }
@@ -1,5 +1,5 @@
1
1
  import { r as duration, t as BoardError } from "./client-D0Px7KzF.mjs";
2
2
  import { t as HttpError } from "./errors-CusN4x2l.mjs";
3
3
  import { t as DroppedError } from "./middleware-ChKM1zuu.mjs";
4
- import { t as board } from "./server-BF4WJ7qi.mjs";
4
+ import { t as board } from "./server-BSXTDTOp.mjs";
5
5
  export { BoardError, DroppedError, HttpError, board, duration };