Skip to content

Commit 3905c9a

Browse files
heygen-rui-botsomanshreddyclaude
authored
codegen: resync gen/ from EF fecc5497 (#226)
* codegen: resync gen/ from EF fecc5497 * codegen: fold batch/status commands into resource groups, add examples The prod spec tags the new batch/status endpoints with distinct tags (Asset Batches, Lipsync Batches, Video Translation Batches), landing them in standalone groups that double the noun (lipsync-batch batches create) and split them off from the single-item commands they belong with. Fold each into its resource group via groupOverrides, matching the existing video-batch convention (heygen video batches create). Add curated examples for the 12 new commands (unblocks TestAllGeneratedCommandsHaveExamples), --human columns for the new statuses/list commands, and e2e-cli-test entries. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * cli: address codex review — accurate status-id labels and e2e producers - asset statuses --human header: "Asset ID" not "Video ID" (video_id holds the asset_id for assets; lipsync/video-translate keep "Video ID" since the field is the underlying produced video's id there). - e2e skill: asset list uses the Phase-1 username; asset status reuses that list's ids; name the asset batch producer correctly (asset direct-uploads batches create). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * cli: label bulk-status id columns per resource Codex round-2 traced the fecc5497 backend: for direct-id lookups get_bulk_video_statuses echoes the queried id into VideoStatusEntry.video_id, so for lipsync/video-translate the field is the queried job id, not a produced video id. Label the columns "Lipsync ID" / "Translation ID" (asset already "Asset ID"); only the video endpoint keeps "Video ID". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Somansh Reddy Satish <somanshreddy@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent a8a5596 commit 3905c9a

12 files changed

Lines changed: 613 additions & 25 deletions

File tree

.claude/skills/e2e-cli-test/SKILL.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ Save the JSON output from each -- Phase 3 will extract IDs from these results.
6666
./bin/heygen brand glossaries list --limit 1
6767
```
6868

69+
`asset list` requires `--username` (the workspace member whose assets to list,
70+
the `owner` value on asset items) while the endpoint is in beta. Use the
71+
`.data.username` captured in Phase 1 (`user me get`):
72+
`./bin/heygen asset list --username <phase-1-username> --limit 1`.
73+
6974
### Step 4: Phase 3 -- Read-only get/detail commands
7075

7176
For each command below, extract the required ID from the corresponding Phase 2
@@ -86,11 +91,19 @@ sufficient data for meaningful get/detail coverage.
8691
./bin/heygen voice get <voice-id> # .data[0].voice_id from voice list
8792
./bin/heygen template get <template-id> # .data[0].id from template list
8893
./bin/heygen video statuses list --video-ids <video-id> # a video-id from video list (bulk status lookup)
94+
./bin/heygen lipsync statuses list --lipsync-ids <id> # .data[0].id from lipsync list
95+
./bin/heygen video-translate statuses list --video-translation-ids <id> # .data[0].id from video-translate list
8996
```
9097

91-
`video batches get <batch-id>` needs a batch id, which has no read-only list
92-
source (batches are created via the write path). Run it only if a batch id is
93-
available from a prior `video batches create`; otherwise skip.
98+
`asset statuses list --asset-ids <asset-id>` needs an asset id from the
99+
`asset list` result above (`.data[0].id`). Skip only if that list is empty.
100+
101+
`<resource> batches get <batch-id>` needs a batch id, which has no read-only
102+
list source (batches are created via the write path). Run each only if a batch
103+
id is available from a prior batch-create call; otherwise skip. The producer is
104+
`video batches create` / `lipsync batches create` /
105+
`video-translate batches create`, and for assets
106+
`asset direct-uploads batches create`.
94107

95108
For `video-agent resources get`: first run `./bin/heygen video-agent get <session-id>`,
96109
then look for a `resource_id` in `messages[*].resource_ids[*]`. Only run

cmd/heygen/columns.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,38 @@ import "github.com/heygen-com/heygen-cli/internal/command"
55
// DefaultColumns defines curated table columns for --human mode.
66
// Keys use the full generated command path: "group/spec.Name".
77
var DefaultColumns = map[string][]command.Column{
8+
// The four bulk-status endpoints share one read model (VideoStatusEntry),
9+
// so columns are the same shape. The id is always carried in the wire key
10+
// "video_id", but for a direct-id lookup the backend echoes the queried
11+
// resource id straight into that field (see get_bulk_video_statuses), so
12+
// each table labels it with its own resource rather than "Video ID".
813
"video/statuses list": {
914
{Header: "Video ID", Field: "video_id"},
1015
{Header: "Status", Field: "status"},
1116
{Header: "Batch ID", Field: "batch_id"},
1217
},
18+
"asset/statuses list": {
19+
{Header: "Asset ID", Field: "video_id"},
20+
{Header: "Status", Field: "status"},
21+
{Header: "Batch ID", Field: "batch_id"},
22+
},
23+
"lipsync/statuses list": {
24+
{Header: "Lipsync ID", Field: "video_id"},
25+
{Header: "Status", Field: "status"},
26+
{Header: "Batch ID", Field: "batch_id"},
27+
},
28+
"video-translate/statuses list": {
29+
{Header: "Translation ID", Field: "video_id"},
30+
{Header: "Status", Field: "status"},
31+
{Header: "Batch ID", Field: "batch_id"},
32+
},
33+
"asset/list": {
34+
{Header: "ID", Field: "id"},
35+
{Header: "Name", Field: "name"},
36+
{Header: "Type", Field: "type"},
37+
{Header: "Owner", Field: "owner"},
38+
{Header: "Uploaded", Field: "uploaded_at"},
39+
},
1340
"template/list": {
1441
{Header: "ID", Field: "id"},
1542
{Header: "Name", Field: "name"},

codegen/examples/asset.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
"POST /v3/assets":
22
- desc: "Upload a file for use in video creation"
33
cmd: "heygen asset create --file ./video.mp4"
4+
"GET /v3/assets":
5+
- desc: "List a workspace member's uploaded assets, newest first"
6+
cmd: "heygen asset list --username <workspace-member> --limit 20"
7+
- desc: "List only the assets filed under one folder"
8+
cmd: "heygen asset list --username <workspace-member> --folder-id <folder-id>"
49
"GET /v3/assets/search":
510
- desc: "Search the asset library by natural-language description"
611
cmd: "heygen asset search --query 'pepperoni pizza on a wooden table'"
@@ -22,3 +27,19 @@
2227
cmd: "heygen asset complete create <asset-id>"
2328
- desc: "Finalize a direct upload and verify the stored checksum"
2429
cmd: "heygen asset complete create <asset-id> --checksum-sha-256 <base64-sha256>"
30+
"POST /v3/assets/direct-uploads/batches":
31+
- desc: "Request presigned upload URLs for up to 100 files in one call"
32+
cmd: "heygen asset direct-uploads batches create --title 'Launch assets' -d '{\"files\":[{\"filename\":\"clip1.mp4\",\"content_type\":\"video/mp4\",\"size_bytes\":10485760},{\"filename\":\"logo.png\",\"content_type\":\"image/png\",\"size_bytes\":204800}]}'"
33+
- desc: "See the full upload-batch request shape (per-file fields)"
34+
cmd: "heygen asset direct-uploads batches create --request-schema"
35+
"POST /v3/assets/complete/batches":
36+
- desc: "Finalize a whole upload batch after every file's PUT has succeeded"
37+
cmd: "heygen asset complete batches create --batch-id <batch-id>"
38+
"GET /v3/assets/batches/{batch_id}":
39+
- desc: "Check a batch's aggregate status and per-item asset ids and statuses"
40+
cmd: "heygen asset batches get <batch-id>"
41+
"GET /v3/assets/statuses":
42+
- desc: "Look up statuses for specific asset ids"
43+
cmd: "heygen asset statuses list --asset-ids <asset-id-1>,<asset-id-2>"
44+
- desc: "Expand batches into their member asset statuses"
45+
cmd: "heygen asset statuses list --batch-ids <batch-id-1>,<batch-id-2>"

codegen/examples/lipsync.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,16 @@
1313
"DELETE /v3/lipsyncs/{lipsync_id}":
1414
- desc: "Delete a lipsync job"
1515
cmd: "heygen lipsync delete <lipsync-id>"
16+
"POST /v3/lipsyncs/batches":
17+
- desc: "Submit a batch of lipsync jobs in one request (up to 100 items)"
18+
cmd: "heygen lipsync batches create --title 'Dub batch' -d '{\"lipsyncs\":[{\"video\":{\"type\":\"url\",\"url\":\"https://example.com/source.mp4\"},\"audio\":{\"type\":\"url\",\"url\":\"https://example.com/replacement.mp3\"}}]}'"
19+
- desc: "See the full batch request shape (per-item lipsync payloads)"
20+
cmd: "heygen lipsync batches create --request-schema"
21+
"GET /v3/lipsyncs/batches/{batch_id}":
22+
- desc: "Check a batch's per-item lipsync ids and statuses"
23+
cmd: "heygen lipsync batches get <batch-id>"
24+
"GET /v3/lipsyncs/statuses":
25+
- desc: "Look up statuses for specific lipsync ids"
26+
cmd: "heygen lipsync statuses list --lipsync-ids <lipsync-id-1>,<lipsync-id-2>"
27+
- desc: "Expand batches into their member lipsync statuses"
28+
cmd: "heygen lipsync statuses list --batch-ids <batch-id-1>,<batch-id-2>"

codegen/examples/video-translate.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,16 @@
3636
"PUT /v3/video-translations/proofreads/{proofread_id}/srt":
3737
- desc: "Upload corrected SRT"
3838
cmd: "heygen video-translate proofreads srt update <proofread-id>"
39+
"POST /v3/video-translations/batches":
40+
- desc: "Submit a batch of translations in one request (up to 100 items; multiple output languages fan out per item)"
41+
cmd: "heygen video-translate batches create --title 'Localization batch' -d '{\"video_translations\":[{\"video\":{\"type\":\"url\",\"url\":\"https://example.com/source.mp4\"},\"output_languages\":[\"Spanish (Spain)\",\"French (France)\"]}]}'"
42+
- desc: "See the full batch request shape (per-item translation payloads)"
43+
cmd: "heygen video-translate batches create --request-schema"
44+
"GET /v3/video-translations/batches/{batch_id}":
45+
- desc: "Check a batch's per-item translation ids and statuses"
46+
cmd: "heygen video-translate batches get <batch-id>"
47+
"GET /v3/video-translations/statuses":
48+
- desc: "Look up statuses for specific translation ids"
49+
cmd: "heygen video-translate statuses list --video-translation-ids <id-1>,<id-2>"
50+
- desc: "Expand batches into their member translation statuses"
51+
cmd: "heygen video-translate statuses list --batch-ids <batch-id-1>,<batch-id-2>"

codegen/grouper.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,34 @@ var nameOverrides = map[string]string{
9090
// groupOverrides reassigns an endpoint to a different CLI group than its
9191
// OpenAPI tag would otherwise produce. Keyed by "METHOD /path".
9292
//
93-
// The batch/status endpoints live at /v3/videos/... and operate on video
94-
// creations, but the spec tags them "Batch", which lands them in a standalone
95-
// "batch" group and doubles the noun ("heygen batch batches create"). Group
96-
// them with their domain instead ("heygen video batches create"), matching the
97-
// path and the convention that resource-specific batches nest under their
98-
// resource. Drop these if the spec re-tags the endpoints; codegen then follows
93+
// Resource-specific batch/status endpoints get their own OpenAPI tag
94+
// ("Batches", "Asset Batches", "Lipsync Batches", "Video Translation Batches"),
95+
// which would land them in standalone groups that double the noun
96+
// ("heygen lipsync-batch batches create") and split them off from the
97+
// single-item commands they belong with. Fold each into its resource group
98+
// instead, so batches read as a sub-command of the resource
99+
// ("heygen video batches create", "heygen lipsync batches create") — matching
100+
// the path and the existing single-item naming in each group (e.g.
101+
// "heygen asset direct-uploads create" already sits next to its batch form).
102+
// The derived names need no nameOverride: the path segments after the resource
103+
// root produce the right sub-command names on their own. Drop an entry if the
104+
// spec re-tags that endpoint into the resource's own tag; codegen then follows
99105
// the tag automatically.
100106
var groupOverrides = map[string]string{
101107
"POST /v3/videos/batches": "video",
102108
"GET /v3/videos/batches/{batch_id}": "video",
103109
"GET /v3/videos/statuses": "video",
110+
111+
"POST /v3/video-translations/batches": "video-translate",
112+
"GET /v3/video-translations/batches/{batch_id}": "video-translate",
113+
"GET /v3/video-translations/statuses": "video-translate",
114+
"POST /v3/lipsyncs/batches": "lipsync",
115+
"GET /v3/lipsyncs/batches/{batch_id}": "lipsync",
116+
"GET /v3/lipsyncs/statuses": "lipsync",
117+
"POST /v3/assets/direct-uploads/batches": "asset",
118+
"POST /v3/assets/complete/batches": "asset",
119+
"GET /v3/assets/batches/{batch_id}": "asset",
120+
"GET /v3/assets/statuses": "asset",
104121
}
105122

106123
func GroupEndpoints(doc *openapi3.T, examples Examples) (command.Groups, GroupDescriptions, error) {
@@ -396,19 +413,19 @@ func isCliAction(op *openapi3.Operation) bool {
396413
// schemaCliDefault returns the effective default value for a CLI flag.
397414
//
398415
// Some fields legitimately need a different default in the CLI than in the HTTP
399-
// API. ``aspect_ratio`` is the canonical example: the API defaults to ``16:9``
416+
// API. aspect_ratio is the canonical example: the API defaults to 16:9
400417
// for backwards compatibility, but agent-driven CLI/MCP flows are better off
401-
// defaulting to ``auto`` so the canvas tracks the source orientation. Authors
418+
// defaulting to auto so the canvas tracks the source orientation. Authors
402419
// signal this from the EF Pydantic field via
403-
// ``json_schema_extra={"x-cli-default": "auto"}``; the value lands verbatim on
420+
// json_schema_extra={"x-cli-default": "auto"}; the value lands verbatim on
404421
// the schema property in the OpenAPI spec.
405422
//
406-
// Precedence: ``x-cli-default`` (if present) wins over ``default``. Returns
407-
// (value, ok, fromExtension). ``fromExtension`` is true only when the value
408-
// came from ``x-cli-default``; the codegen uses it to flip
409-
// ``FlagSpec.SendDefaultWhenOmitted`` so the CLI default is actually written
423+
// Precedence: x-cli-default (if present) wins over default. Returns
424+
// (value, ok, fromExtension). fromExtension is true only when the value
425+
// came from x-cli-default; the codegen uses it to flip
426+
// FlagSpec.SendDefaultWhenOmitted so the CLI default is actually written
410427
// into the request body when the user omits the flag (non-destructively —
411-
// see the field doc). Ordinary OpenAPI ``default`` values keep the existing
428+
// see the field doc). Ordinary OpenAPI default values keep the existing
412429
// omit-unless-changed behavior — the CLI shouldn't echo every server default
413430
// back to the server.
414431
func schemaCliDefault(s *openapi3.Schema) (value interface{}, ok bool, fromExtension bool) {

0 commit comments

Comments
 (0)