@vercel/board 0.22.0 → 0.24.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.
Files changed (50) hide show
  1. package/README.md +14 -19
  2. package/dist/{a2--b1bfuDd.mjs → a2-BxfKZFvJ.mjs} +1 -1
  3. package/dist/{backend-CWmd4UH-.d.mts → backend-D0GDYiFr.d.mts} +1 -1
  4. package/dist/backend-a2.d.mts +1 -1
  5. package/dist/backend-a2.mjs +1 -1
  6. package/dist/{backend-http-BfWQfvqB.d.mts → backend-http-Dvq2p__1.d.mts} +1 -1
  7. package/dist/{backend-http-C8Qyk3vj.mjs → backend-http-rfiG-AKP.mjs} +1 -1
  8. package/dist/{backend-http-DM1T_CP6.mjs → backend-http-tGUo0e8j.mjs} +3 -3
  9. package/dist/backend-http.d.mts +1 -1
  10. package/dist/backend-http.mjs +1 -1
  11. package/dist/backend-http.node.d.mts +2 -2
  12. package/dist/backend-http.node.mjs +1 -1
  13. package/dist/{backend-vercel-CYOqtLPc.d.mts → backend-vercel-01QKDobk.d.mts} +1 -1
  14. package/dist/{backend-vercel-IEtvtvuH.mjs → backend-vercel-C3zuxmcD.mjs} +2 -2
  15. package/dist/{backend-vercel-zo3wg4nM.mjs → backend-vercel-DM5PyMc2.mjs} +2 -2
  16. package/dist/backend-vercel.d.mts +1 -1
  17. package/dist/backend-vercel.mjs +1 -1
  18. package/dist/backend-vercel.node.d.mts +1 -1
  19. package/dist/backend-vercel.node.mjs +1 -1
  20. package/dist/cli-commands.mjs +1 -1
  21. package/dist/cli-embedded.d.mts +4 -4
  22. package/dist/cli-embedded.mjs +3 -3
  23. package/dist/cli.mjs +43 -36
  24. package/dist/{commands-D_ODblQY.mjs → commands-BtL4jFq8.mjs} +0 -30
  25. package/dist/conformance.d.mts +1 -1
  26. package/dist/{exports-ggfE9jNv.d.mts → exports-87_yESpp.d.mts} +1 -1
  27. package/dist/{exports-C46T5hyQ.mjs → exports-Bw81oDDl.mjs} +1 -1
  28. package/dist/{index-DsMPCv_K.d.mts → index-B_hWanKF.d.mts} +3 -3
  29. package/dist/index.d.mts +2 -2
  30. package/dist/{index.default-B8R696fX.mjs → index.default-B6oPlvEa.mjs} +1 -1
  31. package/dist/index.mjs +2 -2
  32. package/dist/index.node.d.mts +2 -2
  33. package/dist/index.node.mjs +1 -1
  34. package/dist/inspect/app.js +1 -1
  35. package/dist/{main-CI5fjlpN.mjs → main-CzWvRy91.mjs} +21 -62
  36. package/dist/{node-BeKPcokJ.mjs → node-CirFYqw0.mjs} +7 -30
  37. package/dist/{serve-DjnbMvu9.mjs → serve-DHyA-6FR.mjs} +3 -3
  38. package/dist/{server-B8nEnlMa.mjs → server-Cp2oIQOj.mjs} +3 -3
  39. package/dist/sync-github.d.mts +1 -1
  40. package/dist/sync-github.mjs +20 -1
  41. package/dist/{watchers-hash-D_VYDwvu.mjs → watchers-hash-C_1jGA53.mjs} +2 -2
  42. package/docs/01-board/01-mounting.md +4 -5
  43. package/docs/01-quickstart.md +8 -8
  44. package/docs/02-sync/04-github.md +2 -1
  45. package/docs/03-guides/01-coding-agents.md +17 -20
  46. package/docs/03-guides/02-inspector.md +1 -1
  47. package/docs/04-reference/01-cli.md +17 -39
  48. package/docs/04-reference/02-board.md +2 -4
  49. package/docs/index.md +2 -3
  50. package/package.json +1 -1
package/README.md CHANGED
@@ -39,31 +39,31 @@ npx vb inspect # the board in your browser, as you
39
39
  For agents on one computer working together, with nothing on the internet:
40
40
 
41
41
  ```bash
42
- npx @vercel/board serve # a board at 127.0.0.1:4100, linked to this project, plus the inspector
42
+ npx @vercel/board serve # a board at 127.0.0.1:4100, plus the inspector
43
+ export BOARD_URL=http://127.0.0.1:4100/api/board # in the terminals your agents run in
43
44
  ```
44
45
 
45
46
  It keeps its log (SQLite) and attachments in the project's `.board/`, across
46
47
  restarts, runs its timers in its own process, and has no sync. You're
47
- `local:user:<your OS user>` (`--handle` to pick another), and `vb` in this
48
- checkout, agents included, finds the board and its token on its own: the token
49
- lives in a file only you can read, for as long as the board runs.
48
+ `local:user:<your OS user>` (`--handle` to pick another), and `vb` pointed at
49
+ it, agents included, finds its token on its own: the token lives in a file
50
+ only you can read, for as long as the board runs.
50
51
 
51
52
  ## Collaborate from a local coding project
52
53
 
53
- Link your checkout to the team's board and install the collaboration skill
54
- for your agents:
54
+ Point the CLI at the team's board and install the collaboration skill for
55
+ your agents:
55
56
 
56
57
  ```bash
57
- npx @vercel/board link https://team.example/api/board
58
+ export BOARD_URL=https://team.example/api/board
58
59
  npx skills add vercel-labs/board --skill board -g
59
60
  ```
60
61
 
61
- `link` saves only the board URL in `.board/config.json` and adds `.board/`
62
- to the project's `.gitignore`. Run it anywhere within a Git checkout; the
63
- link lives at its root, including in worktrees. Without Git, it links the
64
- current directory (a `.git` counts only if it's a directory with a `HEAD` or a
65
- worktree's `gitdir:` file, so a stray empty one in `~` doesn't). Each person links their own checkout and authenticates
66
- with their own `vercel login`; credentials stay in the user-level cache.
62
+ `--url <url>` points one command instead. In a Vercel project with neither,
63
+ the CLI talks to the team's board in Vercel's API, the team `vercel link`
64
+ names. Nothing in a checkout picks a host, so a repo you clone can't send your
65
+ token elsewhere. Each person authenticates with their own `vercel login`;
66
+ credentials stay in the user-level cache.
67
67
 
68
68
  If the board's deployment is behind Vercel Deployment Protection (Vercel
69
69
  Authentication protects production too on many teams), the CLI and a handle in
@@ -77,13 +77,8 @@ deployment on Vercel sends that variable only to its own hosts, and reaches
77
77
  another project's board with its OIDC token, which that project's Trusted
78
78
  Sources must allow.
79
79
 
80
- The CLI and `board()` in Node discover the nearest project link from subdirectories,
81
- stopping at a Git checkout root. An explicit URL or `BOARD_URL` overrides
82
- the link; the global board saved by `vb use` is the fallback. A malformed
83
- project link reports an error rather than falling back to another board.
84
-
85
80
  The skill helps agents discover channels, read discussions, ask questions,
86
- share results, and check replies. Choose channels for the task: the link is
81
+ share results, and check replies. Choose channels for the task: the URL is
87
82
  to the whole board. Posts and replies may sync to the team's Slack, GitHub,
88
83
  or WhatsApp. Automatic wakeups and subscriptions aren't part of this skill.
89
84
  The skill installation is global per user with `-g`; omit it to install in
@@ -1,7 +1,7 @@
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-D_VYDwvu.mjs";
4
+ import { a as METHODS, d as VERSION, f as SYNC, n as compileWatcher, r as hasCriteria, t as canonicalWatchers } from "./watchers-hash-C_1jGA53.mjs";
5
5
  import { r as duration, t as BoardError } from "./client-ClznIBMg.mjs";
6
6
  import { n as derivedId, r as isKeyIdOf } from "./ids-C6AYo1bu.mjs";
7
7
  import { a as forbidden, c as toErrorResponse, i as duplicateId, r as badRequest, s as notFound, t as HttpError } from "./errors-CQ-fwxM3.mjs";
@@ -471,7 +471,7 @@ type BoardOptions = PolicyOptions & {
471
471
  /**
472
472
  * Where the board lives: `a2({ … })` from `@vercel/board/backend-a2` keeps it here, `http(url)` from
473
473
  * `@vercel/board/backend-http` uses another, or your own. By default, `http()`: in Node, the board the
474
- * environment points at (`BOARD_URL`, the repo's link, or `vb use`'s).
474
+ * environment points at (`BOARD_URL`).
475
475
  */
476
476
  backend?: Backend;
477
477
  /**
@@ -3,7 +3,7 @@ import { t as Actor } from "./folds-CRYY14kc.mjs";
3
3
  import { l as Reducer, r as ContractEvent } from "./reducer-CYPHsSmd-BQIfozGi.mjs";
4
4
  import { a as SessionAppend, c as SessionConsumeOptions, d as SessionSchedule, f as StateOptions, l as SessionConsumeResult, n as A2Server, o as SessionClearOptions, p as SessionCleared, r as Consumer, s as SessionClearResult, t as A2Scheduler, u as SessionDeadLetters } from "./server-qgez0Xny-D5mLfqFQ.mjs";
5
5
  import { $ as Discovery, $t as SyncCodeView, Nt as RegistrationView, Tt as PersonView, Wt as SourceJoin, Z as ChannelView, _t as MatchView, bt as MessageView, ct as InboxEntry, fn as SyncedView, hn as ThreadsPage, ht as LinkedAccount, in as SyncFindView, lt as InboxItem, mn as ThreadView, ot as IdentityView, qt as SourceRead, tn as SyncCopiesView, tt as EventsPage, un as SyncThreadView, xn as UploadTicket, xt as MessagesPage, yt as Me, zt as ScheduleView } from "./provider-D11Dfda0.mjs";
6
- import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-CWmd4UH-.mjs";
6
+ import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-D0GDYiFr.mjs";
7
7
  import { n as fsBlob, r as memoryBlob, t as BlobStore } from "./blob-C0J3wbGv.mjs";
8
8
  import { t as BoardStore } from "./types-8yq2VnKI.mjs";
9
9
  import { z } from "zod";
@@ -1,2 +1,2 @@
1
- import { n as fsBlob, r as memoryBlob, t as a2 } from "./a2--b1bfuDd.mjs";
1
+ import { n as fsBlob, r as memoryBlob, t as a2 } from "./a2-BxfKZFvJ.mjs";
2
2
  export { a2, fsBlob, memoryBlob };
@@ -1,7 +1,7 @@
1
1
  import { i as Attachment } from "./schemas-CWxs3ECJ.mjs";
2
2
  import { t as Actor } from "./folds-CRYY14kc.mjs";
3
3
  import { $ as Discovery, $t as SyncCodeView, Nt as RegistrationView, Tt as PersonView, Wt as SourceJoin, Z as ChannelView, _t as MatchView, bt as MessageView, ct as InboxEntry, fn as SyncedView, hn as ThreadsPage, ht as LinkedAccount, in as SyncFindView, lt as InboxItem, mn as ThreadView, ot as IdentityView, qt as SourceRead, tn as SyncCopiesView, tt as EventsPage, un as SyncThreadView, xn as UploadTicket, xt as MessagesPage, yt as Me, z as ProfileOption, zt as ScheduleView } from "./provider-D11Dfda0.mjs";
4
- import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-CWmd4UH-.mjs";
4
+ import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-D0GDYiFr.mjs";
5
5
  //#region src/server/backend-http.d.ts
6
6
  type HttpOptions = {
7
7
  /**
@@ -1,6 +1,6 @@
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-D_VYDwvu.mjs";
3
+ import { K as routes, O as RegisterBody, a as METHODS, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-C_1jGA53.mjs";
4
4
  import { n as createBoardClient, t as BoardError } from "./client-ClznIBMg.mjs";
5
5
  import { a as sha256, i as keyId, n as derivedId, t as DERIVED_ID } from "./ids-C6AYo1bu.mjs";
6
6
  import { a as forbidden, o as json, t as HttpError } from "./errors-CQ-fwxM3.mjs";
@@ -1,5 +1,5 @@
1
- import { r as createHttp } from "./backend-http-C8Qyk3vj.mjs";
2
- import { i as environmentProfile, r as connect, t as boardUrl } from "./node-BeKPcokJ.mjs";
1
+ import { r as createHttp } from "./backend-http-rfiG-AKP.mjs";
2
+ import { n as connect, r as environmentProfile, t as boardUrl } from "./node-CirFYqw0.mjs";
3
3
  //#region src/backend-http/index.ts
4
4
  const environment = {
5
5
  url: boardUrl,
@@ -8,7 +8,7 @@ const environment = {
8
8
  };
9
9
  /**
10
10
  * The board at `url`, which keeps the log: this board uses it as this deployment. Without a
11
- * `url`, the one the environment points at: `BOARD_URL`, the repo's link, or `vb use`'s.
11
+ * `url`, the one the environment points at: `BOARD_URL`.
12
12
  * Without a `fetch`, it sends the credentials `vb` would.
13
13
  */
14
14
  function http(url, options = {}) {
@@ -1,4 +1,4 @@
1
- import { n as HttpOptions, t as HttpBackend } from "./backend-http-BfWQfvqB.mjs";
1
+ import { n as HttpOptions, t as HttpBackend } from "./backend-http-Dvq2p__1.mjs";
2
2
  //#region src/backend-http/index.default.d.ts
3
3
  /**
4
4
  * The board at `url`, which keeps the log. Outside Node there's no environment to find it or a
@@ -1,2 +1,2 @@
1
- import { t as http } from "./index.default-B8R696fX.mjs";
1
+ import { t as http } from "./index.default-B6oPlvEa.mjs";
2
2
  export { http };
@@ -1,8 +1,8 @@
1
- import { n as HttpOptions, t as HttpBackend } from "./backend-http-BfWQfvqB.mjs";
1
+ import { n as HttpOptions, t as HttpBackend } from "./backend-http-Dvq2p__1.mjs";
2
2
  //#region src/backend-http/index.d.ts
3
3
  /**
4
4
  * The board at `url`, which keeps the log: this board uses it as this deployment. Without a
5
- * `url`, the one the environment points at: `BOARD_URL`, the repo's link, or `vb use`'s.
5
+ * `url`, the one the environment points at: `BOARD_URL`.
6
6
  * Without a `fetch`, it sends the credentials `vb` would.
7
7
  */
8
8
  export declare function http(url?: string, options?: HttpOptions): HttpBackend;
@@ -1,2 +1,2 @@
1
- import { t as http } from "./backend-http-DM1T_CP6.mjs";
1
+ import { t as http } from "./backend-http-tGUo0e8j.mjs";
2
2
  export { http };
@@ -1,7 +1,7 @@
1
1
  import { i as Attachment } from "./schemas-CWxs3ECJ.mjs";
2
2
  import { t as Actor } from "./folds-CRYY14kc.mjs";
3
3
  import { $ as Discovery, $t as SyncCodeView, Nt as RegistrationView, Tt as PersonView, Wt as SourceJoin, Z as ChannelView, _t as MatchView, bt as MessageView, ct as InboxEntry, fn as SyncedView, hn as ThreadsPage, ht as LinkedAccount, in as SyncFindView, lt as InboxItem, mn as ThreadView, ot as IdentityView, qt as SourceRead, tn as SyncCopiesView, tt as EventsPage, un as SyncThreadView, xn as UploadTicket, xt as MessagesPage, yt as Me, z as ProfileOption, zt as ScheduleView } from "./provider-D11Dfda0.mjs";
4
- import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-CWmd4UH-.mjs";
4
+ import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-D0GDYiFr.mjs";
5
5
  //#region src/server/backend-vercel.d.ts
6
6
  type VercelOptions = {
7
7
  /** The team whose board it is: its ID (`team_…`) or its slug. In Node, by default your deployment's, or `VERCEL_ORG_ID`. */
@@ -1,6 +1,6 @@
1
1
  import { t as HttpError } from "./errors-CQ-fwxM3.mjs";
2
- import { c as vercelLogin, i as environmentProfile, l as vercelProjectFile } from "./node-BeKPcokJ.mjs";
3
- import { t as createVercel } from "./backend-vercel-zo3wg4nM.mjs";
2
+ import { o as vercelLogin, r as environmentProfile, s as vercelProjectFile } from "./node-CirFYqw0.mjs";
3
+ import { t as createVercel } from "./backend-vercel-DM5PyMc2.mjs";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import { decodeJwt } from "jose";
6
6
  import { getVercelOidcToken } from "@vercel/oidc";
@@ -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-D_VYDwvu.mjs";
2
+ import { O as RegisterBody, a as METHODS, d as VERSION, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-C_1jGA53.mjs";
3
3
  import { a as sha256, n as derivedId } from "./ids-C6AYo1bu.mjs";
4
4
  import { a as forbidden, o as json, s as notFound, t as HttpError } from "./errors-CQ-fwxM3.mjs";
5
- import { a as wakePath, i as registrant, n as callerProfile, t as PROJECTS_OWN } from "./backend-http-C8Qyk3vj.mjs";
5
+ import { a as wakePath, i as registrant, n as callerProfile, t as PROJECTS_OWN } from "./backend-http-rfiG-AKP.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 { n as VercelOptions, t as VercelBackend } from "./backend-vercel-CYOqtLPc.mjs";
1
+ import { n as VercelOptions, t as VercelBackend } from "./backend-vercel-01QKDobk.mjs";
2
2
  //#region src/backend-vercel/index.default.d.ts
3
3
  /**
4
4
  * Your team's board, in Vercel's API. Outside Node there's no environment to find credentials or
@@ -1,4 +1,4 @@
1
- import { t as createVercel } from "./backend-vercel-zo3wg4nM.mjs";
1
+ import { t as createVercel } from "./backend-vercel-DM5PyMc2.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
@@ -1,4 +1,4 @@
1
- import { n as VercelOptions, t as VercelBackend } from "./backend-vercel-CYOqtLPc.mjs";
1
+ import { n as VercelOptions, t as VercelBackend } from "./backend-vercel-01QKDobk.mjs";
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;
@@ -1,2 +1,2 @@
1
- import { n as vercel, t as credentialSource } from "./backend-vercel-IEtvtvuH.mjs";
1
+ import { n as vercel, t as credentialSource } from "./backend-vercel-C3zuxmcD.mjs";
2
2
  export { credentialSource, vercel };
@@ -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-D_ODblQY.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-BtL4jFq8.mjs";
2
2
  export { commands, filters, globalOptions, groups, option, options, usage };
@@ -1,5 +1,5 @@
1
- import { d as Board } from "./backend-CWmd4UH-.mjs";
2
- import "./index-DsMPCv_K.mjs";
1
+ import { d as Board } from "./backend-D0GDYiFr.mjs";
2
+ import "./index-B_hWanKF.mjs";
3
3
  //#region src/cli/main.d.ts
4
4
  /**
5
5
  * The command `argv` runs, by its own name (`delete` for `rm`), as the parser reads it: the
@@ -43,8 +43,8 @@ export type VbResult = {
43
43
  /**
44
44
  * Runs the vb command `argv` (`['read', '42']`, `['reply', '42', 'on it']`) on `board`, in this
45
45
  * process, and returns what the CLI would print. `board` already says which board and who, so
46
- * `--url` and `--handle` don't apply, and the commands about your machine (`link`, `use`, `whoami`,
47
- * `identity`, `hooks`, `serve`, `inspect`) answer 2. Calls run one at a time, in order, so
46
+ * `--url` and `--handle` don't apply, and the commands about your machine (`whoami`, `identity`,
47
+ * `hooks`, `serve`, `inspect`) answer 2. Calls run one at a time, in order, so
48
48
  * `tail` and `wait`, which hold the rest until they end, need `options.signal`.
49
49
  */
50
50
  export declare function vb(board: Board, argv: string[], options?: VbOptions): Promise<VbResult>;
@@ -1,4 +1,4 @@
1
- import { n as main, r as mainWith, t as commandWord } from "./main-CI5fjlpN.mjs";
1
+ import { n as main, r as mainWith, t as commandWord } from "./main-CzWvRy91.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
@@ -21,8 +21,8 @@ let queue = Promise.resolve();
21
21
  /**
22
22
  * Runs the vb command `argv` (`['read', '42']`, `['reply', '42', 'on it']`) on `board`, in this
23
23
  * process, and returns what the CLI would print. `board` already says which board and who, so
24
- * `--url` and `--handle` don't apply, and the commands about your machine (`link`, `use`, `whoami`,
25
- * `identity`, `hooks`, `serve`, `inspect`) answer 2. Calls run one at a time, in order, so
24
+ * `--url` and `--handle` don't apply, and the commands about your machine (`whoami`, `identity`,
25
+ * `hooks`, `serve`, `inspect`) answer 2. Calls run one at a time, in order, so
26
26
  * `tail` and `wait`, which hold the rest until they end, need `options.signal`.
27
27
  */
28
28
  function vb(board, argv, options = {}) {
package/dist/cli.mjs CHANGED
@@ -1,11 +1,11 @@
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-D_ODblQY.mjs";
5
- import { o as projectDir, s as projectUrl } from "./node-BeKPcokJ.mjs";
6
- import { i as who, n as main } from "./main-CI5fjlpN.mjs";
4
+ import { a as option } from "./commands-BtL4jFq8.mjs";
5
+ import { a as projectDir } from "./node-CirFYqw0.mjs";
6
+ import { i as who, n as main } from "./main-CzWvRy91.mjs";
7
7
  import { randomBytes, timingSafeEqual } from "node:crypto";
8
- import { readFile } from "node:fs/promises";
8
+ import { appendFile, readFile } from "node:fs/promises";
9
9
  import { join } from "node:path";
10
10
  import { createServer } from "node:http";
11
11
  //#region src/inspect/style.ts
@@ -605,36 +605,46 @@ const stopped = () => new Promise((resolve) => {
605
605
  process.once("SIGINT", done);
606
606
  process.once("SIGTERM", done);
607
607
  });
608
+ const inspect = {
609
+ spec: {
610
+ name: "inspect",
611
+ description: "the board in your browser, as you: read, post, react (local only)",
612
+ arguments: [],
613
+ options: [option("port", "the port to listen on (default: a free one)"), option("no-open")],
614
+ examples: [{
615
+ name: "open the board in your browser",
616
+ value: "inspect"
617
+ }]
618
+ },
619
+ async run(_args, { flags, out, portFlag, client, openBrowser }) {
620
+ const port = portFlag();
621
+ const inspector = await startInspector({
622
+ client: client(),
623
+ ...port !== void 0 ? { port } : {}
624
+ });
625
+ out(`inspecting ${inspector.board} as ${who(inspector.me)} at ${inspector.url} (Ctrl-C to stop)`);
626
+ if (!flags["no-open"]) openBrowser(inspector.url);
627
+ await stopped();
628
+ await inspector.close();
629
+ return 0;
630
+ }
631
+ };
632
+ /** Keeps the local board's log (`.board/`) out of the project's Git. */
633
+ async function ignoreLog(root) {
634
+ const path = join(root, ".gitignore");
635
+ const ignore = await readFile(path, "utf8").catch((error) => {
636
+ if (error.code === "ENOENT") return "";
637
+ throw error;
638
+ });
639
+ if (!ignore.split(/\r?\n/).some((line) => /^\/?\.board\/?$/.test(line))) await appendFile(path, `${ignore && !ignore.endsWith("\n") ? "\n" : ""}.board/\n`);
640
+ }
608
641
  /** The commands only the standalone `board` has, in the order its help lists them. */
609
642
  const local = {
610
- inspect: {
611
- spec: {
612
- name: "inspect",
613
- description: "the board in your browser, as you: read, post, react (local only)",
614
- arguments: [],
615
- options: [option("port", "the port to listen on (default: a free one)"), option("no-open")],
616
- examples: [{
617
- name: "open the board in your browser",
618
- value: "inspect"
619
- }]
620
- },
621
- async run(_args, { flags, out, portFlag, client, openBrowser }) {
622
- const port = portFlag();
623
- const inspector = await startInspector({
624
- client: client(),
625
- ...port !== void 0 ? { port } : {}
626
- });
627
- out(`inspecting ${inspector.board} as ${who(inspector.me)} at ${inspector.url} (Ctrl-C to stop)`);
628
- if (!flags["no-open"]) openBrowser(inspector.url);
629
- await stopped();
630
- await inspector.close();
631
- return 0;
632
- }
633
- },
643
+ inspect,
634
644
  serve: {
635
645
  spec: {
636
646
  name: "serve",
637
- description: "run a board on this machine (127.0.0.1:4100, no sync), link this project to it, and open the inspector; its log lives in .board/, and you're local:user:<your OS user> (or --handle)",
647
+ description: "run a board on this machine (127.0.0.1:4100, no sync) and open the inspector: other commands reach it with --url or BOARD_URL. Its log lives in .board/, and you're local:user:<your OS user> (or --handle)",
638
648
  arguments: [],
639
649
  options: [
640
650
  option("port", "the port to listen on (default: 4100)"),
@@ -647,11 +657,11 @@ const local = {
647
657
  value: "serve"
648
658
  }]
649
659
  },
650
- async run(args, { flags, out, usage, portFlag, connection, openBrowser, saveLink, linkedByServe }) {
660
+ async run(args, { flags, out, usage, portFlag, connection, openBrowser }) {
651
661
  if (args.length > 0) throw usage("usage: board serve [--port N] [--dir <dir>] [--no-inspect] [--no-open]");
652
662
  const port = portFlag();
653
663
  const root = projectDir();
654
- const { localHandle, serveLocal } = await import("./serve-DjnbMvu9.mjs");
664
+ const { localHandle, serveLocal } = await import("./serve-DHyA-6FR.mjs");
655
665
  const handle = flags.handle ?? process.env.BOARD_HANDLE;
656
666
  const local = await serveLocal({
657
667
  dir: flags.dir ?? join(root, ".board"),
@@ -660,12 +670,9 @@ const local = {
660
670
  });
661
671
  let inspector = null;
662
672
  try {
663
- const linked = projectUrl();
664
- if (linked === void 0 || linked === local.url || linkedByServe(root)) {
665
- await saveLink(root, local.url, { serve: true });
666
- if (linked !== local.url) out(`linked ${root} to ${local.url}`);
667
- } else out(`${root} stays linked to ${linked}; reach this board with BOARD_URL=${local.url}`);
673
+ if (!flags.dir) await ignoreLog(root);
668
674
  out(`serving a local board at ${local.url} as ${local.principal}, its log in ${local.dir} (Ctrl-C to stop)`);
675
+ out(`reach it with --url ${local.url}, or BOARD_URL=${local.url}`);
669
676
  if (!flags["no-inspect"]) {
670
677
  const { board } = connection(local.url, {
671
678
  token: local.token,
@@ -264,36 +264,6 @@ const commands = [
264
264
  value: "whoami"
265
265
  }]
266
266
  },
267
- {
268
- group: "you",
269
- name: "link",
270
- description: "link this project to a board (.board/config.json)",
271
- arguments: [{
272
- name: "url",
273
- required: true,
274
- description: "the board's URL"
275
- }],
276
- options: [],
277
- examples: [{
278
- name: "link this project to a team's board",
279
- value: "link https://www.example.com/api/board"
280
- }]
281
- },
282
- {
283
- group: "you",
284
- name: "use",
285
- description: "save the default board",
286
- arguments: [{
287
- name: "url",
288
- required: true,
289
- description: "the board's URL"
290
- }],
291
- options: [],
292
- examples: [{
293
- name: "use a board everywhere nothing else is linked",
294
- value: "use https://www.example.com/api/board"
295
- }]
296
- },
297
267
  {
298
268
  group: "the board",
299
269
  name: "channels",
@@ -1,4 +1,4 @@
1
- import { d as Board } from "./backend-CWmd4UH-.mjs";
1
+ import { d as Board } from "./backend-D0GDYiFr.mjs";
2
2
  //#region src/conformance/index.d.ts
3
3
  /**
4
4
  * Checks that a board speaks the protocol, through a handle on it (`conformance(board())`), as
@@ -1,4 +1,4 @@
1
1
  import "./auth-CU56Q2Xh.mjs";
2
2
  import "./schemas-CWxs3ECJ.mjs";
3
3
  import "./provider-D11Dfda0.mjs";
4
- import "./backend-CWmd4UH-.mjs";
4
+ import "./backend-D0GDYiFr.mjs";
@@ -1,6 +1,6 @@
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-D_VYDwvu.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-C_1jGA53.mjs";
4
4
  import { n as createBoardClient, t as BoardError } from "./client-ClznIBMg.mjs";
5
5
  import { n as derivedId } from "./ids-C6AYo1bu.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-CQ-fwxM3.mjs";
@@ -1,10 +1,10 @@
1
- import { d as Board, f as BoardOptions } from "./backend-CWmd4UH-.mjs";
2
- import "./exports-ggfE9jNv.mjs";
1
+ import { d as Board, f as BoardOptions } from "./backend-D0GDYiFr.mjs";
2
+ import "./exports-87_yESpp.mjs";
3
3
  //#region src/server/index.d.ts
4
4
  /**
5
5
  * The handle on a board. With a `backend`, the board lives there: `a2()` keeps it in this
6
6
  * deployment, `http(url)` uses another. Without one, it's `http()` to the board the environment
7
- * points at: `BOARD_URL`, then the repo's link (`vb link`, `vb serve`), then `vb use`'s.
7
+ * points at: `BOARD_URL`.
8
8
  */
9
9
  declare function board(options?: BoardOptions): Board;
10
10
  //#endregion
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { a as CallerRequest, o as Claims } from "./auth-CU56Q2Xh.mjs";
2
2
  import { i as Attachment } from "./schemas-CWxs3ECJ.mjs";
3
3
  import { $ as Discovery, $t as SyncCodeView, At as Ref, B as ReplyOptions, Bt as SchedulesQuery, Ct as MessagesQueryInput, Dt as PostInput, Et as PostBody, Ft as RouteName, G as Written, Gt as SourceJoinBody, H as ScheduleTiming, Ht as SchedulesQueryOutput, I as BoardError, It as ScheduleBody, J as ActorView, Jt as SourceReadQuery, K as duration, Kt as SourceMessage, L as Filters, Lt as ScheduleBodyOutput, Mt as RegisterInput, Nt as RegistrationView, Ot as REGISTERED_WATCHERS_MAX, Pt as ResolvedSyncTarget, Q as DeleteBody, Qt as SyncCodeBody, R as PostOptions, Rt as ScheduleInput, Sn as routes, St as MessagesQuery, Tt as PersonView, U as UploadInput, Ut as SignInQuery, V as ScheduleOptions, Vt as SchedulesQueryInput, W as WaitOptions, Wt as SourceJoin, X as BoardEventView, Xt as SyncAccountInput, Y as ApiError, Yt as SyncAccountBody, Z as ChannelView, Zt as SyncBody, _n as ThreadsQueryInput, _t as MatchView, an as SyncImportBody, at as IdentityUnlinkBody, bn as UploadStartBody, bt as MessageView, cn as SyncReceiptInput, ct as InboxEntry, dn as SyncUnlinkBody, dt as InboxPushBody, en as SyncCopiesQuery, et as EditBody, fn as SyncedView, ft as InboxQuery, gn as ThreadsQuery, gt as LinkedQuery, hn as ThreadsPage, ht as LinkedAccount, in as SyncFindView, it as FiltersInput, jt as RegisterBody, kt as ReactBody, ln as SyncRootsQuery, lt as InboxItem, mn as ThreadView, mt as LinkView, nn as SyncFindInput, nt as EventsQuery, on as SyncImportInput, ot as IdentityView, pn as ThreadSummaryView, pt as LabelBody, q as AckBody, qt as SourceRead, rn as SyncFindQuery, rt as EventsQueryInput, sn as SyncReceiptBody, st as InboxAckBody, tn as SyncCopiesView, tt as EventsPage, un as SyncThreadView, ut as InboxNextQuery, vn as TypingBody, vt as MatchesQuery, wt as ParsedFilters, xn as UploadTicket, xt as MessagesPage, yn as TypingResult, yt as Me, z as ProfileOption, zt as ScheduleView } from "./provider-D11Dfda0.mjs";
4
- import { C as Protocol, S as Method, _ as MiddlewareContext, a as Identity, b as WriteSource, c as SelfCaller, d as Board, f as BoardOptions, g as Middleware, h as DroppedError, i as Caller, l as Subscription, m as WatcherContext, n as BackendRoute, o as InboxDelivery, p as Watcher, r as BoardBinding, s as ProtocolMethods, t as Backend, u as VerifiedCaller, v as Write, x as HttpError, y as WritePatch } from "./backend-CWmd4UH-.mjs";
5
- import "./exports-ggfE9jNv.mjs";
4
+ import { C as Protocol, S as Method, _ as MiddlewareContext, a as Identity, b as WriteSource, c as SelfCaller, d as Board, f as BoardOptions, g as Middleware, h as DroppedError, i as Caller, l as Subscription, m as WatcherContext, n as BackendRoute, o as InboxDelivery, p as Watcher, r as BoardBinding, s as ProtocolMethods, t as Backend, u as VerifiedCaller, v as Write, x as HttpError, y as WritePatch } from "./backend-D0GDYiFr.mjs";
5
+ import "./exports-87_yESpp.mjs";
6
6
  //#region src/server/index.default.d.ts
7
7
  /**
8
8
  * The handle on a board. Outside Node there's no environment to find one in, so pass its
@@ -1,4 +1,4 @@
1
- import { r as createHttp } from "./backend-http-C8Qyk3vj.mjs";
1
+ import { r as createHttp } from "./backend-http-rfiG-AKP.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-ClznIBMg.mjs";
2
2
  import { t as HttpError } from "./errors-CQ-fwxM3.mjs";
3
- import { t as http } from "./index.default-B8R696fX.mjs";
4
- import { t as createBoard } from "./exports-C46T5hyQ.mjs";
3
+ import { t as http } from "./index.default-B6oPlvEa.mjs";
4
+ import { t as createBoard } from "./exports-Bw81oDDl.mjs";
5
5
  import { t as DroppedError } from "./middleware-DUjyQP_a.mjs";
6
6
  //#region src/server/index.default.ts
7
7
  /**
@@ -1,6 +1,6 @@
1
1
  import { a as CallerRequest, o as Claims } from "./auth-CU56Q2Xh.mjs";
2
2
  import { i as Attachment } from "./schemas-CWxs3ECJ.mjs";
3
3
  import { $ as Discovery, $t as SyncCodeView, At as Ref, B as ReplyOptions, Bt as SchedulesQuery, Ct as MessagesQueryInput, Dt as PostInput, Et as PostBody, Ft as RouteName, G as Written, Gt as SourceJoinBody, H as ScheduleTiming, Ht as SchedulesQueryOutput, I as BoardError, It as ScheduleBody, J as ActorView, Jt as SourceReadQuery, K as duration, Kt as SourceMessage, L as Filters, Lt as ScheduleBodyOutput, Mt as RegisterInput, Nt as RegistrationView, Ot as REGISTERED_WATCHERS_MAX, Pt as ResolvedSyncTarget, Q as DeleteBody, Qt as SyncCodeBody, R as PostOptions, Rt as ScheduleInput, Sn as routes, St as MessagesQuery, Tt as PersonView, U as UploadInput, Ut as SignInQuery, V as ScheduleOptions, Vt as SchedulesQueryInput, W as WaitOptions, Wt as SourceJoin, X as BoardEventView, Xt as SyncAccountInput, Y as ApiError, Yt as SyncAccountBody, Z as ChannelView, Zt as SyncBody, _n as ThreadsQueryInput, _t as MatchView, an as SyncImportBody, at as IdentityUnlinkBody, bn as UploadStartBody, bt as MessageView, cn as SyncReceiptInput, ct as InboxEntry, dn as SyncUnlinkBody, dt as InboxPushBody, en as SyncCopiesQuery, et as EditBody, fn as SyncedView, ft as InboxQuery, gn as ThreadsQuery, gt as LinkedQuery, hn as ThreadsPage, ht as LinkedAccount, in as SyncFindView, it as FiltersInput, jt as RegisterBody, kt as ReactBody, ln as SyncRootsQuery, lt as InboxItem, mn as ThreadView, mt as LinkView, nn as SyncFindInput, nt as EventsQuery, on as SyncImportInput, ot as IdentityView, pn as ThreadSummaryView, pt as LabelBody, q as AckBody, qt as SourceRead, rn as SyncFindQuery, rt as EventsQueryInput, sn as SyncReceiptBody, st as InboxAckBody, tn as SyncCopiesView, tt as EventsPage, un as SyncThreadView, ut as InboxNextQuery, vn as TypingBody, vt as MatchesQuery, wt as ParsedFilters, xn as UploadTicket, xt as MessagesPage, yn as TypingResult, yt as Me, z as ProfileOption, zt as ScheduleView } from "./provider-D11Dfda0.mjs";
4
- import { C as Protocol, S as Method, _ as MiddlewareContext, a as Identity, b as WriteSource, c as SelfCaller, d as Board, f as BoardOptions, g as Middleware, h as DroppedError, i as Caller, l as Subscription, m as WatcherContext, n as BackendRoute, o as InboxDelivery, p as Watcher, r as BoardBinding, s as ProtocolMethods, t as Backend, u as VerifiedCaller, v as Write, x as HttpError, y as WritePatch } from "./backend-CWmd4UH-.mjs";
5
- import { t as board } from "./index-DsMPCv_K.mjs";
4
+ import { C as Protocol, S as Method, _ as MiddlewareContext, a as Identity, b as WriteSource, c as SelfCaller, d as Board, f as BoardOptions, g as Middleware, h as DroppedError, i as Caller, l as Subscription, m as WatcherContext, n as BackendRoute, o as InboxDelivery, p as Watcher, r as BoardBinding, s as ProtocolMethods, t as Backend, u as VerifiedCaller, v as Write, x as HttpError, y as WritePatch } from "./backend-D0GDYiFr.mjs";
5
+ import { t as board } from "./index-B_hWanKF.mjs";
6
6
  export { type AckBody, type ActorView, type ApiError, type Attachment, type Backend, type BackendRoute, type Board, type BoardBinding, BoardError, type BoardEventView, type BoardOptions, type Caller, type CallerRequest, type ChannelView, type Claims, type DeleteBody, type Discovery, DroppedError, type EditBody, type EventsPage, type EventsQuery, type EventsQueryInput, type Filters, type FiltersInput, HttpError, type Identity, type IdentityUnlinkBody, type IdentityView, type InboxAckBody, type InboxDelivery, type InboxEntry, type InboxItem, type InboxNextQuery, type InboxPushBody, type InboxQuery, type LabelBody, type LinkView, type LinkedAccount, type LinkedQuery, type MatchView, type MatchesQuery, type Me, type MessageView, type MessagesPage, type MessagesQuery, type MessagesQueryInput, type Method, type Middleware, type MiddlewareContext, type ParsedFilters, type PersonView, type PostBody, type PostInput, type PostOptions, type ProfileOption, type Protocol, type ProtocolMethods, type REGISTERED_WATCHERS_MAX, type ReactBody, type Ref, type RegisterBody, type RegisterInput, type RegistrationView, type ReplyOptions, type ResolvedSyncTarget, type RouteName, type ScheduleBody, type ScheduleBodyOutput, type ScheduleInput, type ScheduleOptions, type ScheduleTiming, type ScheduleView, type SchedulesQuery, type SchedulesQueryInput, type SchedulesQueryOutput, type SelfCaller, type SignInQuery, type SourceJoin, type SourceJoinBody, type SourceMessage, type SourceRead, type SourceReadQuery, type Subscription, type SyncAccountBody, type SyncAccountInput, type SyncBody, type SyncCodeBody, type SyncCodeView, type SyncCopiesQuery, type SyncCopiesView, type SyncFindInput, type SyncFindQuery, type SyncFindView, type SyncImportBody, type SyncImportInput, type SyncReceiptBody, type SyncReceiptInput, type SyncRootsQuery, type SyncThreadView, type SyncUnlinkBody, type SyncedView, type ThreadSummaryView, type ThreadView, type ThreadsPage, type ThreadsQuery, type ThreadsQueryInput, type TypingBody, type TypingResult, type UploadInput, type UploadStartBody, type UploadTicket, type VerifiedCaller, type WaitOptions, type Watcher, type WatcherContext, type Write, type WritePatch, type WriteSource, type Written, board, duration, type routes };
@@ -1,5 +1,5 @@
1
1
  import { r as duration, t as BoardError } from "./client-ClznIBMg.mjs";
2
2
  import { t as HttpError } from "./errors-CQ-fwxM3.mjs";
3
3
  import { t as DroppedError } from "./middleware-DUjyQP_a.mjs";
4
- import { t as board } from "./server-B8nEnlMa.mjs";
4
+ import { t as board } from "./server-Cp2oIQOj.mjs";
5
5
  export { BoardError, DroppedError, HttpError, board, duration };