CLI: generator internals — path-param flags, streaming endpoints, OAuth scope fallback (RND-12046, RND-12044, RND-12043)#1247
Merged
Merged
Conversation
Shell completion was generated purely from the spec-derived command tree, so the hand-written groups' subcommands never tab-completed. Add a static HAND_WRITTEN_COMPLETIONS map (integration -> new/dev/publish/unpublish/tail/check, openapi -> publish) merged into the completion map before the scripts are emitted.
…D-12047, RND-12053) - Append a "Command groups (nested)" section to every group's --help so nested subgroups (e.g. organizations sites) are discoverable without drilling in. Root uses a compact one-line-per-group layout; subgroup pages use an indented tree. Attached generically by walking the Commander tree at runtime. - Sort subcommands alphabetically (built-in list via configureHelp + the tree). - Point `gitbook integrations --help` at the singular `gitbook integration` group for the build/publish lifecycle (new/dev/publish/...).
Generated commands now register each OpenAPI path parameter as an optional positional AND a --<name> flag. The positional wins when both are supplied. Missing params produce a helpful error showing both invocation forms.
Streaming operations are no longer skipped by the generator; they are tagged and emitted via a dedicated path that iterates the EventIterator through a new StreamRenderer in output.ts. Machine modes stream one record per event (NDJSON for --json, a YAML document stream for --yaml); pretty mode renders recommended questions live, answer text incrementally, agent-response events as status lines, and sources as end-of-stream citations. SIGINT flushes and exits 130; a mid-flight error surfaces after the partial output. Adds renderer unit tests. Commands (mechanical naming, each mirrors its URL and sits beside its buffered sibling): organizations ask stream, organizations ask questions stream, organizations sites ask stream, organizations sites ask questions stream, organizations sites ai response stream.
… (RND-12043) gitbook login already requests scopes from the OAuth server's .well-known discovery metadata (environment-correct), not a hardcoded list. This adds the spec's oauth securityScheme scopes as a generated fallback (generate-commands.ts now also emits generated-oauth-scopes.ts), used only when discovery's scopes_supported is absent — so login never silently requests zero scopes. The OAuth endpoint stays runtime-derived (the bundled spec is prod-only).
Generated commands (buffered, merged, and streaming) now abort a request that produces no response — for streams, no next event — within CLI_TIMEOUT_MS (default 60s, override via GITBOOK_CLI_TIMEOUT_MS, 0 disables), so the CLI fails loudly with explainTimeout() instead of hanging on an unresponsive endpoint. The stream timer resets on each event so a slow-but-live response is not cut off. Adds createRequestTimeout/explainTimeout to output.ts with unit tests.
🦋 Changeset detectedLatest commit: a0d58b0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
talagluck
marked this pull request as ready for review
July 16, 2026 17:52
…nswer The ask endpoints default `format` to `document` (a structured tree the pretty renderer can't turn into text), so a plain `ask stream` printed only the sources with no answer body. Default `format` to markdown when the user hasn't set it; `--format document` still gets the raw form. Verified end-to-end against a live site: the answer now streams in pretty mode without any extra flag.
Adds documentToText to flatten a GitBook document node tree to plain text, so `ask stream --format document` (and any answer that arrives as a document rather than a markdown string) still shows the answer body in pretty mode instead of only the sources. Marks are dropped; it's a legible fallback, not a full markdown serializer. Verified live + unit-tested.
spastorelli
approved these changes
Jul 17, 2026
Addresses review feedback: the pretty renderer no longer sniffs event shapes in one monolith. createStreamRenderer now owns only the generic mechanics (NDJSON/ YAML serialization, the sink + mid-line tracking, end-of-stream flush) and delegates per-event rendering to an injectable StreamEventRenderer. The three schemas get dedicated strategies (answer / question / agent-response) plus a generic fallback; the generator selects one per endpoint from the SSE response's event schema (STREAM_RENDERERS), so a new/changed schema means a new strategy at the call site rather than editing the core.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bucket 1 of the
mcp-clifollow-ups from #1205 — the generator-internals cluster. Stacked oncli-help-discoverability(#1245, bucket 2); retarget tomainonce that merges.RND-12046 — path params as positionals and
--flagsGenerated commands now register each OpenAPI path parameter as an optional positional and a
--<name>flag; the positional wins when both are given. Missing params produce a clear error showing both invocation forms. Applied uniformly via a newemitCommandPreambleshared by the simple and streaming emitters.RND-12044 — the 5 SSE streaming endpoints
Streaming ops are no longer skipped by the generator — they're tagged (
Route.isStreaming) and emitted via a dedicated path that iterates theEventIteratorthrough a newStreamRendererinoutput.ts:--json→ NDJSON (one object per line);--yaml→ a----delimited YAML document streamCommands (mechanical naming, each mirrors its URL and sits beside its buffered sibling):
organizations ask stream,organizations ask questions stream,organizations sites ask stream,organizations sites ask questions stream,organizations sites ai response stream.RND-12043 — OAuth scopes from the spec (as a fallback)
The premise was stale:
gitbook loginalready requests scopes from the OAuth server's.well-knowndiscovery metadata (environment-correct), not a hardcoded list. This adds the spec'soauthsecurityScheme scopes as a generated fallback (generated-oauth-scopes.ts), used only when discovery omitsscopes_supported, so login never silently requests zero scopes. The OAuth endpoint stays runtime-derived (the bundled spec is prod-only).Idle request timeout (follow-on from testing)
All generated commands (buffered, merged, streaming) now abort a request that produces no response — for streams, no next event — within
CLI_TIMEOUT_MS(default 60s,GITBOOK_CLI_TIMEOUT_MSto override,0disables). The stream timer resets per event so a slow-but-live response isn't cut off. This came out of testing: the org-level AIaskendpoints were observed hanging server-side (rawcurl -i -Nreturns no HTTP status), so the CLI now fails loudly instead of hanging.Testing
bun run generate-commands,tsc --noEmit,./build.sh,bun test(49 pass) all clean.🤖 Generated with Claude Code