Skip to content

[pull] main from fern-api:main#644

Merged
pull[bot] merged 40 commits into
code:mainfrom
fern-api:main
Apr 11, 2026
Merged

[pull] main from fern-api:main#644
pull[bot] merged 40 commits into
code:mainfrom
fern-api:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Apr 10, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

patrickthornton and others added 30 commits April 10, 2026 14:26
* ir66.1 update

* format

* fix(java): update versions.lock and fix biome formatting

Update Gradle lock file for irV65→irV66 dependency change and fix
biome formatting in java-v2 package.json files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* release 4.2.0-rc.1

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…cal and --push-diff (#14856)

* feat: route fern sdk preview through Fiddle for remote generation by default

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* feat(cli): route fern sdk preview through Fiddle for remote generation by default

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* feat(cli): add --push-diff flag and use publishV2 by default for remote preview

- Default fern sdk preview (no flags): publishV2(npmOverride) → registry-only publish, safe to merge independently
- With --push-diff: githubV2(push) + preview=true → Fiddle publishes AND pushes diff branch to SDK repo
- Added explicit isPreview param to remote generation chain (createAndStartJob, runRemoteGenerationForGenerator, runRemoteGenerationForAPIWorkspace) so preview flag can be set independently of absolutePathToPreview

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* chore: trigger CI re-run with correct PR title

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* fix(cli): set isPreview=false for remote preview to avoid dry-run publish

In Fiddle, preview=true causes dryRun=true in the generator config,
which makes the generator run 'npm publish --dry-run' instead of
actually publishing. For sdk preview via publishV2(npmOverride),
we want the generator to actually publish to the registry.

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* chore(cli): remove internal Fiddle implementation details from comments

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* fix(cli): address PR review — _other returns undefined, isPreview conditional on pushDiff, clarify JSDoc

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* fix(cli): decouple isPreview from Fiddle preview field, remove --push-diff

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* fix(cli): replace fiddlePreview with publishV2 output mode check

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* fix(cli): simplify preview field — just send isPreview, let Fiddle handle dryRun

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* feat(cli): decouple fiddlePreview from isPreview, add --push-diff support

- Add `fiddlePreview` param to decouple what's sent to Fiddle as `preview`
  from CLI-internal `isPreview` behavior. For sdk preview, isPreview=true
  (lenient env vars, skip version check) while fiddlePreview=false (so
  Fiddle doesn't set dryRun=true). This preserves fern generate --preview
  behavior exactly as-is.
- Add `pushPreviewBranch` param threaded through the remote generation
  chain. Will be sent to Fiddle once fiddle-sdk is bumped.
- Add `--push-diff` CLI flag for pushing preview branches to SDK repos.
- Add `getGithubOwnerRepo` helper and pushDiff support to
  `overrideGroupOutputForRemotePreview` — uses githubV2(push) with npm
  publishInfo when --push-diff is set and generator has github config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(cli): consolidate overrideGroupOutputForPreview into single function

Merge the local-Docker-only overrideGroupOutputForPreview and remote-only
overrideGroupOutputForRemotePreview into a single exported function with an
optional pushDiff param. Extract createNpmOverrideOutputMode helper to
deduplicate the publishV2(npmOverride) construction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): gate --push-diff, add validation, clarify dryRun comment

- Error out on --push-diff until fiddle-sdk is bumped with
  pushPreviewBranch support — without it, Fiddle would treat the
  githubV2(push) job as a normal push to the default branch.
- Error on --push-diff combined with --output (incompatible flags).
- Warn when --push-diff falls back to registry-only publish because
  the generator has no github output configuration.
- Clarify the dryRun comment in createAndStartJob.ts explaining
  that fiddlePreview is the sole mechanism preventing dryRun for
  sdk preview jobs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(cli): improve --output and --push-diff option descriptions

Document the behavior differences between modes: omitting --output
uses remote generation, providing it uses local Docker. Add examples
for --output combinations. Clarify --push-diff branch naming, GitHub
App requirement, and incompatibility with --output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(cli): add --local flag to fern sdk preview, make --output use remote generation

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* docs(cli): update --push-diff help text to reference --local instead of --output

Co-Authored-By: barry.zou <barry.zou@buildwithfern.com>

* fix(cli): override output mode to downloadFiles for remote disk-only preview

When --output is provided without a registry URL and without --local,
remote generation was using the generator's original output mode (e.g.
npm publish to registry.npmjs.org) which fails. Override to
downloadFiles so the generator produces files without publishing,
and the CLI downloads them from S3 to the specified path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(cli): add unit tests for sdk preview output mode overrides

Cover getGithubOwnerRepo, overrideGroupOutputForDownload, and
overrideGroupOutputForPreview including pushDiff routing logic.
Add clarifying comment on publishV2 being registry-only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): remove unnecessary isPreview param from createAndStartJob

isPreview was threaded to createAndStartJob only to participate in the
fallback chain for the Fiddle preview flag, but no caller needed it —
fern sdk preview already passes fiddlePreview explicitly, and fern
generate --preview relies on absolutePathToPreview != null. Simplify
the fallback to: fiddlePreview ?? absolutePathToPreview != null.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(cli): remove test config files accidentally committed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): remove extra destructured params from createJob inner function

automationMode and autoMerge are in the type signature but not
destructured on main (they're commented out in the createJobV3 call).
The merge conflict resolution incorrectly added them to the
destructuring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: barry.zou <barry.zou@buildwithfern.com>
Co-authored-by: Barry <barry@Barrys-MacBook-Pro.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Initial approach to CLI release refactor

* tidy up + CI autorelease improvements

* enforce human version check by creating PR first to be merged in

* Update .github/workflows/auto-release-cli.yml

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* enforce old versioning system can't be used except from release/* branches

* add release queuing and concurrency guards

* QoL updates

* update RELEASE PR name grab

* update RELEASE PR name grab

* biome/formatting updates

* Update scripts/release-cli.ts

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* use yaml stringify for yaml string creation

* Update .github/workflows/auto-release-cli.yml

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* revised versioning script that genearlizes to any software. Generalized CI enforcement

* Scoping this PR to generalized versioning setup only. Deprecating old prepare-release command

* simplify pnpm commands

* created CI to auto-run on updates to versions files

* fix: address PR review issues — schema validation, setup order-of-ops, shell injection, generalized schema title

Co-Authored-By: adi <aditya.arolkar@berkeley.edu>

* Update scripts/validate-changelogs.js

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* fix: add trailing newline to package.json for biome formatting

Co-Authored-By: adi <aditya.arolkar@berkeley.edu>

* fix: correct biome formatting in validate-changelogs.js

Co-Authored-By: adi <aditya.arolkar@berkeley.edu>

* formatting

* refactor: convert release-all.js and validate-changelogs.js to TypeScript

Co-Authored-By: adi <aditya.arolkar@berkeley.edu>

* refactor: use release-config.ts APIs in release-all.ts and validate-changelogs.ts

Co-Authored-By: adi <aditya.arolkar@berkeley.edu>

* added generator software configs

* scoping changelog enforcement to a separate PR with a 'break-glass' option for software changes that aren't customer-facing

* updated release workflow to detect changes on changelogFolders and to allow manual dispatch on dropdown of language options

* scoping validation of changelogs to different PR

* added rc config, updated check-author check to match on commit name, detach from main-specific workflow and defer to actions/checkout in the CI file

* naming

* Revert "added rc config, updated check-author check to match on commit name, detach from main-specific workflow and defer to actions/checkout in the CI file"

This reverts commit 58991fe.

* chore: rename release-all.ts back to release-workflow.ts

Co-Authored-By: adi <aditya.arolkar@berkeley.edu>

* chore: remove hardcoded main branch references in release.ts

Co-Authored-By: adi <aditya.arolkar@berkeley.edu>

* chore(internal): add agent guide for changelog paths via release-config

Made-with: Cursor

* fix(ci): pass release software input via env in workflow

Made-with: Cursor

* chore(internal): add pnpm release script for release-workflow

Made-with: Cursor

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: patrickthornton <70873350+patrickthornton@users.noreply.github.com>
…mp python SDK to 5.3.10 (#14896)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
## Description

Part of the CLI error classification effort — see #14749 for full context.

Renames `FernCliError` to `TaskAbortSignal` to better reflect its purpose: it is a control-flow signal used to abort a task after an error has already been logged, not an error class itself. This clears the naming space for the `CliError` class introduced in #14749.

## Changes Made

- Renamed `FernCliError` class to `TaskAbortSignal` across all usages
- Deleted `packages/cli/task-context/src/FernCliError.ts`, created `packages/cli/task-context/src/TaskAbortSignal.ts`
- Updated all `import { FernCliError }` → `import { TaskAbortSignal }` and `instanceof FernCliError` → `instanceof TaskAbortSignal` across CLI v1, CLI v2, seed, and test helpers

## Context

The old `FernCliError` was thrown by `failAndThrow()` purely as a sentinel to unwind the call stack — it carried no error metadata. Renaming it to `TaskAbortSignal` makes this intent explicit and avoids confusion with the new `CliError` class that carries typed error codes for Sentry routing.

## Testing

- [x] Existing tests pass (rename is mechanical)
…sioning (#14719)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… union variants (#14874)

* feat(seed): augment server-sent-events-openapi fixture with x-fern-streaming test cases

Add endpoints 8-14 covering x-fern-streaming extension patterns that have
been the source of multiple regressions:

- Endpoint 8: basic stream-condition with $ref request body (#13568)
- Endpoint 9: stream-condition with x-fern-type-name (#14256)
- Endpoints 10-11: shared request schema across streaming/non-streaming (#14291)
- Endpoint 12: discriminated union request with allOf-inherited stream
  condition field, reproducing the Vectara regression (FER-9556, #14730)
- Endpoint 13: nullable stream condition field (#13605)
- Endpoint 14: x-fern-streaming with SSE format only (no stream-condition)

* chore(seed): add debug script for SSE pipeline stage inspection

Runs the locally-built Fern CLI against the server-sent-events-openapi
fixture through each transformation stage (openapi-ir, write-definition,
ir), collecting outputs in .local/results/ for inspection. Continues
past failures so all stages produce output even when earlier ones error.

Usage: pnpm tsx scripts/debug-sse-pipeline.ts

* chore(seed): comment out endpoint 9 (x-fern-type-name collision)

Endpoint 9's ChatCompletionRequest name collision blocks IR generation
for the entire fixture. Comment it out so the remaining endpoints can
be tested end-to-end. Uncomment when investigating the x-fern-type-name
disambiguation fix (PR #14256) in isolation.

* fix: deduplicate stream condition properties in discriminated union variants

When a discriminated union's variants inherit the stream condition field
from a base schema via extends, the property appeared twice in generated
Python code — once from the union's base properties (pinned as a literal)
and once from the variant's extended properties (as boolean). This caused
SyntaxError: Duplicate keyword argument in generated wire tests and
pydantic model definitions.

Two fixes:
1. DynamicTypeLiteralMapper.ts: filter objectEntries that overlap with
   baseFields when building samePropertiesAsObject variant constructor args
2. simple_discriminated_union_generator.py: skip variant properties whose
   wire_value matches any union base property

Fixes FER-9556

Co-Authored-By: bot_apk <apk@cognition.ai>

* chore: update ir-to-jsonschema snapshots for server-sent-events-openapi fixture

Co-Authored-By: bot_apk <apk@cognition.ai>

* chore: add server-sent-events-openapi to go-sdk allowed failures

Co-Authored-By: bot_apk <apk@cognition.ai>

* fix: preserve AST references for streaming endpoint imports in wire tests

Co-Authored-By: bot_apk <apk@cognition.ai>

* style: fix biome formatting in WireTestGenerator.ts

Co-Authored-By: bot_apk <apk@cognition.ai>

* fix: escape triple quotes in docstrings and suppress mypy overload errors in exported client wrapper

Co-Authored-By: judah <jsklan.development@gmail.com>

* chore: update seed snapshot for exported client type ignore comment

Co-Authored-By: judah <jsklan.development@gmail.com>

* fix: use actual stream condition property name in WireMock body patterns

Instead of hardcoding 'stream' in the matchesJsonPath body pattern,
extract the actual stream condition property name from the SSE endpoint's
example request body. This fixes WireMock stub routing for APIs that use
a different property name (e.g. 'stream_response' in the Vectara API).

Co-Authored-By: judah <jsklan.development@gmail.com>

* fix: use explicit None check for mypy type narrowing in wrapper class

Co-Authored-By: judah <jsklan.development@gmail.com>

* fix: update CLI changelog version ordering and regenerate IR test snapshots

Co-Authored-By: judah <jsklan.development@gmail.com>

* nit

* fix(python): replace type: ignore with proper @overload signatures in exported client wrapper

Mirror the base client's @overload signatures on the wrapper class and
use **kwargs pass-through for super().__init__(), so mypy is satisfied
without suppressing the error.

---------

Co-authored-by: jsklan <jsklan.development@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
## Description

Part of the CLI error classification effort — see #14749 for full context.

Makes `instrumentPostHogEvent` synchronous in **CLI v1** by removing its `async` qualifier and dropping unnecessary `await` calls at all call sites. This is the CLI v1 counterpart to #14748 (CLI v2).

## Why

The new error system (#14749) needs to call telemetry from `failWithoutThrowing` — a synchronous method on the `TaskContext` interface. If `instrumentPostHogEvent` remains async, every `failWithoutThrowing` call site would need to become async too, rippling changes through the entire `TaskContext` interface. Making telemetry synchronous avoids that: PostHog's `capture()` is fire-and-forget anyway (it buffers locally and flushes in the background), so the `async` was always unnecessary.

## Changes Made

- Changed `instrumentPostHogEvent` from `async` to synchronous in `TaskContext` interface, `CliContext`, `TaskContextImpl`, `TaskContextAdapter`, and test helpers
- Removed `await` from all call sites (21 files)

## Testing

- [x] Existing tests pass (behavioral no-op)
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
…ory (#14748)

## Description

Part of the CLI error classification effort — see #14749 for full context.

Makes telemetry synchronous in **CLI v2** by eagerly resolving the PostHog `distinctId` at startup via an async factory, so that `Context.telemetry` becomes a synchronous `TelemetryClient`. This is the CLI v2 counterpart to #14747 (CLI v1).

## Why

Same motivation as #14747: the new error system (#14749) introduces a `reportError` function called from `failWithoutThrowing` and top-level catch blocks. This function needs synchronous access to telemetry to capture Sentry exceptions with PostHog correlation. Previously `Context.telemetry` was a `Promise<TelemetryClient>`, which forced all error handlers to be async. Moving the async resolution to startup keeps the hot path simple and avoids changing the `TaskContext` interface.

## Changes Made

- Added `TelemetryClient.create()` async factory that resolves `distinctId` eagerly
- `Context.telemetry` is now a synchronous `TelemetryClient` (no more `Promise<TelemetryClient>`)
- Updated all test helpers to use the new factory (`TelemetryClient.create()` or direct construction)
- Adjusted CLI v2 `withContext` to `await` telemetry creation at startup

## Testing

- [x] Updated TelemetryClient tests for new factory pattern
- [x] Updated test context helpers
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: jsklan <100491078+jsklan@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
fern-support and others added 10 commits April 10, 2026 22:39
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
Co-authored-by: FedeZara <43422322+FedeZara@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators Apr 10, 2026
@pull pull Bot added the ⤵️ pull label Apr 10, 2026
@pull pull Bot merged commit b417a73 into code:main Apr 11, 2026
34 of 38 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants