diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml new file mode 100644 index 000000000..c907b0e68 --- /dev/null +++ b/.github/workflows/release-cli.yml @@ -0,0 +1,36 @@ +name: Release CLI + +on: + workflow_call: + inputs: + version: + description: CLI version to generate (opens a pull request; does not publish) + required: true + type: string + workflow_dispatch: + inputs: + version: + description: CLI version to generate (opens a pull request; does not publish) + required: true + type: string + +permissions: + contents: read + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: actions/setup-node@v4 + with: + node-version: 22 + - name: Install Fern + run: npm install -g fern-api + - name: Generate CLI pull request + env: + FERN_TOKEN: ${{ secrets.FERN_TOKEN }} + CLI_VERSION: ${{ inputs.version }} + run: fern generate --api cli --group cli-sdk --version "$CLI_VERSION" --mode pull-request --log-level debug diff --git a/advanced.md b/advanced.md index a9387a919..71b986934 100644 --- a/advanced.md +++ b/advanced.md @@ -45,6 +45,33 @@ This will generate the SDK and download it to a local folder that can be pip ins pip install -e /fern/.preview/fern-python-sdk ``` +## Managing the CLI + +The `cli-sdk` group in `fern/apis/cli/generators.yml` generates `VapiAI/cli` +from the same OpenAPI definition, naming overrides, and parameter-description +overlay as the server SDKs. Its separate API workspace adds public-client +OAuth with PKCE and a staging default server; the other SDK groups retain their +existing authentication. Promote the CLI issuer, public client, resource and +server together after live OAuth acceptance. + +Run **Release CLI** with an explicit version to open a generated CLI pull +request, just like the SDK release workflows. Generation does not publish a +package. Merge the CLI repository's Fern migration before the first run; +review and merge generated updates there, then use its version-tag publishing +workflow when the release gates are satisfied. + +For a local preview: + +```sh +fern generate --api cli --group cli-sdk --version 1.0.0-beta.1 --preview +``` + +The CLI repository owns its docs, tests and runtime customizations. Its +`.fernignore` preserves repository-owned files, and Fern Replay carries its +schema changes across generated pull requests. The customized HTTP runtime is +protected by `.fernignore` because Replay rejects its embedded test certificate. Keep API naming changes in +shared source annotations or overrides, not CLI-only aliases. + ## How to update documentation? ### Local Development server diff --git a/fern/apis/cli/generators.yml b/fern/apis/cli/generators.yml new file mode 100644 index 000000000..85a1ce27f --- /dev/null +++ b/fern/apis/cli/generators.yml @@ -0,0 +1,65 @@ +# Staging-only beta registration. Promote the issuer, client and API audience +# together after live OAuth acceptance; no client secret belongs in this repo. +auth-schemes: + bearer: + scheme: oauth + type: authorization-code + client-id: client_01M721J47S27BS1GSXK1780TSR + authorization-url: https://nourishing-mulberry-12-staging.authkit.app/oauth2/authorize + token-url: https://nourishing-mulberry-12-staging.authkit.app/oauth2/token + refresh-url: https://nourishing-mulberry-12-staging.authkit.app/oauth2/token + scopes: [openid, offline_access] + redirect-uri: + url: http://127.0.0.1:8484/callback + ports: [8485, 8486] + authorization-parameters: + resource: https://api-mcp-poc.vapi.local + token-parameters: + resource: https://api-mcp-poc.vapi.local + refresh-parameters: + resource: https://api-mcp-poc.vapi.local +# Separate API workspace: the CLI generator embeds the workspace-level spec. +# Generator-level spec overrides affect IR but not that embedded runtime spec. +api: + auth: bearer + specs: + - openapi: ../api/openapi.json + overrides: + - ../api/openapi-overrides.yml + - ./openapi-overrides.yml + overlays: ../api/openapi-parameter-descriptions-overlay.yml + settings: + title-as-schema-name: false + coerce-enums-to-literals: false + respect-nullable-schemas: true +default-group: cli-sdk +groups: + cli-sdk: + generators: + - name: fern-cli-generator + version: 0.59.1 + output: + location: npm + package-name: "@vapi-ai/cli" + token: OIDC + github: + repository: VapiAI/cli + mode: pull-request + config: + binaryName: vapi + customCommands: false + generateWireTests: true + distribution: + homebrew: + tap: VapiAI/homebrew-tap + formula: vapi-cli + profiles: + enabled: true + packageIdentity: + name: vapi-cli + description: Voice AI for developers - Vapi CLI + authors: ["Vapi "] + keywords: ["vapi", "voice", "ai", "cli"] + license: MIT + repository: https://github.com/VapiAI/cli + homepage: https://vapi.ai diff --git a/fern/apis/cli/openapi-overrides.yml b/fern/apis/cli/openapi-overrides.yml new file mode 100644 index 000000000..42af1ec46 --- /dev/null +++ b/fern/apis/cli/openapi-overrides.yml @@ -0,0 +1,37 @@ +# OpenAPI reserves Content-Type for requestBody.content. The upstream +# provider-resource endpoint declares it as a required header instead. +# Fern's IR ignores that header, while the generated runtime requires it. +# Keep the flag available, but let the HTTP stack set Content-Type when +# --json is supplied; callers can still choose --content-type explicitly. +paths: + /provider/{provider}/{resourceName}: + post: + parameters: + - name: content-type + in: header + required: false + schema: + type: string + +# The beta's OAuth issuer and API audience are staging-only. Keep its default +# server in staging too, rather than sending staging credentials to production. +servers: + - url: https://staging-api.vapi.ai +components: + securitySchemes: + bearer: + type: oauth2 + scheme: null + bearerFormat: null + description: Sign in with `vapi auth login`. The CLI uses public-client OAuth with PKCE and refreshes access tokens automatically. + flows: + authorizationCode: + authorizationUrl: https://nourishing-mulberry-12-staging.authkit.app/oauth2/authorize + tokenUrl: https://nourishing-mulberry-12-staging.authkit.app/oauth2/token + refreshUrl: https://nourishing-mulberry-12-staging.authkit.app/oauth2/token + scopes: + openid: Sign in + offline_access: Refresh access + # The shared SDK override adds this unused API-key scheme. The CLI uses + # only the OAuth scheme referenced by the API operations. + BearerAuth: null