@brass-build/cli 0.3.0 → 0.4.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 (60) hide show
  1. package/AGENTS.md +177 -11
  2. package/CHANGELOG.md +29 -0
  3. package/README.md +76 -14
  4. package/dist/api.d.ts +45 -0
  5. package/dist/api.d.ts.map +1 -1
  6. package/dist/api.js +21 -2
  7. package/dist/api.js.map +1 -1
  8. package/dist/approval-prompt.d.ts +25 -0
  9. package/dist/approval-prompt.d.ts.map +1 -0
  10. package/dist/approval-prompt.js +44 -0
  11. package/dist/approval-prompt.js.map +1 -0
  12. package/dist/args.d.ts.map +1 -1
  13. package/dist/args.js +10 -1
  14. package/dist/args.js.map +1 -1
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +197 -19
  17. package/dist/cli.js.map +1 -1
  18. package/dist/commands.d.ts +28 -1
  19. package/dist/commands.d.ts.map +1 -1
  20. package/dist/commands.js +369 -29
  21. package/dist/commands.js.map +1 -1
  22. package/dist/config.d.ts +1 -0
  23. package/dist/config.d.ts.map +1 -1
  24. package/dist/config.js +8 -1
  25. package/dist/config.js.map +1 -1
  26. package/dist/login.d.ts +1 -0
  27. package/dist/login.d.ts.map +1 -1
  28. package/dist/login.js +24 -12
  29. package/dist/login.js.map +1 -1
  30. package/dist/project.d.ts +8 -0
  31. package/dist/project.d.ts.map +1 -1
  32. package/dist/project.js +75 -7
  33. package/dist/project.js.map +1 -1
  34. package/dist/sdk-pairing.d.ts +9 -0
  35. package/dist/sdk-pairing.d.ts.map +1 -0
  36. package/dist/sdk-pairing.js +42 -0
  37. package/dist/sdk-pairing.js.map +1 -0
  38. package/dist/session.d.ts +18 -1
  39. package/dist/session.d.ts.map +1 -1
  40. package/dist/session.js +95 -12
  41. package/dist/session.js.map +1 -1
  42. package/dist/store.d.ts +10 -0
  43. package/dist/store.d.ts.map +1 -1
  44. package/dist/store.js +41 -0
  45. package/dist/store.js.map +1 -1
  46. package/dist/version.d.ts +2 -2
  47. package/dist/version.js +1 -1
  48. package/package.json +2 -1
  49. package/src/api.ts +80 -2
  50. package/src/approval-prompt.ts +75 -0
  51. package/src/args.ts +10 -1
  52. package/src/cli.ts +240 -18
  53. package/src/commands.ts +479 -36
  54. package/src/config.ts +15 -2
  55. package/src/login.ts +34 -11
  56. package/src/project.ts +82 -7
  57. package/src/sdk-pairing.ts +53 -0
  58. package/src/session.ts +135 -11
  59. package/src/store.ts +77 -0
  60. package/src/version.ts +1 -1
package/AGENTS.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Instructions for AI coding agents
2
2
 
3
3
  You are likely an AI coding agent publishing a Brass app you built against
4
- `@brass-build/client`. This tool is how you ship it and how you pull a
5
- schema to build against. The [README](./README.md) is the full reference;
4
+ `@brass-build/client`. This tool is how you ship it, and how you read the
5
+ document you are building against. The [README](./README.md) is the full reference;
6
6
  this file is the short path for you.
7
7
 
8
8
  ## Follow your organization's coding instructions first
@@ -50,8 +50,11 @@ npx @brass-build/cli login --start # prints the approval URL + code
50
50
  npx @brass-build/cli login --check --wait # polls until they approve
51
51
  ```
52
52
 
53
- `--start` prints an approval URL and a short code and exits. Give both to the
54
- human in your next message, then run `--check --wait`. It polls for up to two
53
+ `--start` prints an approval URL and a short code and exits. **Put both in the
54
+ visible text of your next message**, not only in the command output: most
55
+ interfaces collapse tool output, so a link left there reaches nobody and the
56
+ sign-in waits forever. Write the URL and the code out, say what the person has
57
+ to do with them, then run `--check --wait`. It polls for up to two
55
58
  minutes (`--wait <seconds>` for a different bound) and stores the session the
56
59
  moment they approve. A code that lapses is replaced and the new one printed,
57
60
  so the sign-in outlives any single code and a session started early is still
@@ -95,14 +98,16 @@ publish, deploy, or open the live URL). Run it, do what it says, then run it
95
98
  again. The steps below are what it walks you through:
96
99
 
97
100
  1. Build the app to a static bundle (its `brass-app.json` capability
98
- manifest must be in the output).
101
+ manifest must be in the output, at `/.well-known/brass-app.json`).
102
+ Confirm it is there after the build: some bundlers skip dot-directories
103
+ when they copy static assets.
99
104
  2. Make sure a credential is available: `BRASS_SERVICE_TOKEN` in the
100
105
  environment (or `--token`) for CI, or a `brass login` session for local
101
106
  development. When `brass status` reports none, run the sign-in yourself,
102
107
  as [Signing in](#signing-in) describes.
103
108
  Starting it, relaying the URL, and checking it through to approved is your
104
109
  step, not a handoff you stop at. (Or the human mints a service token in
105
- the dashboard: org Settings, then Service tokens.)
110
+ the dashboard: org Settings, then Access tokens.)
106
111
  3. Publish:
107
112
 
108
113
  ```sh
@@ -114,22 +119,148 @@ again. The steps below are what it walks you through:
114
119
  its own organization, so no `--org` is needed. If the pipeline does not
115
120
  persist `.brass/project.json` between runs, set a stable `client_token`
116
121
  (a `"client_token"` in `brass-app.json`, or `--client-token`) so the
117
- first create is idempotent and re-runs resolve the same app.
122
+ first create is idempotent and re-runs resolve the same app. A create
123
+ that carries no `client_token` warns on stderr; act on that warning,
124
+ because the duplicate apps it predicts appear only on later runs.
125
+
126
+ The command reads `<dir>/.well-known/brass-app.json`, then
127
+ `brass-app.json` in the working directory, so a manifest in either place
128
+ is found without `--manifest`.
118
129
 
119
130
  Run with `--json` to get the result (`app_id`, `url`) as JSON on stdout for
120
131
  your own parsing. A non-zero exit means the publish failed, and the reason is
121
132
  on stderr.
122
133
 
134
+ ## Opening the app in a browser, signed in
135
+
136
+ Building the app is not verifying it. What a person will do is open it,
137
+ sign in, and use it, and until you have done that yourself you know only
138
+ that it compiles. `brass browser-session` is how you sign in: it prints a
139
+ URL that opens the app as the human whose machine you are on, so you can
140
+ drive the real thing rather than reporting it verified by types.
141
+
142
+ ```sh
143
+ npx @brass-build/cli browser-session --return-to http://localhost:5173/
144
+ ```
145
+
146
+ That prints one URL on stdout. Open it in the browser you drive, and the
147
+ app boots signed in. The URL is single-use and expires two minutes after
148
+ it is printed, so mint it at the moment you are ready to navigate, not
149
+ ahead of time, and put it straight into the browser: it is a credential
150
+ for as long as it lives, so keep it out of files you commit, PR bodies,
151
+ and anything you print back to the human.
152
+
153
+ `--return-to` is where the browser lands, and it has to be on the app's
154
+ redirect allowlist. A new app allows any `localhost` and `127.0.0.1`
155
+ port, so a dev server needs nothing configured. `--app <appId>` names the
156
+ app, and without it the command reads `.brass/project.json`, so after a
157
+ publish in the same directory you can leave it off. `--json` writes the
158
+ result to stdout as `{ state, url, app_id, return_to, expires_in_seconds }`.
159
+ Read the URL from there in a script, rather than parsing the plain output.
160
+
161
+ Run `brass login` before this command. The URL opens the app as the person
162
+ this machine is signed in as, so the command fails without one.
163
+ `BRASS_SERVICE_TOKEN` does not work here, because a service token belongs to
164
+ an organization rather than to a person.
165
+
166
+ Point it at the published URL to drive what you actually shipped:
167
+
168
+ ```sh
169
+ npx @brass-build/cli browser-session --return-to https://<slug>.onbrass.app/
170
+ ```
171
+
172
+ A published app allows its own URL, and the printed link carries the
173
+ browser through the hosted app's access gate as well as signing it in, so
174
+ one navigation reaches the running app either way.
175
+
176
+ The published URL is also the one to use when the app was first created by
177
+ your CI rather than from a machine someone works on. Such an app carries no
178
+ `localhost` entry, so a handoff aimed at a dev server answers that the
179
+ `return_to` is not on the allowlist. Add the entry yourself to work locally
180
+ (the app's Redirect URLs, in its dashboard page) or point the handoff at
181
+ what CI published.
182
+
183
+ ### You can drive a browser
184
+
185
+ If you have no browser tool to hand, install one rather than concluding
186
+ this cannot be done from where you are: `npm i -D playwright` (then
187
+ `npx playwright install chromium`) or `npm i -D puppeteer` gives you a
188
+ headless Chromium you script from Node, which is all this needs. A
189
+ sandbox with no display still runs headless Chromium. Reaching for a
190
+ `curl` of the page instead does not verify the app: the sign-in and the
191
+ app's own rendering both happen in the browser's JavaScript, so a fetch
192
+ of the HTML shows you a loading shell whatever is wrong underneath.
193
+
194
+ Drive it the way a person would: sign in through the URL, do the thing
195
+ the app is for, and read the result off the screen. Take a screenshot at
196
+ a phone width as well as a desktop one.
197
+
198
+ An app your organization owns needs no approval step: the command mints for
199
+ it directly. That covers the ordinary loop, where `brass publish` creates
200
+ the app after you signed in, and it covers an app somebody else published
201
+ first, from a colleague's machine or from CI.
202
+
203
+ The URL grants no more than your current session: it signs in as the
204
+ same person, in the same apps they have approved. `brass logout` ends
205
+ it along with everything else this machine holds.
206
+
207
+ That is a session for the app, so drive what the app itself renders.
208
+ Brass's own hosted dialogs (the document picker, sharing, version
209
+ history) authenticate from a Brass session the person established in that
210
+ browser by signing in there, which is deliberately more than a machine's
211
+ credential carries: it would reach their whole account. Exercise those in
212
+ a browser you signed in to yourself, and build the app so the paths you
213
+ drive do not depend on one opening.
214
+
215
+ ### When it says the app needs approving
216
+
217
+ Opening an app that belongs to another organization is the one case that
218
+ asks a human first. The command answers `needs_approval` with an
219
+ `approval_url`:
220
+
221
+ ```json
222
+ { "state": "needs_approval", "app_id": "brass_app_...", "approval_url": "https://auth.brass.build/device/approve-app?request=..." }
223
+ ```
224
+
225
+ You cannot approve it. Give the human the `approval_url`, ask them to
226
+ open it and approve, then run the same command again. They have to be
227
+ signed in to Brass as the same account this machine is signed in as: they
228
+ are approving one of their own machines.
229
+
230
+ Re-running the command while you wait hands you the same link, with its
231
+ lifetime refreshed, so nothing you have already relayed stops working and
232
+ there is no second URL to send. `brass status` reports the outstanding
233
+ approval and how long it has left, so you never have to guess whether one
234
+ is still in flight.
235
+
236
+ Do not sign out and back in to attach the app to your session: that
237
+ discards a working credential and still needs the same human approval.
238
+ Relay the URL.
239
+
240
+ When you know that app's id before signing in, and are not signed in yet,
241
+ name it on the sign-in instead and one approval covers the pair:
242
+
243
+ ```sh
244
+ npx @brass-build/cli login --start --app brass_app_...
245
+ ```
246
+
247
+ The approval page then names that app beside the CLI, and
248
+ `brass browser-session` mints for it on the first try.
249
+
123
250
  ## Pulling a schema to build against
124
251
 
125
252
  To interoperate with documents another app or importer produces, do not
126
253
  hand-write the schema. Open one of its documents and pull the real body:
127
254
 
128
255
  ```sh
129
- npx @brass-build/cli schema pull --doc <docId> --out brass-app.json
256
+ npx @brass-build/cli schema pull --doc <docId>
130
257
  ```
131
258
 
132
- This writes the schema verbatim into your manifest. Build your types against
259
+ This writes the schema verbatim into your manifest. Without `--out` it
260
+ merges into an existing one (`brass-app.json`, `.well-known/`,
261
+ `public/.well-known/`, `static/.well-known/`, in that order), so the
262
+ schema lands in the file your bundle serves rather than a second one
263
+ beside it. Build your types against
133
264
  that copy rather than re-approximating it from memory, since a mismatched
134
265
  `required` shape makes the platform read your app as a different shape. This
135
266
  is a development-time step that needs a signed-in session (`brass login`),
@@ -137,13 +268,48 @@ not a service token. When you only have `BRASS_SERVICE_TOKEN`, ask the human
137
268
  to run `brass login` or to copy the schema from the document's dashboard
138
269
  page.
139
270
 
271
+ ## Reading what the document holds
272
+
273
+ The schema is the shape; this is the data. Read it before you write code
274
+ against it, so your field names, types, and the values you branch on come
275
+ from the document rather than from a guess at what the schema's words mean:
276
+
277
+ ```sh
278
+ npx @brass-build/cli contents --doc <docId>
279
+ ```
280
+
281
+ This writes `contents.json`: the whole document, keyed by root container. A
282
+ map root is the object your app reads through `doc.map(root)`, so what is in
283
+ the file is what you will render. `--stdout` pipes it instead.
284
+
285
+ Read the whole file, not the first few records. A file's records are grouped
286
+ by type, so its opening records are a couple of the types it carries and none
287
+ of the rest, and an app built against those breaks on the first record of any
288
+ other type. Work out the full set before you design anything:
289
+
290
+ ```sh
291
+ npx @brass-build/cli contents --doc <docId> --stdout \
292
+ | jq '.instances | map(.type) | group_by(.) | map({type: .[0], count: length})'
293
+ ```
294
+
295
+ Then pull an example of each type you plan to handle and build against those.
296
+ `--stream <name>` reads a stream other than `default`. This needs the same
297
+ signed-in session `schema pull` does.
298
+
299
+ Reading a file Brass is still importing waits for the import to finish, so
300
+ the command runs long on a large one rather than failing. It prints each step
301
+ to stderr; `--no-wait` reads once and fails instead.
302
+
140
303
  ## Verifying
141
304
 
142
305
  `npx @brass-build/cli status` is the check to run before and after a publish:
143
306
  it confirms the credential authenticates and reports whether the app is
144
307
  deployed, with the next step to take. `npx @brass-build/cli whoami` is the
145
- narrower check when you only need to confirm the credential works. After a
146
- publish, open the reported URL to confirm the app loads.
308
+ narrower check when you only need to confirm the credential works.
309
+
310
+ After a publish, open the reported URL and drive the app signed in, as
311
+ [Opening the app in a browser](#opening-the-app-in-a-browser-signed-in)
312
+ describes. That is the check the others stand in for.
147
313
 
148
314
  ## When a command fails
149
315
 
package/CHANGELOG.md CHANGED
@@ -6,6 +6,35 @@ package follows [semantic versioning](https://semver.org/spec/v2.0.0.html).
6
6
  While the version is below `1.0.0`, minor releases may introduce breaking
7
7
  changes.
8
8
 
9
+ ## 0.4.1
10
+
11
+ ### Fixed
12
+
13
+ - `brass publish` checks the build output before it changes anything about the
14
+ app, so a publish from a missing or empty directory leaves the app as it
15
+ was.
16
+ - Commands name the CLI as the app making the call, not only the person signed
17
+ in. `brass login` reports a sign-in the server has stopped accepting, rather
18
+ than waiting out its own deadline on a code that can no longer be approved.
19
+
20
+ ## 0.4.0
21
+
22
+ ### Added
23
+
24
+ - `brass contents --doc <docId>` writes a document out as JSON, so you can
25
+ build and test against the data your app will really see rather than
26
+ against a fixture you wrote by hand. Each root container is a key,
27
+ holding what `doc.map(root)` and `doc.list(root)` return.
28
+ - `brass browser-session --return-to <url>` prints a single-use URL that opens
29
+ your app signed in as you, so a coding agent driving a browser can check its
30
+ work as a signed-in user.
31
+
32
+ ### Changed
33
+
34
+ - `brass publish` and `brass schema pull` look for `brass-app.json` in the
35
+ current directory and the common bundle locations, so neither needs
36
+ `--manifest` or `--out` unless the manifest sits somewhere else.
37
+
9
38
  ## 0.3.0
10
39
 
11
40
  ### Changed
package/README.md CHANGED
@@ -1,12 +1,10 @@
1
1
  # @brass-build/cli
2
2
 
3
3
  From a terminal or a CI pipeline, the `brass` command publishes a Brass
4
- app's built bundle and pulls document schemas. It wraps the same data API the
4
+ app's built bundle and reads the documents you build against. It wraps the same data API the
5
5
  dashboard uses, authenticated by a token instead of a browser session, so
6
6
  the whole publish workflow runs unattended.
7
7
 
8
- This package tracks the platform's `0.2.x` line.
9
-
10
8
  ## Install
11
9
 
12
10
  No install step. Run it with `npx`:
@@ -62,6 +60,21 @@ export BRASS_SERVICE_TOKEN=brass_sk_...
62
60
  npx @brass-build/cli whoami
63
61
  ```
64
62
 
63
+ ## Opening your app signed in
64
+
65
+ `browser-session` prints a single-use URL that opens your app as you, for a
66
+ browser an automated tool is driving:
67
+
68
+ ```sh
69
+ npx @brass-build/cli browser-session --return-to http://localhost:5173/
70
+ ```
71
+
72
+ It exists for coding agents, which have no browser session of their own and
73
+ otherwise cannot check that what they built works for a signed-in user. If you
74
+ are at your own machine, opening the app in your own browser does the same
75
+ thing with fewer steps. `AGENTS.md` in this package documents the flow,
76
+ including what to do when the app has not been approved for this machine yet.
77
+
65
78
  ## Status
66
79
 
67
80
  `status` reports the credential and app state for the target environment and
@@ -99,8 +112,9 @@ For a pipeline that stands the app up from scratch and does not persist
99
112
  `.brass/project.json` between runs, set a stable `client_token` (a
100
113
  `"client_token"` in `brass-app.json`, or `--client-token`). Repeated first
101
114
  publishes then resolve the same app instead of creating a duplicate each run.
102
- A service token creates the app in its own organization, so no `--org` is
103
- needed.
115
+ A create that carries no `client_token` says so on stderr, since the duplicate
116
+ it can produce shows up only later. A service token creates the app in its own
117
+ organization, so no `--org` is needed.
104
118
 
105
119
  The command enables hosting if needed, uploads the bundle, waits for the
106
120
  platform to register the slot, and reports the URL. The URL can answer 404
@@ -109,11 +123,17 @@ misses. The platform reads your app's capabilities
109
123
  (`opens` / `creates` / `schema`) from the `/.well-known/brass-app.json` you
110
124
  serve, so keep that manifest in the bundle.
111
125
 
126
+ Without `--manifest`, the command reads `<dir>/.well-known/brass-app.json`
127
+ and falls back to `brass-app.json` in the working directory, so the manifest
128
+ you ship at `/.well-known/` is found where it already sits. A manifest that is
129
+ present and cannot be parsed fails the publish, naming the file.
130
+
112
131
  Flags: `--app`, `--name`, `--org` (organization to own a newly created app;
113
132
  defaults to a service token's own org), `--client-token` (stable idempotency
114
- key for a first create), `--slug` (preferred subdomain), `--manifest`
115
- (default `brass-app.json`), `--visibility` (`private`, `invitee_visible` or
116
- `public`), `--gate` (`on` or `off`, the hosted load gate).
133
+ key for a first create), `--slug` (preferred subdomain), `--manifest` (a
134
+ manifest path, overriding the search above), `--visibility` (`private`,
135
+ `invitee_visible` or `public`), `--gate` (`on` or `off`, the hosted load
136
+ gate).
117
137
 
118
138
  ## Pull a schema
119
139
 
@@ -121,14 +141,55 @@ To build against a shape another app or importer produces, open one of its
121
141
  documents and copy its schema into your manifest:
122
142
 
123
143
  ```sh
124
- npx @brass-build/cli schema pull --doc <docId> --out brass-app.json
144
+ npx @brass-build/cli schema pull --doc <docId>
125
145
  ```
126
146
 
127
147
  This writes the document's schema body verbatim into the manifest's `schema`
128
148
  field, preserving everything else. That is the same copy-verbatim step the
129
- SDK's schema guide describes, done for you. It is a development-time action
130
- that needs a signed-in session (`brass login`), since a service token cannot
131
- fetch schemas.
149
+ SDK's schema guide describes, done for you.
150
+
151
+ Without `--out` it merges into an existing manifest, checking
152
+ `brass-app.json`, `.well-known/`, `public/.well-known/` and
153
+ `static/.well-known/` in that order, and writes `brass-app.json` when it finds
154
+ none. It never writes into a build output directory, where the next build
155
+ would drop it.
156
+
157
+ Pulling a schema is a development-time action that needs a signed-in session
158
+ (`brass login`), since a service token cannot fetch schemas.
159
+
160
+ ## Read what a document holds
161
+
162
+ A schema says what shape the records take; to get the records themselves,
163
+ write the document out as JSON:
164
+
165
+ ```sh
166
+ npx @brass-build/cli contents --doc <docId>
167
+ ```
168
+
169
+ This writes `contents.json` (`--out <path>` for somewhere else, `--stdout` to
170
+ pipe it). The file is the whole document, keyed by root container: a map root
171
+ is the object your app reads through `doc.map(root)`, a list root its items,
172
+ in the same shapes your code will see.
173
+
174
+ The whole document, not a sample. A file's records are grouped by type, so any
175
+ slice off the front carries a couple of the types it holds and none of the
176
+ rest; with the file on disk you can count the types, pull an example of each,
177
+ or filter to one, and every answer covers everything the document has:
178
+
179
+ ```sh
180
+ npx @brass-build/cli contents --doc <docId> --stdout \
181
+ | jq '.instances | map(.type) | group_by(.) | map({type: .[0], count: length})'
182
+ ```
183
+
184
+ Brass fetches the document the way an app does, as the compact CRDT snapshot
185
+ plus the ops after it, and unpacks it here, so the download stays small
186
+ whatever the file's size. `--stream <name>` reads a stream other than
187
+ `default` and `--branch <id>` a branch other than the default. Like
188
+ `schema pull`, this needs a signed-in session (`brass login`).
189
+
190
+ Reading a file Brass is still importing waits for the import to finish, and
191
+ reports each step it moves through. `--wait <seconds>` moves the deadline
192
+ (900 by default) and `--no-wait` reads once and fails instead.
132
193
 
133
194
  ## Pull your organization's agent instructions
134
195
 
@@ -169,9 +230,10 @@ whenever you pull to any file other than `CLAUDE.md`.
169
230
  ```
170
231
 
171
232
  The service token creates the app in its own organization on the first run.
172
- Give `brass-app.json` a stable `"client_token"` so that first create is
233
+ Give your `brass-app.json` a stable `"client_token"` so that first create is
173
234
  idempotent (repeated runs resolve the same app rather than duplicating it),
174
- or commit `.brass/project.json` to pin the app id.
235
+ or commit `.brass/project.json` to pin the app id. A run with neither creates
236
+ a new app each time, and warns that it did.
175
237
 
176
238
  Add `--json` to any command to emit the machine-readable result on stdout
177
239
  (human status stays on stderr).
package/dist/api.d.ts CHANGED
@@ -42,6 +42,45 @@ export interface DocumentStreams {
42
42
  export interface DocumentTypeSummary {
43
43
  schema_type?: string;
44
44
  }
45
+ export type DocumentJoinSnapshot = {
46
+ kind: 'inline';
47
+ data_b64: string;
48
+ } | {
49
+ kind: 'presigned';
50
+ url: string;
51
+ expires_at: string;
52
+ raw_bytes: number;
53
+ };
54
+ export type DocumentJoinTailOp = {
55
+ seq: number;
56
+ op_blob_b64: string;
57
+ } | {
58
+ seq: number;
59
+ op_blob_url: string;
60
+ op_blob_bytes: number;
61
+ };
62
+ export interface DocumentWorkStatus {
63
+ message: string;
64
+ pending: boolean;
65
+ blocking: boolean;
66
+ progress?: number;
67
+ }
68
+ export interface DocumentJoin {
69
+ doc_id: string;
70
+ branch_id: string;
71
+ stream_branch_id?: string;
72
+ name?: string;
73
+ schema_type?: string;
74
+ snapshot: DocumentJoinSnapshot | null;
75
+ tail_ops: DocumentJoinTailOp[];
76
+ snapshot_seq: number;
77
+ current_seq: number;
78
+ status?: DocumentWorkStatus;
79
+ }
80
+ export interface DocumentDetail {
81
+ doc_id: string;
82
+ status?: DocumentWorkStatus;
83
+ }
45
84
  export interface AgentInstructionsResponse {
46
85
  content: string;
47
86
  updated_at?: string;
@@ -61,6 +100,12 @@ export declare class BrassApiError extends Error {
61
100
  readonly status: number;
62
101
  constructor(status: number, message: string);
63
102
  }
103
+ /**
104
+ * Fetch bytes from a presigned URL. Not an API call: the signature is the
105
+ * credential, so no auth header goes with it, and sending one is refused as
106
+ * a second credential on the request.
107
+ */
108
+ export declare function getPresigned(url: string): Promise<Uint8Array>;
64
109
  /** A failed fetch as the caller should read it, naming a timeout as one. */
65
110
  export declare function networkError(what: string, cause: unknown): BrassApiError;
66
111
  export declare class BrassApi {
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/api.js CHANGED
@@ -23,6 +23,24 @@ const REQUEST_TIMEOUT_MS = 30_000;
23
23
  // The upload carries the whole bundle, so it is bounded far more loosely than
24
24
  // a request that carries a few hundred bytes.
25
25
  const UPLOAD_TIMEOUT_MS = 300_000;
26
+ /**
27
+ * Fetch bytes from a presigned URL. Not an API call: the signature is the
28
+ * credential, so no auth header goes with it, and sending one is refused as
29
+ * a second credential on the request.
30
+ */
31
+ export async function getPresigned(url) {
32
+ let response;
33
+ try {
34
+ response = await fetch(url, { signal: AbortSignal.timeout(UPLOAD_TIMEOUT_MS) });
35
+ }
36
+ catch (cause) {
37
+ throw networkError('fetching document bytes', cause);
38
+ }
39
+ if (!response.ok) {
40
+ throw new BrassApiError(response.status, `Could not fetch the document's bytes (${response.status}).`);
41
+ }
42
+ return new Uint8Array(await response.arrayBuffer());
43
+ }
26
44
  /** A failed fetch as the caller should read it, naming a timeout as one. */
27
45
  export function networkError(what, cause) {
28
46
  const timedOut = cause instanceof Error &&
@@ -50,8 +68,9 @@ export class BrassApi {
50
68
  async request(method, path, body) {
51
69
  const headers = {
52
70
  ...(await this.auth.headers()),
53
- // Version telemetry; the platform logs it so pinned CI copies
54
- // stay visible in the deployed-version distribution.
71
+ // Names this CLI and its version. Brass answers a build too old to
72
+ // serve with an upgrade message, rather than a failure that names
73
+ // something else.
55
74
  'x-brass-client': CLI_CLIENT_ID,
56
75
  };
57
76
  let init = { method, headers };
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface ApprovalPromptInput {
2
+ /** Where the human approves, user code prefilled where the server offers it. */
3
+ url: string;
4
+ /** The code they confirm on that page, for a request that carries one. An
5
+ * app approval names the app on its own page instead, so it has none. */
6
+ code?: string;
7
+ /** What the reader is being asked to approve. Defaults to the device grant,
8
+ * which is what most of these are. */
9
+ heading?: string;
10
+ /** Why this prompt is showing again, when it is not the first time. */
11
+ lead?: string | null;
12
+ /** The command that finishes the sign-in, for a caller that exits before
13
+ * approval. A blocking sign-in polls on its own and passes the line it
14
+ * waits under instead. */
15
+ nextCommand?: string | null;
16
+ /** What a caller with no command to name says under the block. */
17
+ closing?: string | null;
18
+ /** Set by the flow a caller who cannot approve is the usual reason to run
19
+ * (`--start` / `--check`), which adds the note asking an agent to pass the
20
+ * link on. The blocking `brass login` leaves it unset: whoever ran it is
21
+ * waiting to approve. */
22
+ relaying?: boolean;
23
+ }
24
+ export declare function renderApprovalPrompt(input: ApprovalPromptInput): string;
25
+ //# sourceMappingURL=approval-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-prompt.d.ts","sourceRoot":"","sources":["../src/approval-prompt.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ;8EAC0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;2CACuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;+BAE2B;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;8BAG0B;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CA0BvE"}
@@ -0,0 +1,44 @@
1
+ // The one rendering of an approval a human has to give: the URL to open, the
2
+ // code to confirm where there is one, plus what to do next. Every phase of the
3
+ // sign-in prints through here, so a fresh grant, a resumed one, and a renewed
4
+ // one read the same, and so does the app approval `brass browser-session`
5
+ // asks for, which is the same request with a different subject.
6
+ //
7
+ // Whether the reader is the person who approves decides whether the block
8
+ // needs a relay instruction, and the caller narrows it: `brass login` blocks
9
+ // until approval, so whoever ran it is waiting to approve, while `--start` /
10
+ // `--check` exist for a caller that cannot hold a command open, which is
11
+ // usually an agent. Usually, not always, so the note there is addressed to an
12
+ // agent as a condition rather than asserted about the reader, and a person
13
+ // running `--start` themselves reads past it.
14
+ //
15
+ // The caller is what narrows it because `isTTY` answers the wrong question
16
+ // twice: an agent harness that allocates a pty (many do, for colored output)
17
+ // reads as a watched terminal, and `brass login | tee` reads as an agent.
18
+ //
19
+ // The frame is ASCII: this goes to whatever console the caller has, and a
20
+ // box-drawing character that renders as a replacement glyph costs more
21
+ // prominence than the frame buys.
22
+ const RULE = '='.repeat(64);
23
+ export function renderApprovalPrompt(input) {
24
+ const lines = [];
25
+ if (input.lead)
26
+ lines.push(input.lead, '');
27
+ lines.push(RULE, input.heading ?? ' To approve this sign-in, open this link and confirm the code:', '', ` ${input.url}`);
28
+ if (input.code)
29
+ lines.push(` Code: ${input.code}`);
30
+ if (input.relaying === true) {
31
+ lines.push('', input.code
32
+ ? ' If you are an AI agent, put the link and the code directly in your'
33
+ : ' If you are an AI agent, put the link directly in your', ' reply. The person who approves often cannot see this output.');
34
+ }
35
+ lines.push(RULE);
36
+ if (input.nextCommand) {
37
+ lines.push('', `Then run \`${input.nextCommand}\` to finish signing in.`);
38
+ }
39
+ else if (input.closing) {
40
+ lines.push('', input.closing);
41
+ }
42
+ return lines.join('\n');
43
+ }
44
+ //# sourceMappingURL=approval-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-prompt.js","sourceRoot":"","sources":["../src/approval-prompt.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,0EAA0E;AAC1E,gEAAgE;AAChE,EAAE;AACF,0EAA0E;AAC1E,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,8EAA8E;AAC9E,2EAA2E;AAC3E,8CAA8C;AAC9C,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,0EAA0E;AAC1E,EAAE;AACF,0EAA0E;AAC1E,uEAAuE;AACvE,kCAAkC;AAElC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AA0B5B,MAAM,UAAU,oBAAoB,CAAC,KAA0B;IAC7D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC3C,KAAK,CAAC,IAAI,CACR,IAAI,EACJ,KAAK,CAAC,OAAO,IAAI,gEAAgE,EACjF,EAAE,EACF,MAAM,KAAK,CAAC,GAAG,EAAE,CAClB,CAAC;IACF,IAAI,KAAK,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CACR,EAAE,EACF,KAAK,CAAC,IAAI;YACR,CAAC,CAAC,qEAAqE;YACvE,CAAC,CAAC,wDAAwD,EAC5D,+DAA+D,CAChE,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,KAAK,CAAC,WAAW,0BAA0B,CAAC,CAAC;IAC5E,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IAGtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAIrC,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAwCD,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAEzD;AA8CD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAO5E;AAKD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAI9E;AAKD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAMtD;AAcD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAKrF;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAuC7D;AAID,wBAAgB,UAAU,CACxB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAGpB;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAElE"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IAGtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAIrC,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AA4CD,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAEzD;AAmDD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAO5E;AAKD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAI9E;AAKD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAMtD;AAcD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAKrF;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAuC7D;AAID,wBAAgB,UAAU,CACxB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAGpB;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAElE"}