@hexclave/next 1.0.74 → 1.0.76

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/{admin-app-impl-FZdANO62.d.ts → admin-app-impl-CsH-gVGz.d.ts} +2 -2
  2. package/dist/{admin-app-impl-FZdANO62.d.ts.map → admin-app-impl-CsH-gVGz.d.ts.map} +1 -1
  3. package/dist/components/api-key-dialogs.d.ts +1 -1
  4. package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
  5. package/dist/dev-tool/dev-tool-core.js +2 -2
  6. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  7. package/dist/dev-tool/index.d.ts.map +1 -1
  8. package/dist/dev-tool/index.js +2 -8
  9. package/dist/dev-tool/index.js.map +1 -1
  10. package/dist/esm/components/api-key-dialogs.d.ts +1 -1
  11. package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
  12. package/dist/esm/dev-tool/dev-tool-core.js +1 -1
  13. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  14. package/dist/esm/dev-tool/index.d.ts.map +1 -1
  15. package/dist/esm/dev-tool/index.js +2 -8
  16. package/dist/esm/dev-tool/index.js.map +1 -1
  17. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  18. package/dist/esm/in-page-ui/dev-environment.d.ts +5 -0
  19. package/dist/esm/in-page-ui/dev-environment.d.ts.map +1 -0
  20. package/dist/esm/in-page-ui/dev-environment.js +18 -0
  21. package/dist/esm/in-page-ui/dev-environment.js.map +1 -0
  22. package/dist/esm/in-page-ui/issue-card.d.ts +52 -0
  23. package/dist/esm/in-page-ui/issue-card.d.ts.map +1 -0
  24. package/dist/esm/in-page-ui/issue-card.js +392 -0
  25. package/dist/esm/in-page-ui/issue-card.js.map +1 -0
  26. package/dist/esm/in-page-ui/issue-card.test.d.ts +1 -0
  27. package/dist/esm/in-page-ui/issue-card.test.js +60 -0
  28. package/dist/esm/in-page-ui/issue-card.test.js.map +1 -0
  29. package/dist/esm/in-page-ui/logo.d.ts +5 -0
  30. package/dist/esm/in-page-ui/logo.d.ts.map +1 -0
  31. package/dist/esm/in-page-ui/logo.js +6 -0
  32. package/dist/esm/in-page-ui/logo.js.map +1 -0
  33. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  34. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  35. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +140 -15
  36. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  37. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  38. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +95 -12
  39. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  40. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
  41. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +1 -0
  42. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -1
  43. package/dist/esm/pushed-config-error-overlay/index.d.ts.map +1 -1
  44. package/dist/esm/pushed-config-error-overlay/index.js +42 -343
  45. package/dist/esm/pushed-config-error-overlay/index.js.map +1 -1
  46. package/dist/esm/setup-error-overlay/index.d.ts +16 -0
  47. package/dist/esm/setup-error-overlay/index.d.ts.map +1 -0
  48. package/dist/esm/setup-error-overlay/index.js +106 -0
  49. package/dist/esm/setup-error-overlay/index.js.map +1 -0
  50. package/dist/esm/setup-error-overlay/index.test.d.ts +1 -0
  51. package/dist/esm/setup-error-overlay/index.test.js +125 -0
  52. package/dist/esm/setup-error-overlay/index.test.js.map +1 -0
  53. package/dist/generated/quetzal-translations.d.ts +1 -1
  54. package/dist/{hexclave-provider-BKxi3Vy-.d.ts → hexclave-provider-BA97jMlx.d.ts} +2 -2
  55. package/dist/{hexclave-provider-BKxi3Vy-.d.ts.map → hexclave-provider-BA97jMlx.d.ts.map} +1 -1
  56. package/dist/in-page-ui/dev-environment.d.ts +5 -0
  57. package/dist/in-page-ui/dev-environment.d.ts.map +1 -0
  58. package/dist/in-page-ui/dev-environment.js +19 -0
  59. package/dist/in-page-ui/dev-environment.js.map +1 -0
  60. package/dist/in-page-ui/issue-card.d.ts +52 -0
  61. package/dist/in-page-ui/issue-card.d.ts.map +1 -0
  62. package/dist/in-page-ui/issue-card.js +397 -0
  63. package/dist/in-page-ui/issue-card.js.map +1 -0
  64. package/dist/in-page-ui/issue-card.test.d.ts +1 -0
  65. package/dist/in-page-ui/issue-card.test.js +59 -0
  66. package/dist/in-page-ui/issue-card.test.js.map +1 -0
  67. package/dist/in-page-ui/logo.d.ts +5 -0
  68. package/dist/in-page-ui/logo.d.ts.map +1 -0
  69. package/dist/in-page-ui/logo.js +7 -0
  70. package/dist/in-page-ui/logo.js.map +1 -0
  71. package/dist/index.d.ts +1 -1
  72. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  73. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +140 -15
  74. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  75. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
  76. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +94 -11
  77. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  78. package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
  79. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  80. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +1 -0
  81. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -1
  82. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  83. package/dist/providers/hexclave-provider.d.ts +1 -1
  84. package/dist/providers/translation-provider.d.ts +1 -1
  85. package/dist/pushed-config-error-overlay/index.d.ts.map +1 -1
  86. package/dist/pushed-config-error-overlay/index.js +41 -342
  87. package/dist/pushed-config-error-overlay/index.js.map +1 -1
  88. package/dist/{quetzal-translations-XeH3zQ9l.d.ts → quetzal-translations-CK45_4Dm.d.ts} +3 -3
  89. package/dist/{quetzal-translations-XeH3zQ9l.d.ts.map → quetzal-translations-CK45_4Dm.d.ts.map} +1 -1
  90. package/dist/setup-error-overlay/index.d.ts +16 -0
  91. package/dist/setup-error-overlay/index.d.ts.map +1 -0
  92. package/dist/setup-error-overlay/index.js +108 -0
  93. package/dist/setup-error-overlay/index.js.map +1 -0
  94. package/dist/setup-error-overlay/index.test.d.ts +1 -0
  95. package/dist/setup-error-overlay/index.test.js +124 -0
  96. package/dist/setup-error-overlay/index.test.js.map +1 -0
  97. package/dist/{translation-provider-WOaZXqAz.d.ts → translation-provider-DQ3BJepJ.d.ts} +2 -2
  98. package/dist/{translation-provider-WOaZXqAz.d.ts.map → translation-provider-DQ3BJepJ.d.ts.map} +1 -1
  99. package/package.json +4 -4
  100. package/src/dev-tool/dev-tool-core.ts +1 -4
  101. package/src/dev-tool/index.ts +4 -15
  102. package/src/in-page-ui/dev-environment.ts +33 -0
  103. package/src/in-page-ui/issue-card.test.ts +67 -0
  104. package/src/in-page-ui/issue-card.ts +500 -0
  105. package/src/in-page-ui/logo.ts +8 -0
  106. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +158 -0
  107. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +125 -17
  108. package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.test.ts +1 -0
  109. package/src/pushed-config-error-overlay/index.ts +45 -386
  110. package/src/setup-error-overlay/index.test.ts +133 -0
  111. package/src/setup-error-overlay/index.ts +150 -0
@@ -17,8 +17,8 @@ let _hexclave_shared_dist_utils_stores = require("@hexclave/shared/dist/utils/st
17
17
  let ____________generated_env_js = require("../../../../generated/env.js");
18
18
  let ______url_targets_js = require("../../url-targets.js");
19
19
  //#region src/lib/hexclave-app/apps/implementations/common.ts
20
- const clientVersion = "js @hexclave/next@1.0.74";
21
- if ("js @hexclave/next@1.0.74".startsWith("STACK_COMPILE_TIME"));
20
+ const clientVersion = "js @hexclave/next@1.0.76";
21
+ if ("js @hexclave/next@1.0.76".startsWith("STACK_COMPILE_TIME"));
22
22
  const replaceHexclavePortPrefix = (input) => {
23
23
  if (!input) return input;
24
24
  const prefix = ____________generated_env_js.envVars.HEXCLAVE_PORT_PREFIX;
@@ -1,4 +1,4 @@
1
- import { n as _HexclaveServerAppImplIncomplete, r as _HexclaveClientAppImplIncomplete, t as _HexclaveAdminAppImplIncomplete } from "../../../../admin-app-impl-FZdANO62.js";
1
+ import { n as _HexclaveServerAppImplIncomplete, r as _HexclaveClientAppImplIncomplete, t as _HexclaveAdminAppImplIncomplete } from "../../../../admin-app-impl-CsH-gVGz.js";
2
2
 
3
3
  //#region src/lib/hexclave-app/apps/implementations/index.d.ts
4
4
  declare const _HexclaveAdminAppImpl: typeof _HexclaveAdminAppImplIncomplete, _HexclaveClientAppImpl: typeof _HexclaveClientAppImplIncomplete, _HexclaveServerAppImpl: typeof _HexclaveServerAppImplIncomplete;
@@ -7,6 +7,7 @@ async function plan(options) {
7
7
  ...options,
8
8
  noRedirectBack: options.noRedirectBack === true,
9
9
  localOAuthCallbackUrl,
10
+ rawHomeUrl: "/",
10
11
  getCrossDomainHandoffParams: async () => {
11
12
  throw new Error("Continuation-only redirects must not mint a new cross-domain handoff");
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"redirect-page-urls.test.js","names":["crossDomainAuthQueryParams"],"sources":["../../../../../src/lib/hexclave-app/apps/implementations/redirect-page-urls.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it } from \"vitest\";\nimport { crossDomainAuthQueryParams, planRedirectToHandler } from \"./redirect-page-urls\";\n\nconst localOAuthCallbackUrl = \"https://hosted.example.test/handler/oauth-callback\";\n\nasync function plan(options: {\n handlerName: \"signIn\" | \"forgotPassword\" | \"passwordReset\" | \"afterSignIn\" | \"afterSignUp\",\n rawHandlerUrl: string,\n currentUrl: URL,\n noRedirectBack?: boolean,\n}) {\n return await planRedirectToHandler({\n ...options,\n noRedirectBack: options.noRedirectBack === true,\n localOAuthCallbackUrl,\n getCrossDomainHandoffParams: async () => {\n throw new Error(\"Continuation-only redirects must not mint a new cross-domain handoff\");\n },\n });\n}\n\nfunction expectRedirectUrl(planResult: Awaited<ReturnType<typeof plan>>, baseUrl: URL): URL {\n if (planResult.type !== \"redirect\") {\n throw new Error(\"Expected a direct redirect plan\");\n }\n return new URL(planResult.url, baseUrl);\n}\n\nfunction expectContinuation(url: URL, expectedReturnTo: string): void {\n expect(url.searchParams.get(\"after_auth_return_to\")).toBe(expectedReturnTo);\n expect(url.searchParams.get(crossDomainAuthQueryParams.state)).toBe(\"outer-state\");\n expect(url.searchParams.get(crossDomainAuthQueryParams.codeChallenge)).toBe(\"outer-challenge\");\n expect(url.searchParams.get(crossDomainAuthQueryParams.afterCallbackRedirectUrl)).toBe(\"https://customer.example.test/dashboard\");\n}\n\ndescribe(\"password-flow redirect continuation\", () => {\n it(\"carries the complete customer return state through forgot-password and a reset-email new tab\", async () => {\n const customerReturnTo = \"https://customer.example.test/handler/oauth-callback?hexclave_cross_domain_auth=1\";\n const signInUrl = new URL(\"https://hosted.example.test/handler/sign-in\");\n signInUrl.searchParams.set(\"after_auth_return_to\", customerReturnTo);\n signInUrl.searchParams.set(crossDomainAuthQueryParams.state, \"outer-state\");\n signInUrl.searchParams.set(crossDomainAuthQueryParams.codeChallenge, \"outer-challenge\");\n signInUrl.searchParams.set(crossDomainAuthQueryParams.afterCallbackRedirectUrl, \"https://customer.example.test/dashboard\");\n\n const forgotPlan = await plan({\n handlerName: \"forgotPassword\",\n rawHandlerUrl: \"/handler/forgot-password\",\n currentUrl: signInUrl,\n });\n const forgotUrl = expectRedirectUrl(forgotPlan, signInUrl);\n expectContinuation(forgotUrl, customerReturnTo);\n\n const callbackPlan = await plan({\n handlerName: \"passwordReset\",\n rawHandlerUrl: \"/handler/password-reset\",\n currentUrl: forgotUrl,\n });\n const resetEmailCallbackUrl = expectRedirectUrl(callbackPlan, forgotUrl);\n expectContinuation(resetEmailCallbackUrl, customerReturnTo);\n\n // Model opening the callback in a new tab: only URL state is available.\n resetEmailCallbackUrl.searchParams.set(\"code\", \"reset-code\");\n const signInPlan = await plan({\n handlerName: \"signIn\",\n rawHandlerUrl: \"/handler/sign-in\",\n currentUrl: resetEmailCallbackUrl,\n noRedirectBack: true,\n });\n const finalSignInUrl = expectRedirectUrl(signInPlan, resetEmailCallbackUrl);\n expectContinuation(finalSignInUrl, customerReturnTo);\n expect(finalSignInUrl.searchParams.has(\"code\")).toBe(false);\n });\n\n it.each([\n [\"forgotPassword\", \"/handler/forgot-password\"],\n [\"passwordReset\", \"/handler/password-reset\"],\n ] as const)(\"never synthesizes the current %s page as a return target\", async (handlerName, rawHandlerUrl) => {\n const currentUrl = new URL(`https://hosted.example.test${rawHandlerUrl}?code=reset-code`);\n const result = expectRedirectUrl(await plan({\n handlerName,\n rawHandlerUrl,\n currentUrl,\n }), currentUrl);\n\n expect(result.searchParams.has(\"after_auth_return_to\")).toBe(false);\n expect(result.searchParams.has(\"code\")).toBe(false);\n });\n\n it(\"makes sign-in noRedirectBack suppress capture while preserving only inherited state\", async () => {\n const resetUrlWithoutContinuation = new URL(\"https://hosted.example.test/handler/password-reset?code=reset-code\");\n const result = expectRedirectUrl(await plan({\n handlerName: \"signIn\",\n rawHandlerUrl: \"/handler/sign-in\",\n currentUrl: resetUrlWithoutContinuation,\n noRedirectBack: true,\n }), resetUrlWithoutContinuation);\n\n expect(result.toString()).toBe(\"https://hosted.example.test/handler/sign-in\");\n });\n\n it.each([\"afterSignIn\", \"afterSignUp\"] as const)(\n \"keeps existing %s noRedirectBack semantics\",\n async (handlerName) => {\n const currentUrl = new URL(\"https://hosted.example.test/handler/sign-in?after_auth_return_to=%2Fcustomer\");\n const result = expectRedirectUrl(await plan({\n handlerName,\n rawHandlerUrl: \"/default-after-auth\",\n currentUrl,\n noRedirectBack: true,\n }), currentUrl);\n\n expect(result.toString()).toBe(\"https://hosted.example.test/default-after-auth\");\n },\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"redirect-page-urls.test.js","names":["crossDomainAuthQueryParams"],"sources":["../../../../../src/lib/hexclave-app/apps/implementations/redirect-page-urls.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it } from \"vitest\";\nimport { crossDomainAuthQueryParams, planRedirectToHandler } from \"./redirect-page-urls\";\n\nconst localOAuthCallbackUrl = \"https://hosted.example.test/handler/oauth-callback\";\n\nasync function plan(options: {\n handlerName: \"signIn\" | \"forgotPassword\" | \"passwordReset\" | \"afterSignIn\" | \"afterSignUp\",\n rawHandlerUrl: string,\n currentUrl: URL,\n noRedirectBack?: boolean,\n}) {\n return await planRedirectToHandler({\n ...options,\n noRedirectBack: options.noRedirectBack === true,\n localOAuthCallbackUrl,\n rawHomeUrl: \"/\",\n getCrossDomainHandoffParams: async () => {\n throw new Error(\"Continuation-only redirects must not mint a new cross-domain handoff\");\n },\n });\n}\n\nfunction expectRedirectUrl(planResult: Awaited<ReturnType<typeof plan>>, baseUrl: URL): URL {\n if (planResult.type !== \"redirect\") {\n throw new Error(\"Expected a direct redirect plan\");\n }\n return new URL(planResult.url, baseUrl);\n}\n\nfunction expectContinuation(url: URL, expectedReturnTo: string): void {\n expect(url.searchParams.get(\"after_auth_return_to\")).toBe(expectedReturnTo);\n expect(url.searchParams.get(crossDomainAuthQueryParams.state)).toBe(\"outer-state\");\n expect(url.searchParams.get(crossDomainAuthQueryParams.codeChallenge)).toBe(\"outer-challenge\");\n expect(url.searchParams.get(crossDomainAuthQueryParams.afterCallbackRedirectUrl)).toBe(\"https://customer.example.test/dashboard\");\n}\n\ndescribe(\"password-flow redirect continuation\", () => {\n it(\"carries the complete customer return state through forgot-password and a reset-email new tab\", async () => {\n const customerReturnTo = \"https://customer.example.test/handler/oauth-callback?hexclave_cross_domain_auth=1\";\n const signInUrl = new URL(\"https://hosted.example.test/handler/sign-in\");\n signInUrl.searchParams.set(\"after_auth_return_to\", customerReturnTo);\n signInUrl.searchParams.set(crossDomainAuthQueryParams.state, \"outer-state\");\n signInUrl.searchParams.set(crossDomainAuthQueryParams.codeChallenge, \"outer-challenge\");\n signInUrl.searchParams.set(crossDomainAuthQueryParams.afterCallbackRedirectUrl, \"https://customer.example.test/dashboard\");\n\n const forgotPlan = await plan({\n handlerName: \"forgotPassword\",\n rawHandlerUrl: \"/handler/forgot-password\",\n currentUrl: signInUrl,\n });\n const forgotUrl = expectRedirectUrl(forgotPlan, signInUrl);\n expectContinuation(forgotUrl, customerReturnTo);\n\n const callbackPlan = await plan({\n handlerName: \"passwordReset\",\n rawHandlerUrl: \"/handler/password-reset\",\n currentUrl: forgotUrl,\n });\n const resetEmailCallbackUrl = expectRedirectUrl(callbackPlan, forgotUrl);\n expectContinuation(resetEmailCallbackUrl, customerReturnTo);\n\n // Model opening the callback in a new tab: only URL state is available.\n resetEmailCallbackUrl.searchParams.set(\"code\", \"reset-code\");\n const signInPlan = await plan({\n handlerName: \"signIn\",\n rawHandlerUrl: \"/handler/sign-in\",\n currentUrl: resetEmailCallbackUrl,\n noRedirectBack: true,\n });\n const finalSignInUrl = expectRedirectUrl(signInPlan, resetEmailCallbackUrl);\n expectContinuation(finalSignInUrl, customerReturnTo);\n expect(finalSignInUrl.searchParams.has(\"code\")).toBe(false);\n });\n\n it.each([\n [\"forgotPassword\", \"/handler/forgot-password\"],\n [\"passwordReset\", \"/handler/password-reset\"],\n ] as const)(\"never synthesizes the current %s page as a return target\", async (handlerName, rawHandlerUrl) => {\n const currentUrl = new URL(`https://hosted.example.test${rawHandlerUrl}?code=reset-code`);\n const result = expectRedirectUrl(await plan({\n handlerName,\n rawHandlerUrl,\n currentUrl,\n }), currentUrl);\n\n expect(result.searchParams.has(\"after_auth_return_to\")).toBe(false);\n expect(result.searchParams.has(\"code\")).toBe(false);\n });\n\n it(\"makes sign-in noRedirectBack suppress capture while preserving only inherited state\", async () => {\n const resetUrlWithoutContinuation = new URL(\"https://hosted.example.test/handler/password-reset?code=reset-code\");\n const result = expectRedirectUrl(await plan({\n handlerName: \"signIn\",\n rawHandlerUrl: \"/handler/sign-in\",\n currentUrl: resetUrlWithoutContinuation,\n noRedirectBack: true,\n }), resetUrlWithoutContinuation);\n\n expect(result.toString()).toBe(\"https://hosted.example.test/handler/sign-in\");\n });\n\n it.each([\"afterSignIn\", \"afterSignUp\"] as const)(\n \"keeps existing %s noRedirectBack semantics\",\n async (handlerName) => {\n const currentUrl = new URL(\"https://hosted.example.test/handler/sign-in?after_auth_return_to=%2Fcustomer\");\n const result = expectRedirectUrl(await plan({\n handlerName,\n rawHandlerUrl: \"/default-after-auth\",\n currentUrl,\n noRedirectBack: true,\n }), currentUrl);\n\n expect(result.toString()).toBe(\"https://hosted.example.test/default-after-auth\");\n },\n );\n});\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { n as _HexclaveServerAppImplIncomplete } from "../../../../admin-app-impl-FZdANO62.js";
1
+ import { n as _HexclaveServerAppImplIncomplete } from "../../../../admin-app-impl-CsH-gVGz.js";
2
2
  export { _HexclaveServerAppImplIncomplete };
@@ -1,2 +1,2 @@
1
- import { n as HexclaveProvider, r as StackProvider, t as ActiveProvider } from "../hexclave-provider-BKxi3Vy-.js";
1
+ import { n as HexclaveProvider, r as StackProvider, t as ActiveProvider } from "../hexclave-provider-BA97jMlx.js";
2
2
  export { HexclaveProvider, StackProvider, ActiveProvider as default };
@@ -1,2 +1,2 @@
1
- import { t as TranslationProvider } from "../translation-provider-WOaZXqAz.js";
1
+ import { t as TranslationProvider } from "../translation-provider-DQ3BJepJ.js";
2
2
  export { TranslationProvider };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/pushed-config-error-overlay/index.ts"],"mappings":";;iBA6VgB,6BAAA,CAA8B,GAAyB,EAApB,cAAc"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/pushed-config-error-overlay/index.ts"],"mappings":";;iBAkEgB,6BAAA,CAA8B,GAAyB,EAApB,cAAc"}
@@ -1,251 +1,14 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
3
3
  let ___in_page_ui_dom_js = require("../in-page-ui/dom.js");
4
- let ___in_page_ui_base_styles_js = require("../in-page-ui/base-styles.js");
5
4
  let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
6
- let _hexclave_shared_dist_utils_urls = require("@hexclave/shared/dist/utils/urls");
7
- let ___generated_env_js = require("../generated/env.js");
5
+ let ___in_page_ui_dev_environment_js = require("../in-page-ui/dev-environment.js");
6
+ let ___in_page_ui_issue_card_js = require("../in-page-ui/issue-card.js");
8
7
  //#region src/pushed-config-error-overlay/index.ts
9
8
  const GLOBAL_INSTANCE_KEY = "__hexclave-pushed-config-error-overlay";
10
9
  const MINIMIZED_STORAGE_KEY = "hexclave-pushed-config-error-minimized-key";
11
10
  const REFRESH_INTERVAL_MS = 5e3;
12
- const HEXCLAVE_LOGO_SVG = "<svg width=\"16\" height=\"16\" viewBox=\"0 0 48 48\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linejoin=\"miter\"><path d=\"M 24 4 L 41.32 14 L 41.32 34 L 24 44 L 6.68 34 L 6.68 14 Z\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\" transform=\"rotate(120 24 24)\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\" transform=\"rotate(240 24 24)\"/></svg>";
13
- const COPY_ICON_SVG = "<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>";
14
- const css = (0, ___in_page_ui_base_styles_js.getInPageUiBaseCSS)(".hexclave-config-error-overlay") + `
15
- .hexclave-config-error-overlay .hce-backdrop {
16
- position: fixed;
17
- inset: 0;
18
- z-index: 2147483647;
19
- display: flex;
20
- align-items: center;
21
- justify-content: center;
22
- padding: 24px;
23
- background: rgba(0, 0, 0, 0.46);
24
- backdrop-filter: blur(6px);
25
- overflow: auto;
26
- }
27
-
28
- .hexclave-config-error-overlay .hce-card {
29
- --hce-status: var(--sdt-error);
30
- width: min(720px, calc(100vw - 32px));
31
- max-height: min(640px, calc(100dvh - 48px));
32
- border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));
33
- border-radius: 18px;
34
- background: var(--sdt-overlay-bg);
35
- box-shadow: var(--sdt-shadow);
36
- backdrop-filter: blur(18px);
37
- display: flex;
38
- overflow: hidden;
39
- }
40
-
41
- .hexclave-config-error-overlay .hce-card-warning {
42
- --hce-status: var(--sdt-warning);
43
- }
44
-
45
- .hexclave-config-error-overlay .hce-card-inner {
46
- padding: 18px;
47
- width: 100%;
48
- overflow: auto;
49
- }
50
-
51
- .hexclave-config-error-overlay .hce-header {
52
- display: flex;
53
- align-items: flex-start;
54
- justify-content: space-between;
55
- gap: 12px;
56
- margin-bottom: 12px;
57
- }
58
-
59
- .hexclave-config-error-overlay .hce-title-row {
60
- display: flex;
61
- align-items: flex-start;
62
- gap: 10px;
63
- min-width: 0;
64
- }
65
-
66
- .hexclave-config-error-overlay .hce-logo {
67
- flex-shrink: 0;
68
- display: flex;
69
- align-items: center;
70
- justify-content: center;
71
- width: 34px;
72
- height: 34px;
73
- border-radius: 10px;
74
- background: var(--hce-status);
75
- color: white;
76
- box-shadow: 0 10px 30px color-mix(in srgb, var(--hce-status) 32%, transparent);
77
- }
78
-
79
- .hexclave-config-error-overlay .hce-badge {
80
- display: inline-flex;
81
- flex-shrink: 0;
82
- padding: 2px 6px;
83
- border-radius: 999px;
84
- background: var(--hce-status);
85
- color: white;
86
- font-size: 10px;
87
- font-weight: 700;
88
- letter-spacing: 0.06em;
89
- text-transform: uppercase;
90
- }
91
-
92
- .hexclave-config-error-overlay .hce-title {
93
- color: var(--sdt-text);
94
- margin-top: 4px;
95
- font-size: 18px;
96
- font-weight: 700;
97
- line-height: 1.25;
98
- }
99
-
100
- .hexclave-config-error-overlay .hce-actions {
101
- display: flex;
102
- gap: 4px;
103
- }
104
-
105
- .hexclave-config-error-overlay .hce-icon-btn {
106
- display: inline-flex;
107
- align-items: center;
108
- justify-content: center;
109
- width: 28px;
110
- height: 28px;
111
- border: 1px solid var(--sdt-border);
112
- border-radius: 8px;
113
- background: var(--sdt-bg-elevated);
114
- color: var(--sdt-text-secondary);
115
- cursor: pointer;
116
- font: inherit;
117
- line-height: 1;
118
- vertical-align: top;
119
- }
120
-
121
- .hexclave-config-error-overlay .hce-icon-btn svg {
122
- display: block;
123
- flex-shrink: 0;
124
- }
125
-
126
- .hexclave-config-error-overlay .hce-text-btn {
127
- align-items: center;
128
- gap: 6px;
129
- min-height: 28px;
130
- padding: 0 10px;
131
- width: auto;
132
- font-size: 12px;
133
- line-height: 1;
134
- }
135
-
136
- .hexclave-config-error-overlay .hce-icon-btn:hover {
137
- background: var(--sdt-bg-hover);
138
- color: var(--sdt-text);
139
- }
140
-
141
- .hexclave-config-error-overlay .hce-body {
142
- color: var(--sdt-text-secondary);
143
- font-size: 14px;
144
- line-height: 1.5;
145
- }
146
-
147
- .hexclave-config-error-overlay .hce-message-header {
148
- display: flex;
149
- align-items: center;
150
- justify-content: space-between;
151
- gap: 10px;
152
- margin-top: 14px;
153
- margin-bottom: 8px;
154
- }
155
-
156
- .hexclave-config-error-overlay .hce-message-label {
157
- color: var(--sdt-text);
158
- font-size: 12px;
159
- font-weight: 650;
160
- }
161
-
162
- .hexclave-config-error-overlay .hce-message {
163
- padding: 12px;
164
- max-height: min(260px, max(96px, 30dvh));
165
- overflow: auto;
166
- border: 1px solid var(--sdt-border-subtle);
167
- border-radius: 10px;
168
- background: var(--sdt-bg-subtle);
169
- color: var(--sdt-text);
170
- font-family: var(--sdt-font-mono);
171
- font-size: 12px;
172
- white-space: pre-wrap;
173
- overflow-wrap: anywhere;
174
- }
175
-
176
- .hexclave-config-error-overlay .hce-footer {
177
- margin-top: 10px;
178
- color: var(--sdt-text-tertiary);
179
- font-size: 12px;
180
- }
181
-
182
- .hexclave-config-error-overlay .hce-pill {
183
- position: fixed;
184
- right: 18px;
185
- bottom: 18px;
186
- z-index: 2147483647;
187
- display: flex;
188
- align-items: center;
189
- gap: 8px;
190
- padding: 8px 12px 8px 8px;
191
- --hce-status: var(--sdt-error);
192
- border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));
193
- border-radius: 999px;
194
- background: var(--sdt-overlay-bg);
195
- box-shadow: var(--sdt-trigger-shadow);
196
- color: var(--sdt-text);
197
- cursor: pointer;
198
- font: inherit;
199
- backdrop-filter: blur(18px);
200
- }
201
-
202
- .hexclave-config-error-overlay .hce-pill-warning {
203
- --hce-status: var(--sdt-warning);
204
- }
205
-
206
- .hexclave-config-error-overlay .hce-pill-logo {
207
- display: flex;
208
- align-items: center;
209
- justify-content: center;
210
- width: 26px;
211
- height: 26px;
212
- border-radius: 999px;
213
- background: var(--hce-status);
214
- color: white;
215
- }
216
-
217
- @media (max-height: 520px) {
218
- .hexclave-config-error-overlay .hce-backdrop {
219
- align-items: flex-start;
220
- padding: 12px;
221
- }
222
-
223
- .hexclave-config-error-overlay .hce-card {
224
- width: min(720px, calc(100vw - 24px));
225
- max-height: calc(100dvh - 24px);
226
- }
227
-
228
- .hexclave-config-error-overlay .hce-card-inner {
229
- padding: 12px;
230
- }
231
-
232
- .hexclave-config-error-overlay .hce-header {
233
- margin-bottom: 8px;
234
- }
235
-
236
- .hexclave-config-error-overlay .hce-title {
237
- font-size: 16px;
238
- }
239
-
240
- .hexclave-config-error-overlay .hce-body {
241
- font-size: 13px;
242
- }
243
-
244
- .hexclave-config-error-overlay .hce-message {
245
- max-height: max(80px, 24dvh);
246
- }
247
- }
248
- `;
11
+ const css = (0, ___in_page_ui_issue_card_js.getIssueCardCSS)(".hexclave-config-error-overlay");
249
12
  function storageGet(key) {
250
13
  try {
251
14
  return localStorage.getItem(key);
@@ -264,38 +27,7 @@ function storageRemove(key) {
264
27
  } catch {}
265
28
  }
266
29
  function shouldMount() {
267
- if (!(0, ___in_page_ui_dom_js.canMountIntoDom)()) return false;
268
- const nodeEnv = ___generated_env_js.envVars.NODE_ENV;
269
- if (nodeEnv !== void 0) return nodeEnv === "development";
270
- try {
271
- if (new URL(window.location.href).protocol === "file:") return true;
272
- } catch {
273
- return false;
274
- }
275
- return (0, _hexclave_shared_dist_utils_urls.isLocalhost)(window.location.href);
276
- }
277
- async function copyTextToClipboard(text) {
278
- const clipboard = Reflect.get(navigator, "clipboard");
279
- const writeText = clipboard != null && typeof clipboard === "object" ? Reflect.get(clipboard, "writeText") : null;
280
- if (typeof writeText === "function") {
281
- await writeText.call(clipboard, text);
282
- return;
283
- }
284
- const textarea = (0, ___in_page_ui_dom_js.h)("textarea", {
285
- style: {
286
- position: "fixed",
287
- left: "-9999px",
288
- top: "0",
289
- opacity: "0"
290
- },
291
- readonly: "true"
292
- });
293
- textarea.value = text;
294
- document.body.appendChild(textarea);
295
- textarea.select();
296
- const copied = document.execCommand("copy");
297
- textarea.remove();
298
- if (!copied) throw new Error("Browser refused to copy the config error message.");
30
+ return (0, ___in_page_ui_dom_js.canMountIntoDom)() && (0, ___in_page_ui_dev_environment_js.isLikelyDevelopmentEnvironment)();
299
31
  }
300
32
  function buildConfigIssueAiPrompt(issue) {
301
33
  const issueLabel = issue.kind === "error" ? "error" : "warning";
@@ -322,11 +54,19 @@ function mountPushedConfigErrorOverlay(app) {
322
54
  let lastErrorKey = null;
323
55
  let lastConsoleErrorKey = null;
324
56
  let minimized = false;
57
+ let focusedIssueKey = null;
58
+ let focusTrap = null;
59
+ const releaseFocusIfHeld = () => {
60
+ focusTrap?.release();
61
+ focusTrap = null;
62
+ focusedIssueKey = null;
63
+ };
325
64
  const render = (issue) => {
326
65
  root.replaceChildren(style);
327
66
  if (issue == null) {
328
67
  lastErrorKey = null;
329
68
  minimized = false;
69
+ releaseFocusIfHeld();
330
70
  return;
331
71
  }
332
72
  const issueMessage = "Hexclave config " + issue.kind + ": " + issue.messages.join("\n");
@@ -346,87 +86,45 @@ function mountPushedConfigErrorOverlay(app) {
346
86
  minimized = storageGet(MINIMIZED_STORAGE_KEY) === issueKey;
347
87
  }
348
88
  if (minimized) {
349
- const logoSpan = (0, ___in_page_ui_dom_js.h)("span", { className: "hce-pill-logo" });
350
- (0, ___in_page_ui_dom_js.setHtml)(logoSpan, HEXCLAVE_LOGO_SVG);
351
- root.appendChild((0, ___in_page_ui_dom_js.h)("button", {
352
- className: issue.kind === "error" ? "hce-pill" : "hce-pill hce-pill-warning",
353
- type: "button",
89
+ releaseFocusIfHeld();
90
+ root.appendChild((0, ___in_page_ui_issue_card_js.renderIssuePill)({
91
+ kind: issue.kind,
92
+ label: issue.kind === "error" ? "Config error" : "Config warning",
93
+ ariaLabel: `Show Hexclave config ${issueLabel}`,
354
94
  onClick: () => {
355
95
  minimized = false;
356
96
  storageRemove(MINIMIZED_STORAGE_KEY);
357
97
  render(issue);
358
98
  }
359
- }, logoSpan, (0, ___in_page_ui_dom_js.h)("span", null, issue.kind === "error" ? "Config error" : "Config warning")));
99
+ }));
360
100
  return;
361
101
  }
362
- const logoSpan = (0, ___in_page_ui_dom_js.h)("span", { className: "hce-logo" });
363
- (0, ___in_page_ui_dom_js.setHtml)(logoSpan, HEXCLAVE_LOGO_SVG);
364
- const copyButton = (0, ___in_page_ui_dom_js.h)("button", {
365
- className: "hce-icon-btn hce-text-btn",
366
- type: "button",
367
- title: issue.kind === "error" ? "Copy error message" : "Copy warning message",
368
- "aria-label": issue.kind === "error" ? "Copy config error message" : "Copy config warning message",
369
- onClick: () => {
370
- (0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
371
- await copyTextToClipboard(issueMessage);
372
- copyButton.textContent = "Copied";
373
- setTimeout(() => {
374
- (0, ___in_page_ui_dom_js.setHtml)(copyButton, `${COPY_ICON_SVG}Copy`);
375
- }, 1500);
376
- }, {
377
- noErrorLogging: true,
378
- onError: (copyError) => {
379
- (0, _hexclave_shared_dist_utils_errors.captureError)("pushed-config-error-overlay-copy", copyError);
380
- copyButton.textContent = "Copy failed";
381
- setTimeout(() => {
382
- (0, ___in_page_ui_dom_js.setHtml)(copyButton, `${COPY_ICON_SVG}Copy`);
383
- }, 1500);
384
- }
385
- });
386
- }
387
- });
388
- (0, ___in_page_ui_dom_js.setHtml)(copyButton, `${COPY_ICON_SVG}Copy`);
389
- const aiPromptCopyButton = (0, ___in_page_ui_dom_js.h)("button", {
390
- className: "hce-icon-btn",
391
- type: "button",
392
- title: "Copy AI prompt",
393
- "aria-label": issue.kind === "error" ? "Copy AI prompt for config error" : "Copy AI prompt for config warning",
394
- onClick: () => {
395
- (0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
396
- await copyTextToClipboard(buildConfigIssueAiPrompt(issue));
397
- aiPromptCopyButton.textContent = "✓";
398
- setTimeout(() => {
399
- (0, ___in_page_ui_dom_js.setHtml)(aiPromptCopyButton, COPY_ICON_SVG);
400
- }, 1500);
401
- }, {
402
- noErrorLogging: true,
403
- onError: (copyError) => {
404
- (0, _hexclave_shared_dist_utils_errors.captureError)("pushed-config-error-overlay-copy-ai-prompt", copyError);
405
- aiPromptCopyButton.textContent = "!";
406
- setTimeout(() => {
407
- (0, ___in_page_ui_dom_js.setHtml)(aiPromptCopyButton, COPY_ICON_SVG);
408
- }, 1500);
409
- }
410
- });
411
- }
412
- });
413
- (0, ___in_page_ui_dom_js.setHtml)(aiPromptCopyButton, COPY_ICON_SVG);
414
- root.appendChild((0, ___in_page_ui_dom_js.h)("div", { className: "hce-backdrop" }, (0, ___in_page_ui_dom_js.h)("div", {
415
- className: issue.kind === "error" ? "hce-card" : "hce-card hce-card-warning",
416
- role: "alertdialog",
417
- "aria-modal": "true",
418
- "aria-label": `Hexclave config ${issueLabel}`
419
- }, (0, ___in_page_ui_dom_js.h)("div", { className: "hce-card-inner" }, (0, ___in_page_ui_dom_js.h)("div", { className: "hce-header" }, (0, ___in_page_ui_dom_js.h)("div", { className: "hce-title-row" }, logoSpan, (0, ___in_page_ui_dom_js.h)("div", null, (0, ___in_page_ui_dom_js.h)("span", { className: "hce-badge" }, `Config ${issueLabel}`), (0, ___in_page_ui_dom_js.h)("div", { className: "hce-title" }, issueTitle))), (0, ___in_page_ui_dom_js.h)("div", { className: "hce-actions" }, aiPromptCopyButton, (0, ___in_page_ui_dom_js.h)("button", {
420
- className: "hce-icon-btn",
421
- type: "button",
422
- title: "Minimize",
423
- "aria-label": issue.kind === "error" ? "Minimize config error" : "Minimize config warning",
424
- onClick: () => {
102
+ root.appendChild((0, ___in_page_ui_issue_card_js.renderIssueCard)({
103
+ kind: issue.kind,
104
+ badge: `Config ${issueLabel}`,
105
+ title: issueTitle,
106
+ bodyText,
107
+ messageLabel: issue.kind === "error" ? "Error message" : "Warning message",
108
+ message: issueMessage,
109
+ footerText,
110
+ ariaLabel: `Hexclave config ${issueLabel}`,
111
+ aiPrompt: buildConfigIssueAiPrompt(issue),
112
+ onCopyError: (copyError) => (0, _hexclave_shared_dist_utils_errors.captureError)("pushed-config-error-overlay-copy", copyError),
113
+ onCopyAiPromptError: (copyError) => (0, _hexclave_shared_dist_utils_errors.captureError)("pushed-config-error-overlay-copy-ai-prompt", copyError),
114
+ onMinimize: () => {
425
115
  minimized = true;
426
116
  storageSet(MINIMIZED_STORAGE_KEY, issueKey);
427
117
  render(issue);
428
118
  }
429
- }, "–"))), (0, ___in_page_ui_dom_js.h)("div", { className: "hce-body" }, bodyText, (0, ___in_page_ui_dom_js.h)("div", { className: "hce-message-header" }, (0, ___in_page_ui_dom_js.h)("div", { className: "hce-message-label" }, issue.kind === "error" ? "Error message" : "Warning message"), copyButton), (0, ___in_page_ui_dom_js.h)("div", { className: "hce-message" }, issueMessage), (0, ___in_page_ui_dom_js.h)("div", { className: "hce-footer" }, footerText))))));
119
+ }));
120
+ const isNewIssue = focusedIssueKey !== issueKey;
121
+ const previouslyFocused = isNewIssue ? void 0 : focusTrap?.previouslyFocused ?? null;
122
+ focusTrap?.release({ restoreFocus: isNewIssue });
123
+ focusedIssueKey = issueKey;
124
+ focusTrap = (0, ___in_page_ui_issue_card_js.trapFocusInIssueCard)(root, {
125
+ moveFocusIntoCard: isNewIssue,
126
+ previouslyFocused
127
+ });
430
128
  };
431
129
  const refresh = () => {
432
130
  if (disposed || !(0, ___in_page_ui_dom_js.canMountIntoDom)()) return;
@@ -452,6 +150,7 @@ function mountPushedConfigErrorOverlay(app) {
452
150
  const cleanup = () => {
453
151
  disposed = true;
454
152
  clearInterval(interval);
153
+ releaseFocusIfHeld();
455
154
  root.remove();
456
155
  if ((0, ___in_page_ui_dom_js.getGlobalUiInstance)(GLOBAL_INSTANCE_KEY)?.cleanup === cleanup) (0, ___in_page_ui_dom_js.setGlobalUiInstance)(GLOBAL_INSTANCE_KEY, null);
457
156
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["envVars"],"sources":["../../src/pushed-config-error-overlay/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { isLocalhost } from \"@hexclave/shared/dist/utils/urls\";\nimport { envVars } from \"../generated/env\";\nimport { getInPageUiBaseCSS } from \"../in-page-ui/base-styles\";\nimport { canMountIntoDom, getGlobalUiInstance, h, setGlobalUiInstance, setHtml } from \"../in-page-ui/dom\";\nimport type { StackClientApp } from \"../lib/hexclave-app\";\n\nconst GLOBAL_INSTANCE_KEY = \"__hexclave-pushed-config-error-overlay\";\nconst MINIMIZED_STORAGE_KEY = \"hexclave-pushed-config-error-minimized-key\";\nconst REFRESH_INTERVAL_MS = 5_000;\nconst HEXCLAVE_LOGO_SVG = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 48 48\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linejoin=\"miter\"><path d=\"M 24 4 L 41.32 14 L 41.32 34 L 24 44 L 6.68 34 L 6.68 14 Z\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\" transform=\"rotate(120 24 24)\"/><path d=\"M 11 16.87 L 14 15.13 L 14 32.87 L 11 31.13 Z\" fill=\"currentColor\" stroke=\"none\" transform=\"rotate(240 24 24)\"/></svg>';\nconst COPY_ICON_SVG = '<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>';\n\ntype ConfigIssue = {\n kind: \"error\" | \"warning\",\n messages: string[],\n};\n\nconst css = getInPageUiBaseCSS(\".hexclave-config-error-overlay\") + `\n .hexclave-config-error-overlay .hce-backdrop {\n position: fixed;\n inset: 0;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n background: rgba(0, 0, 0, 0.46);\n backdrop-filter: blur(6px);\n overflow: auto;\n }\n\n .hexclave-config-error-overlay .hce-card {\n --hce-status: var(--sdt-error);\n width: min(720px, calc(100vw - 32px));\n max-height: min(640px, calc(100dvh - 48px));\n border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));\n border-radius: 18px;\n background: var(--sdt-overlay-bg);\n box-shadow: var(--sdt-shadow);\n backdrop-filter: blur(18px);\n display: flex;\n overflow: hidden;\n }\n\n .hexclave-config-error-overlay .hce-card-warning {\n --hce-status: var(--sdt-warning);\n }\n\n .hexclave-config-error-overlay .hce-card-inner {\n padding: 18px;\n width: 100%;\n overflow: auto;\n }\n\n .hexclave-config-error-overlay .hce-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 12px;\n }\n\n .hexclave-config-error-overlay .hce-title-row {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n }\n\n .hexclave-config-error-overlay .hce-logo {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 34px;\n border-radius: 10px;\n background: var(--hce-status);\n color: white;\n box-shadow: 0 10px 30px color-mix(in srgb, var(--hce-status) 32%, transparent);\n }\n\n .hexclave-config-error-overlay .hce-badge {\n display: inline-flex;\n flex-shrink: 0;\n padding: 2px 6px;\n border-radius: 999px;\n background: var(--hce-status);\n color: white;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n\n .hexclave-config-error-overlay .hce-title {\n color: var(--sdt-text);\n margin-top: 4px;\n font-size: 18px;\n font-weight: 700;\n line-height: 1.25;\n }\n\n .hexclave-config-error-overlay .hce-actions {\n display: flex;\n gap: 4px;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--sdt-border);\n border-radius: 8px;\n background: var(--sdt-bg-elevated);\n color: var(--sdt-text-secondary);\n cursor: pointer;\n font: inherit;\n line-height: 1;\n vertical-align: top;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn svg {\n display: block;\n flex-shrink: 0;\n }\n\n .hexclave-config-error-overlay .hce-text-btn {\n align-items: center;\n gap: 6px;\n min-height: 28px;\n padding: 0 10px;\n width: auto;\n font-size: 12px;\n line-height: 1;\n }\n\n .hexclave-config-error-overlay .hce-icon-btn:hover {\n background: var(--sdt-bg-hover);\n color: var(--sdt-text);\n }\n\n .hexclave-config-error-overlay .hce-body {\n color: var(--sdt-text-secondary);\n font-size: 14px;\n line-height: 1.5;\n }\n\n .hexclave-config-error-overlay .hce-message-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n margin-top: 14px;\n margin-bottom: 8px;\n }\n\n .hexclave-config-error-overlay .hce-message-label {\n color: var(--sdt-text);\n font-size: 12px;\n font-weight: 650;\n }\n\n .hexclave-config-error-overlay .hce-message {\n padding: 12px;\n max-height: min(260px, max(96px, 30dvh));\n overflow: auto;\n border: 1px solid var(--sdt-border-subtle);\n border-radius: 10px;\n background: var(--sdt-bg-subtle);\n color: var(--sdt-text);\n font-family: var(--sdt-font-mono);\n font-size: 12px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n\n .hexclave-config-error-overlay .hce-footer {\n margin-top: 10px;\n color: var(--sdt-text-tertiary);\n font-size: 12px;\n }\n\n .hexclave-config-error-overlay .hce-pill {\n position: fixed;\n right: 18px;\n bottom: 18px;\n z-index: 2147483647;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px 8px 8px;\n --hce-status: var(--sdt-error);\n border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));\n border-radius: 999px;\n background: var(--sdt-overlay-bg);\n box-shadow: var(--sdt-trigger-shadow);\n color: var(--sdt-text);\n cursor: pointer;\n font: inherit;\n backdrop-filter: blur(18px);\n }\n\n .hexclave-config-error-overlay .hce-pill-warning {\n --hce-status: var(--sdt-warning);\n }\n\n .hexclave-config-error-overlay .hce-pill-logo {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border-radius: 999px;\n background: var(--hce-status);\n color: white;\n }\n\n @media (max-height: 520px) {\n .hexclave-config-error-overlay .hce-backdrop {\n align-items: flex-start;\n padding: 12px;\n }\n\n .hexclave-config-error-overlay .hce-card {\n width: min(720px, calc(100vw - 24px));\n max-height: calc(100dvh - 24px);\n }\n\n .hexclave-config-error-overlay .hce-card-inner {\n padding: 12px;\n }\n\n .hexclave-config-error-overlay .hce-header {\n margin-bottom: 8px;\n }\n\n .hexclave-config-error-overlay .hce-title {\n font-size: 16px;\n }\n\n .hexclave-config-error-overlay .hce-body {\n font-size: 13px;\n }\n\n .hexclave-config-error-overlay .hce-message {\n max-height: max(80px, 24dvh);\n }\n }\n`;\n\nfunction storageGet(key: string): string | null {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction storageSet(key: string, value: string): void {\n try {\n localStorage.setItem(key, value);\n } catch {\n // Storage may be unavailable in private or embedded contexts.\n }\n}\n\nfunction storageRemove(key: string): void {\n try {\n localStorage.removeItem(key);\n } catch {\n // Storage may be unavailable in private or embedded contexts.\n }\n}\n\nfunction shouldMount(): boolean {\n if (!canMountIntoDom()) {\n return false;\n }\n\n const nodeEnv = envVars.NODE_ENV;\n if (nodeEnv !== undefined) {\n return nodeEnv === \"development\";\n }\n\n try {\n const url = new URL(window.location.href);\n if (url.protocol === \"file:\") {\n return true;\n }\n } catch {\n return false;\n }\n return isLocalhost(window.location.href);\n}\n\nasync function copyTextToClipboard(text: string): Promise<void> {\n const clipboard: unknown = Reflect.get(navigator, \"clipboard\");\n const writeText = clipboard != null && typeof clipboard === \"object\"\n ? Reflect.get(clipboard, \"writeText\")\n : null;\n if (typeof writeText === \"function\") {\n await writeText.call(clipboard, text);\n return;\n }\n\n const textarea = h(\"textarea\", {\n style: {\n position: \"fixed\",\n left: \"-9999px\",\n top: \"0\",\n opacity: \"0\",\n },\n readonly: \"true\",\n }) as HTMLTextAreaElement;\n textarea.value = text;\n document.body.appendChild(textarea);\n textarea.select();\n const copied = document.execCommand(\"copy\");\n textarea.remove();\n if (!copied) {\n throw new Error(\"Browser refused to copy the config error message.\");\n }\n}\n\nfunction buildConfigIssueAiPrompt(issue: ConfigIssue): string {\n const issueLabel = issue.kind === \"error\" ? \"error\" : \"warning\";\n return [\n `Help me fix this Hexclave config ${issueLabel}.`,\n \"\",\n \"Hexclave reminder:\",\n `This ${issueLabel} comes from a pushed Hexclave config file. The app may keep running with the synced Hexclave config, but I need to fix the config file mentioned in the message and save it again so Hexclave can sync the config successfully and clear the dialog. Use your web fetch tool to read https://skill.hexclave.com to learn more about Hexclave.`,\n \"\",\n issue.kind === \"error\" ? \"Error message:\" : \"Warning message:\",\n issue.messages.join(\"\\n\"),\n \"\",\n \"Please explain the likely cause, identify the config key or value I should change, and suggest the smallest safe fix.\",\n ].join(\"\\n\");\n}\n\nexport function mountPushedConfigErrorOverlay(app: StackClientApp<true>): () => void {\n if (!shouldMount()) {\n return () => {};\n }\n\n getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup();\n\n const root = h(\"div\", { className: \"hexclave-config-error-overlay\" });\n const style = h(\"style\", null, css);\n root.appendChild(style);\n document.body.appendChild(root);\n\n let disposed = false;\n let lastErrorKey: string | null = null;\n let lastConsoleErrorKey: string | null = null;\n let minimized = false;\n\n const render = (issue: ConfigIssue | null) => {\n root.replaceChildren(style);\n if (issue == null) {\n lastErrorKey = null;\n minimized = false;\n return;\n }\n\n const issueMessage = \"Hexclave config \" + issue.kind + \": \" + issue.messages.join(\"\\n\");\n const issueKey = `${app.projectId}:${issue.kind}:${issueMessage}`;\n const issueLabel = issue.kind === \"error\" ? \"error\" : \"warning\";\n const issueTitle = issue.kind === \"error\"\n ? \"Your Hexclave config has been saved, but contains errors\"\n : \"Your Hexclave config has been saved, but has warnings\";\n const bodyText = issue.kind === \"error\"\n ? \"Your app can keep running, but Hexclave is still using the last valid config until this is fixed.\"\n : \"Your app can keep running, but part of your Hexclave config may not behave the way you expect until this is fixed.\";\n const footerText = issue.kind === \"error\"\n ? \"Fix the config file mentioned above and save it again. This message will disappear after the config sync succeeds.\"\n : \"Fix the config file mentioned above and save it again. This warning will disappear after Hexclave syncs a config without warnings.\";\n if (issueKey !== lastConsoleErrorKey) {\n lastConsoleErrorKey = issueKey;\n const consoleMessage = `[Hexclave] Config ${issueLabel}: ${issueMessage}`;\n if (issue.kind === \"error\") {\n console.error(consoleMessage);\n } else {\n console.warn(consoleMessage);\n }\n }\n\n if (issueKey !== lastErrorKey) {\n lastErrorKey = issueKey;\n minimized = storageGet(MINIMIZED_STORAGE_KEY) === issueKey;\n }\n\n if (minimized) {\n const logoSpan = h(\"span\", { className: \"hce-pill-logo\" });\n setHtml(logoSpan, HEXCLAVE_LOGO_SVG);\n root.appendChild(h(\"button\", {\n className: issue.kind === \"error\" ? \"hce-pill\" : \"hce-pill hce-pill-warning\",\n type: \"button\",\n onClick: () => {\n minimized = false;\n storageRemove(MINIMIZED_STORAGE_KEY);\n render(issue);\n },\n },\n logoSpan,\n h(\"span\", null, issue.kind === \"error\" ? \"Config error\" : \"Config warning\")));\n return;\n }\n\n const logoSpan = h(\"span\", { className: \"hce-logo\" });\n setHtml(logoSpan, HEXCLAVE_LOGO_SVG);\n const copyButton = h(\"button\", {\n className: \"hce-icon-btn hce-text-btn\",\n type: \"button\",\n title: issue.kind === \"error\" ? \"Copy error message\" : \"Copy warning message\",\n \"aria-label\": issue.kind === \"error\" ? \"Copy config error message\" : \"Copy config warning message\",\n onClick: () => {\n runAsynchronously(async () => {\n await copyTextToClipboard(issueMessage);\n copyButton.textContent = \"Copied\";\n setTimeout(() => {\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n }, 1500);\n }, {\n noErrorLogging: true,\n onError: (copyError) => {\n captureError(\"pushed-config-error-overlay-copy\", copyError);\n copyButton.textContent = \"Copy failed\";\n setTimeout(() => {\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n }, 1500);\n },\n });\n },\n });\n setHtml(copyButton, `${COPY_ICON_SVG}Copy`);\n\n const aiPromptCopyButton = h(\"button\", {\n className: \"hce-icon-btn\",\n type: \"button\",\n title: \"Copy AI prompt\",\n \"aria-label\": issue.kind === \"error\" ? \"Copy AI prompt for config error\" : \"Copy AI prompt for config warning\",\n onClick: () => {\n runAsynchronously(async () => {\n await copyTextToClipboard(buildConfigIssueAiPrompt(issue));\n aiPromptCopyButton.textContent = \"✓\";\n setTimeout(() => {\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n }, 1500);\n }, {\n noErrorLogging: true,\n onError: (copyError) => {\n captureError(\"pushed-config-error-overlay-copy-ai-prompt\", copyError);\n aiPromptCopyButton.textContent = \"!\";\n setTimeout(() => {\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n }, 1500);\n },\n });\n },\n });\n setHtml(aiPromptCopyButton, COPY_ICON_SVG);\n\n root.appendChild(h(\"div\", { className: \"hce-backdrop\" },\n h(\"div\", { className: issue.kind === \"error\" ? \"hce-card\" : \"hce-card hce-card-warning\", role: \"alertdialog\", \"aria-modal\": \"true\", \"aria-label\": `Hexclave config ${issueLabel}` },\n h(\"div\", { className: \"hce-card-inner\" },\n h(\"div\", { className: \"hce-header\" },\n h(\"div\", { className: \"hce-title-row\" },\n logoSpan,\n h(\"div\", null,\n h(\"span\", { className: \"hce-badge\" }, `Config ${issueLabel}`),\n h(\"div\", { className: \"hce-title\" }, issueTitle),\n ),\n ),\n h(\"div\", { className: \"hce-actions\" },\n aiPromptCopyButton,\n h(\"button\", {\n className: \"hce-icon-btn\",\n type: \"button\",\n title: \"Minimize\",\n \"aria-label\": issue.kind === \"error\" ? \"Minimize config error\" : \"Minimize config warning\",\n onClick: () => {\n minimized = true;\n storageSet(MINIMIZED_STORAGE_KEY, issueKey);\n render(issue);\n },\n }, \"–\"),\n ),\n ),\n h(\"div\", { className: \"hce-body\" },\n bodyText,\n h(\"div\", { className: \"hce-message-header\" },\n h(\"div\", { className: \"hce-message-label\" }, issue.kind === \"error\" ? \"Error message\" : \"Warning message\"),\n copyButton,\n ),\n h(\"div\", { className: \"hce-message\" }, issueMessage),\n h(\"div\", { className: \"hce-footer\" }, footerText),\n ),\n ),\n )));\n };\n\n const refresh = () => {\n if (disposed || !canMountIntoDom()) {\n return;\n }\n runAsynchronously(async () => {\n const project = await app.getProject();\n if (disposed) {\n return;\n }\n render(project.pushedConfigError == null\n ? project.configWarnings.length === 0\n ? null\n : { kind: \"warning\", messages: project.configWarnings.map((warning) => warning.message) }\n : { kind: \"error\", messages: [project.pushedConfigError.message] });\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"pushed-config-error-overlay-refresh\", error);\n },\n });\n };\n\n // This is mounted from the base client-app constructor, which also runs\n // before subclass field initializers. Defer the first app call so overridden\n // methods like adminApp.getProject() can safely touch subclass caches.\n queueMicrotask(refresh);\n const interval = setInterval(refresh, REFRESH_INTERVAL_MS);\n\n const cleanup = () => {\n disposed = true;\n clearInterval(interval);\n root.remove();\n if (getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup === cleanup) {\n setGlobalUiInstance(GLOBAL_INSTANCE_KEY, null);\n }\n };\n setGlobalUiInstance(GLOBAL_INSTANCE_KEY, { cleanup });\n return cleanup;\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/pushed-config-error-overlay/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { isLikelyDevelopmentEnvironment } from \"../in-page-ui/dev-environment\";\nimport { canMountIntoDom, getGlobalUiInstance, h, setGlobalUiInstance } from \"../in-page-ui/dom\";\nimport { getIssueCardCSS, renderIssueCard, renderIssuePill, trapFocusInIssueCard, type IssueCardFocusTrap } from \"../in-page-ui/issue-card\";\nimport type { StackClientApp } from \"../lib/hexclave-app\";\n\nconst GLOBAL_INSTANCE_KEY = \"__hexclave-pushed-config-error-overlay\";\nconst MINIMIZED_STORAGE_KEY = \"hexclave-pushed-config-error-minimized-key\";\nconst REFRESH_INTERVAL_MS = 5_000;\n\ntype ConfigIssue = {\n kind: \"error\" | \"warning\",\n messages: string[],\n};\n\nconst css = getIssueCardCSS(\".hexclave-config-error-overlay\");\n\nfunction storageGet(key: string): string | null {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction storageSet(key: string, value: string): void {\n try {\n localStorage.setItem(key, value);\n } catch {\n // Storage may be unavailable in private or embedded contexts.\n }\n}\n\nfunction storageRemove(key: string): void {\n try {\n localStorage.removeItem(key);\n } catch {\n // Storage may be unavailable in private or embedded contexts.\n }\n}\n\nfunction shouldMount(): boolean {\n return canMountIntoDom() && isLikelyDevelopmentEnvironment();\n}\n\nfunction buildConfigIssueAiPrompt(issue: ConfigIssue): string {\n const issueLabel = issue.kind === \"error\" ? \"error\" : \"warning\";\n return [\n `Help me fix this Hexclave config ${issueLabel}.`,\n \"\",\n \"Hexclave reminder:\",\n `This ${issueLabel} comes from a pushed Hexclave config file. The app may keep running with the synced Hexclave config, but I need to fix the config file mentioned in the message and save it again so Hexclave can sync the config successfully and clear the dialog. Use your web fetch tool to read https://skill.hexclave.com to learn more about Hexclave.`,\n \"\",\n issue.kind === \"error\" ? \"Error message:\" : \"Warning message:\",\n issue.messages.join(\"\\n\"),\n \"\",\n \"Please explain the likely cause, identify the config key or value I should change, and suggest the smallest safe fix.\",\n ].join(\"\\n\");\n}\n\nexport function mountPushedConfigErrorOverlay(app: StackClientApp<true>): () => void {\n if (!shouldMount()) {\n return () => {};\n }\n\n getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup();\n\n const root = h(\"div\", { className: \"hexclave-config-error-overlay\" });\n const style = h(\"style\", null, css);\n root.appendChild(style);\n document.body.appendChild(root);\n\n let disposed = false;\n let lastErrorKey: string | null = null;\n let lastConsoleErrorKey: string | null = null;\n let minimized = false;\n // The card element is replaced on every poll, so the trap has to be rebound to the new one each time or it would keep\n // trapping Tab inside the detached card. Focus is only *moved* into the card when a card first appears for an issue;\n // doing it on every render would yank focus out of whatever the developer is doing every few seconds.\n let focusedIssueKey: string | null = null;\n let focusTrap: IssueCardFocusTrap | null = null;\n const releaseFocusIfHeld = () => {\n focusTrap?.release();\n focusTrap = null;\n focusedIssueKey = null;\n };\n\n const render = (issue: ConfigIssue | null) => {\n root.replaceChildren(style);\n if (issue == null) {\n lastErrorKey = null;\n minimized = false;\n releaseFocusIfHeld();\n return;\n }\n\n const issueMessage = \"Hexclave config \" + issue.kind + \": \" + issue.messages.join(\"\\n\");\n const issueKey = `${app.projectId}:${issue.kind}:${issueMessage}`;\n const issueLabel = issue.kind === \"error\" ? \"error\" : \"warning\";\n const issueTitle = issue.kind === \"error\"\n ? \"Your Hexclave config has been saved, but contains errors\"\n : \"Your Hexclave config has been saved, but has warnings\";\n const bodyText = issue.kind === \"error\"\n ? \"Your app can keep running, but Hexclave is still using the last valid config until this is fixed.\"\n : \"Your app can keep running, but part of your Hexclave config may not behave the way you expect until this is fixed.\";\n const footerText = issue.kind === \"error\"\n ? \"Fix the config file mentioned above and save it again. This message will disappear after the config sync succeeds.\"\n : \"Fix the config file mentioned above and save it again. This warning will disappear after Hexclave syncs a config without warnings.\";\n if (issueKey !== lastConsoleErrorKey) {\n lastConsoleErrorKey = issueKey;\n const consoleMessage = `[Hexclave] Config ${issueLabel}: ${issueMessage}`;\n if (issue.kind === \"error\") {\n console.error(consoleMessage);\n } else {\n console.warn(consoleMessage);\n }\n }\n\n if (issueKey !== lastErrorKey) {\n lastErrorKey = issueKey;\n minimized = storageGet(MINIMIZED_STORAGE_KEY) === issueKey;\n }\n\n if (minimized) {\n releaseFocusIfHeld();\n root.appendChild(renderIssuePill({\n kind: issue.kind,\n label: issue.kind === \"error\" ? \"Config error\" : \"Config warning\",\n ariaLabel: `Show Hexclave config ${issueLabel}`,\n onClick: () => {\n minimized = false;\n storageRemove(MINIMIZED_STORAGE_KEY);\n render(issue);\n },\n }));\n return;\n }\n\n root.appendChild(renderIssueCard({\n kind: issue.kind,\n badge: `Config ${issueLabel}`,\n title: issueTitle,\n bodyText,\n messageLabel: issue.kind === \"error\" ? \"Error message\" : \"Warning message\",\n message: issueMessage,\n footerText,\n ariaLabel: `Hexclave config ${issueLabel}`,\n aiPrompt: buildConfigIssueAiPrompt(issue),\n onCopyError: (copyError) => captureError(\"pushed-config-error-overlay-copy\", copyError),\n onCopyAiPromptError: (copyError) => captureError(\"pushed-config-error-overlay-copy-ai-prompt\", copyError),\n onMinimize: () => {\n minimized = true;\n storageSet(MINIMIZED_STORAGE_KEY, issueKey);\n render(issue);\n },\n }));\n const isNewIssue = focusedIssueKey !== issueKey;\n const previouslyFocused = isNewIssue ? undefined : focusTrap?.previouslyFocused ?? null;\n focusTrap?.release({ restoreFocus: isNewIssue });\n focusedIssueKey = issueKey;\n focusTrap = trapFocusInIssueCard(root, { moveFocusIntoCard: isNewIssue, previouslyFocused });\n };\n\n const refresh = () => {\n if (disposed || !canMountIntoDom()) {\n return;\n }\n runAsynchronously(async () => {\n const project = await app.getProject();\n if (disposed) {\n return;\n }\n render(project.pushedConfigError == null\n ? project.configWarnings.length === 0\n ? null\n : { kind: \"warning\", messages: project.configWarnings.map((warning) => warning.message) }\n : { kind: \"error\", messages: [project.pushedConfigError.message] });\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"pushed-config-error-overlay-refresh\", error);\n },\n });\n };\n\n // This is mounted from the base client-app constructor, which also runs\n // before subclass field initializers. Defer the first app call so overridden\n // methods like adminApp.getProject() can safely touch subclass caches.\n queueMicrotask(refresh);\n const interval = setInterval(refresh, REFRESH_INTERVAL_MS);\n\n const cleanup = () => {\n disposed = true;\n clearInterval(interval);\n releaseFocusIfHeld();\n root.remove();\n if (getGlobalUiInstance(GLOBAL_INSTANCE_KEY)?.cleanup === cleanup) {\n setGlobalUiInstance(GLOBAL_INSTANCE_KEY, null);\n }\n };\n setGlobalUiInstance(GLOBAL_INSTANCE_KEY, { cleanup });\n return cleanup;\n}\n\n"],"mappings":"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"}