@xyd-js/opencli2go
v0.0.0-build-f0c10f6-20260703195526
Published
Generate a buildable Go CLI (urfave/cli v3) from an OpenCLI document with the x-openapi request binding
Readme
@xyd-js/opencli2go
Generates a buildable, functional Go CLI (urfave/cli v3)
from an OpenCLI document (@xyd-js/opencli). It reads the x-openapi
request binding (emitted by @xyd-js/openapi2opencli) so the
generated commands make real API requests — not stubs.
import { opencli2go, writeProject } from '@xyd-js/opencli2go';
const files = opencli2go(opencliDoc, { binName: 'openai' }); // pure: { path -> contents }
await writeProject(files, './out'); // the only fs-touching stepOutput (mirrors openai-cli's layout)
go.mod
cmd/<bin>/main.go # root cli.Command{ Commands: [...] } + app.Run
pkg/cmd/<resource>.go # one per top-level command; New<Resource>Command() + handlers
internal/runtime/runtime.go # generic HTTP client (vendored verbatim)
internal/runtime/config.go # generated: base URL + auth from x-openapiHow it works
A templated emitter (fern's CLI-generator pattern), not a Go AST:
- The recursive
cli.Commandtree + typed flags are rendered with small Go-literal string helpers; imports are a fixed/known set per file. - Each leaf handler is generated from
x-openapi: positional path params →url.PathEscape, query params →url.Values, body flags → amap[string]anymarshalled to JSON (encodings:int/float/bool/[]string/nested-json), thenruntime.Do(ctx, req). - Flag types follow the encoding:
cli.StringFlag/IntFlag/FloatFlag/BoolFlag/StringSliceFlag. internal/runtimeis a small generic HTTP client;config.gobakes the base URL (overridable via<BIN>_BASE_URL) andapplyAuth(bearer / apiKey-header / apiKey-query / apiKey-cookie / basic), reading credentials from the env var named inx-openapi.security.
opencli2go is pure (returns a file map); writeProject does the disk IO.
Options
binName (default slug(info.title)), modulePath (default example.com/<binName>),
goVersion (default 1.22), baseURL (default first x-openapi.servers).
Tests
Golden multi-file fixtures under __fixtures__/<n>/ (input.json OpenCLI → output/ Go tree):
pnpm --filter @xyd-js/opencli2go test # assert against committed goldens (no Go needed)
REGEN=1 pnpm --filter @xyd-js/opencli2go test # regenerate the output/ trees
O2G_GO_SMOKE=1 pnpm --filter @xyd-js/opencli2go test # opt-in: go mod tidy && go build ./... && go vet ./...Known limits (v1)
- Positional args are read via
cmd.Args().Get(i)(functional) rather than declaredcli.Arguments; declaring typed args (for--helpsurface parity with openai-cli) is a Milestone-3 refinement validated against the oracle. multipart/form-datafile uploads pass the file path through (not yet streamed).- The runtime is generic (untyped JSON in/out); typed response models are future work.
