proto-codegen
Skill447 starsChanged 3 months agoMITView on GitHub
Locally regenerate @temporalio/proto TypeScript types from current temporalio/api protos, to unblock UI development against unreleased proto fields. Use when the published @temporalio/proto package lags the protos you're developing against (missing/renamed fields). The generated output is local-only and never committed.
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 20
Only the tooling is committed: scripts/generate-temporal-proto.ts, this skill, the .gitignore entry, and the protobufjs-cli devDep.
- Distinctive: line 65
Import as usual — the local override makes these resolve to the generated package:
- Very specific: line 72
Only temporal.* and google.* are generated (not coresdk.*, unused here).
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Local @temporalio/proto codegen
The published @temporalio/proto package often lags the protos we develop
against. This tool regenerates a drop-in @temporalio/proto from current
temporalio/api protos so you can build and preview the UI against unreleased
fields locally.
This is a local dev unblock, not a shipped dependency. The generated output,
the pnpm override that activates it, and the ui-server go.mod bump are all
local-only — none of them are committed. A feature must not merge to main
relying on an unreleased proto; wait until the fields ship in a released
@temporalio/proto (and go.temporal.io/api for the ui-server), then delete the
local setup with --reset.
Only the tooling is committed: scripts/generate-temporal-proto.ts, this skill,
the .gitignore entry, and the protobufjs-cli devDep. vendor/temporalio-proto/
is gitignored.
Commands
pnpm generate:proto --help # full option list
pnpm generate:proto # generate from the latest temporalio/api main
pnpm generate:proto --ref v1.63.3 # generate from a specific tag, branch, or commit SHA
pnpm generate:proto --sync-ui-server # also bump server/go.mod + rebuild the ui-server to match
pnpm generate:proto --sync-ui-server --ui-server-version v1.63.3 # pin the ui-server go module version
pnpm generate:proto --reset # undo everything: remove override, delete vendor, revert go.mod, reinstallA normal run generates vendor/temporalio-proto/, injects the
@temporalio/proto override into package.json (a local, uncommitted
change), and runs pnpm install. Do not commit the override or the vendored
output. When you're done previewing, pnpm generate:proto --reset returns the
working tree to the clean, main-matching state.
The two-part bump
Field names/values only line up if two things are on the same proto revision, because gRPC matches by field number — a mismatch silently drops values or renames fields:
- UI TypeScript types — the generated
@temporalio/proto(this tool). - The ui-server (
server/go.mod) — the grpc-gateway that decodes gRPC into the JSON the UI receives; its baked-in descriptors decide the wire field names.
--sync-ui-server does both: generate the types, then
go get go.temporal.io/api@<version> + make build in server/. Restart
pnpm dev:local-temporal afterward. Both changes are local-only; --reset
reverts them.
Version-axis caveat: the TS types come from a temporalio/api git ref,
while the ui-server pins a go.temporal.io/api release tag — no exact 1:1
mapping, so --sync-ui-server defaults to @latest (the practical match for
main). If a field still looks wrong, confirm the release tag contains the ref
you generated from.
Consuming the generated types
Import as usual — the local override makes these resolve to the generated package:
import type { temporal, google } from '@temporalio/proto';Only temporal.* and google.* are generated (not coresdk.*, unused here).
For enum fields that arrive over REST/JSON as SCREAMING_SNAKE strings, derive a
string union from the proto enum so it can't drift:
type ActivityExecutionStatus =
keyof typeof import('@temporalio/proto').temporal.api.enums.v1.ActivityExecutionStatus;Note: while previewing with the override active, these resolve to the unreleased shape. Committed code must still compile against the published package, so don't reference fields that only exist in the unreleased protos until they ship.
In this repository7 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- auth-testingSkill
- local-temporalSkill
- serverless-worker-awsSkill
- setup-worktreeSkill
- svelte-migrateSkill
- system-nexus-operationSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

