hyperframes 0.8.119 → 0.8.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/{add-LVDM5BBO.js → add-SYG3UXKX.js} +5 -5
  2. package/dist/{asset-PA7XD3CI.js → asset-P6K7U3L6.js} +2 -2
  3. package/dist/{auth-SQIHPP3J.js → auth-TCX6TGIH.js} +4 -4
  4. package/dist/{autoUpdate-JCG27FBW.js → autoUpdate-YGT7MYDU.js} +2 -2
  5. package/dist/{backgroundChecks-U7JCBAWI.js → backgroundChecks-CCDNX6P2.js} +3 -3
  6. package/dist/backgroundChecksWorker.js +3 -3
  7. package/dist/{beats-6BSMZTE6.js → beats-HNU6TRID.js} +6 -6
  8. package/dist/{benchmark-WOZCECBF.js → benchmark-UEMJYRLY.js} +6 -6
  9. package/dist/{browser-KNPH25NJ.js → browser-CZJK4WQR.js} +3 -3
  10. package/dist/{bundleWithLocalizedFonts-I4RJWHKR.js → bundleWithLocalizedFonts-ZLXYM43M.js} +1 -1
  11. package/dist/{catalog-OXCKYFHY.js → catalog-G3C7EIL3.js} +5 -5
  12. package/dist/{check-N4QDDW6N.js → check-KTYPDNJD.js} +17 -17
  13. package/dist/{checkBrowser-D3L4OXTQ.js → checkBrowser-MJAN5LSM.js} +14 -14
  14. package/dist/{chunk-KNXXZ73S.js → chunk-4IWDF5OL.js} +2 -2
  15. package/dist/{chunk-Y44PIZOH.js → chunk-6A332WKF.js} +5 -5
  16. package/dist/{chunk-HNOJAFT2.js → chunk-6ZX3YCCU.js} +19 -19
  17. package/dist/{chunk-FRIRP3DN.js → chunk-7N3IODU7.js} +1 -1
  18. package/dist/{chunk-2MMAA5I3.js → chunk-A45JNRYR.js} +1 -1
  19. package/dist/{chunk-6Q3Q7HGA.js → chunk-B3MQEZBK.js} +1 -1
  20. package/dist/{chunk-EEXM24SY.js → chunk-CK2YS3E3.js} +2 -2
  21. package/dist/{chunk-523Q6JDM.js → chunk-DL347PC3.js} +2 -2
  22. package/dist/{chunk-P6UJ22SS.js → chunk-EFC3DCJL.js} +1 -1
  23. package/dist/{chunk-DNXD7TOA.js → chunk-I465DBM6.js} +27 -12
  24. package/dist/chunk-IGLEPPTN.js +24 -0
  25. package/dist/{chunk-CDTPNYO3.js → chunk-IJ2O4BLJ.js} +1 -1
  26. package/dist/{chunk-MVWXSRY6.js → chunk-JH556Q42.js} +69 -21
  27. package/dist/{chunk-3NXDJSD5.js → chunk-LIPKCOYU.js} +2 -2
  28. package/dist/{chunk-M6LKSPER.js → chunk-LJXFGHPO.js} +1 -1
  29. package/dist/{chunk-ZTU5PYQJ.js → chunk-LP3KFEVQ.js} +30 -17
  30. package/dist/{chunk-MYSYOQPV.js → chunk-NP5P2A2K.js} +2 -2
  31. package/dist/{chunk-SUIF4D5H.js → chunk-PCL5KCT7.js} +1 -1
  32. package/dist/{chunk-7UXUVWOY.js → chunk-QWD3NM22.js} +1 -1
  33. package/dist/chunk-SHB5VDMH.js +51 -0
  34. package/dist/{chunk-AMSNSTLK.js → chunk-SVI32JAG.js} +1 -1
  35. package/dist/{chunk-BZKDN6BU.js → chunk-UDYR6TIQ.js} +2 -2
  36. package/dist/{chunk-2FJPEXII.js → chunk-UOKW7DPN.js} +1 -1
  37. package/dist/{chunk-RMDKZTSI.js → chunk-WMCV6DHA.js} +1 -1
  38. package/dist/{chunk-RLYTIMTS.js → chunk-Y6W4DVPS.js} +4 -37
  39. package/dist/{chunk-KK7VGMEF.js → chunk-YV5INYEM.js} +6 -6
  40. package/dist/{chunk-RZAXPDIT.js → chunk-ZTZ7NCJT.js} +1 -1
  41. package/dist/{clean-VWT7OZEN.js → clean-AGTDSSLO.js} +9 -9
  42. package/dist/cli.js +50 -68
  43. package/dist/{cloud-BB7SW4DX.js → cloud-TIKQ43CO.js} +4 -4
  44. package/dist/{compare-3Z4BPHIZ.js → compare-2B7W2HXM.js} +13 -13
  45. package/dist/{component-6H2NIATV.js → component-ZQIN33DC.js} +3 -3
  46. package/dist/{compositions-I357YMW6.js → compositions-D6JAIKFJ.js} +5 -5
  47. package/dist/{delete-YJQPGNJJ.js → delete-UWZ6BBQI.js} +6 -5
  48. package/dist/{deterministicFonts-O7BTFDJU.js → deterministicFonts-ITMUXWD2.js} +2 -2
  49. package/dist/{doctor-NP34O2SX.js → doctor-LHUS7OQG.js} +3 -3
  50. package/dist/dotEnv-AI4SYVTX.js +39 -0
  51. package/dist/{events-NV6CNGUD.js → events-CNSBSROB.js} +2 -2
  52. package/dist/{events-T4KFU5HZ.js → events-EA2PNDU6.js} +3 -3
  53. package/dist/{feedback-DKHIGKC4.js → feedback-RAOT4ZX6.js} +36 -12
  54. package/dist/{figma-ALVXXDIQ.js → figma-HHALPQPX.js} +3 -3
  55. package/dist/fontLocalizeCli.js +4 -4
  56. package/dist/{get-CKKP6UBL.js → get-2VHYWD5M.js} +6 -5
  57. package/dist/{grade-compare-7POS3AY6.js → grade-compare-ZKYGIKRN.js} +9 -9
  58. package/dist/{help-KGRXGCVJ.js → help-YXXIXAVR.js} +1 -1
  59. package/dist/{history-JLXPVI2L.js → history-IFZM4MIB.js} +10 -10
  60. package/dist/hyperframes-player.global.js +1 -1
  61. package/dist/{info-QA5UAYFS.js → info-6TZU6FRJ.js} +5 -5
  62. package/dist/{init-7SM4AD76.js → init-5DPNU4VR.js} +12 -12
  63. package/dist/{inspect-ANJ2CRLP.js → inspect-LASYMXFA.js} +11 -11
  64. package/dist/{keyframes-H2ZUI3DC.js → keyframes-BS6D4QMB.js} +6 -6
  65. package/dist/{layout-EDDKQ67V.js → layout-HMJ5I362.js} +11 -11
  66. package/dist/{lint-SVXOETDR.js → lint-E2DTFSA5.js} +8 -8
  67. package/dist/{list-YRBK24UM.js → list-C3CXWSEA.js} +6 -5
  68. package/dist/{login-VE7VGBOA.js → login-W276LNGF.js} +6 -6
  69. package/dist/{logout-HJQT42RL.js → logout-Q654A3SI.js} +2 -2
  70. package/dist/{media-treatment-ZQOBGLJQ.js → media-treatment-XECAXDZD.js} +8 -8
  71. package/dist/{models-GVMX5TFG.js → models-6YWOFGV2.js} +4 -4
  72. package/dist/{motionShot-2Z6LRHEV.js → motionShot-TNMJ2TNL.js} +1 -1
  73. package/dist/{normalize-audio-QHMZWNNH.js → normalize-audio-JTK53ZDZ.js} +7 -7
  74. package/dist/{play-EYXIIZHG.js → play-PAJQYG2D.js} +17 -17
  75. package/dist/{present-YQ2BRUNH.js → present-TMFT5KD6.js} +13 -13
  76. package/dist/{preview-QMAPLY2S.js → preview-4HHLUOFB.js} +16 -16
  77. package/dist/{producer-FS442D4D.js → producer-6WPA3U6C.js} +1 -1
  78. package/dist/{publish-PCT6JM4B.js → publish-6RRDDVPK.js} +32 -26
  79. package/dist/{refresh-IK6LUV5Z.js → refresh-K24ETHMA.js} +2 -2
  80. package/dist/{render-6QXPYNLY.js → render-N4HBJR46.js} +14 -14
  81. package/dist/{render-HYA6UBZD.js → render-WFBNU2KD.js} +14 -13
  82. package/dist/{sherpa-COBFACPG.js → sherpa-GCD3QEO6.js} +4 -4
  83. package/dist/{skills-CT7TY7SZ.js → skills-D4HKC2WV.js} +5 -5
  84. package/dist/{skillsUpdateCheck-AWHTVNPB.js → skillsUpdateCheck-IPJRWH4Z.js} +3 -3
  85. package/dist/{snapshot-C4PYM7G5.js → snapshot-A7BIVQUX.js} +15 -15
  86. package/dist/{src-GGDAYPPK.js → src-POL5BSEV.js} +3 -3
  87. package/dist/{staticProjectServer-RBGIJQMY.js → staticProjectServer-BM2TZYJY.js} +4 -4
  88. package/dist/{status-FCLZF4FT.js → status-I7R2ATRZ.js} +2 -2
  89. package/dist/studio/assets/{hyperframes-player-7Icl2uVN.js → hyperframes-player-i4gqkhjz.js} +1 -1
  90. package/dist/studio/assets/{index-Dc8FEIEU.js → index-C7LHDM18.js} +1 -1
  91. package/dist/studio/assets/{index-DOO2cYhl.js → index-Ce3Lr-Gt.js} +174 -174
  92. package/dist/studio/assets/{index-7YcUqkoh.js → index-uWOhRqxe.js} +1 -1
  93. package/dist/studio/index.d.ts +5 -1
  94. package/dist/studio/index.html +1 -1
  95. package/dist/studio/index.js +72 -87
  96. package/dist/studio/index.js.map +1 -1
  97. package/dist/{studio-api-Y67F5TPC.js → studio-api-GWTH7IPD.js} +2 -2
  98. package/dist/{studioServer-SCAZGVUQ.js → studioServer-KB3KCVSZ.js} +10 -10
  99. package/dist/{telemetry-JJJQWUA3.js → telemetry-5WHZVQFM.js} +3 -3
  100. package/dist/{timeline-BEWRG3QA.js → timeline-KM5YF4WX.js} +10 -10
  101. package/dist/{tokens-GAZXBXWG.js → tokens-VUPKFWHG.js} +2 -2
  102. package/dist/{transcribe-ZCFEAIAW.js → transcribe-4IJPHM33.js} +5 -5
  103. package/dist/{transcribe-UJUYNNEH.js → transcribe-E7RAUZ2W.js} +2 -2
  104. package/dist/{updateCheck-H5DKTWUO.js → updateCheck-JY2WCSMC.js} +2 -2
  105. package/dist/{upgrade-RUBSQNRS.js → upgrade-QWBPPGTJ.js} +2 -2
  106. package/dist/{validate-5R3OJEGF.js → validate-5LJ6TDCF.js} +6 -6
  107. package/package.json +1 -1
  108. package/dist/{capture-PZQOA465.js → capture-6NN3YJBF.js} +0 -0
  109. package/dist/{chunk-AIYKVE4Y.js → chunk-2GKO3X7F.js} +3 -3
  110. package/dist/{chunk-KFKEMNSW.js → chunk-XUNOKLEJ.js} +3 -3
  111. /package/dist/{lambda-HZ2ZKLVH.js → lambda-AHKA33RE.js} +0 -0
@@ -51,6 +51,16 @@ var ErrRefreshFailed = (detail) => new AuthError(
51
51
  detail ? `Failed to refresh OAuth tokens: ${detail}` : "Failed to refresh OAuth tokens",
52
52
  "Run `hyperframes auth login` to re-authenticate."
53
53
  );
54
+ var ErrLoginExpired = () => new AuthError(
55
+ "LOGIN_EXPIRED",
56
+ "Your HeyGen login expired",
57
+ "Run `hyperframes auth login` to sign in again."
58
+ );
59
+ var ErrLoginChanged = () => new AuthError(
60
+ "LOGIN_CHANGED",
61
+ "Your HeyGen login changed while this command ran",
62
+ "Run the command again."
63
+ );
54
64
  var ErrDeviceAuthFailed = (detail) => new AuthError(
55
65
  "DEVICE_AUTH_FAILED",
56
66
  `Device authorization failed: ${detail}`,
@@ -461,14 +471,12 @@ async function resolveCredential(opts = {}) {
461
471
  const { credentials, source } = await readStore();
462
472
  if (source === "absent") throw ErrNotConfigured();
463
473
  const fileSource = source === "file_legacy" ? "file_legacy" : "file_json";
464
- if (credentials.oauth) {
465
- const oauth = pickOAuth(credentials.oauth, now, fileSource);
466
- if (oauth) return oauth;
467
- }
474
+ const oauth = credentials.oauth ? pickOAuth(credentials.oauth, now, fileSource) : null;
475
+ if (oauth) return oauth;
468
476
  if (credentials.api_key) {
469
477
  return { type: "api_key", key: credentials.api_key, source: fileSource };
470
478
  }
471
- throw ErrNotConfigured();
479
+ throw credentials.oauth ? ErrLoginExpired() : ErrNotConfigured();
472
480
  }
473
481
  async function tryResolveCredential(opts = {}) {
474
482
  try {
@@ -482,7 +490,7 @@ async function tryResolveCredential(opts = {}) {
482
490
  }
483
491
  function pickOAuth(tokens, now, source) {
484
492
  const expiresAt = parseDate(tokens.expires_at);
485
- const expired = expiresAt !== void 0 && expiresAt.getTime() - EXPIRY_SKEW_MS < now.getTime();
493
+ const expired = isTokenExpired(expiresAt, now);
486
494
  if (expired && !tokens.refresh_token) return null;
487
495
  const out = {
488
496
  type: "oauth",
@@ -495,6 +503,9 @@ function pickOAuth(tokens, now, source) {
495
503
  if (tokens.scope) out.scope = tokens.scope;
496
504
  return out;
497
505
  }
506
+ function isTokenExpired(expiresAt, now) {
507
+ return expiresAt !== void 0 && expiresAt.getTime() - EXPIRY_SKEW_MS < now.getTime();
508
+ }
498
509
  function parseDate(s) {
499
510
  if (!s) return void 0;
500
511
  const d = new Date(s);
@@ -736,7 +747,7 @@ async function startAuthorizationCodeFlow(opts = {}) {
736
747
  verifier: pkce.verifier,
737
748
  fetchImpl: opts.fetchImpl
738
749
  });
739
- await persistOAuth(tokens, { preserveMissing: false });
750
+ await persistOAuth(tokens);
740
751
  return { tokens };
741
752
  }
742
753
  async function startDeviceAuthorizationFlow(opts = {}) {
@@ -884,7 +895,7 @@ async function refreshTokens(refresh_token, opts = {}) {
884
895
  }
885
896
  const payload = await readJsonOrThrow(res);
886
897
  const tokens = parseTokenResponse(payload);
887
- await persistOAuth(tokens, { preserveMissing: true });
898
+ await persistOAuth(tokens, { refreshed: refresh_token });
888
899
  return tokens;
889
900
  }
890
901
  async function revokeTokens(token, opts = {}) {
@@ -1009,15 +1020,18 @@ function numericField(obj, key) {
1009
1020
  }
1010
1021
  return void 0;
1011
1022
  }
1012
- async function persistOAuth(tokens, opts) {
1023
+ async function persistOAuth(tokens, opts = {}) {
1013
1024
  let existing = {};
1014
1025
  try {
1015
1026
  const { credentials } = await readStore();
1016
1027
  existing = credentials;
1017
- } catch {
1018
- existing = {};
1028
+ } catch (err) {
1029
+ if (opts.refreshed !== void 0) throw err;
1030
+ }
1031
+ if (opts.refreshed !== void 0 && existing.oauth?.refresh_token !== opts.refreshed) {
1032
+ throw ErrLoginChanged();
1019
1033
  }
1020
- const oauth = opts.preserveMissing ? { ...existing.oauth, ...tokens } : { ...tokens };
1034
+ const oauth = opts.refreshed !== void 0 ? { ...existing.oauth, ...tokens } : { ...tokens };
1021
1035
  await writeStore({ ...existing, oauth });
1022
1036
  }
1023
1037
  async function persistVerifiedOAuthSession(tokens, user) {
@@ -1190,6 +1204,7 @@ export {
1190
1204
  isHeaderSafe,
1191
1205
  resolveCredential,
1192
1206
  tryResolveCredential,
1207
+ isTokenExpired,
1193
1208
  assertOAuthConfiguredOrExit,
1194
1209
  startAuthorizationCodeFlow,
1195
1210
  startDeviceAuthorizationFlow,
@@ -0,0 +1,24 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+
8
+ // src/utils/feedbackSource.ts
9
+ var SOURCES = ["person", "agent"];
10
+ function parseFeedbackSource(raw) {
11
+ if (raw === void 0) return void 0;
12
+ const source = raw.trim();
13
+ return SOURCES.includes(source) ? source : null;
14
+ }
15
+ var FEEDBACK_EMAIL_ENV = "HYPERFRAMES_FEEDBACK_EMAIL";
16
+ function feedbackEmail(env = process.env) {
17
+ return env[FEEDBACK_EMAIL_ENV]?.trim() || void 0;
18
+ }
19
+
20
+ export {
21
+ parseFeedbackSource,
22
+ FEEDBACK_EMAIL_ENV,
23
+ feedbackEmail
24
+ };
@@ -8,7 +8,7 @@ import {
8
8
  flush,
9
9
  shouldTrack,
10
10
  trackEvent
11
- } from "./chunk-M6LKSPER.js";
11
+ } from "./chunk-LJXFGHPO.js";
12
12
  import {
13
13
  getPowerState
14
14
  } from "./chunk-U7AMFQ6G.js";
@@ -4,10 +4,15 @@ import { dirname as __hf_dirname } from "node:path";
4
4
  var require = __hf_createRequire(import.meta.url);
5
5
  var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ refreshIfNeeded
9
+ } from "./chunk-SHB5VDMH.js";
7
10
  import {
8
11
  buildAuthHeaders,
12
+ isAuthError,
13
+ isTokenExpired,
9
14
  tryResolveCredential
10
- } from "./chunk-DNXD7TOA.js";
15
+ } from "./chunk-I465DBM6.js";
11
16
  import {
12
17
  CSS_URL_RE,
13
18
  isNonRelativeUrl,
@@ -191,6 +196,36 @@ function getUploadHeaders(data, uploadUrl, contentType, archiveByteLength) {
191
196
  async function readJson(response) {
192
197
  return response.clone().json().catch(() => null);
193
198
  }
199
+ var CredentialRejectedError = class extends Error {
200
+ };
201
+ async function metadataRequestError(response, fallback) {
202
+ const message = await readErrorMessage(response, fallback);
203
+ return response.status === 401 ? new CredentialRejectedError(message) : new Error(message);
204
+ }
205
+ var LOGIN_EXPIRED = "Your login expired. Run hyperframes auth login, then publish again.";
206
+ var LOGIN_CHANGED = "Your login changed during publish. Run publish again.";
207
+ var API_KEY_ENV_VAR = { env: "HEYGEN_API_KEY", env_alias: "HYPERFRAMES_API_KEY" };
208
+ function rejectedCredentialMessage(credential) {
209
+ if (credential.type === "api_key" && (credential.source === "env" || credential.source === "env_alias")) {
210
+ return `${API_KEY_ENV_VAR[credential.source]} was rejected. Fix or unset it, then publish again.`;
211
+ }
212
+ return LOGIN_EXPIRED;
213
+ }
214
+ async function resolvePublishCredential(checked) {
215
+ try {
216
+ const credential = checked === void 0 ? await tryResolveCredential() : checked;
217
+ if (!credential) return null;
218
+ const expired = credential.type === "oauth" && isTokenExpired(credential.expires_at, /* @__PURE__ */ new Date());
219
+ if (expired && !credential.refresh_token) throw new Error(LOGIN_EXPIRED);
220
+ return await refreshIfNeeded(expired ? { ...credential, refreshable: true } : credential);
221
+ } catch (error) {
222
+ if (isAuthError(error) && (error.code === "REFRESH_FAILED" || error.code === "LOGIN_EXPIRED")) {
223
+ throw new Error(LOGIN_EXPIRED);
224
+ }
225
+ if (isAuthError(error) && error.code === "LOGIN_CHANGED") throw new Error(LOGIN_CHANGED);
226
+ throw error;
227
+ }
228
+ }
194
229
  async function readErrorMessage(response, fallback) {
195
230
  const contentType = response.headers.get("content-type") || "";
196
231
  if (contentType.includes("application/json")) {
@@ -477,7 +512,7 @@ async function publishProjectArchiveDirect(apiBaseUrl, title, archive, isPublic,
477
512
  const payload = await readJson(response);
478
513
  const publishedProject = parsePublishedProjectResponse(payload);
479
514
  if (!response.ok || !publishedProject) {
480
- throw new Error(await readErrorMessage(response, "Failed to publish project"));
515
+ throw await metadataRequestError(response, "Failed to publish project");
481
516
  }
482
517
  return publishedProject;
483
518
  }
@@ -526,7 +561,7 @@ async function publishProjectArchiveStaged(apiBaseUrl, title, archive, isPublic,
526
561
  const uploadPayload = await readJson(uploadResponse);
527
562
  const stagedUpload = parseStagedUploadResponse(uploadPayload, archive.buffer.byteLength);
528
563
  if (!uploadResponse.ok || !stagedUpload) {
529
- throw new Error(await readErrorMessage(uploadResponse, "Failed to prepare project upload"));
564
+ throw await metadataRequestError(uploadResponse, "Failed to prepare project upload");
530
565
  }
531
566
  await uploadArchiveToPresignedUrl(stagedUpload, archive);
532
567
  const completeResponse = await fetchForPublish(
@@ -551,7 +586,7 @@ async function publishProjectArchiveStaged(apiBaseUrl, title, archive, isPublic,
551
586
  const completePayload = await readJson(completeResponse);
552
587
  const publishedProject = parsePublishedProjectResponse(completePayload);
553
588
  if (!completeResponse.ok || !publishedProject) {
554
- throw new Error(await readErrorMessage(completeResponse, "Failed to publish project"));
589
+ throw await metadataRequestError(completeResponse, "Failed to publish project");
555
590
  }
556
591
  return publishedProject;
557
592
  }
@@ -560,27 +595,38 @@ async function publishProjectArchive(projectDir, opts = {}) {
560
595
  const title = basename(projectDir);
561
596
  const archive = opts.archive ?? createPublishArchive(projectDir);
562
597
  const apiBaseUrl = getPublishApiBaseUrl();
563
- const credential = await tryResolveCredential();
598
+ const credential = await resolvePublishCredential(opts.credential);
564
599
  const authHeaders = credential ? buildAuthHeaders(credential) : {};
565
600
  const projectId = credential ? opts.projectId : void 0;
566
601
  const spaceId = credential ? opts.spaceId : void 0;
567
602
  const metadataHeaders = spaceId ? { ...authHeaders, "x-space-id": spaceId } : authHeaders;
568
- const result = await publishProjectArchiveStaged(
569
- apiBaseUrl,
570
- title,
571
- archive,
572
- isPublic,
573
- metadataHeaders,
574
- projectId
575
- ) ?? await publishProjectArchiveDirect(
576
- apiBaseUrl,
577
- title,
578
- archive,
579
- isPublic,
580
- metadataHeaders,
581
- projectId
582
- );
583
- if (credential) {
603
+ let result;
604
+ try {
605
+ result = await publishProjectArchiveStaged(
606
+ apiBaseUrl,
607
+ title,
608
+ archive,
609
+ isPublic,
610
+ metadataHeaders,
611
+ projectId
612
+ ) ?? await publishProjectArchiveDirect(
613
+ apiBaseUrl,
614
+ title,
615
+ archive,
616
+ isPublic,
617
+ metadataHeaders,
618
+ projectId
619
+ );
620
+ if (credential?.type === "oauth" && !result.claimed) {
621
+ throw new CredentialRejectedError("unclaimed publish");
622
+ }
623
+ } catch (error) {
624
+ if (error instanceof CredentialRejectedError && credential) {
625
+ throw new Error(rejectedCredentialMessage(credential));
626
+ }
627
+ throw error;
628
+ }
629
+ if (result.claimed) {
584
630
  writeProjectLink(projectDir, { projectId: result.projectId, url: result.url });
585
631
  }
586
632
  return result;
@@ -591,6 +637,8 @@ export {
591
637
  ensureProjectId,
592
638
  readTeamProject,
593
639
  writeTeamProject,
640
+ API_KEY_ENV_VAR,
641
+ resolvePublishCredential,
594
642
  rewriteHtmlAttributes,
595
643
  buildPublishFileMap,
596
644
  zipPublishFileMap,
@@ -6,8 +6,8 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
 
8
8
  // src/version.ts
9
- var VERSION = true ? "0.8.119" : "0.0.0-dev";
10
- var PRODUCER_VERSION = true ? "0.8.119" : "0.0.0-dev";
9
+ var VERSION = true ? "0.8.120" : "0.0.0-dev";
10
+ var PRODUCER_VERSION = true ? "0.8.120" : "0.0.0-dev";
11
11
 
12
12
  export {
13
13
  VERSION,
@@ -37,7 +37,7 @@ import {
37
37
  } from "./chunk-XUXGIA7H.js";
38
38
  import {
39
39
  VERSION
40
- } from "./chunk-3NXDJSD5.js";
40
+ } from "./chunk-LIPKCOYU.js";
41
41
 
42
42
  // src/telemetry/transport.ts
43
43
  import { spawn } from "child_process";
@@ -9,6 +9,7 @@ import {
9
9
  dedupeClonedCompositionId,
10
10
  findTargetElement,
11
11
  isHTMLElement,
12
+ nextUniqueId,
12
13
  parseSourceDocument,
13
14
  patchElementInHtml,
14
15
  probeElementInSource,
@@ -20,7 +21,7 @@ import {
20
21
  splitElementInHtml,
21
22
  unwrapElementsFromHtml,
22
23
  wrapElementsInHtml
23
- } from "./chunk-HNOJAFT2.js";
24
+ } from "./chunk-6ZX3YCCU.js";
24
25
  import {
25
26
  atomicTempPath,
26
27
  createFileAtomically,
@@ -6021,6 +6022,21 @@ function foldElementPatches(originalContent, patches) {
6021
6022
  return { content, matched };
6022
6023
  }
6023
6024
  var PATCH_CONFLICT_ATTEMPTS = 3;
6025
+ var ID_ATTRIBUTE = /[\s"'/]id\s*=\s*(?=(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))/gi;
6026
+ function projectHtmlIds(projectDir) {
6027
+ const ids = /* @__PURE__ */ new Set();
6028
+ for (const rel of walkDir(projectDir)) {
6029
+ if (!rel.endsWith(".html") || isInHiddenOrVendorDir(rel)) continue;
6030
+ let html;
6031
+ try {
6032
+ html = readFileSync32(join52(projectDir, rel), "utf-8");
6033
+ } catch {
6034
+ continue;
6035
+ }
6036
+ for (const m of html.matchAll(ID_ATTRIBUTE)) ids.add(m[1] ?? m[2] ?? m[3] ?? "");
6037
+ }
6038
+ return ids;
6039
+ }
6024
6040
  function commitElementPatchBatches(projectDir, batches, writeFile2 = (path, content) => replaceFileAtomically(path, content, statSync32(path).mode), requestToken) {
6025
6041
  for (let attempt = 1; ; attempt += 1) {
6026
6042
  try {
@@ -7912,7 +7928,13 @@ function registerFileRoutes(api, adapter) {
7912
7928
  } catch {
7913
7929
  return c.json({ error: "not found" }, 404);
7914
7930
  }
7915
- const element = patchElementInHtml(originalContent, parsed.target, parsed.body.operations);
7931
+ const takenIds = parsed.body.operations.some((op) => op.type === "ensure-id") ? projectHtmlIds(ctx.project.dir) : void 0;
7932
+ const element = patchElementInHtml(
7933
+ originalContent,
7934
+ parsed.target,
7935
+ parsed.body.operations,
7936
+ takenIds
7937
+ );
7916
7938
  const { matched } = element;
7917
7939
  const patched = matched && isStudioFontFaceCss(fontFaceCss) ? ensureStudioFontFaceCss(element.html, fontFaceCss) : element.html;
7918
7940
  if (patched === originalContent) {
@@ -7922,6 +7944,7 @@ function registerFileRoutes(api, adapter) {
7922
7944
  ok: true,
7923
7945
  changed: false,
7924
7946
  matched,
7947
+ elementId: element.elementId,
7925
7948
  content: originalContent,
7926
7949
  path: ctx.filePath,
7927
7950
  version: version2
@@ -7945,6 +7968,7 @@ function registerFileRoutes(api, adapter) {
7945
7968
  ok: true,
7946
7969
  changed: true,
7947
7970
  matched,
7971
+ elementId: element.elementId,
7948
7972
  content: patched,
7949
7973
  path: ctx.filePath,
7950
7974
  version,
@@ -9884,11 +9908,6 @@ function spans(el, time) {
9884
9908
  if (start === null || duration === null) return false;
9885
9909
  return time > start + EPSILON && time < start + duration - EPSILON;
9886
9910
  }
9887
- function uniqueId(document2, base) {
9888
- let id = base;
9889
- for (let n = 2; document2.getElementById(id); n++) id = `${base}-${n}`;
9890
- return id;
9891
- }
9892
9911
  function shiftTracks(document2, tracks, from, by) {
9893
9912
  for (const el of document2.querySelectorAll("[data-start]")) {
9894
9913
  if (el.hasAttribute("data-composition-id") || !tracks.has(trackOf(el))) continue;
@@ -9972,7 +9991,7 @@ function applyFreezeFrameToHtml(html, input) {
9972
9991
  shiftTracks(document2, tracks, input.playhead, hold);
9973
9992
  const leftHalf = findTargetElement(document2, input.target);
9974
9993
  if (!leftHalf?.parentElement) return null;
9975
- const freezeId = uniqueId(document2, `${video.getAttribute("id") || "clip"}-freeze`);
9994
+ const freezeId = nextUniqueId(document2, `${video.getAttribute("id") || "clip"}-freeze`);
9976
9995
  const still = buildStill(document2, leftHalf, {
9977
9996
  id: freezeId,
9978
9997
  imageSrc: input.imageSrc,
@@ -11003,23 +11022,17 @@ function duplicateElementInHtml(source, target, newId, at) {
11003
11022
  if (duration === null || numericAttribute(element, "data-start") === null) {
11004
11023
  return { html: source, matched: false, newId: null };
11005
11024
  }
11006
- const uniqueId2 = nextUniqueId(document2, newId);
11025
+ const uniqueId = nextUniqueId(document2, newId);
11007
11026
  rippleElements(document2, element, at, duration, track);
11008
11027
  const clone = element.cloneNode(true);
11009
11028
  if (!isHTMLElement(clone)) return { html: source, matched: false, newId: null };
11010
- clone.setAttribute("id", uniqueId2);
11029
+ clone.setAttribute("id", uniqueId);
11011
11030
  dedupeClonedCompositionId(document2, clone);
11012
11031
  stripStableIds(clone);
11013
11032
  clone.setAttribute("data-start", String(at));
11014
11033
  element.parentElement.insertBefore(clone, element.nextSibling);
11015
11034
  const html = wrappedFragment ? document2.body.innerHTML || "" : document2.toString();
11016
- return { html: ensureHfIds(html), matched: true, newId: uniqueId2 };
11017
- }
11018
- function nextUniqueId(document2, newId) {
11019
- let uniqueId2 = newId;
11020
- let suffix = 2;
11021
- while (document2.getElementById(uniqueId2)) uniqueId2 = `${newId}-${suffix++}`;
11022
- return uniqueId2;
11035
+ return { html: ensureHfIds(html), matched: true, newId: uniqueId };
11023
11036
  }
11024
11037
  function rippleElements(document2, element, at, duration, track) {
11025
11038
  for (const candidate of Array.from(document2.querySelectorAll("[data-start][data-duration]"))) {
@@ -20,7 +20,7 @@ import {
20
20
  typeDirPath,
21
21
  updateRecord,
22
22
  withFigmaErrors
23
- } from "./chunk-2FJPEXII.js";
23
+ } from "./chunk-UOKW7DPN.js";
24
24
  import {
25
25
  defineCommand
26
26
  } from "./chunk-S3S4TGEH.js";
@@ -221,7 +221,7 @@ var asset_default = defineCommand({
221
221
  rendered > 0 ? `(${results.length} nodes, ${rendered} rendered in 1 figma request)` : `(${results.length} nodes, all reused from cache \u2014 no figma request)`
222
222
  );
223
223
  }
224
- const { trackFigmaImport } = await import("./telemetry-JJJQWUA3.js");
224
+ const { trackFigmaImport } = await import("./telemetry-5WHZVQFM.js");
225
225
  trackFigmaImport({
226
226
  phase: "asset",
227
227
  reused: results.every((r) => r.reused),
@@ -12,7 +12,7 @@ import {
12
12
  iterateFontFamilyDeclarations,
13
13
  normalizeSystemFontPrimaryFamilies,
14
14
  resolveFontFamilyDeclarationFamilies
15
- } from "./chunk-AIYKVE4Y.js";
15
+ } from "./chunk-2GKO3X7F.js";
16
16
  import {
17
17
  EncoderInterruptedError,
18
18
  encoderFailureError,
@@ -6,7 +6,7 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  updateNoticesSuppressed
9
- } from "./chunk-FRIRP3DN.js";
9
+ } from "./chunk-7N3IODU7.js";
10
10
  import {
11
11
  hostAnswers
12
12
  } from "./chunk-K4WIOZFP.js";
@@ -0,0 +1,51 @@
1
+ import { createRequire as __hf_createRequire } from "node:module";
2
+ import { fileURLToPath as __hf_fileURLToPath } from "node:url";
3
+ import { dirname as __hf_dirname } from "node:path";
4
+ var require = __hf_createRequire(import.meta.url);
5
+ var __filename = __hf_fileURLToPath(import.meta.url);
6
+ var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ apiBaseUrl,
9
+ buildAuthHeaders,
10
+ refreshTokens,
11
+ resolveCredential
12
+ } from "./chunk-I465DBM6.js";
13
+
14
+ // src/cloud/auth.ts
15
+ async function resolveCloudAuthHeaders() {
16
+ let credential = await resolveCredential();
17
+ credential = await refreshIfNeeded(credential);
18
+ return buildAuthHeaders(credential);
19
+ }
20
+ function resolveCloudBaseUrl() {
21
+ return apiBaseUrl();
22
+ }
23
+ async function refreshIfNeeded(credential) {
24
+ if (credential.type !== "oauth") return credential;
25
+ if (!credential.refreshable || !credential.refresh_token) return credential;
26
+ const fresh = await refreshTokens(credential.refresh_token);
27
+ return {
28
+ ...credential,
29
+ access_token: fresh.access_token,
30
+ expires_at: parseDateOrUndef(fresh.expires_at),
31
+ refreshable: false,
32
+ ...fresh.refresh_token ? { refresh_token: fresh.refresh_token } : {}
33
+ };
34
+ }
35
+ function parseDateOrUndef(value) {
36
+ if (!value) return void 0;
37
+ const d = new Date(value);
38
+ return Number.isNaN(d.getTime()) ? void 0 : d;
39
+ }
40
+ async function forceRefreshCredentials() {
41
+ const credential = await resolveCredential();
42
+ if (credential.type !== "oauth" || !credential.refresh_token) return;
43
+ await refreshTokens(credential.refresh_token);
44
+ }
45
+
46
+ export {
47
+ resolveCloudAuthHeaders,
48
+ resolveCloudBaseUrl,
49
+ refreshIfNeeded,
50
+ forceRefreshCredentials
51
+ };
@@ -7,7 +7,7 @@ var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  getMimeType,
9
9
  injectMediaCodecMapIntoHtml
10
- } from "./chunk-ZTU5PYQJ.js";
10
+ } from "./chunk-LP3KFEVQ.js";
11
11
  import {
12
12
  PROXY_VARIANT_CONFIG,
13
13
  ProxyCapacityError,
@@ -7,7 +7,7 @@ var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  RegistryCompatibilityError,
9
9
  gateRegistryItemsCompatibility
10
- } from "./chunk-P6UJ22SS.js";
10
+ } from "./chunk-EFC3DCJL.js";
11
11
  import {
12
12
  DEFAULT_PROJECT_CONFIG,
13
13
  createProjectConfig,
@@ -29,7 +29,7 @@ import {
29
29
  } from "./chunk-PPTHGZTG.js";
30
30
  import {
31
31
  trackRegistryItemAdded
32
- } from "./chunk-CDTPNYO3.js";
32
+ } from "./chunk-IJ2O4BLJ.js";
33
33
  import {
34
34
  c
35
35
  } from "./chunk-ZTZA4UWZ.js";
@@ -1278,7 +1278,7 @@ async function withFigmaErrors(command, fn) {
1278
1278
  } catch (err) {
1279
1279
  if (err instanceof Error) {
1280
1280
  try {
1281
- const { trackCommandFailure } = await import("./events-T4KFU5HZ.js");
1281
+ const { trackCommandFailure } = await import("./events-EA2PNDU6.js");
1282
1282
  trackCommandFailure(
1283
1283
  command,
1284
1284
  err,
@@ -6,7 +6,7 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  getMimeType
9
- } from "./chunk-ZTU5PYQJ.js";
9
+ } from "./chunk-LP3KFEVQ.js";
10
10
  import {
11
11
  injectTagsAtHeadStart
12
12
  } from "./chunk-SHLFJFPM.js";
@@ -5,11 +5,10 @@ var require = __hf_createRequire(import.meta.url);
5
5
  var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
- apiBaseUrl,
9
- buildAuthHeaders,
10
- refreshTokens,
11
- resolveCredential
12
- } from "./chunk-DNXD7TOA.js";
8
+ forceRefreshCredentials,
9
+ resolveCloudAuthHeaders,
10
+ resolveCloudBaseUrl
11
+ } from "./chunk-SHB5VDMH.js";
13
12
  import {
14
13
  errorBox
15
14
  } from "./chunk-IHFUKJOR.js";
@@ -277,38 +276,6 @@ var HyperframesCloudClient = class {
277
276
  }
278
277
  };
279
278
 
280
- // src/cloud/auth.ts
281
- async function resolveCloudAuthHeaders() {
282
- let credential = await resolveCredential();
283
- credential = await refreshIfNeeded(credential);
284
- return buildAuthHeaders(credential);
285
- }
286
- function resolveCloudBaseUrl() {
287
- return apiBaseUrl();
288
- }
289
- async function refreshIfNeeded(credential) {
290
- if (credential.type !== "oauth") return credential;
291
- if (!credential.refreshable || !credential.refresh_token) return credential;
292
- const fresh = await refreshTokens(credential.refresh_token);
293
- return {
294
- ...credential,
295
- access_token: fresh.access_token,
296
- expires_at: parseDateOrUndef(fresh.expires_at),
297
- refreshable: false,
298
- ...fresh.refresh_token ? { refresh_token: fresh.refresh_token } : {}
299
- };
300
- }
301
- function parseDateOrUndef(value) {
302
- if (!value) return void 0;
303
- const d = new Date(value);
304
- return Number.isNaN(d.getTime()) ? void 0 : d;
305
- }
306
- async function forceRefreshCredentials() {
307
- const credential = await resolveCredential();
308
- if (credential.type !== "oauth" || !credential.refresh_token) return;
309
- await refreshTokens(credential.refresh_token);
310
- }
311
-
312
279
  // src/cloud/index.ts
313
280
  async function createCloudClient() {
314
281
  const client = new HyperframesCloudClient({
@@ -4,6 +4,9 @@ import { dirname as __hf_dirname } from "node:path";
4
4
  var require = __hf_createRequire(import.meta.url);
5
5
  var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
+ import {
8
+ resolveProject
9
+ } from "./chunk-B3MQEZBK.js";
7
10
  import {
8
11
  installPageFunctionGuard,
9
12
  resolveCliChromeGpuMode,
@@ -16,9 +19,6 @@ import {
16
19
  launchManagedBrowser,
17
20
  resolveManagedGpuMode
18
21
  } from "./chunk-OI3IIR2X.js";
19
- import {
20
- resolveProject
21
- } from "./chunk-6Q3Q7HGA.js";
22
22
  import {
23
23
  c
24
24
  } from "./chunk-ZTZA4UWZ.js";
@@ -32,7 +32,7 @@ import {
32
32
  import {
33
33
  printDeprecationNotice,
34
34
  withMeta
35
- } from "./chunk-FRIRP3DN.js";
35
+ } from "./chunk-7N3IODU7.js";
36
36
  import {
37
37
  normalizeErrorMessage
38
38
  } from "./chunk-KNU5COPB.js";
@@ -221,7 +221,7 @@ function extractCompositionErrorsFromLint(lintResult) {
221
221
  async function localizeRemoteAssets(html) {
222
222
  let dir;
223
223
  try {
224
- const { loadProducer } = await import("./producer-FS442D4D.js");
224
+ const { loadProducer } = await import("./producer-6WPA3U6C.js");
225
225
  const { localizeRemoteMediaSources, localizeRemoteImageSources, localizeRemoteFontFaces } = await loadProducer();
226
226
  dir = mkdtempSync(join(tmpdir(), "hf-validate-assets-"));
227
227
  const assetDir = dir;
@@ -244,7 +244,7 @@ async function validateInBrowser(project, opts) {
244
244
  const projectDir = project.dir;
245
245
  const { bundleToSingleHtml } = await import("./compiler-GPUSYMA6.js");
246
246
  const { ensureBrowser } = await import("./manager-CT3D67CG.js");
247
- const { serveStaticProjectHtml } = await import("./staticProjectServer-RBGIJQMY.js");
247
+ const { serveStaticProjectHtml } = await import("./staticProjectServer-BM2TZYJY.js");
248
248
  const { lintProject } = await import("./lintProject-FDJYTOVM.js");
249
249
  const lintResult = await lintProject(projectDir);
250
250
  const compositionErrors = extractCompositionErrorsFromLint(lintResult);
@@ -10,7 +10,7 @@ import {
10
10
  hasPreservedUnknownData,
11
11
  readStore,
12
12
  writeStore
13
- } from "./chunk-DNXD7TOA.js";
13
+ } from "./chunk-I465DBM6.js";
14
14
 
15
15
  // src/auth/user.ts
16
16
  function isUserInfoEmpty(u) {