Commit Graph
6 Commits
Author SHA1 Message Date
Miguel Ángel 746b6d5b75 feat(cli): tag HeyGen API calls with X-HeyGen-Client-Source (#2368)
Send `X-HeyGen-Client-Source: hyperframes` from buildAuthHeaders on every
HeyGen API call (both OAuth and API-key), so backend billing meta can
isolate hyperframes CLI usage. The single buildAuthHeaders chokepoint covers
the core CLI + cloud client. Mirrors the media-use tagging; the OAuth-only
X-HeyGen-Source cli free-gate header is unchanged.
2026-07-13 19:02:22 -04:00
Miguel ÁngelandClaude Opus 4.8 3b93f516b4 feat(media-use): use CLI free HeyGen usage (#2027)
* feat(media-use): use CLI free HeyGen usage

* fix(media-use): address #2027 R1 nits — gate cli-source header to OAuth, export origin constant

- X-HeyGen-Source is now sent only on OAuth (Bearer) requests, not API-key ones —
  the backend ignores it for API-key traffic (normal billing), so it was dead
  metadata there. buildAuthHeaders + heygenAuthHeaders + tests updated.
- Export HEYGEN_CLI_ORIGIN_HEADER ("X-HeyGen-Client-Origin") for future cli:<origin>
  consumers.
- Document the deliberate paid/X4 confirm-before-call decision on heygen.tts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H5k87mPZ4d6yiFwcWSb8Vv

* refactor(cli): drop unused origin-header export, dedup auth-client tests

Fallow flagged 5 findings on this PR:
- major: HEYGEN_CLI_ORIGIN_HEADER was exported but never emitted or
  imported — speculative dead code ("future consumers"). Remove it; a
  real consumer can add the constant when one exists.
- 4x minor duplication in client.test.ts: fold the repeated
  `.rejects.toSatisfy(auth-code)` assertion into expectAuthCode(), and the
  repeated try/catch scrubbed-message assertion into expectRejectionMessage().

No behavior change; auth/client tests still 17/17.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H5k87mPZ4d6yiFwcWSb8Vv

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 18:28:26 -04:00
Miguel Ángel a5c2636e8c fix(cli): never print "[object Object]" from validate/inspect errors (#1810)
* fix(cli): use normalizeErrorMessage so validate/inspect never print "[object Object]"

The validate and inspect (layout) commands formatted thrown values with
`err instanceof Error ? err.message : String(err)`. When a browser/CDP/
Puppeteer protocol error or a structured page error reaches the formatter
as a plain object without a string `message`, `String(obj)` yields the
useless literal "[object Object]", hiding the real cause.

Route those paths through the existing shared `normalizeErrorMessage`
helper, which returns an Error's message, a string as-is, an object's
`.message` when present, or a compact JSON serialization otherwise (with
a key-list and String fallback for circular/opaque objects). Also fold
the duplicated local `errorMessage` helpers in batchRender and preview
into the same shared helper.

Covered by added assertions in errorMessage.test.ts for the no-message
object and Puppeteer-style protocol-error object cases.

* fix(cli): route remaining browser/process error sites through normalizeErrorMessage

The validate/inspect fix routed only those two commands through the shared
normalizeErrorMessage helper. The same err instanceof Error ? err.message :
String(err) pattern survived in the other commands that drive a headless
browser or an external process (ffmpeg, Docker, CDP) or surface a network
API error, so a thrown structured object without a string message would
still render as the useless literal [object Object].

Route those sites through the shared helper:
  snapshot.ts (the closest sibling to validate/inspect, same bug class),
  render.ts (Chrome launch + Docker build), capture/index.ts and
  commands/capture.ts (page-driven extraction), auth/browser.ts,
  browser/manager.ts (Puppeteer browser resolution), and the cloud/lambda
  paths (cloud/render.ts, cloudrun.ts, lambda/render-batch.ts,
  lambda/policies.ts, cloud/detectAspectRatio.ts) that surface API/network
  error objects.

Only the message-deriving expression changes; control flow and error
propagation are untouched. capture/index.ts keeps appending the stack for
real Errors and only routes the non-Error branch. Adds a helper test for a
structured CDP-style error object (code + nested data, no message).
2026-06-30 10:47:54 -07:00
James RussoandClaude Opus 4.8 b9b5780396 feat(cli): persist + show friendly user identity; preserve unknown credential fields (#1741)
* feat(cli): persist + show friendly user identity; preserve unknown credential fields

The `~/.heygen/credentials` file is SHARED with the Go `heygen` CLI. This
is the hyperframes-side mirror of heygen-cli#197, which adds an optional
`user` block to that file. Two CLIs writing one file must round-trip each
other's data without loss.

Load-bearing change: the credentials reader/writer now PRESERVES unknown
fields on round-trip. Previously readStore/writeStore stripped any key
this CLI didn't model, so writing the file back would silently drop the
`user` block heygen-cli wrote (and any future key). Unrecognized top-level
keys, and unknown keys inside `oauth` / `user`, are captured on a hidden
symbol slot and re-emitted verbatim. Known fields stay strictly validated.

Also mirrors heygen-cli#197's friendly-display feature:
- New optional `user` block schema (email/first_name/last_name/username),
  all omitempty; legacy files without it parse fine.
- After login (OAuth + api-key paths) probe /v3/users/me, persist the
  block, and show a friendly name (email > "first last" > username).
  Probe failure is non-fatal (login still succeeds); a stale block is
  cleared on probe failure so a wrong account can't surface.
- `auth status` surfaces the persisted block (persisted_user in JSON,
  a cached Account row in human output) for file-sourced credentials;
  env-sourced credentials skip it (the on-disk block may belong to a
  different key).
- Fixed the OAuth write path to carry the user block + unknown keys
  across a fresh login / refresh (it previously rebuilt a minimal record).

Tests: preserve-unknown-fields round-trip (top-level, oauth, user), the
exact cross-CLI `user`-block scenario, schema round-trip + omitempty,
backwards-compat with legacy files, login persistence + graceful probe
failure + stale-clear, and the `auth status` surface. Full CLI suite
(1009 tests) green; oxlint + oxfmt + tsc clean.

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

* fix(cli): preserve unknown credential data in cleanup/rollback paths

Addresses Magi's REQUEST_CHANGES on #1741. The credentials reader/writer
already round-trips unknown/foreign keys (the cross-CLI forward-compat
contract), but three destructive paths still deleted the whole file when
no known api_key/oauth survived — even when the hidden Symbol-keyed
unknown-field bag held a future credential another CLI owns. That clobbers
exactly the data this PR preserves.

- Add `hasPreservedUnknownData(record)` to store.ts (checks the top-level
  unknown bag + the oauth/user sub-object bags) and export it via the
  barrel.
- `clearOAuth`, `clearUserInfo`, and the failed `auth login --api-key`
  rollback now write the credential-less remnant (carrying the unknown
  bag) instead of deleting the file when unknown/foreign data survives.
  They still delete when nothing worth preserving remains.
- Regression tests: rollback path + both cleanup paths (clearOAuth,
  clearUserInfo) preserve a foreign top-level key; `hasPreservedUnknownData`
  unit tests at all three levels.

Also addresses the review's minor items:
- Add a refresh-path round-trip test (`refreshTokens`) proving an unknown
  key inside the oauth sub-object survives a no-rotation refresh — the
  most-frequent write path, previously only implicitly covered.
- Clarify the `userDisplayName` / `combineName` docstrings: precedence is
  `email > "first last" > first-only > last-only > username`.
- Replace the stale `expires_at` example date in store.ts with
  `<ISO-8601 UTC>`.

Full CLI suite green (1020 tests); tsc, oxlint, oxfmt --check all clean.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 10:16:23 -07:00
James 81aff68397 fix(cli): address code-review findings on OAuth PR 2026-05-28 05:59:24 +00:00
James 8a9291c434 fix(cli): address code-review findings on auth PR 2026-05-28 05:39:24 +00:00