Skip to content

Commit 74f48c5

Browse files
authored
chore: add Fern regen workflow docs and skills (#674)
## Summary - Add AGENTS.md documenting the Fern SDK regeneration workflow - Add CLAUDE.md stub referencing AGENTS.md - Add Claude Code skills for prepare-regen and review-regen
1 parent 5008103 commit 74f48c5

5 files changed

Lines changed: 126 additions & 0 deletions

File tree

.claude/skills/prepare-regen.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Prepare Repo for Fern SDK Regeneration
2+
3+
Triggers: prepare regen, prepare for regeneration, prep for fern, new sdk gen, prepare sdk gen
4+
5+
## Steps
6+
7+
Read AGENTS.md for full context on the regeneration workflow and freeze classification rules.
8+
9+
1. Fetch latest `main` and create a new branch: `lo/sdk-gen-<YYYY-MM-DD>` (use today's date).
10+
2. Push the branch to origin.
11+
3. Create an empty commit (`chore: initialize SDK regeneration branch`) if needed, then create a PR titled `chore: SDK regeneration <YYYY-MM-DD>`.
12+
4. Read `.fernignore` and classify each entry using the rules in AGENTS.md:
13+
- **Permanently frozen**: entirely hand-written, no Fern equivalent. NEVER touch these.
14+
- **Temporarily frozen**: Fern-generated with manual patches. These get swapped.
15+
5. For each **temporarily frozen** file only:
16+
- Copy the file to `<filename>.bak` alongside the original.
17+
- In `.fernignore`, replace the original path with the `.bak` path (protects our patch, lets Fern overwrite the original).
18+
6. Stage the updated `.fernignore` and all `.bak` files.
19+
7. Commit as `chore: unfreeze files pending regen` and push.
20+
8. Report the PR URL and confirm the branch is ready for generator output.

.claude/skills/review-regen.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Review Fern SDK Regeneration
2+
3+
Triggers: review regen, review regeneration, diff regen, compare regen, post regen review
4+
5+
## Steps
6+
7+
Read AGENTS.md for full context on the regeneration workflow and freeze classification rules.
8+
9+
1. Find all `.bak` files in the repo — these are our pre-regen manually-patched versions (protected by `.fernignore`).
10+
2. For each `.bak` file, diff it against the corresponding newly generated file to show what changed.
11+
3. Identify which manual patches are still needed (the `.bak` has changes the generator doesn't produce).
12+
4. Present a summary of findings to the user, grouped by category:
13+
- Patches no longer needed (generator now handles it)
14+
- Patches still needed (must be re-applied)
15+
- New changes from the generator worth noting
16+
5. Wait for user direction on which patches to re-apply.
17+
6. Re-apply confirmed patches to the generated files.
18+
7. In `.fernignore`, replace each `.bak` path back to the original path for files that still need patches.
19+
8. Remove `.fernignore` entries entirely for files where patches are no longer needed.
20+
9. Delete all `.bak` files.
21+
10. Run `ruff check --fix`, `mypy --ignore-missing-imports src/deepgram/`, and `pytest` to verify.
22+
11. Commit as `chore: re-apply manual patches after regen` and push.

.fernignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ src/deepgram/transport_interface.py
6767
src/deepgram/transport.py
6868
src/deepgram/transports
6969

70+
# Claude Code agent files
71+
CLAUDE.md
72+
AGENTS.md
73+
.claude
74+
7075
# Folders to ignore
7176
.github
7277
docs

AGENTS.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Agents
2+
3+
## Fern SDK Regeneration
4+
5+
### Overview
6+
7+
This SDK is generated by [Fern](https://buildwithfern.com/). Most files under `src/deepgram/` are auto-generated and should not be edited directly. Some files have manual patches and are listed in `.fernignore` to prevent the generator from overwriting them.
8+
9+
When a new Fern generator release is available, we prepare the repo so the generator can overwrite previously-frozen files, then re-apply manual patches after reviewing the diff.
10+
11+
### Freeze classification rules
12+
13+
Every entry in `.fernignore` falls into one of two categories. The **comment above each entry** in `.fernignore` indicates which category it belongs to, but when in doubt, apply these rules:
14+
15+
#### Never unfreeze (permanently frozen)
16+
17+
These files are **entirely hand-written** — they have no Fern-generated counterpart. The generator would delete or replace them with something unrelated. They must stay in `.fernignore` at all times.
18+
19+
How to identify:
20+
- The file was **created by us**, not by Fern (e.g., `src/deepgram/client.py`, custom tests, helpers, transport layer)
21+
- The file is a **doc, config, or folder** we maintain independently (README, CHANGELOG, .github, examples, etc.)
22+
- The file lives **outside `src/deepgram/`** in a hand-maintained location (e.g., `.claude/`, `docs/`)
23+
24+
Current permanently frozen files:
25+
- `src/deepgram/client.py` — entirely custom (Bearer auth, session ID); no Fern equivalent
26+
- `src/deepgram/helpers/` — hand-written TextBuilder helpers
27+
- `src/deepgram/transport_interface.py`, `src/deepgram/transport.py`, `src/deepgram/transports/` — custom transport layer
28+
- `tests/custom/test_text_builder.py`, `tests/custom/test_transport.py` — hand-written tests
29+
- `tests/manual/` — manual standalone tests
30+
- `README.md`, `CHANGELOG.md`, `CONTRIBUTING.md`, `reference.md` — docs
31+
- `CLAUDE.md`, `AGENTS.md`, `.claude/` — agent files
32+
- `.github/`, `docs/`, `examples/` — folders
33+
34+
#### Unfreeze for regen (temporarily frozen)
35+
36+
These files are **Fern-generated but carry manual patches** to fix issues in the generator output. We freeze them to protect our patches between regenerations, but unfreeze them before a regen so we can compare the new output against our patches.
37+
38+
How to identify:
39+
- The file **exists in Fern's output** — if you removed it from `.fernignore` and ran the generator, Fern would produce a version of it
40+
- Our version is a **modified copy** of what Fern generates (e.g., changed `float` to `int`, added optional defaults, broadened a Union type)
41+
42+
Current temporarily frozen files:
43+
- `src/deepgram/speak/v1/socket_client.py` — optional message param defaults, broad exception catch
44+
- `src/deepgram/listen/v1/socket_client.py` — same + `construct_type` for unknown WS messages
45+
- `src/deepgram/listen/v2/socket_client.py` — same
46+
- `src/deepgram/agent/v1/socket_client.py` — same + `_sanitize_numeric_types`
47+
- `src/deepgram/types/listen_v1response_results_utterances_item.py``float``int` fix
48+
- `src/deepgram/types/listen_v1response_results_utterances_item_words_item.py``float``int` fix
49+
- `src/deepgram/types/listen_v1response_results_channels_item_alternatives_item_paragraphs_paragraphs_item.py``float``int` fix
50+
- `src/deepgram/types/listen_v1redact.py` — Union[str, Sequence[str]] support
51+
- `src/deepgram/listen/v1/client.py` — Union[str, Sequence[str]] array param support
52+
- `src/deepgram/listen/v2/client.py` — same
53+
- `tests/wire/test_listen_v1_media.py``transcribe_file()` bytes param fix
54+
- `wiremock/wiremock-mappings.json` — removed duplicate stub
55+
56+
### Prepare repo for regeneration
57+
58+
1. **Create a new branch** off `main` named `lo/sdk-gen-<YYYY-MM-DD>`.
59+
2. **Push the branch** and create a PR titled `chore: SDK regeneration <YYYY-MM-DD>` (empty commit if needed).
60+
3. **Read `.fernignore`** and classify each entry using the rules above.
61+
4. **For each temporarily frozen file only:**
62+
- Copy the file to `<filename>.bak` alongside the original.
63+
- In `.fernignore`, **replace the original path with the `.bak` path**. This protects our patched version from the generator while allowing Fern to overwrite the original.
64+
5. **Never touch permanently frozen entries.** Leave them in `.fernignore` as-is.
65+
6. **Commit** as `chore: unfreeze files pending regen` and push.
66+
7. The branch is now ready for the Fern generator to push changes.
67+
68+
### After regeneration
69+
70+
The `.bak` files are our manually-patched versions (protected by `.fernignore`). The original paths now contain the freshly generated versions. By comparing the two, we can see what the generator now produces vs what we had patched.
71+
72+
1. **Diff each `.bak` file against the new generated version** to understand what changed and whether our patches are still needed.
73+
2. **Re-apply any patches** that are still necessary to the newly generated files.
74+
3. **In `.fernignore`, replace each `.bak` path back to the original path** for any files that still need manual patches.
75+
4. **Remove `.fernignore` entries entirely** for any files where the generator now produces correct output (patches no longer needed).
76+
5. **Delete all `.bak` files** once review is complete.
77+
6. **Run tests** (`pytest`) and linting (`ruff check`, `mypy`) to verify.
78+
7. **Commit** as `chore: re-apply manual patches after regen` and push.

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@AGENTS.md

0 commit comments

Comments
 (0)