@hexclave/tanstack-start 1.0.23 → 1.0.25

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 (80) hide show
  1. package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
  2. package/dist/dev-tool/dev-tool-core.js +3 -67
  3. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  4. package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
  5. package/dist/esm/dev-tool/dev-tool-core.js +3 -67
  6. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  7. package/dist/esm/generated/env.js +20 -20
  8. package/dist/esm/generated/env.js.map +1 -1
  9. package/dist/esm/lib/auth.js +2 -2
  10. package/dist/esm/lib/auth.js.map +1 -1
  11. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  12. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js +2 -0
  13. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
  14. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  15. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +9 -3
  16. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  17. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +1 -1
  18. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
  19. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js +2 -1
  20. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
  21. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js +26 -0
  22. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -1
  23. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.d.ts +7 -1
  24. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.d.ts.map +1 -1
  25. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.js +11 -1
  26. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.js.map +1 -1
  27. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.test.js +43 -0
  28. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.test.js.map +1 -1
  29. package/dist/esm/lib/hexclave-app/projects/index.d.ts +6 -0
  30. package/dist/esm/lib/hexclave-app/projects/index.d.ts.map +1 -1
  31. package/dist/esm/lib/hexclave-app/projects/index.js.map +1 -1
  32. package/dist/esm/lib/hexclave-app/url-targets.test.js +7 -7
  33. package/dist/esm/lib/hexclave-app/url-targets.test.js.map +1 -1
  34. package/dist/esm/pushed-config-error-overlay/index.d.ts +7 -0
  35. package/dist/esm/pushed-config-error-overlay/index.d.ts.map +1 -0
  36. package/dist/esm/pushed-config-error-overlay/index.js +464 -0
  37. package/dist/esm/pushed-config-error-overlay/index.js.map +1 -0
  38. package/dist/generated/env.js +20 -20
  39. package/dist/generated/env.js.map +1 -1
  40. package/dist/lib/auth.js +2 -2
  41. package/dist/lib/auth.js.map +1 -1
  42. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  43. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js +2 -0
  44. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
  45. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  46. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +9 -3
  47. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  48. package/dist/lib/hexclave-app/apps/implementations/common.js +1 -1
  49. package/dist/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
  50. package/dist/lib/hexclave-app/apps/implementations/event-tracker.js +1 -0
  51. package/dist/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
  52. package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js +26 -0
  53. package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -1
  54. package/dist/lib/hexclave-app/apps/implementations/session-replay.d.ts +7 -1
  55. package/dist/lib/hexclave-app/apps/implementations/session-replay.d.ts.map +1 -1
  56. package/dist/lib/hexclave-app/apps/implementations/session-replay.js +11 -0
  57. package/dist/lib/hexclave-app/apps/implementations/session-replay.js.map +1 -1
  58. package/dist/lib/hexclave-app/apps/implementations/session-replay.test.js +43 -0
  59. package/dist/lib/hexclave-app/apps/implementations/session-replay.test.js.map +1 -1
  60. package/dist/lib/hexclave-app/projects/index.d.ts +6 -0
  61. package/dist/lib/hexclave-app/projects/index.d.ts.map +1 -1
  62. package/dist/lib/hexclave-app/projects/index.js.map +1 -1
  63. package/dist/lib/hexclave-app/url-targets.test.js +7 -7
  64. package/dist/lib/hexclave-app/url-targets.test.js.map +1 -1
  65. package/dist/pushed-config-error-overlay/index.d.ts +7 -0
  66. package/dist/pushed-config-error-overlay/index.d.ts.map +1 -0
  67. package/dist/pushed-config-error-overlay/index.js +466 -0
  68. package/dist/pushed-config-error-overlay/index.js.map +1 -0
  69. package/package.json +3 -3
  70. package/src/dev-tool/dev-tool-core.ts +4 -58
  71. package/src/lib/auth.ts +2 -2
  72. package/src/lib/hexclave-app/apps/implementations/admin-app-impl.ts +6 -0
  73. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +11 -3
  74. package/src/lib/hexclave-app/apps/implementations/event-tracker.test.ts +33 -0
  75. package/src/lib/hexclave-app/apps/implementations/event-tracker.ts +6 -1
  76. package/src/lib/hexclave-app/apps/implementations/session-replay.test.ts +52 -0
  77. package/src/lib/hexclave-app/apps/implementations/session-replay.ts +20 -0
  78. package/src/lib/hexclave-app/projects/index.ts +2 -0
  79. package/src/lib/hexclave-app/url-targets.test.ts +7 -7
  80. package/src/pushed-config-error-overlay/index.ts +548 -0
@@ -0,0 +1,466 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_chunk = require('../chunk-BE-pF4vm.js');
3
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
4
+ let ___in_page_ui_dom_js = require("../in-page-ui/dom.js");
5
+ let ___in_page_ui_base_styles_js = require("../in-page-ui/base-styles.js");
6
+ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
7
+ let _hexclave_shared_dist_utils_urls = require("@hexclave/shared/dist/utils/urls");
8
+ let ___generated_env_js = require("../generated/env.js");
9
+
10
+ //#region src/pushed-config-error-overlay/index.ts
11
+ const GLOBAL_INSTANCE_KEY = "__hexclave-pushed-config-error-overlay";
12
+ const MINIMIZED_STORAGE_KEY = "hexclave-pushed-config-error-minimized-key";
13
+ const REFRESH_INTERVAL_MS = 5e3;
14
+ 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>";
15
+ 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>";
16
+ const css = (0, ___in_page_ui_base_styles_js.getInPageUiBaseCSS)(".hexclave-config-error-overlay") + `
17
+ .hexclave-config-error-overlay .hce-backdrop {
18
+ position: fixed;
19
+ inset: 0;
20
+ z-index: 2147483647;
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ padding: 24px;
25
+ background: rgba(0, 0, 0, 0.46);
26
+ backdrop-filter: blur(6px);
27
+ overflow: auto;
28
+ }
29
+
30
+ .hexclave-config-error-overlay .hce-card {
31
+ --hce-status: var(--sdt-error);
32
+ width: min(720px, calc(100vw - 32px));
33
+ max-height: min(640px, calc(100dvh - 48px));
34
+ border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));
35
+ border-radius: 18px;
36
+ background: var(--sdt-overlay-bg);
37
+ box-shadow: var(--sdt-shadow);
38
+ backdrop-filter: blur(18px);
39
+ display: flex;
40
+ overflow: hidden;
41
+ }
42
+
43
+ .hexclave-config-error-overlay .hce-card-warning {
44
+ --hce-status: var(--sdt-warning);
45
+ }
46
+
47
+ .hexclave-config-error-overlay .hce-card-inner {
48
+ padding: 18px;
49
+ width: 100%;
50
+ overflow: auto;
51
+ }
52
+
53
+ .hexclave-config-error-overlay .hce-header {
54
+ display: flex;
55
+ align-items: flex-start;
56
+ justify-content: space-between;
57
+ gap: 12px;
58
+ margin-bottom: 12px;
59
+ }
60
+
61
+ .hexclave-config-error-overlay .hce-title-row {
62
+ display: flex;
63
+ align-items: flex-start;
64
+ gap: 10px;
65
+ min-width: 0;
66
+ }
67
+
68
+ .hexclave-config-error-overlay .hce-logo {
69
+ flex-shrink: 0;
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ width: 34px;
74
+ height: 34px;
75
+ border-radius: 10px;
76
+ background: var(--hce-status);
77
+ color: white;
78
+ box-shadow: 0 10px 30px color-mix(in srgb, var(--hce-status) 32%, transparent);
79
+ }
80
+
81
+ .hexclave-config-error-overlay .hce-badge {
82
+ display: inline-flex;
83
+ flex-shrink: 0;
84
+ padding: 2px 6px;
85
+ border-radius: 999px;
86
+ background: var(--hce-status);
87
+ color: white;
88
+ font-size: 10px;
89
+ font-weight: 700;
90
+ letter-spacing: 0.06em;
91
+ text-transform: uppercase;
92
+ }
93
+
94
+ .hexclave-config-error-overlay .hce-title {
95
+ color: var(--sdt-text);
96
+ margin-top: 4px;
97
+ font-size: 18px;
98
+ font-weight: 700;
99
+ line-height: 1.25;
100
+ }
101
+
102
+ .hexclave-config-error-overlay .hce-actions {
103
+ display: flex;
104
+ gap: 4px;
105
+ }
106
+
107
+ .hexclave-config-error-overlay .hce-icon-btn {
108
+ display: inline-flex;
109
+ align-items: center;
110
+ justify-content: center;
111
+ width: 28px;
112
+ height: 28px;
113
+ border: 1px solid var(--sdt-border);
114
+ border-radius: 8px;
115
+ background: var(--sdt-bg-elevated);
116
+ color: var(--sdt-text-secondary);
117
+ cursor: pointer;
118
+ font: inherit;
119
+ line-height: 1;
120
+ vertical-align: top;
121
+ }
122
+
123
+ .hexclave-config-error-overlay .hce-icon-btn svg {
124
+ display: block;
125
+ flex-shrink: 0;
126
+ }
127
+
128
+ .hexclave-config-error-overlay .hce-text-btn {
129
+ align-items: center;
130
+ gap: 6px;
131
+ min-height: 28px;
132
+ padding: 0 10px;
133
+ width: auto;
134
+ font-size: 12px;
135
+ line-height: 1;
136
+ }
137
+
138
+ .hexclave-config-error-overlay .hce-icon-btn:hover {
139
+ background: var(--sdt-bg-hover);
140
+ color: var(--sdt-text);
141
+ }
142
+
143
+ .hexclave-config-error-overlay .hce-body {
144
+ color: var(--sdt-text-secondary);
145
+ font-size: 14px;
146
+ line-height: 1.5;
147
+ }
148
+
149
+ .hexclave-config-error-overlay .hce-message-header {
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: space-between;
153
+ gap: 10px;
154
+ margin-top: 14px;
155
+ margin-bottom: 8px;
156
+ }
157
+
158
+ .hexclave-config-error-overlay .hce-message-label {
159
+ color: var(--sdt-text);
160
+ font-size: 12px;
161
+ font-weight: 650;
162
+ }
163
+
164
+ .hexclave-config-error-overlay .hce-message {
165
+ padding: 12px;
166
+ max-height: min(260px, max(96px, 30dvh));
167
+ overflow: auto;
168
+ border: 1px solid var(--sdt-border-subtle);
169
+ border-radius: 10px;
170
+ background: var(--sdt-bg-subtle);
171
+ color: var(--sdt-text);
172
+ font-family: var(--sdt-font-mono);
173
+ font-size: 12px;
174
+ white-space: pre-wrap;
175
+ overflow-wrap: anywhere;
176
+ }
177
+
178
+ .hexclave-config-error-overlay .hce-footer {
179
+ margin-top: 10px;
180
+ color: var(--sdt-text-tertiary);
181
+ font-size: 12px;
182
+ }
183
+
184
+ .hexclave-config-error-overlay .hce-pill {
185
+ position: fixed;
186
+ right: 18px;
187
+ bottom: 18px;
188
+ z-index: 2147483647;
189
+ display: flex;
190
+ align-items: center;
191
+ gap: 8px;
192
+ padding: 8px 12px 8px 8px;
193
+ --hce-status: var(--sdt-error);
194
+ border: 1px solid color-mix(in srgb, var(--hce-status) 35%, var(--sdt-border));
195
+ border-radius: 999px;
196
+ background: var(--sdt-overlay-bg);
197
+ box-shadow: var(--sdt-trigger-shadow);
198
+ color: var(--sdt-text);
199
+ cursor: pointer;
200
+ font: inherit;
201
+ backdrop-filter: blur(18px);
202
+ }
203
+
204
+ .hexclave-config-error-overlay .hce-pill-warning {
205
+ --hce-status: var(--sdt-warning);
206
+ }
207
+
208
+ .hexclave-config-error-overlay .hce-pill-logo {
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+ width: 26px;
213
+ height: 26px;
214
+ border-radius: 999px;
215
+ background: var(--hce-status);
216
+ color: white;
217
+ }
218
+
219
+ @media (max-height: 520px) {
220
+ .hexclave-config-error-overlay .hce-backdrop {
221
+ align-items: flex-start;
222
+ padding: 12px;
223
+ }
224
+
225
+ .hexclave-config-error-overlay .hce-card {
226
+ width: min(720px, calc(100vw - 24px));
227
+ max-height: calc(100dvh - 24px);
228
+ }
229
+
230
+ .hexclave-config-error-overlay .hce-card-inner {
231
+ padding: 12px;
232
+ }
233
+
234
+ .hexclave-config-error-overlay .hce-header {
235
+ margin-bottom: 8px;
236
+ }
237
+
238
+ .hexclave-config-error-overlay .hce-title {
239
+ font-size: 16px;
240
+ }
241
+
242
+ .hexclave-config-error-overlay .hce-body {
243
+ font-size: 13px;
244
+ }
245
+
246
+ .hexclave-config-error-overlay .hce-message {
247
+ max-height: max(80px, 24dvh);
248
+ }
249
+ }
250
+ `;
251
+ function storageGet(key) {
252
+ try {
253
+ return localStorage.getItem(key);
254
+ } catch {
255
+ return null;
256
+ }
257
+ }
258
+ function storageSet(key, value) {
259
+ try {
260
+ localStorage.setItem(key, value);
261
+ } catch {}
262
+ }
263
+ function storageRemove(key) {
264
+ try {
265
+ localStorage.removeItem(key);
266
+ } catch {}
267
+ }
268
+ function shouldMount() {
269
+ if (!(0, ___in_page_ui_dom_js.canMountIntoDom)()) return false;
270
+ const nodeEnv = ___generated_env_js.envVars.NODE_ENV;
271
+ if (nodeEnv !== void 0) return nodeEnv === "development";
272
+ try {
273
+ if (new URL(window.location.href).protocol === "file:") return true;
274
+ } catch {
275
+ return false;
276
+ }
277
+ return (0, _hexclave_shared_dist_utils_urls.isLocalhost)(window.location.href);
278
+ }
279
+ async function copyTextToClipboard(text) {
280
+ const clipboard = Reflect.get(navigator, "clipboard");
281
+ const writeText = clipboard != null && typeof clipboard === "object" ? Reflect.get(clipboard, "writeText") : null;
282
+ if (typeof writeText === "function") {
283
+ await writeText.call(clipboard, text);
284
+ return;
285
+ }
286
+ const textarea = (0, ___in_page_ui_dom_js.h)("textarea", {
287
+ style: {
288
+ position: "fixed",
289
+ left: "-9999px",
290
+ top: "0",
291
+ opacity: "0"
292
+ },
293
+ readonly: "true"
294
+ });
295
+ textarea.value = text;
296
+ document.body.appendChild(textarea);
297
+ textarea.select();
298
+ const copied = document.execCommand("copy");
299
+ textarea.remove();
300
+ if (!copied) throw new Error("Browser refused to copy the config error message.");
301
+ }
302
+ function buildConfigIssueAiPrompt(issue) {
303
+ const issueLabel = issue.kind === "error" ? "error" : "warning";
304
+ return [
305
+ `Help me fix this Hexclave config ${issueLabel}.`,
306
+ "",
307
+ "Hexclave reminder:",
308
+ `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.`,
309
+ "",
310
+ issue.kind === "error" ? "Error message:" : "Warning message:",
311
+ issue.messages.join("\n"),
312
+ "",
313
+ "Please explain the likely cause, identify the config key or value I should change, and suggest the smallest safe fix."
314
+ ].join("\n");
315
+ }
316
+ function mountPushedConfigErrorOverlay(app) {
317
+ if (!shouldMount()) return () => {};
318
+ (0, ___in_page_ui_dom_js.getGlobalUiInstance)(GLOBAL_INSTANCE_KEY)?.cleanup();
319
+ const root = (0, ___in_page_ui_dom_js.h)("div", { className: "hexclave-config-error-overlay" });
320
+ const style = (0, ___in_page_ui_dom_js.h)("style", null, css);
321
+ root.appendChild(style);
322
+ document.body.appendChild(root);
323
+ let disposed = false;
324
+ let lastErrorKey = null;
325
+ let lastConsoleErrorKey = null;
326
+ let minimized = false;
327
+ const render = (issue) => {
328
+ root.replaceChildren(style);
329
+ if (issue == null) {
330
+ lastErrorKey = null;
331
+ minimized = false;
332
+ return;
333
+ }
334
+ const issueMessage = issue.messages.join("\n");
335
+ const issueKey = `${app.projectId}:${issue.kind}:${issueMessage}`;
336
+ const issueLabel = issue.kind === "error" ? "error" : "warning";
337
+ const issueTitle = issue.kind === "error" ? "Your Hexclave config has been saved, but contains errors" : "Your Hexclave config has been saved, but has warnings";
338
+ const bodyText = issue.kind === "error" ? "Your app can keep running, but Hexclave is still using the last valid config until this is fixed." : "Your app can keep running, but part of your Hexclave config may not behave the way you expect until this is fixed.";
339
+ const footerText = issue.kind === "error" ? "Fix the config file mentioned above and save it again. This message will disappear after the config sync succeeds." : "Fix the config file mentioned above and save it again. This warning will disappear after Hexclave syncs a config without warnings.";
340
+ if (issueKey !== lastConsoleErrorKey) {
341
+ lastConsoleErrorKey = issueKey;
342
+ const consoleMessage = `[Hexclave] Config ${issueLabel}: ${issueMessage}`;
343
+ if (issue.kind === "error") console.error(consoleMessage);
344
+ else console.warn(consoleMessage);
345
+ }
346
+ if (issueKey !== lastErrorKey) {
347
+ lastErrorKey = issueKey;
348
+ minimized = storageGet(MINIMIZED_STORAGE_KEY) === issueKey;
349
+ }
350
+ if (minimized) {
351
+ const logoSpan = (0, ___in_page_ui_dom_js.h)("span", { className: "hce-pill-logo" });
352
+ (0, ___in_page_ui_dom_js.setHtml)(logoSpan, HEXCLAVE_LOGO_SVG);
353
+ root.appendChild((0, ___in_page_ui_dom_js.h)("button", {
354
+ className: issue.kind === "error" ? "hce-pill" : "hce-pill hce-pill-warning",
355
+ type: "button",
356
+ onClick: () => {
357
+ minimized = false;
358
+ storageRemove(MINIMIZED_STORAGE_KEY);
359
+ render(issue);
360
+ }
361
+ }, logoSpan, (0, ___in_page_ui_dom_js.h)("span", null, issue.kind === "error" ? "Config error" : "Config warning")));
362
+ return;
363
+ }
364
+ const logoSpan = (0, ___in_page_ui_dom_js.h)("span", { className: "hce-logo" });
365
+ (0, ___in_page_ui_dom_js.setHtml)(logoSpan, HEXCLAVE_LOGO_SVG);
366
+ const copyButton = (0, ___in_page_ui_dom_js.h)("button", {
367
+ className: "hce-icon-btn hce-text-btn",
368
+ type: "button",
369
+ title: issue.kind === "error" ? "Copy error message" : "Copy warning message",
370
+ "aria-label": issue.kind === "error" ? "Copy config error message" : "Copy config warning message",
371
+ onClick: () => {
372
+ (0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
373
+ await copyTextToClipboard(issueMessage);
374
+ copyButton.textContent = "Copied";
375
+ setTimeout(() => {
376
+ (0, ___in_page_ui_dom_js.setHtml)(copyButton, `${COPY_ICON_SVG}Copy`);
377
+ }, 1500);
378
+ }, {
379
+ noErrorLogging: true,
380
+ onError: (copyError) => {
381
+ (0, _hexclave_shared_dist_utils_errors.captureError)("pushed-config-error-overlay-copy", copyError);
382
+ copyButton.textContent = "Copy failed";
383
+ setTimeout(() => {
384
+ (0, ___in_page_ui_dom_js.setHtml)(copyButton, `${COPY_ICON_SVG}Copy`);
385
+ }, 1500);
386
+ }
387
+ });
388
+ }
389
+ });
390
+ (0, ___in_page_ui_dom_js.setHtml)(copyButton, `${COPY_ICON_SVG}Copy`);
391
+ const aiPromptCopyButton = (0, ___in_page_ui_dom_js.h)("button", {
392
+ className: "hce-icon-btn",
393
+ type: "button",
394
+ title: "Copy AI prompt",
395
+ "aria-label": issue.kind === "error" ? "Copy AI prompt for config error" : "Copy AI prompt for config warning",
396
+ onClick: () => {
397
+ (0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
398
+ await copyTextToClipboard(buildConfigIssueAiPrompt(issue));
399
+ aiPromptCopyButton.textContent = "✓";
400
+ setTimeout(() => {
401
+ (0, ___in_page_ui_dom_js.setHtml)(aiPromptCopyButton, COPY_ICON_SVG);
402
+ }, 1500);
403
+ }, {
404
+ noErrorLogging: true,
405
+ onError: (copyError) => {
406
+ (0, _hexclave_shared_dist_utils_errors.captureError)("pushed-config-error-overlay-copy-ai-prompt", copyError);
407
+ aiPromptCopyButton.textContent = "!";
408
+ setTimeout(() => {
409
+ (0, ___in_page_ui_dom_js.setHtml)(aiPromptCopyButton, COPY_ICON_SVG);
410
+ }, 1500);
411
+ }
412
+ });
413
+ }
414
+ });
415
+ (0, ___in_page_ui_dom_js.setHtml)(aiPromptCopyButton, COPY_ICON_SVG);
416
+ root.appendChild((0, ___in_page_ui_dom_js.h)("div", { className: "hce-backdrop" }, (0, ___in_page_ui_dom_js.h)("div", {
417
+ className: issue.kind === "error" ? "hce-card" : "hce-card hce-card-warning",
418
+ role: "alertdialog",
419
+ "aria-modal": "true",
420
+ "aria-label": `Hexclave config ${issueLabel}`
421
+ }, (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", {
422
+ className: "hce-icon-btn",
423
+ type: "button",
424
+ title: "Minimize",
425
+ "aria-label": issue.kind === "error" ? "Minimize config error" : "Minimize config warning",
426
+ onClick: () => {
427
+ minimized = true;
428
+ storageSet(MINIMIZED_STORAGE_KEY, issueKey);
429
+ render(issue);
430
+ }
431
+ }, "–"))), (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))))));
432
+ };
433
+ const refresh = () => {
434
+ if (disposed || !(0, ___in_page_ui_dom_js.canMountIntoDom)()) return;
435
+ (0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
436
+ const project = await app.getProject();
437
+ if (disposed) return;
438
+ render(project.pushedConfigError == null ? project.configWarnings.length === 0 ? null : {
439
+ kind: "warning",
440
+ messages: project.configWarnings.map((warning) => warning.message)
441
+ } : {
442
+ kind: "error",
443
+ messages: [project.pushedConfigError.message]
444
+ });
445
+ }, {
446
+ noErrorLogging: true,
447
+ onError: (error) => {
448
+ (0, _hexclave_shared_dist_utils_errors.captureError)("pushed-config-error-overlay-refresh", error);
449
+ }
450
+ });
451
+ };
452
+ refresh();
453
+ const interval = setInterval(refresh, REFRESH_INTERVAL_MS);
454
+ const cleanup = () => {
455
+ disposed = true;
456
+ clearInterval(interval);
457
+ root.remove();
458
+ if ((0, ___in_page_ui_dom_js.getGlobalUiInstance)(GLOBAL_INSTANCE_KEY)?.cleanup === cleanup) (0, ___in_page_ui_dom_js.setGlobalUiInstance)(GLOBAL_INSTANCE_KEY, null);
459
+ };
460
+ (0, ___in_page_ui_dom_js.setGlobalUiInstance)(GLOBAL_INSTANCE_KEY, { cleanup });
461
+ return cleanup;
462
+ }
463
+
464
+ //#endregion
465
+ exports.mountPushedConfigErrorOverlay = mountPushedConfigErrorOverlay;
466
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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 = 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 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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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
3
3
  "name": "@hexclave/tanstack-start",
4
- "version": "1.0.23",
4
+ "version": "1.0.25",
5
5
  "repository": "https://github.com/hexclave/hexclave",
6
6
  "sideEffects": false,
7
7
  "main": "./dist/index.js",
@@ -86,8 +86,8 @@
86
86
  "rrweb": "^1.1.3",
87
87
  "tsx": "^4.21.0",
88
88
  "yup": "^1.7.1",
89
- "@hexclave/shared": "1.0.23",
90
- "@hexclave/ui": "1.0.23"
89
+ "@hexclave/ui": "1.0.25",
90
+ "@hexclave/shared": "1.0.25"
91
91
  },
92
92
  "peerDependencies": {
93
93
  "@types/react": ">=18.0.0",
@@ -638,11 +638,6 @@ function createOverviewTab(app: StackClientApp<true>): TabResult {
638
638
 
639
639
  const actions = h('div', { className: 'sdt-ov-actions' });
640
640
  const toast = h('div', { className: 'sdt-ov-toast', style: { display: 'none' } });
641
- const emailRow = h('div', { className: 'sdt-ov-email-input' });
642
- const emailInput = h('input', { type: 'email', placeholder: 'Sign in as email\u2026' }) as HTMLInputElement;
643
- const emailBtn = h('button', null);
644
- setHtml(emailBtn, '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>');
645
- emailRow.append(emailInput, emailBtn);
646
641
 
647
642
  function isBestEffortOverviewError(error: unknown) {
648
643
  if (error instanceof DOMException && error.name === 'AbortError') {
@@ -704,15 +699,14 @@ function createOverviewTab(app: StackClientApp<true>): TabResult {
704
699
  });
705
700
  actions.append(signOutBtn, randomBtn);
706
701
  } else {
707
- const quickBtn = h('button', { className: 'sdt-ov-btn sdt-ov-btn-primary sdt-ov-btn-wide' }, loading ? 'Working\u2026' : 'Quick Sign In');
702
+ const quickBtn = h('button', { className: 'sdt-ov-btn sdt-ov-btn-primary sdt-ov-btn-wide' }, loading ? 'Working\u2026' : 'Quick Sign Up');
708
703
  quickBtn.disabled = loading;
709
704
  quickBtn.addEventListener('click', () => {
710
705
  runAsynchronously(doQuickSignIn());
711
706
  });
712
707
  actions.appendChild(quickBtn);
713
708
  }
714
- emailInput.placeholder = currentUser ? 'Switch to email\u2026' : 'Sign in as email\u2026';
715
- actions.appendChild(emailRow);
709
+
716
710
  }
717
711
 
718
712
  async function doQuickSignIn() {
@@ -744,54 +738,6 @@ function createOverviewTab(app: StackClientApp<true>): TabResult {
744
738
  await refreshUser();
745
739
  }
746
740
 
747
- async function doSignInAs(targetEmail: string) {
748
- if (!targetEmail.trim()) return;
749
- if (!isLocalhost(window.location.href)) {
750
- showToast('Quick sign-in is only available on localhost', 'error');
751
- return;
752
- }
753
- loading = true;
754
- rebuildActions();
755
- const trimmed = targetEmail.trim();
756
- try {
757
- const signInResult = await app.signInWithCredential({ email: trimmed, password: trimmed, noRedirect: true });
758
- if (signInResult.status === 'ok') {
759
- showToast(`Signed in as ${trimmed}`, 'success');
760
- emailInput.value = '';
761
- loading = false;
762
- await refreshUser();
763
- return;
764
- }
765
- const signUpResult = await app.signUpWithCredential({ email: trimmed, password: trimmed, noRedirect: true } as any);
766
- if (signUpResult.status === 'error') {
767
- showToast(`Failed: ${signUpResult.error.message}`, 'error');
768
- loading = false;
769
- rebuildActions();
770
- return;
771
- }
772
- const retryResult = await app.signInWithCredential({ email: trimmed, password: trimmed, noRedirect: true });
773
- if (retryResult.status === 'error') {
774
- showToast(`Sign in failed: ${retryResult.error.message}`, 'error');
775
- } else {
776
- showToast(`Signed in as ${trimmed}`, 'success');
777
- emailInput.value = '';
778
- }
779
- } catch (e: any) {
780
- showToast(e.message || 'Unknown error', 'error');
781
- }
782
- loading = false;
783
- await refreshUser();
784
- }
785
-
786
- emailBtn.addEventListener('click', () => {
787
- runAsynchronously(doSignInAs(emailInput.value));
788
- });
789
- emailInput.addEventListener('keydown', (e) => {
790
- if (e.key === 'Enter') {
791
- runAsynchronously(doSignInAs(emailInput.value));
792
- }
793
- });
794
-
795
741
  heroCard.append(actions, toast);
796
742
 
797
743
  // ── Auth methods card ──────────────────────────────────────────────────────
@@ -855,7 +801,7 @@ function createOverviewTab(app: StackClientApp<true>): TabResult {
855
801
  function buildChecklist() {
856
802
  checksCard.innerHTML = '';
857
803
  const currentUserCheck = hasPersistentTokenStore
858
- ? { ok: !!currentUser, label: 'Sign in a test user', hint: 'Use \u201cQuick Sign In\u201d above \u2192' }
804
+ ? { ok: !!currentUser, label: 'Sign in a test user', hint: 'Use \u201cQuick Sign Up\u201d above \u2192' }
859
805
  : { ok: true, label: 'Current-user tools unavailable', hint: null };
860
806
  const checks = [
861
807
  { ok: !!projectId && projectId !== 'default', label: 'Project configured', hint: null },
@@ -925,7 +871,7 @@ function createOverviewTab(app: StackClientApp<true>): TabResult {
925
871
  } else {
926
872
  avatar.textContent = initials;
927
873
  }
928
- userName.textContent = currentUser.displayName || 'Anonymous';
874
+ userName.textContent = currentUser.displayName || '(No display name)';
929
875
  userEmail.textContent = currentUser.primaryEmail || 'No email';
930
876
  authIndicator.style.display = '';
931
877
  } else {
package/src/lib/auth.ts CHANGED
@@ -138,13 +138,13 @@ function consumeOAuthCallbackQueryParams(options?: {
138
138
  // If the state can't be found in the cookies, then the callback wasn't meant for us.
139
139
  // Maybe the website uses another OAuth library?
140
140
  console.warn(deindent`
141
- Stack found an outer OAuth callback state in the query parameters, but not in cookies.
141
+ Hexclave found an outer OAuth callback state in the query parameters, but not in cookies.
142
142
 
143
143
  This could have multiple reasons:
144
144
  - The cookie expired, because the OAuth flow took too long.
145
145
  - The user's browser deleted the cookie, either manually or because of a very strict cookie policy.
146
146
  - The cookie was already consumed by this page, and the user already logged in.
147
- - You are using another OAuth client library with the same callback URL as Stack.
147
+ - You are using another OAuth client library with the same callback URL as Hexclave.
148
148
  - The user opened the OAuth callback page from their history.
149
149
 
150
150
  Either way, it is probably safe to ignore this warning unless you are debugging an OAuth issue.
@@ -200,6 +200,12 @@ export class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Proj
200
200
  logoFullUrl: data.logo_full_url,
201
201
  logoDarkModeUrl: data.logo_dark_mode_url,
202
202
  logoFullDarkModeUrl: data.logo_full_dark_mode_url,
203
+ pushedConfigError: data.pushed_config_error == null ? null : {
204
+ message: data.pushed_config_error.message,
205
+ },
206
+ configWarnings: data.config_warnings.map((warning) => ({
207
+ message: warning.message,
208
+ })),
203
209
  config: {
204
210
  signUpEnabled: data.config.sign_up_enabled,
205
211
  credentialEnabled: data.config.credential_enabled,