Commit d52fb27
Autogenerate CLI (#1205)
* cli updates - autogeneration
* Fix Prettier formatting for gitbook2 CLI
Wrap the hand-written CLI source to the repo's printWidth, and exclude the
auto-generated generated-commands.ts from Prettier (it's regenerated on every
build, so formatting it would just be undone).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Regenerate gitbook2 CLI from latest API spec (346 endpoints)
Regenerate generated-commands.ts from the latest deployed OpenAPI spec
(@gitbook/api 0.186.0), adding 5 new endpoints: change-request agent
conversations (list/update/delete), change-request content update, and
site Git Sync installations listing.
Also use bracket-notation accessors for query-param options so flag names
that aren't valid JS identifiers resolve correctly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Port integration lifecycle + openapi publish commands to gitbook2
Bring the non-autogenerated commands from the `gitbook` CLI into `gitbook2`
so it's a functional superset. The integration build/publish lifecycle
commands (new/dev/publish/unpublish/tail/check) are grouped under a singular
`integration` command to stay distinct from the spec-generated `integrations`
group (raw API ops); `openapi publish` is registered top-level. All reuse the
existing shared source modules via registerCustomCommands.
cli2.ts gains a keep-alive guard so `integration dev` doesn't get torn down
by the post-parse process.exit(0).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix empty-body response handling in generated CLI commands
The generated commands hardcoded `if (response.status !== 204)` before
calling response.json(), assuming 204 was the only bodyless success. Endpoints
that return another no-body status (e.g. DELETE openapi spec returns 205 on
deletion, 204 only when absent) hit response.json() on an empty body and failed
with "Unexpected end of JSON input", exiting 1 despite the server-side success.
Key off body presence instead of a specific status, which covers 204, 205, and
any future bodyless success with no regression for JSON responses. Regenerated
all 339 commands.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix array/number body flags in generated CLI commands
The command generator turned each top-level body field into a typed flag
but assigned the raw commander string into the JSON body with no coercion,
so --changes '[...]' shipped {"changes":"[...]"} (a string) and the API
rejected it. Same for --users and any number-typed field.
- Add coerceBodyFlag() to output.ts (unit-tested): JSON-parses array flags,
numeric-coerces number flags, passes string/boolean through, with legible
errors surfaced by the CLI's top-level handler.
- Generator emits coerceBodyFlag(...) for array/number flags and renders
array flags as <json> with a [JSON array] hint.
- Always offer --body <json> alongside typed flags as an escape hatch
(typed flags merge on top), so object-typed fields dropped by
flattenObjectFlags stay reachable.
- Regenerate generated-commands.ts; add coerceBodyFlag tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Add hidden, deprecation-warning top-level aliases for integration verbs
Make gitbook2 a backward-compatible superset of the original `gitbook` CLI:
the integration lifecycle verbs (new/dev/publish/unpublish/tail/check) are now
also reachable via their historical top-level spelling, in addition to the
canonical `integration <verb>` group.
- Factor each lifecycle command's argument/option wiring and action handler into
a shared LIFECYCLE_COMMANDS table so both mounts stay in sync (no duplication).
- The top-level aliases are hidden from help and print a deprecation warning to
stderr (never stdout) before delegating to the same handler.
- The warning derives the binary name from program.name() rather than hardcoding
"gitbook2", so it follows the eventual rename to "gitbook" automatically.
No namespace collisions: auth/whoami/openapi-publish already exist at identical
paths and are left untouched; the six verbs don't clash with any generated group.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Apply Prettier formatting to api-commands.ts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Add usage attribution to the CLI User-Agent
Set a distinct, convention-matching User-Agent (`GitBook-CLI/<version>`,
matching GitBook-Open / GitBook-MCP-Server) and fold the invoked command
path into it, so API requests can be attributed to a specific CLI command
in logs / the GCP per-endpoint dashboard — no per-request plumbing.
- remote.ts: UA base is now `GitBook-CLI/<version>`; getAPIClient takes an
optional command path and emits `GitBook-CLI/<version> (<command>)`. auth
and whoami pass their command names.
- generate-commands.ts: each generated action passes its dotted command path
(e.g. spaces.change-requests.content.update) to getAPIClient.
- generated-commands.ts: regenerated.
Verified on the wire: e.g. `GitBook-CLI/0.28.0 (spaces.change-requests.comments.list)`.
* gitbook2: fix array query params, add whoami JSON, richer help, markdown --normalize
Addresses the CLI-side follow-ups from the review-flow notes:
- Array query params (e.g. `comments list --authors`) were serialized with
String(), flattening them to a single value the API rejected with a 500.
Resolve each query param's schema and route `type: array` params through a new
coerceArrayQueryParam (accepts CSV or a JSON array) so the client emits repeated
`key=v1&key=v2`. query is now Record<string, string | string[]>.
- whoami gained --json/--yaml, so scripts can read their own user id
(`whoami --json | jq -r .id`) instead of parsing the plain `ID:` line.
- --help now documents enum query params (e.g. --orderBy: one of updatedAt,
createdAt) and the operations of a discriminated-oneOf array flag (e.g.
--changes: update_page, insert_page, delete_page), both derived from the spec.
- Schema-union 422s ("expected to match one") get an actionable hint naming the
accepted shape (update_page.document wants {markdown}, insert_page.into optional)
via explainApiError.
- New opt-in --normalize on page-document commands makes markdown round-trip safe
before sending: strips a duplicated leading H1 title and collapses multi-line
{% ... %} integration blocks onto one line. Detected generically from the spec
(array items whose variants carry a `document`).
Unit tests added for the four new output helpers; generated-commands.ts regenerated.
* CLI: address review feedback on autogenerated commands
- Read the OpenAPI spec from openapi.json (drop js-yaml parse)
- Stop tracking generated-commands.ts; gitignore it (regenerated by prebuild)
- Send a plain GitBook-CLI/<version> User-Agent (drop per-command attribution)
- Call the generated typed client methods (api.<ns>.<operationId>) instead of
raw api.request(); use response.data instead of JSON.parse(response.text())
- Skip SSE (text/event-stream) operations: their typed methods return an
EventIterator that doesn't fit the one-response-per-command model
* CLI: add browser OAuth login and make gitbook the autogenerated CLI
- Add 'gitbook login'/'logout' for browser-based OAuth (DCR + PKCE +
loopback redirect) with automatic token refresh. OAuth session and a
personal API token can coexist: OAuth drives API commands, the token is
used/required for publishing integrations.
- Replace the gitbook CLI with the autogenerated (gitbook2) implementation
and remove the separate gitbook2 binary. Integration lifecycle commands
are now 'gitbook integration <verb>', with the historical top-level
spellings kept as deprecated aliases.
- Regenerate shell completions and update docs/changesets accordingly.
* CLI: add prepack to guarantee codegen + build before publish
Ensures 'npm publish'/'changeset publish' always regenerate the
spec-derived commands and bundle dist/cli.js, even when the publish path
doesn't go through 'turbo run build'.
* CLI: fix formatting in output.test.ts
* CI: require a @gitbook/cli changeset when @gitbook/api is bumped
The gitbook CLI generates its commands from the API OpenAPI spec, so an
@gitbook/api bump should also republish the CLI. Adds a 'Changeset guard'
workflow that fails a PR bumping @gitbook/api without a pending
@gitbook/cli changeset, and documents the one-line step in CONTRIBUTING.
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>1 parent 777421c commit d52fb27
21 files changed
Lines changed: 2966 additions & 199 deletions
File tree
- .changeset
- .github
- workflows
- docs/cli
- packages/cli
- src
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
46 | 65 | | |
47 | 66 | | |
48 | 67 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
16 | 20 | | |
17 | 21 | | |
18 | | - | |
| 22 | + | |
19 | 23 | | |
20 | 24 | | |
| 25 | + | |
| 26 | + | |
21 | 27 | | |
22 | 28 | | |
23 | 29 | | |
24 | 30 | | |
25 | 31 | | |
26 | | - | |
| 32 | + | |
27 | 33 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
7 | 19 | | |
8 | 20 | | |
9 | 21 | | |
10 | 22 | | |
11 | 23 | | |
12 | 24 | | |
13 | | - | |
| 25 | + | |
14 | 26 | | |
15 | 27 | | |
16 | 28 | | |
17 | | - | |
| 29 | + | |
18 | 30 | | |
19 | 31 | | |
20 | 32 | | |
21 | 33 | | |
22 | 34 | | |
23 | | - | |
| 35 | + | |
24 | 36 | | |
25 | 37 | | |
26 | 38 | | |
27 | 39 | | |
28 | 40 | | |
29 | | - | |
| 41 | + | |
30 | 42 | | |
31 | 43 | | |
32 | 44 | | |
| 45 | + | |
| 46 | + | |
33 | 47 | | |
34 | 48 | | |
35 | 49 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
0 commit comments