feat(agent-bff): emit the OpenAPI document from a forest-bff openapi subcommand - #1811
Open
Tonours wants to merge 1 commit into
Open
Conversation
1 new issue
|
Tonours
force-pushed
the
feature/prd-886-openapi-static-document
branch
from
August 6, 2026 20:48
ece634c to
b11c332
Compare
Tonours
force-pushed
the
feature/prd-887-openapi-cli-export
branch
3 times, most recently
from
August 6, 2026 21:01
92ca6d4 to
4312e31
Compare
Tonours
force-pushed
the
feature/prd-887-openapi-cli-export
branch
from
August 7, 2026 07:28
4312e31 to
bacd081
Compare
|
Coverage Impact This PR will not change total coverage. Modified Files with Diff Coverage (1)
🛟 Help
|
Tonours
force-pushed
the
feature/prd-886-openapi-static-document
branch
from
August 7, 2026 07:42
d51081e to
9652148
Compare
Tonours
force-pushed
the
feature/prd-887-openapi-cli-export
branch
from
August 7, 2026 07:42
bacd081 to
db6ff62
Compare
Tonours
force-pushed
the
feature/prd-886-openapi-static-document
branch
from
August 7, 2026 13:01
9652148 to
ec8c3e0
Compare
Tonours
force-pushed
the
feature/prd-887-openapi-cli-export
branch
6 times, most recently
from
August 7, 2026 15:38
f078ea2 to
56858d7
Compare
Tonours
force-pushed
the
feature/prd-887-openapi-cli-export
branch
from
August 7, 2026 16:03
56858d7 to
04f7775
Compare
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.

Stacked on #1810 (
feature/prd-886-openapi-static-document), which is itself stacked on #1809. The base is #1810's branch, notmain: both parents must be reviewed and merged first, in order (#1809, then #1810, then this). The diff below is only this branch's commit.Adds
forest-bff openapi: writes the OpenAPI document to stdout, or to a file with--output, without booting the server.fixes PRD-887
Why a CLI at all
GET /agent/openapi.jsonis auth-gated, so a CI job, a codegen step, or a client dev without credentials has no HTTP path to the document. The CLI is that path. It needs no configuration:argv contract
Previously
forest-bff <anything>ignored argv and booted the server. Now argv is parsed:forest-bffforest-bff openapiforest-bff openapi --output [path]forest-bff --help/-hforest-bff --version/-vforest-bff bogusforest-bff openapi extra--helpand--versionprint to stdout, exit 0, and ignore what follows them: GNU tools treat a help request as a success, never an error.openapiis the strict one, because a typo there would otherwise produce a wrong export instead of a message.A deployment that passed a stray flag and silently got a server will now fail on upgrade. The repo's own
startscripts pass no arguments.--output parsing
The token after
--outputis the destination only when it exists, is non-empty, and does not start with-. Otherwise the defaultopenapi.jsonapplies and the leftover token is rejected as an extra. Soopenapi --output --helpexits 1 and writes nothing, rather than creating a file named--help.Extras are validated before any write, so an invalid command line never leaves an artifact behind.
--output=pathand a repeated--outputare rejected the same way.A missing parent directory is created. An existing file is overwritten, like
>and every codegen exporter. An unwritable destination exits 1 withCannot write <path>: <reason>, no stack trace.The success line goes to stderr, not stdout:
--outputmust leave stdout empty so the no-flag form stays pipeable, and so a CI job can keep redirecting without catching a log line.Stdout purity
An export piped to a file must contain only the document. This is easy to break silently:
createConsoleLoggersendsInfotoconsole.info, which writes to stdout. Any future log on the export path would corrupt every pipe without failing anything.Verified rather than assumed: a test pins one single
process.stdout.writecall and assertsconsole.infois never reached. The export path never callsparseConfig, never constructs a logger, never binds a socket, andprocess.exitCodeis set instead of callingprocess.exit(), so a slow pipe cannot truncate the write.Scope and safety
The no-argv path is untouched: same
runCli, same config parsing, same middleware chain. Hand-rolled argv switch in its owncli-dispatch.ts, no arg-parsing dependency.openapi.jsonis added to.gitignore:--outputhas a default filename, and a dev running it from the package would otherwise commit the artifact by accident.How to test
Ran on this branch: 809 tests pass (777 before, 32 added), lint and build clean.
An end-to-end script drove the packaged binary through 40 checks, all passing: every argv path with its exit code and stream, the export under an empty environment, byte equality between the CLI export and the body the route serves, no socket bound, no truncation through a real pipe and a real redirect,
--outputwriting the default name and an explicit path, a created parent directory, a dash token refused as a filename, and a directory destination failing with its path named.Known limitations
DispatchOutcome.exitCodeis typednumberand the type admits{exitCode: 1, server}, a combination the code never produces. Harmless today since the only consumer readsexitCodealone.--outputwrites withwriteFileSync, which truncates before writing. A mid-write failure such asENOSPCleaves a partial file, same as>andcurl -o.Definition of Done
General
Security