@brass-build/cli 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +35 -32
- package/CHANGELOG.md +32 -0
- package/README.md +26 -21
- package/dist/api.d.ts +3 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +28 -8
- package/dist/api.js.map +1 -1
- package/dist/args.d.ts +4 -0
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +92 -6
- package/dist/args.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +166 -61
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +49 -19
- package/dist/commands.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/login.d.ts +1 -0
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +26 -12
- package/dist/login.js.map +1 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +34 -5
- package/dist/project.js.map +1 -1
- package/dist/session.d.ts +2 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +91 -20
- package/dist/session.js.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/api.ts +38 -8
- package/src/args.ts +102 -6
- package/src/cli.ts +198 -60
- package/src/commands.ts +66 -19
- package/src/config.ts +5 -1
- package/src/login.ts +30 -12
- package/src/project.ts +39 -5
- package/src/session.ts +106 -21
- package/src/version.ts +1 -1
package/AGENTS.md
CHANGED
|
@@ -10,10 +10,8 @@ this file is the short path for you.
|
|
|
10
10
|
Before you start building, fetch the organization's own agentic-coding
|
|
11
11
|
instructions and follow them: the conventions it wants every app built on
|
|
12
12
|
Brass to follow (its `AGENTS.md` / `CLAUDE.md`). Run the pull rather than
|
|
13
|
-
deciding up front whether the org has any
|
|
14
|
-
|
|
15
|
-
assuming it. Treat what it returns as an instruction file committed to the
|
|
16
|
-
repo.
|
|
13
|
+
deciding up front whether the org has any, because nothing loads them for
|
|
14
|
+
you. Treat what it returns as an instruction file committed to the repo.
|
|
17
15
|
|
|
18
16
|
```sh
|
|
19
17
|
npx @brass-build/cli agents pull --out AGENTS.md
|
|
@@ -30,18 +28,17 @@ Keep it current one of two ways:
|
|
|
30
28
|
- **Cache:** commit the pulled file and refresh it periodically. Add a
|
|
31
29
|
`CLAUDE.md` whose entire contents are the single line `@AGENTS.md` so
|
|
32
30
|
Claude Code picks it up too (Claude Code auto-loads `CLAUDE.md`, not
|
|
33
|
-
`AGENTS.md`)
|
|
34
|
-
|
|
35
|
-
The pull needs a signed-in session (`brass login`)
|
|
36
|
-
organization member and cannot read the instructions. If you are not
|
|
37
|
-
in, run the sign-in yourself rather than skipping: `brass login
|
|
38
|
-
relay the printed URL and code to the human, then `brass login
|
|
39
|
-
until it reports approved (it is the same credential you will
|
|
40
|
-
[Signing in](#signing-in) covers the whole flow, including
|
|
41
|
-
you wait for the approval.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
instructions, and there is nothing to follow.
|
|
31
|
+
`AGENTS.md`). The command prints this reminder after a pull.
|
|
32
|
+
|
|
33
|
+
The pull needs a signed-in session (`brass login`), since a service token is
|
|
34
|
+
not an organization member and cannot read the instructions. If you are not
|
|
35
|
+
signed in, run the sign-in yourself rather than skipping: `brass login
|
|
36
|
+
--start`, relay the printed URL and code to the human, then `brass login
|
|
37
|
+
--check --wait` until it reports approved (it is the same credential you will
|
|
38
|
+
use to publish). [Signing in](#signing-in) covers the whole flow, including
|
|
39
|
+
what to do while you wait for the approval. Pass `--org <organizationId>`
|
|
40
|
+
when the human belongs to more than one organization. An empty result means
|
|
41
|
+
the organization has set no instructions.
|
|
45
42
|
|
|
46
43
|
## Signing in
|
|
47
44
|
|
|
@@ -62,10 +59,10 @@ good at publish time.
|
|
|
62
59
|
|
|
63
60
|
The session gates your organization's coding conventions, and those shape the
|
|
64
61
|
code you are about to write, so wait for it before you build rather than
|
|
65
|
-
building twice.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
building twice. Do work that does not depend on them in the meantime and
|
|
63
|
+
repeat the wait: a bound reached with the code still approvable reports
|
|
64
|
+
`pending`, and the next `--check --wait` picks the same sign-in back up where
|
|
65
|
+
it left off.
|
|
69
66
|
|
|
70
67
|
Read the `state` in its `--json` result:
|
|
71
68
|
|
|
@@ -73,6 +70,11 @@ Read the `state` in its `--json` result:
|
|
|
73
70
|
- `pending`: the code you relayed is still good. Run the check again.
|
|
74
71
|
- `renewed`: the code changed. Relay the new one from the same output.
|
|
75
72
|
- `denied`: the human refused. Ask them why before starting another.
|
|
73
|
+
- `none`: nothing is in flight. Run `brass login --start` first.
|
|
74
|
+
|
|
75
|
+
`brass login --start` reports `started` with the code to relay, and
|
|
76
|
+
`--start --wait` reports the state it reached instead, so either form leaves
|
|
77
|
+
one `--json` document to read.
|
|
76
78
|
|
|
77
79
|
Run `brass login --start` again only when there is nothing in flight; it
|
|
78
80
|
resumes the sign-in already waiting rather than issuing a second code, so a
|
|
@@ -107,7 +109,7 @@ again. The steps below are what it walks you through:
|
|
|
107
109
|
npx @brass-build/cli publish ./dist
|
|
108
110
|
```
|
|
109
111
|
|
|
110
|
-
The first run creates the app and writes `.brass/project.json
|
|
112
|
+
The first run creates the app and writes `.brass/project.json`. Commit
|
|
111
113
|
that so re-runs target the same app. A service token creates the app in
|
|
112
114
|
its own organization, so no `--org` is needed. If the pipeline does not
|
|
113
115
|
persist `.brass/project.json` between runs, set a stable `client_token`
|
|
@@ -115,8 +117,8 @@ again. The steps below are what it walks you through:
|
|
|
115
117
|
first create is idempotent and re-runs resolve the same app.
|
|
116
118
|
|
|
117
119
|
Run with `--json` to get the result (`app_id`, `url`) as JSON on stdout for
|
|
118
|
-
your own parsing. A non-zero exit means the publish failed
|
|
119
|
-
stderr.
|
|
120
|
+
your own parsing. A non-zero exit means the publish failed, and the reason is
|
|
121
|
+
on stderr.
|
|
120
122
|
|
|
121
123
|
## Pulling a schema to build against
|
|
122
124
|
|
|
@@ -128,11 +130,12 @@ npx @brass-build/cli schema pull --doc <docId> --out brass-app.json
|
|
|
128
130
|
```
|
|
129
131
|
|
|
130
132
|
This writes the schema verbatim into your manifest. Build your types against
|
|
131
|
-
that copy
|
|
132
|
-
shape makes the platform read your app as a different shape
|
|
133
|
-
development-time step that needs a signed-in session (`brass login`),
|
|
134
|
-
service token
|
|
135
|
-
`brass login` or to copy the schema from the document's dashboard
|
|
133
|
+
that copy rather than re-approximating it from memory, since a mismatched
|
|
134
|
+
`required` shape makes the platform read your app as a different shape. This
|
|
135
|
+
is a development-time step that needs a signed-in session (`brass login`),
|
|
136
|
+
not a service token. When you only have `BRASS_SERVICE_TOKEN`, ask the human
|
|
137
|
+
to run `brass login` or to copy the schema from the document's dashboard
|
|
138
|
+
page.
|
|
136
139
|
|
|
137
140
|
## Verifying
|
|
138
141
|
|
|
@@ -149,10 +152,10 @@ are on. The CLI reports the state it observed, and the states have different
|
|
|
149
152
|
fixes:
|
|
150
153
|
|
|
151
154
|
- **A 401 or 403** means the credential is expired, missing, or not allowed.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
container has no session at all, which is the ordinary starting
|
|
155
|
-
a broken one.
|
|
155
|
+
Run `brass login` to replace an expired session, or set a valid
|
|
156
|
+
`BRASS_SERVICE_TOKEN` for a rejected service token. A fresh checkout or a
|
|
157
|
+
fresh container has no session at all, which is the ordinary starting
|
|
158
|
+
state, not a broken one.
|
|
156
159
|
- **"Network error reaching <url>"** is the only error meaning the request
|
|
157
160
|
never completed. It names the host it tried.
|
|
158
161
|
- **Any other status** is a fault on the server side. The credential is
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,38 @@ 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.3.0
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- `brass logout` keeps your credentials and exits non-zero when it cannot
|
|
14
|
+
reach Brass, rather than clearing them and reporting success: only the
|
|
15
|
+
stored record can name the session to end. Run it again once you have a
|
|
16
|
+
connection. `--json` reports `signed_out: false`.
|
|
17
|
+
- `brass login --start --new` cancels the sign-in it replaces, so a code you
|
|
18
|
+
already handed to someone stops working.
|
|
19
|
+
|
|
20
|
+
## 0.2.0
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- `brass publish` waits for the platform to register the hosted slot before
|
|
25
|
+
reporting success, and fails when it never registers. The slot reaches the
|
|
26
|
+
serving edges shortly after that, so a URL the command reports can answer
|
|
27
|
+
404 for a few seconds before it serves.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- `brass logout` ends the sign-in on the server as well as on this machine, so
|
|
32
|
+
a copy of the credentials file left elsewhere stops working. It also cancels
|
|
33
|
+
a started sign-in this machine has not redeemed yet, so a code relayed to a
|
|
34
|
+
human cannot be approved and spent afterwards. When Brass cannot be reached,
|
|
35
|
+
the local credential is still cleared and the command says which half did not
|
|
36
|
+
happen; `--json` carries this as `revoked`.
|
|
37
|
+
- `brass publish --gate` states the load gate when it enables hosting, so a
|
|
38
|
+
publish that wants a world-loadable app no longer turns the gate on and
|
|
39
|
+
straight back off.
|
|
40
|
+
|
|
9
41
|
## 0.1.0
|
|
10
42
|
|
|
11
43
|
Initial public release. The `brass` command-line tool publishes apps and
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ app's built bundle and pulls document schemas. 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.
|
|
8
|
+
This package tracks the platform's `0.2.x` line.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -24,8 +24,8 @@ Two kinds of credential, for two audiences:
|
|
|
24
24
|
under `~/.config/brass/`. It authorizes everything, including `schema pull`.
|
|
25
25
|
- A **service token** (mint one in the dashboard: org Settings, then Service
|
|
26
26
|
tokens) is the CI credential, supplied as `BRASS_SERVICE_TOKEN`. It
|
|
27
|
-
authorizes `publish` and `whoami`. It is an org-scoped machine identity
|
|
28
|
-
|
|
27
|
+
authorizes `publish` and `whoami`. It is an org-scoped machine identity,
|
|
28
|
+
so it cannot fetch schemas.
|
|
29
29
|
|
|
30
30
|
```sh
|
|
31
31
|
npx @brass-build/cli login # developer: sign in with your browser
|
|
@@ -43,7 +43,7 @@ agent driving the sign-in), the flow splits in two: `brass login --start`
|
|
|
43
43
|
prints the approval URL and code and exits immediately, and
|
|
44
44
|
`brass login --check` checks that sign-in, storing the session once you have
|
|
45
45
|
approved. Add `--wait` to poll until you approve, for two minutes by default
|
|
46
|
-
or `--wait <seconds>` for a different bound
|
|
46
|
+
or `--wait <seconds>` for a different bound. A code that lapses inside the
|
|
47
47
|
wait is replaced and the new one printed, so a sign-in started long before it
|
|
48
48
|
is needed still completes. Reaching the bound with the code still good is
|
|
49
49
|
reported as `pending` and exits 0, so the next check picks the same sign-in
|
|
@@ -53,7 +53,9 @@ first. Both phases honor `--json` for a machine-readable result on stdout.
|
|
|
53
53
|
|
|
54
54
|
The CLI picks a credential most-explicit first: `--token <token>`, then
|
|
55
55
|
`BRASS_SERVICE_TOKEN`, then the stored `brass login` session. `brass logout`
|
|
56
|
-
forgets the stored
|
|
56
|
+
ends that session on the server and forgets it here. It keeps the stored
|
|
57
|
+
session and exits non-zero when it cannot reach Brass, so a retry can still
|
|
58
|
+
name the session to end.
|
|
57
59
|
|
|
58
60
|
```sh
|
|
59
61
|
export BRASS_SERVICE_TOKEN=brass_sk_...
|
|
@@ -74,10 +76,10 @@ resolved for this directory, and whether that app is deployed, then prints a
|
|
|
74
76
|
`Next:` line naming the exact next step (sign in, publish to create the app,
|
|
75
77
|
deploy, or open the live URL). When a `brass login --start` sign-in is waiting
|
|
76
78
|
for approval, it reports the code, the approval URL, and how long the code has
|
|
77
|
-
left. Run it before a publish to see what will
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
left. Run it before a publish to see what will happen, and after one to
|
|
80
|
+
confirm the app is live. `whoami` is the narrower check when you only need to
|
|
81
|
+
know the credential works. Add `--json` for the machine-readable result on
|
|
82
|
+
stdout.
|
|
81
83
|
|
|
82
84
|
## Publish
|
|
83
85
|
|
|
@@ -100,15 +102,18 @@ publishes then resolve the same app instead of creating a duplicate each run.
|
|
|
100
102
|
A service token creates the app in its own organization, so no `--org` is
|
|
101
103
|
needed.
|
|
102
104
|
|
|
103
|
-
The command enables hosting if needed, uploads the bundle, waits for
|
|
104
|
-
|
|
105
|
+
The command enables hosting if needed, uploads the bundle, waits for the
|
|
106
|
+
platform to register the slot, and reports the URL. The URL can answer 404
|
|
107
|
+
until the slot reaches the serving edges, so reload if the first request
|
|
108
|
+
misses. The platform reads your app's capabilities
|
|
105
109
|
(`opens` / `creates` / `schema`) from the `/.well-known/brass-app.json` you
|
|
106
110
|
serve, so keep that manifest in the bundle.
|
|
107
111
|
|
|
108
112
|
Flags: `--app`, `--name`, `--org` (organization to own a newly created app;
|
|
109
113
|
defaults to a service token's own org), `--client-token` (stable idempotency
|
|
110
114
|
key for a first create), `--slug` (preferred subdomain), `--manifest`
|
|
111
|
-
(default `brass-app.json`)
|
|
115
|
+
(default `brass-app.json`), `--visibility` (`private`, `invitee_visible` or
|
|
116
|
+
`public`), `--gate` (`on` or `off`, the hosted load gate).
|
|
112
117
|
|
|
113
118
|
## Pull a schema
|
|
114
119
|
|
|
@@ -122,8 +127,8 @@ npx @brass-build/cli schema pull --doc <docId> --out brass-app.json
|
|
|
122
127
|
This writes the document's schema body verbatim into the manifest's `schema`
|
|
123
128
|
field, preserving everything else. That is the same copy-verbatim step the
|
|
124
129
|
SDK's schema guide describes, done for you. It is a development-time action
|
|
125
|
-
that needs a signed-in session (`brass login`)
|
|
126
|
-
schemas.
|
|
130
|
+
that needs a signed-in session (`brass login`), since a service token cannot
|
|
131
|
+
fetch schemas.
|
|
127
132
|
|
|
128
133
|
## Pull your organization's agent instructions
|
|
129
134
|
|
|
@@ -134,13 +139,13 @@ AGENTS.md / CLAUDE.md), pull the current body into your repo:
|
|
|
134
139
|
npx @brass-build/cli agents pull --out AGENTS.md
|
|
135
140
|
```
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
on the dashboard Settings tab) so every developer's coding agent works
|
|
139
|
-
one source of truth. The pull writes the body verbatim, so it
|
|
140
|
-
byte-for-byte with what the dashboard stored.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
Brass stores the instructions once at the organization level (admins edit
|
|
143
|
+
them on the dashboard Settings tab) so every developer's coding agent works
|
|
144
|
+
from one source of truth. The pull writes the body verbatim, so it
|
|
145
|
+
round-trips byte-for-byte with what the dashboard stored. Pass
|
|
146
|
+
`--org <organizationId>` when you belong to more than one organization. This
|
|
147
|
+
needs a signed-in session (`brass login`), since a service token is not an
|
|
148
|
+
organization member and cannot read the instructions.
|
|
144
149
|
|
|
145
150
|
Pass `--stdout` instead of `--out` to print the instructions to stdout
|
|
146
151
|
without writing a file (status goes to stderr, so stdout carries only the
|
package/dist/api.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface HostingStatus {
|
|
|
17
17
|
deployed: boolean;
|
|
18
18
|
active_version: string | null;
|
|
19
19
|
require_access?: boolean;
|
|
20
|
+
gate_settled?: boolean;
|
|
20
21
|
}
|
|
21
22
|
export interface HostingUploadUrl {
|
|
22
23
|
upload_url: string;
|
|
@@ -60,6 +61,8 @@ export declare class BrassApiError extends Error {
|
|
|
60
61
|
readonly status: number;
|
|
61
62
|
constructor(status: number, message: string);
|
|
62
63
|
}
|
|
64
|
+
/** A failed fetch as the caller should read it, naming a timeout as one. */
|
|
65
|
+
export declare function networkError(what: string, cause: unknown): BrassApiError;
|
|
63
66
|
export declare class BrassApi {
|
|
64
67
|
private readonly apiBaseUrl;
|
|
65
68
|
private readonly auth;
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAO9C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAClD;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAErE,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAG9B,cAAc,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
CHANGED
|
@@ -15,6 +15,22 @@ export class BrassApiError extends Error {
|
|
|
15
15
|
this.status = status;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
// `fetch` carries no timeout of its own, so a host that accepts the connection
|
|
19
|
+
// and then answers nothing holds the command open for as long as the caller
|
|
20
|
+
// leaves it running. In CI that is a job that never finishes rather than a
|
|
21
|
+
// failure anyone can read, so every request the CLI makes is bounded.
|
|
22
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
23
|
+
// The upload carries the whole bundle, so it is bounded far more loosely than
|
|
24
|
+
// a request that carries a few hundred bytes.
|
|
25
|
+
const UPLOAD_TIMEOUT_MS = 300_000;
|
|
26
|
+
/** A failed fetch as the caller should read it, naming a timeout as one. */
|
|
27
|
+
export function networkError(what, cause) {
|
|
28
|
+
const timedOut = cause instanceof Error &&
|
|
29
|
+
(cause.name === 'TimeoutError' || cause.name === 'AbortError');
|
|
30
|
+
return new BrassApiError(0, timedOut
|
|
31
|
+
? `Timed out ${what}.`
|
|
32
|
+
: `Network error ${what}: ${String(cause)}`);
|
|
33
|
+
}
|
|
18
34
|
export class BrassApi {
|
|
19
35
|
apiBaseUrl;
|
|
20
36
|
auth;
|
|
@@ -34,7 +50,7 @@ export class BrassApi {
|
|
|
34
50
|
async request(method, path, body) {
|
|
35
51
|
const headers = {
|
|
36
52
|
...(await this.auth.headers()),
|
|
37
|
-
// Version telemetry; the
|
|
53
|
+
// Version telemetry; the platform logs it so pinned CI copies
|
|
38
54
|
// stay visible in the deployed-version distribution.
|
|
39
55
|
'x-brass-client': CLI_CLIENT_ID,
|
|
40
56
|
};
|
|
@@ -45,10 +61,13 @@ export class BrassApi {
|
|
|
45
61
|
}
|
|
46
62
|
let response;
|
|
47
63
|
try {
|
|
48
|
-
response = await fetch(`${this.apiBaseUrl}${path}`,
|
|
64
|
+
response = await fetch(`${this.apiBaseUrl}${path}`, {
|
|
65
|
+
...init,
|
|
66
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
67
|
+
});
|
|
49
68
|
}
|
|
50
69
|
catch (cause) {
|
|
51
|
-
throw
|
|
70
|
+
throw networkError(`reaching ${this.apiBaseUrl}`, cause);
|
|
52
71
|
}
|
|
53
72
|
if (!response.ok) {
|
|
54
73
|
throw new BrassApiError(response.status, await errorMessage(response));
|
|
@@ -58,10 +77,10 @@ export class BrassApi {
|
|
|
58
77
|
return (await response.json());
|
|
59
78
|
}
|
|
60
79
|
}
|
|
61
|
-
// Upload bytes to
|
|
62
|
-
// and no bearer: the presigned
|
|
63
|
-
//
|
|
64
|
-
//
|
|
80
|
+
// Upload bytes to the presigned storage URL the platform handed back.
|
|
81
|
+
// Deliberately carries NO Brass headers and no bearer: the presigned
|
|
82
|
+
// signature pins an exact header set, so a stray `authorization` header
|
|
83
|
+
// invalidates it and the upload is refused.
|
|
65
84
|
export async function putPresigned(url, bytes, contentType) {
|
|
66
85
|
let response;
|
|
67
86
|
try {
|
|
@@ -72,10 +91,11 @@ export async function putPresigned(url, bytes, contentType) {
|
|
|
72
91
|
// `ArrayBufferLike` is sound and satisfies fetch's `BufferSource`
|
|
73
92
|
// (which pins `ArrayBufferView<ArrayBuffer>`) across lib configs.
|
|
74
93
|
body: bytes,
|
|
94
|
+
signal: AbortSignal.timeout(UPLOAD_TIMEOUT_MS),
|
|
75
95
|
});
|
|
76
96
|
}
|
|
77
97
|
catch (cause) {
|
|
78
|
-
throw
|
|
98
|
+
throw networkError('uploading the bundle', cause);
|
|
79
99
|
}
|
|
80
100
|
if (!response.ok) {
|
|
81
101
|
throw new BrassApiError(response.status, `Bundle upload failed (${response.status})`);
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,yEAAyE;AACzE,2EAA2E;AAC3E,mEAAmE;AAGnE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,yEAAyE;AACzE,2EAA2E;AAC3E,mEAAmE;AAGnE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAiG7C,yEAAyE;AACzE,6EAA6E;AAC7E,8CAA8C;AAC9C,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,MAAM,CAAS;IACxB,YAAY,MAAc,EAAE,OAAe;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,sEAAsE;AACtE,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,8EAA8E;AAC9E,8CAA8C;AAC9C,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAElC,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAAc;IACvD,MAAM,QAAQ,GACZ,KAAK,YAAY,KAAK;QACtB,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;IACjE,OAAO,IAAI,aAAa,CACtB,CAAC,EACD,QAAQ;QACN,CAAC,CAAC,aAAa,IAAI,GAAG;QACtB,CAAC,CAAC,iBAAiB,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAC9C,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,QAAQ;IACF,UAAU,CAAS;IACnB,IAAI,CAAe;IAEpC,YAAY,UAAkB,EAAE,IAAkB;QAChD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,GAAG,CAAI,IAAY;QACjB,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,CAAI,IAAY,EAAE,IAAc;QAClC,OAAO,IAAI,CAAC,OAAO,CAAI,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,KAAK,CAAI,IAAY,EAAE,IAAc;QACnC,OAAO,IAAI,CAAC,OAAO,CAAI,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,MAAc,EAAE,IAAY,EAAE,IAAc;QACnE,MAAM,OAAO,GAA2B;YACtC,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9B,8DAA8D;YAC9D,qDAAqD;YACrD,gBAAgB,EAAE,aAAa;SAChC,CAAC;QACF,IAAI,IAAI,GAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC5C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,CAAC;QACD,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,EAAE,EAAE;gBAClD,GAAG,IAAI;gBACP,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;aAChD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,CAAC,YAAY,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,SAAc,CAAC;QACnD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;IACtC,CAAC;CACF;AAED,sEAAsE;AACtE,qEAAqE;AACrE,wEAAwE;AACxE,4CAA4C;AAC5C,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAW,EACX,KAAiB,EACjB,WAAmB;IAEnB,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC1B,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE;YACxC,qEAAqE;YACrE,kEAAkE;YAClE,kEAAkE;YAClE,IAAI,EAAE,KAAgC;YACtC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC;SAC/C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACxF,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,8DAA8D;AAC9D,KAAK,UAAU,YAAY,CAAC,QAAkB;IAC5C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;QAC5D,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;IACD,OAAO,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC;AACzD,CAAC"}
|
package/dist/args.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
export interface ParsedArgs {
|
|
2
2
|
positionals: string[];
|
|
3
3
|
flags: Record<string, string | true>;
|
|
4
|
+
valuedBooleans: string[];
|
|
4
5
|
}
|
|
5
6
|
export declare function unknownFlags(parsed: ParsedArgs): string[];
|
|
7
|
+
export declare function flagsNotReadBy(parsed: ParsedArgs, command: string): string[];
|
|
8
|
+
export declare function extraPositionals(parsed: ParsedArgs, command: string): string[];
|
|
9
|
+
export declare function valueFlagsOf(command: string): string[];
|
|
6
10
|
export declare function valuelessFlags(parsed: ParsedArgs, names: readonly string[]): string[];
|
|
7
11
|
export declare function parseArgs(argv: readonly string[]): ParsedArgs;
|
|
8
12
|
export declare function stringFlag(parsed: ParsedArgs, name: string): string | undefined;
|
package/dist/args.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/args.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
// A minimal argv parser: no dependency, and small enough to unit-test the
|
|
2
2
|
// exact precedence the commands rely on. Supports `--flag value`,
|
|
3
3
|
// `--flag=value`, and boolean `--flag`; everything else is a positional.
|
|
4
|
-
// Flags that never take a value, so `brass
|
|
5
|
-
// `./
|
|
4
|
+
// Flags that never take a value, so `brass agents pull --stdout ./dir` parses
|
|
5
|
+
// `./dir` as a positional rather than the value of `--stdout`.
|
|
6
6
|
const BOOLEAN_FLAGS = new Set([
|
|
7
7
|
'json',
|
|
8
|
-
'yes',
|
|
9
8
|
'help',
|
|
10
9
|
'version',
|
|
11
10
|
'stdout',
|
|
@@ -41,17 +40,95 @@ const KNOWN_FLAGS = new Set([
|
|
|
41
40
|
export function unknownFlags(parsed) {
|
|
42
41
|
return Object.keys(parsed.flags).filter((name) => !KNOWN_FLAGS.has(name));
|
|
43
42
|
}
|
|
43
|
+
// The flags every command reads, whichever it is: where to talk to and what
|
|
44
|
+
// to print.
|
|
45
|
+
const COMMON_FLAGS = [
|
|
46
|
+
'api-url',
|
|
47
|
+
'auth-url',
|
|
48
|
+
'dashboard-url',
|
|
49
|
+
'help',
|
|
50
|
+
'json',
|
|
51
|
+
'version',
|
|
52
|
+
];
|
|
53
|
+
// What each command reads beyond those, and how many positionals it takes
|
|
54
|
+
// (the command word included, so `publish [dir]` is 2). A flag one command
|
|
55
|
+
// reads is not thereby a flag of the next: `--wait` is the sign-in poll's
|
|
56
|
+
// deadline and `publish` has its own, so `brass publish --wait 600` waits
|
|
57
|
+
// exactly as long as it would have without the flag. Refusing it names the
|
|
58
|
+
// mistake, where accepting it leaves the caller believing they set something.
|
|
59
|
+
const COMMAND_ARGS = {
|
|
60
|
+
login: { flags: ['check', 'new', 'start', 'wait'], positionals: 1 },
|
|
61
|
+
logout: { flags: [], positionals: 1 },
|
|
62
|
+
status: { flags: ['app', 'manifest', 'token'], positionals: 2 },
|
|
63
|
+
publish: {
|
|
64
|
+
flags: [
|
|
65
|
+
'app',
|
|
66
|
+
'client-token',
|
|
67
|
+
'gate',
|
|
68
|
+
'manifest',
|
|
69
|
+
'name',
|
|
70
|
+
'org',
|
|
71
|
+
'slug',
|
|
72
|
+
'token',
|
|
73
|
+
'visibility',
|
|
74
|
+
],
|
|
75
|
+
positionals: 2,
|
|
76
|
+
},
|
|
77
|
+
schema: { flags: ['doc', 'out', 'token'], positionals: 2 },
|
|
78
|
+
agents: { flags: ['org', 'out', 'stdout', 'token'], positionals: 2 },
|
|
79
|
+
whoami: { flags: ['token'], positionals: 1 },
|
|
80
|
+
};
|
|
81
|
+
// The flags `command` does not read, out of the ones this CLI knows. A name
|
|
82
|
+
// the CLI knows nowhere is `unknownFlags`' answer and stays there, so a
|
|
83
|
+
// misspelling is reported as one rather than as a flag of another command.
|
|
84
|
+
// A command this CLI does not have answers for itself.
|
|
85
|
+
export function flagsNotReadBy(parsed, command) {
|
|
86
|
+
const spec = COMMAND_ARGS[command];
|
|
87
|
+
if (spec === undefined)
|
|
88
|
+
return [];
|
|
89
|
+
const reads = new Set([...COMMON_FLAGS, ...spec.flags]);
|
|
90
|
+
return Object.keys(parsed.flags).filter((name) => KNOWN_FLAGS.has(name) && !reads.has(name));
|
|
91
|
+
}
|
|
92
|
+
// The positionals past the ones `command` reads. An ignored one is the same
|
|
93
|
+
// silence a flag no command reads leaves: `brass publish out dist` publishes
|
|
94
|
+
// `out`, and the caller who meant `dist` is told nothing.
|
|
95
|
+
export function extraPositionals(parsed, command) {
|
|
96
|
+
const spec = COMMAND_ARGS[command];
|
|
97
|
+
if (spec === undefined)
|
|
98
|
+
return [];
|
|
99
|
+
return parsed.positionals.slice(spec.positionals);
|
|
100
|
+
}
|
|
101
|
+
// The flags of `command` that carry a value, so a bare one is the caller
|
|
102
|
+
// naming something the run then resolves a default for. `--wait` is absent
|
|
103
|
+
// here because a bare `--wait` is its own answer (the default deadline).
|
|
104
|
+
export function valueFlagsOf(command) {
|
|
105
|
+
const spec = COMMAND_ARGS[command];
|
|
106
|
+
if (spec === undefined)
|
|
107
|
+
return [];
|
|
108
|
+
return [...COMMON_FLAGS, ...spec.flags].filter((name) => !BOOLEAN_FLAGS.has(name) && name !== 'wait');
|
|
109
|
+
}
|
|
44
110
|
// Which of `names` were given without a value (`--api-url --json`, or
|
|
45
111
|
// `--api-url` last on the line). The parser stores those as `true` and
|
|
46
112
|
// `stringFlag` reads that as absent, so an origin flag in this state resolves
|
|
47
113
|
// the production default while the command line names another stack. That is
|
|
48
114
|
// the same silent retarget `unknownFlags` catches for a misspelled name.
|
|
115
|
+
//
|
|
116
|
+
// An EMPTY value counts, and it is the shape a caller actually reaches: a
|
|
117
|
+
// script writing `--slug "$SLUG"` against an unset variable passes the flag
|
|
118
|
+
// with nothing behind it. That value is not absent the way a bare flag is, so
|
|
119
|
+
// it resolves no default and travels to the server as an empty string, where
|
|
120
|
+
// the mistake is reported (if at all) in the server's vocabulary rather than
|
|
121
|
+
// as the missing value it is.
|
|
49
122
|
export function valuelessFlags(parsed, names) {
|
|
50
|
-
return names.filter((name) =>
|
|
123
|
+
return names.filter((name) => {
|
|
124
|
+
const value = parsed.flags[name];
|
|
125
|
+
return value === true || value === '';
|
|
126
|
+
});
|
|
51
127
|
}
|
|
52
128
|
export function parseArgs(argv) {
|
|
53
129
|
const positionals = [];
|
|
54
130
|
const flags = {};
|
|
131
|
+
const valuedBooleans = [];
|
|
55
132
|
for (let i = 0; i < argv.length; i++) {
|
|
56
133
|
const arg = argv[i];
|
|
57
134
|
if (arg === undefined)
|
|
@@ -60,7 +137,16 @@ export function parseArgs(argv) {
|
|
|
60
137
|
const body = arg.slice(2);
|
|
61
138
|
const eq = body.indexOf('=');
|
|
62
139
|
if (eq !== -1) {
|
|
63
|
-
|
|
140
|
+
const name = body.slice(0, eq);
|
|
141
|
+
if (BOOLEAN_FLAGS.has(name)) {
|
|
142
|
+
// Recorded rather than read: `--json=false` reads as ON, which is
|
|
143
|
+
// the reverse of what the caller wrote, and `--stdout=false` would
|
|
144
|
+
// send a file's contents to stdout and write nothing.
|
|
145
|
+
valuedBooleans.push(name);
|
|
146
|
+
flags[name] = true;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
flags[name] = body.slice(eq + 1);
|
|
64
150
|
continue;
|
|
65
151
|
}
|
|
66
152
|
if (BOOLEAN_FLAGS.has(body)) {
|
|
@@ -80,7 +166,7 @@ export function parseArgs(argv) {
|
|
|
80
166
|
positionals.push(arg);
|
|
81
167
|
}
|
|
82
168
|
}
|
|
83
|
-
return { positionals, flags };
|
|
169
|
+
return { positionals, flags, valuedBooleans };
|
|
84
170
|
}
|
|
85
171
|
// Read a flag expected to carry a string value; a bare boolean flag (no
|
|
86
172
|
// value) is treated as absent so `--doc` alone doesn't resolve to `true`.
|
package/dist/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,kEAAkE;AAClE,yEAAyE;
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA6CA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,CAAC;AA2CnB,wBAAsB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmGlE"}
|